aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c884
1 files changed, 424 insertions, 460 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index c39564e85e94..61caa8d379e2 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-2006 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2007 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 *
@@ -109,6 +109,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
109 return; 109 return;
110 } 110 }
111 111
112 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
113 return;
114
112 name = (uint8_t *)&ndlp->nlp_portname; 115 name = (uint8_t *)&ndlp->nlp_portname;
113 phba = ndlp->nlp_phba; 116 phba = ndlp->nlp_phba;
114 117
@@ -147,11 +150,17 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
147 ndlp->nlp_state, ndlp->nlp_rpi); 150 ndlp->nlp_state, ndlp->nlp_rpi);
148 } 151 }
149 152
150 ndlp->rport = NULL; 153 if (!(phba->fc_flag & FC_UNLOADING) &&
151 rdata->pnode = NULL; 154 !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
152 155 !(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
153 if (!(phba->fc_flag & FC_UNLOADING)) 156 (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE))
154 lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); 157 lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM);
158 else {
159 rdata->pnode = NULL;
160 ndlp->rport = NULL;
161 lpfc_nlp_put(ndlp);
162 put_device(&rport->dev);
163 }
155 164
156 return; 165 return;
157} 166}
@@ -182,29 +191,35 @@ lpfc_work_list_done(struct lpfc_hba * phba)
182 *(int *)(evtp->evt_arg1) = 0; 191 *(int *)(evtp->evt_arg1) = 0;
183 complete((struct completion *)(evtp->evt_arg2)); 192 complete((struct completion *)(evtp->evt_arg2));
184 break; 193 break;
185 case LPFC_EVT_OFFLINE: 194 case LPFC_EVT_OFFLINE_PREP:
186 if (phba->hba_state >= LPFC_LINK_DOWN) 195 if (phba->hba_state >= LPFC_LINK_DOWN)
187 lpfc_offline(phba); 196 lpfc_offline_prep(phba);
197 *(int *)(evtp->evt_arg1) = 0;
198 complete((struct completion *)(evtp->evt_arg2));
199 break;
200 case LPFC_EVT_OFFLINE:
201 lpfc_offline(phba);
188 lpfc_sli_brdrestart(phba); 202 lpfc_sli_brdrestart(phba);
189 *(int *)(evtp->evt_arg1) = 203 *(int *)(evtp->evt_arg1) =
190 lpfc_sli_brdready(phba,HS_FFRDY | HS_MBRDY); 204 lpfc_sli_brdready(phba, HS_FFRDY | HS_MBRDY);
205 lpfc_unblock_mgmt_io(phba);
191 complete((struct completion *)(evtp->evt_arg2)); 206 complete((struct completion *)(evtp->evt_arg2));
192 break; 207 break;
193 case LPFC_EVT_WARM_START: 208 case LPFC_EVT_WARM_START:
194 if (phba->hba_state >= LPFC_LINK_DOWN) 209 lpfc_offline(phba);
195 lpfc_offline(phba);
196 lpfc_reset_barrier(phba); 210 lpfc_reset_barrier(phba);
197 lpfc_sli_brdreset(phba); 211 lpfc_sli_brdreset(phba);
198 lpfc_hba_down_post(phba); 212 lpfc_hba_down_post(phba);
199 *(int *)(evtp->evt_arg1) = 213 *(int *)(evtp->evt_arg1) =
200 lpfc_sli_brdready(phba, HS_MBRDY); 214 lpfc_sli_brdready(phba, HS_MBRDY);
215 lpfc_unblock_mgmt_io(phba);
201 complete((struct completion *)(evtp->evt_arg2)); 216 complete((struct completion *)(evtp->evt_arg2));
202 break; 217 break;
203 case LPFC_EVT_KILL: 218 case LPFC_EVT_KILL:
204 if (phba->hba_state >= LPFC_LINK_DOWN) 219 lpfc_offline(phba);
205 lpfc_offline(phba);
206 *(int *)(evtp->evt_arg1) 220 *(int *)(evtp->evt_arg1)
207 = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); 221 = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba);
222 lpfc_unblock_mgmt_io(phba);
208 complete((struct completion *)(evtp->evt_arg2)); 223 complete((struct completion *)(evtp->evt_arg2));
209 break; 224 break;
210 } 225 }
@@ -359,13 +374,12 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
359} 374}
360 375
361int 376int
362lpfc_linkdown(struct lpfc_hba * phba) 377lpfc_linkdown(struct lpfc_hba *phba)
363{ 378{
364 struct lpfc_sli *psli; 379 struct lpfc_sli *psli;
365 struct lpfc_nodelist *ndlp, *next_ndlp; 380 struct lpfc_nodelist *ndlp, *next_ndlp;
366 struct list_head *listp, *node_list[7]; 381 LPFC_MBOXQ_t *mb;
367 LPFC_MBOXQ_t *mb; 382 int rc;
368 int rc, i;
369 383
370 psli = &phba->sli; 384 psli = &phba->sli;
371 /* sysfs or selective reset may call this routine to clean up */ 385 /* sysfs or selective reset may call this routine to clean up */
@@ -397,31 +411,16 @@ lpfc_linkdown(struct lpfc_hba * phba)
397 /* Cleanup any outstanding ELS commands */ 411 /* Cleanup any outstanding ELS commands */
398 lpfc_els_flush_cmd(phba); 412 lpfc_els_flush_cmd(phba);
399 413
400 /* Issue a LINK DOWN event to all nodes */ 414 /*
401 node_list[0] = &phba->fc_npr_list; /* MUST do this list first */ 415 * Issue a LINK DOWN event to all nodes.
402 node_list[1] = &phba->fc_nlpmap_list; 416 */
403 node_list[2] = &phba->fc_nlpunmap_list; 417 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
404 node_list[3] = &phba->fc_prli_list; 418 /* free any ndlp's on unused list */
405 node_list[4] = &phba->fc_reglogin_list; 419 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
406 node_list[5] = &phba->fc_adisc_list; 420 lpfc_drop_node(phba, ndlp);
407 node_list[6] = &phba->fc_plogi_list; 421 else /* otherwise, force node recovery. */
408 for (i = 0; i < 7; i++) {
409 listp = node_list[i];
410 if (list_empty(listp))
411 continue;
412
413 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
414
415 rc = lpfc_disc_state_machine(phba, ndlp, NULL, 422 rc = lpfc_disc_state_machine(phba, ndlp, NULL,
416 NLP_EVT_DEVICE_RECOVERY); 423 NLP_EVT_DEVICE_RECOVERY);
417
418 }
419 }
420
421 /* free any ndlp's on unused list */
422 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list,
423 nlp_listp) {
424 lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
425 } 424 }
426 425
427 /* Setup myDID for link up if we are in pt2pt mode */ 426 /* Setup myDID for link up if we are in pt2pt mode */
@@ -452,11 +451,9 @@ lpfc_linkdown(struct lpfc_hba * phba)
452} 451}
453 452
454static int 453static int
455lpfc_linkup(struct lpfc_hba * phba) 454lpfc_linkup(struct lpfc_hba *phba)
456{ 455{
457 struct lpfc_nodelist *ndlp, *next_ndlp; 456 struct lpfc_nodelist *ndlp, *next_ndlp;
458 struct list_head *listp, *node_list[7];
459 int i;
460 457
461 fc_host_post_event(phba->host, fc_get_event_number(), 458 fc_host_post_event(phba->host, fc_get_event_number(),
462 FCH_EVT_LINKUP, 0); 459 FCH_EVT_LINKUP, 0);
@@ -470,29 +467,20 @@ lpfc_linkup(struct lpfc_hba * phba)
470 spin_unlock_irq(phba->host->host_lock); 467 spin_unlock_irq(phba->host->host_lock);
471 468
472 469
473 node_list[0] = &phba->fc_plogi_list; 470 if (phba->fc_flag & FC_LBIT) {
474 node_list[1] = &phba->fc_adisc_list; 471 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
475 node_list[2] = &phba->fc_reglogin_list; 472 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) {
476 node_list[3] = &phba->fc_prli_list;
477 node_list[4] = &phba->fc_nlpunmap_list;
478 node_list[5] = &phba->fc_nlpmap_list;
479 node_list[6] = &phba->fc_npr_list;
480 for (i = 0; i < 7; i++) {
481 listp = node_list[i];
482 if (list_empty(listp))
483 continue;
484
485 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
486 if (phba->fc_flag & FC_LBIT) {
487 if (ndlp->nlp_type & NLP_FABRIC) { 473 if (ndlp->nlp_type & NLP_FABRIC) {
488 /* On Linkup its safe to clean up the 474 /*
475 * On Linkup its safe to clean up the
489 * ndlp from Fabric connections. 476 * ndlp from Fabric connections.
490 */ 477 */
491 lpfc_nlp_list(phba, ndlp, 478 lpfc_nlp_set_state(phba, ndlp,
492 NLP_UNUSED_LIST); 479 NLP_STE_UNUSED_NODE);
493 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 480 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
494 /* Fail outstanding IO now since device 481 /*
495 * is marked for PLOGI. 482 * Fail outstanding IO now since
483 * device is marked for PLOGI.
496 */ 484 */
497 lpfc_unreg_rpi(phba, ndlp); 485 lpfc_unreg_rpi(phba, ndlp);
498 } 486 }
@@ -501,9 +489,10 @@ lpfc_linkup(struct lpfc_hba * phba)
501 } 489 }
502 490
503 /* free any ndlp's on unused list */ 491 /* free any ndlp's on unused list */
504 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, 492 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
505 nlp_listp) { 493 nlp_listp) {
506 lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); 494 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
495 lpfc_drop_node(phba, ndlp);
507 } 496 }
508 497
509 return 0; 498 return 0;
@@ -734,6 +723,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
734 case LA_4GHZ_LINK: 723 case LA_4GHZ_LINK:
735 phba->fc_linkspeed = LA_4GHZ_LINK; 724 phba->fc_linkspeed = LA_4GHZ_LINK;
736 break; 725 break;
726 case LA_8GHZ_LINK:
727 phba->fc_linkspeed = LA_8GHZ_LINK;
728 break;
737 default: 729 default:
738 phba->fc_linkspeed = LA_UNKNW_LINK; 730 phba->fc_linkspeed = LA_UNKNW_LINK;
739 break; 731 break;
@@ -889,12 +881,21 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
889 881
890 if (la->attType == AT_LINK_UP) { 882 if (la->attType == AT_LINK_UP) {
891 phba->fc_stat.LinkUp++; 883 phba->fc_stat.LinkUp++;
892 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, 884 if (phba->fc_flag & FC_LOOPBACK_MODE) {
885 lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
886 "%d:1306 Link Up Event in loop back mode "
887 "x%x received Data: x%x x%x x%x x%x\n",
888 phba->brd_no, la->eventTag, phba->fc_eventTag,
889 la->granted_AL_PA, la->UlnkSpeed,
890 phba->alpa_map[0]);
891 } else {
892 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
893 "%d:1303 Link Up Event x%x received " 893 "%d:1303 Link Up Event x%x received "
894 "Data: x%x x%x x%x x%x\n", 894 "Data: x%x x%x x%x x%x\n",
895 phba->brd_no, la->eventTag, phba->fc_eventTag, 895 phba->brd_no, la->eventTag, phba->fc_eventTag,
896 la->granted_AL_PA, la->UlnkSpeed, 896 la->granted_AL_PA, la->UlnkSpeed,
897 phba->alpa_map[0]); 897 phba->alpa_map[0]);
898 }
898 lpfc_mbx_process_link_up(phba, la); 899 lpfc_mbx_process_link_up(phba, la);
899 } else { 900 } else {
900 phba->fc_stat.LinkDown++; 901 phba->fc_stat.LinkDown++;
@@ -940,6 +941,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
940 lpfc_mbuf_free(phba, mp->virt, mp->phys); 941 lpfc_mbuf_free(phba, mp->virt, mp->phys);
941 kfree(mp); 942 kfree(mp);
942 mempool_free( pmb, phba->mbox_mem_pool); 943 mempool_free( pmb, phba->mbox_mem_pool);
944 lpfc_nlp_put(ndlp);
943 945
944 return; 946 return;
945} 947}
@@ -966,11 +968,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
966 ndlp = (struct lpfc_nodelist *) pmb->context2; 968 ndlp = (struct lpfc_nodelist *) pmb->context2;
967 mp = (struct lpfc_dmabuf *) (pmb->context1); 969 mp = (struct lpfc_dmabuf *) (pmb->context1);
968 970
971 pmb->context1 = NULL;
972 pmb->context2 = NULL;
973
969 if (mb->mbxStatus) { 974 if (mb->mbxStatus) {
970 lpfc_mbuf_free(phba, mp->virt, mp->phys); 975 lpfc_mbuf_free(phba, mp->virt, mp->phys);
971 kfree(mp); 976 kfree(mp);
972 mempool_free( pmb, phba->mbox_mem_pool); 977 mempool_free(pmb, phba->mbox_mem_pool);
973 mempool_free( ndlp, phba->nlp_mem_pool); 978 lpfc_nlp_put(ndlp);
974 979
975 /* FLOGI failed, so just use loop map to make discovery list */ 980 /* FLOGI failed, so just use loop map to make discovery list */
976 lpfc_disc_list_loopmap(phba); 981 lpfc_disc_list_loopmap(phba);
@@ -980,12 +985,11 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
980 return; 985 return;
981 } 986 }
982 987
983 pmb->context1 = NULL;
984
985 ndlp->nlp_rpi = mb->un.varWords[0]; 988 ndlp->nlp_rpi = mb->un.varWords[0];
986 ndlp->nlp_type |= NLP_FABRIC; 989 ndlp->nlp_type |= NLP_FABRIC;
987 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; 990 lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
988 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); 991
992 lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */
989 993
990 if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { 994 if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {
991 /* This NPort has been assigned an NPort_ID by the fabric as a 995 /* This NPort has been assigned an NPort_ID by the fabric as a
@@ -996,7 +1000,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
996 */ 1000 */
997 lpfc_issue_els_scr(phba, SCR_DID, 0); 1001 lpfc_issue_els_scr(phba, SCR_DID, 0);
998 1002
999 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); 1003 ndlp = lpfc_findnode_did(phba, NameServer_DID);
1000 if (!ndlp) { 1004 if (!ndlp) {
1001 /* Allocate a new node instance. If the pool is empty, 1005 /* Allocate a new node instance. If the pool is empty,
1002 * start the discovery process and skip the Nameserver 1006 * start the discovery process and skip the Nameserver
@@ -1008,15 +1012,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1008 lpfc_disc_start(phba); 1012 lpfc_disc_start(phba);
1009 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1013 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1010 kfree(mp); 1014 kfree(mp);
1011 mempool_free( pmb, phba->mbox_mem_pool); 1015 mempool_free(pmb, phba->mbox_mem_pool);
1012 return; 1016 return;
1013 } else { 1017 } else {
1014 lpfc_nlp_init(phba, ndlp, NameServer_DID); 1018 lpfc_nlp_init(phba, ndlp, NameServer_DID);
1015 ndlp->nlp_type |= NLP_FABRIC; 1019 ndlp->nlp_type |= NLP_FABRIC;
1016 } 1020 }
1017 } 1021 }
1018 ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; 1022 lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
1019 lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
1020 lpfc_issue_els_plogi(phba, NameServer_DID, 0); 1023 lpfc_issue_els_plogi(phba, NameServer_DID, 0);
1021 if (phba->cfg_fdmi_on) { 1024 if (phba->cfg_fdmi_on) {
1022 ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, 1025 ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
@@ -1032,7 +1035,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1032 1035
1033 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1036 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1034 kfree(mp); 1037 kfree(mp);
1035 mempool_free( pmb, phba->mbox_mem_pool); 1038 mempool_free(pmb, phba->mbox_mem_pool);
1036 return; 1039 return;
1037} 1040}
1038 1041
@@ -1057,10 +1060,11 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1057 mp = (struct lpfc_dmabuf *) (pmb->context1); 1060 mp = (struct lpfc_dmabuf *) (pmb->context1);
1058 1061
1059 if (mb->mbxStatus) { 1062 if (mb->mbxStatus) {
1063 lpfc_nlp_put(ndlp);
1060 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1064 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1061 kfree(mp); 1065 kfree(mp);
1062 mempool_free( pmb, phba->mbox_mem_pool); 1066 mempool_free(pmb, phba->mbox_mem_pool);
1063 lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); 1067 lpfc_drop_node(phba, ndlp);
1064 1068
1065 /* RegLogin failed, so just use loop map to make discovery 1069 /* RegLogin failed, so just use loop map to make discovery
1066 list */ 1070 list */
@@ -1075,8 +1079,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1075 1079
1076 ndlp->nlp_rpi = mb->un.varWords[0]; 1080 ndlp->nlp_rpi = mb->un.varWords[0];
1077 ndlp->nlp_type |= NLP_FABRIC; 1081 ndlp->nlp_type |= NLP_FABRIC;
1078 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; 1082 lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
1079 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
1080 1083
1081 if (phba->hba_state < LPFC_HBA_READY) { 1084 if (phba->hba_state < LPFC_HBA_READY) {
1082 /* Link up discovery requires Fabrib registration. */ 1085 /* Link up discovery requires Fabrib registration. */
@@ -1093,6 +1096,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1093 lpfc_disc_start(phba); 1096 lpfc_disc_start(phba);
1094 } 1097 }
1095 1098
1099 lpfc_nlp_put(ndlp);
1096 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1100 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1097 kfree(mp); 1101 kfree(mp);
1098 mempool_free( pmb, phba->mbox_mem_pool); 1102 mempool_free( pmb, phba->mbox_mem_pool);
@@ -1101,8 +1105,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1101} 1105}
1102 1106
1103static void 1107static void
1104lpfc_register_remote_port(struct lpfc_hba * phba, 1108lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1105 struct lpfc_nodelist * ndlp)
1106{ 1109{
1107 struct fc_rport *rport; 1110 struct fc_rport *rport;
1108 struct lpfc_rport_data *rdata; 1111 struct lpfc_rport_data *rdata;
@@ -1114,8 +1117,19 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1114 rport_ids.port_id = ndlp->nlp_DID; 1117 rport_ids.port_id = ndlp->nlp_DID;
1115 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 1118 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
1116 1119
1120 /*
1121 * We leave our node pointer in rport->dd_data when we unregister a
1122 * FCP target port. But fc_remote_port_add zeros the space to which
1123 * rport->dd_data points. So, if we're reusing a previously
1124 * registered port, drop the reference that we took the last time we
1125 * registered the port.
1126 */
1127 if (ndlp->rport && ndlp->rport->dd_data &&
1128 *(struct lpfc_rport_data **) ndlp->rport->dd_data) {
1129 lpfc_nlp_put(ndlp);
1130 }
1117 ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); 1131 ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
1118 if (!rport) { 1132 if (!rport || !get_device(&rport->dev)) {
1119 dev_printk(KERN_WARNING, &phba->pcidev->dev, 1133 dev_printk(KERN_WARNING, &phba->pcidev->dev,
1120 "Warning: fc_remote_port_add failed\n"); 1134 "Warning: fc_remote_port_add failed\n");
1121 return; 1135 return;
@@ -1125,7 +1139,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1125 rport->maxframe_size = ndlp->nlp_maxframe; 1139 rport->maxframe_size = ndlp->nlp_maxframe;
1126 rport->supported_classes = ndlp->nlp_class_sup; 1140 rport->supported_classes = ndlp->nlp_class_sup;
1127 rdata = rport->dd_data; 1141 rdata = rport->dd_data;
1128 rdata->pnode = ndlp; 1142 rdata->pnode = lpfc_nlp_get(ndlp);
1129 1143
1130 if (ndlp->nlp_type & NLP_FCP_TARGET) 1144 if (ndlp->nlp_type & NLP_FCP_TARGET)
1131 rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; 1145 rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
@@ -1145,8 +1159,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1145} 1159}
1146 1160
1147static void 1161static void
1148lpfc_unregister_remote_port(struct lpfc_hba * phba, 1162lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1149 struct lpfc_nodelist * ndlp)
1150{ 1163{
1151 struct fc_rport *rport = ndlp->rport; 1164 struct fc_rport *rport = ndlp->rport;
1152 struct lpfc_rport_data *rdata = rport->dd_data; 1165 struct lpfc_rport_data *rdata = rport->dd_data;
@@ -1154,6 +1167,8 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba,
1154 if (rport->scsi_target_id == -1) { 1167 if (rport->scsi_target_id == -1) {
1155 ndlp->rport = NULL; 1168 ndlp->rport = NULL;
1156 rdata->pnode = NULL; 1169 rdata->pnode = NULL;
1170 lpfc_nlp_put(ndlp);
1171 put_device(&rport->dev);
1157 } 1172 }
1158 1173
1159 fc_remote_port_delete(rport); 1174 fc_remote_port_delete(rport);
@@ -1161,178 +1176,70 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba,
1161 return; 1176 return;
1162} 1177}
1163 1178
1164int 1179static void
1165lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) 1180lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count)
1166{ 1181{
1167 enum { none, unmapped, mapped } rport_add = none, rport_del = none;
1168 struct lpfc_sli *psli;
1169
1170 psli = &phba->sli;
1171 /* Sanity check to ensure we are not moving to / from the same list */
1172 if ((nlp->nlp_flag & NLP_LIST_MASK) == list)
1173 if (list != NLP_NO_LIST)
1174 return 0;
1175
1176 spin_lock_irq(phba->host->host_lock); 1182 spin_lock_irq(phba->host->host_lock);
1177 switch (nlp->nlp_flag & NLP_LIST_MASK) { 1183 switch (state) {
1178 case NLP_NO_LIST: /* Not on any list */ 1184 case NLP_STE_UNUSED_NODE:
1185 phba->fc_unused_cnt += count;
1179 break; 1186 break;
1180 case NLP_UNUSED_LIST: 1187 case NLP_STE_PLOGI_ISSUE:
1181 phba->fc_unused_cnt--; 1188 phba->fc_plogi_cnt += count;
1182 list_del(&nlp->nlp_listp);
1183 break; 1189 break;
1184 case NLP_PLOGI_LIST: 1190 case NLP_STE_ADISC_ISSUE:
1185 phba->fc_plogi_cnt--; 1191 phba->fc_adisc_cnt += count;
1186 list_del(&nlp->nlp_listp);
1187 break; 1192 break;
1188 case NLP_ADISC_LIST: 1193 case NLP_STE_REG_LOGIN_ISSUE:
1189 phba->fc_adisc_cnt--; 1194 phba->fc_reglogin_cnt += count;
1190 list_del(&nlp->nlp_listp);
1191 break; 1195 break;
1192 case NLP_REGLOGIN_LIST: 1196 case NLP_STE_PRLI_ISSUE:
1193 phba->fc_reglogin_cnt--; 1197 phba->fc_prli_cnt += count;
1194 list_del(&nlp->nlp_listp);
1195 break; 1198 break;
1196 case NLP_PRLI_LIST: 1199 case NLP_STE_UNMAPPED_NODE:
1197 phba->fc_prli_cnt--; 1200 phba->fc_unmap_cnt += count;
1198 list_del(&nlp->nlp_listp);
1199 break; 1201 break;
1200 case NLP_UNMAPPED_LIST: 1202 case NLP_STE_MAPPED_NODE:
1201 phba->fc_unmap_cnt--; 1203 phba->fc_map_cnt += count;
1202 list_del(&nlp->nlp_listp);
1203 nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID;
1204 nlp->nlp_type &= ~NLP_FC_NODE;
1205 phba->nport_event_cnt++;
1206 if (nlp->rport)
1207 rport_del = unmapped;
1208 break; 1204 break;
1209 case NLP_MAPPED_LIST: 1205 case NLP_STE_NPR_NODE:
1210 phba->fc_map_cnt--; 1206 phba->fc_npr_cnt += count;
1211 list_del(&nlp->nlp_listp);
1212 phba->nport_event_cnt++;
1213 if (nlp->rport)
1214 rport_del = mapped;
1215 break;
1216 case NLP_NPR_LIST:
1217 phba->fc_npr_cnt--;
1218 list_del(&nlp->nlp_listp);
1219 /* Stop delay tmo if taking node off NPR list */
1220 if ((nlp->nlp_flag & NLP_DELAY_TMO) &&
1221 (list != NLP_NPR_LIST)) {
1222 spin_unlock_irq(phba->host->host_lock);
1223 lpfc_cancel_retry_delay_tmo(phba, nlp);
1224 spin_lock_irq(phba->host->host_lock);
1225 }
1226 break; 1207 break;
1227 } 1208 }
1209 spin_unlock_irq(phba->host->host_lock);
1210}
1228 1211
1229 nlp->nlp_flag &= ~NLP_LIST_MASK; 1212static void
1230 1213lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
1231 /* Add NPort <did> to <num> list */ 1214 int old_state, int new_state)
1232 lpfc_printf_log(phba, 1215{
1233 KERN_INFO, 1216 if (new_state == NLP_STE_UNMAPPED_NODE) {
1234 LOG_NODE, 1217 ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
1235 "%d:0904 Add NPort x%x to %d list Data: x%x\n", 1218 ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1236 phba->brd_no, 1219 ndlp->nlp_type |= NLP_FC_NODE;
1237 nlp->nlp_DID, list, nlp->nlp_flag); 1220 }
1238 1221 if (new_state == NLP_STE_MAPPED_NODE)
1239 switch (list) { 1222 ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1240 case NLP_NO_LIST: /* No list, just remove it */ 1223 if (new_state == NLP_STE_NPR_NODE)
1241 spin_unlock_irq(phba->host->host_lock); 1224 ndlp->nlp_flag &= ~NLP_RCV_PLOGI;
1242 lpfc_nlp_remove(phba, nlp); 1225
1243 spin_lock_irq(phba->host->host_lock); 1226 /* Transport interface */
1244 /* as node removed - stop further transport calls */ 1227 if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE ||
1245 rport_del = none; 1228 old_state == NLP_STE_UNMAPPED_NODE)) {
1246 break;
1247 case NLP_UNUSED_LIST:
1248 nlp->nlp_flag |= list;
1249 /* Put it at the end of the unused list */
1250 list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list);
1251 phba->fc_unused_cnt++;
1252 break;
1253 case NLP_PLOGI_LIST:
1254 nlp->nlp_flag |= list;
1255 /* Put it at the end of the plogi list */
1256 list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list);
1257 phba->fc_plogi_cnt++;
1258 break;
1259 case NLP_ADISC_LIST:
1260 nlp->nlp_flag |= list;
1261 /* Put it at the end of the adisc list */
1262 list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list);
1263 phba->fc_adisc_cnt++;
1264 break;
1265 case NLP_REGLOGIN_LIST:
1266 nlp->nlp_flag |= list;
1267 /* Put it at the end of the reglogin list */
1268 list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list);
1269 phba->fc_reglogin_cnt++;
1270 break;
1271 case NLP_PRLI_LIST:
1272 nlp->nlp_flag |= list;
1273 /* Put it at the end of the prli list */
1274 list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list);
1275 phba->fc_prli_cnt++;
1276 break;
1277 case NLP_UNMAPPED_LIST:
1278 rport_add = unmapped;
1279 /* ensure all vestiges of "mapped" significance are gone */
1280 nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
1281 nlp->nlp_flag |= list;
1282 /* Put it at the end of the unmap list */
1283 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list);
1284 phba->fc_unmap_cnt++;
1285 phba->nport_event_cnt++;
1286 nlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1287 nlp->nlp_type |= NLP_FC_NODE;
1288 break;
1289 case NLP_MAPPED_LIST:
1290 rport_add = mapped;
1291 nlp->nlp_flag |= list;
1292 /* Put it at the end of the map list */
1293 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list);
1294 phba->fc_map_cnt++;
1295 phba->nport_event_cnt++; 1229 phba->nport_event_cnt++;
1296 nlp->nlp_flag &= ~NLP_NODEV_REMOVE; 1230 lpfc_unregister_remote_port(phba, ndlp);
1297 break;
1298 case NLP_NPR_LIST:
1299 nlp->nlp_flag |= list;
1300 /* Put it at the end of the npr list */
1301 list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list);
1302 phba->fc_npr_cnt++;
1303
1304 nlp->nlp_flag &= ~NLP_RCV_PLOGI;
1305 break;
1306 case NLP_JUST_DQ:
1307 break;
1308 } 1231 }
1309 1232
1310 spin_unlock_irq(phba->host->host_lock); 1233 if (new_state == NLP_STE_MAPPED_NODE ||
1311 1234 new_state == NLP_STE_UNMAPPED_NODE) {
1312 /* 1235 phba->nport_event_cnt++;
1313 * We make all the calls into the transport after we have
1314 * moved the node between lists. This so that we don't
1315 * release the lock while in-between lists.
1316 */
1317
1318 /* Don't upcall midlayer if we're unloading */
1319 if (!(phba->fc_flag & FC_UNLOADING)) {
1320 /*
1321 * We revalidate the rport pointer as the "add" function
1322 * may have removed the remote port.
1323 */
1324 if ((rport_del != none) && nlp->rport)
1325 lpfc_unregister_remote_port(phba, nlp);
1326
1327 if (rport_add != none) {
1328 /* 1236 /*
1329 * Tell the fc transport about the port, if we haven't 1237 * Tell the fc transport about the port, if we haven't
1330 * already. If we have, and it's a scsi entity, be 1238 * already. If we have, and it's a scsi entity, be
1331 * sure to unblock any attached scsi devices 1239 * sure to unblock any attached scsi devices
1332 */ 1240 */
1333 if ((!nlp->rport) || (nlp->rport->port_state == 1241 lpfc_register_remote_port(phba, ndlp);
1334 FC_PORTSTATE_BLOCKED)) 1242 }
1335 lpfc_register_remote_port(phba, nlp);
1336 1243
1337 /* 1244 /*
1338 * if we added to Mapped list, but the remote port 1245 * if we added to Mapped list, but the remote port
@@ -1340,19 +1247,95 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1340 * our presentable range - move the node to the 1247 * our presentable range - move the node to the
1341 * Unmapped List 1248 * Unmapped List
1342 */ 1249 */
1343 if ((rport_add == mapped) && 1250 if (new_state == NLP_STE_MAPPED_NODE &&
1344 ((!nlp->rport) || 1251 (!ndlp->rport ||
1345 (nlp->rport->scsi_target_id == -1) || 1252 ndlp->rport->scsi_target_id == -1 ||
1346 (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) { 1253 ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) {
1347 nlp->nlp_state = NLP_STE_UNMAPPED_NODE; 1254 spin_lock_irq(phba->host->host_lock);
1348 spin_lock_irq(phba->host->host_lock); 1255 ndlp->nlp_flag |= NLP_TGT_NO_SCSIID;
1349 nlp->nlp_flag |= NLP_TGT_NO_SCSIID; 1256 spin_unlock_irq(phba->host->host_lock);
1350 spin_unlock_irq(phba->host->host_lock); 1257 lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
1351 lpfc_nlp_list(phba, nlp, NLP_UNMAPPED_LIST);
1352 }
1353 }
1354 } 1258 }
1355 return 0; 1259}
1260
1261static char *
1262lpfc_nlp_state_name(char *buffer, size_t size, int state)
1263{
1264 static char *states[] = {
1265 [NLP_STE_UNUSED_NODE] = "UNUSED",
1266 [NLP_STE_PLOGI_ISSUE] = "PLOGI",
1267 [NLP_STE_ADISC_ISSUE] = "ADISC",
1268 [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
1269 [NLP_STE_PRLI_ISSUE] = "PRLI",
1270 [NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
1271 [NLP_STE_MAPPED_NODE] = "MAPPED",
1272 [NLP_STE_NPR_NODE] = "NPR",
1273 };
1274
1275 if (state < ARRAY_SIZE(states) && states[state])
1276 strlcpy(buffer, states[state], size);
1277 else
1278 snprintf(buffer, size, "unknown (%d)", state);
1279 return buffer;
1280}
1281
1282void
1283lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state)
1284{
1285 int old_state = ndlp->nlp_state;
1286 char name1[16], name2[16];
1287
1288 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
1289 "%d:0904 NPort state transition x%06x, %s -> %s\n",
1290 phba->brd_no,
1291 ndlp->nlp_DID,
1292 lpfc_nlp_state_name(name1, sizeof(name1), old_state),
1293 lpfc_nlp_state_name(name2, sizeof(name2), state));
1294 if (old_state == NLP_STE_NPR_NODE &&
1295 (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 &&
1296 state != NLP_STE_NPR_NODE)
1297 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1298 if (old_state == NLP_STE_UNMAPPED_NODE) {
1299 ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID;
1300 ndlp->nlp_type &= ~NLP_FC_NODE;
1301 }
1302
1303 if (list_empty(&ndlp->nlp_listp)) {
1304 spin_lock_irq(phba->host->host_lock);
1305 list_add_tail(&ndlp->nlp_listp, &phba->fc_nodes);
1306 spin_unlock_irq(phba->host->host_lock);
1307 } else if (old_state)
1308 lpfc_nlp_counters(phba, old_state, -1);
1309
1310 ndlp->nlp_state = state;
1311 lpfc_nlp_counters(phba, state, 1);
1312 lpfc_nlp_state_cleanup(phba, ndlp, old_state, state);
1313}
1314
1315void
1316lpfc_dequeue_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1317{
1318 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
1319 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1320 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1321 lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
1322 spin_lock_irq(phba->host->host_lock);
1323 list_del_init(&ndlp->nlp_listp);
1324 spin_unlock_irq(phba->host->host_lock);
1325 lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0);
1326}
1327
1328void
1329lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1330{
1331 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
1332 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1333 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1334 lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
1335 spin_lock_irq(phba->host->host_lock);
1336 list_del_init(&ndlp->nlp_listp);
1337 spin_unlock_irq(phba->host->host_lock);
1338 lpfc_nlp_put(ndlp);
1356} 1339}
1357 1340
1358/* 1341/*
@@ -1464,6 +1447,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
1464static int 1447static int
1465lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1448lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1466{ 1449{
1450 LIST_HEAD(completions);
1467 struct lpfc_sli *psli; 1451 struct lpfc_sli *psli;
1468 struct lpfc_sli_ring *pring; 1452 struct lpfc_sli_ring *pring;
1469 struct lpfc_iocbq *iocb, *next_iocb; 1453 struct lpfc_iocbq *iocb, *next_iocb;
@@ -1492,29 +1476,29 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1492 (phba, pring, iocb, ndlp))) { 1476 (phba, pring, iocb, ndlp))) {
1493 /* It matches, so deque and call compl 1477 /* It matches, so deque and call compl
1494 with an error */ 1478 with an error */
1495 list_del(&iocb->list); 1479 list_move_tail(&iocb->list,
1480 &completions);
1496 pring->txq_cnt--; 1481 pring->txq_cnt--;
1497 if (iocb->iocb_cmpl) {
1498 icmd = &iocb->iocb;
1499 icmd->ulpStatus =
1500 IOSTAT_LOCAL_REJECT;
1501 icmd->un.ulpWord[4] =
1502 IOERR_SLI_ABORTED;
1503 spin_unlock_irq(phba->host->
1504 host_lock);
1505 (iocb->iocb_cmpl) (phba,
1506 iocb, iocb);
1507 spin_lock_irq(phba->host->
1508 host_lock);
1509 } else
1510 lpfc_sli_release_iocbq(phba,
1511 iocb);
1512 } 1482 }
1513 } 1483 }
1514 spin_unlock_irq(phba->host->host_lock); 1484 spin_unlock_irq(phba->host->host_lock);
1515 1485
1516 } 1486 }
1517 } 1487 }
1488
1489 while (!list_empty(&completions)) {
1490 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
1491 list_del(&iocb->list);
1492
1493 if (iocb->iocb_cmpl) {
1494 icmd = &iocb->iocb;
1495 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
1496 icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
1497 (iocb->iocb_cmpl) (phba, iocb, iocb);
1498 } else
1499 lpfc_sli_release_iocbq(phba, iocb);
1500 }
1501
1518 return 0; 1502 return 0;
1519} 1503}
1520 1504
@@ -1554,7 +1538,7 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1554 * so it can be freed. 1538 * so it can be freed.
1555 */ 1539 */
1556static int 1540static int
1557lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1541lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1558{ 1542{
1559 LPFC_MBOXQ_t *mb; 1543 LPFC_MBOXQ_t *mb;
1560 LPFC_MBOXQ_t *nextmb; 1544 LPFC_MBOXQ_t *nextmb;
@@ -1567,17 +1551,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1567 phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, 1551 phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
1568 ndlp->nlp_state, ndlp->nlp_rpi); 1552 ndlp->nlp_state, ndlp->nlp_rpi);
1569 1553
1570 lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); 1554 lpfc_dequeue_node(phba, ndlp);
1571
1572 /*
1573 * if unloading the driver - just leave the remote port in place.
1574 * The driver unload will force the attached devices to detach
1575 * and flush cache's w/o generating flush errors.
1576 */
1577 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
1578 lpfc_unregister_remote_port(phba, ndlp);
1579 ndlp->nlp_sid = NLP_NO_SID;
1580 }
1581 1555
1582 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ 1556 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
1583 if ((mb = phba->sli.mbox_active)) { 1557 if ((mb = phba->sli.mbox_active)) {
@@ -1599,11 +1573,12 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1599 } 1573 }
1600 list_del(&mb->list); 1574 list_del(&mb->list);
1601 mempool_free(mb, phba->mbox_mem_pool); 1575 mempool_free(mb, phba->mbox_mem_pool);
1576 lpfc_nlp_put(ndlp);
1602 } 1577 }
1603 } 1578 }
1604 spin_unlock_irq(phba->host->host_lock); 1579 spin_unlock_irq(phba->host->host_lock);
1605 1580
1606 lpfc_els_abort(phba,ndlp,0); 1581 lpfc_els_abort(phba,ndlp);
1607 spin_lock_irq(phba->host->host_lock); 1582 spin_lock_irq(phba->host->host_lock);
1608 ndlp->nlp_flag &= ~NLP_DELAY_TMO; 1583 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
1609 spin_unlock_irq(phba->host->host_lock); 1584 spin_unlock_irq(phba->host->host_lock);
@@ -1624,27 +1599,27 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1624 * If we are in the middle of using the nlp in the discovery state 1599 * If we are in the middle of using the nlp in the discovery state
1625 * machine, defer the free till we reach the end of the state machine. 1600 * machine, defer the free till we reach the end of the state machine.
1626 */ 1601 */
1627int 1602static void
1628lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1603lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1629{ 1604{
1605 struct lpfc_rport_data *rdata;
1630 1606
1631 if (ndlp->nlp_flag & NLP_DELAY_TMO) { 1607 if (ndlp->nlp_flag & NLP_DELAY_TMO) {
1632 lpfc_cancel_retry_delay_tmo(phba, ndlp); 1608 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1633 } 1609 }
1634 1610
1635 if (ndlp->nlp_disc_refcnt) { 1611 lpfc_cleanup_node(phba, ndlp);
1636 spin_lock_irq(phba->host->host_lock); 1612
1637 ndlp->nlp_flag |= NLP_DELAY_REMOVE; 1613 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
1638 spin_unlock_irq(phba->host->host_lock); 1614 put_device(&ndlp->rport->dev);
1639 } else { 1615 rdata = ndlp->rport->dd_data;
1640 lpfc_freenode(phba, ndlp); 1616 rdata->pnode = NULL;
1641 mempool_free( ndlp, phba->nlp_mem_pool); 1617 ndlp->rport = NULL;
1642 } 1618 }
1643 return 0;
1644} 1619}
1645 1620
1646static int 1621static int
1647lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) 1622lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
1648{ 1623{
1649 D_ID mydid; 1624 D_ID mydid;
1650 D_ID ndlpdid; 1625 D_ID ndlpdid;
@@ -1693,57 +1668,36 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did)
1693 return 0; 1668 return 0;
1694} 1669}
1695 1670
1696/* Search for a nodelist entry on a specific list */ 1671/* Search for a nodelist entry */
1697struct lpfc_nodelist * 1672struct lpfc_nodelist *
1698lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) 1673lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did)
1699{ 1674{
1700 struct lpfc_nodelist *ndlp; 1675 struct lpfc_nodelist *ndlp;
1701 struct list_head *lists[]={&phba->fc_nlpunmap_list,
1702 &phba->fc_nlpmap_list,
1703 &phba->fc_plogi_list,
1704 &phba->fc_adisc_list,
1705 &phba->fc_reglogin_list,
1706 &phba->fc_prli_list,
1707 &phba->fc_npr_list,
1708 &phba->fc_unused_list};
1709 uint32_t search[]={NLP_SEARCH_UNMAPPED,
1710 NLP_SEARCH_MAPPED,
1711 NLP_SEARCH_PLOGI,
1712 NLP_SEARCH_ADISC,
1713 NLP_SEARCH_REGLOGIN,
1714 NLP_SEARCH_PRLI,
1715 NLP_SEARCH_NPR,
1716 NLP_SEARCH_UNUSED};
1717 int i;
1718 uint32_t data1; 1676 uint32_t data1;
1719 1677
1720 spin_lock_irq(phba->host->host_lock); 1678 spin_lock_irq(phba->host->host_lock);
1721 for (i = 0; i < ARRAY_SIZE(lists); i++ ) { 1679 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
1722 if (!(order & search[i])) 1680 if (lpfc_matchdid(phba, ndlp, did)) {
1723 continue; 1681 data1 = (((uint32_t) ndlp->nlp_state << 24) |
1724 list_for_each_entry(ndlp, lists[i], nlp_listp) { 1682 ((uint32_t) ndlp->nlp_xri << 16) |
1725 if (lpfc_matchdid(phba, ndlp, did)) { 1683 ((uint32_t) ndlp->nlp_type << 8) |
1726 data1 = (((uint32_t) ndlp->nlp_state << 24) | 1684 ((uint32_t) ndlp->nlp_rpi & 0xff));
1727 ((uint32_t) ndlp->nlp_xri << 16) | 1685 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
1728 ((uint32_t) ndlp->nlp_type << 8) | 1686 "%d:0929 FIND node DID "
1729 ((uint32_t) ndlp->nlp_rpi & 0xff)); 1687 " Data: x%p x%x x%x x%x\n",
1730 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1688 phba->brd_no,
1731 "%d:0929 FIND node DID " 1689 ndlp, ndlp->nlp_DID,
1732 " Data: x%p x%x x%x x%x\n", 1690 ndlp->nlp_flag, data1);
1733 phba->brd_no, 1691 spin_unlock_irq(phba->host->host_lock);
1734 ndlp, ndlp->nlp_DID, 1692 return ndlp;
1735 ndlp->nlp_flag, data1);
1736 spin_unlock_irq(phba->host->host_lock);
1737 return ndlp;
1738 }
1739 } 1693 }
1740 } 1694 }
1741 spin_unlock_irq(phba->host->host_lock); 1695 spin_unlock_irq(phba->host->host_lock);
1742 1696
1743 /* FIND node did <did> NOT FOUND */ 1697 /* FIND node did <did> NOT FOUND */
1744 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1698 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
1745 "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", 1699 "%d:0932 FIND node did x%x NOT FOUND.\n",
1746 phba->brd_no, did, order); 1700 phba->brd_no, did);
1747 return NULL; 1701 return NULL;
1748} 1702}
1749 1703
@@ -1751,9 +1705,8 @@ struct lpfc_nodelist *
1751lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) 1705lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1752{ 1706{
1753 struct lpfc_nodelist *ndlp; 1707 struct lpfc_nodelist *ndlp;
1754 uint32_t flg;
1755 1708
1756 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); 1709 ndlp = lpfc_findnode_did(phba, did);
1757 if (!ndlp) { 1710 if (!ndlp) {
1758 if ((phba->fc_flag & FC_RSCN_MODE) && 1711 if ((phba->fc_flag & FC_RSCN_MODE) &&
1759 ((lpfc_rscn_payload_check(phba, did) == 0))) 1712 ((lpfc_rscn_payload_check(phba, did) == 0)))
@@ -1763,8 +1716,7 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1763 if (!ndlp) 1716 if (!ndlp)
1764 return NULL; 1717 return NULL;
1765 lpfc_nlp_init(phba, ndlp, did); 1718 lpfc_nlp_init(phba, ndlp, did);
1766 ndlp->nlp_state = NLP_STE_NPR_NODE; 1719 lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
1767 lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1768 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 1720 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1769 return ndlp; 1721 return ndlp;
1770 } 1722 }
@@ -1780,11 +1732,10 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1780 } else 1732 } else
1781 ndlp = NULL; 1733 ndlp = NULL;
1782 } else { 1734 } else {
1783 flg = ndlp->nlp_flag & NLP_LIST_MASK; 1735 if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE ||
1784 if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST)) 1736 ndlp->nlp_state == NLP_STE_PLOGI_ISSUE)
1785 return NULL; 1737 return NULL;
1786 ndlp->nlp_state = NLP_STE_NPR_NODE; 1738 lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
1787 lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1788 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 1739 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1789 } 1740 }
1790 return ndlp; 1741 return ndlp;
@@ -1842,8 +1793,9 @@ lpfc_disc_start(struct lpfc_hba * phba)
1842 struct lpfc_sli *psli; 1793 struct lpfc_sli *psli;
1843 LPFC_MBOXQ_t *mbox; 1794 LPFC_MBOXQ_t *mbox;
1844 struct lpfc_nodelist *ndlp, *next_ndlp; 1795 struct lpfc_nodelist *ndlp, *next_ndlp;
1845 uint32_t did_changed, num_sent; 1796 uint32_t num_sent;
1846 uint32_t clear_la_pending; 1797 uint32_t clear_la_pending;
1798 int did_changed;
1847 int rc; 1799 int rc;
1848 1800
1849 psli = &phba->sli; 1801 psli = &phba->sli;
@@ -1877,14 +1829,13 @@ lpfc_disc_start(struct lpfc_hba * phba)
1877 phba->fc_plogi_cnt, phba->fc_adisc_cnt); 1829 phba->fc_plogi_cnt, phba->fc_adisc_cnt);
1878 1830
1879 /* If our did changed, we MUST do PLOGI */ 1831 /* If our did changed, we MUST do PLOGI */
1880 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 1832 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
1881 nlp_listp) { 1833 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
1882 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { 1834 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
1883 if (did_changed) { 1835 did_changed) {
1884 spin_lock_irq(phba->host->host_lock); 1836 spin_lock_irq(phba->host->host_lock);
1885 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 1837 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1886 spin_unlock_irq(phba->host->host_lock); 1838 spin_unlock_irq(phba->host->host_lock);
1887 }
1888 } 1839 }
1889 } 1840 }
1890 1841
@@ -1944,11 +1895,11 @@ lpfc_disc_start(struct lpfc_hba * phba)
1944static void 1895static void
1945lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1896lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1946{ 1897{
1898 LIST_HEAD(completions);
1947 struct lpfc_sli *psli; 1899 struct lpfc_sli *psli;
1948 IOCB_t *icmd; 1900 IOCB_t *icmd;
1949 struct lpfc_iocbq *iocb, *next_iocb; 1901 struct lpfc_iocbq *iocb, *next_iocb;
1950 struct lpfc_sli_ring *pring; 1902 struct lpfc_sli_ring *pring;
1951 struct lpfc_dmabuf *mp;
1952 1903
1953 psli = &phba->sli; 1904 psli = &phba->sli;
1954 pring = &psli->ring[LPFC_ELS_RING]; 1905 pring = &psli->ring[LPFC_ELS_RING];
@@ -1956,6 +1907,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1956 /* Error matching iocb on txq or txcmplq 1907 /* Error matching iocb on txq or txcmplq
1957 * First check the txq. 1908 * First check the txq.
1958 */ 1909 */
1910 spin_lock_irq(phba->host->host_lock);
1959 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { 1911 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
1960 if (iocb->context1 != ndlp) { 1912 if (iocb->context1 != ndlp) {
1961 continue; 1913 continue;
@@ -1964,9 +1916,8 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1964 if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || 1916 if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
1965 (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { 1917 (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {
1966 1918
1967 list_del(&iocb->list); 1919 list_move_tail(&iocb->list, &completions);
1968 pring->txq_cnt--; 1920 pring->txq_cnt--;
1969 lpfc_els_free_iocb(phba, iocb);
1970 } 1921 }
1971 } 1922 }
1972 1923
@@ -1978,43 +1929,22 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1978 icmd = &iocb->iocb; 1929 icmd = &iocb->iocb;
1979 if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || 1930 if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
1980 (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { 1931 (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {
1932 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
1933 }
1934 }
1935 spin_unlock_irq(phba->host->host_lock);
1981 1936
1982 iocb->iocb_cmpl = NULL; 1937 while (!list_empty(&completions)) {
1983 /* context2 = cmd, context2->next = rsp, context3 = 1938 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
1984 bpl */ 1939 list_del(&iocb->list);
1985 if (iocb->context2) {
1986 /* Free the response IOCB before handling the
1987 command. */
1988
1989 mp = (struct lpfc_dmabuf *) (iocb->context2);
1990 mp = list_get_first(&mp->list,
1991 struct lpfc_dmabuf,
1992 list);
1993 if (mp) {
1994 /* Delay before releasing rsp buffer to
1995 * give UNREG mbox a chance to take
1996 * effect.
1997 */
1998 list_add(&mp->list,
1999 &phba->freebufList);
2000 }
2001 lpfc_mbuf_free(phba,
2002 ((struct lpfc_dmabuf *)
2003 iocb->context2)->virt,
2004 ((struct lpfc_dmabuf *)
2005 iocb->context2)->phys);
2006 kfree(iocb->context2);
2007 }
2008 1940
2009 if (iocb->context3) { 1941 if (iocb->iocb_cmpl) {
2010 lpfc_mbuf_free(phba, 1942 icmd = &iocb->iocb;
2011 ((struct lpfc_dmabuf *) 1943 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2012 iocb->context3)->virt, 1944 icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
2013 ((struct lpfc_dmabuf *) 1945 (iocb->iocb_cmpl) (phba, iocb, iocb);
2014 iocb->context3)->phys); 1946 } else
2015 kfree(iocb->context3); 1947 lpfc_sli_release_iocbq(phba, iocb);
2016 }
2017 }
2018 } 1948 }
2019 1949
2020 return; 1950 return;
@@ -2025,21 +1955,16 @@ lpfc_disc_flush_list(struct lpfc_hba * phba)
2025{ 1955{
2026 struct lpfc_nodelist *ndlp, *next_ndlp; 1956 struct lpfc_nodelist *ndlp, *next_ndlp;
2027 1957
2028 if (phba->fc_plogi_cnt) { 1958 if (phba->fc_plogi_cnt || phba->fc_adisc_cnt) {
2029 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, 1959 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
2030 nlp_listp) { 1960 nlp_listp) {
2031 lpfc_free_tx(phba, ndlp); 1961 if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
2032 lpfc_nlp_remove(phba, ndlp); 1962 ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
2033 } 1963 lpfc_free_tx(phba, ndlp);
2034 } 1964 lpfc_nlp_put(ndlp);
2035 if (phba->fc_adisc_cnt) { 1965 }
2036 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
2037 nlp_listp) {
2038 lpfc_free_tx(phba, ndlp);
2039 lpfc_nlp_remove(phba, ndlp);
2040 } 1966 }
2041 } 1967 }
2042 return;
2043} 1968}
2044 1969
2045/*****************************************************************************/ 1970/*****************************************************************************/
@@ -2108,11 +2033,13 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2108 phba->brd_no); 2033 phba->brd_no);
2109 2034
2110 /* Start discovery by sending FLOGI, clean up old rpis */ 2035 /* Start discovery by sending FLOGI, clean up old rpis */
2111 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, 2036 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
2112 nlp_listp) { 2037 nlp_listp) {
2038 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
2039 continue;
2113 if (ndlp->nlp_type & NLP_FABRIC) { 2040 if (ndlp->nlp_type & NLP_FABRIC) {
2114 /* Clean up the ndlp on Fabric connections */ 2041 /* Clean up the ndlp on Fabric connections */
2115 lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); 2042 lpfc_drop_node(phba, ndlp);
2116 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 2043 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
2117 /* Fail outstanding IO now since device 2044 /* Fail outstanding IO now since device
2118 * is marked for PLOGI. 2045 * is marked for PLOGI.
@@ -2153,9 +2080,9 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2153 "login\n", phba->brd_no); 2080 "login\n", phba->brd_no);
2154 2081
2155 /* Next look for NameServer ndlp */ 2082 /* Next look for NameServer ndlp */
2156 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); 2083 ndlp = lpfc_findnode_did(phba, NameServer_DID);
2157 if (ndlp) 2084 if (ndlp)
2158 lpfc_nlp_remove(phba, ndlp); 2085 lpfc_nlp_put(ndlp);
2159 /* Start discovery */ 2086 /* Start discovery */
2160 lpfc_disc_start(phba); 2087 lpfc_disc_start(phba);
2161 break; 2088 break;
@@ -2168,9 +2095,8 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2168 phba->brd_no, 2095 phba->brd_no,
2169 phba->fc_ns_retry, LPFC_MAX_NS_RETRY); 2096 phba->fc_ns_retry, LPFC_MAX_NS_RETRY);
2170 2097
2171 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, 2098 ndlp = lpfc_findnode_did(phba, NameServer_DID);
2172 NameServer_DID); 2099 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
2173 if (ndlp) {
2174 if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { 2100 if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {
2175 /* Try it one more time */ 2101 /* Try it one more time */
2176 rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT); 2102 rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT);
@@ -2220,6 +2146,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2220 initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0; 2146 initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
2221 rc = lpfc_sli_issue_mbox(phba, initlinkmbox, 2147 rc = lpfc_sli_issue_mbox(phba, initlinkmbox,
2222 (MBX_NOWAIT | MBX_STOP_IOCB)); 2148 (MBX_NOWAIT | MBX_STOP_IOCB));
2149 lpfc_set_loopback_flag(phba);
2223 if (rc == MBX_NOT_FINISHED) 2150 if (rc == MBX_NOT_FINISHED)
2224 mempool_free(initlinkmbox, phba->mbox_mem_pool); 2151 mempool_free(initlinkmbox, phba->mbox_mem_pool);
2225 2152
@@ -2317,8 +2244,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
2317 2244
2318 ndlp->nlp_rpi = mb->un.varWords[0]; 2245 ndlp->nlp_rpi = mb->un.varWords[0];
2319 ndlp->nlp_type |= NLP_FABRIC; 2246 ndlp->nlp_type |= NLP_FABRIC;
2320 ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; 2247 lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
2321 lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
2322 2248
2323 /* Start issuing Fabric-Device Management Interface (FDMI) 2249 /* Start issuing Fabric-Device Management Interface (FDMI)
2324 * command to 0xfffffa (FDMI well known port) 2250 * command to 0xfffffa (FDMI well known port)
@@ -2333,87 +2259,100 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
2333 mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); 2259 mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
2334 } 2260 }
2335 2261
2262 /* Mailbox took a reference to the node */
2263 lpfc_nlp_put(ndlp);
2336 lpfc_mbuf_free(phba, mp->virt, mp->phys); 2264 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2337 kfree(mp); 2265 kfree(mp);
2338 mempool_free( pmb, phba->mbox_mem_pool); 2266 mempool_free(pmb, phba->mbox_mem_pool);
2339 2267
2340 return; 2268 return;
2341} 2269}
2342 2270
2271static int
2272lpfc_filter_by_rpi(struct lpfc_nodelist *ndlp, void *param)
2273{
2274 uint16_t *rpi = param;
2275
2276 return ndlp->nlp_rpi == *rpi;
2277}
2278
2279static int
2280lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param)
2281{
2282 return memcmp(&ndlp->nlp_portname, param,
2283 sizeof(ndlp->nlp_portname)) == 0;
2284}
2285
2286/*
2287 * Search node lists for a remote port matching filter criteria
2288 * Caller needs to hold host_lock before calling this routine.
2289 */
2290struct lpfc_nodelist *
2291__lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
2292{
2293 struct lpfc_nodelist *ndlp;
2294
2295 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
2296 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE &&
2297 filter(ndlp, param))
2298 return ndlp;
2299 }
2300 return NULL;
2301}
2302
2343/* 2303/*
2344 * This routine looks up the ndlp lists 2304 * Search node lists for a remote port matching filter criteria
2345 * for the given RPI. If rpi found 2305 * This routine is used when the caller does NOT have host_lock.
2346 * it return the node list pointer
2347 * else return NULL.
2348 */ 2306 */
2349struct lpfc_nodelist * 2307struct lpfc_nodelist *
2308lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
2309{
2310 struct lpfc_nodelist *ndlp;
2311
2312 spin_lock_irq(phba->host->host_lock);
2313 ndlp = __lpfc_find_node(phba, filter, param);
2314 spin_unlock_irq(phba->host->host_lock);
2315 return ndlp;
2316}
2317
2318/*
2319 * This routine looks up the ndlp lists for the given RPI. If rpi found it
2320 * returns the node list pointer else return NULL.
2321 */
2322struct lpfc_nodelist *
2323__lpfc_findnode_rpi(struct lpfc_hba *phba, uint16_t rpi)
2324{
2325 return __lpfc_find_node(phba, lpfc_filter_by_rpi, &rpi);
2326}
2327
2328struct lpfc_nodelist *
2350lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) 2329lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
2351{ 2330{
2352 struct lpfc_nodelist *ndlp; 2331 struct lpfc_nodelist *ndlp;
2353 struct list_head * lists[]={&phba->fc_nlpunmap_list,
2354 &phba->fc_nlpmap_list,
2355 &phba->fc_plogi_list,
2356 &phba->fc_adisc_list,
2357 &phba->fc_reglogin_list};
2358 int i;
2359 2332
2360 spin_lock_irq(phba->host->host_lock); 2333 spin_lock_irq(phba->host->host_lock);
2361 for (i = 0; i < ARRAY_SIZE(lists); i++ ) 2334 ndlp = __lpfc_findnode_rpi(phba, rpi);
2362 list_for_each_entry(ndlp, lists[i], nlp_listp)
2363 if (ndlp->nlp_rpi == rpi) {
2364 spin_unlock_irq(phba->host->host_lock);
2365 return ndlp;
2366 }
2367 spin_unlock_irq(phba->host->host_lock); 2335 spin_unlock_irq(phba->host->host_lock);
2368 return NULL; 2336 return ndlp;
2369} 2337}
2370 2338
2371/* 2339/*
2372 * This routine looks up the ndlp lists 2340 * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
2373 * for the given WWPN. If WWPN found 2341 * returns the node list pointer else return NULL.
2374 * it return the node list pointer
2375 * else return NULL.
2376 */ 2342 */
2377struct lpfc_nodelist * 2343struct lpfc_nodelist *
2378lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, 2344lpfc_findnode_wwpn(struct lpfc_hba *phba, struct lpfc_name *wwpn)
2379 struct lpfc_name * wwpn)
2380{ 2345{
2381 struct lpfc_nodelist *ndlp; 2346 struct lpfc_nodelist *ndlp;
2382 struct list_head * lists[]={&phba->fc_nlpunmap_list,
2383 &phba->fc_nlpmap_list,
2384 &phba->fc_npr_list,
2385 &phba->fc_plogi_list,
2386 &phba->fc_adisc_list,
2387 &phba->fc_reglogin_list,
2388 &phba->fc_prli_list};
2389 uint32_t search[]={NLP_SEARCH_UNMAPPED,
2390 NLP_SEARCH_MAPPED,
2391 NLP_SEARCH_NPR,
2392 NLP_SEARCH_PLOGI,
2393 NLP_SEARCH_ADISC,
2394 NLP_SEARCH_REGLOGIN,
2395 NLP_SEARCH_PRLI};
2396 int i;
2397 2347
2398 spin_lock_irq(phba->host->host_lock); 2348 spin_lock_irq(phba->host->host_lock);
2399 for (i = 0; i < ARRAY_SIZE(lists); i++ ) { 2349 ndlp = __lpfc_find_node(phba, lpfc_filter_by_wwpn, wwpn);
2400 if (!(order & search[i]))
2401 continue;
2402 list_for_each_entry(ndlp, lists[i], nlp_listp) {
2403 if (memcmp(&ndlp->nlp_portname, wwpn,
2404 sizeof(struct lpfc_name)) == 0) {
2405 spin_unlock_irq(phba->host->host_lock);
2406 return ndlp;
2407 }
2408 }
2409 }
2410 spin_unlock_irq(phba->host->host_lock); 2350 spin_unlock_irq(phba->host->host_lock);
2411 return NULL; 2351 return NULL;
2412} 2352}
2413 2353
2414void 2354void
2415lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, 2355lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
2416 uint32_t did)
2417{ 2356{
2418 memset(ndlp, 0, sizeof (struct lpfc_nodelist)); 2357 memset(ndlp, 0, sizeof (struct lpfc_nodelist));
2419 INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); 2358 INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
@@ -2423,5 +2362,30 @@ lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
2423 ndlp->nlp_DID = did; 2362 ndlp->nlp_DID = did;
2424 ndlp->nlp_phba = phba; 2363 ndlp->nlp_phba = phba;
2425 ndlp->nlp_sid = NLP_NO_SID; 2364 ndlp->nlp_sid = NLP_NO_SID;
2365 INIT_LIST_HEAD(&ndlp->nlp_listp);
2366 kref_init(&ndlp->kref);
2426 return; 2367 return;
2427} 2368}
2369
2370void
2371lpfc_nlp_release(struct kref *kref)
2372{
2373 struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
2374 kref);
2375 lpfc_nlp_remove(ndlp->nlp_phba, ndlp);
2376 mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool);
2377}
2378
2379struct lpfc_nodelist *
2380lpfc_nlp_get(struct lpfc_nodelist *ndlp)
2381{
2382 if (ndlp)
2383 kref_get(&ndlp->kref);
2384 return ndlp;
2385}
2386
2387int
2388lpfc_nlp_put(struct lpfc_nodelist *ndlp)
2389{
2390 return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0;
2391}