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