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