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

Commit 086a345f authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.34: Add LOGO support after ABTS compliance



Make compliant with FC specs by sending LOGO after ABTS timeouts

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 0e58076b
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -457,6 +457,8 @@ int lpfc_sli4_queue_create(struct lpfc_hba *);
void lpfc_sli4_queue_destroy(struct lpfc_hba *);
void lpfc_sli4_queue_destroy(struct lpfc_hba *);
void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *,
void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *,
				struct sli4_wcqe_xri_aborted *);
				struct sli4_wcqe_xri_aborted *);
void lpfc_sli_abts_recover_port(struct lpfc_vport *,
				struct lpfc_nodelist *);
int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t);
int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t);
int lpfc_issue_reg_vfi(struct lpfc_vport *);
int lpfc_issue_reg_vfi(struct lpfc_vport *);
int lpfc_issue_unreg_vfi(struct lpfc_vport *);
int lpfc_issue_unreg_vfi(struct lpfc_vport *);
+10 −2
Original line number Original line Diff line number Diff line
@@ -559,6 +559,9 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
		case NLP_STE_PRLI_ISSUE:
		case NLP_STE_PRLI_ISSUE:
			statep = "PRLI  ";
			statep = "PRLI  ";
			break;
			break;
		case NLP_STE_LOGO_ISSUE:
			statep = "LOGO  ";
			break;
		case NLP_STE_UNMAPPED_NODE:
		case NLP_STE_UNMAPPED_NODE:
			statep = "UNMAP ";
			statep = "UNMAP ";
			break;
			break;
@@ -583,8 +586,13 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
			"WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
			"WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
			*name, *(name+1), *(name+2), *(name+3),
			*name, *(name+1), *(name+2), *(name+3),
			*(name+4), *(name+5), *(name+6), *(name+7));
			*(name+4), *(name+5), *(name+6), *(name+7));
		len +=  snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
		if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
			ndlp->nlp_rpi, ndlp->nlp_flag);
			len +=  snprintf(buf+len, size-len, "RPI:%03d ",
				ndlp->nlp_rpi);
		else
			len +=  snprintf(buf+len, size-len, "RPI:none ");
		len +=  snprintf(buf+len, size-len, "flag:x%08x ",
			ndlp->nlp_flag);
		if (!ndlp->nlp_type)
		if (!ndlp->nlp_type)
			len +=  snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
			len +=  snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
		if (ndlp->nlp_type & NLP_FC_NODE)
		if (ndlp->nlp_type & NLP_FC_NODE)
