summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/subr_bus.c28
-rw-r--r--sys/sys/bus.h1
-rw-r--r--sys/sys/bus_private.h1
3 files changed, 23 insertions, 7 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index ec91ca9..7b66e2e 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -855,6 +855,18 @@ device_get_softc(device_t dev)
return dev->softc;
}
+void
+device_set_softc(device_t dev, void *softc)
+{
+ if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
+ free(dev->softc, M_BUS);
+ dev->softc = softc;
+ if (dev->softc)
+ dev->flags |= DF_EXTERNALSOFTC;
+ else
+ dev->flags &= ~DF_EXTERNALSOFTC;
+}
+
void *
device_get_ivars(device_t dev)
{
@@ -976,7 +988,7 @@ device_set_driver(device_t dev, driver_t *driver)
if (dev->driver == driver)
return 0;
- if (dev->softc) {
+ if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
free(dev->softc, M_BUS);
dev->softc = NULL;
}
@@ -984,13 +996,15 @@ device_set_driver(device_t dev, driver_t *driver)
dev->driver = driver;
if (driver) {
kobj_init((kobj_t) dev, (kobj_class_t) driver);
- dev->softc = malloc(driver->size, M_BUS, M_NOWAIT);
- if (!dev->softc) {
- kobj_init((kobj_t) dev, &null_class);
- dev->driver = NULL;
- return ENOMEM;
+ if (!(dev->flags & DF_EXTERNALSOFTC)) {
+ dev->softc = malloc(driver->size, M_BUS, M_NOWAIT);
+ if (!dev->softc) {
+ kobj_init((kobj_t) dev, &null_class);
+ dev->driver = NULL;
+ return ENOMEM;
+ }
+ bzero(dev->softc, driver->size);
}
- bzero(dev->softc, driver->size);
} else
kobj_init((kobj_t) dev, &null_class);
return 0;
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 8ab2a13..2eff10c 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -247,6 +247,7 @@ void device_set_desc_copy(device_t dev, const char* desc);
int device_set_devclass(device_t dev, const char *classname);
int device_set_driver(device_t dev, driver_t *driver);
void device_set_flags(device_t dev, u_int32_t flags);
+void device_set_softc(device_t dev, void *softc);
int device_set_unit(device_t dev, int unit); /* XXX DONT USE XXX */
int device_shutdown(device_t dev);
void device_unbusy(device_t dev);
diff --git a/sys/sys/bus_private.h b/sys/sys/bus_private.h
index 547892b..e725e4c 100644
--- a/sys/sys/bus_private.h
+++ b/sys/sys/bus_private.h
@@ -114,6 +114,7 @@ struct device {
#define DF_DESCMALLOCED 8 /* description was malloced */
#define DF_QUIET 16 /* don't print verbose attach message */
#define DF_DONENOMATCH 32 /* don't execute DEVICE_NOMATCH again */
+#define DF_EXTERNALSOFTC 64 /* softc not allocated by us */
u_char order; /* order from device_add_child_ordered() */
u_char pad;
#ifdef DEVICE_SYSCTLS
OpenPOWER on IntegriCloud