1 /*
2 paride.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the base module for the family of device drivers
6 that support parallel port IDE devices.
7
8 */
9
10 /* Changes:
11
12 1.01 GRG 1998.05.03 Use spinlocks
13 1.02 GRG 1998.05.05 init_proto, release_proto, ktti
14 1.03 GRG 1998.08.15 eliminate compiler warning
15 1.04 GRG 1998.11.28 added support for FRIQ
16 1.05 TMW 2000.06.06 use parport_find_number instead of
17 parport_enumerate
18 1.06 TMW 2001.03.26 more sane parport-or-not resource management
19 */
20
21 #define PI_VERSION "1.06"
22
23 #include <linux/module.h>
24 #include <linux/config.h>
25 #include <linux/kmod.h>
26 #include <linux/types.h>
27 #include <linux/kernel.h>
28 #include <linux/ioport.h>
29 #include <linux/string.h>
30 #include <linux/spinlock.h>
31 #include <linux/wait.h>
32
33 #ifdef CONFIG_PARPORT_MODULE
34 #define CONFIG_PARPORT
35 #endif
36
37 #ifdef CONFIG_PARPORT
38 #include <linux/parport.h>
39 #endif
40
41 #include "paride.h"
42
43 #define MAX_PROTOS 32
44
45 static struct pi_protocol *protocols[MAX_PROTOS];
46
47 static spinlock_t pi_spinlock = SPIN_LOCK_UNLOCKED;
48
pi_write_regr(PIA * pi,int cont,int regr,int val)49 void pi_write_regr( PIA *pi, int cont, int regr, int val)
50
51 { pi->proto->write_regr(pi,cont,regr,val);
52 }
53
pi_read_regr(PIA * pi,int cont,int regr)54 int pi_read_regr( PIA *pi, int cont, int regr)
55
56 { return pi->proto->read_regr(pi,cont,regr);
57 }
58
pi_write_block(PIA * pi,char * buf,int count)59 void pi_write_block( PIA *pi, char * buf, int count)
60
61 { pi->proto->write_block(pi,buf,count);
62 }
63
pi_read_block(PIA * pi,char * buf,int count)64 void pi_read_block( PIA *pi, char * buf, int count)
65
66 { pi->proto->read_block(pi,buf,count);
67 }
68
69 #ifdef CONFIG_PARPORT
70
pi_wake_up(void * p)71 static void pi_wake_up( void *p)
72
73 { PIA *pi = (PIA *) p;
74 unsigned long flags;
75 void (*cont)(void) = NULL;
76
77 spin_lock_irqsave(&pi_spinlock,flags);
78
79 if (pi->claim_cont && !parport_claim(pi->pardev)) {
80 cont = pi->claim_cont;
81 pi->claim_cont = NULL;
82 pi->claimed = 1;
83 }
84
85 spin_unlock_irqrestore(&pi_spinlock,flags);
86
87 wake_up(&(pi->parq));
88
89 if (cont) cont();
90 }
91
92 #endif
93
pi_do_claimed(PIA * pi,void (* cont)(void))94 void pi_do_claimed( PIA *pi, void(*cont)(void))
95
96 #ifdef CONFIG_PARPORT
97
98 { unsigned long flags;
99
100 spin_lock_irqsave(&pi_spinlock,flags);
101
102 if (!pi->pardev || !parport_claim(pi->pardev)) {
103 pi->claimed = 1;
104 spin_unlock_irqrestore(&pi_spinlock,flags);
105 cont();
106 } else {
107 pi->claim_cont = cont;
108 spin_unlock_irqrestore(&pi_spinlock,flags);
109 }
110 }
111
112 #else
113
114 { cont();
115 }
116
117 #endif
118
pi_claim(PIA * pi)119 static void pi_claim( PIA *pi)
120
121 { if (pi->claimed) return;
122 pi->claimed = 1;
123 #ifdef CONFIG_PARPORT
124 if (pi->pardev)
125 wait_event (pi->parq,
126 !parport_claim ((struct pardevice *)pi->pardev));
127 #endif
128 }
129
pi_unclaim(PIA * pi)130 static void pi_unclaim( PIA *pi)
131
132 { pi->claimed = 0;
133 #ifdef CONFIG_PARPORT
134 if (pi->pardev) parport_release((struct pardevice *)(pi->pardev));
135 #endif
136 }
137
pi_connect(PIA * pi)138 void pi_connect( PIA *pi)
139
140 { pi_claim(pi);
141 pi->proto->connect(pi);
142 }
143
pi_disconnect(PIA * pi)144 void pi_disconnect( PIA *pi)
145
146 { pi->proto->disconnect(pi);
147 pi_unclaim(pi);
148 }
149
pi_unregister_parport(PIA * pi)150 static void pi_unregister_parport( PIA *pi)
151
152 {
153 #ifdef CONFIG_PARPORT
154 if (pi->pardev) {
155 parport_unregister_device((struct pardevice *)(pi->pardev));
156 pi->pardev = NULL;
157 }
158 #endif
159 }
160
pi_release(PIA * pi)161 void pi_release( PIA *pi)
162
163 { pi_unregister_parport(pi);
164 #ifndef CONFIG_PARPORT
165 if (pi->reserved)
166 release_region(pi->port,pi->reserved);
167 #endif /* !CONFIG_PARPORT */
168 pi->proto->release_proto(pi);
169 }
170
171 #define WR(r,v) pi_write_regr(pi,0,r,v)
172 #define RR(r) (pi_read_regr(pi,0,r))
173
pi_test_proto(PIA * pi,char * scratch,int verbose)174 static int pi_test_proto( PIA *pi, char * scratch, int verbose )
175
176 { int j, k;
177 int e[2] = {0,0};
178
179 if (pi->proto->test_proto) {
180 pi_claim(pi);
181 j = pi->proto->test_proto(pi,scratch,verbose);
182 pi_unclaim(pi);
183 return j;
184 }
185
186 pi_connect(pi);
187
188 for (j=0;j<2;j++) {
189 WR(6,0xa0+j*0x10);
190 for (k=0;k<256;k++) {
191 WR(2,k^0xaa);
192 WR(3,k^0x55);
193 if (RR(2) != (k^0xaa)) e[j]++;
194 }
195 }
196
197 pi_disconnect(pi);
198
199 if (verbose)
200 printk("%s: %s: port 0x%x, mode %d, test=(%d,%d)\n",
201 pi->device,pi->proto->name,pi->port,
202 pi->mode,e[0],e[1]);
203
204 return (e[0] && e[1]); /* not here if both > 0 */
205 }
206
pi_register(PIP * pr)207 int pi_register( PIP *pr)
208
209 { int k;
210
211 for (k=0;k<MAX_PROTOS;k++)
212 if (protocols[k] && !strcmp(pr->name,protocols[k]->name)) {
213 printk("paride: %s protocol already registered\n",pr->name);
214 return 0;
215 }
216 k = 0;
217 while((k<MAX_PROTOS) && (protocols[k])) k++;
218 if (k == MAX_PROTOS) {
219 printk("paride: protocol table full\n");
220 return 0;
221 }
222 MOD_INC_USE_COUNT;
223 protocols[k] = pr;
224 pr->index = k;
225 printk("paride: %s registered as protocol %d\n",pr->name,k);
226 return 1;
227 }
228
pi_unregister(PIP * pr)229 void pi_unregister( PIP *pr)
230
231 { if (!pr) return;
232 if (protocols[pr->index] != pr) {
233 printk("paride: %s not registered\n",pr->name);
234 return;
235 }
236 protocols[pr->index] = 0;
237 MOD_DEC_USE_COUNT;
238 }
239
pi_register_parport(PIA * pi,int verbose)240 static int pi_register_parport( PIA *pi, int verbose)
241
242 {
243 #ifdef CONFIG_PARPORT
244
245 struct parport *port;
246
247 port = parport_find_base (pi->port);
248 if (!port)
249 return 0;
250
251 pi->pardev = parport_register_device(port,
252 pi->device,NULL,
253 pi_wake_up,NULL,
254 0,(void *)pi);
255 parport_put_port (port);
256 if (!pi->pardev)
257 return 0;
258
259 init_waitqueue_head(&pi->parq);
260
261 if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,
262 port->name);
263
264 pi->parname = (char *)port->name;
265 #endif
266
267 return 1;
268 }
269
pi_probe_mode(PIA * pi,int max,char * scratch,int verbose)270 static int pi_probe_mode( PIA *pi, int max, char * scratch, int verbose)
271
272 { int best, range;
273
274 if (pi->mode != -1) {
275 if (pi->mode >= max) return 0;
276 range = 3;
277 if (pi->mode >= pi->proto->epp_first) range = 8;
278 if ((range == 8) && (pi->port % 8)) return 0;
279 pi->reserved = range;
280 return (!pi_test_proto(pi,scratch,verbose));
281 }
282 best = -1;
283 for(pi->mode=0;pi->mode<max;pi->mode++) {
284 range = 3;
285 if (pi->mode >= pi->proto->epp_first) range = 8;
286 if ((range == 8) && (pi->port % 8)) break;
287 pi->reserved = range;
288 if (!pi_test_proto(pi,scratch,verbose)) best = pi->mode;
289 }
290 pi->mode = best;
291 return (best > -1);
292 }
293
pi_probe_unit(PIA * pi,int unit,char * scratch,int verbose)294 static int pi_probe_unit( PIA *pi, int unit, char * scratch, int verbose)
295
296 { int max,s,e;
297
298 s = unit; e = s+1;
299
300 if (s == -1) {
301 s = 0;
302 e = pi->proto->max_units;
303 }
304
305 if (!pi_register_parport(pi,verbose))
306 return 0;
307
308 if (pi->proto->test_port) {
309 pi_claim(pi);
310 max = pi->proto->test_port(pi);
311 pi_unclaim(pi);
312 }
313 else max = pi->proto->max_mode;
314
315 if (pi->proto->probe_unit) {
316 pi_claim(pi);
317 for (pi->unit=s;pi->unit<e;pi->unit++)
318 if (pi->proto->probe_unit(pi)) {
319 pi_unclaim(pi);
320 if (pi_probe_mode(pi,max,scratch,verbose)) return 1;
321 pi_unregister_parport(pi);
322 return 0;
323 }
324 pi_unclaim(pi);
325 pi_unregister_parport(pi);
326 return 0;
327 }
328
329 if (!pi_probe_mode(pi,max,scratch,verbose)) {
330 pi_unregister_parport(pi);
331 return 0;
332 }
333 return 1;
334
335 }
336
pi_init(PIA * pi,int autoprobe,int port,int mode,int unit,int protocol,int delay,char * scratch,int devtype,int verbose,char * device)337 int pi_init(PIA *pi, int autoprobe, int port, int mode,
338 int unit, int protocol, int delay, char * scratch,
339 int devtype, int verbose, char *device )
340
341 { int p,k,s,e;
342 int lpts[7] = {0x3bc,0x378,0x278,0x268,0x27c,0x26c,0};
343
344 s = protocol; e = s+1;
345
346 if (!protocols[0])
347 request_module ("paride_protocol");
348
349 if (autoprobe) {
350 s = 0;
351 e = MAX_PROTOS;
352 } else if ((s < 0) || (s >= MAX_PROTOS) || (port <= 0) ||
353 (!protocols[s]) || (unit < 0) ||
354 (unit >= protocols[s]->max_units)) {
355 printk("%s: Invalid parameters\n",device);
356 return 0;
357 }
358
359 for (p=s;p<e;p++) {
360 if (protocols[p]) {
361 pi->proto = protocols[p];
362 pi->private = 0;
363 pi->proto->init_proto(pi);
364 if (delay == -1) pi->delay = pi->proto->default_delay;
365 else pi->delay = delay;
366 pi->devtype = devtype;
367 pi->device = device;
368
369 pi->parname = NULL;
370 pi->pardev = NULL;
371 init_waitqueue_head(&pi->parq);
372 pi->claimed = 0;
373 pi->claim_cont = NULL;
374
375 pi->mode = mode;
376 if (port != -1) {
377 pi->port = port;
378 if (pi_probe_unit(pi,unit,scratch,verbose)) break;
379 pi->port = 0;
380 } else {
381 k = 0;
382 while ((pi->port = lpts[k++]))
383 if (pi_probe_unit(pi,unit,scratch,verbose)) break;
384 if (pi->port) break;
385 }
386 pi->proto->release_proto(pi);
387 }
388 }
389
390 if (!pi->port) {
391 if (autoprobe) printk("%s: Autoprobe failed\n",device);
392 else printk("%s: Adapter not found\n",device);
393 return 0;
394 }
395
396 #ifndef CONFIG_PARPORT
397 if (!request_region(pi->port,pi->reserved,pi->device))
398 {
399 printk(KERN_WARNING"paride: Unable to request region 0x%x\n", pi->port);
400 return 0;
401 }
402 #endif /* !CONFIG_PARPORT */
403
404 if (pi->parname)
405 printk("%s: Sharing %s at 0x%x\n",pi->device,
406 pi->parname,pi->port);
407
408 pi->proto->log_adapter(pi,scratch,verbose);
409
410 return 1;
411 }
412
413 #ifdef MODULE
414
init_module(void)415 int init_module(void)
416
417 {
418 int k;
419 const char *indicate_pp = "";
420 #ifdef CONFIG_PARPORT
421 indicate_pp = " (parport)";
422 #endif
423
424 for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0;
425
426 printk("paride: version %s installed%s\n",PI_VERSION,indicate_pp);
427 return 0;
428 }
429
cleanup_module(void)430 void cleanup_module(void)
431
432 {
433 }
434
435 #else
436
paride_init(void)437 void paride_init( void )
438
439 {
440
441 #ifdef CONFIG_PARIDE_ATEN
442 { extern struct pi_protocol aten;
443 pi_register(&aten);
444 };
445 #endif
446 #ifdef CONFIG_PARIDE_BPCK
447 { extern struct pi_protocol bpck;
448 pi_register(&bpck);
449 };
450 #endif
451 #ifdef CONFIG_PARIDE_COMM
452 { extern struct pi_protocol comm;
453 pi_register(&comm);
454 };
455 #endif
456 #ifdef CONFIG_PARIDE_DSTR
457 { extern struct pi_protocol dstr;
458 pi_register(&dstr);
459 };
460 #endif
461 #ifdef CONFIG_PARIDE_EPAT
462 { extern struct pi_protocol epat;
463 pi_register(&epat);
464 };
465 #endif
466 #ifdef CONFIG_PARIDE_EPIA
467 { extern struct pi_protocol epia;
468 pi_register(&epia);
469 };
470 #endif
471 #ifdef CONFIG_PARIDE_FRPW
472 { extern struct pi_protocol frpw;
473 pi_register(&frpw);
474 };
475 #endif
476 #ifdef CONFIG_PARIDE_FRIQ
477 { extern struct pi_protocol friq;
478 pi_register(&friq);
479 };
480 #endif
481 #ifdef CONFIG_PARIDE_FIT2
482 { extern struct pi_protocol fit2;
483 pi_register(&fit2);
484 };
485 #endif
486 #ifdef CONFIG_PARIDE_FIT3
487 { extern struct pi_protocol fit3;
488 pi_register(&fit3);
489 };
490 #endif
491 #ifdef CONFIG_PARIDE_KBIC
492 { extern struct pi_protocol k951;
493 extern struct pi_protocol k971;
494 pi_register(&k951);
495 pi_register(&k971);
496 };
497 #endif
498 #ifdef CONFIG_PARIDE_KTTI
499 { extern struct pi_protocol ktti;
500 pi_register(&ktti);
501 };
502 #endif
503 #ifdef CONFIG_PARIDE_ON20
504 { extern struct pi_protocol on20;
505 pi_register(&on20);
506 };
507 #endif
508 #ifdef CONFIG_PARIDE_ON26
509 { extern struct pi_protocol on26;
510 pi_register(&on26);
511 };
512 #endif
513
514 #ifdef CONFIG_PARIDE_PD
515 { extern int pd_init(void);
516 pd_init();
517 };
518 #endif
519 #ifdef CONFIG_PARIDE_PCD
520 { extern int pcd_init(void);
521 pcd_init();
522 };
523 #endif
524 #ifdef CONFIG_PARIDE_PF
525 { extern int pf_init(void);
526 pf_init();
527 };
528 #endif
529 #ifdef CONFIG_PARIDE_PT
530 { extern int pt_init(void);
531 pt_init();
532 };
533 #endif
534 #ifdef CONFIG_PARIDE_PG
535 { extern int pg_init(void);
536 pg_init();
537 };
538 #endif
539 }
540
541 #endif
542
543 /* end of paride.c */
544 MODULE_LICENSE("GPL");
545