summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2012-11-30 14:54:43 +0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-12 00:14:18 +0400
commit5d390403fee54a64c660b7d42f7b38d99a486b88 (patch)
tree7996e8239e7ae1a6188dd24a5e0a0c5a1f7469b1
parentefefecf33adefcd28edfd3cee282aa9cbc3374ca (diff)
downloadlinux-5d390403fee54a64c660b7d42f7b38d99a486b88.tar.xz
uas: improve abort handler
Two changes. First we check whenever the request is linked in the work list and if so take it out. Second check whenever the command is actually in flight before asking the device to cancel it via task management, and in case it isn't just zap the data urbs and finish it. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/storage/uas.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 05f1f2b8c33b..5416f2a8f566 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -715,8 +715,23 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
uas_log_cmd_state(cmnd, __func__);
spin_lock_irqsave(&devinfo->lock, flags);
cmdinfo->state |= COMMAND_ABORTED;
- spin_unlock_irqrestore(&devinfo->lock, flags);
- ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK);
+ if (cmdinfo->state & IS_IN_WORK_LIST) {
+ spin_lock(&uas_work_lock);
+ list_del(&cmdinfo->list);
+ cmdinfo->state &= ~IS_IN_WORK_LIST;
+ spin_unlock(&uas_work_lock);
+ }
+ if (cmdinfo->state & COMMAND_INFLIGHT) {
+ spin_unlock_irqrestore(&devinfo->lock, flags);
+ ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK);
+ } else {
+ spin_unlock_irqrestore(&devinfo->lock, flags);
+ uas_unlink_data_urbs(devinfo, cmdinfo);
+ spin_lock_irqsave(&devinfo->lock, flags);
+ uas_try_complete(cmnd, __func__);
+ spin_unlock_irqrestore(&devinfo->lock, flags);
+ ret = SUCCESS;
+ }
return ret;
}