1*2e192b24SSimon Glass /* 2*2e192b24SSimon Glass * cmd_dfu.c -- dfu command 3*2e192b24SSimon Glass * 4*2e192b24SSimon Glass * Copyright (C) 2015 5*2e192b24SSimon Glass * Lukasz Majewski <l.majewski@majess.pl> 6*2e192b24SSimon Glass * 7*2e192b24SSimon Glass * Copyright (C) 2012 Samsung Electronics 8*2e192b24SSimon Glass * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 9*2e192b24SSimon Glass * Lukasz Majewski <l.majewski@samsung.com> 10*2e192b24SSimon Glass * 11*2e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 12*2e192b24SSimon Glass */ 13*2e192b24SSimon Glass 14*2e192b24SSimon Glass #include <common.h> 15*2e192b24SSimon Glass #include <watchdog.h> 16*2e192b24SSimon Glass #include <dfu.h> 17*2e192b24SSimon Glass #include <console.h> 18*2e192b24SSimon Glass #include <g_dnl.h> 19*2e192b24SSimon Glass #include <usb.h> 20*2e192b24SSimon Glass #include <net.h> 21*2e192b24SSimon Glass 22*2e192b24SSimon Glass static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 23*2e192b24SSimon Glass { 24*2e192b24SSimon Glass bool dfu_reset = false; 25*2e192b24SSimon Glass 26*2e192b24SSimon Glass if (argc < 4) 27*2e192b24SSimon Glass return CMD_RET_USAGE; 28*2e192b24SSimon Glass 29*2e192b24SSimon Glass char *usb_controller = argv[1]; 30*2e192b24SSimon Glass char *interface = argv[2]; 31*2e192b24SSimon Glass char *devstring = argv[3]; 32*2e192b24SSimon Glass 33*2e192b24SSimon Glass int ret, i = 0; 34*2e192b24SSimon Glass #ifdef CONFIG_DFU_TFTP 35*2e192b24SSimon Glass unsigned long addr = 0; 36*2e192b24SSimon Glass if (!strcmp(argv[1], "tftp")) { 37*2e192b24SSimon Glass if (argc == 5) 38*2e192b24SSimon Glass addr = simple_strtoul(argv[4], NULL, 0); 39*2e192b24SSimon Glass 40*2e192b24SSimon Glass return update_tftp(addr, interface, devstring); 41*2e192b24SSimon Glass } 42*2e192b24SSimon Glass #endif 43*2e192b24SSimon Glass 44*2e192b24SSimon Glass ret = dfu_init_env_entities(interface, devstring); 45*2e192b24SSimon Glass if (ret) 46*2e192b24SSimon Glass goto done; 47*2e192b24SSimon Glass 48*2e192b24SSimon Glass ret = CMD_RET_SUCCESS; 49*2e192b24SSimon Glass if (argc > 4 && strcmp(argv[4], "list") == 0) { 50*2e192b24SSimon Glass dfu_show_entities(); 51*2e192b24SSimon Glass goto done; 52*2e192b24SSimon Glass } 53*2e192b24SSimon Glass 54*2e192b24SSimon Glass int controller_index = simple_strtoul(usb_controller, NULL, 0); 55*2e192b24SSimon Glass board_usb_init(controller_index, USB_INIT_DEVICE); 56*2e192b24SSimon Glass g_dnl_clear_detach(); 57*2e192b24SSimon Glass g_dnl_register("usb_dnl_dfu"); 58*2e192b24SSimon Glass while (1) { 59*2e192b24SSimon Glass if (g_dnl_detach()) { 60*2e192b24SSimon Glass /* 61*2e192b24SSimon Glass * Check if USB bus reset is performed after detach, 62*2e192b24SSimon Glass * which indicates that -R switch has been passed to 63*2e192b24SSimon Glass * dfu-util. In this case reboot the device 64*2e192b24SSimon Glass */ 65*2e192b24SSimon Glass if (dfu_usb_get_reset()) { 66*2e192b24SSimon Glass dfu_reset = true; 67*2e192b24SSimon Glass goto exit; 68*2e192b24SSimon Glass } 69*2e192b24SSimon Glass 70*2e192b24SSimon Glass /* 71*2e192b24SSimon Glass * This extra number of usb_gadget_handle_interrupts() 72*2e192b24SSimon Glass * calls is necessary to assure correct transmission 73*2e192b24SSimon Glass * completion with dfu-util 74*2e192b24SSimon Glass */ 75*2e192b24SSimon Glass if (++i == 10000) 76*2e192b24SSimon Glass goto exit; 77*2e192b24SSimon Glass } 78*2e192b24SSimon Glass 79*2e192b24SSimon Glass if (ctrlc()) 80*2e192b24SSimon Glass goto exit; 81*2e192b24SSimon Glass 82*2e192b24SSimon Glass WATCHDOG_RESET(); 83*2e192b24SSimon Glass usb_gadget_handle_interrupts(controller_index); 84*2e192b24SSimon Glass } 85*2e192b24SSimon Glass exit: 86*2e192b24SSimon Glass g_dnl_unregister(); 87*2e192b24SSimon Glass board_usb_cleanup(controller_index, USB_INIT_DEVICE); 88*2e192b24SSimon Glass done: 89*2e192b24SSimon Glass dfu_free_entities(); 90*2e192b24SSimon Glass 91*2e192b24SSimon Glass if (dfu_reset) 92*2e192b24SSimon Glass run_command("reset", 0); 93*2e192b24SSimon Glass 94*2e192b24SSimon Glass g_dnl_clear_detach(); 95*2e192b24SSimon Glass 96*2e192b24SSimon Glass return ret; 97*2e192b24SSimon Glass } 98*2e192b24SSimon Glass 99*2e192b24SSimon Glass U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu, 100*2e192b24SSimon Glass "Device Firmware Upgrade", 101*2e192b24SSimon Glass "<USB_controller> <interface> <dev> [list]\n" 102*2e192b24SSimon Glass " - device firmware upgrade via <USB_controller>\n" 103*2e192b24SSimon Glass " on device <dev>, attached to interface\n" 104*2e192b24SSimon Glass " <interface>\n" 105*2e192b24SSimon Glass " [list] - list available alt settings\n" 106*2e192b24SSimon Glass #ifdef CONFIG_DFU_TFTP 107*2e192b24SSimon Glass "dfu tftp <interface> <dev> [<addr>]\n" 108*2e192b24SSimon Glass " - device firmware upgrade via TFTP\n" 109*2e192b24SSimon Glass " on device <dev>, attached to interface\n" 110*2e192b24SSimon Glass " <interface>\n" 111*2e192b24SSimon Glass " [<addr>] - address where FIT image has been stored\n" 112*2e192b24SSimon Glass #endif 113*2e192b24SSimon Glass ); 114