Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2ba65367720d871f9d955ca3ef96358999182765
Commit:     2ba65367720d871f9d955ca3ef96358999182765
Parent:     6c9746b363b8191587191518a65d5de93df80a92
Author:     Matthew Wilcox <[EMAIL PROTECTED]>
AuthorDate: Fri Oct 5 15:55:03 2007 -0400
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Tue Oct 23 15:09:41 2007 -0400

    [SCSI] sym53c8xx: Stop overriding scsi_done
    
    Instead of telling the reset routine that the command completed from
    sym_eh_done, do it from sym_xpt_done.  The 'to_do' element of the ucmd
    is redundant -- it serves only to tell whether eh_done is valid or not,
    and we can tell this by checking to see if it's NULL.
    
    Signed-off-by: Matthew Wilcox <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/sym53c8xx_2/sym_glue.c |   60 ++++++++++------------------------
 1 files changed, 18 insertions(+), 42 deletions(-)

diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c 
b/drivers/scsi/sym53c8xx_2/sym_glue.c
index b5e7c64..4de0692 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -134,8 +134,6 @@ static struct scsi_transport_template 
*sym2_transport_template = NULL;
  *  Driver private area in the SCSI command structure.
  */
 struct sym_ucmd {              /* Override the SCSI pointer structure */
-       unsigned char   to_do;                  /* For error handling */
-       void (*old_done)(struct scsi_cmnd *);   /* For error handling */
        struct completion *eh_done;             /* For error handling */
 };
 
@@ -147,6 +145,12 @@ struct sym_ucmd {          /* Override the SCSI pointer 
structure */
  */
 void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd)
 {
+       struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);
+       BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd));
+
+       if (ucmd->eh_done)
+               complete(ucmd->eh_done);
+
        scsi_dma_unmap(cmd);
        cmd->scsi_done(cmd);
 }
@@ -586,26 +590,6 @@ static void sym53c8xx_timer(unsigned long npref)
 #define SYM_EH_HOST_RESET      3
 
 /*
- *  What we will do regarding the involved SCSI command.
- */
-#define SYM_EH_DO_IGNORE       0
-#define SYM_EH_DO_WAIT         2
-
-/*
- *  scsi_done() alias when error recovery is in progress.
- */
-static void sym_eh_done(struct scsi_cmnd *cmd)
-{
-       struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);
-       BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd));
-
-       cmd->scsi_done = ucmd->old_done;
-
-       if (ucmd->to_do == SYM_EH_DO_WAIT)
-               complete(ucmd->eh_done);
-}
-
-/*
  *  Generic method for our eh processing.
  *  The 'op' argument tells what we have to do.
  */
@@ -615,7 +599,7 @@ static int sym_eh_handler(int op, char *opname, struct 
scsi_cmnd *cmd)
        struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);
        struct Scsi_Host *host = cmd->device->host;
        SYM_QUEHEAD *qp;
-       int to_do = SYM_EH_DO_IGNORE;
+       int cmd_queued = 0;
        int sts = -1;
        struct completion eh_done;
 
@@ -626,19 +610,11 @@ static int sym_eh_handler(int op, char *opname, struct 
scsi_cmnd *cmd)
        FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
                struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, 
link_ccbq);
                if (cp->cmd == cmd) {
-                       to_do = SYM_EH_DO_WAIT;
+                       cmd_queued = 1;
                        break;
                }
        }
 
-       if (to_do == SYM_EH_DO_WAIT) {
-               init_completion(&eh_done);
-               ucmd->old_done = cmd->scsi_done;
-               ucmd->eh_done = &eh_done;
-               wmb();
-               cmd->scsi_done = sym_eh_done;
-       }
-
        /* Try to proceed the operation we have been asked for */
        sts = -1;
        switch(op) {
@@ -662,21 +638,21 @@ static int sym_eh_handler(int op, char *opname, struct 
scsi_cmnd *cmd)
        }
 
        /* On error, restore everything and cross fingers :) */
-       if (sts) {
-               cmd->scsi_done = ucmd->old_done;
-               to_do = SYM_EH_DO_IGNORE;
-       }
-
-       ucmd->to_do = to_do;
-       spin_unlock_irq(host->host_lock);
+       if (sts)
+               cmd_queued = 0;
 
-       if (to_do == SYM_EH_DO_WAIT) {
+       if (cmd_queued) {
+               init_completion(&eh_done);
+               ucmd->eh_done = &eh_done;
+               spin_unlock_irq(host->host_lock);
                if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {
-                       ucmd->to_do = SYM_EH_DO_IGNORE;
-                       wmb();
+                       ucmd->eh_done = NULL;
                        sts = -2;
                }
+       } else {
+               spin_unlock_irq(host->host_lock);
        }
+
        dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname,
                        sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
        return sts ? SCSI_FAILED : SCSI_SUCCESS;
-
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