Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bpck6.c
Go to the documentation of this file.
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 ([email protected])
10  Clive Turvey ([email protected])
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 &
141  )
142  {
143  return 5; /* Can do EPP*/
144  }
145  else if(((struct pardevice *)(pi->pardev))->port->modes &
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)