aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:53:08 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:15 -0400
commit685f0bf7afe087940d34f98ac0fd1df84091d360 (patch)
tree7e7fbfc856f13a3c4c64e14784b7050812753521 /drivers
parent329f9bc735b4665d42267259b1612191f72c4d42 (diff)
[SCSI] lpfc 8.1.12 : Collapse discovery lists to a single node list
Collapse discovery lists to a single node list. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/lpfc/lpfc.h12
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c64
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h7
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h20
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c155
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c458
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c84
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c8
9 files changed, 282 insertions, 536 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index da8b6bb09a76..ccc4ca194c60 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -255,17 +255,7 @@ struct lpfc_hba {
255 255
256 struct lpfc_stats fc_stat; 256 struct lpfc_stats fc_stat;
257 257
258 /* These are the head/tail pointers for the bind, plogi, adisc, unmap, 258 struct list_head fc_nodes;
259 * and map lists. Their counters are immediately following.
260 */
261 struct list_head fc_plogi_list;
262 struct list_head fc_adisc_list;
263 struct list_head fc_reglogin_list;
264 struct list_head fc_prli_list;
265 struct list_head fc_nlpunmap_list;
266 struct list_head fc_nlpmap_list;
267 struct list_head fc_npr_list;
268 struct list_head fc_unused_list;
269 259
270 /* Keep counters for the number of entries in each list. */ 260 /* Keep counters for the number of entries in each list. */
271 uint16_t fc_plogi_cnt; 261 uint16_t fc_plogi_cnt;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index df9847ea1a12..2605bd3502a9 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1781,67 +1781,51 @@ lpfc_reset_stats(struct Scsi_Host *shost)
1781 * The LPFC driver treats linkdown handling as target loss events so there 1781 * The LPFC driver treats linkdown handling as target loss events so there
1782 * are no sysfs handlers for link_down_tmo. 1782 * are no sysfs handlers for link_down_tmo.
1783 */ 1783 */
1784static void 1784
1785lpfc_get_starget_port_id(struct scsi_target *starget) 1785static struct lpfc_nodelist *
1786lpfc_get_node_by_target(struct scsi_target *starget)
1786{ 1787{
1787 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 1788 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
1788 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; 1789 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
1789 uint32_t did = -1; 1790 struct lpfc_nodelist *ndlp;
1790 struct lpfc_nodelist *ndlp = NULL;
1791 1791
1792 spin_lock_irq(shost->host_lock); 1792 spin_lock_irq(shost->host_lock);
1793 /* Search the mapped list for this target ID */ 1793 /* Search for this, mapped, target ID */
1794 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { 1794 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
1795 if (starget->id == ndlp->nlp_sid) { 1795 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
1796 did = ndlp->nlp_DID; 1796 starget->id == ndlp->nlp_sid) {
1797 break; 1797 spin_unlock_irq(shost->host_lock);
1798 return ndlp;
1798 } 1799 }
1799 } 1800 }
1800 spin_unlock_irq(shost->host_lock); 1801 spin_unlock_irq(shost->host_lock);
1802 return NULL;
1803}
1801 1804
1802 fc_starget_port_id(starget) = did; 1805static void
1806lpfc_get_starget_port_id(struct scsi_target *starget)
1807{
1808 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
1809
1810 fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
1803} 1811}
1804 1812
1805static void 1813static void
1806lpfc_get_starget_node_name(struct scsi_target *starget) 1814lpfc_get_starget_node_name(struct scsi_target *starget)
1807{ 1815{
1808 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 1816 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
1809 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
1810 u64 node_name = 0;
1811 struct lpfc_nodelist *ndlp = NULL;
1812 1817
1813 spin_lock_irq(shost->host_lock); 1818 fc_starget_node_name(starget) =
1814 /* Search the mapped list for this target ID */ 1819 ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
1815 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
1816 if (starget->id == ndlp->nlp_sid) {
1817 node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
1818 break;
1819 }
1820 }
1821 spin_unlock_irq(shost->host_lock);
1822
1823 fc_starget_node_name(starget) = node_name;
1824} 1820}
1825 1821
1826static void 1822static void
1827lpfc_get_starget_port_name(struct scsi_target *starget) 1823lpfc_get_starget_port_name(struct scsi_target *starget)
1828{ 1824{
1829 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 1825 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
1830 struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
1831 u64 port_name = 0;
1832 struct lpfc_nodelist *ndlp = NULL;
1833
1834 spin_lock_irq(shost->host_lock);
1835 /* Search the mapped list for this target ID */
1836 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
1837 if (starget->id == ndlp->nlp_sid) {
1838 port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
1839 break;
1840 }
1841 }
1842 spin_unlock_irq(shost->host_lock);
1843 1826
1844 fc_starget_port_name(starget) = port_name; 1827 fc_starget_port_name(starget) =
1828 ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
1845} 1829}
1846 1830
1847static void 1831static void
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index f61d46fce116..9f70b5bc0950 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -18,6 +18,8 @@
18 * included with this package. * 18 * included with this package. *
19 *******************************************************************/ 19 *******************************************************************/
20 20
21typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param);
22
21struct fc_rport; 23struct fc_rport;
22void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); 24void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
23void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); 25void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -178,9 +180,8 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
178void lpfc_mbox_timeout(unsigned long); 180void lpfc_mbox_timeout(unsigned long);
179void lpfc_mbox_timeout_handler(struct lpfc_hba *); 181void lpfc_mbox_timeout_handler(struct lpfc_hba *);
180 182
181struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t, uint32_t); 183struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t);
182struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, uint32_t, 184struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, struct lpfc_name *);
183 struct lpfc_name *);
184 185
185int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, 186int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
186 uint32_t timeout); 187 uint32_t timeout);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 48ae2355de69..af819885213d 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -443,10 +443,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
443 if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { 443 if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {
444 phba->fc_ns_retry++; 444 phba->fc_ns_retry++;
445 /* CT command is being retried */ 445 /* CT command is being retried */
446 ndlp = 446 ndlp = lpfc_findnode_did(phba, NameServer_DID);
447 lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, 447 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
448 NameServer_DID);
449 if (ndlp) {
450 if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 448 if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) ==
451 0) { 449 0) {
452 goto out; 450 goto out;
@@ -730,7 +728,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
730 uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; 728 uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
731 uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; 729 uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
732 730
733 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); 731 ndlp = lpfc_findnode_did(phba, FDMI_DID);
734 if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { 732 if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
735 /* FDMI rsp failed */ 733 /* FDMI rsp failed */
736 lpfc_printf_log(phba, 734 lpfc_printf_log(phba,
@@ -1162,7 +1160,7 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
1162{ 1160{
1163 struct lpfc_nodelist *ndlp; 1161 struct lpfc_nodelist *ndlp;
1164 1162
1165 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); 1163 ndlp = lpfc_findnode_did(phba, FDMI_DID);
1166 if (ndlp) { 1164 if (ndlp) {
1167 if (init_utsname()->nodename[0] != '\0') { 1165 if (init_utsname()->nodename[0] != '\0') {
1168 lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA); 1166 lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 4561327c9946..971b0f80ca7f 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -83,15 +83,6 @@ struct lpfc_nodelist {
83}; 83};
84 84
85/* Defines for nlp_flag (uint32) */ 85/* Defines for nlp_flag (uint32) */
86#define NLP_UNUSED_LIST 0x1 /* Flg to indicate node will be freed */
87#define NLP_PLOGI_LIST 0x2 /* Flg to indicate sent PLOGI */
88#define NLP_ADISC_LIST 0x3 /* Flg to indicate sent ADISC */
89#define NLP_REGLOGIN_LIST 0x4 /* Flg to indicate sent REG_LOGIN */
90#define NLP_PRLI_LIST 0x5 /* Flg to indicate sent PRLI */
91#define NLP_UNMAPPED_LIST 0x6 /* Node is now unmapped */
92#define NLP_MAPPED_LIST 0x7 /* Node is now mapped */
93#define NLP_NPR_LIST 0x8 /* Node is in NPort Recovery state */
94#define NLP_LIST_MASK 0xf /* mask to see what list node is on */
95#define NLP_PLOGI_SND 0x20 /* sent PLOGI request for this entry */ 86#define NLP_PLOGI_SND 0x20 /* sent PLOGI request for this entry */
96#define NLP_PRLI_SND 0x40 /* sent PRLI request for this entry */ 87#define NLP_PRLI_SND 0x40 /* sent PRLI request for this entry */
97#define NLP_ADISC_SND 0x80 /* sent ADISC request for this entry */ 88#define NLP_ADISC_SND 0x80 /* sent ADISC request for this entry */
@@ -109,17 +100,6 @@ struct lpfc_nodelist {
109 NPR list */ 100 NPR list */
110#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ 101#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */
111 102
112/* Defines for list searchs */
113#define NLP_SEARCH_MAPPED 0x1 /* search mapped */
114#define NLP_SEARCH_UNMAPPED 0x2 /* search unmapped */
115#define NLP_SEARCH_PLOGI 0x4 /* search plogi */
116#define NLP_SEARCH_ADISC 0x8 /* search adisc */
117#define NLP_SEARCH_REGLOGIN 0x10 /* search reglogin */
118#define NLP_SEARCH_PRLI 0x20 /* search prli */
119#define NLP_SEARCH_NPR 0x40 /* search npr */
120#define NLP_SEARCH_UNUSED 0x80 /* search mapped */
121#define NLP_SEARCH_ALL 0xff /* search all lists */
122
123/* There are 4 different double linked lists nodelist entries can reside on. 103/* There are 4 different double linked lists nodelist entries can reside on.
124 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used 104 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
125 * when Link Up discovery or Registered State Change Notification (RSCN) 105 * 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 cb63c350c215..ddf7f225ba5c 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -372,7 +372,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
372 } 372 }
373 lpfc_nlp_put(ndlp); 373 lpfc_nlp_put(ndlp);
374 374
375 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); 375 ndlp = lpfc_findnode_did(phba, PT2PT_RemoteID);
376 if (!ndlp) { 376 if (!ndlp) {
377 /* 377 /*
378 * Cannot find existing Fabric ndlp, so allocate a 378 * Cannot find existing Fabric ndlp, so allocate a
@@ -592,12 +592,12 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
592} 592}
593 593
594int 594int
595lpfc_initial_flogi(struct lpfc_hba * phba) 595lpfc_initial_flogi(struct lpfc_hba *phba)
596{ 596{
597 struct lpfc_nodelist *ndlp; 597 struct lpfc_nodelist *ndlp;
598 598
599 /* First look for the Fabric ndlp */ 599 /* First look for the Fabric ndlp */
600 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID); 600 ndlp = lpfc_findnode_did(phba, Fabric_DID);
601 if (!ndlp) { 601 if (!ndlp) {
602 /* Cannot find existing Fabric ndlp, so allocate a new one */ 602 /* Cannot find existing Fabric ndlp, so allocate a new one */
603 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); 603 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
@@ -637,7 +637,7 @@ lpfc_more_plogi(struct lpfc_hba * phba)
637} 637}
638 638
639static struct lpfc_nodelist * 639static struct lpfc_nodelist *
640lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, 640lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp,
641 struct lpfc_nodelist *ndlp) 641 struct lpfc_nodelist *ndlp)
642{ 642{
643 struct lpfc_nodelist *new_ndlp; 643 struct lpfc_nodelist *new_ndlp;
@@ -654,12 +654,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
654 654
655 lp = (uint32_t *) prsp->virt; 655 lp = (uint32_t *) prsp->virt;
656 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); 656 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
657 memset(name, 0, sizeof (struct lpfc_name)); 657 memset(name, 0, sizeof(struct lpfc_name));
658 658
659 /* Now we to find out if the NPort we are logging into, matches the WWPN 659 /* Now we find out if the NPort we are logging into, matches the WWPN
660 * we have for that ndlp. If not, we have some work to do. 660 * we have for that ndlp. If not, we have some work to do.
661 */ 661 */
662 new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); 662 new_ndlp = lpfc_findnode_wwpn(phba, &sp->portName);
663 663
664 if (new_ndlp == ndlp) 664 if (new_ndlp == ndlp)
665 return ndlp; 665 return ndlp;
@@ -705,8 +705,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
705 cmdiocb->context_un.rsp_iocb = rspiocb; 705 cmdiocb->context_un.rsp_iocb = rspiocb;
706 706
707 irsp = &rspiocb->iocb; 707 irsp = &rspiocb->iocb;
708 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, 708 ndlp = lpfc_findnode_did(phba, irsp->un.elsreq64.remoteID);
709 irsp->un.elsreq64.remoteID);
710 if (!ndlp) 709 if (!ndlp)
711 goto out; 710 goto out;
712 711
@@ -1408,7 +1407,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
1408 1407
1409 memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name)); 1408 memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name));
1410 memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); 1409 memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name));
1411 if ((ondlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, nportid))) { 1410 if ((ondlp = lpfc_findnode_did(phba, nportid))) {
1412 memcpy(&fp->OportName, &ondlp->nlp_portname, 1411 memcpy(&fp->OportName, &ondlp->nlp_portname,
1413 sizeof (struct lpfc_name)); 1412 sizeof (struct lpfc_name));
1414 memcpy(&fp->OnodeName, &ondlp->nlp_nodename, 1413 memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
@@ -1595,7 +1594,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
1595 else { 1594 else {
1596 /* We should only hit this case for retrying PLOGI */ 1595 /* We should only hit this case for retrying PLOGI */
1597 did = irsp->un.elsreq64.remoteID; 1596 did = irsp->un.elsreq64.remoteID;
1598 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); 1597 ndlp = lpfc_findnode_did(phba, did);
1599 if (!ndlp && (cmd != ELS_CMD_PLOGI)) 1598 if (!ndlp && (cmd != ELS_CMD_PLOGI))
1600 return 1; 1599 return 1;
1601 } 1600 }
@@ -2291,31 +2290,31 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
2291} 2290}
2292 2291
2293int 2292int
2294lpfc_els_disc_adisc(struct lpfc_hba * phba) 2293lpfc_els_disc_adisc(struct lpfc_hba *phba)
2295{ 2294{
2296 int sentadisc; 2295 int sentadisc;
2297 struct lpfc_nodelist *ndlp, *next_ndlp; 2296 struct lpfc_nodelist *ndlp, *next_ndlp;
2298 2297
2299 sentadisc = 0; 2298 sentadisc = 0;
2300 /* go thru NPR list and issue any remaining ELS ADISCs */ 2299 /* go thru NPR nodes and issue any remaining ELS ADISCs */
2301 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 2300 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
2302 nlp_listp) { 2301 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2303 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { 2302 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2304 if (ndlp->nlp_flag & NLP_NPR_ADISC) { 2303 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
2305 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 2304 spin_lock_irq(phba->host->host_lock);
2306 ndlp->nlp_prev_state = ndlp->nlp_state; 2305 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2307 lpfc_nlp_set_state(phba, ndlp, 2306 spin_unlock_irq(phba->host->host_lock);
2308 NLP_STE_ADISC_ISSUE); 2307 ndlp->nlp_prev_state = ndlp->nlp_state;
2309 lpfc_issue_els_adisc(phba, ndlp, 0); 2308 lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE);
2310 sentadisc++; 2309 lpfc_issue_els_adisc(phba, ndlp, 0);
2311 phba->num_disc_nodes++; 2310 sentadisc++;
2312 if (phba->num_disc_nodes >= 2311 phba->num_disc_nodes++;
2313 phba->cfg_discovery_threads) { 2312 if (phba->num_disc_nodes >=
2314 spin_lock_irq(phba->host->host_lock); 2313 phba->cfg_discovery_threads) {
2315 phba->fc_flag |= FC_NLP_MORE; 2314 spin_lock_irq(phba->host->host_lock);
2316 spin_unlock_irq(phba->host->host_lock); 2315 phba->fc_flag |= FC_NLP_MORE;
2317 break; 2316 spin_unlock_irq(phba->host->host_lock);
2318 } 2317 break;
2319 } 2318 }
2320 } 2319 }
2321 } 2320 }
@@ -2335,24 +2334,22 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba)
2335 2334
2336 sentplogi = 0; 2335 sentplogi = 0;
2337 /* go thru NPR list and issue any remaining ELS PLOGIs */ 2336 /* go thru NPR list and issue any remaining ELS PLOGIs */
2338 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 2337 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
2339 nlp_listp) { 2338 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2340 if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && 2339 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2341 (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { 2340 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
2342 if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 2341 (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
2343 ndlp->nlp_prev_state = ndlp->nlp_state; 2342 ndlp->nlp_prev_state = ndlp->nlp_state;
2344 lpfc_nlp_set_state(phba, ndlp, 2343 lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
2345 NLP_STE_PLOGI_ISSUE); 2344 lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0);
2346 lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); 2345 sentplogi++;
2347 sentplogi++; 2346 phba->num_disc_nodes++;
2348 phba->num_disc_nodes++; 2347 if (phba->num_disc_nodes >=
2349 if (phba->num_disc_nodes >= 2348 phba->cfg_discovery_threads) {
2350 phba->cfg_discovery_threads) { 2349 spin_lock_irq(phba->host->host_lock);
2351 spin_lock_irq(phba->host->host_lock); 2350 phba->fc_flag |= FC_NLP_MORE;
2352 phba->fc_flag |= FC_NLP_MORE; 2351 spin_unlock_irq(phba->host->host_lock);
2353 spin_unlock_irq(phba->host->host_lock); 2352 break;
2354 break;
2355 }
2356 } 2353 }
2357 } 2354 }
2358 } 2355 }
@@ -2456,40 +2453,28 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
2456static int 2453static int
2457lpfc_rscn_recovery_check(struct lpfc_hba *phba) 2454lpfc_rscn_recovery_check(struct lpfc_hba *phba)
2458{ 2455{
2459 struct lpfc_nodelist *ndlp = NULL, *next_ndlp; 2456 struct lpfc_nodelist *ndlp = NULL;
2460 struct list_head *listp;
2461 struct list_head *node_list[7];
2462 int i;
2463 2457
2464 /* Look at all nodes effected by pending RSCNs and move 2458 /* Look at all nodes effected by pending RSCNs and move
2465 * them to NPR list. 2459 * them to NPR state.
2466 */ 2460 */
2467 node_list[0] = &phba->fc_npr_list; /* MUST do this list first */
2468 node_list[1] = &phba->fc_nlpmap_list;
2469 node_list[2] = &phba->fc_nlpunmap_list;
2470 node_list[3] = &phba->fc_prli_list;
2471 node_list[4] = &phba->fc_reglogin_list;
2472 node_list[5] = &phba->fc_adisc_list;
2473 node_list[6] = &phba->fc_plogi_list;
2474 for (i = 0; i < 7; i++) {
2475 listp = node_list[i];
2476 if (list_empty(listp))
2477 continue;
2478 2461
2479 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { 2462 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
2480 if (!(lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) 2463 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE ||
2481 continue; 2464 lpfc_rscn_payload_check(phba, ndlp->nlp_DID) == 0)
2465 continue;
2482 2466
2483 lpfc_disc_state_machine(phba, ndlp, NULL, 2467 lpfc_disc_state_machine(phba, ndlp, NULL,
2484 NLP_EVT_DEVICE_RECOVERY); 2468 NLP_EVT_DEVICE_RECOVERY);
2485 2469
2486 /* Make sure NLP_DELAY_TMO is NOT running 2470 /*
2487 * after a device recovery event. 2471 * Make sure NLP_DELAY_TMO is NOT running after a device
2488 */ 2472 * recovery event.
2489 if (ndlp->nlp_flag & NLP_DELAY_TMO) 2473 */
2490 lpfc_cancel_retry_delay_tmo(phba, ndlp); 2474 if (ndlp->nlp_flag & NLP_DELAY_TMO)
2491 } 2475 lpfc_cancel_retry_delay_tmo(phba, ndlp);
2492 } 2476 }
2477
2493 return 0; 2478 return 0;
2494} 2479}
2495 2480
@@ -2614,8 +2599,8 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
2614 2599
2615 /* To process RSCN, first compare RSCN data with NameServer */ 2600 /* To process RSCN, first compare RSCN data with NameServer */
2616 phba->fc_ns_retry = 0; 2601 phba->fc_ns_retry = 0;
2617 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID); 2602 ndlp = lpfc_findnode_did(phba, NameServer_DID);
2618 if (ndlp) { 2603 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
2619 /* Good ndlp, issue CT Request to NameServer */ 2604 /* Good ndlp, issue CT Request to NameServer */
2620 if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { 2605 if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) {
2621 /* Wait for NameServer query cmpl before we can 2606 /* Wait for NameServer query cmpl before we can
@@ -2625,7 +2610,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
2625 } else { 2610 } else {
2626 /* If login to NameServer does not exist, issue one */ 2611 /* If login to NameServer does not exist, issue one */
2627 /* Good status, issue PLOGI to NameServer */ 2612 /* Good status, issue PLOGI to NameServer */
2628 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); 2613 ndlp = lpfc_findnode_did(phba, NameServer_DID);
2629 if (ndlp) { 2614 if (ndlp) {
2630 /* Wait for NameServer login cmpl before we can 2615 /* Wait for NameServer login cmpl before we can
2631 continue */ 2616 continue */
@@ -2859,6 +2844,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2859 2844
2860 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; 2845 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2861 phba->fc_stat.elsXmitACC++; 2846 phba->fc_stat.elsXmitACC++;
2847
2862 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { 2848 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2863 lpfc_els_free_iocb(phba, elsiocb); 2849 lpfc_els_free_iocb(phba, elsiocb);
2864 } 2850 }
@@ -3144,8 +3130,9 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
3144 */ 3130 */
3145 3131
3146 list_for_each_entry_safe(ndlp, next_ndlp, 3132 list_for_each_entry_safe(ndlp, next_ndlp,
3147 &phba->fc_npr_list, nlp_listp) { 3133 &phba->fc_nodes, nlp_listp) {
3148 3134 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3135 continue;
3149 if (ndlp->nlp_type & NLP_FABRIC) { 3136 if (ndlp->nlp_type & NLP_FABRIC) {
3150 /* 3137 /*
3151 * Clean up old Fabric, Nameserver and 3138 * Clean up old Fabric, Nameserver and
@@ -3168,8 +3155,10 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
3168 /* Discovery not needed, 3155 /* Discovery not needed,
3169 * move the nodes to their original state. 3156 * move the nodes to their original state.
3170 */ 3157 */
3171 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 3158 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
3172 nlp_listp) { 3159 nlp_listp) {
3160 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3161 continue;
3173 3162
3174 switch (ndlp->nlp_prev_state) { 3163 switch (ndlp->nlp_prev_state) {
3175 case NLP_STE_UNMAPPED_NODE: 3164 case NLP_STE_UNMAPPED_NODE:
@@ -3409,7 +3398,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
3409 } 3398 }
3410 3399
3411 did = icmd->un.rcvels.remoteID; 3400 did = icmd->un.rcvels.remoteID;
3412 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); 3401 ndlp = lpfc_findnode_did(phba, did);
3413 if (!ndlp) { 3402 if (!ndlp) {
3414 /* Cannot find existing Fabric ndlp, so allocate a new one */ 3403 /* Cannot find existing Fabric ndlp, so allocate a new one */
3415 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); 3404 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 8ba2f4eadcdd..0ebde2463005 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -374,13 +374,12 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
374} 374}
375 375
376int 376int
377lpfc_linkdown(struct lpfc_hba * phba) 377lpfc_linkdown(struct lpfc_hba *phba)
378{ 378{
379 struct lpfc_sli *psli; 379 struct lpfc_sli *psli;
380 struct lpfc_nodelist *ndlp, *next_ndlp; 380 struct lpfc_nodelist *ndlp, *next_ndlp;
381 struct list_head *listp, *node_list[7]; 381 LPFC_MBOXQ_t *mb;
382 LPFC_MBOXQ_t *mb; 382 int rc;
383 int rc, i;
384 383
385 psli = &phba->sli; 384 psli = &phba->sli;
386 /* sysfs or selective reset may call this routine to clean up */ 385 /* sysfs or selective reset may call this routine to clean up */
@@ -412,32 +411,18 @@ lpfc_linkdown(struct lpfc_hba * phba)
412 /* Cleanup any outstanding ELS commands */ 411 /* Cleanup any outstanding ELS commands */
413 lpfc_els_flush_cmd(phba); 412 lpfc_els_flush_cmd(phba);
414 413
415 /* Issue a LINK DOWN event to all nodes */ 414 /*
416 node_list[0] = &phba->fc_npr_list; /* MUST do this list first */ 415 * Issue a LINK DOWN event to all nodes.
417 node_list[1] = &phba->fc_nlpmap_list; 416 */
418 node_list[2] = &phba->fc_nlpunmap_list; 417 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
419 node_list[3] = &phba->fc_prli_list; 418 /* free any ndlp's on unused list */
420 node_list[4] = &phba->fc_reglogin_list; 419 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
421 node_list[5] = &phba->fc_adisc_list; 420 lpfc_drop_node(phba, ndlp);
422 node_list[6] = &phba->fc_plogi_list; 421 else /* otherwise, force node recovery. */
423 for (i = 0; i < 7; i++) {
424 listp = node_list[i];
425 if (list_empty(listp))
426 continue;
427
428 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
429
430 rc = lpfc_disc_state_machine(phba, ndlp, NULL, 422 rc = lpfc_disc_state_machine(phba, ndlp, NULL,
431 NLP_EVT_DEVICE_RECOVERY); 423 NLP_EVT_DEVICE_RECOVERY);
432
433 }
434 } 424 }
435 425
436 /* free any ndlp's on unused list */
437 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list,
438 nlp_listp)
439 lpfc_drop_node(phba, ndlp);
440
441 /* Setup myDID for link up if we are in pt2pt mode */ 426 /* Setup myDID for link up if we are in pt2pt mode */
442 if (phba->fc_flag & FC_PT2PT) { 427 if (phba->fc_flag & FC_PT2PT) {
443 phba->fc_myDID = 0; 428 phba->fc_myDID = 0;
@@ -466,11 +451,9 @@ lpfc_linkdown(struct lpfc_hba * phba)
466} 451}
467 452
468static int 453static int
469lpfc_linkup(struct lpfc_hba * phba) 454lpfc_linkup(struct lpfc_hba *phba)
470{ 455{
471 struct lpfc_nodelist *ndlp, *next_ndlp; 456 struct lpfc_nodelist *ndlp, *next_ndlp;
472 struct list_head *listp, *node_list[7];
473 int i;
474 457
475 fc_host_post_event(phba->host, fc_get_event_number(), 458 fc_host_post_event(phba->host, fc_get_event_number(),
476 FCH_EVT_LINKUP, 0); 459 FCH_EVT_LINKUP, 0);
@@ -484,29 +467,20 @@ lpfc_linkup(struct lpfc_hba * phba)
484 spin_unlock_irq(phba->host->host_lock); 467 spin_unlock_irq(phba->host->host_lock);
485 468
486 469
487 node_list[0] = &phba->fc_plogi_list; 470 if (phba->fc_flag & FC_LBIT) {
488 node_list[1] = &phba->fc_adisc_list; 471 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
489 node_list[2] = &phba->fc_reglogin_list; 472 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) {
490 node_list[3] = &phba->fc_prli_list;
491 node_list[4] = &phba->fc_nlpunmap_list;
492 node_list[5] = &phba->fc_nlpmap_list;
493 node_list[6] = &phba->fc_npr_list;
494 for (i = 0; i < 7; i++) {
495 listp = node_list[i];
496 if (list_empty(listp))
497 continue;
498
499 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
500 if (phba->fc_flag & FC_LBIT) {
501 if (ndlp->nlp_type & NLP_FABRIC) { 473 if (ndlp->nlp_type & NLP_FABRIC) {
502 /* On Linkup its safe to clean up the 474 /*
475 * On Linkup its safe to clean up the
503 * ndlp from Fabric connections. 476 * ndlp from Fabric connections.
504 */ 477 */
505 lpfc_nlp_set_state(phba, ndlp, 478 lpfc_nlp_set_state(phba, ndlp,
506 NLP_STE_UNUSED_NODE); 479 NLP_STE_UNUSED_NODE);
507 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 480 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
508 /* Fail outstanding IO now since device 481 /*
509 * is marked for PLOGI. 482 * Fail outstanding IO now since
483 * device is marked for PLOGI.
510 */ 484 */
511 lpfc_unreg_rpi(phba, ndlp); 485 lpfc_unreg_rpi(phba, ndlp);
512 } 486 }
@@ -515,9 +489,11 @@ lpfc_linkup(struct lpfc_hba * phba)
515 } 489 }
516 490
517 /* free any ndlp's on unused list */ 491 /* free any ndlp's on unused list */
518 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, 492 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
519 nlp_listp) 493 nlp_listp) {
520 lpfc_drop_node(phba, ndlp); 494 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
495 lpfc_drop_node(phba, ndlp);
496 }
521 497
522 return 0; 498 return 0;
523} 499}
@@ -1021,7 +997,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1021 */ 997 */
1022 lpfc_issue_els_scr(phba, SCR_DID, 0); 998 lpfc_issue_els_scr(phba, SCR_DID, 0);
1023 999
1024 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); 1000 ndlp = lpfc_findnode_did(phba, NameServer_DID);
1025 if (!ndlp) { 1001 if (!ndlp) {
1026 /* Allocate a new node instance. If the pool is empty, 1002 /* Allocate a new node instance. If the pool is empty,
1027 * start the discovery process and skip the Nameserver 1003 * start the discovery process and skip the Nameserver
@@ -1200,6 +1176,7 @@ lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1200static void 1176static void
1201lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count) 1177lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count)
1202{ 1178{
1179 spin_lock_irq(phba->host->host_lock);
1203 switch (state) { 1180 switch (state) {
1204 case NLP_STE_UNUSED_NODE: 1181 case NLP_STE_UNUSED_NODE:
1205 phba->fc_unused_cnt += count; 1182 phba->fc_unused_cnt += count;
@@ -1226,107 +1203,7 @@ lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count)
1226 phba->fc_npr_cnt += count; 1203 phba->fc_npr_cnt += count;
1227 break; 1204 break;
1228 } 1205 }
1229}
1230
1231void
1232lpfc_delink_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1233{
1234 switch (ndlp->nlp_flag & NLP_LIST_MASK) {
1235 case NLP_UNUSED_LIST:
1236 list_del_init(&ndlp->nlp_listp);
1237 break;
1238 case NLP_PLOGI_LIST:
1239 list_del_init(&ndlp->nlp_listp);
1240 break;
1241 case NLP_ADISC_LIST:
1242 list_del_init(&ndlp->nlp_listp);
1243 break;
1244 case NLP_REGLOGIN_LIST:
1245 list_del_init(&ndlp->nlp_listp);
1246 break;
1247 case NLP_PRLI_LIST:
1248 list_del_init(&ndlp->nlp_listp);
1249 break;
1250 case NLP_UNMAPPED_LIST:
1251 list_del_init(&ndlp->nlp_listp);
1252 break;
1253 case NLP_MAPPED_LIST:
1254 list_del_init(&ndlp->nlp_listp);
1255 break;
1256 case NLP_NPR_LIST:
1257 list_del_init(&ndlp->nlp_listp);
1258 break;
1259 }
1260
1261 ndlp->nlp_flag &= ~NLP_LIST_MASK;
1262}
1263
1264static int
1265lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1266{
1267 struct lpfc_sli *psli;
1268
1269 psli = &phba->sli;
1270 /* Sanity check to ensure we are not moving to / from the same list */
1271 if ((nlp->nlp_flag & NLP_LIST_MASK) == list)
1272 return 0;
1273
1274 spin_lock_irq(phba->host->host_lock);
1275 lpfc_delink_node(phba, nlp);
1276
1277 /* Add NPort <did> to <num> list */
1278 lpfc_printf_log(phba,
1279 KERN_INFO,
1280 LOG_NODE,
1281 "%d:0904 Add NPort x%x to %d list Data: x%x\n",
1282 phba->brd_no,
1283 nlp->nlp_DID, list, nlp->nlp_flag);
1284
1285 switch (list) {
1286 case NLP_UNUSED_LIST:
1287 nlp->nlp_flag |= list;
1288 /* Put it at the end of the unused list */
1289 list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list);
1290 break;
1291 case NLP_PLOGI_LIST:
1292 nlp->nlp_flag |= list;
1293 /* Put it at the end of the plogi list */
1294 list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list);
1295 break;
1296 case NLP_ADISC_LIST:
1297 nlp->nlp_flag |= list;
1298 /* Put it at the end of the adisc list */
1299 list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list);
1300 break;
1301 case NLP_REGLOGIN_LIST:
1302 nlp->nlp_flag |= list;
1303 /* Put it at the end of the reglogin list */
1304 list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list);
1305 break;
1306 case NLP_PRLI_LIST:
1307 nlp->nlp_flag |= list;
1308 /* Put it at the end of the prli list */
1309 list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list);
1310 break;
1311 case NLP_UNMAPPED_LIST:
1312 nlp->nlp_flag |= list;
1313 /* Put it at the end of the unmap list */
1314 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list);
1315 break;
1316 case NLP_MAPPED_LIST:
1317 nlp->nlp_flag |= list;
1318 /* Put it at the end of the map list */
1319 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list);
1320 break;
1321 case NLP_NPR_LIST:
1322 nlp->nlp_flag |= list;
1323 /* Put it at the end of the npr list */
1324 list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list);
1325 break;
1326 }
1327
1328 spin_unlock_irq(phba->host->host_lock); 1206 spin_unlock_irq(phba->host->host_lock);
1329 return 0;
1330} 1207}
1331 1208
1332static void 1209static void
@@ -1378,21 +1255,39 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
1378 } 1255 }
1379} 1256}
1380 1257
1258static char *
1259lpfc_nlp_state_name(char *buffer, size_t size, int state)
1260{
1261 static char *states[] = {
1262 [NLP_STE_UNUSED_NODE] = "UNUSED",
1263 [NLP_STE_PLOGI_ISSUE] = "PLOGI",
1264 [NLP_STE_ADISC_ISSUE] = "ADISC",
1265 [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
1266 [NLP_STE_PRLI_ISSUE] = "PRLI",
1267 [NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
1268 [NLP_STE_MAPPED_NODE] = "MAPPED",
1269 [NLP_STE_NPR_NODE] = "NPR",
1270 };
1271
1272 if (state < ARRAY_SIZE(states) && states[state])
1273 strlcpy(buffer, states[state], size);
1274 else
1275 snprintf(buffer, size, "unknown (%d)", state);
1276 return buffer;
1277}
1278
1381void 1279void
1382lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state) 1280lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state)
1383{ 1281{
1384 int old_state = ndlp->nlp_state; 1282 int old_state = ndlp->nlp_state;
1385 static int list_id[] = { 1283 char name1[16], name2[16];
1386 [NLP_STE_UNUSED_NODE] = NLP_UNUSED_LIST,
1387 [NLP_STE_PLOGI_ISSUE] = NLP_PLOGI_LIST,
1388 [NLP_STE_ADISC_ISSUE] = NLP_ADISC_LIST,
1389 [NLP_STE_REG_LOGIN_ISSUE] = NLP_REGLOGIN_LIST,
1390 [NLP_STE_PRLI_ISSUE] = NLP_PRLI_LIST,
1391 [NLP_STE_UNMAPPED_NODE] = NLP_UNMAPPED_LIST,
1392 [NLP_STE_MAPPED_NODE] = NLP_MAPPED_LIST,
1393 [NLP_STE_NPR_NODE] = NLP_NPR_LIST,
1394 };
1395 1284
1285 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
1286 "%d:0904 NPort state transition x%06x, %s -> %s\n",
1287 phba->brd_no,
1288 ndlp->nlp_DID,
1289 lpfc_nlp_state_name(name1, sizeof(name1), old_state),
1290 lpfc_nlp_state_name(name2, sizeof(name2), state));
1396 if (old_state == NLP_STE_NPR_NODE && 1291 if (old_state == NLP_STE_NPR_NODE &&
1397 (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && 1292 (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 &&
1398 state != NLP_STE_NPR_NODE) 1293 state != NLP_STE_NPR_NODE)
@@ -1402,13 +1297,15 @@ lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state)
1402 ndlp->nlp_type &= ~NLP_FC_NODE; 1297 ndlp->nlp_type &= ~NLP_FC_NODE;
1403 } 1298 }
1404 1299
1405 if (old_state && !list_empty(&ndlp->nlp_listp)) 1300 if (list_empty(&ndlp->nlp_listp)) {
1301 spin_lock_irq(phba->host->host_lock);
1302 list_add_tail(&ndlp->nlp_listp, &phba->fc_nodes);
1303 spin_unlock_irq(phba->host->host_lock);
1304 } else if (old_state)
1406 lpfc_nlp_counters(phba, old_state, -1); 1305 lpfc_nlp_counters(phba, old_state, -1);
1407 1306
1408 ndlp->nlp_state = state; 1307 ndlp->nlp_state = state;
1409 lpfc_nlp_list(phba, ndlp, list_id[state]);
1410 lpfc_nlp_counters(phba, state, 1); 1308 lpfc_nlp_counters(phba, state, 1);
1411
1412 lpfc_nlp_state_cleanup(phba, ndlp, old_state, state); 1309 lpfc_nlp_state_cleanup(phba, ndlp, old_state, state);
1413} 1310}
1414 1311
@@ -1417,10 +1314,10 @@ lpfc_dequeue_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1417{ 1314{
1418 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) 1315 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
1419 lpfc_cancel_retry_delay_tmo(phba, ndlp); 1316 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1420 spin_lock_irq(phba->host->host_lock);
1421 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) 1317 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1422 lpfc_nlp_counters(phba, ndlp->nlp_state, -1); 1318 lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
1423 lpfc_delink_node(phba, ndlp); 1319 spin_lock_irq(phba->host->host_lock);
1320 list_del_init(&ndlp->nlp_listp);
1424 spin_unlock_irq(phba->host->host_lock); 1321 spin_unlock_irq(phba->host->host_lock);
1425 lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0); 1322 lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0);
1426} 1323}
@@ -1430,10 +1327,10 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1430{ 1327{
1431 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) 1328 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
1432 lpfc_cancel_retry_delay_tmo(phba, ndlp); 1329 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1433 spin_lock_irq(phba->host->host_lock);
1434 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) 1330 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1435 lpfc_nlp_counters(phba, ndlp->nlp_state, -1); 1331 lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
1436 lpfc_delink_node(phba, ndlp); 1332 spin_lock_irq(phba->host->host_lock);
1333 list_del_init(&ndlp->nlp_listp);
1437 spin_unlock_irq(phba->host->host_lock); 1334 spin_unlock_irq(phba->host->host_lock);
1438 lpfc_nlp_put(ndlp); 1335 lpfc_nlp_put(ndlp);
1439} 1336}
@@ -1638,7 +1535,7 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1638 * so it can be freed. 1535 * so it can be freed.
1639 */ 1536 */
1640static int 1537static int
1641lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1538lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1642{ 1539{
1643 LPFC_MBOXQ_t *mb; 1540 LPFC_MBOXQ_t *mb;
1644 LPFC_MBOXQ_t *nextmb; 1541 LPFC_MBOXQ_t *nextmb;
@@ -1708,7 +1605,7 @@ lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1708 lpfc_cancel_retry_delay_tmo(phba, ndlp); 1605 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1709 } 1606 }
1710 1607
1711 lpfc_freenode(phba, ndlp); 1608 lpfc_cleanup_node(phba, ndlp);
1712 1609
1713 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { 1610 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
1714 put_device(&ndlp->rport->dev); 1611 put_device(&ndlp->rport->dev);
@@ -1719,7 +1616,7 @@ lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1719} 1616}
1720 1617
1721static int 1618static int
1722lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) 1619lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
1723{ 1620{
1724 D_ID mydid; 1621 D_ID mydid;
1725 D_ID ndlpdid; 1622 D_ID ndlpdid;
@@ -1768,57 +1665,36 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did)
1768 return 0; 1665 return 0;
1769} 1666}
1770 1667
1771/* Search for a nodelist entry on a specific list */ 1668/* Search for a nodelist entry */
1772struct lpfc_nodelist * 1669struct lpfc_nodelist *
1773lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) 1670lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did)
1774{ 1671{
1775 struct lpfc_nodelist *ndlp; 1672 struct lpfc_nodelist *ndlp;
1776 struct list_head *lists[]={&phba->fc_nlpunmap_list,
1777 &phba->fc_nlpmap_list,
1778 &phba->fc_plogi_list,
1779 &phba->fc_adisc_list,
1780 &phba->fc_reglogin_list,
1781 &phba->fc_prli_list,
1782 &phba->fc_npr_list,
1783 &phba->fc_unused_list};
1784 uint32_t search[]={NLP_SEARCH_UNMAPPED,
1785 NLP_SEARCH_MAPPED,
1786 NLP_SEARCH_PLOGI,
1787 NLP_SEARCH_ADISC,
1788 NLP_SEARCH_REGLOGIN,
1789 NLP_SEARCH_PRLI,
1790 NLP_SEARCH_NPR,
1791 NLP_SEARCH_UNUSED};
1792 int i;
1793 uint32_t data1; 1673 uint32_t data1;
1794 1674
1795 spin_lock_irq(phba->host->host_lock); 1675 spin_lock_irq(phba->host->host_lock);
1796 for (i = 0; i < ARRAY_SIZE(lists); i++ ) { 1676 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
1797 if (!(order & search[i])) 1677 if (lpfc_matchdid(phba, ndlp, did)) {
1798 continue; 1678 data1 = (((uint32_t) ndlp->nlp_state << 24) |
1799 list_for_each_entry(ndlp, lists[i], nlp_listp) { 1679 ((uint32_t) ndlp->nlp_xri << 16) |
1800 if (lpfc_matchdid(phba, ndlp, did)) { 1680 ((uint32_t) ndlp->nlp_type << 8) |
1801 data1 = (((uint32_t) ndlp->nlp_state << 24) | 1681 ((uint32_t) ndlp->nlp_rpi & 0xff));
1802 ((uint32_t) ndlp->nlp_xri << 16) | 1682 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
1803 ((uint32_t) ndlp->nlp_type << 8) | 1683 "%d:0929 FIND node DID "
1804 ((uint32_t) ndlp->nlp_rpi & 0xff)); 1684 " Data: x%p x%x x%x x%x\n",
1805 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1685 phba->brd_no,
1806 "%d:0929 FIND node DID " 1686 ndlp, ndlp->nlp_DID,
1807 " Data: x%p x%x x%x x%x\n", 1687 ndlp->nlp_flag, data1);
1808 phba->brd_no, 1688 spin_unlock_irq(phba->host->host_lock);
1809 ndlp, ndlp->nlp_DID, 1689 return ndlp;
1810 ndlp->nlp_flag, data1);
1811 spin_unlock_irq(phba->host->host_lock);
1812 return ndlp;
1813 }
1814 } 1690 }
1815 } 1691 }
1816 spin_unlock_irq(phba->host->host_lock); 1692 spin_unlock_irq(phba->host->host_lock);
1817 1693
1818 /* FIND node did <did> NOT FOUND */ 1694 /* FIND node did <did> NOT FOUND */
1819 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1695 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
1820 "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", 1696 "%d:0932 FIND node did x%x NOT FOUND.\n",
1821 phba->brd_no, did, order); 1697 phba->brd_no, did);
1822 return NULL; 1698 return NULL;
1823} 1699}
1824 1700
@@ -1826,9 +1702,8 @@ struct lpfc_nodelist *
1826lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) 1702lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1827{ 1703{
1828 struct lpfc_nodelist *ndlp; 1704 struct lpfc_nodelist *ndlp;
1829 uint32_t flg;
1830 1705
1831 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); 1706 ndlp = lpfc_findnode_did(phba, did);
1832 if (!ndlp) { 1707 if (!ndlp) {
1833 if ((phba->fc_flag & FC_RSCN_MODE) && 1708 if ((phba->fc_flag & FC_RSCN_MODE) &&
1834 ((lpfc_rscn_payload_check(phba, did) == 0))) 1709 ((lpfc_rscn_payload_check(phba, did) == 0)))
@@ -1854,8 +1729,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1854 } else 1729 } else
1855 ndlp = NULL; 1730 ndlp = NULL;
1856 } else { 1731 } else {
1857 flg = ndlp->nlp_flag & NLP_LIST_MASK; 1732 if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE ||
1858 if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST)) 1733 ndlp->nlp_state == NLP_STE_PLOGI_ISSUE)
1859 return NULL; 1734 return NULL;
1860 lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); 1735 lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
1861 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 1736 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
@@ -1915,8 +1790,9 @@ lpfc_disc_start(struct lpfc_hba * phba)
1915 struct lpfc_sli *psli; 1790 struct lpfc_sli *psli;
1916 LPFC_MBOXQ_t *mbox; 1791 LPFC_MBOXQ_t *mbox;
1917 struct lpfc_nodelist *ndlp, *next_ndlp; 1792 struct lpfc_nodelist *ndlp, *next_ndlp;
1918 uint32_t did_changed, num_sent; 1793 uint32_t num_sent;
1919 uint32_t clear_la_pending; 1794 uint32_t clear_la_pending;
1795 int did_changed;
1920 int rc; 1796 int rc;
1921 1797
1922 psli = &phba->sli; 1798 psli = &phba->sli;
@@ -1950,14 +1826,13 @@ lpfc_disc_start(struct lpfc_hba * phba)
1950 phba->fc_plogi_cnt, phba->fc_adisc_cnt); 1826 phba->fc_plogi_cnt, phba->fc_adisc_cnt);
1951 1827
1952 /* If our did changed, we MUST do PLOGI */ 1828 /* If our did changed, we MUST do PLOGI */
1953 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 1829 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
1954 nlp_listp) { 1830 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
1955 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { 1831 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
1956 if (did_changed) { 1832 did_changed) {
1957 spin_lock_irq(phba->host->host_lock); 1833 spin_lock_irq(phba->host->host_lock);
1958 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 1834 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1959 spin_unlock_irq(phba->host->host_lock); 1835 spin_unlock_irq(phba->host->host_lock);
1960 }
1961 } 1836 }
1962 } 1837 }
1963 1838
@@ -2077,21 +1952,16 @@ lpfc_disc_flush_list(struct lpfc_hba * phba)
2077{ 1952{
2078 struct lpfc_nodelist *ndlp, *next_ndlp; 1953 struct lpfc_nodelist *ndlp, *next_ndlp;
2079 1954
2080 if (phba->fc_plogi_cnt) { 1955 if (phba->fc_plogi_cnt || phba->fc_adisc_cnt) {
2081 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, 1956 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
2082 nlp_listp) { 1957 nlp_listp) {
2083 lpfc_free_tx(phba, ndlp); 1958 if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
2084 lpfc_nlp_put(ndlp); 1959 ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
2085 } 1960 lpfc_free_tx(phba, ndlp);
2086 } 1961 lpfc_nlp_put(ndlp);
2087 if (phba->fc_adisc_cnt) { 1962 }
2088 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
2089 nlp_listp) {
2090 lpfc_free_tx(phba, ndlp);
2091 lpfc_nlp_put(ndlp);
2092 } 1963 }
2093 } 1964 }
2094 return;
2095} 1965}
2096 1966
2097/*****************************************************************************/ 1967/*****************************************************************************/
@@ -2160,8 +2030,10 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2160 phba->brd_no); 2030 phba->brd_no);
2161 2031
2162 /* Start discovery by sending FLOGI, clean up old rpis */ 2032 /* Start discovery by sending FLOGI, clean up old rpis */
2163 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 2033 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
2164 nlp_listp) { 2034 nlp_listp) {
2035 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
2036 continue;
2165 if (ndlp->nlp_type & NLP_FABRIC) { 2037 if (ndlp->nlp_type & NLP_FABRIC) {
2166 /* Clean up the ndlp on Fabric connections */ 2038 /* Clean up the ndlp on Fabric connections */
2167 lpfc_drop_node(phba, ndlp); 2039 lpfc_drop_node(phba, ndlp);
@@ -2205,7 +2077,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2205 "login\n", phba->brd_no); 2077 "login\n", phba->brd_no);
2206 2078
2207 /* Next look for NameServer ndlp */ 2079 /* Next look for NameServer ndlp */
2208 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); 2080 ndlp = lpfc_findnode_did(phba, NameServer_DID);
2209 if (ndlp) 2081 if (ndlp)
2210 lpfc_nlp_put(ndlp); 2082 lpfc_nlp_put(ndlp);
2211 /* Start discovery */ 2083 /* Start discovery */
@@ -2220,9 +2092,8 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2220 phba->brd_no, 2092 phba->brd_no,
2221 phba->fc_ns_retry, LPFC_MAX_NS_RETRY); 2093 phba->fc_ns_retry, LPFC_MAX_NS_RETRY);
2222 2094
2223 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, 2095 ndlp = lpfc_findnode_did(phba, NameServer_DID);
2224 NameServer_DID); 2096 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
2225 if (ndlp) {
2226 if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { 2097 if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {
2227 /* Try it one more time */ 2098 /* Try it one more time */
2228 rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT); 2099 rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT);
@@ -2394,31 +2265,63 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
2394 return; 2265 return;
2395} 2266}
2396 2267
2268static int
2269lpfc_filter_by_rpi(struct lpfc_nodelist *ndlp, void *param)
2270{
2271 uint16_t *rpi = param;
2272
2273 return ndlp->nlp_rpi == *rpi;
2274}
2275
2276static int
2277lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param)
2278{
2279 return memcmp(&ndlp->nlp_portname, param,
2280 sizeof(ndlp->nlp_portname)) == 0;
2281}
2282
2397/* 2283/*
2398 * This routine looks up the ndlp lists 2284 * Search node lists for a remote port matching filter criteria
2399 * for the given RPI. If rpi found 2285 * Caller needs to hold host_lock before calling this routine.
2400 * it return the node list pointer
2401 * else return NULL.
2402 */ 2286 */
2403struct lpfc_nodelist * 2287struct lpfc_nodelist *
2404__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) 2288__lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
2405{ 2289{
2406 struct lpfc_nodelist *ndlp; 2290 struct lpfc_nodelist *ndlp;
2407 struct list_head * lists[]={&phba->fc_nlpunmap_list,
2408 &phba->fc_nlpmap_list,
2409 &phba->fc_plogi_list,
2410 &phba->fc_adisc_list,
2411 &phba->fc_reglogin_list};
2412 int i;
2413 2291
2414 for (i = 0; i < ARRAY_SIZE(lists); i++ ) 2292 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
2415 list_for_each_entry(ndlp, lists[i], nlp_listp) 2293 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE &&
2416 if (ndlp->nlp_rpi == rpi) { 2294 filter(ndlp, param))
2417 return ndlp; 2295 return ndlp;
2418 } 2296 }
2419 return NULL; 2297 return NULL;
2420} 2298}
2421 2299
2300/*
2301 * Search node lists for a remote port matching filter criteria
2302 * This routine is used when the caller does NOT have host_lock.
2303 */
2304struct lpfc_nodelist *
2305lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
2306{
2307 struct lpfc_nodelist *ndlp;
2308
2309 spin_lock_irq(phba->host->host_lock);
2310 ndlp = __lpfc_find_node(phba, filter, param);
2311 spin_unlock_irq(phba->host->host_lock);
2312 return ndlp;
2313}
2314
2315/*
2316 * This routine looks up the ndlp lists for the given RPI. If rpi found it
2317 * returns the node list pointer else return NULL.
2318 */
2319struct lpfc_nodelist *
2320__lpfc_findnode_rpi(struct lpfc_hba *phba, uint16_t rpi)
2321{
2322 return __lpfc_find_node(phba, lpfc_filter_by_rpi, &rpi);
2323}
2324
2422struct lpfc_nodelist * 2325struct lpfc_nodelist *
2423lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) 2326lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
2424{ 2327{
@@ -2431,44 +2334,16 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
2431} 2334}
2432 2335
2433/* 2336/*
2434 * This routine looks up the ndlp lists 2337 * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
2435 * for the given WWPN. If WWPN found 2338 * returns the node list pointer else return NULL.
2436 * it return the node list pointer
2437 * else return NULL.
2438 */ 2339 */
2439struct lpfc_nodelist * 2340struct lpfc_nodelist *
2440lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, 2341lpfc_findnode_wwpn(struct lpfc_hba *phba, struct lpfc_name *wwpn)
2441 struct lpfc_name * wwpn)
2442{ 2342{
2443 struct lpfc_nodelist *ndlp; 2343 struct lpfc_nodelist *ndlp;
2444 struct list_head * lists[]={&phba->fc_nlpunmap_list,
2445 &phba->fc_nlpmap_list,
2446 &phba->fc_npr_list,
2447 &phba->fc_plogi_list,
2448 &phba->fc_adisc_list,
2449 &phba->fc_reglogin_list,
2450 &phba->fc_prli_list};
2451 uint32_t search[]={NLP_SEARCH_UNMAPPED,
2452 NLP_SEARCH_MAPPED,
2453 NLP_SEARCH_NPR,
2454 NLP_SEARCH_PLOGI,
2455 NLP_SEARCH_ADISC,
2456 NLP_SEARCH_REGLOGIN,
2457 NLP_SEARCH_PRLI};
2458 int i;
2459 2344
2460 spin_lock_irq(phba->host->host_lock); 2345 spin_lock_irq(phba->host->host_lock);
2461 for (i = 0; i < ARRAY_SIZE(lists); i++ ) { 2346 ndlp = __lpfc_find_node(phba, lpfc_filter_by_wwpn, wwpn);
2462 if (!(order & search[i]))
2463 continue;
2464 list_for_each_entry(ndlp, lists[i], nlp_listp) {
2465 if (memcmp(&ndlp->nlp_portname, wwpn,
2466 sizeof(struct lpfc_name)) == 0) {
2467 spin_unlock_irq(phba->host->host_lock);
2468 return ndlp;
2469 }
2470 }
2471 }
2472 spin_unlock_irq(phba->host->host_lock); 2347 spin_unlock_irq(phba->host->host_lock);
2473 return NULL; 2348 return NULL;
2474} 2349}
@@ -2484,6 +2359,7 @@ lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
2484 ndlp->nlp_DID = did; 2359 ndlp->nlp_DID = did;
2485 ndlp->nlp_phba = phba; 2360 ndlp->nlp_phba = phba;
2486 ndlp->nlp_sid = NLP_NO_SID; 2361 ndlp->nlp_sid = NLP_NO_SID;
2362 INIT_LIST_HEAD(&ndlp->nlp_listp);
2487 kref_init(&ndlp->kref); 2363 kref_init(&ndlp->kref);
2488 return; 2364 return;
2489} 2365}
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 388b92a39589..5e9a839111d2 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1185,63 +1185,11 @@ lpfc_cleanup(struct lpfc_hba * phba)
1185 1185
1186 /* clean up phba - lpfc specific */ 1186 /* clean up phba - lpfc specific */
1187 lpfc_can_disctmo(phba); 1187 lpfc_can_disctmo(phba);
1188 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, 1188 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp)
1189 nlp_listp) {
1190 lpfc_nlp_put(ndlp); 1189 lpfc_nlp_put(ndlp);
1191 }
1192
1193 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list,
1194 nlp_listp) {
1195 lpfc_nlp_put(ndlp);
1196 }
1197
1198 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list,
1199 nlp_listp) {
1200 lpfc_drop_node(phba, ndlp);
1201 }
1202
1203 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,
1204 nlp_listp) {
1205 lpfc_nlp_put(ndlp);
1206 }
1207
1208 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
1209 nlp_listp) {
1210 lpfc_nlp_put(ndlp);
1211 }
1212
1213 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list,
1214 nlp_listp) {
1215 lpfc_nlp_put(ndlp);
1216 }
1217 1190
1218 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, 1191 INIT_LIST_HEAD(&phba->fc_nodes);
1219 nlp_listp) {
1220 lpfc_nlp_put(ndlp);
1221 }
1222 1192
1223 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
1224 nlp_listp) {
1225 lpfc_nlp_put(ndlp);
1226 }
1227
1228 INIT_LIST_HEAD(&phba->fc_nlpmap_list);
1229 INIT_LIST_HEAD(&phba->fc_nlpunmap_list);
1230 INIT_LIST_HEAD(&phba->fc_unused_list);
1231 INIT_LIST_HEAD(&phba->fc_plogi_list);
1232 INIT_LIST_HEAD(&phba->fc_adisc_list);
1233 INIT_LIST_HEAD(&phba->fc_reglogin_list);
1234 INIT_LIST_HEAD(&phba->fc_prli_list);
1235 INIT_LIST_HEAD(&phba->fc_npr_list);
1236
1237 phba->fc_map_cnt = 0;
1238 phba->fc_unmap_cnt = 0;
1239 phba->fc_plogi_cnt = 0;
1240 phba->fc_adisc_cnt = 0;
1241 phba->fc_reglogin_cnt = 0;
1242 phba->fc_prli_cnt = 0;
1243 phba->fc_npr_cnt = 0;
1244 phba->fc_unused_cnt= 0;
1245 return; 1193 return;
1246} 1194}
1247 1195
@@ -1336,8 +1284,6 @@ void
1336lpfc_offline_prep(struct lpfc_hba * phba) 1284lpfc_offline_prep(struct lpfc_hba * phba)
1337{ 1285{
1338 struct lpfc_nodelist *ndlp, *next_ndlp; 1286 struct lpfc_nodelist *ndlp, *next_ndlp;
1339 struct list_head *listp, *node_list[7];
1340 int i;
1341 1287
1342 if (phba->fc_flag & FC_OFFLINE_MODE) 1288 if (phba->fc_flag & FC_OFFLINE_MODE)
1343 return; 1289 return;
@@ -1347,21 +1293,9 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1347 lpfc_linkdown(phba); 1293 lpfc_linkdown(phba);
1348 1294
1349 /* Issue an unreg_login to all nodes */ 1295 /* Issue an unreg_login to all nodes */
1350 node_list[0] = &phba->fc_npr_list; /* MUST do this list first */ 1296 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp)
1351 node_list[1] = &phba->fc_nlpmap_list; 1297 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE)
1352 node_list[2] = &phba->fc_nlpunmap_list;
1353 node_list[3] = &phba->fc_prli_list;
1354 node_list[4] = &phba->fc_reglogin_list;
1355 node_list[5] = &phba->fc_adisc_list;
1356 node_list[6] = &phba->fc_plogi_list;
1357 for (i = 0; i < 7; i++) {
1358 listp = node_list[i];
1359 if (list_empty(listp))
1360 continue;
1361
1362 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp)
1363 lpfc_unreg_rpi(phba, ndlp); 1298 lpfc_unreg_rpi(phba, ndlp);
1364 }
1365 1299
1366 lpfc_sli_flush_mbox_queue(phba); 1300 lpfc_sli_flush_mbox_queue(phba);
1367} 1301}
@@ -1500,15 +1434,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1500 host->max_lun = phba->cfg_max_luns; 1434 host->max_lun = phba->cfg_max_luns;
1501 host->this_id = -1; 1435 host->this_id = -1;
1502 1436
1503 /* Initialize all internally managed lists. */ 1437 INIT_LIST_HEAD(&phba->fc_nodes);
1504 INIT_LIST_HEAD(&phba->fc_nlpmap_list);
1505 INIT_LIST_HEAD(&phba->fc_nlpunmap_list);
1506 INIT_LIST_HEAD(&phba->fc_unused_list);
1507 INIT_LIST_HEAD(&phba->fc_plogi_list);
1508 INIT_LIST_HEAD(&phba->fc_adisc_list);
1509 INIT_LIST_HEAD(&phba->fc_reglogin_list);
1510 INIT_LIST_HEAD(&phba->fc_prli_list);
1511 INIT_LIST_HEAD(&phba->fc_npr_list);
1512 1438
1513 pci_set_master(pdev); 1439 pci_set_master(pdev);
1514 retval = pci_set_mwi(pdev); 1440 retval = pci_set_mwi(pdev);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index efd1cf638b8c..cc0f845d8b38 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1175,10 +1175,12 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
1175 * fail, this routine returns failure to the midlayer. 1175 * fail, this routine returns failure to the midlayer.
1176 */ 1176 */
1177 for (i = 0; i < LPFC_MAX_TARGET; i++) { 1177 for (i = 0; i < LPFC_MAX_TARGET; i++) {
1178 /* Search the mapped list for this target ID */ 1178 /* Search for mapped node by target ID */
1179 match = 0; 1179 match = 0;
1180 list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { 1180 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
1181 if ((i == ndlp->nlp_sid) && ndlp->rport) { 1181 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
1182 i == ndlp->nlp_sid &&
1183 ndlp->rport) {
1182 match = 1; 1184 match = 1;
1183 break; 1185 break;
1184 } 1186 }