[PATCH] PCI: Give PCI config access initialization a defined ordering
authorAndi Kleen <ak@suse.de>
Thu, 23 Mar 2006 22:35:12 +0000 (14:35 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 23 Mar 2006 22:35:12 +0000 (14:35 -0800)
I moved it to a separate function which is safer.

This avoids problems with the linker reordering them and the
less useful PCI config space access methods taking priority
over the better ones.

Fixes some problems with broken MMCONFIG

Cc: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/i386/pci/Makefile
arch/i386/pci/direct.c
arch/i386/pci/init.c [new file with mode: 0644]
arch/i386/pci/mmconfig.c
arch/i386/pci/pcbios.c
arch/i386/pci/pci.h
arch/x86_64/pci/Makefile

index 5461d4d5ea1e414b1e607b9a5066d183831a1fa1..62ad75c57e6ae41047a40d480814fabdfdb28b5a 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                          := i386.o
+obj-y                          := i386.o init.o
 
 obj-$(CONFIG_PCI_BIOS)         += pcbios.o
 obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig.o direct.o
index e3ac502bf2fbac541cf57f52bef2a5a7300b881f..99012b93bd12b9f66e853eb08706be58e301171e 100644 (file)
@@ -245,7 +245,7 @@ static int __init pci_check_type2(void)
        return works;
 }
 
-static int __init pci_direct_init(void)
+void __init pci_direct_init(void)
 {
        struct resource *region, *region2;
 
@@ -258,16 +258,16 @@ static int __init pci_direct_init(void)
        if (pci_check_type1()) {
                printk(KERN_INFO "PCI: Using configuration type 1\n");
                raw_pci_ops = &pci_direct_conf1;
-               return 0;
+               return;
        }
        release_resource(region);
 
  type2:
        if ((pci_probe & PCI_PROBE_CONF2) == 0)
-               goto out;
+               return;
        region = request_region(0xCF8, 4, "PCI conf2");
        if (!region)
-               goto out;
+               return;
        region2 = request_region(0xC000, 0x1000, "PCI conf2");
        if (!region2)
                goto fail2;
@@ -275,15 +275,10 @@ static int __init pci_direct_init(void)
        if (pci_check_type2()) {
                printk(KERN_INFO "PCI: Using configuration type 2\n");
                raw_pci_ops = &pci_direct_conf2;
-               return 0;
+               return;
        }
 
        release_resource(region2);
  fail2:
        release_resource(region);
-
- out:
-       return 0;
 }
-
-arch_initcall(pci_direct_init);
diff --git a/arch/i386/pci/init.c b/arch/i386/pci/init.c
new file mode 100644 (file)
index 0000000..f9156d3
--- /dev/null
@@ -0,0 +1,25 @@
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci.h"
+
+/* arch_initcall has too random ordering, so call the initializers
+   in the right sequence from here. */
+static __init int pci_access_init(void)
+{
+#ifdef CONFIG_PCI_MMCONFIG
+       pci_mmcfg_init();
+#endif
+       if (raw_pci_ops)
+               return 0;
+#ifdef CONFIG_PCI_BIOS
+       pci_pcbios_init();
+#endif
+       if (raw_pci_ops)
+               return 0;
+#ifdef CONFIG_PCI_DIRECT
+       pci_direct_init();
+#endif
+       return 0;
+}
+arch_initcall(pci_access_init);
index 0ee8a983708c078b0e3e8f9b7c27548cd1936845..613789071f30dde13eec78efed2412ae3c399d90 100644 (file)
@@ -172,25 +172,20 @@ static __init void unreachable_devices(void)
        }
 }
 
-static int __init pci_mmcfg_init(void)
+void __init pci_mmcfg_init(void)
 {
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
-               goto out;
+               return;
 
        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))
-               goto out;
+               return;
 
        printk(KERN_INFO "PCI: Using MMCONFIG\n");
        raw_pci_ops = &pci_mmcfg;
        pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
        unreachable_devices();
-
- out:
-       return 0;
 }
-
-arch_initcall(pci_mmcfg_init);
index b9d65f0bc2d161411322d5a94d1456919f66b81f..1eec0868f4b3449df1f22aeb68926ffa2e8dc547 100644 (file)
@@ -476,14 +476,12 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
 }
 EXPORT_SYMBOL(pcibios_set_irq_routing);
 
-static int __init pci_pcbios_init(void)
+void __init pci_pcbios_init(void)
 {
        if ((pci_probe & PCI_PROBE_BIOS) 
                && ((raw_pci_ops = pci_find_bios()))) {
                pci_probe |= PCI_BIOS_SORT;
                pci_bios_present = 1;
        }
-       return 0;
 }
 
-arch_initcall(pci_pcbios_init);
index f550781ec3105f48d517b2ed09fcc80ddc5cba24..12035e29108b445889006bb5aa842057ad9d5bb3 100644 (file)
@@ -80,4 +80,7 @@ extern int pci_conf1_write(unsigned int seg, unsigned int bus,
 extern int pci_conf1_read(unsigned int seg, unsigned int bus,
                          unsigned int devfn, int reg, int len, u32 *value);
 
+extern void pci_direct_init(void);
+extern void pci_pcbios_init(void);
+extern void pci_mmcfg_init(void);
 
index a8f75a2a0f6f0a328eb7b24d336615982310b10d..a3f6ad570179d9a511a242a176a08922da3175bf 100644 (file)
@@ -7,7 +7,7 @@ CFLAGS += -Iarch/i386/pci
 
 obj-y          := i386.o
 obj-$(CONFIG_PCI_DIRECT)+= direct.o
-obj-y          += fixup.o
+obj-y          += fixup.o init.o
 obj-$(CONFIG_ACPI)     += acpi.o
 obj-y                  += legacy.o irq.o common.o
 # mmconfig has a 64bit special
@@ -22,3 +22,4 @@ irq-y    += ../../i386/pci/irq.o
 common-y += ../../i386/pci/common.o
 fixup-y  += ../../i386/pci/fixup.o
 i386-y  += ../../i386/pci/i386.o
+init-y += ../../i386/pci/init.o