summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-09-30 22:05:47 +0000
committerjhb <jhb@FreeBSD.org>2016-09-30 22:05:47 +0000
commit0f41551ef9dde560d9d191d7190af02904dbf611 (patch)
tree00567e70252000c0a9f26250a859dfd20c8e1348 /sys/kern
parentc03db820416e89f29bd1f5cb8f59a221d4d11463 (diff)
downloadFreeBSD-src-0f41551ef9dde560d9d191d7190af02904dbf611.zip
FreeBSD-src-0f41551ef9dde560d9d191d7190af02904dbf611.tar.gz
MFC 305034: Implement 'devctl clear driver' to undo a previous 'set driver'.
Add a new 'clear driver' command for devctl along with the accompanying ioctl and devctl_clear_driver() library routine to reset a device to use a wildcard devclass instead of a fixed devclass. This can be used to undo a previous 'set driver' command. After the device's name has been reset to permit wildcard names, it is reprobed so that it can attach to newly-available (to it) device drivers. Sponsored by: Chelsio Communications
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_bus.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index aba4364..6ccda55 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -5069,6 +5069,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
case DEV_ENABLE:
case DEV_DISABLE:
case DEV_SET_DRIVER:
+ case DEV_CLEAR_DRIVER:
error = priv_check(td, PRIV_DRIVER);
if (error == 0)
error = find_device(req, &dev);
@@ -5210,6 +5211,25 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
error = device_probe_and_attach(dev);
break;
}
+ case DEV_CLEAR_DRIVER:
+ if (!(dev->flags & DF_FIXEDCLASS)) {
+ error = 0;
+ break;
+ }
+ if (device_is_attached(dev)) {
+ if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
+ error = device_detach(dev);
+ else
+ error = EBUSY;
+ if (error)
+ break;
+ }
+
+ dev->flags &= ~DF_FIXEDCLASS;
+ dev->flags |= DF_WILDCARD;
+ devclass_delete_device(dev->devclass, dev);
+ error = device_probe_and_attach(dev);
+ break;
}
mtx_unlock(&Giant);
return (error);
OpenPOWER on IntegriCloud