[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