diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-11-13 03:24:15 -0500 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2014-03-04 18:38:23 -0500 |
commit | c6f63207a3ba689025b2120792ea831cf72f9a81 (patch) | |
tree | 2efb774c24a33ed02a51b9bb507322f174672c5f | |
parent | 040d1a8f11f390f36a8cd7fc04c0c836639b0b6a (diff) |
uas: Fix command / task mgmt submission racing with disconnect
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
-rw-r--r-- | drivers/usb/storage/uas.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index cfe0102fcbae..8c685801e267 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -670,13 +670,15 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
670 | 670 | ||
671 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 671 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
672 | 672 | ||
673 | spin_lock_irqsave(&devinfo->lock, flags); | ||
674 | |||
673 | if (devinfo->resetting) { | 675 | if (devinfo->resetting) { |
674 | cmnd->result = DID_ERROR << 16; | 676 | cmnd->result = DID_ERROR << 16; |
675 | cmnd->scsi_done(cmnd); | 677 | cmnd->scsi_done(cmnd); |
678 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
676 | return 0; | 679 | return 0; |
677 | } | 680 | } |
678 | 681 | ||
679 | spin_lock_irqsave(&devinfo->lock, flags); | ||
680 | if (devinfo->cmnd) { | 682 | if (devinfo->cmnd) { |
681 | spin_unlock_irqrestore(&devinfo->lock, flags); | 683 | spin_unlock_irqrestore(&devinfo->lock, flags); |
682 | return SCSI_MLQUEUE_DEVICE_BUSY; | 684 | return SCSI_MLQUEUE_DEVICE_BUSY; |
@@ -740,6 +742,11 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, | |||
740 | 742 | ||
741 | spin_lock_irqsave(&devinfo->lock, flags); | 743 | spin_lock_irqsave(&devinfo->lock, flags); |
742 | 744 | ||
745 | if (devinfo->resetting) { | ||
746 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
747 | return FAILED; | ||
748 | } | ||
749 | |||
743 | if (devinfo->running_task) { | 750 | if (devinfo->running_task) { |
744 | shost_printk(KERN_INFO, shost, | 751 | shost_printk(KERN_INFO, shost, |
745 | "%s: %s: error already running a task\n", | 752 | "%s: %s: error already running a task\n", |
@@ -809,6 +816,12 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) | |||
809 | int ret; | 816 | int ret; |
810 | 817 | ||
811 | spin_lock_irqsave(&devinfo->lock, flags); | 818 | spin_lock_irqsave(&devinfo->lock, flags); |
819 | |||
820 | if (devinfo->resetting) { | ||
821 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
822 | return FAILED; | ||
823 | } | ||
824 | |||
812 | uas_mark_cmd_dead(devinfo, cmdinfo, __func__); | 825 | uas_mark_cmd_dead(devinfo, cmdinfo, __func__); |
813 | if (cmdinfo->state & COMMAND_INFLIGHT) { | 826 | if (cmdinfo->state & COMMAND_INFLIGHT) { |
814 | spin_unlock_irqrestore(&devinfo->lock, flags); | 827 | spin_unlock_irqrestore(&devinfo->lock, flags); |