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
Landon J. Fuller
landonf at FreeBSD.org
Sun Sep 4 00:58:22 UTC 2016
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 ***
More information about the svn-src-all
mailing list