aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
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 /drivers/scsi/lpfc/lpfc_els.c
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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c30
1 files changed, 17 insertions, 13 deletions
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