blob: 4f35108a369c8fbfbd197941e6359c3ead6542f7 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Sebastian Siewior3aab70a2014-05-05 15:08:10 -05002/*
3 * Copyright 2008 - 2009 Windriver, <www.windriver.com>
4 * Author: Tom Rix <Tom.Rix@windriver.com>
5 *
6 * (C) Copyright 2014 Linaro, Ltd.
7 * Rob Herring <robh@kernel.org>
Sebastian Siewior3aab70a2014-05-05 15:08:10 -05008 */
9#include <common.h>
10#include <command.h>
Simon Glass24b852a2015-11-08 23:47:45 -070011#include <console.h>
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050012#include <g_dnl.h>
Alex Kiernanf73a7df2018-05-29 15:30:53 +000013#include <fastboot.h>
14#include <net.h>
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020015#include <usb.h>
Sean Nyekjaer731785d2019-01-24 15:17:21 +010016#include <watchdog.h>
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050017
Alex Kiernanf73a7df2018-05-29 15:30:53 +000018static int do_fastboot_udp(int argc, char *const argv[],
19 uintptr_t buf_addr, size_t buf_size)
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050020{
Alex Kiernanf73a7df2018-05-29 15:30:53 +000021#if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)
22 int err = net_loop(FASTBOOT);
23
24 if (err < 0) {
25 printf("fastboot udp error: %d\n", err);
26 return CMD_RET_FAILURE;
27 }
28
29 return CMD_RET_SUCCESS;
30#else
31 pr_err("Fastboot UDP not enabled\n");
32 return CMD_RET_FAILURE;
33#endif
34}
35
36static int do_fastboot_usb(int argc, char *const argv[],
37 uintptr_t buf_addr, size_t buf_size)
38{
39#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020040 int controller_index;
41 char *usb_controller;
Sam Protsenkoaa515792018-06-29 21:59:40 +030042 char *endp;
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050043 int ret;
44
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020045 if (argc < 2)
46 return CMD_RET_USAGE;
47
48 usb_controller = argv[1];
Sam Protsenkoaa515792018-06-29 21:59:40 +030049 controller_index = simple_strtoul(usb_controller, &endp, 0);
50 if (*endp != '\0') {
51 pr_err("Error: Wrong USB controller index format\n");
52 return CMD_RET_FAILURE;
53 }
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020054
Jean-Jacques Hiblota06955a2018-11-29 10:52:41 +010055 ret = usb_gadget_initialize(controller_index);
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020056 if (ret) {
Seung-Woo Kim71002b52018-06-04 16:04:51 +090057 pr_err("USB init failed: %d\n", ret);
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020058 return CMD_RET_FAILURE;
59 }
60
Rob Herring267abc62014-12-10 14:43:04 -060061 g_dnl_clear_detach();
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050062 ret = g_dnl_register("usb_dnl_fastboot");
63 if (ret)
64 return ret;
65
Rob Herring7c23bcb2015-01-26 15:14:41 -060066 if (!g_dnl_board_usb_cable_connected()) {
67 puts("\rUSB cable not detected.\n" \
68 "Command exit.\n");
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020069 ret = CMD_RET_FAILURE;
70 goto exit;
Rob Herring7c23bcb2015-01-26 15:14:41 -060071 }
72
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050073 while (1) {
Rob Herring267abc62014-12-10 14:43:04 -060074 if (g_dnl_detach())
75 break;
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050076 if (ctrlc())
77 break;
Sean Nyekjaer731785d2019-01-24 15:17:21 +010078 WATCHDOG_RESET();
Paul Kocialkowskieca76b72015-05-24 11:41:04 +020079 usb_gadget_handle_interrupts(controller_index);
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050080 }
81
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020082 ret = CMD_RET_SUCCESS;
83
84exit:
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050085 g_dnl_unregister();
Rob Herring267abc62014-12-10 14:43:04 -060086 g_dnl_clear_detach();
Jean-Jacques Hiblota06955a2018-11-29 10:52:41 +010087 usb_gadget_release(controller_index);
Paul Kocialkowski8d2f0032015-06-12 19:57:00 +020088
89 return ret;
Alex Kiernanf73a7df2018-05-29 15:30:53 +000090#else
91 pr_err("Fastboot USB not enabled\n");
92 return CMD_RET_FAILURE;
93#endif
Sebastian Siewior3aab70a2014-05-05 15:08:10 -050094}
95
Simon Glass09140112020-05-10 11:40:03 -060096static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
97 char *const argv[])
Alex Kiernanf73a7df2018-05-29 15:30:53 +000098{
99 uintptr_t buf_addr = (uintptr_t)NULL;
100 size_t buf_size = 0;
101
102 if (argc < 2)
103 return CMD_RET_USAGE;
104
105 while (argc > 1 && **(argv + 1) == '-') {
106 char *arg = *++argv;
107
108 --argc;
109 while (*++arg) {
110 switch (*arg) {
111 case 'l':
112 if (--argc <= 0)
113 return CMD_RET_USAGE;
114 buf_addr = simple_strtoul(*++argv, NULL, 16);
115 goto NXTARG;
116
117 case 's':
118 if (--argc <= 0)
119 return CMD_RET_USAGE;
120 buf_size = simple_strtoul(*++argv, NULL, 16);
121 goto NXTARG;
122
123 default:
124 return CMD_RET_USAGE;
125 }
126 }
127NXTARG:
128 ;
129 }
130
Sam Protsenkoaa515792018-06-29 21:59:40 +0300131 /* Handle case when USB controller param is just '-' */
132 if (argc == 1) {
133 pr_err("Error: Incorrect USB controller index\n");
134 return CMD_RET_USAGE;
135 }
136
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000137 fastboot_init((void *)buf_addr, buf_size);
138
139 if (!strcmp(argv[1], "udp"))
140 return do_fastboot_udp(argc, argv, buf_addr, buf_size);
141
142 if (!strcmp(argv[1], "usb")) {
143 argv++;
144 argc--;
145 }
146
147 return do_fastboot_usb(argc, argv, buf_addr, buf_size);
148}
149
150#ifdef CONFIG_SYS_LONGHELP
151static char fastboot_help_text[] =
152 "[-l addr] [-s size] usb <controller> | udp\n"
153 "\taddr - address of buffer used during data transfers ("
154 __stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
155 "\tsize - size of buffer used during data transfers ("
156 __stringify(CONFIG_FASTBOOT_BUF_SIZE) ")"
157 ;
158#endif
159
Sebastian Siewior3aab70a2014-05-05 15:08:10 -0500160U_BOOT_CMD(
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000161 fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
162 "run as a fastboot usb or udp device", fastboot_help_text
Sebastian Siewior3aab70a2014-05-05 15:08:10 -0500163);