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