summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2012-08-15 15:42:57 +0000
committerhselasky <hselasky@FreeBSD.org>2012-08-15 15:42:57 +0000
commit2e74f8d2a5ec1615da87208faeb1c64735fc5c64 (patch)
tree99fdc32e57fe511a68b57a70585fea2b615a844d /sys/kern/subr_bus.c
parent0f8b6a08b6cf5ed24bea18a23d546ae01738c2ef (diff)
downloadFreeBSD-src-2e74f8d2a5ec1615da87208faeb1c64735fc5c64.zip
FreeBSD-src-2e74f8d2a5ec1615da87208faeb1c64735fc5c64.tar.gz
Revert r239178 and implement two new functions, namely
"device_free_softc()" and "device_claim_softc()", to allow USB serial drivers refcounting the softc. These functions are used to grab the softc from auto-free and to free the softc back to the correct malloc type, respectivly. Discussed with: jhb MFC after: 2 weeks
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 1356684..fa19cfd 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -2406,8 +2406,8 @@ device_get_softc(device_t dev)
void
device_set_softc(device_t dev, void *softc)
{
- if (dev->softc != NULL && !(dev->flags & DF_EXTERNALSOFTC))
- DEVICE_FREE_SOFTC(dev, dev->softc);
+ if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
+ free(dev->softc, M_BUS_SC);
dev->softc = softc;
if (dev->softc)
dev->flags |= DF_EXTERNALSOFTC;
@@ -2416,6 +2416,35 @@ device_set_softc(device_t dev, void *softc)
}
/**
+ * @brief Free claimed softc
+ *
+ * Most drivers do not need to use this since the softc is freed
+ * automatically when the driver is detached.
+ */
+void
+device_free_softc(void *softc)
+{
+ free(softc, M_BUS_SC);
+}
+
+/**
+ * @brief Claim softc
+ *
+ * This function can be used to let the driver free the automatically
+ * allocated softc using "device_free_softc()". This function is
+ * useful when the driver is refcounting the softc and the softc
+ * cannot be freed when the "device_detach" method is called.
+ */
+void
+device_claim_softc(device_t dev)
+{
+ if (dev->softc)
+ dev->flags |= DF_EXTERNALSOFTC;
+ else
+ dev->flags &= ~DF_EXTERNALSOFTC;
+}
+
+/**
* @brief Get the device's ivars field
*
* The ivars field is used by the parent device to store per-device
@@ -2604,8 +2633,8 @@ device_set_driver(device_t dev, driver_t *driver)
if (dev->driver == driver)
return (0);
- if (dev->softc != NULL && !(dev->flags & DF_EXTERNALSOFTC)) {
- DEVICE_FREE_SOFTC(dev, dev->softc);
+ if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
+ free(dev->softc, M_BUS_SC);
dev->softc = NULL;
}
device_set_desc(dev, NULL);
@@ -4797,13 +4826,3 @@ bus_free_resource(device_t dev, int type, struct resource *r)
return (0);
return (bus_release_resource(dev, type, rman_get_rid(r), r));
}
-
-/*
- * The "dev" argument passed to "device_free_softc()" is allowed to be
- * NULL, if the device freeing the soft is not available.
- */
-void
-device_free_softc(device_t dev, void *softc)
-{
- free(softc, M_BUS_SC);
-}
OpenPOWER on IntegriCloud