All of lore.kernel.org
 help / color / mirror / Atom feed
* Fixing low-speed USB keyboard detection
@ 2020-02-25 17:45 Stefan
  2020-02-26 11:04 ` Soeren Moch
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan @ 2020-02-25 17:45 UTC (permalink / raw)
  To: u-boot

Hello!

I own a D-Link DBT-120 Bluetooth Adapter, which has a CSR firmware running in a so called ?HID proxy mode?. This firmware pretends to be a USB keyboard (and mouse) and thus allows to use a Bluetooth keyboard in U-Boot.

Unfortunately it acts as a low-speed device and there seems to be some well known troubles about low-speed USB keyboards. There is a FAQ entry for openSUSE about this: https://en.opensuse.org/HCL:Raspberry_Pi3#I_cannot_use_keyboard_in_U-Boot_and_Grub_but_it_works_in_Linux

I spend some effort to solve this issue. There are three tiny changes to get my Bluetooth keyboard working reliably as a low-speed USB keyboard.

Sometimes the Bluetooth adapter needs a bit longer to power on and send its descriptor. As I use a Raspberry Pi 3b, I modified include/configs/rpi.h to add "usb_pgood_delay=100\0" to the CONFIG_EXTRA_ENV_SETTINGS define. However this is actually not a necessary change, even without it, most of the time there is no issue.

Then the Bluetooth adapter needs one millisecond delay before accepting a new address, to avoid the error ?USB device not accepting new address?. This is in common/usb.c at line 1047:

https://github.com/u-boot/u-boot/blob/master/common/usb.c#L1047

	dev->devnum = addr;
	mdelay(1);
	err = usb_set_address(dev); /* set address */

And finally, assuming the use of CONFIG_SYS_USB_EVENT_POLL=y (which is the default), in common/usb_kbd.c at line 520 this first interrupt IN message must not be send:

https://github.com/u-boot/u-boot/blob/master/common/usb_kbd.c#L520

	if (usb_int_msg(dev, data->intpipe, data->new, data->intpktsize,
			data->intinterval, false) < 0) {
#endif
		printf("Failed to get keyboard state from device %04x:%04x\n",
		       dev->descriptor.idVendor, dev->descriptor.idProduct);
		/* Abort, we don't want to use that non-functional keyboard. */
		return 0;
	}

Due to the #if stuff around, its a bit ugly. I solved it simply by modifying the if-statement in line 520:

	if (0) {

With these two fixes my keyboard is working reliably. There is no need to press a key upfront and no error message any longer, as described for openSUSE. A chain-loaded GRUB-EFI is always usable now. I?m pretty sure that these changes will solve the issues for other low-speed USB keyboards as well.


However, with that first interrupt IN message still sent, it seemed to me that there was a NYET loop in chunk_msg() in drivers/usb/host/dwc.c once complete_split got set. I guessed that ?done += actual_len;? happens to often and possibly to early for an unfinished split transaction. With the recent fix 9dcab2c4d2cb50ab1864c818b82a72393c160236 introducing the nonblock argument, a split transfer gets restarted at a higher level, once there were to many NYET responses. But for this first interrupt IN message this nonblock argument is set to false, and in _submit_int_msg() we run into the timeout.

If I understand it correctly, once a NYET message is received, it may take up to a millisecond before a response from a low-speed device is received (one low-speed frame). And a high-speed host has a frame length of 125 ms. That means that it can take up to 8 high-speed frames before a response from a low-speed device is received. Bit chunk_msg() returns already after > 4 high-speed frames. I would expect to wait at least 8 frames.

The check after that first interrupt IN message got added by 5da2dc9789abecb1b018beb0c93f4c38c2985bc6 to workaround non-working keyboards. My suggested change will kind of revert that workaround. So there is some trade-off.


Stefan

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-03-01 17:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-25 17:45 Fixing low-speed USB keyboard detection Stefan
2020-02-26 11:04 ` Soeren Moch
2020-02-28 23:46   ` Marek Vasut
2020-02-29 12:04     ` Soeren Moch
2020-02-29 12:42       ` Stefan
2020-03-01 17:46         ` Soeren Moch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.