This source file includes following definitions.
- zstty_match
- zstty_attach
- zstty
- zsopen
- zsclose
- zsread
- zswrite
- zsioctl
- zsstart
- zsstop
- zsparam
- zs_modem
- zshwiflow
- zs_hwiflow
- zstty_rxint
- zstty_txint
- zstty_stint
- zsoverrun
- zstty_softint
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/proc.h>
68 #include <sys/device.h>
69 #include <sys/conf.h>
70 #include <sys/file.h>
71 #include <sys/ioctl.h>
72 #include <sys/malloc.h>
73 #include <sys/tty.h>
74 #include <sys/time.h>
75 #include <sys/kernel.h>
76 #include <sys/syslog.h>
77
78 #include <dev/ic/z8530reg.h>
79 #include <machine/z8530var.h>
80
81 #ifdef KGDB
82 extern int zs_check_kgdb();
83 #endif
84
85
86
87
88
89 #ifndef ZSTTY_DEF_CFLAG
90 #define ZSTTY_DEF_CFLAG TTYDEF_CFLAG
91 #endif
92
93
94
95
96
97
98 #ifndef ZSTTY_RING_SIZE
99 #define ZSTTY_RING_SIZE 2048
100 #endif
101
102
103
104
105
106 int zstty_rbuf_size = ZSTTY_RING_SIZE;
107
108
109 int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE - (ZSTTY_RING_SIZE >> 2));
110
111 struct zstty_softc {
112 struct device zst_dev;
113 struct tty *zst_tty;
114 struct zs_chanstate *zst_cs;
115
116 int zst_hwflags;
117 int zst_swflags;
118
119
120
121
122
123 long zst_rotime;
124 long zst_fotime;
125
126
127
128
129 int zst_rbget;
130 volatile int zst_rbput;
131 int zst_ringmask;
132 int zst_rbhiwat;
133
134 u_short *zst_rbuf;
135
136
137
138
139
140
141
142 int zst_tbc;
143 caddr_t zst_tba;
144 int zst_heldtbc;
145
146
147 volatile char zst_rx_blocked;
148 volatile char zst_rx_overrun;
149 volatile char zst_tx_busy;
150 volatile char zst_tx_done;
151 volatile char zst_tx_stopped;
152 volatile char zst_st_check;
153 char pad[2];
154 };
155
156
157
158 static int zstty_match(struct device *, void *, void *);
159 static void zstty_attach(struct device *, struct device *, void *);
160
161 struct cfattach zstty_ca = {
162 sizeof(struct zstty_softc), zstty_match, zstty_attach
163 };
164
165 struct cfdriver zstty_cd = {
166 NULL, "zstty", DV_TTY
167 };
168
169 struct zsops zsops_tty;
170
171
172 cdev_decl(zs);
173
174 static void zsstart(struct tty *);
175 static int zsparam(struct tty *, struct termios *);
176 static void zs_modem(struct zstty_softc *zst, int onoff);
177 static int zshwiflow(struct tty *, int);
178 static void zs_hwiflow(struct zstty_softc *, int);
179 static void zstty_rxint(register struct zs_chanstate *);
180 static void zstty_txint(register struct zs_chanstate *);
181 static void zstty_stint(register struct zs_chanstate *);
182 static void zstty_softint(struct zs_chanstate *);
183 static void zsoverrun(struct zstty_softc *, long *, char *);
184
185
186
187 int
188 zstty_match(parent, match, aux)
189 struct device *parent;
190 void *match, *aux;
191 {
192 struct cfdata *cf = match;
193 struct zsc_attach_args *args = aux;
194
195
196 if (cf->cf_loc[0] == args->channel)
197 return 2;
198
199
200 if (cf->cf_loc[0] == -1)
201 return 1;
202
203 return 0;
204 }
205
206 void
207 zstty_attach(parent, self, aux)
208 struct device *parent, *self;
209 void *aux;
210
211 {
212 struct zsc_softc *zsc = (void *) parent;
213 struct zstty_softc *zst = (void *) self;
214 struct zsc_attach_args *args = aux;
215 struct zs_chanstate *cs;
216 struct cfdata *cf;
217 struct tty *tp;
218 int channel, tty_unit;
219 dev_t dev;
220
221 cf = zst->zst_dev.dv_cfdata;
222 tty_unit = zst->zst_dev.dv_unit;
223 channel = args->channel;
224 cs = &zsc->zsc_cs[channel];
225 cs->cs_private = zst;
226 cs->cs_ops = &zsops_tty;
227
228 zst->zst_cs = cs;
229 zst->zst_swflags = cf->cf_flags;
230 zst->zst_hwflags = args->hwflags;
231 dev = makedev(ZSTTY_MAJOR, tty_unit);
232
233 if (zst->zst_swflags)
234 printf(" flags 0x%x", zst->zst_swflags);
235
236 if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE)
237 printf(" (console)");
238 else {
239 #ifdef KGDB
240
241
242
243
244
245
246 if (zs_check_kgdb(cs, dev)) {
247
248
249
250
251 return;
252 }
253 #endif
254 }
255 printf("\n");
256
257 tp = ttymalloc();
258 tp->t_dev = dev;
259 tp->t_oproc = zsstart;
260 tp->t_param = zsparam;
261 tp->t_hwiflow = zshwiflow;
262
263 zst->zst_tty = tp;
264 zst->zst_rbhiwat = zstty_rbuf_size;
265 zst->zst_ringmask = zstty_rbuf_size - 1;
266 zst->zst_rbuf = malloc(zstty_rbuf_size * sizeof(zst->zst_rbuf[0]),
267 M_DEVBUF, M_WAITOK);
268
269
270
271
272 if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) {
273
274 zst->zst_swflags |= TIOCFLAG_SOFTCAR;
275
276 cs->cs_defspeed = zs_getspeed(cs);
277 tp->t_ispeed = cs->cs_defspeed;
278 tp->t_ospeed = cs->cs_defspeed;
279 tp->t_cflag = ZSTTY_DEF_CFLAG;
280 (void) zsparam(tp, &tp->t_termios);
281 } else {
282
283 int reset, s;
284 reset = (channel == 0) ?
285 ZSWR9_A_RESET : ZSWR9_B_RESET;
286 s = splzs();
287 zs_write_reg(cs, 9, reset);
288 splx(s);
289 }
290
291
292
293
294
295
296
297 zs_modem(zst, (zst->zst_swflags & TIOCFLAG_SOFTCAR) ? 1 : 0);
298 }
299
300
301
302
303
304 struct tty *
305 zstty(dev)
306 dev_t dev;
307 {
308 struct zstty_softc *zst;
309 int unit = minor(dev);
310
311 #ifdef DIAGNOSTIC
312 if (unit >= zstty_cd.cd_ndevs)
313 panic("zstty");
314 #endif
315 zst = zstty_cd.cd_devs[unit];
316 return (zst->zst_tty);
317 }
318
319
320
321
322
323 int
324 zsopen(dev, flags, mode, p)
325 dev_t dev;
326 int flags;
327 int mode;
328 struct proc *p;
329 {
330 register struct tty *tp;
331 register struct zs_chanstate *cs;
332 struct zstty_softc *zst;
333 int error, s, unit;
334
335 unit = minor(dev);
336 if (unit >= zstty_cd.cd_ndevs)
337 return (ENXIO);
338 zst = zstty_cd.cd_devs[unit];
339 if (zst == NULL)
340 return (ENXIO);
341 tp = zst->zst_tty;
342 cs = zst->zst_cs;
343
344
345 if (tp == NULL)
346 return (EBUSY);
347
348
349 if (((tp->t_state & (TS_ISOPEN | TS_XCLUDE))
350 == (TS_ISOPEN | TS_XCLUDE))
351 && (p->p_ucred->cr_uid != 0) )
352 {
353 return (EBUSY);
354 }
355
356 s = spltty();
357
358 if ((tp->t_state & TS_ISOPEN) == 0) {
359
360 ttychars(tp);
361 tp->t_iflag = TTYDEF_IFLAG;
362 tp->t_oflag = TTYDEF_OFLAG;
363 tp->t_cflag = ZSTTY_DEF_CFLAG;
364 if (zst->zst_swflags & TIOCFLAG_CLOCAL)
365 tp->t_cflag |= CLOCAL;
366 if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
367 tp->t_cflag |= CRTSCTS;
368 if (zst->zst_swflags & TIOCFLAG_MDMBUF)
369 tp->t_cflag |= MDMBUF;
370 tp->t_lflag = TTYDEF_LFLAG;
371 tp->t_ispeed = tp->t_ospeed = cs->cs_defspeed;
372 (void) zsparam(tp, &tp->t_termios);
373 ttsetwater(tp);
374
375 zst->zst_rbget = zst->zst_rbput;
376 zs_iflush(cs);
377
378 zs_modem(zst, 1);
379 if (zst->zst_swflags & TIOCFLAG_SOFTCAR) {
380 tp->t_state |= TS_CARR_ON;
381 }
382 }
383 error = 0;
384
385
386 for (;;) {
387
388
389 cs->cs_rr0 = zs_read_csr(cs);
390 if (cs->cs_rr0 & ZSRR0_DCD) {
391 tp->t_state |= TS_CARR_ON;
392 break;
393 }
394
395 if ((tp->t_state & TS_CARR_ON) ||
396 (tp->t_cflag & CLOCAL) ||
397 (flags & O_NONBLOCK) )
398 {
399 break;
400 }
401
402 tp->t_state |= TS_WOPEN;
403 error = ttysleep(tp, (caddr_t)&tp->t_rawq,
404 TTIPRI | PCATCH, ttopen, 0);
405 if (error) {
406 if ((tp->t_state & TS_ISOPEN) == 0) {
407
408 zs_modem(zst, 0);
409 tp->t_state &= ~TS_WOPEN;
410 ttwakeup(tp);
411 }
412 break;
413 }
414 }
415
416 splx(s);
417
418 if (error == 0)
419 error = linesw[tp->t_line].l_open(dev, tp);
420
421 return (error);
422 }
423
424
425
426
427 int
428 zsclose(dev, flags, mode, p)
429 dev_t dev;
430 int flags;
431 int mode;
432 struct proc *p;
433 {
434 struct zstty_softc *zst;
435 register struct zs_chanstate *cs;
436 register struct tty *tp;
437 int hup;
438
439 zst = zstty_cd.cd_devs[minor(dev)];
440 cs = zst->zst_cs;
441 tp = zst->zst_tty;
442
443
444 if ((tp->t_state & TS_ISOPEN) == 0)
445 return 0;
446
447 (*linesw[tp->t_line].l_close)(tp, flags);
448 hup = tp->t_cflag & HUPCL;
449 if (zst->zst_swflags & TIOCFLAG_SOFTCAR)
450 hup = 0;
451 if (hup) {
452 zs_modem(zst, 0);
453
454 (void) tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
455 }
456 if (cs->cs_creg[5] & ZSWR5_BREAK) {
457 zs_break(cs, 0);
458 }
459
460
461 ttyclose(tp);
462 return (0);
463 }
464
465
466
467
468 int
469 zsread(dev, uio, flags)
470 dev_t dev;
471 struct uio *uio;
472 int flags;
473 {
474 register struct zstty_softc *zst;
475 register struct tty *tp;
476
477 zst = zstty_cd.cd_devs[minor(dev)];
478 tp = zst->zst_tty;
479 return (linesw[tp->t_line].l_read(tp, uio, flags));
480 }
481
482 int
483 zswrite(dev, uio, flags)
484 dev_t dev;
485 struct uio *uio;
486 int flags;
487 {
488 register struct zstty_softc *zst;
489 register struct tty *tp;
490
491 zst = zstty_cd.cd_devs[minor(dev)];
492 tp = zst->zst_tty;
493 return (linesw[tp->t_line].l_write(tp, uio, flags));
494 }
495
496 #define TIOCFLAG_ALL (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | \
497 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF )
498
499 int
500 zsioctl(dev, cmd, data, flag, p)
501 dev_t dev;
502 u_long cmd;
503 caddr_t data;
504 int flag;
505 struct proc *p;
506 {
507 register struct zstty_softc *zst;
508 register struct zs_chanstate *cs;
509 register struct tty *tp;
510 register int error, tmp;
511
512 zst = zstty_cd.cd_devs[minor(dev)];
513 cs = zst->zst_cs;
514 tp = zst->zst_tty;
515
516 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
517 if (error >= 0)
518 return (error);
519 error = ttioctl(tp, cmd, data, flag, p);
520 if (error >= 0)
521 return (error);
522
523 switch (cmd) {
524
525 case TIOCSBRK:
526 zs_break(cs, 1);
527 break;
528
529 case TIOCCBRK:
530 zs_break(cs, 0);
531 break;
532
533 case TIOCGFLAGS:
534 *(int *)data = zst->zst_swflags;
535 break;
536
537 case TIOCSFLAGS:
538 error = suser(p, 0);
539 if (error != 0)
540 return (EPERM);
541 tmp = *(int *)data;
542
543 if (tmp & ~TIOCFLAG_ALL)
544 return(EINVAL);
545
546 if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE)
547 tmp |= TIOCFLAG_SOFTCAR;
548
549 zst->zst_swflags = tmp;
550 break;
551
552 case TIOCSDTR:
553 zs_modem(zst, 1);
554 break;
555
556 case TIOCCDTR:
557 zs_modem(zst, 0);
558 break;
559
560 case TIOCMSET:
561 case TIOCMBIS:
562 case TIOCMBIC:
563 case TIOCMGET:
564 default:
565 return (ENOTTY);
566 }
567 return (0);
568 }
569
570
571
572
573 static void
574 zsstart(tp)
575 register struct tty *tp;
576 {
577 register struct zstty_softc *zst;
578 register struct zs_chanstate *cs;
579 register int s, nch;
580
581 zst = zstty_cd.cd_devs[minor(tp->t_dev)];
582 cs = zst->zst_cs;
583
584 s = spltty();
585
586
587
588
589 if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
590 goto out;
591
592
593
594
595 if (tp->t_cflag & CRTSCTS)
596 if (zst->zst_tx_stopped)
597 goto out;
598
599
600
601
602
603 if (tp->t_outq.c_cc <= tp->t_lowat) {
604 if (tp->t_state & TS_ASLEEP) {
605 tp->t_state &= ~TS_ASLEEP;
606 wakeup((caddr_t)&tp->t_outq);
607 }
608 selwakeup(&tp->t_wsel);
609 }
610
611 nch = ndqb(&tp->t_outq, 0);
612 (void) splzs();
613
614 if (nch) {
615 register char *p = tp->t_outq.c_cf;
616
617
618 tp->t_state |= TS_BUSY;
619 zst->zst_tx_busy = 1;
620 cs->cs_preg[1] |= ZSWR1_TIE;
621 cs->cs_creg[1] = cs->cs_preg[1];
622 zs_write_reg(cs, 1, cs->cs_creg[1]);
623 zs_write_data(cs, *p);
624 zst->zst_tba = p + 1;
625 zst->zst_tbc = nch - 1;
626 } else {
627
628
629
630
631 cs->cs_preg[1] &= ~ZSWR1_TIE;
632 cs->cs_creg[1] = cs->cs_preg[1];
633 zs_write_reg(cs, 1, cs->cs_creg[1]);
634 }
635 out:
636 splx(s);
637 }
638
639
640
641
642 int
643 zsstop(tp, flag)
644 struct tty *tp;
645 int flag;
646 {
647 register struct zstty_softc *zst;
648 register struct zs_chanstate *cs;
649 register int s;
650
651 zst = zstty_cd.cd_devs[minor(tp->t_dev)];
652 cs = zst->zst_cs;
653
654 s = splzs();
655 if (tp->t_state & TS_BUSY) {
656
657
658
659
660
661 zst->zst_tbc = 0;
662 zst->zst_heldtbc = 0;
663 if ((tp->t_state & TS_TTSTOP) == 0)
664 tp->t_state |= TS_FLUSH;
665 }
666 splx(s);
667 return (0);
668 }
669
670
671
672
673
674
675
676 static int
677 zsparam(tp, t)
678 register struct tty *tp;
679 register struct termios *t;
680 {
681 register struct zstty_softc *zst;
682 register struct zs_chanstate *cs;
683 register int s, bps, cflag, tconst;
684 u_char tmp3, tmp4, tmp5;
685
686 zst = zstty_cd.cd_devs[minor(tp->t_dev)];
687 cs = zst->zst_cs;
688
689
690 bps = t->c_ospeed;
691 if (bps < 0 || (t->c_ispeed && t->c_ispeed != bps))
692 return (EINVAL);
693 if (bps == 0) {
694
695 zs_modem(zst, 0);
696 return (0);
697 }
698 tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
699 if (tconst < 0)
700 return (EINVAL);
701
702
703 bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);
704 if (bps != t->c_ospeed)
705 return (EINVAL);
706 tp->t_ispeed = tp->t_ospeed = bps;
707
708 cflag = t->c_cflag;
709 tp->t_cflag = cflag;
710
711
712
713
714
715 s = splzs();
716
717
718
719
720
721
722
723 cs->cs_preg[12] = tconst;
724 cs->cs_preg[13] = tconst >> 8;
725
726 switch (cflag & CSIZE) {
727 case CS5:
728 tmp3 = ZSWR3_RX_5;
729 tmp5 = ZSWR5_TX_5;
730 break;
731 case CS6:
732 tmp3 = ZSWR3_RX_6;
733 tmp5 = ZSWR5_TX_6;
734 break;
735 case CS7:
736 tmp3 = ZSWR3_RX_7;
737 tmp5 = ZSWR5_TX_7;
738 break;
739 case CS8:
740 default:
741 tmp3 = ZSWR3_RX_8;
742 tmp5 = ZSWR5_TX_8;
743 break;
744 }
745
746 cs->cs_preg[3] = tmp3 | ZSWR3_RX_ENABLE;
747 cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
748
749 tmp4 = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
750 if ((cflag & PARODD) == 0)
751 tmp4 |= ZSWR4_EVENP;
752 if (cflag & PARENB)
753 tmp4 |= ZSWR4_PARENB;
754 cs->cs_preg[4] = tmp4;
755
756
757
758
759
760
761
762 if (cflag & CRTSCTS) {
763 zst->zst_rbhiwat = zstty_rbuf_hiwat;
764 cs->cs_preg[15] |= ZSWR15_CTS_IE;
765 } else {
766 zst->zst_rbhiwat = zstty_rbuf_size;
767 cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
768 }
769
770
771
772
773
774 if (cs->cs_heldchange == 0) {
775 if (zst->zst_tx_busy) {
776 zst->zst_heldtbc = zst->zst_tbc;
777 zst->zst_tbc = 0;
778 cs->cs_heldchange = 0xFF;
779 } else {
780 zs_loadchannelregs(cs);
781 }
782 }
783 splx(s);
784 return (0);
785 }
786
787
788
789
790
791 static void
792 zs_modem(zst, onoff)
793 struct zstty_softc *zst;
794 int onoff;
795 {
796 struct zs_chanstate *cs;
797 struct tty *tp;
798 int s, bis, and;
799
800 cs = zst->zst_cs;
801 tp = zst->zst_tty;
802
803 if (onoff) {
804 bis = ZSWR5_DTR | ZSWR5_RTS;
805 and = ~0;
806 } else {
807 bis = 0;
808 and = ~(ZSWR5_DTR | ZSWR5_RTS);
809 }
810 s = splzs();
811 cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and;
812 if (cs->cs_heldchange == 0) {
813 if (zst->zst_tx_busy) {
814 zst->zst_heldtbc = zst->zst_tbc;
815 zst->zst_tbc = 0;
816 cs->cs_heldchange = (1<<5);
817 } else {
818 cs->cs_creg[5] = cs->cs_preg[5];
819 zs_write_reg(cs, 5, cs->cs_creg[5]);
820 }
821 }
822 splx(s);
823 }
824
825
826
827
828
829
830
831 int
832 zshwiflow(tp, stop)
833 struct tty *tp;
834 int stop;
835 {
836 register struct zstty_softc *zst;
837 int s;
838
839 zst = zstty_cd.cd_devs[minor(tp->t_dev)];
840
841 s = splzs();
842 if (stop) {
843
844
845
846
847 if (zst->zst_rx_blocked)
848 goto out;
849 zst->zst_rx_blocked = 1;
850 } else {
851
852
853
854
855 zst->zst_rx_blocked = 0;
856 }
857 zs_hwiflow(zst, stop);
858 out:
859 splx(s);
860 return 1;
861 }
862
863
864
865
866
867 static void
868 zs_hwiflow(zst, stop)
869 register struct zstty_softc *zst;
870 int stop;
871 {
872 register struct zs_chanstate *cs;
873 register struct tty *tp;
874 register int bis, and;
875
876 cs = zst->zst_cs;
877 tp = zst->zst_tty;
878
879 if (stop) {
880
881 bis = 0;
882 and = ~ZSWR5_RTS;
883 } else {
884
885 bis = ZSWR5_RTS;
886 and = ~0;
887 }
888
889 cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and;
890 if (cs->cs_heldchange == 0) {
891 if (zst->zst_tx_busy) {
892 zst->zst_heldtbc = zst->zst_tbc;
893 zst->zst_tbc = 0;
894 cs->cs_heldchange = (1<<5);
895 } else {
896 cs->cs_creg[5] = cs->cs_preg[5];
897 zs_write_reg(cs, 5, cs->cs_creg[5]);
898 }
899 }
900 }
901
902
903
904
905
906
907
908
909
910
911
912 static void
913 zstty_rxint(cs)
914 register struct zs_chanstate *cs;
915 {
916 register struct zstty_softc *zst;
917 register int cc, put, put_next, ringmask;
918 register u_char c, rr0, rr1;
919 register u_short ch_rr1;
920
921 zst = cs->cs_private;
922 put = zst->zst_rbput;
923 ringmask = zst->zst_ringmask;
924
925 nextchar:
926
927
928
929
930
931 rr1 = zs_read_reg(cs, 1);
932 c = zs_read_data(cs);
933 ch_rr1 = (c << 8) | rr1;
934
935 if (ch_rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
936
937 zs_write_csr(cs, ZSWR0_RESET_ERRORS);
938 }
939
940
941
942 zst->zst_rbuf[put] = ch_rr1;
943 put_next = (put + 1) & ringmask;
944
945
946 if (put_next == zst->zst_rbget) {
947 zst->zst_rx_overrun = 1;
948 } else {
949
950 put = put_next;
951 }
952
953
954 rr0 = zs_read_csr(cs);
955 if (rr0 & ZSRR0_RX_READY)
956 goto nextchar;
957
958
959 zst->zst_rbput = put;
960
961
962
963
964 cc = put - zst->zst_rbget;
965 if (cc < 0)
966 cc += zstty_rbuf_size;
967 if ((cc > zst->zst_rbhiwat) && (zst->zst_rx_blocked == 0)) {
968 zst->zst_rx_blocked = 1;
969 zs_hwiflow(zst, 1);
970 }
971
972
973 cs->cs_softreq = 1;
974 }
975
976
977
978
979 static void
980 zstty_txint(cs)
981 register struct zs_chanstate *cs;
982 {
983 register struct zstty_softc *zst;
984 register int count;
985
986 zst = cs->cs_private;
987
988
989
990
991
992
993
994
995
996 if (cs->cs_heldchange) {
997 if (cs->cs_heldchange == (1<<5)) {
998
999 cs->cs_creg[5] = cs->cs_preg[5];
1000 zs_write_reg(cs, 5, cs->cs_creg[5]);
1001 } else
1002 zs_loadchannelregs(cs);
1003 cs->cs_heldchange = 0;
1004 count = zst->zst_heldtbc;
1005 } else
1006 count = zst->zst_tbc;
1007
1008
1009
1010
1011
1012 if (count > 0) {
1013
1014 zst->zst_tbc = --count;
1015 zs_write_data(cs, *zst->zst_tba);
1016 zst->zst_tba++;
1017 return;
1018 }
1019
1020 zs_write_csr(cs, ZSWR0_RESET_TXINT);
1021
1022
1023 zst->zst_tx_busy = 0;
1024 zst->zst_tx_done = 1;
1025 cs->cs_softreq = 1;
1026 }
1027
1028
1029
1030
1031 static void
1032 zstty_stint(cs)
1033 register struct zs_chanstate *cs;
1034 {
1035 register struct zstty_softc *zst;
1036 register struct tty *tp;
1037 register u_char rr0;
1038
1039 zst = cs->cs_private;
1040 tp = zst->zst_tty;
1041
1042 rr0 = zs_read_csr(cs);
1043 zs_write_csr(cs, ZSWR0_RESET_STATUS);
1044
1045
1046
1047
1048
1049 if ((rr0 & ZSRR0_BREAK) &&
1050 (zst->zst_hwflags & ZS_HWFLAG_CONSOLE))
1051 {
1052 zs_abort();
1053 return;
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063 if (((rr0 & ZSRR0_CTS) == 0) && (tp->t_cflag & CRTSCTS)) {
1064 zst->zst_tbc = 0;
1065 zst->zst_heldtbc = 0;
1066 zst->zst_tx_stopped = 1;
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076 cs->cs_rr0_delta |= (cs->cs_rr0 ^ rr0);
1077
1078 ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS,
1079 cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD);
1080
1081 cs->cs_rr0 = rr0;
1082 zst->zst_st_check = 1;
1083
1084
1085 cs->cs_softreq = 1;
1086 }
1087
1088
1089
1090
1091 static void
1092 zsoverrun(zst, ptime, what)
1093 struct zstty_softc *zst;
1094 long *ptime;
1095 char *what;
1096 {
1097
1098 if (*ptime != time_second) {
1099 *ptime = time_second;
1100 log(LOG_WARNING, "%s: %s overrun\n",
1101 zst->zst_dev.dv_xname, what);
1102 }
1103 }
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117 static void
1118 zstty_softint(cs)
1119 struct zs_chanstate *cs;
1120 {
1121 register struct zstty_softc *zst;
1122 register struct linesw *line;
1123 register struct tty *tp;
1124 register int get, c, s;
1125 int ringmask, overrun;
1126 register u_short ring_data;
1127 register u_char rr0, delta;
1128
1129 zst = cs->cs_private;
1130 tp = zst->zst_tty;
1131 line = &linesw[tp->t_line];
1132 ringmask = zst->zst_ringmask;
1133 overrun = 0;
1134
1135
1136
1137
1138 s = spltty();
1139
1140 if (zst->zst_rx_overrun) {
1141 zst->zst_rx_overrun = 0;
1142 zsoverrun(zst, &zst->zst_rotime, "ring");
1143 }
1144
1145
1146
1147
1148 get = zst->zst_rbget;
1149 while (get != zst->zst_rbput) {
1150 ring_data = zst->zst_rbuf[get];
1151 get = (get + 1) & ringmask;
1152
1153 if (ring_data & ZSRR1_DO)
1154 overrun++;
1155
1156 c = (ring_data >> 8) & 0xff;
1157 if (ring_data & ZSRR1_FE)
1158 c |= TTY_FE;
1159 if (ring_data & ZSRR1_PE)
1160 c |= TTY_PE;
1161
1162 line->l_rint(c, tp);
1163 }
1164 zst->zst_rbget = get;
1165
1166
1167
1168
1169
1170
1171 if (overrun) {
1172 zsoverrun(zst, &zst->zst_fotime, "fifo");
1173 }
1174
1175
1176
1177
1178
1179
1180
1181 if (zst->zst_rx_blocked && ((tp->t_state & TS_TBLOCK) == 0)) {
1182 (void) splzs();
1183 zst->zst_rx_blocked = 0;
1184 zs_hwiflow(zst, 0);
1185 (void) spltty();
1186 }
1187
1188
1189
1190
1191
1192
1193 if (zst->zst_st_check) {
1194 zst->zst_st_check = 0;
1195
1196 rr0 = cs->cs_rr0;
1197 delta = cs->cs_rr0_delta;
1198 cs->cs_rr0_delta = 0;
1199 if (delta & ZSRR0_DCD) {
1200 c = ((rr0 & ZSRR0_DCD) != 0);
1201 if (line->l_modem(tp, c) == 0)
1202 zs_modem(zst, c);
1203 }
1204 if ((delta & ZSRR0_CTS) && (tp->t_cflag & CRTSCTS)) {
1205
1206
1207
1208
1209 if (rr0 & ZSRR0_CTS) {
1210 zst->zst_tx_stopped = 0;
1211 tp->t_state &= ~TS_TTSTOP;
1212 (*line->l_start)(tp);
1213 }
1214 }
1215 }
1216
1217 if (zst->zst_tx_done) {
1218 zst->zst_tx_done = 0;
1219 tp->t_state &= ~TS_BUSY;
1220 if (tp->t_state & TS_FLUSH)
1221 tp->t_state &= ~TS_FLUSH;
1222 else
1223 ndflush(&tp->t_outq, zst->zst_tba -
1224 (caddr_t) tp->t_outq.c_cf);
1225 line->l_start(tp);
1226 }
1227
1228 splx(s);
1229 }
1230
1231 struct zsops zsops_tty = {
1232 zstty_rxint,
1233 zstty_stint,
1234 zstty_txint,
1235 zstty_softint,
1236 };
1237