svn commit: r299235 - in head/sys/dev/bhnd: . bcma bhndb siba

Adrian Chadd adrian at FreeBSD.org
Sun May 8 17:52:15 UTC 2016


Author: adrian
Date: Sun May  8 17:52:12 2016
New Revision: 299235
URL: https://svnweb.freebsd.org/changeset/base/299235

Log:
  [bhnd] Replace is_hostb_device() with a more general find_hostb_device()
  
  This allows bus children to query for the host bridge device, rather
  than having to iterate over all attached devices.
  
  Submitted by:	Landon Fuller <landonf at landonf.org>
  Differential Revision:	https://reviews.freebsd.org/D6193

Modified:
  head/sys/dev/bhnd/bcma/bcma.c
  head/sys/dev/bhnd/bcma/bcma_bhndb.c
  head/sys/dev/bhnd/bcma/bcmavar.h
  head/sys/dev/bhnd/bhnd.c
  head/sys/dev/bhnd/bhnd.h
  head/sys/dev/bhnd/bhnd_bus_if.m
  head/sys/dev/bhnd/bhnd_subr.c
  head/sys/dev/bhnd/bhndb/bhndb.c
  head/sys/dev/bhnd/bhndb/bhndb_if.m
  head/sys/dev/bhnd/siba/siba.c
  head/sys/dev/bhnd/siba/siba_bhndb.c
  head/sys/dev/bhnd/siba/sibavar.h

Modified: head/sys/dev/bhnd/bcma/bcma.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bcma/bcma.c	Sun May  8 17:52:12 2016	(r299235)
@@ -194,6 +194,14 @@ bcma_get_resource_list(device_t dev, dev
 	return (&dinfo->resources);
 }
 
+static device_t
+bcma_find_hostb_device(device_t dev)
+{
+	struct bcma_softc *sc = device_get_softc(dev);
+
+	/* This is set (or not) by the concrete bcma driver subclass. */
+	return (sc->hostb_dev);
+}
 
 static int
 bcma_reset_core(device_t dev, device_t child, uint16_t flags)
@@ -471,6 +479,7 @@ static device_method_t bcma_methods[] = 
 	DEVMETHOD(bus_get_resource_list,	bcma_get_resource_list),
 
 	/* BHND interface */
+	DEVMETHOD(bhnd_bus_find_hostb_device,	bcma_find_hostb_device),
 	DEVMETHOD(bhnd_bus_reset_core,		bcma_reset_core),
 	DEVMETHOD(bhnd_bus_suspend_core,	bcma_suspend_core),
 	DEVMETHOD(bhnd_bus_get_port_count,	bcma_get_port_count),

Modified: head/sys/dev/bhnd/bcma/bcma_bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_bhndb.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bcma/bcma_bhndb.c	Sun May  8 17:52:12 2016	(r299235)
@@ -65,14 +65,16 @@ bcma_bhndb_probe(device_t dev)
 static int
 bcma_bhndb_attach(device_t dev)
 {
+	struct bcma_softc		*sc;
 	const struct bhnd_chipid	*cid;
 	struct resource			*erom_res;
 	int				 error;
 	int				 rid;
 
-	cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
+	sc = device_get_softc(dev);
 
 	/* Map the EROM resource and enumerate our children. */
+	cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
 	rid = 0;
 	erom_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, cid->enum_addr,
 		cid->enum_addr + BCMA_EROM_TABLE_SIZE, BCMA_EROM_TABLE_SIZE,
@@ -95,6 +97,9 @@ bcma_bhndb_attach(device_t dev)
 	if (error)
 		return (error);
 
+	/* Ask our parent bridge to find the corresponding bridge core */
+	sc->hostb_dev = BHNDB_FIND_HOSTB_DEVICE(device_get_parent(dev), dev);
+
 	/* Call our superclass' implementation */
 	return (bcma_attach(dev));
 }

