Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Sep 2016 00:58:19 +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: r305371 - in head/sys: dev/bhnd dev/bhnd/bcma dev/bhnd/bhndb dev/bhnd/cores/chipc dev/bhnd/siba dev/bwn mips/broadcom modules/bhnd/bhndb
Message-ID:  <201609040058.u840wJVs030864@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: landonf
Date: Sun Sep  4 00:58:19 2016
New Revision: 305371
URL: https://svnweb.freebsd.org/changeset/base/305371

Log:
  Migrate bhndb(4) to the new bhnd_erom API.
  
  Adds support for probing and initializing bhndb(4) bridge state using
  the bhnd_erom API, ensuring that full bridge configuration is available
  *prior* to actually attaching and enumerating the bhnd(4) child device,
  allowing us to safely allocate bus-level agent/device resources during
  bhnd(4) bus enumeration.
  
  - Add a bhnd_erom_probe() method usable by bhndb(4). This is an analogue
    to the existing bhnd_erom_probe_static() method, and allows the bhndb
    bridge to discover the best available erom parser class prior to newbus
    probing of its children.
  - Add support for supplying identification hints when probing erom
    devices. This is required on early EXTIF-only chipsets, where chip
    identification registers are not available.
  - Migrate bhndb over to the new bhnd_erom API, using bhnd_core_info
    records rather than bridged bhnd(4) device_t references to determine
    the bridged chipsets' capability/bridge configuration.
  - The bhndb parent (e.g. if_bwn) is now required to supply a hardware
    priority table to the bridge. The default table is currently sufficient
    for our supported devices.
  - Drop the two-pass attach approach we used for compatibility with bhndb(4) in
    the bhnd(4) bus drivers, and instead perform bus enumeration immediately,
    and allocate bridged per-child bus-level resources during that enumeration.
  
  Approved by:	adrian (mentor)
  Differential Revision:	https://reviews.freebsd.org/D7768

Modified:
  head/sys/dev/bhnd/bcma/bcma.c
  head/sys/dev/bhnd/bcma/bcma_bhndb.c
  head/sys/dev/bhnd/bcma/bcma_erom.c
  head/sys/dev/bhnd/bcma/bcma_eromvar.h
  head/sys/dev/bhnd/bcma/bcma_nexus.c
  head/sys/dev/bhnd/bcma/bcma_subr.c
  head/sys/dev/bhnd/bcma/bcmavar.h
  head/sys/dev/bhnd/bhnd.h
  head/sys/dev/bhnd/bhnd_bus_if.m
  head/sys/dev/bhnd/bhnd_erom.c
  head/sys/dev/bhnd/bhnd_erom.h
  head/sys/dev/bhnd/bhnd_erom_if.m
  head/sys/dev/bhnd/bhnd_match.h
  head/sys/dev/bhnd/bhnd_nexus.c
  head/sys/dev/bhnd/bhnd_subr.c
  head/sys/dev/bhnd/bhndb/bhnd_bhndb.c
  head/sys/dev/bhnd/bhndb/bhndb.c
  head/sys/dev/bhnd/bhndb/bhndb_bus_if.m
  head/sys/dev/bhnd/bhndb/bhndb_if.m
  head/sys/dev/bhnd/bhndb/bhndb_pci.c
  head/sys/dev/bhnd/bhndb/bhndb_private.h
  head/sys/dev/bhnd/bhndb/bhndb_subr.c
  head/sys/dev/bhnd/bhndb/bhndbvar.h
  head/sys/dev/bhnd/cores/chipc/chipcreg.h
  head/sys/dev/bhnd/siba/siba.c
  head/sys/dev/bhnd/siba/siba_bhndb.c
  head/sys/dev/bhnd/siba/siba_erom.c
  head/sys/dev/bhnd/siba/siba_nexus.c
  head/sys/dev/bhnd/siba/sibavar.h
  head/sys/dev/bwn/if_bwn_pci.c
  head/sys/dev/bwn/if_bwn_pcivar.h
  head/sys/mips/broadcom/bcm_machdep.c
  head/sys/modules/bhnd/bhndb/Makefile

Modified: head/sys/dev/bhnd/bcma/bcma.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma.c	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcma.c	Sun Sep  4 00:58:19 2016	(r305371)
@@ -48,6 +48,12 @@ __FBSDID("$FreeBSD$");
 /* RID used when allocating EROM table */
 #define	BCMA_EROM_RID	0
 
+static bhnd_erom_class_t *
+bcma_get_erom_class(driver_t *driver)
+{
+	return (&bcma_erom_parser);
+}
+
 int
 bcma_probe(device_t dev)
 {
@@ -55,70 +61,25 @@ bcma_probe(device_t dev)
 	return (BUS_PROBE_DEFAULT);
 }
 
