]> Git Repo - linux.git/blob - drivers/ata/pata_parport/bpck.c
arm64: avoid prototype warnings for syscalls
[linux.git] / drivers / ata / pata_parport / bpck.c
1 /* 
2         bpck.c  (c) 1996-8  Grant R. Guenther <[email protected]>
3                             Under the terms of the GNU General Public License.
4
5         bpck.c is a low-level protocol driver for the MicroSolutions 
6         "backpack" parallel port IDE adapter.  
7
8 */
9
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/wait.h>
16 #include <asm/io.h>
17 #include "pata_parport.h"
18
19 #undef r2
20 #undef w2
21 #undef PC
22
23 #define PC                      pi->private
24 #define r2()                    (PC=(in_p(2) & 0xff))
25 #define w2(byte)                {out_p(2,byte); PC = byte;}
26 #define t2(pat)                 {PC ^= pat; out_p(2,PC);}
27 #define e2()                    {PC &= 0xfe; out_p(2,PC);}
28 #define o2()                    {PC |= 1; out_p(2,PC);}
29
30 #define j44(l,h)     (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
31
32 /* cont = 0 - access the IDE register file 
33    cont = 1 - access the IDE command set 
34    cont = 2 - use internal bpck register addressing
35 */
36
37 static int  cont_map[3] = { 0x40, 0x48, 0 };
38
39 static int bpck_read_regr(struct pi_adapter *pi, int cont, int regr)
40
41 {       int r, l, h;
42
43         r = regr + cont_map[cont];
44
45         switch (pi->mode) {
46
47         case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
48                 l = r1();
49                 t2(4);
50                 h = r1();
51                 return j44(l,h);
52
53         case 1: w0(r & 0xf); w0(r); t2(2);
54                 e2(); t2(0x20);
55                 t2(4); h = r0();
56                 t2(1); t2(0x20);
57                 return h;
58
59         case 2:
60         case 3:
61         case 4: w0(r); w2(9); w2(0); w2(0x20);
62                 h = r4();
63                 w2(0);
64                 return h;
65
66         }
67         return -1;
68 }       
69
70 static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
71
72 {       int     r;
73
74         r = regr + cont_map[cont];
75
76         switch (pi->mode) {
77
78         case 0:
79         case 1: w0(r);
80                 t2(2);
81                 w0(val);
82                 o2(); t2(4); t2(1);
83                 break;
84
85         case 2:
86         case 3:
87         case 4: w0(r); w2(9); w2(0);
88                 w0(val); w2(1); w2(3); w2(0);
89                 break;
90
91         }
92 }
93
94 /* These macros access the bpck registers in native addressing */
95
96 #define WR(r,v)         bpck_write_regr(pi,2,r,v)
97 #define RR(r)           (bpck_read_regr(pi,2,r))
98
99 static void bpck_write_block(struct pi_adapter *pi, char *buf, int count)
100
101 {       int i;
102
103         switch (pi->mode) {
104
105         case 0: WR(4,0x40);
106                 w0(0x40); t2(2); t2(1);
107                 for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
108                 WR(4,0);
109                 break;
110
111         case 1: WR(4,0x50);
112                 w0(0x40); t2(2); t2(1);
113                 for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
114                 WR(4,0x10);
115                 break;
116
117         case 2: WR(4,0x48);
118                 w0(0x40); w2(9); w2(0); w2(1);
119                 for (i=0;i<count;i++) w4(buf[i]);
120                 w2(0);
121                 WR(4,8);
122                 break;
123
124         case 3: WR(4,0x48);
125                 w0(0x40); w2(9); w2(0); w2(1);
126                 for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
127                 w2(0);
128                 WR(4,8);
129                 break;
130  
131         case 4: WR(4,0x48);
132                 w0(0x40); w2(9); w2(0); w2(1);
133                 for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
134                 w2(0);
135                 WR(4,8);
136                 break;
137         }
138 }
139
140 static void bpck_read_block(struct pi_adapter *pi, char *buf, int count)
141
142 {       int i, l, h;
143
144         switch (pi->mode) {
145
146         case 0: WR(4,0x40);
147                 w0(0x40); t2(2);
148                 for (i=0;i<count;i++) {
149                     t2(4); l = r1();
150                     t2(4); h = r1();
151                     buf[i] = j44(l,h);
152                 }
153                 WR(4,0);
154                 break;
155
156         case 1: WR(4,0x50);
157                 w0(0x40); t2(2); t2(0x20);
158                 for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
159                 t2(1); t2(0x20);
160                 WR(4,0x10);
161                 break;
162
163         case 2: WR(4,0x48);
164                 w0(0x40); w2(9); w2(0); w2(0x20);
165                 for (i=0;i<count;i++) buf[i] = r4();
166                 w2(0);
167                 WR(4,8);
168                 break;
169
170         case 3: WR(4,0x48);
171                 w0(0x40); w2(9); w2(0); w2(0x20);
172                 for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
173                 w2(0);
174                 WR(4,8);
175                 break;
176
177         case 4: WR(4,0x48);
178                 w0(0x40); w2(9); w2(0); w2(0x20);
179                 for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
180                 w2(0);
181                 WR(4,8);
182                 break;
183
184         }
185 }
186
187 static int bpck_probe_unit(struct pi_adapter *pi)
188
189 {       int o1, o0, f7, id;
190         int t, s;
191
192         id = pi->unit;
193         s = 0;
194         w2(4); w2(0xe); r2(); t2(2); 
195         o1 = r1()&0xf8;
196         o0 = r0();
197         w0(255-id); w2(4); w0(id);
198         t2(8); t2(8); t2(8);
199         t2(2); t = r1()&0xf8;
200         f7 = ((id % 8) == 7);
201         if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
202         if ((t == o1) && ((!f7) || (s == o1)))  {
203                 w2(0x4c); w0(o0);
204                 return 0;       
205         }
206         t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
207         return 1;
208 }
209         
210 static void bpck_connect(struct pi_adapter *pi)
211
212 {       pi->saved_r0 = r0();
213         w0(0xff-pi->unit); w2(4); w0(pi->unit);
214         t2(8); t2(8); t2(8); 
215         t2(2); t2(2);
216         
217         switch (pi->mode) {
218
219         case 0: t2(8); WR(4,0);
220                 break;
221
222         case 1: t2(8); WR(4,0x10);
223                 break;
224
225         case 2:
226         case 3:
227         case 4: w2(0); WR(4,8);
228                 break;
229
230         }
231
232         WR(5,8);
233
234 /*      if (pi->devtype == PI_PCD) {    possibly wrong, purpose unknown */
235                 WR(0x46,0x10);          /* fiddle with ESS logic ??? */
236                 WR(0x4c,0x38);
237                 WR(0x4d,0x88);
238                 WR(0x46,0xa0);
239                 WR(0x41,0);
240                 WR(0x4e,8);
241 /*      }*/
242 }
243
244 static void bpck_disconnect(struct pi_adapter *pi)
245
246 {       w0(0); 
247         if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
248         w2(0x4c); w0(pi->saved_r0);
249
250
251 static void bpck_force_spp(struct pi_adapter *pi)
252
253 /* This fakes the EPP protocol to turn off EPP ... */
254
255 {       pi->saved_r0 = r0();
256         w0(0xff-pi->unit); w2(4); w0(pi->unit);
257         t2(8); t2(8); t2(8); 
258         t2(2); t2(2);
259
260         w2(0); 
261         w0(4); w2(9); w2(0); 
262         w0(0); w2(1); w2(3); w2(0);     
263         w0(0); w2(9); w2(0);
264         w2(0x4c); w0(pi->saved_r0);
265 }
266
267 #define TEST_LEN  16
268
269 static int bpck_test_proto(struct pi_adapter *pi)
270
271 {       int i, e, l, h, om;
272         char buf[TEST_LEN];
273
274         bpck_force_spp(pi);
275
276         switch (pi->mode) {
277
278         case 0: bpck_connect(pi);
279                 WR(0x13,0x7f);
280                 w0(0x13); t2(2);
281                 for(i=0;i<TEST_LEN;i++) {
282                     t2(4); l = r1();
283                     t2(4); h = r1();
284                     buf[i] = j44(l,h);
285                 }
286                 bpck_disconnect(pi);
287                 break;
288
289         case 1: bpck_connect(pi);
290                 WR(0x13,0x7f);
291                 w0(0x13); t2(2); t2(0x20);
292                 for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
293                 t2(1); t2(0x20);
294                 bpck_disconnect(pi);
295                 break;
296
297         case 2:
298         case 3:
299         case 4: om = pi->mode;
300                 pi->mode = 0;
301                 bpck_connect(pi);
302                 WR(7,3);
303                 WR(4,8);
304                 bpck_disconnect(pi);
305
306                 pi->mode = om;
307                 bpck_connect(pi);
308                 w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
309
310                 switch (pi->mode) {
311                   case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
312                           break;
313                   case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
314                           break;
315                   case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
316                           break;
317                 }
318
319                 w2(0);
320                 WR(7,0);
321                 bpck_disconnect(pi);
322
323                 break;
324
325         }
326
327         dev_dbg(&pi->dev, "bpck: 0x%x unit %d mode %d: ",
328                 pi->port, pi->unit, pi->mode);
329         print_hex_dump_debug("bpck: ", DUMP_PREFIX_NONE, TEST_LEN, 1, buf, TEST_LEN, false);
330
331         e = 0;
332         for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
333         return e;
334 }
335
336 static void bpck_read_eeprom(struct pi_adapter *pi, char *buf)
337
338 {       int i, j, k, p, v, f, om, od;
339
340         bpck_force_spp(pi);
341
342         om = pi->mode;  od = pi->delay;
343         pi->mode = 0; pi->delay = 6;
344
345         bpck_connect(pi);
346         
347         WR(4,0);
348         for (i=0;i<64;i++) {
349             WR(6,8);  
350             WR(6,0xc);
351             p = 0x100;
352             for (k=0;k<9;k++) {
353                 f = (((i + 0x180) & p) != 0) * 2;
354                 WR(6,f+0xc); 
355                 WR(6,f+0xd); 
356                 WR(6,f+0xc);
357                 p = (p >> 1);
358             }
359             for (j=0;j<2;j++) {
360                 v = 0;
361                 for (k=0;k<8;k++) {
362                     WR(6,0xc); 
363                     WR(6,0xd); 
364                     WR(6,0xc); 
365                     f = RR(0);
366                     v = 2*v + (f == 0x84);
367                 }
368                 buf[2*i+1-j] = v;
369             }
370         }
371         WR(6,8);
372         WR(6,0);
373         WR(5,8);
374
375         bpck_disconnect(pi);
376
377         if (om >= 2) {
378                 bpck_connect(pi);
379                 WR(7,3);
380                 WR(4,8);
381                 bpck_disconnect(pi);
382         }
383
384         pi->mode = om; pi->delay = od;
385 }
386
387 static int bpck_test_port(struct pi_adapter *pi)        /* check for 8-bit port */
388
389 {       int     i, r, m;
390
391         w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
392         m = -1;
393         if (r == i) m = 2;
394         if (r == (255-i)) m = 0;
395
396         w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
397         if (r != (255-i)) m = -1;
398         
399         if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
400         if (m == 2) { w2(0x26); w2(0xc); }
401
402         if (m == -1) return 0;
403         return 5;
404 }
405
406 static void bpck_log_adapter(struct pi_adapter *pi)
407
408 {       char    *mode_string[5] = { "4-bit","8-bit","EPP-8",
409                                     "EPP-16","EPP-32" };
410         char scratch[128];
411
412         bpck_read_eeprom(pi,scratch);
413         print_hex_dump_bytes("bpck EEPROM: ", DUMP_PREFIX_NONE, scratch, 128);
414         dev_info(&pi->dev, "backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n",
415                  &scratch[110], pi->unit, pi->port, pi->mode,
416                  mode_string[pi->mode], pi->delay);
417 }
418
419 static struct pi_protocol bpck = {
420         .owner          = THIS_MODULE,
421         .name           = "bpck",
422         .max_mode       = 5,
423         .epp_first      = 2,
424         .default_delay  = 4,
425         .max_units      = 255,
426         .write_regr     = bpck_write_regr,
427         .read_regr      = bpck_read_regr,
428         .write_block    = bpck_write_block,
429         .read_block     = bpck_read_block,
430         .connect        = bpck_connect,
431         .disconnect     = bpck_disconnect,
432         .test_port      = bpck_test_port,
433         .probe_unit     = bpck_probe_unit,
434         .test_proto     = bpck_test_proto,
435         .log_adapter    = bpck_log_adapter,
436 };
437
438 MODULE_LICENSE("GPL");
439 module_pata_parport_driver(bpck);
This page took 0.057458 seconds and 4 git commands to generate.