Commit ef47575f authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Refactor cleanup of mailbox commands

The intention of this patch is to refactor mailbox memory allocation and
cleanup steps in one routine respectively to prevent memory leaks or memory
errors related to mailbox commands.  There are trivial localized fixes as
well.

Provide lpfc_mbox_rsrc_prep() - this routine allocates the dmabuf and the
mbuf associated with it.  It also catches allocation errors and returns
status.

Provide lpfc_mbox_rsrc_cleanup() - this routine verifies a dmabuf exists
and if so releases the associated mbuf and the dmabuf memory.  It then sets
the ctx_buf to NULL and releases the mailbox memory to the mailbox pool.

Link: https://lore.kernel.org/r/20220412222008.126521-22-jsmart2021@gmail.com


Co-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d51cf5bd
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -32,7 +32,9 @@ int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
int lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *, struct lpfcMboxq *);
int lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *, struct lpfcMboxq *);
void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);

int lpfc_mbox_rsrc_prep(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox);
void lpfc_mbox_rsrc_cleanup(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox,
			    enum lpfc_mbox_ctx locked);
void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
int lpfc_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+28 −77
Original line number Original line Diff line number Diff line
@@ -345,7 +345,6 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
{
{
	struct lpfc_hba  *phba = vport->phba;
	struct lpfc_hba  *phba = vport->phba;
	LPFC_MBOXQ_t *mbox;
	LPFC_MBOXQ_t *mbox;
	struct lpfc_dmabuf *mp;
	struct lpfc_nodelist *ndlp;
	struct lpfc_nodelist *ndlp;
	struct serv_parm *sp;
	struct serv_parm *sp;
	int rc;
	int rc;
@@ -395,7 +394,7 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
	mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
	mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
	if (!mbox->ctx_ndlp) {
	if (!mbox->ctx_ndlp) {
		err = 6;
		err = 6;
		goto fail_no_ndlp;
		goto fail_free_mbox;
	}
	}


	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
@@ -411,13 +410,8 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
	 * for the failed mbox command.
	 * for the failed mbox command.
	 */
	 */
	lpfc_nlp_put(ndlp);
	lpfc_nlp_put(ndlp);
fail_no_ndlp:
	mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
fail_free_mbox:
fail_free_mbox:
	mempool_free(mbox, phba->mbox_mem_pool);
	lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);

fail:
fail:
	lpfc_vport_set_state(vport, FC_VPORT_FAILED);
	lpfc_vport_set_state(vport, FC_VPORT_FAILED);
	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
@@ -465,45 +459,37 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)


	/* Supply CSP's only if we are fabric connect or pt-to-pt connect */
	/* Supply CSP's only if we are fabric connect or pt-to-pt connect */
	if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) {
	if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) {
		dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
		rc = lpfc_mbox_rsrc_prep(phba, mboxq);
		if (!dmabuf) {
		if (rc) {
			rc = -ENOMEM;
			goto fail;
		}
		dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
		if (!dmabuf->virt) {
			rc = -ENOMEM;
			rc = -ENOMEM;
			goto fail;
			goto fail_mbox;
		}
		}
		dmabuf = mboxq->ctx_buf;
		memcpy(dmabuf->virt, &phba->fc_fabparam,
		memcpy(dmabuf->virt, &phba->fc_fabparam,
		       sizeof(struct serv_parm));
		       sizeof(struct serv_parm));
	}
	}


	vport->port_state = LPFC_FABRIC_CFG_LINK;
	vport->port_state = LPFC_FABRIC_CFG_LINK;
	if (dmabuf)
	if (dmabuf) {
		lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
		lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
	else
		/* lpfc_reg_vfi memsets the mailbox.  Restore the ctx_buf. */
		mboxq->ctx_buf = dmabuf;
	} else {
		lpfc_reg_vfi(mboxq, vport, 0);
		lpfc_reg_vfi(mboxq, vport, 0);
	}


	mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
	mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
	mboxq->vport = vport;
	mboxq->vport = vport;
	mboxq->ctx_buf = dmabuf;
	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
	if (rc == MBX_NOT_FINISHED) {
	if (rc == MBX_NOT_FINISHED) {
		rc = -ENXIO;
		rc = -ENXIO;
		goto fail;
		goto fail_mbox;
	}
	}
	return 0;
	return 0;


