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