Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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)
269 
  This page was automatically generated by the LXR engine.