|
|
1.1 root 1: /*
2: * ZS driver
3: */
4: #include "zs.h"
5: #define TRC(c)
6:
7: #include "../h/param.h"
8: #include "../h/stream.h"
9: #include "../h/ttyio.h"
10: #include "../h/ttyld.h"
11: #include "../machine/pte.h"
12: #include "../h/map.h"
13: #include "../h/buf.h"
14: #include "../h/systm.h"
15: #include "../h/conf.h"
16:
17: #include "../sundev/mbvar.h"
18: #include "../sundev/zsreg.h"
19: #include "../sundev/zscom.h"
20: #include "../sundev/zsvar.h"
21:
22: #define ZSWR1_INIT (ZSWR1_SIE|ZSWR1_TIE|ZSWR1_RIE)
23: #define ZS_ON (ZSWR5_DTR|ZSWR5_RTS)
24: #define ZS_OFF 0
25:
26: #define NZSLINE (NZS*2)
27: #define SSPEED B9600 /* std speed = 9600 baud */
28:
29: #define EXISTS 01
30: #define ISOPEN 02
31: #define WOPEN 04
32: #define TIMEOUT 010
33: #define CARR_ON 020
34: #define ZSSTOP 040
35: #define HPCL 0100
36: #define BRKING 0200
37: #define DIALOUT 0400 /* set when used as dialout with smart modems */
38:
39: #define ZSPRI 30
40:
41: /*
42: * Modem control commands.
43: */
44: #define DMSET 0
45: #define DMBIS 1
46: #define DMBIC 2
47: #define DMGET 3
48:
49: /*
50: * One structure per line.
51: * Includes communication between H/W level 6 interrupts
52: * and software interrupts
53: */
54: #define ZSIBUFSZ 256
55: struct zsaline {
56: /* from v9 dz.c */
57: short state;
58: short flags;
59: struct block *oblock;
60: struct queue *rdq;
61: char speed;
62: /* from SUN zsasync.c */
63: short za_needsoft; /* need for software interrupt */
64: short za_break; /* break occurred */
65: short za_overrun; /* overrun (either hw or sw) */
66: short za_ext; /* modem status change */
67: short za_work; /* work to do */
68: u_char za_rr0; /* for break detection */
69: u_char za_ibuf[ZSIBUFSZ]; /* circular input buffer */
70: short za_iptr; /* producing ptr for input */
71: short za_sptr; /* consuming ptr for input */
72: /* additions */
73: dev_t za_dev;
74: struct zscom *za_addr;
75: } zsaline[NZSLINE];
76:
77: extern int zssoftflags[NZSLINE];
78:
79: int zsopen(), zsclose(), zsoput(), nodev();
80:
81: static struct qinit zsrinit = { nodev, NULL, zsopen, zsclose, 0, 0 };
82: struct qinit zswinit = { zsoput, NULL, zsopen, zsclose, 200, 100 };
83: struct streamtab zsinfo = { &zsrinit, &zswinit };
84:
85:
86: #define PCLK (19660800/4) /* basic clock rate for UARTs */
87: #define ZSPEED(n) ZSTimeConst(PCLK, n)
88: #define NSPEED 16 /* max # of speeds */
89: u_short zs_speeds[NSPEED] = {
90: 0,
91: ZSPEED(50),
92: ZSPEED(75),
93: ZSPEED(110),
94: #ifdef lint
95: ZSPEED(134),
96: #else
97: ZSPEED(134.5),
98: #endif
99: ZSPEED(150),
100: ZSPEED(200),
101: ZSPEED(300),
102: ZSPEED(600),
103: ZSPEED(1200),
104: ZSPEED(1800),
105: ZSPEED(2400),
106: ZSPEED(4800),
107: ZSPEED(9600),
108: ZSPEED(19200),
109: ZSPEED(38400),
110: };
111:
112: int zsticks = 3; /* polling frequency */
113:
114: /*
115: * The async zs protocol
116: */
117: int zsa_attach(), zsa_txint(), zsa_xsint(), zsa_rxint(), zsa_srint(),
118: zsa_softint();
119:
120: struct zsops zsops_async = {
121: zsa_attach,
122: zsa_txint,
123: zsa_xsint,
124: zsa_rxint,
125: zsa_srint,
126: zsa_softint,
127: };
128:
129: zsa_attach(zs)
130: register struct zscom *zs;
131: {
132: register struct zsaline *za = &zsaline[zs->zs_unit];
133:
134: za->za_addr = zs;
135: za->za_dev = zs->zs_unit;
136: za->state = EXISTS;
137: }
138:
139: /*
140: * Get the current speed of the console and turn it into something
141: * UNIX knows about - used to preserve console speed when UNIX comes up
142: */
143: zsgetspeed(dev)
144: dev_t dev;
145: {
146: struct zscom *zs;
147: register struct zsaline *za;
148: int uspeed, zspeed;
149:
150: dev = minor(dev);
151: if (dev >= NZSLINE)
152: return(SSPEED);
153: za = &zsaline[dev];
154: zs = za->za_addr;
155: zspeed = ZREAD(12);
156: zspeed |= ZREAD(13) << 8;
157: for (uspeed = 0; uspeed < NSPEED; uspeed++)
158: if (zs_speeds[uspeed] == zspeed)
159: return (uspeed);
160: return (SSPEED);
161: }
162:
163: /*ARGSUSED*/
164: zsopen(q, d, flag)
165: register struct queue *q;
166: {
167: register dev;
168: register struct zsaline *za;
169: struct zscom *zs;
170: int s;
171: static int first = 1;
172: int zspoll();
173:
174: if (q->ptr) /* already attached */
175: return(1);
176: dev = minor(d);
177: za = &zsaline[dev];
178: if (dev >= NZSLINE || (za->state&EXISTS)==0)
179: return(0);
180: zs = za->za_addr;
181: q->ptr = (caddr_t)za;
182: WR(q)->ptr = (caddr_t)za;
183: s = splzs();
184: zs->zs_priv = (caddr_t)za;
185: zsopinit(zs, &zsops_async);
186: (void) splx(s);
187: if (first) {
188: first = 0;
189: timeout(zspoll, (caddr_t)0, zsticks);
190: }
191: if ((za->state&ISOPEN)==0 || (za->state&CARR_ON)==0) {
192: register s = spl5();
193: /* clear any stale input */
194: za->za_iptr = 0;
195: za->za_sptr = 0;
196: za->za_overrun = 0;
197: zsmctl(zs, ZS_ON, DMSET);
198: for (;;) {
199: za->flags = F8BIT|ODDP|EVENP;
200: if (zssoftflags[dev] & ZS_KBDMS)
201: za->speed = zsgetspeed(dev);
202: else
203: za->speed = SSPEED;
204: zsparam(za);
205: if (za->state & CARR_ON)
206: break;
207: /* ignore carrier? */
208: if (zssoftflags[dev] & 1) {
209: za->state |= (DIALOUT | CARR_ON);
210: break;
211: }
212: if (tsleep((caddr_t)za, ZSPRI, 0) != TS_OK) {
213: wakeup((caddr_t)za);
214: za->speed = 0;
215: zsparam(za);
216: splx(s);
217: return(0);
218: }
219: }
220: za->rdq = q;
221: za->state |= ISOPEN;
222: /*
223: * The 0 channel of the keyboard UART controls
224: * the keyboard, so push the keyboard line
225: * discipline on it automatically.
226: */
227: if ((zssoftflags[dev] & ZS_KBDMS) && !(dev & 1))
228: pushkeyld(WR(q->next), d);
229: splx(s);
230: }
231: TRC('o');
232: return(1);
233: }
234:
235: zsclose(q, d)
236: register struct queue *q;
237: {
238: register struct zsaline *za;
239: register s;
240: int s1;
241:
242: za = (struct zsaline *)q->ptr;
243: s = spl5();
244: s1 = splzs();
245: if (za->oblock) {
246: register struct block *bp = za->oblock;
247: za->oblock = NULL;
248: splx(s1);
249: freeb(bp);
250: }
251: flushq(WR(q), 1);
252: za->rdq = NULL;
253: if (za->state&HPCL || (za->state&CARR_ON)==0) {
254: za->speed = 0;
255: zsparam(za);
256: }
257: za->state &= EXISTS;
258: splx(s);
259: TRC('c');
260: }
261:
262: /*
263: * ZS write put routine
264: */
265: zsoput(q, bp)
266: register struct queue *q;
267: register struct block *bp;
268: {
269: register struct zsaline *za = (struct zsaline *)q->ptr;
270: register union stmsg *sp;
271: register s;
272: int s1;
273: int delaytime;
274:
275: TRC('p');
276: switch(bp->type) {
277:
278: case M_IOCTL:
279: TRC('i');
280: sp = (union stmsg *)bp->rptr;
281: switch (sp->ioc0.com) {
282:
283: case TIOCSDEV:
284: delaytime = 0;
285: if (za->speed != sp->ioc3.sb.ispeed)
286: delaytime = 20;
287: za->speed = sp->ioc3.sb.ispeed;
288: za->flags = sp->ioc3.sb.flags;
289: bp->type = M_IOCACK;
290: bp->wptr = bp->rptr;
291: qreply(q, bp);
292: qpctl1(q, M_DELAY, delaytime); /* wait a bit */
293: qpctl(q, M_CTL); /* means do zsparam */
294: zsstart(za);
295: return;
296:
297: case TIOCGDEV:
298: sp->ioc3.sb.ispeed =
299: sp->ioc3.sb.ospeed = za->speed;
300: sp->ioc3.sb.flags = za->flags;
301: bp->type = M_IOCACK;
302: qreply(q, bp);
303: return;
304:
305: case TIOCHPCL:
306: za->state |= HPCL;
307: bp->type = M_IOCACK;
308: bp->wptr = bp->rptr;
309: qreply(q, bp);
310: return;
311:
312: default:
313: bp->wptr = bp->rptr;
314: bp->type = M_IOCNAK;
315: qreply(q, bp);
316: return;
317: }
318:
319: case M_STOP:
320: s = spl5();
321: za->state |= ZSSTOP;
322: freeb(bp);
323: s1 = splzs();
324: if (bp = za->oblock) {
325: za->oblock = NULL;
326: splx(s1);
327: putbq(q, bp);
328: }
329: splx(s);
330: return;
331:
332: case M_START:
333: za->state &= ~ZSSTOP;
334: zsstart(za);
335: break;
336:
337: case M_FLUSH:
338: flushq(q, 1);
339: freeb(bp);
340: s = spl5();
341: s1 = splzs();
342: if (bp = za->oblock) {
343: za->oblock = NULL;
344: splx(s1);
345: freeb(bp);
346: }
347: splx(s);
348: return;
349:
350: case M_BREAK:
351: qpctl1(q, M_DELAY, 10);
352: putq(q, bp);
353: qpctl1(q, M_DELAY, 10);
354: zsstart(za);
355: return;
356:
357: case M_HANGUP:
358: za->state &= ~ZSSTOP;
359: case M_DELAY:
360: case M_DATA:
361: putq(q, bp);
362: TRC('d');
363: zsstart(za);
364: return;
365:
366: default: /* not handled; just toss */
367: break;
368: }
369: freeb(bp);
370: }
371:
372: /*
373: * set device parameters
374: */
375: zsparam(za)
376: register struct zsaline *za;
377: {
378: register struct zscom *zs = za->za_addr;
379: register int wr1, wr3, wr4, wr5, speed;
380: int loops;
381: int s;
382: char c;
383:
384: if (za->speed == 0) {
385: (void) zsmctl(zs, ZS_OFF, DMSET); /* hang up line */
386: return;
387: }
388: wr1 = ZSWR1_INIT;
389: wr3 = ZSWR3_RX_ENABLE;
390: wr4 = ZSWR4_X16_CLK;
391: wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
392: if (za->speed == B134) { /* what a joke! */
393: wr1 |= ZSWR1_PARITY_SPECIAL;
394: wr3 |= ZSWR3_RX_6;
395: wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
396: wr5 |= ZSWR5_TX_6;
397: } else if (za->flags&(F8BIT)) {
398: wr3 |= ZSWR3_RX_8;
399: wr5 |= ZSWR5_TX_8;
400: } else switch (za->flags & (EVENP|ODDP)) {
401: case 0:
402: wr3 |= ZSWR3_RX_8;
403: wr5 |= ZSWR5_TX_8;
404: break;
405:
406: case EVENP:
407: wr1 |= ZSWR1_PARITY_SPECIAL;
408: wr3 |= ZSWR3_RX_7;
409: wr4 |= ZSWR4_PARITY_ENABLE + ZSWR4_PARITY_EVEN;
410: wr5 |= ZSWR5_TX_7;
411: break;
412:
413: case ODDP:
414: wr1 |= ZSWR1_PARITY_SPECIAL;
415: wr3 |= ZSWR3_RX_7;
416: wr4 |= ZSWR4_PARITY_ENABLE;
417: wr5 |= ZSWR5_TX_7;
418: break;
419:
420: case EVENP|ODDP:
421: wr3 |= ZSWR3_RX_7;
422: wr4 |= ZSWR4_PARITY_ENABLE + ZSWR4_PARITY_EVEN;
423: wr5 |= ZSWR5_TX_7;
424: break;
425: }
426: if (za->speed == B110)
427: wr4 |= ZSWR4_2_STOP;
428: else if (za->speed == B134)
429: wr4 |= ZSWR4_1_5_STOP;
430: else
431: wr4 |= ZSWR4_1_STOP;
432: speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
433: if (wr1 != zs->zs_wreg[1] || wr3 != zs->zs_wreg[3] ||
434: wr4 != zs->zs_wreg[4] || wr5 != zs->zs_wreg[5] ||
435: speed != zs_speeds[za->speed&017]) {
436: /*
437: * Wait for that last damn character to get out the
438: * door. At most 1000 loops of 100 usec each is worst
439: * case of 110 baud. If something appears on the output
440: * queue then somebody higher up isn't synchronized
441: * and we give up.
442: */
443: s = splzs();
444: loops = 1000;
445: while ((ZREAD(1) & ZSRR1_ALL_SENT) == 0 && --loops > 0) {
446: (void) splx(s);
447: DELAY(100);
448: s = splzs();
449: }
450: ZWRITE(3, 0); /* disable receiver while setting parameters */
451: zs->zs_addr->zscc_control = ZSWR0_RESET_STATUS;
452: zs->zs_addr->zscc_control = ZSWR0_RESET_ERRORS;
453: c = zs->zs_addr->zscc_data; /* swallow junk */
454: c = zs->zs_addr->zscc_data; /* swallow junk */
455: c = zs->zs_addr->zscc_data; /* swallow junk */
456: ZWRITE(1, wr1);
457: ZWRITE(4, wr4);
458: ZWRITE(3, wr3);
459: ZWRITE(5, wr5);
460: speed = zs_speeds[za->speed&017];
461: ZWRITE(11, ZSWR11_TXCLK_BAUD + ZSWR11_RXCLK_BAUD);
462: ZWRITE(14, ZSWR14_BAUD_FROM_PCLK);
463: ZWRITE(12, speed);
464: ZWRITE(13, speed >> 8);
465: ZWRITE(14, ZSWR14_BAUD_ENA + ZSWR14_BAUD_FROM_PCLK);
466: (void) splx(s);
467: }
468: }
469:
470: zstimo(za)
471: register struct zsaline *za;
472: {
473: register struct zscom *zs = za->za_addr;
474: int s;
475:
476: if (za->state&BRKING) {
477: s = splzs();
478: ZBIC(5, ZSWR5_BREAK);
479: splx(s);
480: }
481: za->state &= ~(TIMEOUT|BRKING);
482: zsstart(za);
483: }
484:
485: zsstart(za)
486: register struct zsaline *za;
487: {
488: register struct zscom *zs = za->za_addr;
489: register s = spl5();
490: register struct block *bp;
491: int s1;
492:
493: TRC('s');
494: again:
495: if (za->state & (TIMEOUT|ZSSTOP|BRKING) || za->oblock) {
496: TRC('t');
497: goto out;
498: }
499: if (za->rdq == NULL)
500: goto out;
501: if ((bp = getq(WR(za->rdq))) == NULL) {
502: TRC('n');
503: goto out;
504: }
505: switch (bp->type) {
506:
507: case M_DATA:
508: za->oblock = bp;
509: if (zs->zs_addr->zscc_control & ZSRR0_TX_READY)
510: zs->zs_addr->zscc_data = *bp->rptr++;
511: break;
512:
513: case M_BREAK:
514: s1 = splzs();
515: ZBIS(5, ZSWR5_BREAK);
516: splx(s1);
517: za->state |= BRKING|TIMEOUT;
518: timeout(zstimo, (caddr_t)za, 15); /* about 250 ms */
519: freeb(bp);
520: break;
521:
522: case M_DELAY:
523: za->state |= TIMEOUT;
524: timeout(zstimo, (caddr_t)za, (int)*bp->rptr + 6);
525: freeb(bp);
526: break;
527:
528: case M_HANGUP:
529: za->speed = 0;
530: case M_CTL:
531: freeb(bp);
532: zsparam(za);
533: goto again;
534:
535: }
536: out:
537: splx(s);
538: }
539:
540: zsmctl(zs, bits, how)
541: register struct zscom *zs;
542: int bits, how;
543: {
544: register int mbits, s;
545:
546: s = splzs();
547: mbits = zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR);
548: zs->zs_addr->zscc_control = ZSWR0_RESET_STATUS;
549: DELAY(2);
550: mbits |= zs->zs_addr->zscc_control & (ZSRR0_CD|ZSRR0_CTS);
551: switch (how) {
552: case DMSET:
553: mbits = bits;
554: break;
555:
556: case DMBIS:
557: mbits |= bits;
558: break;
559:
560: case DMBIC:
561: mbits &= ~bits;
562: break;
563:
564: case DMGET:
565: (void) splx(s);
566: return (mbits);
567: }
568: zs->zs_wreg[5] &= ~(ZSWR5_RTS|ZSWR5_DTR);
569: ZBIS(5, mbits & (ZSWR5_RTS|ZSWR5_DTR));
570: (void) splx(s);
571: return (mbits);
572: }
573:
574: zsa_txint(zs)
575: register struct zscom *zs;
576: {
577: register struct zsaline *za = (struct zsaline *)zs->zs_priv;
578: register struct zscc_device *zsaddr = zs->zs_addr;
579: register struct block *bp;
580:
581: if ((bp = za->oblock) && bp->rptr < bp->wptr &&
582: (zsaddr->zscc_control & ZSRR0_TX_READY)) {
583: zsaddr->zscc_data = *bp->rptr++;
584: } else {
585: za->za_work++;
586: zsaddr->zscc_control = ZSWR0_RESET_TXINT;
587: ZSSETSOFT(zs);
588: }
589: }
590:
591: zsa_xsint(zs)
592: register struct zscom *zs;
593: {
594: register struct zsaline *za = (struct zsaline *)zs->zs_priv;
595: register struct zscc_device *zsaddr = zs->zs_addr;
596: register u_char s0, x0, c;
597:
598: s0 = zsaddr->zscc_control;
599: x0 = s0 ^ za->za_rr0;
600: za->za_rr0 = s0;
601: zsaddr->zscc_control = ZSWR0_RESET_STATUS;
602: if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
603: za->za_break++;
604: c = zsaddr->zscc_data; /* swallow null */
605: #ifdef lint
606: c = c;
607: #endif
608: zsaddr->zscc_control = ZSWR0_RESET_ERRORS;
609: /*
610: if (za->za_dev == kbddev)
611: montrap(*romp->v_abortent);
612: */
613: }
614: za->za_work++;
615: za->za_ext++;
616: ZSSETSOFT(zs);
617: }
618:
619: zsa_rxint(zs)
620: register struct zscom *zs;
621: {
622: register struct zsaline *za = (struct zsaline *)zs->zs_priv;
623: register struct zscc_device *zsaddr = zs->zs_addr;
624: register u_char c;
625:
626: c = zsaddr->zscc_data;
627: if (c == 0 && (za->za_rr0 & ZSRR0_BREAK))
628: return;
629: za->za_ibuf[za->za_iptr++] = c;
630: if (za->za_iptr >= ZSIBUFSZ)
631: za->za_iptr = 0;
632: if (za->za_iptr == za->za_sptr)
633: za->za_overrun++;
634: za->za_work++;
635: if (++za->za_needsoft > 20) {
636: za->za_needsoft = 0;
637: ZSSETSOFT(zs);
638: }
639: }
640:
641: zsa_srint(zs)
642: register struct zscom *zs;
643: {
644: register struct zsaline *za = (struct zsaline *)zs->zs_priv;
645: register struct zscc_device *zsaddr = zs->zs_addr;
646: register short s1;
647: register u_char c;
648:
649: s1 = ZREAD(1);
650: c = zsaddr->zscc_data; /* swallow bad char */
651: #ifdef lint
652: c = c;
653: #endif
654: zsaddr->zscc_control = ZSWR0_RESET_ERRORS;
655: if (s1 & ZSRR1_DO) {
656: za->za_overrun++;
657: za->za_work++;
658: ZSSETSOFT(zs);
659: }
660: }
661: /*
662: * Handle a software interrupt
663: */
664: zsa_softint(zs)
665: register struct zscom *zs;
666: {
667: register struct zsaline *za = (struct zsaline *)zs->zs_priv;
668:
669: if (zsa_process(za)) /* true if too much work at once */
670: zspoll(1);
671: return (0);
672: }
673:
674: /*
675: * Poll for events in the zscom structures
676: * This routine is called at level 1, we jack up to 3 to lock
677: * out zsa_softint.
678: */
679: zspoll(direct)
680: {
681: register struct zsaline *za;
682: register short more;
683: register int s;
684:
685: do {
686: more = 0;
687: for (za = &zsaline[0]; za < &zsaline[NZSLINE]; za++)
688: if (za->za_work) {
689: za->za_work = 0;
690: s = spl3();
691: if (zsa_process(za)) {
692: za->za_work++;
693: more++;
694: }
695: (void) splx(s);
696: }
697: } while (more);
698: if (!direct)
699: timeout(zspoll, (caddr_t)0, zsticks);
700: }
701:
702: /*
703: * Process software interrupts (or poll)
704: * Crucial points:
705: * 1. Inner loop gives equal priority to input and output so that
706: * in TANDEM mode the stop character has a chance of being sent
707: * before enough input arrives to exceed TTYHOG. This has happened
708: * in very busy systems.
709: * 2. The inner loop is executed at most 20 times before the next line
710: * is serviced -- this "schedules" more fairly among lines.
711: * 3. BUG - breaks are handled "out-of-band" - their relative position
712: * among input events is lost, as well as multiple breaks together.
713: * This is probably not a problem in practice.
714: */
715: zsa_process(za)
716: register struct zsaline *za;
717: {
718: register struct zscc_device *zsaddr = za->za_addr->zs_addr;
719: register struct block *bp;
720: register short i;
721: register u_char c;
722:
723: if (za->za_ext) {
724: za->za_ext = 0;
725: /* carrier up? */
726: if (zsaddr->zscc_control & ZSRR0_CD) {
727: /* carrier present */
728: if ((za->state & CARR_ON)==0)
729: wakeup((caddr_t)za);
730: za->state |= CARR_ON;
731: } else if ((za->state & CARR_ON) && !(za->state & DIALOUT)) {
732: /* carrier lost */
733: if (za->state & ISOPEN) {
734: (void) zsmctl(za->za_addr, ZSWR5_DTR, DMBIC);
735: if (za->rdq)
736: putctl(za->rdq->next,M_HANGUP);
737: }
738: za->state &= ~CARR_ON;
739: }
740: }
741: if (za->za_overrun) {
742: za->za_overrun = 0;
743: za->za_iptr = 0;
744: za->za_sptr = 0;
745: if (za->state & ISOPEN)
746: printf("zs%d: silo overflow\n", minor(za->za_dev));
747: }
748: if (za->za_break && (zsaddr->zscc_control & ZSRR0_BREAK) == 0) {
749: za->za_break = 0;
750: if (za->rdq != NULL && !(za->rdq->next->flag&QFULL) &&
751: (bp = allocb(16)) != NULL) {
752: bp->type = M_BREAK;
753: (*za->rdq->next->qinfo->putp)(za->rdq->next, bp);
754: }
755: }
756: /* need to handle I & O in same loop to make TANDEM mode work */
757: i = 0;
758: do {
759: if (za->za_sptr != za->za_iptr) {
760: c = za->za_ibuf[za->za_sptr++];
761: if (za->za_sptr >= ZSIBUFSZ)
762: za->za_sptr = 0;
763: if (za->rdq != NULL && !(za->rdq->next->flag&QFULL) &&
764: (bp = allocb(16)) != NULL) {
765: *bp->wptr++ = c;
766: (*za->rdq->next->qinfo->putp)(za->rdq->next, bp);
767: }
768: }
769: if ((bp = za->oblock) && bp->rptr >= bp->wptr) {
770: freeb(bp);
771: za->oblock = NULL;
772: zsstart(za);
773: }
774: } while (za->za_sptr != za->za_iptr && ++i < 20);
775: return (i >= 20);
776: }
777:
778: /*
779: * push the keyboard line discipline on the line
780: * function equivalent of FIOPUSHLD, but occurs automatically on open
781: */
782: #include "kbd.h"
783: #if NKBD > 0
784: extern struct streamtab kbdinfo;
785: #else
786: # define kbdinfo *(struct streamtab *)NULL
787: #endif
788:
789: pushkeyld(q, d)
790: register struct queue *q;
791: {
792: if (&kbdinfo == (struct streamtab *)NULL)
793: return;
794: if (qattach(&kbdinfo, RD(q), d)) {
795: long nip =
796: (*q->next->qinfo->qopen)(RD(q->next), d);
797: if (nip ==0)
798: qdetach(RD(q->next), 0);
799: }
800: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.