Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150996926
D4089.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D4089.id.diff
View Options
Index: head/share/man/man9/Makefile
===================================================================
--- head/share/man/man9/Makefile
+++ head/share/man/man9/Makefile
@@ -1274,6 +1274,7 @@
pci.9 pci_find_device.9 \
pci.9 pci_find_extcap.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_powerstate.9 \
pci.9 pci_get_vpd_ident.9 \
Index: head/share/man/man9/pci.9
===================================================================
--- head/share/man/man9/pci.9
+++ head/share/man/man9/pci.9
@@ -42,6 +42,7 @@
.Nm pci_find_device ,
.Nm pci_find_extcap ,
.Nm pci_find_htcap ,
+.Nm pci_find_pcie_root_port ,
.Nm pci_get_max_read_req ,
.Nm pci_get_powerstate ,
.Nm pci_get_vpd_ident ,
@@ -91,6 +92,8 @@
.Fn pci_find_extcap "device_t dev" "int capability" "int *capreg"
.Ft int
.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
.Fn pci_get_max_read_req "device_t dev"
.Ft int
@@ -338,6 +341,16 @@
returns an error.
.Pp
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
function is used to fetch a device's Vital Product Data
.Pq VPD
Index: head/sys/dev/pci/pci.c
===================================================================
--- head/sys/dev/pci/pci.c
+++ head/sys/dev/pci/pci.c
@@ -5431,3 +5431,44 @@
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;
+ }
+}
Index: head/sys/dev/pci/pcivar.h
===================================================================
--- head/sys/dev/pci/pcivar.h
+++ head/sys/dev/pci/pcivar.h
@@ -547,6 +547,7 @@
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);
void pci_restore_state(device_t dev);
void pci_save_state(device_t dev);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 9:12 AM (13 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30954595
Default Alt Text
D4089.id.diff (3 KB)
Attached To
Mode
D4089: Add a helper method to find a PCI-e root port of a device.
Attached
Detach File
Event Timeline
Log In to Comment