aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-02-13 18:06:38 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-04-21 00:46:58 -0400
commit1ba6ab11d8fbd8d29afec4e39236e1255ae0339a (patch)
tree68970431b31c1fd21966f567113f87d24c6c7196
parent3b57eff02c37c79e6254884d374a6a9233e11efc (diff)
PCI: remove initial bios sort of PCI devices on x86
We currently keep 2 lists of PCI devices in the system, one in the driver core, and one all on its own. This second list is sorted at boot time, in "BIOS" order, to try to remain compatible with older kernels (2.2 and earlier days). There was also a "nosort" option to turn this sorting off, to remain compatible with even older kernel versions, but that just ends up being what we have been doing from 2.5 days... Unfortunately, the second list of devices is not really ever used to determine the probing order of PCI devices or drivers[1]. That is done using the driver core list instead. This change happened back in the early 2.5 days. Relying on BIOS ording for the binding of drivers to specific device names is problematic for many reasons, and userspace tools like udev exist to properly name devices in a persistant manner if that is needed, no reliance on the BIOS is needed. Matt Domsch and others at Dell noticed this back in 2006, and added a boot option to sort the PCI device lists (both of them) in a breadth-first manner to help remain compatible with the 2.4 order, if needed for any reason. This option is not going away, as some systems rely on them. This patch removes the sorting of the internal PCI device list in "BIOS" mode, as it's not needed at all anymore, and hasn't for many years. I've also removed the PCI flags for this from some other arches that for some reason defined them, but never used them. This should not change the ordering of any drivers or device probing. [1] The old-style pci_get_device and pci_find_device() still used this sorting order, but there are very few drivers that use these functions, as they are deprecated for use in this manner. If for some reason, a driver rely on the order and uses these functions, the breadth-first boot option will resolve any problem. Cc: Matt Domsch <Matt_Domsch@dell.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.h2
-rw-r--r--arch/mn10300/unit-asb2305/pci-asb2305.h2
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h2
-rw-r--r--arch/x86/pci/common.c7
-rw-r--r--arch/x86/pci/pcbios.c72
-rw-r--r--arch/x86/pci/pci.h3
-rw-r--r--include/asm-sh/mpc1211/pci.h2
8 files changed, 0 insertions, 94 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4b0f1ae31a4c..e30d8fe4e4b1 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1461,10 +1461,6 @@ and is between 256 and 4096 characters. It is defined in the file
1461 nomsi [MSI] If the PCI_MSI kernel config parameter is 1461 nomsi [MSI] If the PCI_MSI kernel config parameter is
1462 enabled, this kernel boot option can be used to 1462 enabled, this kernel boot option can be used to
1463 disable the use of MSI interrupts system-wide. 1463 disable the use of MSI interrupts system-wide.
1464 nosort [X86-32] Don't sort PCI devices according to
1465 order given by the PCI BIOS. This sorting is
1466 done to get a device order compatible with
1467 older kernels.
1468 biosirq [X86-32] Use PCI BIOS calls to get the interrupt 1464 biosirq [X86-32] Use PCI BIOS calls to get the interrupt
1469 routing table. These calls are known to be buggy 1465 routing table. These calls are known to be buggy
1470 on several machines and they hang the machine 1466 on several machines and they hang the machine
diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h
index 7481797ab382..0c7bf39dc729 100644
--- a/arch/frv/mb93090-mb00/pci-frv.h
+++ b/arch/frv/mb93090-mb00/pci-frv.h
@@ -17,8 +17,6 @@
17#define PCI_PROBE_BIOS 0x0001 17#define PCI_PROBE_BIOS 0x0001
18#define PCI_PROBE_CONF1 0x0002 18#define PCI_PROBE_CONF1 0x0002
19#define PCI_PROBE_CONF2 0x0004 19#define PCI_PROBE_CONF2 0x0004
20#define PCI_NO_SORT 0x0100
21#define PCI_BIOS_SORT 0x0200
22#define PCI_NO_CHECKS 0x0400 20#define PCI_NO_CHECKS 0x0400
23#define PCI_ASSIGN_ROMS 0x1000 21#define PCI_ASSIGN_ROMS 0x1000
24#define PCI_BIOS_IRQ_SCAN 0x2000 22#define PCI_BIOS_IRQ_SCAN 0x2000
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.h b/arch/mn10300/unit-asb2305/pci-asb2305.h
index 84634fa3bce6..9763d1ce343a 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.h
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.h
@@ -23,8 +23,6 @@
23#define PCI_PROBE_BIOS 1 23#define PCI_PROBE_BIOS 1
24#define PCI_PROBE_CONF1 2 24#define PCI_PROBE_CONF1 2
25#define PCI_PROBE_CONF2 4 25#define PCI_PROBE_CONF2 4
26#define PCI_NO_SORT 0x100
27#define PCI_BIOS_SORT 0x200
28#define PCI_NO_CHECKS 0x400 26#define PCI_NO_CHECKS 0x400
29#define PCI_ASSIGN_ROMS 0x1000 27#define PCI_ASSIGN_ROMS 0x1000
30#define PCI_BIOS_IRQ_SCAN 0x2000 28#define PCI_BIOS_IRQ_SCAN 0x2000
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index 07e29506080f..a83dcf70c13b 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -15,8 +15,6 @@
15#define PCI_PROBE_BIOS 1 15#define PCI_PROBE_BIOS 1
16#define PCI_PROBE_CONF1 2 16#define PCI_PROBE_CONF1 2
17#define PCI_PROBE_CONF2 4 17#define PCI_PROBE_CONF2 4
18#define PCI_NO_SORT 0x100
19#define PCI_BIOS_SORT 0x200
20#define PCI_NO_CHECKS 0x400 18#define PCI_NO_CHECKS 0x400
21#define PCI_ASSIGN_ROMS 0x1000 19#define PCI_ASSIGN_ROMS 0x1000
22#define PCI_BIOS_IRQ_SCAN 0x2000 20#define PCI_BIOS_IRQ_SCAN 0x2000
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7b6e3bb9b28c..c9ff4ff66739 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -427,10 +427,6 @@ static int __init pcibios_init(void)
427 427
428 if (pci_bf_sort >= pci_force_bf) 428 if (pci_bf_sort >= pci_force_bf)
429 pci_sort_breadthfirst(); 429 pci_sort_breadthfirst();
430#ifdef CONFIG_PCI_BIOS
431 if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
432 pcibios_sort();
433#endif
434 return 0; 430 return 0;
435} 431}
436 432
@@ -455,9 +451,6 @@ char * __devinit pcibios_setup(char *str)
455 } else if (!strcmp(str, "nobios")) { 451 } else if (!strcmp(str, "nobios")) {
456 pci_probe &= ~PCI_PROBE_BIOS; 452 pci_probe &= ~PCI_PROBE_BIOS;
457 return NULL; 453 return NULL;
458 } else if (!strcmp(str, "nosort")) {
459 pci_probe |= PCI_NO_SORT;
460 return NULL;
461 } else if (!strcmp(str, "biosirq")) { 454 } else if (!strcmp(str, "biosirq")) {
462 pci_probe |= PCI_BIOS_IRQ_SCAN; 455 pci_probe |= PCI_BIOS_IRQ_SCAN;
463 return NULL; 456 return NULL;
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index 2f7109ac4c15..37472fc6f729 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -152,28 +152,6 @@ static int __devinit check_pcibios(void)
152 return 0; 152 return 0;
153} 153}
154 154
155static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short device_id,
156 unsigned short index, unsigned char *bus, unsigned char *device_fn)
157{
158 unsigned short bx;
159 unsigned short ret;
160
161 __asm__("lcall *(%%edi); cld\n\t"
162 "jc 1f\n\t"
163 "xor %%ah, %%ah\n"
164 "1:"
165 : "=b" (bx),
166 "=a" (ret)
167 : "1" (PCIBIOS_FIND_PCI_DEVICE),
168 "c" (device_id),
169 "d" (vendor),
170 "S" ((int) index),
171 "D" (&pci_indirect));
172 *bus = (bx >> 8) & 0xff;
173 *device_fn = bx & 0xff;
174 return (int) (ret & 0xff00) >> 8;
175}
176
177static int pci_bios_read(unsigned int seg, unsigned int bus, 155static int pci_bios_read(unsigned int seg, unsigned int bus,
178 unsigned int devfn, int reg, int len, u32 *value) 156 unsigned int devfn, int reg, int len, u32 *value)
179{ 157{
@@ -364,55 +342,6 @@ static struct pci_raw_ops * __devinit pci_find_bios(void)
364} 342}
365 343
366/* 344/*
367 * Sort the device list according to PCI BIOS. Nasty hack, but since some
368 * fool forgot to define the `correct' device order in the PCI BIOS specs
369 * and we want to be (possibly bug-to-bug ;-]) compatible with older kernels
370 * which used BIOS ordering, we are bound to do this...
371 */
372
373void __devinit pcibios_sort(void)
374{
375 LIST_HEAD(sorted_devices);
376 struct list_head *ln;
377 struct pci_dev *dev, *d;
378 int idx, found;
379 unsigned char bus, devfn;
380
381 DBG("PCI: Sorting device list...\n");
382 while (!list_empty(&pci_devices)) {
383 ln = pci_devices.next;
384 dev = pci_dev_g(ln);
385 idx = found = 0;
386 while (pci_bios_find_device(dev->vendor, dev->device, idx, &bus, &devfn) == PCIBIOS_SUCCESSFUL) {
387 idx++;
388 list_for_each(ln, &pci_devices) {
389 d = pci_dev_g(ln);
390 if (d->bus->number == bus && d->devfn == devfn) {
391 list_move_tail(&d->global_list, &sorted_devices);
392 if (d == dev)
393 found = 1;
394 break;
395 }
396 }
397 if (ln == &pci_devices) {
398 printk(KERN_WARNING "PCI: BIOS reporting unknown device %02x:%02x\n", bus, devfn);
399 /*
400 * We must not continue scanning as several buggy BIOSes
401 * return garbage after the last device. Grr.
402 */
403 break;
404 }
405 }
406 if (!found) {
407 printk(KERN_WARNING "PCI: Device %s not found by BIOS\n",
408 pci_name(dev));
409 list_move_tail(&dev->global_list, &sorted_devices);
410 }
411 }
412 list_splice(&sorted_devices, &pci_devices);
413}
414
415/*
416 * BIOS Functions for IRQ Routing 345 * BIOS Functions for IRQ Routing
417 */ 346 */
418 347
@@ -495,7 +424,6 @@ void __init pci_pcbios_init(void)
495{ 424{
496 if ((pci_probe & PCI_PROBE_BIOS) 425 if ((pci_probe & PCI_PROBE_BIOS)
497 && ((raw_pci_ops = pci_find_bios()))) { 426 && ((raw_pci_ops = pci_find_bios()))) {
498 pci_probe |= PCI_BIOS_SORT;
499 pci_bios_present = 1; 427 pci_bios_present = 1;
500 } 428 }
501} 429}
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index 3431518d921a..02b016a98423 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -19,8 +19,6 @@
19#define PCI_PROBE_MASK 0x000f 19#define PCI_PROBE_MASK 0x000f
20#define PCI_PROBE_NOEARLY 0x0010 20#define PCI_PROBE_NOEARLY 0x0010
21 21
22#define PCI_NO_SORT 0x0100
23#define PCI_BIOS_SORT 0x0200
24#define PCI_NO_CHECKS 0x0400 22#define PCI_NO_CHECKS 0x0400
25#define PCI_USE_PIRQ_MASK 0x0800 23#define PCI_USE_PIRQ_MASK 0x0800
26#define PCI_ASSIGN_ROMS 0x1000 24#define PCI_ASSIGN_ROMS 0x1000
@@ -101,7 +99,6 @@ extern int pci_direct_probe(void);
101extern void pci_direct_init(int type); 99extern void pci_direct_init(int type);
102extern void pci_pcbios_init(void); 100extern void pci_pcbios_init(void);
103extern void pci_mmcfg_init(int type); 101extern void pci_mmcfg_init(int type);
104extern void pcibios_sort(void);
105 102
106/* pci-mmconfig.c */ 103/* pci-mmconfig.c */
107 104
diff --git a/include/asm-sh/mpc1211/pci.h b/include/asm-sh/mpc1211/pci.h
index 5d3712c3a701..d9162c5ed76a 100644
--- a/include/asm-sh/mpc1211/pci.h
+++ b/include/asm-sh/mpc1211/pci.h
@@ -24,8 +24,6 @@
24#define PCI_PROBE_BIOS 1 24#define PCI_PROBE_BIOS 1
25#define PCI_PROBE_CONF1 2 25#define PCI_PROBE_CONF1 2
26#define PCI_PROBE_CONF2 4 26#define PCI_PROBE_CONF2 4
27#define PCI_NO_SORT 0x100
28#define PCI_BIOS_SORT 0x200
29#define PCI_NO_CHECKS 0x400 27#define PCI_NO_CHECKS 0x400
30#define PCI_ASSIGN_ROMS 0x1000 28#define PCI_ASSIGN_ROMS 0x1000
31#define PCI_BIOS_IRQ_SCAN 0x2000 29#define PCI_BIOS_IRQ_SCAN 0x2000