diff options
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6a0a82f0508b..df3bdae2040f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -239,9 +239,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (dev->transparent) { printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev)); - for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) - child->resource[i] = child->parent->resource[i]; - return; + for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) + child->resource[i] = child->parent->resource[i - 3]; } for(i=0; i<3; i++) @@ -398,6 +397,16 @@ static void pci_enable_crs(struct pci_dev *dev) pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); } +static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) +{ + struct pci_bus *parent = child->parent; + while (parent->parent && parent->subordinate < max) { + parent->subordinate = max; + pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); + parent = parent->parent; + } +} + unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); /* @@ -499,7 +508,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max if (!is_cardbus) { child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; - + /* + * Adjust subordinate busnr in parent buses. + * We do this before scanning for children because + * some devices may not be detected if the bios + * was lazy. + */ + pci_fixup_parent_subordinate_busnr(child, max); /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); } else { @@ -513,6 +528,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max max+i+1)) break; max += i; + pci_fixup_parent_subordinate_busnr(child, max); } /* * Set the subordinate bus number to its real value. |