aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/bhnd/bhnd_subr.c
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2016-05-17 06:52:53 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2016-05-17 06:52:53 +0000
commit8ef24a0d4b28fe230e20637f56869cc4148cd2ca (patch)
treea6f48be495b4c02010bf9f75e3fc2ef4743cd5d6 /sys/dev/bhnd/bhnd_subr.c
parent32f8bbf8cda79873753a2442fa20f3c6e07ef162 (diff)
downloadsrc-8ef24a0d4b28fe230e20637f56869cc4148cd2ca.tar.gz
src-8ef24a0d4b28fe230e20637f56869cc4148cd2ca.zip
[bhnd] Finish bhnd(4) PCI/PCIe-G1 hostb support.
Now that we've got access to SPROM and can access board identification, this implements all known remaining hardware work-arounds for the bhnd(4) PCI and PCIe-G1 cores operating endpoint mode. Additionally, this adds an initial set of skeleton PCIe-G2 hostb and pcib drivers, required by fullmac and newer softmac devices. Submitted by: Landon Fuller <landonf@landonf.org> Differential Revision: https://reviews.freebsd.org/D6377
Notes
Notes: svn path=/head/; revision=300015
Diffstat (limited to 'sys/dev/bhnd/bhnd_subr.c')
-rw-r--r--sys/dev/bhnd/bhnd_subr.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/sys/dev/bhnd/bhnd_subr.c b/sys/dev/bhnd/bhnd_subr.c
index 4e1bc6e16b13..ee807b40adde 100644
--- a/sys/dev/bhnd/bhnd_subr.c
+++ b/sys/dev/bhnd/bhnd_subr.c
@@ -350,6 +350,56 @@ done:
}
/**
+ * Walk up the bhnd device hierarchy to locate the root device
+ * to which the bhndb bridge is attached.
+ *
+ * This can be used from within bhnd host bridge drivers to locate the
+ * actual upstream host device.
+ *
+ * @param dev A bhnd device.
+ * @param bus_class The expected bus (e.g. "pci") to which the bridge root
+ * should be attached.
+ *
+ * @retval device_t if a matching parent device is found.
+ * @retval NULL @p dev is not attached via a bhndb bus
+ * @retval NULL no parent device is attached via @p bus_class.
+ */
+device_t
+bhnd_find_bridge_root(device_t dev, devclass_t bus_class)
+{
+ devclass_t bhndb_class;
+ device_t parent;
+
+ KASSERT(device_get_devclass(device_get_parent(dev)) == bhnd_devclass,
+ ("%s not a bhnd device", device_get_nameunit(dev)));
+
+ bhndb_class = devclass_find("bhndb");
+
+ /* Walk the device tree until we hit a bridge */
+ parent = dev;
+ while ((parent = device_get_parent(parent)) != NULL) {
+ if (device_get_devclass(parent) == bhndb_class)
+ break;
+ }
+
+ /* No bridge? */
+ if (parent == NULL)
+ return (NULL);
+
+ /* Search for a parent attached to the expected bus class */
+ while ((parent = device_get_parent(parent)) != NULL) {
+ device_t bus;
+
+ bus = device_get_parent(parent);
+ if (bus != NULL && device_get_devclass(bus) == bus_class)
+ return (parent);
+ }
+
+ /* Not found */
+ return (NULL);
+}
+
+/**
* Find the first core in @p cores that matches @p desc.
*
* @param cores The table to search.