source: mainline/uspace/app/devctl/devctl.c@ 8edec53

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8edec53 was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup devctl
30 * @{
31 */
32/** @file Control device framework (devman server).
33 */
34
35#include <devman.h>
36#include <errno.h>
37#include <io/table.h>
38#include <stdbool.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <str.h>
42#include <str_error.h>
43
44#define NAME "devctl"
45
46#define MAX_NAME_LENGTH 1024
47
48static char name[MAX_NAME_LENGTH];
49static char drv_name[MAX_NAME_LENGTH];
50static bool verbose = false;
51
52static const char *drv_state_str(driver_state_t state)
53{
54 const char *sstate;
55
56 switch (state) {
57 case DRIVER_NOT_STARTED:
58 sstate = "not started";
59 break;
60 case DRIVER_STARTING:
61 sstate = "starting";
62 break;
63 case DRIVER_RUNNING:
64 sstate = "running";
65 break;
66 default:
67 sstate = "unknown";
68 }
69
70 return sstate;
71}
72
73static errno_t fun_subtree_print(devman_handle_t funh, int lvl)
74{
75 devman_handle_t devh;
76 devman_handle_t *cfuns;
77 size_t count, i;
78 unsigned int score;
79 errno_t rc;
80 int j;
81
82 for (j = 0; j < lvl; j++)
83 printf(" ");
84
85 rc = devman_fun_get_name(funh, name, MAX_NAME_LENGTH);
86 if (rc != EOK)
87 return ELIMIT;
88
89 if (name[0] == '\0')
90 str_cpy(name, MAX_NAME_LENGTH, "/");
91
92 rc = devman_fun_get_driver_name(funh, drv_name, MAX_NAME_LENGTH);
93 if (rc != EOK && rc != EINVAL)
94 return ELIMIT;
95
96 if (rc == EINVAL)
97 printf("%s\n", name);
98 else
99 printf("%s : %s\n", name, drv_name);
100
101 if (verbose) {
102 for (i = 0; true; i++) {
103 rc = devman_fun_get_match_id(funh, i, name, MAX_NAME_LENGTH,
104 &score);
105 if (rc != EOK)
106 break;
107
108 for (j = 0; j < lvl; j++)
109 printf(" ");
110
111 printf(" %u %s\n", score, name);
112 }
113 }
114
115 rc = devman_fun_get_child(funh, &devh);
116 if (rc == ENOENT)
117 return EOK;
118
119 if (rc != EOK) {
120 printf(NAME ": Failed getting child device for function "
121 "%s.\n", "xxx");
122 return rc;
123 }
124
125 rc = devman_dev_get_functions(devh, &cfuns, &count);
126 if (rc != EOK) {
127 printf(NAME ": Failed getting list of functions for "
128 "device %s.\n", "xxx");
129 return rc;
130 }
131
132 for (i = 0; i < count; i++)
133 fun_subtree_print(cfuns[i], lvl + 1);
134
135 free(cfuns);
136 return EOK;
137}
138
139static errno_t fun_tree_print(void)
140{
141 devman_handle_t root_fun;
142 errno_t rc;
143
144 rc = devman_fun_get_handle("/", &root_fun, 0);
145 if (rc != EOK) {
146 printf(NAME ": Error resolving root function.\n");
147 return EIO;
148 }
149
150 rc = fun_subtree_print(root_fun, 0);
151 if (rc != EOK)
152 return EIO;
153
154 return EOK;
155}
156
157static errno_t fun_online(const char *path)
158{
159 devman_handle_t funh;
160 errno_t rc;
161
162 rc = devman_fun_get_handle(path, &funh, 0);
163 if (rc != EOK) {
164 printf(NAME ": Error resolving device function '%s' (%s)\n",
165 path, str_error(rc));
166 return rc;
167 }
168
169 rc = devman_fun_online(funh);
170 if (rc != EOK) {
171 printf(NAME ": Failed to online function '%s'.\n", path);
172 return rc;
173 }
174
175 return EOK;
176}
177
178static errno_t fun_offline(const char *path)
179{
180 devman_handle_t funh;
181 errno_t rc;
182
183 rc = devman_fun_get_handle(path, &funh, 0);
184 if (rc != EOK) {
185 printf(NAME ": Error resolving device function '%s' (%s)\n",
186 path, str_error(rc));
187 return rc;
188 }
189
190 rc = devman_fun_offline(funh);
191 if (rc != EOK) {
192 printf(NAME ": Failed to offline function '%s' (%s)\n", path,
193 str_error(rc));
194 return rc;
195 }
196
197 return EOK;
198}
199
200static errno_t drv_list(void)
201{
202 devman_handle_t *devs;
203 devman_handle_t *drvs;
204 driver_state_t state;
205 const char *sstate;
206 size_t ndrvs;
207 size_t ndevs;
208 size_t i;
209 table_t *table = NULL;
210 errno_t rc;
211
212 rc = devman_get_drivers(&drvs, &ndrvs);
213 if (rc != EOK)
214 return rc;
215
216 rc = table_create(&table);
217 if (rc != EOK) {
218 assert(rc == ENOMEM);
219 goto out;
220 }
221
222 table_header_row(table);
223 table_printf(table, "Driver\t" "Devs\t" "State\n");
224
225 for (i = 0; i < ndrvs; i++) {
226 devs = NULL;
227
228 rc = devman_driver_get_name(drvs[i], drv_name, MAX_NAME_LENGTH);
229 if (rc != EOK)
230 goto skip;
231 rc = devman_driver_get_state(drvs[i], &state);
232 if (rc != EOK)
233 goto skip;
234 rc = devman_driver_get_devices(drvs[i], &devs, &ndevs);
235 if (rc != EOK)
236 goto skip;
237
238 sstate = drv_state_str(state);
239
240 table_printf(table, "%s\t" "%zu\t" "%s\n", drv_name, ndevs, sstate);
241 skip:
242 free(devs);
243 }
244
245 rc = table_print_out(table, stdout);
246 if (rc != EOK)
247 printf("Error printing driver table.\n");
248out:
249 free(drvs);
250 table_destroy(table);
251
252 return rc;
253}
254
255static errno_t drv_show(char *drvname)
256{
257 devman_handle_t *devs;
258 devman_handle_t drvh;
259 devman_handle_t funh;
260 driver_state_t state;
261 const char *sstate;
262 unsigned int score;
263 size_t ndevs;
264 size_t i;
265 errno_t rc;
266
267 rc = devman_driver_get_handle(drvname, &drvh);
268 if (rc != EOK)
269 return rc;
270
271 devs = NULL;
272
273 rc = devman_driver_get_name(drvh, drv_name, MAX_NAME_LENGTH);
274 if (rc != EOK)
275 return rc;
276
277 rc = devman_driver_get_state(drvh, &state);
278 if (rc != EOK)
279 return rc;
280
281 rc = devman_driver_get_devices(drvh, &devs, &ndevs);
282 if (rc != EOK)
283 return rc;
284
285 sstate = drv_state_str(state);
286
287 printf("Driver: %s\n", drv_name);
288 printf("State: %s\n", sstate);
289
290 printf("Attached devices:\n");
291
292 for (i = 0; i < ndevs; i++) {
293 rc = devman_dev_get_parent(devs[i], &funh);
294 if (rc != EOK)
295 goto error;
296
297 rc = devman_fun_get_path(funh, name, MAX_NAME_LENGTH);
298 if (rc != EOK)
299 goto error;
300 printf("\t%s\n", name);
301 }
302
303 printf("Match IDs:\n");
304
305 for (i = 0; true; i++) {
306 rc = devman_driver_get_match_id(drvh, i, name, MAX_NAME_LENGTH,
307 &score);
308 if (rc != EOK)
309 break;
310
311 printf("\t%u %s\n", score, name);
312 }
313
314error:
315 free(devs);
316
317 return EOK;
318}
319
320static errno_t drv_load(const char *drvname)
321{
322 errno_t rc;
323 devman_handle_t drvh;
324
325 rc = devman_driver_get_handle(drvname, &drvh);
326 if (rc != EOK) {
327 printf("Failed resolving driver '%s': %s.\n", drvname, str_error(rc));
328 return rc;
329 }
330
331 rc = devman_driver_load(drvh);
332 if (rc != EOK) {
333 printf("Failed loading driver '%s': %s.\n", drvname, str_error(rc));
334 return rc;
335 }
336
337 return EOK;
338}
339
340static errno_t drv_unload(const char *drvname)
341{
342 errno_t rc;
343 devman_handle_t drvh;
344
345 rc = devman_driver_get_handle(drvname, &drvh);
346 if (rc != EOK) {
347 printf("Failed resolving driver '%s': %s.\n", drvname, str_error(rc));
348 return rc;
349 }
350
351 rc = devman_driver_unload(drvh);
352 if (rc != EOK) {
353 printf("Failed unloading driver '%s': %s.\n", drvname, str_error(rc));
354 return rc;
355 }
356
357 return EOK;
358}
359
360static void print_syntax(void)
361{
362 printf("syntax:\n");
363 printf("\tdevctl\n");
364 printf("\tdevctl online <function>]\n");
365 printf("\tdevctl offline <function>]\n");
366 printf("\tdevctl list-drv\n");
367 printf("\tdevctl show-drv <driver-name>\n");
368 printf("\tdevctl load-drv <driver-name>\n");
369 printf("\tdevctl unload-drv <driver-name>\n");
370}
371
372int main(int argc, char *argv[])
373{
374 errno_t rc;
375
376 if (argc == 1 || argv[1][0] == '-') {
377 if (argc > 1) {
378 if (str_cmp(argv[1], "-v") == 0) {
379 verbose = true;
380 } else {
381 printf(NAME ": Invalid argument '%s'\n", argv[1]);
382 print_syntax();
383 return 1;
384 }
385 }
386 rc = fun_tree_print();
387 if (rc != EOK)
388 return 2;
389 } else if (str_cmp(argv[1], "online") == 0) {
390 if (argc < 3) {
391 printf(NAME ": Argument missing.\n");
392 print_syntax();
393 return 1;
394 }
395
396 rc = fun_online(argv[2]);
397 if (rc != EOK) {
398 return 2;
399 }
400 } else if (str_cmp(argv[1], "offline") == 0) {
401 if (argc < 3) {
402 printf(NAME ": Argument missing.\n");
403 print_syntax();
404 return 1;
405 }
406
407 rc = fun_offline(argv[2]);
408 if (rc != EOK) {
409 return 2;
410 }
411 } else if (str_cmp(argv[1], "list-drv") == 0) {
412 rc = drv_list();
413 if (rc != EOK)
414 return 2;
415 } else if (str_cmp(argv[1], "show-drv") == 0) {
416 if (argc < 3) {
417 printf(NAME ": Argument missing.\n");
418 print_syntax();
419 return 1;
420 }
421
422 rc = drv_show(argv[2]);
423 if (rc != EOK) {
424 return 2;
425 }
426 } else if (str_cmp(argv[1], "load-drv") == 0) {
427 if (argc < 3) {
428 printf(NAME ": Argument missing.\n");
429 print_syntax();
430 return 1;
431 }
432
433 rc = drv_load(argv[2]);
434 if (rc != EOK)
435 return 2;
436 } else if (str_cmp(argv[1], "unload-drv") == 0) {
437 if (argc < 3) {
438 printf(NAME ": Argument missing.\n");
439 print_syntax();
440 return 1;
441 }
442
443 rc = drv_unload(argv[2]);
444 if (rc != EOK)
445 return 2;
446 } else {
447 printf(NAME ": Invalid argument '%s'.\n", argv[1]);
448 print_syntax();
449 return 1;
450 }
451
452 return 0;
453}
454
455/** @}
456 */
Note: See TracBrowser for help on using the repository browser.