Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 May 2016 21:20:17 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300628 - in head/sys/dev/bhnd: . bhndb cores/chipc cores/pci cores/pcie2 siba
Message-ID:  <201605242120.u4OLKHuL036436@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue May 24 21:20:17 2016
New Revision: 300628
URL: https://svnweb.freebsd.org/changeset/base/300628

Log:
  [bhnd] Normalize bhnd(4) device matching API
  
  This unifies handling of core, chip, and board-level device
  matching, and adds support for matching device drivers
  against the bus attach type (e.g. SoC vs WiFi adapter).
  
  Core-level quirks on Broadcom's chipsets generally are specific
  to some combination of chip model, core revision, chip
  package (e.g. 12x9 SMT package), SROM revision, etc.
  
  Unifying the match APIs for all three attribute types (core, chip,
  board/srom) allows defining a single device quirk table that
  matches across all of those attributes.
  
  Submitted by:	Landon Fuller <landonf@landonf.org>
  Differential Revision:	 https://reviews.freebsd.org/D6515

Added:
  head/sys/dev/bhnd/bhnd_match.h   (contents, props changed)
Modified:
  head/sys/dev/bhnd/bhnd.h
  head/sys/dev/bhnd/bhnd_subr.c
  head/sys/dev/bhnd/bhndb/bhndb.c
  head/sys/dev/bhnd/bhndb/bhndb_hwdata.c
  head/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
  head/sys/dev/bhnd/bhndb/bhndb_subr.c
  head/sys/dev/bhnd/cores/chipc/chipc.c
  head/sys/dev/bhnd/cores/pci/bhnd_pci.c
  head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
  head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2.c
  head/sys/dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c
  head/sys/dev/bhnd/siba/siba_bhndb.c

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Tue May 24 21:13:33 2016	(r300627)
+++ head/sys/dev/bhnd/bhnd.h	Tue May 24 21:20:17 2016	(r300628)
@@ -41,6 +41,7 @@
 #include "bhnd_types.h"
 #include "bhnd_debug.h"
 #include "bhnd_bus_if.h"
+#include "bhnd_match.h"
 
 extern devclass_t bhnd_devclass;
 extern devclass_t bhnd_hostb_devclass;
@@ -169,17 +170,6 @@ struct bhnd_core_info {
 	int		unit;		/**< bus-assigned core unit */
 };
 
-
-/**
- * A hardware revision match descriptor.
- */
-struct bhnd_hwrev_match {
-	uint16_t	start;	/**< first revision, or BHND_HWREV_INVALID
-					     to match on any revision. */
-	uint16_t	end;	/**< last revision, or BHND_HWREV_INVALID
-					     to match on any revision. */
-};
-
 /**
 * A bhnd(4) bus resource.
 * 
@@ -193,223 +183,70 @@ struct bhnd_resource {
 					 *   is MMIO accessible. */
 };
 
