mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 14:40:41 +00:00
usb: kbd: On a "usb reset" call usb_kbd_deregister() before calling usb_stop()
We need to call usb_kbd_deregister() before calling usb_stop(). usbkbd's stdio_dev->priv points to the usb_device, and usb_kbd_testc dereferences usb_device->privptr. usb_stop zeros usb_device, leaving usb_device->privptr NULL, causing bad things (tm) to happen once control returns to the main loop and usb_kbd_testc gets called. Calling usb_kbd_deregister() avoids this. Note that we do not allow the "usb reset" to continue when the deregister fails. This will be fixed in a later patch. For the same reasons always fail "usb stop" if the usb_kbd_deregister() fails, even in the force path. This can happen when CONFIG_SYS_STDIO_DEREGISTER is not set. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
0ea09dfe87
commit
6e78c74f62
1 changed files with 15 additions and 12 deletions
|
@ -430,6 +430,16 @@ static int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
}
|
||||
#endif /* CONFIG_USB_STORAGE */
|
||||
|
||||
static int do_usb_stop_keyboard(void)
|
||||
{
|
||||
#ifdef CONFIG_USB_KEYBOARD
|
||||
if (usb_kbd_deregister() != 0) {
|
||||
printf("USB not stopped: usbkbd still using USB\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* usb command intepreter
|
||||
|
@ -450,6 +460,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
if ((strncmp(argv[1], "reset", 5) == 0) ||
|
||||
(strncmp(argv[1], "start", 5) == 0)) {
|
||||
bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
|
||||
if (do_usb_stop_keyboard() != 0)
|
||||
return 1;
|
||||
usb_stop();
|
||||
printf("(Re)start USB...\n");
|
||||
if (usb_init() >= 0) {
|
||||
|
@ -468,19 +480,10 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
return 0;
|
||||
}
|
||||
if (strncmp(argv[1], "stop", 4) == 0) {
|
||||
#ifdef CONFIG_USB_KEYBOARD
|
||||
if (argc == 2) {
|
||||
if (usb_kbd_deregister() != 0) {
|
||||
printf("USB not stopped: usbkbd still"
|
||||
" using USB\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* forced stop, switch console in to serial */
|
||||
if (argc != 2)
|
||||
console_assign(stdin, "serial");
|
||||
usb_kbd_deregister();
|
||||
}
|
||||
#endif
|
||||
if (do_usb_stop_keyboard() != 0)
|
||||
return 1;
|
||||
printf("stopping USB..\n");
|
||||
usb_stop();
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue