aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/a3000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/a3000.c')
-rw-r--r--drivers/scsi/a3000.c76
1 files changed, 41 insertions, 35 deletions
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 7f09d89100a1..d9468027fb61 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -17,11 +17,16 @@
17#include "a3000.h" 17#include "a3000.h"
18 18
19 19
20struct a3000_hostdata {
21 struct WD33C93_hostdata wh;
22 struct a3000_scsiregs *regs;
23};
24
20static irqreturn_t a3000_intr(int irq, void *data) 25static irqreturn_t a3000_intr(int irq, void *data)
21{ 26{
22 struct Scsi_Host *instance = data; 27 struct Scsi_Host *instance = data;
23 struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); 28 struct a3000_hostdata *hdata = shost_priv(instance);
24 unsigned int status = regs->ISTR; 29 unsigned int status = hdata->regs->ISTR;
25 unsigned long flags; 30 unsigned long flags;
26 31
27 if (!(status & ISTR_INT_P)) 32 if (!(status & ISTR_INT_P))
@@ -39,8 +44,9 @@ static irqreturn_t a3000_intr(int irq, void *data)
39static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 44static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
40{ 45{
41 struct Scsi_Host *instance = cmd->device->host; 46 struct Scsi_Host *instance = cmd->device->host;
42 struct WD33C93_hostdata *hdata = shost_priv(instance); 47 struct a3000_hostdata *hdata = shost_priv(instance);
43 struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); 48 struct WD33C93_hostdata *wh = &hdata->wh;
49 struct a3000_scsiregs *regs = hdata->regs;
44 unsigned short cntr = CNTR_PDMD | CNTR_INTEN; 50 unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
45 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 51 unsigned long addr = virt_to_bus(cmd->SCp.ptr);
46 52
@@ -51,23 +57,23 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
51 * buffer 57 * buffer
52 */ 58 */
53 if (addr & A3000_XFER_MASK) { 59 if (addr & A3000_XFER_MASK) {
54 hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; 60 wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff;
55 hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, 61 wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
56 GFP_KERNEL); 62 GFP_KERNEL);
57 63
58 /* can't allocate memory; use PIO */ 64 /* can't allocate memory; use PIO */
59 if (!hdata->dma_bounce_buffer) { 65 if (!wh->dma_bounce_buffer) {
60 hdata->dma_bounce_len = 0; 66 wh->dma_bounce_len = 0;
61 return 1; 67 return 1;
62 } 68 }
63 69
64 if (!dir_in) { 70 if (!dir_in) {
65 /* copy to bounce buffer for a write */ 71 /* copy to bounce buffer for a write */
66 memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, 72 memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr,
67 cmd->SCp.this_residual); 73 cmd->SCp.this_residual);
68 } 74 }
69 75
70 addr = virt_to_bus(hdata->dma_bounce_buffer); 76 addr = virt_to_bus(wh->dma_bounce_buffer);
71 } 77 }
72 78
73 /* setup dma direction */ 79 /* setup dma direction */
@@ -75,7 +81,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
75 cntr |= CNTR_DDIR; 81 cntr |= CNTR_DDIR;
76 82
77 /* remember direction */ 83 /* remember direction */
78 hdata->dma_dir = dir_in; 84 wh->dma_dir = dir_in;
79 85
80 regs->CNTR = cntr; 86 regs->CNTR = cntr;
81 87
@@ -102,20 +108,21 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
102static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 108static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
103 int status) 109 int status)
104{ 110{
105 struct WD33C93_hostdata *hdata = shost_priv(instance); 111 struct a3000_hostdata *hdata = shost_priv(instance);
106 struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); 112 struct WD33C93_hostdata *wh = &hdata->wh;
113 struct a3000_scsiregs *regs = hdata->regs;
107 114
108 /* disable SCSI interrupts */ 115 /* disable SCSI interrupts */
109 unsigned short cntr = CNTR_PDMD; 116 unsigned short cntr = CNTR_PDMD;
110 117
111 if (!hdata->dma_dir) 118 if (!wh->dma_dir)
112 cntr |= CNTR_DDIR; 119 cntr |= CNTR_DDIR;
113 120
114 regs->CNTR = cntr; 121 regs->CNTR = cntr;
115 mb(); /* make sure CNTR is updated before next IO */ 122 mb(); /* make sure CNTR is updated before next IO */
116 123
117 /* flush if we were reading */ 124 /* flush if we were reading */
118 if (hdata->dma_dir) { 125 if (wh->dma_dir) {
119 regs->FLUSH = 1; 126 regs->FLUSH = 1;
120 mb(); /* don't allow prefetch */ 127 mb(); /* don't allow prefetch */
121 while (!(regs->ISTR & ISTR_FE_FLG)) 128 while (!(regs->ISTR & ISTR_FE_FLG))
@@ -138,19 +145,18 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
138 mb(); /* make sure CNTR is updated before next IO */ 145 mb(); /* make sure CNTR is updated before next IO */
139 146
140 /* copy from a bounce buffer, if necessary */ 147 /* copy from a bounce buffer, if necessary */
141 if (status && hdata->dma_bounce_buffer) { 148 if (status && wh->dma_bounce_buffer) {
142 if (SCpnt) { 149 if (SCpnt) {
143 if (hdata->dma_dir && SCpnt) 150 if (wh->dma_dir && SCpnt)
144 memcpy(SCpnt->SCp.ptr, 151 memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer,
145 hdata->dma_bounce_buffer,
146 SCpnt->SCp.this_residual); 152 SCpnt->SCp.this_residual);
147 kfree(hdata->dma_bounce_buffer); 153 kfree(wh->dma_bounce_buffer);
148 hdata->dma_bounce_buffer = NULL; 154 wh->dma_bounce_buffer = NULL;
149 hdata->dma_bounce_len = 0; 155 wh->dma_bounce_len = 0;
150 } else { 156 } else {
151 kfree(hdata->dma_bounce_buffer); 157 kfree(wh->dma_bounce_buffer);
152 hdata->dma_bounce_buffer = NULL; 158 wh->dma_bounce_buffer = NULL;
153 hdata->dma_bounce_len = 0; 159 wh->dma_bounce_len = 0;
154 } 160 }
155 } 161 }
156} 162}
@@ -194,7 +200,7 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)
194 int error; 200 int error;
195 struct a3000_scsiregs *regs; 201 struct a3000_scsiregs *regs;
196 wd33c93_regs wdregs; 202 wd33c93_regs wdregs;
197 struct WD33C93_hostdata *hdata; 203 struct a3000_hostdata *hdata;
198 204
199 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 205 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
200 if (!res) 206 if (!res)
@@ -204,25 +210,25 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)
204 return -EBUSY; 210 return -EBUSY;
205 211
206 instance = scsi_host_alloc(&amiga_a3000_scsi_template, 212 instance = scsi_host_alloc(&amiga_a3000_scsi_template,
207 sizeof(struct WD33C93_hostdata)); 213 sizeof(struct a3000_hostdata));
208 if (!instance) { 214 if (!instance) {
209 error = -ENOMEM; 215 error = -ENOMEM;
210 goto fail_alloc; 216 goto fail_alloc;
211 } 217 }
212 218
213 instance->base = ZTWO_VADDR(res->start);
214 instance->irq = IRQ_AMIGA_PORTS; 219 instance->irq = IRQ_AMIGA_PORTS;
215 220
216 regs = (struct a3000_scsiregs *)(instance->base); 221 regs = (struct a3000_scsiregs *)ZTWO_VADDR(res->start);
217 regs->DAWR = DAWR_A3000; 222 regs->DAWR = DAWR_A3000;
218 223
219 wdregs.SASR = &regs->SASR; 224 wdregs.SASR = &regs->SASR;
220 wdregs.SCMD = &regs->SCMD; 225 wdregs.SCMD = &regs->SCMD;
221 226
222 hdata = shost_priv(instance); 227 hdata = shost_priv(instance);
223 hdata->no_sync = 0xff; 228 hdata->wh.no_sync = 0xff;
224 hdata->fast = 0; 229 hdata->wh.fast = 0;
225 hdata->dma_mode = CTRL_DMA; 230 hdata->wh.dma_mode = CTRL_DMA;
231 hdata->regs = regs;
226 232
227 wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_12_15); 233 wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_12_15);
228 error = request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, 234 error = request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED,
@@ -253,10 +259,10 @@ fail_alloc:
253static int __exit amiga_a3000_scsi_remove(struct platform_device *pdev) 259static int __exit amiga_a3000_scsi_remove(struct platform_device *pdev)
254{ 260{
255 struct Scsi_Host *instance = platform_get_drvdata(pdev); 261 struct Scsi_Host *instance = platform_get_drvdata(pdev);
256 struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); 262 struct a3000_hostdata *hdata = shost_priv(instance);
257 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 263 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
258 264
259 regs->CNTR = 0; 265 hdata->regs->CNTR = 0;
260 scsi_remove_host(instance); 266 scsi_remove_host(instance);
261 free_irq(IRQ_AMIGA_PORTS, instance); 267 free_irq(IRQ_AMIGA_PORTS, instance);
262 scsi_host_put(instance); 268 scsi_host_put(instance);