[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>
This commit is contained in:
James Smart 2008-01-11 01:52:42 -05:00 committed by James Bottomley
parent 0ff10d46cf
commit fa61a54e48
2 changed files with 29 additions and 10 deletions

View File

@ -542,6 +542,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
int result; int result;
struct scsi_device *sdev, *tmp_sdev; struct scsi_device *sdev, *tmp_sdev;
int depth = 0; int depth = 0;
unsigned long flags;
lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
lpfc_cmd->status = pIocbOut->iocb.ulpStatus; lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
@ -608,6 +609,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
/*
* If there is a thread waiting for command completion
* wake up the thread.
*/
spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
lpfc_release_scsi_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd);
return; return;
} }
@ -669,6 +679,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
} }
} }
/*
* If there is a thread waiting for command completion
* wake up the thread.
*/
spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
lpfc_release_scsi_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd);
} }
@ -1018,8 +1038,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
struct lpfc_iocbq *abtsiocb; struct lpfc_iocbq *abtsiocb;
struct lpfc_scsi_buf *lpfc_cmd; struct lpfc_scsi_buf *lpfc_cmd;
IOCB_t *cmd, *icmd; IOCB_t *cmd, *icmd;
unsigned int loop_count = 0;
int ret = SUCCESS; int ret = SUCCESS;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
lpfc_block_error_handler(cmnd); lpfc_block_error_handler(cmnd);
lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
@ -1074,17 +1094,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
if (phba->cfg_poll & DISABLE_FCP_RING_INT) if (phba->cfg_poll & DISABLE_FCP_RING_INT)
lpfc_sli_poll_fcp_ring (phba); lpfc_sli_poll_fcp_ring (phba);
lpfc_cmd->waitq = &waitq;
/* Wait for abort to complete */ /* Wait for abort to complete */
while (lpfc_cmd->pCmd == cmnd) wait_event_timeout(waitq,
{ (lpfc_cmd->pCmd != cmnd),
if (phba->cfg_poll & DISABLE_FCP_RING_INT) (2*vport->cfg_devloss_tmo*HZ));
lpfc_sli_poll_fcp_ring (phba);
schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); spin_lock_irq(shost->host_lock);
if (++loop_count lpfc_cmd->waitq = NULL;
> (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT) spin_unlock_irq(shost->host_lock);
break;
}
if (lpfc_cmd->pCmd == cmnd) { if (lpfc_cmd->pCmd == cmnd) {
ret = FAILED; ret = FAILED;

View File

@ -138,6 +138,7 @@ struct lpfc_scsi_buf {
* Iotag is in here * Iotag is in here
*/ */
struct lpfc_iocbq cur_iocbq; struct lpfc_iocbq cur_iocbq;
wait_queue_head_t *waitq;
}; };
#define LPFC_SCSI_DMA_EXT_SIZE 264 #define LPFC_SCSI_DMA_EXT_SIZE 264