fail_mbox:
	lpfc_mbox_rsrc_cleanup(phba, mboxq, MBOX_THD_UNLOCKED);
fail:
fail:
	if (mboxq)
		mempool_free(mboxq, phba->mbox_mem_pool);
	if (dmabuf) {
		if (dmabuf->virt)
			lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
		kfree(dmabuf);
	}

	lpfc_vport_set_state(vport, FC_VPORT_FAILED);
	lpfc_vport_set_state(vport, FC_VPORT_FAILED);
	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
			 "0289 Issue Register VFI failed: Err %d\n", rc);
			 "0289 Issue Register VFI failed: Err %d\n", rc);
@@ -3252,7 +3238,6 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
	struct lpfc_hba *phba = vport->phba;
	struct lpfc_hba *phba = vport->phba;
	struct lpfc_nodelist *ns_ndlp;
	struct lpfc_nodelist *ns_ndlp;
	LPFC_MBOXQ_t *mbox;
	LPFC_MBOXQ_t *mbox;
	struct lpfc_dmabuf *mp;


	if (fc_ndlp->nlp_flag & NLP_RPI_REGISTERED)
	if (fc_ndlp->nlp_flag & NLP_RPI_REGISTERED)
		return rc;
		return rc;
@@ -3289,7 +3274,7 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
	mbox->ctx_ndlp = lpfc_nlp_get(fc_ndlp);
	mbox->ctx_ndlp = lpfc_nlp_get(fc_ndlp);
	if (!mbox->ctx_ndlp) {
	if (!mbox->ctx_ndlp) {
		rc = -ENOMEM;
		rc = -ENOMEM;
		goto out_mem;
		goto out;
	}
	}


	mbox->vport = vport;
	mbox->vport = vport;
@@ -3297,21 +3282,15 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
	if (rc == MBX_NOT_FINISHED) {
	if (rc == MBX_NOT_FINISHED) {
		rc = -ENODEV;
		rc = -ENODEV;
		lpfc_nlp_put(fc_ndlp);
		lpfc_nlp_put(fc_ndlp);
		goto out_mem;
		goto out;
	}
	}
	/* Success path. Exit. */
	/* Success path. Exit. */
	lpfc_nlp_set_state(vport, fc_ndlp,
	lpfc_nlp_set_state(vport, fc_ndlp,
			   NLP_STE_REG_LOGIN_ISSUE);
			   NLP_STE_REG_LOGIN_ISSUE);
	return 0;
	return 0;


 out_mem:
	fc_ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
	mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);

 out:
 out:
	mempool_free(mbox, phba->mbox_mem_pool);
	lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
	lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
	lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
			 "0938 %s: failed to format reg_login "
			 "0938 %s: failed to format reg_login "
			 "Data: x%x x%x x%x x%x\n", __func__,
			 "Data: x%x x%x x%x x%x\n", __func__,
@@ -5248,14 +5227,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
void
void
lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
	struct lpfc_nodelist *ndlp = pmb->ctx_ndlp;
	struct lpfc_nodelist *ndlp = pmb->ctx_ndlp;
	u32 mbx_flag = pmb->mbox_flag;
	u32 mbx_flag = pmb->mbox_flag;
	u32 mbx_cmd = pmb->u.mb.mbxCommand;
	u32 mbx_cmd = pmb->u.mb.mbxCommand;


	pmb->ctx_buf = NULL;
	pmb->ctx_ndlp = NULL;

	if (ndlp) {
	if (ndlp) {
		lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
		lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
				 "0006 rpi x%x DID:%x flg:%x %d x%px "
				 "0006 rpi x%x DID:%x flg:%x %d x%px "
@@ -5278,10 +5253,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		lpfc_drop_node(ndlp->vport, ndlp);
		lpfc_drop_node(ndlp->vport, ndlp);
	}
	}


	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);
	return;
}
}


/**
/**
@@ -5306,7 +5278,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	struct Scsi_Host  *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
	struct Scsi_Host  *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
	IOCB_t  *irsp;
	IOCB_t  *irsp;
	LPFC_MBOXQ_t *mbox = NULL;
	LPFC_MBOXQ_t *mbox = NULL;
	struct lpfc_dmabuf *mp = NULL;
	u32 ulp_status, ulp_word4, tmo, did, iotag;
	u32 ulp_status, ulp_word4, tmo, did, iotag;


	if (!vport) {
	if (!vport) {
@@ -5332,14 +5303,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,


	/* Check to see if link went down during discovery */
	/* Check to see if link went down during discovery */
	if (!ndlp || lpfc_els_chk_latt(vport)) {
	if (!ndlp || lpfc_els_chk_latt(vport)) {
		if (mbox) {
		if (mbox)
			mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
			lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
			if (mp) {
				lpfc_mbuf_free(phba, mp->virt, mp->phys);
				kfree(mp);
			}
			mempool_free(mbox, phba->mbox_mem_pool);
		}
		goto out;
		goto out;
	}
	}


