aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:52:55 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:15 -0400
commit2680eeaaa03e83a87ece2724e71f7cc816cd3ef0 (patch)
treebac4fdee7527d900b81aecf9b1d9e39519c6c21f /drivers/scsi/lpfc/lpfc_sli.c
parent5b8bd0c9be706677327c01df28bf6b54de008f34 (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/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index fd82797df09..645291efce0 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
2741lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, 2743lpfc_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;