-/** 
- * Wildcard hardware revision match descriptor.
- */
-#define	BHND_HWREV_ANY		{ BHND_HWREV_INVALID, BHND_HWREV_INVALID }
-#define	BHND_HWREV_IS_ANY(_m)	\
-	((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID)
-
-/**
- * Hardware revision match descriptor for an inclusive range.
- * 
- * @param _start The first applicable hardware revision.
- * @param _end The last applicable hardware revision, or BHND_HWREV_INVALID
- * to match on any revision.
- */
-#define	BHND_HWREV_RANGE(_start, _end)	{ _start, _end }
-
-/**
- * Hardware revision match descriptor for a single revision.
- * 
- * @param _hwrev The hardware revision to match on.
- */
-#define	BHND_HWREV_EQ(_hwrev)	BHND_HWREV_RANGE(_hwrev, _hwrev)
-
-/**
- * Hardware revision match descriptor for any revision equal to or greater
- * than @p _start.
- * 
- * @param _start The first hardware revision to match on.
- */
-#define	BHND_HWREV_GTE(_start)	BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID)
-
-/**
- * Hardware revision match descriptor for any revision equal to or less
- * than @p _end.
- * 
- * @param _end The last hardware revision to match on.
- */
-#define	BHND_HWREV_LTE(_end)	BHND_HWREV_RANGE(0, _end)
-
-
-/** A core match descriptor. */
-struct bhnd_core_match {
-	uint16_t		vendor;	/**< required JEP106 device vendor or BHND_MFGID_INVALID. */
-	uint16_t		device;	/**< required core ID or BHND_COREID_INVALID */
-	struct bhnd_hwrev_match	hwrev;	/**< matching revisions. */
-	bhnd_devclass_t		class;	/**< required class or BHND_DEVCLASS_INVALID */
-	int			unit;	/**< required core unit, or -1 */
-};
-
-/**
- * Core match descriptor matching against the given @p _vendor, @p _device,
- * and @p _hwrev match descriptors.
- */
-#define	BHND_CORE_MATCH(_vendor, _device, _hwrev)	\
-	{ _vendor, _device, _hwrev, BHND_DEVCLASS_INVALID, -1 }
-
-/** 
- * Wildcard core match descriptor.
- */
-#define	BHND_CORE_MATCH_ANY			\
-	{					\
-		.vendor = BHND_MFGID_INVALID,	\
-		.device = BHND_COREID_INVALID,	\
-		.hwrev = BHND_HWREV_ANY,	\
-		.class = BHND_DEVCLASS_INVALID,	\
-		.unit = -1			\
-	}
-
 /**
- * A chipset match descriptor.
- * 
- * @warning Matching on board/nvram attributes relies on NVRAM access, and will
- * fail if a valid NVRAM device cannot be found, or is not yet attached.
+ * Device quirk table descriptor.
  */
-struct bhnd_chip_match {
-	/** Select fields to be matched */
-	uint16_t
-		match_id:1,
-		match_rev:1,
-		match_pkg:1,
-		match_bvendor:1,
-		match_btype:1,
-		match_brev:1,
-		match_srom_rev:1,
-		match_any:1,
-		match_flags_unused:8;
-
-	uint16_t		chip_id;	/**< required chip id */
-	struct bhnd_hwrev_match	chip_rev;	/**< matching chip revisions */
-	uint8_t			chip_pkg;	/**< required package */
-
-	uint16_t		board_vendor;	/**< required board vendor */
-	uint16_t		board_type;	/**< required board type */
-	struct bhnd_hwrev_match	board_rev;	/**< matching board revisions */
-
-	struct bhnd_hwrev_match	board_srom_rev;	/**< matching board srom revisions */
+struct bhnd_device_quirk {
+	struct bhnd_device_match desc;		/**< device match descriptor */
+	uint32_t		 quirks;	/**< quirk flags */
 };
 
-#define	BHND_CHIP_MATCH_ANY		\
-	{ .match_any = 1 }
-
-#define	BHND_CHIP_MATCH_IS_ANY(_m)	\
-	((_m)->match_any == 1)
-
-#define	BHND_CHIP_MATCH_REQ_BOARD_INFO(_m)		\
-	((_m)->match_srom_rev || (_m)->match_bvendor ||	\
-	    (_m)->match_btype || (_m)->match_brev)
-
-/** 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 chip revision range within a bhnd_chip_match instance */
-#define	BHND_CHIP_REV(_rev)		\
-	.match_rev = 1, .chip_rev = BHND_ ## _rev
+#define	BHND_CORE_QUIRK(_rev, _flags)		\
+	{{ BHND_MATCH_CORE_REV(_rev) }, (_flags) }
 
-/** 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
+#define	BHND_CHIP_QUIRK(_chip, _rev, _flags)	\
+	{{ BHND_CHIP_IR(BCM ## _chip, _rev) }, (_flags) }
 
-/** Set the required board vendor within a bhnd_chip_match instance */
-#define	BHND_CHIP_BVENDOR(_vend)		\
-	.match_bvendor = 1, .board_vendor = _vend
+#define	BHND_PKG_QUIRK(_chip, _pkg, _flags)	\
+	{{ BHND_CHIP_IP(BCM ## _chip, BCM ## _chip ## _pkg) }, (_flags) }
 
-/** Set the required board type within a bhnd_chip_match instance */
-#define	BHND_CHIP_BTYPE(_btype)		\
-	.match_btype = 1, .board_type = BHND_BOARD_ ## _btype
+#define	BHND_BOARD_QUIRK(_board, _flags)	\
+	{{ BHND_MATCH_BOARD_TYPE(_board) },	\
+	    (_flags) }
 
-/** Set the required SROM revision range within a bhnd_chip_match instance */
-#define	BHND_CHIP_SROMREV(_rev)		\
-	.match_srom_rev = 1, .board_srom_rev = BHND_ ## _rev
-
-/** Set the required board revision range within a bhnd_chip_match instance */
-#define	BHND_CHIP_BREV(_rev)	\
-	.match_brev = 1, .board_rev = BHND_ ## _rev
-
-/** Set the required board vendor and type within a bhnd_chip_match instance */
-#define	BHND_CHIP_BVT(_vend, _type)	\
-	BHND_CHIP_BVENDOR(_vend), BHND_CHIP_BTYPE(_type)
-
-/** Set the required board vendor, type, and revision within a bhnd_chip_match
- *  instance */
-#define	BHND_CHIP_BVTR(_vend, _type, _rev)	\
-	BHND_CHIP_BVT(_vend, _type), BHND_CHIP_BREV(_rev)
-
-/** 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.
- */
-struct bhnd_device_quirk {
-	struct bhnd_hwrev_match	 hwrev;		/**< applicable hardware revisions */
-	uint32_t		 quirks;	/**< quirk flags */
-};
-#define	BHND_DEVICE_QUIRK_END		{ BHND_HWREV_ANY, 0 }
+#define	BHND_DEVICE_QUIRK_END		{ { BHND_MATCH_ANY }, 0 }
 #define	BHND_DEVICE_QUIRK_IS_END(_q)	\
-	(BHND_HWREV_IS_ANY(&(_q)->hwrev) && (_q)->quirks == 0)
+	(((_q)->desc.m.match_flags == 0) && (_q)->quirks == 0)
 
 enum {
 	BHND_DF_ANY	= 0,
-	BHND_DF_HOSTB	= (1<<0)	/**< core is serving as the bus'
-					  *  host bridge */
+	BHND_DF_HOSTB	= (1<<0),	/**< core is serving as the bus' host
+					  *  bridge. implies BHND_DF_ADAPTER */
+	BHND_DF_SOC	= (1<<1),	/**< core is attached to a native
+					     bus (BHND_ATTACH_NATIVE) */
+	BHND_DF_ADAPTER	= (1<<2),	/**< core is attached to a bridged
+					  *  adapter (BHND_ATTACH_ADAPTER) */
 };
 
 /** Device probe table descriptor */
 struct bhnd_device {
-	const struct bhnd_core_match	 core;			/**< core match descriptor */ 
-	const char			*desc;			/**< device description, or NULL. */
-	const struct bhnd_device_quirk	*quirks_table;		/**< quirks table for this device, or NULL */
-	const struct bhnd_chip_quirk	*chip_quirks_table;	/**< chipset-specific quirks for this device, or NULL */
-	uint32_t			 device_flags;		/**< required BHND_DF_* flags */
+	const struct bhnd_device_match	 core;		/**< core match descriptor */ 
+	const char			*desc;		/**< device description, or NULL. */
+	const struct bhnd_device_quirk	*quirks_table;	/**< quirks table for this device, or NULL */
+	uint32_t			 device_flags;	/**< required BHND_DF_* flags */
 };
 
-#define	_BHND_DEVICE(_vendor, _device, _desc, _quirks, _chip_quirks,	\
-     _flags, ...)							\
-	{ BHND_CORE_MATCH(BHND_MFGID_ ## _vendor,			\
-	    BHND_COREID_ ## _device, BHND_HWREV_ANY), _desc, _quirks,	\
-	    _chip_quirks, _flags }
+#define	_BHND_DEVICE(_vendor, _device, _desc, _quirks,		\
+     _flags, ...)						\
+	{ { BHND_MATCH_CORE(BHND_MFGID_ ## _vendor,		\
+	    BHND_COREID_ ## _device) }, _desc, _quirks,		\
+	    _flags }
 
-#define	BHND_MIPS_DEVICE(_device, _desc, _quirks, _chip_quirks, ...)	\
-	_BHND_DEVICE(MIPS, _device, _desc, _quirks, _chip_quirks,	\
+#define	BHND_MIPS_DEVICE(_device, _desc, _quirks, ...)	\
+	_BHND_DEVICE(MIPS, _device, _desc, _quirks,	\
 	    ## __VA_ARGS__, 0)
 
-#define	BHND_ARM_DEVICE(_device, _desc, _quirks, _chip_quirks, ...)	\
-	_BHND_DEVICE(ARM, _device, _desc, _quirks, _chip_quirks,	\
+#define	BHND_ARM_DEVICE(_device, _desc, _quirks, ...)	\
+	_BHND_DEVICE(ARM, _device, _desc, _quirks,	\
 	    ## __VA_ARGS__, 0)
 
-#define	BHND_DEVICE(_device, _desc, _quirks, _chip_quirks, ...)		\
-	_BHND_DEVICE(BCM, _device, _desc, _quirks, _chip_quirks,	\
+#define	BHND_DEVICE(_device, _desc, _quirks, ...)		\
+	_BHND_DEVICE(BCM, _device, _desc, _quirks,	\
 	    ## __VA_ARGS__, 0)
 
-#define	BHND_DEVICE_END	{ BHND_CORE_MATCH_ANY, NULL, NULL, NULL, 0 }
+#define	BHND_DEVICE_END		{ { BHND_MATCH_ANY }, NULL, NULL, 0 }
+#define	BHND_DEVICE_IS_END(_d)	\
+	(BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL)
 
 const char			*bhnd_vendor_name(uint16_t vendor);
 const char			*bhnd_port_type_name(bhnd_port_type port_type);
@@ -447,17 +284,17 @@ bool				 bhnd_core_matches(
 
 bool				 bhnd_chip_matches(
 				     const struct bhnd_chipid *chipid,
-				     const struct bhnd_board_info *binfo,
 				     const struct bhnd_chip_match *desc);
 
+bool				 bhnd_board_matches(
+				     const struct bhnd_board_info *info,
+				     const struct bhnd_board_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);
+				     const struct bhnd_device_match *desc);
 
 const struct bhnd_device	*bhnd_device_lookup(device_t dev,
 				     const struct bhnd_device *table,
@@ -469,7 +306,6 @@ uint32_t			 bhnd_device_quirks(device_t 
 
 struct bhnd_core_info		 bhnd_get_core_info(device_t dev);
 
-
 int				 bhnd_alloc_resources(device_t dev,
 				     struct resource_spec *rs,
 				     struct bhnd_resource **res);

Added: head/sys/dev/bhnd/bhnd_match.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/bhnd/bhnd_match.h	Tue May 24 21:20:17 2016	(r300628)
@@ -0,0 +1,291 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_BHND_MATCH_H_
+#define _BHND_BHND_MATCH_H_
+
+#include "bhnd_types.h"
+
+/**
+ * A hardware revision match descriptor.
+ */
+struct bhnd_hwrev_match {
+	uint16_t	start;	/**< first revision, or BHND_HWREV_INVALID
+					     to match on any revision. */
+	uint16_t	end;	/**< last revision, or BHND_HWREV_INVALID
+					     to match on any revision. */
+};
+
+/* Copy match field @p _name from @p _src */
+#define	_BHND_COPY_MATCH_FIELD(_src, _name)	\
+	.m.match._name = (_src)->m.match._name,	\
+	._name = (_src)->_name
+	
+/* Set match field @p _name with @p _value */
+#define	_BHND_SET_MATCH_FIELD(_name, _value)	\
+	.m.match._name = 1, ._name = _value
+
+/** 
+ * Wildcard hardware revision match descriptor.
+ */
+#define	BHND_HWREV_ANY		{ BHND_HWREV_INVALID, BHND_HWREV_INVALID }
+#define	BHND_HWREV_IS_ANY(_m)	\
+	((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID)
+
+/**
+ * Hardware revision match descriptor for an inclusive range.
+ * 
+ * @param _start The first applicable hardware revision.
+ * @param _end The last applicable hardware revision, or BHND_HWREV_INVALID
+ * to match on any revision.
+ */
+#define	BHND_HWREV_RANGE(_start, _end)	{ _start, _end }
+
+/**
+ * Hardware revision match descriptor for a single revision.
+ * 
+ * @param _hwrev The hardware revision to match on.
+ */
+#define	BHND_HWREV_EQ(_hwrev)	BHND_HWREV_RANGE(_hwrev, _hwrev)
+
+/**
+ * Hardware revision match descriptor for any revision equal to or greater
+ * than @p _start.
+ * 
+ * @param _start The first hardware revision to match on.
+ */
+#define	BHND_HWREV_GTE(_start)	BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID)
+
+/**
+ * Hardware revision match descriptor for any revision equal to or less
+ * than @p _end.
+ * 
+ * @param _end The last hardware revision to match on.
+ */
+#define	BHND_HWREV_LTE(_end)	BHND_HWREV_RANGE(0, _end)
+
+/**
+ * A bhnd(4) core match descriptor.
+ */
+struct bhnd_core_match {
+	/** Select fields to be matched */
+	union {
+		uint8_t match_flags;
+		struct {
+			uint8_t
+			    core_vendor:1,
+			    core_id:1,
+			    core_rev:1,
+			    core_class:1,
+			    core_unit:1,
+			    flags_unused:3;
+		} match;
+	} m;
+	
+	uint16_t		core_vendor;	/**< required JEP106 device vendor */
+	uint16_t		core_id;	/**< required core ID */
+	struct bhnd_hwrev_match	core_rev;	/**< matching core revisions. */
+	bhnd_devclass_t		core_class;	/**< required bhnd class */
+	int			core_unit;	/**< required core unit */
+};
+
+#define	_BHND_CORE_MATCH_COPY(_src)			\
+	_BHND_COPY_MATCH_FIELD(_src, core_vendor),	\
+	_BHND_COPY_MATCH_FIELD(_src, core_id),		\
+	_BHND_COPY_MATCH_FIELD(_src, core_rev),		\
+	_BHND_COPY_MATCH_FIELD(_src, core_class),	\
+	_BHND_COPY_MATCH_FIELD(_src, core_unit)		\
+
+#define	BHND_MATCH_CORE_VENDOR(_v)	_BHND_SET_MATCH_FIELD(core_vendor, _v)
+#define	BHND_MATCH_CORE_ID(_id)		_BHND_SET_MATCH_FIELD(core_id, _id)
+#define	BHND_MATCH_CORE_REV(_rev)	_BHND_SET_MATCH_FIELD(core_rev,	\
+					    BHND_ ## _rev)
+#define	BHND_MATCH_CORE_CLASS(_cls)	_BHND_SET_MATCH_FIELD(core_class, _cls)
+#define	BHND_MATCH_CORE_UNIT(_unit)	_BHND_SET_MATCH_FIELD(core_unit, _unit)
+
+/**
+ * Match against the given @p _vendor and @p _id,
+ */
+#define	BHND_MATCH_CORE(_vendor, _id)		\
+	BHND_MATCH_CORE_VENDOR(_vendor),	\
+	BHND_MATCH_CORE_ID(_id)
+
+/**
+ * A bhnd(4) chip match descriptor.
+ */
+struct bhnd_chip_match {
+	/** Select fields to be matched */
+	union {
+		uint8_t match_flags;
+		struct {
+			uint8_t
+			    chip_id:1,
+			    chip_rev:1,
+			    chip_pkg:1,
+			    flags_unused:5;
+		} match;
+
+	} m;
+
+	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_COPY(_src)		\
+	_BHND_COPY_MATCH_FIELD(_src, chip_id),	\
+	_BHND_COPY_MATCH_FIELD(_src, chip_rev),	\
+	_BHND_COPY_MATCH_FIELD(_src, chip_pkg)	\
+
+/** Set the required chip ID within a bhnd match descriptor */
+#define	BHND_CHIP_ID(_cid)	_BHND_SET_MATCH_FIELD(chip_id,	\
+					    BHND_CHIPID_ ## _cid)
+
+/** Set the required chip revision range within a bhnd match descriptor */
+#define	BHND_CHIP_REV(_rev)	_BHND_SET_MATCH_FIELD(chip_rev,	\
+					    BHND_ ## _rev)
+
+/** Set the required package ID within a bhnd match descriptor */
+#define	BHND_CHIP_PKG(_pkg)	_BHND_SET_MATCH_FIELD(chip_pkg,	\
+					    BHND_PKGID_ ## _pkg)
+
+/** Set the required chip and package ID within a bhnd match descriptor */
+#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_device_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_device_match
+ *  instance */
+#define	BHND_CHIP_IR(_cid, _rev)	\
+    BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev)
+
+/**
+ * A bhnd(4) board match descriptor.
+ */
+struct bhnd_board_match {
+	/** Select fields to be matched */
+	union {
+		uint8_t match_flags;
+		struct {
+			uint8_t
+			    board_vendor:1,
+			    board_type:1,
+			    board_rev:1,
+			    board_srom_rev:1,
+			    flags_unused:4;
+		} match;
+	} m;
+
+	uint16_t		board_vendor;	/**< required board vendor */
+	uint16_t		board_type;	/**< required board type */
+	struct bhnd_hwrev_match	board_rev;	/**< matching board revisions */
+	struct bhnd_hwrev_match	board_srom_rev;	/**< matching board srom revisions */
+};
+
+#define	_BHND_BOARD_MATCH_COPY(_src)			\
+	_BHND_COPY_MATCH_FIELD(_src, board_vendor),	\
+	_BHND_COPY_MATCH_FIELD(_src, board_type),	\
+	_BHND_COPY_MATCH_FIELD(_src, board_rev),	\
+	_BHND_COPY_MATCH_FIELD(_src, board_srom_rev)
+
+/** Set the required board vendor within a bhnd match descriptor */
+#define	BHND_MATCH_BOARD_VENDOR(_v)	_BHND_SET_MATCH_FIELD(board_vendor, _v)
+
+/** Set the required board type within a bhnd match descriptor */
+#define	BHND_MATCH_BOARD_TYPE(_type)	_BHND_SET_MATCH_FIELD(board_type, \
+					    BHND_BOARD_ ## _type)
+/** Set the required SROM revision range within a bhnd match descriptor */
+#define	BHND_MATCH_SROMREV(_rev)	_BHND_SET_MATCH_FIELD(board_srom_rev, \
+					    BHND_HWREV_ ## _rev)
+
+/** Set the required board revision range within a bhnd match descriptor */
+#define	BHND_MATCH_BOARD_REV(_rev)	_BHND_SET_MATCH_FIELD(board_rev, \
+					    BHND_ ## _rev)
+
+/** Set the required board vendor and type within a bhnd match descriptor */
+#define	BHND_MATCH_BOARD(_vend, _type)	\
+	BHND_MATCH_BOARD_VENDOR(_vend), BHND_MATCH_BOARD_TYPE(_type)
+
+
+/**
+ * A bhnd(4) device match descriptor.
+ *
+ * @warning Matching on board attributes relies on NVRAM access, and will
+ * fail if a valid NVRAM device cannot be found, or is not yet attached.
+ */
+struct bhnd_device_match {
+	/** Select fields to be matched */
+	union {
+		uint16_t match_flags;
+		struct {
+			uint16_t
+			core_vendor:1,
+			core_id:1,
+			core_rev:1,
+			core_class:1,
+			core_unit:1,
+			chip_id:1,
+			chip_rev:1,
+			chip_pkg:1,
+			board_vendor:1,
+			board_type:1,
+			board_rev:1,
+			board_srom_rev:1,
+			flags_unused:2;
+		} match;
+	} m;
+	
+	uint16_t		core_vendor;	/**< required JEP106 device vendor */
+	uint16_t		core_id;	/**< required core ID */
+	struct bhnd_hwrev_match	core_rev;	/**< matching core revisions. */
+	bhnd_devclass_t		core_class;	/**< required bhnd class */
+	int			core_unit;	/**< required core unit */
+
+	uint16_t		chip_id;	/**< required chip id */
+	struct bhnd_hwrev_match	chip_rev;	/**< matching chip revisions */
+	uint8_t			chip_pkg;	/**< required package */
+
+	uint16_t		board_vendor;	/**< required board vendor */
+	uint16_t		board_type;	/**< required board type */
+	struct bhnd_hwrev_match	board_rev;	/**< matching board revisions */
+	struct bhnd_hwrev_match	board_srom_rev;	/**< matching board srom revisions */
+};
+
+/** Define a wildcard match requirement (matches on any device). */
+#define	BHND_MATCH_ANY		.m.match_flags = 0
+#define	BHND_MATCH_IS_ANY(_m)	\
+	((_m)->m.match_flags == 0)
+
+#endif /* _BHND_BHND_MATCH_H_ */

Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c	Tue May 24 21:13:33 2016	(r300627)
+++ head/sys/dev/bhnd/bhnd_subr.c	Tue May 24 21:20:17 2016	(r300628)
@@ -303,14 +303,13 @@ device_t
 bhnd_find_child(device_t dev, bhnd_devclass_t class, int unit)
 {
 	struct bhnd_core_match md = {
-		.vendor = BHND_MFGID_INVALID,
-		.device = BHND_COREID_INVALID,
-		.hwrev.start = BHND_HWREV_INVALID,
-		.hwrev.end = BHND_HWREV_INVALID,
-		.class = class,
-		.unit = unit
+		BHND_MATCH_CORE_CLASS(class),
+		BHND_MATCH_CORE_UNIT(unit)
 	};
 
+	if (unit == -1)
+		md.m.match.core_unit = 0;
+
 	return bhnd_match_child(dev, &md);
 }
 
@@ -337,9 +336,10 @@ bhnd_match_child(device_t dev, const str
 
 	match = NULL;
 	for (int i = 0; i < devcnt; i++) {
-		device_t dev = devlistp[i];
-		if (bhnd_device_matches(dev, desc)) {
-			match = dev;
+		struct bhnd_core_info ci = bhnd_get_core_info(devlistp[i]);
+
+		if (bhnd_core_matches(&ci, desc)) {
+			match = devlistp[i];
 			goto done;
 		}
 	}
@@ -437,12 +437,7 @@ bhnd_find_core(const struct bhnd_core_in
     bhnd_devclass_t class)
 {
 	struct bhnd_core_match md = {
-		.vendor = BHND_MFGID_INVALID,
-		.device = BHND_COREID_INVALID,
-		.hwrev.start = BHND_HWREV_INVALID,
-		.hwrev.end = BHND_HWREV_INVALID,
-		.class = class,
-		.unit = -1
+		BHND_MATCH_CORE_CLASS(class)
 	};
 
 	return bhnd_match_core(cores, num_cores, &md);
@@ -461,22 +456,21 @@ bool
 bhnd_core_matches(const struct bhnd_core_info *core,
     const struct bhnd_core_match *desc)
 {
-	if (desc->vendor != BHND_MFGID_INVALID &&
-	    desc->vendor != core->vendor)
+	if (desc->m.match.core_vendor && desc->core_vendor != core->vendor)
 		return (false);
 
-	if (desc->device != BHND_COREID_INVALID &&
-	    desc->device != core->device)
+	if (desc->m.match.core_id && desc->core_id != core->device)
 		return (false);
 
-	if (desc->unit != -1 && desc->unit != core->unit)
+	if (desc->m.match.core_unit && desc->core_unit != core->unit)
 		return (false);
 
-	if (!bhnd_hwrev_matches(core->hwrev, &desc->hwrev))
+	if (desc->m.match.core_rev && 
+	    !bhnd_hwrev_matches(core->hwrev, &desc->core_rev))
 		return (false);
 
-	if (desc->class != BHND_DEVCLASS_INVALID &&
-	    desc->class != bhnd_core_class(core))
+	if (desc->m.match.core_class &&
+	    desc->core_class != bhnd_core_class(core))
 		return (false);
 
 	return true;
@@ -486,7 +480,6 @@ bhnd_core_matches(const struct bhnd_core
  * Return true if the @p chip matches @p desc.
  * 
  * @param chip A bhnd chip identifier.
- * @param board The bhnd board info, or NULL if unavailable.
  * @param desc A match descriptor to compare against @p chip.
  * 
  * @retval true if @p chip matches @p match
@@ -494,46 +487,49 @@ bhnd_core_matches(const struct bhnd_core
  */
 bool
 bhnd_chip_matches(const struct bhnd_chipid *chip,
-    const struct bhnd_board_info *board,
     const struct bhnd_chip_match *desc)
 {
-	/* Explicit wildcard match */
-	if (desc->match_any)
-		return (true);
-
-	/* If board_info is missing, but required, we cannot match. */
-	if (BHND_CHIP_MATCH_REQ_BOARD_INFO(desc) && board == NULL)
-		return (false);
-
-
-	/* Chip matching */
-	if (desc->match_id && chip->chip_id != desc->chip_id)
+	if (desc->m.match.chip_id && chip->chip_id != desc->chip_id)
 		return (false);
 
-	if (desc->match_pkg && chip->chip_pkg != desc->chip_pkg)
+	if (desc->m.match.chip_pkg && chip->chip_pkg != desc->chip_pkg)
 		return (false);
 
-	if (desc->match_rev &&
+	if (desc->m.match.chip_rev &&
 	    !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev))
 		return (false);
 
+	return (true);
+}
 
-	/* Board info matching */
-	if (desc->match_srom_rev &&
+/**
+ * Return true if the @p board matches @p desc.
+ * 
+ * @param board The bhnd board info.
+ * @param desc A match descriptor to compare against @p board.
+ * 
+ * @retval true if @p chip matches @p match
+ * @retval false if @p chip does not match @p match.
+ */
+bool
+bhnd_board_matches(const struct bhnd_board_info *board,
+    const struct bhnd_board_match *desc)
+{
+	if (desc->m.match.board_srom_rev &&
 	    !bhnd_hwrev_matches(board->board_srom_rev, &desc->board_srom_rev))
 		return (false);
 
-	if (desc->match_bvendor && board->board_vendor != desc->board_vendor)
+	if (desc->m.match.board_vendor &&
+	    board->board_vendor != desc->board_vendor)
 		return (false);
 
-	if (desc->match_btype && board->board_type != desc->board_type)
+	if (desc->m.match.board_type && board->board_type != desc->board_type)
 		return (false);
 
-	if (desc->match_brev &&
+	if (desc->m.match.board_rev &&
 	    !bhnd_hwrev_matches(board->board_rev, &desc->board_rev))
 		return (false);
 
-
 	return (true);
 }
 
@@ -570,16 +566,59 @@ bhnd_hwrev_matches(uint16_t hwrev, const
  * @retval false if @p dev does not match @p match.
  */
 bool
-bhnd_device_matches(device_t dev, const struct bhnd_core_match *desc)
+bhnd_device_matches(device_t dev, const struct bhnd_device_match *desc)
 {
-	struct bhnd_core_info ci = {
-		.vendor = bhnd_get_vendor(dev),
-		.device = bhnd_get_device(dev),
-		.unit = bhnd_get_core_unit(dev),
-		.hwrev = bhnd_get_hwrev(dev)
-	};
+	struct bhnd_core_info		 core;
+	const struct bhnd_chipid	*chip;
+	struct bhnd_board_info		 board;
+	device_t			 parent;
+	int				 error;
 
-	return bhnd_core_matches(&ci, desc);
+	/* Construct individual match descriptors */
+	struct bhnd_core_match	m_core	= { _BHND_CORE_MATCH_COPY(desc) };
+	struct bhnd_chip_match	m_chip	= { _BHND_CHIP_MATCH_COPY(desc) };
+	struct bhnd_board_match	m_board	= { _BHND_BOARD_MATCH_COPY(desc) };
+
+	/* Fetch and match core info */
+	if (m_core.m.match_flags) {
+		/* Only applicable to bhnd-attached cores */
+		parent = device_get_parent(dev);
+		if (device_get_devclass(parent) != bhnd_devclass) {
+			device_printf(dev, "attempting to match core "
+			    "attributes against non-core device\n");
+			return (false);
+		}
+
+		core = bhnd_get_core_info(dev);
+		if (!bhnd_core_matches(&core, &m_core))
+			return (false);
+	}
+
+	/* Fetch and match chip info */
+	if (m_chip.m.match_flags) {
+		chip = bhnd_get_chipid(dev);
+
+		if (!bhnd_chip_matches(chip, &m_chip))
+			return (false);
+	}
+
+	/* Fetch and match board info.
+	 *
+	 * This is not available until  after NVRAM is up; earlier device
+	 * matches should not include board requirements */
+	if (m_board.m.match_flags) {
+		if ((error = bhnd_read_board_info(dev, &board))) {
+			device_printf(dev, "failed to read required board info "
+			    "during device matching: %d\n", error);
+			return (false);
+		}
+
+		if (!bhnd_board_matches(&board, &m_board))
+			return (false);
+	}
+
+	/* All matched */
+	return (true);
 }
 
 /**
@@ -598,11 +637,14 @@ bhnd_device_lookup(device_t dev, const s
 {
 	const struct bhnd_device	*entry;
 	device_t			 hostb, parent;
+	bhnd_attach_type		 attach_type;
+	uint32_t			 dflags;
 
 	parent = device_get_parent(dev);
 	hostb = bhnd_find_hostb_device(parent);
+	attach_type = bhnd_get_attach_type(dev);
 
-	for (entry = table; entry->desc != NULL; entry =
+	for (entry = table; !BHND_DEVICE_IS_END(entry); entry =
 	    (const struct bhnd_device *) ((const char *) entry + entry_size))
 	{
 		/* match core info */
@@ -610,10 +652,23 @@ bhnd_device_lookup(device_t dev, const s
 			continue;
 
 		/* match device flags */
-		if (entry->device_flags & BHND_DF_HOSTB) {			
+		dflags = entry->device_flags;
+
+		/* hostb implies BHND_ATTACH_ADAPTER requirement */
+		if (dflags & BHND_DF_HOSTB)
+			dflags |= BHND_DF_ADAPTER;
+	
+		if (dflags & BHND_DF_ADAPTER)
+			if (attach_type != BHND_ATTACH_ADAPTER)
+				continue;
+
+		if (dflags & BHND_DF_HOSTB)
 			if (dev != hostb)
 				continue;
-		}
+
+		if (dflags & BHND_DF_SOC)
+			if (attach_type != BHND_ATTACH_NATIVE)
+				continue;
 
 		/* device found */
 		return (entry);
@@ -624,66 +679,10 @@ 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)
-{
-	struct bhnd_board_info		 bi, *board;
-	const struct bhnd_chipid	*cid;
-	const struct bhnd_chip_quirk	*qent;
-	uint32_t			 quirks;
-	int				 error;
-	bool				 need_boardinfo;
-
-	cid = bhnd_get_chipid(dev);
-	quirks = 0;
-	need_boardinfo = 0;
-	board = NULL;
-
-	/* Determine whether quirk matching requires board_info; we want to
-	 * avoid fetching board_info for early devices (e.g. ChipCommon)
-	 * that are brought up prior to NVRAM being readable. */
-	for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) {
-		if (!BHND_CHIP_MATCH_REQ_BOARD_INFO(&qent->chip))
-			continue;
-
-		need_boardinfo = true;
-		break;
-	}
-
-	/* If required, fetch board info */
-	if (need_boardinfo) {
-		error = bhnd_read_board_info(dev, &bi);
-		if (!error) {
-			board = &bi;
-		} else {
-			device_printf(dev, "failed to read required board info "
-			    "during quirk matching: %d\n", error);
-		}
-	}
-
-	/* Apply all matching quirk flags */
-	for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) {
-		if (bhnd_chip_matches(cid, board, &qent->chip))
-			quirks |= qent->quirks;
-	}
-
-	return (quirks);
-}
-
-/**
- * Scan @p table for all quirk flags applicable to @p dev.
+ * Scan the device @p table for all quirk flags applicable to @p dev.
  * 
  * @param dev A bhnd device to match against @p table.
  * @param table The device table to search.
- * @param entry_size The @p table entry size, in bytes.
  * 
  * @return returns all matching quirk flags.
  */
@@ -692,32 +691,25 @@ bhnd_device_quirks(device_t dev, const s
     size_t entry_size)
 {
 	const struct bhnd_device	*dent;
-	const struct bhnd_device_quirk	*qtable, *qent;
+	const struct bhnd_device_quirk	*qent, *qtable;
 	uint32_t			 quirks;
-	uint16_t			 hwrev;
 
-	hwrev = bhnd_get_hwrev(dev);
-	quirks = 0;
+	/* Locate the device entry */
+	if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL)
+		return (0);
 
-	/* Find the quirk table */
-	if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL) {
-		/* This is almost certainly a (caller) implementation bug */
-		device_printf(dev, "quirk lookup did not match any device\n");
+	/* Quirks table is optional */
+	qtable = dent->quirks_table;
+	if (qtable == NULL)
 		return (0);
-	}
 
 	/* Collect matching device quirk entries */
-	if ((qtable = dent->quirks_table) != NULL) {
-		for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
-			if (bhnd_hwrev_matches(hwrev, &qent->hwrev))
-				quirks |= qent->quirks;
-		}
+	quirks = 0;
+	for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
+		if (bhnd_device_matches(dev, &qent->desc))
+			quirks |= qent->quirks;
 	}
 
-	/* Collect matching chip quirk entries */
-	if (dent->chip_quirks_table != NULL)
-		quirks |= bhnd_chip_quirks(dev, dent->chip_quirks_table);
-
 	return (quirks);
 }
 

Modified: head/sys/dev/bhnd/bhndb/bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb.c	Tue May 24 21:13:33 2016	(r300627)
+++ head/sys/dev/bhnd/bhndb/bhndb.c	Tue May 24 21:20:17 2016	(r300628)
@@ -194,13 +194,15 @@ bhndb_hw_matches(device_t *devlist, int 
 {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605242120.u4OLKHuL036436>