diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index d5b4d0a4df..ee47742d02 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -52,27 +52,37 @@ Stack::Stack() } // Check for host controller modules - void *moduleList = open_module_list("busses/usb"); - char moduleName[B_PATH_NAME_LENGTH]; - size_t bufferSize = sizeof(moduleName); + // While using a fixed list of names is inflexible it allows us to control + // the order in which we try modules. There are controllers/BIOSes that + // require UHCI/OHCI to be initialized before EHCI or otherwise they + // refuse to publish any high-speed devices. + // On other systems the ordering is probably ensured because the EHCI + // controller is required to have a higher PCI function number than the + // companion host controllers (per the EHCI specs) and it would therefore + // be enumerated as the last item. As this does not apply to us we have to + // ensure ordering using another method. + const char *moduleNames[] = { + "busses/usb/uhci", + "busses/usb/ohci", + "busses/usb/ehci", + NULL + }; TRACE(("USB Stack: looking for host controller modules\n")); - while (read_next_module_name(moduleList, moduleName, &bufferSize) == B_OK) { - bufferSize = sizeof(moduleName); - TRACE(("USB Stack: found module %s\n", moduleName)); + for (uint32 i = 0; moduleNames[i]; i++) { + TRACE(("USB Stack: looking for module %s\n", moduleNames[i])); usb_host_controller_info *module = NULL; - if (get_module(moduleName, (module_info **)&module) != B_OK) + if (get_module(moduleNames[i], (module_info **)&module) != B_OK) continue; + TRACE(("USB Stack: adding module %s\n", moduleNames[i])); if (module->add_to(this) < B_OK) continue; - TRACE(("USB Stack: module %s successfully loaded\n", moduleName)); + TRACE(("USB Stack: module %s successfully loaded\n", moduleNames[i])); } - close_module_list(moduleList); - if (fBusManagers.Count() == 0) { TRACE_ERROR(("USB Stack: no bus managers available\n")); return;