aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c54
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 */
842static 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",