|
@@ -0,0 +1,96 @@
|
|
|
|
+From patchwork Tue Mar 12 09:51:42 2019
|
|
|
|
+Content-Type: text/plain; charset="utf-8"
|
|
|
|
+MIME-Version: 1.0
|
|
|
|
+Content-Transfer-Encoding: 7bit
|
|
|
|
+X-Patchwork-Submitter: Stanislaw Gruszka <[email protected]>
|
|
|
|
+X-Patchwork-Id: 10848961
|
|
|
|
+X-Patchwork-Delegate: [email protected]
|
|
|
|
+From: Stanislaw Gruszka <[email protected]>
|
|
|
|
+To: [email protected]
|
|
|
|
+Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= <[email protected]>,
|
|
|
|
+ Daniel Golle <[email protected]>, Felix Fietkau <[email protected]>,
|
|
|
|
+ Mathias Kresin <[email protected]>
|
|
|
|
+Subject: [PATCH v3 3/4] rt2x00: check number of EPROTO errors
|
|
|
|
+Date: Tue, 12 Mar 2019 10:51:42 +0100
|
|
|
|
+Message-Id: <[email protected]>
|
|
|
|
+In-Reply-To: <[email protected]>
|
|
|
|
+References: <[email protected]>
|
|
|
|
+
|
|
|
|
+Some USB host devices/drivers on some conditions can always return
|
|
|
|
+EPROTO error on submitted URBs. That can cause infinity loop in the
|
|
|
|
+rt2x00 driver.
|
|
|
|
+
|
|
|
|
+Since we can have single EPROTO errors we can not mark as device as
|
|
|
|
+removed to avoid infinity loop. However we can count consecutive
|
|
|
|
+EPROTO errors and mark device as removed if get lot of it.
|
|
|
|
+I choose number 10 as threshold.
|
|
|
|
+
|
|
|
|
+Reported-and-tested-by: Randy Oostdyk <[email protected]>
|
|
|
|
+Signed-off-by: Stanislaw Gruszka <[email protected]>
|
|
|
|
+---
|
|
|
|
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
|
|
|
|
+ drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 22 +++++++++++++++++++---
|
|
|
|
+ 2 files changed, 20 insertions(+), 3 deletions(-)
|
|
|
|
+
|
|
|
|
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
|
|
|
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
|
|
|
+@@ -1017,6 +1017,7 @@ struct rt2x00_dev {
|
|
|
|
+ unsigned int extra_tx_headroom;
|
|
|
|
+
|
|
|
|
+ struct usb_anchor *anchor;
|
|
|
|
++ unsigned int num_proto_errs;
|
|
|
|
+
|
|
|
|
+ /* Clock for System On Chip devices. */
|
|
|
|
+ struct clk *clk;
|
|
|
|
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
|
|
|
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
|
|
|
+@@ -31,6 +31,22 @@
|
|
|
|
+ #include "rt2x00.h"
|
|
|
|
+ #include "rt2x00usb.h"
|
|
|
|
+
|
|
|
|
++static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status)
|
|
|
|
++{
|
|
|
|
++ if (status == -ENODEV || status == -ENOENT)
|
|
|
|
++ return true;
|
|
|
|
++
|
|
|
|
++ if (status == -EPROTO || status == -ETIMEDOUT)
|
|
|
|
++ rt2x00dev->num_proto_errs++;
|
|
|
|
++ else
|
|
|
|
++ rt2x00dev->num_proto_errs = 0;
|
|
|
|
++
|
|
|
|
++ if (rt2x00dev->num_proto_errs > 3)
|
|
|
|
++ return true;
|
|
|
|
++
|
|
|
|
++ return false;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
+ /*
|
|
|
|
+ * Interfacing with the HW.
|
|
|
|
+ */
|
|
|
|
+@@ -57,7 +73,7 @@ int rt2x00usb_vendor_request(struct rt2x
|
|
|
|
+ if (status >= 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+- if (status == -ENODEV || status == -ENOENT) {
|
|
|
|
++ if (rt2x00usb_check_usb_error(rt2x00dev, status)) {
|
|
|
|
+ /* Device has disappeared. */
|
|
|
|
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
|
|
|
+ break;
|
|
|
|
+@@ -321,7 +337,7 @@ static bool rt2x00usb_kick_tx_entry(stru
|
|
|
|
+
|
|
|
|
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
|
|
|
+ if (status) {
|
|
|
|
+- if (status == -ENODEV || status == -ENOENT)
|
|
|
|
++ if (rt2x00usb_check_usb_error(rt2x00dev, status))
|
|
|
|
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
|
|
|
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
|
|
|
+ rt2x00lib_dmadone(entry);
|
|
|
|
+@@ -410,7 +426,7 @@ static bool rt2x00usb_kick_rx_entry(stru
|
|
|
|
+
|
|
|
|
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
|
|
|
+ if (status) {
|
|
|
|
+- if (status == -ENODEV || status == -ENOENT)
|
|
|
|
++ if (rt2x00usb_check_usb_error(rt2x00dev, status))
|
|
|
|
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
|
|
|
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
|
|
|
+ rt2x00lib_dmadone(entry);
|