linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* USB HID random timeout failures fix proposal
@ 2020-02-04  3:44 Lauri Jakku
  2020-02-04  7:20 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: Lauri Jakku @ 2020-02-04  3:44 UTC (permalink / raw)
  To: linux-usb, gregkh

Hi,


I made a patch that does to tackle the USB HID device random behavior by

re-trying to send command 400ms, 20ms sleep per try.

---------------------------------------------------------------------------------------

From d4214685de329ebe07dfd2298bce46dfae5f80bf Mon Sep 17 00:00:00 2001
From: Lauri Jakku <lja@iki.fi>
Date: Tue, 4 Feb 2020 04:52:01 +0200
Subject: [PATCH] USB HID random timeout failures fixed by trying 20 times
 send, 20ms apart, control messages, if error is timeout.

Signed-off-by: Lauri Jakku <lja@iki.fi>
---
 drivers/usb/core/message.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 5adf489428aa..5d615b2f92d8 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -20,6 +20,7 @@
 #include <linux/usb/hcd.h>     /* for usbcore internals */
 #include <linux/usb/of.h>
 #include <asm/byteorder.h>
+#include <linux/errno.h>
 
 #include "usb.h"
 
@@ -137,7 +138,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
                    __u16 size, int timeout)
 {
        struct usb_ctrlrequest *dr;
-       int ret;
+       int ret = -ETIMEDOUT;
+
+       /* retry_cnt * 10ms, max retry time set to 400ms */
+       int retry_cnt = 20;
 
        dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
        if (!dr)
@@ -149,11 +153,27 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
        dr->wIndex = cpu_to_le16(index);
        dr->wLength = cpu_to_le16(size);
 
-       ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
+       do {
+               ret = usb_internal_control_msg(dev,
+                                       pipe,
+                                       dr,
+                                       data,
+                                       size,
+                                       timeout);
+
+               /*
+                * Linger a bit, prior to the next control message
+                * or if return value is timeout, but do try few
+                * times (max 200ms) before quitting.
+                */
+               if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
+                       msleep(200);
+               else if (ret == -ETIMEDOUT)
+                       msleep(20);
+
+               /* Loop while timeout, max retry_cnt times. */
+       } while ((retry_cnt-- > 0) && (ret == -ETIMEDOUT));
 
-       /* Linger a bit, prior to the next control message. */
-       if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
-               msleep(200);
 
        kfree(dr);
 
-- 
2.25.0


-- 
Br,
Lauri J.


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

end of thread, other threads:[~2020-02-04  7:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-02-04  3:44 USB HID random timeout failures fix proposal Lauri Jakku
2020-02-04  7:20 ` Greg KH
     [not found]   ` <3de3f2e8-5ab0-92f7-bdeb-09351042e630@pp.inet.fi>
2020-02-04  7:39     ` USB: HID: " Lauri Jakku

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).