aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/usb-rx.c
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-10-19 22:10:59 -0400
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2009-11-03 15:49:40 -0500
commitfaf57162e462eafe87458e21bf641f9d138f8171 (patch)
treec59c3a457768924a37b2feb80125b35cd15ac056 /drivers/net/wimax/i2400m/usb-rx.c
parentfae92216da87d1c78aa51c4503acb312a47266e9 (diff)
wimax/i2400m: handle USB stalls
When the device stalls, clear it and retry; if it keeps failing too often, reset the device. This specially happens when running on virtual machines; the real hardware doesn't seem to trip on stalls too much, except for a few reports in the mailing list (still to be confirmed this is the cause, although it seems likely. NOTE: it is not clear if the URB has to be resubmitted fully or start only at the offset of the first transaction sent. Can't find documentation to clarify one end or the other. Tests that just resubmit the whole URB seemed to work in my environment. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers/net/wimax/i2400m/usb-rx.c')
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c
index 22d127bf79e1..ba1b02362dfc 100644
--- a/drivers/net/wimax/i2400m/usb-rx.c
+++ b/drivers/net/wimax/i2400m/usb-rx.c
@@ -222,6 +222,26 @@ retry:
222 goto retry; /* ZLP, just resubmit */ 222 goto retry; /* ZLP, just resubmit */
223 skb_put(rx_skb, read_size); 223 skb_put(rx_skb, read_size);
224 break; 224 break;
225 case -EPIPE:
226 /*
227 * Stall -- maybe the device is choking with our
228 * requests. Clear it and give it some time. If they
229 * happen to often, it might be another symptom, so we
230 * reset.
231 *
232 * No error handling for usb_clear_halt(0; if it
233 * works, the retry works; if it fails, this switch
234 * does the error handling for us.
235 */
236 if (edc_inc(&i2400mu->urb_edc,
237 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
238 dev_err(dev, "BM-CMD: too many stalls in "
239 "URB; resetting device\n");
240 goto do_reset;
241 }
242 usb_clear_halt(i2400mu->usb_dev, usb_pipe);
243 msleep(10); /* give the device some time */
244 goto retry;
225 case -EINVAL: /* while removing driver */ 245 case -EINVAL: /* while removing driver */
226 case -ENODEV: /* dev disconnect ... */ 246 case -ENODEV: /* dev disconnect ... */
227 case -ENOENT: /* just ignore it */ 247 case -ENOENT: /* just ignore it */
@@ -283,6 +303,7 @@ out:
283error_reset: 303error_reset:
284 dev_err(dev, "RX: maximum errors in URB exceeded; " 304 dev_err(dev, "RX: maximum errors in URB exceeded; "
285 "resetting device\n"); 305 "resetting device\n");
306do_reset:
286 usb_queue_reset_device(i2400mu->usb_iface); 307 usb_queue_reset_device(i2400mu->usb_iface);
287 rx_skb = ERR_PTR(result); 308 rx_skb = ERR_PTR(result);
288 goto out; 309 goto out;