diff options
author | James Smart <james.smart@emulex.com> | 2014-04-04 13:52:31 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-06-02 12:29:01 -0400 |
commit | 98912dda4d287a7bc6f0b7a91cceb0fedd1492f6 (patch) | |
tree | e07fe118abc3c93d608bb5ae183f6cac483d20a3 /drivers/scsi/lpfc/lpfc_scsi.c | |
parent | f38fa0bb7c4a54dc7eff622adc6fa7cf763d834d (diff) |
lpfc: Fixed locking for scsi task management commands
Fixed locking for scsi task management commands.
Signed-off-by: James Smart <james.smart@emulex.com>
Reviewed-By: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7d0f2951ca52..aa7fbdbf4e6c 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -4783,7 +4783,9 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
4783 | struct lpfc_scsi_buf *lpfc_cmd; | 4783 | struct lpfc_scsi_buf *lpfc_cmd; |
4784 | IOCB_t *cmd, *icmd; | 4784 | IOCB_t *cmd, *icmd; |
4785 | int ret = SUCCESS, status = 0; | 4785 | int ret = SUCCESS, status = 0; |
4786 | unsigned long flags; | 4786 | struct lpfc_sli_ring *pring_s4; |
4787 | int ring_number, ret_val; | ||
4788 | unsigned long flags, iflags; | ||
4787 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | 4789 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); |
4788 | 4790 | ||
4789 | status = fc_block_scsi_eh(cmnd); | 4791 | status = fc_block_scsi_eh(cmnd); |
@@ -4880,11 +4882,23 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
4880 | 4882 | ||
4881 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; | 4883 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; |
4882 | abtsiocb->vport = vport; | 4884 | abtsiocb->vport = vport; |
4885 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
4886 | ring_number = MAX_SLI3_CONFIGURED_RINGS + iocb->fcp_wqidx; | ||
4887 | pring_s4 = &phba->sli.ring[ring_number]; | ||
4888 | /* Note: both hbalock and ring_lock must be set here */ | ||
4889 | spin_lock_irqsave(&pring_s4->ring_lock, iflags); | ||
4890 | ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno, | ||
4891 | abtsiocb, 0); | ||
4892 | spin_unlock_irqrestore(&pring_s4->ring_lock, iflags); | ||
4893 | } else { | ||
4894 | ret_val = __lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, | ||
4895 | abtsiocb, 0); | ||
4896 | } | ||
4883 | /* no longer need the lock after this point */ | 4897 | /* no longer need the lock after this point */ |
4884 | spin_unlock_irqrestore(&phba->hbalock, flags); | 4898 | spin_unlock_irqrestore(&phba->hbalock, flags); |
4885 | 4899 | ||
4886 | if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) == | 4900 | |
4887 | IOCB_ERROR) { | 4901 | if (ret_val == IOCB_ERROR) { |
4888 | lpfc_sli_release_iocbq(phba, abtsiocb); | 4902 | lpfc_sli_release_iocbq(phba, abtsiocb); |
4889 | ret = FAILED; | 4903 | ret = FAILED; |
4890 | goto out; | 4904 | goto out; |
@@ -5185,8 +5199,9 @@ lpfc_reset_flush_io_context(struct lpfc_vport *vport, uint16_t tgt_id, | |||
5185 | 5199 | ||
5186 | cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); | 5200 | cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); |
5187 | if (cnt) | 5201 | if (cnt) |
5188 | lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], | 5202 | lpfc_sli_abort_taskmgmt(vport, |
5189 | tgt_id, lun_id, context); | 5203 | &phba->sli.ring[phba->sli.fcp_ring], |
5204 | tgt_id, lun_id, context); | ||
5190 | later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; | 5205 | later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; |
5191 | while (time_after(later, jiffies) && cnt) { | 5206 | while (time_after(later, jiffies) && cnt) { |
5192 | schedule_timeout_uninterruptible(msecs_to_jiffies(20)); | 5207 | schedule_timeout_uninterruptible(msecs_to_jiffies(20)); |