+6 −4
Original line number Original line Diff line number Diff line
@@ -145,6 +145,7 @@ struct lpfc_node_rrq {
#define NLP_RCV_PLOGI      0x00080000	/* Rcv'ed PLOGI from remote system */
#define NLP_RCV_PLOGI      0x00080000	/* Rcv'ed PLOGI from remote system */
#define NLP_LOGO_ACC       0x00100000	/* Process LOGO after ACC completes */
#define NLP_LOGO_ACC       0x00100000	/* Process LOGO after ACC completes */
#define NLP_TGT_NO_SCSIID  0x00200000	/* good PRLI but no binding for scsid */
#define NLP_TGT_NO_SCSIID  0x00200000	/* good PRLI but no binding for scsid */
#define NLP_ISSUE_LOGO     0x00400000	/* waiting to issue a LOGO */
#define NLP_ACC_REGLOGIN   0x01000000	/* Issue Reg Login after successful
#define NLP_ACC_REGLOGIN   0x01000000	/* Issue Reg Login after successful
					   ACC */
					   ACC */
#define NLP_NPR_ADISC      0x02000000	/* Issue ADISC when dq'ed from
#define NLP_NPR_ADISC      0x02000000	/* Issue ADISC when dq'ed from
@@ -201,10 +202,11 @@ struct lpfc_node_rrq {
#define NLP_STE_ADISC_ISSUE       0x2	/* ADISC was sent to NL_PORT */
#define NLP_STE_ADISC_ISSUE       0x2	/* ADISC was sent to NL_PORT */
#define NLP_STE_REG_LOGIN_ISSUE   0x3	/* REG_LOGIN was issued for NL_PORT */
#define NLP_STE_REG_LOGIN_ISSUE   0x3	/* REG_LOGIN was issued for NL_PORT */
#define NLP_STE_PRLI_ISSUE        0x4	/* PRLI was sent to NL_PORT */
#define NLP_STE_PRLI_ISSUE        0x4	/* PRLI was sent to NL_PORT */
#define NLP_STE_UNMAPPED_NODE     0x5	/* PRLI completed from NL_PORT */
#define NLP_STE_LOGO_ISSUE	  0x5	/* LOGO was sent to NL_PORT */
#define NLP_STE_MAPPED_NODE       0x6	/* Identified as a FCP Target */
#define NLP_STE_UNMAPPED_NODE     0x6	/* PRLI completed from NL_PORT */
#define NLP_STE_NPR_NODE          0x7	/* NPort disappeared */
#define NLP_STE_MAPPED_NODE       0x7	/* Identified as a FCP Target */
#define NLP_STE_MAX_STATE         0x8
#define NLP_STE_NPR_NODE          0x8	/* NPort disappeared */
#define NLP_STE_MAX_STATE         0x9
#define NLP_STE_FREED_NODE        0xff	/* node entry was freed to MEM_NLP */
#define NLP_STE_FREED_NODE        0xff	/* node entry was freed to MEM_NLP */


/* For UNUSED_NODE state, the node has just been allocated.
/* For UNUSED_NODE state, the node has just been allocated.
+115 −22
Original line number Original line Diff line number Diff line
@@ -2385,6 +2385,8 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	IOCB_t *irsp;
	IOCB_t *irsp;
	struct lpfc_sli *psli;
	struct lpfc_sli *psli;
	struct lpfcMboxq *mbox;
	struct lpfcMboxq *mbox;
	unsigned long flags;
	uint32_t skip_recovery = 0;


	psli = &phba->sli;
	psli = &phba->sli;
	/* we pass cmdiocb to state machine which needs rspiocb as well */
	/* we pass cmdiocb to state machine which needs rspiocb as well */
@@ -2399,47 +2401,52 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		"LOGO cmpl:       status:x%x/x%x did:x%x",
		"LOGO cmpl:       status:x%x/x%x did:x%x",
		irsp->ulpStatus, irsp->un.ulpWord[4],
		irsp->ulpStatus, irsp->un.ulpWord[4],
		ndlp->nlp_DID);
		ndlp->nlp_DID);

	/* LOGO completes to NPort <nlp_DID> */
	/* LOGO completes to NPort <nlp_DID> */
	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
			 "0105 LOGO completes to NPort x%x "
			 "0105 LOGO completes to NPort x%x "
			 "Data: x%x x%x x%x x%x\n",
			 "Data: x%x x%x x%x x%x\n",
			 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
			 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
			 irsp->ulpTimeout, vport->num_disc_nodes);
			 irsp->ulpTimeout, vport->num_disc_nodes);
	/* Check to see if link went down during discovery */

	if (lpfc_els_chk_latt(vport))
	if (lpfc_els_chk_latt(vport)) {
		skip_recovery = 1;
		goto out;
		goto out;
	}


	/* Check to see if link went down during discovery */
	if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
	if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
	        /* NLP_EVT_DEVICE_RM should unregister the RPI
	        /* NLP_EVT_DEVICE_RM should unregister the RPI
		 * which should abort all outstanding IOs.
		 * which should abort all outstanding IOs.
		 */
		 */
		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
					NLP_EVT_DEVICE_RM);
					NLP_EVT_DEVICE_RM);
		skip_recovery = 1;
		goto out;
		goto out;
	}
	}


	if (irsp->ulpStatus) {
	if (irsp->ulpStatus) {
		/* Check for retry */
		/* Check for retry */
		if (lpfc_els_retry(phba, cmdiocb, rspiocb))
		if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
			/* ELS command is being retried */
			/* ELS command is being retried */
			skip_recovery = 1;
			goto out;
			goto out;
		}
		/* LOGO failed */
		/* LOGO failed */
		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
				 "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
				 "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
				 ndlp->nlp_DID, irsp->ulpStatus,
				 ndlp->nlp_DID, irsp->ulpStatus,
				 irsp->un.ulpWord[4]);
				 irsp->un.ulpWord[4]);
		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
		if (lpfc_error_lost_link(irsp))
		if (lpfc_error_lost_link(irsp)) {
			skip_recovery = 1;
			goto out;
			goto out;
		else
		}
			lpfc_disc_state_machine(vport, ndlp, cmdiocb,
	}
						NLP_EVT_CMPL_LOGO);

	} else
	/* Call state machine. This will unregister the rpi if needed. */
		/* Good status, call state machine.
	lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
		 * This will unregister the rpi if needed.

		 */
		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
					NLP_EVT_CMPL_LOGO);
