source: rtems/cpukit/libdrvmgr/drvmgr_print.c @ 3663be53

Last change on this file since 3663be53 was 3663be53, checked in by Daniel Hellstrom <daniel@…>, on Aug 24, 2017 at 3:23:23 PM

drvmgr: clean up info_drv print

Fixes #2930

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/* Driver Manager Information printing Interface Implementation
2 *
3 * COPYRIGHT (c) 2009 Cobham Gaisler AB.
4 *
5 * The license and distribution terms for this file may be
6 * found in the file LICENSE in this distribution or at
7 * http://www.rtems.org/license/LICENSE.
8 */
9
10/*
11 *  These functions print stuff about the driver manager, what devices were
12 *  found and were united with a driver, the Bus topology, memory taken, etc.
13 *
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include <drvmgr/drvmgr.h>
21#include "drvmgr_internal.h"
22
23typedef void (*fun_ptr)(void);
24
25static int print_dev_found(struct drvmgr_dev *dev, void *arg)
26{
27        char **pparg = arg;
28
29        if (pparg && *pparg) {
30                printf(*pparg);
31                *pparg = NULL;
32        }
33
34        printf(" DEV %p  %s on bus %p\n", dev,
35                dev->name ? dev->name : "NO_NAME", dev->parent);
36
37        return 0; /* Continue to next device */
38}
39
40void drvmgr_print_devs(unsigned int options)
41{
42        struct drvmgr *mgr = &drvmgr;
43        char *parg;
44
45        /* Print Drivers */
46        if (options & PRINT_DEVS_ASSIGNED) {
47                parg = " --- DEVICES ASSIGNED TO DRIVER ---\n";
48                drvmgr_for_each_listdev(&mgr->devices[DRVMGR_LEVEL_MAX],
49                                DEV_STATE_UNITED, 0, print_dev_found, &parg);
50                if (parg != NULL)
51                        printf("\n NO DEVICES WERE ASSIGNED A DRIVER\n");
52        }
53
54        if (options & PRINT_DEVS_UNASSIGNED) {
55                parg = "\n --- DEVICES WITHOUT DRIVER ---\n";
56                drvmgr_for_each_listdev(&mgr->devices_inactive, 0,
57                        DEV_STATE_UNITED, print_dev_found, &parg);
58                if (parg != NULL)
59                        printf("\n NO DEVICES WERE WITHOUT DRIVER\n");
60        }
61
62        if (options & PRINT_DEVS_FAILED) {
63                parg = "\n --- DEVICES FAILED TO INITIALIZE ---\n";
64                drvmgr_for_each_listdev(&mgr->devices_inactive,
65                        DEV_STATE_INIT_FAILED, 0, print_dev_found, &parg);
66                if (parg != NULL)
67                        printf("\n NO DEVICES FAILED TO INITIALIZE\n");
68        }
69
70        if (options & PRINT_DEVS_IGNORED) {
71                parg = "\n --- DEVICES IGNORED ---\n";
72                drvmgr_for_each_listdev(&mgr->devices_inactive,
73                        DEV_STATE_IGNORED, 0, print_dev_found, &parg);
74                if (parg != NULL)
75                        printf("\n NO DEVICES WERE IGNORED\n");
76        }
77
78        printf("\n\n");
79}
80
81static int drvmgr_topo_func(struct drvmgr_dev *dev, void *arg)
82{
83        char prefix[32];
84        int depth = dev->parent->depth;
85
86        if (depth > 30)
87                return 0; /* depth more than 30 not supported */
88        memset(prefix, ' ', depth + 1);
89        prefix[depth + 1] = '\0';
90
91        printf(" %s|-> DEV  %p  %s\n", prefix, dev,
92                dev->name ? dev->name :  "NO_NAME");
93        return 0;
94}
95
96void drvmgr_print_topo(void)
97{
98        /* Print Bus topology */
99        printf(" --- BUS TOPOLOGY ---\n");
100        drvmgr_for_each_dev(drvmgr_topo_func, NULL, DRVMGR_FED_DF);
101        printf("\n\n");
102}
103
104/* Print the memory usage */
105void drvmgr_print_mem(void)
106{
107        struct drvmgr *mgr = &drvmgr;
108        struct drvmgr_bus *bus;
109        struct drvmgr_dev *dev;
110        struct drvmgr_drv *drv;
111
112        struct drvmgr_bus_res *node;
113        struct drvmgr_drv_res *res;
114        struct drvmgr_key *key;
115
116        unsigned int busmem = 0;
117        unsigned int devmem = 0;
118        unsigned int drvmem = 0;
119        unsigned int resmem = 0;
120        unsigned int devprivmem = 0;
121
122        DRVMGR_LOCK_READ();
123
124        bus = BUS_LIST_HEAD(&mgr->buses[DRVMGR_LEVEL_MAX]);
125        while (bus) {
126                busmem += sizeof(struct drvmgr_bus);
127
128                /* Get size of resources on this bus */
129                node = bus->reslist;
130                while (node) {
131                        resmem += sizeof(struct drvmgr_bus_res);
132
133                        res = node->resource;
134                        while (res->keys) {
135                                resmem += sizeof(struct drvmgr_drv_res);
136
137                                key = res->keys;
138                                while (key->key_type != DRVMGR_KT_NONE) {
139                                        resmem += sizeof
140                                                (struct drvmgr_key);
141                                        key++;
142                                }
143                                resmem += sizeof(struct drvmgr_key);
144                                res++;
145                        }
146
147                        node = node->next;
148                }
149
150                bus = bus->next;
151        }
152
153        drv = DRV_LIST_HEAD(&mgr->drivers);
154        while (drv) {
155                drvmem += sizeof(struct drvmgr_drv);
156                drv = drv->next;
157        }
158
159        dev = DEV_LIST_HEAD(&mgr->devices[DRVMGR_LEVEL_MAX]);
160        while (dev) {
161                devmem += sizeof(struct drvmgr_dev);
162                if (dev->drv && dev->drv->dev_priv_size > 0)
163                        devprivmem += dev->drv->dev_priv_size;
164                dev = dev->next;
165        }
166
167        DRVMGR_UNLOCK();
168
169        printf(" --- MEMORY USAGE ---\n");
170        printf(" BUS:          %d bytes\n", busmem);
171        printf(" DRV:          %d bytes\n", drvmem);
172        printf(" DEV:          %d bytes\n", devmem);
173        printf(" DEV private:  %d bytes\n", devprivmem);
174        printf(" RES:          %d bytes\n", resmem);
175        printf(" TOTAL:        %d bytes\n",
176                        busmem + drvmem + devmem + devprivmem + resmem);
177        printf("\n\n");
178}
179
180/* Print the memory usage */
181void drvmgr_summary(void)
182{
183        struct drvmgr *mgr = &drvmgr;
184        struct drvmgr_bus *bus;
185        struct drvmgr_dev *dev;
186        struct drvmgr_drv *drv;
187        int i, buscnt = 0, devcnt = 0, drvcnt = 0;
188
189        printf(" --- SUMMARY ---\n");
190
191        drv = DRV_LIST_HEAD(&mgr->drivers);
192        while (drv) {
193                drvcnt++;
194                drv = drv->next;
195        }
196        printf(" NUMBER OF DRIVERS:               %d\n", drvcnt);
197
198        DRVMGR_LOCK_READ();
199
200        for (i = 0; i <= DRVMGR_LEVEL_MAX; i++) {
201                buscnt = 0;
202                bus = BUS_LIST_HEAD(&mgr->buses[i]);
203                while (bus) {
204                        buscnt++;
205                        bus = bus->next;
206                }
207                if (buscnt > 0) {
208                        printf(" NUMBER OF BUSES IN LEVEL[%d]:     %d\n",
209                                i, buscnt);
210                }
211        }
212
213        for (i = 0; i <= DRVMGR_LEVEL_MAX; i++) {
214                devcnt = 0;
215                dev = DEV_LIST_HEAD(&mgr->devices[i]);
216                while (dev) {
217                        devcnt++;
218                        dev = dev->next;
219                }
220                if (devcnt > 0) {
221                        printf(" NUMBER OF DEVS IN LEVEL[%d]:      %d\n",
222                                i, devcnt);
223                }
224        }
225
226        DRVMGR_UNLOCK();
227
228        printf("\n\n");
229}
230
231static void print_info(void *p, char *str)
232{
233        printf("  ");
234        puts(str);
235}
236
237void drvmgr_info_dev(struct drvmgr_dev *dev, unsigned int options)
238{
239        if (!dev)
240                return;
241
242        printf(" -- DEVICE %p --\n", dev);
243        if (options & OPTION_DEV_GENINFO) {
244                printf("  PARENT BUS:  %p\n", dev->parent);
245                printf("  NAME:        %s\n", dev->name ? dev->name : "NO_NAME");
246                printf("  STATE:       0x%08x\n", dev->state);
247                if (dev->bus)
248                        printf("  BRIDGE TO:   %p\n", dev->bus);
249                printf("  INIT LEVEL:  %d\n", dev->level);
250                printf("  ERROR:       %d\n", dev->error);
251                printf("  MINOR BUS:   %d\n", dev->minor_bus);
252                if (dev->drv) {
253                        printf("  MINOR DRV:   %d\n", dev->minor_drv);
254                        printf("  DRIVER:      %p (%s)\n", dev->drv,
255                                dev->drv->name ? dev->drv->name : "NO_NAME");
256                        printf("  PRIVATE:     %p\n", dev->priv);
257                }
258        }
259
260        if (options & OPTION_DEV_BUSINFO) {
261                printf("  --- DEVICE INFO FROM BUS DRIVER ---\n");
262                if (!dev->parent)
263                        printf("  !! device has no parent bus !!\n");
264                else if (dev->parent->ops->get_info_dev)
265                        dev->parent->ops->get_info_dev(dev, print_info, NULL);
266                else
267                        printf("  Bus doesn't implement get_info_dev func\n");
268        }
269
270        if (options & OPTION_DEV_DRVINFO) {
271                if (dev->drv) {
272                        printf("  --- DEVICE INFO FROM DEVICE DRIVER ---\n");
273                        if (dev->drv->ops->info)
274                                dev->drv->ops->info(dev, print_info, NULL, 0, 0);
275                        else
276                                printf("  Driver doesn't implement info func\n");
277                }
278        }
279}
280
281static void drvmgr_info_bus_map(struct drvmgr_map_entry *map)
282{
283        if (map == NULL)
284                printf("    Addresses mapped 1:1\n");
285        else if (map == DRVMGR_TRANSLATE_NO_BRIDGE)
286                printf("    No bridge in this direction\n");
287        else {
288                while (map->size != 0) {
289                        printf("    0x%08lx-0x%08lx => 0x%08lx-0x%08lx  %s\n",
290                                (unsigned long)map->from_adr,
291                                (unsigned long)(map->from_adr + map->size - 1),
292                                (unsigned long)map->to_adr,
293                                (unsigned long)(map->to_adr + map->size - 1),
294                                map->name ? map->name : "no label");
295                        map++;
296                }
297        }
298}
299
300void drvmgr_info_bus(struct drvmgr_bus *bus, unsigned int options)
301{
302        struct drvmgr_dev *dev;
303
304        /* Print Driver */
305        printf("-- BUS %p --\n", bus);
306        printf("  BUS TYPE:    %d\n", bus->bus_type);
307        printf("  DEVICE:      %p (%s)\n", bus->dev,
308                bus->dev->name ? bus->dev->name : "NO_NAME");
309        printf("  OPS:         %p\n", bus->ops);
310        printf("  CHILDREN:    %d devices\n", bus->dev_cnt);
311        printf("  LEVEL:       %d\n", bus->level);
312        printf("  STATE:       0x%08x\n", bus->state);
313        printf("  ERROR:       %d\n", bus->error);
314
315        /* Print address mappings up- (to parent) and down- (from parent to
316         * this bus) stream the bridge of this bus
317         */
318        printf("  DOWN STREAMS BRIDGE MAPPINGS  (from parent to this bus)\n");
319        drvmgr_info_bus_map(bus->maps_down);
320        printf("  UP STREAMS BRIDGE MAPPINGS    (from this bus to parent)\n");
321        drvmgr_info_bus_map(bus->maps_up);
322
323        /* Print Devices on this bus? */
324        if (options & OPTION_BUS_DEVS) {
325                printf("  CHILDREN:\n");
326                DRVMGR_LOCK_READ();
327                dev = bus->children;
328                while (dev) {
329                        printf("   |- DEV[%02d]: %p  %s\n", dev->minor_bus,
330                                dev, dev->name ? dev->name : "NO_NAME");
331                        dev = dev->next_in_bus;
332                }
333                DRVMGR_UNLOCK();
334        }
335}
336
337void drvmgr_info_drv(struct drvmgr_drv *drv, unsigned int options)
338{
339        struct drvmgr_dev *dev;
340        int i;
341
342        /* Print Driver */
343        printf(" -- DRIVER %p --\n", drv);
344        printf("  DRIVER ID:   0x%llx\n", drv->drv_id);
345        printf("  NAME:        %s\n", drv->name ? drv->name : "NO_NAME");
346        printf("  BUS TYPE:    %d\n", drv->bus_type);
347        printf("  OPERATIONS:\n");
348        for (i = 0; i < DRVMGR_LEVEL_MAX; i++)
349                printf("   init[%d]:    %p\n", i + 1, drv->ops->init[i]);
350        printf("   remove:     %p\n", drv->ops->remove);
351        printf("   info:       %p\n", drv->ops->info);
352        printf("  NO. DEVICES: %d\n", drv->dev_cnt);
353
354        /* Print devices united with this driver? */
355        if (options & OPTION_DRV_DEVS) {
356                DRVMGR_LOCK_READ();
357                dev = drv->dev;
358                while (dev) {
359                        printf("  DEV[%02d]:     %p  %s\n", dev->minor_drv,
360                                dev, dev->name ? dev->name : "NO_NAME");
361                        dev = dev->next_in_drv;
362                }
363                DRVMGR_UNLOCK();
364        }
365}
366
367void (*info_obj[3])(void *obj, unsigned int) = {
368        /* DRVMGR_OBJ_DRV */ (void (*)(void *, unsigned int))drvmgr_info_drv,
369        /* DRVMGR_OBJ_BUS */ (void (*)(void *, unsigned int))drvmgr_info_bus,
370        /* DRVMGR_OBJ_DEV */ (void (*)(void *, unsigned int))drvmgr_info_dev,
371};
372
373/* Get information about a device/bus/driver */
374void drvmgr_info(void *id, unsigned int options)
375{
376        int obj_type;
377        void (*func)(void *, unsigned int);
378
379        if (!id)
380                return;
381        obj_type = *(int *)id;
382        if ((obj_type < DRVMGR_OBJ_DRV) || (obj_type > DRVMGR_OBJ_DEV))
383                return;
384        func = info_obj[obj_type - 1];
385        func(id, options);
386}
387
388void drvmgr_info_devs_on_bus(struct drvmgr_bus *bus, unsigned int options)
389{
390        struct drvmgr_dev *dev;
391
392        /* Print All Devices on Bus */
393        printf("\n\n  -= All Devices on BUS %p =-\n\n", bus);
394        dev = bus->children;
395        while (dev) {
396                drvmgr_info_dev(dev, options);
397                puts("");
398                dev = dev->next_in_bus;
399        }
400
401        if ((options & OPTION_RECURSIVE) == 0)
402                return;
403
404        /* This device provides a bus, print the bus */
405        dev = bus->children;
406        while (dev) {
407                if (dev->bus)
408                        drvmgr_info_devs_on_bus(dev->bus, options);
409                dev = dev->next_in_bus;
410        }
411}
412
413void drvmgr_info_devs(unsigned int options)
414{
415        struct drvmgr *mgr = &drvmgr;
416        struct drvmgr_dev *dev;
417
418        /* Print device information of all devices and their child devices */
419        dev = &mgr->root_dev;
420        drvmgr_info_devs_on_bus(dev->bus, options);
421        printf("\n\n");
422}
423
424void drvmgr_info_drvs(unsigned int options)
425{
426        struct drvmgr *mgr = &drvmgr;
427        struct drvmgr_drv *drv;
428
429        drv = DRV_LIST_HEAD(&mgr->drivers);
430        while (drv) {
431                drvmgr_info_drv(drv, options);
432                puts("\n");
433                drv = drv->next;
434        }
435}
436
437void drvmgr_info_buses(unsigned int options)
438{
439        struct drvmgr *mgr = &drvmgr;
440        struct drvmgr_bus *bus;
441
442        bus = BUS_LIST_HEAD(&mgr->buses[DRVMGR_LEVEL_MAX]);
443        while (bus) {
444                drvmgr_info_bus(bus, options);
445                puts("\n");
446                bus = bus->next;
447        }
448}
Note: See TracBrowser for help on using the repository browser.