diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2b6b5fc671fe..48ca4a612f80 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -73,6 +73,16 @@ static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); static int lpfc_fcf_inuse(struct lpfc_hba *); static void lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); +static int +lpfc_valid_xpt_node(struct lpfc_nodelist *ndlp) +{ + if (ndlp->nlp_fc4_type || + ndlp->nlp_DID == Fabric_DID || + ndlp->nlp_DID == NameServer_DID || + ndlp->nlp_DID == FDMI_DID) + return 1; + return 0; +} /* The source of a terminate rport I/O is either a dev_loss_tmo * event or a call to fc_remove_host. While the rport should be * valid during these downcalls, the transport can call twice @@ -1145,13 +1155,14 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) struct lpfc_vport *vport = pmb->vport; LPFC_MBOXQ_t *sparam_mb; struct lpfc_dmabuf *sparam_mp; + u16 status = pmb->u.mb.mbxStatus; int rc; - if (pmb->u.mb.mbxStatus) - goto out; - mempool_free(pmb, phba->mbox_mem_pool); + if (status) + goto out; + /* don't perform discovery for SLI4 loopback diagnostic test */ if ((phba->sli_rev == LPFC_SLI_REV4) && !(phba->hba_flag & HBA_FCOE_MODE) && @@ -1214,12 +1225,10 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) out: lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "0306 CONFIG_LINK mbxStatus error x%x " - "HBA state x%x\n", - pmb->u.mb.mbxStatus, vport->port_state); -sparam_out: - mempool_free(pmb, phba->mbox_mem_pool); + "0306 CONFIG_LINK mbxStatus error x%x HBA state x%x\n", + status, vport->port_state); +sparam_out: lpfc_linkdown(phba); lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, @@ -4318,7 +4327,8 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* FCP and NVME Transport interface */ if ((old_state == NLP_STE_MAPPED_NODE || old_state == NLP_STE_UNMAPPED_NODE)) { - if (ndlp->rport) { + if (ndlp->rport && + lpfc_valid_xpt_node(ndlp)) { vport->phba->nport_event_cnt++; lpfc_unregister_remote_port(ndlp); } @@ -4340,10 +4350,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (new_state == NLP_STE_MAPPED_NODE || new_state == NLP_STE_UNMAPPED_NODE) { - if (ndlp->nlp_fc4_type || - ndlp->nlp_DID == Fabric_DID || - ndlp->nlp_DID == NameServer_DID || - ndlp->nlp_DID == FDMI_DID) { + if (lpfc_valid_xpt_node(ndlp)) { vport->phba->nport_event_cnt++; /* * Tell the fc transport about the port, if we haven't @@ -5611,6 +5618,9 @@ lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) } spin_unlock_irq(&phba->hbalock); + /* Make sure HBA is alive */ + lpfc_issue_hb_tmo(phba); + /* Cancel all the IOCBs from the completions list */ lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED); |