Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
[sfrench/cifs-2.6.git] / lib / iomap.c
index 4990c736bc4b6864df839b45b85dcfa8b3d361e2..a57d262a5ed9b574a27445b8f72b6d6030a85c3b 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/pci.h>
 #include <linux/io.h>
 
-#ifdef CONFIG_GENERIC_IOMAP
 #include <linux/module.h>
 
 /*
 #define PIO_RESERVED   0x40000UL
 #endif
 
+static void bad_io_access(unsigned long port, const char *access)
+{
+       static int count = 10;
+       if (count) {
+               count--;
+               printk(KERN_ERR "Bad IO access at port %lx (%s)\n", port, access);
+               WARN_ON(1);
+       }
+}
+
 /*
  * Ugly macros are a way of life.
  */
-#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET)
-
 #define IO_COND(addr, is_pio, is_mmio) do {                    \
        unsigned long port = (unsigned long __force)addr;       \
-       if (port < PIO_RESERVED) {                              \
-               VERIFY_PIO(port);                               \
+       if (port >= PIO_RESERVED) {                             \
+               is_mmio;                                        \
+       } else if (port > PIO_OFFSET) {                         \
                port &= PIO_MASK;                               \
                is_pio;                                         \
-       } else {                                                \
-               is_mmio;                                        \
-       }                                                       \
+       } else                                                  \
+               bad_io_access(port, #is_pio );                  \
 } while (0)
 
 #ifndef pio_read16be
 unsigned int fastcall ioread8(void __iomem *addr)
 {
        IO_COND(addr, return inb(port), return readb(addr));
+       return 0xff;
 }
 unsigned int fastcall ioread16(void __iomem *addr)
 {
        IO_COND(addr, return inw(port), return readw(addr));
+       return 0xffff;
 }
 unsigned int fastcall ioread16be(void __iomem *addr)
 {
        IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
+       return 0xffff;
 }
 unsigned int fastcall ioread32(void __iomem *addr)
 {
        IO_COND(addr, return inl(port), return readl(addr));
+       return 0xffffffff;
 }
 unsigned int fastcall ioread32be(void __iomem *addr)
 {
        IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
+       return 0xffffffff;
 }
 EXPORT_SYMBOL(ioread8);
 EXPORT_SYMBOL(ioread16);
@@ -256,298 +268,3 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
 }
 EXPORT_SYMBOL(pci_iomap);
 EXPORT_SYMBOL(pci_iounmap);
