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.

Move that lifecycle into fastboot_usb_run() and leave cmd/fastboot.c
responsible only for argument parsing and transport selection.
Initialize network sessions in their transport path so their existing
behavior is preserved.

Signed-off-by: Julien Masson <[email protected]>
Signed-off-by: Vitor Sato Eschholz <[email protected]>
Signed-off-by: Carlo Caione <[email protected]>
---
 cmd/fastboot.c            | 53 ++++-----------------------------------
 drivers/fastboot/Makefile |  1 +
 drivers/fastboot/fb_usb.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
 include/fastboot.h        | 10 ++++++++
 4 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index f3929f88dfa..ace877b6e28 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -7,12 +7,9 @@
  * Rob Herring <[email protected]>
  */
 #include <command.h>
-#include <console.h>
-#include <g_dnl.h>
 #include <fastboot.h>
 #include <net.h>
-#include <usb.h>
-#include <watchdog.h>
+#include <vsprintf.h>
 #include <linux/printk.h>
 #include <linux/stringify.h>
 
@@ -27,6 +24,7 @@ static int do_fastboot_udp(int argc, char *const argv[],
                return CMD_RET_FAILURE;
        }
 
+       fastboot_init((void *)buf_addr, buf_size);
        err = net_loop(FASTBOOT_UDP);
 
        if (err < 0) {
@@ -47,6 +45,7 @@ static int do_fastboot_tcp(int argc, char *const argv[],
                return CMD_RET_FAILURE;
        }
 
+       fastboot_init((void *)buf_addr, buf_size);
        err = net_loop(FASTBOOT_TCP);
 
        if (err < 0) {
@@ -63,7 +62,6 @@ static int do_fastboot_usb(int argc, char *const argv[],
 {
        int controller_index;
        char *usb_controller;
-       struct udevice *udc;
        char *endp;
        int ret;
 
@@ -82,48 +80,9 @@ static int do_fastboot_usb(int argc, char *const argv[],
                return CMD_RET_FAILURE;
        }
 
-       ret = udc_device_get_by_index(controller_index, &udc);
-       if (ret) {
-               pr_err("USB init failed: %d\n", ret);
-               return CMD_RET_FAILURE;
-       }
-
-       g_dnl_clear_detach();
-       ret = g_dnl_register("usb_dnl_fastboot");
-       if (ret)
-               return ret;
-
-       if (!g_dnl_board_usb_cable_connected()) {
-               puts("\rUSB cable not detected.\n" \
-                    "Command exit.\n");
-               ret = CMD_RET_FAILURE;
-               goto exit;
-       }
+       ret = fastboot_usb_run(controller_index, (void *)buf_addr, buf_size);
 
-       while (1) {
-               if (g_dnl_detach())
-                       break;
-               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);
-       }
-
-       ret = CMD_RET_SUCCESS;
-
-exit:
-       udc_device_put(udc);
-       g_dnl_unregister();
-       g_dnl_clear_detach();
-
-       return ret;
+       return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
 }
 
 static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -167,8 +126,6 @@ NXTARG:
                return CMD_RET_USAGE;
        }
 
-       fastboot_init((void *)buf_addr, buf_size);
-
 #if CONFIG_IS_ENABLED(NET_LEGACY)
        if (!strcmp(argv[1], "udp"))
                return do_fastboot_udp(argc, argv, buf_addr, buf_size);
diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
index a341af076d1..32e8e072c88 100644
--- a/drivers/fastboot/Makefile
+++ b/drivers/fastboot/Makefile
@@ -3,6 +3,7 @@
 obj-y += fb_common.o
 obj-y += fb_getvar.o
 obj-y += fb_command.o
+obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += fb_usb.o
 obj-$(CONFIG_FASTBOOT_FLASH_BLOCK) += fb_block.o
 # MMC reuses block implementation
 obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_block.o fb_mmc.o
diff --git a/drivers/fastboot/fb_usb.c b/drivers/fastboot/fb_usb.c
new file mode 100644
index 00000000000..ecb27f28362
--- /dev/null
+++ b/drivers/fastboot/fb_usb.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * 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>
+
+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");
+               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);
+       }
+
+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
  *

-- 
2.55.0

Reply via email to