+/**
+ * Default bcma(4) bus driver implementation of DEVICE_ATTACH().
+ * 
+ * This implementation initializes internal bcma(4) state and performs
+ * bus enumeration, and must be called by subclassing drivers in
+ * DEVICE_ATTACH() before any other bus methods.
+ */
 int
 bcma_attach(device_t dev)
 {
-	struct bcma_devinfo	*dinfo;
-	device_t		*devs, child;
-	int			 ndevs;
-	int			 error;
+	int error;
 
-
-	if ((error = device_get_children(dev, &devs, &ndevs)))
+	/* Enumerate children */
+	if ((error = bcma_add_children(dev))) {
+		device_delete_children(dev);
 		return (error);
-
-	/*
-	 * Map our children's agent register block.
-	 */
-	for (int i = 0; i < ndevs; i++) {
-		bhnd_addr_t	addr;
-		bhnd_size_t	size;
-		rman_res_t	r_start, r_count, r_end;
-
-		child = devs[i];
-		dinfo = device_get_ivars(child);
-
-		KASSERT(!device_is_suspended(child),
-		    ("bcma(4) stateful suspend handling requires that devices "
-		        "not be suspended before bcma_attach()"));
-		
-		/* Verify that the agent register block exists and is
-		 * mappable */
-		if (bhnd_get_port_rid(child, BHND_PORT_AGENT, 0, 0) == -1)
-			continue;
-
-		/* Fetch the address of the agent register block */
-		error = bhnd_get_region_addr(child, BHND_PORT_AGENT, 0, 0,
-		    &addr, &size);
-		if (error) {
-			device_printf(dev, "failed fetching agent register "
-			    "block address for core %d\n", i);
-			goto cleanup;
-		}
-
-		/* Allocate the resource */
-		r_start = addr;
-		r_count = size;
-		r_end = r_start + r_count - 1;
-
-		dinfo->rid_agent = i + 1;
-		dinfo->res_agent = BHND_BUS_ALLOC_RESOURCE(dev, dev,
-		    SYS_RES_MEMORY, &dinfo->rid_agent, r_start, r_end, r_count,
-		    RF_ACTIVE);
-		if (dinfo->res_agent == NULL) {
-			device_printf(dev, "failed allocating agent register "
-			    "block for core %d\n", i);
-			error = ENXIO;
-			goto cleanup;
-		}
 	}
 
-cleanup:
-	free(devs, M_BHND);
-	if (error)
-		return (error);
-	
-	return (bhnd_generic_attach(dev));
+	return (0);
 }
 
 int
@@ -191,15 +152,6 @@ 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)
 {
@@ -516,8 +468,7 @@ bcma_add_children(device_t bus)
 	corecfg = NULL;
 
 	/* Allocate our EROM parser */
-	erom = bhnd_erom_alloc(&bcma_erom_parser, bus, BCMA_EROM_RID,
-	    cid->enum_addr);
+	erom = bhnd_erom_alloc(&bcma_erom_parser, cid, bus, BCMA_EROM_RID);
 	if (erom == NULL)
 		return (ENODEV);
 
@@ -528,17 +479,21 @@ bcma_add_children(device_t bus)
 		child = BUS_ADD_CHILD(bus, 0, NULL, -1);
 		if (child == NULL) {
 			error = ENXIO;
-			goto failed;
+			goto cleanup;
 		}
 
 		/* Initialize device ivars */
 		dinfo = device_get_ivars(child);
 		if ((error = bcma_init_dinfo(bus, dinfo, corecfg)))
-			goto failed;
+			goto cleanup;
 
 		/* The dinfo instance now owns the corecfg value */
 		corecfg = NULL;
 
+		/* Allocate device's agent registers, if any */
+		if ((error = bcma_dinfo_alloc_agent(bus, child, dinfo)))
+			goto cleanup;
+
 		/* If pins are floating or the hardware is otherwise
 		 * unpopulated, the device shouldn't be used. */
 		if (bhnd_is_hw_disabled(child))
@@ -548,16 +503,19 @@ bcma_add_children(device_t bus)
 		BHND_BUS_CHILD_ADDED(bus, child);
 	}
 
-	/* Hit EOF parsing cores? */
+	/* EOF while parsing cores is expected */
 	if (error == ENOENT)
 		error = 0;
 	
-failed:
+cleanup:
 	bhnd_erom_free(erom);
 
 	if (corecfg != NULL)
 		bcma_free_corecfg(corecfg);
 
+	if (error)
+		device_delete_children(bus);
+
 	return (error);
 }
 
@@ -574,7 +532,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_get_erom_class,	bcma_get_erom_class),
 	DEVMETHOD(bhnd_bus_alloc_devinfo,	bcma_alloc_bhnd_dinfo),
 	DEVMETHOD(bhnd_bus_free_devinfo,	bcma_free_bhnd_dinfo),
 	DEVMETHOD(bhnd_bus_reset_core,		bcma_reset_core),

Modified: head/sys/dev/bhnd/bcma/bcma_bhndb.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_bhndb.c	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcma_bhndb.c	Sun Sep  4 00:58:19 2016	(r305371)
@@ -72,26 +72,21 @@ bcma_bhndb_probe(device_t dev)
 static int
 bcma_bhndb_attach(device_t dev)
 {
-	struct bcma_softc		*sc;
-	int				 error;
+	int error;
 
-	sc = device_get_softc(dev);
+	/* Perform initial attach and enumerate our children. */
+	if ((error = bcma_attach(dev)))
+		goto failed;
+
+	/* Delegate remainder to standard bhnd method implementation */
+	if ((error = bhnd_generic_attach(dev)))
+		goto failed;
 
-	/* Enumerate our children. */
-	if ((error = bcma_add_children(dev)))
-		return (error);
-
-	/* Initialize full bridge configuration */
-	error = BHNDB_INIT_FULL_CONFIG(device_get_parent(dev), dev,
-	    bhndb_bcma_priority_table);
-	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);
+	return (0);
 
