Patch "PCI: Enumerate switches below PCI-to-PCIe bridges" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
PCI: Enumerate switches below PCI-to-PCIe bridges
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
pci-enumerate-switches-below-pci-to-pcie-bridges.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
51ebfc92b72b4f7dac1ab45683bf56741e454b8cMon Sep 17 00:00:00 2001
From: Bjorn Helgaas <[email protected]>
Date: Wed, 11 Jan 2017 09:11:53 -0600
Subject: PCI: Enumerate switches below PCI-to-PCIe bridges
From: Bjorn Helgaas <[email protected]>
commit 51ebfc92b72b4f7dac1ab45683bf56741e454b8c upstream.
A PCI-to-PCIe bridge (a "reverse bridge") has a PCI or PCI-X primary interface and a PCI Express secondary interface. The PCIe interface is a Downstream Port that originates a Link. See the "PCI Express to PCI/PCI-X Bridge Specification", rev 1.0, sections 1.2 and A.6.
The bug report below involves a PCI-to-PCIe bridge and a PCIe switch below the bridge:
00:1e.0 Intel 82801 PCI Bridge to [bus 01-0a]
01:00.0 Pericom PI7C9X111SL PCIe-to-PCI Reversible Bridge to [bus 02-0a] 02:00.0 Pericom Device 8608 [PCIe Upstream Port] to [bus 03-0a] 03:01.0 Pericom Device 8608 [PCIe Downstream Port] to [bus 0a]
01:00.0 is configured as a PCI-to-PCIe bridge (despite the name printed by lspci). As we traverse a PCIe hierarchy, device connections alternate between PCIe Links and internal Switch logic. Previously we did not recognize that 01:00.0 had a secondary link, so we thought the 02:00.0 Upstream Port *did* have a secondary link. In fact, it's the other way
around: 01:00.0 has a secondary link, and 02:00.0 has internal Switch logic on its secondary side.
When we thought 02:00.0 had a secondary link, the pci_scan_slot() -> only_one_child() path assumed 02:00.0 could have only one child, so 03:00.0 was the only possible downstream device. But 03:00.0 doesn't exist, so we didn't look for any other devices on bus 03.
Booting with "pci=pcie_scan_all" is a workaround, but we don't want users to have to do that.
Recognize that PCI-to-PCIe bridges originate links on their secondary interfaces.
--- drivers/pci/probe.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/pci/probe.c +7 -5
@@ -1050,6 +1050,7 @@ void set_pcie_port_type(struct pci_dev * pos =pci_find_capability (pdev,PCI_CAP_ID_EXP );if (!pos)return ; + pdev->pcie_cap = pos;pci_read_config_word (pdev, pos +PCI_EXP_FLAGS , ®16); pdev->pcie_flags_reg = reg16;
@@ -1057,13 +1058,14 @@ void set_pcie_port_type(struct pci_dev * pdev->pcie_mpss = reg16 &PCI_EXP_DEVCAP_PAYLOAD ;/* -* A Root Port is always the upstream end of a Link. No PCIe -* component has two Links. Two Links are connected by a Switch -* that has a Port on each Link and internal logic to connect the -* two Ports. +* A Root Port or a PCI-to-PCIe bridge is always the upstream end +* of a Link. No PCIe component has two Links. Two Links are +* connected by a Switch that has a Port on each Link and internal +* logic to connect the two Ports. */ type =pci_pcie_type (pdev); -if (type ==PCI_EXP_TYPE_ROOT_PORT ) +if (type ==PCI_EXP_TYPE_ROOT_PORT || + type ==PCI_EXP_TYPE_PCIE_BRIDGE ) pdev->has_secondary_link =1 ;else if (type ==PCI_EXP_TYPE_UPSTREAM || type ==PCI_EXP_TYPE_DOWNSTREAM ) {
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/x86-pci-ignore-_crs-on-supermicro-x8dth-i-6-if-6f.patch queue-4.9/pci-designware-check-for-iatu-unroll-only-on-platforms-that-use-atu.patch queue-4.9/pci-enumerate-switches-below-pci-to-pcie-bridges.patch