aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 8c99e89c7685..c6d7620b49a3 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -204,10 +204,13 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
spin_lock_irqsave(&ndlp->lock, iflags);
ndlp->nlp_flag |= NLP_IN_DEV_LOSS;
+ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+
/*
- * The backend does not expect any more calls assoicated with this
- * rport, Remove the association between rport and ndlp
+ * The backend does not expect any more calls associated with this
+ * rport. Remove the association between rport and ndlp.
*/
+ ndlp->fc4_xpt_flags &= ~SCSI_XPT_REGD;
((struct lpfc_rport_data *)rport->dd_data)->pnode = NULL;
ndlp->rport = NULL;
spin_unlock_irqrestore(&ndlp->lock, iflags);
@@ -248,7 +251,6 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
int warn_on = 0;
int fcf_inuse = 0;
unsigned long iflags;
- u32 fc4_xpt_flags;
vport = ndlp->vport;
shost = lpfc_shost_from_vport(vport);
@@ -267,10 +269,11 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
ndlp->nlp_DID, ndlp->nlp_type, ndlp->nlp_sid);
lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
- "3182 %s x%06x, nflag x%x xflags x%x\n",
+ "3182 %s x%06x, nflag x%x xflags x%x refcnt %d\n",
__func__, ndlp->nlp_DID, ndlp->nlp_flag,
- ndlp->fc4_xpt_flags);
+ ndlp->fc4_xpt_flags, kref_read(&ndlp->kref));
+ /* If the driver is recovering the rport, ignore devloss. */
if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0284 Devloss timeout Ignored on "
@@ -282,8 +285,11 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
return fcf_inuse;
}
- if (ndlp->nlp_type & NLP_FABRIC)
+ /* Fabric nodes are done. */
+ if (ndlp->nlp_type & NLP_FABRIC) {
+ lpfc_nlp_put(ndlp);
return fcf_inuse;
+ }
if (ndlp->nlp_sid != NLP_NO_SID) {
warn_on = 1;
@@ -311,12 +317,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
ndlp->nlp_state, ndlp->nlp_rpi);
}
- /* Should be final reference removal triggering a node free. */
- spin_lock_irqsave(shost->host_lock, iflags);
- fc4_xpt_flags = ndlp->fc4_xpt_flags;
- spin_unlock_irqrestore(shost->host_lock, iflags);
-
- if (!(fc4_xpt_flags & (NVME_XPT_REGD | SCSI_XPT_REGD)))
+ if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
return fcf_inuse;
@@ -3587,7 +3588,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
pmb->ctx_buf = NULL;
pmb->ctx_ndlp = NULL;
- lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI | LOG_NODE | LOG_DISCOVERY,
"0002 rpi:%x DID:%x flg:%x %d x%px\n",
ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
kref_read(&ndlp->kref),
@@ -4079,8 +4080,16 @@ out:
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
- /* If no other thread is using the ndlp, free it */
- lpfc_nlp_not_used(ndlp);
+ /* If the node is not registered with the scsi or nvme
+ * transport, remove the fabric node. The failed reg_login
+ * is terminal.
+ */
+ if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) {
+ spin_lock_irq(&ndlp->lock);
+ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+ spin_unlock_irq(&ndlp->lock);
+ lpfc_nlp_not_used(ndlp);
+ }
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
/*