diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 154 |
1 files changed, 114 insertions, 40 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b73612d4fc53..813eeca7ce1e 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -109,9 +109,10 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
109 | 109 | ||
110 | /* fill in BDEs for command */ | 110 | /* fill in BDEs for command */ |
111 | /* Allocate buffer for command payload */ | 111 | /* Allocate buffer for command payload */ |
112 | if (((pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL)) == 0) || | 112 | pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); |
113 | ((pcmd->virt = lpfc_mbuf_alloc(phba, | 113 | if (pcmd) |
114 | MEM_PRI, &(pcmd->phys))) == 0)) { | 114 | pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); |
115 | if (!pcmd || !pcmd->virt) { | ||
115 | kfree(pcmd); | 116 | kfree(pcmd); |
116 | 117 | ||
117 | lpfc_sli_release_iocbq(phba, elsiocb); | 118 | lpfc_sli_release_iocbq(phba, elsiocb); |
@@ -126,7 +127,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
126 | if (prsp) | 127 | if (prsp) |
127 | prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 128 | prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, |
128 | &prsp->phys); | 129 | &prsp->phys); |
129 | if (prsp == 0 || prsp->virt == 0) { | 130 | if (!prsp || !prsp->virt) { |
130 | kfree(prsp); | 131 | kfree(prsp); |
131 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | 132 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); |
132 | kfree(pcmd); | 133 | kfree(pcmd); |
@@ -143,7 +144,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
143 | if (pbuflist) | 144 | if (pbuflist) |
144 | pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 145 | pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, |
145 | &pbuflist->phys); | 146 | &pbuflist->phys); |
146 | if (pbuflist == 0 || pbuflist->virt == 0) { | 147 | if (!pbuflist || !pbuflist->virt) { |
147 | lpfc_sli_release_iocbq(phba, elsiocb); | 148 | lpfc_sli_release_iocbq(phba, elsiocb); |
148 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | 149 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); |
149 | lpfc_mbuf_free(phba, prsp->virt, prsp->phys); | 150 | lpfc_mbuf_free(phba, prsp->virt, prsp->phys); |
@@ -234,15 +235,20 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
234 | struct lpfc_nodelist *ndlp; | 235 | struct lpfc_nodelist *ndlp; |
235 | struct serv_parm *sp; | 236 | struct serv_parm *sp; |
236 | int rc; | 237 | int rc; |
238 | int err = 0; | ||
237 | 239 | ||
238 | sp = &phba->fc_fabparam; | 240 | sp = &phba->fc_fabparam; |
239 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 241 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
240 | if (!ndlp) | 242 | if (!ndlp) { |
243 | err = 1; | ||
241 | goto fail; | 244 | goto fail; |
245 | } | ||
242 | 246 | ||
243 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 247 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
244 | if (!mbox) | 248 | if (!mbox) { |
249 | err = 2; | ||
245 | goto fail; | 250 | goto fail; |
251 | } | ||
246 | 252 | ||
247 | vport->port_state = LPFC_FABRIC_CFG_LINK; | 253 | vport->port_state = LPFC_FABRIC_CFG_LINK; |
248 | lpfc_config_link(phba, mbox); | 254 | lpfc_config_link(phba, mbox); |
@@ -250,24 +256,32 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
250 | mbox->vport = vport; | 256 | mbox->vport = vport; |
251 | 257 | ||
252 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 258 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
253 | if (rc == MBX_NOT_FINISHED) | 259 | if (rc == MBX_NOT_FINISHED) { |
260 | err = 3; | ||
254 | goto fail_free_mbox; | 261 | goto fail_free_mbox; |
262 | } | ||
255 | 263 | ||
256 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 264 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
257 | if (!mbox) | 265 | if (!mbox) { |
266 | err = 4; | ||
258 | goto fail; | 267 | goto fail; |
268 | } | ||
259 | rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, | 269 | rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, |
260 | 0); | 270 | 0); |
261 | if (rc) | 271 | if (rc) { |
272 | err = 5; | ||
262 | goto fail_free_mbox; | 273 | goto fail_free_mbox; |
274 | } | ||
263 | 275 | ||
264 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; | 276 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; |
265 | mbox->vport = vport; | 277 | mbox->vport = vport; |
266 | mbox->context2 = lpfc_nlp_get(ndlp); | 278 | mbox->context2 = lpfc_nlp_get(ndlp); |
267 | 279 | ||
268 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 280 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
269 | if (rc == MBX_NOT_FINISHED) | 281 | if (rc == MBX_NOT_FINISHED) { |
282 | err = 6; | ||
270 | goto fail_issue_reg_login; | 283 | goto fail_issue_reg_login; |
284 | } | ||
271 | 285 | ||
272 | return 0; | 286 | return 0; |
273 | 287 | ||
@@ -282,7 +296,7 @@ fail_free_mbox: | |||
282 | fail: | 296 | fail: |
283 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 297 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
284 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 298 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
285 | "0249 Cannot issue Register Fabric login\n"); | 299 | "0249 Cannot issue Register Fabric login: Err %d\n", err); |
286 | return -ENXIO; | 300 | return -ENXIO; |
287 | } | 301 | } |
288 | 302 | ||
@@ -684,6 +698,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
684 | struct lpfc_hba *phba = vport->phba; | 698 | struct lpfc_hba *phba = vport->phba; |
685 | struct lpfc_nodelist *ndlp; | 699 | struct lpfc_nodelist *ndlp; |
686 | 700 | ||
701 | vport->port_state = LPFC_FLOGI; | ||
702 | lpfc_set_disctmo(vport); | ||
703 | |||
687 | /* First look for the Fabric ndlp */ | 704 | /* First look for the Fabric ndlp */ |
688 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 705 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
689 | if (!ndlp) { | 706 | if (!ndlp) { |
@@ -694,6 +711,12 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
694 | lpfc_nlp_init(vport, ndlp, Fabric_DID); | 711 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
695 | } else { | 712 | } else { |
696 | lpfc_dequeue_node(vport, ndlp); | 713 | lpfc_dequeue_node(vport, ndlp); |
714 | |||
715 | /* If we go thru this path, Fabric_DID ndlp is in the process | ||
716 | * of being removed. We need to bump the reference count by 1 | ||
717 | * so it stays around all through this link up period. | ||
718 | */ | ||
719 | lpfc_nlp_get(ndlp); | ||
697 | } | 720 | } |
698 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) { | 721 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) { |
699 | lpfc_nlp_put(ndlp); | 722 | lpfc_nlp_put(ndlp); |
@@ -932,6 +955,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
932 | struct lpfc_hba *phba = vport->phba; | 955 | struct lpfc_hba *phba = vport->phba; |
933 | struct serv_parm *sp; | 956 | struct serv_parm *sp; |
934 | IOCB_t *icmd; | 957 | IOCB_t *icmd; |
958 | struct lpfc_nodelist *ndlp; | ||
935 | struct lpfc_iocbq *elsiocb; | 959 | struct lpfc_iocbq *elsiocb; |
936 | struct lpfc_sli_ring *pring; | 960 | struct lpfc_sli_ring *pring; |
937 | struct lpfc_sli *psli; | 961 | struct lpfc_sli *psli; |
@@ -942,8 +966,11 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
942 | psli = &phba->sli; | 966 | psli = &phba->sli; |
943 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 967 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
944 | 968 | ||
969 | ndlp = lpfc_findnode_did(vport, did); | ||
970 | /* If ndlp if not NULL, we will bump the reference count on it */ | ||
971 | |||
945 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); | 972 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); |
946 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did, | 973 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, |
947 | ELS_CMD_PLOGI); | 974 | ELS_CMD_PLOGI); |
948 | if (!elsiocb) | 975 | if (!elsiocb) |
949 | return 1; | 976 | return 1; |
@@ -1412,6 +1439,13 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1412 | psli = &phba->sli; | 1439 | psli = &phba->sli; |
1413 | pring = &psli->ring[LPFC_ELS_RING]; | 1440 | pring = &psli->ring[LPFC_ELS_RING]; |
1414 | 1441 | ||
1442 | spin_lock_irq(shost->host_lock); | ||
1443 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | ||
1444 | spin_unlock_irq(shost->host_lock); | ||
1445 | return 0; | ||
1446 | } | ||
1447 | spin_unlock_irq(shost->host_lock); | ||
1448 | |||
1415 | cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name); | 1449 | cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name); |
1416 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | 1450 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1417 | ndlp->nlp_DID, ELS_CMD_LOGO); | 1451 | ndlp->nlp_DID, ELS_CMD_LOGO); |
@@ -1758,6 +1792,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1758 | uint32_t *elscmd; | 1792 | uint32_t *elscmd; |
1759 | struct ls_rjt stat; | 1793 | struct ls_rjt stat; |
1760 | int retry = 0, maxretry = lpfc_max_els_tries, delay = 0; | 1794 | int retry = 0, maxretry = lpfc_max_els_tries, delay = 0; |
1795 | int logerr = 0; | ||
1761 | uint32_t cmd = 0; | 1796 | uint32_t cmd = 0; |
1762 | uint32_t did; | 1797 | uint32_t did; |
1763 | 1798 | ||
@@ -1814,6 +1849,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1814 | break; | 1849 | break; |
1815 | 1850 | ||
1816 | case IOERR_NO_RESOURCES: | 1851 | case IOERR_NO_RESOURCES: |
1852 | logerr = 1; /* HBA out of resources */ | ||
1817 | retry = 1; | 1853 | retry = 1; |
1818 | if (cmdiocb->retry > 100) | 1854 | if (cmdiocb->retry > 100) |
1819 | delay = 100; | 1855 | delay = 100; |
@@ -1842,6 +1878,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1842 | 1878 | ||
1843 | case IOSTAT_NPORT_BSY: | 1879 | case IOSTAT_NPORT_BSY: |
1844 | case IOSTAT_FABRIC_BSY: | 1880 | case IOSTAT_FABRIC_BSY: |
1881 | logerr = 1; /* Fabric / Remote NPort out of resources */ | ||
1845 | retry = 1; | 1882 | retry = 1; |
1846 | break; | 1883 | break; |
1847 | 1884 | ||
@@ -1922,6 +1959,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1922 | if (did == FDMI_DID) | 1959 | if (did == FDMI_DID) |
1923 | retry = 1; | 1960 | retry = 1; |
1924 | 1961 | ||
1962 | if ((cmd == ELS_CMD_FLOGI) && | ||
1963 | (phba->fc_topology != TOPOLOGY_LOOP)) { | ||
1964 | /* FLOGI retry policy */ | ||
1965 | retry = 1; | ||
1966 | maxretry = 48; | ||
1967 | if (cmdiocb->retry >= 32) | ||
1968 | delay = 1000; | ||
1969 | } | ||
1970 | |||
1925 | if ((++cmdiocb->retry) >= maxretry) { | 1971 | if ((++cmdiocb->retry) >= maxretry) { |
1926 | phba->fc_stat.elsRetryExceeded++; | 1972 | phba->fc_stat.elsRetryExceeded++; |
1927 | retry = 0; | 1973 | retry = 0; |
@@ -2005,11 +2051,20 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2005 | } | 2051 | } |
2006 | } | 2052 | } |
2007 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ | 2053 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ |
2008 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 2054 | if (logerr) { |
2055 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
2056 | "0137 No retry ELS command x%x to remote " | ||
2057 | "NPORT x%x: Out of Resources: Error:x%x/%x\n", | ||
2058 | cmd, did, irsp->ulpStatus, | ||
2059 | irsp->un.ulpWord[4]); | ||
2060 | } | ||
2061 | else { | ||
2062 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | ||
2009 | "0108 No retry ELS command x%x to remote " | 2063 | "0108 No retry ELS command x%x to remote " |
2010 | "NPORT x%x Retried:%d Error:x%x/%x\n", | 2064 | "NPORT x%x Retried:%d Error:x%x/%x\n", |
2011 | cmd, did, cmdiocb->retry, irsp->ulpStatus, | 2065 | cmd, did, cmdiocb->retry, irsp->ulpStatus, |
2012 | irsp->un.ulpWord[4]); | 2066 | irsp->un.ulpWord[4]); |
2067 | } | ||
2013 | return 0; | 2068 | return 0; |
2014 | } | 2069 | } |
2015 | 2070 | ||
@@ -2089,6 +2144,12 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2089 | kfree(mp); | 2144 | kfree(mp); |
2090 | mempool_free(pmb, phba->mbox_mem_pool); | 2145 | mempool_free(pmb, phba->mbox_mem_pool); |
2091 | lpfc_nlp_put(ndlp); | 2146 | lpfc_nlp_put(ndlp); |
2147 | |||
2148 | /* This is the end of the default RPI cleanup logic for this | ||
2149 | * ndlp. If no other discovery threads are using this ndlp. | ||
2150 | * we should free all resources associated with it. | ||
2151 | */ | ||
2152 | lpfc_nlp_not_used(ndlp); | ||
2092 | return; | 2153 | return; |
2093 | } | 2154 | } |
2094 | 2155 | ||
@@ -2118,6 +2179,9 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2118 | } | 2179 | } |
2119 | mempool_free(mbox, phba->mbox_mem_pool); | 2180 | mempool_free(mbox, phba->mbox_mem_pool); |
2120 | } | 2181 | } |
2182 | if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | ||
2183 | if (lpfc_nlp_not_used(ndlp)) | ||
2184 | ndlp = NULL; | ||
2121 | goto out; | 2185 | goto out; |
2122 | } | 2186 | } |
2123 | 2187 | ||
@@ -2153,15 +2217,22 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2153 | != MBX_NOT_FINISHED) { | 2217 | != MBX_NOT_FINISHED) { |
2154 | goto out; | 2218 | goto out; |
2155 | } | 2219 | } |
2156 | lpfc_nlp_put(ndlp); | 2220 | |
2157 | /* NOTE: we should have messages for unsuccessful | 2221 | /* ELS rsp: Cannot issue reg_login for <NPortid> */ |
2158 | reglogin */ | 2222 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
2223 | "0138 ELS rsp: Cannot issue reg_login for x%x " | ||
2224 | "Data: x%x x%x x%x\n", | ||
2225 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, | ||
2226 | ndlp->nlp_rpi); | ||
2227 | |||
2228 | if (lpfc_nlp_not_used(ndlp)) | ||
2229 | ndlp = NULL; | ||
2159 | } else { | 2230 | } else { |
2160 | /* Do not drop node for lpfc_els_abort'ed ELS cmds */ | 2231 | /* Do not drop node for lpfc_els_abort'ed ELS cmds */ |
2161 | if (!lpfc_error_lost_link(irsp) && | 2232 | if (!lpfc_error_lost_link(irsp) && |
2162 | ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 2233 | ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
2163 | lpfc_drop_node(vport, ndlp); | 2234 | if (lpfc_nlp_not_used(ndlp)) |
2164 | ndlp = NULL; | 2235 | ndlp = NULL; |
2165 | } | 2236 | } |
2166 | } | 2237 | } |
2167 | mp = (struct lpfc_dmabuf *) mbox->context1; | 2238 | mp = (struct lpfc_dmabuf *) mbox->context1; |
@@ -2350,10 +2421,14 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
2350 | /* If the node is in the UNUSED state, and we are sending | 2421 | /* If the node is in the UNUSED state, and we are sending |
2351 | * a reject, we are done with it. Release driver reference | 2422 | * a reject, we are done with it. Release driver reference |
2352 | * count here. The outstanding els will release its reference on | 2423 | * count here. The outstanding els will release its reference on |
2353 | * completion and the node can be freed then. | 2424 | * completion, as long as the ndlp stays in the UNUSED list, |
2425 | * and the node can be freed then. | ||
2354 | */ | 2426 | */ |
2355 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 2427 | if ((ndlp->nlp_state == NLP_STE_UNUSED_NODE) && |
2428 | !(ndlp->nlp_flag & NLP_DELAYED_RM)) { | ||
2429 | ndlp->nlp_flag |= NLP_DELAYED_RM; | ||
2356 | lpfc_nlp_put(ndlp); | 2430 | lpfc_nlp_put(ndlp); |
2431 | } | ||
2357 | 2432 | ||
2358 | if (rc == IOCB_ERROR) { | 2433 | if (rc == IOCB_ERROR) { |
2359 | lpfc_els_free_iocb(phba, elsiocb); | 2434 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -3466,8 +3541,6 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3466 | } | 3541 | } |
3467 | } | 3542 | } |
3468 | 3543 | ||
3469 | vport->port_state = LPFC_FLOGI; | ||
3470 | lpfc_set_disctmo(vport); | ||
3471 | lpfc_initial_flogi(vport); | 3544 | lpfc_initial_flogi(vport); |
3472 | return 0; | 3545 | return 0; |
3473 | } | 3546 | } |
@@ -3747,11 +3820,11 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3747 | goto dropit; | 3820 | goto dropit; |
3748 | 3821 | ||
3749 | lpfc_nlp_init(vport, ndlp, did); | 3822 | lpfc_nlp_init(vport, ndlp, did); |
3823 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | ||
3750 | newnode = 1; | 3824 | newnode = 1; |
3751 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 3825 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { |
3752 | ndlp->nlp_type |= NLP_FABRIC; | 3826 | ndlp->nlp_type |= NLP_FABRIC; |
3753 | } | 3827 | } |
3754 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
3755 | } | 3828 | } |
3756 | 3829 | ||
3757 | phba->fc_stat.elsRcvFrame++; | 3830 | phba->fc_stat.elsRcvFrame++; |
@@ -3791,8 +3864,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3791 | 3864 | ||
3792 | phba->fc_stat.elsRcvFLOGI++; | 3865 | phba->fc_stat.elsRcvFLOGI++; |
3793 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp); | 3866 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp); |
3794 | if (newnode) | 3867 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3795 | lpfc_drop_node(vport, ndlp); | 3868 | lpfc_nlp_put(ndlp); |
3796 | break; | 3869 | break; |
3797 | case ELS_CMD_LOGO: | 3870 | case ELS_CMD_LOGO: |
3798 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3871 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3821,8 +3894,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3821 | case ELS_CMD_RSCN: | 3894 | case ELS_CMD_RSCN: |
3822 | phba->fc_stat.elsRcvRSCN++; | 3895 | phba->fc_stat.elsRcvRSCN++; |
3823 | lpfc_els_rcv_rscn(vport, elsiocb, ndlp); | 3896 | lpfc_els_rcv_rscn(vport, elsiocb, ndlp); |
3824 | if (newnode) | 3897 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3825 | lpfc_drop_node(vport, ndlp); | 3898 | lpfc_nlp_put(ndlp); |
3826 | break; | 3899 | break; |
3827 | case ELS_CMD_ADISC: | 3900 | case ELS_CMD_ADISC: |
3828 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3901 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3893,8 +3966,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3893 | 3966 | ||
3894 | phba->fc_stat.elsRcvLIRR++; | 3967 | phba->fc_stat.elsRcvLIRR++; |
3895 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); | 3968 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); |
3896 | if (newnode) | 3969 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3897 | lpfc_drop_node(vport, ndlp); | 3970 | lpfc_nlp_put(ndlp); |
3898 | break; | 3971 | break; |
3899 | case ELS_CMD_RPS: | 3972 | case ELS_CMD_RPS: |
3900 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3973 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3903,8 +3976,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3903 | 3976 | ||
3904 | phba->fc_stat.elsRcvRPS++; | 3977 | phba->fc_stat.elsRcvRPS++; |
3905 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); | 3978 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); |
3906 | if (newnode) | 3979 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3907 | lpfc_drop_node(vport, ndlp); | 3980 | lpfc_nlp_put(ndlp); |
3908 | break; | 3981 | break; |
3909 | case ELS_CMD_RPL: | 3982 | case ELS_CMD_RPL: |
3910 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3983 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3913,8 +3986,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3913 | 3986 | ||
3914 | phba->fc_stat.elsRcvRPL++; | 3987 | phba->fc_stat.elsRcvRPL++; |
3915 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); | 3988 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); |
3916 | if (newnode) | 3989 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3917 | lpfc_drop_node(vport, ndlp); | 3990 | lpfc_nlp_put(ndlp); |
3918 | break; | 3991 | break; |
3919 | case ELS_CMD_RNID: | 3992 | case ELS_CMD_RNID: |
3920 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3993 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3923,8 +3996,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3923 | 3996 | ||
3924 | phba->fc_stat.elsRcvRNID++; | 3997 | phba->fc_stat.elsRcvRNID++; |
3925 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); | 3998 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); |
3926 | if (newnode) | 3999 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3927 | lpfc_drop_node(vport, ndlp); | 4000 | lpfc_nlp_put(ndlp); |
3928 | break; | 4001 | break; |
3929 | default: | 4002 | default: |
3930 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4003 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3938,8 +4011,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3938 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 4011 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
3939 | "0115 Unknown ELS command x%x " | 4012 | "0115 Unknown ELS command x%x " |
3940 | "received from NPORT x%x\n", cmd, did); | 4013 | "received from NPORT x%x\n", cmd, did); |
3941 | if (newnode) | 4014 | if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) |
3942 | lpfc_drop_node(vport, ndlp); | 4015 | lpfc_nlp_put(ndlp); |
3943 | break; | 4016 | break; |
3944 | } | 4017 | } |
3945 | 4018 | ||
@@ -3955,10 +4028,11 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3955 | return; | 4028 | return; |
3956 | 4029 | ||
3957 | dropit: | 4030 | dropit: |
3958 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 4031 | if (vport && !(vport->load_flag & FC_UNLOADING)) |
4032 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
3959 | "(%d):0111 Dropping received ELS cmd " | 4033 | "(%d):0111 Dropping received ELS cmd " |
3960 | "Data: x%x x%x x%x\n", | 4034 | "Data: x%x x%x x%x\n", |
3961 | vport ? vport->vpi : 0xffff, icmd->ulpStatus, | 4035 | vport->vpi, icmd->ulpStatus, |
3962 | icmd->un.ulpWord[4], icmd->ulpTimeout); | 4036 | icmd->un.ulpWord[4], icmd->ulpTimeout); |
3963 | phba->fc_stat.elsRcvDrop++; | 4037 | phba->fc_stat.elsRcvDrop++; |
3964 | } | 4038 | } |