diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-01-11 01:52:42 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:21 -0500 |
commit | fa61a54e48efc8e5c7a6d4680ad8ceb74a5fca84 (patch) | |
tree | abd25d2d2a801bde1891cd4291b4ae05b38f6cdc /drivers/scsi/lpfc | |
parent | 0ff10d46cf0a373c9c855a23cc9383ba4030d8d2 (diff) |
[SCSI] lpfc 8.2.4 : Correct abort handler logic
Correct Abort handler logic. It was unconditionally waiting a minimum
of 2 seconds rather than looking for abort completion.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 38 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.h | 1 |
2 files changed, 29 insertions, 10 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4e46045dea6d..c987c4fcdadc 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -542,6 +542,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
542 | int result; | 542 | int result; |
543 | struct scsi_device *sdev, *tmp_sdev; | 543 | struct scsi_device *sdev, *tmp_sdev; |
544 | int depth = 0; | 544 | int depth = 0; |
545 | unsigned long flags; | ||
545 | 546 | ||
546 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; | 547 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; |
547 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; | 548 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; |
@@ -608,6 +609,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
608 | cmd->scsi_done(cmd); | 609 | cmd->scsi_done(cmd); |
609 | 610 | ||
610 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
612 | /* | ||
613 | * If there is a thread waiting for command completion | ||
614 | * wake up the thread. | ||
615 | */ | ||
616 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
617 | lpfc_cmd->pCmd = NULL; | ||
618 | if (lpfc_cmd->waitq) | ||
619 | wake_up(lpfc_cmd->waitq); | ||
620 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
611 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 621 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
612 | return; | 622 | return; |
613 | } | 623 | } |
@@ -669,6 +679,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
669 | } | 679 | } |
670 | } | 680 | } |
671 | 681 | ||
682 | /* | ||
683 | * If there is a thread waiting for command completion | ||
684 | * wake up the thread. | ||
685 | */ | ||
686 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
687 | lpfc_cmd->pCmd = NULL; | ||
688 | if (lpfc_cmd->waitq) | ||
689 | wake_up(lpfc_cmd->waitq); | ||
690 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
691 | |||
672 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 692 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
673 | } | 693 | } |
674 | 694 | ||
@@ -1018,8 +1038,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1018 | struct lpfc_iocbq *abtsiocb; | 1038 | struct lpfc_iocbq *abtsiocb; |
1019 | struct lpfc_scsi_buf *lpfc_cmd; | 1039 | struct lpfc_scsi_buf *lpfc_cmd; |
1020 | IOCB_t *cmd, *icmd; | 1040 | IOCB_t *cmd, *icmd; |
1021 | unsigned int loop_count = 0; | ||
1022 | int ret = SUCCESS; | 1041 | int ret = SUCCESS; |
1042 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | ||
1023 | 1043 | ||
1024 | lpfc_block_error_handler(cmnd); | 1044 | lpfc_block_error_handler(cmnd); |
1025 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 1045 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -1074,17 +1094,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1074 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 1094 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) |
1075 | lpfc_sli_poll_fcp_ring (phba); | 1095 | lpfc_sli_poll_fcp_ring (phba); |
1076 | 1096 | ||
1097 | lpfc_cmd->waitq = &waitq; | ||
1077 | /* Wait for abort to complete */ | 1098 | /* Wait for abort to complete */ |
1078 | while (lpfc_cmd->pCmd == cmnd) | 1099 | wait_event_timeout(waitq, |
1079 | { | 1100 | (lpfc_cmd->pCmd != cmnd), |
1080 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 1101 | (2*vport->cfg_devloss_tmo*HZ)); |
1081 | lpfc_sli_poll_fcp_ring (phba); | ||
1082 | 1102 | ||
1083 | schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); | 1103 | spin_lock_irq(shost->host_lock); |
1084 | if (++loop_count | 1104 | lpfc_cmd->waitq = NULL; |
1085 | > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT) | 1105 | spin_unlock_irq(shost->host_lock); |
1086 | break; | ||
1087 | } | ||
1088 | 1106 | ||
1089 | if (lpfc_cmd->pCmd == cmnd) { | 1107 | if (lpfc_cmd->pCmd == cmnd) { |
1090 | ret = FAILED; | 1108 | ret = FAILED; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index 31787bb6d53e..daba92374985 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h | |||
@@ -138,6 +138,7 @@ struct lpfc_scsi_buf { | |||
138 | * Iotag is in here | 138 | * Iotag is in here |
139 | */ | 139 | */ |
140 | struct lpfc_iocbq cur_iocbq; | 140 | struct lpfc_iocbq cur_iocbq; |
141 | wait_queue_head_t *waitq; | ||
141 | }; | 142 | }; |
142 | 143 | ||
143 | #define LPFC_SCSI_DMA_EXT_SIZE 264 | 144 | #define LPFC_SCSI_DMA_EXT_SIZE 264 |