vserver 1.9.5.x5
[linux-2.6.git] / drivers / block / paride / bpck6.c
1 /*
2         backpack.c (c) 2001 Micro Solutions Inc.
3                 Released under the terms of the GNU General Public license
4
5         backpack.c is a low-level protocol driver for the Micro Solutions
6                 "BACKPACK" parallel port IDE adapter
7                 (Works on Series 6 drives)
8
9         Written by: Ken Hahn     (linux-dev@micro-solutions.com)
10                     Clive Turvey (linux-dev@micro-solutions.com)
11
12 */
13
14 /*
15    This is Ken's linux wrapper for the PPC library
16    Version 1.0.0 is the backpack driver for which source is not available
17    Version 2.0.0 is the first to have source released 
18    Version 2.0.1 is the "Cox-ified" source code 
19    Version 2.0.2 - fixed version string usage, and made ppc functions static 
20 */
21
22
23 /* PARAMETERS */
24 static int verbose; /* set this to 1 to see debugging messages and whatnot */
25
26 #define BACKPACK_VERSION "2.0.2"
27
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/kernel.h>
31 #include <linux/slab.h>
32 #include <linux/types.h>
33 #include <asm/io.h>
34
35 #if defined(CONFIG_PARPORT_MODULE)||defined(CONFIG_PARPORT)
36 #include <linux/parport.h>
37 #endif
38
39 #include "ppc6lnx.c"
40 #include "paride.h"
41
42  
43
44 #define PPCSTRUCT(pi) ((Interface *)(pi->private))
45
46 /****************************************************************/
47 /*
48  ATAPI CDROM DRIVE REGISTERS
49 */
50 #define ATAPI_DATA       0      /* data port                  */
51 #define ATAPI_ERROR      1      /* error register (read)      */
52 #define ATAPI_FEATURES   1      /* feature register (write)   */
53 #define ATAPI_INT_REASON 2      /* interrupt reason register  */
54 #define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
55 #define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
56 #define ATAPI_DRIVE_SEL  6      /* drive select register      */
57 #define ATAPI_STATUS     7      /* status port (read)         */
58 #define ATAPI_COMMAND    7      /* command port (write)       */
59 #define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
60 #define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
61 /****************************************************************/
62
63 static int bpck6_read_regr(PIA *pi, int cont, int reg)
64 {
65         unsigned int out;
66
67         /* check for bad settings */
68         if (reg<0 || reg>7 || cont<0 || cont>2)
69         {
70                 return(-1);
71         }
72         out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
73         return(out);
74 }
75
76 static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
77 {
78         /* check for bad settings */
79         if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
80         {
81                 ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
82         }
83 }
84
85 static void bpck6_write_block( PIA *pi, char * buf, int len )
86 {
87         ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
88 }
89
90 static void bpck6_read_block( PIA *pi, char * buf, int len )
91 {
92         ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
93 }
94
95 static void bpck6_connect ( PIA *pi  )
96 {
97         if(verbose)
98         {
99                 printk(KERN_DEBUG "connect\n");
100         }
101
102         if(pi->mode >=2)
103         {
104                 PPCSTRUCT(pi)->mode=4+pi->mode-2;       
105         }
106         else if(pi->mode==1)
107         {
108                 PPCSTRUCT(pi)->mode=3;  
109         }
110         else
111         {
112                 PPCSTRUCT(pi)->mode=1;          
113         }
114
115         ppc6_open(PPCSTRUCT(pi));  
116         ppc6_wr_extout(PPCSTRUCT(pi),0x3);
117 }
118
119 static void bpck6_disconnect ( PIA *pi )
120 {
121         if(verbose)
122         {
123                 printk("disconnect\n");
124         }
125         ppc6_wr_extout(PPCSTRUCT(pi),0x0);
126         ppc6_close(PPCSTRUCT(pi));
127 }
128
129 static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
130 {
131         if(verbose)
132         {
133                 printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
134                         ((struct pardevice*)(pi->pardev))->port->modes,
135                         ((struct pardevice *)(pi->pardev))->port->base); 
136         }
137
138         /*copy over duplicate stuff.. initialize state info*/
139         PPCSTRUCT(pi)->ppc_id=pi->unit;
140         PPCSTRUCT(pi)->lpt_addr=pi->port;
141
142 #ifdef CONFIG_PARPORT_PC_MODULE
143 #define CONFIG_PARPORT_PC
144 #endif
145
146 #ifdef CONFIG_PARPORT_PC
147         /* look at the parport device to see if what modes we can use */
148         if(((struct pardevice *)(pi->pardev))->port->modes & 
149                 (PARPORT_MODE_EPP)
150           )
151         {
152                 return 5; /* Can do EPP*/
153         }
154         else if(((struct pardevice *)(pi->pardev))->port->modes & 
155                         (PARPORT_MODE_TRISTATE)
156                )
157         {
158                 return 2;
159         }
160         else /*Just flat SPP*/
161         {
162                 return 1;
163         }
164 #else
165         /* there is no way of knowing what kind of port we have
166            default to the highest mode possible */
167         return 5;
168 #endif
169 }
170
171 static int bpck6_probe_unit ( PIA *pi )
172 {
173         int out;
174
175         if(verbose)
176         {
177                 printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
178         }
179
180         /*SET PPC UNIT NUMBER*/
181         PPCSTRUCT(pi)->ppc_id=pi->unit;
182
183         /*LOWER DOWN TO UNIDIRECTIONAL*/
184         PPCSTRUCT(pi)->mode=1;          
185
186         out=ppc6_open(PPCSTRUCT(pi));
187
188         if(verbose)
189         {
190                 printk(KERN_DEBUG "ppc_open returned %2x\n",out);
191         }
192
193         if(out)
194         {
195                 ppc6_close(PPCSTRUCT(pi));
196                 if(verbose)
197                 {
198                         printk(KERN_DEBUG "leaving probe\n");
199                 }
200                return(1);
201         }
202         else
203         {
204                 if(verbose)
205                 {
206                         printk(KERN_DEBUG "Failed open\n");
207                 }
208                 return(0);
209         }
210 }
211
212 static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
213 {
214         char *mode_string[5]=
215                 {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
216
217         printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
218         printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
219         printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
220                 pi->device,BACKPACK_VERSION,pi->port);
221         printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
222                 pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
223 }
224
225 static int bpck6_init_proto(PIA *pi)
226 {
227         Interface *p = kmalloc(sizeof(Interface), GFP_KERNEL);
228
229         if (p) {
230                 memset(p, 0, sizeof(Interface));
231                 pi->private = (unsigned long)p;
232                 return 0;
233         }
234
235         printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
236         return -1;
237 }
238
239 static void bpck6_release_proto(PIA *pi)
240 {
241         kfree((void *)(pi->private)); 
242 }
243
244 static struct pi_protocol bpck6 = {
245         .owner          = THIS_MODULE,
246         .name           = "bpck6",
247         .max_mode       = 5,
248         .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
249         .max_units      = 255,
250         .write_regr     = bpck6_write_regr,
251         .read_regr      = bpck6_read_regr,
252         .write_block    = bpck6_write_block,
253         .read_block     = bpck6_read_block,
254         .connect        = bpck6_connect,
255         .disconnect     = bpck6_disconnect,
256         .test_port      = bpck6_test_port,
257         .probe_unit     = bpck6_probe_unit,
258         .log_adapter    = bpck6_log_adapter,
259         .init_proto     = bpck6_init_proto,
260         .release_proto  = bpck6_release_proto,
261 };
262
263 static int __init bpck6_init(void)
264 {
265         printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
266         printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
267         if(verbose)
268                 printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
269         return pi_register(&bpck6) - 1;  
270 }
271
272 static void __exit bpck6_exit(void)
273 {
274         pi_unregister(&bpck6);
275 }
276
277 MODULE_LICENSE("GPL");
278 MODULE_AUTHOR("Micro Solutions Inc.");
279 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
280 module_param(verbose, bool, 0644);
281 module_init(bpck6_init)
282 module_exit(bpck6_exit)