aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-02-08 18:49:26 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-11 18:52:57 -0500
commite47c9093531d3406a8ae38acca4ce207ef70cc0e (patch)
treecb115ec0b7981a100ef39ecfc68a36aa7e3e0f2e /drivers/scsi/lpfc
parent4660c8ed5aaed99d82785499f034a8cc9199866d (diff)
[SCSI] lpfc 8.2.5 : Correct ndlp referencing issues
Correct ndlp referencing issues: - Fix ndlp kref issues due to race conditions between threads - Fix cancel els delay retry event which missed an ndlp reference count Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c39
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h33
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c237
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c296
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c41
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c39
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c70
11 files changed, 630 insertions, 142 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 83567b9755b4..572c525ad2b5 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -595,6 +595,8 @@ struct lpfc_hba {
595 unsigned long last_completion_time; 595 unsigned long last_completion_time;
596 struct timer_list hb_tmofunc; 596 struct timer_list hb_tmofunc;
597 uint8_t hb_outstanding; 597 uint8_t hb_outstanding;
598 /* ndlp reference management */
599 spinlock_t ndlp_lock;
598 /* 600 /*
599 * Following bit will be set for all buffer tags which are not 601 * Following bit will be set for all buffer tags which are not
600 * associated with any HBQ. 602 * associated with any HBQ.
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 4bae4a2ed2f1..ef061d97a222 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1191,7 +1191,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
1191 shost = lpfc_shost_from_vport(vport); 1191 shost = lpfc_shost_from_vport(vport);
1192 spin_lock_irq(shost->host_lock); 1192 spin_lock_irq(shost->host_lock);
1193 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) 1193 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
1194 if (ndlp->rport) 1194 if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport)
1195 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo; 1195 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
1196 spin_unlock_irq(shost->host_lock); 1196 spin_unlock_irq(shost->host_lock);
1197} 1197}
@@ -2384,7 +2384,8 @@ lpfc_get_node_by_target(struct scsi_target *starget)
2384 spin_lock_irq(shost->host_lock); 2384 spin_lock_irq(shost->host_lock);
2385 /* Search for this, mapped, target ID */ 2385 /* Search for this, mapped, target ID */
2386 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 2386 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
2387 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && 2387 if (NLP_CHK_NODE_ACT(ndlp) &&
2388 ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
2388 starget->id == ndlp->nlp_sid) { 2389 starget->id == ndlp->nlp_sid) {
2389 spin_unlock_irq(shost->host_lock); 2390 spin_unlock_irq(shost->host_lock);
2390 return ndlp; 2391 return ndlp;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 50fcb7c930bc..848d97744b4d 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -53,7 +53,11 @@ void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
53void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); 53void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
54void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); 54void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
55void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); 55void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
56void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *);
56void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); 57void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
58void lpfc_disable_node(struct lpfc_vport *, struct lpfc_nodelist *);
59struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *,
60 struct lpfc_nodelist *, int);
57void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); 61void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int);
58void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *); 62void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *);
59void lpfc_set_disctmo(struct lpfc_vport *); 63void lpfc_set_disctmo(struct lpfc_vport *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 92441ce610ed..aea8d33f6d09 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -294,7 +294,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
294 /* Save for completion so we can release these resources */ 294 /* Save for completion so we can release these resources */
295 geniocb->context1 = (uint8_t *) inp; 295 geniocb->context1 = (uint8_t *) inp;
296 geniocb->context2 = (uint8_t *) outp; 296 geniocb->context2 = (uint8_t *) outp;
297 geniocb->context_un.ndlp = ndlp; 297 geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
298 298
299 /* Fill in payload, bp points to frame payload */ 299 /* Fill in payload, bp points to frame payload */
300 icmd->ulpCommand = CMD_GEN_REQUEST64_CR; 300 icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
@@ -489,8 +489,10 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
489 */ 489 */
490 ndlp = lpfc_findnode_did(vport, 490 ndlp = lpfc_findnode_did(vport,
491 Did); 491 Did);
492 if (ndlp && (ndlp->nlp_type & 492 if (ndlp &&
493 NLP_FCP_TARGET)) 493 NLP_CHK_NODE_ACT(ndlp)
494 && (ndlp->nlp_type &
495 NLP_FCP_TARGET))
494 lpfc_setup_disc_node 496 lpfc_setup_disc_node
495 (vport, Did); 497 (vport, Did);
496 else if (lpfc_ns_cmd(vport, 498 else if (lpfc_ns_cmd(vport,
@@ -1064,7 +1066,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1064 int rc = 0; 1066 int rc = 0;
1065 1067
1066 ndlp = lpfc_findnode_did(vport, NameServer_DID); 1068 ndlp = lpfc_findnode_did(vport, NameServer_DID);
1067 if (ndlp == NULL || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) { 1069 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)
1070 || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {
1068 rc=1; 1071 rc=1;
1069 goto ns_cmd_exit; 1072 goto ns_cmd_exit;
1070 } 1073 }
@@ -1213,8 +1216,9 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1213 cmpl = lpfc_cmpl_ct_cmd_rff_id; 1216 cmpl = lpfc_cmpl_ct_cmd_rff_id;
1214 break; 1217 break;
1215 } 1218 }
1216 lpfc_nlp_get(ndlp); 1219 /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1217 1220 * to hold ndlp reference for the corresponding callback function.
1221 */
1218 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) { 1222 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
1219 /* On success, The cmpl function will free the buffers */ 1223 /* On success, The cmpl function will free the buffers */
1220 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, 1224 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
@@ -1222,9 +1226,13 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1222 cmdcode, ndlp->nlp_DID, 0); 1226 cmdcode, ndlp->nlp_DID, 0);
1223 return 0; 1227 return 0;
1224 } 1228 }
1225
1226 rc=6; 1229 rc=6;
1230
1231 /* Decrement ndlp reference count to release ndlp reference held
1232 * for the failed command's callback function.
1233 */
1227 lpfc_nlp_put(ndlp); 1234 lpfc_nlp_put(ndlp);
1235
1228 lpfc_mbuf_free(phba, bmp->virt, bmp->phys); 1236 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1229ns_cmd_free_bmp: 1237ns_cmd_free_bmp:
1230 kfree(bmp); 1238 kfree(bmp);
@@ -1271,6 +1279,9 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1271 } 1279 }
1272 1280
1273 ndlp = lpfc_findnode_did(vport, FDMI_DID); 1281 ndlp = lpfc_findnode_did(vport, FDMI_DID);
1282 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1283 goto fail_out;
1284
1274 if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { 1285 if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
1275 /* FDMI rsp failed */ 1286 /* FDMI rsp failed */
1276 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 1287 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
@@ -1294,6 +1305,8 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1294 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); 1305 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA);
1295 break; 1306 break;
1296 } 1307 }
1308
1309fail_out:
1297 lpfc_ct_free_iocb(phba, cmdiocb); 1310 lpfc_ct_free_iocb(phba, cmdiocb);
1298 return; 1311 return;
1299} 1312}
@@ -1650,12 +1663,18 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
1650 bpl->tus.w = le32_to_cpu(bpl->tus.w); 1663 bpl->tus.w = le32_to_cpu(bpl->tus.w);
1651 1664
1652 cmpl = lpfc_cmpl_ct_cmd_fdmi; 1665 cmpl = lpfc_cmpl_ct_cmd_fdmi;
1653 lpfc_nlp_get(ndlp);
1654 1666
1667 /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1668 * to hold ndlp reference for the corresponding callback function.
1669 */
1655 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0)) 1670 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0))
1656 return 0; 1671 return 0;
1657 1672
1673 /* Decrement ndlp reference count to release ndlp reference held
1674 * for the failed command's callback function.
1675 */
1658 lpfc_nlp_put(ndlp); 1676 lpfc_nlp_put(ndlp);
1677
1659 lpfc_mbuf_free(phba, bmp->virt, bmp->phys); 1678 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1660fdmi_cmd_free_bmp: 1679fdmi_cmd_free_bmp:
1661 kfree(bmp); 1680 kfree(bmp);
@@ -1698,7 +1717,7 @@ lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
1698 struct lpfc_nodelist *ndlp; 1717 struct lpfc_nodelist *ndlp;
1699 1718
1700 ndlp = lpfc_findnode_did(vport, FDMI_DID); 1719 ndlp = lpfc_findnode_did(vport, FDMI_DID);
1701 if (ndlp) { 1720 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
1702 if (init_utsname()->nodename[0] != '\0') 1721 if (init_utsname()->nodename[0] != '\0')
1703 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); 1722 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
1704 else 1723 else
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index cfe81c50529a..8eb007309599 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -73,6 +73,12 @@ struct lpfc_nodelist {
73 uint8_t nlp_fcp_info; /* class info, bits 0-3 */ 73 uint8_t nlp_fcp_info; /* class info, bits 0-3 */
74#define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ 74#define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */
75 75
76 uint16_t nlp_usg_map; /* ndlp management usage bitmap */
77#define NLP_USG_NODE_ACT_BIT 0x1 /* Indicate ndlp is actively used */
78#define NLP_USG_IACT_REQ_BIT 0x2 /* Request to inactivate ndlp */
79#define NLP_USG_FREE_REQ_BIT 0x4 /* Request to invoke ndlp memory free */
80#define NLP_USG_FREE_ACK_BIT 0x8 /* Indicate ndlp memory free invoked */
81
76 struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */ 82 struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */
77 struct fc_rport *rport; /* Corresponding FC transport 83 struct fc_rport *rport; /* Corresponding FC transport
78 port structure */ 84 port structure */
@@ -105,6 +111,31 @@ struct lpfc_nodelist {
105#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ 111#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */
106#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */ 112#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */
107 113
114/* ndlp usage management macros */
115#define NLP_CHK_NODE_ACT(ndlp) (((ndlp)->nlp_usg_map \
116 & NLP_USG_NODE_ACT_BIT) \
117 && \
118 !((ndlp)->nlp_usg_map \
119 & NLP_USG_FREE_ACK_BIT))
120#define NLP_SET_NODE_ACT(ndlp) ((ndlp)->nlp_usg_map \
121 |= NLP_USG_NODE_ACT_BIT)
122#define NLP_INT_NODE_ACT(ndlp) ((ndlp)->nlp_usg_map \
123 = NLP_USG_NODE_ACT_BIT)
124#define NLP_CLR_NODE_ACT(ndlp) ((ndlp)->nlp_usg_map \
125 &= ~NLP_USG_NODE_ACT_BIT)
126#define NLP_CHK_IACT_REQ(ndlp) ((ndlp)->nlp_usg_map \
127 & NLP_USG_IACT_REQ_BIT)
128#define NLP_SET_IACT_REQ(ndlp) ((ndlp)->nlp_usg_map \
129 |= NLP_USG_IACT_REQ_BIT)
130#define NLP_CHK_FREE_REQ(ndlp) ((ndlp)->nlp_usg_map \
131 & NLP_USG_FREE_REQ_BIT)
132#define NLP_SET_FREE_REQ(ndlp) ((ndlp)->nlp_usg_map \
133 |= NLP_USG_FREE_REQ_BIT)
134#define NLP_CHK_FREE_ACK(ndlp) ((ndlp)->nlp_usg_map \
135 & NLP_USG_FREE_ACK_BIT)
136#define NLP_SET_FREE_ACK(ndlp) ((ndlp)->nlp_usg_map \
137 |= NLP_USG_FREE_ACK_BIT)
138
108/* There are 4 different double linked lists nodelist entries can reside on. 139/* There are 4 different double linked lists nodelist entries can reside on.
109 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used 140 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
110 * when Link Up discovery or Registered State Change Notification (RSCN) 141 * when Link Up discovery or Registered State Change Notification (RSCN)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index c6b739dc6bc3..39268e6a1a05 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -113,6 +113,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
113 113
114 if (elsiocb == NULL) 114 if (elsiocb == NULL)
115 return NULL; 115 return NULL;
116
116 icmd = &elsiocb->iocb; 117 icmd = &elsiocb->iocb;
117 118
118 /* fill in BDEs for command */ 119 /* fill in BDEs for command */
@@ -134,9 +135,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
134 if (!prsp || !prsp->virt) 135 if (!prsp || !prsp->virt)
135 goto els_iocb_free_prsp_exit; 136 goto els_iocb_free_prsp_exit;
136 INIT_LIST_HEAD(&prsp->list); 137 INIT_LIST_HEAD(&prsp->list);
137 } else { 138 } else
138 prsp = NULL; 139 prsp = NULL;
139 }
140 140
141 /* Allocate buffer for Buffer ptr list */ 141 /* Allocate buffer for Buffer ptr list */
142 pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 142 pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
@@ -246,7 +246,7 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
246 246
247 sp = &phba->fc_fabparam; 247 sp = &phba->fc_fabparam;
248 ndlp = lpfc_findnode_did(vport, Fabric_DID); 248 ndlp = lpfc_findnode_did(vport, Fabric_DID);
249 if (!ndlp) { 249 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
250 err = 1; 250 err = 1;
251 goto fail; 251 goto fail;
252 } 252 }
@@ -282,6 +282,9 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
282 282
283 mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; 283 mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
284 mbox->vport = vport; 284 mbox->vport = vport;
285 /* increment the reference count on ndlp to hold reference
286 * for the callback routine.
287 */
285 mbox->context2 = lpfc_nlp_get(ndlp); 288 mbox->context2 = lpfc_nlp_get(ndlp);
286 289
287 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); 290 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
@@ -293,6 +296,9 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
293 return 0; 296 return 0;
294 297
295fail_issue_reg_login: 298fail_issue_reg_login:
299 /* decrement the reference count on ndlp just incremented
300 * for the failed mbox command.
301 */
296 lpfc_nlp_put(ndlp); 302 lpfc_nlp_put(ndlp);
297 mp = (struct lpfc_dmabuf *) mbox->context1; 303 mp = (struct lpfc_dmabuf *) mbox->context1;
298 lpfc_mbuf_free(phba, mp->virt, mp->phys); 304 lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -381,6 +387,8 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
381 */ 387 */
382 list_for_each_entry_safe(np, next_np, 388 list_for_each_entry_safe(np, next_np,
383 &vport->fc_nodes, nlp_listp) { 389 &vport->fc_nodes, nlp_listp) {
390 if (!NLP_CHK_NODE_ACT(ndlp))
391 continue;
384 if ((np->nlp_state != NLP_STE_NPR_NODE) || 392 if ((np->nlp_state != NLP_STE_NPR_NODE) ||
385 !(np->nlp_flag & NLP_NPR_ADISC)) 393 !(np->nlp_flag & NLP_NPR_ADISC))
386 continue; 394 continue;
@@ -456,6 +464,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
456 mempool_free(mbox, phba->mbox_mem_pool); 464 mempool_free(mbox, phba->mbox_mem_pool);
457 goto fail; 465 goto fail;
458 } 466 }
467 /* Decrement ndlp reference count indicating that ndlp can be
468 * safely released when other references to it are done.
469 */
459 lpfc_nlp_put(ndlp); 470 lpfc_nlp_put(ndlp);
460 471
461 ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID); 472 ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
@@ -467,22 +478,29 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
467 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); 478 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
468 if (!ndlp) 479 if (!ndlp)
469 goto fail; 480 goto fail;
470
471 lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID); 481 lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
482 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
483 ndlp = lpfc_enable_node(vport, ndlp,
484 NLP_STE_UNUSED_NODE);
485 if(!ndlp)
486 goto fail;
472 } 487 }
473 488
474 memcpy(&ndlp->nlp_portname, &sp->portName, 489 memcpy(&ndlp->nlp_portname, &sp->portName,
475 sizeof(struct lpfc_name)); 490 sizeof(struct lpfc_name));
476 memcpy(&ndlp->nlp_nodename, &sp->nodeName, 491 memcpy(&ndlp->nlp_nodename, &sp->nodeName,
477 sizeof(struct lpfc_name)); 492 sizeof(struct lpfc_name));
493 /* Set state will put ndlp onto node list if not already done */
478 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 494 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
479 spin_lock_irq(shost->host_lock); 495 spin_lock_irq(shost->host_lock);
480 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 496 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
481 spin_unlock_irq(shost->host_lock); 497 spin_unlock_irq(shost->host_lock);
482 } else { 498 } else
483 /* This side will wait for the PLOGI */ 499 /* This side will wait for the PLOGI, decrement ndlp reference
500 * count indicating that ndlp can be released when other
501 * references to it are done.
502 */
484 lpfc_nlp_put(ndlp); 503 lpfc_nlp_put(ndlp);
485 }
486 504
487 /* If we are pt2pt with another NPort, force NPIV off! */ 505 /* If we are pt2pt with another NPort, force NPIV off! */
488 phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; 506 phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
@@ -728,16 +746,21 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
728 if (!ndlp) 746 if (!ndlp)
729 return 0; 747 return 0;
730 lpfc_nlp_init(vport, ndlp, Fabric_DID); 748 lpfc_nlp_init(vport, ndlp, Fabric_DID);
731 } else { 749 /* Put ndlp onto node list */
732 lpfc_dequeue_node(vport, ndlp); 750 lpfc_enqueue_node(vport, ndlp);
751 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
752 /* re-setup ndlp without removing from node list */
753 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
754 if (!ndlp)
755 return 0;
733 } 756 }
734 757
735 if (lpfc_issue_els_flogi(vport, ndlp, 0)) { 758 if (lpfc_issue_els_flogi(vport, ndlp, 0))
736 /* This decrement of reference count to node shall kick off 759 /* This decrement of reference count to node shall kick off
737 * the release of the node. 760 * the release of the node.
738 */ 761 */
739 lpfc_nlp_put(ndlp); 762 lpfc_nlp_put(ndlp);
740 } 763
741 return 1; 764 return 1;
742} 765}
743 766
@@ -755,9 +778,15 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
755 if (!ndlp) 778 if (!ndlp)
756 return 0; 779 return 0;
757 lpfc_nlp_init(vport, ndlp, Fabric_DID); 780 lpfc_nlp_init(vport, ndlp, Fabric_DID);
758 } else { 781 /* Put ndlp onto node list */
759 lpfc_dequeue_node(vport, ndlp); 782 lpfc_enqueue_node(vport, ndlp);
783 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
784 /* re-setup ndlp without removing from node list */
785 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
786 if (!ndlp)
787 return 0;
760 } 788 }
789
761 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { 790 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
762 /* decrement node reference count to trigger the release of 791 /* decrement node reference count to trigger the release of
763 * the node. 792 * the node.
@@ -816,7 +845,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
816 */ 845 */
817 new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName); 846 new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
818 847
819 if (new_ndlp == ndlp) 848 if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
820 return ndlp; 849 return ndlp;
821 850
822 if (!new_ndlp) { 851 if (!new_ndlp) {
@@ -827,8 +856,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
827 new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); 856 new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
828 if (!new_ndlp) 857 if (!new_ndlp)
829 return ndlp; 858 return ndlp;
830
831 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); 859 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
860 } else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
861 new_ndlp = lpfc_enable_node(vport, new_ndlp,
862 NLP_STE_UNUSED_NODE);
863 if (!new_ndlp)
864 return ndlp;
832 } 865 }
833 866
834 lpfc_unreg_rpi(vport, new_ndlp); 867 lpfc_unreg_rpi(vport, new_ndlp);
@@ -839,6 +872,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
839 new_ndlp->nlp_flag |= NLP_NPR_2B_DISC; 872 new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
840 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; 873 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
841 874
875 /* Set state will put new_ndlp on to node list if not already done */
842 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); 876 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
843 877
844 /* Move this back to NPR state */ 878 /* Move this back to NPR state */
@@ -912,7 +946,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
912 irsp->un.elsreq64.remoteID); 946 irsp->un.elsreq64.remoteID);
913 947
914 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); 948 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
915 if (!ndlp) { 949 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
916 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 950 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
917 "0136 PLOGI completes to NPort x%x " 951 "0136 PLOGI completes to NPort x%x "
918 "with no ndlp. Data: x%x x%x x%x\n", 952 "with no ndlp. Data: x%x x%x x%x\n",
@@ -962,12 +996,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
962 } 996 }
963 /* PLOGI failed */ 997 /* PLOGI failed */
964 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 998 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
965 if (lpfc_error_lost_link(irsp)) { 999 if (lpfc_error_lost_link(irsp))
966 rc = NLP_STE_FREED_NODE; 1000 rc = NLP_STE_FREED_NODE;
967 } else { 1001 else
968 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1002 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
969 NLP_EVT_CMPL_PLOGI); 1003 NLP_EVT_CMPL_PLOGI);
970 }
971 } else { 1004 } else {
972 /* Good status, call state machine */ 1005 /* Good status, call state machine */
973 prsp = list_entry(((struct lpfc_dmabuf *) 1006 prsp = list_entry(((struct lpfc_dmabuf *)
@@ -1015,8 +1048,10 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
1015 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ 1048 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1016 1049
1017 ndlp = lpfc_findnode_did(vport, did); 1050 ndlp = lpfc_findnode_did(vport, did);
1018 /* If ndlp if not NULL, we will bump the reference count on it */ 1051 if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
1052 ndlp = NULL;
1019 1053
1054 /* If ndlp is not NULL, we will bump the reference count on it */
1020 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); 1055 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
1021 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, 1056 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
1022 ELS_CMD_PLOGI); 1057 ELS_CMD_PLOGI);
@@ -1097,18 +1132,15 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1097 } 1132 }
1098 /* PRLI failed */ 1133 /* PRLI failed */
1099 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1134 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1100 if (lpfc_error_lost_link(irsp)) { 1135 if (lpfc_error_lost_link(irsp))
1101 goto out; 1136 goto out;
1102 } else { 1137 else
1103 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1138 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1104 NLP_EVT_CMPL_PRLI); 1139 NLP_EVT_CMPL_PRLI);
1105 } 1140 } else
1106 } else {
1107 /* Good status, call state machine */ 1141 /* Good status, call state machine */
1108 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1142 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1109 NLP_EVT_CMPL_PRLI); 1143 NLP_EVT_CMPL_PRLI);
1110 }
1111
1112out: 1144out:
1113 lpfc_els_free_iocb(phba, cmdiocb); 1145 lpfc_els_free_iocb(phba, cmdiocb);
1114 return; 1146 return;
@@ -1275,15 +1307,13 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1275 } 1307 }
1276 /* ADISC failed */ 1308 /* ADISC failed */
1277 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1309 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1278 if (!lpfc_error_lost_link(irsp)) { 1310 if (!lpfc_error_lost_link(irsp))
1279 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1311 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1280 NLP_EVT_CMPL_ADISC); 1312 NLP_EVT_CMPL_ADISC);
1281 } 1313 } else
1282 } else {
1283 /* Good status, call state machine */ 1314 /* Good status, call state machine */
1284 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1315 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1285 NLP_EVT_CMPL_ADISC); 1316 NLP_EVT_CMPL_ADISC);
1286 }
1287 1317
1288 if (disc && vport->num_disc_nodes) { 1318 if (disc && vport->num_disc_nodes) {
1289 /* Check to see if there are more ADISCs to be sent */ 1319 /* Check to see if there are more ADISCs to be sent */
@@ -1443,14 +1473,12 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1443 else 1473 else
1444 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1474 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1445 NLP_EVT_CMPL_LOGO); 1475 NLP_EVT_CMPL_LOGO);
1446 } else { 1476 } else
1447 /* Good status, call state machine. 1477 /* Good status, call state machine.
1448 * This will unregister the rpi if needed. 1478 * This will unregister the rpi if needed.
1449 */ 1479 */
1450 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1480 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1451 NLP_EVT_CMPL_LOGO); 1481 NLP_EVT_CMPL_LOGO);
1452 }
1453
1454out: 1482out:
1455 lpfc_els_free_iocb(phba, cmdiocb); 1483 lpfc_els_free_iocb(phba, cmdiocb);
1456 return; 1484 return;
@@ -1556,11 +1584,19 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1556 psli = &phba->sli; 1584 psli = &phba->sli;
1557 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ 1585 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1558 cmdsize = (sizeof(uint32_t) + sizeof(SCR)); 1586 cmdsize = (sizeof(uint32_t) + sizeof(SCR));
1559 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1560 if (!ndlp)
1561 return 1;
1562 1587
1563 lpfc_nlp_init(vport, ndlp, nportid); 1588 ndlp = lpfc_findnode_did(vport, nportid);
1589 if (!ndlp) {
1590 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1591 if (!ndlp)
1592 return 1;
1593 lpfc_nlp_init(vport, ndlp, nportid);
1594 lpfc_enqueue_node(vport, ndlp);
1595 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
1596 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
1597 if (!ndlp)
1598 return 1;
1599 }
1564 1600
1565 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, 1601 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1566 ndlp->nlp_DID, ELS_CMD_SCR); 1602 ndlp->nlp_DID, ELS_CMD_SCR);
@@ -1623,11 +1659,19 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1623 psli = &phba->sli; 1659 psli = &phba->sli;
1624 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ 1660 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1625 cmdsize = (sizeof(uint32_t) + sizeof(FARP)); 1661 cmdsize = (sizeof(uint32_t) + sizeof(FARP));
1626 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1627 if (!ndlp)
1628 return 1;
1629 1662
1630 lpfc_nlp_init(vport, ndlp, nportid); 1663 ndlp = lpfc_findnode_did(vport, nportid);
1664 if (!ndlp) {
1665 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1666 if (!ndlp)
1667 return 1;
1668 lpfc_nlp_init(vport, ndlp, nportid);
1669 lpfc_enqueue_node(vport, ndlp);
1670 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
1671 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
1672 if (!ndlp)
1673 return 1;
1674 }
1631 1675
1632 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, 1676 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1633 ndlp->nlp_DID, ELS_CMD_RNID); 1677 ndlp->nlp_DID, ELS_CMD_RNID);
@@ -1657,7 +1701,7 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1657 memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name)); 1701 memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name));
1658 memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); 1702 memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
1659 ondlp = lpfc_findnode_did(vport, nportid); 1703 ondlp = lpfc_findnode_did(vport, nportid);
1660 if (ondlp) { 1704 if (ondlp && NLP_CHK_NODE_ACT(ondlp)) {
1661 memcpy(&fp->OportName, &ondlp->nlp_portname, 1705 memcpy(&fp->OportName, &ondlp->nlp_portname,
1662 sizeof(struct lpfc_name)); 1706 sizeof(struct lpfc_name));
1663 memcpy(&fp->OnodeName, &ondlp->nlp_nodename, 1707 memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
@@ -1690,6 +1734,7 @@ void
1690lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) 1734lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
1691{ 1735{
1692 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1736 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1737 struct lpfc_work_evt *evtp;
1693 1738
1694 spin_lock_irq(shost->host_lock); 1739 spin_lock_irq(shost->host_lock);
1695 nlp->nlp_flag &= ~NLP_DELAY_TMO; 1740 nlp->nlp_flag &= ~NLP_DELAY_TMO;
@@ -1697,8 +1742,12 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
1697 del_timer_sync(&nlp->nlp_delayfunc); 1742 del_timer_sync(&nlp->nlp_delayfunc);
1698 nlp->nlp_last_elscmd = 0; 1743 nlp->nlp_last_elscmd = 0;
1699 1744
1700 if (!list_empty(&nlp->els_retry_evt.evt_listp)) 1745 if (!list_empty(&nlp->els_retry_evt.evt_listp)) {
1701 list_del_init(&nlp->els_retry_evt.evt_listp); 1746 list_del_init(&nlp->els_retry_evt.evt_listp);
1747 /* Decrement nlp reference count held for the delayed retry */
1748 evtp = &nlp->els_retry_evt;
1749 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
1750 }
1702 1751
1703 if (nlp->nlp_flag & NLP_NPR_2B_DISC) { 1752 if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
1704 spin_lock_irq(shost->host_lock); 1753 spin_lock_irq(shost->host_lock);
@@ -1842,13 +1891,14 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1842 cmd = *elscmd++; 1891 cmd = *elscmd++;
1843 } 1892 }
1844 1893
1845 if (ndlp) 1894 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
1846 did = ndlp->nlp_DID; 1895 did = ndlp->nlp_DID;
1847 else { 1896 else {
1848 /* We should only hit this case for retrying PLOGI */ 1897 /* We should only hit this case for retrying PLOGI */
1849 did = irsp->un.elsreq64.remoteID; 1898 did = irsp->un.elsreq64.remoteID;
1850 ndlp = lpfc_findnode_did(vport, did); 1899 ndlp = lpfc_findnode_did(vport, did);
1851 if (!ndlp && (cmd != ELS_CMD_PLOGI)) 1900 if ((!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1901 && (cmd != ELS_CMD_PLOGI))
1852 return 1; 1902 return 1;
1853 } 1903 }
1854 1904
@@ -2322,6 +2372,9 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2322 if ((rspiocb->iocb.ulpStatus == 0) 2372 if ((rspiocb->iocb.ulpStatus == 0)
2323 && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { 2373 && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
2324 lpfc_unreg_rpi(vport, ndlp); 2374 lpfc_unreg_rpi(vport, ndlp);
2375 /* Increment reference count to ndlp to hold the
2376 * reference to ndlp for the callback function.
2377 */
2325 mbox->context2 = lpfc_nlp_get(ndlp); 2378 mbox->context2 = lpfc_nlp_get(ndlp);
2326 mbox->vport = vport; 2379 mbox->vport = vport;
2327 if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) { 2380 if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
@@ -2335,9 +2388,13 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2335 NLP_STE_REG_LOGIN_ISSUE); 2388 NLP_STE_REG_LOGIN_ISSUE);
2336 } 2389 }
2337 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) 2390 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
2338 != MBX_NOT_FINISHED) { 2391 != MBX_NOT_FINISHED)
2339 goto out; 2392 goto out;
2340 } 2393 else
2394 /* Decrement the ndlp reference count we
2395 * set for this failed mailbox command.
2396 */
2397 lpfc_nlp_put(ndlp);
2341 2398
2342 /* ELS rsp: Cannot issue reg_login for <NPortid> */ 2399 /* ELS rsp: Cannot issue reg_login for <NPortid> */
2343 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 2400 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -2796,6 +2853,8 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport)
2796 2853
2797 /* go thru NPR nodes and issue any remaining ELS ADISCs */ 2854 /* go thru NPR nodes and issue any remaining ELS ADISCs */
2798 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 2855 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
2856 if (!NLP_CHK_NODE_ACT(ndlp))
2857 continue;
2799 if (ndlp->nlp_state == NLP_STE_NPR_NODE && 2858 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2800 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && 2859 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2801 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { 2860 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
@@ -2833,6 +2892,8 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport)
2833 2892
2834 /* go thru NPR nodes and issue any remaining ELS PLOGIs */ 2893 /* go thru NPR nodes and issue any remaining ELS PLOGIs */
2835 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 2894 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
2895 if (!NLP_CHK_NODE_ACT(ndlp))
2896 continue;
2836 if (ndlp->nlp_state == NLP_STE_NPR_NODE && 2897 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2837 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && 2898 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2838 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && 2899 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
@@ -2943,7 +3004,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
2943 */ 3004 */
2944 3005
2945 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 3006 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
2946 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE || 3007 if (!NLP_CHK_NODE_ACT(ndlp) ||
3008 ndlp->nlp_state == NLP_STE_UNUSED_NODE ||
2947 lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0) 3009 lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0)
2948 continue; 3010 continue;
2949 3011
@@ -3145,7 +3207,8 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
3145 vport->num_disc_nodes = 0; 3207 vport->num_disc_nodes = 0;
3146 3208
3147 ndlp = lpfc_findnode_did(vport, NameServer_DID); 3209 ndlp = lpfc_findnode_did(vport, NameServer_DID);
3148 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { 3210 if (ndlp && NLP_CHK_NODE_ACT(ndlp)
3211 && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
3149 /* Good ndlp, issue CT Request to NameServer */ 3212 /* Good ndlp, issue CT Request to NameServer */
3150 if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0) 3213 if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0)
3151 /* Wait for NameServer query cmpl before we can 3214 /* Wait for NameServer query cmpl before we can
@@ -3155,25 +3218,35 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
3155 /* If login to NameServer does not exist, issue one */ 3218 /* If login to NameServer does not exist, issue one */
3156 /* Good status, issue PLOGI to NameServer */ 3219 /* Good status, issue PLOGI to NameServer */
3157 ndlp = lpfc_findnode_did(vport, NameServer_DID); 3220 ndlp = lpfc_findnode_did(vport, NameServer_DID);
3158 if (ndlp) 3221 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
3159 /* Wait for NameServer login cmpl before we can 3222 /* Wait for NameServer login cmpl before we can
3160 continue */ 3223 continue */
3161 return 1; 3224 return 1;
3162 3225
3163 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); 3226 if (ndlp) {
3164 if (!ndlp) { 3227 ndlp = lpfc_enable_node(vport, ndlp,
3165 lpfc_els_flush_rscn(vport); 3228 NLP_STE_PLOGI_ISSUE);
3166 return 0; 3229 if (!ndlp) {
3230 lpfc_els_flush_rscn(vport);
3231 return 0;
3232 }
3233 ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
3167 } else { 3234 } else {
3235 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
3236 if (!ndlp) {
3237 lpfc_els_flush_rscn(vport);
3238 return 0;
3239 }
3168 lpfc_nlp_init(vport, ndlp, NameServer_DID); 3240 lpfc_nlp_init(vport, ndlp, NameServer_DID);
3169 ndlp->nlp_type |= NLP_FABRIC;
3170 ndlp->nlp_prev_state = ndlp->nlp_state; 3241 ndlp->nlp_prev_state = ndlp->nlp_state;
3171 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); 3242 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
3172 lpfc_issue_els_plogi(vport, NameServer_DID, 0);
3173 /* Wait for NameServer login cmpl before we can
3174 continue */
3175 return 1;
3176 } 3243 }
3244 ndlp->nlp_type |= NLP_FABRIC;
3245 lpfc_issue_els_plogi(vport, NameServer_DID, 0);
3246 /* Wait for NameServer login cmpl before we can
3247 * continue
3248 */
3249 return 1;
3177 } 3250 }
3178 3251
3179 lpfc_els_flush_rscn(vport); 3252 lpfc_els_flush_rscn(vport);
@@ -3672,6 +3745,8 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3672 3745
3673 list_for_each_entry_safe(ndlp, next_ndlp, 3746 list_for_each_entry_safe(ndlp, next_ndlp,
3674 &vport->fc_nodes, nlp_listp) { 3747 &vport->fc_nodes, nlp_listp) {
3748 if (!NLP_CHK_NODE_ACT(ndlp))
3749 continue;
3675 if (ndlp->nlp_state != NLP_STE_NPR_NODE) 3750 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3676 continue; 3751 continue;
3677 if (ndlp->nlp_type & NLP_FABRIC) { 3752 if (ndlp->nlp_type & NLP_FABRIC) {
@@ -3697,6 +3772,8 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3697 */ 3772 */
3698 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, 3773 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
3699 nlp_listp) { 3774 nlp_listp) {
3775 if (!NLP_CHK_NODE_ACT(ndlp))
3776 continue;
3700 if (ndlp->nlp_state != NLP_STE_NPR_NODE) 3777 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3701 continue; 3778 continue;
3702 3779
@@ -3936,7 +4013,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3936 uint32_t cmd, did, newnode, rjt_err = 0; 4013 uint32_t cmd, did, newnode, rjt_err = 0;
3937 IOCB_t *icmd = &elsiocb->iocb; 4014 IOCB_t *icmd = &elsiocb->iocb;
3938 4015
3939 if (vport == NULL || elsiocb->context2 == NULL) 4016 if (!vport || !(elsiocb->context2))
3940 goto dropit; 4017 goto dropit;
3941 4018
3942 newnode = 0; 4019 newnode = 0;
@@ -3971,14 +4048,20 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3971 lpfc_nlp_init(vport, ndlp, did); 4048 lpfc_nlp_init(vport, ndlp, did);
3972 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 4049 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
3973 newnode = 1; 4050 newnode = 1;
3974 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { 4051 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
3975 ndlp->nlp_type |= NLP_FABRIC; 4052 ndlp->nlp_type |= NLP_FABRIC;
4053 } else {
4054 if (!NLP_CHK_NODE_ACT(ndlp)) {
4055 ndlp = lpfc_enable_node(vport, ndlp,
4056 NLP_STE_UNUSED_NODE);
4057 if (!ndlp)
4058 goto dropit;
3976 } 4059 }
3977 }
3978 else {
3979 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { 4060 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
3980 /* This is simular to the new node path */ 4061 /* This is simular to the new node path */
3981 lpfc_nlp_get(ndlp); 4062 ndlp = lpfc_nlp_get(ndlp);
4063 if (!ndlp)
4064 goto dropit;
3982 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 4065 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
3983 newnode = 1; 4066 newnode = 1;
3984 } 4067 }
@@ -3987,6 +4070,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3987 phba->fc_stat.elsRcvFrame++; 4070 phba->fc_stat.elsRcvFrame++;
3988 if (elsiocb->context1) 4071 if (elsiocb->context1)
3989 lpfc_nlp_put(elsiocb->context1); 4072 lpfc_nlp_put(elsiocb->context1);
4073
3990 elsiocb->context1 = lpfc_nlp_get(ndlp); 4074 elsiocb->context1 = lpfc_nlp_get(ndlp);
3991 elsiocb->vport = vport; 4075 elsiocb->vport = vport;
3992 4076
@@ -4314,6 +4398,18 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
4314 } 4398 }
4315 lpfc_nlp_init(vport, ndlp, NameServer_DID); 4399 lpfc_nlp_init(vport, ndlp, NameServer_DID);
4316 ndlp->nlp_type |= NLP_FABRIC; 4400 ndlp->nlp_type |= NLP_FABRIC;
4401 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
4402 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
4403 if (!ndlp) {
4404 if (phba->fc_topology == TOPOLOGY_LOOP) {
4405 lpfc_disc_start(vport);
4406 return;
4407 }
4408 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4409 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
4410 "0348 NameServer login: node freed\n");
4411 return;
4412 }
4317 } 4413 }
4318 4414
4319 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); 4415 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
@@ -4471,7 +4567,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4471 irsp->ulpStatus, irsp->un.ulpWord[4]); 4567 irsp->ulpStatus, irsp->un.ulpWord[4]);
4472 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) 4568 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
4473 lpfc_vport_set_state(vport, FC_VPORT_FAILED); 4569 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4474
4475 lpfc_nlp_put(ndlp); 4570 lpfc_nlp_put(ndlp);
4476 /* giving up on FDISC. Cancel discovery timer */ 4571 /* giving up on FDISC. Cancel discovery timer */
4477 lpfc_can_disctmo(vport); 4572 lpfc_can_disctmo(vport);
@@ -4492,8 +4587,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4492 */ 4587 */
4493 list_for_each_entry_safe(np, next_np, 4588 list_for_each_entry_safe(np, next_np,
4494 &vport->fc_nodes, nlp_listp) { 4589 &vport->fc_nodes, nlp_listp) {
4495 if (np->nlp_state != NLP_STE_NPR_NODE 4590 if (!NLP_CHK_NODE_ACT(ndlp) ||
4496 || !(np->nlp_flag & NLP_NPR_ADISC)) 4591 (np->nlp_state != NLP_STE_NPR_NODE) ||
4592 !(np->nlp_flag & NLP_NPR_ADISC))
4497 continue; 4593 continue;
4498 spin_lock_irq(shost->host_lock); 4594 spin_lock_irq(shost->host_lock);
4499 np->nlp_flag &= ~NLP_NPR_ADISC; 4595 np->nlp_flag &= ~NLP_NPR_ADISC;
@@ -4599,6 +4695,8 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4599{ 4695{
4600 struct lpfc_vport *vport = cmdiocb->vport; 4696 struct lpfc_vport *vport = cmdiocb->vport;
4601 IOCB_t *irsp; 4697 IOCB_t *irsp;
4698 struct lpfc_nodelist *ndlp;
4699 ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
4602 4700
4603 irsp = &rspiocb->iocb; 4701 irsp = &rspiocb->iocb;
4604 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, 4702 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
@@ -4607,6 +4705,9 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4607 4705
4608 lpfc_els_free_iocb(phba, cmdiocb); 4706 lpfc_els_free_iocb(phba, cmdiocb);
4609 vport->unreg_vpi_cmpl = VPORT_ERROR; 4707 vport->unreg_vpi_cmpl = VPORT_ERROR;
4708
4709 /* Trigger the release of the ndlp after logo */
4710 lpfc_nlp_put(ndlp);
4610} 4711}
4611 4712
4612int 4713int
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index dc042bd97baa..1ee3e62c78a7 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -272,9 +272,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
272 if (!(vport->load_flag & FC_UNLOADING) && 272 if (!(vport->load_flag & FC_UNLOADING) &&
273 !(ndlp->nlp_flag & NLP_DELAY_TMO) && 273 !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
274 !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && 274 !(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
275 (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) { 275 (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE))
276 lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); 276 lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
277 }
278} 277}
279 278
280 279
@@ -566,9 +565,10 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
566 int rc; 565 int rc;
567 566
568 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 567 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
568 if (!NLP_CHK_NODE_ACT(ndlp))
569 continue;
569 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 570 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
570 continue; 571 continue;
571
572 if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) || 572 if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) ||
573 ((vport->port_type == LPFC_NPIV_PORT) && 573 ((vport->port_type == LPFC_NPIV_PORT) &&
574 (ndlp->nlp_DID == NameServer_DID))) 574 (ndlp->nlp_DID == NameServer_DID)))
@@ -684,20 +684,21 @@ lpfc_linkup_cleanup_nodes(struct lpfc_vport *vport)
684 struct lpfc_nodelist *ndlp; 684 struct lpfc_nodelist *ndlp;
685 685
686 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 686 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
687 if (!NLP_CHK_NODE_ACT(ndlp))
688 continue;
687 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 689 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
688 continue; 690 continue;
689
690 if (ndlp->nlp_type & NLP_FABRIC) { 691 if (ndlp->nlp_type & NLP_FABRIC) {
691 /* On Linkup its safe to clean up the ndlp 692 /* On Linkup its safe to clean up the ndlp
692 * from Fabric connections. 693 * from Fabric connections.
693 */ 694 */
694 if (ndlp->nlp_DID != Fabric_DID) 695 if (ndlp->nlp_DID != Fabric_DID)
695 lpfc_unreg_rpi(vport, ndlp); 696 lpfc_unreg_rpi(vport, ndlp);
696 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 697 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
697 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 698 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
698 /* Fail outstanding IO now since device is 699 /* Fail outstanding IO now since device is
699 * marked for PLOGI. 700 * marked for PLOGI.
700 */ 701 */
701 lpfc_unreg_rpi(vport, ndlp); 702 lpfc_unreg_rpi(vport, ndlp);
702 } 703 }
703 } 704 }
@@ -1305,7 +1306,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1305 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1306 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1306 kfree(mp); 1307 kfree(mp);
1307 mempool_free(pmb, phba->mbox_mem_pool); 1308 mempool_free(pmb, phba->mbox_mem_pool);
1308 lpfc_nlp_put(ndlp);
1309 1309
1310 if (phba->fc_topology == TOPOLOGY_LOOP) { 1310 if (phba->fc_topology == TOPOLOGY_LOOP) {
1311 /* FLOGI failed, use loop map to make discovery list */ 1311 /* FLOGI failed, use loop map to make discovery list */
@@ -1313,6 +1313,10 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1313 1313
1314 /* Start discovery */ 1314 /* Start discovery */
1315 lpfc_disc_start(vport); 1315 lpfc_disc_start(vport);
1316 /* Decrement the reference count to ndlp after the
1317 * reference to the ndlp are done.
1318 */
1319 lpfc_nlp_put(ndlp);
1316 return; 1320 return;
1317 } 1321 }
1318 1322
@@ -1320,6 +1324,10 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1320 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, 1324 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
1321 "0258 Register Fabric login error: 0x%x\n", 1325 "0258 Register Fabric login error: 0x%x\n",
1322 mb->mbxStatus); 1326 mb->mbxStatus);
1327 /* Decrement the reference count to ndlp after the reference
1328 * to the ndlp are done.
1329 */
1330 lpfc_nlp_put(ndlp);
1323 return; 1331 return;
1324 } 1332 }
1325 1333
@@ -1327,8 +1335,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1327 ndlp->nlp_type |= NLP_FABRIC; 1335 ndlp->nlp_type |= NLP_FABRIC;
1328 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 1336 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1329 1337
1330 lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */
1331
1332 if (vport->port_state == LPFC_FABRIC_CFG_LINK) { 1338 if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
1333 vports = lpfc_create_vport_work_array(phba); 1339 vports = lpfc_create_vport_work_array(phba);
1334 if (vports != NULL) 1340 if (vports != NULL)
@@ -1356,6 +1362,11 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1356 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1362 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1357 kfree(mp); 1363 kfree(mp);
1358 mempool_free(pmb, phba->mbox_mem_pool); 1364 mempool_free(pmb, phba->mbox_mem_pool);
1365
1366 /* Drop the reference count from the mbox at the end after
1367 * all the current reference to the ndlp have been done.
1368 */
1369 lpfc_nlp_put(ndlp);
1359 return; 1370 return;
1360} 1371}
1361 1372
@@ -1463,9 +1474,8 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1463 * registered the port. 1474 * registered the port.
1464 */ 1475 */
1465 if (ndlp->rport && ndlp->rport->dd_data && 1476 if (ndlp->rport && ndlp->rport->dd_data &&
1466 ((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp) { 1477 ((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp)
1467 lpfc_nlp_put(ndlp); 1478 lpfc_nlp_put(ndlp);
1468 }
1469 1479
1470 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT, 1480 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
1471 "rport add: did:x%x flg:x%x type x%x", 1481 "rport add: did:x%x flg:x%x type x%x",
@@ -1660,6 +1670,18 @@ lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1660} 1670}
1661 1671
1662void 1672void
1673lpfc_enqueue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1674{
1675 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1676
1677 if (list_empty(&ndlp->nlp_listp)) {
1678 spin_lock_irq(shost->host_lock);
1679 list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
1680 spin_unlock_irq(shost->host_lock);
1681 }
1682}
1683
1684void
1663lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 1685lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1664{ 1686{
1665 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1687 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
@@ -1672,7 +1694,80 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1672 list_del_init(&ndlp->nlp_listp); 1694 list_del_init(&ndlp->nlp_listp);
1673 spin_unlock_irq(shost->host_lock); 1695 spin_unlock_irq(shost->host_lock);
1674 lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, 1696 lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state,
1675 NLP_STE_UNUSED_NODE); 1697 NLP_STE_UNUSED_NODE);
1698}
1699
1700void
1701lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1702{
1703 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
1704 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1705 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1706 lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
1707 lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state,
1708 NLP_STE_UNUSED_NODE);
1709}
1710
1711struct lpfc_nodelist *
1712lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1713 int state)
1714{
1715 struct lpfc_hba *phba = vport->phba;
1716 uint32_t did;
1717 unsigned long flags;
1718
1719 if (!ndlp)
1720 return NULL;
1721
1722 spin_lock_irqsave(&phba->ndlp_lock, flags);
1723 /* The ndlp should not be in memory free mode */
1724 if (NLP_CHK_FREE_REQ(ndlp)) {
1725 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
1726 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
1727 "0277 lpfc_enable_node: ndlp:x%p "
1728 "usgmap:x%x refcnt:%d\n",
1729 (void *)ndlp, ndlp->nlp_usg_map,
1730 atomic_read(&ndlp->kref.refcount));
1731 return NULL;
1732 }
1733 /* The ndlp should not already be in active mode */
1734 if (NLP_CHK_NODE_ACT(ndlp)) {
1735 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
1736 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
1737 "0278 lpfc_enable_node: ndlp:x%p "
1738 "usgmap:x%x refcnt:%d\n",
1739 (void *)ndlp, ndlp->nlp_usg_map,
1740 atomic_read(&ndlp->kref.refcount));
1741 return NULL;
1742 }
1743
1744 /* Keep the original DID */
1745 did = ndlp->nlp_DID;
1746
1747 /* re-initialize ndlp except of ndlp linked list pointer */
1748 memset((((char *)ndlp) + sizeof (struct list_head)), 0,
1749 sizeof (struct lpfc_nodelist) - sizeof (struct list_head));
1750 INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
1751 INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
1752 init_timer(&ndlp->nlp_delayfunc);
1753 ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
1754 ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
1755 ndlp->nlp_DID = did;
1756 ndlp->vport = vport;
1757 ndlp->nlp_sid = NLP_NO_SID;
1758 /* ndlp management re-initialize */
1759 kref_init(&ndlp->kref);
1760 NLP_INT_NODE_ACT(ndlp);
1761
1762 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
1763
1764 if (state != NLP_STE_UNUSED_NODE)
1765 lpfc_nlp_set_state(vport, ndlp, state);
1766
1767 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
1768 "node enable: did:x%x",
1769 ndlp->nlp_DID, 0, 0);
1770 return ndlp;
1676} 1771}
1677 1772
1678void 1773void
@@ -1972,7 +2067,21 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1972 "Data: x%x x%x x%x\n", 2067 "Data: x%x x%x x%x\n",
1973 ndlp->nlp_DID, ndlp->nlp_flag, 2068 ndlp->nlp_DID, ndlp->nlp_flag,
1974 ndlp->nlp_state, ndlp->nlp_rpi); 2069 ndlp->nlp_state, ndlp->nlp_rpi);
1975 lpfc_dequeue_node(vport, ndlp); 2070 if (NLP_CHK_FREE_REQ(ndlp)) {
2071 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
2072 "0280 lpfc_cleanup_node: ndlp:x%p "
2073 "usgmap:x%x refcnt:%d\n",
2074 (void *)ndlp, ndlp->nlp_usg_map,
2075 atomic_read(&ndlp->kref.refcount));
2076 lpfc_dequeue_node(vport, ndlp);
2077 } else {
2078 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
2079 "0281 lpfc_cleanup_node: ndlp:x%p "
2080 "usgmap:x%x refcnt:%d\n",
2081 (void *)ndlp, ndlp->nlp_usg_map,
2082 atomic_read(&ndlp->kref.refcount));
2083 lpfc_disable_node(vport, ndlp);
2084 }
1976 2085
1977 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ 2086 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
1978 if ((mb = phba->sli.mbox_active)) { 2087 if ((mb = phba->sli.mbox_active)) {
@@ -1994,12 +2103,16 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1994 } 2103 }
1995 list_del(&mb->list); 2104 list_del(&mb->list);
1996 mempool_free(mb, phba->mbox_mem_pool); 2105 mempool_free(mb, phba->mbox_mem_pool);
1997 lpfc_nlp_put(ndlp); 2106 /* We shall not invoke the lpfc_nlp_put to decrement
2107 * the ndlp reference count as we are in the process
2108 * of lpfc_nlp_release.
2109 */
1998 } 2110 }
1999 } 2111 }
2000 spin_unlock_irq(&phba->hbalock); 2112 spin_unlock_irq(&phba->hbalock);
2001 2113
2002 lpfc_els_abort(phba,ndlp); 2114 lpfc_els_abort(phba, ndlp);
2115
2003 spin_lock_irq(shost->host_lock); 2116 spin_lock_irq(shost->host_lock);
2004 ndlp->nlp_flag &= ~NLP_DELAY_TMO; 2117 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
2005 spin_unlock_irq(shost->host_lock); 2118 spin_unlock_irq(shost->host_lock);
@@ -2057,7 +2170,6 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2057 } 2170 }
2058 } 2171 }
2059 } 2172 }
2060
2061 lpfc_cleanup_node(vport, ndlp); 2173 lpfc_cleanup_node(vport, ndlp);
2062 2174
2063 /* 2175 /*
@@ -2182,7 +2294,16 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
2182 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 2294 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2183 spin_unlock_irq(shost->host_lock); 2295 spin_unlock_irq(shost->host_lock);
2184 return ndlp; 2296 return ndlp;
2297 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
2298 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE);
2299 if (!ndlp)
2300 return NULL;
2301 spin_lock_irq(shost->host_lock);
2302 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2303 spin_unlock_irq(shost->host_lock);
2304 return ndlp;
2185 } 2305 }
2306
2186 if (vport->fc_flag & FC_RSCN_MODE) { 2307 if (vport->fc_flag & FC_RSCN_MODE) {
2187 if (lpfc_rscn_payload_check(vport, did)) { 2308 if (lpfc_rscn_payload_check(vport, did)) {
2188 /* If we've already recieved a PLOGI from this NPort 2309 /* If we've already recieved a PLOGI from this NPort
@@ -2485,6 +2606,8 @@ lpfc_disc_flush_list(struct lpfc_vport *vport)
2485 if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) { 2606 if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) {
2486 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, 2607 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
2487 nlp_listp) { 2608 nlp_listp) {
2609 if (!NLP_CHK_NODE_ACT(ndlp))
2610 continue;
2488 if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || 2611 if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
2489 ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { 2612 ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
2490 lpfc_free_tx(phba, ndlp); 2613 lpfc_free_tx(phba, ndlp);
@@ -2572,6 +2695,8 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2572 /* Start discovery by sending FLOGI, clean up old rpis */ 2695 /* Start discovery by sending FLOGI, clean up old rpis */
2573 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, 2696 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
2574 nlp_listp) { 2697 nlp_listp) {
2698 if (!NLP_CHK_NODE_ACT(ndlp))
2699 continue;
2575 if (ndlp->nlp_state != NLP_STE_NPR_NODE) 2700 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
2576 continue; 2701 continue;
2577 if (ndlp->nlp_type & NLP_FABRIC) { 2702 if (ndlp->nlp_type & NLP_FABRIC) {
@@ -2618,7 +2743,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2618 "NameServer login\n"); 2743 "NameServer login\n");
2619 /* Next look for NameServer ndlp */ 2744 /* Next look for NameServer ndlp */
2620 ndlp = lpfc_findnode_did(vport, NameServer_DID); 2745 ndlp = lpfc_findnode_did(vport, NameServer_DID);
2621 if (ndlp) 2746 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
2622 lpfc_els_abort(phba, ndlp); 2747 lpfc_els_abort(phba, ndlp);
2623 2748
2624 /* ReStart discovery */ 2749 /* ReStart discovery */
@@ -2897,6 +3022,7 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2897 ndlp->nlp_sid = NLP_NO_SID; 3022 ndlp->nlp_sid = NLP_NO_SID;
2898 INIT_LIST_HEAD(&ndlp->nlp_listp); 3023 INIT_LIST_HEAD(&ndlp->nlp_listp);
2899 kref_init(&ndlp->kref); 3024 kref_init(&ndlp->kref);
3025 NLP_INT_NODE_ACT(ndlp);
2900 3026
2901 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE, 3027 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
2902 "node init: did:x%x", 3028 "node init: did:x%x",
@@ -2911,6 +3037,8 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2911static void 3037static void
2912lpfc_nlp_release(struct kref *kref) 3038lpfc_nlp_release(struct kref *kref)
2913{ 3039{
3040 struct lpfc_hba *phba;
3041 unsigned long flags;
2914 struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, 3042 struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
2915 kref); 3043 kref);
2916 3044
@@ -2918,8 +3046,24 @@ lpfc_nlp_release(struct kref *kref)
2918 "node release: did:x%x flg:x%x type:x%x", 3046 "node release: did:x%x flg:x%x type:x%x",
2919 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); 3047 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
2920 3048
3049 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
3050 "0279 lpfc_nlp_release: ndlp:x%p "
3051 "usgmap:x%x refcnt:%d\n",
3052 (void *)ndlp, ndlp->nlp_usg_map,
3053 atomic_read(&ndlp->kref.refcount));
3054
3055 /* remove ndlp from action. */
2921 lpfc_nlp_remove(ndlp->vport, ndlp); 3056 lpfc_nlp_remove(ndlp->vport, ndlp);
2922 mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); 3057
3058 /* clear the ndlp active flag for all release cases */
3059 phba = ndlp->vport->phba;
3060 spin_lock_irqsave(&phba->ndlp_lock, flags);
3061 NLP_CLR_NODE_ACT(ndlp);
3062 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3063
3064 /* free ndlp memory for final ndlp release */
3065 if (NLP_CHK_FREE_REQ(ndlp))
3066 mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool);
2923} 3067}
2924 3068
2925/* This routine bumps the reference count for a ndlp structure to ensure 3069/* This routine bumps the reference count for a ndlp structure to ensure
@@ -2929,37 +3073,108 @@ lpfc_nlp_release(struct kref *kref)
2929struct lpfc_nodelist * 3073struct lpfc_nodelist *
2930lpfc_nlp_get(struct lpfc_nodelist *ndlp) 3074lpfc_nlp_get(struct lpfc_nodelist *ndlp)
2931{ 3075{
3076 struct lpfc_hba *phba;
3077 unsigned long flags;
3078
2932 if (ndlp) { 3079 if (ndlp) {
2933 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, 3080 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
2934 "node get: did:x%x flg:x%x refcnt:x%x", 3081 "node get: did:x%x flg:x%x refcnt:x%x",
2935 ndlp->nlp_DID, ndlp->nlp_flag, 3082 ndlp->nlp_DID, ndlp->nlp_flag,
2936 atomic_read(&ndlp->kref.refcount)); 3083 atomic_read(&ndlp->kref.refcount));
2937 kref_get(&ndlp->kref); 3084 /* The check of ndlp usage to prevent incrementing the
3085 * ndlp reference count that is in the process of being
3086 * released.
3087 */
3088 phba = ndlp->vport->phba;
3089 spin_lock_irqsave(&phba->ndlp_lock, flags);
3090 if (!NLP_CHK_NODE_ACT(ndlp) || NLP_CHK_FREE_ACK(ndlp)) {
3091 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3092 lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
3093 "0276 lpfc_nlp_get: ndlp:x%p "
3094 "usgmap:x%x refcnt:%d\n",
3095 (void *)ndlp, ndlp->nlp_usg_map,
3096 atomic_read(&ndlp->kref.refcount));
3097 return NULL;
3098 } else
3099 kref_get(&ndlp->kref);
3100 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
2938 } 3101 }
2939 return ndlp; 3102 return ndlp;
2940} 3103}
2941 3104
2942
2943/* This routine decrements the reference count for a ndlp structure. If the 3105/* This routine decrements the reference count for a ndlp structure. If the
2944 * count goes to 0, this indicates the the associated nodelist should be freed. 3106 * count goes to 0, this indicates the the associated nodelist should be
3107 * freed. Returning 1 indicates the ndlp resource has been released; on the
3108 * other hand, returning 0 indicates the ndlp resource has not been released
3109 * yet.
2945 */ 3110 */
2946int 3111int
2947lpfc_nlp_put(struct lpfc_nodelist *ndlp) 3112lpfc_nlp_put(struct lpfc_nodelist *ndlp)
2948{ 3113{
2949 if (ndlp) { 3114 struct lpfc_hba *phba;
2950 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, 3115 unsigned long flags;
2951 "node put: did:x%x flg:x%x refcnt:x%x", 3116
2952 ndlp->nlp_DID, ndlp->nlp_flag, 3117 if (!ndlp)
2953 atomic_read(&ndlp->kref.refcount)); 3118 return 1;
3119
3120 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
3121 "node put: did:x%x flg:x%x refcnt:x%x",
3122 ndlp->nlp_DID, ndlp->nlp_flag,
3123 atomic_read(&ndlp->kref.refcount));
3124 phba = ndlp->vport->phba;
3125 spin_lock_irqsave(&phba->ndlp_lock, flags);
3126 /* Check the ndlp memory free acknowledge flag to avoid the
3127 * possible race condition that kref_put got invoked again
3128 * after previous one has done ndlp memory free.
3129 */
3130 if (NLP_CHK_FREE_ACK(ndlp)) {
3131 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3132 lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
3133 "0274 lpfc_nlp_put: ndlp:x%p "
3134 "usgmap:x%x refcnt:%d\n",
3135 (void *)ndlp, ndlp->nlp_usg_map,
3136 atomic_read(&ndlp->kref.refcount));
3137 return 1;
3138 }
3139 /* Check the ndlp inactivate log flag to avoid the possible
3140 * race condition that kref_put got invoked again after ndlp
3141 * is already in inactivating state.
3142 */
3143 if (NLP_CHK_IACT_REQ(ndlp)) {
3144 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3145 lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
3146 "0275 lpfc_nlp_put: ndlp:x%p "
3147 "usgmap:x%x refcnt:%d\n",
3148 (void *)ndlp, ndlp->nlp_usg_map,
3149 atomic_read(&ndlp->kref.refcount));
3150 return 1;
2954 } 3151 }
2955 return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; 3152 /* For last put, mark the ndlp usage flags to make sure no
3153 * other kref_get and kref_put on the same ndlp shall get
3154 * in between the process when the final kref_put has been
3155 * invoked on this ndlp.
3156 */
3157 if (atomic_read(&ndlp->kref.refcount) == 1) {
3158 /* Indicate ndlp is put to inactive state. */
3159 NLP_SET_IACT_REQ(ndlp);
3160 /* Acknowledge ndlp memory free has been seen. */
3161 if (NLP_CHK_FREE_REQ(ndlp))
3162 NLP_SET_FREE_ACK(ndlp);
3163 }
3164 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3165 /* Note, the kref_put returns 1 when decrementing a reference
3166 * count that was 1, it invokes the release callback function,
3167 * but it still left the reference count as 1 (not actually
3168 * performs the last decrementation). Otherwise, it actually
3169 * decrements the reference count and returns 0.
3170 */
3171 return kref_put(&ndlp->kref, lpfc_nlp_release);
2956} 3172}
2957 3173
2958/* This routine free's the specified nodelist if it is not in use 3174/* This routine free's the specified nodelist if it is not in use
2959 * by any other discovery thread. This routine returns 1 if the ndlp 3175 * by any other discovery thread. This routine returns 1 if the
2960 * is not being used by anyone and has been freed. A return value of 3176 * ndlp has been freed. A return value of 0 indicates the ndlp is
2961 * 0 indicates it is being used by another discovery thread and the 3177 * not yet been released.
2962 * refcount is left unchanged.
2963 */ 3178 */
2964int 3179int
2965lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) 3180lpfc_nlp_not_used(struct lpfc_nodelist *ndlp)
@@ -2968,11 +3183,8 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp)
2968 "node not used: did:x%x flg:x%x refcnt:x%x", 3183 "node not used: did:x%x flg:x%x refcnt:x%x",
2969 ndlp->nlp_DID, ndlp->nlp_flag, 3184 ndlp->nlp_DID, ndlp->nlp_flag,
2970 atomic_read(&ndlp->kref.refcount)); 3185 atomic_read(&ndlp->kref.refcount));
2971 3186 if (atomic_read(&ndlp->kref.refcount) == 1)
2972 if (atomic_read(&ndlp->kref.refcount) == 1) { 3187 if (lpfc_nlp_put(ndlp))
2973 lpfc_nlp_put(ndlp); 3188 return 1;
2974 return 1;
2975 }
2976 return 0; 3189 return 0;
2977} 3190}
2978
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 6cfeba7454d4..e0363bef6d29 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -1422,9 +1422,32 @@ lpfc_cleanup(struct lpfc_vport *vport)
1422 lpfc_port_link_failure(vport); 1422 lpfc_port_link_failure(vport);
1423 1423
1424 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 1424 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
1425 if (!NLP_CHK_NODE_ACT(ndlp)) {
1426 ndlp = lpfc_enable_node(vport, ndlp,
1427 NLP_STE_UNUSED_NODE);
1428 if (!ndlp)
1429 continue;
1430 spin_lock_irq(&phba->ndlp_lock);
1431 NLP_SET_FREE_REQ(ndlp);
1432 spin_unlock_irq(&phba->ndlp_lock);
1433 /* Trigger the release of the ndlp memory */
1434 lpfc_nlp_put(ndlp);
1435 continue;
1436 }
1437 spin_lock_irq(&phba->ndlp_lock);
1438 if (NLP_CHK_FREE_REQ(ndlp)) {
1439 /* The ndlp should not be in memory free mode already */
1440 spin_unlock_irq(&phba->ndlp_lock);
1441 continue;
1442 } else
1443 /* Indicate request for freeing ndlp memory */
1444 NLP_SET_FREE_REQ(ndlp);
1445 spin_unlock_irq(&phba->ndlp_lock);
1446
1425 if (ndlp->nlp_type & NLP_FABRIC) 1447 if (ndlp->nlp_type & NLP_FABRIC)
1426 lpfc_disc_state_machine(vport, ndlp, NULL, 1448 lpfc_disc_state_machine(vport, ndlp, NULL,
1427 NLP_EVT_DEVICE_RECOVERY); 1449 NLP_EVT_DEVICE_RECOVERY);
1450
1428 lpfc_disc_state_machine(vport, ndlp, NULL, 1451 lpfc_disc_state_machine(vport, ndlp, NULL,
1429 NLP_EVT_DEVICE_RM); 1452 NLP_EVT_DEVICE_RM);
1430 } 1453 }
@@ -1438,6 +1461,17 @@ lpfc_cleanup(struct lpfc_vport *vport)
1438 if (i++ > 3000) { 1461 if (i++ > 3000) {
1439 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 1462 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1440 "0233 Nodelist not empty\n"); 1463 "0233 Nodelist not empty\n");
1464 list_for_each_entry_safe(ndlp, next_ndlp,
1465 &vport->fc_nodes, nlp_listp) {
1466 lpfc_printf_vlog(ndlp->vport, KERN_ERR,
1467 LOG_NODE,
1468 "0282: did:x%x ndlp:x%p "
1469 "usgmap:x%x refcnt:%d\n",
1470 ndlp->nlp_DID, (void *)ndlp,
1471 ndlp->nlp_usg_map,
1472 atomic_read(
1473 &ndlp->kref.refcount));
1474 }
1441 break; 1475 break;
1442 } 1476 }
1443 1477
@@ -1586,6 +1620,8 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1586 list_for_each_entry_safe(ndlp, next_ndlp, 1620 list_for_each_entry_safe(ndlp, next_ndlp,
1587 &vports[i]->fc_nodes, 1621 &vports[i]->fc_nodes,
1588 nlp_listp) { 1622 nlp_listp) {
1623 if (!NLP_CHK_NODE_ACT(ndlp))
1624 continue;
1589 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 1625 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
1590 continue; 1626 continue;
1591 if (ndlp->nlp_type & NLP_FABRIC) { 1627 if (ndlp->nlp_type & NLP_FABRIC) {
@@ -1905,6 +1941,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1905 1941
1906 spin_lock_init(&phba->hbalock); 1942 spin_lock_init(&phba->hbalock);
1907 1943
1944 /* Initialize ndlp management spinlock */
1945 spin_lock_init(&phba->ndlp_lock);
1946
1908 phba->pcidev = pdev; 1947 phba->pcidev = pdev;
1909 1948
1910 /* Assign an unused board number */ 1949 /* Assign an unused board number */
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 4a0e3406e37a..01d548375811 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1,7 +1,7 @@
1 /******************************************************************* 1 /*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -249,6 +249,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
249 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 249 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
250 struct lpfc_hba *phba = vport->phba; 250 struct lpfc_hba *phba = vport->phba;
251 struct lpfc_dmabuf *pcmd; 251 struct lpfc_dmabuf *pcmd;
252 struct lpfc_work_evt *evtp;
252 uint32_t *lp; 253 uint32_t *lp;
253 IOCB_t *icmd; 254 IOCB_t *icmd;
254 struct serv_parm *sp; 255 struct serv_parm *sp;
@@ -435,8 +436,14 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
435 del_timer_sync(&ndlp->nlp_delayfunc); 436 del_timer_sync(&ndlp->nlp_delayfunc);
436 ndlp->nlp_last_elscmd = 0; 437 ndlp->nlp_last_elscmd = 0;
437 438
438 if (!list_empty(&ndlp->els_retry_evt.evt_listp)) 439 if (!list_empty(&ndlp->els_retry_evt.evt_listp)) {
439 list_del_init(&ndlp->els_retry_evt.evt_listp); 440 list_del_init(&ndlp->els_retry_evt.evt_listp);
441 /* Decrement ndlp reference count held for the
442 * delayed retry
443 */
444 evtp = &ndlp->els_retry_evt;
445 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
446 }
440 447
441 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { 448 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
442 spin_lock_irq(shost->host_lock); 449 spin_lock_irq(shost->host_lock);
@@ -656,7 +663,7 @@ lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
656 void *arg, uint32_t evt) 663 void *arg, uint32_t evt)
657{ 664{
658 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 665 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
659 "0253 Illegal State Transition: node x%x " 666 "0271 Illegal State Transition: node x%x "
660 "event x%x, state x%x Data: x%x x%x\n", 667 "event x%x, state x%x Data: x%x x%x\n",
661 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, 668 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
662 ndlp->nlp_flag); 669 ndlp->nlp_flag);
@@ -674,7 +681,7 @@ lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
674 */ 681 */
675 if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) { 682 if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {
676 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 683 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
677 "0253 Illegal State Transition: node x%x " 684 "0272 Illegal State Transition: node x%x "
678 "event x%x, state x%x Data: x%x x%x\n", 685 "event x%x, state x%x Data: x%x x%x\n",
679 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, 686 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
680 ndlp->nlp_flag); 687 ndlp->nlp_flag);
@@ -2144,8 +2151,11 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2144 uint32_t cur_state, rc; 2151 uint32_t cur_state, rc;
2145 uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, 2152 uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
2146 uint32_t); 2153 uint32_t);
2154 uint32_t got_ndlp = 0;
2155
2156 if (lpfc_nlp_get(ndlp))
2157 got_ndlp = 1;
2147 2158
2148 lpfc_nlp_get(ndlp);
2149 cur_state = ndlp->nlp_state; 2159 cur_state = ndlp->nlp_state;
2150 2160
2151 /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */ 2161 /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
@@ -2162,15 +2172,24 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2162 rc = (func) (vport, ndlp, arg, evt); 2172 rc = (func) (vport, ndlp, arg, evt);
2163 2173
2164 /* DSM out state <rc> on NPort <nlp_DID> */ 2174 /* DSM out state <rc> on NPort <nlp_DID> */
2165 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 2175 if (got_ndlp) {
2176 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2166 "0212 DSM out state %d on NPort x%x Data: x%x\n", 2177 "0212 DSM out state %d on NPort x%x Data: x%x\n",
2167 rc, ndlp->nlp_DID, ndlp->nlp_flag); 2178 rc, ndlp->nlp_DID, ndlp->nlp_flag);
2168 2179
2169 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, 2180 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2170 "DSM out: ste:%d did:x%x flg:x%x", 2181 "DSM out: ste:%d did:x%x flg:x%x",
2171 rc, ndlp->nlp_DID, ndlp->nlp_flag); 2182 rc, ndlp->nlp_DID, ndlp->nlp_flag);
2183 /* Decrement the ndlp reference count held for this function */
2184 lpfc_nlp_put(ndlp);
2185 } else {
2186 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2187 "0212 DSM out state %d on NPort free\n", rc);
2172 2188
2173 lpfc_nlp_put(ndlp); 2189 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2190 "DSM out: ste:%d did:x%x flg:x%x",
2191 rc, 0, 0);
2192 }
2174 2193
2175 return rc; 2194 return rc;
2176} 2195}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index fc5c3a42b05a..70255c11d3ad 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -1283,6 +1283,8 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
1283 match = 0; 1283 match = 0;
1284 spin_lock_irq(shost->host_lock); 1284 spin_lock_irq(shost->host_lock);
1285 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 1285 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
1286 if (!NLP_CHK_NODE_ACT(ndlp))
1287 continue;
1286 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && 1288 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
1287 i == ndlp->nlp_sid && 1289 i == ndlp->nlp_sid &&
1288 ndlp->rport) { 1290 ndlp->rport) {
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 9fad7663c117..86d05beb00b8 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2006 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -327,7 +327,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
327 * up and ready to FDISC. 327 * up and ready to FDISC.
328 */ 328 */
329 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); 329 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
330 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { 330 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
331 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
331 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { 332 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) {
332 lpfc_set_disctmo(vport); 333 lpfc_set_disctmo(vport);
333 lpfc_initial_fdisc(vport); 334 lpfc_initial_fdisc(vport);
@@ -358,7 +359,8 @@ disable_vport(struct fc_vport *fc_vport)
358 long timeout; 359 long timeout;
359 360
360 ndlp = lpfc_findnode_did(vport, Fabric_DID); 361 ndlp = lpfc_findnode_did(vport, Fabric_DID);
361 if (ndlp && phba->link_state >= LPFC_LINK_UP) { 362 if (ndlp && NLP_CHK_NODE_ACT(ndlp)
363 && phba->link_state >= LPFC_LINK_UP) {
362 vport->unreg_vpi_cmpl = VPORT_INVAL; 364 vport->unreg_vpi_cmpl = VPORT_INVAL;
363 timeout = msecs_to_jiffies(phba->fc_ratov * 2000); 365 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
364 if (!lpfc_issue_els_npiv_logo(vport, ndlp)) 366 if (!lpfc_issue_els_npiv_logo(vport, ndlp))
@@ -372,6 +374,8 @@ disable_vport(struct fc_vport *fc_vport)
372 * calling lpfc_cleanup_rpis(vport, 1) 374 * calling lpfc_cleanup_rpis(vport, 1)
373 */ 375 */
374 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 376 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
377 if (!NLP_CHK_NODE_ACT(ndlp))
378 continue;
375 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 379 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
376 continue; 380 continue;
377 lpfc_disc_state_machine(vport, ndlp, NULL, 381 lpfc_disc_state_machine(vport, ndlp, NULL,
@@ -414,7 +418,8 @@ enable_vport(struct fc_vport *fc_vport)
414 * up and ready to FDISC. 418 * up and ready to FDISC.
415 */ 419 */
416 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); 420 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
417 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { 421 if (ndlp && NLP_CHK_NODE_ACT(ndlp)
422 && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
418 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { 423 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) {
419 lpfc_set_disctmo(vport); 424 lpfc_set_disctmo(vport);
420 lpfc_initial_fdisc(vport); 425 lpfc_initial_fdisc(vport);
@@ -498,7 +503,41 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
498 scsi_remove_host(lpfc_shost_from_vport(vport)); 503 scsi_remove_host(lpfc_shost_from_vport(vport));
499 504
500 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); 505 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
501 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && 506
507 /* In case of driver unload, we shall not perform fabric logo as the
508 * worker thread already stopped at this stage and, in this case, we
509 * can safely skip the fabric logo.
510 */
511 if (phba->pport->load_flag & FC_UNLOADING) {
512 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
513 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
514 phba->link_state >= LPFC_LINK_UP) {
515 /* First look for the Fabric ndlp */
516 ndlp = lpfc_findnode_did(vport, Fabric_DID);
517 if (!ndlp)
518 goto skip_logo;
519 else if (!NLP_CHK_NODE_ACT(ndlp)) {
520 ndlp = lpfc_enable_node(vport, ndlp,
521 NLP_STE_UNUSED_NODE);
522 if (!ndlp)
523 goto skip_logo;
524 }
525 /* Remove ndlp from vport npld list */
526 lpfc_dequeue_node(vport, ndlp);
527
528 /* Indicate free memory when release */
529 spin_lock_irq(&phba->ndlp_lock);
530 NLP_SET_FREE_REQ(ndlp);
531 spin_unlock_irq(&phba->ndlp_lock);
532 /* Kick off release ndlp when it can be safely done */
533 lpfc_nlp_put(ndlp);
534 }
535 goto skip_logo;
536 }
537
538 /* Otherwise, we will perform fabric logo as needed */
539 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
540 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
502 phba->link_state >= LPFC_LINK_UP) { 541 phba->link_state >= LPFC_LINK_UP) {
503 if (vport->cfg_enable_da_id) { 542 if (vport->cfg_enable_da_id) {
504 timeout = msecs_to_jiffies(phba->fc_ratov * 2000); 543 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
@@ -519,8 +558,27 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
519 if (!ndlp) 558 if (!ndlp)
520 goto skip_logo; 559 goto skip_logo;
521 lpfc_nlp_init(vport, ndlp, Fabric_DID); 560 lpfc_nlp_init(vport, ndlp, Fabric_DID);
561 /* Indicate free memory when release */
562 NLP_SET_FREE_REQ(ndlp);
522 } else { 563 } else {
564 if (!NLP_CHK_NODE_ACT(ndlp))
565 ndlp = lpfc_enable_node(vport, ndlp,
566 NLP_STE_UNUSED_NODE);
567 if (!ndlp)
568 goto skip_logo;
569
570 /* Remove ndlp from vport npld list */
523 lpfc_dequeue_node(vport, ndlp); 571 lpfc_dequeue_node(vport, ndlp);
572 spin_lock_irq(&phba->ndlp_lock);
573 if (!NLP_CHK_FREE_REQ(ndlp))
574 /* Indicate free memory when release */
575 NLP_SET_FREE_REQ(ndlp);
576 else {
577 /* Skip this if ndlp is already in free mode */
578 spin_unlock_irq(&phba->ndlp_lock);
579 goto skip_logo;
580 }
581 spin_unlock_irq(&phba->ndlp_lock);
524 } 582 }
525 vport->unreg_vpi_cmpl = VPORT_INVAL; 583 vport->unreg_vpi_cmpl = VPORT_INVAL;
526 timeout = msecs_to_jiffies(phba->fc_ratov * 2000); 584 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
@@ -534,9 +592,9 @@ skip_logo:
534 lpfc_sli_host_down(vport); 592 lpfc_sli_host_down(vport);
535 593
536 lpfc_stop_vport_timers(vport); 594 lpfc_stop_vport_timers(vport);
537 lpfc_unreg_all_rpis(vport);
538 595
539 if (!(phba->pport->load_flag & FC_UNLOADING)) { 596 if (!(phba->pport->load_flag & FC_UNLOADING)) {
597 lpfc_unreg_all_rpis(vport);
540 lpfc_unreg_default_rpis(vport); 598 lpfc_unreg_default_rpis(vport);
541 /* 599 /*
542 * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) 600 * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)