Message ID | 20250318104659.1114340-11-jerome.forissier@linaro.org |
---|---|
State | New |
Headers | show |
Series | Uthreads | expand |
On 3/18/25 11:46 AM, Jerome Forissier wrote: > To prepare for the introduction of threads in the USB initialization > sequence, move code out of usb_init() into a new helper function: > usb_init_bus(). No functional change. > > Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> > Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > --- > drivers/usb/host/usb-uclass.c | 88 +++++++++++++++++++---------------- > 1 file changed, 48 insertions(+), 40 deletions(-) > > diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c > index bfec303e7af..cc803241461 100644 > --- a/drivers/usb/host/usb-uclass.c > +++ b/drivers/usb/host/usb-uclass.c > @@ -287,9 +287,55 @@ static int usb_probe_companion(struct udevice *bus) > return 0; > } > > +static int controllers_initialized; I'm afraid this won't work, you will have to track the controllers in a list somehow, because it is possible to unbind DM devices even using the 'unbind' command from U-Boot command line. Also, why not simply track the controller state using DM in the first place?
Hello Marek, On 3/18/25 13:20, Marek Vasut wrote: > On 3/18/25 11:46 AM, Jerome Forissier wrote: >> To prepare for the introduction of threads in the USB initialization >> sequence, move code out of usb_init() into a new helper function: >> usb_init_bus(). No functional change. >> >> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> >> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> >> --- >> drivers/usb/host/usb-uclass.c | 88 +++++++++++++++++++---------------- >> 1 file changed, 48 insertions(+), 40 deletions(-) >> >> diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c >> index bfec303e7af..cc803241461 100644 >> --- a/drivers/usb/host/usb-uclass.c >> +++ b/drivers/usb/host/usb-uclass.c >> @@ -287,9 +287,55 @@ static int usb_probe_companion(struct udevice *bus) >> return 0; >> } >> +static int controllers_initialized; > I'm afraid this won't work, you will have to track the controllers in a list somehow, because it is possible to unbind DM devices even using the 'unbind' command from U-Boot command line. > > Also, why not simply track the controller state using DM in the first place? I'll keep controllers_initialized local to usb_init() and use device_active() in the second uclass_foreach_dev() loop. Thanks,
Hi Jerome, On Wed, 19 Mar 2025 at 11:44, Jerome Forissier <jerome.forissier@linaro.org> wrote: > > Hello Marek, > > On 3/18/25 13:20, Marek Vasut wrote: > > On 3/18/25 11:46 AM, Jerome Forissier wrote: > >> To prepare for the introduction of threads in the USB initialization > >> sequence, move code out of usb_init() into a new helper function: > >> usb_init_bus(). No functional change. > >> > >> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> > >> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > >> --- > >> drivers/usb/host/usb-uclass.c | 88 +++++++++++++++++++---------------- > >> 1 file changed, 48 insertions(+), 40 deletions(-) > >> > >> diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c > >> index bfec303e7af..cc803241461 100644 > >> --- a/drivers/usb/host/usb-uclass.c > >> +++ b/drivers/usb/host/usb-uclass.c > >> @@ -287,9 +287,55 @@ static int usb_probe_companion(struct udevice *bus) > >> return 0; > >> } > >> +static int controllers_initialized; > > I'm afraid this won't work, you will have to track the controllers in a list somehow, because it is possible to unbind DM devices even using the 'unbind' command from U-Boot command line. > > > > Also, why not simply track the controller state using DM in the first place? > > I'll keep controllers_initialized local to usb_init() and use device_active() > in the second uclass_foreach_dev() loop. Could you please take a bit of a look at collecting the USB-scanning state into a struct? We should be able to call it using iteration: struct usb_iter iter; usb_iter_init(&iter); usb_iter_process() It could collect all the devices it finds into an alist and then the caller can take a look. The reason I am keen on this is that it will potentially allow removal of the time delays in the USB stack, so we can deal with sticks which take longer to respond. I may have this wrong, but it seems that the primary delay is in usb_urb_submit(). So what we really need is an usb_urb_async() which enqueues the urb and then another method to poll it. That would perhaps allow much faster USB since all devices would be scanning in parallel, including individual devices on the same hub. Turning the USB stack 'inside out' is how I've made bootstd work. I means that devices which are found can be reported as they are found and we can potentially wait a long time for the long-tail devices, while still returning immediately to the cmdline so the user can continue. Regards, Simon
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index bfec303e7af..cc803241461 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -287,9 +287,55 @@ static int usb_probe_companion(struct udevice *bus) return 0; } +static int controllers_initialized; + +static void usb_init_bus(struct udevice *bus) +{ + int ret; + + /* init low_level USB */ + printf("Bus %s: ", bus->name); + + /* + * For Sandbox, we need scan the device tree each time when we + * start the USB stack, in order to re-create the emulated USB + * devices and bind drivers for them before we actually do the + * driver probe. + * + * For USB onboard HUB, we need to do some non-trivial init + * like enabling a power regulator, before enumeration. + */ + if (IS_ENABLED(CONFIG_SANDBOX) || + IS_ENABLED(CONFIG_USB_ONBOARD_HUB)) { + ret = dm_scan_fdt_dev(bus); + if (ret) { + printf("USB device scan from fdt failed (%d)", ret); + return; + } + } + + ret = device_probe(bus); + if (ret == -ENODEV) { /* No such device. */ + puts("Port not available.\n"); + controllers_initialized++; + return; + } + + if (ret) { /* Other error. */ + printf("probe failed, error %d\n", ret); + return; + } + + ret = usb_probe_companion(bus); + if (ret) + return; + + controllers_initialized++; + usb_started = true; +} + int usb_init(void) { - int controllers_initialized = 0; struct usb_uclass_priv *uc_priv; struct usb_bus_priv *priv; struct udevice *bus; @@ -305,45 +351,7 @@ int usb_init(void) uc_priv = uclass_get_priv(uc); uclass_foreach_dev(bus, uc) { - /* init low_level USB */ - printf("Bus %s: ", bus->name); - - /* - * For Sandbox, we need scan the device tree each time when we - * start the USB stack, in order to re-create the emulated USB - * devices and bind drivers for them before we actually do the - * driver probe. - * - * For USB onboard HUB, we need to do some non-trivial init - * like enabling a power regulator, before enumeration. - */ - if (IS_ENABLED(CONFIG_SANDBOX) || - IS_ENABLED(CONFIG_USB_ONBOARD_HUB)) { - ret = dm_scan_fdt_dev(bus); - if (ret) { - printf("USB device scan from fdt failed (%d)", ret); - continue; - } - } - - ret = device_probe(bus); - if (ret == -ENODEV) { /* No such device. */ - puts("Port not available.\n"); - controllers_initialized++; - continue; - } - - if (ret) { /* Other error. */ - printf("probe failed, error %d\n", ret); - continue; - } - - ret = usb_probe_companion(bus); - if (ret) - continue; - - controllers_initialized++; - usb_started = true; + usb_init_bus(bus); } /*