Skip to contentSkip to conversation

usb: kbd: add transfer error interrupt handling

RFC PATCH New Stephen Warren 2 participants 3 messages Apr 11, 2015

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 usb: kbd: add transfer error interrupt handling

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.

---
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(-)
common/usb_kbd.c +3 -3
index ecc3085cc081..532551af7a6b 100644
@@ -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;
Signature · 1 line
1.9.1
#1 lore raw

RFC PATCH 1/1 usb: kbd: add transfer error interrupt handling

Quoted 7 lines · Stephen Warren

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've tracked down the issue here, and it looks like I can replace this patch with a patch to DWC2. So, ignore this patch and I'll post the DWC2 patch soon; it's working now but I need to add a timeout to a loop and do some more testing.

Quoted 3 lines

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.

#2 lore raw

RFC PATCH 1/1 usb: kbd: add transfer error interrupt handling

Quoted 6 lines · Stephen Warren
Quoted 5 lines · Stephen Warren

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.

Quoted 7 lines
Quoted 2 lines

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

I've tracked down the issue here, and it looks like I can replace this patch with a patch to DWC2. So, ignore this patch and I'll post the DWC2 patch soon; it's working now but I need to add a timeout to a loop and do some more testing.

Roger. I just got to handling my ML traffic now. Sorry for the delays!

Best regards,
Marek Vasut