diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-08-28 17:28:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 09:46:18 -0400 |
commit | 2f697f6cbff155b3ce4053a50cdf00b5be4dda11 (patch) | |
tree | 30072ed5d37493d913da510bf87d93647fd736a8 | |
parent | 204970a4bb2f584afc430ae330cd44aee329cea4 (diff) |
USB: xhci: Set -EREMOTEIO when xHC gives bad transfer length.
The xHCI hardware reports the number of bytes untransferred for a given
transfer buffer. If the hardware reports a bytes untransferred value
greater than the submitted buffer size, we want to play it safe and say no
data was transferred. If the driver considers a short packet to be an
error, remember to set -EREMOTEIO.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d264f9a6c559..aac379e1c883 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1104,6 +1104,11 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1104 | "of %d bytes left\n", | 1104 | "of %d bytes left\n", |
1105 | TRB_LEN(event->transfer_len)); | 1105 | TRB_LEN(event->transfer_len)); |
1106 | td->urb->actual_length = 0; | 1106 | td->urb->actual_length = 0; |
1107 | if (td->urb->transfer_flags & | ||
1108 | URB_SHORT_NOT_OK) | ||
1109 | status = -EREMOTEIO; | ||
1110 | else | ||
1111 | status = 0; | ||
1107 | } | 1112 | } |
1108 | /* Don't overwrite a previously set error code */ | 1113 | /* Don't overwrite a previously set error code */ |
1109 | if (status == -EINPROGRESS) { | 1114 | if (status == -EINPROGRESS) { |
@@ -1187,6 +1192,10 @@ td_cleanup: | |||
1187 | urb->transfer_buffer_length, | 1192 | urb->transfer_buffer_length, |
1188 | urb->actual_length); | 1193 | urb->actual_length); |
1189 | urb->actual_length = 0; | 1194 | urb->actual_length = 0; |
1195 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | ||
1196 | status = -EREMOTEIO; | ||
1197 | else | ||
1198 | status = 0; | ||
1190 | } | 1199 | } |
1191 | list_del(&td->td_list); | 1200 | list_del(&td->td_list); |
1192 | /* Was this TD slated to be cancelled but completed anyway? */ | 1201 | /* Was this TD slated to be cancelled but completed anyway? */ |