source: mainline/uspace/app/devctl/devctl.c@ 120d5bc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 120d5bc was 7354b5e, checked in by Jakub Jermar <jakub@…>, 8 years ago

Remove sys/typefmt.h

  • Property mode set to 100644
File size: 8.2 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 <stdbool.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <str_error.h>
41
42#define NAME "devctl"
43
44#define MAX_NAME_LENGTH 1024
45
46static char name[MAX_NAME_LENGTH];
47static char drv_name[MAX_NAME_LENGTH];
48static bool verbose = false;
49
50static const char *drv_state_str(driver_state_t state)
51{
52 const char *sstate;
53
54 switch (state) {
55 case DRIVER_NOT_STARTED:
56 sstate = "not started";
57 break;
58 case DRIVER_STARTING:
59 sstate = "starting";
60 break;
61 case DRIVER_RUNNING:
62 sstate = "running";
63 break;
64 default:
65 sstate = "unknown";
66 }
67
68 return sstate;
69}
70
71static int fun_subtree_print(devman_handle_t funh, int lvl)
72{
73 devman_handle_t devh;
74 devman_handle_t *cfuns;
75 size_t count, i;
76 unsigned int score;
77 int rc;
78 int j;
79
80 for (j = 0; j < lvl; j++)
81 printf(" ");
82
83 rc = devman_fun_get_name(funh, name, MAX_NAME_LENGTH);
84 if (rc != EOK)
85 return ELIMIT;
86
87 if (name[0] == '\0')
88 str_cpy(name, MAX_NAME_LENGTH, "/");
89
90 rc = devman_fun_get_driver_name(funh, drv_name, MAX_NAME_LENGTH);
91 if (rc != EOK && rc != EINVAL)
92 return ELIMIT;
93
94 if (rc == EINVAL)
95 printf("%s\n", name);
96 else
97 printf("%s : %s\n", name, drv_name);
98
99 if (verbose) {
100 for (i = 0; true; i++) {
101 rc = devman_fun_get_match_id(funh, i, name, MAX_NAME_LENGTH,
102 &score);
103 if (rc != EOK)
104 break;
105
106 for (j = 0; j < lvl; j++)
107 printf(" ");
108
109 printf(" %u %s\n", score, name);
110 }
111 }
112
113 rc = devman_fun_get_child(funh, &devh);
114 if (rc == ENOENT)
115 return EOK;
116
117 if (rc != EOK) {
118 printf(NAME ": Failed getting child device for function "
119 "%s.\n", "xxx");
120 return rc;
121 }
122
123 rc = devman_dev_get_functions(devh, &cfuns, &count);
124 if (rc != EOK) {
125 printf(NAME ": Failed getting list of functions for "
126 "device %s.\n", "xxx");
127 return rc;
128 }
129
130 for (i = 0; i < count; i++)
131 fun_subtree_print(cfuns[i], lvl + 1);
132
133 free(cfuns);
134 return EOK;
135}
136
137static int fun_tree_print(void)
138{
139 devman_handle_t root_fun;
140 int rc;
141
142 rc = devman_fun_get_handle("/", &root_fun, 0);
143 if (rc != EOK) {
144 printf(NAME ": Error resolving root function.\n");
145 return EIO;
146 }
147
148 rc = fun_subtree_print(root_fun, 0);
149 if (rc != EOK)
150 return EIO;
151
152 return EOK;
153}
154
155static int fun_online(const char *path)
156{
157 devman_handle_t funh;
158 int rc;
159
160 rc = devman_fun_get_handle(path, &funh, 0);
161 if (rc != EOK) {
162 printf(NAME ": Error resolving device function '%s' (%s)\n",
163 path, str_error(rc));
164 return rc;
165 }
166
167 rc = devman_fun_online(funh);
168 if (rc != EOK) {
169 printf(NAME ": Failed to online function '%s'.\n", path);
170 return rc;
171 }
172
173 return EOK;
174}
175
176static int fun_offline(const char *path)
177{
178 devman_handle_t funh;
179 int rc;
180
181 rc = devman_fun_get_handle(path, &funh, 0);
182 if (rc != EOK) {
183 printf(NAME ": Error resolving device function '%s' (%s)\n",
184 path, str_error(rc));
185 return rc;
186 }
187
188 rc = devman_fun_offline(funh);
189 if (rc != EOK) {
190 printf(NAME ": Failed to offline function '%s' (%s)\n", path,
191 str_error(rc));
192 return rc;
193 }
194
195 return EOK;
196}
197
198static int drv_list(void)
199{
200 devman_handle_t *devs;
201 devman_handle_t *drvs;
202 driver_state_t state;
203 const char *sstate;
204 size_t ndrvs;
205 size_t ndevs;
206 size_t i;
207 int rc;
208
209 rc = devman_get_drivers(&drvs, &ndrvs);
210 if (rc != EOK)
211 return rc;
212
213 for (i = 0; i < ndrvs; i++) {
214 devs = NULL;
215
216 rc = devman_driver_get_name(drvs[i], drv_name, MAX_NAME_LENGTH);
217 if (rc != EOK)
218 goto skip;
219 rc = devman_driver_get_state(drvs[i], &state);
220 if (rc != EOK)
221 goto skip;
222 rc = devman_driver_get_devices(drvs[i], &devs, &ndevs);
223 if (rc != EOK)
224 goto skip;
225
226 sstate = drv_state_str(state);
227
228 printf("%-11s %3zu %s\n", sstate, ndevs, drv_name);
229skip:
230 free(devs);
231 }
232 free(drvs);
233
234 return EOK;
235}
236
237static int drv_show(char *drvname)
238{
239 devman_handle_t *devs;
240 devman_handle_t drvh;
241 devman_handle_t funh;
242 driver_state_t state;
243 const char *sstate;
244 unsigned int score;
245 size_t ndevs;
246 size_t i;
247 int rc;
248
249 rc = devman_driver_get_handle(drvname, &drvh);
250 if (rc != EOK)
251 return rc;
252
253 devs = NULL;
254
255 rc = devman_driver_get_name(drvh, drv_name, MAX_NAME_LENGTH);
256 if (rc != EOK)
257 return rc;
258
259 rc = devman_driver_get_state(drvh, &state);
260 if (rc != EOK)
261 return rc;
262
263 rc = devman_driver_get_devices(drvh, &devs, &ndevs);
264 if (rc != EOK)
265 return rc;
266
267 sstate = drv_state_str(state);
268
269 printf("Driver: %s\n", drv_name);
270 printf("State: %s\n", sstate);
271
272 printf("Attached devices:\n");
273
274 for (i = 0; i < ndevs; i++) {
275 rc = devman_dev_get_parent(devs[i], &funh);
276 if (rc != EOK)
277 goto error;
278
279 rc = devman_fun_get_path(funh, name, MAX_NAME_LENGTH);
280 if (rc != EOK)
281 goto error;
282 printf("\t%s\n", name);
283 }
284
285 printf("Match IDs:\n");
286
287 for (i = 0; true; i++) {
288 rc = devman_driver_get_match_id(drvh, i, name, MAX_NAME_LENGTH,
289 &score);
290 if (rc != EOK)
291 break;
292
293 printf("\t%u %s\n", score, name);
294 }
295
296error:
297 free(devs);
298
299 return EOK;
300}
301
302static int drv_load(const char *drvname)
303{
304 int rc;
305 devman_handle_t drvh;
306
307 rc = devman_driver_get_handle(drvname, &drvh);
308 if (rc != EOK) {
309 printf("Failed resolving driver '%s' (%d).\n", drvname, rc);
310 return rc;
311 }
312
313 rc = devman_driver_load(drvh);
314 if (rc != EOK) {
315 printf("Failed loading driver '%s' (%d).\n", drvname, rc);
316 return rc;
317 }
318
319 return EOK;
320}
321
322static void print_syntax(void)
323{
324 printf("syntax:\n");
325 printf("\tdevctl\n");
326 printf("\tdevctl online <function>]\n");
327 printf("\tdevctl offline <function>]\n");
328 printf("\tdevctl list-drv\n");
329 printf("\tdevctl show-drv <driver-name>\n");
330 printf("\tdevctl load-drv <driver-name>\n");
331}
332
333int main(int argc, char *argv[])
334{
335 int rc;
336
337 if (argc == 1 || argv[1][0] == '-') {
338 if (argc > 1) {
339 if (str_cmp(argv[1], "-v") == 0) {
340 verbose = true;
341 } else {
342 printf(NAME ": Invalid argument '%s'\n", argv[1]);
343 print_syntax();
344 return 1;
345 }
346 }
347 rc = fun_tree_print();
348 if (rc != EOK)
349 return 2;
350 } else if (str_cmp(argv[1], "online") == 0) {
351 if (argc < 3) {
352 printf(NAME ": Argument missing.\n");
353 print_syntax();
354 return 1;
355 }
356
357 rc = fun_online(argv[2]);
358 if (rc != EOK) {
359 return 2;
360 }
361 } else if (str_cmp(argv[1], "offline") == 0) {
362 if (argc < 3) {
363 printf(NAME ": Argument missing.\n");
364 print_syntax();
365 return 1;
366 }
367
368 rc = fun_offline(argv[2]);
369 if (rc != EOK) {
370 return 2;
371 }
372 } else if (str_cmp(argv[1], "list-drv") == 0) {
373 rc = drv_list();
374 if (rc != EOK)
375 return 2;
376 } else if (str_cmp(argv[1], "show-drv") == 0) {
377 if (argc < 3) {
378 printf(NAME ": Argument missing.\n");
379 print_syntax();
380 return 1;
381 }
382
383 rc = drv_show(argv[2]);
384 if (rc != EOK) {
385 return 2;
386 }
387 } else if (str_cmp(argv[1], "load-drv") == 0) {
388 if (argc < 3) {
389 printf(NAME ": Argument missing.\n");
390 print_syntax();
391 return 1;
392 }
393
394 rc = drv_load(argv[2]);
395 if (rc != EOK)
396 return 2;
397 } else {
398 printf(NAME ": Invalid argument '%s'.\n", argv[1]);
399 print_syntax();
400 return 1;
401 }
402
403 return 0;
404}
405
406/** @}
407 */
Note: See TracBrowser for help on using the repository browser.