source: rtems/cpukit/libmisc/shell/main_drvmgr.c @ a7e8996

5
Last change on this file since a7e8996 was a7e8996, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 21, 2018 at 8:09:53 PM

drvmgr: Improve LP64 compatibility

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