diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 391 |
1 files changed, 227 insertions, 164 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index fbead786031f..3d77bd999b70 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-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 * |
@@ -46,13 +46,13 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
46 | * table entry for that node. | 46 | * table entry for that node. |
47 | */ | 47 | */ |
48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) | 48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) |
49 | return (0); | 49 | return 0; |
50 | 50 | ||
51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) | 51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) |
52 | return (0); | 52 | return 0; |
53 | 53 | ||
54 | /* we match, return success */ | 54 | /* we match, return success */ |
55 | return (1); | 55 | return 1; |
56 | } | 56 | } |
57 | 57 | ||
58 | int | 58 | int |
@@ -150,8 +150,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | |||
150 | lp = (uint32_t *) prsp->virt; | 150 | lp = (uint32_t *) prsp->virt; |
151 | ptr = (void *)((uint8_t *)lp + sizeof(uint32_t)); | 151 | ptr = (void *)((uint8_t *)lp + sizeof(uint32_t)); |
152 | } | 152 | } |
153 | } | 153 | } else { |
154 | else { | ||
155 | /* Force ulpStatus error since we are returning NULL ptr */ | 154 | /* Force ulpStatus error since we are returning NULL ptr */ |
156 | if (!(irsp->ulpStatus)) { | 155 | if (!(irsp->ulpStatus)) { |
157 | irsp->ulpStatus = IOSTAT_LOCAL_REJECT; | 156 | irsp->ulpStatus = IOSTAT_LOCAL_REJECT; |
@@ -159,7 +158,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | |||
159 | } | 158 | } |
160 | ptr = NULL; | 159 | ptr = NULL; |
161 | } | 160 | } |
162 | return (ptr); | 161 | return ptr; |
163 | } | 162 | } |
164 | 163 | ||
165 | 164 | ||
@@ -260,13 +259,9 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
260 | } while(found); | 259 | } while(found); |
261 | 260 | ||
262 | /* If we are delaying issuing an ELS command, cancel it */ | 261 | /* If we are delaying issuing an ELS command, cancel it */ |
263 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 262 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
264 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 263 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |
265 | del_timer_sync(&ndlp->nlp_delayfunc); | 264 | return 0; |
266 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | ||
267 | list_del_init(&ndlp->els_retry_evt.evt_listp); | ||
268 | } | ||
269 | return (0); | ||
270 | } | 265 | } |
271 | 266 | ||
272 | static int | 267 | static int |
@@ -300,12 +295,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
300 | /* Start discovery - this should just do | 295 | /* Start discovery - this should just do |
301 | CLEAR_LA */ | 296 | CLEAR_LA */ |
302 | lpfc_disc_start(phba); | 297 | lpfc_disc_start(phba); |
303 | } | 298 | } else { |
304 | else { | ||
305 | lpfc_initial_flogi(phba); | 299 | lpfc_initial_flogi(phba); |
306 | } | 300 | } |
307 | } | 301 | } else { |
308 | else { | ||
309 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; | 302 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; |
310 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 303 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
311 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, | 304 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, |
@@ -321,7 +314,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
321 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 314 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
322 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 315 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
323 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 316 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
324 | return (0); | 317 | return 0; |
325 | } | 318 | } |
326 | icmd = &cmdiocb->iocb; | 319 | icmd = &cmdiocb->iocb; |
327 | 320 | ||
@@ -353,7 +346,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
353 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; | 346 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; |
354 | 347 | ||
355 | /* no need to reg_login if we are already in one of these states */ | 348 | /* no need to reg_login if we are already in one of these states */ |
356 | switch(ndlp->nlp_state) { | 349 | switch (ndlp->nlp_state) { |
357 | case NLP_STE_NPR_NODE: | 350 | case NLP_STE_NPR_NODE: |
358 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) | 351 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) |
359 | break; | 352 | break; |
@@ -362,7 +355,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
362 | case NLP_STE_UNMAPPED_NODE: | 355 | case NLP_STE_UNMAPPED_NODE: |
363 | case NLP_STE_MAPPED_NODE: | 356 | case NLP_STE_MAPPED_NODE: |
364 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); | 357 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); |
365 | return (1); | 358 | return 1; |
366 | } | 359 | } |
367 | 360 | ||
368 | if ((phba->fc_flag & FC_PT2PT) | 361 | if ((phba->fc_flag & FC_PT2PT) |
@@ -398,24 +391,16 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
398 | */ | 391 | */ |
399 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 392 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
400 | mbox->context2 = ndlp; | 393 | mbox->context2 = ndlp; |
401 | ndlp->nlp_flag |= NLP_ACC_REGLOGIN; | 394 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
402 | 395 | ||
403 | /* If there is an outstanding PLOGI issued, abort it before | ||
404 | * sending ACC rsp to PLOGI recieved. | ||
405 | */ | ||
406 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { | ||
407 | /* software abort outstanding PLOGI */ | ||
408 | lpfc_els_abort(phba, ndlp, 1); | ||
409 | } | ||
410 | ndlp->nlp_flag |= NLP_RCV_PLOGI; | ||
411 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); | 396 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); |
412 | return (1); | 397 | return 1; |
413 | 398 | ||
414 | out: | 399 | out: |
415 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 400 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
416 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; | 401 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; |
417 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 402 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
418 | return (0); | 403 | return 0; |
419 | } | 404 | } |
420 | 405 | ||
421 | static int | 406 | static int |
@@ -451,12 +436,11 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
451 | (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { | 436 | (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { |
452 | if (cmd == ELS_CMD_ADISC) { | 437 | if (cmd == ELS_CMD_ADISC) { |
453 | lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); | 438 | lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); |
454 | } | 439 | } else { |
455 | else { | ||
456 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, | 440 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, |
457 | NULL, 0); | 441 | NULL, 0); |
458 | } | 442 | } |
459 | return (1); | 443 | return 1; |
460 | } | 444 | } |
461 | /* Reject this request because invalid parameters */ | 445 | /* Reject this request because invalid parameters */ |
462 | stat.un.b.lsRjtRsvd0 = 0; | 446 | stat.un.b.lsRjtRsvd0 = 0; |
@@ -465,16 +449,17 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
465 | stat.un.b.vendorUnique = 0; | 449 | stat.un.b.vendorUnique = 0; |
466 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 450 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
467 | 451 | ||
468 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
469 | /* 1 sec timeout */ | 452 | /* 1 sec timeout */ |
470 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 453 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
471 | 454 | ||
472 | spin_lock_irq(phba->host->host_lock); | 455 | spin_lock_irq(phba->host->host_lock); |
473 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 456 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
474 | spin_unlock_irq(phba->host->host_lock); | 457 | spin_unlock_irq(phba->host->host_lock); |
458 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
459 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
475 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 460 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
476 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 461 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
477 | return (0); | 462 | return 0; |
478 | } | 463 | } |
479 | 464 | ||
480 | static int | 465 | static int |
@@ -489,25 +474,33 @@ lpfc_rcv_logo(struct lpfc_hba * phba, | |||
489 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 474 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
490 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 475 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
491 | 476 | ||
492 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 477 | if (!(ndlp->nlp_type & NLP_FABRIC) || |
478 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | ||
493 | /* Only try to re-login if this is NOT a Fabric Node */ | 479 | /* Only try to re-login if this is NOT a Fabric Node */ |
494 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
495 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 480 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
496 | spin_lock_irq(phba->host->host_lock); | 481 | spin_lock_irq(phba->host->host_lock); |
497 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 482 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
498 | spin_unlock_irq(phba->host->host_lock); | 483 | spin_unlock_irq(phba->host->host_lock); |
499 | } | ||
500 | 484 | ||
501 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 485 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
502 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 486 | ndlp->nlp_prev_state = ndlp->nlp_state; |
487 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
488 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
489 | } else { | ||
490 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
491 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | ||
492 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | ||
493 | } | ||
503 | 494 | ||
495 | spin_lock_irq(phba->host->host_lock); | ||
504 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 496 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
497 | spin_unlock_irq(phba->host->host_lock); | ||
505 | /* The driver has to wait until the ACC completes before it continues | 498 | /* The driver has to wait until the ACC completes before it continues |
506 | * processing the LOGO. The action will resume in | 499 | * processing the LOGO. The action will resume in |
507 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an | 500 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an |
508 | * unreg_login, the driver waits so the ACC does not get aborted. | 501 | * unreg_login, the driver waits so the ACC does not get aborted. |
509 | */ | 502 | */ |
510 | return (0); | 503 | return 0; |
511 | } | 504 | } |
512 | 505 | ||
513 | static void | 506 | static void |
@@ -555,20 +548,12 @@ lpfc_disc_set_adisc(struct lpfc_hba * phba, | |||
555 | if ((phba->cfg_use_adisc == 0) && | 548 | if ((phba->cfg_use_adisc == 0) && |
556 | !(phba->fc_flag & FC_RSCN_MODE)) { | 549 | !(phba->fc_flag & FC_RSCN_MODE)) { |
557 | if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) | 550 | if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) |
558 | return (0); | 551 | return 0; |
559 | } | 552 | } |
560 | spin_lock_irq(phba->host->host_lock); | 553 | spin_lock_irq(phba->host->host_lock); |
561 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 554 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
562 | spin_unlock_irq(phba->host->host_lock); | 555 | spin_unlock_irq(phba->host->host_lock); |
563 | return (1); | 556 | return 1; |
564 | } | ||
565 | |||
566 | static uint32_t | ||
567 | lpfc_disc_noop(struct lpfc_hba * phba, | ||
568 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | ||
569 | { | ||
570 | /* This routine does nothing, just return the current state */ | ||
571 | return (ndlp->nlp_state); | ||
572 | } | 557 | } |
573 | 558 | ||
574 | static uint32_t | 559 | static uint32_t |
@@ -583,7 +568,7 @@ lpfc_disc_illegal(struct lpfc_hba * phba, | |||
583 | phba->brd_no, | 568 | phba->brd_no, |
584 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | 569 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
585 | ndlp->nlp_flag); | 570 | ndlp->nlp_flag); |
586 | return (ndlp->nlp_state); | 571 | return ndlp->nlp_state; |
587 | } | 572 | } |
588 | 573 | ||
589 | /* Start of Discovery State Machine routines */ | 574 | /* Start of Discovery State Machine routines */ |
@@ -597,12 +582,13 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, | |||
597 | cmdiocb = (struct lpfc_iocbq *) arg; | 582 | cmdiocb = (struct lpfc_iocbq *) arg; |
598 | 583 | ||
599 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 584 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
585 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | ||
600 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | 586 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; |
601 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 587 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
602 | return (ndlp->nlp_state); | 588 | return ndlp->nlp_state; |
603 | } | 589 | } |
604 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 590 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
605 | return (NLP_STE_FREED_NODE); | 591 | return NLP_STE_FREED_NODE; |
606 | } | 592 | } |
607 | 593 | ||
608 | static uint32_t | 594 | static uint32_t |
@@ -611,7 +597,7 @@ lpfc_rcv_els_unused_node(struct lpfc_hba * phba, | |||
611 | { | 597 | { |
612 | lpfc_issue_els_logo(phba, ndlp, 0); | 598 | lpfc_issue_els_logo(phba, ndlp, 0); |
613 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 599 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
614 | return (ndlp->nlp_state); | 600 | return ndlp->nlp_state; |
615 | } | 601 | } |
616 | 602 | ||
617 | static uint32_t | 603 | static uint32_t |
@@ -628,7 +614,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, | |||
628 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 614 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
629 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 615 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
630 | 616 | ||
631 | return (ndlp->nlp_state); | 617 | return ndlp->nlp_state; |
632 | } | 618 | } |
633 | 619 | ||
634 | static uint32_t | 620 | static uint32_t |
@@ -636,7 +622,7 @@ lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, | |||
636 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 622 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
637 | { | 623 | { |
638 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 624 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
639 | return (NLP_STE_FREED_NODE); | 625 | return NLP_STE_FREED_NODE; |
640 | } | 626 | } |
641 | 627 | ||
642 | static uint32_t | 628 | static uint32_t |
@@ -644,7 +630,7 @@ lpfc_device_rm_unused_node(struct lpfc_hba * phba, | |||
644 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 630 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
645 | { | 631 | { |
646 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 632 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
647 | return (NLP_STE_FREED_NODE); | 633 | return NLP_STE_FREED_NODE; |
648 | } | 634 | } |
649 | 635 | ||
650 | static uint32_t | 636 | static uint32_t |
@@ -677,12 +663,26 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
677 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 663 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
678 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; | 664 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; |
679 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 665 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
680 | } | 666 | } else { |
681 | else { | ||
682 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 667 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
683 | } /* if our portname was less */ | 668 | } /* if our portname was less */ |
684 | 669 | ||
685 | return (ndlp->nlp_state); | 670 | return ndlp->nlp_state; |
671 | } | ||
672 | |||
673 | static uint32_t | ||
674 | lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, | ||
675 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | ||
676 | { | ||
677 | struct lpfc_iocbq *cmdiocb; | ||
678 | |||
679 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
680 | |||
681 | /* software abort outstanding PLOGI */ | ||
682 | lpfc_els_abort(phba, ndlp, 1); | ||
683 | |||
684 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | ||
685 | return ndlp->nlp_state; | ||
686 | } | 686 | } |
687 | 687 | ||
688 | static uint32_t | 688 | static uint32_t |
@@ -695,24 +695,24 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, | |||
695 | 695 | ||
696 | /* software abort outstanding PLOGI */ | 696 | /* software abort outstanding PLOGI */ |
697 | lpfc_els_abort(phba, ndlp, 1); | 697 | lpfc_els_abort(phba, ndlp, 1); |
698 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | ||
699 | spin_lock_irq(phba->host->host_lock); | ||
700 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
701 | spin_unlock_irq(phba->host->host_lock); | ||
702 | 698 | ||
703 | if (evt == NLP_EVT_RCV_LOGO) { | 699 | if (evt == NLP_EVT_RCV_LOGO) { |
704 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 700 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
705 | } | 701 | } else { |
706 | else { | ||
707 | lpfc_issue_els_logo(phba, ndlp, 0); | 702 | lpfc_issue_els_logo(phba, ndlp, 0); |
708 | } | 703 | } |
709 | 704 | ||
710 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 705 | /* Put ndlp in npr list set plogi timer for 1 sec */ |
711 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | 706 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
707 | spin_lock_irq(phba->host->host_lock); | ||
708 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
709 | spin_unlock_irq(phba->host->host_lock); | ||
710 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
711 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | ||
712 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 712 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
713 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 713 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
714 | 714 | ||
715 | return (ndlp->nlp_state); | 715 | return ndlp->nlp_state; |
716 | } | 716 | } |
717 | 717 | ||
718 | static uint32_t | 718 | static uint32_t |
@@ -731,7 +731,8 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
731 | rspiocb = cmdiocb->context_un.rsp_iocb; | 731 | rspiocb = cmdiocb->context_un.rsp_iocb; |
732 | 732 | ||
733 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 733 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
734 | return (ndlp->nlp_state); | 734 | /* Recovery from PLOGI collision logic */ |
735 | return ndlp->nlp_state; | ||
735 | } | 736 | } |
736 | 737 | ||
737 | irsp = &rspiocb->iocb; | 738 | irsp = &rspiocb->iocb; |
@@ -791,7 +792,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
791 | * execute first, queue this command to | 792 | * execute first, queue this command to |
792 | * be processed later. | 793 | * be processed later. |
793 | */ | 794 | */ |
794 | switch(ndlp->nlp_DID) { | 795 | switch (ndlp->nlp_DID) { |
795 | case NameServer_DID: | 796 | case NameServer_DID: |
796 | mbox->mbox_cmpl = | 797 | mbox->mbox_cmpl = |
797 | lpfc_mbx_cmpl_ns_reg_login; | 798 | lpfc_mbx_cmpl_ns_reg_login; |
@@ -812,7 +813,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
812 | NLP_STE_REG_LOGIN_ISSUE; | 813 | NLP_STE_REG_LOGIN_ISSUE; |
813 | lpfc_nlp_list(phba, ndlp, | 814 | lpfc_nlp_list(phba, ndlp, |
814 | NLP_REGLOGIN_LIST); | 815 | NLP_REGLOGIN_LIST); |
815 | return (ndlp->nlp_state); | 816 | return ndlp->nlp_state; |
816 | } | 817 | } |
817 | mempool_free(mbox, phba->mbox_mem_pool); | 818 | mempool_free(mbox, phba->mbox_mem_pool); |
818 | } else { | 819 | } else { |
@@ -824,7 +825,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
824 | /* Free this node since the driver cannot login or has the wrong | 825 | /* Free this node since the driver cannot login or has the wrong |
825 | sparm */ | 826 | sparm */ |
826 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 827 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
827 | return (NLP_STE_FREED_NODE); | 828 | return NLP_STE_FREED_NODE; |
828 | } | 829 | } |
829 | 830 | ||
830 | static uint32_t | 831 | static uint32_t |
@@ -835,7 +836,7 @@ lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, | |||
835 | lpfc_els_abort(phba, ndlp, 1); | 836 | lpfc_els_abort(phba, ndlp, 1); |
836 | 837 | ||
837 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 838 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
838 | return (NLP_STE_FREED_NODE); | 839 | return NLP_STE_FREED_NODE; |
839 | } | 840 | } |
840 | 841 | ||
841 | static uint32_t | 842 | static uint32_t |
@@ -846,13 +847,14 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, | |||
846 | /* software abort outstanding PLOGI */ | 847 | /* software abort outstanding PLOGI */ |
847 | lpfc_els_abort(phba, ndlp, 1); | 848 | lpfc_els_abort(phba, ndlp, 1); |
848 | 849 | ||
850 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | ||
849 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 851 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
850 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 852 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
851 | spin_lock_irq(phba->host->host_lock); | 853 | spin_lock_irq(phba->host->host_lock); |
852 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 854 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
853 | spin_unlock_irq(phba->host->host_lock); | 855 | spin_unlock_irq(phba->host->host_lock); |
854 | 856 | ||
855 | return (ndlp->nlp_state); | 857 | return ndlp->nlp_state; |
856 | } | 858 | } |
857 | 859 | ||
858 | static uint32_t | 860 | static uint32_t |
@@ -868,13 +870,14 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | |||
868 | cmdiocb = (struct lpfc_iocbq *) arg; | 870 | cmdiocb = (struct lpfc_iocbq *) arg; |
869 | 871 | ||
870 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 872 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
871 | return (ndlp->nlp_state); | 873 | return ndlp->nlp_state; |
872 | } | 874 | } |
875 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
873 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 876 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
874 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 877 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
875 | lpfc_issue_els_plogi(phba, ndlp, 0); | 878 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
876 | 879 | ||
877 | return (ndlp->nlp_state); | 880 | return ndlp->nlp_state; |
878 | } | 881 | } |
879 | 882 | ||
880 | static uint32_t | 883 | static uint32_t |
@@ -887,7 +890,7 @@ lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba, | |||
887 | cmdiocb = (struct lpfc_iocbq *) arg; | 890 | cmdiocb = (struct lpfc_iocbq *) arg; |
888 | 891 | ||
889 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 892 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
890 | return (ndlp->nlp_state); | 893 | return ndlp->nlp_state; |
891 | } | 894 | } |
892 | 895 | ||
893 | static uint32_t | 896 | static uint32_t |
@@ -903,7 +906,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | |||
903 | lpfc_els_abort(phba, ndlp, 0); | 906 | lpfc_els_abort(phba, ndlp, 0); |
904 | 907 | ||
905 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 908 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
906 | return (ndlp->nlp_state); | 909 | return ndlp->nlp_state; |
907 | } | 910 | } |
908 | 911 | ||
909 | static uint32_t | 912 | static uint32_t |
@@ -916,7 +919,7 @@ lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba, | |||
916 | cmdiocb = (struct lpfc_iocbq *) arg; | 919 | cmdiocb = (struct lpfc_iocbq *) arg; |
917 | 920 | ||
918 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 921 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
919 | return (ndlp->nlp_state); | 922 | return ndlp->nlp_state; |
920 | } | 923 | } |
921 | 924 | ||
922 | static uint32_t | 925 | static uint32_t |
@@ -930,7 +933,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, | |||
930 | 933 | ||
931 | /* Treat like rcv logo */ | 934 | /* Treat like rcv logo */ |
932 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 935 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
933 | return (ndlp->nlp_state); | 936 | return ndlp->nlp_state; |
934 | } | 937 | } |
935 | 938 | ||
936 | static uint32_t | 939 | static uint32_t |
@@ -950,29 +953,33 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | |||
950 | 953 | ||
951 | if ((irsp->ulpStatus) || | 954 | if ((irsp->ulpStatus) || |
952 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { | 955 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { |
953 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
954 | /* 1 sec timeout */ | 956 | /* 1 sec timeout */ |
955 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 957 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
956 | spin_lock_irq(phba->host->host_lock); | 958 | spin_lock_irq(phba->host->host_lock); |
957 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 959 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
958 | spin_unlock_irq(phba->host->host_lock); | 960 | spin_unlock_irq(phba->host->host_lock); |
961 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
959 | 962 | ||
960 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); | 963 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); |
961 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); | 964 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); |
962 | 965 | ||
966 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
963 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 967 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
964 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 968 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
965 | lpfc_unreg_rpi(phba, ndlp); | 969 | lpfc_unreg_rpi(phba, ndlp); |
966 | return (ndlp->nlp_state); | 970 | return ndlp->nlp_state; |
967 | } | 971 | } |
972 | |||
968 | if (ndlp->nlp_type & NLP_FCP_TARGET) { | 973 | if (ndlp->nlp_type & NLP_FCP_TARGET) { |
974 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
969 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | 975 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; |
970 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | 976 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); |
971 | } else { | 977 | } else { |
978 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
972 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 979 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
973 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 980 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
974 | } | 981 | } |
975 | return (ndlp->nlp_state); | 982 | return ndlp->nlp_state; |
976 | } | 983 | } |
977 | 984 | ||
978 | static uint32_t | 985 | static uint32_t |
@@ -984,7 +991,7 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, | |||
984 | lpfc_els_abort(phba, ndlp, 1); | 991 | lpfc_els_abort(phba, ndlp, 1); |
985 | 992 | ||
986 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 993 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
987 | return (NLP_STE_FREED_NODE); | 994 | return NLP_STE_FREED_NODE; |
988 | } | 995 | } |
989 | 996 | ||
990 | static uint32_t | 997 | static uint32_t |
@@ -995,14 +1002,15 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, | |||
995 | /* software abort outstanding ADISC */ | 1002 | /* software abort outstanding ADISC */ |
996 | lpfc_els_abort(phba, ndlp, 1); | 1003 | lpfc_els_abort(phba, ndlp, 1); |
997 | 1004 | ||
1005 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
998 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1006 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
999 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1007 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1000 | spin_lock_irq(phba->host->host_lock); | 1008 | spin_lock_irq(phba->host->host_lock); |
1001 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1009 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1010 | ndlp->nlp_flag |= NLP_NPR_ADISC; | ||
1002 | spin_unlock_irq(phba->host->host_lock); | 1011 | spin_unlock_irq(phba->host->host_lock); |
1003 | 1012 | ||
1004 | lpfc_disc_set_adisc(phba, ndlp); | 1013 | return ndlp->nlp_state; |
1005 | return (ndlp->nlp_state); | ||
1006 | } | 1014 | } |
1007 | 1015 | ||
1008 | static uint32_t | 1016 | static uint32_t |
@@ -1015,7 +1023,7 @@ lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba, | |||
1015 | cmdiocb = (struct lpfc_iocbq *) arg; | 1023 | cmdiocb = (struct lpfc_iocbq *) arg; |
1016 | 1024 | ||
1017 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1025 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1018 | return (ndlp->nlp_state); | 1026 | return ndlp->nlp_state; |
1019 | } | 1027 | } |
1020 | 1028 | ||
1021 | static uint32_t | 1029 | static uint32_t |
@@ -1028,7 +1036,7 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba, | |||
1028 | cmdiocb = (struct lpfc_iocbq *) arg; | 1036 | cmdiocb = (struct lpfc_iocbq *) arg; |
1029 | 1037 | ||
1030 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1038 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1031 | return (ndlp->nlp_state); | 1039 | return ndlp->nlp_state; |
1032 | } | 1040 | } |
1033 | 1041 | ||
1034 | static uint32_t | 1042 | static uint32_t |
@@ -1041,7 +1049,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1041 | cmdiocb = (struct lpfc_iocbq *) arg; | 1049 | cmdiocb = (struct lpfc_iocbq *) arg; |
1042 | 1050 | ||
1043 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1051 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1044 | return (ndlp->nlp_state); | 1052 | return ndlp->nlp_state; |
1045 | } | 1053 | } |
1046 | 1054 | ||
1047 | static uint32_t | 1055 | static uint32_t |
@@ -1054,7 +1062,7 @@ lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba, | |||
1054 | cmdiocb = (struct lpfc_iocbq *) arg; | 1062 | cmdiocb = (struct lpfc_iocbq *) arg; |
1055 | 1063 | ||
1056 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1064 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1057 | return (ndlp->nlp_state); | 1065 | return ndlp->nlp_state; |
1058 | } | 1066 | } |
1059 | 1067 | ||
1060 | static uint32_t | 1068 | static uint32_t |
@@ -1066,7 +1074,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, | |||
1066 | 1074 | ||
1067 | cmdiocb = (struct lpfc_iocbq *) arg; | 1075 | cmdiocb = (struct lpfc_iocbq *) arg; |
1068 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1076 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1069 | return (ndlp->nlp_state); | 1077 | return ndlp->nlp_state; |
1070 | } | 1078 | } |
1071 | 1079 | ||
1072 | static uint32_t | 1080 | static uint32_t |
@@ -1090,31 +1098,34 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1090 | phba->brd_no, | 1098 | phba->brd_no, |
1091 | did, mb->mbxStatus, phba->hba_state); | 1099 | did, mb->mbxStatus, phba->hba_state); |
1092 | 1100 | ||
1101 | /* Put ndlp in npr list set plogi timer for 1 sec */ | ||
1093 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1102 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1094 | spin_lock_irq(phba->host->host_lock); | 1103 | spin_lock_irq(phba->host->host_lock); |
1095 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1104 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1096 | spin_unlock_irq(phba->host->host_lock); | 1105 | spin_unlock_irq(phba->host->host_lock); |
1106 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
1097 | 1107 | ||
1098 | lpfc_issue_els_logo(phba, ndlp, 0); | 1108 | lpfc_issue_els_logo(phba, ndlp, 0); |
1099 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 1109 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1100 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
1101 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1110 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1102 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1111 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1103 | return (ndlp->nlp_state); | 1112 | return ndlp->nlp_state; |
1104 | } | 1113 | } |
1105 | 1114 | ||
1106 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1115 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1107 | 1116 | ||
1108 | /* Only if we are not a fabric nport do we issue PRLI */ | 1117 | /* Only if we are not a fabric nport do we issue PRLI */ |
1109 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 1118 | if (!(ndlp->nlp_type & NLP_FABRIC)) { |
1119 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1110 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1120 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1111 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1121 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); |
1112 | lpfc_issue_els_prli(phba, ndlp, 0); | 1122 | lpfc_issue_els_prli(phba, ndlp, 0); |
1113 | } else { | 1123 | } else { |
1124 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1114 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1125 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1115 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 1126 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
1116 | } | 1127 | } |
1117 | return (ndlp->nlp_state); | 1128 | return ndlp->nlp_state; |
1118 | } | 1129 | } |
1119 | 1130 | ||
1120 | static uint32_t | 1131 | static uint32_t |
@@ -1123,7 +1134,7 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, | |||
1123 | uint32_t evt) | 1134 | uint32_t evt) |
1124 | { | 1135 | { |
1125 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1136 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1126 | return (NLP_STE_FREED_NODE); | 1137 | return NLP_STE_FREED_NODE; |
1127 | } | 1138 | } |
1128 | 1139 | ||
1129 | static uint32_t | 1140 | static uint32_t |
@@ -1131,12 +1142,13 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, | |||
1131 | struct lpfc_nodelist * ndlp, void *arg, | 1142 | struct lpfc_nodelist * ndlp, void *arg, |
1132 | uint32_t evt) | 1143 | uint32_t evt) |
1133 | { | 1144 | { |
1145 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1134 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1146 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1135 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1147 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1136 | spin_lock_irq(phba->host->host_lock); | 1148 | spin_lock_irq(phba->host->host_lock); |
1137 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1149 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1138 | spin_unlock_irq(phba->host->host_lock); | 1150 | spin_unlock_irq(phba->host->host_lock); |
1139 | return (ndlp->nlp_state); | 1151 | return ndlp->nlp_state; |
1140 | } | 1152 | } |
1141 | 1153 | ||
1142 | static uint32_t | 1154 | static uint32_t |
@@ -1148,7 +1160,7 @@ lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba, | |||
1148 | cmdiocb = (struct lpfc_iocbq *) arg; | 1160 | cmdiocb = (struct lpfc_iocbq *) arg; |
1149 | 1161 | ||
1150 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1162 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1151 | return (ndlp->nlp_state); | 1163 | return ndlp->nlp_state; |
1152 | } | 1164 | } |
1153 | 1165 | ||
1154 | static uint32_t | 1166 | static uint32_t |
@@ -1160,7 +1172,7 @@ lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba, | |||
1160 | cmdiocb = (struct lpfc_iocbq *) arg; | 1172 | cmdiocb = (struct lpfc_iocbq *) arg; |
1161 | 1173 | ||
1162 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1174 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1163 | return (ndlp->nlp_state); | 1175 | return ndlp->nlp_state; |
1164 | } | 1176 | } |
1165 | 1177 | ||
1166 | static uint32_t | 1178 | static uint32_t |
@@ -1175,7 +1187,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, | |||
1175 | lpfc_els_abort(phba, ndlp, 1); | 1187 | lpfc_els_abort(phba, ndlp, 1); |
1176 | 1188 | ||
1177 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1189 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1178 | return (ndlp->nlp_state); | 1190 | return ndlp->nlp_state; |
1179 | } | 1191 | } |
1180 | 1192 | ||
1181 | static uint32_t | 1193 | static uint32_t |
@@ -1187,7 +1199,7 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, | |||
1187 | cmdiocb = (struct lpfc_iocbq *) arg; | 1199 | cmdiocb = (struct lpfc_iocbq *) arg; |
1188 | 1200 | ||
1189 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1201 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1190 | return (ndlp->nlp_state); | 1202 | return ndlp->nlp_state; |
1191 | } | 1203 | } |
1192 | 1204 | ||
1193 | /* This routine is envoked when we rcv a PRLO request from a nport | 1205 | /* This routine is envoked when we rcv a PRLO request from a nport |
@@ -1203,7 +1215,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, | |||
1203 | 1215 | ||
1204 | cmdiocb = (struct lpfc_iocbq *) arg; | 1216 | cmdiocb = (struct lpfc_iocbq *) arg; |
1205 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1217 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1206 | return (ndlp->nlp_state); | 1218 | return ndlp->nlp_state; |
1207 | } | 1219 | } |
1208 | 1220 | ||
1209 | static uint32_t | 1221 | static uint32_t |
@@ -1220,9 +1232,10 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1220 | 1232 | ||
1221 | irsp = &rspiocb->iocb; | 1233 | irsp = &rspiocb->iocb; |
1222 | if (irsp->ulpStatus) { | 1234 | if (irsp->ulpStatus) { |
1235 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1223 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1236 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1224 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 1237 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
1225 | return (ndlp->nlp_state); | 1238 | return ndlp->nlp_state; |
1226 | } | 1239 | } |
1227 | 1240 | ||
1228 | /* Check out PRLI rsp */ | 1241 | /* Check out PRLI rsp */ |
@@ -1238,9 +1251,10 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1238 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; | 1251 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; |
1239 | } | 1252 | } |
1240 | 1253 | ||
1254 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1241 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | 1255 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; |
1242 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | 1256 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); |
1243 | return (ndlp->nlp_state); | 1257 | return ndlp->nlp_state; |
1244 | } | 1258 | } |
1245 | 1259 | ||
1246 | /*! lpfc_device_rm_prli_issue | 1260 | /*! lpfc_device_rm_prli_issue |
@@ -1268,7 +1282,7 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | |||
1268 | lpfc_els_abort(phba, ndlp, 1); | 1282 | lpfc_els_abort(phba, ndlp, 1); |
1269 | 1283 | ||
1270 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1284 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1271 | return (NLP_STE_FREED_NODE); | 1285 | return NLP_STE_FREED_NODE; |
1272 | } | 1286 | } |
1273 | 1287 | ||
1274 | 1288 | ||
@@ -1295,12 +1309,13 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, | |||
1295 | /* software abort outstanding PRLI */ | 1309 | /* software abort outstanding PRLI */ |
1296 | lpfc_els_abort(phba, ndlp, 1); | 1310 | lpfc_els_abort(phba, ndlp, 1); |
1297 | 1311 | ||
1312 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1298 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1313 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1299 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1314 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1300 | spin_lock_irq(phba->host->host_lock); | 1315 | spin_lock_irq(phba->host->host_lock); |
1301 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1316 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1302 | spin_unlock_irq(phba->host->host_lock); | 1317 | spin_unlock_irq(phba->host->host_lock); |
1303 | return (ndlp->nlp_state); | 1318 | return ndlp->nlp_state; |
1304 | } | 1319 | } |
1305 | 1320 | ||
1306 | static uint32_t | 1321 | static uint32_t |
@@ -1312,7 +1327,7 @@ lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba, | |||
1312 | cmdiocb = (struct lpfc_iocbq *) arg; | 1327 | cmdiocb = (struct lpfc_iocbq *) arg; |
1313 | 1328 | ||
1314 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1329 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1315 | return (ndlp->nlp_state); | 1330 | return ndlp->nlp_state; |
1316 | } | 1331 | } |
1317 | 1332 | ||
1318 | static uint32_t | 1333 | static uint32_t |
@@ -1325,7 +1340,7 @@ lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba, | |||
1325 | 1340 | ||
1326 | lpfc_rcv_prli(phba, ndlp, cmdiocb); | 1341 | lpfc_rcv_prli(phba, ndlp, cmdiocb); |
1327 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1342 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1328 | return (ndlp->nlp_state); | 1343 | return ndlp->nlp_state; |
1329 | } | 1344 | } |
1330 | 1345 | ||
1331 | static uint32_t | 1346 | static uint32_t |
@@ -1337,7 +1352,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, | |||
1337 | cmdiocb = (struct lpfc_iocbq *) arg; | 1352 | cmdiocb = (struct lpfc_iocbq *) arg; |
1338 | 1353 | ||
1339 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1354 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1340 | return (ndlp->nlp_state); | 1355 | return ndlp->nlp_state; |
1341 | } | 1356 | } |
1342 | 1357 | ||
1343 | static uint32_t | 1358 | static uint32_t |
@@ -1349,7 +1364,7 @@ lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba, | |||
1349 | cmdiocb = (struct lpfc_iocbq *) arg; | 1364 | cmdiocb = (struct lpfc_iocbq *) arg; |
1350 | 1365 | ||
1351 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1366 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1352 | return (ndlp->nlp_state); | 1367 | return ndlp->nlp_state; |
1353 | } | 1368 | } |
1354 | 1369 | ||
1355 | static uint32_t | 1370 | static uint32_t |
@@ -1360,21 +1375,21 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, | |||
1360 | 1375 | ||
1361 | cmdiocb = (struct lpfc_iocbq *) arg; | 1376 | cmdiocb = (struct lpfc_iocbq *) arg; |
1362 | 1377 | ||
1363 | /* Treat like rcv logo */ | 1378 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1364 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1379 | return ndlp->nlp_state; |
1365 | return (ndlp->nlp_state); | ||
1366 | } | 1380 | } |
1367 | 1381 | ||
1368 | static uint32_t | 1382 | static uint32_t |
1369 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, | 1383 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, |
1370 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1384 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1371 | { | 1385 | { |
1386 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; | ||
1372 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1387 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1373 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1388 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1374 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1389 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1375 | lpfc_disc_set_adisc(phba, ndlp); | 1390 | lpfc_disc_set_adisc(phba, ndlp); |
1376 | 1391 | ||
1377 | return (ndlp->nlp_state); | 1392 | return ndlp->nlp_state; |
1378 | } | 1393 | } |
1379 | 1394 | ||
1380 | static uint32_t | 1395 | static uint32_t |
@@ -1386,7 +1401,7 @@ lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba, | |||
1386 | cmdiocb = (struct lpfc_iocbq *) arg; | 1401 | cmdiocb = (struct lpfc_iocbq *) arg; |
1387 | 1402 | ||
1388 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1403 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1389 | return (ndlp->nlp_state); | 1404 | return ndlp->nlp_state; |
1390 | } | 1405 | } |
1391 | 1406 | ||
1392 | static uint32_t | 1407 | static uint32_t |
@@ -1398,7 +1413,7 @@ lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba, | |||
1398 | cmdiocb = (struct lpfc_iocbq *) arg; | 1413 | cmdiocb = (struct lpfc_iocbq *) arg; |
1399 | 1414 | ||
1400 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1415 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1401 | return (ndlp->nlp_state); | 1416 | return ndlp->nlp_state; |
1402 | } | 1417 | } |
1403 | 1418 | ||
1404 | static uint32_t | 1419 | static uint32_t |
@@ -1410,7 +1425,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, | |||
1410 | cmdiocb = (struct lpfc_iocbq *) arg; | 1425 | cmdiocb = (struct lpfc_iocbq *) arg; |
1411 | 1426 | ||
1412 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1427 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1413 | return (ndlp->nlp_state); | 1428 | return ndlp->nlp_state; |
1414 | } | 1429 | } |
1415 | 1430 | ||
1416 | static uint32_t | 1431 | static uint32_t |
@@ -1423,7 +1438,7 @@ lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba, | |||
1423 | cmdiocb = (struct lpfc_iocbq *) arg; | 1438 | cmdiocb = (struct lpfc_iocbq *) arg; |
1424 | 1439 | ||
1425 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1440 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1426 | return (ndlp->nlp_state); | 1441 | return ndlp->nlp_state; |
1427 | } | 1442 | } |
1428 | 1443 | ||
1429 | static uint32_t | 1444 | static uint32_t |
@@ -1442,7 +1457,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, | |||
1442 | 1457 | ||
1443 | /* Treat like rcv logo */ | 1458 | /* Treat like rcv logo */ |
1444 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1459 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1445 | return (ndlp->nlp_state); | 1460 | return ndlp->nlp_state; |
1446 | } | 1461 | } |
1447 | 1462 | ||
1448 | static uint32_t | 1463 | static uint32_t |
@@ -1450,13 +1465,14 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, | |||
1450 | struct lpfc_nodelist * ndlp, void *arg, | 1465 | struct lpfc_nodelist * ndlp, void *arg, |
1451 | uint32_t evt) | 1466 | uint32_t evt) |
1452 | { | 1467 | { |
1468 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; | ||
1453 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1469 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1454 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1470 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1455 | spin_lock_irq(phba->host->host_lock); | 1471 | spin_lock_irq(phba->host->host_lock); |
1456 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1472 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1457 | spin_unlock_irq(phba->host->host_lock); | 1473 | spin_unlock_irq(phba->host->host_lock); |
1458 | lpfc_disc_set_adisc(phba, ndlp); | 1474 | lpfc_disc_set_adisc(phba, ndlp); |
1459 | return (ndlp->nlp_state); | 1475 | return ndlp->nlp_state; |
1460 | } | 1476 | } |
1461 | 1477 | ||
1462 | static uint32_t | 1478 | static uint32_t |
@@ -1470,23 +1486,25 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, | |||
1470 | 1486 | ||
1471 | /* Ignore PLOGI if we have an outstanding LOGO */ | 1487 | /* Ignore PLOGI if we have an outstanding LOGO */ |
1472 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | 1488 | if (ndlp->nlp_flag & NLP_LOGO_SND) { |
1473 | return (ndlp->nlp_state); | 1489 | return ndlp->nlp_state; |
1474 | } | 1490 | } |
1475 | 1491 | ||
1476 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 1492 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
1477 | spin_lock_irq(phba->host->host_lock); | 1493 | spin_lock_irq(phba->host->host_lock); |
1478 | ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC); | 1494 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1479 | spin_unlock_irq(phba->host->host_lock); | 1495 | spin_unlock_irq(phba->host->host_lock); |
1480 | return (ndlp->nlp_state); | 1496 | return ndlp->nlp_state; |
1481 | } | 1497 | } |
1482 | 1498 | ||
1483 | /* send PLOGI immediately, move to PLOGI issue state */ | 1499 | /* send PLOGI immediately, move to PLOGI issue state */ |
1484 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1500 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1485 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1501 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1486 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1502 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1487 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1503 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1504 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | ||
1488 | } | 1505 | } |
1489 | return (ndlp->nlp_state); | 1506 | |
1507 | return ndlp->nlp_state; | ||
1490 | } | 1508 | } |
1491 | 1509 | ||
1492 | static uint32_t | 1510 | static uint32_t |
@@ -1506,16 +1524,22 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, | |||
1506 | 1524 | ||
1507 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1525 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1508 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1526 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1527 | spin_lock_irq(phba->host->host_lock); | ||
1528 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | ||
1529 | spin_unlock_irq(phba->host->host_lock); | ||
1530 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1509 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1531 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1510 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1532 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1511 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1533 | lpfc_issue_els_adisc(phba, ndlp, 0); |
1512 | } else { | 1534 | } else { |
1535 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1513 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1536 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1514 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1537 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1515 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1538 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
1516 | } | 1539 | } |
1540 | |||
1517 | } | 1541 | } |
1518 | return (ndlp->nlp_state); | 1542 | return ndlp->nlp_state; |
1519 | } | 1543 | } |
1520 | 1544 | ||
1521 | static uint32_t | 1545 | static uint32_t |
@@ -1528,7 +1552,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, | |||
1528 | cmdiocb = (struct lpfc_iocbq *) arg; | 1552 | cmdiocb = (struct lpfc_iocbq *) arg; |
1529 | 1553 | ||
1530 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1554 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1531 | return (ndlp->nlp_state); | 1555 | return ndlp->nlp_state; |
1532 | } | 1556 | } |
1533 | 1557 | ||
1534 | static uint32_t | 1558 | static uint32_t |
@@ -1544,16 +1568,18 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
1544 | 1568 | ||
1545 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1569 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1546 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1570 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1571 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1547 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1572 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1548 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1573 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1549 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1574 | lpfc_issue_els_adisc(phba, ndlp, 0); |
1550 | } else { | 1575 | } else { |
1576 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1551 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1577 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1552 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1578 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1553 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1579 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
1554 | } | 1580 | } |
1555 | } | 1581 | } |
1556 | return (ndlp->nlp_state); | 1582 | return ndlp->nlp_state; |
1557 | } | 1583 | } |
1558 | 1584 | ||
1559 | static uint32_t | 1585 | static uint32_t |
@@ -1565,25 +1591,47 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, | |||
1565 | 1591 | ||
1566 | cmdiocb = (struct lpfc_iocbq *) arg; | 1592 | cmdiocb = (struct lpfc_iocbq *) arg; |
1567 | 1593 | ||
1594 | spin_lock_irq(phba->host->host_lock); | ||
1595 | ndlp->nlp_flag |= NLP_LOGO_ACC; | ||
1596 | spin_unlock_irq(phba->host->host_lock); | ||
1597 | |||
1568 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1598 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1569 | 1599 | ||
1570 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1600 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1571 | if (ndlp->nlp_last_elscmd == (unsigned long)ELS_CMD_PLOGI) { | 1601 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1572 | return (ndlp->nlp_state); | 1602 | spin_lock_irq(phba->host->host_lock); |
1573 | } else { | 1603 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1574 | spin_lock_irq(phba->host->host_lock); | 1604 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1575 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1605 | spin_unlock_irq(phba->host->host_lock); |
1576 | spin_unlock_irq(phba->host->host_lock); | 1606 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
1577 | del_timer_sync(&ndlp->nlp_delayfunc); | 1607 | } else { |
1578 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 1608 | spin_lock_irq(phba->host->host_lock); |
1579 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 1609 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1580 | } | 1610 | spin_unlock_irq(phba->host->host_lock); |
1581 | } | 1611 | } |
1612 | return ndlp->nlp_state; | ||
1613 | } | ||
1582 | 1614 | ||
1583 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1615 | static uint32_t |
1584 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1616 | lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, |
1585 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1617 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1586 | return (ndlp->nlp_state); | 1618 | { |
1619 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
1620 | |||
1621 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1622 | rspiocb = cmdiocb->context_un.rsp_iocb; | ||
1623 | return ndlp->nlp_state; | ||
1624 | } | ||
1625 | |||
1626 | static uint32_t | ||
1627 | lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | ||
1628 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | ||
1629 | { | ||
1630 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
1631 | |||
1632 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1633 | rspiocb = cmdiocb->context_un.rsp_iocb; | ||
1634 | return ndlp->nlp_state; | ||
1587 | } | 1635 | } |
1588 | 1636 | ||
1589 | static uint32_t | 1637 | static uint32_t |
@@ -1592,7 +1640,19 @@ lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba, | |||
1592 | { | 1640 | { |
1593 | lpfc_unreg_rpi(phba, ndlp); | 1641 | lpfc_unreg_rpi(phba, ndlp); |
1594 | /* This routine does nothing, just return the current state */ | 1642 | /* This routine does nothing, just return the current state */ |
1595 | return (ndlp->nlp_state); | 1643 | return ndlp->nlp_state; |
1644 | } | ||
1645 | |||
1646 | static uint32_t | ||
1647 | lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | ||
1648 | struct lpfc_nodelist * ndlp, void *arg, | ||
1649 | uint32_t evt) | ||
1650 | { | ||
1651 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
1652 | |||
1653 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1654 | rspiocb = cmdiocb->context_un.rsp_iocb; | ||
1655 | return ndlp->nlp_state; | ||
1596 | } | 1656 | } |
1597 | 1657 | ||
1598 | static uint32_t | 1658 | static uint32_t |
@@ -1606,9 +1666,10 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | |||
1606 | pmb = (LPFC_MBOXQ_t *) arg; | 1666 | pmb = (LPFC_MBOXQ_t *) arg; |
1607 | mb = &pmb->mb; | 1667 | mb = &pmb->mb; |
1608 | 1668 | ||
1609 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1669 | if (!mb->mbxStatus) |
1670 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
1610 | 1671 | ||
1611 | return (ndlp->nlp_state); | 1672 | return ndlp->nlp_state; |
1612 | } | 1673 | } |
1613 | 1674 | ||
1614 | static uint32_t | 1675 | static uint32_t |
@@ -1617,7 +1678,7 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, | |||
1617 | uint32_t evt) | 1678 | uint32_t evt) |
1618 | { | 1679 | { |
1619 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1680 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1620 | return (NLP_STE_FREED_NODE); | 1681 | return NLP_STE_FREED_NODE; |
1621 | } | 1682 | } |
1622 | 1683 | ||
1623 | static uint32_t | 1684 | static uint32_t |
@@ -1628,7 +1689,10 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, | |||
1628 | spin_lock_irq(phba->host->host_lock); | 1689 | spin_lock_irq(phba->host->host_lock); |
1629 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1690 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1630 | spin_unlock_irq(phba->host->host_lock); | 1691 | spin_unlock_irq(phba->host->host_lock); |
1631 | return (ndlp->nlp_state); | 1692 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1693 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | ||
1694 | } | ||
1695 | return ndlp->nlp_state; | ||
1632 | } | 1696 | } |
1633 | 1697 | ||
1634 | 1698 | ||
@@ -1707,7 +1771,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1707 | 1771 | ||
1708 | lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ | 1772 | lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ |
1709 | lpfc_rcv_els_plogi_issue, /* RCV_PRLI */ | 1773 | lpfc_rcv_els_plogi_issue, /* RCV_PRLI */ |
1710 | lpfc_rcv_els_plogi_issue, /* RCV_LOGO */ | 1774 | lpfc_rcv_logo_plogi_issue, /* RCV_LOGO */ |
1711 | lpfc_rcv_els_plogi_issue, /* RCV_ADISC */ | 1775 | lpfc_rcv_els_plogi_issue, /* RCV_ADISC */ |
1712 | lpfc_rcv_els_plogi_issue, /* RCV_PDISC */ | 1776 | lpfc_rcv_els_plogi_issue, /* RCV_PDISC */ |
1713 | lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ | 1777 | lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ |
@@ -1795,10 +1859,10 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1795 | lpfc_rcv_padisc_npr_node, /* RCV_ADISC */ | 1859 | lpfc_rcv_padisc_npr_node, /* RCV_ADISC */ |
1796 | lpfc_rcv_padisc_npr_node, /* RCV_PDISC */ | 1860 | lpfc_rcv_padisc_npr_node, /* RCV_PDISC */ |
1797 | lpfc_rcv_prlo_npr_node, /* RCV_PRLO */ | 1861 | lpfc_rcv_prlo_npr_node, /* RCV_PRLO */ |
1798 | lpfc_disc_noop, /* CMPL_PLOGI */ | 1862 | lpfc_cmpl_plogi_npr_node, /* CMPL_PLOGI */ |
1799 | lpfc_disc_noop, /* CMPL_PRLI */ | 1863 | lpfc_cmpl_prli_npr_node, /* CMPL_PRLI */ |
1800 | lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */ | 1864 | lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */ |
1801 | lpfc_disc_noop, /* CMPL_ADISC */ | 1865 | lpfc_cmpl_adisc_npr_node, /* CMPL_ADISC */ |
1802 | lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */ | 1866 | lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */ |
1803 | lpfc_device_rm_npr_node, /* DEVICE_RM */ | 1867 | lpfc_device_rm_npr_node, /* DEVICE_RM */ |
1804 | lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */ | 1868 | lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */ |
@@ -1844,10 +1908,9 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, | |||
1844 | ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; | 1908 | ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; |
1845 | spin_unlock_irq(phba->host->host_lock); | 1909 | spin_unlock_irq(phba->host->host_lock); |
1846 | lpfc_nlp_remove(phba, ndlp); | 1910 | lpfc_nlp_remove(phba, ndlp); |
1847 | return (NLP_STE_FREED_NODE); | 1911 | return NLP_STE_FREED_NODE; |
1848 | } | 1912 | } |
1849 | if (rc == NLP_STE_FREED_NODE) | 1913 | if (rc == NLP_STE_FREED_NODE) |
1850 | return (NLP_STE_FREED_NODE); | 1914 | return NLP_STE_FREED_NODE; |
1851 | ndlp->nlp_state = rc; | 1915 | return rc; |
1852 | return (rc); | ||
1853 | } | 1916 | } |