@@ -5370,14 +5335,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
							 ndlp->nlp_state,
							 ndlp->nlp_state,
							 ndlp->nlp_rpi,
							 ndlp->nlp_rpi,
							 ndlp->nlp_flag);
							 ndlp->nlp_flag);
					mp = mbox->ctx_buf;
					goto out_free_mbox;
					if (mp) {
						lpfc_mbuf_free(phba, mp->virt,
							       mp->phys);
						kfree(mp);
					}
					mempool_free(mbox, phba->mbox_mem_pool);
					goto out;
				}
				}
			}
			}


@@ -5386,7 +5344,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			 */
			 */
			mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
			mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
			if (!mbox->ctx_ndlp)
			if (!mbox->ctx_ndlp)
				goto out;
				goto out_free_mbox;


			mbox->vport = vport;
			mbox->vport = vport;
			if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
			if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
@@ -5418,12 +5376,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
				ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
				ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
				ndlp->nlp_rpi);
				ndlp->nlp_rpi);
		}
		}
		mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
out_free_mbox:
		if (mp) {
		lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
		}
		mempool_free(mbox, phba->mbox_mem_pool);
	}
	}
out:
out:
	if (ndlp && shost) {
	if (ndlp && shost) {
@@ -7188,7 +7142,6 @@ static int
lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
{
{
	LPFC_MBOXQ_t *mbox = NULL;
	LPFC_MBOXQ_t *mbox = NULL;
	struct lpfc_dmabuf *mp;
	int rc;
	int rc;


	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -7199,21 +7152,19 @@ lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
	}
	}


	if (lpfc_sli4_dump_page_a0(phba, mbox))
	if (lpfc_sli4_dump_page_a0(phba, mbox))
		goto prep_mbox_fail;
		goto rdp_fail;
	mbox->vport = rdp_context->ndlp->vport;
	mbox->vport = rdp_context->ndlp->vport;
	mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
	mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
	mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
	mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
	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) {
		mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
		lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		return 1;
		goto issue_mbox_fail;
	}
	}


	return 0;
	return 0;


prep_mbox_fail:
rdp_fail:
issue_mbox_fail:
	mempool_free(mbox, phba->mbox_mem_pool);
	mempool_free(mbox, phba->mbox_mem_pool);
	return 1;
	return 1;
}
}
+33 −91
Original line number Original line Diff line number Diff line
@@ -1459,7 +1459,6 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	struct lpfc_vport *vport = pmb->vport;
	struct lpfc_vport *vport = pmb->vport;
	LPFC_MBOXQ_t *sparam_mb;
	LPFC_MBOXQ_t *sparam_mb;
	struct lpfc_dmabuf *sparam_mp;
	u16 status = pmb->u.mb.mbxStatus;
	u16 status = pmb->u.mb.mbxStatus;
	int rc;
	int rc;


@@ -1508,13 +1507,8 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
			sparam_mb->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
			sparam_mb->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
			rc = lpfc_sli_issue_mbox(phba, sparam_mb, MBX_NOWAIT);
			rc = lpfc_sli_issue_mbox(phba, sparam_mb, MBX_NOWAIT);
			if (rc == MBX_NOT_FINISHED) {
			if (rc == MBX_NOT_FINISHED) {
				sparam_mp = (struct lpfc_dmabuf *)
				lpfc_mbox_rsrc_cleanup(phba, sparam_mb,
						sparam_mb->ctx_buf;
						       MBOX_THD_UNLOCKED);
				lpfc_mbuf_free(phba, sparam_mp->virt,
					       sparam_mp->phys);
				kfree(sparam_mp);
				sparam_mb->ctx_buf = NULL;
				mempool_free(sparam_mb, phba->mbox_mem_pool);
				goto sparam_out;
				goto sparam_out;
			}
			}


