164de8019SJohn Baldwin /*-
264de8019SJohn Baldwin * Copyright (c) 2014 John Baldwin <jhb@FreeBSD.org>
364de8019SJohn Baldwin *
464de8019SJohn Baldwin * Redistribution and use in source and binary forms, with or without
564de8019SJohn Baldwin * modification, are permitted provided that the following conditions
664de8019SJohn Baldwin * are met:
764de8019SJohn Baldwin * 1. Redistributions of source code must retain the above copyright
864de8019SJohn Baldwin * notice, this list of conditions and the following disclaimer.
964de8019SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright
1064de8019SJohn Baldwin * notice, this list of conditions and the following disclaimer in the
1164de8019SJohn Baldwin * documentation and/or other materials provided with the distribution.
1264de8019SJohn Baldwin *
1364de8019SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1464de8019SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1564de8019SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1664de8019SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1764de8019SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1864de8019SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1964de8019SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2064de8019SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2164de8019SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2264de8019SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2364de8019SJohn Baldwin * SUCH DAMAGE.
2464de8019SJohn Baldwin */
2564de8019SJohn Baldwin
2664de8019SJohn Baldwin #include <sys/cdefs.h>
2764de8019SJohn Baldwin #include <sys/linker_set.h>
2864de8019SJohn Baldwin #include <devctl.h>
2964de8019SJohn Baldwin #include <err.h>
3064de8019SJohn Baldwin #include <errno.h>
3164de8019SJohn Baldwin #include <stdio.h>
3264de8019SJohn Baldwin #include <stdlib.h>
3364de8019SJohn Baldwin #include <string.h>
3464de8019SJohn Baldwin #include <strings.h>
3564de8019SJohn Baldwin #include <unistd.h>
3664de8019SJohn Baldwin
3764de8019SJohn Baldwin struct devctl_command {
3864de8019SJohn Baldwin const char *name;
3964de8019SJohn Baldwin int (*handler)(int ac, char **av);
4064de8019SJohn Baldwin };
4164de8019SJohn Baldwin
4264de8019SJohn Baldwin #define DEVCTL_DATASET(name) devctl_ ## name ## _table
4364de8019SJohn Baldwin
4464de8019SJohn Baldwin #define DEVCTL_COMMAND(set, name, function) \
4564de8019SJohn Baldwin static struct devctl_command function ## _devctl_command = \
4664de8019SJohn Baldwin { #name, function }; \
4764de8019SJohn Baldwin DATA_SET(DEVCTL_DATASET(set), function ## _devctl_command)
4864de8019SJohn Baldwin
4964de8019SJohn Baldwin #define DEVCTL_TABLE(set, name) \
5064de8019SJohn Baldwin SET_DECLARE(DEVCTL_DATASET(name), struct devctl_command); \
5164de8019SJohn Baldwin \
5264de8019SJohn Baldwin static int \
5364de8019SJohn Baldwin devctl_ ## name ## _table_handler(int ac, char **av) \
5464de8019SJohn Baldwin { \
5564de8019SJohn Baldwin return (devctl_table_handler(SET_BEGIN(DEVCTL_DATASET(name)), \
5664de8019SJohn Baldwin SET_LIMIT(DEVCTL_DATASET(name)), ac, av)); \
5764de8019SJohn Baldwin } \
5864de8019SJohn Baldwin DEVCTL_COMMAND(set, name, devctl_ ## name ## _table_handler)
5964de8019SJohn Baldwin
6064de8019SJohn Baldwin static int devctl_table_handler(struct devctl_command **start,
6164de8019SJohn Baldwin struct devctl_command **end, int ac, char **av);
6264de8019SJohn Baldwin
6364de8019SJohn Baldwin SET_DECLARE(DEVCTL_DATASET(top), struct devctl_command);
6464de8019SJohn Baldwin
65e05ec081SJohn Baldwin DEVCTL_TABLE(top, clear);
6664de8019SJohn Baldwin DEVCTL_TABLE(top, set);
6764de8019SJohn Baldwin
6864de8019SJohn Baldwin static void
usage(void)6964de8019SJohn Baldwin usage(void)
7064de8019SJohn Baldwin {
715fa29797SWarner Losh fprintf(stderr,
725fa29797SWarner Losh "usage: devctl attach device\n"
735fa29797SWarner Losh " devctl detach [-f] device\n"
745fa29797SWarner Losh " devctl disable [-f] device\n"
755fa29797SWarner Losh " devctl enable device\n"
765fa29797SWarner Losh " devctl suspend device\n"
775fa29797SWarner Losh " devctl resume device\n"
785fa29797SWarner Losh " devctl set driver [-f] device driver\n"
795fa29797SWarner Losh " devctl clear driver [-f] device\n"
805fa29797SWarner Losh " devctl rescan device\n"
815fa29797SWarner Losh " devctl delete [-f] device\n"
825fa29797SWarner Losh " devctl freeze\n"
834fbf8e1cSKonstantin Belousov " devctl thaw\n"
844fbf8e1cSKonstantin Belousov " devctl reset [-d] device\n"
85*f5366026SWarner Losh " devctl getpath locator device\n"
864fbf8e1cSKonstantin Belousov );
8764de8019SJohn Baldwin exit(1);
8864de8019SJohn Baldwin }
8964de8019SJohn Baldwin
9064de8019SJohn Baldwin static int
devctl_table_handler(struct devctl_command ** start,struct devctl_command ** end,int ac,char ** av)9164de8019SJohn Baldwin devctl_table_handler(struct devctl_command **start,
9264de8019SJohn Baldwin struct devctl_command **end, int ac, char **av)
9364de8019SJohn Baldwin {
9464de8019SJohn Baldwin struct devctl_command **cmd;
9564de8019SJohn Baldwin
9664de8019SJohn Baldwin if (ac < 2) {
9764de8019SJohn Baldwin warnx("The %s command requires a sub-command.", av[0]);
9864de8019SJohn Baldwin return (EINVAL);
9964de8019SJohn Baldwin }
10064de8019SJohn Baldwin for (cmd = start; cmd < end; cmd++) {
10164de8019SJohn Baldwin if (strcmp((*cmd)->name, av[1]) == 0)
10264de8019SJohn Baldwin return ((*cmd)->handler(ac - 1, av + 1));
10364de8019SJohn Baldwin }
10464de8019SJohn Baldwin
10564de8019SJohn Baldwin warnx("%s is not a valid sub-command of %s.", av[1], av[0]);
10664de8019SJohn Baldwin return (ENOENT);
10764de8019SJohn Baldwin }
10864de8019SJohn Baldwin
10964de8019SJohn Baldwin static int
help(int ac __unused,char ** av __unused)11064de8019SJohn Baldwin help(int ac __unused, char **av __unused)
11164de8019SJohn Baldwin {
11264de8019SJohn Baldwin
11364de8019SJohn Baldwin usage();
11464de8019SJohn Baldwin return (0);
11564de8019SJohn Baldwin }
11664de8019SJohn Baldwin DEVCTL_COMMAND(top, help, help);
11764de8019SJohn Baldwin
11864de8019SJohn Baldwin static int
attach(int ac,char ** av)11964de8019SJohn Baldwin attach(int ac, char **av)
12064de8019SJohn Baldwin {
12164de8019SJohn Baldwin
12264de8019SJohn Baldwin if (ac != 2)
12364de8019SJohn Baldwin usage();
12464de8019SJohn Baldwin if (devctl_attach(av[1]) < 0)
12564de8019SJohn Baldwin err(1, "Failed to attach %s", av[1]);
12664de8019SJohn Baldwin return (0);
12764de8019SJohn Baldwin }
12864de8019SJohn Baldwin DEVCTL_COMMAND(top, attach, attach);
12964de8019SJohn Baldwin
13064de8019SJohn Baldwin static void
detach_usage(void)13164de8019SJohn Baldwin detach_usage(void)
13264de8019SJohn Baldwin {
13364de8019SJohn Baldwin
13464de8019SJohn Baldwin fprintf(stderr, "usage: devctl detach [-f] device\n");
13564de8019SJohn Baldwin exit(1);
13664de8019SJohn Baldwin }
13764de8019SJohn Baldwin
13864de8019SJohn Baldwin static int
detach(int ac,char ** av)13964de8019SJohn Baldwin detach(int ac, char **av)
14064de8019SJohn Baldwin {
14164de8019SJohn Baldwin bool force;
14264de8019SJohn Baldwin int ch;
14364de8019SJohn Baldwin
14464de8019SJohn Baldwin force = false;
14564de8019SJohn Baldwin while ((ch = getopt(ac, av, "f")) != -1)
14664de8019SJohn Baldwin switch (ch) {
14764de8019SJohn Baldwin case 'f':
14864de8019SJohn Baldwin force = true;
14964de8019SJohn Baldwin break;
15064de8019SJohn Baldwin default:
15164de8019SJohn Baldwin detach_usage();
15264de8019SJohn Baldwin }
15364de8019SJohn Baldwin ac -= optind;
15464de8019SJohn Baldwin av += optind;
15564de8019SJohn Baldwin
15664de8019SJohn Baldwin if (ac != 1)
15764de8019SJohn Baldwin detach_usage();
15864de8019SJohn Baldwin if (devctl_detach(av[0], force) < 0)
15964de8019SJohn Baldwin err(1, "Failed to detach %s", av[0]);
16064de8019SJohn Baldwin return (0);
16164de8019SJohn Baldwin }
16264de8019SJohn Baldwin DEVCTL_COMMAND(top, detach, detach);
16364de8019SJohn Baldwin
16464de8019SJohn Baldwin static void
disable_usage(void)16564de8019SJohn Baldwin disable_usage(void)
16664de8019SJohn Baldwin {
16764de8019SJohn Baldwin
16864de8019SJohn Baldwin fprintf(stderr, "usage: devctl disable [-f] device\n");
16964de8019SJohn Baldwin exit(1);
17064de8019SJohn Baldwin }
17164de8019SJohn Baldwin
17264de8019SJohn Baldwin static int
disable(int ac,char ** av)17364de8019SJohn Baldwin disable(int ac, char **av)
17464de8019SJohn Baldwin {
17564de8019SJohn Baldwin bool force;
17664de8019SJohn Baldwin int ch;
17764de8019SJohn Baldwin
17864de8019SJohn Baldwin force = false;
17964de8019SJohn Baldwin while ((ch = getopt(ac, av, "f")) != -1)
18064de8019SJohn Baldwin switch (ch) {
18164de8019SJohn Baldwin case 'f':
18264de8019SJohn Baldwin force = true;
18364de8019SJohn Baldwin break;
18464de8019SJohn Baldwin default:
18564de8019SJohn Baldwin disable_usage();
18664de8019SJohn Baldwin }
18764de8019SJohn Baldwin ac -= optind;
18864de8019SJohn Baldwin av += optind;
18964de8019SJohn Baldwin
19064de8019SJohn Baldwin if (ac != 1)
19164de8019SJohn Baldwin disable_usage();
19264de8019SJohn Baldwin if (devctl_disable(av[0], force) < 0)
19364de8019SJohn Baldwin err(1, "Failed to disable %s", av[0]);
19464de8019SJohn Baldwin return (0);
19564de8019SJohn Baldwin }
19664de8019SJohn Baldwin DEVCTL_COMMAND(top, disable, disable);
19764de8019SJohn Baldwin
19864de8019SJohn Baldwin static int
enable(int ac,char ** av)19964de8019SJohn Baldwin enable(int ac, char **av)
20064de8019SJohn Baldwin {
20164de8019SJohn Baldwin
20264de8019SJohn Baldwin if (ac != 2)
20364de8019SJohn Baldwin usage();
20464de8019SJohn Baldwin if (devctl_enable(av[1]) < 0)
20564de8019SJohn Baldwin err(1, "Failed to enable %s", av[1]);
20664de8019SJohn Baldwin return (0);
20764de8019SJohn Baldwin }
20864de8019SJohn Baldwin DEVCTL_COMMAND(top, enable, enable);
20964de8019SJohn Baldwin
21064de8019SJohn Baldwin static int
suspend(int ac,char ** av)21164de8019SJohn Baldwin suspend(int ac, char **av)
21264de8019SJohn Baldwin {
21364de8019SJohn Baldwin
21464de8019SJohn Baldwin if (ac != 2)
21564de8019SJohn Baldwin usage();
21664de8019SJohn Baldwin if (devctl_suspend(av[1]) < 0)
21764de8019SJohn Baldwin err(1, "Failed to suspend %s", av[1]);
21864de8019SJohn Baldwin return (0);
21964de8019SJohn Baldwin }
22064de8019SJohn Baldwin DEVCTL_COMMAND(top, suspend, suspend);
22164de8019SJohn Baldwin
22264de8019SJohn Baldwin static int
resume(int ac,char ** av)22364de8019SJohn Baldwin resume(int ac, char **av)
22464de8019SJohn Baldwin {
22564de8019SJohn Baldwin
22664de8019SJohn Baldwin if (ac != 2)
22764de8019SJohn Baldwin usage();
22864de8019SJohn Baldwin if (devctl_resume(av[1]) < 0)
22964de8019SJohn Baldwin err(1, "Failed to resume %s", av[1]);
23064de8019SJohn Baldwin return (0);
23164de8019SJohn Baldwin }
23264de8019SJohn Baldwin DEVCTL_COMMAND(top, resume, resume);
23364de8019SJohn Baldwin
23464de8019SJohn Baldwin static void
set_driver_usage(void)23564de8019SJohn Baldwin set_driver_usage(void)
23664de8019SJohn Baldwin {
23764de8019SJohn Baldwin
23864de8019SJohn Baldwin fprintf(stderr, "usage: devctl set driver [-f] device driver\n");
23964de8019SJohn Baldwin exit(1);
24064de8019SJohn Baldwin }
24164de8019SJohn Baldwin
24264de8019SJohn Baldwin static int
set_driver(int ac,char ** av)24364de8019SJohn Baldwin set_driver(int ac, char **av)
24464de8019SJohn Baldwin {
24564de8019SJohn Baldwin bool force;
24664de8019SJohn Baldwin int ch;
24764de8019SJohn Baldwin
24864de8019SJohn Baldwin force = false;
24964de8019SJohn Baldwin while ((ch = getopt(ac, av, "f")) != -1)
25064de8019SJohn Baldwin switch (ch) {
25164de8019SJohn Baldwin case 'f':
25264de8019SJohn Baldwin force = true;
25364de8019SJohn Baldwin break;
25464de8019SJohn Baldwin default:
25564de8019SJohn Baldwin set_driver_usage();
25664de8019SJohn Baldwin }
25764de8019SJohn Baldwin ac -= optind;
25864de8019SJohn Baldwin av += optind;
25964de8019SJohn Baldwin
26064de8019SJohn Baldwin if (ac != 2)
26164de8019SJohn Baldwin set_driver_usage();
26264de8019SJohn Baldwin if (devctl_set_driver(av[0], av[1], force) < 0)
26364de8019SJohn Baldwin err(1, "Failed to set %s driver to %s", av[0], av[1]);
26464de8019SJohn Baldwin return (0);
26564de8019SJohn Baldwin }
26664de8019SJohn Baldwin DEVCTL_COMMAND(set, driver, set_driver);
26764de8019SJohn Baldwin
268e05ec081SJohn Baldwin static void
clear_driver_usage(void)269e05ec081SJohn Baldwin clear_driver_usage(void)
270e05ec081SJohn Baldwin {
271e05ec081SJohn Baldwin
272e05ec081SJohn Baldwin fprintf(stderr, "usage: devctl clear driver [-f] device\n");
273e05ec081SJohn Baldwin exit(1);
274e05ec081SJohn Baldwin }
275e05ec081SJohn Baldwin
276e05ec081SJohn Baldwin static int
clear_driver(int ac,char ** av)277e05ec081SJohn Baldwin clear_driver(int ac, char **av)
278e05ec081SJohn Baldwin {
279e05ec081SJohn Baldwin bool force;
280e05ec081SJohn Baldwin int ch;
281e05ec081SJohn Baldwin
282e05ec081SJohn Baldwin force = false;
283e05ec081SJohn Baldwin while ((ch = getopt(ac, av, "f")) != -1)
284e05ec081SJohn Baldwin switch (ch) {
285e05ec081SJohn Baldwin case 'f':
286e05ec081SJohn Baldwin force = true;
287e05ec081SJohn Baldwin break;
288e05ec081SJohn Baldwin default:
289e05ec081SJohn Baldwin clear_driver_usage();
290e05ec081SJohn Baldwin }
291e05ec081SJohn Baldwin ac -= optind;
292e05ec081SJohn Baldwin av += optind;
293e05ec081SJohn Baldwin
294e05ec081SJohn Baldwin if (ac != 1)
295e05ec081SJohn Baldwin clear_driver_usage();
296e05ec081SJohn Baldwin if (devctl_clear_driver(av[0], force) < 0)
297e05ec081SJohn Baldwin err(1, "Failed to clear %s driver", av[0]);
298e05ec081SJohn Baldwin return (0);
299e05ec081SJohn Baldwin }
300e05ec081SJohn Baldwin DEVCTL_COMMAND(clear, driver, clear_driver);
301e05ec081SJohn Baldwin
302a907c691SJohn Baldwin static int
rescan(int ac,char ** av)303a907c691SJohn Baldwin rescan(int ac, char **av)
304a907c691SJohn Baldwin {
305a907c691SJohn Baldwin
306a907c691SJohn Baldwin if (ac != 2)
307a907c691SJohn Baldwin usage();
308a907c691SJohn Baldwin if (devctl_rescan(av[1]) < 0)
309a907c691SJohn Baldwin err(1, "Failed to rescan %s", av[1]);
310a907c691SJohn Baldwin return (0);
311a907c691SJohn Baldwin }
312a907c691SJohn Baldwin DEVCTL_COMMAND(top, rescan, rescan);
313a907c691SJohn Baldwin
31488eb5c50SJohn Baldwin static void
delete_usage(void)31588eb5c50SJohn Baldwin delete_usage(void)
31688eb5c50SJohn Baldwin {
31788eb5c50SJohn Baldwin
31888eb5c50SJohn Baldwin fprintf(stderr, "usage: devctl delete [-f] device\n");
31988eb5c50SJohn Baldwin exit(1);
32088eb5c50SJohn Baldwin }
32188eb5c50SJohn Baldwin
32288eb5c50SJohn Baldwin static int
delete(int ac,char ** av)32388eb5c50SJohn Baldwin delete(int ac, char **av)
32488eb5c50SJohn Baldwin {
32588eb5c50SJohn Baldwin bool force;
32688eb5c50SJohn Baldwin int ch;
32788eb5c50SJohn Baldwin
32888eb5c50SJohn Baldwin force = false;
32988eb5c50SJohn Baldwin while ((ch = getopt(ac, av, "f")) != -1)
33088eb5c50SJohn Baldwin switch (ch) {
33188eb5c50SJohn Baldwin case 'f':
33288eb5c50SJohn Baldwin force = true;
33388eb5c50SJohn Baldwin break;
33488eb5c50SJohn Baldwin default:
33588eb5c50SJohn Baldwin delete_usage();
33688eb5c50SJohn Baldwin }
33788eb5c50SJohn Baldwin ac -= optind;
33888eb5c50SJohn Baldwin av += optind;
33988eb5c50SJohn Baldwin
34088eb5c50SJohn Baldwin if (ac != 1)
34188eb5c50SJohn Baldwin delete_usage();
34288eb5c50SJohn Baldwin if (devctl_delete(av[0], force) < 0)
34388eb5c50SJohn Baldwin err(1, "Failed to delete %s", av[0]);
34488eb5c50SJohn Baldwin return (0);
34588eb5c50SJohn Baldwin }
34688eb5c50SJohn Baldwin DEVCTL_COMMAND(top, delete, delete);
34788eb5c50SJohn Baldwin
3485fa29797SWarner Losh static void
freeze_usage(void)3495fa29797SWarner Losh freeze_usage(void)
3505fa29797SWarner Losh {
3515fa29797SWarner Losh
3525fa29797SWarner Losh fprintf(stderr, "usage: devctl freeze\n");
3535fa29797SWarner Losh exit(1);
3545fa29797SWarner Losh }
3555fa29797SWarner Losh
3565fa29797SWarner Losh static int
freeze(int ac,char ** av __unused)3575fa29797SWarner Losh freeze(int ac, char **av __unused)
3585fa29797SWarner Losh {
3595fa29797SWarner Losh
3605fa29797SWarner Losh if (ac != 1)
3615fa29797SWarner Losh freeze_usage();
3625fa29797SWarner Losh if (devctl_freeze() < 0)
3635fa29797SWarner Losh err(1, "Failed to freeze probe/attach");
3645fa29797SWarner Losh return (0);
3655fa29797SWarner Losh }
3665fa29797SWarner Losh DEVCTL_COMMAND(top, freeze, freeze);
3675fa29797SWarner Losh
3685fa29797SWarner Losh static void
thaw_usage(void)3695fa29797SWarner Losh thaw_usage(void)
3705fa29797SWarner Losh {
3715fa29797SWarner Losh
3725fa29797SWarner Losh fprintf(stderr, "usage: devctl thaw\n");
3735fa29797SWarner Losh exit(1);
3745fa29797SWarner Losh }
3755fa29797SWarner Losh
3765fa29797SWarner Losh static int
thaw(int ac,char ** av __unused)3775fa29797SWarner Losh thaw(int ac, char **av __unused)
3785fa29797SWarner Losh {
3795fa29797SWarner Losh
3805fa29797SWarner Losh if (ac != 1)
3815fa29797SWarner Losh thaw_usage();
3825fa29797SWarner Losh if (devctl_thaw() < 0)
3835fa29797SWarner Losh err(1, "Failed to thaw probe/attach");
3845fa29797SWarner Losh return (0);
3855fa29797SWarner Losh }
3865fa29797SWarner Losh DEVCTL_COMMAND(top, thaw, thaw);
3875fa29797SWarner Losh
3884fbf8e1cSKonstantin Belousov static void
reset_usage(void)3894fbf8e1cSKonstantin Belousov reset_usage(void)
3904fbf8e1cSKonstantin Belousov {
3914fbf8e1cSKonstantin Belousov
3924fbf8e1cSKonstantin Belousov fprintf(stderr, "usage: devctl reset [-d] device\n");
3934fbf8e1cSKonstantin Belousov exit(1);
3944fbf8e1cSKonstantin Belousov }
3954fbf8e1cSKonstantin Belousov
3964fbf8e1cSKonstantin Belousov static int
reset(int ac,char ** av)3974fbf8e1cSKonstantin Belousov reset(int ac, char **av)
3984fbf8e1cSKonstantin Belousov {
399ca34d6aeSKonstantin Belousov bool detach_drv;
4004fbf8e1cSKonstantin Belousov int ch;
4014fbf8e1cSKonstantin Belousov
402ca34d6aeSKonstantin Belousov detach_drv = false;
4034fbf8e1cSKonstantin Belousov while ((ch = getopt(ac, av, "d")) != -1)
4044fbf8e1cSKonstantin Belousov switch (ch) {
4054fbf8e1cSKonstantin Belousov case 'd':
406ca34d6aeSKonstantin Belousov detach_drv = true;
4074fbf8e1cSKonstantin Belousov break;
4084fbf8e1cSKonstantin Belousov default:
4094fbf8e1cSKonstantin Belousov reset_usage();
4104fbf8e1cSKonstantin Belousov }
4114fbf8e1cSKonstantin Belousov ac -= optind;
4124fbf8e1cSKonstantin Belousov av += optind;
4134fbf8e1cSKonstantin Belousov
4144fbf8e1cSKonstantin Belousov if (ac != 1)
4154fbf8e1cSKonstantin Belousov reset_usage();
416ca34d6aeSKonstantin Belousov if (devctl_reset(av[0], detach_drv) < 0)
4174fbf8e1cSKonstantin Belousov err(1, "Failed to reset %s", av[0]);
4184fbf8e1cSKonstantin Belousov return (0);
4194fbf8e1cSKonstantin Belousov }
4204fbf8e1cSKonstantin Belousov DEVCTL_COMMAND(top, reset, reset);
4214fbf8e1cSKonstantin Belousov
422*f5366026SWarner Losh static int
getpath(int ac,char ** av)423*f5366026SWarner Losh getpath(int ac, char **av)
424*f5366026SWarner Losh {
425*f5366026SWarner Losh char *buffer = NULL;
426*f5366026SWarner Losh
427*f5366026SWarner Losh if (ac != 3)
428*f5366026SWarner Losh usage();
429*f5366026SWarner Losh if (devctl_getpath(av[2], av[1], &buffer) < 0)
430*f5366026SWarner Losh err(1, "Failed to get path via %s to %s", av[1], av[2]);
431*f5366026SWarner Losh printf("%s\n", buffer);
432*f5366026SWarner Losh free(buffer);
433*f5366026SWarner Losh return (0);
434*f5366026SWarner Losh }
435*f5366026SWarner Losh DEVCTL_COMMAND(top, getpath, getpath);
436*f5366026SWarner Losh
43764de8019SJohn Baldwin int
main(int ac,char * av[])43864de8019SJohn Baldwin main(int ac, char *av[])
43964de8019SJohn Baldwin {
44064de8019SJohn Baldwin struct devctl_command **cmd;
44164de8019SJohn Baldwin
44264de8019SJohn Baldwin if (ac == 1)
44364de8019SJohn Baldwin usage();
44464de8019SJohn Baldwin ac--;
44564de8019SJohn Baldwin av++;
44664de8019SJohn Baldwin
44764de8019SJohn Baldwin SET_FOREACH(cmd, DEVCTL_DATASET(top)) {
44864de8019SJohn Baldwin if (strcmp((*cmd)->name, av[0]) == 0) {
44964de8019SJohn Baldwin if ((*cmd)->handler(ac, av) != 0)
45064de8019SJohn Baldwin return (1);
45164de8019SJohn Baldwin else
45264de8019SJohn Baldwin return (0);
45364de8019SJohn Baldwin }
45464de8019SJohn Baldwin }
45564de8019SJohn Baldwin warnx("Unknown command %s.", av[0]);
45664de8019SJohn Baldwin return (1);
45764de8019SJohn Baldwin }
458