Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/block/paride/comm.c
15112 views
1
/*
2
comm.c (c) 1997-8 Grant R. Guenther <[email protected]>
3
Under the terms of the GNU General Public License.
4
5
comm.c is a low-level protocol driver for some older models
6
of the DataStor "Commuter" parallel to IDE adapter. Some of
7
the parallel port devices marketed by Arista currently
8
use this adapter.
9
*/
10
11
/* Changes:
12
13
1.01 GRG 1998.05.05 init_proto, release_proto
14
15
*/
16
17
#define COMM_VERSION "1.01"
18
19
#include <linux/module.h>
20
#include <linux/init.h>
21
#include <linux/delay.h>
22
#include <linux/kernel.h>
23
#include <linux/types.h>
24
#include <linux/wait.h>
25
#include <asm/io.h>
26
27
#include "paride.h"
28
29
/* mode codes: 0 nybble reads, 8-bit writes
30
1 8-bit reads and writes
31
2 8-bit EPP mode
32
*/
33
34
#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
35
36
#define P1 w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
37
#define P2 w2(5);w2(7);w2(7);w2(5);w2(4);
38
39
/* cont = 0 - access the IDE register file
40
cont = 1 - access the IDE command set
41
*/
42
43
static int cont_map[2] = { 0x08, 0x10 };
44
45
static int comm_read_regr( PIA *pi, int cont, int regr )
46
47
{ int l, h, r;
48
49
r = regr + cont_map[cont];
50
51
switch (pi->mode) {
52
53
case 0: w0(r); P1; w0(0);
54
w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
55
return j44(l,h);
56
57
case 1: w0(r+0x20); P1;
58
w0(0); w2(0x26); h = r0(); w2(4);
59
return h;
60
61
case 2:
62
case 3:
63
case 4: w3(r+0x20); (void)r1();
64
w2(0x24); h = r4(); w2(4);
65
return h;
66
67
}
68
return -1;
69
}
70
71
static void comm_write_regr( PIA *pi, int cont, int regr, int val )
72
73
{ int r;
74
75
r = regr + cont_map[cont];
76
77
switch (pi->mode) {
78
79
case 0:
80
case 1: w0(r); P1; w0(val); P2;
81
break;
82
83
case 2:
84
case 3:
85
case 4: w3(r); (void)r1(); w4(val);
86
break;
87
}
88
}
89
90
static void comm_connect ( PIA *pi )
91
92
{ pi->saved_r0 = r0();
93
pi->saved_r2 = r2();
94
w2(4); w0(0xff); w2(6);
95
w2(4); w0(0xaa); w2(6);
96
w2(4); w0(0x00); w2(6);
97
w2(4); w0(0x87); w2(6);
98
w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
99
}
100
101
static void comm_disconnect ( PIA *pi )
102
103
{ w2(0); w2(0); w2(0); w2(4);
104
w0(pi->saved_r0);
105
w2(pi->saved_r2);
106
}
107
108
static void comm_read_block( PIA *pi, char * buf, int count )
109
110
{ int i, l, h;
111
112
switch (pi->mode) {
113
114
case 0: w0(0x48); P1;
115
for(i=0;i<count;i++) {
116
w0(0); w2(6); l = r1();
117
w0(0x80); h = r1(); w2(4);
118
buf[i] = j44(l,h);
119
}
120
break;
121
122
case 1: w0(0x68); P1; w0(0);
123
for(i=0;i<count;i++) {
124
w2(0x26); buf[i] = r0(); w2(0x24);
125
}
126
w2(4);
127
break;
128
129
case 2: w3(0x68); (void)r1(); w2(0x24);
130
for (i=0;i<count;i++) buf[i] = r4();
131
w2(4);
132
break;
133
134
case 3: w3(0x68); (void)r1(); w2(0x24);
135
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
136
w2(4);
137
break;
138
139
case 4: w3(0x68); (void)r1(); w2(0x24);
140
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
141
w2(4);
142
break;
143
144
}
145
}
146
147
/* NB: Watch out for the byte swapped writes ! */
148
149
static void comm_write_block( PIA *pi, char * buf, int count )
150
151
{ int k;
152
153
switch (pi->mode) {
154
155
case 0:
156
case 1: w0(0x68); P1;
157
for (k=0;k<count;k++) {
158
w2(5); w0(buf[k^1]); w2(7);
159
}
160
w2(5); w2(4);
161
break;
162
163
case 2: w3(0x48); (void)r1();
164
for (k=0;k<count;k++) w4(buf[k^1]);
165
break;
166
167
case 3: w3(0x48); (void)r1();
168
for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
169
break;
170
171
case 4: w3(0x48); (void)r1();
172
for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
173
break;
174
175
176
}
177
}
178
179
static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
180
181
{ char *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
182
183
printk("%s: comm %s, DataStor Commuter at 0x%x, ",
184
pi->device,COMM_VERSION,pi->port);
185
printk("mode %d (%s), delay %d\n",pi->mode,
186
mode_string[pi->mode],pi->delay);
187
188
}
189
190
static struct pi_protocol comm = {
191
.owner = THIS_MODULE,
192
.name = "comm",
193
.max_mode = 5,
194
.epp_first = 2,
195
.default_delay = 1,
196
.max_units = 1,
197
.write_regr = comm_write_regr,
198
.read_regr = comm_read_regr,
199
.write_block = comm_write_block,
200
.read_block = comm_read_block,
201
.connect = comm_connect,
202
.disconnect = comm_disconnect,
203
.log_adapter = comm_log_adapter,
204
};
205
206
static int __init comm_init(void)
207
{
208
return paride_register(&comm);
209
}
210
211
static void __exit comm_exit(void)
212
{
213
paride_unregister(&comm);
214
}
215
216
MODULE_LICENSE("GPL");
217
module_init(comm_init)
218
module_exit(comm_exit)
219
220