Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2680eeaa authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.1.12 : Improve handling of failed ELS aborts



Improve handling of failed ELS aborts.

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5b8bd0c9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
		icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64));
		icmd->un.elsreq64.remoteID = did;	/* DID */
		icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
		icmd->ulpTimeout = phba->fc_ratov * 2;
	} else {
		icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64);
		icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
+54 −1
Original line number Diff line number Diff line
@@ -2403,7 +2403,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,

	if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) {
		/*
		 * Only CREATE_XRI, CLOSE_XRI, ABORT_XRI, and QUE_RING_BUF
		 * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF
		 * can be issued if the link is not up.
		 */
		switch (piocb->iocb.ulpCommand) {
@@ -2417,6 +2417,8 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
				piocb->iocb_cmpl = NULL;
			/*FALLTHROUGH*/
		case CMD_CREATE_XRI_CR:
		case CMD_CLOSE_XRI_CN:
		case CMD_CLOSE_XRI_CX:
			break;
		default:
			goto iocb_busy;
@@ -2741,7 +2743,58 @@ static void
lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
			struct lpfc_iocbq * rspiocb)
{
	IOCB_t *irsp;
	uint16_t abort_iotag, abort_context;
	struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb;
	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];

	abort_iocb = NULL;
	irsp = &rspiocb->iocb;

	spin_lock_irq(phba->host->host_lock);

	if (irsp->ulpStatus) {
		abort_context = cmdiocb->iocb.un.acxri.abortContextTag;
		abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag;

		if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag)
			abort_iocb = phba->sli.iocbq_lookup[abort_iotag];

		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
				"%d:0327 Cannot abort els iocb %p"
				" with tag %x context %x\n",
				phba->brd_no, abort_iocb,
				abort_iotag, abort_context);

		/*
		 * make sure we have the right iocbq before taking it
		 * off the txcmplq and try to call completion routine.
		 */
		if (abort_iocb &&
		    abort_iocb->iocb.ulpContext == abort_context &&
		    abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) {
			list_del(&abort_iocb->list);
			pring->txcmplq_cnt--;

			rsp_ab_iocb = lpfc_sli_get_iocbq(phba);
			if (rsp_ab_iocb == NULL)
				lpfc_sli_release_iocbq(phba, abort_iocb);
			else {
				abort_iocb->iocb_flag &=
					~LPFC_DRIVER_ABORTED;
				rsp_ab_iocb->iocb.ulpStatus =
					IOSTAT_LOCAL_REJECT;
				rsp_ab_iocb->iocb.un.ulpWord[4] =
					IOERR_SLI_ABORTED;
				spin_unlock_irq(phba->host->host_lock);
				(abort_iocb->iocb_cmpl)
					(phba, abort_iocb, rsp_ab_iocb);
				spin_lock_irq(phba->host->host_lock);
				lpfc_sli_release_iocbq(phba, rsp_ab_iocb);
			}
		}
	}

	lpfc_sli_release_iocbq(phba, cmdiocb);
	spin_unlock_irq(phba->host->host_lock);
	return;