From d637c4543fdc86cbef5805c679d24bb665172a7d Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 29 Mar 2006 14:45:18 -0700 Subject: [SCSI] sym2: Fix build when spinlock debugging is enabled When spinlock debugging is turned on, a struct completion grows beyond the size allowed for the scsi_pointer. So move the struct completion back onto the stack. The additional memory barriers are to keep us from completing a random piece of kernel stack if the command happens to complete after the error handling has finished. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/sym53c8xx_2/sym_glue.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/scsi/sym53c8xx_2') diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 2c4e5f1e7a94..9c83b4d39a26 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -140,11 +140,11 @@ 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 */ - struct completion done; - void (*old_done)(struct scsi_cmnd *); - dma_addr_t data_mapping; - int to_do; - u_char data_mapped; /* corresponds to data_mapping above */ + dma_addr_t data_mapping; + unsigned char data_mapped; + unsigned char to_do; /* For error handling */ + void (*old_done)(struct scsi_cmnd *); /* For error handling */ + struct completion *eh_done; /* For error handling */ }; #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) @@ -713,7 +713,7 @@ static void sym_eh_done(struct scsi_cmnd *cmd) cmd->scsi_done = ucmd->old_done; if (ucmd->to_do == SYM_EH_DO_WAIT) - complete(&ucmd->done); + complete(ucmd->eh_done); } /* @@ -728,6 +728,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) SYM_QUEHEAD *qp; int to_do = SYM_EH_DO_IGNORE; int sts = -1; + struct completion eh_done; dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname); @@ -742,8 +743,10 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) } if (to_do == SYM_EH_DO_WAIT) { - init_completion(&ucmd->done); + init_completion(&eh_done); ucmd->old_done = cmd->scsi_done; + ucmd->eh_done = &eh_done; + wmb(); cmd->scsi_done = sym_eh_done; } @@ -779,8 +782,9 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) spin_unlock_irq(host->host_lock); if (to_do == SYM_EH_DO_WAIT) { - if (!wait_for_completion_timeout(&ucmd->done, 5*HZ)) { + if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { ucmd->to_do = SYM_EH_DO_IGNORE; + wmb(); sts = -2; } } -- cgit v1.2.3