Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Sep 2016 01:43:55 +0000 (UTC)
From:      "Landon J. Fuller" <landonf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305374 - head/sys/dev/bhnd/bhndb
Message-ID:  <201609040143.u841htkf049147@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: landonf
Date: Sun Sep  4 01:43:54 2016
New Revision: 305374
URL: https://svnweb.freebsd.org/changeset/base/305374

Log:
  bhndb(4): Skip disabled cores when performing bridge configuration probing.
  
  On BCM4321 chipsets, both PCI and PCIe cores are included, with one of
  the cores potentially left floating.
  
  Since the PCI core appears first in the device table, and the PCI
  profiles appear first in the resource configuration tables, this resulted in
  incorrectly matching and using the PCI/v1 resource configuration on PCIe
  devices, rather than the correct PCIe/v1 profile.
  
  Approved by:	adrian (mentor, implicit)

Modified:
  head/sys/dev/bhnd/bhndb/bhnd_bhndb.c
  head/sys/dev/bhnd/bhndb/bhndb.c
  head/sys/dev/bhnd/bhndb/bhndb_if.m

Modified: head/sys/dev/bhnd/bhndb/bhnd_bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhnd_bhndb.c	Sun Sep  4 01:25:46 2016	(r305373)
+++ head/sys/dev/bhnd/bhndb/bhnd_bhndb.c	Sun Sep  4 01:43:54 2016	(r305374)
@@ -66,6 +66,17 @@ bhnd_bhndb_get_attach_type(device_t dev,
 	return (BHND_ATTACH_ADAPTER);
 }
 
