diff options
author | hselasky <hselasky@FreeBSD.org> | 2012-08-10 15:02:49 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2012-08-10 15:02:49 +0000 |
commit | 3ccdeed50760f5c01b649834ab49f50f7ae5872b (patch) | |
tree | f2d07ce3573fe7542f1582ab309e5d65b25be685 /sys/kern/subr_bus.c | |
parent | fd073d8747e8941e1c70a3204040745a69d43b5c (diff) | |
download | FreeBSD-src-3ccdeed50760f5c01b649834ab49f50f7ae5872b.zip FreeBSD-src-3ccdeed50760f5c01b649834ab49f50f7ae5872b.tar.gz |
Add new device method to free the automatically
allocated softc structure which is returned by
device_get_softc(). This method can be used to
easily implement softc refcounting. This can be
desirable when the softc has memory references
which are controlled by userspace handles for
example.
This solves the problem of blocking the caller
of device_detach() for a non-deterministic time.
Discussed with: kib, ed
MFC after: 2 weeks
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r-- | sys/kern/subr_bus.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index def1652..1356684 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 && !(dev->flags & DF_EXTERNALSOFTC)) - free(dev->softc, M_BUS_SC); + if (dev->softc != NULL && !(dev->flags & DF_EXTERNALSOFTC)) + DEVICE_FREE_SOFTC(dev, dev->softc); dev->softc = softc; if (dev->softc) dev->flags |= DF_EXTERNALSOFTC; @@ -2604,8 +2604,8 @@ device_set_driver(device_t dev, driver_t *driver) if (dev->driver == driver) return (0); - if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) { - free(dev->softc, M_BUS_SC); + if (dev->softc != NULL && !(dev->flags & DF_EXTERNALSOFTC)) { + DEVICE_FREE_SOFTC(dev, dev->softc); dev->softc = NULL; } device_set_desc(dev, NULL); @@ -4797,3 +4797,13 @@ 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); +} |