source: mainline/uspace/app/devctl/devctl.c@ 1db5669

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1db5669 was 1db5669, checked in by Jiri Svoboda <jiri@…>, 12 years ago

devctl show-drv lists attached devices, add device count to list-drv.

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