+
+static bool
+bhnd_bhndb_is_hw_disabled(device_t dev, device_t child)
+{
+	struct bhnd_core_info core = bhnd_get_core_info(child);
+
+	/* Delegate to parent bridge */
+	return (BHNDB_IS_CORE_DISABLED(device_get_parent(dev), dev, &core));
+}
+
+
 static device_t
 bhnd_bhndb_find_hostb_device(device_t dev)
 {
@@ -112,6 +123,7 @@ bhnd_bhndb_pwrctl_ungate_clock(device_t 
 static device_method_t bhnd_bhndb_methods[] = {
 	/* BHND interface */
 	DEVMETHOD(bhnd_bus_get_attach_type,	bhnd_bhndb_get_attach_type),
+	DEVMETHOD(bhnd_bus_is_hw_disabled,	bhnd_bhndb_is_hw_disabled),
 	DEVMETHOD(bhnd_bus_find_hostb_device,	bhnd_bhndb_find_hostb_device),
 	DEVMETHOD(bhnd_bus_read_board_info,	bhnd_bhndb_read_board_info),
 

Modified: head/sys/dev/bhnd/bhndb/bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb.c	Sun Sep  4 01:25:46 2016	(r305373)
+++ head/sys/dev/bhnd/bhndb/bhndb.c	Sun Sep  4 01:43:54 2016	(r305374)
@@ -85,8 +85,9 @@ static int			 bhndb_init_full_config(str
 
 static struct bhnd_core_info	*bhndb_get_bridge_core(struct bhndb_softc *sc);
 
-static bool			 bhndb_hw_matches(struct bhnd_core_info *cores,
-				     u_int ncores, const struct bhndb_hw *hw);
+static bool			 bhndb_hw_matches(struct bhndb_softc *sc,
+				     struct bhnd_core_info *cores, u_int ncores,
+				     const struct bhndb_hw *hw);
 
 static int			 bhndb_init_region_cfg(struct bhndb_softc *sc,
 				     bhnd_erom_t *erom,
@@ -212,14 +213,15 @@ bhndb_get_bridge_core(struct bhndb_softc
 
 /**
  * Return true if @p cores matches the @p hw specification.
- * 
+ *
+ * @param sc BHNDB device state.
  * @param cores A device table to match against.
  * @param ncores The number of cores in @p cores.
  * @param hw The hardware description to be matched against.
  */
 static bool
-bhndb_hw_matches(struct bhnd_core_info *cores, u_int ncores,
-    const struct bhndb_hw *hw)
+bhndb_hw_matches(struct bhndb_softc *sc, struct bhnd_core_info *cores,
+    u_int ncores, const struct bhndb_hw *hw)
 {
 	for (u_int i = 0; i < hw->num_hw_reqs; i++) {
 		const struct bhnd_core_match	*match;
@@ -229,7 +231,12 @@ bhndb_hw_matches(struct bhnd_core_info *
 		found = false;
 
 		for (u_int d = 0; d < ncores; d++) {
-			if (!bhnd_core_matches(&cores[d], match))
+			struct bhnd_core_info *core = &cores[d];
+			
+			if (BHNDB_IS_CORE_DISABLED(sc->dev, sc->bus_dev, core))
+				continue;
+
+			if (!bhnd_core_matches(core, match))
 				continue;
 
 			found = true;
@@ -353,7 +360,7 @@ bhndb_init_region_cfg(struct bhndb_softc
 		 */
 		
 		/* ... do not require bridge resources */
-		if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, sc->dev, core))
+		if (BHNDB_IS_CORE_DISABLED(sc->dev, sc->bus_dev, core))
 			continue;
 
 		/* ... do not have a priority table entry */
@@ -475,7 +482,7 @@ bhndb_find_hwspec(struct bhndb_softc *sc
 	/* Search for the first matching hardware config. */
 	hw_table = BHNDB_BUS_GET_HARDWARE_TABLE(sc->parent_dev, sc->dev);
 	for (next = hw_table; next->hw_reqs != NULL; next++) {
-		if (!bhndb_hw_matches(cores, ncores, next))
+		if (!bhndb_hw_matches(sc, cores, ncores, next))
 			continue;
 
 		/* Found */
@@ -1166,30 +1173,27 @@ bhndb_get_chipid(device_t dev, device_t 
 	return (&sc->chipid);
 }
 
-
 /**
- * Default implementation of BHND_BUS_IS_HW_DISABLED().
+ * Default implementation of BHNDB_IS_CORE_DISABLED().
  */
 static bool
-bhndb_is_hw_disabled(device_t dev, device_t child)
+bhndb_is_core_disabled(device_t dev, device_t child,
+    struct bhnd_core_info *core)
 {
 	struct bhndb_softc	*sc;
 	struct bhnd_core_info	*bridge_core;
-	struct bhnd_core_info	 core;
 
 	sc = device_get_softc(dev);
 
-	core = bhnd_get_core_info(child);
-
 	/* Try to defer to the bhndb bus parent */
-	if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, &core))
+	if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, core))
 		return (true);
 
 	/* Otherwise, we treat bridge-capable cores as unpopulated if they're
 	 * not the configured host bridge */
 	bridge_core = bhndb_get_bridge_core(sc);
-	if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(&core)))
-		return (!bhnd_cores_equal(&core, bridge_core));
+	if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(core)))
+		return (!bhnd_cores_equal(core, bridge_core));
 
 	/* Assume the core is populated */
 	return (false);
@@ -2153,12 +2157,12 @@ static device_method_t bhndb_methods[] =
 
 	/* BHNDB interface */
 	DEVMETHOD(bhndb_get_chipid,		bhndb_get_chipid),
+	DEVMETHOD(bhndb_is_core_disabled,	bhndb_is_core_disabled),
 	DEVMETHOD(bhndb_get_hostb_core,		bhndb_get_hostb_core),
 	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_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 Sep  4 01:25:46 2016	(r305373)
+++ head/sys/dev/bhnd/bhndb/bhndb_if.m	Sun Sep  4 01:43:54 2016	(r305374)
@@ -61,7 +61,14 @@ CODE {
 	{
 		panic("bhndb_populate_board_info unimplemented");
 	}
-	
+
+	static int
+	bhndb_null_is_core_disabled(device_t dev, device_t child,
+	    struct bhnd_core_info *core)
+	{
+		panic("bhndb_is_core_disabled unimplemented");
+	}
+
 	static int
 	bhndb_null_get_hostb_core(device_t dev, device_t child,
 	    struct bhnd_core_info *core)
@@ -118,6 +125,24 @@ METHOD int populate_board_info {
 } DEFAULT bhndb_null_populate_board_info;
 
 /**
+ * Return true if the hardware required by @p core is unpopulated or
+ * otherwise unusable.
+ *
+ * In some cases, the core's pins may be left floating, or the hardware
+ * may otherwise be non-functional; this method allows the parent device
+ * to explicitly specify whether @p core should be disabled.
+ *
+ * @param dev The parent device of @p child.
+ * @param child The attached bhnd device.
+ * @param core A core discovered on @p child.
+ */
+METHOD bool is_core_disabled {
+	device_t dev;
+	device_t child;
+	struct bhnd_core_info *core;
+} DEFAULT bhndb_null_is_core_disabled;
+
+/**
  * Get the host bridge core info for the attached bhnd bus.
  *
  * @param	dev	The bridge device.



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