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