]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/i386/pci/mmconfig.c
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[linux-2.6-omap-h63xx.git] / arch / i386 / pci / mmconfig.c
index 08a084901212ecddbf1b27b57a2ab48c62eddb7a..0ee8a983708c078b0e3e8f9b7c27548cd1936845 100644 (file)
@@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
        while (1) {
                ++cfg_num;
                if (cfg_num >= pci_mmcfg_config_num) {
-                       /* Not found - fallback to type 1 */
-                       return 0;
+                       break;
                }
                cfg = &pci_mmcfg_config[cfg_num];
                if (cfg->pci_segment_group_number != seg)
@@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
                    (cfg->end_bus_number >= bus))
                        return cfg->base_address;
        }
+
+       /* 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 cfg->base_address;
+
+       /* Fall back to type 0 */
+       return 0;
 }
 
 static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
@@ -155,7 +166,7 @@ static __init void unreachable_devices(void)
                addr = get_base_addr(0, 0, PCI_DEVFN(i, 0));
                if (addr != 0)
                        pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0));
-               if (addr == 0 || readl((u32 *)addr) != val1)
+               if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1)
                        set_bit(i, fallback_slots);
                spin_unlock_irqrestore(&pci_config_lock, flags);
        }