[SCSI] lpfc 8.1.12 : Modify ELS abort handling to prevent double completion

Modify ELS abort handling to prevent double completion

Rework portions of ELS abort handling to prevent double completion
 - Rework ELS iotags and correct abort routine
 - Move the (badly wrong) ELS completion logic from the initial ELS
   abort request function to the ELS completion function.
 - Fixup the iocb completion handling to account for the ELS abort
   completions.

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index e1c61db..4a9e613 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -582,24 +582,8 @@
 		icmd = &iocb->iocb;
 		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
 			ndlp = (struct lpfc_nodelist *)(iocb->context1);
-			if (ndlp && (ndlp->nlp_DID == Fabric_DID)) {
-				list_del(&iocb->list);
-				pring->txcmplq_cnt--;
-
-				if ((icmd->un.elsreq64.bdl.ulpIoTag32)) {
-					lpfc_sli_issue_abort_iotag32
-						(phba, pring, iocb);
-				}
-				if (iocb->iocb_cmpl) {
-					icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
-					icmd->un.ulpWord[4] =
-					    IOERR_SLI_ABORTED;
-					spin_unlock_irq(phba->host->host_lock);
-					(iocb->iocb_cmpl) (phba, iocb, iocb);
-					spin_lock_irq(phba->host->host_lock);
-				} else
-					lpfc_sli_release_iocbq(phba, iocb);
-			}
+			if (ndlp && (ndlp->nlp_DID == Fabric_DID))
+				lpfc_sli_issue_abort_iotag(phba, pring, iocb);
 		}
 	}
 	spin_unlock_irq(phba->host->host_lock);
@@ -3245,7 +3229,6 @@
 	struct lpfc_iocbq *tmp_iocb, *piocb;
 	IOCB_t *cmd = NULL;
 	struct lpfc_dmabuf *pcmd;
-	struct list_head *dlp;
 	uint32_t *elscmd;
 	uint32_t els_command;
 	uint32_t timeout;
@@ -3262,7 +3245,6 @@
 	timeout = (uint32_t)(phba->fc_ratov << 1);
 
 	pring = &phba->sli.ring[LPFC_ELS_RING];
-	dlp = &pring->txcmplq;
 
 	list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
 		cmd = &piocb->iocb;
@@ -3288,19 +3270,12 @@
 			continue;
 		}
 
-		list_del(&piocb->list);
-		pring->txcmplq_cnt--;
-
 		if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
 			struct lpfc_nodelist *ndlp;
 			spin_unlock_irq(phba->host->host_lock);
 			ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
 			spin_lock_irq(phba->host->host_lock);
 			remote_ID = ndlp->nlp_DID;
-			if (cmd->un.elsreq64.bdl.ulpIoTag32) {
-				lpfc_sli_issue_abort_iotag32(phba,
-					pring, piocb);
-			}
 		} else {
 			remote_ID = cmd->un.elsreq64.remoteID;
 		}
@@ -3312,17 +3287,7 @@
 				phba->brd_no, els_command,
 				remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
 
-		/*
-		 * The iocb has timed out; abort it.
-		 */
-		if (piocb->iocb_cmpl) {
-			cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
-			cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
-			spin_unlock_irq(phba->host->host_lock);
-			(piocb->iocb_cmpl) (phba, piocb, piocb);
-			spin_lock_irq(phba->host->host_lock);
-		} else
-			lpfc_sli_release_iocbq(phba, piocb);
+		lpfc_sli_issue_abort_iotag(phba, pring, piocb);
 	}
 	if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
 		mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
@@ -3336,9 +3301,6 @@
 	struct lpfc_sli_ring *pring;
 	struct lpfc_iocbq *tmp_iocb, *piocb;
 	IOCB_t *cmd = NULL;
-	struct lpfc_dmabuf *pcmd;
-	uint32_t *elscmd;
-	uint32_t els_command;
 
 	pring = &phba->sli.ring[LPFC_ELS_RING];
 	spin_lock_irq(phba->host->host_lock);
@@ -3357,10 +3319,6 @@
 			continue;
 		}
 
-		pcmd = (struct lpfc_dmabuf *) piocb->context2;
-		elscmd = (uint32_t *) (pcmd->virt);
-		els_command = *elscmd;
-
 		list_del(&piocb->list);
 		pring->txq_cnt--;
 
@@ -3381,22 +3339,8 @@
 		if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
 			continue;
 		}
-		pcmd = (struct lpfc_dmabuf *) piocb->context2;
-		elscmd = (uint32_t *) (pcmd->virt);
-		els_command = *elscmd;
 
-		list_del(&piocb->list);
-		pring->txcmplq_cnt--;
-
-		cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
-		cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
-
-		if (piocb->iocb_cmpl) {
-			spin_unlock_irq(phba->host->host_lock);
-			(piocb->iocb_cmpl) (phba, piocb, piocb);
-			spin_lock_irq(phba->host->host_lock);
-		} else
-			lpfc_sli_release_iocbq(phba, piocb);
+		lpfc_sli_issue_abort_iotag(phba, pring, piocb);
 	}
 	spin_unlock_irq(phba->host->host_lock);
 	return;