Commit 2ba65367 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by James Bottomley

[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: default avatarMatthew Wilcox <willy@linux.intel.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 6c9746b3
...@@ -134,8 +134,6 @@ static struct scsi_transport_template *sym2_transport_template = NULL; ...@@ -134,8 +134,6 @@ static struct scsi_transport_template *sym2_transport_template = NULL;
* Driver private area in the SCSI command structure. * Driver private area in the SCSI command structure.
*/ */
struct sym_ucmd { /* Override the SCSI pointer 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 */ struct completion *eh_done; /* For error handling */
}; };
...@@ -147,6 +145,12 @@ struct sym_ucmd { /* Override the SCSI pointer structure */ ...@@ -147,6 +145,12 @@ struct sym_ucmd { /* Override the SCSI pointer structure */
*/ */
void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd) 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); scsi_dma_unmap(cmd);
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
} }
...@@ -585,26 +589,6 @@ static void sym53c8xx_timer(unsigned long npref) ...@@ -585,26 +589,6 @@ static void sym53c8xx_timer(unsigned long npref)
#define SYM_EH_BUS_RESET 2 #define SYM_EH_BUS_RESET 2
#define SYM_EH_HOST_RESET 3 #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. * Generic method for our eh processing.
* The 'op' argument tells what we have to do. * 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) ...@@ -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 sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);
struct Scsi_Host *host = cmd->device->host; struct Scsi_Host *host = cmd->device->host;
SYM_QUEHEAD *qp; SYM_QUEHEAD *qp;
int to_do = SYM_EH_DO_IGNORE; int cmd_queued = 0;
int sts = -1; int sts = -1;
struct completion eh_done; struct completion eh_done;
...@@ -626,19 +610,11 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) ...@@ -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) { FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
if (cp->cmd == cmd) { if (cp->cmd == cmd) {
to_do = SYM_EH_DO_WAIT; cmd_queued = 1;
break; 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 */ /* Try to proceed the operation we have been asked for */
sts = -1; sts = -1;
switch(op) { switch(op) {
...@@ -662,21 +638,21 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) ...@@ -662,21 +638,21 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
} }
/* On error, restore everything and cross fingers :) */ /* On error, restore everything and cross fingers :) */
if (sts) { if (sts)
cmd->scsi_done = ucmd->old_done; cmd_queued = 0;
to_do = SYM_EH_DO_IGNORE;
}
ucmd->to_do = to_do;
spin_unlock_irq(host->host_lock);
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)) { if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {
ucmd->to_do = SYM_EH_DO_IGNORE; ucmd->eh_done = NULL;
wmb();
sts = -2; sts = -2;
} }
} else {
spin_unlock_irq(host->host_lock);
} }
dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname,
sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
return sts ? SCSI_FAILED : SCSI_SUCCESS; return sts ? SCSI_FAILED : SCSI_SUCCESS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment