diff options
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index a16f2a05736f..db287d79bdcf 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -819,7 +819,7 @@ _scsih_is_end_device(u32 device_info) | |||
819 | } | 819 | } |
820 | 820 | ||
821 | /** | 821 | /** |
822 | * mptscsih_get_scsi_lookup - returns scmd entry | 822 | * _scsih_scsi_lookup_get - returns scmd entry |
823 | * @ioc: per adapter object | 823 | * @ioc: per adapter object |
824 | * @smid: system request message index | 824 | * @smid: system request message index |
825 | * | 825 | * |
@@ -832,6 +832,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
832 | } | 832 | } |
833 | 833 | ||
834 | /** | 834 | /** |
835 | * _scsih_scsi_lookup_get_clear - returns scmd entry | ||
836 | * @ioc: per adapter object | ||
837 | * @smid: system request message index | ||
838 | * | ||
839 | * Returns the smid stored scmd pointer. | ||
840 | * Then will derefrence the stored scmd pointer. | ||
841 | */ | ||
842 | static inline struct scsi_cmnd * | ||
843 | _scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid) | ||
844 | { | ||
845 | unsigned long flags; | ||
846 | struct scsi_cmnd *scmd; | ||
847 | |||
848 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
849 | scmd = ioc->scsi_lookup[smid - 1].scmd; | ||
850 | ioc->scsi_lookup[smid - 1].scmd = NULL; | ||
851 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
852 | |||
853 | return scmd; | ||
854 | } | ||
855 | |||
856 | /** | ||
835 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup | 857 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup |
836 | * @ioc: per adapter object | 858 | * @ioc: per adapter object |
837 | * @smid: system request message index | 859 | * @smid: system request message index |
@@ -3207,7 +3229,7 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc) | |||
3207 | u16 count = 0; | 3229 | u16 count = 0; |
3208 | 3230 | ||
3209 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { | 3231 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { |
3210 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3232 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
3211 | if (!scmd) | 3233 | if (!scmd) |
3212 | continue; | 3234 | continue; |
3213 | count++; | 3235 | count++; |
@@ -3801,7 +3823,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3801 | u32 response_code = 0; | 3823 | u32 response_code = 0; |
3802 | 3824 | ||
3803 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 3825 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
3804 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3826 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
3805 | if (scmd == NULL) | 3827 | if (scmd == NULL) |
3806 | return 1; | 3828 | return 1; |
3807 | 3829 | ||
@@ -5102,6 +5124,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5102 | struct fw_event_work *fw_event) | 5124 | struct fw_event_work *fw_event) |
5103 | { | 5125 | { |
5104 | struct scsi_cmnd *scmd; | 5126 | struct scsi_cmnd *scmd; |
5127 | struct scsi_device *sdev; | ||
5105 | u16 smid, handle; | 5128 | u16 smid, handle; |
5106 | u32 lun; | 5129 | u32 lun; |
5107 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 5130 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
@@ -5112,12 +5135,17 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5112 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; | 5135 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; |
5113 | #endif | 5136 | #endif |
5114 | u16 ioc_status; | 5137 | u16 ioc_status; |
5138 | unsigned long flags; | ||
5139 | int r; | ||
5140 | |||
5115 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " | 5141 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " |
5116 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, | 5142 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, |
5117 | event_data->PortWidth)); | 5143 | event_data->PortWidth)); |
5118 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 5144 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
5119 | __func__)); | 5145 | __func__)); |
5120 | 5146 | ||
5147 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5148 | ioc->broadcast_aen_busy = 0; | ||
5121 | termination_count = 0; | 5149 | termination_count = 0; |
5122 | query_count = 0; | 5150 | query_count = 0; |
5123 | mpi_reply = ioc->tm_cmds.reply; | 5151 | mpi_reply = ioc->tm_cmds.reply; |
@@ -5125,7 +5153,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5125 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 5153 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
5126 | if (!scmd) | 5154 | if (!scmd) |
5127 | continue; | 5155 | continue; |
5128 | sas_device_priv_data = scmd->device->hostdata; | 5156 | sdev = scmd->device; |
5157 | sas_device_priv_data = sdev->hostdata; | ||
5129 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) | 5158 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) |
5130 | continue; | 5159 | continue; |
5131 | /* skip hidden raid components */ | 5160 | /* skip hidden raid components */ |
@@ -5141,6 +5170,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5141 | lun = sas_device_priv_data->lun; | 5170 | lun = sas_device_priv_data->lun; |
5142 | query_count++; | 5171 | query_count++; |
5143 | 5172 | ||
5173 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
5144 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5174 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, |
5145 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); | 5175 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); |
5146 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 5176 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
@@ -5150,14 +5180,20 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5150 | (mpi_reply->ResponseCode == | 5180 | (mpi_reply->ResponseCode == |
5151 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || | 5181 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || |
5152 | mpi_reply->ResponseCode == | 5182 | mpi_reply->ResponseCode == |
5153 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) | 5183 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) { |
5184 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5154 | continue; | 5185 | continue; |
5155 | 5186 | } | |
5156 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5187 | r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, |
5157 | MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL); | 5188 | sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, |
5189 | scmd); | ||
5190 | if (r == FAILED) | ||
5191 | sdev_printk(KERN_WARNING, sdev, "task abort: FAILED " | ||
5192 | "scmd(%p)\n", scmd); | ||
5158 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); | 5193 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); |
5194 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5159 | } | 5195 | } |
5160 | ioc->broadcast_aen_busy = 0; | 5196 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
5161 | 5197 | ||
5162 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 5198 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
5163 | "%s - exit, query_count = %d termination_count = %d\n", | 5199 | "%s - exit, query_count = %d termination_count = %d\n", |