On 9/6/26 3:01 PM, Carlo Caione wrote:
> The fastboot command currently owns USB gadget setup, protocol
> initialization, the service loop and teardown. This prevents callers
> which do not use the command line from starting USB fastboot without
> duplicating the same session lifecycle.
> 

...

> diff --git a/drivers/fastboot/fb_usb.c b/drivers/fastboot/fb_usb.c
> new file mode 100644
> index 00000000000..5c62bf42e72
> --- /dev/null
> +++ b/drivers/fastboot/fb_usb.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2026 BayLibre SAS
> + *
> + * Copyright 2008 - 2009 Windriver, <www.windriver.com>
> + * Author: Tom Rix <[email protected]>
> + *
> + * (C) Copyright 2014 Linaro, Ltd.
> + * Rob Herring <[email protected]>
> + */
> +
> +#include <console.h>
> +#include <fastboot.h>
> +#include <g_dnl.h>
> +#include <usb.h>
> +#include <u-boot/schedule.h>
> +#include <linux/errno.h>
> +#include <linux/printk.h>

Could also use stdio.h and linux/usb/gadget.h

> +
> +int fastboot_usb_run(int controller_index, void *buf_addr, u32 buf_size)
> +{
> +     struct udevice *udc;
> +     int ret;
> +
> +     ret = udc_device_get_by_index(controller_index, &udc);
> +     if (ret) {
> +             pr_err("USB init failed: %d\n", ret);
> +             return ret;
> +     }
> +
> +     fastboot_init(buf_addr, buf_size);
> +     g_dnl_clear_detach();
> +
> +     ret = g_dnl_register("usb_dnl_fastboot");
> +     if (ret)
> +             goto err_put;
> +
> +     if (!g_dnl_board_usb_cable_connected()) {
> +             puts("\rUSB cable not detected.\n"
> +                  "Command exit.\n");

Technically this can be called by something other than a command now, so
perhaps leave out the 2nd line.

> +             ret = -ENODEV;
> +             goto err_unregister;
> +     }
> +
> +     while (!g_dnl_detach()) {
> +             if (IS_ENABLED(CONFIG_CMD_FASTBOOT_ABORT_KEYED)) {
> +                     if (tstc()) {
> +                             getchar();
> +                             puts("\rOperation aborted.\n");
> +                             break;
> +                     }
> +             } else if (ctrlc()) {
> +                     break;
> +             }
> +             schedule();
> +             dm_usb_gadget_handle_interrupts(udc);
> +     }
> +

The code below runs on success to, so perhaps labels shoudl be out_ rather
than err_.

> +err_unregister:
> +     g_dnl_unregister();
> +     g_dnl_clear_detach();
> +err_put:
> +     udc_device_put(udc);
> +
> +     return ret;
> +}
> diff --git a/include/fastboot.h b/include/fastboot.h
> index b106d617749..f02d2559f2b 100644
> --- a/include/fastboot.h
> +++ b/include/fastboot.h
> @@ -125,6 +125,16 @@ void fastboot_set_progress_callback(void 
> (*progress)(const char *msg));
>   */
>  void fastboot_init(void *buf_addr, u32 buf_size);
>  
> +/**
> + * fastboot_usb_run() - run a USB fastboot session
> + *
> + * @controller_index: USB gadget controller index
> + * @buf_addr: Pointer to download buffer, or NULL for default
> + * @buf_size: Size of download buffer, or zero for default
> + * Return: 0 on success, or a negative error code
> + */
> +int fastboot_usb_run(int controller_index, void *buf_addr, u32 buf_size);
> +
>  /**
>   * fastboot_boot() - Execute fastboot boot command
>   *
> 

Reply via email to