]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86_64/pci/mmconfig.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[linux-2.6-omap-h63xx.git] / arch / x86_64 / pci / mmconfig.c
index 9c4f907e301c7878bc94748d0f41b3db84cd0904..18f371fe37f89639f06ba4e24f876ea9854fd003 100644 (file)
@@ -18,22 +18,19 @@ static DECLARE_BITMAP(fallback_slots, 32);
 /* Static virtual mapping of the MMCONFIG aperture */
 struct mmcfg_virt {
        struct acpi_table_mcfg_config *cfg;
-       char *virt;
+       char __iomem *virt;
 };
 static struct mmcfg_virt *pci_mmcfg_virt;
 
-static char *get_virt(unsigned int seg, unsigned bus)
+static char __iomem *get_virt(unsigned int seg, unsigned bus)
 {
        int cfg_num = -1;
        struct acpi_table_mcfg_config *cfg;
 
        while (1) {
                ++cfg_num;
-               if (cfg_num >= pci_mmcfg_config_num) {
-                       /* Not found - fall back to type 1. This happens
-                          e.g. on the internal devices of a K8 northbridge. */
-                       return NULL;
-               }
+               if (cfg_num >= pci_mmcfg_config_num)
+                       break;
                cfg = pci_mmcfg_virt[cfg_num].cfg;
                if (cfg->pci_segment_group_number != seg)
                        continue;
@@ -41,11 +38,23 @@ static char *get_virt(unsigned int seg, unsigned bus)
                    (cfg->end_bus_number >= bus))
                        return pci_mmcfg_virt[cfg_num].virt;
        }
+
+       /* Handle more broken MCFG tables on Asus etc.
+          They only contain a single entry for bus 0-0. Assume
+          this applies to all busses. */
+       cfg = &pci_mmcfg_config[0];
+       if (pci_mmcfg_config_num == 1 &&
+               cfg->pci_segment_group_number == 0 &&
+               (cfg->start_bus_number | cfg->end_bus_number) == 0)
+               return pci_mmcfg_virt[0].virt;
+
+       /* Fall back to type 0 */
+       return NULL;
 }
 
-static char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
+static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-       char *addr;
+       char __iomem *addr;
        if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots))
                return NULL;
        addr = get_virt(seg, bus);
@@ -57,7 +66,7 @@ static char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                          unsigned int devfn, int reg, int len, u32 *value)
 {
-       char *addr;
+       char __iomem *addr;
 
        /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
        if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
@@ -85,7 +94,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
                           unsigned int devfn, int reg, int len, u32 value)
 {
-       char *addr;
+       char __iomem *addr;
 
        /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
        if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
@@ -127,7 +136,7 @@ static __init void unreachable_devices(void)
        int i;
        for (i = 0; i < 32; i++) {
                u32 val1;
-               char *addr;
+               char __iomem *addr;
 
                pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
                if (val1 == 0xffffffff)