aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2005-12-08 10:53:12 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-09 15:13:19 -0500
commit498879417756effe6dc385ee04645a83d724fdef (patch)
tree086bca4dd313d5fce46dccfd945f1b211ff5f141 /drivers
parent0eb3bcfd088e3234f7af29e189a7900ccfdd278a (diff)
[PATCH] PCI: use bus numbers sparsely, if necessary
Add a warning if a child bus may be inaccessible because the parent bridge has wrong secondary or subordinate bus numbers. Note that this may or may not happen on "transparent" bridges, as can be seen in bug #5557. Also, if we do not fix up the assignment of bus numbers, try to make use of the bus number space available. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/probe.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 00ba6a03dca5..3c9834d80850 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -433,7 +433,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
433{ 433{
434 struct pci_bus *child; 434 struct pci_bus *child;
435 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); 435 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
436 u32 buses, i; 436 u32 buses, i, j = 0;
437 u16 bctl; 437 u16 bctl;
438 438
439 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); 439 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -543,10 +543,29 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
543 * as cards with a PCI-to-PCI bridge can be 543 * as cards with a PCI-to-PCI bridge can be
544 * inserted later. 544 * inserted later.
545 */ 545 */
546 for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) 546 for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) {
547 struct pci_bus *parent = bus;
547 if (pci_find_bus(pci_domain_nr(bus), 548 if (pci_find_bus(pci_domain_nr(bus),
548 max+i+1)) 549 max+i+1))
549 break; 550 break;
551 while (parent->parent) {
552 if ((!pcibios_assign_all_busses()) &&
553 (parent->subordinate > max) &&
554 (parent->subordinate <= max+i)) {
555 j = 1;
556 }
557 parent = parent->parent;
558 }
559 if (j) {
560 /*
561 * Often, there are two cardbus bridges
562 * -- try to leave one valid bus number
563 * for each one.
564 */
565 i /= 2;
566 break;
567 }
568 }
550 max += i; 569 max += i;
551 pci_fixup_parent_subordinate_busnr(child, max); 570 pci_fixup_parent_subordinate_busnr(child, max);
552 } 571 }
@@ -561,6 +580,22 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
561 580
562 sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); 581 sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
563 582
583 while (bus->parent) {
584 if ((child->subordinate > bus->subordinate) ||
585 (child->number > bus->subordinate) ||
586 (child->number < bus->number) ||
587 (child->subordinate < bus->number)) {
588 printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be "
589 "hidden behind%s bridge #%02x (-#%02x)%s\n",
590 child->number, child->subordinate,
591 bus->self->transparent ? " transparent" : " ",
592 bus->number, bus->subordinate,
593 pcibios_assign_all_busses() ? " " :
594 " (try 'pci=assign-busses')");
595 }
596 bus = bus->parent;
597 }
598
564 return max; 599 return max;
565} 600}
566 601