aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:51:38 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:13 -0400
commit07951076aefa4194e1dbf1d8c89eaff040c45155 (patch)
tree636052abb3f9f2a1bdc0d9adfec130b224a02289 /drivers/scsi/lpfc/lpfc_els.c
parent1dcb58e5680b6673bf984696d3d8b9033b6e41bf (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.c64
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;