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

Last change on this file was 9384ac2, checked in by Daniel Cederman <cederman@…>, on 11/14/22 at 09:55:53

cpukit: Change license to BSD-2 for files with Gaisler copyright

This patch changes the license to BSD-2 for all source files where the
copyright is held by Aeroflex Gaisler, Cobham Gaisler, or Gaisler Research.
Some files also includes copyright right statements from OAR and/or
embedded Brains in addition to Gaisler.

Updates #3053.

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