diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:53:01 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 10:33:15 -0400 |
commit | 329f9bc735b4665d42267259b1612191f72c4d42 (patch) | |
tree | b696a632e19afa0d0e42012efd7992690f69e1a1 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 2680eeaaa03e83a87ece2724e71f7cc816cd3ef0 (diff) |
[SCSI] lpfc 8.1.12 : Reference count node structures for node lifetime management
Reference count node structures for node lifetime management.
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 | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 14d204ba8a39..cb63c350c215 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -209,9 +209,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | /* Save for completion so we can release these resources */ | 211 | /* Save for completion so we can release these resources */ |
212 | elsiocb->context1 = (uint8_t *) ndlp; | 212 | elsiocb->context1 = lpfc_nlp_get(ndlp); |
213 | elsiocb->context2 = (uint8_t *) pcmd; | 213 | elsiocb->context2 = pcmd; |
214 | elsiocb->context3 = (uint8_t *) pbuflist; | 214 | elsiocb->context3 = pbuflist; |
215 | elsiocb->retry = retry; | 215 | elsiocb->retry = retry; |
216 | elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; | 216 | elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; |
217 | 217 | ||
@@ -305,7 +305,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
305 | goto fail_free_mbox; | 305 | goto fail_free_mbox; |
306 | 306 | ||
307 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; | 307 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; |
308 | mbox->context2 = ndlp; | 308 | mbox->context2 = lpfc_nlp_get(ndlp); |
309 | 309 | ||
310 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); | 310 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); |
311 | if (rc == MBX_NOT_FINISHED) | 311 | if (rc == MBX_NOT_FINISHED) |
@@ -314,6 +314,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
314 | return 0; | 314 | return 0; |
315 | 315 | ||
316 | fail_issue_reg_login: | 316 | fail_issue_reg_login: |
317 | lpfc_nlp_put(ndlp); | ||
317 | mp = (struct lpfc_dmabuf *) mbox->context1; | 318 | mp = (struct lpfc_dmabuf *) mbox->context1; |
318 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 319 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
319 | kfree(mp); | 320 | kfree(mp); |
@@ -369,7 +370,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
369 | mempool_free(mbox, phba->mbox_mem_pool); | 370 | mempool_free(mbox, phba->mbox_mem_pool); |
370 | goto fail; | 371 | goto fail; |
371 | } | 372 | } |
372 | mempool_free(ndlp, phba->nlp_mem_pool); | 373 | lpfc_nlp_put(ndlp); |
373 | 374 | ||
374 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); | 375 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); |
375 | if (!ndlp) { | 376 | if (!ndlp) { |
@@ -392,7 +393,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
392 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 393 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
393 | } else { | 394 | } else { |
394 | /* This side will wait for the PLOGI */ | 395 | /* This side will wait for the PLOGI */ |
395 | mempool_free( ndlp, phba->nlp_mem_pool); | 396 | lpfc_nlp_put(ndlp); |
396 | } | 397 | } |
397 | 398 | ||
398 | spin_lock_irq(phba->host->host_lock); | 399 | spin_lock_irq(phba->host->host_lock); |
@@ -407,8 +408,8 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
407 | } | 408 | } |
408 | 409 | ||
409 | static void | 410 | static void |
410 | lpfc_cmpl_els_flogi(struct lpfc_hba * phba, | 411 | lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
411 | struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) | 412 | struct lpfc_iocbq *rspiocb) |
412 | { | 413 | { |
413 | IOCB_t *irsp = &rspiocb->iocb; | 414 | IOCB_t *irsp = &rspiocb->iocb; |
414 | struct lpfc_nodelist *ndlp = cmdiocb->context1; | 415 | struct lpfc_nodelist *ndlp = cmdiocb->context1; |
@@ -418,7 +419,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, | |||
418 | 419 | ||
419 | /* Check to see if link went down during discovery */ | 420 | /* Check to see if link went down during discovery */ |
420 | if (lpfc_els_chk_latt(phba)) { | 421 | if (lpfc_els_chk_latt(phba)) { |
421 | lpfc_nlp_remove(phba, ndlp); | 422 | lpfc_nlp_put(ndlp); |
422 | goto out; | 423 | goto out; |
423 | } | 424 | } |
424 | 425 | ||
@@ -433,13 +434,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, | |||
433 | phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | 434 | phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); |
434 | spin_unlock_irq(phba->host->host_lock); | 435 | spin_unlock_irq(phba->host->host_lock); |
435 | 436 | ||
436 | /* If private loop, then allow max outstandting els to be | 437 | /* If private loop, then allow max outstanding els to be |
437 | * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no | 438 | * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no |
438 | * alpa map would take too long otherwise. | 439 | * alpa map would take too long otherwise. |
439 | */ | 440 | */ |
440 | if (phba->alpa_map[0] == 0) { | 441 | if (phba->alpa_map[0] == 0) { |
441 | phba->cfg_discovery_threads = | 442 | phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; |
442 | LPFC_MAX_DISC_THREADS; | ||
443 | } | 443 | } |
444 | 444 | ||
445 | /* FLOGI failure */ | 445 | /* FLOGI failure */ |
@@ -484,7 +484,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, | |||
484 | } | 484 | } |
485 | 485 | ||
486 | flogifail: | 486 | flogifail: |
487 | lpfc_nlp_remove(phba, ndlp); | 487 | lpfc_nlp_put(ndlp); |
488 | 488 | ||
489 | if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || | 489 | if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || |
490 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && | 490 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && |
@@ -608,7 +608,7 @@ lpfc_initial_flogi(struct lpfc_hba * phba) | |||
608 | lpfc_dequeue_node(phba, ndlp); | 608 | lpfc_dequeue_node(phba, ndlp); |
609 | } | 609 | } |
610 | if (lpfc_issue_els_flogi(phba, ndlp, 0)) { | 610 | if (lpfc_issue_els_flogi(phba, ndlp, 0)) { |
611 | mempool_free( ndlp, phba->nlp_mem_pool); | 611 | lpfc_nlp_put(ndlp); |
612 | } | 612 | } |
613 | return 1; | 613 | return 1; |
614 | } | 614 | } |
@@ -1334,7 +1334,7 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1334 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 1334 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1335 | ndlp->nlp_DID, ELS_CMD_SCR); | 1335 | ndlp->nlp_DID, ELS_CMD_SCR); |
1336 | if (!elsiocb) { | 1336 | if (!elsiocb) { |
1337 | mempool_free( ndlp, phba->nlp_mem_pool); | 1337 | lpfc_nlp_put(ndlp); |
1338 | return 1; | 1338 | return 1; |
1339 | } | 1339 | } |
1340 | 1340 | ||
@@ -1353,12 +1353,12 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1353 | spin_lock_irq(phba->host->host_lock); | 1353 | spin_lock_irq(phba->host->host_lock); |
1354 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1354 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1355 | spin_unlock_irq(phba->host->host_lock); | 1355 | spin_unlock_irq(phba->host->host_lock); |
1356 | mempool_free( ndlp, phba->nlp_mem_pool); | 1356 | lpfc_nlp_put(ndlp); |
1357 | lpfc_els_free_iocb(phba, elsiocb); | 1357 | lpfc_els_free_iocb(phba, elsiocb); |
1358 | return 1; | 1358 | return 1; |
1359 | } | 1359 | } |
1360 | spin_unlock_irq(phba->host->host_lock); | 1360 | spin_unlock_irq(phba->host->host_lock); |
1361 | mempool_free( ndlp, phba->nlp_mem_pool); | 1361 | lpfc_nlp_put(ndlp); |
1362 | return 0; | 1362 | return 0; |
1363 | } | 1363 | } |
1364 | 1364 | ||
@@ -1387,7 +1387,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1387 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 1387 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1388 | ndlp->nlp_DID, ELS_CMD_RNID); | 1388 | ndlp->nlp_DID, ELS_CMD_RNID); |
1389 | if (!elsiocb) { | 1389 | if (!elsiocb) { |
1390 | mempool_free( ndlp, phba->nlp_mem_pool); | 1390 | lpfc_nlp_put(ndlp); |
1391 | return 1; | 1391 | return 1; |
1392 | } | 1392 | } |
1393 | 1393 | ||
@@ -1420,12 +1420,12 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1420 | spin_lock_irq(phba->host->host_lock); | 1420 | spin_lock_irq(phba->host->host_lock); |
1421 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1421 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1422 | spin_unlock_irq(phba->host->host_lock); | 1422 | spin_unlock_irq(phba->host->host_lock); |
1423 | mempool_free( ndlp, phba->nlp_mem_pool); | 1423 | lpfc_nlp_put(ndlp); |
1424 | lpfc_els_free_iocb(phba, elsiocb); | 1424 | lpfc_els_free_iocb(phba, elsiocb); |
1425 | return 1; | 1425 | return 1; |
1426 | } | 1426 | } |
1427 | spin_unlock_irq(phba->host->host_lock); | 1427 | spin_unlock_irq(phba->host->host_lock); |
1428 | mempool_free( ndlp, phba->nlp_mem_pool); | 1428 | lpfc_nlp_put(ndlp); |
1429 | return 0; | 1429 | return 0; |
1430 | } | 1430 | } |
1431 | 1431 | ||
@@ -1590,7 +1590,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1590 | cmd = *elscmd++; | 1590 | cmd = *elscmd++; |
1591 | } | 1591 | } |
1592 | 1592 | ||
1593 | if(ndlp) | 1593 | if (ndlp) |
1594 | did = ndlp->nlp_DID; | 1594 | did = ndlp->nlp_DID; |
1595 | else { | 1595 | else { |
1596 | /* We should only hit this case for retrying PLOGI */ | 1596 | /* We should only hit this case for retrying PLOGI */ |
@@ -1768,10 +1768,14 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1768 | } | 1768 | } |
1769 | 1769 | ||
1770 | int | 1770 | int |
1771 | lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb) | 1771 | lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) |
1772 | { | 1772 | { |
1773 | struct lpfc_dmabuf *buf_ptr, *buf_ptr1; | 1773 | struct lpfc_dmabuf *buf_ptr, *buf_ptr1; |
1774 | 1774 | ||
1775 | if (elsiocb->context1) { | ||
1776 | lpfc_nlp_put(elsiocb->context1); | ||
1777 | elsiocb->context1 = NULL; | ||
1778 | } | ||
1775 | /* context2 = cmd, context2->next = rsp, context3 = bpl */ | 1779 | /* context2 = cmd, context2->next = rsp, context3 = bpl */ |
1776 | if (elsiocb->context2) { | 1780 | if (elsiocb->context2) { |
1777 | buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; | 1781 | buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; |
@@ -1828,8 +1832,8 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1828 | } | 1832 | } |
1829 | 1833 | ||
1830 | static void | 1834 | static void |
1831 | lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1835 | lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1832 | struct lpfc_iocbq * rspiocb) | 1836 | struct lpfc_iocbq *rspiocb) |
1833 | { | 1837 | { |
1834 | IOCB_t *irsp; | 1838 | IOCB_t *irsp; |
1835 | struct lpfc_nodelist *ndlp; | 1839 | struct lpfc_nodelist *ndlp; |
@@ -1844,14 +1848,14 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1844 | 1848 | ||
1845 | 1849 | ||
1846 | /* Check to see if link went down during discovery */ | 1850 | /* Check to see if link went down during discovery */ |
1847 | if ((lpfc_els_chk_latt(phba)) || !ndlp) { | 1851 | if (lpfc_els_chk_latt(phba) || !ndlp) { |
1848 | if (mbox) { | 1852 | if (mbox) { |
1849 | mp = (struct lpfc_dmabuf *) mbox->context1; | 1853 | mp = (struct lpfc_dmabuf *) mbox->context1; |
1850 | if (mp) { | 1854 | if (mp) { |
1851 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1855 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1852 | kfree(mp); | 1856 | kfree(mp); |
1853 | } | 1857 | } |
1854 | mempool_free( mbox, phba->mbox_mem_pool); | 1858 | mempool_free(mbox, phba->mbox_mem_pool); |
1855 | } | 1859 | } |
1856 | goto out; | 1860 | goto out; |
1857 | } | 1861 | } |
@@ -1871,7 +1875,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1871 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { | 1875 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { |
1872 | lpfc_unreg_rpi(phba, ndlp); | 1876 | lpfc_unreg_rpi(phba, ndlp); |
1873 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 1877 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
1874 | mbox->context2 = ndlp; | 1878 | mbox->context2 = lpfc_nlp_get(ndlp); |
1875 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1879 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1876 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 1880 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); |
1877 | if (lpfc_sli_issue_mbox(phba, mbox, | 1881 | if (lpfc_sli_issue_mbox(phba, mbox, |
@@ -1879,6 +1883,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1879 | != MBX_NOT_FINISHED) { | 1883 | != MBX_NOT_FINISHED) { |
1880 | goto out; | 1884 | goto out; |
1881 | } | 1885 | } |
1886 | lpfc_nlp_put(ndlp); | ||
1882 | /* NOTE: we should have messages for unsuccessful | 1887 | /* NOTE: we should have messages for unsuccessful |
1883 | reglogin */ | 1888 | reglogin */ |
1884 | } else { | 1889 | } else { |
@@ -1983,8 +1988,10 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1983 | return 1; | 1988 | return 1; |
1984 | } | 1989 | } |
1985 | 1990 | ||
1986 | if (newnode) | 1991 | if (newnode) { |
1992 | lpfc_nlp_put(ndlp); | ||
1987 | elsiocb->context1 = NULL; | 1993 | elsiocb->context1 = NULL; |
1994 | } | ||
1988 | 1995 | ||
1989 | /* Xmit ELS ACC response tag <ulpIoTag> */ | 1996 | /* Xmit ELS ACC response tag <ulpIoTag> */ |
1990 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1997 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2201,9 +2208,8 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, | |||
2201 | } | 2208 | } |
2202 | 2209 | ||
2203 | static int | 2210 | static int |
2204 | lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, | 2211 | lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, |
2205 | uint8_t format, | 2212 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) |
2206 | struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) | ||
2207 | { | 2213 | { |
2208 | RNID *rn; | 2214 | RNID *rn; |
2209 | IOCB_t *icmd; | 2215 | IOCB_t *icmd; |
@@ -2270,6 +2276,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, | |||
2270 | 2276 | ||
2271 | phba->fc_stat.elsXmitACC++; | 2277 | phba->fc_stat.elsXmitACC++; |
2272 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2278 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
2279 | lpfc_nlp_put(ndlp); | ||
2273 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, | 2280 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, |
2274 | * it could be freed */ | 2281 | * it could be freed */ |
2275 | 2282 | ||
@@ -2447,7 +2454,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) | |||
2447 | } | 2454 | } |
2448 | 2455 | ||
2449 | static int | 2456 | static int |
2450 | lpfc_rscn_recovery_check(struct lpfc_hba * phba) | 2457 | lpfc_rscn_recovery_check(struct lpfc_hba *phba) |
2451 | { | 2458 | { |
2452 | struct lpfc_nodelist *ndlp = NULL, *next_ndlp; | 2459 | struct lpfc_nodelist *ndlp = NULL, *next_ndlp; |
2453 | struct list_head *listp; | 2460 | struct list_head *listp; |
@@ -2703,7 +2710,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2703 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); | 2710 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); |
2704 | lpfc_set_loopback_flag(phba); | 2711 | lpfc_set_loopback_flag(phba); |
2705 | if (rc == MBX_NOT_FINISHED) { | 2712 | if (rc == MBX_NOT_FINISHED) { |
2706 | mempool_free( mbox, phba->mbox_mem_pool); | 2713 | mempool_free(mbox, phba->mbox_mem_pool); |
2707 | } | 2714 | } |
2708 | return 1; | 2715 | return 1; |
2709 | } else if (rc > 0) { /* greater than */ | 2716 | } else if (rc > 0) { /* greater than */ |
@@ -2768,8 +2775,8 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, | |||
2768 | } | 2775 | } |
2769 | 2776 | ||
2770 | static int | 2777 | static int |
2771 | lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2778 | lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
2772 | struct lpfc_nodelist * ndlp) | 2779 | struct lpfc_nodelist *ndlp) |
2773 | { | 2780 | { |
2774 | struct ls_rjt stat; | 2781 | struct ls_rjt stat; |
2775 | 2782 | ||
@@ -2783,7 +2790,7 @@ lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2783 | } | 2790 | } |
2784 | 2791 | ||
2785 | static void | 2792 | static void |
2786 | lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 2793 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
2787 | { | 2794 | { |
2788 | struct lpfc_sli *psli; | 2795 | struct lpfc_sli *psli; |
2789 | struct lpfc_sli_ring *pring; | 2796 | struct lpfc_sli_ring *pring; |
@@ -2806,14 +2813,15 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2806 | pmb->context2 = NULL; | 2813 | pmb->context2 = NULL; |
2807 | 2814 | ||
2808 | if (mb->mbxStatus) { | 2815 | if (mb->mbxStatus) { |
2809 | mempool_free( pmb, phba->mbox_mem_pool); | 2816 | mempool_free(pmb, phba->mbox_mem_pool); |
2810 | return; | 2817 | return; |
2811 | } | 2818 | } |
2812 | 2819 | ||
2813 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); | 2820 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); |
2814 | mempool_free( pmb, phba->mbox_mem_pool); | 2821 | mempool_free(pmb, phba->mbox_mem_pool); |
2815 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, | 2822 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, |
2816 | ndlp->nlp_DID, ELS_CMD_ACC); | 2823 | ndlp->nlp_DID, ELS_CMD_ACC); |
2824 | lpfc_nlp_put(ndlp); | ||
2817 | if (!elsiocb) | 2825 | if (!elsiocb) |
2818 | return; | 2826 | return; |
2819 | 2827 | ||
@@ -2890,13 +2898,14 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2890 | lpfc_read_lnk_stat(phba, mbox); | 2898 | lpfc_read_lnk_stat(phba, mbox); |
2891 | mbox->context1 = | 2899 | mbox->context1 = |
2892 | (void *)((unsigned long)cmdiocb->iocb.ulpContext); | 2900 | (void *)((unsigned long)cmdiocb->iocb.ulpContext); |
2893 | mbox->context2 = ndlp; | 2901 | mbox->context2 = lpfc_nlp_get(ndlp); |
2894 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; | 2902 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; |
2895 | if (lpfc_sli_issue_mbox (phba, mbox, | 2903 | if (lpfc_sli_issue_mbox (phba, mbox, |
2896 | (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { | 2904 | (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { |
2897 | /* Mbox completion will send ELS Response */ | 2905 | /* Mbox completion will send ELS Response */ |
2898 | return 0; | 2906 | return 0; |
2899 | } | 2907 | } |
2908 | lpfc_nlp_put(ndlp); | ||
2900 | mempool_free(mbox, phba->mbox_mem_pool); | 2909 | mempool_free(mbox, phba->mbox_mem_pool); |
2901 | } | 2910 | } |
2902 | } | 2911 | } |
@@ -3281,14 +3290,13 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3281 | } | 3290 | } |
3282 | 3291 | ||
3283 | void | 3292 | void |
3284 | lpfc_els_flush_cmd(struct lpfc_hba * phba) | 3293 | lpfc_els_flush_cmd(struct lpfc_hba *phba) |
3285 | { | 3294 | { |
3286 | LIST_HEAD(completions); | 3295 | LIST_HEAD(completions); |
3287 | struct lpfc_sli_ring *pring; | 3296 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; |
3288 | struct lpfc_iocbq *tmp_iocb, *piocb; | 3297 | struct lpfc_iocbq *tmp_iocb, *piocb; |
3289 | IOCB_t *cmd = NULL; | 3298 | IOCB_t *cmd = NULL; |
3290 | 3299 | ||
3291 | pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
3292 | spin_lock_irq(phba->host->host_lock); | 3300 | spin_lock_irq(phba->host->host_lock); |
3293 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { | 3301 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { |
3294 | cmd = &piocb->iocb; | 3302 | cmd = &piocb->iocb; |
@@ -3298,12 +3306,11 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3298 | } | 3306 | } |
3299 | 3307 | ||
3300 | /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */ | 3308 | /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */ |
3301 | if ((cmd->ulpCommand == CMD_QUE_RING_BUF_CN) || | 3309 | if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN || |
3302 | (cmd->ulpCommand == CMD_QUE_RING_BUF64_CN) || | 3310 | cmd->ulpCommand == CMD_QUE_RING_BUF64_CN || |
3303 | (cmd->ulpCommand == CMD_CLOSE_XRI_CN) || | 3311 | cmd->ulpCommand == CMD_CLOSE_XRI_CN || |
3304 | (cmd->ulpCommand == CMD_ABORT_XRI_CN)) { | 3312 | cmd->ulpCommand == CMD_ABORT_XRI_CN) |
3305 | continue; | 3313 | continue; |
3306 | } | ||
3307 | 3314 | ||
3308 | list_move_tail(&piocb->list, &completions); | 3315 | list_move_tail(&piocb->list, &completions); |
3309 | pring->txq_cnt--; | 3316 | pring->txq_cnt--; |
@@ -3422,7 +3429,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3422 | } | 3429 | } |
3423 | 3430 | ||
3424 | phba->fc_stat.elsRcvFrame++; | 3431 | phba->fc_stat.elsRcvFrame++; |
3425 | elsiocb->context1 = ndlp; | 3432 | if (elsiocb->context1) |
3433 | lpfc_nlp_put(elsiocb->context1); | ||
3434 | elsiocb->context1 = lpfc_nlp_get(ndlp); | ||
3426 | elsiocb->context2 = mp; | 3435 | elsiocb->context2 = mp; |
3427 | 3436 | ||
3428 | if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { | 3437 | if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { |
@@ -3553,6 +3562,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3553 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp); | 3562 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp); |
3554 | } | 3563 | } |
3555 | 3564 | ||
3565 | lpfc_nlp_put(elsiocb->context1); | ||
3566 | elsiocb->context1 = NULL; | ||
3556 | if (elsiocb->context2) { | 3567 | if (elsiocb->context2) { |
3557 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 3568 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
3558 | kfree(mp); | 3569 | kfree(mp); |