[U-Boot] [RFC PATCH] usb: kbd: add transfer error interrupt handling

Stephen Warren swarren at wwwdotorg.org
Sat Apr 11 05:07:01 CEST 2015


If the USB transfer fails or otherwise returns no data, don't process the
(non-existent) reponse data and generate keypresses from it. Doing so
makes each successful transaction appear to be a new keypress, which
results in ridiculously fast key repeat rates.

FIXME: This breaks USB keyboard on at least NVIDIA Tegra Seaboard, hence
why this is an RFC.

I wonder if submit_int_msg() is expected to keep executing until a
successful transfer is made? That would likely explain why the existing
lack of error handling has no negative effect on non-DWC2 platforms.

Signed-off-by: Stephen Warren <swarren at wwwdotorg.org>
---
With all these commits applied, both my USB keyboards (one LS Lenovo and
one FS Dell) work correctly when there is no USB hub between the SoC and
the keyboard; I still need split transactions to be implemented for hubs
to work.

Tested with this series on top of u-boot-usb/topic/dwc2 plus a patch to
enable USB keyboard in include/configs/rpi-common.h (see my github):

Model A, model A+:
* USB SD card reader
* Both keyboards
Early model B, model B, model B+, RPi 2:
* USB SD card reader
* Both keyboards
* Built-in Ethernet
Compute module:
* USB SD card reader
For some reason, the keyboards don't work on the CM. I don't believe it
has a USB hub, so I don't know why this is. Perhaps a USB power issue?
---
 common/usb_kbd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index ecc3085cc081..532551af7a6b 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -313,10 +313,10 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
 	struct usb_kbd_pdata *data = dev->privptr;
 
 	/* Submit a interrupt transfer request */
-	usb_submit_int_msg(dev, data->intpipe, &data->new[0], data->intpktsize,
+	int ret = usb_submit_int_msg(dev, data->intpipe, &data->new[0], data->intpktsize,
 			   data->intinterval);
-
-	usb_kbd_irq_worker(dev);
+	if ((!ret) && dev->act_len)
+		usb_kbd_irq_worker(dev);
 #elif	defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
 	struct usb_interface *iface;
 	struct usb_kbd_pdata *data = dev->privptr;
-- 
1.9.1



More information about the U-Boot mailing list