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 10:33:14 -0400 |
commit | 2534ba756ec407d343af45168273d3a64825a7ba (patch) | |
tree | ebefbc11ba342bd93ceac0946d1e4154809e5d92 /drivers/scsi/lpfc/lpfc_els.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_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 30 |
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) | |||
3298 | void | 3296 | void |
3299 | lpfc_els_flush_cmd(struct lpfc_hba * phba) | 3297 | lpfc_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 | ||