diff options
-rw-r--r-- | drivers/scsi/a3000.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 31434f7c3685..bc6eb69f5fd0 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | 24 | ||
25 | #define DMA(ptr) ((a3000_scsiregs *)((ptr)->base)) | 25 | #define DMA(ptr) ((a3000_scsiregs *)((ptr)->base)) |
26 | #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) | ||
27 | 26 | ||
28 | static struct Scsi_Host *a3000_host = NULL; | 27 | static struct Scsi_Host *a3000_host = NULL; |
29 | 28 | ||
@@ -48,6 +47,7 @@ static irqreturn_t a3000_intr(int irq, void *dummy) | |||
48 | 47 | ||
49 | static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | 48 | static int dma_setup(struct scsi_cmnd *cmd, int dir_in) |
50 | { | 49 | { |
50 | struct WD33C93_hostdata *hdata = shost_priv(a3000_host); | ||
51 | unsigned short cntr = CNTR_PDMD | CNTR_INTEN; | 51 | unsigned short cntr = CNTR_PDMD | CNTR_INTEN; |
52 | unsigned long addr = virt_to_bus(cmd->SCp.ptr); | 52 | unsigned long addr = virt_to_bus(cmd->SCp.ptr); |
53 | 53 | ||
@@ -58,24 +58,23 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
58 | * buffer | 58 | * buffer |
59 | */ | 59 | */ |
60 | if (addr & A3000_XFER_MASK) { | 60 | if (addr & A3000_XFER_MASK) { |
61 | HDATA(a3000_host)->dma_bounce_len = | 61 | hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; |
62 | (cmd->SCp.this_residual + 511) & ~0x1ff; | 62 | hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, |
63 | HDATA(a3000_host)->dma_bounce_buffer = | 63 | GFP_KERNEL); |
64 | kmalloc(HDATA(a3000_host)->dma_bounce_len, GFP_KERNEL); | ||
65 | 64 | ||
66 | /* can't allocate memory; use PIO */ | 65 | /* can't allocate memory; use PIO */ |
67 | if (!HDATA(a3000_host)->dma_bounce_buffer) { | 66 | if (!hdata->dma_bounce_buffer) { |
68 | HDATA(a3000_host)->dma_bounce_len = 0; | 67 | hdata->dma_bounce_len = 0; |
69 | return 1; | 68 | return 1; |
70 | } | 69 | } |
71 | 70 | ||
72 | if (!dir_in) { | 71 | if (!dir_in) { |
73 | /* copy to bounce buffer for a write */ | 72 | /* copy to bounce buffer for a write */ |
74 | memcpy(HDATA(a3000_host)->dma_bounce_buffer, | 73 | memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, |
75 | cmd->SCp.ptr, cmd->SCp.this_residual); | 74 | cmd->SCp.this_residual); |
76 | } | 75 | } |
77 | 76 | ||
78 | addr = virt_to_bus(HDATA(a3000_host)->dma_bounce_buffer); | 77 | addr = virt_to_bus(hdata->dma_bounce_buffer); |
79 | } | 78 | } |
80 | 79 | ||
81 | /* setup dma direction */ | 80 | /* setup dma direction */ |
@@ -83,7 +82,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
83 | cntr |= CNTR_DDIR; | 82 | cntr |= CNTR_DDIR; |
84 | 83 | ||
85 | /* remember direction */ | 84 | /* remember direction */ |
86 | HDATA(a3000_host)->dma_dir = dir_in; | 85 | hdata->dma_dir = dir_in; |
87 | 86 | ||
88 | DMA(a3000_host)->CNTR = cntr; | 87 | DMA(a3000_host)->CNTR = cntr; |
89 | 88 | ||
@@ -110,17 +109,19 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
110 | static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | 109 | static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, |
111 | int status) | 110 | int status) |
112 | { | 111 | { |
112 | struct WD33C93_hostdata *hdata = shost_priv(instance); | ||
113 | |||
113 | /* disable SCSI interrupts */ | 114 | /* disable SCSI interrupts */ |
114 | unsigned short cntr = CNTR_PDMD; | 115 | unsigned short cntr = CNTR_PDMD; |
115 | 116 | ||
116 | if (!HDATA(instance)->dma_dir) | 117 | if (!hdata->dma_dir) |
117 | cntr |= CNTR_DDIR; | 118 | cntr |= CNTR_DDIR; |
118 | 119 | ||
119 | DMA(instance)->CNTR = cntr; | 120 | DMA(instance)->CNTR = cntr; |
120 | mb(); /* make sure CNTR is updated before next IO */ | 121 | mb(); /* make sure CNTR is updated before next IO */ |
121 | 122 | ||
122 | /* flush if we were reading */ | 123 | /* flush if we were reading */ |
123 | if (HDATA(instance)->dma_dir) { | 124 | if (hdata->dma_dir) { |
124 | DMA(instance)->FLUSH = 1; | 125 | DMA(instance)->FLUSH = 1; |
125 | mb(); /* don't allow prefetch */ | 126 | mb(); /* don't allow prefetch */ |
126 | while (!(DMA(instance)->ISTR & ISTR_FE_FLG)) | 127 | while (!(DMA(instance)->ISTR & ISTR_FE_FLG)) |
@@ -143,19 +144,19 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | |||
143 | mb(); /* make sure CNTR is updated before next IO */ | 144 | mb(); /* make sure CNTR is updated before next IO */ |
144 | 145 | ||
145 | /* copy from a bounce buffer, if necessary */ | 146 | /* copy from a bounce buffer, if necessary */ |
146 | if (status && HDATA(instance)->dma_bounce_buffer) { | 147 | if (status && hdata->dma_bounce_buffer) { |
147 | if (SCpnt) { | 148 | if (SCpnt) { |
148 | if (HDATA(instance)->dma_dir && SCpnt) | 149 | if (hdata->dma_dir && SCpnt) |
149 | memcpy(SCpnt->SCp.ptr, | 150 | memcpy(SCpnt->SCp.ptr, |
150 | HDATA(instance)->dma_bounce_buffer, | 151 | hdata->dma_bounce_buffer, |
151 | SCpnt->SCp.this_residual); | 152 | SCpnt->SCp.this_residual); |
152 | kfree(HDATA(instance)->dma_bounce_buffer); | 153 | kfree(hdata->dma_bounce_buffer); |
153 | HDATA(instance)->dma_bounce_buffer = NULL; | 154 | hdata->dma_bounce_buffer = NULL; |
154 | HDATA(instance)->dma_bounce_len = 0; | 155 | hdata->dma_bounce_len = 0; |
155 | } else { | 156 | } else { |
156 | kfree(HDATA(instance)->dma_bounce_buffer); | 157 | kfree(hdata->dma_bounce_buffer); |
157 | HDATA(instance)->dma_bounce_buffer = NULL; | 158 | hdata->dma_bounce_buffer = NULL; |
158 | HDATA(instance)->dma_bounce_len = 0; | 159 | hdata->dma_bounce_len = 0; |
159 | } | 160 | } |
160 | } | 161 | } |
161 | } | 162 | } |
@@ -163,6 +164,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | |||
163 | static int __init a3000_detect(struct scsi_host_template *tpnt) | 164 | static int __init a3000_detect(struct scsi_host_template *tpnt) |
164 | { | 165 | { |
165 | wd33c93_regs regs; | 166 | wd33c93_regs regs; |
167 | struct WD33C93_hostdata *hdata; | ||
166 | 168 | ||
167 | if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) | 169 | if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) |
168 | return 0; | 170 | return 0; |
@@ -181,9 +183,10 @@ static int __init a3000_detect(struct scsi_host_template *tpnt) | |||
181 | DMA(a3000_host)->DAWR = DAWR_A3000; | 183 | DMA(a3000_host)->DAWR = DAWR_A3000; |
182 | regs.SASR = &(DMA(a3000_host)->SASR); | 184 | regs.SASR = &(DMA(a3000_host)->SASR); |
183 | regs.SCMD = &(DMA(a3000_host)->SCMD); | 185 | regs.SCMD = &(DMA(a3000_host)->SCMD); |
184 | HDATA(a3000_host)->no_sync = 0xff; | 186 | hdata = shost_priv(a3000_host); |
185 | HDATA(a3000_host)->fast = 0; | 187 | hdata->no_sync = 0xff; |
186 | HDATA(a3000_host)->dma_mode = CTRL_DMA; | 188 | hdata->fast = 0; |
189 | hdata->dma_mode = CTRL_DMA; | ||
187 | wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); | 190 | wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); |
188 | if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", | 191 | if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", |
189 | a3000_intr)) | 192 | a3000_intr)) |