1 // SPDX-License-Identifier: GPL-2.0+
8 * Copyright (C) 2012 Samsung Electronics
22 #include <linux/printk.h>
24 int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget)
26 bool dfu_reset = false;
30 ret = udc_device_get_by_index(usbctrl_index, &udc);
32 pr_err("udc_device_get_by_index failed\n");
33 return CMD_RET_FAILURE;
36 ret = g_dnl_register(usb_dnl_gadget);
38 pr_err("g_dnl_register failed");
39 ret = CMD_RET_FAILURE;
43 #ifdef CONFIG_DFU_TIMEOUT
44 unsigned long start_time = get_timer(0);
50 * Check if USB bus reset is performed after detach,
51 * which indicates that -R switch has been passed to
52 * dfu-util. In this case reboot the device
54 if (dfu_usb_get_reset()) {
60 * This extra number of dm_usb_gadget_handle_interrupts()
61 * calls is necessary to assure correct transmission
62 * completion with dfu-util
71 if (dfu_get_defer_flush()) {
73 * Call to dm_usb_gadget_handle_interrupts() is necessary
74 * to act on ZLP OUT transaction from HOST PC after
75 * transmitting the whole file.
77 * If this ZLP OUT packet is NAK'ed, the HOST libusb
78 * function fails after timeout (by default it is set to
79 * 5 seconds). In such situation the dfu-util program
80 * exits with error message.
82 dm_usb_gadget_handle_interrupts(udc);
83 ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0);
84 dfu_set_defer_flush(NULL);
86 pr_err("Deferred dfu_flush() failed!");
91 #ifdef CONFIG_DFU_TIMEOUT
92 unsigned long wait_time = dfu_get_timeout();
95 unsigned long current_time = get_timer(start_time);
97 if (current_time > wait_time) {
98 debug("Inactivity timeout, abort DFU\n");
104 if (dfu_reinit_needed)
108 dm_usb_gadget_handle_interrupts(udc);
116 do_reset(NULL, 0, 0, NULL);
118 g_dnl_clear_detach();