aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2006-03-29 16:45:18 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-04-13 11:13:30 -0400
commitd637c4543fdc86cbef5805c679d24bb665172a7d (patch)
tree45ed36215b8e2623e75d02ab76ff2e50a3e937a0
parent80286d478c2b0e07959e79cf34591a4061ff1797 (diff)
[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 <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c20
1 files changed, 12 insertions, 8 deletions
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;
140 * Driver private area in the SCSI command structure. 140 * Driver private area in the SCSI command structure.
141 */ 141 */
142struct sym_ucmd { /* Override the SCSI pointer structure */ 142struct sym_ucmd { /* Override the SCSI pointer structure */
143 struct completion done; 143 dma_addr_t data_mapping;
144 void (*old_done)(struct scsi_cmnd *); 144 unsigned char data_mapped;
145 dma_addr_t data_mapping; 145 unsigned char to_do; /* For error handling */
146 int to_do; 146 void (*old_done)(struct scsi_cmnd *); /* For error handling */
147 u_char data_mapped; /* corresponds to data_mapping above */ 147 struct completion *eh_done; /* For error handling */
148}; 148};
149 149
150#define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) 150#define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp))
@@ -713,7 +713,7 @@ static void sym_eh_done(struct scsi_cmnd *cmd)
713 cmd->scsi_done = ucmd->old_done; 713 cmd->scsi_done = ucmd->old_done;
714 714
715 if (ucmd->to_do == SYM_EH_DO_WAIT) 715 if (ucmd->to_do == SYM_EH_DO_WAIT)
716 complete(&ucmd->done); 716 complete(ucmd->eh_done);
717} 717}
718 718
719/* 719/*
@@ -728,6 +728,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
728 SYM_QUEHEAD *qp; 728 SYM_QUEHEAD *qp;
729 int to_do = SYM_EH_DO_IGNORE; 729 int to_do = SYM_EH_DO_IGNORE;
730 int sts = -1; 730 int sts = -1;
731 struct completion eh_done;
731 732
732 dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname); 733 dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname);
733 734
@@ -742,8 +743,10 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
742 } 743 }
743 744
744 if (to_do == SYM_EH_DO_WAIT) { 745 if (to_do == SYM_EH_DO_WAIT) {
745 init_completion(&ucmd->done); 746 init_completion(&eh_done);
746 ucmd->old_done = cmd->scsi_done; 747 ucmd->old_done = cmd->scsi_done;
748 ucmd->eh_done = &eh_done;
749 wmb();
747 cmd->scsi_done = sym_eh_done; 750 cmd->scsi_done = sym_eh_done;
748 } 751 }
749 752
@@ -779,8 +782,9 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
779 spin_unlock_irq(host->host_lock); 782 spin_unlock_irq(host->host_lock);
780 783
781 if (to_do == SYM_EH_DO_WAIT) { 784 if (to_do == SYM_EH_DO_WAIT) {
782 if (!wait_for_completion_timeout(&ucmd->done, 5*HZ)) { 785 if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {
783 ucmd->to_do = SYM_EH_DO_IGNORE; 786 ucmd->to_do = SYM_EH_DO_IGNORE;
787 wmb();
784 sts = -2; 788 sts = -2;
785 } 789 }
786 } 790 }