diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 10:16:53 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 10:16:53 -0700 |
commit | a3415dc34f4a615a904852e7a9d0cc2877007e9e (patch) | |
tree | 0072b4b3f266c03220ffb2a9b329b2591f2a8e19 /drivers/pci/probe.c | |
parent | b4d0b08a4c3947c6ac004c9d83154ec5999c1861 (diff) | |
parent | 05a34f51ba451c65773ad6f1acf4cc089cc474d8 (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (32 commits)
PCI hotplug: fix logic in Compaq hotplug controller bus speed setup
PCI: don't export linux/io.h from pci.h
PCI: PCI_QUIRKS depends on PCI
PCI hotplug: pciehp: poll data link layer link active
PCI hotplug: pciehp: fix possible memory leak in pcie_init
PCI: Workaround invalid P2P bridge bus numbers
PCI Hotplug: fakephp: add duplicate slot name debugging
PCI: Hotplug core: remove 'name'
PCI: shcphp: remove 'name' parameter
PCI: SGI Hotplug: stop managing bss_hotplug_slot->name
PCI: rpaphp: kmalloc/kfree slot->name directly
PCI: pciehp: remove 'name' parameter
PCI: ibmphp: stop managing hotplug_slot->name
PCI: fakephp: remove 'name' parameter
PCI, PCI Hotplug: introduce slot_name helpers
PCI: cpqphp: stop managing hotplug_slot->name
PCI: cpci_hotplug: stop managing hotplug_slot->name
PCI: acpiphp: remove 'name' parameter
PCI: prevent duplicate slot names
PCI Hotplug: serialize pci_hp_register and pci_hp_deregister
...
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index aaaf0a1fed2..6f1e51d77bc 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -480,19 +480,27 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); u32 buses, i, j = 0; u16 bctl; + int broken = 0; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", buses & 0xffffff, pass); + /* Check if setup is sensible at all */ + if (!pass && + ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { + dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); + broken = 1; + } + /* Disable MasterAbortMode during probing to avoid reporting of bus errors (in some architectures) */ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl); pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); - if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) { + if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { unsigned int cmax, busnr; /* * Bus already configured by firmware, process it in the first @@ -530,7 +538,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, * do in the second pass. */ if (!pass) { - if (pcibios_assign_all_busses()) + if (pcibios_assign_all_busses() || broken) /* Temporarily disable forwarding of the configuration cycles on all bridges in this bus segment to avoid possible |