aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/usb-tx.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-tx.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-tx.c')
-rw-r--r--drivers/net/wimax/i2400m/usb-tx.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/net/wimax/i2400m/usb-tx.c b/drivers/net/wimax/i2400m/usb-tx.c
index 6cdf0036a146..c65b9979f87e 100644
--- a/drivers/net/wimax/i2400m/usb-tx.c
+++ b/drivers/net/wimax/i2400m/usb-tx.c
@@ -115,6 +115,28 @@ retry:
115 result = -EIO; 115 result = -EIO;
116 } 116 }
117 break; 117 break;
118 case -EPIPE:
119 /*
120 * Stall -- maybe the device is choking with our
121 * requests. Clear it and give it some time. If they
122 * happen to often, it might be another symptom, so we
123 * reset.
124 *
125 * No error handling for usb_clear_halt(0; if it
126 * works, the retry works; if it fails, this switch
127 * does the error handling for us.
128 */
129 if (edc_inc(&i2400mu->urb_edc,
130 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
131 dev_err(dev, "BM-CMD: too many stalls in "
132 "URB; resetting device\n");
133 usb_queue_reset_device(i2400mu->usb_iface);
134 /* fallthrough */
135 } else {
136 usb_clear_halt(i2400mu->usb_dev, usb_pipe);
137 msleep(10); /* give the device some time */
138 goto retry;
139 }
118 case -EINVAL: /* while removing driver */ 140 case -EINVAL: /* while removing driver */
119 case -ENODEV: /* dev disconnect ... */ 141 case -ENODEV: /* dev disconnect ... */
120 case -ENOENT: /* just ignore it */ 142 case -ENOENT: /* just ignore it */