aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/arm/cumana_1.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-07-20 05:38:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-07-20 16:29:33 -0400
commit8b801ead3d7ab3cce991ea3a2d00c7336215fc7d (patch)
treee06f5378ebd8ecd67ec28ec2ed32d6ca39d291be /drivers/scsi/arm/cumana_1.c
parent13d5fadf45d12786b90916e95e97f593e91aaf0a (diff)
[ARM] rpc: update Acorn SCSI drivers to modern ecard interfaces
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/scsi/arm/cumana_1.c')
-rw-r--r--drivers/scsi/arm/cumana_1.c207
1 files changed, 100 insertions, 107 deletions
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index cf9a21cea6d9..49d838e90a24 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -24,7 +24,7 @@
24 24
25#define CUMANASCSI_PUBLIC_RELEASE 1 25#define CUMANASCSI_PUBLIC_RELEASE 1
26 26
27#define NCR5380_implementation_fields int port, ctrl 27#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
28#define NCR5380_local_declare() struct Scsi_Host *_instance 28#define NCR5380_local_declare() struct Scsi_Host *_instance
29#define NCR5380_setup(instance) _instance = instance 29#define NCR5380_setup(instance) _instance = instance
30#define NCR5380_read(reg) cumanascsi_read(_instance, reg) 30#define NCR5380_read(reg) cumanascsi_read(_instance, reg)
@@ -33,6 +33,11 @@
33#define NCR5380_queue_command cumanascsi_queue_command 33#define NCR5380_queue_command cumanascsi_queue_command
34#define NCR5380_proc_info cumanascsi_proc_info 34#define NCR5380_proc_info cumanascsi_proc_info
35 35
36#define NCR5380_implementation_fields \
37 unsigned ctrl; \
38 void __iomem *base; \
39 void __iomem *dma
40
36#define BOARD_NORMAL 0 41#define BOARD_NORMAL 0
37#define BOARD_NCR53C400 1 42#define BOARD_NCR53C400 1
38 43
@@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt)
47 return ""; 52 return "";
48} 53}
49 54
50#ifdef NOT_EFFICIENT 55#define CTRL 0x16fc
51#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) 56#define STAT 0x2004
52#define STAT(p) inb((p)+1) 57#define L(v) (((v)<<16)|((v) & 0x0000ffff))
53#define IN(p) inb((p)) 58#define H(v) (((v)>>16)|((v) & 0xffff0000))
54#define OUT(v,p) outb((v), (p))
55#else
56#define CTRL(p,v) (p[-2308] = (*ctrl = (v)))
57#define STAT(p) (p[4])
58#define IN(p) (*(p))
59#define IN2(p) ((unsigned short)(*(volatile unsigned long *)(p)))
60#define OUT(v,p) (*(p) = (v))
61#define OUT2(v,p) (*((volatile unsigned long *)(p)) = (v))
62#endif
63#define L(v) (((v)<<16)|((v) & 0x0000ffff))
64#define H(v) (((v)>>16)|((v) & 0xffff0000))
65 59
66static inline int 60static inline int
67NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len) 61NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
68{ 62{
69 int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
70 int oldctrl = *ctrl;
71 unsigned long *laddr; 63 unsigned long *laddr;
72#ifdef NOT_EFFICIENT 64 void __iomem *dma = priv(host)->dma + 0x2000;
73 int iobase = instance->io_port;
74 int dma_io = iobase & ~(0x3C0000>>2);
75#else
76 volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port);
77 volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000);
78#endif
79 65
80 if(!len) return 0; 66 if(!len) return 0;
81 67
82 CTRL(iobase, 0x02); 68 writeb(0x02, priv(host)->base + CTRL);
83 laddr = (unsigned long *)addr; 69 laddr = (unsigned long *)addr;
84 while(len >= 32) 70 while(len >= 32)
85 { 71 {
86 int status; 72 unsigned int status;
87 unsigned long v; 73 unsigned long v;
88 status = STAT(iobase); 74 status = readb(priv(host)->base + STAT);
89 if(status & 0x80) 75 if(status & 0x80)
90 goto end; 76 goto end;
91 if(!(status & 0x40)) 77 if(!(status & 0x40))
92 continue; 78 continue;
93 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 79 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
94 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 80 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
95 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 81 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
96 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 82 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
97 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 83 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
98 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 84 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
99 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 85 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
100 v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); 86 v=*laddr++; writew(L(v), dma); writew(H(v), dma);
101 len -= 32; 87 len -= 32;
102 if(len == 0) 88 if(len == 0)
103 break; 89 break;
104 } 90 }
105 91
106 addr = (unsigned char *)laddr; 92 addr = (unsigned char *)laddr;
107 CTRL(iobase, 0x12); 93 writeb(0x12, priv(host)->base + CTRL);
94
108 while(len > 0) 95 while(len > 0)
109 { 96 {
110 int status; 97 unsigned int status;
111 status = STAT(iobase); 98 status = readb(priv(host)->base + STAT);
112 if(status & 0x80) 99 if(status & 0x80)
113 goto end; 100 goto end;
114 if(status & 0x40) 101 if(status & 0x40)
115 { 102 {
116 OUT(*addr++, dma_io); 103 writeb(*addr++, dma);
117 if(--len == 0) 104 if(--len == 0)
118 break; 105 break;
119 } 106 }
120 107
121 status = STAT(iobase); 108 status = readb(priv(host)->base + STAT);
122 if(status & 0x80) 109 if(status & 0x80)
123 goto end; 110 goto end;
124 if(status & 0x40) 111 if(status & 0x40)
125 { 112 {
126 OUT(*addr++, dma_io); 113 writeb(*addr++, dma);
127 if(--len == 0) 114 if(--len == 0)
128 break; 115 break;
129 } 116 }
130 } 117 }
131end: 118end:
132 CTRL(iobase, oldctrl|0x40); 119 writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
133 return len; 120 return len;
134} 121}
135 122
136static inline int 123static inline int
137NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len) 124NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
138{ 125{
139 int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
140 int oldctrl = *ctrl;
141 unsigned long *laddr; 126 unsigned long *laddr;
142#ifdef NOT_EFFICIENT 127 void __iomem *dma = priv(host)->dma + 0x2000;
143 int iobase = instance->io_port;
144 int dma_io = iobase & ~(0x3C0000>>2);
145#else
146 volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port);
147 volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000);
148#endif
149 128
150 if(!len) return 0; 129 if(!len) return 0;
151 130
152 CTRL(iobase, 0x00); 131 writeb(0x00, priv(host)->base + CTRL);
153 laddr = (unsigned long *)addr; 132 laddr = (unsigned long *)addr;
154 while(len >= 32) 133 while(len >= 32)
155 { 134 {
156 int status; 135 unsigned int status;
157 status = STAT(iobase); 136 status = readb(priv(host)->base + STAT);
158 if(status & 0x80) 137 if(status & 0x80)
159 goto end; 138 goto end;
160 if(!(status & 0x40)) 139 if(!(status & 0x40))
161 continue; 140 continue;
162 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 141 *laddr++ = readw(dma) | (readw(dma) << 16);
163 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 142 *laddr++ = readw(dma) | (readw(dma) << 16);
164 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 143 *laddr++ = readw(dma) | (readw(dma) << 16);
165 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 144 *laddr++ = readw(dma) | (readw(dma) << 16);
166 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 145 *laddr++ = readw(dma) | (readw(dma) << 16);
167 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 146 *laddr++ = readw(dma) | (readw(dma) << 16);
168 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 147 *laddr++ = readw(dma) | (readw(dma) << 16);
169 *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); 148 *laddr++ = readw(dma) | (readw(dma) << 16);
170 len -= 32; 149 len -= 32;
171 if(len == 0) 150 if(len == 0)
172 break; 151 break;
173 } 152 }
174 153
175 addr = (unsigned char *)laddr; 154 addr = (unsigned char *)laddr;
176 CTRL(iobase, 0x10); 155 writeb(0x10, priv(host)->base + CTRL);
156
177 while(len > 0) 157 while(len > 0)
178 { 158 {
179 int status; 159 unsigned int status;
180 status = STAT(iobase); 160 status = readb(priv(host)->base + STAT);
181 if(status & 0x80) 161 if(status & 0x80)
182 goto end; 162 goto end;
183 if(status & 0x40) 163 if(status & 0x40)
184 { 164 {
185 *addr++ = IN(dma_io); 165 *addr++ = readb(dma);
186 if(--len == 0) 166 if(--len == 0)
187 break; 167 break;
188 } 168 }
189 169
190 status = STAT(iobase); 170 status = readb(priv(host)->base + STAT);
191 if(status & 0x80) 171 if(status & 0x80)
192 goto end; 172 goto end;
193 if(status & 0x40) 173 if(status & 0x40)
194 { 174 {
195 *addr++ = IN(dma_io); 175 *addr++ = readb(dma);
196 if(--len == 0) 176 if(--len == 0)
197 break; 177 break;
198 } 178 }
199 } 179 }
200end: 180end:
201 CTRL(iobase, oldctrl|0x40); 181 writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
202 return len; 182 return len;
203} 183}
204 184
205#undef STAT 185static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
206#undef CTRL 186{
207#undef IN 187 void __iomem *base = priv(host)->base;
208#undef OUT 188 unsigned char val;
209 189
210#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) 190 writeb(0, base + CTRL);
211 191
212static char cumanascsi_read(struct Scsi_Host *instance, int reg) 192 val = readb(base + 0x2100 + (reg << 2));
213{
214 unsigned int iobase = instance->io_port;
215 int i;
216 int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
217 193
218 CTRL(iobase, 0); 194 priv(host)->ctrl = 0x40;
219 i = inb(iobase + 64 + reg); 195 writeb(0x40, base + CTRL);
220 CTRL(iobase, 0x40);
221 196
222 return i; 197 return val;
223} 198}
224 199
225static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value) 200static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value)
226{ 201{
227 int iobase = instance->io_port; 202 void __iomem *base = priv(host)->base;
228 int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
229 203
230 CTRL(iobase, 0); 204 writeb(0, base + CTRL);
231 outb(value, iobase + 64 + reg);
232 CTRL(iobase, 0x40);
233}
234 205
235#undef CTRL 206 writeb(value, base + 0x2100 + (reg << 2));
207
208 priv(host)->ctrl = 0x40;
209 writeb(0x40, base + CTRL);
210}
236 211
237#include "../NCR5380.c" 212#include "../NCR5380.c"
238 213
@@ -256,32 +231,46 @@ static int __devinit
256cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) 231cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
257{ 232{
258 struct Scsi_Host *host; 233 struct Scsi_Host *host;
259 int ret = -ENOMEM; 234 int ret;
260 235
261 host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); 236 ret = ecard_request_resources(ec);
262 if (!host) 237 if (ret)
263 goto out; 238 goto out;
264 239
265 host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800; 240 host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
241 if (!host) {
242 ret = -ENOMEM;
243 goto out_release;
244 }
245
246 priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
247 ecard_resource_len(ec, ECARD_RES_IOCSLOW));
248 priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
249 ecard_resource_len(ec, ECARD_RES_MEMC));
250 if (!priv(host)->base || !priv(host)->dma) {
251 ret = -ENOMEM;
252 goto out_unmap;
253 }
254
266 host->irq = ec->irq; 255 host->irq = ec->irq;
267 256
268 NCR5380_init(host, 0); 257 NCR5380_init(host, 0);
269 258
259 priv(host)->ctrl = 0;
260 writeb(0, priv(host)->base + CTRL);
261
270 host->n_io_port = 255; 262 host->n_io_port = 255;
271 if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { 263 if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
272 ret = -EBUSY; 264 ret = -EBUSY;
273 goto out_free; 265 goto out_unmap;
274 } 266 }
275 267
276 ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0;
277 outb(0x00, host->io_port - 577);
278
279 ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED, 268 ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED,
280 "CumanaSCSI-1", host); 269 "CumanaSCSI-1", host);
281 if (ret) { 270 if (ret) {
282 printk("scsi%d: IRQ%d not free: %d\n", 271 printk("scsi%d: IRQ%d not free: %d\n",
283 host->host_no, host->irq, ret); 272 host->host_no, host->irq, ret);
284 goto out_release; 273 goto out_unmap;
285 } 274 }
286 275
287 printk("scsi%d: at port 0x%08lx irq %d", 276 printk("scsi%d: at port 0x%08lx irq %d",
@@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
301 290
302 out_free_irq: 291 out_free_irq:
303 free_irq(host->irq, host); 292 free_irq(host->irq, host);
304 out_release: 293 out_unmap:
305 release_region(host->io_port, host->n_io_port); 294 iounmap(priv(host)->base);
306 out_free: 295 iounmap(priv(host)->dma);
307 scsi_host_put(host); 296 scsi_host_put(host);
297 out_release:
298 ecard_release_resources(ec);
308 out: 299 out:
309 return ret; 300 return ret;
310} 301}
@@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec)
318 scsi_remove_host(host); 309 scsi_remove_host(host);
319 free_irq(host->irq, host); 310 free_irq(host->irq, host);
320 NCR5380_exit(host); 311 NCR5380_exit(host);
321 release_region(host->io_port, host->n_io_port); 312 iounmap(priv(host)->base);
313 iounmap(priv(host)->dma);
322 scsi_host_put(host); 314 scsi_host_put(host);
315 ecard_release_resources(ec);
323} 316}
324 317
325static const struct ecard_id cumanascsi1_cids[] = { 318static const struct ecard_id cumanascsi1_cids[] = {