int drvmgr_for_each_listdev( struct drvmgr_list *devlist, unsigned int state_set_mask, unsigned int state_clr_mask, int (*func)(struct drvmgr_dev *dev, void *arg), void *arg ) { struct drvmgr_dev *dev; int ret = 0; DRVMGR_LOCK_READ(); /* Get First Device */ dev = DEV_LIST_HEAD(devlist); while (dev) { if (((state_set_mask != 0) && ((dev->state & state_set_mask) == state_set_mask)) || ((state_clr_mask != 0) && ((dev->state & state_clr_mask) == 0)) || ((state_set_mask == 0) && (state_clr_mask == 0))) { ret = func(dev, arg); if (ret != 0) break; } dev = dev->next; } DRVMGR_UNLOCK(); return ret; }
/* Take ready devices and buses into the correct init level step by step. * Once a bus or a device has been registered there is no turning * back - they are taken to the level of the driver manager. */ void drvmgr_init_update(void) { struct rtems_driver_manager *mgr = &drv_mgr; struct drvmgr_bus *bus; struct drvmgr_dev *dev; int bus_might_been_registered; int level; /* "Lock" to make sure we don't use up the stack and that the lists * remain consistent. */ DRVMGR_LOCK_WRITE(); if (mgr->initializing_objs || (mgr->level == 0)) goto out; mgr->initializing_objs = 1; init_registered_buses: /* Take all buses and devices ready into the same stage * as the driver manager global level. */ for (level = 0; level < mgr->level; level++) { bus_might_been_registered = 0; /* Take buses into next level */ while ((bus = BUS_LIST_HEAD(&mgr->buses[level])) != NULL) { /* Remove first in the list (will be inserted in * appropriate list by do_bus_init()) */ drvmgr_list_remove_head(&mgr->buses[level]); DRVMGR_UNLOCK(); /* Initialize Bus, this will register devices on * the bus. Take bus into next level. */ do_bus_init(mgr, bus, level+1); DRVMGR_LOCK_WRITE(); } /* Take devices into next level */ while ((dev = DEV_LIST_HEAD(&mgr->devices[level])) != NULL) { /* Always process first in list */ dev = DEV_LIST_HEAD(&mgr->devices[level]); /* Remove first in the list (will be inserted in * appropriate list by do_dev_init()) */ drvmgr_list_remove_head(&mgr->devices[level]); DRVMGR_UNLOCK(); /* Initialize Device, this may register a new bus */ do_dev_init(mgr, dev, level+1); DRVMGR_LOCK_WRITE(); bus_might_been_registered = 1; } /* Make sure all buses registered and ready are taken at * the same time into init level N. */ if (bus_might_been_registered) goto init_registered_buses; } /* Release bus/device initialization "Lock" */ mgr->initializing_objs = 0; out: DRVMGR_UNLOCK(); }