@@ -3313,7 +3307,6 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
void
void
lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{
{
	struct lpfc_dmabuf *dmabuf = mboxq->ctx_buf;
	struct lpfc_vport *vport = mboxq->vport;
	struct lpfc_vport *vport = mboxq->vport;
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);


@@ -3394,12 +3387,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
	}
	}


out_free_mem:
out_free_mem:
	mempool_free(mboxq, phba->mbox_mem_pool);
	lpfc_mbox_rsrc_cleanup(phba, mboxq, MBOX_THD_UNLOCKED);
	if (dmabuf) {
		lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
		kfree(dmabuf);
	}
	return;
}
}


static void
static void
@@ -3444,9 +3432,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn));
		memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn));
	}
	}


	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);


	/* Check if sending the FLOGI is being deferred to after we get
	/* Check if sending the FLOGI is being deferred to after we get
	 * up to date CSPs from MBX_READ_SPARAM.
	 * up to date CSPs from MBX_READ_SPARAM.
@@ -3458,12 +3444,8 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	return;
	return;


out:
out:
	pmb->ctx_buf = NULL;
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	lpfc_issue_clear_la(phba, vport);
	lpfc_issue_clear_la(phba, vport);
	mempool_free(pmb, phba->mbox_mem_pool);
	return;
}
}


static void
static void
@@ -3473,7 +3455,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
	LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL;
	LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL;
	struct Scsi_Host *shost;
	struct Scsi_Host *shost;
	int i;
	int i;
	struct lpfc_dmabuf *mp;
	int rc;
	int rc;
	struct fcf_record *fcf_record;
	struct fcf_record *fcf_record;
	uint32_t fc_flags = 0;
	uint32_t fc_flags = 0;
@@ -3601,10 +3582,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
	sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
	sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
	rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
	rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
	if (rc == MBX_NOT_FINISHED) {
	if (rc == MBX_NOT_FINISHED) {
		mp = (struct lpfc_dmabuf *)sparam_mbox->ctx_buf;
		lpfc_mbox_rsrc_cleanup(phba, sparam_mbox, MBOX_THD_UNLOCKED);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
		mempool_free(sparam_mbox, phba->mbox_mem_pool);
		goto out;
		goto out;
	}
	}


@@ -3880,10 +3858,7 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	}
	}


lpfc_mbx_cmpl_read_topology_free_mbuf:
lpfc_mbx_cmpl_read_topology_free_mbuf:
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);
	return;
}
}


/*
/*
@@ -3896,9 +3871,13 @@ void
lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	struct lpfc_vport  *vport = pmb->vport;
	struct lpfc_vport  *vport = pmb->vport;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;


	/* The driver calls the state machine with the pmb pointer
	 * but wants to make sure a stale ctx_buf isn't acted on.
	 * The ctx_buf is restored later and cleaned up.
	 */
	pmb->ctx_buf = NULL;
	pmb->ctx_buf = NULL;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_ndlp = NULL;


@@ -3935,10 +3914,9 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)


	/* Call state machine */
	/* Call state machine */
	lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
	lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
	pmb->ctx_buf = mp;
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);


	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);
	/* decrement the node reference count held for this callback
	/* decrement the node reference count held for this callback
	 * function.
	 * function.
	 */
	 */
@@ -4105,11 +4083,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba)


	vport_buff = (uint8_t *) vport_info;
	vport_buff = (uint8_t *) vport_info;
	do {
	do {
		/* free dma buffer from previous round */
		/* While loop iteration forces a free dma buffer from
		 * the previous loop because the mbox is reused and
		 * the dump routine is a single-use construct.
		 */
		if (pmb->ctx_buf) {
		if (pmb->ctx_buf) {
			mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
			mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
			kfree(mp);
			pmb->ctx_buf = NULL;
		}
		}
		if (lpfc_dump_static_vport(phba, pmb, offset))
		if (lpfc_dump_static_vport(phba, pmb, offset))
			goto out;
			goto out;
@@ -4194,16 +4176,8 @@ lpfc_create_static_vport(struct lpfc_hba *phba)


out:
out:
	kfree(vport_info);
	kfree(vport_info);
	if (mbx_wait_rc != MBX_TIMEOUT) {
	if (mbx_wait_rc != MBX_TIMEOUT)
		if (pmb->ctx_buf) {
		lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
			mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
		}
		mempool_free(pmb, phba->mbox_mem_pool);
	}

	return;
}
}


/*
/*
@@ -4217,22 +4191,16 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	struct lpfc_vport *vport = pmb->vport;
	struct lpfc_vport *vport = pmb->vport;
	MAILBOX_t *mb = &pmb->u.mb;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_nodelist *ndlp;
	struct Scsi_Host *shost;
	struct Scsi_Host *shost;


	ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_buf = NULL;


	if (mb->mbxStatus) {
	if (mb->mbxStatus) {
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
				 "0258 Register Fabric login error: 0x%x\n",
				 "0258 Register Fabric login error: 0x%x\n",
				 mb->mbxStatus);
				 mb->mbxStatus);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
		kfree(mp);
		mempool_free(pmb, phba->mbox_mem_pool);

		if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
		if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
			/* FLOGI failed, use loop map to make discovery list */
			/* FLOGI failed, use loop map to make discovery list */
			lpfc_disc_list_loopmap(vport);
			lpfc_disc_list_loopmap(vport);
@@ -4274,9 +4242,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		lpfc_do_scr_ns_plogi(phba, vport);
		lpfc_do_scr_ns_plogi(phba, vport);
	}
	}


	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);


	/* Drop the reference count from the mbox at the end after
	/* Drop the reference count from the mbox at the end after
	 * all the current reference to the ndlp have been done.
	 * all the current reference to the ndlp have been done.
@@ -4370,12 +4336,10 @@ void
lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	MAILBOX_t *mb = &pmb->u.mb;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_vport *vport = pmb->vport;
	struct lpfc_vport *vport = pmb->vport;
	int rc;
	int rc;


	pmb->ctx_buf = NULL;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_ndlp = NULL;
	vport->gidft_inp = 0;
	vport->gidft_inp = 0;


@@ -4389,9 +4353,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		 * callback function.
		 * callback function.
		 */
		 */
		lpfc_nlp_put(ndlp);
		lpfc_nlp_put(ndlp);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
		kfree(mp);
		mempool_free(pmb, phba->mbox_mem_pool);


		/* If the node is not registered with the scsi or nvme
		/* If the node is not registered with the scsi or nvme
		 * transport, remove the fabric node.  The failed reg_login
		 * transport, remove the fabric node.  The failed reg_login
@@ -4480,10 +4442,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	 * callback function.
	 * callback function.
	 */
	 */
	lpfc_nlp_put(ndlp);
	lpfc_nlp_put(ndlp);
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);

	return;
	return;
}
}


@@ -4497,13 +4456,9 @@ lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	struct lpfc_vport *vport = pmb->vport;
	struct lpfc_vport *vport = pmb->vport;
	MAILBOX_t *mb = &pmb->u.mb;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_nodelist *ndlp;


	ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_buf = NULL;

	if (mb->mbxStatus) {
	if (mb->mbxStatus) {
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
				 "0933 %s: Register FC login error: 0x%x\n",
				 "0933 %s: Register FC login error: 0x%x\n",
@@ -4527,9 +4482,7 @@ lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);


 out:
 out:
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);


	/* Drop the reference count from the mbox at the end after
	/* Drop the reference count from the mbox at the end after
	 * all the current reference to the ndlp have been done.
	 * all the current reference to the ndlp have been done.
@@ -5570,7 +5523,6 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
{
	struct lpfc_hba  *phba = vport->phba;
	struct lpfc_hba  *phba = vport->phba;
	LPFC_MBOXQ_t *mb, *nextmb;
	LPFC_MBOXQ_t *mb, *nextmb;
	struct lpfc_dmabuf *mp;


	/* Cleanup node for NPort <nlp_DID> */
	/* Cleanup node for NPort <nlp_DID> */
	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
@@ -5608,16 +5560,11 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
		   !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
		   !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
		    (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) {
		    (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) {
			mp = (struct lpfc_dmabuf *)(mb->ctx_buf);
			if (mp) {
				__lpfc_mbuf_free(phba, mp->virt, mp->phys);
				kfree(mp);
			}
			list_del(&mb->list);
			list_del(&mb->list);
			mempool_free(mb, phba->mbox_mem_pool);
			lpfc_mbox_rsrc_cleanup(phba, mb, MBOX_THD_LOCKED);
			/* We shall not invoke the lpfc_nlp_put to decrement

			 * the ndlp reference count as we are in the process
			/* Don't invoke lpfc_nlp_put. The driver is in
			 * of lpfc_nlp_release.
			 * lpfc_nlp_release context.
			 */
			 */
		}
		}
	}
	}
