aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2016-04-27 16:33:17 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2016-04-27 16:33:17 +0000
commit88eb5c506d00e446dcfeb0f84b36d5132a8d9f6b (patch)
tree9d890003db3954532ce3e8f39ed0184a8e9983dc /sys
parent3d0338a09278a0cc38785321f102de9775c57ed3 (diff)
downloadsrc-88eb5c506d00e446dcfeb0f84b36d5132a8d9f6b.tar.gz
src-88eb5c506d00e446dcfeb0f84b36d5132a8d9f6b.zip
Add 'devctl delete' that calls device_delete_child().
'devctl delete' can be used to delete a device that is no longer present. As an anti-foot-shooting measure, 'delete' will not delete a device unless it's parent bus says it is no longer present. This can be overridden by passing the force ('-f') flag. Note that this command should be used with care. If a device is deleted that is actually present it can't be resurrected unless the parent bus device's driver supports rescans. Differential Revision: https://reviews.freebsd.org/D6019
Notes
Notes: svn path=/head/; revision=298709
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_bus.c19
-rw-r--r--sys/sys/bus.h4
2 files changed, 23 insertions, 0 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index d9c2ac1b6e24..968cb99f8e50 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -5204,6 +5204,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
case DEV_RESUME:
case DEV_SET_DRIVER:
case DEV_RESCAN:
+ case DEV_DELETE:
error = priv_check(td, PRIV_DRIVER);
if (error == 0)
error = find_device(req, &dev);
@@ -5374,6 +5375,24 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
}
error = BUS_RESCAN(dev);
break;
+ case DEV_DELETE: {
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ if (parent == NULL) {
+ error = EINVAL;
+ break;
+ }
+ if (!(req->dr_flags & DEVF_FORCE_DELETE)) {
+ if (bus_child_present(dev) != 0) {
+ error = EBUSY;
+ break;
+ }
+ }
+
+ error = device_delete_child(parent, dev);
+ break;
+ }
}
mtx_unlock(&Giant);
return (error);
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index c46fbb24a544..85cfb0ec4aed 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -118,6 +118,7 @@ struct devreq {
#define DEV_RESUME _IOW('D', 6, struct devreq)
#define DEV_SET_DRIVER _IOW('D', 7, struct devreq)
#define DEV_RESCAN _IOW('D', 9, struct devreq)
+#define DEV_DELETE _IOW('D', 10, struct devreq)
/* Flags for DEV_DETACH and DEV_DISABLE. */
#define DEVF_FORCE_DETACH 0x0000001
@@ -125,6 +126,9 @@ struct devreq {
/* Flags for DEV_SET_DRIVER. */
#define DEVF_SET_DRIVER_DETACH 0x0000001 /* Detach existing driver. */
+/* Flags for DEV_DELETE. */
+#define DEVF_FORCE_DELETE 0x0000001
+
#ifdef _KERNEL
#include <sys/eventhandler.h>