|
@@ -2215,22 +2215,27 @@ static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn)
|
|
|
|
|
|
static int only_one_child(struct pci_bus *bus)
|
|
|
{
|
|
|
- struct pci_dev *parent = bus->self;
|
|
|
+ struct pci_dev *bridge = bus->self;
|
|
|
|
|
|
- if (!parent || !pci_is_pcie(parent))
|
|
|
+ /*
|
|
|
+ * Systems with unusual topologies set PCI_SCAN_ALL_PCIE_DEVS so
|
|
|
+ * we scan for all possible devices, not just Device 0.
|
|
|
+ */
|
|
|
+ if (pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
|
|
|
return 0;
|
|
|
- if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
|
|
|
- return 1;
|
|
|
|
|
|
/*
|
|
|
- * PCIe downstream ports are bridges that normally lead to only a
|
|
|
- * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all
|
|
|
- * possible devices, not just device 0. See PCIe spec r3.0,
|
|
|
- * sec 7.3.1.
|
|
|
+ * A PCIe Downstream Port normally leads to a Link with only Device
|
|
|
+ * 0 on it (PCIe spec r3.1, sec 7.3.1). As an optimization, scan
|
|
|
+ * only for Device 0 in that situation.
|
|
|
+ *
|
|
|
+ * Checking has_secondary_link is a hack to identify Downstream
|
|
|
+ * Ports because sometimes Switches are configured such that the
|
|
|
+ * PCIe Port Type labels are backwards.
|
|
|
*/
|
|
|
- if (parent->has_secondary_link &&
|
|
|
- !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
|
|
|
+ if (bridge && pci_is_pcie(bridge) && bridge->has_secondary_link)
|
|
|
return 1;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|