diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-01-14 14:04:29 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-01-14 14:04:29 +0000 |
commit | 99b91105134836ab8410881a39784eacdcd8a1c2 (patch) | |
tree | c8cfae0b952598052767f1b3247322249ead54e6 | |
parent | e0e859773e6e787ee1ca89e7705018f8ae353638 (diff) | |
download | FreeBSD-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.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_conf.c | 17 | ||||
-rw-r--r-- | sys/sys/conf.h | 1 |
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); |