diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:51:38 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 10:33:13 -0400 |
commit | 07951076aefa4194e1dbf1d8c89eaff040c45155 (patch) | |
tree | 636052abb3f9f2a1bdc0d9adfec130b224a02289 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 1dcb58e5680b6673bf984696d3d8b9033b6e41bf (diff) |
[SCSI] lpfc 8.1.12 : Modify ELS abort handling to prevent double completion
Modify ELS abort handling to prevent double completion
Rework portions of ELS abort handling to prevent double completion
- Rework ELS iotags and correct abort routine
- Move the (badly wrong) ELS completion logic from the initial ELS
abort request function to the ELS completion function.
- Fixup the iocb completion handling to account for the ELS abort
completions.
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 | 64 |
1 files changed, 4 insertions, 60 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e1c61dbb3d0f..4a9e61345693 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -582,24 +582,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) | |||
582 | icmd = &iocb->iocb; | 582 | icmd = &iocb->iocb; |
583 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) { | 583 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) { |
584 | ndlp = (struct lpfc_nodelist *)(iocb->context1); | 584 | ndlp = (struct lpfc_nodelist *)(iocb->context1); |
585 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { | 585 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) |
586 | list_del(&iocb->list); | 586 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
587 | pring->txcmplq_cnt--; | ||
588 | |||
589 | if ((icmd->un.elsreq64.bdl.ulpIoTag32)) { | ||
590 | lpfc_sli_issue_abort_iotag32 | ||
591 | (phba, pring, iocb); | ||
592 | } | ||
593 | if (iocb->iocb_cmpl) { | ||
594 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
595 | icmd->un.ulpWord[4] = | ||
596 | IOERR_SLI_ABORTED; | ||
597 | spin_unlock_irq(phba->host->host_lock); | ||
598 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
599 | spin_lock_irq(phba->host->host_lock); | ||
600 | } else | ||
601 | lpfc_sli_release_iocbq(phba, iocb); | ||
602 | } | ||
603 | } | 587 | } |
604 | } | 588 | } |
605 | spin_unlock_irq(phba->host->host_lock); | 589 | spin_unlock_irq(phba->host->host_lock); |
@@ -3245,7 +3229,6 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3245 | struct lpfc_iocbq *tmp_iocb, *piocb; | 3229 | struct lpfc_iocbq *tmp_iocb, *piocb; |
3246 | IOCB_t *cmd = NULL; | 3230 | IOCB_t *cmd = NULL; |
3247 | struct lpfc_dmabuf *pcmd; | 3231 | struct lpfc_dmabuf *pcmd; |
3248 | struct list_head *dlp; | ||
3249 | uint32_t *elscmd; | 3232 | uint32_t *elscmd; |
3250 | uint32_t els_command; | 3233 | uint32_t els_command; |
3251 | uint32_t timeout; | 3234 | uint32_t timeout; |
@@ -3262,7 +3245,6 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3262 | timeout = (uint32_t)(phba->fc_ratov << 1); | 3245 | timeout = (uint32_t)(phba->fc_ratov << 1); |
3263 | 3246 | ||
3264 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 3247 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
3265 | dlp = &pring->txcmplq; | ||
3266 | 3248 | ||
3267 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { | 3249 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { |
3268 | cmd = &piocb->iocb; | 3250 | cmd = &piocb->iocb; |
@@ -3288,19 +3270,12 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3288 | continue; | 3270 | continue; |
3289 | } | 3271 | } |
3290 | 3272 | ||
3291 | list_del(&piocb->list); | ||
3292 | pring->txcmplq_cnt--; | ||
3293 | |||
3294 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { | 3273 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { |
3295 | struct lpfc_nodelist *ndlp; | 3274 | struct lpfc_nodelist *ndlp; |
3296 | spin_unlock_irq(phba->host->host_lock); | 3275 | spin_unlock_irq(phba->host->host_lock); |
3297 | ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); | 3276 | ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); |
3298 | spin_lock_irq(phba->host->host_lock); | 3277 | spin_lock_irq(phba->host->host_lock); |
3299 | remote_ID = ndlp->nlp_DID; | 3278 | remote_ID = ndlp->nlp_DID; |
3300 | if (cmd->un.elsreq64.bdl.ulpIoTag32) { | ||
3301 | lpfc_sli_issue_abort_iotag32(phba, | ||
3302 | pring, piocb); | ||
3303 | } | ||
3304 | } else { | 3279 | } else { |
3305 | remote_ID = cmd->un.elsreq64.remoteID; | 3280 | remote_ID = cmd->un.elsreq64.remoteID; |
3306 | } | 3281 | } |
@@ -3312,17 +3287,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3312 | phba->brd_no, els_command, | 3287 | phba->brd_no, els_command, |
3313 | remote_ID, cmd->ulpCommand, cmd->ulpIoTag); | 3288 | remote_ID, cmd->ulpCommand, cmd->ulpIoTag); |
3314 | 3289 | ||
3315 | /* | 3290 | lpfc_sli_issue_abort_iotag(phba, pring, piocb); |
3316 | * The iocb has timed out; abort it. | ||
3317 | */ | ||
3318 | if (piocb->iocb_cmpl) { | ||
3319 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
3320 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
3321 | spin_unlock_irq(phba->host->host_lock); | ||
3322 | (piocb->iocb_cmpl) (phba, piocb, piocb); | ||
3323 | spin_lock_irq(phba->host->host_lock); | ||
3324 | } else | ||
3325 | lpfc_sli_release_iocbq(phba, piocb); | ||
3326 | } | 3291 | } |
3327 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) | 3292 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) |
3328 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); | 3293 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); |
@@ -3336,9 +3301,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3336 | struct lpfc_sli_ring *pring; | 3301 | struct lpfc_sli_ring *pring; |
3337 | struct lpfc_iocbq *tmp_iocb, *piocb; | 3302 | struct lpfc_iocbq *tmp_iocb, *piocb; |
3338 | IOCB_t *cmd = NULL; | 3303 | IOCB_t *cmd = NULL; |
3339 | struct lpfc_dmabuf *pcmd; | ||
3340 | uint32_t *elscmd; | ||
3341 | uint32_t els_command; | ||
3342 | 3304 | ||
3343 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 3305 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
3344 | spin_lock_irq(phba->host->host_lock); | 3306 | spin_lock_irq(phba->host->host_lock); |
@@ -3357,10 +3319,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3357 | continue; | 3319 | continue; |
3358 | } | 3320 | } |
3359 | 3321 | ||
3360 | pcmd = (struct lpfc_dmabuf *) piocb->context2; | ||
3361 | elscmd = (uint32_t *) (pcmd->virt); | ||
3362 | els_command = *elscmd; | ||
3363 | |||
3364 | list_del(&piocb->list); | 3322 | list_del(&piocb->list); |
3365 | pring->txq_cnt--; | 3323 | pring->txq_cnt--; |
3366 | 3324 | ||
@@ -3381,22 +3339,8 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3381 | if (piocb->iocb_flag & LPFC_IO_LIBDFC) { | 3339 | if (piocb->iocb_flag & LPFC_IO_LIBDFC) { |
3382 | continue; | 3340 | continue; |
3383 | } | 3341 | } |
3384 | pcmd = (struct lpfc_dmabuf *) piocb->context2; | ||
3385 | elscmd = (uint32_t *) (pcmd->virt); | ||
3386 | els_command = *elscmd; | ||
3387 | |||
3388 | list_del(&piocb->list); | ||
3389 | pring->txcmplq_cnt--; | ||
3390 | 3342 | ||
3391 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 3343 | lpfc_sli_issue_abort_iotag(phba, pring, piocb); |
3392 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
3393 | |||
3394 | if (piocb->iocb_cmpl) { | ||
3395 | spin_unlock_irq(phba->host->host_lock); | ||
3396 | (piocb->iocb_cmpl) (phba, piocb, piocb); | ||
3397 | spin_lock_irq(phba->host->host_lock); | ||
3398 | } else | ||
3399 | lpfc_sli_release_iocbq(phba, piocb); | ||
3400 | } | 3344 | } |
3401 | spin_unlock_irq(phba->host->host_lock); | 3345 | spin_unlock_irq(phba->host->host_lock); |
3402 | return; | 3346 | return; |