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>
21 int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget)
23 bool dfu_reset = false;
26 ret = usb_gadget_initialize(usbctrl_index);
28 pr_err("usb_gadget_initialize failed\n");
29 return CMD_RET_FAILURE;
32 ret = g_dnl_register(usb_dnl_gadget);
34 pr_err("g_dnl_register failed");
35 return CMD_RET_FAILURE;
38 #ifdef CONFIG_DFU_TIMEOUT
39 unsigned long start_time = get_timer(0);
45 * Check if USB bus reset is performed after detach,
46 * which indicates that -R switch has been passed to
47 * dfu-util. In this case reboot the device
49 if (dfu_usb_get_reset()) {
55 * This extra number of usb_gadget_handle_interrupts()
56 * calls is necessary to assure correct transmission
57 * completion with dfu-util
66 if (dfu_get_defer_flush()) {
68 * Call to usb_gadget_handle_interrupts() is necessary
69 * to act on ZLP OUT transaction from HOST PC after
70 * transmitting the whole file.
72 * If this ZLP OUT packet is NAK'ed, the HOST libusb
73 * function fails after timeout (by default it is set to
74 * 5 seconds). In such situation the dfu-util program
75 * exits with error message.
77 usb_gadget_handle_interrupts(usbctrl_index);
78 ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0);
79 dfu_set_defer_flush(NULL);
81 pr_err("Deferred dfu_flush() failed!");
86 #ifdef CONFIG_DFU_TIMEOUT
87 unsigned long wait_time = dfu_get_timeout();
90 unsigned long current_time = get_timer(start_time);
92 if (current_time > wait_time) {
93 debug("Inactivity timeout, abort DFU\n");
100 usb_gadget_handle_interrupts(usbctrl_index);
104 usb_gadget_release(usbctrl_index);
107 do_reset(NULL, 0, 0, NULL);
109 g_dnl_clear_detach();