1 // SPDX-License-Identifier: GPL-2.0+
6 * Lukasz Majewski <l.majewski@majess.pl>
8 * Copyright (C) 2012 Samsung Electronics
9 * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10 * Lukasz Majewski <l.majewski@samsung.com>
22 int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget)
24 bool dfu_reset = false;
27 ret = usb_gadget_initialize(usbctrl_index);
29 pr_err("usb_gadget_initialize failed\n");
30 return CMD_RET_FAILURE;
33 ret = g_dnl_register(usb_dnl_gadget);
35 pr_err("g_dnl_register failed");
36 return CMD_RET_FAILURE;
39 #ifdef CONFIG_DFU_TIMEOUT
40 unsigned long start_time = get_timer(0);
46 * Check if USB bus reset is performed after detach,
47 * which indicates that -R switch has been passed to
48 * dfu-util. In this case reboot the device
50 if (dfu_usb_get_reset()) {
56 * This extra number of usb_gadget_handle_interrupts()
57 * calls is necessary to assure correct transmission
58 * completion with dfu-util
67 if (dfu_get_defer_flush()) {
69 * Call to usb_gadget_handle_interrupts() is necessary
70 * to act on ZLP OUT transaction from HOST PC after
71 * transmitting the whole file.
73 * If this ZLP OUT packet is NAK'ed, the HOST libusb
74 * function fails after timeout (by default it is set to
75 * 5 seconds). In such situation the dfu-util program
76 * exits with error message.
78 usb_gadget_handle_interrupts(usbctrl_index);
79 ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0);
80 dfu_set_defer_flush(NULL);
82 pr_err("Deferred dfu_flush() failed!");
87 #ifdef CONFIG_DFU_TIMEOUT
88 unsigned long wait_time = dfu_get_timeout();
91 unsigned long current_time = get_timer(start_time);
93 if (current_time > wait_time) {
94 debug("Inactivity timeout, abort DFU\n");
101 usb_gadget_handle_interrupts(usbctrl_index);
105 usb_gadget_release(usbctrl_index);
108 do_reset(NULL, 0, 0, NULL);
110 g_dnl_clear_detach();