aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/cmd/fastboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/cmd/fastboot.c')
-rw-r--r--roms/u-boot/cmd/fastboot.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/roms/u-boot/cmd/fastboot.c b/roms/u-boot/cmd/fastboot.c
new file mode 100644
index 000000000..ad5c06491
--- /dev/null
+++ b/roms/u-boot/cmd/fastboot.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2008 - 2009 Windriver, <www.windriver.com>
+ * Author: Tom Rix <Tom.Rix@windriver.com>
+ *
+ * (C) Copyright 2014 Linaro, Ltd.
+ * Rob Herring <robh@kernel.org>
+ */
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <g_dnl.h>
+#include <fastboot.h>
+#include <net.h>
+#include <usb.h>
+#include <watchdog.h>
+#include <linux/stringify.h>
+
+static int do_fastboot_udp(int argc, char *const argv[],
+ uintptr_t buf_addr, size_t buf_size)
+{
+#if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)
+ int err = net_loop(FASTBOOT);
+
+ if (err < 0) {
+ printf("fastboot udp error: %d\n", err);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+#else
+ pr_err("Fastboot UDP not enabled\n");
+ return CMD_RET_FAILURE;
+#endif
+}
+
+static int do_fastboot_usb(int argc, char *const argv[],
+ uintptr_t buf_addr, size_t buf_size)
+{
+#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
+ int controller_index;
+ char *usb_controller;
+ char *endp;
+ int ret;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ usb_controller = argv[1];
+ controller_index = simple_strtoul(usb_controller, &endp, 0);
+ if (*endp != '\0') {
+ pr_err("Error: Wrong USB controller index format\n");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = usb_gadget_initialize(controller_index);
+ 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;
+ }
+
+ while (1) {
+ if (g_dnl_detach())
+ break;
+ if (ctrlc())
+ break;
+ WATCHDOG_RESET();
+ usb_gadget_handle_interrupts(controller_index);
+ }
+
+ ret = CMD_RET_SUCCESS;
+
+exit:
+ g_dnl_unregister();
+ g_dnl_clear_detach();
+ usb_gadget_release(controller_index);
+
+ return ret;
+#else
+ pr_err("Fastboot USB not enabled\n");
+ return CMD_RET_FAILURE;
+#endif
+}
+
+static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ uintptr_t buf_addr = (uintptr_t)NULL;
+ size_t buf_size = 0;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ while (argc > 1 && **(argv + 1) == '-') {
+ char *arg = *++argv;
+
+ --argc;
+ while (*++arg) {
+ switch (*arg) {
+ case 'l':
+ if (--argc <= 0)
+ return CMD_RET_USAGE;
+ buf_addr = simple_strtoul(*++argv, NULL, 16);
+ goto NXTARG;
+
+ case 's':
+ if (--argc <= 0)
+ return CMD_RET_USAGE;
+ buf_size = simple_strtoul(*++argv, NULL, 16);
+ goto NXTARG;
+
+ default:
+ return CMD_RET_USAGE;
+ }
+ }
+NXTARG:
+ ;
+ }
+
+ /* Handle case when USB controller param is just '-' */
+ if (argc == 1) {
+ pr_err("Error: Incorrect USB controller index\n");
+ return CMD_RET_USAGE;
+ }
+
+ fastboot_init((void *)buf_addr, buf_size);
+
+ if (!strcmp(argv[1], "udp"))
+ return do_fastboot_udp(argc, argv, buf_addr, buf_size);
+
+ if (!strcmp(argv[1], "usb")) {
+ argv++;
+ argc--;
+ }
+
+ return do_fastboot_usb(argc, argv, buf_addr, buf_size);
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char fastboot_help_text[] =
+ "[-l addr] [-s size] usb <controller> | udp\n"
+ "\taddr - address of buffer used during data transfers ("
+ __stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
+ "\tsize - size of buffer used during data transfers ("
+ __stringify(CONFIG_FASTBOOT_BUF_SIZE) ")"
+ ;
+#endif
+
+U_BOOT_CMD(
+ fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
+ "run as a fastboot usb or udp device", fastboot_help_text
+);