diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 158 |
1 files changed, 130 insertions, 28 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 9d2e1347cb1d..ce4145377efd 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1735,6 +1735,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1735 | struct lpfc_vport *vport = pmb->vport; | 1735 | struct lpfc_vport *vport = pmb->vport; |
1736 | struct lpfc_dmabuf *mp; | 1736 | struct lpfc_dmabuf *mp; |
1737 | struct lpfc_nodelist *ndlp; | 1737 | struct lpfc_nodelist *ndlp; |
1738 | struct Scsi_Host *shost; | ||
1738 | uint16_t rpi, vpi; | 1739 | uint16_t rpi, vpi; |
1739 | int rc; | 1740 | int rc; |
1740 | 1741 | ||
@@ -1746,7 +1747,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1746 | } | 1747 | } |
1747 | 1748 | ||
1748 | if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) && | 1749 | if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) && |
1749 | (phba->sli_rev == LPFC_SLI_REV4)) | 1750 | (phba->sli_rev == LPFC_SLI_REV4) && |
1751 | (pmb->u.mb.un.varUnregLogin.rsvd1 == 0x0)) | ||
1750 | lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi); | 1752 | lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi); |
1751 | 1753 | ||
1752 | /* | 1754 | /* |
@@ -1765,16 +1767,14 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1765 | return; | 1767 | return; |
1766 | } | 1768 | } |
1767 | 1769 | ||
1768 | /* Unreg VPI, if the REG_VPI succeed after VLink failure */ | ||
1769 | if ((pmb->u.mb.mbxCommand == MBX_REG_VPI) && | 1770 | if ((pmb->u.mb.mbxCommand == MBX_REG_VPI) && |
1770 | !(phba->pport->load_flag & FC_UNLOADING) && | 1771 | !(phba->pport->load_flag & FC_UNLOADING) && |
1771 | !pmb->u.mb.mbxStatus) { | 1772 | !pmb->u.mb.mbxStatus) { |
1772 | lpfc_unreg_vpi(phba, pmb->u.mb.un.varRegVpi.vpi, pmb); | 1773 | shost = lpfc_shost_from_vport(vport); |
1773 | pmb->vport = vport; | 1774 | spin_lock_irq(shost->host_lock); |
1774 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1775 | vport->vpi_state |= LPFC_VPI_REGISTERED; |
1775 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 1776 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
1776 | if (rc != MBX_NOT_FINISHED) | 1777 | spin_unlock_irq(shost->host_lock); |
1777 | return; | ||
1778 | } | 1778 | } |
1779 | 1779 | ||
1780 | if (pmb->u.mb.mbxCommand == MBX_REG_LOGIN64) { | 1780 | if (pmb->u.mb.mbxCommand == MBX_REG_LOGIN64) { |
@@ -7257,25 +7257,26 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
7257 | } | 7257 | } |
7258 | 7258 | ||
7259 | /** | 7259 | /** |
7260 | * lpfc_sli_issue_abort_iotag - Abort function for a command iocb | 7260 | * lpfc_sli_abort_iotag_issue - Issue abort for a command iocb |
7261 | * @phba: Pointer to HBA context object. | 7261 | * @phba: Pointer to HBA context object. |
7262 | * @pring: Pointer to driver SLI ring object. | 7262 | * @pring: Pointer to driver SLI ring object. |
7263 | * @cmdiocb: Pointer to driver command iocb object. | 7263 | * @cmdiocb: Pointer to driver command iocb object. |
7264 | * | 7264 | * |
7265 | * This function issues an abort iocb for the provided command | 7265 | * This function issues an abort iocb for the provided command iocb down to |
7266 | * iocb. This function is called with hbalock held. | 7266 | * the port. Other than the case the outstanding command iocb is an abort |
7267 | * The function returns 0 when it fails due to memory allocation | 7267 | * request, this function issues abort out unconditionally. This function is |
7268 | * failure or when the command iocb is an abort request. | 7268 | * called with hbalock held. The function returns 0 when it fails due to |
7269 | * memory allocation failure or when the command iocb is an abort request. | ||
7269 | **/ | 7270 | **/ |
7270 | int | 7271 | static int |
7271 | lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 7272 | lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
7272 | struct lpfc_iocbq *cmdiocb) | 7273 | struct lpfc_iocbq *cmdiocb) |
7273 | { | 7274 | { |
7274 | struct lpfc_vport *vport = cmdiocb->vport; | 7275 | struct lpfc_vport *vport = cmdiocb->vport; |
7275 | struct lpfc_iocbq *abtsiocbp; | 7276 | struct lpfc_iocbq *abtsiocbp; |
7276 | IOCB_t *icmd = NULL; | 7277 | IOCB_t *icmd = NULL; |
7277 | IOCB_t *iabt = NULL; | 7278 | IOCB_t *iabt = NULL; |
7278 | int retval = IOCB_ERROR; | 7279 | int retval; |
7279 | 7280 | ||
7280 | /* | 7281 | /* |
7281 | * There are certain command types we don't want to abort. And we | 7282 | * There are certain command types we don't want to abort. And we |
@@ -7288,18 +7289,6 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
7288 | (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0) | 7289 | (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0) |
7289 | return 0; | 7290 | return 0; |
7290 | 7291 | ||
7291 | /* If we're unloading, don't abort iocb on the ELS ring, but change the | ||
7292 | * callback so that nothing happens when it finishes. | ||
7293 | */ | ||
7294 | if ((vport->load_flag & FC_UNLOADING) && | ||
7295 | (pring->ringno == LPFC_ELS_RING)) { | ||
7296 | if (cmdiocb->iocb_flag & LPFC_IO_FABRIC) | ||
7297 | cmdiocb->fabric_iocb_cmpl = lpfc_ignore_els_cmpl; | ||
7298 | else | ||
7299 | cmdiocb->iocb_cmpl = lpfc_ignore_els_cmpl; | ||
7300 | goto abort_iotag_exit; | ||
7301 | } | ||
7302 | |||
7303 | /* issue ABTS for this IOCB based on iotag */ | 7292 | /* issue ABTS for this IOCB based on iotag */ |
7304 | abtsiocbp = __lpfc_sli_get_iocbq(phba); | 7293 | abtsiocbp = __lpfc_sli_get_iocbq(phba); |
7305 | if (abtsiocbp == NULL) | 7294 | if (abtsiocbp == NULL) |
@@ -7344,6 +7333,63 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
7344 | 7333 | ||
7345 | if (retval) | 7334 | if (retval) |
7346 | __lpfc_sli_release_iocbq(phba, abtsiocbp); | 7335 | __lpfc_sli_release_iocbq(phba, abtsiocbp); |
7336 | |||
7337 | /* | ||
7338 | * Caller to this routine should check for IOCB_ERROR | ||
7339 | * and handle it properly. This routine no longer removes | ||
7340 | * iocb off txcmplq and call compl in case of IOCB_ERROR. | ||
7341 | */ | ||
7342 | return retval; | ||
7343 | } | ||
7344 | |||
7345 | /** | ||
7346 | * lpfc_sli_issue_abort_iotag - Abort function for a command iocb | ||
7347 | * @phba: Pointer to HBA context object. | ||
7348 | * @pring: Pointer to driver SLI ring object. | ||
7349 | * @cmdiocb: Pointer to driver command iocb object. | ||
7350 | * | ||
7351 | * This function issues an abort iocb for the provided command iocb. In case | ||
7352 | * of unloading, the abort iocb will not be issued to commands on the ELS | ||
7353 | * ring. Instead, the callback function shall be changed to those commands | ||
7354 | * so that nothing happens when them finishes. This function is called with | ||
7355 | * hbalock held. The function returns 0 when the command iocb is an abort | ||
7356 | * request. | ||
7357 | **/ | ||
7358 | int | ||
7359 | lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | ||
7360 | struct lpfc_iocbq *cmdiocb) | ||
7361 | { | ||
7362 | struct lpfc_vport *vport = cmdiocb->vport; | ||
7363 | int retval = IOCB_ERROR; | ||
7364 | IOCB_t *icmd = NULL; | ||
7365 | |||
7366 | /* | ||
7367 | * There are certain command types we don't want to abort. And we | ||
7368 | * don't want to abort commands that are already in the process of | ||
7369 | * being aborted. | ||
7370 | */ | ||
7371 | icmd = &cmdiocb->iocb; | ||
7372 | if (icmd->ulpCommand == CMD_ABORT_XRI_CN || | ||
7373 | icmd->ulpCommand == CMD_CLOSE_XRI_CN || | ||
7374 | (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0) | ||
7375 | return 0; | ||
7376 | |||
7377 | /* | ||
7378 | * If we're unloading, don't abort iocb on the ELS ring, but change | ||
7379 | * the callback so that nothing happens when it finishes. | ||
7380 | */ | ||
7381 | if ((vport->load_flag & FC_UNLOADING) && | ||
7382 | (pring->ringno == LPFC_ELS_RING)) { | ||
7383 | if (cmdiocb->iocb_flag & LPFC_IO_FABRIC) | ||
7384 | cmdiocb->fabric_iocb_cmpl = lpfc_ignore_els_cmpl; | ||
7385 | else | ||
7386 | cmdiocb->iocb_cmpl = lpfc_ignore_els_cmpl; | ||
7387 | goto abort_iotag_exit; | ||
7388 | } | ||
7389 | |||
7390 | /* Now, we try to issue the abort to the cmdiocb out */ | ||
7391 | retval = lpfc_sli_abort_iotag_issue(phba, pring, cmdiocb); | ||
7392 | |||
7347 | abort_iotag_exit: | 7393 | abort_iotag_exit: |
7348 | /* | 7394 | /* |
7349 | * Caller to this routine should check for IOCB_ERROR | 7395 | * Caller to this routine should check for IOCB_ERROR |
@@ -7354,6 +7400,62 @@ abort_iotag_exit: | |||
7354 | } | 7400 | } |
7355 | 7401 | ||
7356 | /** | 7402 | /** |
7403 | * lpfc_sli_iocb_ring_abort - Unconditionally abort all iocbs on an iocb ring | ||
7404 | * @phba: Pointer to HBA context object. | ||
7405 | * @pring: Pointer to driver SLI ring object. | ||
7406 | * | ||
7407 | * This function aborts all iocbs in the given ring and frees all the iocb | ||
7408 | * objects in txq. This function issues abort iocbs unconditionally for all | ||
7409 | * the iocb commands in txcmplq. The iocbs in the txcmplq is not guaranteed | ||
7410 | * to complete before the return of this function. The caller is not required | ||
7411 | * to hold any locks. | ||
7412 | **/ | ||
7413 | static void | ||
7414 | lpfc_sli_iocb_ring_abort(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | ||
7415 | { | ||
7416 | LIST_HEAD(completions); | ||
7417 | struct lpfc_iocbq *iocb, *next_iocb; | ||
7418 | |||
7419 | if (pring->ringno == LPFC_ELS_RING) | ||
7420 | lpfc_fabric_abort_hba(phba); | ||
7421 | |||
7422 | spin_lock_irq(&phba->hbalock); | ||
7423 | |||
7424 | /* Take off all the iocbs on txq for cancelling */ | ||
7425 | list_splice_init(&pring->txq, &completions); | ||
7426 | pring->txq_cnt = 0; | ||
7427 | |||
7428 | /* Next issue ABTS for everything on the txcmplq */ | ||
7429 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) | ||
7430 | lpfc_sli_abort_iotag_issue(phba, pring, iocb); | ||
7431 | |||
7432 | spin_unlock_irq(&phba->hbalock); | ||
7433 | |||
7434 | /* Cancel all the IOCBs from the completions list */ | ||
7435 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, | ||
7436 | IOERR_SLI_ABORTED); | ||
7437 | } | ||
7438 | |||
7439 | /** | ||
7440 | * lpfc_sli_hba_iocb_abort - Abort all iocbs to an hba. | ||
7441 | * @phba: pointer to lpfc HBA data structure. | ||
7442 | * | ||
7443 | * This routine will abort all pending and outstanding iocbs to an HBA. | ||
7444 | **/ | ||
7445 | void | ||
7446 | lpfc_sli_hba_iocb_abort(struct lpfc_hba *phba) | ||
7447 | { | ||
7448 | struct lpfc_sli *psli = &phba->sli; | ||
7449 | struct lpfc_sli_ring *pring; | ||
7450 | int i; | ||
7451 | |||
7452 | for (i = 0; i < psli->num_rings; i++) { | ||
7453 | pring = &psli->ring[i]; | ||
7454 | lpfc_sli_iocb_ring_abort(phba, pring); | ||
7455 | } | ||
7456 | } | ||
7457 | |||
7458 | /** | ||
7357 | * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN | 7459 | * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN |
7358 | * @iocbq: Pointer to driver iocb object. | 7460 | * @iocbq: Pointer to driver iocb object. |
7359 | * @vport: Pointer to driver virtual port object. | 7461 | * @vport: Pointer to driver virtual port object. |