-
-#endif /* CONFIG_GENERIC_IOMAP */
-
-/*
- * Generic iomap devres
- */
-static void devm_ioport_map_release(struct device *dev, void *res)
-{
-       ioport_unmap(*(void __iomem **)res);
-}
-
-static int devm_ioport_map_match(struct device *dev, void *res,
-                                void *match_data)
-{
-       return *(void **)res == match_data;
-}
-
-/**
- * devm_ioport_map - Managed ioport_map()
- * @dev: Generic device to map ioport for
- * @port: Port to map
- * @nr: Number of ports to map
- *
- * Managed ioport_map().  Map is automatically unmapped on driver
- * detach.
- */
-void __iomem * devm_ioport_map(struct device *dev, unsigned long port,
-                              unsigned int nr)
-{
-       void __iomem **ptr, *addr;
-
-       ptr = devres_alloc(devm_ioport_map_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return NULL;
-
-       addr = ioport_map(port, nr);
-       if (addr) {
-               *ptr = addr;
-               devres_add(dev, ptr);
-       } else
-               devres_free(ptr);
-
-       return addr;
-}
-EXPORT_SYMBOL(devm_ioport_map);
-
-/**
- * devm_ioport_unmap - Managed ioport_unmap()
- * @dev: Generic device to unmap for
- * @addr: Address to unmap
- *
- * Managed ioport_unmap().  @addr must have been mapped using
- * devm_ioport_map().
- */
-void devm_ioport_unmap(struct device *dev, void __iomem *addr)
-{
-       ioport_unmap(addr);
-       WARN_ON(devres_destroy(dev, devm_ioport_map_release,
-                              devm_ioport_map_match, (void *)addr));
-}
-EXPORT_SYMBOL(devm_ioport_unmap);
-
-static void devm_ioremap_release(struct device *dev, void *res)
-{
-       iounmap(*(void __iomem **)res);
-}
-
-static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
-{
-       return *(void **)res == match_data;
-}
-
-/**
- * devm_ioremap - Managed ioremap()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap().  Map is automatically unmapped on driver detach.
- */
-void __iomem *devm_ioremap(struct device *dev, unsigned long offset,
-                          unsigned long size)
-{
-       void __iomem **ptr, *addr;
-
-       ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return NULL;
-
-       addr = ioremap(offset, size);
-       if (addr) {
-               *ptr = addr;
-               devres_add(dev, ptr);
-       } else
-               devres_free(ptr);
-
-       return addr;
-}
-EXPORT_SYMBOL(devm_ioremap);
-
-/**
- * devm_ioremap_nocache - Managed ioremap_nocache()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap_nocache().  Map is automatically unmapped on driver
- * detach.
- */
-void __iomem *devm_ioremap_nocache(struct device *dev, unsigned long offset,
-                                  unsigned long size)
-{
-       void __iomem **ptr, *addr;
-
-       ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return NULL;
-
-       addr = ioremap_nocache(offset, size);
-       if (addr) {
-               *ptr = addr;
-               devres_add(dev, ptr);
-       } else
-               devres_free(ptr);
-
-       return addr;
-}
-EXPORT_SYMBOL(devm_ioremap_nocache);
-
-/**
- * devm_iounmap - Managed iounmap()
- * @dev: Generic device to unmap for
- * @addr: Address to unmap
- *
- * Managed iounmap().  @addr must have been mapped using devm_ioremap*().
- */
-void devm_iounmap(struct device *dev, void __iomem *addr)
-{
-       iounmap(addr);
-       WARN_ON(devres_destroy(dev, devm_ioremap_release, devm_ioremap_match,
-                              (void *)addr));
-}
-EXPORT_SYMBOL(devm_iounmap);
-
-/*
- * PCI iomap devres
- */
-#define PCIM_IOMAP_MAX PCI_ROM_RESOURCE
-
-struct pcim_iomap_devres {
-       void __iomem *table[PCIM_IOMAP_MAX];
-};
-
-static void pcim_iomap_release(struct device *gendev, void *res)
-{
-       struct pci_dev *dev = container_of(gendev, struct pci_dev, dev);
-       struct pcim_iomap_devres *this = res;
-       int i;
-
-       for (i = 0; i < PCIM_IOMAP_MAX; i++)
-               if (this->table[i])
-                       pci_iounmap(dev, this->table[i]);
-}
-
-/**
- * pcim_iomap_table - access iomap allocation table
- * @pdev: PCI device to access iomap table for
- *
- * Access iomap allocation table for @dev.  If iomap table doesn't
- * exist and @pdev is managed, it will be allocated.  All iomaps
- * recorded in the iomap table are automatically unmapped on driver
- * detach.
- *
- * This function might sleep when the table is first allocated but can
- * be safely called without context and guaranteed to succed once
- * allocated.
- */
-void __iomem * const * pcim_iomap_table(struct pci_dev *pdev)
-{
-       struct pcim_iomap_devres *dr, *new_dr;
-
-       dr = devres_find(&pdev->dev, pcim_iomap_release, NULL, NULL);
-       if (dr)
-               return dr->table;
-
-       new_dr = devres_alloc(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL);
-       if (!new_dr)
-               return NULL;
-       dr = devres_get(&pdev->dev, new_dr, NULL, NULL);
-       return dr->table;
-}
-EXPORT_SYMBOL(pcim_iomap_table);
-
-/**
- * pcim_iomap - Managed pcim_iomap()
- * @pdev: PCI device to iomap for
- * @bar: BAR to iomap
- * @maxlen: Maximum length of iomap
- *
- * Managed pci_iomap().  Map is automatically unmapped on driver
- * detach.
- */
-void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen)
-{
-       void __iomem **tbl;
-
-       BUG_ON(bar >= PCIM_IOMAP_MAX);
-
-       tbl = (void __iomem **)pcim_iomap_table(pdev);
-       if (!tbl || tbl[bar])   /* duplicate mappings not allowed */
-               return NULL;
-
-       tbl[bar] = pci_iomap(pdev, bar, maxlen);
-       return tbl[bar];
-}
-EXPORT_SYMBOL(pcim_iomap);
-
-/**
- * pcim_iounmap - Managed pci_iounmap()
- * @pdev: PCI device to iounmap for
- * @addr: Address to unmap
- *
- * Managed pci_iounmap().  @addr must have been mapped using pcim_iomap().
- */
-void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr)
-{
-       void __iomem **tbl;
-       int i;
-
-       pci_iounmap(pdev, addr);
-
-       tbl = (void __iomem **)pcim_iomap_table(pdev);
-       BUG_ON(!tbl);
-
-       for (i = 0; i < PCIM_IOMAP_MAX; i++)
-               if (tbl[i] == addr) {
-                       tbl[i] = NULL;
-                       return;
-               }
-       WARN_ON(1);
-}
-EXPORT_SYMBOL(pcim_iounmap);
-
-/**
- * pcim_iomap_regions - Request and iomap PCI BARs
- * @pdev: PCI device to map IO resources for
- * @mask: Mask of BARs to request and iomap
- * @name: Name used when requesting regions
- *
- * Request and iomap regions specified by @mask.
- */
-int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
-{
-       void __iomem * const *iomap;
-       int i, rc;
-
-       iomap = pcim_iomap_table(pdev);
-       if (!iomap)
-               return -ENOMEM;
-
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               unsigned long len;
-
-               if (!(mask & (1 << i)))
-                       continue;
-
-               rc = -EINVAL;
-               len = pci_resource_len(pdev, i);
-               if (!len)
-                       goto err_inval;
-
-               rc = pci_request_region(pdev, i, name);
-               if (rc)
-                       goto err_region;
-
-               rc = -ENOMEM;
-               if (!pcim_iomap(pdev, i, 0))
-                       goto err_iomap;
-       }
-
-       return 0;
-
- err_iomap:
-       pcim_iounmap(pdev, iomap[i]);
- err_region:
-       pci_release_region(pdev, i);
- err_inval:
-       while (--i >= 0) {
-               pcim_iounmap(pdev, iomap[i]);
-               pci_release_region(pdev, i);
-       }
-
-       return rc;
-}
-EXPORT_SYMBOL(pcim_iomap_regions);