svn commit: r299240 - head/sys/dev/bhnd

Adrian Chadd adrian at FreeBSD.org
Sun May 8 18:30:10 UTC 2016


Author: adrian
Date: Sun May  8 18:30:08 2016
New Revision: 299240
URL: https://svnweb.freebsd.org/changeset/base/299240

Log:
  [bhnd] Add support for matching on chip identifiers.
  
  This is used by the upcoming SPROM code to match on chipsets
  that require special handling of muxed SPROM pins.
  
  Submitted by:	Landon Fuller <landonf at landonf.org>
  Differential Revision:	https://reviews.freebsd.org/D6195

Modified:
  head/sys/dev/bhnd/bhnd.h
  head/sys/dev/bhnd/bhnd_subr.c

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Sun May  8 18:20:01 2016	(r299239)
+++ head/sys/dev/bhnd/bhnd.h	Sun May  8 18:30:08 2016	(r299240)
@@ -232,6 +232,65 @@ struct bhnd_core_match {
 		.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,16 @@ bool				 bhnd_core_matches(
 				     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);
+
 bool				 bhnd_device_matches(device_t dev,
 				     const struct bhnd_core_match *desc);
 
@@ -389,6 +455,17 @@ bhnd_is_hw_disabled(device_t dev) {
 }
 
 /**
+ * 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.

Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c	Sun May  8 18:20:01 2016	(r299239)
+++ head/sys/dev/bhnd/bhnd_subr.c	Sun May  8 18:30:08 2016	(r299240)
@@ -415,10 +415,6 @@ bhnd_core_matches(const struct bhnd_core
 
 	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))
@@ -428,6 +424,32 @@ bhnd_core_matches(const struct bhnd_core
 }
 
 /**
+ * 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.
@@ -514,6 +536,33 @@ bhnd_device_lookup(device_t dev, const s
 }
 
 /**
+ * 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.


More information about the svn-src-all mailing list