Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/block/paride/epia.c
15111 views
1
/*
2
epia.c (c) 1997-8 Grant R. Guenther <[email protected]>
3
Under the terms of the GNU General Public License.
4
5
epia.c is a low-level protocol driver for Shuttle Technologies
6
EPIA parallel to IDE adapter chip. This device is now obsolete
7
and has been replaced with the EPAT chip, which is supported
8
by epat.c, however, some devices based on EPIA are still
9
available.
10
11
*/
12
13
/* Changes:
14
15
1.01 GRG 1998.05.06 init_proto, release_proto
16
1.02 GRG 1998.06.17 support older versions of EPIA
17
18
*/
19
20
#define EPIA_VERSION "1.02"
21
22
#include <linux/module.h>
23
#include <linux/init.h>
24
#include <linux/delay.h>
25
#include <linux/kernel.h>
26
#include <linux/types.h>
27
#include <linux/wait.h>
28
#include <asm/io.h>
29
30
#include "paride.h"
31
32
/* mode codes: 0 nybble reads on port 1, 8-bit writes
33
1 5/3 reads on ports 1 & 2, 8-bit writes
34
2 8-bit reads and writes
35
3 8-bit EPP mode
36
4 16-bit EPP
37
5 32-bit EPP
38
*/
39
40
#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
41
#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
42
43
/* cont = 0 IDE register file
44
cont = 1 IDE control registers
45
*/
46
47
static int cont_map[2] = { 0, 0x80 };
48
49
static int epia_read_regr( PIA *pi, int cont, int regr )
50
51
{ int a, b, r;
52
53
regr += cont_map[cont];
54
55
switch (pi->mode) {
56
57
case 0: r = regr^0x39;
58
w0(r); w2(1); w2(3); w0(r);
59
a = r1(); w2(1); b = r1(); w2(4);
60
return j44(a,b);
61
62
case 1: r = regr^0x31;
63
w0(r); w2(1); w0(r&0x37);
64
w2(3); w2(5); w0(r|0xf0);
65
a = r1(); b = r2(); w2(4);
66
return j53(a,b);
67
68
case 2: r = regr^0x29;
69
w0(r); w2(1); w2(0X21); w2(0x23);
70
a = r0(); w2(4);
71
return a;
72
73
case 3:
74
case 4:
75
case 5: w3(regr); w2(0x24); a = r4(); w2(4);
76
return a;
77
78
}
79
return -1;
80
}
81
82
static void epia_write_regr( PIA *pi, int cont, int regr, int val)
83
84
{ int r;
85
86
regr += cont_map[cont];
87
88
switch (pi->mode) {
89
90
case 0:
91
case 1:
92
case 2: r = regr^0x19;
93
w0(r); w2(1); w0(val); w2(3); w2(4);
94
break;
95
96
case 3:
97
case 4:
98
case 5: r = regr^0x40;
99
w3(r); w4(val); w2(4);
100
break;
101
}
102
}
103
104
#define WR(r,v) epia_write_regr(pi,0,r,v)
105
#define RR(r) (epia_read_regr(pi,0,r))
106
107
/* The use of register 0x84 is entirely unclear - it seems to control
108
some EPP counters ... currently we know about 3 different block
109
sizes: the standard 512 byte reads and writes, 12 byte writes and
110
2048 byte reads (the last two being used in the CDrom drivers.
111
*/
112
113
static void epia_connect ( PIA *pi )
114
115
{ pi->saved_r0 = r0();
116
pi->saved_r2 = r2();
117
118
w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
119
w2(1); w2(4);
120
if (pi->mode >= 3) {
121
w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
122
w2(0x24); w2(0x26); w2(4);
123
}
124
WR(0x86,8);
125
}
126
127
static void epia_disconnect ( PIA *pi )
128
129
{ /* WR(0x84,0x10); */
130
w0(pi->saved_r0);
131
w2(1); w2(4);
132
w0(pi->saved_r0);
133
w2(pi->saved_r2);
134
}
135
136
static void epia_read_block( PIA *pi, char * buf, int count )
137
138
{ int k, ph, a, b;
139
140
switch (pi->mode) {
141
142
case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
143
ph = 1;
144
for (k=0;k<count;k++) {
145
w2(2+ph); a = r1();
146
w2(4+ph); b = r1();
147
buf[k] = j44(a,b);
148
ph = 1 - ph;
149
}
150
w0(0); w2(4);
151
break;
152
153
case 1: w0(0x91); w2(1); w0(0x10); w2(3);
154
w0(0x51); w2(5); w0(0xd1);
155
ph = 1;
156
for (k=0;k<count;k++) {
157
w2(4+ph);
158
a = r1(); b = r2();
159
buf[k] = j53(a,b);
160
ph = 1 - ph;
161
}
162
w0(0); w2(4);
163
break;
164
165
case 2: w0(0x89); w2(1); w2(0x23); w2(0x21);
166
ph = 1;
167
for (k=0;k<count;k++) {
168
w2(0x24+ph);
169
buf[k] = r0();
170
ph = 1 - ph;
171
}
172
w2(6); w2(4);
173
break;
174
175
case 3: if (count > 512) WR(0x84,3);
176
w3(0); w2(0x24);
177
for (k=0;k<count;k++) buf[k] = r4();
178
w2(4); WR(0x84,0);
179
break;
180
181
case 4: if (count > 512) WR(0x84,3);
182
w3(0); w2(0x24);
183
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
184
w2(4); WR(0x84,0);
185
break;
186
187
case 5: if (count > 512) WR(0x84,3);
188
w3(0); w2(0x24);
189
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
190
w2(4); WR(0x84,0);
191
break;
192
193
}
194
}
195
196
static void epia_write_block( PIA *pi, char * buf, int count )
197
198
{ int ph, k, last, d;
199
200
switch (pi->mode) {
201
202
case 0:
203
case 1:
204
case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
205
ph = 0; last = 0x8000;
206
for (k=0;k<count;k++) {
207
d = buf[k];
208
if (d != last) { last = d; w0(d); }
209
w2(4+ph);
210
ph = 1 - ph;
211
}
212
w2(7); w2(4);
213
break;
214
215
case 3: if (count < 512) WR(0x84,1);
216
w3(0x40);
217
for (k=0;k<count;k++) w4(buf[k]);
218
if (count < 512) WR(0x84,0);
219
break;
220
221
case 4: if (count < 512) WR(0x84,1);
222
w3(0x40);
223
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
224
if (count < 512) WR(0x84,0);
225
break;
226
227
case 5: if (count < 512) WR(0x84,1);
228
w3(0x40);
229
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
230
if (count < 512) WR(0x84,0);
231
break;
232
233
}
234
235
}
236
237
static int epia_test_proto( PIA *pi, char * scratch, int verbose )
238
239
{ int j, k, f;
240
int e[2] = {0,0};
241
242
epia_connect(pi);
243
for (j=0;j<2;j++) {
244
WR(6,0xa0+j*0x10);
245
for (k=0;k<256;k++) {
246
WR(2,k^0xaa);
247
WR(3,k^0x55);
248
if (RR(2) != (k^0xaa)) e[j]++;
249
}
250
WR(2,1); WR(3,1);
251
}
252
epia_disconnect(pi);
253
254
f = 0;
255
epia_connect(pi);
256
WR(0x84,8);
257
epia_read_block(pi,scratch,512);
258
for (k=0;k<256;k++) {
259
if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
260
if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
261
}
262
WR(0x84,0);
263
epia_disconnect(pi);
264
265
if (verbose) {
266
printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
267
pi->device,pi->port,pi->mode,e[0],e[1],f);
268
}
269
270
return (e[0] && e[1]) || f;
271
272
}
273
274
275
static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
276
277
{ char *mode_string[6] = {"4-bit","5/3","8-bit",
278
"EPP-8","EPP-16","EPP-32"};
279
280
printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
281
pi->device,EPIA_VERSION,pi->port);
282
printk("mode %d (%s), delay %d\n",pi->mode,
283
mode_string[pi->mode],pi->delay);
284
285
}
286
287
static struct pi_protocol epia = {
288
.owner = THIS_MODULE,
289
.name = "epia",
290
.max_mode = 6,
291
.epp_first = 3,
292
.default_delay = 1,
293
.max_units = 1,
294
.write_regr = epia_write_regr,
295
.read_regr = epia_read_regr,
296
.write_block = epia_write_block,
297
.read_block = epia_read_block,
298
.connect = epia_connect,
299
.disconnect = epia_disconnect,
300
.test_proto = epia_test_proto,
301
.log_adapter = epia_log_adapter,
302
};
303
304
static int __init epia_init(void)
305
{
306
return paride_register(&epia);
307
}
308
309
static void __exit epia_exit(void)
310
{
311
paride_unregister(&epia);
312
}
313
314
MODULE_LICENSE("GPL");
315
module_init(epia_init)
316
module_exit(epia_exit)
317
318