out:
out:
	lpfc_els_free_iocb(phba, cmdiocb);
	lpfc_els_free_iocb(phba, cmdiocb);
	/* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */
	/* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */
@@ -2454,8 +2461,29 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
			if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
				MBX_NOT_FINISHED) {
				MBX_NOT_FINISHED) {
				mempool_free(mbox, phba->mbox_mem_pool);
				mempool_free(mbox, phba->mbox_mem_pool);
				skip_recovery = 1;
			}
		}
		}
	}
	}

	/*
	 * If the node is a target, the handling attempts to recover the port.
	 * For any other port type, the rpi is unregistered as an implicit
	 * LOGO.
	 */
	if ((ndlp->nlp_type & NLP_FCP_TARGET) && (skip_recovery == 0)) {
		lpfc_cancel_retry_delay_tmo(vport, ndlp);
		spin_lock_irqsave(shost->host_lock, flags);
		ndlp->nlp_flag |= NLP_NPR_2B_DISC;
		spin_unlock_irqrestore(shost->host_lock, flags);

		lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
				 "3187 LOGO completes to NPort x%x: Start "
				 "Recovery Data: x%x x%x x%x x%x\n",
				 ndlp->nlp_DID, irsp->ulpStatus,
				 irsp->un.ulpWord[4], irsp->ulpTimeout,
				 vport->num_disc_nodes);
		lpfc_disc_start(vport);
	}
	}
	return;
	return;
}
}
@@ -2519,10 +2547,27 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
		"Issue LOGO:      did:x%x",
		"Issue LOGO:      did:x%x",
		ndlp->nlp_DID, 0, 0);
		ndlp->nlp_DID, 0, 0);


	/*
	 * If we are issuing a LOGO, we may try to recover the remote NPort
	 * by issuing a PLOGI later. Even though we issue ELS cmds by the
	 * VPI, if we have a valid RPI, and that RPI gets unreg'ed while
	 * that ELS command is in-flight, the HBA returns a IOERR_INVALID_RPI
	 * for that ELS cmd. To avoid this situation, lets get rid of the
	 * RPI right now, before any ELS cmds are sent.
	 */
	spin_lock_irq(shost->host_lock);
	ndlp->nlp_flag |= NLP_ISSUE_LOGO;
	spin_unlock_irq(shost->host_lock);
	if (lpfc_unreg_rpi(vport, ndlp)) {
		lpfc_els_free_iocb(phba, elsiocb);
		return 0;
	}

	phba->fc_stat.elsXmitLOGO++;
	phba->fc_stat.elsXmitLOGO++;
	elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
	elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
	spin_lock_irq(shost->host_lock);
	spin_lock_irq(shost->host_lock);
	ndlp->nlp_flag |= NLP_LOGO_SND;
	ndlp->nlp_flag |= NLP_LOGO_SND;
	ndlp->nlp_flag &= ~NLP_ISSUE_LOGO;
	spin_unlock_irq(shost->host_lock);
	spin_unlock_irq(shost->host_lock);
	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);