-	/* Call our superclass' implementation */
-	return (bcma_attach(dev));
+failed:
+	device_delete_children(dev);
+	return (error);
 }
 
 static int

Modified: head/sys/dev/bhnd/bcma/bcma_erom.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_erom.c	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcma_erom.c	Sun Sep  4 00:58:19 2016	(r305371)
@@ -58,7 +58,13 @@ __FBSDID("$FreeBSD$");
  * marker.
  */
 
+struct bcma_erom_io;
+
 static const char	*bcma_erom_entry_type_name (uint8_t entry);
+
+static uint32_t		 bcma_eio_read4(struct bcma_erom_io *io,
+			     bus_size_t offset);
+
 static int		 bcma_erom_read32(struct bcma_erom *erom,
 			     uint32_t *entry);
 static int		 bcma_erom_skip32(struct bcma_erom *erom);
@@ -72,8 +78,10 @@ static int		 bcma_erom_seek_next(struct 
 static int		 bcma_erom_region_to_port_type(struct bcma_erom *erom,
 			     uint8_t region_type, bhnd_port_type *port_type);
 
+
 static int		 bcma_erom_peek32(struct bcma_erom *erom,
 			     uint32_t *entry);
+
 static bus_size_t	 bcma_erom_tell(struct bcma_erom *erom);
 static void		 bcma_erom_seek(struct bcma_erom *erom,
 			     bus_size_t offset);
@@ -96,9 +104,33 @@ static void		 bcma_erom_to_core_info(con
 			     u_int core_idx, int core_unit,
 			     struct bhnd_core_info *info);
 
+/**
+ * BCMA EROM generic I/O context
+ */
+struct bcma_erom_io {
+	struct bhnd_resource	*res;		/**< memory resource, or NULL if initialized
+						     with bus space tag and handle */
+	int			 rid;		/**< memory resource id, or -1 */
+
+	bus_space_tag_t		 bst;		/**< bus space tag, if any */
+	bus_space_handle_t	 bsh;		/**< bus space handle, if any */
+
+	bus_size_t	 	 start;		/**< base read offset */
+};
+
+/**
+ * BCMA EROM per-instance state.
+ */
+struct bcma_erom {
+	struct bhnd_erom	obj;
+	device_t	 	dev;	/**< parent device, or NULL if none. */
+	struct bcma_erom_io	io;	/**< I/O context */
+	bus_size_t	 	offset;	/**< current read offset */
+};
+
 #define	EROM_LOG(erom, fmt, ...)	do {				\
 	if (erom->dev != NULL) {					\
-		device_printf(erom->dev, "erom[0x%llx]: " fmt,		\
+		device_printf(erom->dev, "erom[0x%llx]: " fmt,	\
 		    (unsigned long long) (erom->offset), ##__VA_ARGS__);\
 	} else {							\
 		printf("erom[0x%llx]: " fmt,				\
@@ -106,7 +138,6 @@ static void		 bcma_erom_to_core_info(con
 	}								\
 } while(0)
 
-
 /** Return the type name for an EROM entry */
 static const char *
 bcma_erom_entry_type_name (uint8_t entry)
@@ -123,47 +154,112 @@ bcma_erom_entry_type_name (uint8_t entry
 	}
 }
 
+
+/**
+ * Read a 32-bit value from an EROM I/O context.
+ * 
+ * @param io EROM I/O context.
+ * @param offset Read offset.
+ */
+static uint32_t
+bcma_eio_read4(struct bcma_erom_io *io, bus_size_t offset)
+{
+	bus_size_t read_off;
+
+	read_off = io->start + offset;
+	if (io->res != NULL)
+		return (bhnd_bus_read_4(io->res, read_off));
+	else
+		return (bus_space_read_4(io->bst, io->bsh, read_off));
+}
+
+/* Initialize bcma_erom resource I/O context */
+static void
+bcma_eio_init(struct bcma_erom_io *io, struct bhnd_resource *res, int rid,
+    bus_size_t offset)
+{
+	io->res = res;
+	io->rid = rid;
+	io->start = offset;
+}
+
+/* Initialize bcma_erom bus space I/O context */
+static void
+bcma_eio_init_static(struct bcma_erom_io *io, bus_space_tag_t bst,
+    bus_space_handle_t bsh, bus_size_t offset)
+{
+	io->res = NULL;
+	io->rid = -1;
+	io->bst = bst;
+	io->bsh = bsh;
+	io->start = offset;
+}
+
+/* BCMA implementation of BHND_EROM_INIT() */
 static int
-bcma_erom_init(bhnd_erom_t *erom, device_t parent, int rid, bus_addr_t enum_addr)
+bcma_erom_init(bhnd_erom_t *erom, const struct bhnd_chipid *cid,
+    device_t parent, int rid)
 {
-	struct bcma_erom *sc = (struct bcma_erom *)erom;
+	struct bcma_erom	*sc;
+	struct bhnd_resource	*res;
 
+	sc = (struct bcma_erom *)erom;
 	sc->dev = parent;
+	sc->offset = 0;
+
+	res = bhnd_alloc_resource(parent, SYS_RES_MEMORY, &rid, cid->enum_addr,
+	    cid->enum_addr + BCMA_EROM_TABLE_SIZE - 1, BCMA_EROM_TABLE_SIZE,
+	    RF_ACTIVE|RF_SHAREABLE);
 
-	sc->rid = rid;
-	sc->res = bhnd_alloc_resource(parent, SYS_RES_MEMORY, &sc->rid,
-	    enum_addr, enum_addr + BCMA_EROM_TABLE_SIZE - 1,
-	    BCMA_EROM_TABLE_SIZE, RF_ACTIVE|RF_SHAREABLE);
-	if (sc->res == NULL)
+	if (res == NULL)
 		return (ENOMEM);
-	
-	sc->start = BCMA_EROM_TABLE_START;
+
+	bcma_eio_init(&sc->io, res, rid, BCMA_EROM_TABLE_START);
+
+	return (0);
+}
+
+/* BCMA implementation of BHND_EROM_INIT_STATIC() */
+static int
+bcma_erom_init_static(bhnd_erom_t *erom, const struct bhnd_chipid *cid,
+    bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+	struct bcma_erom	*sc;
+
+	sc = (struct bcma_erom *)erom;
+	sc->dev = NULL;
 	sc->offset = 0;
 
+	bcma_eio_init_static(&sc->io, bst, bsh, BCMA_EROM_TABLE_START);
+
 	return (0);
 }
 
+/* Common implementation of BHND_EROM_PROBE/BHND_EROM_PROBE_STATIC */
 static int
-bcma_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst,
-     bus_space_handle_t bsh, bus_addr_t paddr, struct bhnd_chipid *cid)
+bcma_erom_probe_common(struct bcma_erom_io *io, const struct bhnd_chipid *hint,
+    struct bhnd_chipid *cid)
 {
-	uint32_t	idreg, eaddr;
-	uint8_t		chip_type;
+	uint32_t	idreg, eromptr;
 
-	idreg = bus_space_read_4(bst, bsh, CHIPC_ID);
-	chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS);
+	/* Hints aren't supported; all BCMA devices have a ChipCommon
+	 * core */
+	if (hint != NULL)
+		return (EINVAL);
 
-	/* Fetch EROM physical address */
-	if (!BHND_CHIPTYPE_HAS_EROM(chip_type))
+	/* Confirm CHIPC_EROMPTR availability */
+	idreg = bcma_eio_read4(io, CHIPC_ID);
+	if (!BHND_CHIPTYPE_HAS_EROM(CHIPC_GET_BITS(idreg, CHIPC_ID_BUS)))
 		return (ENXIO);
 
-	eaddr = bus_space_read_4(bst, bsh, CHIPC_EROMPTR);
+	/* Fetch EROM address */
+	eromptr = bcma_eio_read4(io, CHIPC_EROMPTR);
 
 	/* Parse chip identifier */
-	*cid = bhnd_parse_chipid(idreg, eaddr);
+	*cid = bhnd_parse_chipid(idreg, eromptr);
 
 	/* Verify chip type */
-	switch (chip_type) {
+	switch (cid->chip_type) {
 		case BHND_CHIPTYPE_BCMA:
 			return (BUS_PROBE_DEFAULT);
 
@@ -173,37 +269,44 @@ bcma_erom_probe_static(bhnd_erom_class_t
 
 		default:
 			return (ENXIO);
-	}
+	}	
 }
 
 static int
-bcma_erom_init_static(bhnd_erom_t *erom, bus_space_tag_t bst,
-     bus_space_handle_t bsh)
+bcma_erom_probe(bhnd_erom_class_t *cls, struct bhnd_resource *res,
+    bus_size_t offset, const struct bhnd_chipid *hint, struct bhnd_chipid *cid)
 {
-	struct bcma_erom *sc = (struct bcma_erom *)erom;
+	struct bcma_erom_io io;
 
-	sc->dev = NULL;
-	sc->rid = -1;
-	sc->res = NULL;
-	sc->bst = bst;
-	sc->bsh = bsh;
-	sc->start = BCMA_EROM_TABLE_START;
-	sc->offset = 0;
+	bcma_eio_init(&io, res, rman_get_rid(res->res),
+	    offset + BCMA_EROM_TABLE_START);
 
-	return (0);
+	return (bcma_erom_probe_common(&io, hint, cid));
 }
 
+static int
+bcma_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst,
+     bus_space_handle_t bsh, bus_addr_t paddr, const struct bhnd_chipid *hint,
+     struct bhnd_chipid *cid)
+{
+	struct bcma_erom_io io;
+
+	bcma_eio_init_static(&io, bst, bsh, BCMA_EROM_TABLE_START);
+	return (bcma_erom_probe_common(&io, hint, cid));
+}
+
+
 static void
 bcma_erom_fini(bhnd_erom_t *erom)
 {
 	struct bcma_erom *sc = (struct bcma_erom *)erom;
 
-	if (sc->res != NULL) {
-		bhnd_release_resource(sc->dev, SYS_RES_MEMORY, sc->rid,
-		    sc->res);
+	if (sc->io.res != NULL) {
+		bhnd_release_resource(sc->dev, SYS_RES_MEMORY, sc->io.rid,
+		    sc->io.res);
 
-		sc->res = NULL;
-		sc->rid = -1;
+		sc->io.res = NULL;
+		sc->io.rid = -1;
 	}
 }
 
@@ -484,19 +587,12 @@ bcma_erom_seek(struct bcma_erom *erom, b
 static int
 bcma_erom_peek32(struct bcma_erom *erom, uint32_t *entry)
 {
-	bus_size_t off;
-
-	if (erom->offset >= BCMA_EROM_TABLE_SIZE) {
+	if (erom->offset >= (BCMA_EROM_TABLE_SIZE - sizeof(uint32_t))) {
 		EROM_LOG(erom, "BCMA EROM table missing terminating EOF\n");
 		return (EINVAL);
 	}
-
-	off = erom->start + erom->offset;
-	if (erom->res != NULL)
-		*entry = bhnd_bus_read_4(erom->res, off);
-	else
-		*entry = bus_space_read_4(erom->bst, erom->bsh, off);
-
+	
+	*entry = bcma_eio_read4(&erom->io, erom->offset);
 	return (0);
 }
 
@@ -1259,6 +1355,7 @@ failed:
 }
 
 static kobj_method_t bcma_erom_methods[] = {
+	KOBJMETHOD(bhnd_erom_probe,		bcma_erom_probe),
 	KOBJMETHOD(bhnd_erom_probe_static,	bcma_erom_probe_static),
 	KOBJMETHOD(bhnd_erom_init,		bcma_erom_init),
 	KOBJMETHOD(bhnd_erom_init_static,	bcma_erom_init_static),

Modified: head/sys/dev/bhnd/bcma/bcma_eromvar.h
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_eromvar.h	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcma_eromvar.h	Sun Sep  4 00:58:19 2016	(r305371)
@@ -42,25 +42,6 @@ struct bcma_erom;
 int	bcma_erom_next_corecfg(struct bcma_erom *sc,
 	    struct bcma_corecfg **result);
 
-/**
- * BCMA EROM per-instance state.
- */
-struct bcma_erom {
-	struct bhnd_erom	 obj;
-	device_t	 	 dev;		/**< EROM parent device, or NULL
-						     if none. */
-	struct bhnd_resource	*res;		/**< EROM table resource, or
-						     NULL if initialized with
-						     bus space tag and handle */
-	int			 rid;		/**< EROM table rid, or -1 */
-
-	bus_space_tag_t		 bst;		/**< EROM table bus space */
-	bus_space_handle_t	 bsh;		/**< EROM table bus handle */
-
-	bus_size_t	 	 start;		/**< EROM table offset */
-	bus_size_t	 	 offset;	/**< current read offset */
-};
-
 /** EROM core descriptor. */
 struct bcma_erom_core {
 	uint16_t	vendor;		/**< core's designer */

Modified: head/sys/dev/bhnd/bcma/bcma_nexus.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_nexus.c	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcma_nexus.c	Sun Sep  4 00:58:19 2016	(r305371)
@@ -93,10 +93,19 @@ bcma_nexus_attach(device_t dev)
 {
 	int error;
 
-	if ((error = bcma_add_children(dev)))
-		return (error);
-
-	return (bcma_attach(dev));
+	/* Perform initial attach and enumerate our children. */
+	if ((error = bcma_attach(dev)))
+		goto failed;
+
+	/* Delegate remainder to standard bhnd method implementation */
+	if ((error = bhnd_generic_attach(dev)))
+		goto failed;
+
+	return (0);
+
+failed:
+	device_delete_children(dev);
+	return (error);
 }
 
 static const struct bhnd_chipid *

Modified: head/sys/dev/bhnd/bcma/bcma_subr.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_subr.c	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcma_subr.c	Sun Sep  4 00:58:19 2016	(r305371)
@@ -43,6 +43,10 @@ __FBSDID("$FreeBSD$");
 
 #include "bcmavar.h"
 
+/* Return the resource ID for a device's agent register allocation */
+#define	BCMA_AGENT_RID(_dinfo)	\
+    (BCMA_AGENT_RID_BASE + BCMA_DINFO_COREIDX(_dinfo))
+
  /**
  * Allocate and initialize new core config structure.
  * 
@@ -244,6 +248,63 @@ bcma_init_dinfo(device_t bus, struct bcm
 	return (0);
 }
 
+
+/**
+ * Allocate the per-core agent register block for a device info structure
+ * previous initialized via bcma_init_dinfo().
+ * 
+ * If an agent0.0 region is not defined on @p dinfo, the device info
+ * agent resource is set to NULL and 0 is returned.
+ * 
+ * @param bus The requesting bus device.
+ * @param child The bcma child device.
+ * @param dinfo The device info associated with @p child
+ * 
+ * @retval 0 success
+ * @retval non-zero resource allocation failed.
+ */
+int
+bcma_dinfo_alloc_agent(device_t bus, device_t child, struct bcma_devinfo *dinfo)
+{
+	bhnd_addr_t	addr;
+	bhnd_size_t	size;
+	rman_res_t	r_start, r_count, r_end;
+	int		error;
+
+	KASSERT(dinfo->res_agent == NULL, ("double allocation of agent"));
+	
+	/* Verify that the agent register block exists and is
+	 * mappable */
+	if (bhnd_get_port_rid(child, BHND_PORT_AGENT, 0, 0) == -1)
+		return (0);	/* nothing to do */
+
+	/* Fetch the address of the agent register block */
+	error = bhnd_get_region_addr(child, BHND_PORT_AGENT, 0, 0,
+	    &addr, &size);
+	if (error) {
+		device_printf(bus, "failed fetching agent register block "
+		    "address for core %u\n", BCMA_DINFO_COREIDX(dinfo));
+		return (error);
+	}
+
+	/* Allocate the resource */
+	r_start = addr;
+	r_count = size;
+	r_end = r_start + r_count - 1;
+
+	dinfo->rid_agent = BCMA_AGENT_RID(dinfo);
+	dinfo->res_agent = BHND_BUS_ALLOC_RESOURCE(bus, bus, SYS_RES_MEMORY,
+	    &dinfo->rid_agent, r_start, r_end, r_count, RF_ACTIVE);
+	if (dinfo->res_agent == NULL) {
+		device_printf(bus, "failed allocating agent register block for "
+		    "core %u\n", BCMA_DINFO_COREIDX(dinfo));
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+
 /**
  * Deallocate the given device info structure and any associated resources.
  * 

Modified: head/sys/dev/bhnd/bcma/bcmavar.h
==============================================================================
--- head/sys/dev/bhnd/bcma/bcmavar.h	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bcma/bcmavar.h	Sun Sep  4 00:58:19 2016	(r305371)
@@ -45,6 +45,18 @@
  * Internal definitions shared by bcma(4) driver implementations.
  */
 
+/** Base resource ID for per-core agent register allocations */
+#define	BCMA_AGENT_RID_BASE	100
+
+/**
+ * Return the device's core index.
+ * 
+ * @param _dinfo The bcma_devinfo instance to query.
+ */
+#define	BCMA_DINFO_COREIDX(_dinfo)	\
+	((_dinfo)->corecfg->core_info.core_idx)
+
+
 /** BCMA port identifier. */
 typedef u_int		bcma_pid_t;
 #define BCMA_PID_MAX	UINT_MAX	/**< Maximum bcma_pid_t value */
@@ -72,6 +84,8 @@ struct bcma_devinfo	*bcma_alloc_dinfo(de
 int			 bcma_init_dinfo(device_t bus,
 			     struct bcma_devinfo *dinfo,
 			     struct bcma_corecfg *corecfg);
+int			 bcma_dinfo_alloc_agent(device_t bus, device_t child,
+			     struct bcma_devinfo *dinfo);
 void			 bcma_free_dinfo(device_t bus,
 			     struct bcma_devinfo *dinfo);
 
@@ -147,7 +161,6 @@ 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_ */

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bhnd.h	Sun Sep  4 00:58:19 2016	(r305371)
@@ -39,6 +39,7 @@
 
 #include "bhnd_ids.h"
 #include "bhnd_types.h"
+#include "bhnd_erom_types.h"
 #include "bhnd_debug.h"
 #include "bhnd_bus_if.h"
 #include "bhnd_match.h"
@@ -188,6 +189,12 @@ struct bhnd_resource {
 					 *   is MMIO accessible. */
 };
 
+/** Wrap the active resource @p _r in a bhnd_resource structure */
+#define	BHND_DIRECT_RESOURCE(_r)	((struct bhnd_resource) {	\
+	.res = (_r),							\
+	.direct = true,							\
+})
+
 /**
  * Device quirk table descriptor.
  */
@@ -278,6 +285,13 @@ const struct bhnd_core_info	*bhnd_find_c
 				     const struct bhnd_core_info *cores,
 				     u_int num_cores, bhnd_devclass_t class);
 
+struct bhnd_core_match		 bhnd_core_get_match_desc(
+				     const struct bhnd_core_info *core);
+
+bool				 bhnd_cores_equal(
+				     const struct bhnd_core_info *lhs,
+				     const struct bhnd_core_info *rhs);
+
 bool				 bhnd_core_matches(
 				     const struct bhnd_core_info *core,
 				     const struct bhnd_core_match *desc);
@@ -389,7 +403,16 @@ int				 bhnd_bus_generic_deactivate_reso
 bhnd_attach_type		 bhnd_bus_generic_get_attach_type(device_t dev,
 				     device_t child);
 
-
+/**
+ * Return the bhnd(4) bus driver's device enumeration parser class
+ *
+ * @param driver A bhnd bus driver instance.
+ */
+static inline bhnd_erom_class_t *
+bhnd_driver_get_erom_class(driver_t *driver)
+{
+	return (BHND_BUS_GET_EROM_CLASS(driver));
+}
 
 /**
  * Return the active host bridge core for the bhnd bus, if any, or NULL if

Modified: head/sys/dev/bhnd/bhnd_bus_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bhnd_bus_if.m	Sun Sep  4 00:58:19 2016	(r305371)
@@ -29,6 +29,7 @@
 #include <sys/rman.h>
 
 #include <dev/bhnd/bhnd_types.h>
+#include <dev/bhnd/bhnd_erom_types.h>
 
 INTERFACE bhnd_bus;
 
@@ -49,7 +50,13 @@ CODE {
 	#include <sys/systm.h>
 
 	#include <dev/bhnd/bhndvar.h>
-	
+
+	static bhnd_erom_class_t *
+	bhnd_bus_null_get_erom_class(driver_t *driver)
+	{
+		return (NULL);
+	}
+
 	static struct bhnd_chipid *
 	bhnd_bus_null_get_chipid(device_t dev, device_t child)
 	{
@@ -152,7 +159,7 @@ CODE {
 	static device_t
 	bhnd_bus_null_find_hostb_device(device_t dev)
 	{
-		panic("bhnd_bus_find_hostb_device unimplemented");
+		return (NULL);
 	}
 
 	static bool
@@ -199,6 +206,15 @@ CODE {
 }
 
 /**
+ * Return the bhnd(4) bus driver's device enumeration parser class.
+ *
+ * @param driver	The bhnd bus driver instance.
+ */
+STATICMETHOD bhnd_erom_class_t * get_erom_class {
+	driver_t			*driver;
+} DEFAULT bhnd_bus_null_get_erom_class;
+
+/**
  * Return the active host bridge core for the bhnd bus, if any.
  *
  * @param dev The bhnd bus device.

Modified: head/sys/dev/bhnd/bhnd_erom.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_erom.c	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bhnd_erom.c	Sun Sep  4 00:58:19 2016	(r305371)
@@ -45,15 +45,15 @@ __FBSDID("$FreeBSD$");
  *			be allocated.
  * @param rid		The resource ID to be used when allocating EROM
  *			resources.
- * @param enum_addr	The base address of the device enumeration table.
+ * @param cid		The device's chip identifier.
  *
  * @retval non-NULL	success
  * @retval NULL		if an error occured allocating or initializing the
  *			EROM parser.
  */
 bhnd_erom_t *
-bhnd_erom_alloc(bhnd_erom_class_t *cls, device_t parent, int rid,
-    bus_addr_t enum_addr)
+bhnd_erom_alloc(bhnd_erom_class_t *cls, const struct bhnd_chipid *cid,
+    device_t parent, int rid)
 {
 	bhnd_erom_t	*erom;
 	int		 error;
@@ -61,9 +61,9 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, 
 	erom = (bhnd_erom_t *)kobj_create((kobj_class_t)cls, M_BHND,
 	    M_WAITOK|M_ZERO);
 
-	if ((error = BHND_EROM_INIT(erom, parent, rid, enum_addr))) {
+	if ((error = BHND_EROM_INIT(erom, cid, parent, rid))) {
 		printf("error initializing %s parser at %#jx with "
-		    "rid %d: %d\n", cls->name, (uintmax_t)enum_addr, rid,
+		    "rid %d: %d\n", cls->name, (uintmax_t)cid->enum_addr, rid,
 		     error);
 
 		kobj_delete((kobj_t)erom, M_BHND);
@@ -86,6 +86,7 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, 
  * @param esize		The total available number of bytes allocated for
  *			@p erom. If this is less than is required by @p cls,
  *			ENOMEM will be returned.
+ * @param cid		The device's chip identifier.
  * @param bst		Bus space tag.
  * @param bsh		Bus space handle mapping the device enumeration
  *			space.
@@ -97,7 +98,7 @@ bhnd_erom_alloc(bhnd_erom_class_t *cls, 
  */
 int
 bhnd_erom_init_static(bhnd_erom_class_t *cls, bhnd_erom_t *erom, size_t esize,
-    bus_space_tag_t bst, bus_space_handle_t bsh)
+    const struct bhnd_chipid *cid, bus_space_tag_t bst, bus_space_handle_t bsh)
 {
 	kobj_class_t	kcls;
 
@@ -109,7 +110,7 @@ bhnd_erom_init_static(bhnd_erom_class_t 
 
 	/* Perform instance initialization */
 	kobj_init_static((kobj_t)erom, kcls);
-	return (BHND_EROM_INIT_STATIC(erom, bst, bsh)); 
+	return (BHND_EROM_INIT_STATIC(erom, cid, bst, bsh)); 
 }
 
 /**

Modified: head/sys/dev/bhnd/bhnd_erom.h
==============================================================================
--- head/sys/dev/bhnd/bhnd_erom.h	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bhnd_erom.h	Sun Sep  4 00:58:19 2016	(r305371)
@@ -42,11 +42,12 @@
 #include "bhnd_erom_if.h"
 
 bhnd_erom_t			*bhnd_erom_alloc(bhnd_erom_class_t *cls,
-				     device_t parent, int rid,
-				     bus_addr_t enum_addr);
+				     const struct bhnd_chipid *cid,
+				     device_t parent, int rid);
 
 int				 bhnd_erom_init_static(bhnd_erom_class_t *cls,
 				     bhnd_erom_t *erom, size_t esize,
+				     const struct bhnd_chipid *cid,
 				     bus_space_tag_t bst,
 				     bus_space_handle_t bsh);
 
@@ -94,15 +95,48 @@ SET_DECLARE(bhnd_erom_class_set, bhnd_er
 
 /**
  * Probe to see if this device enumeration class supports the bhnd bus
+ * mapped by the given resource, returning a standard newbus device probe
+ * result (see BUS_PROBE_*) and the probed chip identification.
+ *
+ * @param	cls	The erom class to probe.
+ * @param	res	A resource mapping the first bus core (EXTIF or
+ *			ChipCommon)
+ * @param	offset	Offset to the first bus core within @p res.
+ * @param	hint	Identification hint used to identify the device. If
+ *			chipset supports standard chip identification registers
+ *			within the first core, this parameter should be NULL.
+ * @param[out]	cid	On success, the probed chip identifier.
+ *
+ * @retval 0		if this is the only possible device enumeration
+ *			parser for the probed bus.
+ * @retval negative	if the probe succeeds, a negative value should be
+ *			returned; the parser returning the highest negative
+ *			value will be selected to handle device enumeration.
+ * @retval ENXIO	If the bhnd bus type is not handled by this parser.
+ * @retval positive	if an error occurs during probing, a regular unix error
+ *			code should be returned.
+ */
+static inline int
+bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_resource *res,
+    bus_size_t offset, const struct bhnd_chipid *hint, struct bhnd_chipid *cid)
+{
+	return (BHND_EROM_PROBE(cls, res, offset, hint, cid));
+}
+
+/**
+ * Probe to see if this device enumeration class supports the bhnd bus
  * mapped at the given bus space tag and handle, returning a standard
  * newbus device probe result (see BUS_PROBE_*) and the probed
  * chip identification.
  *
- * @param	cls	The parser class to be probed.
+ * @param	cls	The erom class to probe.
  * @param	bst	Bus space tag.
  * @param	bsh	Bus space handle mapping the EXTIF or ChipCommon core.
  * @param	paddr	The physical address of the core mapped by @p bst and
  *			@p bsh.
+ * @param	hint	Identification hint used to identify the device. If
+ *			chipset supports standard chip identification registers
+ *			within the first core, this parameter should be NULL.
  * @param[out]	cid	On success, the probed chip identifier.
  *
  * @retval 0		if this is the only possible device enumeration
@@ -116,9 +150,10 @@ SET_DECLARE(bhnd_erom_class_set, bhnd_er
  */
 static inline int
 bhnd_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst,
-    bus_space_handle_t bsh, bus_addr_t paddr, struct bhnd_chipid *cid)
+    bus_space_handle_t bsh, bus_addr_t paddr, const struct bhnd_chipid *hint,
+    struct bhnd_chipid *cid)
 {
-	return (BHND_EROM_PROBE_STATIC(cls, bst, bsh, paddr, cid));
+	return (BHND_EROM_PROBE_STATIC(cls, bst, bsh, paddr, hint, cid));
 }
 
 /**

Modified: head/sys/dev/bhnd/bhnd_erom_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_erom_if.m	Sun Sep  4 00:35:55 2016	(r305370)
+++ head/sys/dev/bhnd/bhnd_erom_if.m	Sun Sep  4 00:58:19 2016	(r305371)
@@ -45,15 +45,48 @@ INTERFACE bhnd_erom;
 
 /**
  * Probe to see if this device enumeration class supports the bhnd bus
+ * mapped by the given resource, returning a standard newbus device probe
+ * result (see BUS_PROBE_*) and the probed chip identification.
+ *
+ * @param	cls	The erom class to probe.
+ * @param	res	A resource mapping the first bus core.
+ * @param	offset	Offset to the first bus core within @p res.
+ * @param	hint	Hint used to identify the device. If chipset supports
+ *			standard chip identification registers within the first 
+ *			core, this parameter should be NULL.
+ * @param[out]	cid	On success, the probed chip identifier.
+ *
+ * @retval 0		if this is the only possible device enumeration
+ *			parser for the probed bus.
+ * @retval negative	if the probe succeeds, a negative value should be
+ *			returned; the parser returning the highest negative
+ *			value will be selected to handle device enumeration.
+ * @retval ENXIO	If the bhnd bus type is not handled by this parser.
+ * @retval positive	if an error occurs during probing, a regular unix error
+ *			code should be returned.
+ */
+STATICMETHOD int probe {
+	bhnd_erom_class_t		*cls;
+	struct bhnd_resource		*res;
+	bus_size_t			 offset;
+	const struct bhnd_chipid	*hint;
+	struct bhnd_chipid		*cid;
+};
+
+/**
+ * Probe to see if this device enumeration class supports the bhnd bus
  * mapped at the given bus space tag and handle, returning a standard
  * newbus device probe result (see BUS_PROBE_*) and the probed
  * chip identification.
  *
- * @param	cls	The erom parse class to probe.
+ * @param	cls	The erom class to probe.
  * @param	bst	Bus space tag.
- * @param	bsh	Bus space handle mapping the EXTIF or ChipCommon core.
+ * @param	bsh	Bus space handle mapping the first bus core.
  * @param	paddr	The physical address of the core mapped by @p bst and
  *			@p bsh.
+ * @param	hint	Hint used to identify the device. If chipset supports
+ *			standard chip identification registers within the first 
+ *			core, this parameter should be NULL.
  * @param[out]	cid	On success, the probed chip identifier.
  *
  * @retval 0		if this is the only possible device enumeration
@@ -66,51 +99,54 @@ INTERFACE bhnd_erom;
  *			code should be returned.
  */
 STATICMETHOD int probe_static {
-	bhnd_erom_class_t	*cls;
-	bus_space_tag_t 	 bst;
-	bus_space_handle_t	 bsh;
-	bus_addr_t		 paddr;
-	struct bhnd_chipid	*cid;
+	bhnd_erom_class_t		*cls;
+	bus_space_tag_t 		 bst;
+	bus_space_handle_t		 bsh;
+	bus_addr_t			 paddr;
+	const struct bhnd_chipid	*hint;
+	struct bhnd_chipid		*cid;
 };
 
 /**

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



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