summaryrefslogtreecommitdiff
path: root/hw/pci
diff options
context:
space:
mode:
authorJonathan Cameron <jonathan.cameron@huawei.com>2022-04-29 15:40:55 +0100
committerMichael S. Tsirkin <mst@redhat.com>2022-05-13 07:57:26 -0400
commitaa970ed586f9c7f178b813bda2919e329b841e3c (patch)
treea13dac626ff3e491b3a38c737a87ddfa82ba345f /hw/pci
parentfc1e01e009fd4b1e08399253591b32e01f10808f (diff)
pci/pcie_port: Add pci_find_port_by_pn()
Simple function to search a PCIBus to find a port by it's port number. CXL interleave decoding uses the port number as a target so it is necessary to locate the port when doing interleave decoding. Signed-off-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20220429144110.25167-31-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r--hw/pci/pcie_port.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index e95c1e5519..687e4e763a 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -136,6 +136,31 @@ static void pcie_port_class_init(ObjectClass *oc, void *data)
device_class_set_props(dc, pcie_port_props);
}
+PCIDevice *pcie_find_port_by_pn(PCIBus *bus, uint8_t pn)
+{
+ int devfn;
+
+ for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+ PCIDevice *d = bus->devices[devfn];
+ PCIEPort *port;
+
+ if (!d || !pci_is_express(d) || !d->exp.exp_cap) {
+ continue;
+ }
+
+ if (!object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) {
+ continue;
+ }
+
+ port = PCIE_PORT(d);
+ if (port->port == pn) {
+ return d;
+ }
+ }
+
+ return NULL;
+}
+
static const TypeInfo pcie_port_type_info = {
.name = TYPE_PCIE_PORT,
.parent = TYPE_PCI_BRIDGE,