File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include <inttypes.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <string.h>
0039
0040 #include <drvmgr/drvmgr.h>
0041 #include "drvmgr_internal.h"
0042
0043 typedef void (*fun_ptr)(void);
0044
0045 static int print_dev_found(struct drvmgr_dev *dev, void *arg)
0046 {
0047 char **pparg = arg;
0048
0049 if (pparg && *pparg) {
0050 printf(*pparg);
0051 *pparg = NULL;
0052 }
0053
0054 printf(" DEV %p %s on bus %p\n", dev,
0055 dev->name ? dev->name : "NO_NAME", dev->parent);
0056
0057 return 0;
0058 }
0059
0060 void drvmgr_print_devs(unsigned int options)
0061 {
0062 struct drvmgr *mgr = &drvmgr;
0063 char *parg;
0064
0065
0066 if (options & PRINT_DEVS_ASSIGNED) {
0067 parg = " --- DEVICES ASSIGNED TO DRIVER ---\n";
0068 drvmgr_for_each_listdev(&mgr->devices[DRVMGR_LEVEL_MAX],
0069 DEV_STATE_UNITED, 0, print_dev_found, &parg);
0070 if (parg != NULL)
0071 printf("\n NO DEVICES WERE ASSIGNED A DRIVER\n");
0072 }
0073
0074 if (options & PRINT_DEVS_UNASSIGNED) {
0075 parg = "\n --- DEVICES WITHOUT DRIVER ---\n";
0076 drvmgr_for_each_listdev(&mgr->devices_inactive, 0,
0077 DEV_STATE_UNITED, print_dev_found, &parg);
0078 if (parg != NULL)
0079 printf("\n NO DEVICES WERE WITHOUT DRIVER\n");
0080 }
0081
0082 if (options & PRINT_DEVS_FAILED) {
0083 parg = "\n --- DEVICES FAILED TO INITIALIZE ---\n";
0084 drvmgr_for_each_listdev(&mgr->devices_inactive,
0085 DEV_STATE_INIT_FAILED, 0, print_dev_found, &parg);
0086 if (parg != NULL)
0087 printf("\n NO DEVICES FAILED TO INITIALIZE\n");
0088 }
0089
0090 if (options & PRINT_DEVS_IGNORED) {
0091 parg = "\n --- DEVICES IGNORED ---\n";
0092 drvmgr_for_each_listdev(&mgr->devices_inactive,
0093 DEV_STATE_IGNORED, 0, print_dev_found, &parg);
0094 if (parg != NULL)
0095 printf("\n NO DEVICES WERE IGNORED\n");
0096 }
0097
0098 printf("\n\n");
0099 }
0100
0101 static intptr_t drvmgr_topo_func(struct drvmgr_dev *dev, void *arg)
0102 {
0103 char prefix[32];
0104 int depth = dev->parent->depth;
0105
0106 if (depth > 30)
0107 return 0;
0108 memset(prefix, ' ', depth + 1);
0109 prefix[depth + 1] = '\0';
0110
0111 printf(" %s|-> DEV %p %s\n", prefix, dev,
0112 dev->name ? dev->name : "NO_NAME");
0113 return 0;
0114 }
0115
0116 void drvmgr_print_topo(void)
0117 {
0118
0119 printf(" --- BUS TOPOLOGY ---\n");
0120 drvmgr_for_each_dev(drvmgr_topo_func, NULL, DRVMGR_FED_DF);
0121 printf("\n\n");
0122 }
0123
0124
0125 void drvmgr_print_mem(void)
0126 {
0127 struct drvmgr *mgr = &drvmgr;
0128 struct drvmgr_bus *bus;
0129 struct drvmgr_dev *dev;
0130 struct drvmgr_drv *drv;
0131
0132 struct drvmgr_bus_res *node;
0133 struct drvmgr_drv_res *res;
0134 struct drvmgr_key *key;
0135
0136 unsigned int busmem = 0;
0137 unsigned int devmem = 0;
0138 unsigned int drvmem = 0;
0139 unsigned int resmem = 0;
0140 unsigned int devprivmem = 0;
0141
0142 DRVMGR_LOCK_READ();
0143
0144 bus = BUS_LIST_HEAD(&mgr->buses[DRVMGR_LEVEL_MAX]);
0145 while (bus) {
0146 busmem += sizeof(struct drvmgr_bus);
0147
0148
0149 node = bus->reslist;
0150 while (node) {
0151 resmem += sizeof(struct drvmgr_bus_res);
0152
0153 res = node->resource;
0154 while (res->keys) {
0155 resmem += sizeof(struct drvmgr_drv_res);
0156
0157 key = res->keys;
0158 while (key->key_type != DRVMGR_KT_NONE) {
0159 resmem += sizeof
0160 (struct drvmgr_key);
0161 key++;
0162 }
0163 resmem += sizeof(struct drvmgr_key);
0164 res++;
0165 }
0166
0167 node = node->next;
0168 }
0169
0170 bus = bus->next;
0171 }
0172
0173 drv = DRV_LIST_HEAD(&mgr->drivers);
0174 while (drv) {
0175 drvmem += sizeof(struct drvmgr_drv);
0176 drv = drv->next;
0177 }
0178
0179 dev = DEV_LIST_HEAD(&mgr->devices[DRVMGR_LEVEL_MAX]);
0180 while (dev) {
0181 devmem += sizeof(struct drvmgr_dev);
0182 if (dev->drv && dev->drv->dev_priv_size > 0)
0183 devprivmem += dev->drv->dev_priv_size;
0184 dev = dev->next;
0185 }
0186
0187 DRVMGR_UNLOCK();
0188
0189 printf(" --- MEMORY USAGE ---\n");
0190 printf(" BUS: %d bytes\n", busmem);
0191 printf(" DRV: %d bytes\n", drvmem);
0192 printf(" DEV: %d bytes\n", devmem);
0193 printf(" DEV private: %d bytes\n", devprivmem);
0194 printf(" RES: %d bytes\n", resmem);
0195 printf(" TOTAL: %d bytes\n",
0196 busmem + drvmem + devmem + devprivmem + resmem);
0197 printf("\n\n");
0198 }
0199
0200
0201 void drvmgr_summary(void)
0202 {
0203 struct drvmgr *mgr = &drvmgr;
0204 struct drvmgr_bus *bus;
0205 struct drvmgr_dev *dev;
0206 struct drvmgr_drv *drv;
0207 int i, buscnt = 0, devcnt = 0, drvcnt = 0;
0208
0209 printf(" --- SUMMARY ---\n");
0210
0211 drv = DRV_LIST_HEAD(&mgr->drivers);
0212 while (drv) {
0213 drvcnt++;
0214 drv = drv->next;
0215 }
0216 printf(" NUMBER OF DRIVERS: %d\n", drvcnt);
0217
0218 DRVMGR_LOCK_READ();
0219
0220 for (i = 0; i <= DRVMGR_LEVEL_MAX; i++) {
0221 buscnt = 0;
0222 bus = BUS_LIST_HEAD(&mgr->buses[i]);
0223 while (bus) {
0224 buscnt++;
0225 bus = bus->next;
0226 }
0227 if (buscnt > 0) {
0228 printf(" NUMBER OF BUSES IN LEVEL[%d]: %d\n",
0229 i, buscnt);
0230 }
0231 }
0232
0233 for (i = 0; i <= DRVMGR_LEVEL_MAX; i++) {
0234 devcnt = 0;
0235 dev = DEV_LIST_HEAD(&mgr->devices[i]);
0236 while (dev) {
0237 devcnt++;
0238 dev = dev->next;
0239 }
0240 if (devcnt > 0) {
0241 printf(" NUMBER OF DEVS IN LEVEL[%d]: %d\n",
0242 i, devcnt);
0243 }
0244 }
0245
0246 DRVMGR_UNLOCK();
0247
0248 printf("\n\n");
0249 }
0250
0251 static void print_info(void *p, char *str)
0252 {
0253 printf(" ");
0254 puts(str);
0255 }
0256
0257 void drvmgr_info_dev(struct drvmgr_dev *dev, unsigned int options)
0258 {
0259 if (!dev)
0260 return;
0261
0262 printf(" -- DEVICE %p --\n", dev);
0263 if (options & OPTION_DEV_GENINFO) {
0264 printf(" PARENT BUS: %p\n", dev->parent);
0265 printf(" NAME: %s\n", dev->name ? dev->name : "NO_NAME");
0266 printf(" STATE: 0x%08x\n", dev->state);
0267 if (dev->bus)
0268 printf(" BRIDGE TO: %p\n", dev->bus);
0269 printf(" INIT LEVEL: %d\n", dev->level);
0270 printf(" ERROR: %d\n", dev->error);
0271 printf(" MINOR BUS: %d\n", dev->minor_bus);
0272 if (dev->drv) {
0273 printf(" MINOR DRV: %d\n", dev->minor_drv);
0274 printf(" DRIVER: %p (%s)\n", dev->drv,
0275 dev->drv->name ? dev->drv->name : "NO_NAME");
0276 printf(" PRIVATE: %p\n", dev->priv);
0277 }
0278 }
0279
0280 if (options & OPTION_DEV_BUSINFO) {
0281 printf(" --- DEVICE INFO FROM BUS DRIVER ---\n");
0282 if (!dev->parent)
0283 printf(" !! device has no parent bus !!\n");
0284 else if (dev->parent->ops->get_info_dev)
0285 dev->parent->ops->get_info_dev(dev, print_info, NULL);
0286 else
0287 printf(" Bus doesn't implement get_info_dev func\n");
0288 }
0289
0290 if (options & OPTION_DEV_DRVINFO) {
0291 if (dev->drv) {
0292 printf(" --- DEVICE INFO FROM DEVICE DRIVER ---\n");
0293 if (dev->drv->ops->info)
0294 dev->drv->ops->info(dev, print_info, NULL, 0, 0);
0295 else
0296 printf(" Driver doesn't implement info func\n");
0297 }
0298 }
0299 }
0300
0301 static void drvmgr_info_bus_map(struct drvmgr_map_entry *map)
0302 {
0303 if (map == NULL)
0304 printf(" Addresses mapped 1:1\n");
0305 else if (map == DRVMGR_TRANSLATE_NO_BRIDGE)
0306 printf(" No bridge in this direction\n");
0307 else {
0308 while (map->size != 0) {
0309 printf(" 0x%08lx-0x%08lx => 0x%08lx-0x%08lx %s\n",
0310 (unsigned long)map->from_adr,
0311 (unsigned long)(map->from_adr + map->size - 1),
0312 (unsigned long)map->to_adr,
0313 (unsigned long)(map->to_adr + map->size - 1),
0314 map->name ? map->name : "no label");
0315 map++;
0316 }
0317 }
0318 }
0319
0320 void drvmgr_info_bus(struct drvmgr_bus *bus, unsigned int options)
0321 {
0322 struct drvmgr_dev *dev;
0323
0324
0325 printf("-- BUS %p --\n", bus);
0326 printf(" BUS TYPE: %d\n", bus->bus_type);
0327 printf(" DEVICE: %p (%s)\n", bus->dev,
0328 bus->dev->name ? bus->dev->name : "NO_NAME");
0329 printf(" OPS: %p\n", bus->ops);
0330 printf(" CHILDREN: %d devices\n", bus->dev_cnt);
0331 printf(" LEVEL: %d\n", bus->level);
0332 printf(" STATE: 0x%08x\n", bus->state);
0333 printf(" ERROR: %d\n", bus->error);
0334
0335
0336
0337
0338 printf(" DOWN STREAMS BRIDGE MAPPINGS (from parent to this bus)\n");
0339 drvmgr_info_bus_map(bus->maps_down);
0340 printf(" UP STREAMS BRIDGE MAPPINGS (from this bus to parent)\n");
0341 drvmgr_info_bus_map(bus->maps_up);
0342
0343
0344 if (options & OPTION_BUS_DEVS) {
0345 printf(" CHILDREN:\n");
0346 DRVMGR_LOCK_READ();
0347 dev = bus->children;
0348 while (dev) {
0349 printf(" |- DEV[%02d]: %p %s\n", dev->minor_bus,
0350 dev, dev->name ? dev->name : "NO_NAME");
0351 dev = dev->next_in_bus;
0352 }
0353 DRVMGR_UNLOCK();
0354 }
0355 }
0356
0357 void drvmgr_info_drv(struct drvmgr_drv *drv, unsigned int options)
0358 {
0359 struct drvmgr_dev *dev;
0360 int i;
0361
0362
0363 printf(" -- DRIVER %p --\n", drv);
0364 printf(" DRIVER ID: 0x%" PRIx64 "\n", drv->drv_id);
0365 printf(" NAME: %s\n", drv->name ? drv->name : "NO_NAME");
0366 printf(" BUS TYPE: %d\n", drv->bus_type);
0367 printf(" OPERATIONS:\n");
0368 for (i = 0; i < DRVMGR_LEVEL_MAX; i++)
0369 printf(" init[%d]: %p\n", i + 1, drv->ops->init[i]);
0370 printf(" remove: %p\n", drv->ops->remove);
0371 printf(" info: %p\n", drv->ops->info);
0372 printf(" NO. DEVICES: %d\n", drv->dev_cnt);
0373
0374
0375 if (options & OPTION_DRV_DEVS) {
0376 DRVMGR_LOCK_READ();
0377 dev = drv->dev;
0378 while (dev) {
0379 printf(" DEV[%02d]: %p %s\n", dev->minor_drv,
0380 dev, dev->name ? dev->name : "NO_NAME");
0381 dev = dev->next_in_drv;
0382 }
0383 DRVMGR_UNLOCK();
0384 }
0385 }
0386
0387 void (*info_obj[3])(void *obj, unsigned int) = {
0388 (void (*)(void *, unsigned int))drvmgr_info_drv,
0389 (void (*)(void *, unsigned int))drvmgr_info_bus,
0390 (void (*)(void *, unsigned int))drvmgr_info_dev,
0391 };
0392
0393
0394 void drvmgr_info(void *id, unsigned int options)
0395 {
0396 int obj_type;
0397 void (*func)(void *, unsigned int);
0398
0399 if (!id)
0400 return;
0401 obj_type = *(int *)id;
0402 if ((obj_type < DRVMGR_OBJ_DRV) || (obj_type > DRVMGR_OBJ_DEV))
0403 return;
0404 func = info_obj[obj_type - 1];
0405 func(id, options);
0406 }
0407
0408 void drvmgr_info_devs_on_bus(struct drvmgr_bus *bus, unsigned int options)
0409 {
0410 struct drvmgr_dev *dev;
0411
0412
0413 printf("\n\n -= All Devices on BUS %p =-\n\n", bus);
0414 dev = bus->children;
0415 while (dev) {
0416 drvmgr_info_dev(dev, options);
0417 puts("");
0418 dev = dev->next_in_bus;
0419 }
0420
0421 if ((options & OPTION_RECURSIVE) == 0)
0422 return;
0423
0424
0425 dev = bus->children;
0426 while (dev) {
0427 if (dev->bus)
0428 drvmgr_info_devs_on_bus(dev->bus, options);
0429 dev = dev->next_in_bus;
0430 }
0431 }
0432
0433 void drvmgr_info_devs(unsigned int options)
0434 {
0435 struct drvmgr *mgr = &drvmgr;
0436 struct drvmgr_dev *dev;
0437
0438
0439 dev = &mgr->root_dev;
0440 drvmgr_info_devs_on_bus(dev->bus, options);
0441 printf("\n\n");
0442 }
0443
0444 void drvmgr_info_drvs(unsigned int options)
0445 {
0446 struct drvmgr *mgr = &drvmgr;
0447 struct drvmgr_drv *drv;
0448
0449 drv = DRV_LIST_HEAD(&mgr->drivers);
0450 while (drv) {
0451 drvmgr_info_drv(drv, options);
0452 puts("\n");
0453 drv = drv->next;
0454 }
0455 }
0456
0457 void drvmgr_info_buses(unsigned int options)
0458 {
0459 struct drvmgr *mgr = &drvmgr;
0460 struct drvmgr_bus *bus;
0461
0462 bus = BUS_LIST_HEAD(&mgr->buses[DRVMGR_LEVEL_MAX]);
0463 while (bus) {
0464 drvmgr_info_bus(bus, options);
0465 puts("\n");
0466 bus = bus->next;
0467 }
0468 }