USB: ohci: quirk AMD prefetch for USB 1.1 ISO transfer
[safe/jmp/linux-2.6] / drivers / pci / rom.c
index cbb69cf..36864a9 100644 (file)
@@ -6,7 +6,6 @@
  *
  * PCI ROM access routines
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
@@ -22,7 +21,7 @@
  * between the ROM and other resources, so enabling it may disable access
  * to MMIO registers or other card memory.
  */
-static int pci_enable_rom(struct pci_dev *pdev)
+int pci_enable_rom(struct pci_dev *pdev)
 {
        struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
        struct pci_bus_region region;
@@ -46,7 +45,7 @@ static int pci_enable_rom(struct pci_dev *pdev)
  * Disable ROM decoding on a PCI device by turning off the last bit in the
  * ROM BAR.
  */
-static void pci_disable_rom(struct pci_dev *pdev)
+void pci_disable_rom(struct pci_dev *pdev)
 {
        u32 rom_addr;
        pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
@@ -55,10 +54,57 @@ static void pci_disable_rom(struct pci_dev *pdev)
 }
 
 /**
+ * pci_get_rom_size - obtain the actual size of the ROM image
+ * @pdev: target PCI device
+ * @rom: kernel virtual pointer to image of ROM
+ * @size: size of PCI window
+ *  return: size of actual ROM image
+ *
+ * Determine the actual length of the ROM image.
+ * The PCI window size could be much larger than the
+ * actual image size.
+ */
+size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
+{
+       void __iomem *image;
+       int last_image;
+
+       image = rom;
+       do {
+               void __iomem *pds;
+               /* Standard PCI ROMs start out with these bytes 55 AA */
+               if (readb(image) != 0x55) {
+                       dev_err(&pdev->dev, "Invalid ROM contents\n");
+                       break;
+               }
+               if (readb(image + 1) != 0xAA)
+                       break;
+               /* get the PCI data structure and check its signature */
+               pds = image + readw(image + 24);
+               if (readb(pds) != 'P')
+                       break;
+               if (readb(pds + 1) != 'C')
+                       break;
+               if (readb(pds + 2) != 'I')
+                       break;
+               if (readb(pds + 3) != 'R')
+                       break;
+               last_image = readb(pds + 21) & 0x80;
+               /* this length is reliable */
+               image += readw(pds + 16) * 512;
+       } while (!last_image);
+
+       /* never return a size larger than the PCI resource window */
+       /* there are known ROMs that get the size wrong */
+       return min((size_t)(image - rom), size);
+}
+
+/**
  * pci_map_rom - map a PCI ROM to kernel space
  * @pdev: pointer to pci device struct
  * @size: pointer to receive size of pci window over ROM
- * @return: kernel virtual pointer to image of ROM
+ *
+ * Return: kernel virtual pointer to image of ROM
  *
  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
  * the shadow BIOS copy will be returned instead of the
@@ -69,16 +115,19 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
        struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
        loff_t start;
        void __iomem *rom;
-       void __iomem *image;
-       int last_image;
 
-       /* IORESOURCE_ROM_SHADOW only set on x86 */
+       /*
+        * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
+        * memory map if the VGA enable bit of the Bridge Control register is
+        * set for embedded VGA.
+        */
        if (res->flags & IORESOURCE_ROM_SHADOW) {
                /* primary video rom always starts here */
                start = (loff_t)0xC0000;
                *size = 0x20000; /* cover C000:0 through E000:0 */
        } else {
-               if (res->flags & IORESOURCE_ROM_COPY) {
+               if (res->flags &
+                       (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
                        *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
                        return (void __iomem *)(unsigned long)
                                pci_resource_start(pdev, PCI_ROM_RESOURCE);
@@ -113,41 +162,17 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
         * size is much larger than the actual size of the ROM.
         * True size is important if the ROM is going to be copied.
         */
-       image = rom;
-       do {
-               void __iomem *pds;
-               /* Standard PCI ROMs start out with these bytes 55 AA */
-               if (readb(image) != 0x55)
-                       break;
-               if (readb(image + 1) != 0xAA)
-                       break;
-               /* get the PCI data structure and check its signature */
-               pds = image + readw(image + 24);
-               if (readb(pds) != 'P')
-                       break;
-               if (readb(pds + 1) != 'C')
-                       break;
-               if (readb(pds + 2) != 'I')
-                       break;
-               if (readb(pds + 3) != 'R')
-                       break;
-               last_image = readb(pds + 21) & 0x80;
-               /* this length is reliable */
-               image += readw(pds + 16) * 512;
-       } while (!last_image);
-
-       /* never return a size larger than the PCI resource window */
-       /* there are known ROMs that get the size wrong */
-       *size = min((size_t)(image - rom), *size);
-
+       *size = pci_get_rom_size(pdev, rom, *size);
        return rom;
 }
 
+#if 0
 /**
  * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
  * @pdev: pointer to pci device struct
  * @size: pointer to receive size of pci window over ROM
- * @return: kernel virtual pointer to image of ROM
+ *
+ * Return: kernel virtual pointer to image of ROM
  *
  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
  * the shadow BIOS copy will be returned instead of the
@@ -162,7 +187,8 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
        if (!rom)
                return NULL;
 
-       if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
+       if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW |
+                         IORESOURCE_ROM_BIOS_COPY))
                return rom;
 
        res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
@@ -176,6 +202,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
 
        return (void __iomem *)(unsigned long)res->start;
 }
+#endif  /*  0  */
 
 /**
  * pci_unmap_rom - unmap the ROM from kernel space
@@ -188,7 +215,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
 {
        struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 
-       if (res->flags & IORESOURCE_ROM_COPY)
+       if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
                return;
 
        iounmap(rom);
@@ -198,6 +225,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
                pci_disable_rom(pdev);
 }
 
+#if 0
 /**
  * pci_remove_rom - disable the ROM and remove its sysfs attribute
  * @pdev: pointer to pci device struct
@@ -212,13 +240,14 @@ void pci_remove_rom(struct pci_dev *pdev)
                sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
        if (!(res->flags & (IORESOURCE_ROM_ENABLE |
                            IORESOURCE_ROM_SHADOW |
+                           IORESOURCE_ROM_BIOS_COPY |
                            IORESOURCE_ROM_COPY)))
                pci_disable_rom(pdev);
 }
+#endif  /*  0  */
 
 /**
- * pci_cleanup_rom - internal routine for freeing the ROM copy created
- * by pci_map_rom_copy called from remove.c
+ * pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy
  * @pdev: pointer to pci device struct
  *
  * Free the copied ROM if we allocated one.
@@ -235,6 +264,6 @@ void pci_cleanup_rom(struct pci_dev *pdev)
 }
 
 EXPORT_SYMBOL(pci_map_rom);
-EXPORT_SYMBOL(pci_map_rom_copy);
 EXPORT_SYMBOL(pci_unmap_rom);
-EXPORT_SYMBOL(pci_remove_rom);
+EXPORT_SYMBOL_GPL(pci_enable_rom);
+EXPORT_SYMBOL_GPL(pci_disable_rom);