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