aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
authorAlex Chiang <achiang@hp.com>2009-03-20 16:56:10 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-03-20 17:57:21 -0400
commit74710ded8e16fc8dacbb702a5bac1a493d88549a (patch)
tree274171a30a202a708a6aacbf9e0a693a2b5474ad /drivers/pci/probe.c
parent1b69dfc649e6658fc38499cf704750d74cabc73d (diff)
PCI: always scan child buses
While scanning bridges, we stop our scan if we encounter a bus that we've seen before, to work around some buggy chipsets. This is a good idea, but prevents us from fully scanning the PCI bus at a future time (to find newly hot-added devices, for example). Change the logic so that we skip _re-adding_ an existing bus that we've seen before, but also allow the scan to descend to all child buses. Now that we're potentially scanning our child buses again, we also need to be sure not to attempt re-initializing their BARs so we avoid that. This patch lays the groundwork to allow the user to issue a rescan of the PCI bus at any time. Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f3aabdf28f84..f69256c63b2b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
511 511
512 /* 512 /*
513 * If we already got to this bus through a different bridge, 513 * If we already got to this bus through a different bridge,
514 * ignore it. This can happen with the i450NX chipset. 514 * don't re-add it. This can happen with the i450NX chipset.
515 *
516 * However, we continue to descend down the hierarchy and
517 * scan remaining child buses.
515 */ 518 */
516 if (pci_find_bus(pci_domain_nr(bus), busnr)) { 519 child = pci_find_bus(pci_domain_nr(bus), busnr);
517 dev_info(&dev->dev, "bus %04x:%02x already known\n", 520 if (!child) {
518 pci_domain_nr(bus), busnr); 521 child = pci_add_new_bus(bus, dev, busnr);
519 goto out; 522 if (!child)
523 goto out;
524 child->primary = buses & 0xFF;
525 child->subordinate = (buses >> 16) & 0xFF;
526 child->bridge_ctl = bctl;
520 } 527 }
521 528
522 child = pci_add_new_bus(bus, dev, busnr);
523 if (!child)
524 goto out;
525 child->primary = buses & 0xFF;
526 child->subordinate = (buses >> 16) & 0xFF;
527 child->bridge_ctl = bctl;
528
529 cmax = pci_scan_child_bus(child); 529 cmax = pci_scan_child_bus(child);
530 if (cmax > max) 530 if (cmax > max)
531 max = cmax; 531 max = cmax;
@@ -1092,8 +1092,14 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
1092 * After performing arch-dependent fixup of the bus, look behind 1092 * After performing arch-dependent fixup of the bus, look behind
1093 * all PCI-to-PCI bridges on this bus. 1093 * all PCI-to-PCI bridges on this bus.
1094 */ 1094 */
1095 pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number); 1095 if (!bus->is_added) {
1096 pcibios_fixup_bus(bus); 1096 pr_debug("PCI: Fixups for bus %04x:%02x\n",
1097 pci_domain_nr(bus), bus->number);
1098 pcibios_fixup_bus(bus);
1099 if (pci_is_root_bus(bus))
1100 bus->is_added = 1;
1101 }
1102
1097 for (pass=0; pass < 2; pass++) 1103 for (pass=0; pass < 2; pass++)
1098 list_for_each_entry(dev, &bus->devices, bus_list) { 1104 list_for_each_entry(dev, &bus->devices, bus_list) {
1099 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 1105 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||