diff options
author | Adrian Chadd <adrian@FreeBSD.org> | 2016-05-17 06:52:53 +0000 |
---|---|---|
committer | Adrian Chadd <adrian@FreeBSD.org> | 2016-05-17 06:52:53 +0000 |
commit | 8ef24a0d4b28fe230e20637f56869cc4148cd2ca (patch) | |
tree | a6f48be495b4c02010bf9f75e3fc2ef4743cd5d6 /sys/dev/bhnd/bhnd_subr.c | |
parent | 32f8bbf8cda79873753a2442fa20f3c6e07ef162 (diff) | |
download | src-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.c | 50 |
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. |