All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan <stefan-guix@vodafonemail.de>
To: u-boot@lists.denx.de
Subject: Fixing low-speed USB keyboard detection
Date: Tue, 25 Feb 2020 18:45:22 +0100	[thread overview]
Message-ID: <5FD3A422-B6FC-4C40-A1A7-656FA384CA37@vodafonemail.de> (raw)

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

             reply	other threads:[~2020-02-25 17:45 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-25 17:45 Stefan [this message]
2020-02-26 11:04 ` Fixing low-speed USB keyboard detection 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5FD3A422-B6FC-4C40-A1A7-656FA384CA37@vodafonemail.de \
    --to=stefan-guix@vodafonemail.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.