提交 2534ba75 编写于 作者: J James Smart 提交者: James Bottomley

[SCSI] lpfc 8.1.12 : Fix unlock inside list traversal

Fix unlock inside list traversal.
Signed-off-by: NJames Smart <James.Smart@emulex.com>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 46fa311e
...@@ -57,6 +57,7 @@ void lpfc_disc_start(struct lpfc_hba *); ...@@ -57,6 +57,7 @@ void lpfc_disc_start(struct lpfc_hba *);
void lpfc_disc_flush_list(struct lpfc_hba *); void lpfc_disc_flush_list(struct lpfc_hba *);
void lpfc_disc_timeout(unsigned long); void lpfc_disc_timeout(unsigned long);
struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
......
...@@ -3272,9 +3272,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) ...@@ -3272,9 +3272,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
spin_unlock_irq(phba->host->host_lock); ndlp = __lpfc_findnode_rpi(phba, cmd->ulpContext);
ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
spin_lock_irq(phba->host->host_lock);
remote_ID = ndlp->nlp_DID; remote_ID = ndlp->nlp_DID;
} else { } else {
remote_ID = cmd->un.elsreq64.remoteID; remote_ID = cmd->un.elsreq64.remoteID;
...@@ -3298,6 +3296,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) ...@@ -3298,6 +3296,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
void void
lpfc_els_flush_cmd(struct lpfc_hba * phba) lpfc_els_flush_cmd(struct lpfc_hba * phba)
{ {
LIST_HEAD(completions);
struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring;
struct lpfc_iocbq *tmp_iocb, *piocb; struct lpfc_iocbq *tmp_iocb, *piocb;
IOCB_t *cmd = NULL; IOCB_t *cmd = NULL;
...@@ -3319,18 +3318,9 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -3319,18 +3318,9 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
continue; continue;
} }
list_del(&piocb->list); list_move_tail(&piocb->list, &completions);
pring->txq_cnt--; pring->txq_cnt--;
cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
if (piocb->iocb_cmpl) {
spin_unlock_irq(phba->host->host_lock);
(piocb->iocb_cmpl) (phba, piocb, piocb);
spin_lock_irq(phba->host->host_lock);
} else
lpfc_sli_release_iocbq(phba, piocb);
} }
list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
...@@ -3343,6 +3333,20 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -3343,6 +3333,20 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
lpfc_sli_issue_abort_iotag(phba, pring, piocb); lpfc_sli_issue_abort_iotag(phba, pring, piocb);
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
while(!list_empty(&completions)) {
piocb = list_get_first(&completions, struct lpfc_iocbq, list);
cmd = &piocb->iocb;
list_del(&piocb->list);
if (piocb->iocb_cmpl) {
cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
(piocb->iocb_cmpl) (phba, piocb, piocb);
} else
lpfc_sli_release_iocbq(phba, piocb);
}
return; return;
} }
......
...@@ -1473,6 +1473,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, ...@@ -1473,6 +1473,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
static int static int
lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
{ {
LIST_HEAD(completions);
struct lpfc_sli *psli; struct lpfc_sli *psli;
struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring;
struct lpfc_iocbq *iocb, *next_iocb; struct lpfc_iocbq *iocb, *next_iocb;
...@@ -1501,29 +1502,29 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1501,29 +1502,29 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
(phba, pring, iocb, ndlp))) { (phba, pring, iocb, ndlp))) {
/* It matches, so deque and call compl /* It matches, so deque and call compl
with an error */ with an error */
list_del(&iocb->list); list_move_tail(&iocb->list,
&completions);
pring->txq_cnt--; pring->txq_cnt--;
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);
} }
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
} }
} }
while (!list_empty(&completions)) {
iocb = list_get_first(&completions, struct lpfc_iocbq, list);
list_del(&iocb->list);
if (iocb->iocb_cmpl) {
icmd = &iocb->iocb;
icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
(iocb->iocb_cmpl) (phba, iocb, iocb);
} else
lpfc_sli_release_iocbq(phba, iocb);
}
return 0; return 0;
} }
...@@ -1951,11 +1952,11 @@ lpfc_disc_start(struct lpfc_hba * phba) ...@@ -1951,11 +1952,11 @@ lpfc_disc_start(struct lpfc_hba * phba)
static void static void
lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
{ {
LIST_HEAD(completions);
struct lpfc_sli *psli; struct lpfc_sli *psli;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *iocb, *next_iocb; struct lpfc_iocbq *iocb, *next_iocb;
struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring;
struct lpfc_dmabuf *mp;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; pring = &psli->ring[LPFC_ELS_RING];
...@@ -1963,6 +1964,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1963,6 +1964,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
/* Error matching iocb on txq or txcmplq /* Error matching iocb on txq or txcmplq
* First check the txq. * First check the txq.
*/ */
spin_lock_irq(phba->host->host_lock);
list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
if (iocb->context1 != ndlp) { if (iocb->context1 != ndlp) {
continue; continue;
...@@ -1971,9 +1973,8 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1971,9 +1973,8 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
(icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {
list_del(&iocb->list); list_move_tail(&iocb->list, &completions);
pring->txq_cnt--; pring->txq_cnt--;
lpfc_els_free_iocb(phba, iocb);
} }
} }
...@@ -1985,43 +1986,22 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1985,43 +1986,22 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
icmd = &iocb->iocb; icmd = &iocb->iocb;
if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
(icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {
lpfc_sli_issue_abort_iotag(phba, pring, iocb);
}
}
spin_unlock_irq(phba->host->host_lock);
iocb->iocb_cmpl = NULL; while (!list_empty(&completions)) {
/* context2 = cmd, context2->next = rsp, context3 = iocb = list_get_first(&completions, struct lpfc_iocbq, list);
bpl */ list_del(&iocb->list);
if (iocb->context2) {
/* Free the response IOCB before handling the
command. */
mp = (struct lpfc_dmabuf *) (iocb->context2);
mp = list_get_first(&mp->list,
struct lpfc_dmabuf,
list);
if (mp) {
/* Delay before releasing rsp buffer to
* give UNREG mbox a chance to take
* effect.
*/
list_add(&mp->list,
&phba->freebufList);
}
lpfc_mbuf_free(phba,
((struct lpfc_dmabuf *)
iocb->context2)->virt,
((struct lpfc_dmabuf *)
iocb->context2)->phys);
kfree(iocb->context2);
}
if (iocb->context3) { if (iocb->iocb_cmpl) {
lpfc_mbuf_free(phba, icmd = &iocb->iocb;
((struct lpfc_dmabuf *) icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
iocb->context3)->virt, icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
((struct lpfc_dmabuf *) (iocb->iocb_cmpl) (phba, iocb, iocb);
iocb->context3)->phys); } else
kfree(iocb->context3); lpfc_sli_release_iocbq(phba, iocb);
}
}
} }
return; return;
...@@ -2354,7 +2334,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -2354,7 +2334,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
* else return NULL. * else return NULL.
*/ */
struct lpfc_nodelist * struct lpfc_nodelist *
lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) __lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
{ {
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct list_head * lists[]={&phba->fc_nlpunmap_list, struct list_head * lists[]={&phba->fc_nlpunmap_list,
...@@ -2364,17 +2344,25 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) ...@@ -2364,17 +2344,25 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
&phba->fc_reglogin_list}; &phba->fc_reglogin_list};
int i; int i;
spin_lock_irq(phba->host->host_lock);
for (i = 0; i < ARRAY_SIZE(lists); i++ ) for (i = 0; i < ARRAY_SIZE(lists); i++ )
list_for_each_entry(ndlp, lists[i], nlp_listp) list_for_each_entry(ndlp, lists[i], nlp_listp)
if (ndlp->nlp_rpi == rpi) { if (ndlp->nlp_rpi == rpi) {
spin_unlock_irq(phba->host->host_lock);
return ndlp; return ndlp;
} }
spin_unlock_irq(phba->host->host_lock);
return NULL; return NULL;
} }
struct lpfc_nodelist *
lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
{
struct lpfc_nodelist *ndlp;
spin_lock_irq(phba->host->host_lock);
ndlp = __lpfc_findnode_rpi(phba, rpi);
spin_unlock_irq(phba->host->host_lock);
return ndlp;
}
/* /*
* This routine looks up the ndlp lists * This routine looks up the ndlp lists
* for the given WWPN. If WWPN found * for the given WWPN. If WWPN found
......
...@@ -170,11 +170,11 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, ...@@ -170,11 +170,11 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba,
int int
lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
{ {
LIST_HEAD(completions);
struct lpfc_sli *psli; struct lpfc_sli *psli;
struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring;
struct lpfc_iocbq *iocb, *next_iocb; struct lpfc_iocbq *iocb, *next_iocb;
IOCB_t *icmd; IOCB_t *cmd;
int found = 0;
/* Abort outstanding I/O on NPort <nlp_DID> */ /* Abort outstanding I/O on NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
...@@ -187,45 +187,40 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -187,45 +187,40 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
pring = &psli->ring[LPFC_ELS_RING]; pring = &psli->ring[LPFC_ELS_RING];
/* First check the txq */ /* First check the txq */
do { spin_lock_irq(phba->host->host_lock);
found = 0; list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
spin_lock_irq(phba->host->host_lock); /* Check to see if iocb matches the nport we are looking
list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { for */
/* Check to see if iocb matches the nport we are looking if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {
for */ /* It matches, so deque and call compl with an
if ((lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))) { error */
found = 1; list_move_tail(&iocb->list, &completions);
/* It matches, so deque and call compl with an pring->txq_cnt--;
error */
list_del(&iocb->list);
pring->txq_cnt--;
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);
break;
}
} }
spin_unlock_irq(phba->host->host_lock); }
} while (found);
/* Next check the txcmplq */ /* Next check the txcmplq */
spin_lock_irq(phba->host->host_lock);
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
/* Check to see if iocb matches the nport we are looking /* Check to see if iocb matches the nport we are looking
for */ for */
if ((lpfc_check_sli_ndlp (phba, pring, iocb, ndlp))) { if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))
icmd = &iocb->iocb;
lpfc_sli_issue_abort_iotag(phba, pring, iocb); lpfc_sli_issue_abort_iotag(phba, pring, iocb);
}
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
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;
(iocb->iocb_cmpl) (phba, iocb, iocb);
} else
lpfc_sli_release_iocbq(phba, iocb);
}
/* If we are delaying issuing an ELS command, cancel it */ /* If we are delaying issuing an ELS command, cancel it */
if (ndlp->nlp_flag & NLP_DELAY_TMO) if (ndlp->nlp_flag & NLP_DELAY_TMO)
lpfc_cancel_retry_delay_tmo(phba, ndlp); lpfc_cancel_retry_delay_tmo(phba, ndlp);
......
...@@ -1455,8 +1455,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, ...@@ -1455,8 +1455,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
int int
lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{ {
LIST_HEAD(completions);
struct lpfc_iocbq *iocb, *next_iocb; struct lpfc_iocbq *iocb, *next_iocb;
IOCB_t *icmd = NULL, *cmd = NULL; IOCB_t *cmd = NULL;
int errcnt; int errcnt;
errcnt = 0; errcnt = 0;
...@@ -1465,46 +1466,28 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) ...@@ -1465,46 +1466,28 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
* First do the txq. * First do the txq.
*/ */
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { list_splice_init(&pring->txq, &completions);
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);
}
pring->txq_cnt = 0; pring->txq_cnt = 0;
INIT_LIST_HEAD(&(pring->txq));
/* Next issue ABTS for everything on the txcmplq */ /* Next issue ABTS for everything on the txcmplq */
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
cmd = &iocb->iocb; lpfc_sli_issue_abort_iotag(phba, pring, iocb);
/* spin_unlock_irq(phba->host->host_lock);
* Imediate abort of IOCB, deque and call compl
*/
list_del_init(&iocb->list); while (!list_empty(&completions)) {
pring->txcmplq_cnt--; iocb = list_get_first(&completions, struct lpfc_iocbq, list);
cmd = &iocb->iocb;
list_del(&iocb->list);
if (iocb->iocb_cmpl) { if (iocb->iocb_cmpl) {
cmd->ulpStatus = IOSTAT_LOCAL_REJECT; cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb); (iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
} else } else
lpfc_sli_release_iocbq(phba, iocb); lpfc_sli_release_iocbq(phba, iocb);
} }
INIT_LIST_HEAD(&pring->txcmplq);
pring->txcmplq_cnt = 0;
spin_unlock_irq(phba->host->host_lock);
return errcnt; return errcnt;
} }
...@@ -2605,11 +2588,12 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) ...@@ -2605,11 +2588,12 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
int int
lpfc_sli_hba_down(struct lpfc_hba * phba) lpfc_sli_hba_down(struct lpfc_hba * phba)
{ {
LIST_HEAD(completions);
struct lpfc_sli *psli; struct lpfc_sli *psli;
struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring;
LPFC_MBOXQ_t *pmb; LPFC_MBOXQ_t *pmb;
struct lpfc_iocbq *iocb, *next_iocb; struct lpfc_iocbq *iocb;
IOCB_t *icmd = NULL; IOCB_t *cmd = NULL;
int i; int i;
unsigned long flags = 0; unsigned long flags = 0;
...@@ -2617,7 +2601,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) ...@@ -2617,7 +2601,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
lpfc_hba_down_prep(phba); lpfc_hba_down_prep(phba);
spin_lock_irqsave(phba->host->host_lock, flags); spin_lock_irqsave(phba->host->host_lock, flags);
for (i = 0; i < psli->num_rings; i++) { for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i]; pring = &psli->ring[i];
pring->flag |= LPFC_DEFERRED_RING_EVENT; pring->flag |= LPFC_DEFERRED_RING_EVENT;
...@@ -2626,28 +2609,25 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) ...@@ -2626,28 +2609,25 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
* Error everything on the txq since these iocbs have not been * Error everything on the txq since these iocbs have not been
* given to the FW yet. * given to the FW yet.
*/ */
list_splice_init(&pring->txq, &completions);
pring->txq_cnt = 0; pring->txq_cnt = 0;
list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { }
list_del_init(&iocb->list); spin_unlock_irqrestore(phba->host->host_lock, flags);
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);
}
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 */ /* Return any active mbox cmds */
del_timer_sync(&psli->mbox_tmo); del_timer_sync(&psli->mbox_tmo);
spin_lock_irqsave(phba->host->host_lock, flags); spin_lock_irqsave(phba->host->host_lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册