diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 104 |
1 files changed, 46 insertions, 58 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 92c0c4b88953..2c21641265b5 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1473,6 +1473,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, | |||
1473 | static int | 1473 | static int |
1474 | lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1474 | lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) |
1475 | { | 1475 | { |
1476 | LIST_HEAD(completions); | ||
1476 | struct lpfc_sli *psli; | 1477 | struct lpfc_sli *psli; |
1477 | struct lpfc_sli_ring *pring; | 1478 | struct lpfc_sli_ring *pring; |
1478 | struct lpfc_iocbq *iocb, *next_iocb; | 1479 | struct lpfc_iocbq *iocb, *next_iocb; |
@@ -1501,29 +1502,29 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1501 | (phba, pring, iocb, ndlp))) { | 1502 | (phba, pring, iocb, ndlp))) { |
1502 | /* It matches, so deque and call compl | 1503 | /* It matches, so deque and call compl |
1503 | with an error */ | 1504 | with an error */ |
1504 | list_del(&iocb->list); | 1505 | list_move_tail(&iocb->list, |
1506 | &completions); | ||
1505 | pring->txq_cnt--; | 1507 | pring->txq_cnt--; |
1506 | if (iocb->iocb_cmpl) { | ||
1507 | icmd = &iocb->iocb; | ||
1508 | icmd->ulpStatus = | ||
1509 | IOSTAT_LOCAL_REJECT; | ||
1510 | icmd->un.ulpWord[4] = | ||
1511 | IOERR_SLI_ABORTED; | ||
1512 | spin_unlock_irq(phba->host-> | ||
1513 | host_lock); | ||
1514 | (iocb->iocb_cmpl) (phba, | ||
1515 | iocb, iocb); | ||
1516 | spin_lock_irq(phba->host-> | ||
1517 | host_lock); | ||
1518 | } else | ||
1519 | lpfc_sli_release_iocbq(phba, | ||
1520 | iocb); | ||
1521 | } | 1508 | } |
1522 | } | 1509 | } |
1523 | spin_unlock_irq(phba->host->host_lock); | 1510 | spin_unlock_irq(phba->host->host_lock); |
1524 | 1511 | ||
1525 | } | 1512 | } |
1526 | } | 1513 | } |
1514 | |||
1515 | while (!list_empty(&completions)) { | ||
1516 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | ||
1517 | list_del(&iocb->list); | ||
1518 | |||
1519 | if (iocb->iocb_cmpl) { | ||
1520 | icmd = &iocb->iocb; | ||
1521 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
1522 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
1523 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
1524 | } else | ||
1525 | lpfc_sli_release_iocbq(phba, iocb); | ||
1526 | } | ||
1527 | |||
1527 | return 0; | 1528 | return 0; |
1528 | } | 1529 | } |
1529 | 1530 | ||
@@ -1951,11 +1952,11 @@ lpfc_disc_start(struct lpfc_hba * phba) | |||
1951 | static void | 1952 | static void |
1952 | lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1953 | lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) |
1953 | { | 1954 | { |
1955 | LIST_HEAD(completions); | ||
1954 | struct lpfc_sli *psli; | 1956 | struct lpfc_sli *psli; |
1955 | IOCB_t *icmd; | 1957 | IOCB_t *icmd; |
1956 | struct lpfc_iocbq *iocb, *next_iocb; | 1958 | struct lpfc_iocbq *iocb, *next_iocb; |
1957 | struct lpfc_sli_ring *pring; | 1959 | struct lpfc_sli_ring *pring; |
1958 | struct lpfc_dmabuf *mp; | ||
1959 | 1960 | ||
1960 | psli = &phba->sli; | 1961 | psli = &phba->sli; |
1961 | pring = &psli->ring[LPFC_ELS_RING]; | 1962 | pring = &psli->ring[LPFC_ELS_RING]; |
@@ -1963,6 +1964,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1963 | /* Error matching iocb on txq or txcmplq | 1964 | /* Error matching iocb on txq or txcmplq |
1964 | * First check the txq. | 1965 | * First check the txq. |
1965 | */ | 1966 | */ |
1967 | spin_lock_irq(phba->host->host_lock); | ||
1966 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 1968 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { |
1967 | if (iocb->context1 != ndlp) { | 1969 | if (iocb->context1 != ndlp) { |
1968 | continue; | 1970 | continue; |
@@ -1971,9 +1973,8 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1971 | if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || | 1973 | if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || |
1972 | (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { | 1974 | (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { |
1973 | 1975 | ||
1974 | list_del(&iocb->list); | 1976 | list_move_tail(&iocb->list, &completions); |
1975 | pring->txq_cnt--; | 1977 | pring->txq_cnt--; |
1976 | lpfc_els_free_iocb(phba, iocb); | ||
1977 | } | 1978 | } |
1978 | } | 1979 | } |
1979 | 1980 | ||
@@ -1985,43 +1986,22 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1985 | icmd = &iocb->iocb; | 1986 | icmd = &iocb->iocb; |
1986 | if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || | 1987 | if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || |
1987 | (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { | 1988 | (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { |
1989 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | ||
1990 | } | ||
1991 | } | ||
1992 | spin_unlock_irq(phba->host->host_lock); | ||
1988 | 1993 | ||
1989 | iocb->iocb_cmpl = NULL; | 1994 | while (!list_empty(&completions)) { |
1990 | /* context2 = cmd, context2->next = rsp, context3 = | 1995 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1991 | bpl */ | 1996 | list_del(&iocb->list); |
1992 | if (iocb->context2) { | ||
1993 | /* Free the response IOCB before handling the | ||
1994 | command. */ | ||
1995 | |||
1996 | mp = (struct lpfc_dmabuf *) (iocb->context2); | ||
1997 | mp = list_get_first(&mp->list, | ||
1998 | struct lpfc_dmabuf, | ||
1999 | list); | ||
2000 | if (mp) { | ||
2001 | /* Delay before releasing rsp buffer to | ||
2002 | * give UNREG mbox a chance to take | ||
2003 | * effect. | ||
2004 | */ | ||
2005 | list_add(&mp->list, | ||
2006 | &phba->freebufList); | ||
2007 | } | ||
2008 | lpfc_mbuf_free(phba, | ||
2009 | ((struct lpfc_dmabuf *) | ||
2010 | iocb->context2)->virt, | ||
2011 | ((struct lpfc_dmabuf *) | ||
2012 | iocb->context2)->phys); | ||
2013 | kfree(iocb->context2); | ||
2014 | } | ||
2015 | 1997 | ||
2016 | if (iocb->context3) { | 1998 | if (iocb->iocb_cmpl) { |
2017 | lpfc_mbuf_free(phba, | 1999 | icmd = &iocb->iocb; |
2018 | ((struct lpfc_dmabuf *) | 2000 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
2019 | iocb->context3)->virt, | 2001 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
2020 | ((struct lpfc_dmabuf *) | 2002 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
2021 | iocb->context3)->phys); | 2003 | } else |
2022 | kfree(iocb->context3); | 2004 | lpfc_sli_release_iocbq(phba, iocb); |
2023 | } | ||
2024 | } | ||
2025 | } | 2005 | } |
2026 | 2006 | ||
2027 | return; | 2007 | return; |
@@ -2354,7 +2334,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2354 | * else return NULL. | 2334 | * else return NULL. |
2355 | */ | 2335 | */ |
2356 | struct lpfc_nodelist * | 2336 | struct lpfc_nodelist * |
2357 | lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | 2337 | __lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) |
2358 | { | 2338 | { |
2359 | struct lpfc_nodelist *ndlp; | 2339 | struct lpfc_nodelist *ndlp; |
2360 | struct list_head * lists[]={&phba->fc_nlpunmap_list, | 2340 | struct list_head * lists[]={&phba->fc_nlpunmap_list, |
@@ -2364,17 +2344,25 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | |||
2364 | &phba->fc_reglogin_list}; | 2344 | &phba->fc_reglogin_list}; |
2365 | int i; | 2345 | int i; |
2366 | 2346 | ||
2367 | spin_lock_irq(phba->host->host_lock); | ||
2368 | for (i = 0; i < ARRAY_SIZE(lists); i++ ) | 2347 | for (i = 0; i < ARRAY_SIZE(lists); i++ ) |
2369 | list_for_each_entry(ndlp, lists[i], nlp_listp) | 2348 | list_for_each_entry(ndlp, lists[i], nlp_listp) |
2370 | if (ndlp->nlp_rpi == rpi) { | 2349 | if (ndlp->nlp_rpi == rpi) { |
2371 | spin_unlock_irq(phba->host->host_lock); | ||
2372 | return ndlp; | 2350 | return ndlp; |
2373 | } | 2351 | } |
2374 | spin_unlock_irq(phba->host->host_lock); | ||
2375 | return NULL; | 2352 | return NULL; |
2376 | } | 2353 | } |
2377 | 2354 | ||
2355 | struct lpfc_nodelist * | ||
2356 | lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | ||
2357 | { | ||
2358 | struct lpfc_nodelist *ndlp; | ||
2359 | |||
2360 | spin_lock_irq(phba->host->host_lock); | ||
2361 | ndlp = __lpfc_findnode_rpi(phba, rpi); | ||
2362 | spin_unlock_irq(phba->host->host_lock); | ||
2363 | return ndlp; | ||
2364 | } | ||
2365 | |||
2378 | /* | 2366 | /* |
2379 | * This routine looks up the ndlp lists | 2367 | * This routine looks up the ndlp lists |
2380 | * for the given WWPN. If WWPN found | 2368 | * for the given WWPN. If WWPN found |