diff options
author | James Smart <James.Smart@Emulex.Com> | 2006-03-07 15:02:37 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-03-12 09:54:29 -0500 |
commit | 488d1469b318e6bf2b907743d626008340bc4f6e (patch) | |
tree | 66853f237b78ebbe2b28b991c640aefe83297615 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 071a651e28bfc1a66a885dc285792e335427a097 (diff) |
[SCSI] lpfc 8.1.4 : Fix Discovery processing for NPorts that change their NPortId on the fly
Fix Discovery processing for NPorts that change their NPortId on the fly
due to a cable swap.
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 | 207 |
1 files changed, 131 insertions, 76 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 090f4609d2af..efba875e53e4 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -97,10 +97,9 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | static struct lpfc_iocbq * | 99 | static struct lpfc_iocbq * |
100 | lpfc_prep_els_iocb(struct lpfc_hba * phba, | 100 | lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, |
101 | uint8_t expectRsp, | 101 | uint16_t cmdSize, uint8_t retry, struct lpfc_nodelist * ndlp, |
102 | uint16_t cmdSize, | 102 | uint32_t did, uint32_t elscmd) |
103 | uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd) | ||
104 | { | 103 | { |
105 | struct lpfc_sli_ring *pring; | 104 | struct lpfc_sli_ring *pring; |
106 | struct lpfc_iocbq *elsiocb; | 105 | struct lpfc_iocbq *elsiocb; |
@@ -181,7 +180,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
181 | icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; | 180 | icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; |
182 | if (expectRsp) { | 181 | if (expectRsp) { |
183 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); | 182 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); |
184 | icmd->un.elsreq64.remoteID = ndlp->nlp_DID; /* DID */ | 183 | icmd->un.elsreq64.remoteID = did; /* DID */ |
185 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; | 184 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; |
186 | } else { | 185 | } else { |
187 | icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); | 186 | icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); |
@@ -225,7 +224,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
225 | "%d:0116 Xmit ELS command x%x to remote " | 224 | "%d:0116 Xmit ELS command x%x to remote " |
226 | "NPORT x%x Data: x%x x%x\n", | 225 | "NPORT x%x Data: x%x x%x\n", |
227 | phba->brd_no, elscmd, | 226 | phba->brd_no, elscmd, |
228 | ndlp->nlp_DID, icmd->ulpIoTag, phba->hba_state); | 227 | did, icmd->ulpIoTag, phba->hba_state); |
229 | } else { | 228 | } else { |
230 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ | 229 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ |
231 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 230 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -516,10 +515,10 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
516 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 515 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
517 | 516 | ||
518 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 517 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
519 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 518 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
520 | ndlp, ELS_CMD_FLOGI)) == 0) { | 519 | ndlp->nlp_DID, ELS_CMD_FLOGI); |
520 | if (!elsiocb) | ||
521 | return 1; | 521 | return 1; |
522 | } | ||
523 | 522 | ||
524 | icmd = &elsiocb->iocb; | 523 | icmd = &elsiocb->iocb; |
525 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 524 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -652,29 +651,80 @@ lpfc_more_plogi(struct lpfc_hba * phba) | |||
652 | return; | 651 | return; |
653 | } | 652 | } |
654 | 653 | ||
654 | static struct lpfc_nodelist * | ||
655 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | ||
656 | struct lpfc_nodelist *ndlp) | ||
657 | { | ||
658 | struct lpfc_nodelist *new_ndlp; | ||
659 | struct lpfc_dmabuf *pcmd, *prsp; | ||
660 | uint32_t *lp; | ||
661 | struct serv_parm *sp; | ||
662 | uint8_t name[sizeof (struct lpfc_name)]; | ||
663 | uint32_t rc; | ||
664 | |||
665 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
666 | prsp = (struct lpfc_dmabuf *) pcmd->list.next; | ||
667 | lp = (uint32_t *) prsp->virt; | ||
668 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | ||
669 | |||
670 | /* Now we to find out if the NPort we are logging into, matches the WWPN | ||
671 | * we have for that ndlp. If not, we have some work to do. | ||
672 | */ | ||
673 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); | ||
674 | |||
675 | memset(name, 0, sizeof (struct lpfc_name)); | ||
676 | rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
677 | if (!rc || (new_ndlp == ndlp)) { | ||
678 | return ndlp; | ||
679 | } | ||
680 | |||
681 | if (!new_ndlp) { | ||
682 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | ||
683 | if (!new_ndlp) | ||
684 | return ndlp; | ||
685 | |||
686 | lpfc_nlp_init(phba, new_ndlp, ndlp->nlp_DID); | ||
687 | } | ||
688 | |||
689 | lpfc_unreg_rpi(phba, new_ndlp); | ||
690 | new_ndlp->nlp_prev_state = ndlp->nlp_state; | ||
691 | new_ndlp->nlp_DID = ndlp->nlp_DID; | ||
692 | new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | ||
693 | lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); | ||
694 | |||
695 | /* Move this back to NPR list */ | ||
696 | lpfc_unreg_rpi(phba, ndlp); | ||
697 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | ||
698 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
699 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
700 | |||
701 | return new_ndlp; | ||
702 | } | ||
703 | |||
655 | static void | 704 | static void |
656 | lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 705 | lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
657 | struct lpfc_iocbq * rspiocb) | 706 | struct lpfc_iocbq * rspiocb) |
658 | { | 707 | { |
659 | IOCB_t *irsp; | 708 | IOCB_t *irsp; |
660 | struct lpfc_sli *psli; | ||
661 | struct lpfc_nodelist *ndlp; | 709 | struct lpfc_nodelist *ndlp; |
662 | int disc, rc, did, type; | 710 | int disc, rc, did, type; |
663 | 711 | ||
664 | psli = &phba->sli; | ||
665 | 712 | ||
666 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 713 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
667 | cmdiocb->context_un.rsp_iocb = rspiocb; | 714 | cmdiocb->context_un.rsp_iocb = rspiocb; |
668 | 715 | ||
669 | irsp = &rspiocb->iocb; | 716 | irsp = &rspiocb->iocb; |
670 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 717 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, |
718 | irsp->un.elsreq64.remoteID); | ||
719 | if (!ndlp) | ||
720 | goto out; | ||
671 | 721 | ||
672 | /* Since ndlp can be freed in the disc state machine, note if this node | 722 | /* Since ndlp can be freed in the disc state machine, note if this node |
673 | * is being used during discovery. | 723 | * is being used during discovery. |
674 | */ | 724 | */ |
675 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 725 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); |
676 | spin_lock_irq(phba->host->host_lock); | 726 | spin_lock_irq(phba->host->host_lock); |
677 | ndlp->nlp_flag &= ~(NLP_PLOGI_SND | NLP_NPR_2B_DISC); | 727 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
678 | spin_unlock_irq(phba->host->host_lock); | 728 | spin_unlock_irq(phba->host->host_lock); |
679 | rc = 0; | 729 | rc = 0; |
680 | 730 | ||
@@ -723,18 +773,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
723 | } | 773 | } |
724 | } else { | 774 | } else { |
725 | /* Good status, call state machine */ | 775 | /* Good status, call state machine */ |
776 | ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); | ||
726 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 777 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
727 | NLP_EVT_CMPL_PLOGI); | 778 | NLP_EVT_CMPL_PLOGI); |
728 | } | 779 | } |
729 | 780 | ||
730 | if (type & NLP_FABRIC) { | ||
731 | /* If we cannot login to Nameserver, kick off discovery now */ | ||
732 | if ((did == NameServer_DID) && (rc == NLP_STE_FREED_NODE)) { | ||
733 | lpfc_disc_start(phba); | ||
734 | } | ||
735 | goto out; | ||
736 | } | ||
737 | |||
738 | if (disc && phba->num_disc_nodes) { | 781 | if (disc && phba->num_disc_nodes) { |
739 | /* Check to see if there are more PLOGIs to be sent */ | 782 | /* Check to see if there are more PLOGIs to be sent */ |
740 | lpfc_more_plogi(phba); | 783 | lpfc_more_plogi(phba); |
@@ -767,8 +810,7 @@ out: | |||
767 | } | 810 | } |
768 | 811 | ||
769 | int | 812 | int |
770 | lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 813 | lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) |
771 | uint8_t retry) | ||
772 | { | 814 | { |
773 | struct serv_parm *sp; | 815 | struct serv_parm *sp; |
774 | IOCB_t *icmd; | 816 | IOCB_t *icmd; |
@@ -782,7 +824,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
782 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 824 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
783 | 825 | ||
784 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 826 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
785 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 827 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, |
786 | ELS_CMD_PLOGI); | 828 | ELS_CMD_PLOGI); |
787 | if (!elsiocb) | 829 | if (!elsiocb) |
788 | return 1; | 830 | return 1; |
@@ -805,9 +847,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
805 | phba->fc_stat.elsXmitPLOGI++; | 847 | phba->fc_stat.elsXmitPLOGI++; |
806 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; | 848 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; |
807 | spin_lock_irq(phba->host->host_lock); | 849 | spin_lock_irq(phba->host->host_lock); |
808 | ndlp->nlp_flag |= NLP_PLOGI_SND; | ||
809 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 850 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
810 | ndlp->nlp_flag &= ~NLP_PLOGI_SND; | ||
811 | spin_unlock_irq(phba->host->host_lock); | 851 | spin_unlock_irq(phba->host->host_lock); |
812 | lpfc_els_free_iocb(phba, elsiocb); | 852 | lpfc_els_free_iocb(phba, elsiocb); |
813 | return 1; | 853 | return 1; |
@@ -890,10 +930,10 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
890 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 930 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
891 | 931 | ||
892 | cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); | 932 | cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); |
893 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 933 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
894 | ndlp, ELS_CMD_PRLI)) == 0) { | 934 | ndlp->nlp_DID, ELS_CMD_PRLI); |
935 | if (!elsiocb) | ||
895 | return 1; | 936 | return 1; |
896 | } | ||
897 | 937 | ||
898 | icmd = &elsiocb->iocb; | 938 | icmd = &elsiocb->iocb; |
899 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 939 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1117,10 +1157,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1117 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1157 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1118 | 1158 | ||
1119 | cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); | 1159 | cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); |
1120 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1160 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1121 | ndlp, ELS_CMD_ADISC)) == 0) { | 1161 | ndlp->nlp_DID, ELS_CMD_ADISC); |
1162 | if (!elsiocb) | ||
1122 | return 1; | 1163 | return 1; |
1123 | } | ||
1124 | 1164 | ||
1125 | icmd = &elsiocb->iocb; | 1165 | icmd = &elsiocb->iocb; |
1126 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1166 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1224,10 +1264,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1224 | pring = &psli->ring[LPFC_ELS_RING]; | 1264 | pring = &psli->ring[LPFC_ELS_RING]; |
1225 | 1265 | ||
1226 | cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); | 1266 | cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); |
1227 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1267 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1228 | ndlp, ELS_CMD_LOGO)) == 0) { | 1268 | ndlp->nlp_DID, ELS_CMD_LOGO); |
1269 | if (!elsiocb) | ||
1229 | return 1; | 1270 | return 1; |
1230 | } | ||
1231 | 1271 | ||
1232 | icmd = &elsiocb->iocb; | 1272 | icmd = &elsiocb->iocb; |
1233 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1273 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1296,8 +1336,9 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1296 | 1336 | ||
1297 | lpfc_nlp_init(phba, ndlp, nportid); | 1337 | lpfc_nlp_init(phba, ndlp, nportid); |
1298 | 1338 | ||
1299 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1339 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1300 | ndlp, ELS_CMD_SCR)) == 0) { | 1340 | ndlp->nlp_DID, ELS_CMD_SCR); |
1341 | if (!elsiocb) { | ||
1301 | mempool_free( ndlp, phba->nlp_mem_pool); | 1342 | mempool_free( ndlp, phba->nlp_mem_pool); |
1302 | return 1; | 1343 | return 1; |
1303 | } | 1344 | } |
@@ -1348,8 +1389,9 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1348 | return 1; | 1389 | return 1; |
1349 | lpfc_nlp_init(phba, ndlp, nportid); | 1390 | lpfc_nlp_init(phba, ndlp, nportid); |
1350 | 1391 | ||
1351 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1392 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1352 | ndlp, ELS_CMD_RNID)) == 0) { | 1393 | ndlp->nlp_DID, ELS_CMD_RNID); |
1394 | if (!elsiocb) { | ||
1353 | mempool_free( ndlp, phba->nlp_mem_pool); | 1395 | mempool_free( ndlp, phba->nlp_mem_pool); |
1354 | return 1; | 1396 | return 1; |
1355 | } | 1397 | } |
@@ -1448,7 +1490,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1448 | lpfc_issue_els_flogi(phba, ndlp, retry); | 1490 | lpfc_issue_els_flogi(phba, ndlp, retry); |
1449 | break; | 1491 | break; |
1450 | case ELS_CMD_PLOGI: | 1492 | case ELS_CMD_PLOGI: |
1451 | if (!lpfc_issue_els_plogi(phba, ndlp, retry)) { | 1493 | if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) { |
1452 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1494 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1453 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1495 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1454 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1496 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
@@ -1491,6 +1533,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1491 | int retry, maxretry; | 1533 | int retry, maxretry; |
1492 | int delay; | 1534 | int delay; |
1493 | uint32_t cmd; | 1535 | uint32_t cmd; |
1536 | uint32_t did; | ||
1494 | 1537 | ||
1495 | retry = 0; | 1538 | retry = 0; |
1496 | delay = 0; | 1539 | delay = 0; |
@@ -1499,6 +1542,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1499 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1542 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
1500 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 1543 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
1501 | cmd = 0; | 1544 | cmd = 0; |
1545 | |||
1502 | /* Note: context2 may be 0 for internal driver abort | 1546 | /* Note: context2 may be 0 for internal driver abort |
1503 | * of delays ELS command. | 1547 | * of delays ELS command. |
1504 | */ | 1548 | */ |
@@ -1508,6 +1552,16 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1508 | cmd = *elscmd++; | 1552 | cmd = *elscmd++; |
1509 | } | 1553 | } |
1510 | 1554 | ||
1555 | if(ndlp) | ||
1556 | did = ndlp->nlp_DID; | ||
1557 | else { | ||
1558 | /* We should only hit this case for retrying PLOGI */ | ||
1559 | did = irsp->un.elsreq64.remoteID; | ||
1560 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); | ||
1561 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) | ||
1562 | return 1; | ||
1563 | } | ||
1564 | |||
1511 | switch (irsp->ulpStatus) { | 1565 | switch (irsp->ulpStatus) { |
1512 | case IOSTAT_FCP_RSP_ERROR: | 1566 | case IOSTAT_FCP_RSP_ERROR: |
1513 | case IOSTAT_REMOTE_STOP: | 1567 | case IOSTAT_REMOTE_STOP: |
@@ -1596,9 +1650,8 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1596 | break; | 1650 | break; |
1597 | } | 1651 | } |
1598 | 1652 | ||
1599 | if (ndlp->nlp_DID == FDMI_DID) { | 1653 | if (did == FDMI_DID) |
1600 | retry = 1; | 1654 | retry = 1; |
1601 | } | ||
1602 | 1655 | ||
1603 | if ((++cmdiocb->retry) >= maxretry) { | 1656 | if ((++cmdiocb->retry) >= maxretry) { |
1604 | phba->fc_stat.elsRetryExceeded++; | 1657 | phba->fc_stat.elsRetryExceeded++; |
@@ -1612,7 +1665,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1612 | "%d:0107 Retry ELS command x%x to remote " | 1665 | "%d:0107 Retry ELS command x%x to remote " |
1613 | "NPORT x%x Data: x%x x%x\n", | 1666 | "NPORT x%x Data: x%x x%x\n", |
1614 | phba->brd_no, | 1667 | phba->brd_no, |
1615 | cmd, ndlp->nlp_DID, cmdiocb->retry, delay); | 1668 | cmd, did, cmdiocb->retry, delay); |
1616 | 1669 | ||
1617 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { | 1670 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { |
1618 | /* If discovery / RSCN timer is running, reset it */ | 1671 | /* If discovery / RSCN timer is running, reset it */ |
@@ -1623,7 +1676,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1623 | } | 1676 | } |
1624 | 1677 | ||
1625 | phba->fc_stat.elsXmitRetry++; | 1678 | phba->fc_stat.elsXmitRetry++; |
1626 | if (delay) { | 1679 | if (ndlp && delay) { |
1627 | phba->fc_stat.elsDelayRetry++; | 1680 | phba->fc_stat.elsDelayRetry++; |
1628 | ndlp->nlp_retry = cmdiocb->retry; | 1681 | ndlp->nlp_retry = cmdiocb->retry; |
1629 | 1682 | ||
@@ -1642,10 +1695,12 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1642 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); | 1695 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); |
1643 | return 1; | 1696 | return 1; |
1644 | case ELS_CMD_PLOGI: | 1697 | case ELS_CMD_PLOGI: |
1645 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1698 | if (ndlp) { |
1646 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1699 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1647 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1700 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1648 | lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry); | 1701 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1702 | } | ||
1703 | lpfc_issue_els_plogi(phba, did, cmdiocb->retry); | ||
1649 | return 1; | 1704 | return 1; |
1650 | case ELS_CMD_ADISC: | 1705 | case ELS_CMD_ADISC: |
1651 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1706 | ndlp->nlp_prev_state = ndlp->nlp_state; |
@@ -1671,9 +1726,9 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1671 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ | 1726 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ |
1672 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1727 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1673 | "%d:0108 No retry ELS command x%x to remote NPORT x%x " | 1728 | "%d:0108 No retry ELS command x%x to remote NPORT x%x " |
1674 | "Data: x%x x%x\n", | 1729 | "Data: x%x\n", |
1675 | phba->brd_no, | 1730 | phba->brd_no, |
1676 | cmd, ndlp->nlp_DID, cmdiocb->retry, ndlp->nlp_flag); | 1731 | cmd, did, cmdiocb->retry); |
1677 | 1732 | ||
1678 | return 0; | 1733 | return 0; |
1679 | } | 1734 | } |
@@ -1827,9 +1882,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1827 | switch (flag) { | 1882 | switch (flag) { |
1828 | case ELS_CMD_ACC: | 1883 | case ELS_CMD_ACC: |
1829 | cmdsize = sizeof (uint32_t); | 1884 | cmdsize = sizeof (uint32_t); |
1830 | if ((elsiocb = | 1885 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1831 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1886 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1832 | ndlp, ELS_CMD_ACC)) == 0) { | 1887 | if (!elsiocb) { |
1833 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | 1888 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; |
1834 | return 1; | 1889 | return 1; |
1835 | } | 1890 | } |
@@ -1841,11 +1896,11 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1841 | break; | 1896 | break; |
1842 | case ELS_CMD_PLOGI: | 1897 | case ELS_CMD_PLOGI: |
1843 | cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); | 1898 | cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); |
1844 | if ((elsiocb = | 1899 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1845 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1900 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1846 | ndlp, ELS_CMD_ACC)) == 0) { | 1901 | if (!elsiocb) |
1847 | return 1; | 1902 | return 1; |
1848 | } | 1903 | |
1849 | icmd = &elsiocb->iocb; | 1904 | icmd = &elsiocb->iocb; |
1850 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | 1905 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ |
1851 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1906 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1910,10 +1965,10 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | |||
1910 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1965 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1911 | 1966 | ||
1912 | cmdsize = 2 * sizeof (uint32_t); | 1967 | cmdsize = 2 * sizeof (uint32_t); |
1913 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1968 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1914 | ndlp, ELS_CMD_LS_RJT)) == 0) { | 1969 | ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT); |
1970 | if (!elsiocb) | ||
1915 | return 1; | 1971 | return 1; |
1916 | } | ||
1917 | 1972 | ||
1918 | icmd = &elsiocb->iocb; | 1973 | icmd = &elsiocb->iocb; |
1919 | oldcmd = &oldiocb->iocb; | 1974 | oldcmd = &oldiocb->iocb; |
@@ -1963,10 +2018,10 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, | |||
1963 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2018 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1964 | 2019 | ||
1965 | cmdsize = sizeof (uint32_t) + sizeof (ADISC); | 2020 | cmdsize = sizeof (uint32_t) + sizeof (ADISC); |
1966 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2021 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1967 | ndlp, ELS_CMD_ACC)) == 0) { | 2022 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
2023 | if (!elsiocb) | ||
1968 | return 1; | 2024 | return 1; |
1969 | } | ||
1970 | 2025 | ||
1971 | /* Xmit ADISC ACC response tag <ulpIoTag> */ | 2026 | /* Xmit ADISC ACC response tag <ulpIoTag> */ |
1972 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2027 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2023,7 +2078,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, | |||
2023 | 2078 | ||
2024 | cmdsize = sizeof (uint32_t) + sizeof (PRLI); | 2079 | cmdsize = sizeof (uint32_t) + sizeof (PRLI); |
2025 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp, | 2080 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp, |
2026 | (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); | 2081 | ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); |
2027 | if (!elsiocb) | 2082 | if (!elsiocb) |
2028 | return 1; | 2083 | return 1; |
2029 | 2084 | ||
@@ -2103,10 +2158,10 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, | |||
2103 | if (format) | 2158 | if (format) |
2104 | cmdsize += sizeof (RNID_TOP_DISC); | 2159 | cmdsize += sizeof (RNID_TOP_DISC); |
2105 | 2160 | ||
2106 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2161 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
2107 | ndlp, ELS_CMD_ACC)) == 0) { | 2162 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
2163 | if (!elsiocb) | ||
2108 | return 1; | 2164 | return 1; |
2109 | } | ||
2110 | 2165 | ||
2111 | /* Xmit RNID ACC response tag <ulpIoTag> */ | 2166 | /* Xmit RNID ACC response tag <ulpIoTag> */ |
2112 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2167 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2217,7 +2272,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) | |||
2217 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2272 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2218 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2273 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2219 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 2274 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
2220 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2275 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
2221 | sentplogi++; | 2276 | sentplogi++; |
2222 | phba->num_disc_nodes++; | 2277 | phba->num_disc_nodes++; |
2223 | if (phba->num_disc_nodes >= | 2278 | if (phba->num_disc_nodes >= |
@@ -2516,7 +2571,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2516 | ndlp->nlp_type |= NLP_FABRIC; | 2571 | ndlp->nlp_type |= NLP_FABRIC; |
2517 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2572 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2518 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2573 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2519 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2574 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); |
2520 | /* Wait for NameServer login cmpl before we can | 2575 | /* Wait for NameServer login cmpl before we can |
2521 | continue */ | 2576 | continue */ |
2522 | return 1; | 2577 | return 1; |
@@ -2694,8 +2749,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2694 | 2749 | ||
2695 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); | 2750 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); |
2696 | mempool_free( pmb, phba->mbox_mem_pool); | 2751 | mempool_free( pmb, phba->mbox_mem_pool); |
2697 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, | 2752 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, |
2698 | ndlp, ELS_CMD_ACC); | 2753 | ndlp->nlp_DID, ELS_CMD_ACC); |
2699 | if (!elsiocb) | 2754 | if (!elsiocb) |
2700 | return; | 2755 | return; |
2701 | 2756 | ||
@@ -2806,11 +2861,11 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, | |||
2806 | psli = &phba->sli; | 2861 | psli = &phba->sli; |
2807 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2862 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
2808 | 2863 | ||
2809 | if ((elsiocb = | 2864 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
2810 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2865 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
2811 | ndlp, ELS_CMD_ACC)) == 0) { | 2866 | if (!elsiocb) |
2812 | return 1; | 2867 | return 1; |
2813 | } | 2868 | |
2814 | icmd = &elsiocb->iocb; | 2869 | icmd = &elsiocb->iocb; |
2815 | oldcmd = &oldiocb->iocb; | 2870 | oldcmd = &oldiocb->iocb; |
2816 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | 2871 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ |
@@ -2943,7 +2998,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
2943 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2998 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2944 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2999 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2945 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 3000 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
2946 | lpfc_issue_els_plogi(phba, ndlp, 0); | 3001 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
2947 | } | 3002 | } |
2948 | 3003 | ||
2949 | /* Send a FARP response to that node */ | 3004 | /* Send a FARP response to that node */ |