aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorAndreas Noever <andreas.noever@gmail.com>2014-01-23 15:59:25 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-02-10 19:12:45 -0500
commit1820ffdccb9b4398c5f0f70360edc68e039c3c72 (patch)
treee8a5b0c822e36c98e89989337fc86b89888a5ebc /drivers/pci
parentced04d15519a15d38b46162b94a1f26b4022116e (diff)
PCI: Make sure bus number resources stay within their parents bounds
Right now we use 0xff for busn_res.end when probing and later reduce it to the value that is actually used. This does not work if a parent bridge has already a lower subordinate value. For example during hotplug of a new bridge below an already-configured bridge the following message is printed from pci_bus_insert_busn_res(): pci_bus 0000:06: busn_res: can not insert [bus 06-ff] under [bus 05-9b] (conflicts with (null) [bus 05-9b]) This patch clamps the bus range to that of the parent and also ensures that we do not exceed the parents range when assigning the final subordinate value. We also check that busses configured by the firmware fit into their parents bounds. [bhelgaas: reword dev_warn() and fix printk format warning] Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/probe.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 21f162c5c7bb..9a641cc4275d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -782,7 +782,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
782 /* Check if setup is sensible at all */ 782 /* Check if setup is sensible at all */
783 if (!pass && 783 if (!pass &&
784 (primary != bus->number || secondary <= bus->number || 784 (primary != bus->number || secondary <= bus->number ||
785 secondary > subordinate)) { 785 secondary > subordinate || subordinate > bus->busn_res.end)) {
786 dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", 786 dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
787 secondary, subordinate); 787 secondary, subordinate);
788 broken = 1; 788 broken = 1;
@@ -854,7 +854,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
854 child = pci_add_new_bus(bus, dev, max+1); 854 child = pci_add_new_bus(bus, dev, max+1);
855 if (!child) 855 if (!child)
856 goto out; 856 goto out;
857 pci_bus_insert_busn_res(child, max+1, 0xff); 857 pci_bus_insert_busn_res(child, max+1,
858 bus->busn_res.end);
858 } 859 }
859 max++; 860 max++;
860 buses = (buses & 0xff000000) 861 buses = (buses & 0xff000000)
@@ -927,6 +928,11 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
927 /* 928 /*
928 * Set the subordinate bus number to its real value. 929 * Set the subordinate bus number to its real value.
929 */ 930 */
931 if (max > bus->busn_res.end) {
932 dev_warn(&dev->dev, "max busn %02x is outside %pR\n",
933 max, &bus->busn_res);
934 max = bus->busn_res.end;
935 }
930 pci_bus_update_busn_res_end(child, max); 936 pci_bus_update_busn_res_end(child, max);
931 pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); 937 pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
932 } 938 }