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