diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2016-06-09 00:34:57 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-06-09 18:26:16 +1000 |
commit | cf65cec520068f1910155eb7e252a0c6965bb2c8 (patch) | |
tree | c8864f839634e4f5875d91ebf7cccce38dfc4918 | |
parent | d8f080c635364a36fd0dcb251c3237284630cadf (diff) | |
download | skiboot-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.c | 7 |
1 files changed, 7 insertions, 0 deletions
@@ -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"); |