aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c85
1 files changed, 54 insertions, 31 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index cbb68a942255..6e0e991c6445 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
719 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && 719 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
720 icmd->un.elsreq64.bdl.ulpIoTag32) { 720 icmd->un.elsreq64.bdl.ulpIoTag32) {
721 ndlp = (struct lpfc_nodelist *)(iocb->context1); 721 ndlp = (struct lpfc_nodelist *)(iocb->context1);
722 if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { 722 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
723 (ndlp->nlp_DID == Fabric_DID))
723 lpfc_sli_issue_abort_iotag(phba, pring, iocb); 724 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
724 }
725 } 725 }
726 } 726 }
727 spin_unlock_irq(&phba->hbalock); 727 spin_unlock_irq(&phba->hbalock);
@@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
829 struct fc_rport *rport; 829 struct fc_rport *rport;
830 struct serv_parm *sp; 830 struct serv_parm *sp;
831 uint8_t name[sizeof(struct lpfc_name)]; 831 uint8_t name[sizeof(struct lpfc_name)];
832 uint32_t rc; 832 uint32_t rc, keepDID = 0;
833 833
834 /* Fabric nodes can have the same WWPN so we don't bother searching 834 /* Fabric nodes can have the same WWPN so we don't bother searching
835 * by WWPN. Just return the ndlp that was given to us. 835 * by WWPN. Just return the ndlp that was given to us.
@@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
858 return ndlp; 858 return ndlp;
859 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); 859 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
860 } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { 860 } else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
861 rc = memcmp(&ndlp->nlp_portname, name,
862 sizeof(struct lpfc_name));
863 if (!rc)
864 return ndlp;
861 new_ndlp = lpfc_enable_node(vport, new_ndlp, 865 new_ndlp = lpfc_enable_node(vport, new_ndlp,
862 NLP_STE_UNUSED_NODE); 866 NLP_STE_UNUSED_NODE);
863 if (!new_ndlp) 867 if (!new_ndlp)
864 return ndlp; 868 return ndlp;
865 } 869 keepDID = new_ndlp->nlp_DID;
870 } else
871 keepDID = new_ndlp->nlp_DID;
866 872
867 lpfc_unreg_rpi(vport, new_ndlp); 873 lpfc_unreg_rpi(vport, new_ndlp);
868 new_ndlp->nlp_DID = ndlp->nlp_DID; 874 new_ndlp->nlp_DID = ndlp->nlp_DID;
@@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
893 } 899 }
894 new_ndlp->nlp_type = ndlp->nlp_type; 900 new_ndlp->nlp_type = ndlp->nlp_type;
895 } 901 }
902 /* We shall actually free the ndlp with both nlp_DID and
903 * nlp_portname fields equals 0 to avoid any ndlp on the
904 * nodelist never to be used.
905 */
906 if (ndlp->nlp_DID == 0) {
907 spin_lock_irq(&phba->ndlp_lock);
908 NLP_SET_FREE_REQ(ndlp);
909 spin_unlock_irq(&phba->ndlp_lock);
910 }
896 911
912 /* Two ndlps cannot have the same did on the nodelist */
913 ndlp->nlp_DID = keepDID;
897 lpfc_drop_node(vport, ndlp); 914 lpfc_drop_node(vport, ndlp);
898 } 915 }
899 else { 916 else {
900 lpfc_unreg_rpi(vport, ndlp); 917 lpfc_unreg_rpi(vport, ndlp);
901 ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ 918 /* Two ndlps cannot have the same did */
919 ndlp->nlp_DID = keepDID;
902 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 920 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
903 } 921 }
904 return new_ndlp; 922 return new_ndlp;
@@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2091 } 2109 }
2092 2110
2093 phba->fc_stat.elsXmitRetry++; 2111 phba->fc_stat.elsXmitRetry++;
2094 if (ndlp && delay) { 2112 if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) {
2095 phba->fc_stat.elsDelayRetry++; 2113 phba->fc_stat.elsDelayRetry++;
2096 ndlp->nlp_retry = cmdiocb->retry; 2114 ndlp->nlp_retry = cmdiocb->retry;
2097 2115
@@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2121 lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); 2139 lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
2122 return 1; 2140 return 1;
2123 case ELS_CMD_PLOGI: 2141 case ELS_CMD_PLOGI:
2124 if (ndlp) { 2142 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
2125 ndlp->nlp_prev_state = ndlp->nlp_state; 2143 ndlp->nlp_prev_state = ndlp->nlp_state;
2126 lpfc_nlp_set_state(vport, ndlp, 2144 lpfc_nlp_set_state(vport, ndlp,
2127 NLP_STE_PLOGI_ISSUE); 2145 NLP_STE_PLOGI_ISSUE);
@@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2302 lpfc_mbuf_free(phba, mp->virt, mp->phys); 2320 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2303 kfree(mp); 2321 kfree(mp);
2304 mempool_free(pmb, phba->mbox_mem_pool); 2322 mempool_free(pmb, phba->mbox_mem_pool);
2305 if (ndlp) { 2323 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
2306 lpfc_nlp_put(ndlp); 2324 lpfc_nlp_put(ndlp);
2307 /* This is the end of the default RPI cleanup logic for this 2325 /* This is the end of the default RPI cleanup logic for this
2308 * ndlp. If no other discovery threads are using this ndlp. 2326 * ndlp. If no other discovery threads are using this ndlp.
@@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2335 * function can have cmdiocb->contest1 (ndlp) field set to NULL. 2353 * function can have cmdiocb->contest1 (ndlp) field set to NULL.
2336 */ 2354 */
2337 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); 2355 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
2338 if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { 2356 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
2357 (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
2339 /* A LS_RJT associated with Default RPI cleanup has its own 2358 /* A LS_RJT associated with Default RPI cleanup has its own
2340 * seperate code path. 2359 * seperate code path.
2341 */ 2360 */
@@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2344 } 2363 }
2345 2364
2346 /* Check to see if link went down during discovery */ 2365 /* Check to see if link went down during discovery */
2347 if (!ndlp || lpfc_els_chk_latt(vport)) { 2366 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
2348 if (mbox) { 2367 if (mbox) {
2349 mp = (struct lpfc_dmabuf *) mbox->context1; 2368 mp = (struct lpfc_dmabuf *) mbox->context1;
2350 if (mp) { 2369 if (mp) {
@@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2353 } 2372 }
2354 mempool_free(mbox, phba->mbox_mem_pool); 2373 mempool_free(mbox, phba->mbox_mem_pool);
2355 } 2374 }
2356 if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) 2375 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
2376 (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
2357 if (lpfc_nlp_not_used(ndlp)) { 2377 if (lpfc_nlp_not_used(ndlp)) {
2358 ndlp = NULL; 2378 ndlp = NULL;
2359 /* Indicate the node has already released, 2379 /* Indicate the node has already released,
@@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2443 mempool_free(mbox, phba->mbox_mem_pool); 2463 mempool_free(mbox, phba->mbox_mem_pool);
2444 } 2464 }
2445out: 2465out:
2446 if (ndlp) { 2466 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
2447 spin_lock_irq(shost->host_lock); 2467 spin_lock_irq(shost->host_lock);
2448 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); 2468 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
2449 spin_unlock_irq(shost->host_lock); 2469 spin_unlock_irq(shost->host_lock);
@@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3139 /* Another thread is walking fc_rscn_id_list on this vport */ 3159 /* Another thread is walking fc_rscn_id_list on this vport */
3140 spin_unlock_irq(shost->host_lock); 3160 spin_unlock_irq(shost->host_lock);
3141 vport->fc_flag |= FC_RSCN_DISCOVERY; 3161 vport->fc_flag |= FC_RSCN_DISCOVERY;
3162 /* Send back ACC */
3163 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
3142 return 0; 3164 return 0;
3143 } 3165 }
3144 /* Indicate we are walking fc_rscn_id_list on this vport */ 3166 /* Indicate we are walking fc_rscn_id_list on this vport */
@@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
3928 else { 3950 else {
3929 struct lpfc_nodelist *ndlp; 3951 struct lpfc_nodelist *ndlp;
3930 ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); 3952 ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
3931 if (ndlp) 3953 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
3932 remote_ID = ndlp->nlp_DID; 3954 remote_ID = ndlp->nlp_DID;
3933 } 3955 }
3934 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 3956 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
4097 newnode = 1; 4119 newnode = 1;
4098 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) 4120 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
4099 ndlp->nlp_type |= NLP_FABRIC; 4121 ndlp->nlp_type |= NLP_FABRIC;
4100 } else { 4122 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
4101 if (!NLP_CHK_NODE_ACT(ndlp)) { 4123 ndlp = lpfc_enable_node(vport, ndlp,
4102 ndlp = lpfc_enable_node(vport, ndlp, 4124 NLP_STE_UNUSED_NODE);
4103 NLP_STE_UNUSED_NODE); 4125 if (!ndlp)
4104 if (!ndlp) 4126 goto dropit;
4105 goto dropit; 4127 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
4106 } 4128 newnode = 1;
4107 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { 4129 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
4108 /* This is simular to the new node path */ 4130 ndlp->nlp_type |= NLP_FABRIC;
4109 ndlp = lpfc_nlp_get(ndlp); 4131 } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
4110 if (!ndlp) 4132 /* This is similar to the new node path */
4111 goto dropit; 4133 ndlp = lpfc_nlp_get(ndlp);
4112 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 4134 if (!ndlp)
4113 newnode = 1; 4135 goto dropit;
4114 } 4136 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
4137 newnode = 1;
4115 } 4138 }
4116 4139
4117 phba->fc_stat.elsRcvFrame++; 4140 phba->fc_stat.elsRcvFrame++;
@@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
4451 return; 4474 return;
4452 } 4475 }
4453 lpfc_nlp_init(vport, ndlp, NameServer_DID); 4476 lpfc_nlp_init(vport, ndlp, NameServer_DID);
4454 ndlp->nlp_type |= NLP_FABRIC;
4455 } else if (!NLP_CHK_NODE_ACT(ndlp)) { 4477 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
4456 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); 4478 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
4457 if (!ndlp) { 4479 if (!ndlp) {
@@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
4465 return; 4487 return;
4466 } 4488 }
4467 } 4489 }
4490 ndlp->nlp_type |= NLP_FABRIC;
4468 4491
4469 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); 4492 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
4470 4493
@@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
4481 if (ndlp_fdmi) { 4504 if (ndlp_fdmi) {
4482 lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); 4505 lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
4483 ndlp_fdmi->nlp_type |= NLP_FABRIC; 4506 ndlp_fdmi->nlp_type |= NLP_FABRIC;
4484 ndlp_fdmi->nlp_state = 4507 lpfc_nlp_set_state(vport, ndlp_fdmi,
4485 NLP_STE_PLOGI_ISSUE; 4508 NLP_STE_PLOGI_ISSUE);
4486 lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 4509 lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
4487 0); 4510 0);
4488 } 4511 }