diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:52:20 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 09:33:14 -0500 |
commit | 2534ba756ec407d343af45168273d3a64825a7ba (patch) | |
tree | ebefbc11ba342bd93ceac0946d1e4154809e5d92 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 46fa311e6967b526e1fd9b0b44edda6841dcac27 (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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 72 |
1 files changed, 26 insertions, 46 deletions
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, int lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { + LIST_HEAD(completions); struct lpfc_iocbq *iocb, *next_iocb; - IOCB_t *icmd = NULL, *cmd = NULL; + IOCB_t *cmd = NULL; int errcnt; errcnt = 0; @@ -1465,46 +1466,28 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) * First do the txq. */ spin_lock_irq(phba->host->host_lock); - list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { - list_del_init(&iocb->list); - if (iocb->iocb_cmpl) { - icmd = &iocb->iocb; - icmd->ulpStatus = IOSTAT_LOCAL_REJECT; - icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - spin_unlock_irq(phba->host->host_lock); - (iocb->iocb_cmpl) (phba, iocb, iocb); - spin_lock_irq(phba->host->host_lock); - } else - lpfc_sli_release_iocbq(phba, iocb); - } + list_splice_init(&pring->txq, &completions); pring->txq_cnt = 0; - INIT_LIST_HEAD(&(pring->txq)); /* Next issue ABTS for everything on the txcmplq */ - list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { - cmd = &iocb->iocb; + list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) + lpfc_sli_issue_abort_iotag(phba, pring, iocb); - /* - * Imediate abort of IOCB, deque and call compl - */ + spin_unlock_irq(phba->host->host_lock); - list_del_init(&iocb->list); - pring->txcmplq_cnt--; + while (!list_empty(&completions)) { + iocb = list_get_first(&completions, struct lpfc_iocbq, list); + cmd = &iocb->iocb; + list_del(&iocb->list); if (iocb->iocb_cmpl) { cmd->ulpStatus = IOSTAT_LOCAL_REJECT; cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); - spin_lock_irq(phba->host->host_lock); } else lpfc_sli_release_iocbq(phba, iocb); } - INIT_LIST_HEAD(&pring->txcmplq); - pring->txcmplq_cnt = 0; - spin_unlock_irq(phba->host->host_lock); - return errcnt; } @@ -2605,11 +2588,12 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) int lpfc_sli_hba_down(struct lpfc_hba * phba) { + LIST_HEAD(completions); struct lpfc_sli *psli; struct lpfc_sli_ring *pring; LPFC_MBOXQ_t *pmb; - struct lpfc_iocbq *iocb, *next_iocb; - IOCB_t *icmd = NULL; + struct lpfc_iocbq *iocb; + IOCB_t *cmd = NULL; int i; unsigned long flags = 0; @@ -2617,7 +2601,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) lpfc_hba_down_prep(phba); spin_lock_irqsave(phba->host->host_lock, flags); - for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; pring->flag |= LPFC_DEFERRED_RING_EVENT; @@ -2626,28 +2609,25 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) * Error everything on the txq since these iocbs have not been * given to the FW yet. */ + list_splice_init(&pring->txq, &completions); pring->txq_cnt = 0; - list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { - list_del_init(&iocb->list); - if (iocb->iocb_cmpl) { - icmd = &iocb->iocb; - icmd->ulpStatus = IOSTAT_LOCAL_REJECT; - icmd->un.ulpWord[4] = IOERR_SLI_DOWN; - spin_unlock_irqrestore(phba->host->host_lock, - flags); - (iocb->iocb_cmpl) (phba, iocb, iocb); - spin_lock_irqsave(phba->host->host_lock, flags); - } else - lpfc_sli_release_iocbq(phba, iocb); - } + } + spin_unlock_irqrestore(phba->host->host_lock, flags); - INIT_LIST_HEAD(&(pring->txq)); + while (!list_empty(&completions)) { + iocb = list_get_first(&completions, struct lpfc_iocbq, list); + cmd = &iocb->iocb; + list_del(&iocb->list); + if (iocb->iocb_cmpl) { + cmd->ulpStatus = IOSTAT_LOCAL_REJECT; + cmd->un.ulpWord[4] = IOERR_SLI_DOWN; + (iocb->iocb_cmpl) (phba, iocb, iocb); + } else + lpfc_sli_release_iocbq(phba, iocb); } - spin_unlock_irqrestore(phba->host->host_lock, flags); - /* Return any active mbox cmds */ del_timer_sync(&psli->mbox_tmo); spin_lock_irqsave(phba->host->host_lock, flags); |