diff options
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 25 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 118 |
3 files changed, 141 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 429116a9cb7d..7d4271d0be8f 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
| @@ -311,6 +311,9 @@ int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, | |||
| 311 | int lpfc_sli_sum_iocb(struct lpfc_vport *, uint16_t, uint64_t, lpfc_ctx_cmd); | 311 | int lpfc_sli_sum_iocb(struct lpfc_vport *, uint16_t, uint64_t, lpfc_ctx_cmd); |
| 312 | int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t, | 312 | int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t, |
| 313 | uint64_t, lpfc_ctx_cmd); | 313 | uint64_t, lpfc_ctx_cmd); |
| 314 | int | ||
| 315 | lpfc_sli_abort_taskmgmt(struct lpfc_vport *, struct lpfc_sli_ring *, | ||
| 316 | uint16_t, uint64_t, lpfc_ctx_cmd); | ||
| 314 | 317 | ||
| 315 | void lpfc_mbox_timeout(unsigned long); | 318 | void lpfc_mbox_timeout(unsigned long); |
| 316 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); | 319 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); |
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)); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8791312e5977..34ba7aaec48c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
| @@ -10118,6 +10118,124 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, | |||
| 10118 | } | 10118 | } |
| 10119 | 10119 | ||
| 10120 | /** | 10120 | /** |
| 10121 | * lpfc_sli_abort_taskmgmt - issue abort for all commands on a host/target/LUN | ||
| 10122 | * @vport: Pointer to virtual port. | ||
| 10123 | * @pring: Pointer to driver SLI ring object. | ||
| 10124 | * @tgt_id: SCSI ID of the target. | ||
| 10125 | * @lun_id: LUN ID of the scsi device. | ||
| 10126 | * @taskmgmt_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST. | ||
| 10127 | * | ||
| 10128 | * This function sends an abort command for every SCSI command | ||
| 10129 | * associated with the given virtual port pending on the ring | ||
| 10130 | * filtered by lpfc_sli_validate_fcp_iocb function. | ||
| 10131 | * When taskmgmt_cmd == LPFC_CTX_LUN, the function sends abort only to the | ||
| 10132 | * FCP iocbs associated with lun specified by tgt_id and lun_id | ||
| 10133 | * parameters | ||
| 10134 | * When taskmgmt_cmd == LPFC_CTX_TGT, the function sends abort only to the | ||
| 10135 | * FCP iocbs associated with SCSI target specified by tgt_id parameter. | ||
| 10136 | * When taskmgmt_cmd == LPFC_CTX_HOST, the function sends abort to all | ||
| 10137 | * FCP iocbs associated with virtual port. | ||
| 10138 | * This function returns number of iocbs it aborted . | ||
| 10139 | * This function is called with no locks held right after a taskmgmt | ||
| 10140 | * command is sent. | ||
| 10141 | **/ | ||
| 10142 | int | ||
| 10143 | lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, | ||
| 10144 | uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd cmd) | ||
| 10145 | { | ||
| 10146 | struct lpfc_hba *phba = vport->phba; | ||
| 10147 | struct lpfc_iocbq *abtsiocbq; | ||
| 10148 | struct lpfc_iocbq *iocbq; | ||
| 10149 | IOCB_t *icmd; | ||
| 10150 | int sum, i, ret_val; | ||
| 10151 | unsigned long iflags; | ||
| 10152 | struct lpfc_sli_ring *pring_s4; | ||
| 10153 | uint32_t ring_number; | ||
| 10154 | |||
| 10155 | spin_lock_irq(&phba->hbalock); | ||
| 10156 | |||
| 10157 | /* all I/Os are in process of being flushed */ | ||
| 10158 | if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { | ||
| 10159 | spin_unlock_irq(&phba->hbalock); | ||
| 10160 | return 0; | ||
| 10161 | } | ||
| 10162 | sum = 0; | ||
| 10163 | |||
| 10164 | for (i = 1; i <= phba->sli.last_iotag; i++) { | ||
| 10165 | iocbq = phba->sli.iocbq_lookup[i]; | ||
| 10166 | |||
| 10167 | if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, | ||
| 10168 | cmd) != 0) | ||
| 10169 | continue; | ||
| 10170 | |||
| 10171 | /* | ||
| 10172 | * If the iocbq is already being aborted, don't take a second | ||
| 10173 | * action, but do count it. | ||
| 10174 | */ | ||
| 10175 | if (iocbq->iocb_flag & LPFC_DRIVER_ABORTED) | ||
| 10176 | continue; | ||
| 10177 | |||
| 10178 | /* issue ABTS for this IOCB based on iotag */ | ||
| 10179 | abtsiocbq = __lpfc_sli_get_iocbq(phba); | ||
| 10180 | if (abtsiocbq == NULL) | ||
| 10181 | continue; | ||
| 10182 | |||
| 10183 | icmd = &iocbq->iocb; | ||
| 10184 | abtsiocbq->iocb.un.acxri.abortType = ABORT_TYPE_ABTS; | ||
| 10185 | abtsiocbq->iocb.un.acxri.abortContextTag = icmd->ulpContext; | ||
| 10186 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
| 10187 | abtsiocbq->iocb.un.acxri.abortIoTag = | ||
| 10188 | iocbq->sli4_xritag; | ||
| 10189 | else | ||
| 10190 | abtsiocbq->iocb.un.acxri.abortIoTag = icmd->ulpIoTag; | ||
| 10191 | abtsiocbq->iocb.ulpLe = 1; | ||
| 10192 | abtsiocbq->iocb.ulpClass = icmd->ulpClass; | ||
| 10193 | abtsiocbq->vport = vport; | ||
| 10194 | |||
| 10195 | /* ABTS WQE must go to the same WQ as the WQE to be aborted */ | ||
| 10196 | abtsiocbq->fcp_wqidx = iocbq->fcp_wqidx; | ||
| 10197 | if (iocbq->iocb_flag & LPFC_IO_FCP) | ||
| 10198 | abtsiocbq->iocb_flag |= LPFC_USE_FCPWQIDX; | ||
| 10199 | |||
| 10200 | if (lpfc_is_link_up(phba)) | ||
| 10201 | abtsiocbq->iocb.ulpCommand = CMD_ABORT_XRI_CN; | ||
| 10202 | else | ||
| 10203 | abtsiocbq->iocb.ulpCommand = CMD_CLOSE_XRI_CN; | ||
| 10204 | |||
| 10205 | /* Setup callback routine and issue the command. */ | ||
| 10206 | abtsiocbq->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; | ||
| 10207 | |||
| 10208 | /* | ||
| 10209 | * Indicate the IO is being aborted by the driver and set | ||
| 10210 | * the caller's flag into the aborted IO. | ||
| 10211 | */ | ||
| 10212 | iocbq->iocb_flag |= LPFC_DRIVER_ABORTED; | ||
| 10213 | |||
| 10214 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
| 10215 | ring_number = MAX_SLI3_CONFIGURED_RINGS + | ||
| 10216 | iocbq->fcp_wqidx; | ||
| 10217 | pring_s4 = &phba->sli.ring[ring_number]; | ||
| 10218 | /* Note: both hbalock and ring_lock must be set here */ | ||
| 10219 | spin_lock_irqsave(&pring_s4->ring_lock, iflags); | ||
| 10220 | ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno, | ||
| 10221 | abtsiocbq, 0); | ||
| 10222 | spin_unlock_irqrestore(&pring_s4->ring_lock, iflags); | ||
| 10223 | } else { | ||
| 10224 | ret_val = __lpfc_sli_issue_iocb(phba, pring->ringno, | ||
| 10225 | abtsiocbq, 0); | ||
| 10226 | } | ||
| 10227 | |||
| 10228 | |||
| 10229 | if (ret_val == IOCB_ERROR) | ||
| 10230 | __lpfc_sli_release_iocbq(phba, abtsiocbq); | ||
| 10231 | else | ||
| 10232 | sum++; | ||
| 10233 | } | ||
| 10234 | spin_unlock_irq(&phba->hbalock); | ||
| 10235 | return sum; | ||
| 10236 | } | ||
| 10237 | |||
| 10238 | /** | ||
| 10121 | * lpfc_sli_wake_iocb_wait - lpfc_sli_issue_iocb_wait's completion handler | 10239 | * lpfc_sli_wake_iocb_wait - lpfc_sli_issue_iocb_wait's completion handler |
| 10122 | * @phba: Pointer to HBA context object. | 10240 | * @phba: Pointer to HBA context object. |
| 10123 | * @cmdiocbq: Pointer to command iocb. | 10241 | * @cmdiocbq: Pointer to command iocb. |
