static void scan_modules(const char* path) { void* cookie = open_module_list(path); if (cookie == NULL) return; while (true) { char name[B_FILE_NAME_LENGTH]; size_t length = sizeof(name); if (read_next_module_name(cookie, name, &length) != B_OK) break; TRACE(("scan %s\n", name)); module_info* module; if (get_module(name, &module) == B_OK) { // we don't need the module right now, but we give it a chance // to register itself put_module(name); } } close_module_list(cookie); }
status_t device_node::_FindBestDriver(const char* path, driver_module_info*& bestDriver, float& bestSupport, device_node* previous) { if (bestDriver == NULL) bestSupport = previous != NULL ? previous->fSupportsParent : 0.0f; void* list = open_module_list_etc(path, "driver_v1"); driver_module_info* driver; while (_GetNextDriver(list, driver) == B_OK) { if (previous != NULL && driver == previous->DriverModule()) { put_module(driver->info.name); continue; } float support = driver->supports_device(this); if (support > bestSupport) { if (bestDriver != NULL) put_module(bestDriver->info.name); bestDriver = driver; bestSupport = support; continue; // keep reference to best module around } put_module(driver->info.name); } close_module_list(list); return bestDriver != NULL ? B_OK : B_ENTRY_NOT_FOUND; }
static int load_hc_modules() { char module_name[SYS_MAX_PATH_LEN]; size_t bufsize; modules_cookie cookie; struct usb_hc_module_hooks *hooks; int err; int count = 0; // scan through the host controller module dir and load all of them cookie = module_open_list(USB_HC_MODULE_NAME_PREFIX); bufsize = sizeof(module_name); while(read_next_module_name(cookie, module_name, &bufsize) >= NO_ERROR) { bufsize = sizeof(module_name); // reset this for the next iteration err = module_get(module_name, 0, (void **)&hooks); if(err < 0) continue; err = hooks->init_hc(&hc_init_callback, hooks); if(err < 0) { module_put(module_name); // it failed, put it away } count++; } close_module_list(cookie); return count; }
static void publish_directories(const char* subPath) { if (gBootDevice < 0) { if (subPath[0]) { // we only support the top-level directory for modules return; } // we can only iterate over the known modules to find all directories KPath path("drivers"); if (path.Append(subPath) != B_OK) return; size_t length = strlen(path.Path()) + 1; // account for the separating '/' void* list = open_module_list_etc(path.Path(), "driver_v1"); char name[B_FILE_NAME_LENGTH]; size_t nameLength = sizeof(name); while (read_next_module_name(list, name, &nameLength) == B_OK) { if (nameLength == length) continue; char* leaf = name + length; char* end = strchr(leaf, '/'); if (end != NULL) end[0] = '\0'; path.SetTo(subPath); path.Append(leaf); devfs_publish_directory(path.Path()); } close_module_list(list); } else { // TODO: implement module directory traversal! } }
status_t device_node::_RegisterPath(const char* path) { void* list = open_module_list_etc(path, "driver_v1"); driver_module_info* driver; uint32 count = 0; while (_GetNextDriver(list, driver) == B_OK) { float support = driver->supports_device(this); if (support > 0.0) { TRACE((" register module \"%s\", support %f\n", driver->info.name, support)); if (driver->register_device(this) == B_OK) count++; } put_module(driver->info.name); } close_module_list(list); return count > 0 ? B_OK : B_ENTRY_NOT_FOUND; }