This source file includes following definitions.
- init_module
- cleanup_module
- stli_memalloc
- stli_open
- stli_close
- stli_initopen
- stli_rawopen
- stli_rawclose
- stli_cmdwait
- stli_setport
- stli_delay
- stli_waitcarrier
- stli_write
- stli_putchar
- stli_flushchars
- stli_writeroom
- stli_charsinbuffer
- stli_getserial
- stli_setserial
- stli_ioctl
- stli_settermios
- stli_throttle
- stli_unthrottle
- stli_stop
- stli_start
- stli_dohangup
- stli_hangup
- stli_flushbuffer
- stli_sendcmd
- stli_read
- stli_dodelaycmd
- stli_hostcmd
- stli_poll
- stli_mkasyport
- stli_mkasysigs
- stli_mktiocm
- stli_initports
- stli_ecpinit
- stli_ecpenable
- stli_ecpdisable
- stli_ecpgetmemptr
- stli_ecpreset
- stli_ecpintr
- stli_ecpeiinit
- stli_ecpeienable
- stli_ecpeidisable
- stli_ecpeigetmemptr
- stli_ecpeireset
- stli_ecpmcenable
- stli_ecpmcdisable
- stli_ecpmcgetmemptr
- stli_ecpmcreset
- stli_onbinit
- stli_onbenable
- stli_onbdisable
- stli_onbgetmemptr
- stli_onbreset
- stli_onbeinit
- stli_onbeenable
- stli_onbedisable
- stli_onbegetmemptr
- stli_onbereset
- stli_bbyinit
- stli_bbygetmemptr
- stli_bbyreset
- stli_stalinit
- stli_stalgetmemptr
- stli_stalreset
- stli_initecp
- stli_initonb
- stli_startbrd
- stli_brdinit
- stli_eisamemprobe
- stli_findeisabrds
- stli_initbrds
- stli_memread
- stli_memwrite
- stli_getbrdstats
- stli_getport
- stli_getportstats
- stli_clrportstats
- stli_getportstruct
- stli_getbrdstruct
- stli_memioctl
- stli_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <linux/module.h>
29 #include <linux/errno.h>
30 #include <linux/sched.h>
31 #include <linux/timer.h>
32 #include <linux/wait.h>
33 #include <linux/interrupt.h>
34 #include <linux/termios.h>
35 #include <linux/fcntl.h>
36 #include <linux/tty_driver.h>
37 #include <linux/tty.h>
38 #include <linux/tty_flip.h>
39 #include <linux/serial.h>
40 #include <linux/cdk.h>
41 #include <linux/comstats.h>
42 #include <linux/istallion.h>
43 #include <linux/string.h>
44 #include <linux/malloc.h>
45 #include <linux/ioport.h>
46 #include <linux/delay.h>
47 #include <asm/io.h>
48
49
50
51
52
53
54
55
56
57
58 #define BRD_UNKNOWN 0
59 #define BRD_STALLION 1
60 #define BRD_BRUMBY4 2
61 #define BRD_ONBOARD2 3
62 #define BRD_ONBOARD 4
63 #define BRD_BRUMBY8 5
64 #define BRD_BRUMBY16 6
65 #define BRD_ONBOARDE 7
66 #define BRD_ONBOARD32 9
67 #define BRD_ONBOARD2_32 10
68 #define BRD_ONBOARDRS 11
69 #define BRD_EASYIO 20
70 #define BRD_ECH 21
71 #define BRD_ECHMC 22
72 #define BRD_ECP 23
73 #define BRD_ECPE 24
74 #define BRD_ECPMC 25
75 #define BRD_ECHPCI 26
76
77 #define BRD_BRUMBY BRD_BRUMBY4
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 typedef struct {
113 int brdtype;
114 int ioaddr1;
115 int ioaddr2;
116 unsigned long memaddr;
117 int irq;
118 int irqtype;
119 } stlconf_t;
120
121 static stlconf_t stli_brdconf[] = {
122 { BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },
123 };
124
125 static int stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t);
126
127
128
129
130
131
132 #define STLI_EISAPROBE 0
133
134
135
136
137
138
139
140 #ifndef STL_SIOMEMMAJOR
141 #define STL_SIOMEMMAJOR 28
142 #endif
143 #ifndef STL_SERIALMAJOR
144 #define STL_SERIALMAJOR 24
145 #endif
146 #ifndef STL_CALLOUTMAJOR
147 #define STL_CALLOUTMAJOR 25
148 #endif
149
150 #define STL_DRVTYPSERIAL 1
151 #define STL_DRVTYPCALLOUT 2
152
153
154
155
156
157
158
159 static char *stli_drvname = "Stallion Intelligent Multiport Serial Driver";
160 static char *stli_drvversion = "1.1.3";
161 static char *stli_serialname = "ttyE";
162 static char *stli_calloutname = "cue";
163
164 static struct tty_driver stli_serial;
165 static struct tty_driver stli_callout;
166 static struct tty_struct *stli_ttys[STL_MAXDEVS];
167 static struct termios *stli_termios[STL_MAXDEVS];
168 static struct termios *stli_termioslocked[STL_MAXDEVS];
169 static int stli_refcount;
170
171
172
173
174
175
176
177
178 static char *stli_tmpwritebuf = (char *) NULL;
179 static struct semaphore stli_tmpwritesem = MUTEX;
180
181 #define STLI_TXBUFSIZE 4096
182
183
184
185
186
187
188
189
190 static char *stli_txcookbuf = (char *) NULL;
191 static int stli_txcooksize = 0;
192 static int stli_txcookrealsize = 0;
193 static struct tty_struct *stli_txcooktty = (struct tty_struct *) NULL;
194
195
196
197
198
199
200 static struct termios stli_deftermios = {
201 0,
202 0,
203 (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
204 0,
205 0,
206 INIT_C_CC
207 };
208
209
210
211
212
213 static comstats_t stli_comstats;
214 static combrd_t stli_brdstats;
215 static asystats_t stli_cdkstats;
216 static stlibrd_t stli_dummybrd;
217 static stliport_t stli_dummyport;
218
219
220
221 static stlibrd_t *stli_brds[STL_MAXBRDS];
222
223 static int stli_shared = 0;
224
225
226
227
228
229
230
231 #define BST_FOUND 0x1
232 #define BST_STARTED 0x2
233
234
235
236
237
238
239
240 #define ST_INITIALIZING 1
241 #define ST_OPENING 2
242 #define ST_CLOSING 3
243 #define ST_CMDING 4
244 #define ST_TXBUSY 5
245 #define ST_RXING 6
246 #define ST_DOFLUSHRX 7
247 #define ST_DOFLUSHTX 8
248 #define ST_DOSIGS 9
249 #define ST_RXSTOP 10
250 #define ST_GETSIGS 11
251
252
253
254
255
256 static char *stli_brdnames[] = {
257 "Unknown",
258 "Stallion",
259 "Brumby",
260 "ONboard-MC",
261 "ONboard",
262 "Brumby",
263 "Brumby",
264 "ONboard-EI",
265 (char *) NULL,
266 "ONboard",
267 "ONboard-MC",
268 "ONboard-MC",
269 (char *) NULL,
270 (char *) NULL,
271 (char *) NULL,
272 (char *) NULL,
273 (char *) NULL,
274 (char *) NULL,
275 (char *) NULL,
276 (char *) NULL,
277 "EasyIO",
278 "EC8/32-AT",
279 "EC8/32-MC",
280 "EC8/64-AT",
281 "EC8/64-EI",
282 "EC8/64-MC",
283 "EC8/32-PCI",
284 };
285
286
287
288
289
290
291
292
293
294 static unsigned long stli_eisamemprobeaddrs[] = {
295 0xc0000, 0xd0000, 0xe0000, 0xf0000,
296 0x80000000, 0x80010000, 0x80020000, 0x80030000,
297 0x40000000, 0x40010000, 0x40020000, 0x40030000,
298 0xc0000000, 0xc0010000, 0xc0020000, 0xc0030000,
299 0xff000000, 0xff010000, 0xff020000, 0xff030000,
300 };
301
302 static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
303 int stli_eisaprobe = STLI_EISAPROBE;
304
305
306
307
308
309
310
311
312 #define ECP_IOSIZE 4
313 #define ECP_MEMSIZE (128 * 1024)
314 #define ECP_ATPAGESIZE (4 * 1024)
315 #define ECP_EIPAGESIZE (64 * 1024)
316 #define ECP_MCPAGESIZE (4 * 1024)
317
318 #define STL_EISAID 0x8c4e
319
320
321
322
323 #define ECP_ATIREG 0
324 #define ECP_ATCONFR 1
325 #define ECP_ATMEMAR 2
326 #define ECP_ATMEMPR 3
327 #define ECP_ATSTOP 0x1
328 #define ECP_ATINTENAB 0x10
329 #define ECP_ATENABLE 0x20
330 #define ECP_ATDISABLE 0x00
331 #define ECP_ATADDRMASK 0x3f000
332 #define ECP_ATADDRSHFT 12
333
334
335
336
337 #define ECP_EIIREG 0
338 #define ECP_EIMEMARL 1
339 #define ECP_EICONFR 2
340 #define ECP_EIMEMARH 3
341 #define ECP_EIENABLE 0x1
342 #define ECP_EIDISABLE 0x0
343 #define ECP_EISTOP 0x4
344 #define ECP_EIEDGE 0x00
345 #define ECP_EILEVEL 0x80
346 #define ECP_EIADDRMASKL 0x00ff0000
347 #define ECP_EIADDRSHFTL 16
348 #define ECP_EIADDRMASKH 0xff000000
349 #define ECP_EIADDRSHFTH 24
350 #define ECP_EIBRDENAB 0xc84
351
352 #define ECP_EISAID 0x4
353
354
355
356
357
358 #define ECP_MCIREG 0
359 #define ECP_MCCONFR 1
360 #define ECP_MCSTOP 0x20
361 #define ECP_MCENABLE 0x80
362 #define ECP_MCDISABLE 0x00
363
364
365
366
367
368 #define ONB_IOSIZE 16
369 #define ONB_MEMSIZE (64 * 1024)
370 #define ONB_ATPAGESIZE (64 * 1024)
371 #define ONB_MCPAGESIZE (64 * 1024)
372 #define ONB_EIMEMSIZE (128 * 1024)
373 #define ONB_EIPAGESIZE (64 * 1024)
374
375
376
377
378 #define ONB_ATIREG 0
379 #define ONB_ATMEMAR 1
380 #define ONB_ATCONFR 2
381 #define ONB_ATSTOP 0x4
382 #define ONB_ATENABLE 0x01
383 #define ONB_ATDISABLE 0x00
384 #define ONB_ATADDRMASK 0xff0000
385 #define ONB_ATADDRSHFT 16
386
387 #define ONB_MEMENABLO 0
388 #define ONB_MEMENABHI 0x02
389
390
391
392
393 #define ONB_EIIREG 0
394 #define ONB_EIMEMARL 1
395 #define ONB_EICONFR 2
396 #define ONB_EIMEMARH 3
397 #define ONB_EIENABLE 0x1
398 #define ONB_EIDISABLE 0x0
399 #define ONB_EISTOP 0x4
400 #define ONB_EIEDGE 0x00
401 #define ONB_EILEVEL 0x80
402 #define ONB_EIADDRMASKL 0x00ff0000
403 #define ONB_EIADDRSHFTL 16
404 #define ONB_EIADDRMASKH 0xff000000
405 #define ONB_EIADDRSHFTH 24
406 #define ONB_EIBRDENAB 0xc84
407
408 #define ONB_EISAID 0x1
409
410
411
412
413
414 #define BBY_IOSIZE 16
415 #define BBY_MEMSIZE (64 * 1024)
416 #define BBY_PAGESIZE (16 * 1024)
417
418 #define BBY_ATIREG 0
419 #define BBY_ATCONFR 1
420 #define BBY_ATSTOP 0x4
421
422
423
424
425
426 #define STAL_IOSIZE 16
427 #define STAL_MEMSIZE (64 * 1024)
428 #define STAL_PAGESIZE (64 * 1024)
429
430
431
432
433
434
435
436 #define ECH_PNLSTATUS 2
437 #define ECH_PNL16PORT 0x20
438 #define ECH_PNLIDMASK 0x07
439 #define ECH_PNLINTRPEND 0x80
440
441
442
443
444
445
446
447
448
449
450 #define EBRDINIT(brdp) \
451 if (brdp->init != NULL) \
452 (* brdp->init)(brdp)
453
454 #define EBRDENABLE(brdp) \
455 if (brdp->enable != NULL) \
456 (* brdp->enable)(brdp);
457
458 #define EBRDDISABLE(brdp) \
459 if (brdp->disable != NULL) \
460 (* brdp->disable)(brdp);
461
462 #define EBRDINTR(brdp) \
463 if (brdp->intr != NULL) \
464 (* brdp->intr)(brdp);
465
466 #define EBRDRESET(brdp) \
467 if (brdp->reset != NULL) \
468 (* brdp->reset)(brdp);
469
470 #define EBRDGETMEMPTR(brdp,offset) \
471 (* brdp->getmemptr)(brdp, offset, __LINE__)
472
473
474
475
476 #define STL_MAXBAUD 230400
477 #define STL_BAUDBASE 115200
478 #define STL_CLOSEDELAY 50
479
480
481
482
483
484
485 #define MKDEV2BRD(min) (((min) & 0xc0) >> 6)
486 #define MKDEV2PORT(min) ((min) & 0x3f)
487
488
489
490
491
492
493 static unsigned int stli_baudrates[] = {
494 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
495 9600, 19200, 38400, 57600, 115200, 230400
496 };
497
498
499
500
501
502
503 #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
504
505
506
507
508
509
510
511 #ifdef MODULE
512 int init_module(void);
513 void cleanup_module(void);
514 #endif
515
516 int stli_init(void);
517 static int stli_open(struct tty_struct *tty, struct file *filp);
518 static void stli_close(struct tty_struct *tty, struct file *filp);
519 static int stli_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
520 static void stli_putchar(struct tty_struct *tty, unsigned char ch);
521 static void stli_flushchars(struct tty_struct *tty);
522 static int stli_writeroom(struct tty_struct *tty);
523 static int stli_charsinbuffer(struct tty_struct *tty);
524 static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
525 static void stli_settermios(struct tty_struct *tty, struct termios *old);
526 static void stli_throttle(struct tty_struct *tty);
527 static void stli_unthrottle(struct tty_struct *tty);
528 static void stli_stop(struct tty_struct *tty);
529 static void stli_start(struct tty_struct *tty);
530 static void stli_flushbuffer(struct tty_struct *tty);
531 static void stli_hangup(struct tty_struct *tty);
532
533 static int stli_initbrds(void);
534 static int stli_brdinit(stlibrd_t *brdp);
535 static int stli_initecp(stlibrd_t *brdp);
536 static int stli_initonb(stlibrd_t *brdp);
537 static int stli_eisamemprobe(stlibrd_t *brdp);
538 static int stli_findeisabrds(void);
539 static int stli_initports(stlibrd_t *brdp);
540 static int stli_startbrd(stlibrd_t *brdp);
541 static int stli_memread(struct inode *ip, struct file *fp, char *buf, int count);
542 static int stli_memwrite(struct inode *ip, struct file *fp, const char *buf, int count);
543 static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
544 static void stli_poll(unsigned long arg);
545 static int stli_hostcmd(stlibrd_t *brdp, int channr);
546 static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);
547 static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
548 static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
549 static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp);
550 static void stli_dohangup(void *arg);
551 static void stli_delay(int len);
552 static int stli_setport(stliport_t *portp);
553 static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
554 static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
555 static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp);
556 static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);
557 static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
558 static long stli_mktiocm(unsigned long sigvalue);
559 static void stli_read(stlibrd_t *brdp, stliport_t *portp);
560 static void stli_getserial(stliport_t *portp, struct serial_struct *sp);
561 static int stli_setserial(stliport_t *portp, struct serial_struct *sp);
562 static int stli_getbrdstats(combrd_t *bp);
563 static int stli_getportstats(stliport_t *portp, comstats_t *cp);
564 static int stli_clrportstats(stliport_t *portp, comstats_t *cp);
565 static int stli_getportstruct(unsigned long arg);
566 static int stli_getbrdstruct(unsigned long arg);
567 static void *stli_memalloc(int len);
568
569 static void stli_ecpinit(stlibrd_t *brdp);
570 static void stli_ecpenable(stlibrd_t *brdp);
571 static void stli_ecpdisable(stlibrd_t *brdp);
572 static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
573 static void stli_ecpreset(stlibrd_t *brdp);
574 static void stli_ecpintr(stlibrd_t *brdp);
575 static void stli_ecpeiinit(stlibrd_t *brdp);
576 static void stli_ecpeienable(stlibrd_t *brdp);
577 static void stli_ecpeidisable(stlibrd_t *brdp);
578 static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
579 static void stli_ecpeireset(stlibrd_t *brdp);
580 static void stli_ecpmcenable(stlibrd_t *brdp);
581 static void stli_ecpmcdisable(stlibrd_t *brdp);
582 static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
583 static void stli_ecpmcreset(stlibrd_t *brdp);
584
585 static void stli_onbinit(stlibrd_t *brdp);
586 static void stli_onbenable(stlibrd_t *brdp);
587 static void stli_onbdisable(stlibrd_t *brdp);
588 static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
589 static void stli_onbreset(stlibrd_t *brdp);
590 static void stli_onbeinit(stlibrd_t *brdp);
591 static void stli_onbeenable(stlibrd_t *brdp);
592 static void stli_onbedisable(stlibrd_t *brdp);
593 static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
594 static void stli_onbereset(stlibrd_t *brdp);
595 static void stli_bbyinit(stlibrd_t *brdp);
596 static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
597 static void stli_bbyreset(stlibrd_t *brdp);
598 static void stli_stalinit(stlibrd_t *brdp);
599 static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
600 static void stli_stalreset(stlibrd_t *brdp);
601
602 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
603
604
605
606
607
608
609
610
611
612 static struct file_operations stli_fsiomem = {
613 NULL,
614 stli_memread,
615 stli_memwrite,
616 NULL,
617 NULL,
618 stli_memioctl,
619 NULL,
620 NULL,
621 NULL,
622 NULL
623 };
624
625
626
627
628
629
630
631
632
633 static struct timer_list stli_timerlist = {
634 NULL, NULL, 0, 0, stli_poll
635 };
636
637 static int stli_timeron = 0;
638
639
640
641
642 #define STLI_TIMEOUT (jiffies + 1)
643
644
645
646 #ifdef MODULE
647
648
649
650
651
652 int init_module()
653 {
654 unsigned long flags;
655
656 #if DEBUG
657 printk("init_module()\n");
658 #endif
659
660 save_flags(flags);
661 cli();
662 stli_init();
663 restore_flags(flags);
664
665 return(0);
666 }
667
668
669
670 void cleanup_module()
671 {
672 stlibrd_t *brdp;
673 stliport_t *portp;
674 unsigned long flags;
675 int i, j;
676
677 #if DEBUG
678 printk("cleanup_module()\n");
679 #endif
680
681 printk(KERN_INFO "Unloading %s: version %s\n", stli_drvname, stli_drvversion);
682
683 save_flags(flags);
684 cli();
685
686
687
688
689
690 if (stli_timeron) {
691 stli_timeron = 0;
692 del_timer(&stli_timerlist);
693 }
694
695 i = tty_unregister_driver(&stli_serial);
696 j = tty_unregister_driver(&stli_callout);
697 if (i || j) {
698 printk("STALLION: failed to un-register tty driver, errno=%d,%d\n", -i, -j);
699 restore_flags(flags);
700 return;
701 }
702 if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
703 printk("STALLION: failed to un-register serial memory device, errno=%d\n", -i);
704
705 if (stli_tmpwritebuf != (char *) NULL)
706 kfree_s(stli_tmpwritebuf, STLI_TXBUFSIZE);
707 if (stli_txcookbuf != (char *) NULL)
708 kfree_s(stli_txcookbuf, STLI_TXBUFSIZE);
709
710 for (i = 0; (i < stli_nrbrds); i++) {
711 brdp = stli_brds[i];
712 if (brdp == (stlibrd_t *) NULL)
713 continue;
714 for (j = 0; (j < STL_MAXPORTS); j++) {
715 portp = brdp->ports[j];
716 if (portp != (stliport_t *) NULL) {
717 if (portp->tty != (struct tty_struct *) NULL)
718 tty_hangup(portp->tty);
719 kfree_s(portp, sizeof(stliport_t));
720 }
721 }
722
723 if (brdp->memaddr >= 0x100000)
724 vfree(brdp->membase);
725 if ((brdp->brdtype == BRD_ECP) || (brdp->brdtype == BRD_ECPE) || (brdp->brdtype == BRD_ECPMC))
726 release_region(brdp->iobase, ECP_IOSIZE);
727 else
728 release_region(brdp->iobase, ONB_IOSIZE);
729 kfree_s(brdp, sizeof(stlibrd_t));
730 stli_brds[i] = (stlibrd_t *) NULL;
731 }
732
733 restore_flags(flags);
734 }
735
736 #endif
737
738
739
740
741
742
743
744 static void *stli_memalloc(int len)
745 {
746 return((void *) kmalloc(len, GFP_KERNEL));
747 }
748
749
750
751 static int stli_open(struct tty_struct *tty, struct file *filp)
752 {
753 stlibrd_t *brdp;
754 stliport_t *portp;
755 unsigned int minordev;
756 int brdnr, portnr, rc;
757
758 #if DEBUG
759 printk("stli_open(tty=%x,filp=%x): device=%x\n", (int) tty, (int) filp, tty->device);
760 #endif
761
762 minordev = MINOR(tty->device);
763 brdnr = MKDEV2BRD(minordev);
764 if (brdnr >= stli_nrbrds)
765 return(-ENODEV);
766 brdp = stli_brds[brdnr];
767 if (brdp == (stlibrd_t *) NULL)
768 return(-ENODEV);
769 if ((brdp->state & BST_STARTED) == 0)
770 return(-ENODEV);
771 portnr = MKDEV2PORT(minordev);
772 if ((portnr < 0) || (portnr > brdp->nrports))
773 return(-ENODEV);
774
775 portp = brdp->ports[portnr];
776 if (portp == (stliport_t *) NULL)
777 return(-ENODEV);
778 if (portp->devnr < 1)
779 return(-ENODEV);
780
781
782
783
784
785
786
787 if (portp->flags & ASYNC_CLOSING) {
788 interruptible_sleep_on(&portp->close_wait);
789 if (portp->flags & ASYNC_HUP_NOTIFY)
790 return(-EAGAIN);
791 return(-ERESTARTSYS);
792 }
793
794
795
796
797
798
799
800 portp->tty = tty;
801 tty->driver_data = portp;
802 portp->refcount++;
803
804 while (test_bit(ST_INITIALIZING, &portp->state)) {
805 if (current->signal & ~current->blocked)
806 return(-ERESTARTSYS);
807 interruptible_sleep_on(&portp->raw_wait);
808 }
809
810 if ((portp->flags & ASYNC_INITIALIZED) == 0) {
811 set_bit(ST_INITIALIZING, &portp->state);
812 if ((rc = stli_initopen(brdp, portp)) >= 0) {
813 portp->flags |= ASYNC_INITIALIZED;
814 clear_bit(TTY_IO_ERROR, &tty->flags);
815 }
816 clear_bit(ST_INITIALIZING, &portp->state);
817 wake_up_interruptible(&portp->raw_wait);
818 if (rc < 0)
819 return(rc);
820 }
821
822
823
824
825
826
827
828 if (portp->flags & ASYNC_CLOSING) {
829 interruptible_sleep_on(&portp->close_wait);
830 if (portp->flags & ASYNC_HUP_NOTIFY)
831 return(-EAGAIN);
832 return(-ERESTARTSYS);
833 }
834
835
836
837
838
839
840 if (tty->driver.subtype == STL_DRVTYPCALLOUT) {
841 if (portp->flags & ASYNC_NORMAL_ACTIVE)
842 return(-EBUSY);
843 if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
844 if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
845 (portp->session != current->session))
846 return(-EBUSY);
847 if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
848 (portp->pgrp != current->pgrp))
849 return(-EBUSY);
850 }
851 portp->flags |= ASYNC_CALLOUT_ACTIVE;
852 } else {
853 if (filp->f_flags & O_NONBLOCK) {
854 if (portp->flags & ASYNC_CALLOUT_ACTIVE)
855 return(-EBUSY);
856 } else {
857 if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
858 return(rc);
859 }
860 portp->flags |= ASYNC_NORMAL_ACTIVE;
861 }
862
863 if ((portp->refcount == 1) && (portp->flags & ASYNC_SPLIT_TERMIOS)) {
864 if (tty->driver.subtype == STL_DRVTYPSERIAL)
865 *tty->termios = portp->normaltermios;
866 else
867 *tty->termios = portp->callouttermios;
868 stli_setport(portp);
869 }
870
871 portp->session = current->session;
872 portp->pgrp = current->pgrp;
873 return(0);
874 }
875
876
877
878 static void stli_close(struct tty_struct *tty, struct file *filp)
879 {
880 stlibrd_t *brdp;
881 stliport_t *portp;
882 unsigned long flags;
883
884 #if DEBUG
885 printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);
886 #endif
887
888 portp = tty->driver_data;
889 if (portp == (stliport_t *) NULL)
890 return;
891
892 save_flags(flags);
893 cli();
894 if (tty_hung_up_p(filp)) {
895 restore_flags(flags);
896 return;
897 }
898 if (portp->refcount-- > 1) {
899 restore_flags(flags);
900 return;
901 }
902
903 portp->flags |= ASYNC_CLOSING;
904
905 if (portp->flags & ASYNC_NORMAL_ACTIVE)
906 portp->normaltermios = *tty->termios;
907 if (portp->flags & ASYNC_CALLOUT_ACTIVE)
908 portp->callouttermios = *tty->termios;
909
910
911
912
913
914
915
916 if (tty == stli_txcooktty)
917 stli_flushchars(tty);
918 tty->closing = 1;
919 if (test_bit(ST_TXBUSY, &portp->state)) {
920 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
921 tty_wait_until_sent(tty, portp->closing_wait);
922 }
923
924 portp->flags &= ~ASYNC_INITIALIZED;
925 brdp = stli_brds[portp->brdnr];
926 stli_rawclose(brdp, portp, 0, 0);
927 if (tty->termios->c_cflag & HUPCL) {
928 stli_mkasysigs(&portp->asig, 0, 0);
929 if (test_bit(ST_CMDING, &portp->state))
930 set_bit(ST_DOSIGS, &portp->state);
931 else
932 stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
933 }
934 clear_bit(ST_TXBUSY, &portp->state);
935 clear_bit(ST_RXSTOP, &portp->state);
936 set_bit(TTY_IO_ERROR, &tty->flags);
937 if (tty->ldisc.flush_buffer)
938 (tty->ldisc.flush_buffer)(tty);
939 set_bit(ST_DOFLUSHRX, &portp->state);
940 stli_flushbuffer(tty);
941
942 tty->closing = 0;
943 tty->driver_data = (void *) NULL;
944 portp->tty = (struct tty_struct *) NULL;
945
946 if (portp->openwaitcnt) {
947 if (portp->close_delay)
948 stli_delay(portp->close_delay);
949 wake_up_interruptible(&portp->open_wait);
950 }
951
952 portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
953 wake_up_interruptible(&portp->close_wait);
954 restore_flags(flags);
955 }
956
957
958
959
960
961
962
963
964
965
966
967 static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)
968 {
969 struct tty_struct *tty;
970 asynotify_t nt;
971 asyport_t aport;
972 int rc;
973
974 #if DEBUG
975 printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp);
976 #endif
977
978 if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)
979 return(rc);
980
981 memset(&nt, 0, sizeof(asynotify_t));
982 nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
983 nt.signal = SG_DCD;
984 if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, sizeof(asynotify_t), 0)) < 0)
985 return(rc);
986
987 tty = portp->tty;
988 if (tty == (struct tty_struct *) NULL)
989 return(-ENODEV);
990 stli_mkasyport(portp, &aport, tty->termios);
991 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)) < 0)
992 return(rc);
993
994 set_bit(ST_GETSIGS, &portp->state);
995 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
996 return(rc);
997 if (clear_bit(ST_GETSIGS, &portp->state))
998 portp->sigs = stli_mktiocm(portp->asig.sigvalue);
999 stli_mkasysigs(&portp->asig, 1, 1);
1000 if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
1001 return(rc);
1002
1003 return(0);
1004 }
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
1016 {
1017 volatile cdkhdr_t *hdrp;
1018 volatile cdkctrl_t *cp;
1019 volatile unsigned char *bits;
1020 unsigned long flags;
1021 int rc;
1022
1023 #if DEBUG
1024 printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp, (int) portp, (int) arg, wait);
1025 #endif
1026
1027
1028
1029
1030 save_flags(flags);
1031 cli();
1032
1033
1034
1035
1036
1037
1038
1039 while (test_bit(ST_CLOSING, &portp->state)) {
1040 if (current->signal & ~current->blocked) {
1041 restore_flags(flags);
1042 return(-ERESTARTSYS);
1043 }
1044 interruptible_sleep_on(&portp->raw_wait);
1045 }
1046
1047
1048
1049
1050
1051
1052 EBRDENABLE(brdp);
1053 cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1054 cp->openarg = arg;
1055 cp->open = 1;
1056 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1057 hdrp->slavereq |= portp->reqbit;
1058 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
1059 *bits |= portp->portbit;
1060 EBRDDISABLE(brdp);
1061
1062 if (wait == 0) {
1063 restore_flags(flags);
1064 return(0);
1065 }
1066
1067
1068
1069
1070
1071 rc = 0;
1072 set_bit(ST_OPENING, &portp->state);
1073 while (test_bit(ST_OPENING, &portp->state)) {
1074 if (current->signal & ~current->blocked) {
1075 rc = -ERESTARTSYS;
1076 break;
1077 }
1078 interruptible_sleep_on(&portp->raw_wait);
1079 }
1080 restore_flags(flags);
1081
1082 if ((rc == 0) && (portp->rc != 0))
1083 rc = -EIO;
1084 return(rc);
1085 }
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
1096 {
1097 volatile cdkhdr_t *hdrp;
1098 volatile cdkctrl_t *cp;
1099 volatile unsigned char *bits;
1100 unsigned long flags;
1101 int rc;
1102
1103 #if DEBUG
1104 printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp, (int) portp, (int) arg, wait);
1105 #endif
1106
1107 save_flags(flags);
1108 cli();
1109
1110
1111
1112
1113
1114 if (wait) {
1115 while (test_bit(ST_CLOSING, &portp->state)) {
1116 if (current->signal & ~current->blocked) {
1117 restore_flags(flags);
1118 return(-ERESTARTSYS);
1119 }
1120 interruptible_sleep_on(&portp->raw_wait);
1121 }
1122 }
1123
1124
1125
1126
1127 EBRDENABLE(brdp);
1128 cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1129 cp->closearg = arg;
1130 cp->close = 1;
1131 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1132 hdrp->slavereq |= portp->reqbit;
1133 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
1134 *bits |= portp->portbit;
1135 EBRDDISABLE(brdp);
1136
1137 set_bit(ST_CLOSING, &portp->state);
1138 if (wait == 0) {
1139 restore_flags(flags);
1140 return(0);
1141 }
1142
1143
1144
1145
1146
1147 rc = 0;
1148 while (test_bit(ST_CLOSING, &portp->state)) {
1149 if (current->signal & ~current->blocked) {
1150 rc = -ERESTARTSYS;
1151 break;
1152 }
1153 interruptible_sleep_on(&portp->raw_wait);
1154 }
1155 restore_flags(flags);
1156
1157 if ((rc == 0) && (portp->rc != 0))
1158 rc = -EIO;
1159 return(rc);
1160 }
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171 static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
1172 {
1173 unsigned long flags;
1174
1175 #if DEBUG
1176 printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, (int) arg, size, copyback);
1177 #endif
1178
1179 save_flags(flags);
1180 cli();
1181 while (test_bit(ST_CMDING, &portp->state)) {
1182 if (current->signal & ~current->blocked) {
1183 restore_flags(flags);
1184 return(-ERESTARTSYS);
1185 }
1186 interruptible_sleep_on(&portp->raw_wait);
1187 }
1188
1189 stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
1190
1191 while (test_bit(ST_CMDING, &portp->state)) {
1192 if (current->signal & ~current->blocked) {
1193 restore_flags(flags);
1194 return(-ERESTARTSYS);
1195 }
1196 interruptible_sleep_on(&portp->raw_wait);
1197 }
1198 restore_flags(flags);
1199
1200 if (portp->rc != 0)
1201 return(-EIO);
1202 return(0);
1203 }
1204
1205
1206
1207
1208
1209
1210
1211
1212 static int stli_setport(stliport_t *portp)
1213 {
1214 stlibrd_t *brdp;
1215 asyport_t aport;
1216
1217 #if DEBUG
1218 printk("stli_setport(portp=%x)\n", (int) portp);
1219 #endif
1220
1221 if (portp == (stliport_t *) NULL)
1222 return(-ENODEV);
1223 if (portp->tty == (struct tty_struct *) NULL)
1224 return(-ENODEV);
1225 if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds))
1226 return(-ENODEV);
1227 brdp = stli_brds[portp->brdnr];
1228 if (brdp == (stlibrd_t *) NULL)
1229 return(-ENODEV);
1230
1231 stli_mkasyport(portp, &aport, portp->tty->termios);
1232 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
1233 }
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 static void stli_delay(int len)
1244 {
1245 #if DEBUG
1246 printk("stl_delay(len=%d)\n", len);
1247 #endif
1248 if (len > 0) {
1249 current->state = TASK_INTERRUPTIBLE;
1250 current->timeout = jiffies + len;
1251 schedule();
1252 }
1253 }
1254
1255
1256
1257
1258
1259
1260
1261
1262 static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp)
1263 {
1264 unsigned long flags;
1265 int rc, doclocal;
1266
1267 #if DEBUG
1268 printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", (int) brdp, (int) portp, (int) filp);
1269 #endif
1270
1271 rc = 0;
1272 doclocal = 0;
1273
1274 if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
1275 if (portp->normaltermios.c_cflag & CLOCAL)
1276 doclocal++;
1277 } else {
1278 if (portp->tty->termios->c_cflag & CLOCAL)
1279 doclocal++;
1280 }
1281
1282 save_flags(flags);
1283 cli();
1284 portp->openwaitcnt++;
1285 if (portp->refcount > 0)
1286 portp->refcount--;
1287
1288 for (;;) {
1289 if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) {
1290 stli_mkasysigs(&portp->asig, 1, 1);
1291 if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
1292 break;
1293 }
1294 if (tty_hung_up_p(filp) || ((portp->flags & ASYNC_INITIALIZED) == 0)) {
1295 if (portp->flags & ASYNC_HUP_NOTIFY)
1296 rc = -EBUSY;
1297 else
1298 rc = -ERESTARTSYS;
1299 break;
1300 }
1301 if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
1302 ((portp->flags & ASYNC_CLOSING) == 0) &&
1303 (doclocal || (portp->sigs & TIOCM_CD))) {
1304 break;
1305 }
1306 if (current->signal & ~current->blocked) {
1307 rc = -ERESTARTSYS;
1308 break;
1309 }
1310 interruptible_sleep_on(&portp->open_wait);
1311 }
1312
1313 if (! tty_hung_up_p(filp))
1314 portp->refcount++;
1315 portp->openwaitcnt--;
1316 restore_flags(flags);
1317
1318 return(rc);
1319 }
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329 static int stli_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
1330 {
1331 volatile cdkasy_t *ap;
1332 volatile cdkhdr_t *hdrp;
1333 volatile unsigned char *bits;
1334 unsigned char *shbuf, *chbuf;
1335 stliport_t *portp;
1336 stlibrd_t *brdp;
1337 unsigned int len, stlen, head, tail, size;
1338 unsigned long flags;
1339
1340 #if DEBUG
1341 printk("stli_write(tty=%x,from_user=%d,buf=%x,count=%d)\n", (int) tty, from_user, (int) buf, count);
1342 #endif
1343
1344 if ((tty == (struct tty_struct *) NULL) || (stli_tmpwritebuf == (char *) NULL))
1345 return(0);
1346 if (tty == stli_txcooktty)
1347 stli_flushchars(tty);
1348 portp = tty->driver_data;
1349 if (portp == (stliport_t *) NULL)
1350 return(0);
1351 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1352 return(0);
1353 brdp = stli_brds[portp->brdnr];
1354 if (brdp == (stlibrd_t *) NULL)
1355 return(0);
1356 chbuf = (unsigned char *) buf;
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369 if (from_user) {
1370 save_flags(flags);
1371 cli();
1372 EBRDENABLE(brdp);
1373 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1374 head = (unsigned int) ap->txq.head;
1375 tail = (unsigned int) ap->txq.tail;
1376 if (tail != ((unsigned int) ap->txq.tail))
1377 tail = (unsigned int) ap->txq.tail;
1378 len = (head >= tail) ? (portp->txsize - (head - tail) - 1) : (tail - head - 1);
1379 count = MIN(len, count);
1380 EBRDDISABLE(brdp);
1381
1382 down(&stli_tmpwritesem);
1383 memcpy_fromfs(stli_tmpwritebuf, chbuf, count);
1384 up(&stli_tmpwritesem);
1385 chbuf = &stli_tmpwritebuf[0];
1386 restore_flags(flags);
1387 }
1388
1389
1390
1391
1392 save_flags(flags);
1393 cli();
1394 EBRDENABLE(brdp);
1395 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1396 head = (unsigned int) ap->txq.head;
1397 tail = (unsigned int) ap->txq.tail;
1398 if (tail != ((unsigned int) ap->txq.tail))
1399 tail = (unsigned int) ap->txq.tail;
1400 size = portp->txsize;
1401 if (head >= tail) {
1402 len = size - (head - tail) - 1;
1403 stlen = size - head;
1404 } else {
1405 len = tail - head - 1;
1406 stlen = len;
1407 }
1408
1409 len = MIN(len, count);
1410 count = 0;
1411 shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
1412
1413 while (len > 0) {
1414 stlen = MIN(len, stlen);
1415 memcpy((shbuf + head), chbuf, stlen);
1416 chbuf += stlen;
1417 len -= stlen;
1418 count += stlen;
1419 head += stlen;
1420 if (head >= size) {
1421 head = 0;
1422 stlen = tail;
1423 }
1424 }
1425
1426 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1427 ap->txq.head = head;
1428 if (test_bit(ST_TXBUSY, &portp->state)) {
1429 if (ap->changed.data & DT_TXEMPTY)
1430 ap->changed.data &= ~DT_TXEMPTY;
1431 }
1432 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1433 hdrp->slavereq |= portp->reqbit;
1434 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
1435 *bits |= portp->portbit;
1436 set_bit(ST_TXBUSY, &portp->state);
1437
1438 EBRDDISABLE(brdp);
1439 restore_flags(flags);
1440
1441 return(count);
1442 }
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454 static void stli_putchar(struct tty_struct *tty, unsigned char ch)
1455 {
1456 #if DEBUG
1457 printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);
1458 #endif
1459
1460 if (tty == (struct tty_struct *) NULL)
1461 return;
1462 if (tty != stli_txcooktty) {
1463 if (stli_txcooktty != (struct tty_struct *) NULL)
1464 stli_flushchars(stli_txcooktty);
1465 stli_txcooktty = tty;
1466 }
1467
1468 stli_txcookbuf[stli_txcooksize++] = ch;
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481 static void stli_flushchars(struct tty_struct *tty)
1482 {
1483 volatile cdkhdr_t *hdrp;
1484 volatile unsigned char *bits;
1485 volatile cdkasy_t *ap;
1486 struct tty_struct *cooktty;
1487 stliport_t *portp;
1488 stlibrd_t *brdp;
1489 unsigned int len, stlen, head, tail, size, count, cooksize;
1490 unsigned char *buf, *shbuf;
1491 unsigned long flags;
1492
1493 #if DEBUG
1494 printk("stli_flushchars(tty=%x)\n", (int) tty);
1495 #endif
1496
1497 cooksize = stli_txcooksize;
1498 cooktty = stli_txcooktty;
1499 stli_txcooksize = 0;
1500 stli_txcookrealsize = 0;
1501 stli_txcooktty = (struct tty_struct *) NULL;
1502
1503 if (tty == (struct tty_struct *) NULL)
1504 return;
1505 if (cooktty == (struct tty_struct *) NULL)
1506 return;
1507 if (tty != cooktty)
1508 tty = cooktty;
1509 if (cooksize == 0)
1510 return;
1511
1512 portp = tty->driver_data;
1513 if (portp == (stliport_t *) NULL)
1514 return;
1515 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1516 return;
1517 brdp = stli_brds[portp->brdnr];
1518 if (brdp == (stlibrd_t *) NULL)
1519 return;
1520
1521 save_flags(flags);
1522 cli();
1523 EBRDENABLE(brdp);
1524
1525 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1526 head = (unsigned int) ap->txq.head;
1527 tail = (unsigned int) ap->txq.tail;
1528 if (tail != ((unsigned int) ap->txq.tail))
1529 tail = (unsigned int) ap->txq.tail;
1530 size = portp->txsize;
1531 if (head >= tail) {
1532 len = size - (head - tail) - 1;
1533 stlen = size - head;
1534 } else {
1535 len = tail - head - 1;
1536 stlen = len;
1537 }
1538
1539 len = MIN(len, cooksize);
1540 count = 0;
1541 shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
1542 buf = stli_txcookbuf;
1543
1544 while (len > 0) {
1545 stlen = MIN(len, stlen);
1546 memcpy((shbuf + head), buf, stlen);
1547 buf += stlen;
1548 len -= stlen;
1549 count += stlen;
1550 head += stlen;
1551 if (head >= size) {
1552 head = 0;
1553 stlen = tail;
1554 }
1555 }
1556
1557 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
1558 ap->txq.head = head;
1559
1560 if (test_bit(ST_TXBUSY, &portp->state)) {
1561 if (ap->changed.data & DT_TXEMPTY)
1562 ap->changed.data &= ~DT_TXEMPTY;
1563 }
1564 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1565 hdrp->slavereq |= portp->reqbit;
1566 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
1567 *bits |= portp->portbit;
1568 set_bit(ST_TXBUSY, &portp->state);
1569
1570 EBRDDISABLE(brdp);
1571 restore_flags(flags);
1572 }
1573
1574
1575
1576 static int stli_writeroom(struct tty_struct *tty)
1577 {
1578 volatile cdkasyrq_t *rp;
1579 stliport_t *portp;
1580 stlibrd_t *brdp;
1581 unsigned int head, tail, len;
1582 unsigned long flags;
1583
1584 #if DEBUG
1585 printk("stli_writeroom(tty=%x)\n", (int) tty);
1586 #endif
1587
1588 if (tty == (struct tty_struct *) NULL)
1589 return(0);
1590 if (tty == stli_txcooktty) {
1591 if (stli_txcookrealsize != 0) {
1592 len = stli_txcookrealsize - stli_txcooksize;
1593 return(len);
1594 }
1595 }
1596
1597 portp = tty->driver_data;
1598 if (portp == (stliport_t *) NULL)
1599 return(0);
1600 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1601 return(0);
1602 brdp = stli_brds[portp->brdnr];
1603 if (brdp == (stlibrd_t *) NULL)
1604 return(0);
1605
1606 save_flags(flags);
1607 cli();
1608 EBRDENABLE(brdp);
1609 rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
1610 head = (unsigned int) rp->head;
1611 tail = (unsigned int) rp->tail;
1612 if (tail != ((unsigned int) rp->tail))
1613 tail = (unsigned int) rp->tail;
1614 len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head);
1615 len--;
1616 EBRDDISABLE(brdp);
1617 restore_flags(flags);
1618
1619 if (tty == stli_txcooktty) {
1620 stli_txcookrealsize = len;
1621 len -= stli_txcooksize;
1622 }
1623 return(len);
1624 }
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636 static int stli_charsinbuffer(struct tty_struct *tty)
1637 {
1638 volatile cdkasyrq_t *rp;
1639 stliport_t *portp;
1640 stlibrd_t *brdp;
1641 unsigned int head, tail, len;
1642 unsigned long flags;
1643
1644 #if DEBUG
1645 printk("stli_charsinbuffer(tty=%x)\n", (int) tty);
1646 #endif
1647
1648 if (tty == (struct tty_struct *) NULL)
1649 return(0);
1650 if (tty == stli_txcooktty)
1651 stli_flushchars(tty);
1652 portp = tty->driver_data;
1653 if (portp == (stliport_t *) NULL)
1654 return(0);
1655 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1656 return(0);
1657 brdp = stli_brds[portp->brdnr];
1658 if (brdp == (stlibrd_t *) NULL)
1659 return(0);
1660
1661 save_flags(flags);
1662 cli();
1663 EBRDENABLE(brdp);
1664 rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
1665 head = (unsigned int) rp->head;
1666 tail = (unsigned int) rp->tail;
1667 if (tail != ((unsigned int) rp->tail))
1668 tail = (unsigned int) rp->tail;
1669 len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head));
1670 if ((len == 0) && test_bit(ST_TXBUSY, &portp->state))
1671 len = 1;
1672 EBRDDISABLE(brdp);
1673 restore_flags(flags);
1674
1675 return(len);
1676 }
1677
1678
1679
1680
1681
1682
1683
1684 static void stli_getserial(stliport_t *portp, struct serial_struct *sp)
1685 {
1686 struct serial_struct sio;
1687 stlibrd_t *brdp;
1688
1689 #if DEBUG
1690 printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
1691 #endif
1692
1693 memset(&sio, 0, sizeof(struct serial_struct));
1694 sio.type = PORT_UNKNOWN;
1695 sio.line = portp->portnr;
1696 sio.irq = 0;
1697 sio.flags = portp->flags;
1698 sio.baud_base = portp->baud_base;
1699 sio.close_delay = portp->close_delay;
1700 sio.closing_wait = portp->closing_wait;
1701 sio.custom_divisor = portp->custom_divisor;
1702 sio.xmit_fifo_size = 0;
1703 sio.hub6 = 0;
1704
1705 brdp = stli_brds[portp->brdnr];
1706 if (brdp != (stlibrd_t *) NULL)
1707 sio.port = brdp->iobase;
1708
1709 memcpy_tofs(sp, &sio, sizeof(struct serial_struct));
1710 }
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720 static int stli_setserial(stliport_t *portp, struct serial_struct *sp)
1721 {
1722 struct serial_struct sio;
1723 int rc;
1724
1725 #if DEBUG
1726 printk("stli_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
1727 #endif
1728
1729 memcpy_fromfs(&sio, sp, sizeof(struct serial_struct));
1730 if (!suser()) {
1731 if ((sio.baud_base != portp->baud_base) ||
1732 (sio.close_delay != portp->close_delay) ||
1733 ((sio.flags & ~ASYNC_USR_MASK) != (portp->flags & ~ASYNC_USR_MASK)))
1734 return(-EPERM);
1735 }
1736
1737 portp->flags = (portp->flags & ~ASYNC_USR_MASK) | (sio.flags & ASYNC_USR_MASK);
1738 portp->baud_base = sio.baud_base;
1739 portp->close_delay = sio.close_delay;
1740 portp->closing_wait = sio.closing_wait;
1741 portp->custom_divisor = sio.custom_divisor;
1742
1743 if ((rc = stli_setport(portp)) < 0)
1744 return(rc);
1745 return(0);
1746 }
1747
1748
1749
1750 static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1751 {
1752 stliport_t *portp;
1753 stlibrd_t *brdp;
1754 unsigned long val;
1755 int rc;
1756
1757 #if DEBUG
1758 printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", (int) tty, (int) file, cmd, (int) arg);
1759 #endif
1760
1761 if (tty == (struct tty_struct *) NULL)
1762 return(-ENODEV);
1763 portp = tty->driver_data;
1764 if (portp == (stliport_t *) NULL)
1765 return(-ENODEV);
1766 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1767 return(0);
1768 brdp = stli_brds[portp->brdnr];
1769 if (brdp == (stlibrd_t *) NULL)
1770 return(0);
1771
1772 rc = 0;
1773
1774 switch (cmd) {
1775 case TCSBRK:
1776 if ((rc = tty_check_change(tty)) == 0) {
1777 tty_wait_until_sent(tty, 0);
1778 if (! arg) {
1779 val = 250;
1780 rc = stli_cmdwait(brdp, portp, A_BREAK, &val, sizeof(unsigned long), 0);
1781 }
1782 }
1783 break;
1784 case TCSBRKP:
1785 if ((rc = tty_check_change(tty)) == 0) {
1786 tty_wait_until_sent(tty, 0);
1787 val = (arg ? (arg * 100) : 250);
1788 rc = stli_cmdwait(brdp, portp, A_BREAK, &val, sizeof(unsigned long), 0);
1789 }
1790 break;
1791 case TIOCGSOFTCAR:
1792 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long))) == 0)
1793 put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), (unsigned long *) arg);
1794 break;
1795 case TIOCSSOFTCAR:
1796 if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
1797 arg = get_fs_long((unsigned long *) arg);
1798 tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0);
1799 }
1800 break;
1801 case TIOCMGET:
1802 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int))) == 0) {
1803 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
1804 return(rc);
1805 val = stli_mktiocm(portp->asig.sigvalue);
1806 put_fs_long(val, (unsigned long *) arg);
1807 }
1808 break;
1809 case TIOCMBIS:
1810 if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
1811 arg = get_fs_long((unsigned long *) arg);
1812 stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 1 : -1), ((arg & TIOCM_RTS) ? 1 : -1));
1813 rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
1814 }
1815 break;
1816 case TIOCMBIC:
1817 if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
1818 arg = get_fs_long((unsigned long *) arg);
1819 stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 0 : -1), ((arg & TIOCM_RTS) ? 0 : -1));
1820 rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
1821 }
1822 break;
1823 case TIOCMSET:
1824 if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
1825 arg = get_fs_long((unsigned long *) arg);
1826 stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 1 : 0), ((arg & TIOCM_RTS) ? 1 : 0));
1827 rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
1828 }
1829 break;
1830 case TIOCGSERIAL:
1831 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) == 0)
1832 stli_getserial(portp, (struct serial_struct *) arg);
1833 break;
1834 case TIOCSSERIAL:
1835 if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) == 0)
1836 rc = stli_setserial(portp, (struct serial_struct *) arg);
1837 break;
1838 case STL_GETPFLAG:
1839 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long))) == 0)
1840 put_fs_long(portp->pflag, (unsigned long *) arg);
1841 break;
1842 case STL_SETPFLAG:
1843 if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(unsigned long))) == 0) {
1844 portp->pflag = get_fs_long((unsigned long *) arg);
1845 stli_setport(portp);
1846 }
1847 break;
1848 case COM_GETPORTSTATS:
1849 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
1850 rc = stli_getportstats(portp, (comstats_t *) arg);
1851 break;
1852 case COM_CLRPORTSTATS:
1853 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
1854 rc = stli_clrportstats(portp, (comstats_t *) arg);
1855 break;
1856 case TIOCSERCONFIG:
1857 case TIOCSERGWILD:
1858 case TIOCSERSWILD:
1859 case TIOCSERGETLSR:
1860 case TIOCSERGSTRUCT:
1861 case TIOCSERGETMULTI:
1862 case TIOCSERSETMULTI:
1863 default:
1864 rc = -ENOIOCTLCMD;
1865 break;
1866 }
1867
1868 return(rc);
1869 }
1870
1871
1872
1873
1874
1875
1876
1877
1878 static void stli_settermios(struct tty_struct *tty, struct termios *old)
1879 {
1880 stliport_t *portp;
1881 stlibrd_t *brdp;
1882 struct termios *tiosp;
1883 asyport_t aport;
1884
1885 #if DEBUG
1886 printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);
1887 #endif
1888
1889 if (tty == (struct tty_struct *) NULL)
1890 return;
1891 portp = tty->driver_data;
1892 if (portp == (stliport_t *) NULL)
1893 return;
1894 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1895 return;
1896 brdp = stli_brds[portp->brdnr];
1897 if (brdp == (stlibrd_t *) NULL)
1898 return;
1899
1900 tiosp = tty->termios;
1901 if ((tiosp->c_cflag == old->c_cflag) && (tiosp->c_iflag == old->c_iflag))
1902 return;
1903
1904 stli_mkasyport(portp, &aport, tiosp);
1905 stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
1906 stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1);
1907 stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
1908 if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
1909 tty->hw_stopped = 0;
1910 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
1911 wake_up_interruptible(&portp->open_wait);
1912 }
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926 static void stli_throttle(struct tty_struct *tty)
1927 {
1928 stliport_t *portp;
1929
1930 #if DEBUG
1931 printk("stli_throttle(tty=%x)\n", (int) tty);
1932 #endif
1933
1934 if (tty == (struct tty_struct *) NULL)
1935 return;
1936 portp = tty->driver_data;
1937 if (portp == (stliport_t *) NULL)
1938 return;
1939
1940 set_bit(ST_RXSTOP, &portp->state);
1941 }
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951 static void stli_unthrottle(struct tty_struct *tty)
1952 {
1953 stliport_t *portp;
1954
1955 #if DEBUG
1956 printk("stli_unthrottle(tty=%x)\n", (int) tty);
1957 #endif
1958
1959 if (tty == (struct tty_struct *) NULL)
1960 return;
1961 portp = tty->driver_data;
1962 if (portp == (stliport_t *) NULL)
1963 return;
1964
1965 clear_bit(ST_RXSTOP, &portp->state);
1966 }
1967
1968
1969
1970
1971
1972
1973
1974
1975 static void stli_stop(struct tty_struct *tty)
1976 {
1977 stlibrd_t *brdp;
1978 stliport_t *portp;
1979 asyctrl_t actrl;
1980
1981 #if DEBUG
1982 printk("stli_stop(tty=%x)\n", (int) tty);
1983 #endif
1984
1985 if (tty == (struct tty_struct *) NULL)
1986 return;
1987 portp = tty->driver_data;
1988 if (portp == (stliport_t *) NULL)
1989 return;
1990 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
1991 return;
1992 brdp = stli_brds[portp->brdnr];
1993 if (brdp == (stlibrd_t *) NULL)
1994 return;
1995
1996 memset(&actrl, 0, sizeof(asyctrl_t));
1997 actrl.txctrl = CT_STOPFLOW;
1998 #if 0
1999 stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t));
2000 #endif
2001 }
2002
2003
2004
2005
2006
2007
2008
2009 static void stli_start(struct tty_struct *tty)
2010 {
2011 stliport_t *portp;
2012 stlibrd_t *brdp;
2013 asyctrl_t actrl;
2014
2015 #if DEBUG
2016 printk("stli_start(tty=%x)\n", (int) tty);
2017 #endif
2018
2019 if (tty == (struct tty_struct *) NULL)
2020 return;
2021 portp = tty->driver_data;
2022 if (portp == (stliport_t *) NULL)
2023 return;
2024 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
2025 return;
2026 brdp = stli_brds[portp->brdnr];
2027 if (brdp == (stlibrd_t *) NULL)
2028 return;
2029
2030 memset(&actrl, 0, sizeof(asyctrl_t));
2031 actrl.txctrl = CT_STARTFLOW;
2032 #if 0
2033 stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t));
2034 #endif
2035 }
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048 static void stli_dohangup(void *arg)
2049 {
2050 stliport_t *portp;
2051
2052 #if DEBUG
2053 printk("stli_dohangup(portp=%x)\n", (int) arg);
2054 #endif
2055
2056 portp = (stliport_t *) arg;
2057 if (portp == (stliport_t *) NULL)
2058 return;
2059 if (portp->tty == (struct tty_struct *) NULL)
2060 return;
2061 tty_hangup(portp->tty);
2062 }
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073 static void stli_hangup(struct tty_struct *tty)
2074 {
2075 stliport_t *portp;
2076 stlibrd_t *brdp;
2077 unsigned long flags;
2078
2079 #if DEBUG
2080 printk("stli_hangup(tty=%x)\n", (int) tty);
2081 #endif
2082
2083 if (tty == (struct tty_struct *) NULL)
2084 return;
2085 portp = tty->driver_data;
2086 if (portp == (stliport_t *) NULL)
2087 return;
2088 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
2089 return;
2090 brdp = stli_brds[portp->brdnr];
2091 if (brdp == (stlibrd_t *) NULL)
2092 return;
2093
2094 portp->flags &= ~ASYNC_INITIALIZED;
2095
2096 save_flags(flags);
2097 cli();
2098 if (! test_bit(ST_CLOSING, &portp->state))
2099 stli_rawclose(brdp, portp, 0, 0);
2100 if (tty->termios->c_cflag & HUPCL) {
2101 stli_mkasysigs(&portp->asig, 0, 0);
2102 if (test_bit(ST_CMDING, &portp->state)) {
2103 set_bit(ST_DOSIGS, &portp->state);
2104 set_bit(ST_DOFLUSHTX, &portp->state);
2105 set_bit(ST_DOFLUSHRX, &portp->state);
2106 } else {
2107 stli_sendcmd(brdp, portp, A_SETSIGNALSF, &portp->asig, sizeof(asysigs_t), 0);
2108 }
2109 }
2110 restore_flags(flags);
2111
2112 clear_bit(ST_TXBUSY, &portp->state);
2113 clear_bit(ST_RXSTOP, &portp->state);
2114 set_bit(TTY_IO_ERROR, &tty->flags);
2115 tty->driver_data = (void *) NULL;
2116 portp->tty = (struct tty_struct *) NULL;
2117 portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
2118 portp->refcount = 0;
2119 wake_up_interruptible(&portp->open_wait);
2120 }
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131 static void stli_flushbuffer(struct tty_struct *tty)
2132 {
2133 stliport_t *portp;
2134 stlibrd_t *brdp;
2135 unsigned long ftype, flags;
2136
2137 #if DEBUG
2138 printk("stli_flushbuffer(tty=%x)\n", (int) tty);
2139 #endif
2140
2141 if (tty == (struct tty_struct *) NULL)
2142 return;
2143 portp = tty->driver_data;
2144 if (portp == (stliport_t *) NULL)
2145 return;
2146 if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
2147 return;
2148 brdp = stli_brds[portp->brdnr];
2149 if (brdp == (stlibrd_t *) NULL)
2150 return;
2151
2152 save_flags(flags);
2153 cli();
2154 if (tty == stli_txcooktty) {
2155 stli_txcooktty = (struct tty_struct *) NULL;
2156 stli_txcooksize = 0;
2157 stli_txcookrealsize = 0;
2158 }
2159 if (test_bit(ST_CMDING, &portp->state)) {
2160 set_bit(ST_DOFLUSHTX, &portp->state);
2161 } else {
2162 ftype = FLUSHTX;
2163 if (test_bit(ST_DOFLUSHRX, &portp->state)) {
2164 ftype |= FLUSHRX;
2165 clear_bit(ST_DOFLUSHRX, &portp->state);
2166 }
2167 stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(unsigned long), 0);
2168 }
2169 restore_flags(flags);
2170
2171 wake_up_interruptible(&tty->write_wait);
2172 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
2173 (tty->ldisc.write_wakeup)(tty);
2174 }
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188 static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
2189 {
2190 volatile cdkhdr_t *hdrp;
2191 volatile cdkctrl_t *cp;
2192 volatile unsigned char *bits;
2193 unsigned long flags;
2194
2195 #if DEBUG
2196 printk("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, (int) arg, size, copyback);
2197 #endif
2198
2199 save_flags(flags);
2200 cli();
2201
2202 if (test_bit(ST_CMDING, &portp->state)) {
2203 printk("STALLION: command already busy, cmd=%x!\n", (int) cmd);
2204 restore_flags(flags);
2205 return;
2206 }
2207
2208 EBRDENABLE(brdp);
2209 cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
2210 if (size > 0) {
2211 memcpy((void *) &(cp->args[0]), arg, size);
2212 if (copyback) {
2213 portp->argp = arg;
2214 portp->argsize = size;
2215 }
2216 }
2217 cp->status = 0;
2218 cp->cmd = cmd;
2219 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2220 hdrp->slavereq |= portp->reqbit;
2221 bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
2222 *bits |= portp->portbit;
2223 set_bit(ST_CMDING, &portp->state);
2224 EBRDDISABLE(brdp);
2225 restore_flags(flags);
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238 static inline void stli_read(stlibrd_t *brdp, stliport_t *portp)
2239 {
2240 volatile cdkasyrq_t *rp;
2241 volatile char *shbuf;
2242 struct tty_struct *tty;
2243 unsigned int head, tail, size;
2244 unsigned int len, stlen;
2245
2246 #if DEBUG
2247 printk("stli_read(brdp=%x,portp=%d)\n", (int) brdp, (int) portp);
2248 #endif
2249
2250 if (test_bit(ST_RXSTOP, &portp->state))
2251 return;
2252 tty = portp->tty;
2253 if (tty == (struct tty_struct *) NULL)
2254 return;
2255
2256 rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
2257 head = (unsigned int) rp->head;
2258 if (head != ((unsigned int) rp->head))
2259 head = (unsigned int) rp->head;
2260 tail = (unsigned int) rp->tail;
2261 size = portp->rxsize;
2262 if (head >= tail) {
2263 len = head - tail;
2264 stlen = len;
2265 } else {
2266 len = size - (tail - head);
2267 stlen = size - tail;
2268 }
2269
2270 len = MIN(len, (TTY_FLIPBUF_SIZE - tty->flip.count));
2271 shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
2272
2273 while (len > 0) {
2274 stlen = MIN(len, stlen);
2275 memcpy(tty->flip.char_buf_ptr, (char *) (shbuf + tail), stlen);
2276 memset(tty->flip.flag_buf_ptr, 0, stlen);
2277 tty->flip.char_buf_ptr += stlen;
2278 tty->flip.flag_buf_ptr += stlen;
2279 tty->flip.count += stlen;
2280
2281 len -= stlen;
2282 tail += stlen;
2283 if (tail >= size) {
2284 tail = 0;
2285 stlen = head;
2286 }
2287 }
2288 rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
2289 rp->tail = tail;
2290
2291 if (head != tail)
2292 set_bit(ST_RXING, &portp->state);
2293
2294 tty_schedule_flip(tty);
2295 }
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305 static inline void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
2306 {
2307 int cmd;
2308
2309 if (test_bit(ST_DOSIGS, &portp->state)) {
2310 if (test_bit(ST_DOFLUSHTX, &portp->state) && test_bit(ST_DOFLUSHRX, &portp->state))
2311 cmd = A_SETSIGNALSF;
2312 else if (test_bit(ST_DOFLUSHTX, &portp->state))
2313 cmd = A_SETSIGNALSFTX;
2314 else if (test_bit(ST_DOFLUSHRX, &portp->state))
2315 cmd = A_SETSIGNALSFRX;
2316 else
2317 cmd = A_SETSIGNALS;
2318 clear_bit(ST_DOFLUSHTX, &portp->state);
2319 clear_bit(ST_DOFLUSHRX, &portp->state);
2320 clear_bit(ST_DOSIGS, &portp->state);
2321 memcpy((void *) &(cp->args[0]), (void *) &portp->asig, sizeof(asysigs_t));
2322 cp->status = 0;
2323 cp->cmd = cmd;
2324 set_bit(ST_CMDING, &portp->state);
2325 } else if (test_bit(ST_DOFLUSHTX, &portp->state) || test_bit(ST_DOFLUSHRX, &portp->state)) {
2326 cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0);
2327 cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);
2328 clear_bit(ST_DOFLUSHTX, &portp->state);
2329 clear_bit(ST_DOFLUSHRX, &portp->state);
2330 memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int));
2331 cp->status = 0;
2332 cp->cmd = A_FLUSH;
2333 set_bit(ST_CMDING, &portp->state);
2334 }
2335 }
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347 static inline int stli_hostcmd(stlibrd_t *brdp, int channr)
2348 {
2349 volatile cdkasy_t *ap;
2350 volatile cdkctrl_t *cp;
2351 struct tty_struct *tty;
2352 asynotify_t nt;
2353 stliport_t *portp;
2354 unsigned long oldsigs;
2355 int rc, donerx;
2356
2357 #if DEBUG
2358 printk("stli_hostcmd(brdp=%x,channr=%d)\n", (int) brdp, channr);
2359 #endif
2360
2361 portp = brdp->ports[(channr - 1)];
2362 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
2363 cp = &ap->ctrl;
2364
2365
2366
2367
2368 if (test_bit(ST_OPENING, &portp->state)) {
2369 rc = (int) cp->openarg;
2370 if ((cp->open == 0) && (rc != 0)) {
2371 if (rc > 0)
2372 rc--;
2373 cp->openarg = 0;
2374 portp->rc = rc;
2375 clear_bit(ST_OPENING, &portp->state);
2376 wake_up_interruptible(&portp->raw_wait);
2377 }
2378 }
2379
2380
2381
2382
2383 if (test_bit(ST_CLOSING, &portp->state)) {
2384 rc = (int) cp->closearg;
2385 if ((cp->close == 0) && (rc != 0)) {
2386 if (rc > 0)
2387 rc--;
2388 cp->closearg = 0;
2389 portp->rc = rc;
2390 clear_bit(ST_CLOSING, &portp->state);
2391 wake_up_interruptible(&portp->raw_wait);
2392 }
2393 }
2394
2395
2396
2397
2398
2399 if (test_bit(ST_CMDING, &portp->state)) {
2400 rc = cp->status;
2401 if ((cp->cmd == 0) && (rc != 0)) {
2402 if (rc > 0)
2403 rc--;
2404 if (portp->argp != (void *) NULL) {
2405 memcpy(portp->argp, (void *) &(cp->args[0]), portp->argsize);
2406 portp->argp = (void *) NULL;
2407 }
2408 cp->status = 0;
2409 portp->rc = rc;
2410 clear_bit(ST_CMDING, &portp->state);
2411 stli_dodelaycmd(portp, cp);
2412 wake_up_interruptible(&portp->raw_wait);
2413 }
2414 }
2415
2416
2417
2418
2419
2420
2421 donerx = 0;
2422
2423 if (ap->notify) {
2424 nt = ap->changed;
2425 ap->notify = 0;
2426 tty = portp->tty;
2427
2428 if (nt.signal & SG_DCD) {
2429 oldsigs = portp->sigs;
2430 portp->sigs = stli_mktiocm(nt.sigvalue);
2431 clear_bit(ST_GETSIGS, &portp->state);
2432 if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
2433 wake_up_interruptible(&portp->open_wait);
2434 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
2435 if (portp->flags & ASYNC_CHECK_CD) {
2436 if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
2437 (portp->flags & ASYNC_CALLOUT_NOHUP))) {
2438 if (tty != (struct tty_struct *) NULL)
2439 queue_task_irq_off(&portp->tqhangup, &tq_scheduler);
2440 }
2441 }
2442 }
2443 }
2444
2445 if (nt.data & DT_TXEMPTY)
2446 clear_bit(ST_TXBUSY, &portp->state);
2447 if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
2448 if (tty != (struct tty_struct *) NULL) {
2449 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
2450 (tty->ldisc.write_wakeup)(tty);
2451 EBRDENABLE(brdp);
2452 }
2453 wake_up_interruptible(&tty->write_wait);
2454 }
2455 }
2456
2457 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
2458 if (tty != (struct tty_struct *) NULL) {
2459 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
2460 tty->flip.count++;
2461 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
2462 *tty->flip.char_buf_ptr++ = 0;
2463 #ifndef MODULE
2464 if (portp->flags & ASYNC_SAK) {
2465 do_SAK(tty);
2466 EBRDENABLE(brdp);
2467 }
2468 #endif
2469 tty_schedule_flip(tty);
2470 }
2471 }
2472 }
2473
2474 if (nt.data & DT_RXBUSY) {
2475 donerx++;
2476 stli_read(brdp, portp);
2477 }
2478 }
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488 if ((!donerx) && test_bit(ST_RXING, &portp->state)) {
2489 clear_bit(ST_RXING, &portp->state);
2490 stli_read(brdp, portp);
2491 }
2492
2493 return(0);
2494 }
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507 static void stli_poll(unsigned long arg)
2508 {
2509 volatile cdkhdr_t *hdrp;
2510 unsigned char bits[(STL_MAXCHANS / 8) + 1];
2511 unsigned char hostreq, slavereq;
2512 stliport_t *portp;
2513 stlibrd_t *brdp;
2514 int bitpos, bitat, bitsize;
2515 int brdnr, channr, nrdevs;
2516
2517 stli_timerlist.expires = STLI_TIMEOUT;
2518 add_timer(&stli_timerlist);
2519
2520
2521
2522
2523 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
2524 brdp = stli_brds[brdnr];
2525 if (brdp == (stlibrd_t *) NULL)
2526 continue;
2527 if ((brdp->state & BST_STARTED) == 0)
2528 continue;
2529
2530 EBRDENABLE(brdp);
2531 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2532 hostreq = hdrp->hostreq;
2533 slavereq = hdrp->slavereq;
2534 bitsize = brdp->bitsize;
2535 nrdevs = brdp->nrdevs;
2536
2537
2538
2539
2540
2541
2542
2543
2544 if (hostreq) {
2545 memcpy(&bits[0], (((unsigned char *) hdrp) + brdp->hostoffset), bitsize);
2546
2547 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2548 if (bits[bitpos] == 0)
2549 continue;
2550 channr = bitpos * 8;
2551 for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
2552 if (bits[bitpos] & bitat) {
2553 stli_hostcmd(brdp, channr);
2554 }
2555 }
2556 }
2557 }
2558
2559
2560
2561
2562
2563
2564 if (slavereq) {
2565 slavereq = 0;
2566 hostreq = 0;
2567 memcpy(&bits[0], (((unsigned char *) hdrp) + brdp->slaveoffset), bitsize);
2568
2569 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2570 if (bits[bitpos] == 0)
2571 continue;
2572 channr = bitpos * 8;
2573 for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
2574 if (bits[bitpos] & bitat) {
2575 portp = brdp->ports[(channr - 1)];
2576 if (test_bit(ST_OPENING, &portp->state) ||
2577 test_bit(ST_CLOSING, &portp->state) ||
2578 test_bit(ST_CMDING, &portp->state) ||
2579 test_bit(ST_TXBUSY, &portp->state)) {
2580 slavereq |= portp->reqbit;
2581 } else {
2582 bits[bitpos] &= ~bitat;
2583 hostreq++;
2584 }
2585 }
2586 }
2587 }
2588 hdrp->slavereq = slavereq;
2589 if (hostreq)
2590 memcpy((((unsigned char *) hdrp) + brdp->slaveoffset), &bits[0], bitsize);
2591 }
2592
2593 EBRDDISABLE(brdp);
2594 }
2595 }
2596
2597
2598
2599
2600
2601
2602
2603
2604 static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
2605 {
2606 #if DEBUG
2607 printk("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", (int) portp, (int) pp, (int) tiosp);
2608 #endif
2609
2610 memset(pp, 0, sizeof(asyport_t));
2611
2612
2613
2614
2615 pp->baudout = tiosp->c_cflag & CBAUD;
2616 if (pp->baudout & CBAUDEX) {
2617 pp->baudout &= ~CBAUDEX;
2618 if ((pp->baudout < 1) || (pp->baudout > 2))
2619 tiosp->c_cflag &= ~CBAUDEX;
2620 else
2621 pp->baudout += 15;
2622 }
2623 pp->baudout = stli_baudrates[pp->baudout];
2624 if ((tiosp->c_cflag & CBAUD) == B38400) {
2625 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2626 pp->baudout = 57600;
2627 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2628 pp->baudout = 115200;
2629 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
2630 pp->baudout = (portp->baud_base / portp->custom_divisor);
2631 }
2632 if (pp->baudout > STL_MAXBAUD)
2633 pp->baudout = STL_MAXBAUD;
2634 pp->baudin = pp->baudout;
2635
2636 switch (tiosp->c_cflag & CSIZE) {
2637 case CS5:
2638 pp->csize = 5;
2639 break;
2640 case CS6:
2641 pp->csize = 6;
2642 break;
2643 case CS7:
2644 pp->csize = 7;
2645 break;
2646 default:
2647 pp->csize = 8;
2648 break;
2649 }
2650
2651 if (tiosp->c_cflag & CSTOPB)
2652 pp->stopbs = PT_STOP2;
2653 else
2654 pp->stopbs = PT_STOP1;
2655
2656 if (tiosp->c_cflag & PARENB) {
2657 if (tiosp->c_cflag & PARODD)
2658 pp->parity = PT_ODDPARITY;
2659 else
2660 pp->parity = PT_EVENPARITY;
2661 } else {
2662 pp->parity = PT_NOPARITY;
2663 }
2664
2665
2666
2667
2668 if (tiosp->c_iflag & IXON) {
2669 pp->flow |= F_IXON;
2670 if (tiosp->c_iflag & IXANY)
2671 pp->flow |= F_IXANY;
2672 }
2673 if (tiosp->c_cflag & CRTSCTS)
2674 pp->flow |= (F_RTSFLOW | F_CTSFLOW);
2675
2676 pp->startin = tiosp->c_cc[VSTART];
2677 pp->stopin = tiosp->c_cc[VSTOP];
2678 pp->startout = tiosp->c_cc[VSTART];
2679 pp->stopout = tiosp->c_cc[VSTOP];
2680
2681
2682
2683
2684
2685
2686
2687 if (tiosp->c_iflag & IGNPAR)
2688 pp->iflag |= FI_IGNRXERRS;
2689 if (tiosp->c_iflag & IGNBRK)
2690 pp->iflag |= FI_IGNBREAK;
2691
2692 portp->rxmarkmsk = 0;
2693 if (tiosp->c_iflag & (INPCK | PARMRK))
2694 pp->iflag |= FI_1MARKRXERRS;
2695 if (tiosp->c_iflag & BRKINT)
2696 portp->rxmarkmsk |= BRKINT;
2697
2698
2699
2700
2701 if (tiosp->c_cflag & CLOCAL)
2702 portp->flags &= ~ASYNC_CHECK_CD;
2703 else
2704 portp->flags |= ASYNC_CHECK_CD;
2705
2706
2707
2708
2709 pp->pflag = portp->pflag;
2710 }
2711
2712
2713
2714
2715
2716
2717
2718
2719 static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
2720 {
2721 #if DEBUG
2722 printk("stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n", (int) sp, dtr, rts);
2723 #endif
2724
2725 memset(sp, 0, sizeof(asysigs_t));
2726 if (dtr >= 0) {
2727 sp->signal |= SG_DTR;
2728 sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0);
2729 }
2730 if (rts >= 0) {
2731 sp->signal |= SG_RTS;
2732 sp->sigvalue |= ((rts > 0) ? SG_RTS : 0);
2733 }
2734 }
2735
2736
2737
2738
2739
2740
2741
2742
2743 static long stli_mktiocm(unsigned long sigvalue)
2744 {
2745 long tiocm;
2746
2747 #if DEBUG
2748 printk("stli_mktiocm(sigvalue=%x)\n", (int) sigvalue);
2749 #endif
2750
2751 tiocm = 0;
2752 tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);
2753 tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);
2754 tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);
2755 tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0);
2756 tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0);
2757 tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0);
2758 return(tiocm);
2759 }
2760
2761
2762
2763
2764
2765
2766
2767
2768 static int stli_initports(stlibrd_t *brdp)
2769 {
2770 stliport_t *portp;
2771 int i, panelnr, panelport;
2772
2773 #if DEBUG
2774 printk("stli_initports(brdp=%x)\n", (int) brdp);
2775 #endif
2776
2777 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
2778 portp = (stliport_t *) stli_memalloc(sizeof(stliport_t));
2779 if (portp == (stliport_t *) NULL) {
2780 printk("STALLION: failed to allocate port structure\n");
2781 continue;
2782 }
2783
2784 memset(portp, 0, sizeof(stliport_t));
2785 portp->magic = STLI_PORTMAGIC;
2786 portp->portnr = i;
2787 portp->brdnr = brdp->brdnr;
2788 portp->panelnr = panelnr;
2789 portp->baud_base = STL_BAUDBASE;
2790 portp->close_delay = STL_CLOSEDELAY;
2791 portp->closing_wait = 30 * HZ;
2792 portp->tqhangup.routine = stli_dohangup;
2793 portp->tqhangup.data = portp;
2794 portp->normaltermios = stli_deftermios;
2795 portp->callouttermios = stli_deftermios;
2796 panelport++;
2797 if (panelport >= brdp->panels[panelnr]) {
2798 panelport = 0;
2799 panelnr++;
2800 }
2801 brdp->ports[i] = portp;
2802 }
2803
2804 return(0);
2805 }
2806
2807
2808
2809
2810
2811
2812
2813 static void stli_ecpinit(stlibrd_t *brdp)
2814 {
2815 unsigned long memconf;
2816
2817 #if DEBUG
2818 printk("stli_ecpinit(brdp=%d)\n", (int) brdp);
2819 #endif
2820
2821 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
2822 udelay(10);
2823 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
2824 udelay(100);
2825
2826 memconf = (brdp->memaddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT;
2827 outb(memconf, (brdp->iobase + ECP_ATMEMAR));
2828 }
2829
2830
2831
2832 static void stli_ecpenable(stlibrd_t *brdp)
2833 {
2834 #if DEBUG
2835 printk("stli_ecpenable(brdp=%x)\n", (int) brdp);
2836 #endif
2837 outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));
2838 }
2839
2840
2841
2842 static void stli_ecpdisable(stlibrd_t *brdp)
2843 {
2844 #if DEBUG
2845 printk("stli_ecpdisable(brdp=%x)\n", (int) brdp);
2846 #endif
2847 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
2848 }
2849
2850
2851
2852 static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2853 {
2854 void *ptr;
2855 unsigned char val;
2856
2857 #if DEBUG
2858 printk("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
2859 #endif
2860
2861 if (offset > brdp->memsize) {
2862 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
2863 ptr = 0;
2864 val = 0;
2865 } else {
2866 ptr = brdp->membase + (offset % ECP_ATPAGESIZE);
2867 val = (unsigned char) (offset / ECP_ATPAGESIZE);
2868 }
2869 outb(val, (brdp->iobase + ECP_ATMEMPR));
2870 return(ptr);
2871 }
2872
2873
2874
2875 static void stli_ecpreset(stlibrd_t *brdp)
2876 {
2877 #if DEBUG
2878 printk("stli_ecpreset(brdp=%x)\n", (int) brdp);
2879 #endif
2880
2881 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
2882 udelay(10);
2883 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
2884 udelay(500);
2885 }
2886
2887
2888
2889 static void stli_ecpintr(stlibrd_t *brdp)
2890 {
2891 #if DEBUG
2892 printk("stli_ecpintr(brdp=%x)\n", (int) brdp);
2893 #endif
2894 outb(0x1, brdp->iobase);
2895 }
2896
2897
2898
2899
2900
2901
2902
2903 static void stli_ecpeiinit(stlibrd_t *brdp)
2904 {
2905 unsigned long memconf;
2906
2907 #if DEBUG
2908 printk("stli_ecpeiinit(brdp=%x)\n", (int) brdp);
2909 #endif
2910
2911 outb(0x1, (brdp->iobase + ECP_EIBRDENAB));
2912 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
2913 udelay(10);
2914 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
2915 udelay(500);
2916
2917 memconf = (brdp->memaddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL;
2918 outb(memconf, (brdp->iobase + ECP_EIMEMARL));
2919 memconf = (brdp->memaddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH;
2920 outb(memconf, (brdp->iobase + ECP_EIMEMARH));
2921 }
2922
2923
2924
2925 static void stli_ecpeienable(stlibrd_t *brdp)
2926 {
2927 outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR));
2928 }
2929
2930
2931
2932 static void stli_ecpeidisable(stlibrd_t *brdp)
2933 {
2934 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
2935 }
2936
2937
2938
2939 static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2940 {
2941 void *ptr;
2942 unsigned char val;
2943
2944 #if DEBUG
2945 printk("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp, (int) offset, line);
2946 #endif
2947
2948 if (offset > brdp->memsize) {
2949 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
2950 ptr = 0;
2951 val = 0;
2952 } else {
2953 ptr = brdp->membase + (offset % ECP_EIPAGESIZE);
2954 if (offset < ECP_EIPAGESIZE)
2955 val = ECP_EIENABLE;
2956 else
2957 val = ECP_EIENABLE | 0x40;
2958 }
2959 outb(val, (brdp->iobase + ECP_EICONFR));
2960 return(ptr);
2961 }
2962
2963
2964
2965 static void stli_ecpeireset(stlibrd_t *brdp)
2966 {
2967 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
2968 udelay(10);
2969 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
2970 udelay(500);
2971 }
2972
2973
2974
2975
2976
2977
2978
2979 static void stli_ecpmcenable(stlibrd_t *brdp)
2980 {
2981 outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR));
2982 }
2983
2984
2985
2986 static void stli_ecpmcdisable(stlibrd_t *brdp)
2987 {
2988 outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR));
2989 }
2990
2991
2992
2993 static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
2994 {
2995 void *ptr;
2996 unsigned char val;
2997
2998 if (offset > brdp->memsize) {
2999 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
3000 ptr = 0;
3001 val = 0;
3002 } else {
3003 ptr = brdp->membase + (offset % ECP_MCPAGESIZE);
3004 val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE;
3005 }
3006 outb(val, (brdp->iobase + ECP_MCCONFR));
3007 return(ptr);
3008 }
3009
3010
3011
3012 static void stli_ecpmcreset(stlibrd_t *brdp)
3013 {
3014 outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR));
3015 udelay(10);
3016 outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR));
3017 udelay(500);
3018 }
3019
3020
3021
3022
3023
3024
3025
3026 static void stli_onbinit(stlibrd_t *brdp)
3027 {
3028 unsigned long memconf;
3029 int i;
3030
3031 #if DEBUG
3032 printk("stli_onbinit(brdp=%d)\n", (int) brdp);
3033 #endif
3034
3035 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
3036 udelay(10);
3037 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
3038 for (i = 0; (i < 1000); i++)
3039 udelay(1000);
3040
3041 memconf = (brdp->memaddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT;
3042 outb(memconf, (brdp->iobase + ONB_ATMEMAR));
3043 outb(0x1, brdp->iobase);
3044 udelay(1000);
3045 }
3046
3047
3048
3049 static void stli_onbenable(stlibrd_t *brdp)
3050 {
3051 #if DEBUG
3052 printk("stli_onbenable(brdp=%x)\n", (int) brdp);
3053 #endif
3054 outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));
3055 }
3056
3057
3058
3059 static void stli_onbdisable(stlibrd_t *brdp)
3060 {
3061 #if DEBUG
3062 printk("stli_onbdisable(brdp=%x)\n", (int) brdp);
3063 #endif
3064 outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));
3065 }
3066
3067
3068
3069 static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
3070 {
3071 void *ptr;
3072
3073 #if DEBUG
3074 printk("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
3075 #endif
3076
3077 if (offset > brdp->memsize) {
3078 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
3079 ptr = 0;
3080 } else {
3081 ptr = brdp->membase + (offset % ONB_ATPAGESIZE);
3082 }
3083 return(ptr);
3084 }
3085
3086
3087
3088 static void stli_onbreset(stlibrd_t *brdp)
3089 {
3090 int i;
3091
3092 #if DEBUG
3093 printk("stli_onbreset(brdp=%x)\n", (int) brdp);
3094 #endif
3095
3096 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
3097 udelay(10);
3098 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
3099 for (i = 0; (i < 1000); i++)
3100 udelay(1000);
3101 }
3102
3103
3104
3105
3106
3107
3108
3109 static void stli_onbeinit(stlibrd_t *brdp)
3110 {
3111 unsigned long memconf;
3112 int i;
3113
3114 #if DEBUG
3115 printk("stli_onbeinit(brdp=%d)\n", (int) brdp);
3116 #endif
3117
3118 outb(0x1, (brdp->iobase + ONB_EIBRDENAB));
3119 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
3120 udelay(10);
3121 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
3122 for (i = 0; (i < 1000); i++)
3123 udelay(1000);
3124
3125 memconf = (brdp->memaddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL;
3126 outb(memconf, (brdp->iobase + ONB_EIMEMARL));
3127 memconf = (brdp->memaddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH;
3128 outb(memconf, (brdp->iobase + ONB_EIMEMARH));
3129 outb(0x1, brdp->iobase);
3130 udelay(1000);
3131 }
3132
3133
3134
3135 static void stli_onbeenable(stlibrd_t *brdp)
3136 {
3137 #if DEBUG
3138 printk("stli_onbeenable(brdp=%x)\n", (int) brdp);
3139 #endif
3140 outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));
3141 }
3142
3143
3144
3145 static void stli_onbedisable(stlibrd_t *brdp)
3146 {
3147 #if DEBUG
3148 printk("stli_onbedisable(brdp=%x)\n", (int) brdp);
3149 #endif
3150 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
3151 }
3152
3153
3154
3155 static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
3156 {
3157 void *ptr;
3158 unsigned char val;
3159
3160 #if DEBUG
3161 printk("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp, (int) offset, line);
3162 #endif
3163
3164 if (offset > brdp->memsize) {
3165 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
3166 ptr = 0;
3167 val = 0;
3168 } else {
3169 ptr = brdp->membase + (offset % ONB_EIPAGESIZE);
3170 if (offset < ONB_EIPAGESIZE)
3171 val = ONB_EIENABLE;
3172 else
3173 val = ONB_EIENABLE | 0x40;
3174 }
3175 outb(val, (brdp->iobase + ONB_EICONFR));
3176 return(ptr);
3177 }
3178
3179
3180
3181 static void stli_onbereset(stlibrd_t *brdp)
3182 {
3183 int i;
3184
3185 #if DEBUG
3186 printk("stli_onbereset(brdp=%x)\n", (int) brdp);
3187 #endif
3188
3189 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
3190 udelay(10);
3191 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
3192 for (i = 0; (i < 1000); i++)
3193 udelay(1000);
3194 }
3195
3196
3197
3198
3199
3200
3201
3202 static void stli_bbyinit(stlibrd_t *brdp)
3203 {
3204 int i;
3205
3206 #if DEBUG
3207 printk("stli_bbyinit(brdp=%d)\n", (int) brdp);
3208 #endif
3209
3210 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
3211 udelay(10);
3212 outb(0, (brdp->iobase + BBY_ATCONFR));
3213 for (i = 0; (i < 1000); i++)
3214 udelay(1000);
3215 outb(0x1, brdp->iobase);
3216 udelay(1000);
3217 }
3218
3219
3220
3221 static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
3222 {
3223 void *ptr;
3224 unsigned char val;
3225
3226 #if DEBUG
3227 printk("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
3228 #endif
3229
3230 if (offset > brdp->memsize) {
3231 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
3232 ptr = 0;
3233 val = 0;
3234 } else {
3235 ptr = brdp->membase + (offset % BBY_PAGESIZE);
3236 val = (unsigned char) (offset / BBY_PAGESIZE);
3237 }
3238 outb(val, (brdp->iobase + BBY_ATCONFR));
3239 return(ptr);
3240 }
3241
3242
3243
3244 static void stli_bbyreset(stlibrd_t *brdp)
3245 {
3246 int i;
3247
3248 #if DEBUG
3249 printk("stli_bbyreset(brdp=%x)\n", (int) brdp);
3250 #endif
3251
3252 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
3253 udelay(10);
3254 outb(0, (brdp->iobase + BBY_ATCONFR));
3255 for (i = 0; (i < 1000); i++)
3256 udelay(1000);
3257 }
3258
3259
3260
3261
3262
3263
3264
3265 static void stli_stalinit(stlibrd_t *brdp)
3266 {
3267 int i;
3268
3269 #if DEBUG
3270 printk("stli_stalinit(brdp=%d)\n", (int) brdp);
3271 #endif
3272
3273 outb(0x1, brdp->iobase);
3274 for (i = 0; (i < 1000); i++)
3275 udelay(1000);
3276 }
3277
3278
3279
3280 static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
3281 {
3282 void *ptr;
3283
3284 #if DEBUG
3285 printk("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
3286 #endif
3287
3288 if (offset > brdp->memsize) {
3289 printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
3290 ptr = 0;
3291 } else {
3292 ptr = brdp->membase + (offset % STAL_PAGESIZE);
3293 }
3294 return(ptr);
3295 }
3296
3297
3298
3299 static void stli_stalreset(stlibrd_t *brdp)
3300 {
3301 volatile unsigned long *vecp;
3302 int i;
3303
3304 #if DEBUG
3305 printk("stli_stalreset(brdp=%x)\n", (int) brdp);
3306 #endif
3307
3308 vecp = (volatile unsigned long *) (brdp->membase + 0x30);
3309 *vecp = 0xffff0000;
3310 outb(0, brdp->iobase);
3311 for (i = 0; (i < 1000); i++)
3312 udelay(1000);
3313 }
3314
3315
3316
3317
3318
3319
3320
3321
3322 static int stli_initecp(stlibrd_t *brdp)
3323 {
3324 cdkecpsig_t sig;
3325 cdkecpsig_t *sigsp;
3326 unsigned int status, nxtid;
3327 int panelnr;
3328
3329 #if DEBUG
3330 printk("stli_initecp(brdp=%x)\n", (int) brdp);
3331 #endif
3332
3333
3334
3335
3336 if ((brdp->iobase == 0) || (brdp->memaddr == 0))
3337 return(-ENODEV);
3338
3339
3340
3341
3342
3343
3344 switch (brdp->brdtype) {
3345 case BRD_ECP:
3346 brdp->membase = (void *) brdp->memaddr;
3347 brdp->memsize = ECP_MEMSIZE;
3348 brdp->pagesize = ECP_ATPAGESIZE;
3349 brdp->init = stli_ecpinit;
3350 brdp->enable = stli_ecpenable;
3351 brdp->reenable = stli_ecpenable;
3352 brdp->disable = stli_ecpdisable;
3353 brdp->getmemptr = stli_ecpgetmemptr;
3354 brdp->intr = stli_ecpintr;
3355 brdp->reset = stli_ecpreset;
3356 break;
3357
3358 case BRD_ECPE:
3359 brdp->membase = (void *) brdp->memaddr;
3360 brdp->memsize = ECP_MEMSIZE;
3361 brdp->pagesize = ECP_EIPAGESIZE;
3362 brdp->init = stli_ecpeiinit;
3363 brdp->enable = stli_ecpeienable;
3364 brdp->reenable = stli_ecpeienable;
3365 brdp->disable = stli_ecpeidisable;
3366 brdp->getmemptr = stli_ecpeigetmemptr;
3367 brdp->intr = stli_ecpintr;
3368 brdp->reset = stli_ecpeireset;
3369 break;
3370
3371 case BRD_ECPMC:
3372 brdp->membase = (void *) brdp->memaddr;
3373 brdp->memsize = ECP_MEMSIZE;
3374 brdp->pagesize = ECP_MCPAGESIZE;
3375 brdp->init = NULL;
3376 brdp->enable = stli_ecpmcenable;
3377 brdp->reenable = stli_ecpmcenable;
3378 brdp->disable = stli_ecpmcdisable;
3379 brdp->getmemptr = stli_ecpmcgetmemptr;
3380 brdp->intr = stli_ecpintr;
3381 brdp->reset = stli_ecpmcreset;
3382 break;
3383
3384 default:
3385 return(-EINVAL);
3386 }
3387
3388
3389
3390
3391
3392
3393
3394 EBRDINIT(brdp);
3395
3396 if (brdp->memaddr > 0x100000) {
3397 brdp->membase = vremap(brdp->memaddr, brdp->memsize);
3398 if (brdp->membase == (void *) NULL)
3399 return(-ENOMEM);
3400 }
3401
3402
3403
3404
3405
3406
3407 EBRDENABLE(brdp);
3408 sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3409 memcpy(&sig, sigsp, sizeof(cdkecpsig_t));
3410 EBRDDISABLE(brdp);
3411
3412 #if 0
3413 printk("%s(%d): sig-> magic=%x romver=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
3414 __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0],
3415 (int) sig.panelid[1], (int) sig.panelid[2], (int) sig.panelid[3],
3416 (int) sig.panelid[4], (int) sig.panelid[5], (int) sig.panelid[6],
3417 (int) sig.panelid[7]);
3418 #endif
3419
3420 if (sig.magic != ECP_MAGIC)
3421 return(-ENODEV);
3422
3423
3424
3425
3426
3427 for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) {
3428 status = sig.panelid[nxtid];
3429 if ((status & ECH_PNLIDMASK) != nxtid)
3430 break;
3431 if (status & ECH_PNL16PORT) {
3432 brdp->panels[panelnr] = 16;
3433 brdp->nrports += 16;
3434 nxtid += 2;
3435 } else {
3436 brdp->panels[panelnr] = 8;
3437 brdp->nrports += 8;
3438 nxtid++;
3439 }
3440 brdp->panelids[panelnr] = status;
3441 brdp->nrpanels++;
3442 }
3443
3444 request_region(brdp->iobase, ECP_IOSIZE, "serial(ECP)");
3445 brdp->state |= BST_FOUND;
3446 return(0);
3447 }
3448
3449
3450
3451
3452
3453
3454
3455
3456 static int stli_initonb(stlibrd_t *brdp)
3457 {
3458 cdkonbsig_t sig;
3459 cdkonbsig_t *sigsp;
3460 int i;
3461
3462 #if DEBUG
3463 printk("stli_initonb(brdp=%x)\n", (int) brdp);
3464 #endif
3465
3466
3467
3468
3469 if ((brdp->iobase == 0) || (brdp->memaddr == 0))
3470 return(-ENODEV);
3471
3472
3473
3474
3475
3476
3477 switch (brdp->brdtype) {
3478 case BRD_ONBOARD:
3479 case BRD_ONBOARD32:
3480 case BRD_ONBOARD2:
3481 case BRD_ONBOARD2_32:
3482 case BRD_ONBOARDRS:
3483 brdp->membase = (void *) brdp->memaddr;
3484 brdp->memsize = ONB_MEMSIZE;
3485 brdp->pagesize = ONB_ATPAGESIZE;
3486 brdp->init = stli_onbinit;
3487 brdp->enable = stli_onbenable;
3488 brdp->reenable = stli_onbenable;
3489 brdp->disable = stli_onbdisable;
3490 brdp->getmemptr = stli_onbgetmemptr;
3491 brdp->intr = stli_ecpintr;
3492 brdp->reset = stli_onbreset;
3493 if (brdp->memaddr > 0x100000)
3494 brdp->enabval = ONB_MEMENABHI;
3495 else
3496 brdp->enabval = ONB_MEMENABLO;
3497 break;
3498
3499 case BRD_ONBOARDE:
3500 brdp->membase = (void *) brdp->memaddr;
3501 brdp->memsize = ONB_EIMEMSIZE;
3502 brdp->pagesize = ONB_EIPAGESIZE;
3503 brdp->init = stli_onbeinit;
3504 brdp->enable = stli_onbeenable;
3505 brdp->reenable = stli_onbeenable;
3506 brdp->disable = stli_onbedisable;
3507 brdp->getmemptr = stli_onbegetmemptr;
3508 brdp->intr = stli_ecpintr;
3509 brdp->reset = stli_onbereset;
3510 break;
3511
3512 case BRD_BRUMBY4:
3513 case BRD_BRUMBY8:
3514 case BRD_BRUMBY16:
3515 brdp->membase = (void *) brdp->memaddr;
3516 brdp->memsize = BBY_MEMSIZE;
3517 brdp->pagesize = BBY_PAGESIZE;
3518 brdp->init = stli_bbyinit;
3519 brdp->enable = NULL;
3520 brdp->reenable = NULL;
3521 brdp->disable = NULL;
3522 brdp->getmemptr = stli_bbygetmemptr;
3523 brdp->intr = stli_ecpintr;
3524 brdp->reset = stli_bbyreset;
3525 break;
3526
3527 case BRD_STALLION:
3528 brdp->membase = (void *) brdp->memaddr;
3529 brdp->memsize = STAL_MEMSIZE;
3530 brdp->pagesize = STAL_PAGESIZE;
3531 brdp->init = stli_stalinit;
3532 brdp->enable = NULL;
3533 brdp->reenable = NULL;
3534 brdp->disable = NULL;
3535 brdp->getmemptr = stli_stalgetmemptr;
3536 brdp->intr = stli_ecpintr;
3537 brdp->reset = stli_stalreset;
3538 break;
3539
3540 default:
3541 return(-EINVAL);
3542 }
3543
3544
3545
3546
3547
3548
3549
3550 EBRDINIT(brdp);
3551
3552 if (brdp->memaddr > 0x100000) {
3553 brdp->membase = vremap(brdp->memaddr, brdp->memsize);
3554 if (brdp->membase == (void *) NULL)
3555 return(-ENOMEM);
3556 }
3557
3558
3559
3560
3561
3562
3563 EBRDENABLE(brdp);
3564 sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3565 memcpy(&sig, sigsp, sizeof(cdkonbsig_t));
3566 EBRDDISABLE(brdp);
3567
3568 #if 0
3569 printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n",
3570 __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2,
3571 sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2);
3572 #endif
3573
3574 if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
3575 (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
3576 return(-ENODEV);
3577
3578
3579
3580
3581
3582 brdp->nrpanels = 1;
3583 if (sig.amask1) {
3584 brdp->nrports = 32;
3585 } else {
3586 for (i = 0; (i < 16); i++) {
3587 if (((sig.amask0 << i) & 0x8000) == 0)
3588 break;
3589 }
3590 brdp->nrports = i;
3591 }
3592 brdp->panels[0] = brdp->nrports;
3593
3594 request_region(brdp->iobase, ONB_IOSIZE, "serial(ONB/BBY)");
3595 brdp->state |= BST_FOUND;
3596 return(0);
3597 }
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607 static int stli_startbrd(stlibrd_t *brdp)
3608 {
3609 volatile cdkhdr_t *hdrp;
3610 volatile cdkmem_t *memp;
3611 volatile cdkasy_t *ap;
3612 unsigned long flags;
3613 stliport_t *portp;
3614 int portnr, nrdevs, i, rc;
3615
3616 #if DEBUG
3617 printk("stli_startbrd(brdp=%x)\n", (int) brdp);
3618 #endif
3619
3620 rc = 0;
3621
3622 save_flags(flags);
3623 cli();
3624 EBRDENABLE(brdp);
3625 hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
3626 nrdevs = hdrp->nrdevs;
3627
3628 #if 0
3629 printk("%s(%d): CDK version %d.%d.%d --> nrdevs=%d memp=%x hostp=%x slavep=%x\n",
3630 __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification,
3631 hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp,
3632 (int) hdrp->slavep);
3633 #endif
3634
3635 if (nrdevs < (brdp->nrports + 1)) {
3636 printk("STALLION: slave failed to allocate memory for all devices, devices=%d\n", nrdevs);
3637 brdp->nrports = nrdevs - 1;
3638 }
3639 brdp->nrdevs = nrdevs;
3640 brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;
3641 brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;
3642 brdp->bitsize = (nrdevs + 7) / 8;
3643 memp = (volatile cdkmem_t *) hdrp->memp;
3644 if (((unsigned long) memp) > brdp->memsize) {
3645 printk("STALLION: corrupted shared memory region?\n");
3646 rc = -EIO;
3647 goto stli_donestartup;
3648 }
3649 memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp);
3650 if (memp->dtype != TYP_ASYNCTRL) {
3651 printk("STALLION: no slave control device found\n");
3652 goto stli_donestartup;
3653 }
3654 memp++;
3655
3656
3657
3658
3659
3660
3661 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {
3662 if (memp->dtype != TYP_ASYNC)
3663 break;
3664 portp = brdp->ports[portnr];
3665 if (portp == (stliport_t *) NULL)
3666 break;
3667 portp->devnr = i;
3668 portp->addr = memp->offset;
3669 portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs));
3670 portp->portidx = (unsigned char) (i / 8);
3671 portp->portbit = (unsigned char) (0x1 << (i % 8));
3672 }
3673
3674
3675
3676
3677
3678
3679 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {
3680 portp = brdp->ports[portnr];
3681 if (portp == (stliport_t *) NULL)
3682 break;
3683 if (portp->addr == 0)
3684 break;
3685 ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
3686 if (ap != (volatile cdkasy_t *) NULL) {
3687 portp->rxsize = ap->rxq.size;
3688 portp->txsize = ap->txq.size;
3689 portp->rxoffset = ap->rxq.offset;
3690 portp->txoffset = ap->txq.offset;
3691 }
3692 }
3693
3694 stli_donestartup:
3695 EBRDDISABLE(brdp);
3696 restore_flags(flags);
3697
3698 if (rc == 0)
3699 brdp->state |= BST_STARTED;
3700
3701 if (! stli_timeron) {
3702 stli_timeron++;
3703 stli_timerlist.expires = STLI_TIMEOUT;
3704 add_timer(&stli_timerlist);
3705 }
3706
3707 return(rc);
3708 }
3709
3710
3711
3712
3713
3714
3715
3716 static int stli_brdinit(stlibrd_t *brdp)
3717 {
3718 #if DEBUG
3719 printk("stli_brdinit(brdp=%x)\n", (int) brdp);
3720 #endif
3721
3722 stli_brds[brdp->brdnr] = brdp;
3723
3724 switch (brdp->brdtype) {
3725 case BRD_ECP:
3726 case BRD_ECPE:
3727 case BRD_ECPMC:
3728 stli_initecp(brdp);
3729 break;
3730 case BRD_ONBOARD:
3731 case BRD_ONBOARDE:
3732 case BRD_ONBOARD2:
3733 case BRD_ONBOARD32:
3734 case BRD_ONBOARD2_32:
3735 case BRD_ONBOARDRS:
3736 case BRD_BRUMBY4:
3737 case BRD_BRUMBY8:
3738 case BRD_BRUMBY16:
3739 case BRD_STALLION:
3740 stli_initonb(brdp);
3741 break;
3742 case BRD_EASYIO:
3743 case BRD_ECH:
3744 case BRD_ECHMC:
3745 case BRD_ECHPCI:
3746 printk("STALLION: %s board type not supported in this driver\n", stli_brdnames[brdp->brdtype]);
3747 return(ENODEV);
3748 default:
3749 printk("STALLION: unit=%d is unknown board type=%d\n", brdp->brdnr, brdp->brdtype);
3750 return(ENODEV);
3751 }
3752
3753 if ((brdp->state & BST_FOUND) == 0) {
3754 printk("STALLION: %s board not found, unit=%d io=%x mem=%x\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr);
3755 return(ENODEV);
3756 }
3757
3758 stli_initports(brdp);
3759 printk("STALLION: %s found, unit=%d io=%x mem=%x nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr, brdp->nrpanels, brdp->nrports);
3760 return(0);
3761 }
3762
3763
3764
3765
3766
3767
3768
3769
3770 static int stli_eisamemprobe(stlibrd_t *brdp)
3771 {
3772 cdkecpsig_t ecpsig, *ecpsigp;
3773 cdkonbsig_t onbsig, *onbsigp;
3774 int i, foundit;
3775
3776 #if DEBUG
3777 printk("stli_eisamemprobe(brdp=%x)\n", (int) brdp);
3778 #endif
3779
3780
3781
3782
3783
3784
3785
3786 if (brdp->brdtype == BRD_ECPE) {
3787 outb(0x1, (brdp->iobase + ECP_EIBRDENAB));
3788 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
3789 udelay(10);
3790 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
3791 udelay(500);
3792 stli_ecpeienable(brdp);
3793 } else if (brdp->brdtype == BRD_ONBOARDE) {
3794 outb(0x1, (brdp->iobase + ONB_EIBRDENAB));
3795 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
3796 udelay(10);
3797 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
3798 for (i = 0; (i < 100); i++)
3799 udelay(1000);
3800 outb(0x1, brdp->iobase);
3801 udelay(1000);
3802 stli_onbeenable(brdp);
3803 } else {
3804 return(-ENODEV);
3805 }
3806
3807 foundit = 0;
3808 brdp->memsize = ECP_MEMSIZE;
3809
3810
3811
3812
3813
3814 for (i = 0; (i < stli_eisamempsize); i++) {
3815 brdp->memaddr = stli_eisamemprobeaddrs[i];
3816 brdp->membase = (void *) brdp->memaddr;
3817 if (brdp->memaddr > 0x100000) {
3818 brdp->membase = vremap(brdp->memaddr, brdp->memsize);
3819 if (brdp->membase == (void *) NULL)
3820 continue;
3821 }
3822 if (brdp->brdtype == BRD_ECPE) {
3823 ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp, CDK_SIGADDR, __LINE__);
3824 memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
3825 if (ecpsig.magic == ECP_MAGIC)
3826 foundit = 1;
3827 } else {
3828 onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp, CDK_SIGADDR, __LINE__);
3829 memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t));
3830 if ((onbsig.magic0 == ONB_MAGIC0) && (onbsig.magic1 == ONB_MAGIC1) &&
3831 (onbsig.magic2 == ONB_MAGIC2) && (onbsig.magic3 == ONB_MAGIC3))
3832 foundit = 1;
3833 }
3834 if (brdp->memaddr >= 0x100000)
3835 vfree(brdp->membase);
3836 if (foundit)
3837 break;
3838 }
3839
3840
3841
3842
3843
3844 if (brdp->brdtype == BRD_ECPE)
3845 stli_ecpeidisable(brdp);
3846 else
3847 stli_onbedisable(brdp);
3848
3849 if (! foundit) {
3850 brdp->memaddr = 0;
3851 brdp->membase = 0;
3852 printk("STALLION: failed to probe shared memory region for %s in EISA slot=%d\n", stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
3853 return(-ENODEV);
3854 }
3855 return(0);
3856 }
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870 static int stli_findeisabrds()
3871 {
3872 stlibrd_t *brdp;
3873 unsigned int iobase, eid;
3874 int i;
3875
3876 #if DEBUG
3877 printk("stli_findeisabrds()\n");
3878 #endif
3879
3880
3881
3882
3883
3884
3885 outb(0xff, 0xc80);
3886 if (inb(0xc80) == 0xff)
3887 return(0);
3888
3889
3890
3891
3892 for (iobase = 0x1000; (iobase <= 0xc000); iobase += 0x1000) {
3893 outb(0xff, (iobase + 0xc80));
3894 eid = inb(iobase + 0xc80);
3895 eid |= inb(iobase + 0xc81) << 8;
3896 if (eid != STL_EISAID)
3897 continue;
3898
3899
3900
3901
3902
3903 for (i = 0; (i < STL_MAXBRDS); i++) {
3904 brdp = stli_brds[i];
3905 if (brdp == (stlibrd_t *) NULL)
3906 continue;
3907 if (brdp->iobase == iobase)
3908 break;
3909 }
3910 if (i < STL_MAXBRDS)
3911 continue;
3912
3913
3914
3915
3916
3917 if (stli_nrbrds >= STL_MAXBRDS) {
3918 printk("STALLION: no room for more probed boards, maximum supported %d\n", STL_MAXBRDS);
3919 break;
3920 }
3921
3922
3923
3924
3925
3926 brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
3927 if (brdp == (stlibrd_t *) NULL) {
3928 printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlibrd_t));
3929 return(-ENOMEM);
3930 }
3931 memset(brdp, 0, sizeof(stlibrd_t));
3932
3933 brdp->magic = STLI_BOARDMAGIC;
3934 brdp->brdnr = stli_nrbrds++;
3935 eid = inb(iobase + 0xc82);
3936 if (eid == ECP_EISAID)
3937 brdp->brdtype = BRD_ECPE;
3938 else if (eid == ONB_EISAID)
3939 brdp->brdtype = BRD_ONBOARDE;
3940 else
3941 brdp->brdtype = BRD_UNKNOWN;
3942 brdp->iobase = iobase;
3943 outb(0x1, (iobase + 0xc84));
3944 if (stli_eisamemprobe(brdp))
3945 outb(0, (iobase + 0xc84));
3946 stli_brdinit(brdp);
3947 }
3948
3949 return(0);
3950 }
3951
3952
3953
3954
3955
3956
3957
3958
3959 static int stli_initbrds()
3960 {
3961 stlibrd_t *brdp, *nxtbrdp;
3962 stlconf_t *confp;
3963 int i, j;
3964
3965 #if DEBUG
3966 printk("stli_initbrds()\n");
3967 #endif
3968
3969 if (stli_nrbrds > STL_MAXBRDS) {
3970 printk("STALLION: too many boards in configuration table, truncating to %d\n", STL_MAXBRDS);
3971 stli_nrbrds = STL_MAXBRDS;
3972 }
3973
3974
3975
3976
3977
3978 for (i = 0; (i < stli_nrbrds); i++) {
3979 confp = &stli_brdconf[i];
3980 brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
3981 if (brdp == (stlibrd_t *) NULL) {
3982 printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlibrd_t));
3983 return(-ENOMEM);
3984 }
3985 memset(brdp, 0, sizeof(stlibrd_t));
3986
3987 brdp->magic = STLI_BOARDMAGIC;
3988 brdp->brdnr = i;
3989 brdp->brdtype = confp->brdtype;
3990 brdp->iobase = confp->ioaddr1;
3991 brdp->memaddr = confp->memaddr;
3992 stli_brdinit(brdp);
3993 }
3994
3995
3996
3997
3998 if (stli_eisaprobe)
3999 stli_findeisabrds();
4000
4001
4002
4003
4004
4005
4006 stli_shared = 0;
4007 if (stli_nrbrds > 1) {
4008 for (i = 0; (i < stli_nrbrds); i++) {
4009 brdp = stli_brds[i];
4010 if (brdp == (stlibrd_t *) NULL)
4011 continue;
4012 for (j = i + 1; (j < stli_nrbrds); j++) {
4013 nxtbrdp = stli_brds[j];
4014 if (nxtbrdp == (stlibrd_t *) NULL)
4015 continue;
4016 if ((brdp->membase >= nxtbrdp->membase) && (brdp->membase <= (nxtbrdp->membase + nxtbrdp->memsize - 1))) {
4017 stli_shared++;
4018 break;
4019 }
4020 }
4021 }
4022 }
4023
4024 if (stli_shared == 0) {
4025 for (i = 0; (i < stli_nrbrds); i++) {
4026 brdp = stli_brds[i];
4027 if (brdp == (stlibrd_t *) NULL)
4028 continue;
4029 if (brdp->state & BST_FOUND) {
4030 EBRDENABLE(brdp);
4031 brdp->enable = NULL;
4032 brdp->disable = NULL;
4033 }
4034 }
4035 }
4036
4037 return(0);
4038 }
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048 static int stli_memread(struct inode *ip, struct file *fp, char *buf, int count)
4049 {
4050 unsigned long flags;
4051 void *memptr;
4052 stlibrd_t *brdp;
4053 int brdnr, size, n;
4054
4055 #if DEBUG
4056 printk("stli_memread(ip=%x,fp=%x,buf=%x,count=%d)\n", (int) ip, (int) fp, (int) buf, count);
4057 #endif
4058
4059 brdnr = MINOR(ip->i_rdev);
4060 if (brdnr >= stli_nrbrds)
4061 return(-ENODEV);
4062 brdp = stli_brds[brdnr];
4063 if (brdp == (stlibrd_t *) NULL)
4064 return(-ENODEV);
4065 if (brdp->state == 0)
4066 return(-ENODEV);
4067 if (fp->f_pos >= brdp->memsize)
4068 return(0);
4069
4070 size = MIN(count, (brdp->memsize - fp->f_pos));
4071
4072 save_flags(flags);
4073 cli();
4074 EBRDENABLE(brdp);
4075 while (size > 0) {
4076 memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
4077 n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
4078 memcpy_tofs(buf, memptr, n);
4079 fp->f_pos += n;
4080 buf += n;
4081 size -= n;
4082 }
4083 EBRDDISABLE(brdp);
4084 restore_flags(flags);
4085
4086 return(count);
4087 }
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097 static int stli_memwrite(struct inode *ip, struct file *fp, const char *buf, int count)
4098 {
4099 unsigned long flags;
4100 void *memptr;
4101 stlibrd_t *brdp;
4102 char *chbuf;
4103 int brdnr, size, n;
4104
4105 #if DEBUG
4106 printk("stli_memwrite(ip=%x,fp=%x,buf=%x,count=%x)\n", (int) ip, (int) fp, (int) buf, count);
4107 #endif
4108
4109 brdnr = MINOR(ip->i_rdev);
4110 if (brdnr >= stli_nrbrds)
4111 return(-ENODEV);
4112 brdp = stli_brds[brdnr];
4113 if (brdp == (stlibrd_t *) NULL)
4114 return(-ENODEV);
4115 if (brdp->state == 0)
4116 return(-ENODEV);
4117 if (fp->f_pos >= brdp->memsize)
4118 return(0);
4119
4120 chbuf = (char *) buf;
4121 size = MIN(count, (brdp->memsize - fp->f_pos));
4122
4123 save_flags(flags);
4124 cli();
4125 EBRDENABLE(brdp);
4126 while (size > 0) {
4127 memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
4128 n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
4129 memcpy_fromfs(memptr, chbuf, n);
4130 fp->f_pos += n;
4131 chbuf += n;
4132 size -= n;
4133 }
4134 EBRDDISABLE(brdp);
4135 restore_flags(flags);
4136
4137 return(count);
4138 }
4139
4140
4141
4142
4143
4144
4145
4146 static int stli_getbrdstats(combrd_t *bp)
4147 {
4148 stlibrd_t *brdp;
4149 int i;
4150
4151 memcpy_fromfs(&stli_brdstats, bp, sizeof(combrd_t));
4152 if (stli_brdstats.brd >= STL_MAXBRDS)
4153 return(-ENODEV);
4154 brdp = stli_brds[stli_brdstats.brd];
4155 if (brdp == (stlibrd_t *) NULL)
4156 return(-ENODEV);
4157
4158 memset(&stli_brdstats, 0, sizeof(combrd_t));
4159 stli_brdstats.brd = brdp->brdnr;
4160 stli_brdstats.type = brdp->brdtype;
4161 stli_brdstats.hwid = 0;
4162 stli_brdstats.state = brdp->state;
4163 stli_brdstats.ioaddr = brdp->iobase;
4164 stli_brdstats.memaddr = brdp->memaddr;
4165 stli_brdstats.nrpanels = brdp->nrpanels;
4166 stli_brdstats.nrports = brdp->nrports;
4167 for (i = 0; (i < brdp->nrpanels); i++) {
4168 stli_brdstats.panels[i].panel = i;
4169 stli_brdstats.panels[i].hwid = brdp->panelids[i];
4170 stli_brdstats.panels[i].nrports = brdp->panels[i];
4171 }
4172
4173 memcpy_tofs(bp, &stli_brdstats, sizeof(combrd_t));
4174 return(0);
4175 }
4176
4177
4178
4179
4180
4181
4182
4183 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
4184 {
4185 stlibrd_t *brdp;
4186 int i;
4187
4188 if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
4189 return((stliport_t *) NULL);
4190 brdp = stli_brds[brdnr];
4191 if (brdp == (stlibrd_t *) NULL)
4192 return((stliport_t *) NULL);
4193 for (i = 0; (i < panelnr); i++)
4194 portnr += brdp->panels[i];
4195 if ((portnr < 0) || (portnr >= brdp->nrports))
4196 return((stliport_t *) NULL);
4197 return(brdp->ports[portnr]);
4198 }
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208 static int stli_getportstats(stliport_t *portp, comstats_t *cp)
4209 {
4210 unsigned long flags;
4211 stlibrd_t *brdp;
4212 int rc;
4213
4214 if (portp == (stliport_t *) NULL) {
4215 memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
4216 portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
4217 if (portp == (stliport_t *) NULL)
4218 return(-ENODEV);
4219 }
4220
4221 brdp = stli_brds[portp->brdnr];
4222 if (brdp == (stlibrd_t *) NULL)
4223 return(-ENODEV);
4224
4225 if (brdp->state & BST_STARTED) {
4226 if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
4227 return(rc);
4228 } else {
4229 memset(&stli_cdkstats, 0, sizeof(asystats_t));
4230 }
4231
4232 memset(&stli_comstats, 0, sizeof(comstats_t));
4233 stli_comstats.brd = portp->brdnr;
4234 stli_comstats.panel = portp->panelnr;
4235 stli_comstats.port = portp->portnr;
4236 stli_comstats.state = portp->state;
4237 stli_comstats.flags = portp->flags;
4238
4239 save_flags(flags);
4240 cli();
4241 if (portp->tty != (struct tty_struct *) NULL) {
4242 if (portp->tty->driver_data == portp) {
4243 stli_comstats.ttystate = portp->tty->flags;
4244 stli_comstats.rxbuffered = portp->tty->flip.count;
4245 if (portp->tty->termios != (struct termios *) NULL) {
4246 stli_comstats.cflags = portp->tty->termios->c_cflag;
4247 stli_comstats.iflags = portp->tty->termios->c_iflag;
4248 stli_comstats.oflags = portp->tty->termios->c_oflag;
4249 stli_comstats.lflags = portp->tty->termios->c_lflag;
4250 }
4251 }
4252 }
4253 restore_flags(flags);
4254
4255 stli_comstats.txtotal = stli_cdkstats.txchars;
4256 stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
4257 stli_comstats.txbuffered = stli_cdkstats.txringq;
4258 stli_comstats.rxbuffered += stli_cdkstats.rxringq;
4259 stli_comstats.rxoverrun = stli_cdkstats.overruns;
4260 stli_comstats.rxparity = stli_cdkstats.parity;
4261 stli_comstats.rxframing = stli_cdkstats.framing;
4262 stli_comstats.rxlost = stli_cdkstats.ringover;
4263 stli_comstats.rxbreaks = stli_cdkstats.rxbreaks;
4264 stli_comstats.txbreaks = stli_cdkstats.txbreaks;
4265 stli_comstats.txxon = stli_cdkstats.txstart;
4266 stli_comstats.txxoff = stli_cdkstats.txstop;
4267 stli_comstats.rxxon = stli_cdkstats.rxstart;
4268 stli_comstats.rxxoff = stli_cdkstats.rxstop;
4269 stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2;
4270 stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff;
4271 stli_comstats.modem = stli_cdkstats.dcdcnt;
4272 stli_comstats.hwid = stli_cdkstats.hwid;
4273 stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
4274
4275 memcpy_tofs(cp, &stli_comstats, sizeof(comstats_t));
4276 return(0);
4277 }
4278
4279
4280
4281
4282
4283
4284
4285 static int stli_clrportstats(stliport_t *portp, comstats_t *cp)
4286 {
4287 stlibrd_t *brdp;
4288 int rc;
4289
4290 if (portp == (stliport_t *) NULL) {
4291 memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
4292 portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
4293 if (portp == (stliport_t *) NULL)
4294 return(-ENODEV);
4295 }
4296
4297 brdp = stli_brds[portp->brdnr];
4298 if (brdp == (stlibrd_t *) NULL)
4299 return(-ENODEV);
4300
4301 if (brdp->state & BST_STARTED) {
4302 if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, 0, 0, 0)) < 0)
4303 return(rc);
4304 }
4305
4306 memset(&stli_comstats, 0, sizeof(comstats_t));
4307 stli_comstats.brd = portp->brdnr;
4308 stli_comstats.panel = portp->panelnr;
4309 stli_comstats.port = portp->portnr;
4310
4311 memcpy_tofs(cp, &stli_comstats, sizeof(comstats_t));
4312 return(0);
4313 }
4314
4315
4316
4317
4318
4319
4320
4321 static int stli_getportstruct(unsigned long arg)
4322 {
4323 stliport_t *portp;
4324
4325 memcpy_fromfs(&stli_dummyport, (void *) arg, sizeof(stliport_t));
4326 portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr,
4327 stli_dummyport.portnr);
4328 if (portp == (stliport_t *) NULL)
4329 return(-ENODEV);
4330 memcpy_tofs((void *) arg, portp, sizeof(stliport_t));
4331 return(0);
4332 }
4333
4334
4335
4336
4337
4338
4339
4340 static int stli_getbrdstruct(unsigned long arg)
4341 {
4342 stlibrd_t *brdp;
4343
4344 memcpy_fromfs(&stli_dummybrd, (void *) arg, sizeof(stlibrd_t));
4345 if ((stli_dummybrd.brdnr < 0) || (stli_dummybrd.brdnr >= STL_MAXBRDS))
4346 return(-ENODEV);
4347 brdp = stli_brds[stli_dummybrd.brdnr];
4348 if (brdp == (stlibrd_t *) NULL)
4349 return(-ENODEV);
4350 memcpy_tofs((void *) arg, brdp, sizeof(stlibrd_t));
4351 return(0);
4352 }
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362 static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
4363 {
4364 stlibrd_t *brdp;
4365 int brdnr, rc, done;
4366
4367 #if DEBUG
4368 printk("stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip, (int) fp, cmd, (int) arg);
4369 #endif
4370
4371
4372
4373
4374 done = 0;
4375 rc = 0;
4376
4377 switch (cmd) {
4378 case COM_GETPORTSTATS:
4379 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
4380 rc = stli_getportstats((stliport_t *) NULL, (comstats_t *) arg);
4381 done++;
4382 break;
4383 case COM_CLRPORTSTATS:
4384 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
4385 rc = stli_clrportstats((stliport_t *) NULL, (comstats_t *) arg);
4386 done++;
4387 break;
4388 case COM_GETBRDSTATS:
4389 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0)
4390 rc = stli_getbrdstats((combrd_t *) arg);
4391 done++;
4392 break;
4393 case COM_READPORT:
4394 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stliport_t))) == 0)
4395 rc = stli_getportstruct(arg);
4396 done++;
4397 break;
4398 case COM_READBOARD:
4399 if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlibrd_t))) == 0)
4400 rc = stli_getbrdstruct(arg);
4401 done++;
4402 break;
4403 default:
4404 break;
4405 }
4406
4407 if (done)
4408 return(rc);
4409
4410
4411
4412
4413
4414 brdnr = MINOR(ip->i_rdev);
4415 if (brdnr >= STL_MAXBRDS)
4416 return(-ENODEV);
4417 brdp = stli_brds[brdnr];
4418 if (brdp == (stlibrd_t *) NULL)
4419 return(-ENODEV);
4420 if (brdp->state == 0)
4421 return(-ENODEV);
4422
4423 switch (cmd) {
4424 case STL_BINTR:
4425 EBRDINTR(brdp);
4426 break;
4427 case STL_BSTART:
4428 rc = stli_startbrd(brdp);
4429 break;
4430 case STL_BSTOP:
4431 brdp->state &= ~BST_STARTED;
4432 break;
4433 case STL_BRESET:
4434 brdp->state &= ~BST_STARTED;
4435 EBRDRESET(brdp);
4436 if (stli_shared == 0) {
4437 if (brdp->reenable != NULL)
4438 (* brdp->reenable)(brdp);
4439 }
4440 break;
4441 default:
4442 rc = -ENOIOCTLCMD;
4443 break;
4444 }
4445
4446 return(rc);
4447 }
4448
4449
4450
4451 int stli_init()
4452 {
4453 printk(KERN_INFO "%s: version %s\n", stli_drvname, stli_drvversion);
4454
4455 stli_initbrds();
4456
4457
4458
4459
4460 stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
4461 if (stli_tmpwritebuf == (char *) NULL)
4462 printk("STALLION: failed to allocate memory (size=%d)\n", STLI_TXBUFSIZE);
4463 stli_txcookbuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
4464 if (stli_txcookbuf == (char *) NULL)
4465 printk("STALLION: failed to allocate memory (size=%d)\n", STLI_TXBUFSIZE);
4466
4467
4468
4469
4470
4471 if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem))
4472 printk("STALLION: failed to register serial memory device\n");
4473
4474
4475
4476
4477
4478 memset(&stli_serial, 0, sizeof(struct tty_driver));
4479 stli_serial.magic = TTY_DRIVER_MAGIC;
4480 stli_serial.name = stli_serialname;
4481 stli_serial.major = STL_SERIALMAJOR;
4482 stli_serial.minor_start = 0;
4483 stli_serial.num = STL_MAXBRDS * STL_MAXPORTS;
4484 stli_serial.type = TTY_DRIVER_TYPE_SERIAL;
4485 stli_serial.subtype = STL_DRVTYPSERIAL;
4486 stli_serial.init_termios = stli_deftermios;
4487 stli_serial.flags = TTY_DRIVER_REAL_RAW;
4488 stli_serial.refcount = &stli_refcount;
4489 stli_serial.table = stli_ttys;
4490 stli_serial.termios = stli_termios;
4491 stli_serial.termios_locked = stli_termioslocked;
4492
4493 stli_serial.open = stli_open;
4494 stli_serial.close = stli_close;
4495 stli_serial.write = stli_write;
4496 stli_serial.put_char = stli_putchar;
4497 stli_serial.flush_chars = stli_flushchars;
4498 stli_serial.write_room = stli_writeroom;
4499 stli_serial.chars_in_buffer = stli_charsinbuffer;
4500 stli_serial.ioctl = stli_ioctl;
4501 stli_serial.set_termios = stli_settermios;
4502 stli_serial.throttle = stli_throttle;
4503 stli_serial.unthrottle = stli_unthrottle;
4504 stli_serial.stop = stli_stop;
4505 stli_serial.start = stli_start;
4506 stli_serial.hangup = stli_hangup;
4507 stli_serial.flush_buffer = stli_flushbuffer;
4508
4509 stli_callout = stli_serial;
4510 stli_callout.name = stli_calloutname;
4511 stli_callout.major = STL_CALLOUTMAJOR;
4512 stli_callout.subtype = STL_DRVTYPCALLOUT;
4513
4514 if (tty_register_driver(&stli_serial))
4515 printk("STALLION: failed to register serial driver\n");
4516 if (tty_register_driver(&stli_callout))
4517 printk("STALLION: failed to register callout driver\n");
4518
4519 return(0);
4520 }
4521
4522