diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:52:55 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 10:33:15 -0400 |
commit | 2680eeaaa03e83a87ece2724e71f7cc816cd3ef0 (patch) | |
tree | bac4fdee7527d900b81aecf9b1d9e39519c6c21f /drivers/scsi/lpfc | |
parent | 5b8bd0c9be706677327c01df28bf6b54de008f34 (diff) |
[SCSI] lpfc 8.1.12 : Improve handling of failed ELS aborts
Improve handling of failed ELS aborts.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 55 |
2 files changed, 55 insertions, 1 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 8f98c5b0bf8c..14d204ba8a39 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -182,6 +182,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
182 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); | 182 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); |
183 | icmd->un.elsreq64.remoteID = did; /* DID */ | 183 | icmd->un.elsreq64.remoteID = did; /* DID */ |
184 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; | 184 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; |
185 | icmd->ulpTimeout = phba->fc_ratov * 2; | ||
185 | } else { | 186 | } else { |
186 | icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); | 187 | icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); |
187 | icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; | 188 | icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fd82797df095..645291efce08 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -2403,7 +2403,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2403 | 2403 | ||
2404 | if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) { | 2404 | if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) { |
2405 | /* | 2405 | /* |
2406 | * Only CREATE_XRI, CLOSE_XRI, ABORT_XRI, and QUE_RING_BUF | 2406 | * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF |
2407 | * can be issued if the link is not up. | 2407 | * can be issued if the link is not up. |
2408 | */ | 2408 | */ |
2409 | switch (piocb->iocb.ulpCommand) { | 2409 | switch (piocb->iocb.ulpCommand) { |
@@ -2417,6 +2417,8 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2417 | piocb->iocb_cmpl = NULL; | 2417 | piocb->iocb_cmpl = NULL; |
2418 | /*FALLTHROUGH*/ | 2418 | /*FALLTHROUGH*/ |
2419 | case CMD_CREATE_XRI_CR: | 2419 | case CMD_CREATE_XRI_CR: |
2420 | case CMD_CLOSE_XRI_CN: | ||
2421 | case CMD_CLOSE_XRI_CX: | ||
2420 | break; | 2422 | break; |
2421 | default: | 2423 | default: |
2422 | goto iocb_busy; | 2424 | goto iocb_busy; |
@@ -2741,7 +2743,58 @@ static void | |||
2741 | lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2743 | lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
2742 | struct lpfc_iocbq * rspiocb) | 2744 | struct lpfc_iocbq * rspiocb) |
2743 | { | 2745 | { |
2746 | IOCB_t *irsp; | ||
2747 | uint16_t abort_iotag, abort_context; | ||
2748 | struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb; | ||
2749 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
2750 | |||
2751 | abort_iocb = NULL; | ||
2752 | irsp = &rspiocb->iocb; | ||
2753 | |||
2744 | spin_lock_irq(phba->host->host_lock); | 2754 | spin_lock_irq(phba->host->host_lock); |
2755 | |||
2756 | if (irsp->ulpStatus) { | ||
2757 | abort_context = cmdiocb->iocb.un.acxri.abortContextTag; | ||
2758 | abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag; | ||
2759 | |||
2760 | if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag) | ||
2761 | abort_iocb = phba->sli.iocbq_lookup[abort_iotag]; | ||
2762 | |||
2763 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
2764 | "%d:0327 Cannot abort els iocb %p" | ||
2765 | " with tag %x context %x\n", | ||
2766 | phba->brd_no, abort_iocb, | ||
2767 | abort_iotag, abort_context); | ||
2768 | |||
2769 | /* | ||
2770 | * make sure we have the right iocbq before taking it | ||
2771 | * off the txcmplq and try to call completion routine. | ||
2772 | */ | ||
2773 | if (abort_iocb && | ||
2774 | abort_iocb->iocb.ulpContext == abort_context && | ||
2775 | abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
2776 | list_del(&abort_iocb->list); | ||
2777 | pring->txcmplq_cnt--; | ||
2778 | |||
2779 | rsp_ab_iocb = lpfc_sli_get_iocbq(phba); | ||
2780 | if (rsp_ab_iocb == NULL) | ||
2781 | lpfc_sli_release_iocbq(phba, abort_iocb); | ||
2782 | else { | ||
2783 | abort_iocb->iocb_flag &= | ||
2784 | ~LPFC_DRIVER_ABORTED; | ||
2785 | rsp_ab_iocb->iocb.ulpStatus = | ||
2786 | IOSTAT_LOCAL_REJECT; | ||
2787 | rsp_ab_iocb->iocb.un.ulpWord[4] = | ||
2788 | IOERR_SLI_ABORTED; | ||
2789 | spin_unlock_irq(phba->host->host_lock); | ||
2790 | (abort_iocb->iocb_cmpl) | ||
2791 | (phba, abort_iocb, rsp_ab_iocb); | ||
2792 | spin_lock_irq(phba->host->host_lock); | ||
2793 | lpfc_sli_release_iocbq(phba, rsp_ab_iocb); | ||
2794 | } | ||
2795 | } | ||
2796 | } | ||
2797 | |||
2745 | lpfc_sli_release_iocbq(phba, cmdiocb); | 2798 | lpfc_sli_release_iocbq(phba, cmdiocb); |
2746 | spin_unlock_irq(phba->host->host_lock); | 2799 | spin_unlock_irq(phba->host->host_lock); |
2747 | return; | 2800 | return; |