aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c104
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,
1473static int 1473static int
1474lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1474lpfc_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)
1951static void 1952static void
1952lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1953lpfc_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 */
2356struct lpfc_nodelist * 2336struct lpfc_nodelist *
2357lpfc_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
2355struct lpfc_nodelist *
2356lpfc_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