aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:52:20 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:14 -0400
commit2534ba756ec407d343af45168273d3a64825a7ba (patch)
treeebefbc11ba342bd93ceac0946d1e4154809e5d92
parent46fa311e6967b526e1fd9b0b44edda6841dcac27 (diff)
[SCSI] lpfc 8.1.12 : Fix unlock inside list traversal
Fix unlock inside list traversal. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c30
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c104
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c57
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c72
5 files changed, 116 insertions, 148 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index bf555d37e8d9..80dcfaa37867 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -57,6 +57,7 @@ void lpfc_disc_start(struct lpfc_hba *);
57void lpfc_disc_flush_list(struct lpfc_hba *); 57void lpfc_disc_flush_list(struct lpfc_hba *);
58void lpfc_disc_timeout(unsigned long); 58void lpfc_disc_timeout(unsigned long);
59 59
60struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
60struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); 61struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
61 62
62int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); 63int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 4a9e61345693..e3bebf9ee832 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -3272,9 +3272,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
3272 3272
3273 if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { 3273 if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
3274 struct lpfc_nodelist *ndlp; 3274 struct lpfc_nodelist *ndlp;
3275 spin_unlock_irq(phba->host->host_lock); 3275 ndlp = __lpfc_findnode_rpi(phba, cmd->ulpContext);
3276 ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
3277 spin_lock_irq(phba->host->host_lock);
3278 remote_ID = ndlp->nlp_DID; 3276 remote_ID = ndlp->nlp_DID;
3279 } else { 3277 } else {
3280 remote_ID = cmd->un.elsreq64.remoteID; 3278 remote_ID = cmd->un.elsreq64.remoteID;
@@ -3298,6 +3296,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
3298void 3296void
3299lpfc_els_flush_cmd(struct lpfc_hba * phba) 3297lpfc_els_flush_cmd(struct lpfc_hba * phba)
3300{ 3298{
3299 LIST_HEAD(completions);
3301 struct lpfc_sli_ring *pring; 3300 struct lpfc_sli_ring *pring;
3302 struct lpfc_iocbq *tmp_iocb, *piocb; 3301 struct lpfc_iocbq *tmp_iocb, *piocb;
3303 IOCB_t *cmd = NULL; 3302 IOCB_t *cmd = NULL;
@@ -3319,18 +3318,9 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
3319 continue; 3318 continue;
3320 } 3319 }
3321 3320
3322 list_del(&piocb->list); 3321 list_move_tail(&piocb->list, &completions);
3323 pring->txq_cnt--; 3322 pring->txq_cnt--;
3324 3323
3325 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
3326 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
3327
3328 if (piocb->iocb_cmpl) {
3329 spin_unlock_irq(phba->host->host_lock);
3330 (piocb->iocb_cmpl) (phba, piocb, piocb);
3331 spin_lock_irq(phba->host->host_lock);
3332 } else
3333 lpfc_sli_release_iocbq(phba, piocb);
3334 } 3324 }
3335 3325
3336 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { 3326 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3343,6 +3333,20 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
3343 lpfc_sli_issue_abort_iotag(phba, pring, piocb); 3333 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
3344 } 3334 }
3345 spin_unlock_irq(phba->host->host_lock); 3335 spin_unlock_irq(phba->host->host_lock);
3336
3337 while(!list_empty(&completions)) {
3338 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
3339 cmd = &piocb->iocb;
3340 list_del(&piocb->list);
3341
3342 if (piocb->iocb_cmpl) {
3343 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
3344 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
3345 (piocb->iocb_cmpl) (phba, piocb, piocb);
3346 } else
3347 lpfc_sli_release_iocbq(phba, piocb);
3348 }
3349
3346 return; 3350 return;
3347} 3351}
3348 3352
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
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index aa7f446c8da1..1c78a71b404d 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -170,11 +170,11 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba,
170int 170int
171lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 171lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
172{ 172{
173 LIST_HEAD(completions);
173 struct lpfc_sli *psli; 174 struct lpfc_sli *psli;
174 struct lpfc_sli_ring *pring; 175 struct lpfc_sli_ring *pring;
175 struct lpfc_iocbq *iocb, *next_iocb; 176 struct lpfc_iocbq *iocb, *next_iocb;
176 IOCB_t *icmd; 177 IOCB_t *cmd;
177 int found = 0;
178 178
179 /* Abort outstanding I/O on NPort <nlp_DID> */ 179 /* Abort outstanding I/O on NPort <nlp_DID> */
180 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, 180 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
@@ -187,45 +187,40 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
187 pring = &psli->ring[LPFC_ELS_RING]; 187 pring = &psli->ring[LPFC_ELS_RING];
188 188
189 /* First check the txq */ 189 /* First check the txq */
190 do { 190 spin_lock_irq(phba->host->host_lock);
191 found = 0; 191 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
192 spin_lock_irq(phba->host->host_lock); 192 /* Check to see if iocb matches the nport we are looking
193 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { 193 for */
194 /* Check to see if iocb matches the nport we are looking 194 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {
195 for */ 195 /* It matches, so deque and call compl with an
196 if ((lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))) { 196 error */
197 found = 1; 197 list_move_tail(&iocb->list, &completions);
198 /* It matches, so deque and call compl with an 198 pring->txq_cnt--;
199 error */
200 list_del(&iocb->list);
201 pring->txq_cnt--;
202 if (iocb->iocb_cmpl) {
203 icmd = &iocb->iocb;
204 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
205 icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
206 spin_unlock_irq(phba->host->host_lock);
207 (iocb->iocb_cmpl) (phba, iocb, iocb);
208 spin_lock_irq(phba->host->host_lock);
209 } else
210 lpfc_sli_release_iocbq(phba, iocb);
211 break;
212 }
213 } 199 }
214 spin_unlock_irq(phba->host->host_lock); 200 }
215 } while (found);
216 201
217 /* Next check the txcmplq */ 202 /* Next check the txcmplq */
218 spin_lock_irq(phba->host->host_lock);
219 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { 203 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
220 /* Check to see if iocb matches the nport we are looking 204 /* Check to see if iocb matches the nport we are looking
221 for */ 205 for */
222 if ((lpfc_check_sli_ndlp (phba, pring, iocb, ndlp))) { 206 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))
223 icmd = &iocb->iocb;
224 lpfc_sli_issue_abort_iotag(phba, pring, iocb); 207 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
225 }
226 } 208 }
227 spin_unlock_irq(phba->host->host_lock); 209 spin_unlock_irq(phba->host->host_lock);
228 210
211 while (!list_empty(&completions)) {
212 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
213 cmd = &iocb->iocb;
214 list_del(&iocb->list);
215
216 if (iocb->iocb_cmpl) {
217 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
218 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
219 (iocb->iocb_cmpl) (phba, iocb, iocb);
220 } else
221 lpfc_sli_release_iocbq(phba, iocb);
222 }
223
229 /* If we are delaying issuing an ELS command, cancel it */ 224 /* If we are delaying issuing an ELS command, cancel it */
230 if (ndlp->nlp_flag & NLP_DELAY_TMO) 225 if (ndlp->nlp_flag & NLP_DELAY_TMO)
231 lpfc_cancel_retry_delay_tmo(phba, ndlp); 226 lpfc_cancel_retry_delay_tmo(phba, ndlp);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index dcd313ab4a72..16825243e603 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1455,8 +1455,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
1455int 1455int
1456lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) 1456lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1457{ 1457{
1458 LIST_HEAD(completions);
1458 struct lpfc_iocbq *iocb, *next_iocb; 1459 struct lpfc_iocbq *iocb, *next_iocb;
1459 IOCB_t *icmd = NULL, *cmd = NULL; 1460 IOCB_t *cmd = NULL;
1460 int errcnt; 1461 int errcnt;
1461 1462
1462 errcnt = 0; 1463 errcnt = 0;
@@ -1465,46 +1466,28 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1465 * First do the txq. 1466 * First do the txq.
1466 */ 1467 */
1467 spin_lock_irq(phba->host->host_lock); 1468 spin_lock_irq(phba->host->host_lock);
1468 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { 1469 list_splice_init(&pring->txq, &completions);
1469 list_del_init(&iocb->list);
1470 if (iocb->iocb_cmpl) {
1471 icmd = &iocb->iocb;
1472 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
1473 icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
1474 spin_unlock_irq(phba->host->host_lock);
1475 (iocb->iocb_cmpl) (phba, iocb, iocb);
1476 spin_lock_irq(phba->host->host_lock);
1477 } else
1478 lpfc_sli_release_iocbq(phba, iocb);
1479 }
1480 pring->txq_cnt = 0; 1470 pring->txq_cnt = 0;
1481 INIT_LIST_HEAD(&(pring->txq));
1482 1471
1483 /* Next issue ABTS for everything on the txcmplq */ 1472 /* Next issue ABTS for everything on the txcmplq */
1484 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { 1473 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
1485 cmd = &iocb->iocb; 1474 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
1486 1475
1487 /* 1476 spin_unlock_irq(phba->host->host_lock);
1488 * Imediate abort of IOCB, deque and call compl
1489 */
1490 1477
1491 list_del_init(&iocb->list); 1478 while (!list_empty(&completions)) {
1492 pring->txcmplq_cnt--; 1479 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
1480 cmd = &iocb->iocb;
1481 list_del(&iocb->list);
1493 1482
1494 if (iocb->iocb_cmpl) { 1483 if (iocb->iocb_cmpl) {
1495 cmd->ulpStatus = IOSTAT_LOCAL_REJECT; 1484 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
1496 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; 1485 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
1497 spin_unlock_irq(phba->host->host_lock);
1498 (iocb->iocb_cmpl) (phba, iocb, iocb); 1486 (iocb->iocb_cmpl) (phba, iocb, iocb);
1499 spin_lock_irq(phba->host->host_lock);
1500 } else 1487 } else
1501 lpfc_sli_release_iocbq(phba, iocb); 1488 lpfc_sli_release_iocbq(phba, iocb);
1502 } 1489 }
1503 1490
1504 INIT_LIST_HEAD(&pring->txcmplq);
1505 pring->txcmplq_cnt = 0;
1506 spin_unlock_irq(phba->host->host_lock);
1507
1508 return errcnt; 1491 return errcnt;
1509} 1492}
1510 1493
@@ -2605,11 +2588,12 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
2605int 2588int
2606lpfc_sli_hba_down(struct lpfc_hba * phba) 2589lpfc_sli_hba_down(struct lpfc_hba * phba)
2607{ 2590{
2591 LIST_HEAD(completions);
2608 struct lpfc_sli *psli; 2592 struct lpfc_sli *psli;
2609 struct lpfc_sli_ring *pring; 2593 struct lpfc_sli_ring *pring;
2610 LPFC_MBOXQ_t *pmb; 2594 LPFC_MBOXQ_t *pmb;
2611 struct lpfc_iocbq *iocb, *next_iocb; 2595 struct lpfc_iocbq *iocb;
2612 IOCB_t *icmd = NULL; 2596 IOCB_t *cmd = NULL;
2613 int i; 2597 int i;
2614 unsigned long flags = 0; 2598 unsigned long flags = 0;
2615 2599
@@ -2617,7 +2601,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
2617 lpfc_hba_down_prep(phba); 2601 lpfc_hba_down_prep(phba);
2618 2602
2619 spin_lock_irqsave(phba->host->host_lock, flags); 2603 spin_lock_irqsave(phba->host->host_lock, flags);
2620
2621 for (i = 0; i < psli->num_rings; i++) { 2604 for (i = 0; i < psli->num_rings; i++) {
2622 pring = &psli->ring[i]; 2605 pring = &psli->ring[i];
2623 pring->flag |= LPFC_DEFERRED_RING_EVENT; 2606 pring->flag |= LPFC_DEFERRED_RING_EVENT;
@@ -2626,28 +2609,25 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
2626 * Error everything on the txq since these iocbs have not been 2609 * Error everything on the txq since these iocbs have not been
2627 * given to the FW yet. 2610 * given to the FW yet.
2628 */ 2611 */
2612 list_splice_init(&pring->txq, &completions);
2629 pring->txq_cnt = 0; 2613 pring->txq_cnt = 0;
2630 2614
2631 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { 2615 }
2632 list_del_init(&iocb->list); 2616 spin_unlock_irqrestore(phba->host->host_lock, flags);
2633 if (iocb->iocb_cmpl) {
2634 icmd = &iocb->iocb;
2635 icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2636 icmd->un.ulpWord[4] = IOERR_SLI_DOWN;
2637 spin_unlock_irqrestore(phba->host->host_lock,
2638 flags);
2639 (iocb->iocb_cmpl) (phba, iocb, iocb);
2640 spin_lock_irqsave(phba->host->host_lock, flags);
2641 } else
2642 lpfc_sli_release_iocbq(phba, iocb);
2643 }
2644 2617
2645 INIT_LIST_HEAD(&(pring->txq)); 2618 while (!list_empty(&completions)) {
2619 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
2620 cmd = &iocb->iocb;
2621 list_del(&iocb->list);
2646 2622
2623 if (iocb->iocb_cmpl) {
2624 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2625 cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
2626 (iocb->iocb_cmpl) (phba, iocb, iocb);
2627 } else
2628 lpfc_sli_release_iocbq(phba, iocb);
2647 } 2629 }
2648 2630
2649 spin_unlock_irqrestore(phba->host->host_lock, flags);
2650
2651 /* Return any active mbox cmds */ 2631 /* Return any active mbox cmds */
2652 del_timer_sync(&psli->mbox_tmo); 2632 del_timer_sync(&psli->mbox_tmo);
2653 spin_lock_irqsave(phba->host->host_lock, flags); 2633 spin_lock_irqsave(phba->host->host_lock, flags);