aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2016-06-09 00:34:57 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-06-09 18:26:16 +1000
commitcf65cec520068f1910155eb7e252a0c6965bb2c8 (patch)
treec8864f839634e4f5875d91ebf7cccce38dfc4918
parentd8f080c635364a36fd0dcb251c3237284630cadf (diff)
downloadskiboot-cf65cec520068f1910155eb7e252a0c6965bb2c8.zip
skiboot-cf65cec520068f1910155eb7e252a0c6965bb2c8.tar.gz
skiboot-cf65cec520068f1910155eb7e252a0c6965bb2c8.tar.bz2
pci: Do a dummy config write to devices to establish bus number
On PCI Express, devices need to know their own bus number in order to provide the correct source identification (aka RID) in upstream packets they might send, such as error messages or DMAs. However while devices know (and hard wire) their own device and function number, they know nothing about bus numbers by default, those are decoded by bridges for routing. All they know is that if their parent bridge sends a "type 0" configuration access, they should decode it provided the device and function numbers match. The PCIe spec thus defines that when a device receive such a configuration access and it's a write, it should "capture" the bus number in the source field of the packet, and re-use as the originator bus number of all subsequent outgoing requests. In order to ensure that a device has this bus number firmly established before it's likely to send error packets upstream, we should thus do a dummy configuration write to it as soon as possible after probing. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com> [stewart@linux.vnet.ibm.com: fix Evolution broken patch, write vdid rather than &vdid as per Gavin suggestion] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com> (cherry picked from commit f46c1e506d199332b0f9741278c8ec35b3e39135)
-rw-r--r--core/pci.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/core/pci.c b/core/pci.c
index 58c5ac5..931c3dd 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -156,6 +156,13 @@ static struct pci_device *pci_scan_one(struct phb *phb, struct pci_device *paren
}
if (had_crs)
PCIDBG(phb, bdfn, "Probe success after CRS\n");
+
+ /* Perform a dummy write to the device in order for it to
+  * capture it's own bus number, so any subsequent error
+  * messages will be properly tagged
+  */
+ pci_cfg_write32(phb, bdfn, 0, &vdid);
+
pd = zalloc(sizeof(struct pci_device));
if (!pd) {
PCIERR(phb, bdfn,"Failed to allocate structure pci_device !\n");