Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139440179
D6849.id17643.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D6849.id17643.diff
View Options
Index: head/sys/dev/bhnd/bhnd_nexus.c
===================================================================
--- head/sys/dev/bhnd/bhnd_nexus.c
+++ head/sys/dev/bhnd/bhnd_nexus.c
@@ -106,10 +106,26 @@
return (0);
}
+static int
+bhnd_nexus_deactivate_resource(device_t dev, device_t child,
+ int type, int rid, struct bhnd_resource *r)
+{
+ int error;
+
+ /* Always direct */
+ KASSERT(r->direct, ("indirect resource delegated to bhnd_nexus\n"));
+
+ if ((error = bus_deactivate_resource(child, type, rid, r->res)))
+ return (error);
+
+ r->direct = false;
+ return (0);
+}
static device_method_t bhnd_nexus_methods[] = {
/* bhnd interface */
DEVMETHOD(bhnd_bus_activate_resource, bhnd_nexus_activate_resource),
+ DEVMETHOD(bhnd_bus_deactivate_resource, bhnd_nexus_deactivate_resource),
DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_nexus_is_hw_disabled),
DEVMETHOD(bhnd_bus_get_attach_type, bhnd_nexus_get_attach_type),
Index: head/sys/dev/bhnd/cores/chipc/chipc.c
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c
+++ head/sys/dev/bhnd/cores/chipc/chipc.c
@@ -282,6 +282,8 @@
return (0);
failed:
+ device_delete_children(sc->dev);
+
if (sc->core_region != NULL) {
chipc_release_region(sc, sc->core_region,
RF_ALLOCATED|RF_ACTIVE);
@@ -878,10 +880,8 @@
}
/* Try to retain a region reference */
- if ((error = chipc_retain_region(sc, cr, RF_ALLOCATED))) {
- CHIPC_UNLOCK(sc);
+ if ((error = chipc_retain_region(sc, cr, RF_ALLOCATED)))
return (NULL);
- }
/* Make our rman reservation */
rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
Index: head/sys/dev/bhnd/cores/chipc/chipc_private.h
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_private.h
+++ head/sys/dev/bhnd/cores/chipc/chipc_private.h
@@ -84,11 +84,13 @@
bhnd_addr_t cr_addr; /**< region base address */
bhnd_addr_t cr_end; /**< region end address */
bhnd_size_t cr_count; /**< region count */
- int cr_rid; /**< rid, or -1 if no rid
- * is allocated by the bus for
- * this region */
+ int cr_rid; /**< rid to use when performing
+ resource allocation, or -1
+ if region has no assigned
+ resource ID */
struct bhnd_resource *cr_res; /**< bus resource, or NULL */
+ int cr_res_rid; /**< cr_res RID, if any. */
u_int cr_refs; /**< RF_ALLOCATED refcount */
u_int cr_act_refs; /**< RF_ACTIVE refcount */
Index: head/sys/dev/bhnd/cores/chipc/chipc_subr.c
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_subr.c
+++ head/sys/dev/bhnd/cores/chipc/chipc_subr.c
@@ -150,9 +150,10 @@
cr->cr_end = cr->cr_addr + cr->cr_count - 1;
- /* Note that not all regions have an assigned rid, in which case
- * this will return -1 */
+ /* Fetch default resource ID for this region. Not all regions have an
+ * assigned rid, in which case this will return -1 */
cr->cr_rid = bhnd_get_port_rid(sc->dev, type, port, region);
+
return (cr);
failed:
@@ -177,7 +178,7 @@
cr->cr_region_num, cr->cr_refs));
if (cr->cr_res != NULL) {
- bhnd_release_resource(sc->dev, SYS_RES_MEMORY, cr->cr_rid,
+ bhnd_release_resource(sc->dev, SYS_RES_MEMORY, cr->cr_res_rid,
cr->cr_res);
}
@@ -264,10 +265,16 @@
KASSERT(cr->cr_res == NULL,
("non-NULL resource has refcount"));
+ /* Fetch initial resource ID */
+ if ((cr->cr_res_rid = cr->cr_rid) == -1) {
+ CHIPC_UNLOCK(sc);
+ return (EINVAL);
+ }
+
+ /* Allocate resource */
cr->cr_res = bhnd_alloc_resource(sc->dev,
- SYS_RES_MEMORY, &cr->cr_rid, cr->cr_addr,
+ SYS_RES_MEMORY, &cr->cr_res_rid, cr->cr_addr,
cr->cr_end, cr->cr_count, 0);
-
if (cr->cr_res == NULL) {
CHIPC_UNLOCK(sc);
return (ENXIO);
@@ -287,7 +294,7 @@
/* If this is the first reference, activate the resource */
if (cr->cr_act_refs == 0) {
error = bhnd_activate_resource(sc->dev, SYS_RES_MEMORY,
- cr->cr_rid, cr->cr_res);
+ cr->cr_res_rid, cr->cr_res);
if (error) {
/* Drop any allocation reference acquired
* above */
@@ -324,6 +331,8 @@
CHIPC_LOCK(sc);
error = 0;
+ KASSERT(cr->cr_res != NULL, ("release on NULL region resource"));
+
if (flags & RF_ACTIVE) {
KASSERT(cr->cr_act_refs > 0, ("RF_ACTIVE over-released"));
KASSERT(cr->cr_act_refs <= cr->cr_refs,
@@ -332,7 +341,7 @@
/* If this is the last reference, deactivate the resource */
if (cr->cr_act_refs == 1) {
error = bhnd_deactivate_resource(sc->dev,
- SYS_RES_MEMORY, cr->cr_rid, cr->cr_res);
+ SYS_RES_MEMORY, cr->cr_res_rid, cr->cr_res);
if (error)
goto done;
}
@@ -343,16 +352,14 @@
if (flags & RF_ALLOCATED) {
KASSERT(cr->cr_refs > 0, ("overrelease of refs"));
-
/* If this is the last reference, release the resource */
if (cr->cr_refs == 1) {
- error = bhnd_release_resource(sc->dev,
- SYS_RES_MEMORY, cr->cr_rid, cr->cr_res);
+ error = bhnd_release_resource(sc->dev, SYS_RES_MEMORY,
+ cr->cr_res_rid, cr->cr_res);
if (error)
goto done;
cr->cr_res = NULL;
- cr->cr_rid = -1;
}
/* Drop our allocation refcount */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 13, 3:01 AM (15 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26919171
Default Alt Text
D6849.id17643.diff (5 KB)
Attached To
Mode
D6849: [bhnd] Fix bhnd_nexus/chipc resource management bugs
Attached
Detach File
Event Timeline
Log In to Comment