summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2015-01-14 14:04:29 +0000
committerhselasky <hselasky@FreeBSD.org>2015-01-14 14:04:29 +0000
commit99b91105134836ab8410881a39784eacdcd8a1c2 (patch)
treec8cfae0b952598052767f1b3247322249ead54e6
parente0e859773e6e787ee1ca89e7705018f8ae353638 (diff)
downloadFreeBSD-src-99b91105134836ab8410881a39784eacdcd8a1c2.zip
FreeBSD-src-99b91105134836ab8410881a39784eacdcd8a1c2.tar.gz
Add a kernel function to delist our kernel character devices, so that
the device name can be re-used right away in case we are destroying the character devices in the background. MFC after: 4 days Reported by: dchagin@
-rw-r--r--sys/dev/usb/usb_device.c5
-rw-r--r--sys/kern/kern_conf.c17
-rw-r--r--sys/sys/conf.h1
3 files changed, 22 insertions, 1 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index e1ab279..b3b46b3 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -2019,7 +2019,10 @@ usb_destroy_dev(struct usb_fs_privdata *pd)
usb_destroy_dev_sync(pd);
return;
}
-
+
+ /* make sure we can re-use the device name */
+ delist_dev(pd->cdev);
+
USB_BUS_LOCK(bus);
LIST_INSERT_HEAD(&bus->pd_cleanup_list, pd, pd_next);
/* get cleanup going */
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index d15e5da..8b1fdc1 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -1114,6 +1114,23 @@ destroy_devl(struct cdev *dev)
}
}
+static void
+delist_dev_locked(struct cdev *dev)
+{
+ struct cdev *child;
+ devfs_destroy(dev);
+ LIST_FOREACH(child, &dev->si_children, si_siblings)
+ delist_dev_locked(child);
+}
+
+void
+delist_dev(struct cdev *dev)
+{
+ dev_lock();
+ delist_dev_locked(dev);
+ dev_unlock();
+}
+
void
destroy_dev(struct cdev *dev)
{
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 68e9d0f..035a5fd 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -245,6 +245,7 @@ void clone_cleanup(struct clonedevs **);
int clone_create(struct clonedevs **, struct cdevsw *, int *unit, struct cdev **dev, int extra);
int count_dev(struct cdev *_dev);
+void delist_dev(struct cdev *_dev);
void destroy_dev(struct cdev *_dev);
int destroy_dev_sched(struct cdev *dev);
int destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg);
OpenPOWER on IntegriCloud