mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
usb: ums: add ums exit feature by ctrl+c or by detach usb cable
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. Changes v2: - add a note to the README Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com> Cc: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
4b19ed6c76
commit
351e9b2069
4 changed files with 51 additions and 11 deletions
7
README
7
README
|
|
@ -1367,6 +1367,13 @@ The following options need to be configured:
|
||||||
for your device
|
for your device
|
||||||
- CONFIG_USBD_PRODUCTID 0xFFFF
|
- CONFIG_USBD_PRODUCTID 0xFFFF
|
||||||
|
|
||||||
|
Some USB device drivers may need to check USB cable attachment.
|
||||||
|
In this case you can enable following config in BoardName.h:
|
||||||
|
CONFIG_USB_CABLE_CHECK
|
||||||
|
This enables function definition:
|
||||||
|
- usb_cable_connected() in include/usb.h
|
||||||
|
Implementation of this function is board-specific.
|
||||||
|
|
||||||
- ULPI Layer Support:
|
- ULPI Layer Support:
|
||||||
The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via
|
The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via
|
||||||
the generic ULPI layer. The generic layer accesses the ULPI PHY
|
the generic ULPI layer. The generic layer accesses the ULPI PHY
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <g_dnl.h>
|
#include <g_dnl.h>
|
||||||
|
|
@ -42,16 +43,20 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
|
||||||
g_dnl_register("ums");
|
g_dnl_register("ums");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Handle control-c and timeouts */
|
usb_gadget_handle_interrupts();
|
||||||
if (ctrlc()) {
|
|
||||||
error("The remote end did not respond in time.");
|
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;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_gadget_handle_interrupts();
|
|
||||||
/* Check if USB cable has been detached */
|
|
||||||
if (fsg_main_thread(NULL) == EIO)
|
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
g_dnl_unregister();
|
g_dnl_unregister();
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <usb.h>
|
||||||
|
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
|
|
@ -675,6 +676,18 @@ static int sleep_thread(struct fsg_common *common)
|
||||||
k++;
|
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();
|
usb_gadget_handle_interrupts();
|
||||||
}
|
}
|
||||||
common->thread_wakeup_needed = 0;
|
common->thread_wakeup_needed = 0;
|
||||||
|
|
@ -2387,6 +2400,7 @@ static void handle_exception(struct fsg_common *common)
|
||||||
|
|
||||||
int fsg_main_thread(void *common_)
|
int fsg_main_thread(void *common_)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct fsg_common *common = the_fsg_common;
|
struct fsg_common *common = the_fsg_common;
|
||||||
/* The main loop */
|
/* The main loop */
|
||||||
do {
|
do {
|
||||||
|
|
@ -2396,12 +2410,16 @@ int fsg_main_thread(void *common_)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!common->running) {
|
if (!common->running) {
|
||||||
sleep_thread(common);
|
ret = sleep_thread(common);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_next_command(common))
|
ret = get_next_command(common);
|
||||||
continue;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!exception_in_progress(common))
|
if (!exception_in_progress(common))
|
||||||
common->state = FSG_STATE_DATA_PHASE;
|
common->state = FSG_STATE_DATA_PHASE;
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,16 @@ int board_usb_init(int index, enum usb_init_type init);
|
||||||
*/
|
*/
|
||||||
int board_usb_cleanup(int index, enum usb_init_type init);
|
int board_usb_cleanup(int index, enum 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
|
#ifdef CONFIG_USB_STORAGE
|
||||||
|
|
||||||
#define USB_MAX_STOR_DEV 5
|
#define USB_MAX_STOR_DEV 5
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue