diff options
Diffstat (limited to 'drivers/net/wimax')
-rw-r--r-- | drivers/net/wimax/i2400m/usb-fw.c | 22 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/usb-rx.c | 21 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/usb-tx.c | 22 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/usb.c | 57 |
4 files changed, 116 insertions, 6 deletions
diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c index 8ec8b6d56a13..d8f6ce29efff 100644 --- a/drivers/net/wimax/i2400m/usb-fw.c +++ b/drivers/net/wimax/i2400m/usb-fw.c | |||
@@ -113,6 +113,28 @@ retry: | |||
113 | } | 113 | } |
114 | result = len; | 114 | result = len; |
115 | break; | 115 | break; |
116 | case -EPIPE: | ||
117 | /* | ||
118 | * Stall -- maybe the device is choking with our | ||
119 | * requests. Clear it and give it some time. If they | ||
120 | * happen to often, it might be another symptom, so we | ||
121 | * reset. | ||
122 | * | ||
123 | * No error handling for usb_clear_halt(0; if it | ||
124 | * works, the retry works; if it fails, this switch | ||
125 | * does the error handling for us. | ||
126 | */ | ||
127 | if (edc_inc(&i2400mu->urb_edc, | ||
128 | 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { | ||
129 | dev_err(dev, "BM-CMD: too many stalls in " | ||
130 | "URB; resetting device\n"); | ||
131 | usb_queue_reset_device(i2400mu->usb_iface); | ||
132 | /* fallthrough */ | ||
133 | } else { | ||
134 | usb_clear_halt(i2400mu->usb_dev, pipe); | ||
135 | msleep(10); /* give the device some time */ | ||
136 | goto retry; | ||
137 | } | ||
116 | case -EINVAL: /* while removing driver */ | 138 | case -EINVAL: /* while removing driver */ |
117 | case -ENODEV: /* dev disconnect ... */ | 139 | case -ENODEV: /* dev disconnect ... */ |
118 | case -ENOENT: /* just ignore it */ | 140 | case -ENOENT: /* just ignore it */ |
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: | |||
283 | error_reset: | 303 | error_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"); |
306 | do_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; |
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 */ |
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 34df0906caae..47e84ef355c5 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c | |||
@@ -172,14 +172,59 @@ int __i2400mu_send_barker(struct i2400mu *i2400mu, | |||
172 | epd = usb_get_epd(i2400mu->usb_iface, endpoint); | 172 | epd = usb_get_epd(i2400mu->usb_iface, endpoint); |
173 | pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); | 173 | pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); |
174 | memcpy(buffer, barker, barker_size); | 174 | memcpy(buffer, barker, barker_size); |
175 | retry: | ||
175 | ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size, | 176 | ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size, |
176 | &actual_len, 200); | 177 | &actual_len, 200); |
177 | if (ret < 0) { | 178 | switch (ret) { |
178 | if (ret != -EINVAL) | 179 | case 0: |
179 | dev_err(dev, "E: barker error: %d\n", ret); | 180 | if (actual_len != barker_size) { /* Too short? drop it */ |
180 | } else if (actual_len != barker_size) { | 181 | dev_err(dev, "E: %s: short write (%d B vs %zu " |
181 | dev_err(dev, "E: only %d bytes transmitted\n", actual_len); | 182 | "expected)\n", |
182 | ret = -EIO; | 183 | __func__, actual_len, barker_size); |
184 | ret = -EIO; | ||
185 | } | ||
186 | break; | ||
187 | case -EPIPE: | ||
188 | /* | ||
189 | * Stall -- maybe the device is choking with our | ||
190 | * requests. Clear it and give it some time. If they | ||
191 | * happen to often, it might be another symptom, so we | ||
192 | * reset. | ||
193 | * | ||
194 | * No error handling for usb_clear_halt(0; if it | ||
195 | * works, the retry works; if it fails, this switch | ||
196 | * does the error handling for us. | ||
197 | */ | ||
198 | if (edc_inc(&i2400mu->urb_edc, | ||
199 | 10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { | ||
200 | dev_err(dev, "E: %s: too many stalls in " | ||
201 | "URB; resetting device\n", __func__); | ||
202 | usb_queue_reset_device(i2400mu->usb_iface); | ||
203 | /* fallthrough */ | ||
204 | } else { | ||
205 | usb_clear_halt(i2400mu->usb_dev, pipe); | ||
206 | msleep(10); /* give the device some time */ | ||
207 | goto retry; | ||
208 | } | ||
209 | case -EINVAL: /* while removing driver */ | ||
210 | case -ENODEV: /* dev disconnect ... */ | ||
211 | case -ENOENT: /* just ignore it */ | ||
212 | case -ESHUTDOWN: /* and exit */ | ||
213 | case -ECONNRESET: | ||
214 | ret = -ESHUTDOWN; | ||
215 | break; | ||
216 | default: /* Some error? */ | ||
217 | if (edc_inc(&i2400mu->urb_edc, | ||
218 | EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { | ||
219 | dev_err(dev, "E: %s: maximum errors in URB " | ||
220 | "exceeded; resetting device\n", | ||
221 | __func__); | ||
222 | usb_queue_reset_device(i2400mu->usb_iface); | ||
223 | } else { | ||
224 | dev_warn(dev, "W: %s: cannot send URB: %d\n", | ||
225 | __func__, ret); | ||
226 | goto retry; | ||
227 | } | ||
183 | } | 228 | } |
184 | kfree(buffer); | 229 | kfree(buffer); |
185 | error_kzalloc: | 230 | error_kzalloc: |