Index: sys/dev/bhnd/bhnd.h =================================================================== --- sys/dev/bhnd/bhnd.h +++ sys/dev/bhnd/bhnd.h @@ -232,6 +232,65 @@ .unit = -1 \ } +/** A chipset match descriptor. */ +struct bhnd_chip_match { + /** Select fields to be matched */ + uint8_t + match_id:1, + match_rev:1, + match_pkg:1, + match_flags_unused:5; + + uint16_t chip_id; /**< required chip id */ + struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */ + uint8_t chip_pkg; /**< required package */ +}; + +#define BHND_CHIP_MATCH_ANY \ + { .match_id = 0, .match_rev = 0, .match_pkg = 0 } + +#define BHND_CHIP_MATCH_IS_ANY(_m) \ + ((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0) + +/** Set the required chip ID within a bhnd_chip_match instance */ +#define BHND_CHIP_ID(_cid) \ + .match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid + +/** Set the required revision range within a bhnd_chip_match instance */ +#define BHND_CHIP_REV(_rev) \ + .match_rev = 1, .chip_rev = BHND_ ## _rev + +/** Set the required package ID within a bhnd_chip_match instance */ +#define BHND_CHIP_PKG(_pkg) \ + .match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg + +/** Set the required chip and package ID within a bhnd_chip_match instance */ +#define BHND_CHIP_IP(_cid, _pkg) \ + BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg) + +/** Set the required chip ID, package ID, and revision within a bhnd_chip_match + * instance */ +#define BHND_CHIP_IPR(_cid, _pkg, _rev) \ + BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev) + +/** Set the required chip ID and revision within a bhnd_chip_match + * instance */ +#define BHND_CHIP_IR(_cid, _rev) \ + BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev) + +/** + * Chipset quirk table descriptor. + */ +struct bhnd_chip_quirk { + const struct bhnd_chip_match chip; /**< chip match descriptor */ + uint32_t quirks; /**< quirk flags */ +}; + +#define BHND_CHIP_QUIRK_END { BHND_CHIP_MATCH_ANY, 0 } + +#define BHND_CHIP_QUIRK_IS_END(_q) \ + (BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0) + /** * Device quirk table descriptor. */ @@ -297,9 +356,20 @@ const struct bhnd_core_info *core, const struct bhnd_core_match *desc); +bool bhnd_chip_matches( + const struct bhnd_chipid *chipid, + const struct bhnd_chip_match *desc); + bool bhnd_hwrev_matches(uint16_t hwrev, const struct bhnd_hwrev_match *desc); +uint32_t bhnd_chip_quirks(device_t dev, + const struct bhnd_chip_quirk *table); + +uint32_t bhnd_device_quirks(device_t dev, + const struct bhnd_device *table, + size_t entry_size); + bool bhnd_device_matches(device_t dev, const struct bhnd_core_match *desc); @@ -389,6 +459,17 @@ } /** + * Return the BHND chip identification info for the bhnd bus. + * + * @param dev A bhnd bus child device. + */ +static inline const struct bhnd_chipid * +bhnd_get_chipid(device_t dev) { + return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev)); +}; + + +/** * Allocate a resource from a device's parent bhnd(4) bus. * * @param dev The device requesting resource ownership. Index: sys/dev/bhnd/bhnd_subr.c =================================================================== --- sys/dev/bhnd/bhnd_subr.c +++ sys/dev/bhnd/bhnd_subr.c @@ -413,10 +413,6 @@ if (!bhnd_hwrev_matches(core->hwrev, &desc->hwrev)) return (false); - - if (desc->hwrev.end != BHND_HWREV_INVALID && - desc->hwrev.end < core->hwrev) - return (false); if (desc->class != BHND_DEVCLASS_INVALID && desc->class != bhnd_core_class(core)) @@ -426,6 +422,32 @@ } /** + * Return true if the @p chip matches @p desc. + * + * @param chip A bhnd chip identifier. + * @param desc A match descriptor to compare against @p chip. + * + * @retval true if @p chip matches @p match + * @retval false if @p chip does not match @p match. + */ +bool +bhnd_chip_matches(const struct bhnd_chipid *chip, + const struct bhnd_chip_match *desc) +{ + if (desc->match_id && chip->chip_id != desc->chip_id) + return (false); + + if (desc->match_pkg && chip->chip_pkg != desc->chip_pkg) + return (false); + + if (desc->match_rev && + !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev)) + return (false); + + return (true); +} + +/** * Return true if the @p hwrev matches @p desc. * * @param hwrev A bhnd hardware revision. @@ -512,6 +534,33 @@ } /** + * Scan @p table for all quirk flags applicable to @p dev's chip identifier + * (as returned by bhnd_get_chipid). + * + * @param dev A bhnd device. + * @param table The chip quirk table to search. + * + * @return returns all matching quirk flags. + */ +uint32_t +bhnd_chip_quirks(device_t dev, const struct bhnd_chip_quirk *table) +{ + const struct bhnd_chipid *cid; + const struct bhnd_chip_quirk *qent; + uint32_t quirks; + + cid = bhnd_get_chipid(dev); + quirks = 0; + + for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) { + if (bhnd_chip_matches(cid, &qent->chip)) + quirks |= qent->quirks; + } + + return (quirks); +} + +/** * Scan @p table for all quirk flags applicable to @p dev. * * @param dev A bhnd device to match against @p table.