diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-08-21 15:40:36 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:19 -0400 |
commit | eb23105462304fd35571fd0cab1de7aec79a9ec5 (patch) | |
tree | 3579e74b3f1a6e68d42de01c122d206447454d4b | |
parent | b0d9efba3ec53468984aecef8eeaf079089f2e5a (diff) |
USB: add urb->unlinked field
This patch (as970) adds a new urb->unlinked field, which is used to
store the status of unlinked URBs since we can't use urb->status for
that purpose any more. To help simplify the HCDs, usbcore will check
urb->unlinked before calling the completion handler; if the value is
set it will automatically override the status reported by the HCD.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
CC: Olav Kongas <ok@artecdesign.ee>
CC: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
CC: Tony Olech <tony.olech@elandigitalsystems.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/core/hcd.c | 19 | ||||
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 29 | ||||
-rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/ohci-q.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 24 | ||||
-rw-r--r-- | drivers/usb/host/sl811-hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/u132-hcd.c | 124 | ||||
-rw-r--r-- | drivers/usb/host/uhci-debug.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/uhci-q.c | 9 | ||||
-rw-r--r-- | include/linux/usb.h | 1 |
11 files changed, 108 insertions, 125 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 22a098b318c0..ec17fc4d2861 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -532,8 +532,7 @@ error: | |||
532 | 532 | ||
533 | /* any errors get returned through the urb completion */ | 533 | /* any errors get returned through the urb completion */ |
534 | spin_lock_irq(&hcd_root_hub_lock); | 534 | spin_lock_irq(&hcd_root_hub_lock); |
535 | if (urb->status == -EINPROGRESS) | 535 | urb->status = status; |
536 | urb->status = status; | ||
537 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 536 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
538 | 537 | ||
539 | /* This peculiar use of spinlocks echoes what real HC drivers do. | 538 | /* This peculiar use of spinlocks echoes what real HC drivers do. |
@@ -1024,6 +1023,7 @@ int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb) | |||
1024 | switch (hcd->state) { | 1023 | switch (hcd->state) { |
1025 | case HC_STATE_RUNNING: | 1024 | case HC_STATE_RUNNING: |
1026 | case HC_STATE_RESUMING: | 1025 | case HC_STATE_RESUMING: |
1026 | urb->unlinked = 0; | ||
1027 | list_add_tail(&urb->urb_list, &urb->ep->urb_list); | 1027 | list_add_tail(&urb->urb_list, &urb->ep->urb_list); |
1028 | break; | 1028 | break; |
1029 | default: | 1029 | default: |
@@ -1071,9 +1071,9 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | |||
1071 | /* Any status except -EINPROGRESS means something already started to | 1071 | /* Any status except -EINPROGRESS means something already started to |
1072 | * unlink this URB from the hardware. So there's no more work to do. | 1072 | * unlink this URB from the hardware. So there's no more work to do. |
1073 | */ | 1073 | */ |
1074 | if (urb->status != -EINPROGRESS) | 1074 | if (urb->unlinked) |
1075 | return -EBUSY; | 1075 | return -EBUSY; |
1076 | urb->status = status; | 1076 | urb->unlinked = status; |
1077 | 1077 | ||
1078 | /* IRQ setup can easily be broken so that USB controllers | 1078 | /* IRQ setup can easily be broken so that USB controllers |
1079 | * never get completion IRQs ... maybe even the ones we need to | 1079 | * never get completion IRQs ... maybe even the ones we need to |
@@ -1259,6 +1259,10 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1259 | * (and is done using urb->hcpriv). It also released all HCD locks; | 1259 | * (and is done using urb->hcpriv). It also released all HCD locks; |
1260 | * the device driver won't cause problems if it frees, modifies, | 1260 | * the device driver won't cause problems if it frees, modifies, |
1261 | * or resubmits this URB. | 1261 | * or resubmits this URB. |
1262 | * | ||
1263 | * If @urb was unlinked, the value of @urb->status will be overridden by | ||
1264 | * @urb->unlinked. Erroneous short transfers are detected in case | ||
1265 | * the HCD hasn't checked for them. | ||
1262 | */ | 1266 | */ |
1263 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | 1267 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) |
1264 | { | 1268 | { |
@@ -1266,7 +1270,9 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | |||
1266 | usbmon_urb_complete (&hcd->self, urb); | 1270 | usbmon_urb_complete (&hcd->self, urb); |
1267 | usb_unanchor_urb(urb); | 1271 | usb_unanchor_urb(urb); |
1268 | urb->hcpriv = NULL; | 1272 | urb->hcpriv = NULL; |
1269 | if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | 1273 | if (unlikely(urb->unlinked)) |
1274 | urb->status = urb->unlinked; | ||
1275 | else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | ||
1270 | urb->actual_length < urb->transfer_buffer_length && | 1276 | urb->actual_length < urb->transfer_buffer_length && |
1271 | !urb->status)) | 1277 | !urb->status)) |
1272 | urb->status = -EREMOTEIO; | 1278 | urb->status = -EREMOTEIO; |
@@ -1305,8 +1311,7 @@ rescan: | |||
1305 | list_for_each_entry (urb, &ep->urb_list, urb_list) { | 1311 | list_for_each_entry (urb, &ep->urb_list, urb_list) { |
1306 | int is_in; | 1312 | int is_in; |
1307 | 1313 | ||
1308 | /* the urb may already have been unlinked */ | 1314 | if (urb->unlinked) |
1309 | if (urb->status != -EINPROGRESS) | ||
1310 | continue; | 1315 | continue; |
1311 | usb_get_urb (urb); | 1316 | usb_get_urb (urb); |
1312 | is_in = usb_urb_dir_in(urb); | 1317 | is_in = usb_urb_dir_in(urb); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 0cb032526ca2..f2b124cf3206 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1029,8 +1029,7 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1029 | static void maybe_set_status (struct urb *urb, int status) | 1029 | static void maybe_set_status (struct urb *urb, int status) |
1030 | { | 1030 | { |
1031 | spin_lock (&urb->lock); | 1031 | spin_lock (&urb->lock); |
1032 | if (urb->status == -EINPROGRESS) | 1032 | urb->status = status; |
1033 | urb->status = status; | ||
1034 | spin_unlock (&urb->lock); | 1033 | spin_unlock (&urb->lock); |
1035 | } | 1034 | } |
1036 | 1035 | ||
@@ -1257,10 +1256,9 @@ restart: | |||
1257 | int type; | 1256 | int type; |
1258 | 1257 | ||
1259 | urb = urbp->urb; | 1258 | urb = urbp->urb; |
1260 | if (urb->status != -EINPROGRESS) { | 1259 | if (urb->unlinked) |
1261 | /* likely it was just unlinked */ | ||
1262 | goto return_urb; | 1260 | goto return_urb; |
1263 | } else if (dum->rh_state != DUMMY_RH_RUNNING) | 1261 | else if (dum->rh_state != DUMMY_RH_RUNNING) |
1264 | continue; | 1262 | continue; |
1265 | type = usb_pipetype (urb->pipe); | 1263 | type = usb_pipetype (urb->pipe); |
1266 | 1264 | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index e80b5c417d74..a8f5408c161d 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -151,7 +151,7 @@ static void qtd_copy_status ( | |||
151 | urb->actual_length += length - QTD_LENGTH (token); | 151 | urb->actual_length += length - QTD_LENGTH (token); |
152 | 152 | ||
153 | /* don't modify error codes */ | 153 | /* don't modify error codes */ |
154 | if (unlikely (urb->status != -EINPROGRESS)) | 154 | if (unlikely(urb->unlinked)) |
155 | return; | 155 | return; |
156 | 156 | ||
157 | /* force cleanup after short read; not always an error */ | 157 | /* force cleanup after short read; not always an error */ |
@@ -232,21 +232,14 @@ __acquires(ehci->lock) | |||
232 | } | 232 | } |
233 | 233 | ||
234 | spin_lock (&urb->lock); | 234 | spin_lock (&urb->lock); |
235 | switch (urb->status) { | 235 | if (unlikely(urb->unlinked)) { |
236 | case -EINPROGRESS: /* success */ | 236 | COUNT(ehci->stats.unlink); |
237 | urb->status = 0; | 237 | } else { |
238 | default: /* fault */ | 238 | if (likely(urb->status == -EINPROGRESS || |
239 | COUNT (ehci->stats.complete); | 239 | (urb->status == -EREMOTEIO && |
240 | break; | 240 | !(urb->transfer_flags & URB_SHORT_NOT_OK)))) |
241 | case -EREMOTEIO: /* fault or normal */ | ||
242 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) | ||
243 | urb->status = 0; | 241 | urb->status = 0; |
244 | COUNT (ehci->stats.complete); | 242 | COUNT(ehci->stats.complete); |
245 | break; | ||
246 | case -ECONNRESET: /* canceled */ | ||
247 | case -ENOENT: | ||
248 | COUNT (ehci->stats.unlink); | ||
249 | break; | ||
250 | } | 243 | } |
251 | spin_unlock (&urb->lock); | 244 | spin_unlock (&urb->lock); |
252 | 245 | ||
@@ -364,7 +357,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
364 | * for the urb faulted (including short read) or | 357 | * for the urb faulted (including short read) or |
365 | * its urb was canceled. we may patch qh or qtds. | 358 | * its urb was canceled. we may patch qh or qtds. |
366 | */ | 359 | */ |
367 | if (likely (urb->status == -EINPROGRESS)) | 360 | if (likely(urb->status == -EINPROGRESS && |
361 | !urb->unlinked)) | ||
368 | continue; | 362 | continue; |
369 | 363 | ||
370 | /* issue status after short control reads */ | 364 | /* issue status after short control reads */ |
@@ -395,7 +389,8 @@ halt: | |||
395 | spin_lock (&urb->lock); | 389 | spin_lock (&urb->lock); |
396 | qtd_copy_status (ehci, urb, qtd->length, token); | 390 | qtd_copy_status (ehci, urb, qtd->length, token); |
397 | if (unlikely(urb->status == -EREMOTEIO)) { | 391 | if (unlikely(urb->status == -EREMOTEIO)) { |
398 | do_status = usb_pipecontrol(urb->pipe); | 392 | do_status = (!urb->unlinked && |
393 | usb_pipecontrol(urb->pipe)); | ||
399 | urb->status = 0; | 394 | urb->status = 0; |
400 | } | 395 | } |
401 | spin_unlock (&urb->lock); | 396 | spin_unlock (&urb->lock); |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index c2919dbc3f54..35b3507ff401 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -455,11 +455,10 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
455 | done: | 455 | done: |
456 | if (status != -EINPROGRESS) { | 456 | if (status != -EINPROGRESS) { |
457 | spin_lock(&urb->lock); | 457 | spin_lock(&urb->lock); |
458 | if (urb->status == -EINPROGRESS) | 458 | urb->status = status; |
459 | urb->status = status; | ||
460 | spin_unlock(&urb->lock); | 459 | spin_unlock(&urb->lock); |
461 | } | 460 | } |
462 | if (urb->status != -EINPROGRESS) | 461 | if (urb->status != -EINPROGRESS || urb->unlinked) |
463 | finish_request(isp116x, ep, urb); | 462 | finish_request(isp116x, ep, urb); |
464 | } | 463 | } |
465 | } | 464 | } |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 8aad6199cdcc..3c793fad178d 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -758,8 +758,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
758 | cc = TD_CC_NOERROR; | 758 | cc = TD_CC_NOERROR; |
759 | if (cc != TD_CC_NOERROR && cc < 0x0E) { | 759 | if (cc != TD_CC_NOERROR && cc < 0x0E) { |
760 | spin_lock (&urb->lock); | 760 | spin_lock (&urb->lock); |
761 | if (urb->status == -EINPROGRESS) | 761 | urb->status = cc_to_error[cc]; |
762 | urb->status = cc_to_error [cc]; | ||
763 | spin_unlock (&urb->lock); | 762 | spin_unlock (&urb->lock); |
764 | } | 763 | } |
765 | 764 | ||
@@ -972,7 +971,7 @@ rescan_this: | |||
972 | urb = td->urb; | 971 | urb = td->urb; |
973 | urb_priv = td->urb->hcpriv; | 972 | urb_priv = td->urb->hcpriv; |
974 | 973 | ||
975 | if (urb->status == -EINPROGRESS) { | 974 | if (!urb->unlinked) { |
976 | prev = &td->hwNextTD; | 975 | prev = &td->hwNextTD; |
977 | continue; | 976 | continue; |
978 | } | 977 | } |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 60248b01ce14..98b9e0547544 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -1118,7 +1118,7 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock) | |||
1118 | r8a66597->timeout_map &= ~(1 << pipenum); | 1118 | r8a66597->timeout_map &= ~(1 << pipenum); |
1119 | 1119 | ||
1120 | if (likely(td)) { | 1120 | if (likely(td)) { |
1121 | if (td->set_address && urb->status != 0) | 1121 | if (td->set_address && (urb->status != 0 || urb->unlinked)) |
1122 | r8a66597->address_map &= ~(1 << urb->setup_packet[2]); | 1122 | r8a66597->address_map &= ~(1 << urb->setup_packet[2]); |
1123 | 1123 | ||
1124 | pipe_toggle_save(r8a66597, td->pipe, urb); | 1124 | pipe_toggle_save(r8a66597, td->pipe, urb); |
@@ -1225,8 +1225,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | if (finish && pipenum != 0) { | 1227 | if (finish && pipenum != 0) { |
1228 | if (td->urb->status == -EINPROGRESS) | 1228 | td->urb->status = status; |
1229 | td->urb->status = status; | ||
1230 | finish_request(r8a66597, td, pipenum, urb); | 1229 | finish_request(r8a66597, td, pipenum, urb); |
1231 | } | 1230 | } |
1232 | } | 1231 | } |
@@ -1308,32 +1307,24 @@ static void check_next_phase(struct r8a66597 *r8a66597) | |||
1308 | switch (td->type) { | 1307 | switch (td->type) { |
1309 | case USB_PID_IN: | 1308 | case USB_PID_IN: |
1310 | case USB_PID_OUT: | 1309 | case USB_PID_OUT: |
1311 | if (urb->status != -EINPROGRESS) { | ||
1312 | finish = 1; | ||
1313 | break; | ||
1314 | } | ||
1315 | if (check_transfer_finish(td, urb)) | 1310 | if (check_transfer_finish(td, urb)) |
1316 | td->type = USB_PID_ACK; | 1311 | td->type = USB_PID_ACK; |
1317 | break; | 1312 | break; |
1318 | case USB_PID_SETUP: | 1313 | case USB_PID_SETUP: |
1319 | if (urb->status != -EINPROGRESS) | 1314 | if (urb->transfer_buffer_length == urb->actual_length) |
1320 | finish = 1; | ||
1321 | else if (urb->transfer_buffer_length == urb->actual_length) { | ||
1322 | td->type = USB_PID_ACK; | 1315 | td->type = USB_PID_ACK; |
1323 | urb->status = 0; | 1316 | else if (usb_pipeout(urb->pipe)) |
1324 | } else if (usb_pipeout(urb->pipe)) | ||
1325 | td->type = USB_PID_OUT; | 1317 | td->type = USB_PID_OUT; |
1326 | else | 1318 | else |
1327 | td->type = USB_PID_IN; | 1319 | td->type = USB_PID_IN; |
1328 | break; | 1320 | break; |
1329 | case USB_PID_ACK: | 1321 | case USB_PID_ACK: |
1330 | finish = 1; | 1322 | finish = 1; |
1331 | if (urb->status == -EINPROGRESS) | 1323 | urb->status = 0; |
1332 | urb->status = 0; | ||
1333 | break; | 1324 | break; |
1334 | } | 1325 | } |
1335 | 1326 | ||
1336 | if (finish) | 1327 | if (finish || urb->unlinked) |
1337 | finish_request(r8a66597, td, 0, urb); | 1328 | finish_request(r8a66597, td, 0, urb); |
1338 | else | 1329 | else |
1339 | start_transfer(r8a66597, td); | 1330 | start_transfer(r8a66597, td); |
@@ -1418,8 +1409,7 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) | |||
1418 | if ((tmp & INBUFM) == 0) { | 1409 | if ((tmp & INBUFM) == 0) { |
1419 | disable_irq_empty(r8a66597, pipenum); | 1410 | disable_irq_empty(r8a66597, pipenum); |
1420 | pipe_irq_disable(r8a66597, pipenum); | 1411 | pipe_irq_disable(r8a66597, pipenum); |
1421 | if (td->urb->status == -EINPROGRESS) | 1412 | td->urb->status = 0; |
1422 | td->urb->status = 0; | ||
1423 | finish_request(r8a66597, td, pipenum, td->urb); | 1413 | finish_request(r8a66597, td, pipenum, td->urb); |
1424 | } | 1414 | } |
1425 | } | 1415 | } |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index e90953a9c9fb..f0fa94148d9d 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -436,8 +436,7 @@ static void finish_request( | |||
436 | ep->nextpid = USB_PID_SETUP; | 436 | ep->nextpid = USB_PID_SETUP; |
437 | 437 | ||
438 | spin_lock(&urb->lock); | 438 | spin_lock(&urb->lock); |
439 | if (urb->status == -EINPROGRESS) | 439 | urb->status = status; |
440 | urb->status = status; | ||
441 | spin_unlock(&urb->lock); | 440 | spin_unlock(&urb->lock); |
442 | 441 | ||
443 | usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); | 442 | usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); |
@@ -598,7 +597,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) | |||
598 | bank, status, ep, urbstat); | 597 | bank, status, ep, urbstat); |
599 | } | 598 | } |
600 | 599 | ||
601 | if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)) | 600 | if (urb && (urbstat != -EINPROGRESS || urb->unlinked)) |
602 | finish_request(sl811, ep, urb, urbstat); | 601 | finish_request(sl811, ep, urb, urbstat); |
603 | } | 602 | } |
604 | 603 | ||
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 1381275d448f..db800a434b83 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -645,12 +645,12 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
645 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 645 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
646 | return; | 646 | return; |
647 | } else if (u132->going > 0) { | 647 | } else if (u132->going > 0) { |
648 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 648 | dev_err(&u132->platform_dev->dev, "device is being removed " |
649 | "%p status=%d\n", urb, urb->status); | 649 | "urb=%p\n", urb); |
650 | up(&u132->scheduler_lock); | 650 | up(&u132->scheduler_lock); |
651 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 651 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
652 | return; | 652 | return; |
653 | } else if (urb->status == -EINPROGRESS) { | 653 | } else if (!urb->unlinked) { |
654 | struct u132_ring *ring = endp->ring; | 654 | struct u132_ring *ring = endp->ring; |
655 | u8 *u = urb->transfer_buffer + urb->actual_length; | 655 | u8 *u = urb->transfer_buffer + urb->actual_length; |
656 | u8 *b = buf; | 656 | u8 *b = buf; |
@@ -716,8 +716,8 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
716 | return; | 716 | return; |
717 | } | 717 | } |
718 | } else { | 718 | } else { |
719 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 719 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
720 | "s=%d\n", urb, urb->status); | 720 | "unlinked=%d\n", urb, urb->unlinked); |
721 | up(&u132->scheduler_lock); | 721 | up(&u132->scheduler_lock); |
722 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 722 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
723 | return; | 723 | return; |
@@ -744,12 +744,12 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
744 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 744 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
745 | return; | 745 | return; |
746 | } else if (u132->going > 0) { | 746 | } else if (u132->going > 0) { |
747 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 747 | dev_err(&u132->platform_dev->dev, "device is being removed " |
748 | "%p status=%d\n", urb, urb->status); | 748 | "urb=%p\n", urb); |
749 | up(&u132->scheduler_lock); | 749 | up(&u132->scheduler_lock); |
750 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 750 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
751 | return; | 751 | return; |
752 | } else if (urb->status == -EINPROGRESS) { | 752 | } else if (!urb->unlinked) { |
753 | struct u132_ring *ring = endp->ring; | 753 | struct u132_ring *ring = endp->ring; |
754 | urb->actual_length += len; | 754 | urb->actual_length += len; |
755 | endp->toggle_bits = toggle_bits; | 755 | endp->toggle_bits = toggle_bits; |
@@ -768,8 +768,8 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
768 | return; | 768 | return; |
769 | } | 769 | } |
770 | } else { | 770 | } else { |
771 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 771 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
772 | "s=%d\n", urb, urb->status); | 772 | "unlinked=%d\n", urb, urb->unlinked); |
773 | up(&u132->scheduler_lock); | 773 | up(&u132->scheduler_lock); |
774 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 774 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
775 | return; | 775 | return; |
@@ -797,12 +797,12 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
797 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 797 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
798 | return; | 798 | return; |
799 | } else if (u132->going > 0) { | 799 | } else if (u132->going > 0) { |
800 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 800 | dev_err(&u132->platform_dev->dev, "device is being removed " |
801 | "%p status=%d\n", urb, urb->status); | 801 | "urb=%p\n", urb); |
802 | up(&u132->scheduler_lock); | 802 | up(&u132->scheduler_lock); |
803 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 803 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
804 | return; | 804 | return; |
805 | } else if (urb->status == -EINPROGRESS) { | 805 | } else if (!urb->unlinked) { |
806 | struct u132_ring *ring = endp->ring; | 806 | struct u132_ring *ring = endp->ring; |
807 | u8 *u = urb->transfer_buffer + urb->actual_length; | 807 | u8 *u = urb->transfer_buffer + urb->actual_length; |
808 | u8 *b = buf; | 808 | u8 *b = buf; |
@@ -871,8 +871,8 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
871 | return; | 871 | return; |
872 | } | 872 | } |
873 | } else { | 873 | } else { |
874 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 874 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
875 | "s=%d\n", urb, urb->status); | 875 | "unlinked=%d\n", urb, urb->unlinked); |
876 | up(&u132->scheduler_lock); | 876 | up(&u132->scheduler_lock); |
877 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 877 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
878 | return; | 878 | return; |
@@ -898,18 +898,18 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
898 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 898 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
899 | return; | 899 | return; |
900 | } else if (u132->going > 0) { | 900 | } else if (u132->going > 0) { |
901 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 901 | dev_err(&u132->platform_dev->dev, "device is being removed " |
902 | "%p status=%d\n", urb, urb->status); | 902 | "urb=%p\n", urb); |
903 | up(&u132->scheduler_lock); | 903 | up(&u132->scheduler_lock); |
904 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 904 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
905 | return; | 905 | return; |
906 | } else if (urb->status == -EINPROGRESS) { | 906 | } else if (!urb->unlinked) { |
907 | up(&u132->scheduler_lock); | 907 | up(&u132->scheduler_lock); |
908 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 908 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
909 | return; | 909 | return; |
910 | } else { | 910 | } else { |
911 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 911 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
912 | "s=%d\n", urb, urb->status); | 912 | "unlinked=%d\n", urb, urb->unlinked); |
913 | up(&u132->scheduler_lock); | 913 | up(&u132->scheduler_lock); |
914 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 914 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
915 | return; | 915 | return; |
@@ -936,12 +936,12 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
936 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 936 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
937 | return; | 937 | return; |
938 | } else if (u132->going > 0) { | 938 | } else if (u132->going > 0) { |
939 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 939 | dev_err(&u132->platform_dev->dev, "device is being removed " |
940 | "%p status=%d\n", urb, urb->status); | 940 | "urb=%p\n", urb); |
941 | up(&u132->scheduler_lock); | 941 | up(&u132->scheduler_lock); |
942 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 942 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
943 | return; | 943 | return; |
944 | } else if (urb->status == -EINPROGRESS) { | 944 | } else if (!urb->unlinked) { |
945 | struct u132_ring *ring = endp->ring; | 945 | struct u132_ring *ring = endp->ring; |
946 | u8 *u = urb->transfer_buffer; | 946 | u8 *u = urb->transfer_buffer; |
947 | u8 *b = buf; | 947 | u8 *b = buf; |
@@ -980,8 +980,8 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
980 | return; | 980 | return; |
981 | } | 981 | } |
982 | } else { | 982 | } else { |
983 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 983 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
984 | "s=%d\n", urb, urb->status); | 984 | "unlinked=%d\n", urb, urb->unlinked); |
985 | up(&u132->scheduler_lock); | 985 | up(&u132->scheduler_lock); |
986 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 986 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
987 | return; | 987 | return; |
@@ -1007,18 +1007,18 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, | |||
1007 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1007 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1008 | return; | 1008 | return; |
1009 | } else if (u132->going > 0) { | 1009 | } else if (u132->going > 0) { |
1010 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1010 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1011 | "%p status=%d\n", urb, urb->status); | 1011 | "urb=%p\n", urb); |
1012 | up(&u132->scheduler_lock); | 1012 | up(&u132->scheduler_lock); |
1013 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1013 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1014 | return; | 1014 | return; |
1015 | } else if (urb->status == -EINPROGRESS) { | 1015 | } else if (!urb->unlinked) { |
1016 | up(&u132->scheduler_lock); | 1016 | up(&u132->scheduler_lock); |
1017 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1017 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1018 | return; | 1018 | return; |
1019 | } else { | 1019 | } else { |
1020 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1020 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1021 | "s=%d\n", urb, urb->status); | 1021 | "unlinked=%d\n", urb, urb->unlinked); |
1022 | up(&u132->scheduler_lock); | 1022 | up(&u132->scheduler_lock); |
1023 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1023 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1024 | return; | 1024 | return; |
@@ -1045,12 +1045,12 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1045 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1045 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1046 | return; | 1046 | return; |
1047 | } else if (u132->going > 0) { | 1047 | } else if (u132->going > 0) { |
1048 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1048 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1049 | "%p status=%d\n", urb, urb->status); | 1049 | "urb=%p\n", urb); |
1050 | up(&u132->scheduler_lock); | 1050 | up(&u132->scheduler_lock); |
1051 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1051 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1052 | return; | 1052 | return; |
1053 | } else if (urb->status == -EINPROGRESS) { | 1053 | } else if (!urb->unlinked) { |
1054 | if (usb_pipein(urb->pipe)) { | 1054 | if (usb_pipein(urb->pipe)) { |
1055 | int retval; | 1055 | int retval; |
1056 | struct u132_ring *ring = endp->ring; | 1056 | struct u132_ring *ring = endp->ring; |
@@ -1077,8 +1077,8 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1077 | return; | 1077 | return; |
1078 | } | 1078 | } |
1079 | } else { | 1079 | } else { |
1080 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1080 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1081 | "s=%d\n", urb, urb->status); | 1081 | "unlinked=%d\n", urb, urb->unlinked); |
1082 | up(&u132->scheduler_lock); | 1082 | up(&u132->scheduler_lock); |
1083 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1083 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1084 | return; | 1084 | return; |
@@ -1106,20 +1106,20 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, | |||
1106 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1106 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1107 | return; | 1107 | return; |
1108 | } else if (u132->going > 0) { | 1108 | } else if (u132->going > 0) { |
1109 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1109 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1110 | "%p status=%d\n", urb, urb->status); | 1110 | "urb=%p\n", urb); |
1111 | up(&u132->scheduler_lock); | 1111 | up(&u132->scheduler_lock); |
1112 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1112 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1113 | return; | 1113 | return; |
1114 | } else if (urb->status == -EINPROGRESS) { | 1114 | } else if (!urb->unlinked) { |
1115 | u132->addr[0].address = 0; | 1115 | u132->addr[0].address = 0; |
1116 | endp->usb_addr = udev->usb_addr; | 1116 | endp->usb_addr = udev->usb_addr; |
1117 | up(&u132->scheduler_lock); | 1117 | up(&u132->scheduler_lock); |
1118 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1118 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1119 | return; | 1119 | return; |
1120 | } else { | 1120 | } else { |
1121 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1121 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1122 | "s=%d\n", urb, urb->status); | 1122 | "unlinked=%d\n", urb, urb->unlinked); |
1123 | up(&u132->scheduler_lock); | 1123 | up(&u132->scheduler_lock); |
1124 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1124 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1125 | return; | 1125 | return; |
@@ -1145,12 +1145,12 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1145 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1145 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1146 | return; | 1146 | return; |
1147 | } else if (u132->going > 0) { | 1147 | } else if (u132->going > 0) { |
1148 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1148 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1149 | "%p status=%d\n", urb, urb->status); | 1149 | "urb=%p\n", urb); |
1150 | up(&u132->scheduler_lock); | 1150 | up(&u132->scheduler_lock); |
1151 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1151 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1152 | return; | 1152 | return; |
1153 | } else if (urb->status == -EINPROGRESS) { | 1153 | } else if (!urb->unlinked) { |
1154 | int retval; | 1154 | int retval; |
1155 | struct u132_ring *ring = endp->ring; | 1155 | struct u132_ring *ring = endp->ring; |
1156 | up(&u132->scheduler_lock); | 1156 | up(&u132->scheduler_lock); |
@@ -1162,8 +1162,8 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1162 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1162 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1163 | return; | 1163 | return; |
1164 | } else { | 1164 | } else { |
1165 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1165 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1166 | "s=%d\n", urb, urb->status); | 1166 | "unlinked=%d\n", urb, urb->unlinked); |
1167 | up(&u132->scheduler_lock); | 1167 | up(&u132->scheduler_lock); |
1168 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1168 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1169 | return; | 1169 | return; |
@@ -1189,18 +1189,18 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
1189 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1189 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1190 | return; | 1190 | return; |
1191 | } else if (u132->going > 0) { | 1191 | } else if (u132->going > 0) { |
1192 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1192 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1193 | "%p status=%d\n", urb, urb->status); | 1193 | "urb=%p\n", urb); |
1194 | up(&u132->scheduler_lock); | 1194 | up(&u132->scheduler_lock); |
1195 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1195 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1196 | return; | 1196 | return; |
1197 | } else if (urb->status == -EINPROGRESS) { | 1197 | } else if (!urb->unlinked) { |
1198 | up(&u132->scheduler_lock); | 1198 | up(&u132->scheduler_lock); |
1199 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1199 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1200 | return; | 1200 | return; |
1201 | } else { | 1201 | } else { |
1202 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1202 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1203 | "s=%d\n", urb, urb->status); | 1203 | "unlinked=%d\n", urb, urb->unlinked); |
1204 | up(&u132->scheduler_lock); | 1204 | up(&u132->scheduler_lock); |
1205 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1205 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1206 | return; | 1206 | return; |
@@ -1227,12 +1227,12 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1227 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1227 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1228 | return; | 1228 | return; |
1229 | } else if (u132->going > 0) { | 1229 | } else if (u132->going > 0) { |
1230 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1230 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1231 | "%p status=%d\n", urb, urb->status); | 1231 | "urb=%p\n", urb); |
1232 | up(&u132->scheduler_lock); | 1232 | up(&u132->scheduler_lock); |
1233 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1233 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1234 | return; | 1234 | return; |
1235 | } else if (urb->status == -EINPROGRESS) { | 1235 | } else if (!urb->unlinked) { |
1236 | int retval; | 1236 | int retval; |
1237 | struct u132_ring *ring = endp->ring; | 1237 | struct u132_ring *ring = endp->ring; |
1238 | u8 *u = urb->transfer_buffer; | 1238 | u8 *u = urb->transfer_buffer; |
@@ -1251,8 +1251,8 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1251 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1251 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1252 | return; | 1252 | return; |
1253 | } else { | 1253 | } else { |
1254 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1254 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1255 | "s=%d\n", urb, urb->status); | 1255 | "unlinked=%d\n", urb, urb->unlinked); |
1256 | up(&u132->scheduler_lock); | 1256 | up(&u132->scheduler_lock); |
1257 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1257 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1258 | return; | 1258 | return; |
@@ -1279,12 +1279,12 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1279 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1279 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1280 | return; | 1280 | return; |
1281 | } else if (u132->going > 0) { | 1281 | } else if (u132->going > 0) { |
1282 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1282 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1283 | "%p status=%d\n", urb, urb->status); | 1283 | "urb=%p\n", urb); |
1284 | up(&u132->scheduler_lock); | 1284 | up(&u132->scheduler_lock); |
1285 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1285 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1286 | return; | 1286 | return; |
1287 | } else if (urb->status == -EINPROGRESS) { | 1287 | } else if (!urb->unlinked) { |
1288 | int retval; | 1288 | int retval; |
1289 | struct u132_ring *ring = endp->ring; | 1289 | struct u132_ring *ring = endp->ring; |
1290 | up(&u132->scheduler_lock); | 1290 | up(&u132->scheduler_lock); |
@@ -1296,8 +1296,8 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1296 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1296 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1297 | return; | 1297 | return; |
1298 | } else { | 1298 | } else { |
1299 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1299 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1300 | "s=%d\n", urb, urb->status); | 1300 | "unlinked=%d\n", urb, urb->unlinked); |
1301 | up(&u132->scheduler_lock); | 1301 | up(&u132->scheduler_lock); |
1302 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1302 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); |
1303 | return; | 1303 | return; |
@@ -2279,8 +2279,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
2279 | , u132->going); | 2279 | , u132->going); |
2280 | return -ENODEV; | 2280 | return -ENODEV; |
2281 | } else if (u132->going > 0) { | 2281 | } else if (u132->going > 0) { |
2282 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 2282 | dev_err(&u132->platform_dev->dev, "device is being removed " |
2283 | "%p status=%d\n", urb, urb->status); | 2283 | "urb=%p\n", urb); |
2284 | return -ESHUTDOWN; | 2284 | return -ESHUTDOWN; |
2285 | } else { | 2285 | } else { |
2286 | u8 usb_addr = usb_pipedevice(urb->pipe); | 2286 | u8 usb_addr = usb_pipedevice(urb->pipe); |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 1497371583b9..20cc58b97807 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -120,8 +120,8 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | |||
120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); | 120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); |
121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); | 121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); |
122 | 122 | ||
123 | if (urbp->urb->status != -EINPROGRESS) | 123 | if (urbp->urb->unlinked) |
124 | out += sprintf(out, " Status=%d", urbp->urb->status); | 124 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); |
125 | out += sprintf(out, "\n"); | 125 | out += sprintf(out, "\n"); |
126 | 126 | ||
127 | i = nactive = ninactive = 0; | 127 | i = nactive = ninactive = 0; |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index fbc3af392c26..bab567266559 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -1557,15 +1557,12 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1557 | break; | 1557 | break; |
1558 | 1558 | ||
1559 | spin_lock(&urb->lock); | 1559 | spin_lock(&urb->lock); |
1560 | if (urb->status == -EINPROGRESS) /* Not dequeued */ | 1560 | urb->status = status; |
1561 | urb->status = status; | ||
1562 | else | ||
1563 | status = ECONNRESET; /* Not -ECONNRESET */ | ||
1564 | spin_unlock(&urb->lock); | 1561 | spin_unlock(&urb->lock); |
1565 | 1562 | ||
1566 | /* Dequeued but completed URBs can't be given back unless | 1563 | /* Dequeued but completed URBs can't be given back unless |
1567 | * the QH is stopped or has finished unlinking. */ | 1564 | * the QH is stopped or has finished unlinking. */ |
1568 | if (status == ECONNRESET) { | 1565 | if (urb->unlinked) { |
1569 | if (QH_FINISHED_UNLINKING(qh)) | 1566 | if (QH_FINISHED_UNLINKING(qh)) |
1570 | qh->is_stopped = 1; | 1567 | qh->is_stopped = 1; |
1571 | else if (!qh->is_stopped) | 1568 | else if (!qh->is_stopped) |
@@ -1588,7 +1585,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1588 | restart: | 1585 | restart: |
1589 | list_for_each_entry(urbp, &qh->queue, node) { | 1586 | list_for_each_entry(urbp, &qh->queue, node) { |
1590 | urb = urbp->urb; | 1587 | urb = urbp->urb; |
1591 | if (urb->status != -EINPROGRESS) { | 1588 | if (urb->unlinked) { |
1592 | 1589 | ||
1593 | /* Fix up the TD links and save the toggles for | 1590 | /* Fix up the TD links and save the toggles for |
1594 | * non-Isochronous queues. For Isochronous queues, | 1591 | * non-Isochronous queues. For Isochronous queues, |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 92d63c6b6fc6..5c7b79088add 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -1245,6 +1245,7 @@ struct urb | |||
1245 | void *hcpriv; /* private data for host controller */ | 1245 | void *hcpriv; /* private data for host controller */ |
1246 | atomic_t use_count; /* concurrent submissions counter */ | 1246 | atomic_t use_count; /* concurrent submissions counter */ |
1247 | u8 reject; /* submissions will fail */ | 1247 | u8 reject; /* submissions will fail */ |
1248 | int unlinked; /* unlink error code */ | ||
1248 | 1249 | ||
1249 | /* public: documented fields in the urb that can be used by drivers */ | 1250 | /* public: documented fields in the urb that can be used by drivers */ |
1250 | struct list_head urb_list; /* list head for use by the urb's | 1251 | struct list_head urb_list; /* list head for use by the urb's |