Linux 2.6.31-rc6
[linux-2.6] / 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 #include <linux/parport.h>
35
36 #include "ppc6lnx.c"
37 #include "paride.h"
38
39  
40
41 #define PPCSTRUCT(pi) ((Interface *)(pi->private))
42
43 /****************************************************************/
44 /*
45  ATAPI CDROM DRIVE REGISTERS
46 */
47 #define ATAPI_DATA       0      /* data port                  */
48 #define ATAPI_ERROR      1      /* error register (read)      */
49 #define ATAPI_FEATURES   1      /* feature register (write)   */
50 #define ATAPI_INT_REASON 2      /* interrupt reason register  */
51 #define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
52 #define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
53 #define ATAPI_DRIVE_SEL  6      /* drive select register      */
54 #define ATAPI_STATUS     7      /* status port (read)         */
55 #define ATAPI_COMMAND    7      /* command port (write)       */
56 #define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
57 #define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
58 /****************************************************************/
59
60 static int bpck6_read_regr(PIA *pi, int cont, int reg)
61 {
62         unsigned int out;
63
64         /* check for bad settings */
65         if (reg<0 || reg>7 || cont<0 || cont>2)
66         {
67                 return(-1);
68         }
69         out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
70         return(out);
71 }
72
73 static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
74 {
75         /* check for bad settings */
76         if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
77         {
78                 ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
79         }
80 }
81
82 static void bpck6_write_block( PIA *pi, char * buf, int len )
83 {
84         ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
85 }
86
87 static void bpck6_read_block( PIA *pi, char * buf, int len )
88 {
89         ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
90 }
91
92 static void bpck6_connect ( PIA *pi  )
93 {
94         if(verbose)
95         {
96                 printk(KERN_DEBUG "connect\n");
97         }
98
99         if(pi->mode >=2)
100         {
101                 PPCSTRUCT(pi)->mode=4+pi->mode-2;       
102         }
103         else if(pi->mode==1)
104         {
105                 PPCSTRUCT(pi)->mode=3;  
106         }
107         else
108         {
109                 PPCSTRUCT(pi)->mode=1;          
110         }
111
112         ppc6_open(PPCSTRUCT(pi));  
113         ppc6_wr_extout(PPCSTRUCT(pi),0x3);
114 }
115
116 static void bpck6_disconnect ( PIA *pi )
117 {
118         if(verbose)
119         {
120                 printk("disconnect\n");
121         }
122         ppc6_wr_extout(PPCSTRUCT(pi),0x0);
123         ppc6_close(PPCSTRUCT(pi));
124 }
125
126 static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
127 {
128         if(verbose)
129         {
130                 printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
131                         ((struct pardevice*)(pi->pardev))->port->modes,
132                         ((struct pardevice *)(pi->pardev))->port->base); 
133         }
134
135         /*copy over duplicate stuff.. initialize state info*/
136         PPCSTRUCT(pi)->ppc_id=pi->unit;
137         PPCSTRUCT(pi)->lpt_addr=pi->port;
138
139         /* look at the parport device to see if what modes we can use */
140         if(((struct pardevice *)(pi->pardev))->port->modes & 
141                 (PARPORT_MODE_EPP)
142           )
143         {
144                 return 5; /* Can do EPP*/
145         }
146         else if(((struct pardevice *)(pi->pardev))->port->modes & 
147                         (PARPORT_MODE_TRISTATE)
148                )
149         {
150                 return 2;
151         }
152         else /*Just flat SPP*/
153         {
154                 return 1;
155         }
156 }
157
158 static int bpck6_probe_unit ( PIA *pi )
159 {
160         int out;
161
162         if(verbose)
163         {
164                 printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
165         }
166
167         /*SET PPC UNIT NUMBER*/
168         PPCSTRUCT(pi)->ppc_id=pi->unit;
169
170         /*LOWER DOWN TO UNIDIRECTIONAL*/
171         PPCSTRUCT(pi)->mode=1;          
172
173         out=ppc6_open(PPCSTRUCT(pi));
174
175         if(verbose)
176         {
177                 printk(KERN_DEBUG "ppc_open returned %2x\n",out);
178         }
179
180         if(out)
181         {
182                 ppc6_close(PPCSTRUCT(pi));
183                 if(verbose)
184                 {
185                         printk(KERN_DEBUG "leaving probe\n");
186                 }
187                return(1);
188         }
189         else
190         {
191                 if(verbose)
192                 {
193                         printk(KERN_DEBUG "Failed open\n");
194                 }
195                 return(0);
196         }
197 }
198
199 static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
200 {
201         char *mode_string[5]=
202                 {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
203
204         printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
205         printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
206         printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
207                 pi->device,BACKPACK_VERSION,pi->port);
208         printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
209                 pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
210 }
211
212 static int bpck6_init_proto(PIA *pi)
213 {
214         Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
215
216         if (p) {
217                 pi->private = (unsigned long)p;
218                 return 0;
219         }
220
221         printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
222         return -1;
223 }
224
225 static void bpck6_release_proto(PIA *pi)
226 {
227         kfree((void *)(pi->private)); 
228 }
229
230 static struct pi_protocol bpck6 = {
231         .owner          = THIS_MODULE,
232         .name           = "bpck6",
233         .max_mode       = 5,
234         .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
235         .max_units      = 255,
236         .write_regr     = bpck6_write_regr,
237         .read_regr      = bpck6_read_regr,
238         .write_block    = bpck6_write_block,
239         .read_block     = bpck6_read_block,
240         .connect        = bpck6_connect,
241         .disconnect     = bpck6_disconnect,
242         .test_port      = bpck6_test_port,
243         .probe_unit     = bpck6_probe_unit,
244         .log_adapter    = bpck6_log_adapter,
245         .init_proto     = bpck6_init_proto,
246         .release_proto  = bpck6_release_proto,
247 };
248
249 static int __init bpck6_init(void)
250 {
251         printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
252         printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
253         if(verbose)
254                 printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
255         return paride_register(&bpck6);
256 }
257
258 static void __exit bpck6_exit(void)
259 {
260         paride_unregister(&bpck6);
261 }
262
263 MODULE_LICENSE("GPL");
264 MODULE_AUTHOR("Micro Solutions Inc.");
265 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
266 module_param(verbose, bool, 0644);
267 module_init(bpck6_init)
268 module_exit(bpck6_exit)