aboutsummaryrefslogtreecommitdiffstats
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
parent13d5fadf45d12786b90916e95e97f593e91aaf0a (diff)
[ARM] rpc: update Acorn SCSI drivers to modern ecard interfaces
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/scsi/arm/cumana_1.c207
-rw-r--r--drivers/scsi/arm/ecoscsi.c152
-rw-r--r--drivers/scsi/arm/oak.c74
3 files changed, 185 insertions, 248 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[] = {
diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
index 378e7af0c5d6..5265a9884338 100644
--- a/drivers/scsi/arm/ecoscsi.c
+++ b/drivers/scsi/arm/ecoscsi.c
@@ -34,35 +34,25 @@
34#include "../scsi.h" 34#include "../scsi.h"
35#include <scsi/scsi_host.h> 35#include <scsi/scsi_host.h>
36 36
37#define NCR5380_implementation_fields int port, ctrl 37#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
38#define NCR5380_local_declare() struct Scsi_Host *_instance
39#define NCR5380_setup(instance) _instance = instance
40 38
41#define NCR5380_read(reg) ecoscsi_read(_instance, reg) 39#define NCR5380_local_declare() void __iomem *_base
42#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value) 40#define NCR5380_setup(host) _base = priv(host)->base
41
42#define NCR5380_read(reg) ({ writeb(reg | 8, _base); readb(_base + 4); })
43#define NCR5380_write(reg, value) ({ writeb(reg | 8, _base); writeb(value, _base + 4); })
43 44
44#define NCR5380_intr ecoscsi_intr 45#define NCR5380_intr ecoscsi_intr
45#define NCR5380_queue_command ecoscsi_queue_command 46#define NCR5380_queue_command ecoscsi_queue_command
46#define NCR5380_proc_info ecoscsi_proc_info 47#define NCR5380_proc_info ecoscsi_proc_info
47 48
49#define NCR5380_implementation_fields \
50 void __iomem *base
51
48#include "../NCR5380.h" 52#include "../NCR5380.h"
49 53
50#define ECOSCSI_PUBLIC_RELEASE 1 54#define ECOSCSI_PUBLIC_RELEASE 1
51 55
52static char ecoscsi_read(struct Scsi_Host *instance, int reg)
53{
54 int iobase = instance->io_port;
55 outb(reg | 8, iobase);
56 return inb(iobase + 1);
57}
58
59static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value)
60{
61 int iobase = instance->io_port;
62 outb(reg | 8, iobase);
63 outb(value, iobase + 1);
64}
65
66/* 56/*
67 * Function : ecoscsi_setup(char *str, int *ints) 57 * Function : ecoscsi_setup(char *str, int *ints)
68 * 58 *
@@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt)
82 return ""; 72 return "";
83} 73}
84 74
85#if 0
86#define STAT(p) inw(p + 144)
87
88static inline int NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr,
89 int len)
90{
91 int iobase = host->io_port;
92printk("writing %p len %d\n",addr, len);
93 if(!len) return -1;
94
95 while(1)
96 {
97 int status;
98 while(((status = STAT(iobase)) & 0x100)==0);
99 }
100}
101
102static inline int NCR5380_pread(struct Scsi_Host *host, unsigned char *addr,
103 int len)
104{
105 int iobase = host->io_port;
106 int iobase2= host->io_port + 0x100;
107 unsigned char *start = addr;
108 int s;
109printk("reading %p len %d\n",addr, len);
110 outb(inb(iobase + 128), iobase + 135);
111 while(len > 0)
112 {
113 int status,b,i, timeout;
114 timeout = 0x07FFFFFF;
115 while(((status = STAT(iobase)) & 0x100)==0)
116 {
117 timeout--;
118 if(status & 0x200 || !timeout)
119 {
120 printk("status = %p\n",status);
121 outb(0, iobase + 135);
122 return 1;
123 }
124 }
125 if(len >= 128)
126 {
127 for(i=0; i<64; i++)
128 {
129 b = inw(iobase + 136);
130 *addr++ = b;
131 *addr++ = b>>8;
132 }
133 len -= 128;
134 }
135 else
136 {
137 b = inw(iobase + 136);
138 *addr ++ = b;
139 len -= 1;
140 if(len)
141 *addr ++ = b>>8;
142 len -= 1;
143 }
144 }
145 outb(0, iobase + 135);
146 printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start, start[1], start[2], start[3], start[4], start[5], start[6]);
147 return 1;
148}
149#endif
150#undef STAT
151
152#define BOARD_NORMAL 0 75#define BOARD_NORMAL 0
153#define BOARD_NCR53C400 1 76#define BOARD_NCR53C400 1
154 77
@@ -173,25 +96,36 @@ static struct Scsi_Host *host;
173 96
174static int __init ecoscsi_init(void) 97static int __init ecoscsi_init(void)
175{ 98{
99 void __iomem *_base;
100 int ret;
176 101
177 host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); 102 if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) {
178 if (!host) 103 ret = -EBUSY;
179 return 0; 104 goto out;
105 }
180 106
181 host->io_port = 0x80ce8000; 107 _base = ioremap(0x33a0000, 4096);
182 host->n_io_port = 144; 108 if (!_base) {
183 host->irq = IRQ_NONE; 109 ret = -ENOMEM;
110 goto out_release;
111 }
184 112
185 if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) ) 113 NCR5380_write(MODE_REG, 0x20); /* Is it really SCSI? */
186 goto unregister_scsi; 114 if (NCR5380_read(MODE_REG) != 0x20) /* Write to a reg. */
115 goto out_unmap;
187 116
188 ecoscsi_write(host, MODE_REG, 0x20); /* Is it really SCSI? */ 117 NCR5380_write(MODE_REG, 0x00); /* it back. */
189 if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg. */ 118 if (NCR5380_read(MODE_REG) != 0x00)
190 goto release_reg; 119 goto out_unmap;
191 120
192 ecoscsi_write(host, MODE_REG, 0x00 ); /* it back. */ 121 host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
193 if (ecoscsi_read(host, MODE_REG) != 0x00) 122 if (!host) {
194 goto release_reg; 123 ret = -ENOMEM;
124 goto out_unmap;
125 }
126
127 priv(host)->base = _base;
128 host->irq = IRQ_NONE;
195 129
196 NCR5380_init(host, 0); 130 NCR5380_init(host, 0);
197 131
@@ -206,24 +140,20 @@ static int __init ecoscsi_init(void)
206 scsi_scan_host(host); 140 scsi_scan_host(host);
207 return 0; 141 return 0;
208 142
209release_reg: 143 out_unmap:
210 release_region(host->io_port, host->n_io_port); 144 iounmap(_base);
211unregister_scsi: 145 out_release:
212 scsi_host_put(host); 146 release_mem_region(0x33a0000, 4096);
213 return -ENODEV; 147 out:
148 return ret;
214} 149}
215 150
216static void __exit ecoscsi_exit(void) 151static void __exit ecoscsi_exit(void)
217{ 152{
218 scsi_remove_host(host); 153 scsi_remove_host(host);
219
220 if (shpnt->irq != IRQ_NONE)
221 free_irq(shpnt->irq, NULL);
222 NCR5380_exit(host); 154 NCR5380_exit(host);
223 if (shpnt->io_port)
224 release_region(shpnt->io_port, shpnt->n_io_port);
225
226 scsi_host_put(host); 155 scsi_host_put(host);
156 release_mem_region(0x33a0000, 4096);
227 return 0; 157 return 0;
228} 158}
229 159
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index c21b8392c928..849cdf89f7bb 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -23,15 +23,18 @@
23 23
24#define OAKSCSI_PUBLIC_RELEASE 1 24#define OAKSCSI_PUBLIC_RELEASE 1
25 25
26#define NCR5380_read(reg) oakscsi_read(_instance, reg) 26#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
27#define NCR5380_write(reg, value) oakscsi_write(_instance, reg, value) 27#define NCR5380_local_declare() void __iomem *_base
28#define NCR5380_setup(host) _base = priv(host)->base
29
30#define NCR5380_read(reg) readb(_base + ((reg) << 2))
31#define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2))
28#define NCR5380_intr oakscsi_intr 32#define NCR5380_intr oakscsi_intr
29#define NCR5380_queue_command oakscsi_queue_command 33#define NCR5380_queue_command oakscsi_queue_command
30#define NCR5380_proc_info oakscsi_proc_info 34#define NCR5380_proc_info oakscsi_proc_info
31 35
32#define NCR5380_implementation_fields int port, ctrl 36#define NCR5380_implementation_fields \
33#define NCR5380_local_declare() struct Scsi_Host *_instance 37 void __iomem *base
34#define NCR5380_setup(instance) _instance = instance
35 38
36#define BOARD_NORMAL 0 39#define BOARD_NORMAL 0
37#define BOARD_NCR53C400 1 40#define BOARD_NCR53C400 1
@@ -39,60 +42,62 @@
39#include "../NCR5380.h" 42#include "../NCR5380.h"
40 43
41#undef START_DMA_INITIATOR_RECEIVE_REG 44#undef START_DMA_INITIATOR_RECEIVE_REG
42#define START_DMA_INITIATOR_RECEIVE_REG (7 + 128) 45#define START_DMA_INITIATOR_RECEIVE_REG (128 + 7)
43 46
44const char * oakscsi_info (struct Scsi_Host *spnt) 47const char * oakscsi_info (struct Scsi_Host *spnt)
45{ 48{
46 return ""; 49 return "";
47} 50}
48 51
49#define STAT(p) inw(p + 144) 52#define STAT ((128 + 16) << 2)
50extern void inswb(int from, void *to, int len); 53#define DATA ((128 + 8) << 2)
51 54
52static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, 55static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
53 int len) 56 int len)
54{ 57{
55 int iobase = instance->io_port; 58 void __iomem *base = priv(instance)->base;
59
56printk("writing %p len %d\n",addr, len); 60printk("writing %p len %d\n",addr, len);
57 if(!len) return -1; 61 if(!len) return -1;
58 62
59 while(1) 63 while(1)
60 { 64 {
61 int status; 65 int status;
62 while(((status = STAT(iobase)) & 0x100)==0); 66 while (((status = readw(base + STAT)) & 0x100)==0);
63 } 67 }
64} 68}
65 69
66static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, 70static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
67 int len) 71 int len)
68{ 72{
69 int iobase = instance->io_port; 73 void __iomem *base = priv(instance)->base;
70printk("reading %p len %d\n", addr, len); 74printk("reading %p len %d\n", addr, len);
71 while(len > 0) 75 while(len > 0)
72 { 76 {
73 int status, timeout; 77 unsigned int status, timeout;
74 unsigned long b; 78 unsigned long b;
75 79
76 timeout = 0x01FFFFFF; 80 timeout = 0x01FFFFFF;
77 81
78 while(((status = STAT(iobase)) & 0x100)==0) 82 while (((status = readw(base + STAT)) & 0x100)==0)
79 { 83 {
80 timeout--; 84 timeout--;
81 if(status & 0x200 || !timeout) 85 if(status & 0x200 || !timeout)
82 { 86 {
83 printk("status = %08X\n",status); 87 printk("status = %08X\n", status);
84 return 1; 88 return 1;
85 } 89 }
86 } 90 }
91
87 if(len >= 128) 92 if(len >= 128)
88 { 93 {
89 inswb(iobase + 136, addr, 128); 94 readsw(base + DATA, addr, 128);
90 addr += 128; 95 addr += 128;
91 len -= 128; 96 len -= 128;
92 } 97 }
93 else 98 else
94 { 99 {
95 b = (unsigned long) inw(iobase + 136); 100 b = (unsigned long) readw(base + DATA);
96 *addr ++ = b; 101 *addr ++ = b;
97 len -= 1; 102 len -= 1;
98 if(len) 103 if(len)
@@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len);
103 return 0; 108 return 0;
104} 109}
105 110
106#define oakscsi_read(instance,reg) (inb((instance)->io_port + (reg)))
107#define oakscsi_write(instance,reg,val) (outb((val), (instance)->io_port + (reg)))
108
109#undef STAT 111#undef STAT
112#undef DATA
110 113
111#include "../NCR5380.c" 114#include "../NCR5380.c"
112 115
@@ -132,18 +135,26 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
132 struct Scsi_Host *host; 135 struct Scsi_Host *host;
133 int ret = -ENOMEM; 136 int ret = -ENOMEM;
134 137
135 host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); 138 ret = ecard_request_resources(ec);
136 if (!host) 139 if (ret)
137 goto out; 140 goto out;
138 141
139 host->io_port = ecard_address(ec, ECARD_MEMC, 0); 142 host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
143 if (!host) {
144 ret = -ENOMEM;
145 goto release;
146 }
147
148 priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
149 ecard_resource_len(ec, ECARD_RES_MEMC));
150 if (!priv(host)->base) {
151 ret = -ENOMEM;
152 goto unreg;
153 }
154
140 host->irq = IRQ_NONE; 155 host->irq = IRQ_NONE;
141 host->n_io_port = 255; 156 host->n_io_port = 255;
142 157
143 ret = -EBUSY;
144 if (!request_region (host->io_port, host->n_io_port, "Oak SCSI"))
145 goto unreg;
146
147 NCR5380_init(host, 0); 158 NCR5380_init(host, 0);
148 159
149 printk("scsi%d: at port 0x%08lx irqs disabled", 160 printk("scsi%d: at port 0x%08lx irqs disabled",
@@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
156 167
157 ret = scsi_add_host(host, &ec->dev); 168 ret = scsi_add_host(host, &ec->dev);
158 if (ret) 169 if (ret)
159 goto out_release; 170 goto out_unmap;
160 171
161 scsi_scan_host(host); 172 scsi_scan_host(host);
162 goto out; 173 goto out;
163 174
164 out_release: 175 out_unmap:
165 release_region(host->io_port, host->n_io_port); 176 iounmap(priv(host)->base);
166 unreg: 177 unreg:
167 scsi_host_put(host); 178 scsi_host_put(host);
179 release:
180 ecard_release_resources(ec);
168 out: 181 out:
169 return ret; 182 return ret;
170} 183}
@@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec)
177 scsi_remove_host(host); 190 scsi_remove_host(host);
178 191
179 NCR5380_exit(host); 192 NCR5380_exit(host);
180 release_region(host->io_port, host->n_io_port); 193 iounmap(priv(host)->base);
181 scsi_host_put(host); 194 scsi_host_put(host);
195 ecard_release_resources(ec);
182} 196}
183 197
184static const struct ecard_id oakscsi_cids[] = { 198static const struct ecard_id oakscsi_cids[] = {