@@ -2938,7 +2983,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
	case ELS_CMD_LOGO:
	case ELS_CMD_LOGO:
		if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
		if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
			ndlp->nlp_prev_state = ndlp->nlp_state;
			ndlp->nlp_prev_state = ndlp->nlp_state;
			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
			lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
		}
		}
		break;
		break;
	case ELS_CMD_FDISC:
	case ELS_CMD_FDISC:
@@ -3291,7 +3336,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			return 1;
			return 1;
		case ELS_CMD_LOGO:
		case ELS_CMD_LOGO:
			ndlp->nlp_prev_state = ndlp->nlp_state;
			ndlp->nlp_prev_state = ndlp->nlp_state;
			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
			lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
			lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
			lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
			return 1;
			return 1;
		}
		}
@@ -3551,13 +3596,17 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);
	mempool_free(pmb, phba->mbox_mem_pool);
	if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
	if (ndlp) {
		if (NLP_CHK_NODE_ACT(ndlp)) {
			lpfc_nlp_put(ndlp);
			lpfc_nlp_put(ndlp);
		/* This is the end of the default RPI cleanup logic for this
			/* This is the end of the default RPI cleanup logic for
		 * ndlp. If no other discovery threads are using this ndlp.
			 * this ndlp. If no other discovery threads are using
		 * we should free all resources associated with it.
			 * this ndlp, free all resources associated with it.
			 */
			 */
			lpfc_nlp_not_used(ndlp);
			lpfc_nlp_not_used(ndlp);
		} else {
			lpfc_drop_node(ndlp->vport, ndlp);
		}
	}
	}


	return;
	return;
@@ -8003,3 +8052,47 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
	spin_unlock_irqrestore(&phba->hbalock, iflag);
	spin_unlock_irqrestore(&phba->hbalock, iflag);
	return;
	return;
}
}

/* lpfc_sli_abts_recover_port - Recover a port that failed a BLS_ABORT req.
 * @vport: pointer to virtual port object.
 * @ndlp: nodelist pointer for the impacted node.
 *
 * The driver calls this routine in response to an SLI4 XRI ABORT CQE
 * or an SLI3 ASYNC_STATUS_CN event from the port.  For either event,
 * the driver is required to send a LOGO to the remote node before it
 * attempts to recover its login to the remote node.
 */
void
lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
			   struct lpfc_nodelist *ndlp)
{
	struct Scsi_Host *shost;
	struct lpfc_hba *phba;
	unsigned long flags = 0;

