Add cdevsw->d_purge() support.
This device method shall wake up any threads sleeping in the device driver and make the depart the drivers code for good.
This commit is contained in:
parent
c7f4c39534
commit
743cd76a73
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135843
@ -551,11 +551,11 @@ make_dev_alias(struct cdev *pdev, const char *fmt, ...)
|
||||
static void
|
||||
idestroy_dev(struct cdev *dev)
|
||||
{
|
||||
if (!(dev->si_flags & SI_NAMED)) {
|
||||
printf( "WARNING: Driver mistake: destroy_dev on %d/%d\n",
|
||||
major(dev), minor(dev));
|
||||
panic("don't do that");
|
||||
}
|
||||
struct cdevsw *csw;
|
||||
|
||||
KASSERT(dev->si_flags & SI_NAMED,
|
||||
("WARNING: Driver mistake: destroy_dev on %d/%d\n",
|
||||
major(dev), minor(dev)));
|
||||
|
||||
devfs_destroy(dev);
|
||||
|
||||
@ -578,6 +578,19 @@ idestroy_dev(struct cdev *dev)
|
||||
dev->si_flags &= ~SI_CLONELIST;
|
||||
}
|
||||
|
||||
csw = dev->si_devsw;
|
||||
dev->si_devsw = NULL;
|
||||
while (csw->d_purge != NULL && dev->si_threadcount) {
|
||||
printf("Purging %lu threads from %s\n",
|
||||
dev->si_threadcount, devtoname(dev));
|
||||
csw->d_purge(dev);
|
||||
msleep(csw, &devmtx, PRIBIO, "devprg", hz/10);
|
||||
}
|
||||
|
||||
dev->si_drv1 = 0;
|
||||
dev->si_drv2 = 0;
|
||||
bzero(&dev->__si_u, sizeof(dev->__si_u));
|
||||
|
||||
if (!(dev->si_flags & SI_ALIAS)) {
|
||||
/* Remove from cdevsw list */
|
||||
LIST_REMOVE(dev, si_list);
|
||||
@ -588,11 +601,8 @@ idestroy_dev(struct cdev *dev)
|
||||
|
||||
LIST_REMOVE(dev, si_hash);
|
||||
}
|
||||
dev->si_drv1 = 0;
|
||||
dev->si_drv2 = 0;
|
||||
dev->si_devsw = NULL;
|
||||
bzero(&dev->__si_u, sizeof(dev->__si_u));
|
||||
dev->si_flags &= ~SI_ALIAS;
|
||||
|
||||
if (dev->si_refcount > 0) {
|
||||
LIST_INSERT_HEAD(&dead_cdevsw.d_devs, dev, si_list);
|
||||
} else {
|
||||
|
@ -149,8 +149,8 @@ typedef int d_poll_t(struct cdev *dev, int events, struct thread *td);
|
||||
typedef int d_kqfilter_t(struct cdev *dev, struct knote *kn);
|
||||
typedef int d_mmap_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr,
|
||||
int nprot);
|
||||
typedef void d_purge_t(struct cdev *dev);
|
||||
|
||||
typedef int d_spare1_t(struct cdev *dev);
|
||||
typedef int d_spare2_t(struct cdev *dev);
|
||||
|
||||
typedef int dumper_t(
|
||||
@ -214,7 +214,7 @@ struct cdevsw {
|
||||
d_strategy_t *d_strategy;
|
||||
dumper_t *d_dump;
|
||||
d_kqfilter_t *d_kqfilter;
|
||||
d_spare1_t *d_spare1;
|
||||
d_purge_t *d_purge;
|
||||
d_spare2_t *d_spare2;
|
||||
|
||||
/* These fields should not be messed with by drivers */
|
||||
|
Loading…
Reference in New Issue
Block a user