command: Remove the cmd_tbl_t typedef
[oweals/u-boot.git] / cmd / fastboot.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
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>
8  */
9 #include <common.h>
10 #include <command.h>
11 #include <console.h>
12 #include <g_dnl.h>
13 #include <fastboot.h>
14 #include <net.h>
15 #include <usb.h>
16 #include <watchdog.h>
17
18 static int do_fastboot_udp(int argc, char *const argv[],
19                            uintptr_t buf_addr, size_t buf_size)
20 {
21 #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
36 static 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)
40         int controller_index;
41         char *usb_controller;
42         char *endp;
43         int ret;
44
45         if (argc < 2)
46                 return CMD_RET_USAGE;
47
48         usb_controller = argv[1];
49         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         }
54
55         ret = usb_gadget_initialize(controller_index);
56         if (ret) {
57                 pr_err("USB init failed: %d\n", ret);
58                 return CMD_RET_FAILURE;
59         }
60
61         g_dnl_clear_detach();
62         ret = g_dnl_register("usb_dnl_fastboot");
63         if (ret)
64                 return ret;
65
66         if (!g_dnl_board_usb_cable_connected()) {
67                 puts("\rUSB cable not detected.\n" \
68                      "Command exit.\n");
69                 ret = CMD_RET_FAILURE;
70                 goto exit;
71         }
72
73         while (1) {
74                 if (g_dnl_detach())
75                         break;
76                 if (ctrlc())
77                         break;
78                 WATCHDOG_RESET();
79                 usb_gadget_handle_interrupts(controller_index);
80         }
81
82         ret = CMD_RET_SUCCESS;
83
84 exit:
85         g_dnl_unregister();
86         g_dnl_clear_detach();
87         usb_gadget_release(controller_index);
88
89         return ret;
90 #else
91         pr_err("Fastboot USB not enabled\n");
92         return CMD_RET_FAILURE;
93 #endif
94 }
95
96 static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
97                        char *const argv[])
98 {
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                 }
127 NXTARG:
128                 ;
129         }
130
131         /* 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
137         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
151 static 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
160 U_BOOT_CMD(
161         fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
162         "run as a fastboot usb or udp device", fastboot_help_text
163 );