linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / x86_64 / pci / mmconfig.c
index a4056c6..18f371f 100644 (file)
@@ -9,19 +9,11 @@
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
-#include <asm/e820.h>
-
 #include "pci.h"
 
-/* aperture is up to 256MB but BIOS may reserve less */
-#define MMCONFIG_APER_MIN      (2 * 1024*1024)
-#define MMCONFIG_APER_MAX      (256 * 1024*1024)
-
-/* Verify the first 16 busses. We assume that systems with more busses
-   get MCFG right. */
-#define MAX_CHECK_BUS 16
+#define MMCONFIG_APER_SIZE (256*1024*1024)
 
-static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS);
+static DECLARE_BITMAP(fallback_slots, 32);
 
 /* Static virtual mapping of the MMCONFIG aperture */
 struct mmcfg_virt {
@@ -63,8 +55,7 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus)
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
        char __iomem *addr;
-       if (seg == 0 && bus < MAX_CHECK_BUS &&
-               test_bit(32*bus + PCI_SLOT(devfn), fallback_slots))
+       if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots))
                return NULL;
        addr = get_virt(seg, bus);
        if (!addr)
@@ -78,10 +69,8 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
        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))) {
-               *value = -1;
+       if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
                return -EINVAL;
-       }
 
        addr = pci_dev_base(seg, bus, devfn);
        if (!addr)
@@ -140,66 +129,51 @@ static struct pci_raw_ops pci_mmcfg = {
    Normally this can be expressed in the MCFG by not listing them
    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
    Instead try to discover all devices on bus 0 that are unreachable using MM
-   and fallback for them. */
+   and fallback for them.
+   We only do this for bus 0/seg 0 */
 static __init void unreachable_devices(void)
 {
-       int i, k;
-       /* Use the max bus number from ACPI here? */
-       for (k = 0; k < MAX_CHECK_BUS; k++) {
-               for (i = 0; i < 32; i++) {
-                       u32 val1;
-                       char __iomem *addr;
-
-                       pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
-                       if (val1 == 0xffffffff)
-                               continue;
-                       addr = pci_dev_base(0, k, PCI_DEVFN(i, 0));
-                       if (addr == NULL|| readl(addr) != val1) {
-                               set_bit(i + 32*k, fallback_slots);
-                               printk(KERN_NOTICE
-                               "PCI: No mmconfig possible on device %x:%x\n",
-                                       k, i);
-                       }
+       int i;
+       for (i = 0; i < 32; i++) {
+               u32 val1;
+               char __iomem *addr;
+
+               pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
+               if (val1 == 0xffffffff)
+                       continue;
+               addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0));
+               if (addr == NULL|| readl(addr) != val1) {
+                       set_bit(i, &fallback_slots);
                }
        }
 }
 
-void __init pci_mmcfg_init(void)
+static int __init pci_mmcfg_init(void)
 {
        int i;
 
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
-               return;
+               return 0;
 
        acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
        if ((pci_mmcfg_config_num == 0) ||
            (pci_mmcfg_config == NULL) ||
            (pci_mmcfg_config[0].base_address == 0))
-               return;
-
-       if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
-                       pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
-                       E820_RESERVED)) {
-               printk(KERN_INFO "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
-                               pci_mmcfg_config[0].base_address);
-               printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
-               return;
-       }
+               return 0;
 
        /* RED-PEN i386 doesn't do _nocache right now */
        pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
        if (pci_mmcfg_virt == NULL) {
                printk("PCI: Can not allocate memory for mmconfig structures\n");
-               return;
+               return 0;
        }
        for (i = 0; i < pci_mmcfg_config_num; ++i) {
                pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
-               pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
-                                                        MMCONFIG_APER_MAX);
+               pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
                if (!pci_mmcfg_virt[i].virt) {
                        printk("PCI: Cannot map mmconfig aperture for segment %d\n",
                               pci_mmcfg_config[i].pci_segment_group_number);
-                       return;
+                       return 0;
                }
                printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
        }
@@ -208,4 +182,8 @@ void __init pci_mmcfg_init(void)
 
        raw_pci_ops = &pci_mmcfg;
        pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
+
+       return 0;
 }
+
+arch_initcall(pci_mmcfg_init);