source: rtems/cpukit/libmisc/shell/main_drvmgr.c @ 6073c71d

5
Last change on this file since 6073c71d was 1f22b26, checked in by Sebastian Huber <sebastian.huber@…>, on 08/25/17 at 08:59:52

Include missing <limits.h>

Update #2132.

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