diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-06-19 11:54:52 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-25 22:51:00 +0400 |
commit | 8aac863e9295c42683b5b39ab65e17711e21b34c (patch) | |
tree | 8a8a11d38fa012aa19a33abbf5f1172ca5097412 /drivers/usb/storage | |
parent | b1d6769333496b05818fe6cec72ef7f7504ef9e4 (diff) | |
download | linux-8aac863e9295c42683b5b39ab65e17711e21b34c.tar.xz |
uas: improve error handling
(1) Handle data pipe errors: When the data urb failed we
didn't transfer anything, update scsi_cmnd accordingly.
(2) Cancel data transfers when we got back an error on the
status pipe.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/uas.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index b589b2e0e928..d8b7bc6ea141 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -242,6 +242,13 @@ static void uas_stat_cmplt(struct urb *urb) uas_sense_old(urb, cmnd); else uas_sense(urb, cmnd); + if (cmnd->result != 0) { + /* cancel data transfers on error */ + if (cmdinfo->state & DATA_IN_URB_INFLIGHT) + usb_unlink_urb(cmdinfo->data_in_urb); + if (cmdinfo->state & DATA_OUT_URB_INFLIGHT) + usb_unlink_urb(cmdinfo->data_out_urb); + } cmdinfo->state &= ~COMMAND_INFLIGHT; uas_try_complete(cmnd, __func__); break; @@ -272,7 +279,12 @@ static void uas_data_cmplt(struct urb *urb) cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT; } BUG_ON(sdb == NULL); - sdb->resid = sdb->length - urb->actual_length; + if (urb->status) { + /* error: no data transfered */ + sdb->resid = sdb->length; + } else { + sdb->resid = sdb->length - urb->actual_length; + } uas_try_complete(cmnd, __func__); } |