summaryrefslogtreecommitdiffstats
path: root/cpukit/libdrvmgr/drvmgr_print.c
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2011-11-28 09:52:03 +0100
committerDaniel Hellstrom <daniel@gaisler.com>2015-04-17 01:10:16 +0200
commite7fade3ac4559214ab0508dc54a71a3d1f522afb (patch)
tree13e32728a3b6adccd3f435db73091a8233d5dadf /cpukit/libdrvmgr/drvmgr_print.c
parentLIBPCI: added PCI shell command (diff)
downloadrtems-e7fade3ac4559214ab0508dc54a71a3d1f522afb.tar.bz2
DRVMGR: added driver manager to cpukit/libdrvmgr
Diffstat (limited to 'cpukit/libdrvmgr/drvmgr_print.c')
-rw-r--r--cpukit/libdrvmgr/drvmgr_print.c457
1 files changed, 457 insertions, 0 deletions
diff --git a/cpukit/libdrvmgr/drvmgr_print.c b/cpukit/libdrvmgr/drvmgr_print.c
new file mode 100644
index 0000000000..c36abfe527
--- /dev/null
+++ b/cpukit/libdrvmgr/drvmgr_print.c
@@ -0,0 +1,457 @@
+/* Driver Manager Information printing Interface Implementation
+ *
+ * COPYRIGHT (c) 2009.
+ * Cobham Gaisler AB.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+/*
+ * These functions print stuff about the driver manager, what devices were
+ * found and were united with a driver, the Bus topology, memory taken, etc.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <drvmgr/drvmgr.h>
+#include "drvmgr_internal.h"
+
+typedef void (*fun_ptr)(void);
+
+static int print_dev_found(struct drvmgr_dev *dev, void *arg)
+{
+ char **pparg = arg;
+
+ if (pparg && *pparg) {
+ printf(*pparg);
+ *pparg = NULL;
+ }
+
+ printf(" DEV %p %s on bus %p\n", dev,
+ dev->name ? dev->name : "NO_NAME", dev->parent);
+
+ return 0; /* Continue to next device */
+}
+
+void drvmgr_print_devs(unsigned int options)
+{
+ struct rtems_driver_manager *mgr = &drv_mgr;
+ char *parg;
+
+ /* Print Drivers */
+ if (options & PRINT_DEVS_ASSIGNED) {
+ parg = " --- DEVICES ASSIGNED TO DRIVER ---\n";
+ drvmgr_for_each_listdev(&mgr->devices[DRVMGR_LEVEL_MAX],
+ DEV_STATE_UNITED, 0, print_dev_found, &parg);
+ if (parg != NULL)
+ printf("\n NO DEVICES WERE ASSIGNED A DRIVER\n");
+ }
+
+ if (options & PRINT_DEVS_UNASSIGNED) {
+ parg = "\n --- DEVICES WITHOUT DRIVER ---\n";
+ drvmgr_for_each_listdev(&mgr->devices_inactive, 0,
+ DEV_STATE_UNITED, print_dev_found, &parg);
+ if (parg != NULL)
+ printf("\n NO DEVICES WERE WITHOUT DRIVER\n");
+ }
+
+ if (options & PRINT_DEVS_FAILED) {
+ parg = "\n --- DEVICES FAILED TO INITIALIZE ---\n";
+ drvmgr_for_each_listdev(&mgr->devices_inactive,
+ DEV_STATE_INIT_FAILED, 0, print_dev_found, &parg);
+ if (parg != NULL)
+ printf("\n NO DEVICES FAILED TO INITIALIZE\n");
+ }
+
+ if (options & PRINT_DEVS_IGNORED) {
+ parg = "\n --- DEVICES IGNORED ---\n";
+ drvmgr_for_each_listdev(&mgr->devices_inactive,
+ DEV_STATE_IGNORED, 0, print_dev_found, &parg);
+ if (parg != NULL)
+ printf("\n NO DEVICES WERE IGNORED\n");
+ }
+
+ printf("\n\n");
+}
+
+static int drvmgr_topo_func(struct drvmgr_dev *dev, void *arg)
+{
+ char prefix[32];
+ int depth = dev->parent->depth;
+
+ if (depth > 30)
+ return 0; /* depth more than 30 not supported */
+ memset(prefix, ' ', depth + 1);
+ prefix[depth + 1] = '\0';
+
+ printf(" %s|-> DEV %p %s\n", prefix, dev,
+ dev->name ? dev->name : "NO_NAME");
+ return 0;
+}
+
+void drvmgr_print_topo(void)
+{
+ /* Print Bus topology */
+ printf(" --- BUS TOPOLOGY ---\n");
+ drvmgr_for_each_dev(drvmgr_topo_func, NULL, DRVMGR_FED_DF);
+ printf("\n\n");
+}
+
+/* Print the memory usage */
+void drvmgr_print_mem(void)
+{
+ struct rtems_driver_manager *mgr = &drv_mgr;
+ struct drvmgr_bus *bus;
+ struct drvmgr_dev *dev;
+ struct drvmgr_drv *drv;
+
+ struct drvmgr_bus_res *node;
+ struct drvmgr_drv_res *res;
+ struct drvmgr_key *key;
+
+ unsigned int busmem = 0;
+ unsigned int devmem = 0;
+ unsigned int drvmem = 0;
+ unsigned int resmem = 0;
+ unsigned int devprivmem = 0;
+
+ DRVMGR_LOCK_READ();
+
+ bus = BUS_LIST_HEAD(&mgr->buses[DRVMGR_LEVEL_MAX]);
+ while (bus) {
+ busmem += sizeof(struct drvmgr_bus);
+
+ /* Get size of resources on this bus */
+ node = bus->reslist;
+ while (node) {
+ resmem += sizeof(struct drvmgr_bus_res);
+
+ res = node->resource;
+ while (res->keys) {
+ resmem += sizeof(struct drvmgr_drv_res);
+
+ key = res->keys;
+ while (key->key_type != KEY_TYPE_NONE) {
+ resmem += sizeof
+ (struct drvmgr_key);
+ key++;
+ }
+ resmem += sizeof(struct drvmgr_key);
+ res++;
+ }
+
+ node = node->next;
+ }
+
+ bus = bus->next;
+ }
+
+ drv = DRV_LIST_HEAD(&mgr->drivers);
+ while (drv) {
+ drvmem += sizeof(struct drvmgr_drv);
+ drv = drv->next;
+ }
+
+ dev = DEV_LIST_HEAD(&mgr->devices[DRVMGR_LEVEL_MAX]);
+ while (dev) {
+ devmem += sizeof(struct drvmgr_dev);
+ if (dev->drv && dev->drv->dev_priv_size > 0)
+ devprivmem += dev->drv->dev_priv_size;
+ dev = dev->next;
+ }
+
+ DRVMGR_UNLOCK();
+
+ printf(" --- MEMORY USAGE ---\n");
+ printf(" BUS: %d bytes\n", busmem);
+ printf(" DRV: %d bytes\n", drvmem);
+ printf(" DEV: %d bytes\n", devmem);
+ printf(" DEV private: %d bytes\n", devprivmem);
+ printf(" RES: %d bytes\n", resmem);
+ printf(" TOTAL: %d bytes\n",
+ busmem + drvmem + devmem + devprivmem + resmem);
+ printf("\n\n");
+}
+
+/* Print the memory usage */
+void drvmgr_summary(void)
+{
+ struct rtems_driver_manager *mgr = &drv_mgr;
+ struct drvmgr_bus *bus;
+ struct drvmgr_dev *dev;
+ struct drvmgr_drv *drv;
+ int i, buscnt = 0, devcnt = 0, drvcnt = 0;
+
+ printf(" --- SUMMARY ---\n");
+
+ drv = DRV_LIST_HEAD(&mgr->drivers);
+ while (drv) {
+ drvcnt++;
+ drv = drv->next;
+ }
+ printf(" NUMBER OF DRIVERS: %d\n", drvcnt);
+
+ DRVMGR_LOCK_READ();
+
+ for (i = 0; i <= DRVMGR_LEVEL_MAX; i++) {
+ buscnt = 0;
+ bus = BUS_LIST_HEAD(&mgr->buses[i]);
+ while (bus) {
+ buscnt++;
+ bus = bus->next;
+ }
+ if (buscnt > 0) {
+ printf(" NUMBER OF BUSES IN LEVEL[%d]: %d\n",
+ i, buscnt);
+ }
+ }
+
+ for (i = 0; i <= DRVMGR_LEVEL_MAX; i++) {
+ devcnt = 0;
+ dev = DEV_LIST_HEAD(&mgr->devices[i]);
+ while (dev) {
+ devcnt++;
+ dev = dev->next;
+ }
+ if (devcnt > 0) {
+ printf(" NUMBER OF DEVS IN LEVEL[%d]: %d\n",
+ i, devcnt);
+ }
+ }
+
+ DRVMGR_UNLOCK();
+
+ printf("\n\n");
+}
+
+static void print_info(void *p, char *str)
+{
+ printf(" ");
+ puts(str);
+}
+
+void drvmgr_info_dev(struct drvmgr_dev *dev, unsigned int options)
+{
+ if (!dev)
+ return;
+
+ printf(" -- DEVICE %p --\n", dev);
+ if (options & OPTION_DEV_GENINFO) {
+ printf(" PARENT BUS: %p\n", dev->parent);
+ printf(" NAME: %s\n", dev->name ? dev->name : "NO_NAME");
+ printf(" STATE: 0x%08x\n", dev->state);
+ if (dev->bus)
+ printf(" BRIDGE TO: %p\n", dev->bus);
+ printf(" INIT LEVEL: %d\n", dev->level);
+ printf(" ERROR: %d\n", dev->error);
+ printf(" MINOR BUS: %d\n", dev->minor_bus);
+ if (dev->drv) {
+ printf(" MINOR DRV: %d\n", dev->minor_drv);
+ printf(" DRIVER: %p (%s)\n", dev->drv,
+ dev->drv->name ? dev->drv->name : "NO_NAME");
+ printf(" PRIVATE: %p\n", dev->priv);
+ }
+ }
+
+ if (options & OPTION_DEV_BUSINFO) {
+ printf(" --- DEVICE INFO FROM BUS DRIVER ---\n");
+ if (!dev->parent)
+ printf(" !! device has no parent bus !!\n");
+ else if (dev->parent->ops->info_dev)
+ dev->parent->ops->info_dev(dev, print_info, NULL);
+ else
+ printf(" Bus doesn't implement info_dev func\n");
+ }
+
+ if (options & OPTION_DEV_DRVINFO) {
+ if (dev->drv) {
+ printf(" --- DEVICE INFO FROM DEVICE DRIVER ---\n");
+ if (dev->drv->ops->info)
+ dev->drv->ops->info(dev, print_info, NULL, 0, 0);
+ else
+ printf(" Driver doesn't implement info func\n");
+ }
+ }
+}
+
+static void drvmgr_info_bus_map(struct drvmgr_map_entry *map)
+{
+ if (map == NULL)
+ printf(" Addresses mapped 1:1\n");
+ else if (map == DRVMGR_TRANSLATE_NO_BRIDGE)
+ printf(" No bridge in this direction\n");
+ else {
+ while (map->size != 0) {
+ printf(" 0x%08lx-0x%08lx => 0x%08lx-0x%08lx %s\n",
+ (unsigned long)map->from_adr,
+ (unsigned long)(map->from_adr + map->size - 1),
+ (unsigned long)map->to_adr,
+ (unsigned long)(map->to_adr + map->size - 1),
+ map->name ? map->name : "no label");
+ map++;
+ }
+ }
+}
+
+void drvmgr_info_bus(struct drvmgr_bus *bus, unsigned int options)
+{
+ struct drvmgr_dev *dev;
+
+ /* Print Driver */
+ printf("-- BUS %p --\n", bus);
+ printf(" BUS TYPE: %d\n", bus->bus_type);
+ printf(" DEVICE: %p (%s)\n", bus->dev,
+ bus->dev->name ? bus->dev->name : "NO_NAME");
+ printf(" OPS: %p\n", bus->ops);
+ printf(" CHILDREN: %d devices\n", bus->dev_cnt);
+ printf(" LEVEL: %d\n", bus->level);
+ printf(" STATE: 0x%08x\n", bus->state);
+ printf(" ERROR: %d\n", bus->error);
+
+ /* Print address mappings up- (to parent) and down- (from parent to
+ * this bus) stream the bridge of this bus
+ */
+ printf(" DOWN STREAMS BRIDGE MAPPINGS (from parent to this bus)\n");
+ drvmgr_info_bus_map(bus->maps_down);
+ printf(" UP STREAMS BRIDGE MAPPINGS (from this bus to parent)\n");
+ drvmgr_info_bus_map(bus->maps_up);
+
+ /* Print Devices on this bus? */
+ if (options & OPTION_BUS_DEVS) {
+ printf(" CHILDREN:\n");
+ DRVMGR_LOCK_READ();
+ dev = bus->children;
+ while (dev) {
+ printf(" |- DEV[%02d]: %p %s\n", dev->minor_bus,
+ dev, dev->name ? dev->name : "NO_NAME");
+ dev = dev->next_in_bus;
+ }
+ DRVMGR_UNLOCK();
+ }
+}
+
+char *drv_ops_names[DRV_OPS_NUM] = {
+ "init[1]:",
+ "init[2]:",
+ "init[3]:",
+ "init[4]:",
+ "remove: ",
+ "info: "
+};
+
+void drvmgr_info_drv(struct drvmgr_drv *drv, unsigned int options)
+{
+ struct drvmgr_dev *dev;
+ fun_ptr *ppfunc;
+ int i;
+
+ /* Print Driver */
+ printf(" -- DRIVER %p --\n", drv);
+ printf(" DRIVER ID: 0x%llx\n", drv->drv_id);
+ printf(" NAME: %s\n", drv->name ? drv->name : "NO_NAME");
+ printf(" BUS TYPE: %d\n", drv->bus_type);
+ printf(" OPERATIONS:\n");
+ for (i = 0, ppfunc = (fun_ptr *)&drv->ops->init[0]; i<DRV_OPS_NUM; i++)
+ printf(" %s %p\n", drv_ops_names[i], ppfunc[i]);
+ printf(" NO. DEVICES: %d\n", drv->dev_cnt);
+
+ /* Print devices united with this driver? */
+ if (options & OPTION_DRV_DEVS) {
+ DRVMGR_LOCK_READ();
+ dev = drv->dev;
+ while (dev) {
+ printf(" DEV[%02d]: %p %s\n", dev->minor_drv,
+ dev, dev->name ? dev->name : "NO_NAME");
+ dev = dev->next_in_drv;
+ }
+ DRVMGR_UNLOCK();
+ }
+}
+
+void (*info_obj[3])(void *obj, unsigned int) = {
+ /* DRVMGR_OBJ_DRV */ (void (*)(void *, unsigned int))drvmgr_info_drv,
+ /* DRVMGR_OBJ_BUS */ (void (*)(void *, unsigned int))drvmgr_info_bus,
+ /* DRVMGR_OBJ_DEV */ (void (*)(void *, unsigned int))drvmgr_info_dev,
+};
+
+/* Get information about a device/bus/driver */
+void drvmgr_info(void *id, unsigned int options)
+{
+ int obj_type;
+ void (*func)(void *, unsigned int);
+
+ if (!id)
+ return;
+ obj_type = *(int *)id;
+ if ((obj_type < DRVMGR_OBJ_DRV) || (obj_type > DRVMGR_OBJ_DEV))
+ return;
+ func = info_obj[obj_type - 1];
+ func(id, options);
+}
+
+void drvmgr_info_devs_on_bus(struct drvmgr_bus *bus, unsigned int options)
+{
+ struct drvmgr_dev *dev;
+
+ /* Print All Devices on Bus */
+ printf("\n\n -= All Devices on BUS %p =-\n\n", bus);
+ dev = bus->children;
+ while (dev) {
+ drvmgr_info_dev(dev, options);
+ puts("");
+ dev = dev->next_in_bus;
+ }
+
+ if ((options & OPTION_RECURSIVE) == 0)
+ return;
+
+ /* This device provides a bus, print the bus */
+ dev = bus->children;
+ while (dev) {
+ if (dev->bus)
+ drvmgr_info_devs_on_bus(dev->bus, options);
+ dev = dev->next_in_bus;
+ }
+}
+
+void drvmgr_info_devs(unsigned int options)
+{
+ struct rtems_driver_manager *mgr = &drv_mgr;
+ struct drvmgr_dev *dev;
+
+ /* Print device information of all devices and their child devices */
+ dev = &mgr->root_dev;
+ drvmgr_info_devs_on_bus(dev->bus, options);
+ printf("\n\n");
+}
+
+void drvmgr_info_drvs(unsigned int options)
+{
+ struct rtems_driver_manager *mgr = &drv_mgr;
+ struct drvmgr_drv *drv;
+
+ drv = DRV_LIST_HEAD(&mgr->drivers);
+ while (drv) {
+ drvmgr_info_drv(drv, options);
+ puts("\n");
+ drv = drv->next;
+ }
+}
+
+void drvmgr_info_buses(unsigned int options)
+{
+ struct rtems_driver_manager *mgr = &drv_mgr;
+ struct drvmgr_bus *bus;
+
+ bus = BUS_LIST_HEAD(&mgr->buses[DRVMGR_LEVEL_MAX]);
+ while (bus) {
+ drvmgr_info_bus(bus, options);
+ puts("\n");
+ bus = bus->next;
+ }
+}