diff options
author | Matthew Wilcox <matthew@wil.cx> | 2006-03-29 16:45:18 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-04-13 11:13:30 -0400 |
commit | d637c4543fdc86cbef5805c679d24bb665172a7d (patch) | |
tree | 45ed36215b8e2623e75d02ab76ff2e50a3e937a0 /drivers/scsi | |
parent | 80286d478c2b0e07959e79cf34591a4061ff1797 (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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 20 |
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 | */ |
142 | struct sym_ucmd { /* Override the SCSI pointer structure */ | 142 | struct 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 | } |