uas: improve abort handler
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 30 Nov 2012 10:54:43 +0000 (11:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Jan 2013 20:14:18 +0000 (12:14 -0800)
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>
drivers/usb/storage/uas.c

index 05f1f2b8c33bcc627c387600b0f7154b7e8e1c83..5416f2a8f5665115053ef3de405fe31c2ad7d443 100644 (file)
@@ -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;
 }