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