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