File: /usr/src/linux/drivers/block/paride/on20.c

1     /* 
2     	on20.c	(c) 1996-8  Grant R. Guenther <grant@torque.net>
3     		            Under the terms of the GNU General Public License.
4     
5             on20.c is a low-level protocol driver for the
6             Onspec 90c20 parallel to IDE adapter. 
7     */
8     
9     /* Changes:
10     
11             1.01    GRG 1998.05.06 init_proto, release_proto
12     
13     */
14     
15     #define	ON20_VERSION	"1.01"
16     
17     #include <linux/module.h>
18     #include <linux/delay.h>
19     #include <linux/kernel.h>
20     #include <linux/types.h>
21     #include <linux/wait.h>
22     #include <asm/io.h>
23     
24     #include "paride.h"
25     
26     #define op(f)	w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
27     #define vl(v)	w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
28     
29     #define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
30     
31     /* cont = 0 - access the IDE register file 
32        cont = 1 - access the IDE command set 
33     */
34     
35     static int on20_read_regr( PIA *pi, int cont, int regr )
36     
37     {	int h,l, r ;
38     
39             r = (regr<<2) + 1 + cont;
40     
41             op(1); vl(r); op(0);
42     
43     	switch (pi->mode)  {
44     
45             case 0:  w2(4); w2(6); l = r1();
46                      w2(4); w2(6); h = r1();
47                      w2(4); w2(6); w2(4); w2(6); w2(4);
48     		 return j44(l,h);
49     
50     	case 1:  w2(4); w2(0x26); r = r0(); 
51                      w2(4); w2(0x26); w2(4);
52     		 return r;
53     
54     	}
55     	return -1;
56     }	
57     
58     static void on20_write_regr( PIA *pi, int cont, int regr, int val )
59     
60     {	int r;
61     
62     	r = (regr<<2) + 1 + cont;
63     
64     	op(1); vl(r); 
65     	op(0); vl(val); 
66     	op(0); vl(val);
67     }
68     
69     static void on20_connect ( PIA *pi)
70     
71     {	pi->saved_r0 = r0();
72             pi->saved_r2 = r2();
73     
74     	w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); 
75     	if (pi->mode) { op(2); vl(8); op(2); vl(9); }
76     	       else   { op(2); vl(0); op(2); vl(8); }
77     }
78     
79     static void on20_disconnect ( PIA *pi )
80     
81     {	w2(4);w0(7);w2(4);w2(0xc);w2(4);
82             w0(pi->saved_r0);
83             w2(pi->saved_r2);
84     } 
85     
86     static void on20_read_block( PIA *pi, char * buf, int count )
87     
88     {	int     k, l, h; 
89     
90     	op(1); vl(1); op(0);
91     
92     	for (k=0;k<count;k++) 
93     	    if (pi->mode) {
94     		w2(4); w2(0x26); buf[k] = r0();
95     	    } else {
96     		w2(6); l = r1(); w2(4);
97     		w2(6); h = r1(); w2(4);
98     		buf[k] = j44(l,h);
99     	    }
100     	w2(4);
101     }
102     
103     static void on20_write_block(  PIA *pi, char * buf, int count )
104     
105     {	int	k;
106     
107     	op(1); vl(1); op(0);
108     
109     	for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
110     	w2(4);
111     }
112     
113     static void on20_log_adapter( PIA *pi, char * scratch, int verbose )
114     
115     {       char    *mode_string[2] = {"4-bit","8-bit"};
116     
117             printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ",
118                     pi->device,ON20_VERSION,pi->port);
119             printk("mode %d (%s), delay %d\n",pi->mode,
120     		mode_string[pi->mode],pi->delay);
121     
122     }
123     
124     static void on20_init_proto( PIA *pi)
125     
126     {       MOD_INC_USE_COUNT;
127     }
128     
129     static void on20_release_proto( PIA *pi)
130     
131     {       MOD_DEC_USE_COUNT;
132     }
133     
134     struct pi_protocol on20 = {"on20",0,2,2,1,1,
135                                on20_write_regr,
136                                on20_read_regr,
137                                on20_write_block,
138                                on20_read_block,
139                                on20_connect,
140                                on20_disconnect,
141                                0,
142                                0,
143                                0,
144                                on20_log_adapter,
145                                on20_init_proto,
146                                on20_release_proto
147                               };
148     
149     
150     #ifdef MODULE
151     
152     int     init_module(void)
153     
154     {       return pi_register( &on20 ) - 1;
155     }
156     
157     void    cleanup_module(void)
158     
159     {       pi_unregister( &on20 );
160     }
161     
162     #endif
163     
164     /* end of on20.c */
165