Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105780406
D6959.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D6959.diff
View Options
Index: head/sys/dev/bhnd/bcma/bcma.c
===================================================================
--- head/sys/dev/bhnd/bcma/bcma.c
+++ head/sys/dev/bhnd/bcma/bcma.c
@@ -181,14 +181,6 @@
}
}
-static void
-bcma_child_deleted(device_t dev, device_t child)
-{
- struct bcma_devinfo *dinfo = device_get_ivars(child);
- if (dinfo != NULL)
- bcma_free_dinfo(dev, dinfo);
-}
-
static struct resource_list *
bcma_get_resource_list(device_t dev, device_t child)
{
@@ -415,6 +407,19 @@
return (ENOENT);
}
+static struct bhnd_devinfo *
+bcma_alloc_bhnd_dinfo(device_t dev)
+{
+ struct bcma_devinfo *dinfo = bcma_alloc_dinfo(dev);
+ return ((struct bhnd_devinfo *)dinfo);
+}
+
+static void
+bcma_free_bhnd_dinfo(device_t dev, struct bhnd_devinfo *dinfo)
+{
+ bcma_free_dinfo(dev, (struct bcma_devinfo *)dinfo);
+}
+
/**
* Scan a device enumeration ROM table, adding all valid discovered cores to
* the bus.
@@ -431,8 +436,7 @@
struct bcma_devinfo *dinfo;
device_t child;
int error;
-
- dinfo = NULL;
+
corecfg = NULL;
/* Initialize our reader */
@@ -450,26 +454,20 @@
goto failed;
}
- /* Allocate per-device bus info */
- dinfo = bcma_alloc_dinfo(bus, corecfg);
- if (dinfo == NULL) {
- error = ENXIO;
- goto failed;
- }
-
- /* The dinfo instance now owns the corecfg value */
- corecfg = NULL;
-
/* Add the child device */
- child = device_add_child(bus, NULL, -1);
+ child = BUS_ADD_CHILD(bus, 0, NULL, -1);
if (child == NULL) {
error = ENXIO;
goto failed;
}
- /* The child device now owns the dinfo pointer */
- device_set_ivars(child, dinfo);
- dinfo = NULL;
+ /* Initialize device ivars */
+ dinfo = device_get_ivars(child);
+ if ((error = bcma_init_dinfo(bus, dinfo, corecfg)))
+ goto failed;
+
+ /* The dinfo instance now owns the corecfg value */
+ corecfg = NULL;
/* If pins are floating or the hardware is otherwise
* unpopulated, the device shouldn't be used. */
@@ -482,9 +480,6 @@
return (0);
failed:
- if (dinfo != NULL)
- bcma_free_dinfo(bus, dinfo);
-
if (corecfg != NULL)
bcma_free_corecfg(corecfg);
@@ -499,13 +494,14 @@
DEVMETHOD(device_detach, bcma_detach),
/* Bus interface */
- DEVMETHOD(bus_child_deleted, bcma_child_deleted),
DEVMETHOD(bus_read_ivar, bcma_read_ivar),
DEVMETHOD(bus_write_ivar, bcma_write_ivar),
DEVMETHOD(bus_get_resource_list, bcma_get_resource_list),
/* BHND interface */
DEVMETHOD(bhnd_bus_find_hostb_device, bcma_find_hostb_device),
+ 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),
DEVMETHOD(bhnd_bus_suspend_core, bcma_suspend_core),
DEVMETHOD(bhnd_bus_get_port_count, bcma_get_port_count),
Index: head/sys/dev/bhnd/bcma/bcma_subr.c
===================================================================
--- head/sys/dev/bhnd/bcma/bcma_subr.c
+++ head/sys/dev/bhnd/bcma/bcma_subr.c
@@ -186,28 +186,54 @@
}
}
+
/**
- * Allocate and initialize new device info structure, assuming ownership
- * of the provided core configuration.
+ * Allocate and return a new empty device info structure.
*
* @param bus The requesting bus device.
- * @param corecfg Device core configuration.
+ *
+ * @retval NULL if allocation failed.
*/
struct bcma_devinfo *
-bcma_alloc_dinfo(device_t bus, struct bcma_corecfg *corecfg)
+bcma_alloc_dinfo(device_t bus)
{
struct bcma_devinfo *dinfo;
- dinfo = malloc(sizeof(struct bcma_devinfo), M_BHND, M_NOWAIT);
+ dinfo = malloc(sizeof(struct bcma_devinfo), M_BHND, M_NOWAIT|M_ZERO);
if (dinfo == NULL)
- return NULL;
+ return (NULL);
- dinfo->corecfg = corecfg;
+ dinfo->corecfg = NULL;
dinfo->res_agent = NULL;
dinfo->rid_agent = -1;
resource_list_init(&dinfo->resources);
+ return (dinfo);
+}
+
+/**
+ * Initialize a device info structure previously allocated via
+ * bcma_alloc_dinfo, assuming ownership of the provided core
+ * configuration.
+ *
+ * @param bus The requesting bus device.
+ * @param dinfo The device info instance.
+ * @param corecfg Device core configuration; ownership of this value
+ * will be assumed by @p dinfo.
+ *
+ * @retval 0 success
+ * @retval non-zero initialization failed.
+ */
+int
+bcma_init_dinfo(device_t bus, struct bcma_devinfo *dinfo,
+ struct bcma_corecfg *corecfg)
+{
+ KASSERT(dinfo->corecfg == NULL, ("dinfo previously initialized"));
+
+ /* Save core configuration value */
+ dinfo->corecfg = corecfg;
+
/* The device ports must always be initialized first to ensure that
* rid 0 maps to the first device port */
bcma_dinfo_init_resource_info(bus, dinfo, &corecfg->dev_ports);
@@ -215,7 +241,7 @@
bcma_dinfo_init_resource_info(bus, dinfo, &corecfg->bridge_ports);
bcma_dinfo_init_resource_info(bus, dinfo, &corecfg->wrapper_ports);
- return dinfo;
+ return (0);
}
/**
@@ -227,9 +253,11 @@
void
bcma_free_dinfo(device_t bus, struct bcma_devinfo *dinfo)
{
- bcma_free_corecfg(dinfo->corecfg);
resource_list_free(&dinfo->resources);
+ if (dinfo->corecfg != NULL)
+ bcma_free_corecfg(dinfo->corecfg);
+
/* Release agent resource, if any */
if (dinfo->res_agent != NULL) {
bhnd_release_resource(bus, SYS_RES_MEMORY, dinfo->rid_agent,
Index: head/sys/dev/bhnd/bcma/bcmavar.h
===================================================================
--- head/sys/dev/bhnd/bcma/bcmavar.h
+++ head/sys/dev/bhnd/bcma/bcmavar.h
@@ -69,7 +69,9 @@
struct bcma_sport_list *bcma_corecfg_get_port_list(struct bcma_corecfg *cfg,
bhnd_port_type type);
-struct bcma_devinfo *bcma_alloc_dinfo(device_t bus,
+struct bcma_devinfo *bcma_alloc_dinfo(device_t bus);
+int bcma_init_dinfo(device_t bus,
+ struct bcma_devinfo *dinfo,
struct bcma_corecfg *corecfg);
void bcma_free_dinfo(device_t bus,
struct bcma_devinfo *dinfo);
@@ -132,7 +134,9 @@
* BCMA per-device info
*/
struct bcma_devinfo {
- struct resource_list resources; /**< Slave port memory regions. */
+ struct bhnd_devinfo bhnd_dinfo; /**< superclass device info. */
+
+ struct resource_list resources; /**< Slave port memory regions. */
struct bcma_corecfg *corecfg; /**< IP core/block config */
struct bhnd_resource *res_agent; /**< Agent (wrapper) resource, or NULL. Not
@@ -147,4 +151,4 @@
device_t hostb_dev; /**< host bridge core, or NULL */
};
-#endif /* _BCMA_BCMAVAR_H_ */
\ No newline at end of file
+#endif /* _BCMA_BCMAVAR_H_ */
Index: head/sys/dev/bhnd/bhnd.c
===================================================================
--- head/sys/dev/bhnd/bhnd.c
+++ head/sys/dev/bhnd/bhnd.c
@@ -493,6 +493,54 @@
}
/**
+ * Default bhnd(4) bus driver implementation of BUS_ADD_CHILD().
+ *
+ * This implementation manages internal bhnd(4) state, and must be called
+ * by subclassing drivers.
+ */
+device_t
+bhnd_generic_add_child(device_t dev, u_int order, const char *name, int unit)
+{
+ struct bhnd_devinfo *dinfo;
+ device_t child;
+
+ child = device_add_child_ordered(dev, order, name, unit);
+ if (child == NULL)
+ return (NULL);
+
+ if ((dinfo = BHND_BUS_ALLOC_DEVINFO(dev)) == NULL) {
+ device_delete_child(dev, child);
+ return (NULL);
+ }
+
+ device_set_ivars(child, dinfo);
+
+ /* Inform concrete bus driver. */
+ BHND_BUS_CHILD_ADDED(dev, child);
+
+ return (child);
+}
+
+/**
+ * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
+ *
+ * This implementation manages internal bhnd(4) state, and must be called
+ * by subclassing drivers.
+ */
+void
+bhnd_generic_child_deleted(device_t dev, device_t child)
+{
+ struct bhnd_softc *sc;
+ struct bhnd_devinfo *dinfo;
+
+ sc = device_get_softc(dev);
+
+ /* Free device info */
+ if ((dinfo = device_get_ivars(child)) != NULL)
+ BHND_BUS_FREE_DEVINFO(dev, dinfo);
+}
+
+/**
* Helper function for implementing BUS_SUSPEND_CHILD().
*
* TODO: Power management
@@ -611,6 +659,8 @@
DEVMETHOD(device_resume, bhnd_generic_resume),
/* Bus interface */
+ DEVMETHOD(bus_add_child, bhnd_generic_add_child),
+ DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted),
DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch),
DEVMETHOD(bus_print_child, bhnd_generic_print_child),
DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str),
Index: head/sys/dev/bhnd/bhnd_bus_if.m
===================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m
+++ head/sys/dev/bhnd/bhnd_bus_if.m
@@ -41,6 +41,7 @@
struct bhnd_board_info;
struct bhnd_core_info;
struct bhnd_chipid;
+ struct bhnd_devinfo;
struct bhnd_resource;
}
@@ -67,6 +68,11 @@
{
panic("bhnd_bus_read_boardinfo unimplemented");
}
+
+ static void
+ bhnd_bus_null_child_added(device_t dev, device_t child)
+ {
+ }
static device_t
bhnd_bus_null_find_hostb_device(device_t dev)
@@ -228,6 +234,46 @@
} DEFAULT bhnd_bus_null_read_board_info;
/**
+ * Allocate and zero-initialize a buffer suitably sized and aligned for a
+ * bhnd_devinfo structure.
+ *
+ * @param dev The bhnd bus device.
+ *
+ * @retval non-NULL success
+ * @retval NULL allocation failed
+ */
+METHOD struct bhnd_devinfo * alloc_devinfo {
+ device_t dev;
+};
+
+/**
+ * Release memory previously allocated for @p devinfo.
+ *
+ * @param dev The bhnd bus device.
+ * @param dinfo A devinfo buffer previously allocated via
+ * BHND_BUS_ALLOC_DEVINFO().
+ */
+METHOD void free_devinfo {
+ device_t dev;
+ struct bhnd_devinfo *dinfo;
+};
+
+/**
+ * Notify a bhnd bus that a child was added.
+ *
+ * Called at the end of BUS_ADD_CHILD() to allow the concrete bhnd(4)
+ * driver instance to initialize any additional driver-specific state for the
+ * child.
+ *
+ * @param dev The bhnd bus whose child is being added.
+ * @param child The child added to @p dev.
+ */
+METHOD void child_added {
+ device_t dev;
+ device_t child;
+} DEFAULT bhnd_bus_null_child_added;
+
+/**
* Reset the device's hardware core.
*
* @param dev The parent of @p child.
Index: head/sys/dev/bhnd/bhndvar.h
===================================================================
--- head/sys/dev/bhnd/bhndvar.h
+++ head/sys/dev/bhnd/bhndvar.h
@@ -46,6 +46,13 @@
DECLARE_CLASS(bhnd_driver);
/**
+ * bhnd per-device info. Must be first member of all subclass
+ * devinfo structures.
+ */
+struct bhnd_devinfo {
+};
+
+/**
* bhnd driver instance state. Must be first member of all subclass
* softc structures.
*/
@@ -66,6 +73,10 @@
void bhnd_generic_probe_nomatch(device_t dev,
device_t child);
+device_t bhnd_generic_add_child(device_t dev, u_int order,
+ const char *name, int unit);
+void bhnd_generic_child_deleted(device_t dev,
+ device_t child);
int bhnd_generic_suspend_child(device_t dev,
device_t child);
int bhnd_generic_resume_child(device_t dev,
Index: head/sys/dev/bhnd/siba/siba.c
===================================================================
--- head/sys/dev/bhnd/siba/siba.c
+++ head/sys/dev/bhnd/siba/siba.c
@@ -206,14 +206,6 @@
}
}
-static void
-siba_child_deleted(device_t dev, device_t child)
-{
- struct siba_devinfo *dinfo = device_get_ivars(child);
- if (dinfo != NULL)
- siba_free_dinfo(dev, dinfo);
-}
-
static struct resource_list *
siba_get_resource_list(device_t dev, device_t child)
{
@@ -436,6 +428,19 @@
return (0);
}
+static struct bhnd_devinfo *
+siba_alloc_bhnd_dinfo(device_t dev)
+{
+ struct siba_devinfo *dinfo = siba_alloc_dinfo(dev);
+ return ((struct bhnd_devinfo *)dinfo);
+}
+
+static void
+siba_free_bhnd_dinfo(device_t dev, struct bhnd_devinfo *dinfo)
+{
+ siba_free_dinfo(dev, (struct siba_devinfo *)dinfo);
+}
+
/**
* Scan the core table and add all valid discovered cores to
* the bus.
@@ -556,6 +561,13 @@
goto cleanup;
}
+ /* Add the child device */
+ child = BUS_ADD_CHILD(dev, 0, NULL, -1);
+ if (child == NULL) {
+ error = ENXIO;
+ goto cleanup;
+ }
+
/* Read the core info */
idhigh = bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
idlow = bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDLOW));
@@ -570,27 +582,18 @@
cores[i].unit++;
}
- /* Allocate per-device bus info */
- dinfo = siba_alloc_dinfo(dev, &cid);
- if (dinfo == NULL) {
+ /* Initialize per-device bus info */
+ if ((dinfo = device_get_ivars(child)) == NULL) {
error = ENXIO;
goto cleanup;
}
- /* Register the core's address space(s). */
- if ((error = siba_register_addrspaces(dev, dinfo, r)))
+ if ((error = siba_init_dinfo(dev, dinfo, &cid)))
goto cleanup;
- /* Add the child device */
- child = device_add_child(dev, NULL, -1);
- if (child == NULL) {
- error = ENXIO;
+ /* Register the core's address space(s). */
+ if ((error = siba_register_addrspaces(dev, dinfo, r)))
goto cleanup;
- }
-
- /* The child device now owns the dinfo pointer */
- device_set_ivars(child, dinfo);
- dinfo = NULL;
/* If pins are floating or the hardware is otherwise
* unpopulated, the device shouldn't be used. */
@@ -606,9 +609,6 @@
if (cores != NULL)
free(cores, M_BHND);
- if (dinfo != NULL)
- siba_free_dinfo(dev, dinfo);
-
if (r != NULL)
bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
@@ -624,13 +624,14 @@
DEVMETHOD(device_suspend, siba_suspend),
/* Bus interface */
- DEVMETHOD(bus_child_deleted, siba_child_deleted),
DEVMETHOD(bus_read_ivar, siba_read_ivar),
DEVMETHOD(bus_write_ivar, siba_write_ivar),
DEVMETHOD(bus_get_resource_list, siba_get_resource_list),
/* BHND interface */
DEVMETHOD(bhnd_bus_find_hostb_device, siba_find_hostb_device),
+ DEVMETHOD(bhnd_bus_alloc_devinfo, siba_alloc_bhnd_dinfo),
+ DEVMETHOD(bhnd_bus_free_devinfo, siba_free_bhnd_dinfo),
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),
Index: head/sys/dev/bhnd/siba/siba_subr.c
===================================================================
--- head/sys/dev/bhnd/siba/siba_subr.c
+++ head/sys/dev/bhnd/siba/siba_subr.c
@@ -106,23 +106,21 @@
}
/**
- * Allocate and initialize new device info structure, copying the
- * provided core id.
+ * Allocate and return a new empty device info structure.
*
- * @param dev The requesting bus device.
- * @param core Device core info.
+ * @param bus The requesting bus device.
+ *
+ * @retval NULL if allocation failed.
*/
struct siba_devinfo *
-siba_alloc_dinfo(device_t bus, const struct siba_core_id *core_id)
+siba_alloc_dinfo(device_t bus)
{
struct siba_devinfo *dinfo;
- dinfo = malloc(sizeof(struct siba_devinfo), M_BHND, M_NOWAIT);
+ dinfo = malloc(sizeof(struct siba_devinfo), M_BHND, M_NOWAIT|M_ZERO);
if (dinfo == NULL)
return NULL;
- dinfo->core_id = *core_id;
-
for (u_int i = 0; i < nitems(dinfo->cfg); i++) {
dinfo->cfg[i] = NULL;
dinfo->cfg_rid[i] = -1;
@@ -134,6 +132,25 @@
}
/**
+ * Initialize a device info structure previously allocated via
+ * siba_alloc_dinfo, copying the provided core id.
+ *
+ * @param dev The requesting bus device.
+ * @param dinfo The device info instance.
+ * @param core Device core info.
+ *
+ * @retval 0 success
+ * @retval non-zero initialization failed.
+ */
+int
+siba_init_dinfo(device_t dev, struct siba_devinfo *dinfo,
+ const struct siba_core_id *core_id)
+{
+ dinfo->core_id = *core_id;
+ return (0);
+}
+
+/**
* Map an addrspace index to its corresponding bhnd(4) port number.
*
* @param addrspace Address space index.
Index: head/sys/dev/bhnd/siba/sibavar.h
===================================================================
--- head/sys/dev/bhnd/siba/sibavar.h
+++ head/sys/dev/bhnd/siba/sibavar.h
@@ -63,7 +63,9 @@
int siba_add_children(device_t bus,
const struct bhnd_chipid *chipid);
-struct siba_devinfo *siba_alloc_dinfo(device_t dev,
+struct siba_devinfo *siba_alloc_dinfo(device_t dev);
+int siba_init_dinfo(device_t dev,
+ struct siba_devinfo *dinfo,
const struct siba_core_id *core_id);
void siba_free_dinfo(device_t dev,
struct siba_devinfo *dinfo);
@@ -136,6 +138,8 @@
* siba(4) per-device info
*/
struct siba_devinfo {
+ struct bhnd_devinfo bhnd_dinfo; /**< superclass device info. */
+
struct resource_list resources; /**< per-core memory regions. */
struct siba_core_id core_id; /**< core identification info */
struct siba_addrspace addrspace[SIBA_MAX_ADDRSPACE]; /**< memory map descriptors */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 21, 2:32 PM (19 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15542262
Default Alt Text
D6959.diff (16 KB)
Attached To
Mode
D6959: bhnd(4): Add devinfo allocation and child addition methods, modeled on pci_if.
Attached
Detach File
Event Timeline
Log In to Comment