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 17 static int do_fastboot_udp(int argc, char *const argv[], 18 uintptr_t buf_addr, size_t buf_size) 19 { 20 #if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT) 21 int err = net_loop(FASTBOOT); 22 23 if (err < 0) { 24 printf("fastboot udp error: %d\n", err); 25 return CMD_RET_FAILURE; 26 } 27 28 return CMD_RET_SUCCESS; 29 #else 30 pr_err("Fastboot UDP not enabled\n"); 31 return CMD_RET_FAILURE; 32 #endif 33 } 34 35 static int do_fastboot_usb(int argc, char *const argv[], 36 uintptr_t buf_addr, size_t buf_size) 37 { 38 #if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT) 39 int controller_index; 40 char *usb_controller; 41 int ret; 42 43 if (argc < 2) 44 return CMD_RET_USAGE; 45 46 usb_controller = argv[1]; 47 controller_index = simple_strtoul(usb_controller, NULL, 0); 48 49 ret = board_usb_init(controller_index, USB_INIT_DEVICE); 50 if (ret) { 51 pr_err("USB init failed: %d\n", ret); 52 return CMD_RET_FAILURE; 53 } 54 55 g_dnl_clear_detach(); 56 ret = g_dnl_register("usb_dnl_fastboot"); 57 if (ret) 58 return ret; 59 60 if (!g_dnl_board_usb_cable_connected()) { 61 puts("\rUSB cable not detected.\n" \ 62 "Command exit.\n"); 63 ret = CMD_RET_FAILURE; 64 goto exit; 65 } 66 67 while (1) { 68 if (g_dnl_detach()) 69 break; 70 if (ctrlc()) 71 break; 72 usb_gadget_handle_interrupts(controller_index); 73 } 74 75 ret = CMD_RET_SUCCESS; 76 77 exit: 78 g_dnl_unregister(); 79 g_dnl_clear_detach(); 80 board_usb_cleanup(controller_index, USB_INIT_DEVICE); 81 82 return ret; 83 #else 84 pr_err("Fastboot USB not enabled\n"); 85 return CMD_RET_FAILURE; 86 #endif 87 } 88 89 static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 90 { 91 uintptr_t buf_addr = (uintptr_t)NULL; 92 size_t buf_size = 0; 93 94 if (argc < 2) 95 return CMD_RET_USAGE; 96 97 while (argc > 1 && **(argv + 1) == '-') { 98 char *arg = *++argv; 99 100 --argc; 101 while (*++arg) { 102 switch (*arg) { 103 case 'l': 104 if (--argc <= 0) 105 return CMD_RET_USAGE; 106 buf_addr = simple_strtoul(*++argv, NULL, 16); 107 goto NXTARG; 108 109 case 's': 110 if (--argc <= 0) 111 return CMD_RET_USAGE; 112 buf_size = simple_strtoul(*++argv, NULL, 16); 113 goto NXTARG; 114 115 default: 116 return CMD_RET_USAGE; 117 } 118 } 119 NXTARG: 120 ; 121 } 122 123 fastboot_init((void *)buf_addr, buf_size); 124 125 if (!strcmp(argv[1], "udp")) 126 return do_fastboot_udp(argc, argv, buf_addr, buf_size); 127 128 if (!strcmp(argv[1], "usb")) { 129 argv++; 130 argc--; 131 } 132 133 return do_fastboot_usb(argc, argv, buf_addr, buf_size); 134 } 135 136 #ifdef CONFIG_SYS_LONGHELP 137 static char fastboot_help_text[] = 138 "[-l addr] [-s size] usb <controller> | udp\n" 139 "\taddr - address of buffer used during data transfers (" 140 __stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n" 141 "\tsize - size of buffer used during data transfers (" 142 __stringify(CONFIG_FASTBOOT_BUF_SIZE) ")" 143 ; 144 #endif 145 146 U_BOOT_CMD( 147 fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot, 148 "run as a fastboot usb or udp device", fastboot_help_text 149 ); 150