diff options
author | jhb <jhb@FreeBSD.org> | 2016-09-30 22:05:47 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2016-09-30 22:05:47 +0000 |
commit | 96b406e9cc04e8c5edc75ab1cfb0edae6a57b9ab (patch) | |
tree | 35007123c9912c6cc8bff3312fac05355298a8f6 /usr.sbin | |
parent | a6368448347da338ea1adc921d086119490e1022 (diff) | |
download | FreeBSD-src-96b406e9cc04e8c5edc75ab1cfb0edae6a57b9ab.zip FreeBSD-src-96b406e9cc04e8c5edc75ab1cfb0edae6a57b9ab.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 'usr.sbin')
-rw-r--r-- | usr.sbin/devctl/devctl.8 | 21 | ||||
-rw-r--r-- | usr.sbin/devctl/devctl.c | 38 |
2 files changed, 57 insertions, 2 deletions
diff --git a/usr.sbin/devctl/devctl.8 b/usr.sbin/devctl/devctl.8 index ec8abaf..67b8709 100644 --- a/usr.sbin/devctl/devctl.8 +++ b/usr.sbin/devctl/devctl.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 27, 2016 +.Dd August 29, 2016 .Dt DEVCTL 8 .Os .Sh NAME @@ -36,6 +36,10 @@ .Cm attach .Ar device .Nm +.Cm clear driver +.Op Fl f +.Ar device +.Nm .Cm detach .Op Fl f .Ar device @@ -133,6 +137,21 @@ If the device is already attached to a device driver and the .Fl f flag is not specified, the device will not be changed. +.It Xo Cm clear driver +.Op Fl f +.Ar device +.Xc +Clear a previously-forced driver name so that the device is able to use any +valid device driver. +After the previous name has been cleared, +the device is reprobed so that other device drivers may attach to it. +This can be used to undo an earlier +.Cm set driver +command. +If the device is currently attached to a device driver and the +.Fl f +flag is not specified, +the device will not be changed. .It Cm rescan Ar device Rescan a bus device checking for devices that have been added or removed. diff --git a/usr.sbin/devctl/devctl.c b/usr.sbin/devctl/devctl.c index 824b907..6b266f4 100644 --- a/usr.sbin/devctl/devctl.c +++ b/usr.sbin/devctl/devctl.c @@ -65,12 +65,13 @@ static int devctl_table_handler(struct devctl_command **start, SET_DECLARE(DEVCTL_DATASET(top), struct devctl_command); +DEVCTL_TABLE(top, clear); DEVCTL_TABLE(top, set); static void usage(void) { - fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: devctl attach device", " devctl detach [-f] device", " devctl disable [-f] device", @@ -78,6 +79,7 @@ usage(void) " devctl suspend device", " devctl resume device", " devctl set driver [-f] device driver", + " devctl clear driver [-f] device", " devctl rescan device", " devctl delete [-f] device"); exit(1); @@ -261,6 +263,40 @@ set_driver(int ac, char **av) } DEVCTL_COMMAND(set, driver, set_driver); +static void +clear_driver_usage(void) +{ + + fprintf(stderr, "usage: devctl clear driver [-f] device\n"); + exit(1); +} + +static int +clear_driver(int ac, char **av) +{ + bool force; + int ch; + + force = false; + while ((ch = getopt(ac, av, "f")) != -1) + switch (ch) { + case 'f': + force = true; + break; + default: + clear_driver_usage(); + } + ac -= optind; + av += optind; + + if (ac != 1) + clear_driver_usage(); + if (devctl_clear_driver(av[0], force) < 0) + err(1, "Failed to clear %s driver", av[0]); + return (0); +} +DEVCTL_COMMAND(clear, driver, clear_driver); + static int rescan(int ac, char **av) { |