@@ -6462,11 +6409,9 @@ void
lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	MAILBOX_t *mb = &pmb->u.mb;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf   *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
	struct lpfc_vport    *vport = pmb->vport;
	struct lpfc_vport    *vport = pmb->vport;


	pmb->ctx_buf = NULL;
	pmb->ctx_ndlp = NULL;
	pmb->ctx_ndlp = NULL;


	if (phba->sli_rev < LPFC_SLI_REV4)
	if (phba->sli_rev < LPFC_SLI_REV4)
@@ -6497,10 +6442,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	 * function.
	 * function.
	 */
	 */
	lpfc_nlp_put(ndlp);
	lpfc_nlp_put(ndlp);
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);

	return;
	return;
}
}


+26 −57
Original line number Original line Diff line number Diff line
@@ -443,15 +443,16 @@ lpfc_config_port_post(struct lpfc_hba *phba)
				"READ_SPARM mbxStatus x%x\n",
				"READ_SPARM mbxStatus x%x\n",
				mb->mbxCommand, mb->mbxStatus);
				mb->mbxCommand, mb->mbxStatus);
		phba->link_state = LPFC_HBA_ERROR;
		phba->link_state = LPFC_HBA_ERROR;
		mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
		lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
		mempool_free(pmb, phba->mbox_mem_pool);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
		return -EIO;
		return -EIO;
	}
	}


	mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
	mp = (struct lpfc_dmabuf *)pmb->ctx_buf;


	/* This dmabuf was allocated by lpfc_read_sparam. The dmabuf is no
	 * longer needed.  Prevent unintended ctx_buf access as the mbox is
	 * reused.
	 */
	memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
	memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	kfree(mp);
@@ -2182,7 +2183,6 @@ lpfc_handle_latt(struct lpfc_hba *phba)
	struct lpfc_sli   *psli = &phba->sli;
	struct lpfc_sli   *psli = &phba->sli;
	LPFC_MBOXQ_t *pmb;
	LPFC_MBOXQ_t *pmb;
	volatile uint32_t control;
	volatile uint32_t control;
	struct lpfc_dmabuf *mp;
	int rc = 0;
	int rc = 0;


	pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -2191,23 +2191,17 @@ lpfc_handle_latt(struct lpfc_hba *phba)
		goto lpfc_handle_latt_err_exit;
		goto lpfc_handle_latt_err_exit;
	}
	}


	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	rc = lpfc_mbox_rsrc_prep(phba, pmb);
	if (!mp) {
	if (rc) {
		rc = 2;
		rc = 2;
		goto lpfc_handle_latt_free_pmb;
		mempool_free(pmb, phba->mbox_mem_pool);
	}
		goto lpfc_handle_latt_err_exit;

	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
	if (!mp->virt) {
		rc = 3;
		goto lpfc_handle_latt_free_mp;
	}
	}


	/* Cleanup any outstanding ELS commands */
	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_all_cmd(phba);
	lpfc_els_flush_all_cmd(phba);

	psli->slistat.link_event++;
	psli->slistat.link_event++;
	lpfc_read_topology(phba, pmb, mp);
	lpfc_read_topology(phba, pmb, (struct lpfc_dmabuf *)pmb->ctx_buf);
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->vport = vport;
	pmb->vport = vport;
	/* Block ELS IOCBs until we have processed this mbox command */
	/* Block ELS IOCBs until we have processed this mbox command */
@@ -2228,11 +2222,7 @@ lpfc_handle_latt(struct lpfc_hba *phba)


lpfc_handle_latt_free_mbuf:
lpfc_handle_latt_free_mbuf:
	phba->sli.sli3_ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT;
	phba->sli.sli3_ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT;
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
lpfc_handle_latt_free_mp:
	kfree(mp);
lpfc_handle_latt_free_pmb:
	mempool_free(pmb, phba->mbox_mem_pool);
lpfc_handle_latt_err_exit:
lpfc_handle_latt_err_exit:
	/* Enable Link attention interrupts */
	/* Enable Link attention interrupts */
	spin_lock_irq(&phba->hbalock);
	spin_lock_irq(&phba->hbalock);
