source: rtems/cpukit/libmisc/shell/main_drvmgr.c @ 219d4045

4.115
Last change on this file since 219d4045 was 219d4045, checked in by Daniel Hellstrom <daniel@…>, on Nov 28, 2011 at 9:28:23 AM

DRVMGR: added drvmgr shell command

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*
2 * DRVMGR Command Implementation
3 *
4 * COPYRIGHT (c) 2010.
5 * Cobham Gaisler AB.
6 *
7 * The license and distribution terms for this file may be
8 * found in the file LICENSE in this distribution or at
9 * http://www.rtems.com/license/LICENSE.
10 */
11
12#ifdef HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19#include <errno.h>
20#include <drvmgr/drvmgr.h>
21
22#include <rtems.h>
23#include <rtems/shell.h>
24#include "internal.h"
25
26static void usage(void);
27
28static void *get_obj_adr(char *arg)
29{
30  unsigned long obj_adr;
31
32  obj_adr = strtoul(arg, NULL, 16);
33  if (obj_adr == ULONG_MAX || obj_adr == 0) {
34    puts(" Not a valid ID");
35    return NULL;
36  }
37
38  return (void *)obj_adr;
39}
40
41/* General info, root bus, number of devices etc. */
42static void show_drvmgr_info(void)
43{
44  drvmgr_summary();
45  drvmgr_print_devs(PRINT_DEVS_ALL);
46}
47
48static int shell_drvmgr_topo(int argc, char *argv[])
49{
50  drvmgr_print_topo();
51  return 0;
52}
53
54static int shell_drvmgr_short(int argc, char *argv[])
55{
56  void *obj;
57
58  if (argc < 2)
59    return -1;
60  if (argc < 3) {
61    /* All Devices */
62    drvmgr_info_drvs(0);
63    drvmgr_info_buses(0);
64    drvmgr_info_devs(OPTION_DEV_GENINFO);
65    return 0;
66  }
67
68  /* Get ID from string */
69  obj = get_obj_adr(argv[2]);
70  if (!obj)
71    return -3;
72
73  drvmgr_info(obj, OPTION_DEV_GENINFO);
74
75  return 0;
76}
77
78static int shell_drvmgr_info(int argc, char *argv[])
79{
80  void *obj;
81
82  if (argc < 2)
83    return -1;
84  if (argc < 3) {
85    /* All Drivers, Buses and Devices */
86    drvmgr_info_drvs(OPTION_INFO_ALL);
87    drvmgr_info_buses(OPTION_INFO_ALL);
88    drvmgr_info_devs(OPTION_INFO_ALL);
89    return 0;
90  }
91
92  /* Get ID from string */
93  obj = get_obj_adr(argv[2]);
94  if (!obj)
95    return -3;
96
97  drvmgr_info(obj, OPTION_INFO_ALL);
98
99  return 0;
100}
101
102static int shell_drvmgr_remove(int argc, char *argv[])
103{
104  puts(" Not implemented");
105  return 0;
106}
107
108static int shell_drvmgr_parent(int argc, char *argv[])
109{
110  void *obj;
111  int obj_type;
112  struct drvmgr_dev *dev;
113  struct drvmgr_bus *bus;
114
115  /* Get ID from string */
116  if (argc < 3)
117    return -2;
118  obj = get_obj_adr(argv[2]);
119  if (!obj)
120    return -3;
121
122  obj_type = *(int *)obj;
123  if (obj_type == DRVMGR_OBJ_BUS) {
124    bus = obj;
125    if (!bus->dev) {
126      puts(" bus has no bridge device");
127    } else if(!bus->dev->parent) {
128      puts(" bridge device has no parent");
129    } else {
130      dev = bus->dev;
131      printf(" BUSID=%p\n", dev->parent);
132    }
133  } else if (obj_type == DRVMGR_OBJ_DEV) {
134    dev = obj;
135    if (!dev->parent) {
136      puts(" device has no parent bus");
137    } else {
138      printf(" BUSID=%p\n", dev->parent);
139    }
140  } else {
141    puts(" ID is not a device or bus");
142    return 1;
143  }
144
145  return 0;
146}
147
148static void shell_drvmgr_print_key_array(struct drvmgr_key *keys)
149{
150  struct drvmgr_key *key;
151  static char *type_strs[4] = {"UNKNOWN","INTEGER","STRING ","POINTER"};
152  int type;
153  union drvmgr_key_value *val;
154
155  if (keys == NULL) {
156    printf("  DEV HAS NO KEYS\n");
157    return;
158  }
159
160  key = &keys[0];
161  while (key->key_type != KEY_TYPE_NONE) {
162    if (key->key_type > KEY_TYPE_POINTER)
163      type = 0;
164    else
165      type = key->key_type;
166    printf("  NAME=%-14s TYPE=%s  VALUE=", key->key_name, type_strs[type]);
167    val = &key->key_value;
168    switch (type) {
169      default:
170      case 0:
171      case KEY_TYPE_INT:
172        printf("0x%x (%d)\n", val->i, val->i);
173        break;
174      case KEY_TYPE_STRING:
175        printf("%s\n", val->str);
176        break;
177      case KEY_TYPE_POINTER:
178        printf("%p\n", val->ptr);
179        break;
180    }
181    key++;
182  }
183}
184
185static void shell_drvmgr_print_res_array(struct drvmgr_drv_res *resources)
186{
187  struct drvmgr_drv_res *res = &resources[0];
188  struct drvmgr_drv *drv;
189  char *drv_name;
190
191  while (res->drv_id) {
192    /* Find Driver in order to print name of driver */
193    drv = drvmgr_drv_by_id(res->drv_id);
194    if (drv && drv->name)
195      drv_name = drv->name;
196    else
197      drv_name = "UNKNOWN";
198    printf(" RESOURCES FOR DEVICE[%02d] DRIVER[0x%llx (%s)]\n",
199            res->minor_bus, res->drv_id, drv_name);
200    shell_drvmgr_print_key_array(res->keys);
201    res++;
202  }
203}
204
205static int shell_drvmgr_res(int argc, char *argv[])
206{
207  void *obj;
208  int obj_type;
209  struct drvmgr_dev *dev;
210  struct drvmgr_bus *bus;
211  struct drvmgr_key *keys;
212  struct drvmgr_bus_res *lst;
213  int i;
214
215  /* Get ID from string */
216  if (argc < 3)
217    return -2;
218  obj = get_obj_adr(argv[2]);
219  if (!obj)
220    return -3;
221
222  obj_type = *(int *)obj;
223  if (obj_type == DRVMGR_OBJ_BUS) {
224    bus = obj;
225    lst = bus->reslist;
226    if (lst == NULL) {
227      puts(" BUS does not have resources\n");
228      return 0;
229    }
230    i = 0;
231    while (lst) {
232      printf(" -- RESOURCES ARRAY %d --\n", i);
233      shell_drvmgr_print_res_array(lst->resource);
234      puts("");
235      i++;
236      lst = lst->next;
237    }
238  } else if (obj_type == DRVMGR_OBJ_DEV) {
239    dev = obj;
240    if (dev->drv == NULL) {
241      puts(" DEVICE has no driver ==> resources not available\n");
242      return 0;
243    }
244    drvmgr_keys_get(dev, &keys);
245    if (keys == NULL) {
246      puts(" DEVICE does not have resources\n");
247      return 0;
248    }
249    shell_drvmgr_print_key_array(keys);
250  } else {
251    puts(" ID is not a device or bus");
252    return 1;
253  }
254
255  return 0;
256}
257
258static int shell_drvmgr_buses(int argc, char *argv[])
259{
260  drvmgr_info_buses(OPTION_INFO_ALL);
261  return 0;
262}
263
264static int shell_drvmgr_devs(int argc, char *argv[])
265{
266  drvmgr_info_devs(OPTION_INFO_ALL);
267  return 0;
268}
269
270static int shell_drvmgr_drvs(int argc, char *argv[])
271{
272  drvmgr_info_drvs(OPTION_INFO_ALL);
273  return 0;
274}
275
276static int shell_drvmgr_mem(int argc, char *argv[])
277{
278  drvmgr_print_mem();
279  return 0;
280}
281
282static int shell_drvmgr_translate(int argc, char *argv[])
283{
284  int rc, rev, up, obj_type;
285  void *obj, *dst;
286  unsigned long src, tmp;
287
288  if (argc != 5)
289    return -1;
290
291  obj = get_obj_adr(argv[2]);
292  if (!obj)
293    return -3;
294
295  obj_type = *(int *)obj;
296  if (obj_type != DRVMGR_OBJ_DEV) {
297    puts(" ID is not a device\n");
298    return 0;
299  }
300
301  tmp = strtoul(argv[3], NULL, 0);
302  if (tmp > 3) {
303    puts(" Not a valid option OPT, only [0..3] is valid");
304    return 0;
305  }
306  rev = tmp & DRVMGR_TR_REVERSE;
307  up = tmp & DRVMGR_TR_PATH;
308
309  src = strtoul(argv[4], NULL, 0);
310  if (src == ULONG_MAX && errno == ERANGE) {
311    puts(" Not a valid source address");
312    return 0;
313  }
314
315  rc = drvmgr_translate((struct drvmgr_dev *)obj, up | rev, (void *)src, &dst);
316  if (rc == 0)
317    printf(" Address %p could not be translated\n", (void *)src);
318  else if (rc == 0xffffffff)
319    printf(" %p => %p  (no translation required)\n", (void *)src, dst);
320  else
321    printf(" %p => %p  (map size 0x%x)\n", (void *)src, dst, rc);
322
323  return 0;
324}
325
326static const char drvmgr_usage_str[] =
327 " usage:\n"
328 "  drvmgr buses         List bus specfic information on all buses\n"
329 "  drvmgr devs          List general and driver specfic information\n"
330 "                       about all devices\n"
331 "  drvmgr drvs          List driver specfic information on all drivers\n"
332 "  drvmgr info [ID]     List general and driver specfic information\n"
333 "                       about all devices or one device, bus or driver\n"
334 "  drvmgr mem           Dynamically memory usage\n"
335 "  drvmgr parent ID     Short info about parent bus of a device\n"
336 "  drvmgr remove ID     Remove a device or a bus\n"
337 "  drvmgr res ID        List Resources of a device or bus\n"
338 "  drvmgr short [ID]    Short info about all devices/buses or one\n"
339 "                       device/bus\n"
340 "  drvmgr topo          Show bus topology with all devices\n"
341 "  drvmgr tr ID OPT ADR Translate ADR down(0)/up(1) -streams (OPT bit 1) in\n"
342 "                       std(0)/reverse(1) (OPT bit 0) direction for device\n"
343 "  drvmgr --help\n";
344
345static void usage(void)
346{
347  puts(drvmgr_usage_str);
348}
349
350static int shell_drvmgr_usage(int argc, char *argv[])
351{
352  usage();
353  return 0;
354}
355
356struct shell_drvmgr_modifier {
357  char *name;
358  int (*func)(int argc, char *argv[]);
359};
360
361#define MODIFIER_NUM 12
362static struct shell_drvmgr_modifier shell_drvmgr_modifiers[MODIFIER_NUM] =
363{
364  {"buses", shell_drvmgr_buses},
365  {"devs", shell_drvmgr_devs},
366  {"drvs", shell_drvmgr_drvs},
367  {"info", shell_drvmgr_info},
368  {"mem", shell_drvmgr_mem},
369  {"parent", shell_drvmgr_parent},
370  {"remove", shell_drvmgr_remove},
371  {"res", shell_drvmgr_res},
372  {"short", shell_drvmgr_short},
373  {"topo", shell_drvmgr_topo},
374  {"tr", shell_drvmgr_translate},
375  {"--help", shell_drvmgr_usage},
376};
377
378static struct shell_drvmgr_modifier *shell_drvmgr_find_modifier(char *name)
379{
380  struct shell_drvmgr_modifier *mod;
381  int i;
382
383  if (name == NULL)
384    return NULL;
385
386  for (i=0, mod=&shell_drvmgr_modifiers[0]; i<MODIFIER_NUM; i++, mod++) {
387    if (strcmp(name, mod->name) == 0)
388      return mod;
389  }
390
391  return NULL;
392}
393
394static int rtems_shell_main_drvmgr(
395  int   argc,
396  char *argv[]
397)
398{
399  struct shell_drvmgr_modifier *mod;
400  int rc;
401
402  if (argc < 2) {
403    show_drvmgr_info();
404    rc = 0;
405  } else if ((mod=shell_drvmgr_find_modifier(argv[1])) != NULL) {
406    rc = mod->func(argc, argv);
407  } else {
408    rc = -1;
409  }
410
411  if (rc < 0) {
412    printf(" invalid argument\n");
413    usage();
414  }
415
416  return rc;
417}
418
419rtems_shell_cmd_t rtems_shell_DRVMGR_Command = {
420  "drvmgr",                      /* name */
421  drvmgr_usage_str,              /* usage */
422  "system",                      /* topic */
423  rtems_shell_main_drvmgr,       /* command */
424  NULL,                          /* alias */
425  NULL                           /* next */
426};
Note: See TracBrowser for help on using the repository browser.