	shost = lpfc_shost_from_vport(vport);
	phba = vport->phba;
	if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
		lpfc_printf_log(phba, KERN_INFO,
				LOG_SLI, "3093 No rport recovery needed. "
				"rport in state 0x%x\n", ndlp->nlp_state);
		return;
	}
	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
			"3094 Start rport recovery on shost id 0x%x "
			"fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
			"flags 0x%x\n",
			shost->host_no, ndlp->nlp_DID,
			vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state,
			ndlp->nlp_flag);
	/*
	 * The rport is not responding.  Remove the FCP-2 flag to prevent
	 * an ADISC in the follow-up recovery code.
	 */
	spin_lock_irqsave(shost->host_lock, flags);
	ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
	spin_unlock_irqrestore(shost->host_lock, flags);
	lpfc_issue_els_logo(vport, ndlp, 0);
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
}
+36 −2
Original line number Original line Diff line number Diff line
@@ -3989,6 +3989,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state)
		[NLP_STE_ADISC_ISSUE] = "ADISC",
		[NLP_STE_ADISC_ISSUE] = "ADISC",
		[NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
		[NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
		[NLP_STE_PRLI_ISSUE] = "PRLI",
		[NLP_STE_PRLI_ISSUE] = "PRLI",
		[NLP_STE_LOGO_ISSUE] = "LOGO",
		[NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
		[NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
		[NLP_STE_MAPPED_NODE] = "MAPPED",
		[NLP_STE_MAPPED_NODE] = "MAPPED",
		[NLP_STE_NPR_NODE] = "NPR",
		[NLP_STE_NPR_NODE] = "NPR",
@@ -4355,6 +4356,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
	return 0;
	return 0;
}
}


/**
 * lpfc_nlp_logo_unreg - Unreg mailbox completion handler before LOGO
 * @phba: Pointer to HBA context object.
 * @pmb: Pointer to mailbox object.
 *
 * This function will issue an ELS LOGO command after completing
 * the UNREG_RPI.
 **/
void
lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
	struct lpfc_vport  *vport = pmb->vport;
	struct lpfc_nodelist *ndlp;

	ndlp = (struct lpfc_nodelist *)(pmb->context1);
	if (!ndlp)
		return;
	lpfc_issue_els_logo(vport, ndlp, 0);
}

/*
/*
 * Free rpi associated with LPFC_NODELIST entry.
 * Free rpi associated with LPFC_NODELIST entry.
 * This routine is called from lpfc_freenode(), when we are removing
 * This routine is called from lpfc_freenode(), when we are removing
@@ -4379,9 +4400,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
			rpi = ndlp->nlp_rpi;
			rpi = ndlp->nlp_rpi;
			if (phba->sli_rev == LPFC_SLI_REV4)
			if (phba->sli_rev == LPFC_SLI_REV4)
				rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
				rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];

			lpfc_unreg_login(phba, vport->vpi, rpi, mbox);
			lpfc_unreg_login(phba, vport->vpi, rpi, mbox);
			mbox->vport = vport;
			mbox->vport = vport;
			if (ndlp->nlp_flag & NLP_ISSUE_LOGO) {
				mbox->context1 = ndlp;
				mbox->mbox_cmpl = lpfc_nlp_logo_unreg;
			} else {
				mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
				mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
			}

			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
			if (rc == MBX_NOT_FINISHED)
			if (rc == MBX_NOT_FINISHED)
				mempool_free(mbox, phba->mbox_mem_pool);
				mempool_free(mbox, phba->mbox_mem_pool);
@@ -4524,9 +4552,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
		lpfc_disable_node(vport, ndlp);
		lpfc_disable_node(vport, ndlp);
	}
	}



	/* Don't need to clean up REG_LOGIN64 cmds for Default RPI cleanup */

	/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
	/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
	if ((mb = phba->sli.mbox_active)) {
	if ((mb = phba->sli.mbox_active)) {
		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
		   !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
			mb->context2 = NULL;
			mb->context2 = NULL;
			mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
			mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -4537,6 +4569,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
	/* Cleanup REG_LOGIN completions which are not yet processed */
	/* Cleanup REG_LOGIN completions which are not yet processed */
	list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
	list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
		if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) ||
		if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) ||
			(mb->mbox_flag & LPFC_MBX_IMED_UNREG) ||
			(ndlp != (struct lpfc_nodelist *) mb->context2))
			(ndlp != (struct lpfc_nodelist *) mb->context2))
			continue;
			continue;


@@ -4546,6 +4579,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)


	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
		   !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
		    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
		    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
			mp = (struct lpfc_dmabuf *) (mb->context1);
			mp = (struct lpfc_dmabuf *) (mb->context1);
			if (mp) {
			if (mp) {
@@ -4610,7 +4644,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
				mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
				mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
				mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
				mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
				mbox->vport = vport;
				mbox->vport = vport;
				mbox->context2 = NULL;
				mbox->context2 = ndlp;
				rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
				rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
				if (rc == MBX_NOT_FINISHED) {
				if (rc == MBX_NOT_FINISHED) {
					mempool_free(mbox, phba->mbox_mem_pool);
					mempool_free(mbox, phba->mbox_mem_pool);
Loading