From fc40ce623603ad2b0ea1bc231834fc323ce599d4 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 11 Jul 2022 22:37:06 +0100 Subject: [PATCH] Add a "usbinit" boot option to handle various buggy USB devices. This replaces the "keyboard=buggy-usb" option, and adds a second workaround to handle the problem seen in issue #107. --- README.md | 16 ++++++++++++---- app/config.c | 11 ++++++++--- system/usbhcd.c | 4 ++-- system/usbhcd.h | 3 ++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 369438d..9d05dcf 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,13 @@ recognised: * where *type* is one of * legacy * usb - * buggy-usb + * usbdebug + * pauses after probing for USB keyboards + * usbinit=*mode* + * where *mode* is one of + * 1 = use the two-step init sequence for high speed devices + * 2 = add a second USB reset in the init sequence + * 3 = the combination of modes 1 and 2 * console=ttyS*x*,*y* * activate serial/tty console output, where *x* is one of the following IO port * 0 = 0x3F8 @@ -152,9 +158,7 @@ recognised: Memtest86+ supports both the legacy keyboard interface (using I/O ports 0x60 and 0x64) and USB keyboards (using its own USB device drivers). One or the other can be selected via the boot command line, If neither is selected, the -default is to use both. An additional option on the boot command line is -`buggy-usb` which enables the longer initialisation sequence required by some -older USB devices. +default is to use both. Older BIOSs usually support USB legacy keyboard emulation, which makes USB keyboards act like legacy keyboards connected to ports 0x60 and 0x64. This @@ -170,6 +174,10 @@ emulation and add `keyboard=legacy` on the boot command line. you enable the Compatibility System Module (CSM) in the BIOS setup. Others only support it when actually booting in legacy mode. +Many USB devices don't fully conform to the USB specification. If the USB +keyboard probe hangs or fails to detect your keyboard, try the various +workarounds provided by the "usbinit" boot option. + **NOTE**: Memtest86+'s USB device drivers are work in progress. Not all USB devices are supported yet, and there may be problems on some hardware. diff --git a/app/config.c b/app/config.c index edfe3ab..ea4d400 100644 --- a/app/config.c +++ b/app/config.c @@ -175,9 +175,6 @@ static void parse_option(const char *option, const char *params) keyboard_types = KT_LEGACY; } else if (strncmp(params, "usb", 4) == 0) { keyboard_types = KT_USB; - } else if (strncmp(params, "buggy-usb", 10) == 0) { - keyboard_types = KT_USB; - usb_init_options |= USB_EXTRA_RESET; } } else if (strncmp(option, "powersave", 10) == 0) { if (strncmp(params, "off", 4) == 0) { @@ -201,6 +198,14 @@ static void parse_option(const char *option, const char *params) enable_trace = true; } else if (strncmp(option, "usbdebug", 9) == 0) { usb_init_options |= USB_DEBUG; + } else if (strncmp(option, "usbinit", 8) == 0) { + if (strncmp(params, "1", 2) == 0) { + usb_init_options |= USB_2_STEP_INIT; + } else if (strncmp(params, "2", 2) == 0) { + usb_init_options |= USB_EXTRA_RESET; + } else if (strncmp(params, "3", 2) == 0) { + usb_init_options |= USB_2_STEP_INIT|USB_EXTRA_RESET; + } } else if (strncmp(option, "nosm", 5) == 0) { enable_sm = false; } diff --git a/system/usbhcd.c b/system/usbhcd.c index cb50b1b..456ab43 100644 --- a/system/usbhcd.c +++ b/system/usbhcd.c @@ -543,12 +543,12 @@ bool assign_usb_address(const usb_hcd_t *hcd, const usb_hub_t *hub, int port_num ep0->max_packet_size = default_max_packet_size(device_speed); ep0->interval = 0; - // The device should currently be in Default state. For loww and full speed devices, We first fetch the first + // The device should currently be in Default state. For low and full speed devices, we first fetch the first // 8 bytes of the device descriptor to discover the maximum packet size for the control endpoint. We then set // the device address, which moves the device into Address state, and fetch the full device descriptor. size_t fetch_length = sizeof(usb_device_desc_t); - if (device_speed < USB_SPEED_HIGH) { + if (device_speed < USB_SPEED_HIGH || usb_init_options & USB_2_STEP_INIT) { fetch_length = 8; goto fetch_descriptor; } diff --git a/system/usbhcd.h b/system/usbhcd.h index 3d1fc29..df81288 100644 --- a/system/usbhcd.h +++ b/system/usbhcd.h @@ -121,7 +121,8 @@ typedef enum { USB_DEFAULT_INIT = 0, USB_EXTRA_RESET = 1 << 0, USB_IGNORE_EHCI = 1 << 1, - USB_DEBUG = 1 << 2 + USB_2_STEP_INIT = 1 << 2, + USB_DEBUG = 1 << 3 } usb_init_options_t; /**