Modified: head/sys/dev/bhnd/bcma/bcmavar.h
==============================================================================
--- head/sys/dev/bhnd/bcma/bcmavar.h	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bcma/bcmavar.h	Sun May  8 17:52:12 2016	(r299235)
@@ -144,6 +144,7 @@ struct bcma_devinfo {
 /** BMCA per-instance state */
 struct bcma_softc {
 	struct bhnd_softc	bhnd_sc;	/**< bhnd state */
+	device_t		hostb_dev;	/**< host bridge core, or NULL */
 };
 
 #endif /* _BCMA_BCMAVAR_H_ */
\ No newline at end of file

Modified: head/sys/dev/bhnd/bhnd.c
==============================================================================
--- head/sys/dev/bhnd/bhnd.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bhnd.c	Sun May  8 17:52:12 2016	(r299235)
@@ -347,7 +347,7 @@ bhnd_generic_get_probe_order(device_t de
 	case BHND_DEVCLASS_EROM:
 	case BHND_DEVCLASS_OTHER:
 	case BHND_DEVCLASS_INVALID:
-		if (bhnd_is_hostb_device(child))
+		if (bhnd_find_hostb_device(dev) == child)
 			return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
 
 		return (BHND_PROBE_DEFAULT);
@@ -676,7 +676,6 @@ static device_method_t bhnd_methods[] = 
 	DEVMETHOD(bhnd_bus_get_chipid,		bhnd_bus_generic_get_chipid),
 	DEVMETHOD(bhnd_bus_get_probe_order,	bhnd_generic_get_probe_order),
 	DEVMETHOD(bhnd_bus_is_region_valid,	bhnd_generic_is_region_valid),
-	DEVMETHOD(bhnd_bus_is_hostb_device,	bhnd_bus_generic_is_hostb_device),
 	DEVMETHOD(bhnd_bus_is_hw_disabled,	bhnd_bus_generic_is_hw_disabled),
 	DEVMETHOD(bhnd_bus_read_nvram_var,	bhnd_generic_read_nvram_var),
 	DEVMETHOD(bhnd_bus_read_1,		bhnd_read_1),

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bhnd.h	Sun May  8 17:52:12 2016	(r299235)
@@ -335,8 +335,6 @@ void				 bhnd_set_custom_core_desc(devic
 void				 bhnd_set_default_core_desc(device_t dev);
 
 
-bool				 bhnd_bus_generic_is_hostb_device(device_t dev,
-				     device_t child);
 bool				 bhnd_bus_generic_is_hw_disabled(device_t dev,
 				     device_t child);
 bool				 bhnd_bus_generic_is_region_valid(device_t dev,
@@ -364,14 +362,14 @@ int				 bhnd_bus_generic_deactivate_reso
 
 
 /**
- * Return true if @p dev is serving as a host bridge for its parent bhnd
- * bus.
+ * Return the active host bridge core for the bhnd bus, if any, or NULL if
+ * not found.
  *
- * @param dev A bhnd bus child device.
+ * @param dev A bhnd bus device.
  */
-static inline bool
-bhnd_is_hostb_device(device_t dev) {
-	return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev), dev));
+static inline device_t
+bhnd_find_hostb_device(device_t dev) {
+	return (BHND_BUS_FIND_HOSTB_DEVICE(dev));
 }
 
 /**

Modified: head/sys/dev/bhnd/bhnd_bus_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bhnd_bus_if.m	Sun May  8 17:52:12 2016	(r299235)
@@ -55,10 +55,10 @@ CODE {
 		panic("bhnd_bus_get_chipid unimplemented");
 	}
 	
-	static bool
-	bhnd_bus_null_is_hostb_device(device_t dev, device_t child)
+	static device_t
+	bhnd_bus_null_find_hostb_device(device_t dev)
 	{
-		panic("bhnd_bus_is_hostb_device unimplemented");
+		panic("bhnd_bus_find_hostb_device unimplemented");
 	}
 
 	static bool
@@ -105,19 +105,16 @@ CODE {
 }
 
 /**
- * Returns true if @p child is serving as a host bridge for the bhnd
- * bus.
+ * Return the active host bridge core for the bhnd bus, if any.
  *
- * The default implementation will walk the parent device tree until
- * the root node is hit, returning false.
+ * @param dev The bhnd bus device.
  *
- * @param dev The device whose child is being examined.
- * @param child The child device.
+ * @retval device_t if a hostb device exists
+ * @retval NULL if no hostb device is found.
  */
-METHOD bool is_hostb_device {
+METHOD device_t find_hostb_device {
 	device_t dev;
-	device_t child;
-} DEFAULT bhnd_bus_null_is_hostb_device;
+} DEFAULT bhnd_bus_null_find_hostb_device;
 
 /**
  * Return true if the hardware components required by @p child are unpopulated

Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bhnd_subr.c	Sun May  8 17:52:12 2016	(r299235)
@@ -486,7 +486,11 @@ const struct bhnd_device *
 bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
     size_t entry_size)
 {
-	const struct bhnd_device *entry;
+	const struct bhnd_device	*entry;
+	device_t			 hostb, parent;
+
+	parent = device_get_parent(dev);
+	hostb = bhnd_find_hostb_device(parent);
 
 	for (entry = table; entry->desc != NULL; entry =
 	    (const struct bhnd_device *) ((const char *) entry + entry_size))
@@ -496,8 +500,8 @@ bhnd_device_lookup(device_t dev, const s
 			continue;
 
 		/* match device flags */
-		if (entry->device_flags & BHND_DF_HOSTB) {
-			if (!bhnd_is_hostb_device(dev))
+		if (entry->device_flags & BHND_DF_HOSTB) {			
+			if (dev != hostb)
 				continue;
 		}
 
@@ -738,24 +742,6 @@ bhnd_set_default_core_desc(device_t dev)
 }
 
 /**
- * Helper function for implementing BHND_BUS_IS_HOSTB_DEVICE().
- * 
- * If a parent device is available, this implementation delegates the
- * request to the BHND_BUS_IS_HOSTB_DEVICE() method on the parent of @p dev.
- * 
- * If no parent device is available (i.e. on a the bus root), false
- * is returned.
- */
-bool
-bhnd_bus_generic_is_hostb_device(device_t dev, device_t child) {
-	if (device_get_parent(dev) != NULL)
-		return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev),
-		    child));
-
-	return (false);
-}
-
-/**
  * Helper function for implementing BHND_BUS_IS_HW_DISABLED().
  * 
  * If a parent device is available, this implementation delegates the

Modified: head/sys/dev/bhnd/bhndb/bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bhndb/bhndb.c	Sun May  8 17:52:12 2016	(r299235)
@@ -589,18 +589,12 @@ bhndb_generic_init_full_config(device_t 
 	sc = device_get_softc(dev);
 	hostb = NULL;
 
-	/* Fetch the full set of attached devices */
+	/* Fetch the full set of bhnd-attached cores */
 	if ((error = device_get_children(sc->bus_dev, &devs, &ndevs)))
 		return (error);
 
 	/* Find our host bridge device */
-	for (int i = 0; i < ndevs; i++) {
-		if (bhnd_is_hostb_device(devs[i])) {
-			hostb = devs[i];
-			break;
-		}
-	}
-
+	hostb = BHNDB_FIND_HOSTB_DEVICE(dev, child);
 	if (hostb == NULL) {
 		device_printf(sc->dev, "no host bridge core found\n");
 		error = ENODEV;
@@ -950,13 +944,13 @@ bhndb_is_hw_disabled(device_t dev, devic
 	/* Otherwise, we treat bridge-capable cores as unpopulated if they're
 	 * not the configured host bridge */
 	if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(&core)))
-		return (!BHND_BUS_IS_HOSTB_DEVICE(dev, child));
+		return (BHNDB_FIND_HOSTB_DEVICE(dev, sc->bus_dev) != child);
 
 	/* Otherwise, assume the core is populated */
 	return (false);
 }
 
-/* ascending core index comparison used by bhndb_is_hostb_device() */ 
+/* ascending core index comparison used by bhndb_find_hostb_device() */ 
 static int
 compare_core_index(const void *lhs, const void *rhs)
 {
@@ -972,7 +966,7 @@ compare_core_index(const void *lhs, cons
 }
 
 /**
- * Default bhndb(4) implementation of BHND_BUS_IS_HOSTB_DEVICE().
+ * Default bhndb(4) implementation of BHND_BUS_FIND_HOSTB_DEVICE().
  * 
  * This function uses a heuristic valid on all known PCI/PCIe/PCMCIA-bridged
  * bhnd(4) devices to determine the hostb core:
@@ -982,27 +976,19 @@ compare_core_index(const void *lhs, cons
  * - The core must be the first device on the bus with the bridged device
  *   class.
  * 
- * @param sc The bridge device state.
- * @param cores The table of bridge-enumerated cores.
- * @param num_cores The length of @p cores.
- * @param core The core to check.
+ * @param dev The bhndb device
+ * @param child The requesting bhnd bus.
  */
-static bool
-bhndb_is_hostb_device(device_t dev, device_t child)
+static device_t
+bhndb_find_hostb_device(device_t dev, device_t child)
 {
 	struct bhndb_softc	*sc;
 	struct bhnd_core_match	 md;
 	device_t		 hostb_dev, *devlist;
 	int                      devcnt, error;
 
-	
 	sc = device_get_softc(dev);
 
-	/* Requestor must be attached to the bhnd bus */
-	if (device_get_parent(child) != sc->bus_dev)
-		return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev),
-		    child));
-
 	/* Determine required device class and set up a match descriptor. */
 	md = (struct bhnd_core_match) {
 		.vendor = BHND_MFGID_BCM,
@@ -1011,19 +997,15 @@ bhndb_is_hostb_device(device_t dev, devi
 		.class = sc->bridge_class,
 		.unit = 0
 	};
-
-	/* Pre-screen the device before searching over the full device list. */
-	if (!bhnd_device_matches(child, &md))
-		return (false);
 	
 	/* Must be the absolute first matching device on the bus. */
-	if ((error = device_get_children(sc->bus_dev, &devlist, &devcnt)))
+	if ((error = device_get_children(child, &devlist, &devcnt)))
 		return (false);
 
 	/* Sort by core index value, ascending */
 	qsort(devlist, devcnt, sizeof(*devlist), compare_core_index);
 
-	/* Find the actual hostb device */
+	/* Find the hostb device */
 	hostb_dev = NULL;
 	for (int i = 0; i < devcnt; i++) {
 		if (bhnd_device_matches(devlist[i], &md)) {
@@ -1035,7 +1017,7 @@ bhndb_is_hostb_device(device_t dev, devi
 	/* Clean up */
 	free(devlist, M_TEMP);
 
-	return (child == hostb_dev);
+	return (hostb_dev);
 }
 
 /**
@@ -1922,12 +1904,12 @@ static device_method_t bhndb_methods[] =
 	/* BHNDB interface */
 	DEVMETHOD(bhndb_get_chipid,		bhndb_get_chipid),
 	DEVMETHOD(bhndb_init_full_config,	bhndb_generic_init_full_config),
+	DEVMETHOD(bhndb_find_hostb_device,	bhndb_find_hostb_device),
 	DEVMETHOD(bhndb_suspend_resource,	bhndb_suspend_resource),
 	DEVMETHOD(bhndb_resume_resource,	bhndb_resume_resource),
 
 	/* BHND interface */
 	DEVMETHOD(bhnd_bus_is_hw_disabled,	bhndb_is_hw_disabled),
-	DEVMETHOD(bhnd_bus_is_hostb_device,	bhndb_is_hostb_device),
 	DEVMETHOD(bhnd_bus_get_chipid,		bhndb_get_chipid),
 	DEVMETHOD(bhnd_bus_activate_resource,	bhndb_activate_bhnd_resource),
 	DEVMETHOD(bhnd_bus_deactivate_resource,	bhndb_deactivate_bhnd_resource),

Modified: head/sys/dev/bhnd/bhndb/bhndb_if.m
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_if.m	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/bhndb/bhndb_if.m	Sun May  8 17:52:12 2016	(r299235)
@@ -62,6 +62,12 @@ CODE {
 		panic("bhndb_init_full_config unimplemented");
 	}
 	
+	static device_t
+	bhndb_null_find_hostb_device(device_t dev, device_t child)
+	{
+		panic("bhndb_find_hostb_device unimplemented");
+	}
+	
 	static void
 	bhndb_null_suspend_resource(device_t dev, device_t child, int type,
 	    struct resource *r)
@@ -120,6 +126,17 @@ METHOD int init_full_config {
 } DEFAULT bhndb_null_init_full_config;
 
 /**
+ * Locate the active host bridge core for the attached bhnd bus.
+ *
+ * @param dev The bridge device.
+ * @param child The bhnd bus device attached to @p dev.
+ */
+METHOD device_t find_hostb_device {
+	device_t dev;
+	device_t child;
+} DEFAULT bhndb_null_find_hostb_device;
+
+/**
  * Mark a resource as 'suspended', gauranteeing to the bridge that no
  * further use of the resource will be made until BHNDB_RESUME_RESOURCE()
  * is called.

Modified: head/sys/dev/bhnd/siba/siba.c
==============================================================================
--- head/sys/dev/bhnd/siba/siba.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/siba/siba.c	Sun May  8 17:52:12 2016	(r299235)
@@ -216,6 +216,15 @@ siba_get_resource_list(device_t dev, dev
 	return (&dinfo->resources);
 }
 
+static device_t
+siba_find_hostb_device(device_t dev)
+{
+	struct siba_softc *sc = device_get_softc(dev);
+
+	/* This is set (or not) by the concrete siba driver subclass. */
+	return (sc->hostb_dev);
+}
+
 static int
 siba_reset_core(device_t dev, device_t child, uint16_t flags)
 {
@@ -662,6 +671,7 @@ static device_method_t siba_methods[] = 
 	DEVMETHOD(bus_get_resource_list,	siba_get_resource_list),
 
 	/* BHND interface */
+	DEVMETHOD(bhnd_bus_find_hostb_device,	siba_find_hostb_device),
 	DEVMETHOD(bhnd_bus_reset_core,		siba_reset_core),
 	DEVMETHOD(bhnd_bus_suspend_core,	siba_suspend_core),
 	DEVMETHOD(bhnd_bus_get_port_count,	siba_get_port_count),

Modified: head/sys/dev/bhnd/siba/siba_bhndb.c
==============================================================================
--- head/sys/dev/bhnd/siba/siba_bhndb.c	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/siba/siba_bhndb.c	Sun May  8 17:52:12 2016	(r299235)
@@ -73,9 +73,12 @@ siba_bhndb_probe(device_t dev)
 static int
 siba_bhndb_attach(device_t dev)
 {
+	struct siba_softc		*sc;
 	const struct bhnd_chipid	*chipid;
 	int				 error;
 
+	sc = device_get_softc(dev);
+
 	/* Enumerate our children. */
 	chipid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
 	if ((error = siba_add_children(dev, chipid)))
@@ -87,6 +90,9 @@ siba_bhndb_attach(device_t dev)
 	if (error)
 		return (error);
 
+	/* Ask our parent bridge to find the corresponding bridge core */
+	sc->hostb_dev = BHNDB_FIND_HOSTB_DEVICE(device_get_parent(dev), dev);
+
 	/* Call our superclass' implementation */
 	return (siba_attach(dev));
 }

Modified: head/sys/dev/bhnd/siba/sibavar.h
==============================================================================
--- head/sys/dev/bhnd/siba/sibavar.h	Sun May  8 09:30:36 2016	(r299234)
+++ head/sys/dev/bhnd/siba/sibavar.h	Sun May  8 17:52:12 2016	(r299235)
@@ -145,6 +145,7 @@ struct siba_devinfo {
 /** siba(4) per-instance state */
 struct siba_softc {
 	struct bhnd_softc	bhnd_sc;	/**< bhnd state */
+	device_t		hostb_dev;	/**< host bridge core, or NULL */
 };
 
 #endif /* _SIBA_SIBAVAR_H_ */


More information about the svn-src-head mailing list