Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fa61a54e48efc8e5c7a6d4680ad8ceb74a5fca84
Commit:     fa61a54e48efc8e5c7a6d4680ad8ceb74a5fca84
Parent:     0ff10d46cf0a373c9c855a23cc9383ba4030d8d2
Author:     James Smart <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 11 01:52:42 2008 -0500
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Wed Jan 23 11:29:21 2008 -0600

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/lpfc/lpfc_scsi.c |   38 ++++++++++++++++++++++++++++----------
 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 4e46045..c987c4f 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,
        int result;
        struct scsi_device *sdev, *tmp_sdev;
        int depth = 0;
+       unsigned long flags;
 
        lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
        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);
 
        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);
                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);
 }
 
@@ -1018,8 +1038,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
        struct lpfc_iocbq *abtsiocb;
        struct lpfc_scsi_buf *lpfc_cmd;
        IOCB_t *cmd, *icmd;
-       unsigned int loop_count = 0;
        int ret = SUCCESS;
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
 
        lpfc_block_error_handler(cmnd);
        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)
                lpfc_sli_poll_fcp_ring (phba);
 
+       lpfc_cmd->waitq = &waitq;
        /* Wait for abort to complete */
-       while (lpfc_cmd->pCmd == cmnd)
-       {
-               if (phba->cfg_poll & DISABLE_FCP_RING_INT)
-                       lpfc_sli_poll_fcp_ring (phba);
+       wait_event_timeout(waitq,
+                         (lpfc_cmd->pCmd != cmnd),
+                          (2*vport->cfg_devloss_tmo*HZ));
 
-               schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ);
-               if (++loop_count
-                   > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT)
-                       break;
-       }
+       spin_lock_irq(shost->host_lock);
+       lpfc_cmd->waitq = NULL;
+       spin_unlock_irq(shost->host_lock);
 
        if (lpfc_cmd->pCmd == cmnd) {
                ret = FAILED;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index 31787bb..daba923 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -138,6 +138,7 @@ struct lpfc_scsi_buf {
         * Iotag is in here
         */
        struct lpfc_iocbq cur_iocbq;
+       wait_queue_head_t *waitq;
 };
 
 #define LPFC_SCSI_DMA_EXT_SIZE 264
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to