aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-11-30 16:22:39 -0500
committerBjorn Helgaas <bhelgaas@google.com>2017-12-19 00:04:17 -0500
commitd57f0b8c81393e7105331ac037fa465d5a45c65f (patch)
treedd39b3e48799e25ea2ca73583d63d0b8ba9ef532
parent1291a0d5049dbc06baaaf66a9ff3f53db493b19b (diff)
PCI: Make PCI_SCAN_ALL_PCIE_DEVS work for Root as well as Downstream Ports
PCIe Downstream Ports normally have only a Device 0 below them. To optimize enumeration, we don't scan for other devices *unless* the PCI_SCAN_ALL_PCIE_DEVS flag is set by set by quirks or the "pci=pcie_scan_all" kernel parameter. Previously PCI_SCAN_ALL_PCIE_DEVS only affected scanning below Switch Downstream Ports, not Root Ports. But the "Nemo" system, also known as the AmigaOne X1000, has a PA Semi Root Port whose link leads to an AMD/ATI SB600 South Bridge. The Root Port is a PCIe device, of course, but the SB600 contains only conventional PCI devices with no visible PCIe port. Simplify and restructure only_one_child() so that we scan for all possible devices below Root Ports as well as Switch Downstream Ports when PCI_SCAN_ALL_PCIE_DEVS is set. This is enough to make Nemo work with "pci=pcie_scan_all". We would also like to add a quirk to set PCI_SCAN_ALL_PCIE_DEVS automatically on Nemo so users wouldn't have to use the "pci=pcie_scan_all" parameter, but we don't have that yet. Link: https://lkml.kernel.org/r/CAErSpo55Q8Q=5p6_+uu7ahnw+53ibVDNRXxrzRV9QnUr_9EUfw@mail.gmail.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=198057 Reported-and-Tested-by: Christian Zigotzky <chzigotzky@xenosoft.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/probe.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 14e0ea1ff38b..303c0cb0550c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2215,22 +2215,27 @@ static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn)
2215 2215
2216static int only_one_child(struct pci_bus *bus) 2216static int only_one_child(struct pci_bus *bus)
2217{ 2217{
2218 struct pci_dev *parent = bus->self; 2218 struct pci_dev *bridge = bus->self;
2219 2219
2220 if (!parent || !pci_is_pcie(parent)) 2220 /*
2221 * Systems with unusual topologies set PCI_SCAN_ALL_PCIE_DEVS so
2222 * we scan for all possible devices, not just Device 0.
2223 */
2224 if (pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
2221 return 0; 2225 return 0;
2222 if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
2223 return 1;
2224 2226
2225 /* 2227 /*
2226 * PCIe downstream ports are bridges that normally lead to only a 2228 * A PCIe Downstream Port normally leads to a Link with only Device
2227 * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all 2229 * 0 on it (PCIe spec r3.1, sec 7.3.1). As an optimization, scan
2228 * possible devices, not just device 0. See PCIe spec r3.0, 2230 * only for Device 0 in that situation.
2229 * sec 7.3.1. 2231 *
2232 * Checking has_secondary_link is a hack to identify Downstream
2233 * Ports because sometimes Switches are configured such that the
2234 * PCIe Port Type labels are backwards.
2230 */ 2235 */
2231 if (parent->has_secondary_link && 2236 if (bridge && pci_is_pcie(bridge) && bridge->has_secondary_link)
2232 !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
2233 return 1; 2237 return 1;
2238
2234 return 0; 2239 return 0;
2235} 2240}
2236 2241