Merge branch 'upstream'
[sfrench/cifs-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 = kzalloc(sizeof(Interface), GFP_KERNEL);
228
229         if (p) {
230                 pi->private = (unsigned long)p;
231                 return 0;
232         }
233
234         printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
235         return -1;
236 }
237
238 static void bpck6_release_proto(PIA *pi)
239 {
240         kfree((void *)(pi->private)); 
241 }
242
243 static struct pi_protocol bpck6 = {
244         .owner          = THIS_MODULE,
245         .name           = "bpck6",
246         .max_mode       = 5,
247         .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
248         .max_units      = 255,
249         .write_regr     = bpck6_write_regr,
250         .read_regr      = bpck6_read_regr,
251         .write_block    = bpck6_write_block,
252         .read_block     = bpck6_read_block,
253         .connect        = bpck6_connect,
254         .disconnect     = bpck6_disconnect,
255         .test_port      = bpck6_test_port,
256         .probe_unit     = bpck6_probe_unit,
257         .log_adapter    = bpck6_log_adapter,
258         .init_proto     = bpck6_init_proto,
259         .release_proto  = bpck6_release_proto,
260 };
261
262 static int __init bpck6_init(void)
263 {
264         printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
265         printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
266         if(verbose)
267                 printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
268         return pi_register(&bpck6) - 1;  
269 }
270
271 static void __exit bpck6_exit(void)
272 {
273         pi_unregister(&bpck6);
274 }
275
276 MODULE_LICENSE("GPL");
277 MODULE_AUTHOR("Micro Solutions Inc.");
278 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
279 module_param(verbose, bool, 0644);
280 module_init(bpck6_init)
281 module_exit(bpck6_exit)