diff options
author | James Smart <James.Smart@Emulex.Com> | 2006-07-06 15:50:02 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-07-09 11:23:29 -0400 |
commit | 9279565046f39f3ab338818c9923a23b9f25be5f (patch) | |
tree | ae096286fae5558b59c90aea0b2c4548187609a7 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 688a88635f9d0d9251d35198e931eaac8816abef (diff) |
[SCSI] lpfc 8.1.7: Correct bogus nodev_tmo message on NPort that changes its NPort Id
Correct bogus nodev_tmo message on NPort that changes its NPort Id
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cac9e870838a..b89f6cb641e6 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba) | |||
648 | } | 648 | } |
649 | 649 | ||
650 | static struct lpfc_nodelist * | 650 | static struct lpfc_nodelist * |
651 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 651 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, |
652 | struct lpfc_nodelist *ndlp) | 652 | struct lpfc_nodelist *ndlp) |
653 | { | 653 | { |
654 | struct lpfc_nodelist *new_ndlp; | 654 | struct lpfc_nodelist *new_ndlp; |
655 | struct lpfc_dmabuf *pcmd, *prsp; | ||
656 | uint32_t *lp; | 655 | uint32_t *lp; |
657 | struct serv_parm *sp; | 656 | struct serv_parm *sp; |
658 | uint8_t name[sizeof (struct lpfc_name)]; | 657 | uint8_t name[sizeof (struct lpfc_name)]; |
659 | uint32_t rc; | 658 | uint32_t rc; |
660 | 659 | ||
661 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
662 | prsp = (struct lpfc_dmabuf *) pcmd->list.next; | ||
663 | lp = (uint32_t *) prsp->virt; | 660 | lp = (uint32_t *) prsp->virt; |
664 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 661 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
662 | memset(name, 0, sizeof (struct lpfc_name)); | ||
665 | 663 | ||
666 | /* Now we to find out if the NPort we are logging into, matches the WWPN | 664 | /* Now we to find out if the NPort we are logging into, matches the WWPN |
667 | * we have for that ndlp. If not, we have some work to do. | 665 | * we have for that ndlp. If not, we have some work to do. |
668 | */ | 666 | */ |
669 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); | 667 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); |
670 | 668 | ||
671 | memset(name, 0, sizeof (struct lpfc_name)); | 669 | if (new_ndlp == ndlp) |
672 | rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
673 | if (!rc || (new_ndlp == ndlp)) { | ||
674 | return ndlp; | 670 | return ndlp; |
675 | } | ||
676 | 671 | ||
677 | if (!new_ndlp) { | 672 | if (!new_ndlp) { |
673 | rc = | ||
674 | memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
675 | if (!rc) | ||
676 | return ndlp; | ||
678 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 677 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); |
679 | if (!new_ndlp) | 678 | if (!new_ndlp) |
680 | return ndlp; | 679 | return ndlp; |
@@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
683 | } | 682 | } |
684 | 683 | ||
685 | lpfc_unreg_rpi(phba, new_ndlp); | 684 | lpfc_unreg_rpi(phba, new_ndlp); |
686 | new_ndlp->nlp_prev_state = ndlp->nlp_state; | ||
687 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 685 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
688 | new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 686 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; |
689 | lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); | 687 | new_ndlp->nlp_state = ndlp->nlp_state; |
688 | lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK); | ||
690 | 689 | ||
691 | /* Move this back to NPR list */ | 690 | /* Move this back to NPR list */ |
692 | lpfc_unreg_rpi(phba, ndlp); | 691 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { |
693 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 692 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
694 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 693 | } |
695 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 694 | else { |
696 | 695 | lpfc_unreg_rpi(phba, ndlp); | |
696 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | ||
697 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
698 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
699 | } | ||
697 | return new_ndlp; | 700 | return new_ndlp; |
698 | } | 701 | } |
699 | 702 | ||
@@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
703 | { | 706 | { |
704 | IOCB_t *irsp; | 707 | IOCB_t *irsp; |
705 | struct lpfc_nodelist *ndlp; | 708 | struct lpfc_nodelist *ndlp; |
709 | struct lpfc_dmabuf *prsp; | ||
706 | int disc, rc, did, type; | 710 | int disc, rc, did, type; |
707 | 711 | ||
708 | 712 | ||
@@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
769 | } | 773 | } |
770 | } else { | 774 | } else { |
771 | /* Good status, call state machine */ | 775 | /* Good status, call state machine */ |
772 | ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); | 776 | prsp = list_entry(((struct lpfc_dmabuf *) |
777 | cmdiocb->context2)->list.next, | ||
778 | struct lpfc_dmabuf, list); | ||
779 | ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); | ||
773 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 780 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
774 | NLP_EVT_CMPL_PLOGI); | 781 | NLP_EVT_CMPL_PLOGI); |
775 | } | 782 | } |
@@ -3441,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3441 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 3448 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { |
3442 | ndlp->nlp_type |= NLP_FABRIC; | 3449 | ndlp->nlp_type |= NLP_FABRIC; |
3443 | } | 3450 | } |
3451 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | ||
3452 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | ||
3444 | } | 3453 | } |
3445 | 3454 | ||
3446 | phba->fc_stat.elsRcvFrame++; | 3455 | phba->fc_stat.elsRcvFrame++; |
@@ -3462,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3462 | rjt_err = 1; | 3471 | rjt_err = 1; |
3463 | break; | 3472 | break; |
3464 | } | 3473 | } |
3474 | ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); | ||
3465 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); | 3475 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); |
3466 | break; | 3476 | break; |
3467 | case ELS_CMD_FLOGI: | 3477 | case ELS_CMD_FLOGI: |
3468 | phba->fc_stat.elsRcvFLOGI++; | 3478 | phba->fc_stat.elsRcvFLOGI++; |
3469 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); | 3479 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); |
3470 | if (newnode) { | 3480 | if (newnode) { |
3471 | mempool_free( ndlp, phba->nlp_mem_pool); | 3481 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3472 | } | 3482 | } |
3473 | break; | 3483 | break; |
3474 | case ELS_CMD_LOGO: | 3484 | case ELS_CMD_LOGO: |
@@ -3491,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3491 | phba->fc_stat.elsRcvRSCN++; | 3501 | phba->fc_stat.elsRcvRSCN++; |
3492 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); | 3502 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); |
3493 | if (newnode) { | 3503 | if (newnode) { |
3494 | mempool_free( ndlp, phba->nlp_mem_pool); | 3504 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3495 | } | 3505 | } |
3496 | break; | 3506 | break; |
3497 | case ELS_CMD_ADISC: | 3507 | case ELS_CMD_ADISC: |
@@ -3534,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3534 | phba->fc_stat.elsRcvLIRR++; | 3544 | phba->fc_stat.elsRcvLIRR++; |
3535 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); | 3545 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); |
3536 | if (newnode) { | 3546 | if (newnode) { |
3537 | mempool_free( ndlp, phba->nlp_mem_pool); | 3547 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3538 | } | 3548 | } |
3539 | break; | 3549 | break; |
3540 | case ELS_CMD_RPS: | 3550 | case ELS_CMD_RPS: |
3541 | phba->fc_stat.elsRcvRPS++; | 3551 | phba->fc_stat.elsRcvRPS++; |
3542 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); | 3552 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); |
3543 | if (newnode) { | 3553 | if (newnode) { |
3544 | mempool_free( ndlp, phba->nlp_mem_pool); | 3554 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3545 | } | 3555 | } |
3546 | break; | 3556 | break; |
3547 | case ELS_CMD_RPL: | 3557 | case ELS_CMD_RPL: |
3548 | phba->fc_stat.elsRcvRPL++; | 3558 | phba->fc_stat.elsRcvRPL++; |
3549 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); | 3559 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); |
3550 | if (newnode) { | 3560 | if (newnode) { |
3551 | mempool_free( ndlp, phba->nlp_mem_pool); | 3561 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3552 | } | 3562 | } |
3553 | break; | 3563 | break; |
3554 | case ELS_CMD_RNID: | 3564 | case ELS_CMD_RNID: |
3555 | phba->fc_stat.elsRcvRNID++; | 3565 | phba->fc_stat.elsRcvRNID++; |
3556 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); | 3566 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); |
3557 | if (newnode) { | 3567 | if (newnode) { |
3558 | mempool_free( ndlp, phba->nlp_mem_pool); | 3568 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3559 | } | 3569 | } |
3560 | break; | 3570 | break; |
3561 | default: | 3571 | default: |
@@ -3567,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3567 | "%d:0115 Unknown ELS command x%x received from " | 3577 | "%d:0115 Unknown ELS command x%x received from " |
3568 | "NPORT x%x\n", phba->brd_no, cmd, did); | 3578 | "NPORT x%x\n", phba->brd_no, cmd, did); |
3569 | if (newnode) { | 3579 | if (newnode) { |
3570 | mempool_free( ndlp, phba->nlp_mem_pool); | 3580 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3571 | } | 3581 | } |
3572 | break; | 3582 | break; |
3573 | } | 3583 | } |