aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 13:47:24 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 13:47:24 -0500
commit2152f8536668a957ea3214735b4761e7b22ef7d8 (patch)
tree56723fc51445b1bc930c6400d4c00fd6fc831f88 /drivers/scsi/lpfc/lpfc_hbadisc.c
parent7cae7e26f245151b9ccad868bf2edf8c8048d307 (diff)
parent30afc84cf7325e88fb9746340eba3c161080ff49 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (138 commits) [SCSI] libata: implement minimal transport template for ->eh_timed_out [SCSI] eliminate rphy allocation in favour of expander/end device allocation [SCSI] convert mptsas over to end_device/expander allocations [SCSI] allow displaying and setting of cache type via sysfs [SCSI] add scsi_mode_select to scsi_lib.c [SCSI] 3ware 9000 add big endian support [SCSI] qla2xxx: update MAINTAINERS [SCSI] scsi: move target_destroy call [SCSI] fusion - bump version [SCSI] fusion - expander hotplug suport in mptsas module [SCSI] fusion - exposing raid components in mptsas [SCSI] fusion - memory leak, and initializing fields [SCSI] fusion - exclosure misspelled [SCSI] fusion - cleanup mptsas event handling functions [SCSI] fusion - removing target_id/bus_id from the VirtDevice structure [SCSI] fusion - static fix's [SCSI] fusion - move some debug firmware event debug msgs to verbose level [SCSI] fusion - loginfo header update [SCSI] add scsi_reprobe_device [SCSI] megaraid_sas: fix extended timeout handling ...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c575
1 files changed, 331 insertions, 244 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index a1f751e79405..6721e679df62 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-2005 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2006 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 *
@@ -59,6 +59,7 @@ static void lpfc_disc_timeout_handler(struct lpfc_hba *);
59static void 59static void
60lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) 60lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
61{ 61{
62 uint8_t *name = (uint8_t *)&ndlp->nlp_portname;
62 int warn_on = 0; 63 int warn_on = 0;
63 64
64 spin_lock_irq(phba->host->host_lock); 65 spin_lock_irq(phba->host->host_lock);
@@ -67,6 +68,15 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
67 return; 68 return;
68 } 69 }
69 70
71 /*
72 * If a discovery event readded nodev_timer after timer
73 * firing and before processing the timer, cancel the
74 * nlp_tmofunc.
75 */
76 spin_unlock_irq(phba->host->host_lock);
77 del_timer_sync(&ndlp->nlp_tmofunc);
78 spin_lock_irq(phba->host->host_lock);
79
70 ndlp->nlp_flag &= ~NLP_NODEV_TMO; 80 ndlp->nlp_flag &= ~NLP_NODEV_TMO;
71 81
72 if (ndlp->nlp_sid != NLP_NO_SID) { 82 if (ndlp->nlp_sid != NLP_NO_SID) {
@@ -79,15 +89,23 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
79 89
80 if (warn_on) { 90 if (warn_on) {
81 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 91 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
82 "%d:0203 Nodev timeout on NPort x%x " 92 "%d:0203 Nodev timeout on "
83 "Data: x%x x%x x%x\n", 93 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
84 phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, 94 "NPort x%x Data: x%x x%x x%x\n",
95 phba->brd_no,
96 *name, *(name+1), *(name+2), *(name+3),
97 *(name+4), *(name+5), *(name+6), *(name+7),
98 ndlp->nlp_DID, ndlp->nlp_flag,
85 ndlp->nlp_state, ndlp->nlp_rpi); 99 ndlp->nlp_state, ndlp->nlp_rpi);
86 } else { 100 } else {
87 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, 101 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
88 "%d:0204 Nodev timeout on NPort x%x " 102 "%d:0204 Nodev timeout on "
89 "Data: x%x x%x x%x\n", 103 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
90 phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, 104 "NPort x%x Data: x%x x%x x%x\n",
105 phba->brd_no,
106 *name, *(name+1), *(name+2), *(name+3),
107 *(name+4), *(name+5), *(name+6), *(name+7),
108 ndlp->nlp_DID, ndlp->nlp_flag,
91 ndlp->nlp_state, ndlp->nlp_rpi); 109 ndlp->nlp_state, ndlp->nlp_rpi);
92 } 110 }
93 111
@@ -108,7 +126,7 @@ lpfc_work_list_done(struct lpfc_hba * phba)
108 evt_listp); 126 evt_listp);
109 spin_unlock_irq(phba->host->host_lock); 127 spin_unlock_irq(phba->host->host_lock);
110 free_evt = 1; 128 free_evt = 1;
111 switch(evtp->evt) { 129 switch (evtp->evt) {
112 case LPFC_EVT_NODEV_TMO: 130 case LPFC_EVT_NODEV_TMO:
113 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); 131 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
114 lpfc_process_nodev_timeout(phba, ndlp); 132 lpfc_process_nodev_timeout(phba, ndlp);
@@ -120,11 +138,35 @@ lpfc_work_list_done(struct lpfc_hba * phba)
120 free_evt = 0; 138 free_evt = 0;
121 break; 139 break;
122 case LPFC_EVT_ONLINE: 140 case LPFC_EVT_ONLINE:
123 *(int *)(evtp->evt_arg1) = lpfc_online(phba); 141 if (phba->hba_state < LPFC_LINK_DOWN)
142 *(int *)(evtp->evt_arg1) = lpfc_online(phba);
143 else
144 *(int *)(evtp->evt_arg1) = 0;
124 complete((struct completion *)(evtp->evt_arg2)); 145 complete((struct completion *)(evtp->evt_arg2));
125 break; 146 break;
126 case LPFC_EVT_OFFLINE: 147 case LPFC_EVT_OFFLINE:
127 *(int *)(evtp->evt_arg1) = lpfc_offline(phba); 148 if (phba->hba_state >= LPFC_LINK_DOWN)
149 lpfc_offline(phba);
150 lpfc_sli_brdrestart(phba);
151 *(int *)(evtp->evt_arg1) =
152 lpfc_sli_brdready(phba,HS_FFRDY | HS_MBRDY);
153 complete((struct completion *)(evtp->evt_arg2));
154 break;
155 case LPFC_EVT_WARM_START:
156 if (phba->hba_state >= LPFC_LINK_DOWN)
157 lpfc_offline(phba);
158 lpfc_reset_barrier(phba);
159 lpfc_sli_brdreset(phba);
160 lpfc_hba_down_post(phba);
161 *(int *)(evtp->evt_arg1) =
162 lpfc_sli_brdready(phba, HS_MBRDY);
163 complete((struct completion *)(evtp->evt_arg2));
164 break;
165 case LPFC_EVT_KILL:
166 if (phba->hba_state >= LPFC_LINK_DOWN)
167 lpfc_offline(phba);
168 *(int *)(evtp->evt_arg1)
169 = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba);
128 complete((struct completion *)(evtp->evt_arg2)); 170 complete((struct completion *)(evtp->evt_arg2));
129 break; 171 break;
130 } 172 }
@@ -151,13 +193,13 @@ lpfc_work_done(struct lpfc_hba * phba)
151 work_hba_events=phba->work_hba_events; 193 work_hba_events=phba->work_hba_events;
152 spin_unlock_irq(phba->host->host_lock); 194 spin_unlock_irq(phba->host->host_lock);
153 195
154 if(ha_copy & HA_ERATT) 196 if (ha_copy & HA_ERATT)
155 lpfc_handle_eratt(phba); 197 lpfc_handle_eratt(phba);
156 198
157 if(ha_copy & HA_MBATT) 199 if (ha_copy & HA_MBATT)
158 lpfc_sli_handle_mb_event(phba); 200 lpfc_sli_handle_mb_event(phba);
159 201
160 if(ha_copy & HA_LATT) 202 if (ha_copy & HA_LATT)
161 lpfc_handle_latt(phba); 203 lpfc_handle_latt(phba);
162 204
163 if (work_hba_events & WORKER_DISC_TMO) 205 if (work_hba_events & WORKER_DISC_TMO)
@@ -283,16 +325,20 @@ lpfc_linkdown(struct lpfc_hba * phba)
283{ 325{
284 struct lpfc_sli *psli; 326 struct lpfc_sli *psli;
285 struct lpfc_nodelist *ndlp, *next_ndlp; 327 struct lpfc_nodelist *ndlp, *next_ndlp;
286 struct list_head *listp; 328 struct list_head *listp, *node_list[7];
287 struct list_head *node_list[7];
288 LPFC_MBOXQ_t *mb; 329 LPFC_MBOXQ_t *mb;
289 int rc, i; 330 int rc, i;
290 331
291 psli = &phba->sli; 332 psli = &phba->sli;
333 /* sysfs or selective reset may call this routine to clean up */
334 if (phba->hba_state >= LPFC_LINK_DOWN) {
335 if (phba->hba_state == LPFC_LINK_DOWN)
336 return 0;
292 337
293 spin_lock_irq(phba->host->host_lock); 338 spin_lock_irq(phba->host->host_lock);
294 phba->hba_state = LPFC_LINK_DOWN; 339 phba->hba_state = LPFC_LINK_DOWN;
295 spin_unlock_irq(phba->host->host_lock); 340 spin_unlock_irq(phba->host->host_lock);
341 }
296 342
297 /* Clean up any firmware default rpi's */ 343 /* Clean up any firmware default rpi's */
298 if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { 344 if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
@@ -324,32 +370,19 @@ lpfc_linkdown(struct lpfc_hba * phba)
324 continue; 370 continue;
325 371
326 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { 372 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
327 /* Fabric nodes are not handled thru state machine for 373
328 link down */ 374 rc = lpfc_disc_state_machine(phba, ndlp, NULL,
329 if (ndlp->nlp_type & NLP_FABRIC) { 375 NLP_EVT_DEVICE_RECOVERY);
330 /* Remove ALL Fabric nodes except Fabric_DID */ 376
331 if (ndlp->nlp_DID != Fabric_DID) { 377 /* Check config parameter use-adisc or FCP-2 */
332 /* Take it off current list and free */ 378 if ((rc != NLP_STE_FREED_NODE) &&
333 lpfc_nlp_list(phba, ndlp, 379 (phba->cfg_use_adisc == 0) &&
334 NLP_NO_LIST); 380 !(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) {
335 } 381 /* We know we will have to relogin, so
336 } 382 * unreglogin the rpi right now to fail
337 else { 383 * any outstanding I/Os quickly.
338 384 */
339 rc = lpfc_disc_state_machine(phba, ndlp, NULL, 385 lpfc_unreg_rpi(phba, ndlp);
340 NLP_EVT_DEVICE_RECOVERY);
341
342 /* Check config parameter use-adisc or FCP-2 */
343 if ((rc != NLP_STE_FREED_NODE) &&
344 (phba->cfg_use_adisc == 0) &&
345 !(ndlp->nlp_fcp_info &
346 NLP_FCP_2_DEVICE)) {
347 /* We know we will have to relogin, so
348 * unreglogin the rpi right now to fail
349 * any outstanding I/Os quickly.
350 */
351 lpfc_unreg_rpi(phba, ndlp);
352 }
353 } 386 }
354 } 387 }
355 } 388 }
@@ -384,13 +417,15 @@ lpfc_linkdown(struct lpfc_hba * phba)
384 lpfc_can_disctmo(phba); 417 lpfc_can_disctmo(phba);
385 418
386 /* Must process IOCBs on all rings to handle ABORTed I/Os */ 419 /* Must process IOCBs on all rings to handle ABORTed I/Os */
387 return (0); 420 return 0;
388} 421}
389 422
390static int 423static int
391lpfc_linkup(struct lpfc_hba * phba) 424lpfc_linkup(struct lpfc_hba * phba)
392{ 425{
393 struct lpfc_nodelist *ndlp, *next_ndlp; 426 struct lpfc_nodelist *ndlp, *next_ndlp;
427 struct list_head *listp, *node_list[7];
428 int i;
394 429
395 spin_lock_irq(phba->host->host_lock); 430 spin_lock_irq(phba->host->host_lock);
396 phba->hba_state = LPFC_LINK_UP; 431 phba->hba_state = LPFC_LINK_UP;
@@ -401,14 +436,33 @@ lpfc_linkup(struct lpfc_hba * phba)
401 spin_unlock_irq(phba->host->host_lock); 436 spin_unlock_irq(phba->host->host_lock);
402 437
403 438
404 /* 439 node_list[0] = &phba->fc_plogi_list;
405 * Clean up old Fabric NLP_FABRIC logins. 440 node_list[1] = &phba->fc_adisc_list;
406 */ 441 node_list[2] = &phba->fc_reglogin_list;
407 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, 442 node_list[3] = &phba->fc_prli_list;
408 nlp_listp) { 443 node_list[4] = &phba->fc_nlpunmap_list;
409 if (ndlp->nlp_DID == Fabric_DID) { 444 node_list[5] = &phba->fc_nlpmap_list;
410 /* Take it off current list and free */ 445 node_list[6] = &phba->fc_npr_list;
411 lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); 446 for (i = 0; i < 7; i++) {
447 listp = node_list[i];
448 if (list_empty(listp))
449 continue;
450
451 list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
452 if (phba->fc_flag & FC_LBIT) {
453 if (ndlp->nlp_type & NLP_FABRIC) {
454 /* On Linkup its safe to clean up the
455 * ndlp from Fabric connections.
456 */
457 lpfc_nlp_list(phba, ndlp,
458 NLP_UNUSED_LIST);
459 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
460 /* Fail outstanding IO now since device
461 * is marked for PLOGI.
462 */
463 lpfc_unreg_rpi(phba, ndlp);
464 }
465 }
412 } 466 }
413 } 467 }
414 468
@@ -462,7 +516,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
462 lpfc_els_disc_plogi(phba); 516 lpfc_els_disc_plogi(phba);
463 } 517 }
464 518
465 if(!phba->num_disc_nodes) { 519 if (!phba->num_disc_nodes) {
466 spin_lock_irq(phba->host->host_lock); 520 spin_lock_irq(phba->host->host_lock);
467 phba->fc_flag &= ~FC_NDISC_ACTIVE; 521 phba->fc_flag &= ~FC_NDISC_ACTIVE;
468 spin_unlock_irq(phba->host->host_lock); 522 spin_unlock_irq(phba->host->host_lock);
@@ -504,80 +558,59 @@ out:
504} 558}
505 559
506static void 560static void
507lpfc_mbx_cmpl_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 561lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
508{ 562{
509 struct lpfc_sli *psli; 563 struct lpfc_sli *psli = &phba->sli;
510 MAILBOX_t *mb; 564 int rc;
511
512 psli = &phba->sli;
513 mb = &pmb->mb;
514 /* Check for error */
515 if (mb->mbxStatus) {
516 /* CONFIG_LINK mbox error <mbxStatus> state <hba_state> */
517 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
518 "%d:0306 CONFIG_LINK mbxStatus error x%x "
519 "HBA state x%x\n",
520 phba->brd_no, mb->mbxStatus, phba->hba_state);
521 565
522 lpfc_linkdown(phba); 566 if (pmb->mb.mbxStatus)
523 phba->hba_state = LPFC_HBA_ERROR;
524 goto out; 567 goto out;
525 }
526 568
527 if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { 569 mempool_free(pmb, phba->mbox_mem_pool);
528 if (phba->fc_topology == TOPOLOGY_LOOP) { 570
529 /* If we are public loop and L bit was set */ 571 if (phba->fc_topology == TOPOLOGY_LOOP &&
530 if ((phba->fc_flag & FC_PUBLIC_LOOP) && 572 phba->fc_flag & FC_PUBLIC_LOOP &&
531 !(phba->fc_flag & FC_LBIT)) { 573 !(phba->fc_flag & FC_LBIT)) {
532 /* Need to wait for FAN - use discovery timer 574 /* Need to wait for FAN - use discovery timer
533 * for timeout. hba_state is identically 575 * for timeout. hba_state is identically
534 * LPFC_LOCAL_CFG_LINK while waiting for FAN 576 * LPFC_LOCAL_CFG_LINK while waiting for FAN
535 */ 577 */
536 lpfc_set_disctmo(phba); 578 lpfc_set_disctmo(phba);
537 mempool_free( pmb, phba->mbox_mem_pool); 579 return;
538 return;
539 }
540 } 580 }
541 581
542 /* Start discovery by sending a FLOGI hba_state is identically 582 /* Start discovery by sending a FLOGI. hba_state is identically
543 * LPFC_FLOGI while waiting for FLOGI cmpl 583 * LPFC_FLOGI while waiting for FLOGI cmpl
544 */ 584 */
545 phba->hba_state = LPFC_FLOGI; 585 phba->hba_state = LPFC_FLOGI;
546 lpfc_set_disctmo(phba); 586 lpfc_set_disctmo(phba);
547 lpfc_initial_flogi(phba); 587 lpfc_initial_flogi(phba);
548 mempool_free( pmb, phba->mbox_mem_pool); 588 return;
549 return;
550 }
551 if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {
552 mempool_free( pmb, phba->mbox_mem_pool);
553 return;
554 }
555 589
556out: 590out:
557 /* CONFIG_LINK bad hba state <hba_state> */ 591 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
558 lpfc_printf_log(phba, 592 "%d:0306 CONFIG_LINK mbxStatus error x%x "
559 KERN_ERR, 593 "HBA state x%x\n",
560 LOG_DISCOVERY, 594 phba->brd_no, pmb->mb.mbxStatus, phba->hba_state);
595
596 lpfc_linkdown(phba);
597
598 phba->hba_state = LPFC_HBA_ERROR;
599
600 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
561 "%d:0200 CONFIG_LINK bad hba state x%x\n", 601 "%d:0200 CONFIG_LINK bad hba state x%x\n",
562 phba->brd_no, phba->hba_state); 602 phba->brd_no, phba->hba_state);
563 603
564 if (phba->hba_state != LPFC_CLEAR_LA) { 604 lpfc_clear_la(phba, pmb);
565 lpfc_clear_la(phba, pmb); 605 pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
566 pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; 606 rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
567 if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) 607 if (rc == MBX_NOT_FINISHED) {
568 == MBX_NOT_FINISHED) { 608 mempool_free(pmb, phba->mbox_mem_pool);
569 mempool_free( pmb, phba->mbox_mem_pool); 609 lpfc_disc_flush_list(phba);
570 lpfc_disc_flush_list(phba); 610 psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
571 psli->ring[(psli->ip_ring)].flag &= 611 psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
572 ~LPFC_STOP_IOCB_EVENT; 612 psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
573 psli->ring[(psli->fcp_ring)].flag &= 613 phba->hba_state = LPFC_HBA_READY;
574 ~LPFC_STOP_IOCB_EVENT;
575 psli->ring[(psli->next_ring)].flag &=
576 ~LPFC_STOP_IOCB_EVENT;
577 phba->hba_state = LPFC_HBA_READY;
578 }
579 } else {
580 mempool_free( pmb, phba->mbox_mem_pool);
581 } 614 }
582 return; 615 return;
583} 616}
@@ -650,7 +683,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
650 cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 683 cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
651 684
652 spin_lock_irq(phba->host->host_lock); 685 spin_lock_irq(phba->host->host_lock);
653 switch(la->UlnkSpeed) { 686 switch (la->UlnkSpeed) {
654 case LA_1GHZ_LINK: 687 case LA_1GHZ_LINK:
655 phba->fc_linkspeed = LA_1GHZ_LINK; 688 phba->fc_linkspeed = LA_1GHZ_LINK;
656 break; 689 break;
@@ -731,7 +764,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
731 if (cfglink_mbox) { 764 if (cfglink_mbox) {
732 phba->hba_state = LPFC_LOCAL_CFG_LINK; 765 phba->hba_state = LPFC_LOCAL_CFG_LINK;
733 lpfc_config_link(phba, cfglink_mbox); 766 lpfc_config_link(phba, cfglink_mbox);
734 cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_config_link; 767 cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
735 lpfc_sli_issue_mbox(phba, cfglink_mbox, 768 lpfc_sli_issue_mbox(phba, cfglink_mbox,
736 (MBX_NOWAIT | MBX_STOP_IOCB)); 769 (MBX_NOWAIT | MBX_STOP_IOCB));
737 } 770 }
@@ -784,6 +817,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
784 817
785 memcpy(&phba->alpa_map[0], mp->virt, 128); 818 memcpy(&phba->alpa_map[0], mp->virt, 128);
786 819
820 spin_lock_irq(phba->host->host_lock);
821 if (la->pb)
822 phba->fc_flag |= FC_BYPASSED_MODE;
823 else
824 phba->fc_flag &= ~FC_BYPASSED_MODE;
825 spin_unlock_irq(phba->host->host_lock);
826
787 if (((phba->fc_eventTag + 1) < la->eventTag) || 827 if (((phba->fc_eventTag + 1) < la->eventTag) ||
788 (phba->fc_eventTag == la->eventTag)) { 828 (phba->fc_eventTag == la->eventTag)) {
789 phba->fc_stat.LinkMultiEvent++; 829 phba->fc_stat.LinkMultiEvent++;
@@ -904,32 +944,36 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
904 */ 944 */
905 lpfc_issue_els_scr(phba, SCR_DID, 0); 945 lpfc_issue_els_scr(phba, SCR_DID, 0);
906 946
907 /* Allocate a new node instance. If the pool is empty, just 947 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID);
908 * start the discovery process and skip the Nameserver login 948 if (!ndlp) {
909 * process. This is attempted again later on. Otherwise, issue 949 /* Allocate a new node instance. If the pool is empty,
910 * a Port Login (PLOGI) to the NameServer 950 * start the discovery process and skip the Nameserver
911 */ 951 * login process. This is attempted again later on.
912 if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) 952 * Otherwise, issue a Port Login (PLOGI) to NameServer.
913 == 0) { 953 */
914 lpfc_disc_start(phba); 954 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
915 } else { 955 if (!ndlp) {
916 lpfc_nlp_init(phba, ndlp, NameServer_DID); 956 lpfc_disc_start(phba);
917 ndlp->nlp_type |= NLP_FABRIC; 957 lpfc_mbuf_free(phba, mp->virt, mp->phys);
918 ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; 958 kfree(mp);
919 lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); 959 mempool_free( pmb, phba->mbox_mem_pool);
920 lpfc_issue_els_plogi(phba, ndlp, 0); 960 return;
921 if (phba->cfg_fdmi_on) { 961 } else {
922 if ((ndlp_fdmi = mempool_alloc( 962 lpfc_nlp_init(phba, ndlp, NameServer_DID);
923 phba->nlp_mem_pool, 963 ndlp->nlp_type |= NLP_FABRIC;
924 GFP_KERNEL))) { 964 }
925 lpfc_nlp_init(phba, ndlp_fdmi, 965 }
926 FDMI_DID); 966 ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
927 ndlp_fdmi->nlp_type |= NLP_FABRIC; 967 lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
928 ndlp_fdmi->nlp_state = 968 lpfc_issue_els_plogi(phba, NameServer_DID, 0);
929 NLP_STE_PLOGI_ISSUE; 969 if (phba->cfg_fdmi_on) {
930 lpfc_issue_els_plogi(phba, ndlp_fdmi, 970 ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
931 0); 971 GFP_KERNEL);
932 } 972 if (ndlp_fdmi) {
973 lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID);
974 ndlp_fdmi->nlp_type |= NLP_FABRIC;
975 ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE;
976 lpfc_issue_els_plogi(phba, FDMI_DID, 0);
933 } 977 }
934 } 978 }
935 } 979 }
@@ -937,7 +981,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
937 lpfc_mbuf_free(phba, mp->virt, mp->phys); 981 lpfc_mbuf_free(phba, mp->virt, mp->phys);
938 kfree(mp); 982 kfree(mp);
939 mempool_free( pmb, phba->mbox_mem_pool); 983 mempool_free( pmb, phba->mbox_mem_pool);
940
941 return; 984 return;
942} 985}
943 986
@@ -1070,12 +1113,12 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1070 1113
1071 psli = &phba->sli; 1114 psli = &phba->sli;
1072 /* Sanity check to ensure we are not moving to / from the same list */ 1115 /* Sanity check to ensure we are not moving to / from the same list */
1073 if ((nlp->nlp_flag & NLP_LIST_MASK) == list) { 1116 if ((nlp->nlp_flag & NLP_LIST_MASK) == list)
1074 if (list != NLP_NO_LIST) 1117 if (list != NLP_NO_LIST)
1075 return(0); 1118 return 0;
1076 }
1077 1119
1078 switch(nlp->nlp_flag & NLP_LIST_MASK) { 1120 spin_lock_irq(phba->host->host_lock);
1121 switch (nlp->nlp_flag & NLP_LIST_MASK) {
1079 case NLP_NO_LIST: /* Not on any list */ 1122 case NLP_NO_LIST: /* Not on any list */
1080 break; 1123 break;
1081 case NLP_UNUSED_LIST: 1124 case NLP_UNUSED_LIST:
@@ -1101,10 +1144,8 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1101 case NLP_UNMAPPED_LIST: 1144 case NLP_UNMAPPED_LIST:
1102 phba->fc_unmap_cnt--; 1145 phba->fc_unmap_cnt--;
1103 list_del(&nlp->nlp_listp); 1146 list_del(&nlp->nlp_listp);
1104 spin_lock_irq(phba->host->host_lock);
1105 nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; 1147 nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID;
1106 nlp->nlp_type &= ~NLP_FC_NODE; 1148 nlp->nlp_type &= ~NLP_FC_NODE;
1107 spin_unlock_irq(phba->host->host_lock);
1108 phba->nport_event_cnt++; 1149 phba->nport_event_cnt++;
1109 if (nlp->rport) 1150 if (nlp->rport)
1110 rport_del = unmapped; 1151 rport_del = unmapped;
@@ -1122,19 +1163,14 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1122 /* Stop delay tmo if taking node off NPR list */ 1163 /* Stop delay tmo if taking node off NPR list */
1123 if ((nlp->nlp_flag & NLP_DELAY_TMO) && 1164 if ((nlp->nlp_flag & NLP_DELAY_TMO) &&
1124 (list != NLP_NPR_LIST)) { 1165 (list != NLP_NPR_LIST)) {
1125 spin_lock_irq(phba->host->host_lock);
1126 nlp->nlp_flag &= ~NLP_DELAY_TMO;
1127 spin_unlock_irq(phba->host->host_lock); 1166 spin_unlock_irq(phba->host->host_lock);
1128 del_timer_sync(&nlp->nlp_delayfunc); 1167 lpfc_cancel_retry_delay_tmo(phba, nlp);
1129 if (!list_empty(&nlp->els_retry_evt.evt_listp)) 1168 spin_lock_irq(phba->host->host_lock);
1130 list_del_init(&nlp->els_retry_evt.evt_listp);
1131 } 1169 }
1132 break; 1170 break;
1133 } 1171 }
1134 1172
1135 spin_lock_irq(phba->host->host_lock);
1136 nlp->nlp_flag &= ~NLP_LIST_MASK; 1173 nlp->nlp_flag &= ~NLP_LIST_MASK;
1137 spin_unlock_irq(phba->host->host_lock);
1138 1174
1139 /* Add NPort <did> to <num> list */ 1175 /* Add NPort <did> to <num> list */
1140 lpfc_printf_log(phba, 1176 lpfc_printf_log(phba,
@@ -1144,48 +1180,40 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1144 phba->brd_no, 1180 phba->brd_no,
1145 nlp->nlp_DID, list, nlp->nlp_flag); 1181 nlp->nlp_DID, list, nlp->nlp_flag);
1146 1182
1147 switch(list) { 1183 switch (list) {
1148 case NLP_NO_LIST: /* No list, just remove it */ 1184 case NLP_NO_LIST: /* No list, just remove it */
1185 spin_unlock_irq(phba->host->host_lock);
1149 lpfc_nlp_remove(phba, nlp); 1186 lpfc_nlp_remove(phba, nlp);
1187 spin_lock_irq(phba->host->host_lock);
1150 /* as node removed - stop further transport calls */ 1188 /* as node removed - stop further transport calls */
1151 rport_del = none; 1189 rport_del = none;
1152 break; 1190 break;
1153 case NLP_UNUSED_LIST: 1191 case NLP_UNUSED_LIST:
1154 spin_lock_irq(phba->host->host_lock);
1155 nlp->nlp_flag |= list; 1192 nlp->nlp_flag |= list;
1156 spin_unlock_irq(phba->host->host_lock);
1157 /* Put it at the end of the unused list */ 1193 /* Put it at the end of the unused list */
1158 list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list); 1194 list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list);
1159 phba->fc_unused_cnt++; 1195 phba->fc_unused_cnt++;
1160 break; 1196 break;
1161 case NLP_PLOGI_LIST: 1197 case NLP_PLOGI_LIST:
1162 spin_lock_irq(phba->host->host_lock);
1163 nlp->nlp_flag |= list; 1198 nlp->nlp_flag |= list;
1164 spin_unlock_irq(phba->host->host_lock);
1165 /* Put it at the end of the plogi list */ 1199 /* Put it at the end of the plogi list */
1166 list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list); 1200 list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list);
1167 phba->fc_plogi_cnt++; 1201 phba->fc_plogi_cnt++;
1168 break; 1202 break;
1169 case NLP_ADISC_LIST: 1203 case NLP_ADISC_LIST:
1170 spin_lock_irq(phba->host->host_lock);
1171 nlp->nlp_flag |= list; 1204 nlp->nlp_flag |= list;
1172 spin_unlock_irq(phba->host->host_lock);
1173 /* Put it at the end of the adisc list */ 1205 /* Put it at the end of the adisc list */
1174 list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list); 1206 list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list);
1175 phba->fc_adisc_cnt++; 1207 phba->fc_adisc_cnt++;
1176 break; 1208 break;
1177 case NLP_REGLOGIN_LIST: 1209 case NLP_REGLOGIN_LIST:
1178 spin_lock_irq(phba->host->host_lock);
1179 nlp->nlp_flag |= list; 1210 nlp->nlp_flag |= list;
1180 spin_unlock_irq(phba->host->host_lock);
1181 /* Put it at the end of the reglogin list */ 1211 /* Put it at the end of the reglogin list */
1182 list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list); 1212 list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list);
1183 phba->fc_reglogin_cnt++; 1213 phba->fc_reglogin_cnt++;
1184 break; 1214 break;
1185 case NLP_PRLI_LIST: 1215 case NLP_PRLI_LIST:
1186 spin_lock_irq(phba->host->host_lock);
1187 nlp->nlp_flag |= list; 1216 nlp->nlp_flag |= list;
1188 spin_unlock_irq(phba->host->host_lock);
1189 /* Put it at the end of the prli list */ 1217 /* Put it at the end of the prli list */
1190 list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list); 1218 list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list);
1191 phba->fc_prli_cnt++; 1219 phba->fc_prli_cnt++;
@@ -1194,19 +1222,17 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1194 rport_add = unmapped; 1222 rport_add = unmapped;
1195 /* ensure all vestiges of "mapped" significance are gone */ 1223 /* ensure all vestiges of "mapped" significance are gone */
1196 nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); 1224 nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
1197 spin_lock_irq(phba->host->host_lock);
1198 nlp->nlp_flag |= list; 1225 nlp->nlp_flag |= list;
1199 spin_unlock_irq(phba->host->host_lock);
1200 /* Put it at the end of the unmap list */ 1226 /* Put it at the end of the unmap list */
1201 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list); 1227 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list);
1202 phba->fc_unmap_cnt++; 1228 phba->fc_unmap_cnt++;
1203 phba->nport_event_cnt++; 1229 phba->nport_event_cnt++;
1204 /* stop nodev tmo if running */ 1230 /* stop nodev tmo if running */
1205 if (nlp->nlp_flag & NLP_NODEV_TMO) { 1231 if (nlp->nlp_flag & NLP_NODEV_TMO) {
1206 spin_lock_irq(phba->host->host_lock);
1207 nlp->nlp_flag &= ~NLP_NODEV_TMO; 1232 nlp->nlp_flag &= ~NLP_NODEV_TMO;
1208 spin_unlock_irq(phba->host->host_lock); 1233 spin_unlock_irq(phba->host->host_lock);
1209 del_timer_sync(&nlp->nlp_tmofunc); 1234 del_timer_sync(&nlp->nlp_tmofunc);
1235 spin_lock_irq(phba->host->host_lock);
1210 if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) 1236 if (!list_empty(&nlp->nodev_timeout_evt.evt_listp))
1211 list_del_init(&nlp->nodev_timeout_evt. 1237 list_del_init(&nlp->nodev_timeout_evt.
1212 evt_listp); 1238 evt_listp);
@@ -1216,9 +1242,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1216 break; 1242 break;
1217 case NLP_MAPPED_LIST: 1243 case NLP_MAPPED_LIST:
1218 rport_add = mapped; 1244 rport_add = mapped;
1219 spin_lock_irq(phba->host->host_lock);
1220 nlp->nlp_flag |= list; 1245 nlp->nlp_flag |= list;
1221 spin_unlock_irq(phba->host->host_lock);
1222 /* Put it at the end of the map list */ 1246 /* Put it at the end of the map list */
1223 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list); 1247 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list);
1224 phba->fc_map_cnt++; 1248 phba->fc_map_cnt++;
@@ -1226,7 +1250,9 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1226 /* stop nodev tmo if running */ 1250 /* stop nodev tmo if running */
1227 if (nlp->nlp_flag & NLP_NODEV_TMO) { 1251 if (nlp->nlp_flag & NLP_NODEV_TMO) {
1228 nlp->nlp_flag &= ~NLP_NODEV_TMO; 1252 nlp->nlp_flag &= ~NLP_NODEV_TMO;
1253 spin_unlock_irq(phba->host->host_lock);
1229 del_timer_sync(&nlp->nlp_tmofunc); 1254 del_timer_sync(&nlp->nlp_tmofunc);
1255 spin_lock_irq(phba->host->host_lock);
1230 if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) 1256 if (!list_empty(&nlp->nodev_timeout_evt.evt_listp))
1231 list_del_init(&nlp->nodev_timeout_evt. 1257 list_del_init(&nlp->nodev_timeout_evt.
1232 evt_listp); 1258 evt_listp);
@@ -1234,33 +1260,24 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1234 } 1260 }
1235 break; 1261 break;
1236 case NLP_NPR_LIST: 1262 case NLP_NPR_LIST:
1237 spin_lock_irq(phba->host->host_lock);
1238 nlp->nlp_flag |= list; 1263 nlp->nlp_flag |= list;
1239 spin_unlock_irq(phba->host->host_lock);
1240 /* Put it at the end of the npr list */ 1264 /* Put it at the end of the npr list */
1241 list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); 1265 list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list);
1242 phba->fc_npr_cnt++; 1266 phba->fc_npr_cnt++;
1243 1267
1244 /* 1268 if (!(nlp->nlp_flag & NLP_NODEV_TMO))
1245 * Sanity check for Fabric entity.
1246 * Set nodev_tmo for NPR state, for Fabric use 1 sec.
1247 */
1248 if (nlp->nlp_type & NLP_FABRIC) {
1249 mod_timer(&nlp->nlp_tmofunc, jiffies + HZ);
1250 }
1251 else {
1252 mod_timer(&nlp->nlp_tmofunc, 1269 mod_timer(&nlp->nlp_tmofunc,
1253 jiffies + HZ * phba->cfg_nodev_tmo); 1270 jiffies + HZ * phba->cfg_nodev_tmo);
1254 } 1271
1255 spin_lock_irq(phba->host->host_lock);
1256 nlp->nlp_flag |= NLP_NODEV_TMO; 1272 nlp->nlp_flag |= NLP_NODEV_TMO;
1257 nlp->nlp_flag &= ~NLP_RCV_PLOGI; 1273 nlp->nlp_flag &= ~NLP_RCV_PLOGI;
1258 spin_unlock_irq(phba->host->host_lock);
1259 break; 1274 break;
1260 case NLP_JUST_DQ: 1275 case NLP_JUST_DQ:
1261 break; 1276 break;
1262 } 1277 }
1263 1278
1279 spin_unlock_irq(phba->host->host_lock);
1280
1264 /* 1281 /*
1265 * We make all the calls into the transport after we have 1282 * We make all the calls into the transport after we have
1266 * moved the node between lists. This so that we don't 1283 * moved the node between lists. This so that we don't
@@ -1303,7 +1320,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1303 } 1320 }
1304 } 1321 }
1305 } 1322 }
1306 return (0); 1323 return 0;
1307} 1324}
1308 1325
1309/* 1326/*
@@ -1314,7 +1331,15 @@ lpfc_set_disctmo(struct lpfc_hba * phba)
1314{ 1331{
1315 uint32_t tmo; 1332 uint32_t tmo;
1316 1333
1317 tmo = ((phba->fc_ratov * 2) + 1); 1334 if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
1335 /* For FAN, timeout should be greater then edtov */
1336 tmo = (((phba->fc_edtov + 999) / 1000) + 1);
1337 } else {
1338 /* Normal discovery timeout should be > then ELS/CT timeout
1339 * FC spec states we need 3 * ratov for CT requests
1340 */
1341 tmo = ((phba->fc_ratov * 3) + 3);
1342 }
1318 1343
1319 mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); 1344 mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo);
1320 spin_lock_irq(phba->host->host_lock); 1345 spin_lock_irq(phba->host->host_lock);
@@ -1354,7 +1379,7 @@ lpfc_can_disctmo(struct lpfc_hba * phba)
1354 phba->brd_no, phba->hba_state, phba->fc_flag, 1379 phba->brd_no, phba->hba_state, phba->fc_flag,
1355 phba->fc_plogi_cnt, phba->fc_adisc_cnt); 1380 phba->fc_plogi_cnt, phba->fc_adisc_cnt);
1356 1381
1357 return (0); 1382 return 0;
1358} 1383}
1359 1384
1360/* 1385/*
@@ -1375,11 +1400,11 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
1375 switch (icmd->ulpCommand) { 1400 switch (icmd->ulpCommand) {
1376 case CMD_GEN_REQUEST64_CR: 1401 case CMD_GEN_REQUEST64_CR:
1377 if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) 1402 if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi)
1378 return (1); 1403 return 1;
1379 case CMD_ELS_REQUEST64_CR: 1404 case CMD_ELS_REQUEST64_CR:
1380 case CMD_XMIT_ELS_RSP64_CX: 1405 case CMD_XMIT_ELS_RSP64_CX:
1381 if (iocb->context1 == (uint8_t *) ndlp) 1406 if (iocb->context1 == (uint8_t *) ndlp)
1382 return (1); 1407 return 1;
1383 } 1408 }
1384 } else if (pring->ringno == psli->ip_ring) { 1409 } else if (pring->ringno == psli->ip_ring) {
1385 1410
@@ -1387,15 +1412,15 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
1387 /* Skip match check if waiting to relogin to FCP target */ 1412 /* Skip match check if waiting to relogin to FCP target */
1388 if ((ndlp->nlp_type & NLP_FCP_TARGET) && 1413 if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
1389 (ndlp->nlp_flag & NLP_DELAY_TMO)) { 1414 (ndlp->nlp_flag & NLP_DELAY_TMO)) {
1390 return (0); 1415 return 0;
1391 } 1416 }
1392 if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) { 1417 if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) {
1393 return (1); 1418 return 1;
1394 } 1419 }
1395 } else if (pring->ringno == psli->next_ring) { 1420 } else if (pring->ringno == psli->next_ring) {
1396 1421
1397 } 1422 }
1398 return (0); 1423 return 0;
1399} 1424}
1400 1425
1401/* 1426/*
@@ -1456,7 +1481,7 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1456 1481
1457 } 1482 }
1458 } 1483 }
1459 return (0); 1484 return 0;
1460} 1485}
1461 1486
1462/* 1487/*
@@ -1547,6 +1572,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1547 spin_unlock_irq(phba->host->host_lock); 1572 spin_unlock_irq(phba->host->host_lock);
1548 del_timer_sync(&ndlp->nlp_tmofunc); 1573 del_timer_sync(&ndlp->nlp_tmofunc);
1549 1574
1575 ndlp->nlp_last_elscmd = 0;
1550 del_timer_sync(&ndlp->nlp_delayfunc); 1576 del_timer_sync(&ndlp->nlp_delayfunc);
1551 1577
1552 if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) 1578 if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp))
@@ -1556,7 +1582,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1556 1582
1557 lpfc_unreg_rpi(phba, ndlp); 1583 lpfc_unreg_rpi(phba, ndlp);
1558 1584
1559 return (0); 1585 return 0;
1560} 1586}
1561 1587
1562/* 1588/*
@@ -1579,24 +1605,18 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1579 1605
1580 1606
1581 if (ndlp->nlp_flag & NLP_DELAY_TMO) { 1607 if (ndlp->nlp_flag & NLP_DELAY_TMO) {
1582 spin_lock_irq(phba->host->host_lock); 1608 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1583 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
1584 spin_unlock_irq(phba->host->host_lock);
1585 del_timer_sync(&ndlp->nlp_delayfunc);
1586 if (!list_empty(&ndlp->els_retry_evt.evt_listp))
1587 list_del_init(&ndlp->els_retry_evt.evt_listp);
1588 } 1609 }
1589 1610
1590 if (ndlp->nlp_disc_refcnt) { 1611 if (ndlp->nlp_disc_refcnt) {
1591 spin_lock_irq(phba->host->host_lock); 1612 spin_lock_irq(phba->host->host_lock);
1592 ndlp->nlp_flag |= NLP_DELAY_REMOVE; 1613 ndlp->nlp_flag |= NLP_DELAY_REMOVE;
1593 spin_unlock_irq(phba->host->host_lock); 1614 spin_unlock_irq(phba->host->host_lock);
1594 } 1615 } else {
1595 else {
1596 lpfc_freenode(phba, ndlp); 1616 lpfc_freenode(phba, ndlp);
1597 mempool_free( ndlp, phba->nlp_mem_pool); 1617 mempool_free( ndlp, phba->nlp_mem_pool);
1598 } 1618 }
1599 return(0); 1619 return 0;
1600} 1620}
1601 1621
1602static int 1622static int
@@ -1607,20 +1627,20 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did)
1607 D_ID matchdid; 1627 D_ID matchdid;
1608 1628
1609 if (did == Bcast_DID) 1629 if (did == Bcast_DID)
1610 return (0); 1630 return 0;
1611 1631
1612 if (ndlp->nlp_DID == 0) { 1632 if (ndlp->nlp_DID == 0) {
1613 return (0); 1633 return 0;
1614 } 1634 }
1615 1635
1616 /* First check for Direct match */ 1636 /* First check for Direct match */
1617 if (ndlp->nlp_DID == did) 1637 if (ndlp->nlp_DID == did)
1618 return (1); 1638 return 1;
1619 1639
1620 /* Next check for area/domain identically equals 0 match */ 1640 /* Next check for area/domain identically equals 0 match */
1621 mydid.un.word = phba->fc_myDID; 1641 mydid.un.word = phba->fc_myDID;
1622 if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { 1642 if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) {
1623 return (0); 1643 return 0;
1624 } 1644 }
1625 1645
1626 matchdid.un.word = did; 1646 matchdid.un.word = did;
@@ -1631,9 +1651,9 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did)
1631 if ((ndlpdid.un.b.domain == 0) && 1651 if ((ndlpdid.un.b.domain == 0) &&
1632 (ndlpdid.un.b.area == 0)) { 1652 (ndlpdid.un.b.area == 0)) {
1633 if (ndlpdid.un.b.id) 1653 if (ndlpdid.un.b.id)
1634 return (1); 1654 return 1;
1635 } 1655 }
1636 return (0); 1656 return 0;
1637 } 1657 }
1638 1658
1639 matchdid.un.word = ndlp->nlp_DID; 1659 matchdid.un.word = ndlp->nlp_DID;
@@ -1642,11 +1662,11 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did)
1642 if ((matchdid.un.b.domain == 0) && 1662 if ((matchdid.un.b.domain == 0) &&
1643 (matchdid.un.b.area == 0)) { 1663 (matchdid.un.b.area == 0)) {
1644 if (matchdid.un.b.id) 1664 if (matchdid.un.b.id)
1645 return (1); 1665 return 1;
1646 } 1666 }
1647 } 1667 }
1648 } 1668 }
1649 return (0); 1669 return 0;
1650} 1670}
1651 1671
1652/* Search for a nodelist entry on a specific list */ 1672/* Search for a nodelist entry on a specific list */
@@ -1656,6 +1676,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1656 struct lpfc_nodelist *ndlp, *next_ndlp; 1676 struct lpfc_nodelist *ndlp, *next_ndlp;
1657 uint32_t data1; 1677 uint32_t data1;
1658 1678
1679 spin_lock_irq(phba->host->host_lock);
1659 if (order & NLP_SEARCH_UNMAPPED) { 1680 if (order & NLP_SEARCH_UNMAPPED) {
1660 list_for_each_entry_safe(ndlp, next_ndlp, 1681 list_for_each_entry_safe(ndlp, next_ndlp,
1661 &phba->fc_nlpunmap_list, nlp_listp) { 1682 &phba->fc_nlpunmap_list, nlp_listp) {
@@ -1671,7 +1692,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1671 phba->brd_no, 1692 phba->brd_no,
1672 ndlp, ndlp->nlp_DID, 1693 ndlp, ndlp->nlp_DID,
1673 ndlp->nlp_flag, data1); 1694 ndlp->nlp_flag, data1);
1674 return (ndlp); 1695 spin_unlock_irq(phba->host->host_lock);
1696 return ndlp;
1675 } 1697 }
1676 } 1698 }
1677 } 1699 }
@@ -1692,7 +1714,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1692 phba->brd_no, 1714 phba->brd_no,
1693 ndlp, ndlp->nlp_DID, 1715 ndlp, ndlp->nlp_DID,
1694 ndlp->nlp_flag, data1); 1716 ndlp->nlp_flag, data1);
1695 return (ndlp); 1717 spin_unlock_irq(phba->host->host_lock);
1718 return ndlp;
1696 } 1719 }
1697 } 1720 }
1698 } 1721 }
@@ -1714,7 +1737,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1714 phba->brd_no, 1737 phba->brd_no,
1715 ndlp, ndlp->nlp_DID, 1738 ndlp, ndlp->nlp_DID,
1716 ndlp->nlp_flag, data1); 1739 ndlp->nlp_flag, data1);
1717 return (ndlp); 1740 spin_unlock_irq(phba->host->host_lock);
1741 return ndlp;
1718 } 1742 }
1719 } 1743 }
1720 } 1744 }
@@ -1736,7 +1760,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1736 phba->brd_no, 1760 phba->brd_no,
1737 ndlp, ndlp->nlp_DID, 1761 ndlp, ndlp->nlp_DID,
1738 ndlp->nlp_flag, data1); 1762 ndlp->nlp_flag, data1);
1739 return (ndlp); 1763 spin_unlock_irq(phba->host->host_lock);
1764 return ndlp;
1740 } 1765 }
1741 } 1766 }
1742 } 1767 }
@@ -1758,7 +1783,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1758 phba->brd_no, 1783 phba->brd_no,
1759 ndlp, ndlp->nlp_DID, 1784 ndlp, ndlp->nlp_DID,
1760 ndlp->nlp_flag, data1); 1785 ndlp->nlp_flag, data1);
1761 return (ndlp); 1786 spin_unlock_irq(phba->host->host_lock);
1787 return ndlp;
1762 } 1788 }
1763 } 1789 }
1764 } 1790 }
@@ -1780,7 +1806,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1780 phba->brd_no, 1806 phba->brd_no,
1781 ndlp, ndlp->nlp_DID, 1807 ndlp, ndlp->nlp_DID,
1782 ndlp->nlp_flag, data1); 1808 ndlp->nlp_flag, data1);
1783 return (ndlp); 1809 spin_unlock_irq(phba->host->host_lock);
1810 return ndlp;
1784 } 1811 }
1785 } 1812 }
1786 } 1813 }
@@ -1802,7 +1829,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1802 phba->brd_no, 1829 phba->brd_no,
1803 ndlp, ndlp->nlp_DID, 1830 ndlp, ndlp->nlp_DID,
1804 ndlp->nlp_flag, data1); 1831 ndlp->nlp_flag, data1);
1805 return (ndlp); 1832 spin_unlock_irq(phba->host->host_lock);
1833 return ndlp;
1806 } 1834 }
1807 } 1835 }
1808 } 1836 }
@@ -1824,11 +1852,14 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did)
1824 phba->brd_no, 1852 phba->brd_no,
1825 ndlp, ndlp->nlp_DID, 1853 ndlp, ndlp->nlp_DID,
1826 ndlp->nlp_flag, data1); 1854 ndlp->nlp_flag, data1);
1827 return (ndlp); 1855 spin_unlock_irq(phba->host->host_lock);
1856 return ndlp;
1828 } 1857 }
1829 } 1858 }
1830 } 1859 }
1831 1860
1861 spin_unlock_irq(phba->host->host_lock);
1862
1832 /* FIND node did <did> NOT FOUND */ 1863 /* FIND node did <did> NOT FOUND */
1833 lpfc_printf_log(phba, 1864 lpfc_printf_log(phba,
1834 KERN_INFO, 1865 KERN_INFO,
@@ -1846,8 +1877,9 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1846 struct lpfc_nodelist *ndlp; 1877 struct lpfc_nodelist *ndlp;
1847 uint32_t flg; 1878 uint32_t flg;
1848 1879
1849 if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { 1880 ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did);
1850 if ((phba->hba_state == LPFC_HBA_READY) && 1881 if (!ndlp) {
1882 if ((phba->fc_flag & FC_RSCN_MODE) &&
1851 ((lpfc_rscn_payload_check(phba, did) == 0))) 1883 ((lpfc_rscn_payload_check(phba, did) == 0)))
1852 return NULL; 1884 return NULL;
1853 ndlp = (struct lpfc_nodelist *) 1885 ndlp = (struct lpfc_nodelist *)
@@ -1860,22 +1892,23 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
1860 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 1892 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1861 return ndlp; 1893 return ndlp;
1862 } 1894 }
1863 if ((phba->hba_state == LPFC_HBA_READY) && 1895 if (phba->fc_flag & FC_RSCN_MODE) {
1864 (phba->fc_flag & FC_RSCN_MODE)) {
1865 if (lpfc_rscn_payload_check(phba, did)) { 1896 if (lpfc_rscn_payload_check(phba, did)) {
1866 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 1897 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1867 } 1898
1868 else { 1899 /* Since this node is marked for discovery,
1900 * delay timeout is not needed.
1901 */
1902 if (ndlp->nlp_flag & NLP_DELAY_TMO)
1903 lpfc_cancel_retry_delay_tmo(phba, ndlp);
1904 } else {
1869 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; 1905 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1870 ndlp = NULL; 1906 ndlp = NULL;
1871 } 1907 }
1872 } 1908 } else {
1873 else {
1874 flg = ndlp->nlp_flag & NLP_LIST_MASK; 1909 flg = ndlp->nlp_flag & NLP_LIST_MASK;
1875 if ((flg == NLP_ADISC_LIST) || 1910 if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST))
1876 (flg == NLP_PLOGI_LIST)) {
1877 return NULL; 1911 return NULL;
1878 }
1879 ndlp->nlp_state = NLP_STE_NPR_NODE; 1912 ndlp->nlp_state = NLP_STE_NPR_NODE;
1880 lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); 1913 lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1881 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 1914 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
@@ -2023,8 +2056,7 @@ lpfc_disc_start(struct lpfc_hba * phba)
2023 spin_lock_irq(phba->host->host_lock); 2056 spin_lock_irq(phba->host->host_lock);
2024 phba->fc_flag &= ~FC_RSCN_MODE; 2057 phba->fc_flag &= ~FC_RSCN_MODE;
2025 spin_unlock_irq(phba->host->host_lock); 2058 spin_unlock_irq(phba->host->host_lock);
2026 } 2059 } else
2027 else
2028 lpfc_els_handle_rscn(phba); 2060 lpfc_els_handle_rscn(phba);
2029 } 2061 }
2030 } 2062 }
@@ -2174,7 +2206,7 @@ static void
2174lpfc_disc_timeout_handler(struct lpfc_hba *phba) 2206lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2175{ 2207{
2176 struct lpfc_sli *psli; 2208 struct lpfc_sli *psli;
2177 struct lpfc_nodelist *ndlp; 2209 struct lpfc_nodelist *ndlp, *next_ndlp;
2178 LPFC_MBOXQ_t *clearlambox, *initlinkmbox; 2210 LPFC_MBOXQ_t *clearlambox, *initlinkmbox;
2179 int rc, clrlaerr = 0; 2211 int rc, clrlaerr = 0;
2180 2212
@@ -2201,10 +2233,19 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2201 "%d:0221 FAN timeout\n", 2233 "%d:0221 FAN timeout\n",
2202 phba->brd_no); 2234 phba->brd_no);
2203 2235
2204 /* Forget about FAN, Start discovery by sending a FLOGI 2236 /* Start discovery by sending FLOGI, clean up old rpis */
2205 * hba_state is identically LPFC_FLOGI while waiting for FLOGI 2237 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
2206 * cmpl 2238 nlp_listp) {
2207 */ 2239 if (ndlp->nlp_type & NLP_FABRIC) {
2240 /* Clean up the ndlp on Fabric connections */
2241 lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
2242 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
2243 /* Fail outstanding IO now since device
2244 * is marked for PLOGI.
2245 */
2246 lpfc_unreg_rpi(phba, ndlp);
2247 }
2248 }
2208 phba->hba_state = LPFC_FLOGI; 2249 phba->hba_state = LPFC_FLOGI;
2209 lpfc_set_disctmo(phba); 2250 lpfc_set_disctmo(phba);
2210 lpfc_initial_flogi(phba); 2251 lpfc_initial_flogi(phba);
@@ -2470,11 +2511,57 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
2470 &phba->fc_reglogin_list}; 2511 &phba->fc_reglogin_list};
2471 int i; 2512 int i;
2472 2513
2514 spin_lock_irq(phba->host->host_lock);
2473 for (i = 0; i < ARRAY_SIZE(lists); i++ ) 2515 for (i = 0; i < ARRAY_SIZE(lists); i++ )
2474 list_for_each_entry(ndlp, lists[i], nlp_listp) 2516 list_for_each_entry(ndlp, lists[i], nlp_listp)
2475 if (ndlp->nlp_rpi == rpi) 2517 if (ndlp->nlp_rpi == rpi) {
2476 return (ndlp); 2518 spin_unlock_irq(phba->host->host_lock);
2519 return ndlp;
2520 }
2521 spin_unlock_irq(phba->host->host_lock);
2522 return NULL;
2523}
2524
2525/*
2526 * This routine looks up the ndlp lists
2527 * for the given WWPN. If WWPN found
2528 * it return the node list pointer
2529 * else return NULL.
2530 */
2531struct lpfc_nodelist *
2532lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order,
2533 struct lpfc_name * wwpn)
2534{
2535 struct lpfc_nodelist *ndlp;
2536 struct list_head * lists[]={&phba->fc_nlpunmap_list,
2537 &phba->fc_nlpmap_list,
2538 &phba->fc_npr_list,
2539 &phba->fc_plogi_list,
2540 &phba->fc_adisc_list,
2541 &phba->fc_reglogin_list,
2542 &phba->fc_prli_list};
2543 uint32_t search[]={NLP_SEARCH_UNMAPPED,
2544 NLP_SEARCH_MAPPED,
2545 NLP_SEARCH_NPR,
2546 NLP_SEARCH_PLOGI,
2547 NLP_SEARCH_ADISC,
2548 NLP_SEARCH_REGLOGIN,
2549 NLP_SEARCH_PRLI};
2550 int i;
2477 2551
2552 spin_lock_irq(phba->host->host_lock);
2553 for (i = 0; i < ARRAY_SIZE(lists); i++ ) {
2554 if (!(order & search[i]))
2555 continue;
2556 list_for_each_entry(ndlp, lists[i], nlp_listp) {
2557 if (memcmp(&ndlp->nlp_portname, wwpn,
2558 sizeof(struct lpfc_name)) == 0) {
2559 spin_unlock_irq(phba->host->host_lock);
2560 return ndlp;
2561 }
2562 }
2563 }
2564 spin_unlock_irq(phba->host->host_lock);
2478 return NULL; 2565 return NULL;
2479} 2566}
2480 2567