Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/block/paride/fit3.c
15112 views
1
/*
2
fit3.c (c) 1998 Grant R. Guenther <[email protected]>
3
Under the terms of the GNU General Public License.
4
5
fit3.c is a low-level protocol driver for newer models
6
of the Fidelity International Technology parallel port adapter.
7
This adapter is used in their TransDisk 3000 portable
8
hard-drives, as well as CD-ROM, PD-CD and other devices.
9
10
The TD-2000 and certain older devices use a different protocol.
11
Try the fit2 protocol module with them.
12
13
NB: The FIT adapters do not appear to support the control
14
registers. So, we map ALT_STATUS to STATUS and NO-OP writes
15
to the device control register - this means that IDE reset
16
will not work on these devices.
17
18
*/
19
20
#define FIT3_VERSION "1.0"
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
#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
33
34
#define w7(byte) {out_p(7,byte);}
35
#define r7() (in_p(7) & 0xff)
36
37
/* cont = 0 - access the IDE register file
38
cont = 1 - access the IDE command set
39
40
*/
41
42
static void fit3_write_regr( PIA *pi, int cont, int regr, int val)
43
44
{ if (cont == 1) return;
45
46
switch (pi->mode) {
47
48
case 0:
49
case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc);
50
w0(val); w2(0xd);
51
w0(0); w2(0xc);
52
break;
53
54
case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
55
w4(val); w4(0);
56
w2(0xc);
57
break;
58
59
}
60
}
61
62
static int fit3_read_regr( PIA *pi, int cont, int regr )
63
64
{ int a, b;
65
66
if (cont) {
67
if (regr != 6) return 0xff;
68
regr = 7;
69
}
70
71
switch (pi->mode) {
72
73
case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
74
w2(0xd); a = r1();
75
w2(0xf); b = r1();
76
w2(0xc);
77
return j44(a,b);
78
79
case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
80
w2(0xec); w2(0xee); w2(0xef); a = r0();
81
w2(0xc);
82
return a;
83
84
case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
85
w2(0xec);
86
a = r4(); b = r4();
87
w2(0xc);
88
return a;
89
90
}
91
return -1;
92
93
}
94
95
static void fit3_read_block( PIA *pi, char * buf, int count )
96
97
{ int k, a, b, c, d;
98
99
switch (pi->mode) {
100
101
case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
102
for (k=0;k<count/2;k++) {
103
w2(0xd); a = r1();
104
w2(0xf); b = r1();
105
w2(0xc); c = r1();
106
w2(0xe); d = r1();
107
buf[2*k ] = j44(a,b);
108
buf[2*k+1] = j44(c,d);
109
}
110
w2(0xc);
111
break;
112
113
case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
114
w2(0xec); w2(0xee);
115
for (k=0;k<count/2;k++) {
116
w2(0xef); a = r0();
117
w2(0xee); b = r0();
118
buf[2*k ] = a;
119
buf[2*k+1] = b;
120
}
121
w2(0xec);
122
w2(0xc);
123
break;
124
125
case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
126
w2(0xec);
127
for (k=0;k<count;k++) buf[k] = r4();
128
w2(0xc);
129
break;
130
131
}
132
}
133
134
static void fit3_write_block( PIA *pi, char * buf, int count )
135
136
{ int k;
137
138
switch (pi->mode) {
139
140
case 0:
141
case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
142
for (k=0;k<count/2;k++) {
143
w0(buf[2*k ]); w2(0xd);
144
w0(buf[2*k+1]); w2(0xc);
145
}
146
break;
147
148
case 2: w2(0xc); w0(0); w2(0x8); w2(0xc);
149
for (k=0;k<count;k++) w4(buf[k]);
150
w2(0xc);
151
break;
152
}
153
}
154
155
static void fit3_connect ( PIA *pi )
156
157
{ pi->saved_r0 = r0();
158
pi->saved_r2 = r2();
159
w2(0xc); w0(0); w2(0xa);
160
if (pi->mode == 2) {
161
w2(0xc); w0(0x9); w2(0x8); w2(0xc);
162
}
163
}
164
165
static void fit3_disconnect ( PIA *pi )
166
167
{ w2(0xc); w0(0xa); w2(0x8); w2(0xc);
168
w0(pi->saved_r0);
169
w2(pi->saved_r2);
170
}
171
172
static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
173
174
{ char *mode_string[3] = {"4-bit","8-bit","EPP"};
175
176
printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
177
"mode %d (%s), delay %d\n",
178
pi->device,FIT3_VERSION,pi->port,
179
pi->mode,mode_string[pi->mode],pi->delay);
180
181
}
182
183
static struct pi_protocol fit3 = {
184
.owner = THIS_MODULE,
185
.name = "fit3",
186
.max_mode = 3,
187
.epp_first = 2,
188
.default_delay = 1,
189
.max_units = 1,
190
.write_regr = fit3_write_regr,
191
.read_regr = fit3_read_regr,
192
.write_block = fit3_write_block,
193
.read_block = fit3_read_block,
194
.connect = fit3_connect,
195
.disconnect = fit3_disconnect,
196
.log_adapter = fit3_log_adapter,
197
};
198
199
static int __init fit3_init(void)
200
{
201
return paride_register(&fit3);
202
}
203
204
static void __exit fit3_exit(void)
205
{
206
paride_unregister(&fit3);
207
}
208
209
MODULE_LICENSE("GPL");
210
module_init(fit3_init)
211
module_exit(fit3_exit)
212
213