1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24static int verbose;
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
46
47#define ATAPI_DATA 0
48#define ATAPI_ERROR 1
49#define ATAPI_FEATURES 1
50#define ATAPI_INT_REASON 2
51#define ATAPI_COUNT_LOW 4
52#define ATAPI_COUNT_HIGH 5
53#define ATAPI_DRIVE_SEL 6
54#define ATAPI_STATUS 7
55#define ATAPI_COMMAND 7
56#define ATAPI_ALT_STATUS 0x0e
57#define ATAPI_DEVICE_CONTROL 0x0e
58
59
60static int bpck6_read_regr(PIA *pi, int cont, int reg)
61{
62 unsigned int out;
63
64
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
73static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
74{
75
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
82static 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
87static 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
92static 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
116static 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
126static int bpck6_test_port ( PIA *pi )
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
136 PPCSTRUCT(pi)->ppc_id=pi->unit;
137 PPCSTRUCT(pi)->lpt_addr=pi->port;
138
139
140 if(((struct pardevice *)(pi->pardev))->port->modes &
141 (PARPORT_MODE_EPP)
142 )
143 {
144 return 5;
145 }
146 else if(((struct pardevice *)(pi->pardev))->port->modes &
147 (PARPORT_MODE_TRISTATE)
148 )
149 {
150 return 2;
151 }
152 else
153 {
154 return 1;
155 }
156}
157
158static 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
168 PPCSTRUCT(pi)->ppc_id=pi->unit;
169
170
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
199static 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
212static 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
225static void bpck6_release_proto(PIA *pi)
226{
227 kfree((void *)(pi->private));
228}
229
230static struct pi_protocol bpck6 = {
231 .owner = THIS_MODULE,
232 .name = "bpck6",
233 .max_mode = 5,
234 .epp_first = 2,
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
249static 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
258static void __exit bpck6_exit(void)
259{
260 paride_unregister(&bpck6);
261}
262
263MODULE_LICENSE("GPL");
264MODULE_AUTHOR("Micro Solutions Inc.");
265MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
266module_param(verbose, bool, 0644);
267module_init(bpck6_init)
268module_exit(bpck6_exit)
269