Hannes Reinecke 4b53c8
From: James Smart <jsmart2021@gmail.com>
Hannes Reinecke 4b53c8
Date: Tue, 31 Jul 2018 17:23:18 -0700
Hannes Reinecke 4b53c8
Subject: [PATCH] scsi: lpfc: Fix ELS abort on SLI-3 adapters
Hannes Reinecke 4b53c8
References: bsc#1102658
Hannes Reinecke 4b53c8
Git-commit: faa832e97a0c0d79838c3a6521a473d870217053
Takashi Iwai 22ff2f
Patch-mainline: v4.19-rc1
Hannes Reinecke 4b53c8
Hannes Reinecke 4b53c8
For ABORT_XRI_CN command, firmware identifies XRI to abort by IOTAG and RPI
Hannes Reinecke 4b53c8
combination. For ELS aborts, driver specifies IOTAG correctly but RPI is
Hannes Reinecke 4b53c8
not specified.
Hannes Reinecke 4b53c8
Hannes Reinecke 4b53c8
Fix by setting RPI in WQE.
Hannes Reinecke 4b53c8
Hannes Reinecke 4b53c8
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Hannes Reinecke 4b53c8
Signed-off-by: James Smart <james.smart@broadcom.com>
Hannes Reinecke 4b53c8
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Hannes Reinecke 4b53c8
Signed-off-by: Hannes Reinecke <hare@suse.de>
Hannes Reinecke 4b53c8
---
Hannes Reinecke 4b53c8
 drivers/scsi/lpfc/lpfc_nportdisc.c |  3 +++
Hannes Reinecke 4b53c8
 drivers/scsi/lpfc/lpfc_sli.c       | 16 ++++++++++++++--
Hannes Reinecke 4b53c8
 2 files changed, 17 insertions(+), 2 deletions(-)
Hannes Reinecke 4b53c8
Hannes Reinecke 4b53c8
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
Hannes Reinecke 4b53c8
index 1f0a7d7dbc54..843e765db86d 100644
Hannes Reinecke 4b53c8
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
Hannes Reinecke 4b53c8
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
Hannes Reinecke 4b53c8
@@ -1062,6 +1062,9 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
Hannes Reinecke 4b53c8
 {
Hannes Reinecke 4b53c8
 	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
+	/* Retrieve RPI from LOGO IOCB. RPI is used for CMD_ABORT_XRI_CN */
Hannes Reinecke 4b53c8
+	if (vport->phba->sli_rev == LPFC_SLI_REV3)
Hannes Reinecke 4b53c8
+		ndlp->nlp_rpi = cmdiocb->iocb.ulpIoTag;
Hannes Reinecke 4b53c8
 				/* software abort outstanding PLOGI */
Hannes Reinecke 4b53c8
 	lpfc_els_abort(vport->phba, ndlp);
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
Hannes Reinecke 4b53c8
index 72500dcb13a9..9830bdb6e072 100644
Hannes Reinecke 4b53c8
--- a/drivers/scsi/lpfc/lpfc_sli.c
Hannes Reinecke 4b53c8
+++ b/drivers/scsi/lpfc/lpfc_sli.c
Hannes Reinecke 4b53c8
@@ -10703,6 +10703,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
 		spin_lock_irq(&phba->hbalock);
Hannes Reinecke 4b53c8
 		if (phba->sli_rev < LPFC_SLI_REV4) {
Hannes Reinecke 4b53c8
+			if (irsp->ulpCommand == CMD_ABORT_XRI_CX &&
Hannes Reinecke 4b53c8
+			    irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
Hannes Reinecke 4b53c8
+			    irsp->un.ulpWord[4] == IOERR_ABORT_REQUESTED) {
Hannes Reinecke 4b53c8
+				spin_unlock_irq(&phba->hbalock);
Hannes Reinecke 4b53c8
+				goto release_iocb;
Hannes Reinecke 4b53c8
+			}
Hannes Reinecke 4b53c8
 			if (abort_iotag != 0 &&
Hannes Reinecke 4b53c8
 				abort_iotag <= phba->sli.last_iotag)
Hannes Reinecke 4b53c8
 				abort_iocb =
Hannes Reinecke 4b53c8
@@ -10724,6 +10730,7 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
 		spin_unlock_irq(&phba->hbalock);
Hannes Reinecke 4b53c8
 	}
Hannes Reinecke 4b53c8
+release_iocb:
Hannes Reinecke 4b53c8
 	lpfc_sli_release_iocbq(phba, cmdiocb);
Hannes Reinecke 4b53c8
 	return;
Hannes Reinecke 4b53c8
 }
Hannes Reinecke 4b53c8
@@ -10780,6 +10787,7 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
Hannes Reinecke 4b53c8
 	IOCB_t *iabt = NULL;
Hannes Reinecke 4b53c8
 	int retval;
Hannes Reinecke 4b53c8
 	unsigned long iflags;
Hannes Reinecke 4b53c8
+	struct lpfc_nodelist *ndlp;
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
 	lockdep_assert_held(&phba->hbalock);
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
@@ -10810,9 +10818,13 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
Hannes Reinecke 4b53c8
 	if (phba->sli_rev == LPFC_SLI_REV4) {
Hannes Reinecke 4b53c8
 		iabt->un.acxri.abortIoTag = cmdiocb->sli4_xritag;
Hannes Reinecke 4b53c8
 		iabt->un.acxri.abortContextTag = cmdiocb->iotag;
Hannes Reinecke 4b53c8
-	}
Hannes Reinecke 4b53c8
-	else
Hannes Reinecke 4b53c8
+	} else {
Hannes Reinecke 4b53c8
 		iabt->un.acxri.abortIoTag = icmd->ulpIoTag;
Hannes Reinecke 4b53c8
+		if (pring->ringno == LPFC_ELS_RING) {
Hannes Reinecke 4b53c8
+			ndlp = (struct lpfc_nodelist *)(cmdiocb->context1);
Hannes Reinecke 4b53c8
+			iabt->un.acxri.abortContextTag = ndlp->nlp_rpi;
Hannes Reinecke 4b53c8
+		}
Hannes Reinecke 4b53c8
+	}
Hannes Reinecke 4b53c8
 	iabt->ulpLe = 1;
Hannes Reinecke 4b53c8
 	iabt->ulpClass = icmd->ulpClass;
Hannes Reinecke 4b53c8
 
Hannes Reinecke 4b53c8
-- 
Hannes Reinecke 4b53c8
2.12.3
Hannes Reinecke 4b53c8