
This patch allows exiting from UMS mode to u-boot prompt by detaching usb cable or by pressing ctrl+c.
Add new config: CONFIG_USB_CABLE_CHECK. If defined then board file should provide function: usb_cable_connected() (include/usb.h) that return 1 if cable is connected and 0 otherwise.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Marek Vasut marex@denx.de --- common/cmd_usb_mass_storage.c | 21 +++++++++++++-------- drivers/usb/gadget/f_mass_storage.c | 24 +++++++++++++++++++++--- include/usb.h | 10 ++++++++++ 3 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index f6ceba7..9224d3c 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: GPL-2.0+ */
+#include <errno.h> #include <common.h> #include <command.h> #include <g_dnl.h> @@ -47,16 +48,20 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, g_dnl_register("ums");
while (1) { - /* Handle control-c and timeouts */ - if (ctrlc()) { - error("The remote end did not respond in time."); - goto exit; - } - usb_gadget_handle_interrupts(); - /* Check if USB cable has been detached */ - if (fsg_main_thread(NULL) == EIO) + + rc = fsg_main_thread(NULL); + if (rc) { + /* Check I/O error */ + if (rc == -EIO) + printf("\rCheck USB cable connection\n"); + + /* Check CTRL+C */ + if (rc == -EPIPE) + printf("\rCTRL+C - Operation aborted\n"); + goto exit; + } } exit: g_dnl_unregister(); diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 9560deb..a49572d 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -245,6 +245,7 @@ #include <config.h> #include <malloc.h> #include <common.h> +#include <usb.h>
#include <linux/err.h> #include <linux/usb/ch9.h> @@ -678,6 +679,18 @@ static int sleep_thread(struct fsg_common *common) k++; }
+ if (k == 10) { + /* Handle CTRL+C */ + if (ctrlc()) + return -EPIPE; +#ifdef CONFIG_USB_CABLE_CHECK + /* Check cable connection */ + if (!usb_cable_connected()) + return -EIO; +#endif + k = 0; + } + usb_gadget_handle_interrupts(); } common->thread_wakeup_needed = 0; @@ -2389,6 +2402,7 @@ static void handle_exception(struct fsg_common *common)
int fsg_main_thread(void *common_) { + int ret; struct fsg_common *common = the_fsg_common; /* The main loop */ do { @@ -2398,12 +2412,16 @@ int fsg_main_thread(void *common_) }
if (!common->running) { - sleep_thread(common); + ret = sleep_thread(common); + if (ret) + return ret; + continue; }
- if (get_next_command(common)) - continue; + ret = get_next_command(common); + if (ret) + return ret;
if (!exception_in_progress(common)) common->state = FSG_STATE_DATA_PHASE; diff --git a/include/usb.h b/include/usb.h index 17fb68c..8c1789f 100644 --- a/include/usb.h +++ b/include/usb.h @@ -197,6 +197,16 @@ int board_usb_init(int index, enum board_usb_init_type init); */ int board_usb_cleanup(int index, enum board_usb_init_type init);
+/* + * If CONFIG_USB_CABLE_CHECK is set then this function + * should be defined in board file. + * + * @return 1 if cable is connected and 0 otherwise. + */ +#ifdef CONFIG_USB_CABLE_CHECK +int usb_cable_connected(void); +#endif + #ifdef CONFIG_USB_STORAGE
#define USB_MAX_STOR_DEV 5