@@ -5315,7 +5305,6 @@ static void
lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
			 struct lpfc_acqe_link *acqe_link)
			 struct lpfc_acqe_link *acqe_link)
{
{
	struct lpfc_dmabuf *mp;
	LPFC_MBOXQ_t *pmb;
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	MAILBOX_t *mb;
	struct lpfc_mbx_read_top *la;
	struct lpfc_mbx_read_top *la;
@@ -5332,18 +5321,13 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
				"0395 The mboxq allocation failed\n");
				"0395 The mboxq allocation failed\n");
		return;
		return;
	}
	}
	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);

	if (!mp) {
	rc = lpfc_mbox_rsrc_prep(phba, pmb);
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0396 The lpfc_dmabuf allocation failed\n");
				"0396 mailbox allocation failed\n");
		goto out_free_pmb;
		goto out_free_pmb;
	}
	}
	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
	if (!mp->virt) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"0397 The mbuf allocation failed\n");
		goto out_free_dmabuf;
	}


	/* Cleanup any outstanding ELS commands */
	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_all_cmd(phba);
	lpfc_els_flush_all_cmd(phba);
@@ -5355,7 +5339,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
	phba->sli.slistat.link_event++;
	phba->sli.slistat.link_event++;


	/* Create lpfc_handle_latt mailbox command from link ACQE */
	/* Create lpfc_handle_latt mailbox command from link ACQE */
	lpfc_read_topology(phba, pmb, mp);
	lpfc_read_topology(phba, pmb, (struct lpfc_dmabuf *)pmb->ctx_buf);
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->vport = phba->pport;
	pmb->vport = phba->pport;


@@ -5393,10 +5377,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
	 */
	 */
	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
	if (!(phba->hba_flag & HBA_FCOE_MODE)) {
		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
		if (rc == MBX_NOT_FINISHED) {
		if (rc == MBX_NOT_FINISHED)
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			goto out_free_pmb;
			goto out_free_dmabuf;
		}
		return;
		return;
	}
	}
	/*
	/*
@@ -5431,10 +5413,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,


	return;
	return;


out_free_dmabuf:
	kfree(mp);
out_free_pmb:
out_free_pmb:
	mempool_free(pmb, phba->mbox_mem_pool);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
}
}


/**
/**
@@ -6245,7 +6225,6 @@ lpfc_update_trunk_link_status(struct lpfc_hba *phba,
static void
static void
lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
{
{
	struct lpfc_dmabuf *mp;
	LPFC_MBOXQ_t *pmb;
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	MAILBOX_t *mb;
	struct lpfc_mbx_read_top *la;
	struct lpfc_mbx_read_top *la;
@@ -6305,18 +6284,12 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
				"2897 The mboxq allocation failed\n");
				"2897 The mboxq allocation failed\n");
		return;
		return;
	}
	}
	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
	rc = lpfc_mbox_rsrc_prep(phba, pmb);
	if (!mp) {
	if (rc) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2898 The lpfc_dmabuf allocation failed\n");
				"2898 The mboxq prep failed\n");
		goto out_free_pmb;
		goto out_free_pmb;
	}
	}
	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
	if (!mp->virt) {
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2899 The mbuf allocation failed\n");
		goto out_free_dmabuf;
	}


	/* Cleanup any outstanding ELS commands */
	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_all_cmd(phba);
	lpfc_els_flush_all_cmd(phba);
@@ -6328,7 +6301,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
	phba->sli.slistat.link_event++;
	phba->sli.slistat.link_event++;


	/* Create lpfc_handle_latt mailbox command from link ACQE */
	/* Create lpfc_handle_latt mailbox command from link ACQE */
	lpfc_read_topology(phba, pmb, mp);
	lpfc_read_topology(phba, pmb, (struct lpfc_dmabuf *)pmb->ctx_buf);
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
	pmb->vport = phba->pport;
	pmb->vport = phba->pport;


@@ -6372,16 +6345,12 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
	}
	}


	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
	if (rc == MBX_NOT_FINISHED) {
	if (rc == MBX_NOT_FINISHED)
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		goto out_free_pmb;
		goto out_free_dmabuf;
	}
	return;
	return;


out_free_dmabuf:
	kfree(mp);
out_free_pmb:
out_free_pmb:
	mempool_free(pmb, phba->mbox_mem_pool);
	lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
}
}


/**
/**
+119 −82

File changed.

Preview size limit exceeded, changes collapsed.

Loading