Add a new helper function for PCI devices to locate the upstream
PCI-express root port of a given PCI device. Reviewed by: kib, imp MFC after: 1 week Sponsored by: Chelsio Differential Revision: https://reviews.freebsd.org/D4089
This commit is contained in:
parent
ec603c7297
commit
87dd2f95d2
@ -1274,6 +1274,7 @@ MLINKS+=pci.9 pci_alloc_msi.9 \
|
|||||||
pci.9 pci_find_device.9 \
|
pci.9 pci_find_device.9 \
|
||||||
pci.9 pci_find_extcap.9 \
|
pci.9 pci_find_extcap.9 \
|
||||||
pci.9 pci_find_htcap.9 \
|
pci.9 pci_find_htcap.9 \
|
||||||
|
pci.9 pci_find_pcie_root_port.9 \
|
||||||
pci.9 pci_get_max_read_req.9 \
|
pci.9 pci_get_max_read_req.9 \
|
||||||
pci.9 pci_get_powerstate.9 \
|
pci.9 pci_get_powerstate.9 \
|
||||||
pci.9 pci_get_vpd_ident.9 \
|
pci.9 pci_get_vpd_ident.9 \
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
.Nm pci_find_device ,
|
.Nm pci_find_device ,
|
||||||
.Nm pci_find_extcap ,
|
.Nm pci_find_extcap ,
|
||||||
.Nm pci_find_htcap ,
|
.Nm pci_find_htcap ,
|
||||||
|
.Nm pci_find_pcie_root_port ,
|
||||||
.Nm pci_get_max_read_req ,
|
.Nm pci_get_max_read_req ,
|
||||||
.Nm pci_get_powerstate ,
|
.Nm pci_get_powerstate ,
|
||||||
.Nm pci_get_vpd_ident ,
|
.Nm pci_get_vpd_ident ,
|
||||||
@ -91,6 +92,8 @@
|
|||||||
.Fn pci_find_extcap "device_t dev" "int capability" "int *capreg"
|
.Fn pci_find_extcap "device_t dev" "int capability" "int *capreg"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn pci_find_htcap "device_t dev" "int capability" "int *capreg"
|
.Fn pci_find_htcap "device_t dev" "int capability" "int *capreg"
|
||||||
|
.Ft device_t
|
||||||
|
.Fn pci_find_pcie_root_port "device_t dev"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn pci_get_max_read_req "device_t dev"
|
.Fn pci_get_max_read_req "device_t dev"
|
||||||
.Ft int
|
.Ft int
|
||||||
@ -338,6 +341,16 @@ If the capability is not found or the device is not a HyperTransport device,
|
|||||||
returns an error.
|
returns an error.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
|
.Fn pci_find_pcie_root_port
|
||||||
|
function walks up the PCI device hierarchy to locate the PCI-express root
|
||||||
|
port upstream of
|
||||||
|
.Fa dev .
|
||||||
|
If a root port is not found,
|
||||||
|
.Fn pci_find_pcie_root_port
|
||||||
|
returns
|
||||||
|
.Dv NULL .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
.Fn pci_get_vpd_ident
|
.Fn pci_get_vpd_ident
|
||||||
function is used to fetch a device's Vital Product Data
|
function is used to fetch a device's Vital Product Data
|
||||||
.Pq VPD
|
.Pq VPD
|
||||||
|
@ -5431,3 +5431,44 @@ pci_get_rid_method(device_t dev, device_t child)
|
|||||||
|
|
||||||
return (PCIB_GET_RID(device_get_parent(dev), child));
|
return (PCIB_GET_RID(device_get_parent(dev), child));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find the upstream port of a given PCI device in a root complex. */
|
||||||
|
device_t
|
||||||
|
pci_find_pcie_root_port(device_t dev)
|
||||||
|
{
|
||||||
|
struct pci_devinfo *dinfo;
|
||||||
|
devclass_t pci_class;
|
||||||
|
device_t pcib, bus;
|
||||||
|
|
||||||
|
pci_class = devclass_find("pci");
|
||||||
|
KASSERT(device_get_devclass(device_get_parent(dev)) == pci_class,
|
||||||
|
("%s: non-pci device %s", __func__, device_get_nameunit(dev)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk the bridge hierarchy until we find a PCI-e root
|
||||||
|
* port or a non-PCI device.
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
bus = device_get_parent(dev);
|
||||||
|
KASSERT(bus != NULL, ("%s: null parent of %s", __func__,
|
||||||
|
device_get_nameunit(dev)));
|
||||||
|
|
||||||
|
pcib = device_get_parent(bus);
|
||||||
|
KASSERT(pcib != NULL, ("%s: null bridge of %s", __func__,
|
||||||
|
device_get_nameunit(bus)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pcib's parent must be a PCI bus for this to be a
|
||||||
|
* PCI-PCI bridge.
|
||||||
|
*/
|
||||||
|
if (device_get_devclass(device_get_parent(pcib)) != pci_class)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
dinfo = device_get_ivars(pcib);
|
||||||
|
if (dinfo->cfg.pcie.pcie_location != 0 &&
|
||||||
|
dinfo->cfg.pcie.pcie_type == PCIEM_TYPE_ROOT_PORT)
|
||||||
|
return (pcib);
|
||||||
|
|
||||||
|
dev = pcib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -547,6 +547,7 @@ int pci_msix_device_blacklisted(device_t dev);
|
|||||||
|
|
||||||
void pci_ht_map_msi(device_t dev, uint64_t addr);
|
void pci_ht_map_msi(device_t dev, uint64_t addr);
|
||||||
|
|
||||||
|
device_t pci_find_pcie_root_port(device_t dev);
|
||||||
int pci_get_max_read_req(device_t dev);
|
int pci_get_max_read_req(device_t dev);
|
||||||
void pci_restore_state(device_t dev);
|
void pci_restore_state(device_t dev);
|
||||||
void pci_save_state(device_t dev);
|
void pci_save_state(device_t dev);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user