OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [block/] [paride/] [paride.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.