|
|
1.1 root 1: /* dz.c 4.3 11/9/80 */
2:
3: #include "../conf/dz.h"
4: #if NDZ11 > 0
5: /*
6: * DZ-11 Driver
7: */
8: #include "../h/param.h"
9: #include "../h/systm.h"
10: #include "../h/tty.h"
11: #include "../h/dir.h"
12: #include "../h/user.h"
13: #include "../h/map.h"
14: #include "../h/pte.h"
15: #include "../h/uba.h"
16: #include "../h/conf.h"
17: #include "../h/pdma.h"
18: #include "../h/bk.h"
19: #include "../h/file.h"
20: #include "../h/mx.h"
21:
22: /*
23: * When running dz's using only SAE (silo alarm) on input
24: * it is necessary to call dzrint() at clock interrupt time.
25: * This is unsafe unless spl5()s in tty code are changed to
26: * spl6()s to block clock interrupts. Note that the dh driver
27: * currently in use works the same way as the dz, even though
28: * we could try to more intelligently manage its silo.
29: * Thus don't take this out if you have no dz's unless you
30: * change clock.c and dhtimer().
31: */
32: #define spl5 spl6
33:
34: #define NDZ (NDZ11*8)
35:
36: #define BITS7 020
37: #define BITS8 030
38: #define TWOSB 040
39: #define PENABLE 0100
40: #define OPAR 0200
41: #define MSE 040 /* Master Scan Enable */
42: #define RIE 0100 /* Receiver Interrupt Enable */
43: #define SAE 010000 /* Silo Alarm Enable */
44: #define TIE 040000 /* Transmit Interrupt Enable */
45: #define DZ_IEN (MSE+RIE+TIE+SAE)
46: #define PERROR 010000
47: #define FRERROR 020000
48: #define OVERRUN 040000
49: #define SSPEED 7 /* std speed = 300 baud */
50:
51:
52: #define dzlpr dzrbuf
53: #define dzmsr dzbrk
54: #define ON 1
55: #define OFF 0
56:
57: int dzstart();
58: int dzxint();
59: int ttrstrt();
60: struct tty dz_tty[NDZ];
61: int dz_cnt = { NDZ };
62: int dzact;
63:
64: struct device {
65: short dzcsr;
66: short dzrbuf;
67: char dztcr;
68: char dzdtr;
69: char dztbuf;
70: char dzbrk;
71: };
72:
73: struct pdma dzpdma[] = {
74: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint,
75: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint,
76: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint,
77: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint,
78: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint,
79: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint,
80: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint,
81: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint,
82: #if NDZ11 >= 2
83: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint,
84: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint,
85: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint,
86: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint,
87: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint,
88: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint,
89: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint,
90: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint,
91: #endif
92: #if NDZ11 >= 3
93: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint,
94: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint,
95: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint,
96: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint,
97: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint,
98: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint,
99: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint,
100: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint,
101: #endif
102: #if NDZ11 >= 4
103: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[24], dzxint,
104: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[25], dzxint,
105: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[26], dzxint,
106: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[27], dzxint,
107: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[28], dzxint,
108: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[29], dzxint,
109: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[30], dzxint,
110: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[31], dzxint,
111: #endif
112: };
113: char dz_timer;
114: char dz_speeds[] = {
115: 0, 020 , 021 , 022 , 023 , 024 , 0, 025,
116: 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0,
117: };
118:
119: /*ARGSUSED*/
120: dzopen(d, flag)
121: {
122: register struct tty *tp;
123: register dev;
124: extern dzscan();
125:
126: dev = minor(d);
127: if (dev >= dz_cnt) {
128: u.u_error = ENXIO;
129: return;
130: }
131: if (dz_timer == 0) {
132: dz_timer++;
133: timeout(dzscan, (caddr_t)0, 60);
134: }
135: tp = &dz_tty[dev];
136: tp->t_addr = (caddr_t)&dzpdma[dev];
137: tp->t_oproc = dzstart;
138: tp->t_iproc = NULL;
139: tp->t_state |= WOPEN;
140: if ((tp->t_state & ISOPEN) == 0) {
141: ttychars(tp);
142: tp->t_ospeed = tp->t_ispeed = SSPEED;
143: tp->t_flags = ODDP|EVENP|ECHO;
144: /*tp->t_state |= HUPCLS;*/
145: dzparam(dev);
146: } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
147: u.u_error = EBUSY;
148: return;
149: }
150: dzmodem(dev, ON);
151: (void) spl5();
152: while ((tp->t_state & CARR_ON) == 0) {
153: tp->t_state |= WOPEN;
154: sleep((caddr_t)&tp->t_rawq, TTIPRI);
155: }
156: (void) spl0();
157: (*linesw[tp->t_line].l_open)(d, tp);
158: }
159:
160: dzclose(d)
161: {
162: register struct tty *tp;
163: register dev;
164:
165: dev = minor(d);
166: tp = &dz_tty[dev];
167: (*linesw[tp->t_line].l_close)(tp);
168: if (tp->t_state & HUPCLS)
169: dzmodem(dev, OFF);
170: ttyclose(tp);
171: }
172:
173: dzread(d)
174: {
175: register struct tty *tp;
176:
177: tp = &dz_tty[minor(d)];
178: (*linesw[tp->t_line].l_read)(tp);
179: }
180:
181: dzwrite(d)
182: {
183: register struct tty *tp;
184:
185: tp = &dz_tty[minor(d)];
186: (*linesw[tp->t_line].l_write)(tp);
187: }
188:
189: /*ARGSUSED*/
190: dzrint(dev)
191: {
192: register struct tty *tp;
193: register int c;
194: register struct device *dzaddr;
195: register struct tty *tp0;
196: int s;
197:
198: s = spl6(); /* see comment in clock.c */
199: /* as long as we are here, service them all */
200: for (dev = 0; dev < NDZ; dev += 8) {
201: if ((dzact & (1<<(dev>>3))) == 0)
202: continue;
203: dzaddr = dzpdma[dev].p_addr;
204: tp0 = &dz_tty[dev];
205: while ((c = dzaddr->dzrbuf) < 0) { /* char present */
206: tp = tp0 + ((c>>8)&07);
207: if (tp >= &dz_tty[dz_cnt])
208: continue;
209: if ((tp->t_state & ISOPEN) == 0) {
210: wakeup((caddr_t)&tp->t_rawq);
211: continue;
212: }
213: if (c&FRERROR)
214: /* framing error = break */
215: if (tp->t_flags & RAW)
216: c = 0; /* null for getty */
217: else
218: #ifdef IIASA
219: continue;
220: #else
221: c = tun.t_intrc;
222: #endif
223: if (c&OVERRUN)
224: printf("o");
225: if (c&PERROR)
226: /* parity error */
227: if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
228: || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
229: continue;
230: if (tp->t_line == NETLDISC) {
231: c &= 0177;
232: BKINPUT(c, tp);
233: } else
234: (*linesw[tp->t_line].l_rint)(c, tp);
235: }
236: }
237: splx(s);
238: }
239:
240: /*ARGSUSED*/
241: dzioctl(dev, cmd, addr, flag)
242: caddr_t addr;
243: dev_t dev;
244: {
245: register struct tty *tp;
246: static char dz_brk[NDZ11];
247:
248: tp = &dz_tty[minor(dev)];
249: cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
250: if (cmd == 0)
251: return;
252: if (ttioctl(cmd, tp, addr, dev, flag)) {
253: if (cmd==TIOCSETP || cmd==TIOCSETN)
254: dzparam(minor(dev));
255: } else switch(cmd) {
256: case TIOCSBRK:
257: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
258: (dz_brk[minor(dev)>>3] |= 1 << (dev&07));
259: break;
260: case TIOCCBRK:
261: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
262: (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07)));
263: break;
264: case TIOCSDTR:
265: dzmodem(minor(dev), ON);
266: break;
267: case TIOCCDTR:
268: dzmodem(minor(dev), OFF);
269: break;
270: default:
271: u.u_error = ENOTTY;
272: }
273: }
274:
275: dzparam(dev)
276: {
277: register struct tty *tp;
278: register struct device *dzaddr;
279: register short lpr;
280:
281: tp = &dz_tty[dev];
282: dzaddr = dzpdma[dev].p_addr;
283: dzaddr->dzcsr = DZ_IEN;
284: dzact |= (1<<(dev>>3));
285: if (tp->t_ispeed == 0) {
286: dzmodem(dev, OFF); /* hang up line */
287: return;
288: }
289: lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07);
290: #ifndef IIASA
291: if (tp->t_flags & RAW)
292: lpr |= BITS8;
293: else
294: lpr |= (BITS7|PENABLE);
295: if ((tp->t_flags & EVENP) == 0)
296: lpr |= OPAR;
297: #else IIASA
298: if ((tp->t_flags & (EVENP|ODDP)) == (EVENP|ODDP))
299: lpr |= BITS8;
300: else if (tp->t_flags & EVENP)
301: lpr |= (BITS7|PENABLE);
302: else if (tp->t_flags & ODDP)
303: lpr |= (BITS7|OPAR|PENABLE);
304: else
305: lpr |= BITS7;
306: #endif IIASA
307: if (tp->t_ispeed == 3)
308: lpr |= TWOSB; /* 110 baud: 2 stop bits */
309: dzaddr->dzlpr = lpr;
310: }
311:
312: dzxint(tp)
313: register struct tty *tp;
314: {
315: register struct pdma *dp;
316: register s;
317: s = spl6(); /* block the clock */
318:
319: dp = &dzpdma[tp-dz_tty];
320: tp->t_state &= ~BUSY;
321: if (tp->t_state & FLUSH)
322: tp->t_state &= ~FLUSH;
323: else
324: ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
325: if (tp->t_line)
326: (*linesw[tp->t_line].l_start)(tp);
327: else
328: dzstart(tp);
329: if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
330: dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8));
331: splx(s);
332: }
333:
334: dzstart(tp)
335: register struct tty *tp;
336: {
337: register struct pdma *dp;
338: register struct device *dzaddr;
339: register cc;
340: int sps;
341:
342: dp = &dzpdma[tp-dz_tty];
343: dzaddr = dp->p_addr;
344: sps = spl5();
345: if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
346: goto out;
347: if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
348: tp->t_state &= ~ASLEEP;
349: if (tp->t_chan)
350: mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
351: else
352: wakeup((caddr_t)&tp->t_outq);
353: }
354: if (tp->t_outq.c_cc == 0)
355: goto out;
356: if (tp->t_flags&RAW)
357: cc = ndqb(&tp->t_outq, 0);
358: else {
359: cc = ndqb(&tp->t_outq, 0200);
360: if (cc == 0) {
361: cc = getc(&tp->t_outq);
362: timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6);
363: tp->t_state |= TIMEOUT;
364: goto out;
365: }
366: }
367: tp->t_state |= BUSY;
368: dp->p_end = dp->p_mem = tp->t_outq.c_cf;
369: dp->p_end += cc;
370: dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8);
371: out:
372: splx(sps);
373: }
374:
375: /*
376: * Stop output on a line.
377: * Assume call is made at spl6.
378: */
379: /*ARGSUSED*/
380: dzstop(tp, flag)
381: register struct tty *tp;
382: {
383: register struct pdma *dp;
384: register int s;
385:
386: dp = &dzpdma[tp-dz_tty];
387: s = spl6();
388: if (tp->t_state & BUSY) {
389: dp->p_end = dp->p_mem;
390: if ((tp->t_state&TTSTOP)==0) {
391: tp->t_state |= FLUSH;
392: }
393: }
394: splx(s);
395: }
396:
397: dzmodem(dev, flag)
398: register int dev;
399: {
400: register struct device *dzaddr;
401: register char bit;
402:
403: dzaddr = dzpdma[dev].p_addr;
404: bit = 1<<(dev&07);
405: if (flag == OFF)
406: dzaddr->dzdtr &= ~bit;
407: else
408: dzaddr->dzdtr |= bit;
409: }
410:
411: dzscan()
412: {
413: register i;
414: register struct device *dzaddr;
415: register bit;
416: register struct tty *tp;
417:
418: for (i = 0; i < dz_cnt ; i++) {
419: dzaddr = dzpdma[i].p_addr;
420: tp = &dz_tty[i];
421: bit = 1<<(i&07);
422: if (dzaddr->dzmsr & bit) {
423: /* carrier present */
424: if ((tp->t_state & CARR_ON) == 0) {
425: wakeup((caddr_t)&tp->t_rawq);
426: tp->t_state |= CARR_ON;
427: }
428: } else {
429: if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG) == 0) {
430: /* carrier lost */
431: if (tp->t_state&ISOPEN) {
432: gsignal(tp->t_pgrp, SIGHUP);
433: gsignal(tp->t_pgrp, SIGCONT);
434: dzaddr->dzdtr &= ~bit;
435: flushtty(tp, FREAD|FWRITE);
436: }
437: tp->t_state &= ~CARR_ON;
438: }
439: }
440: }
441: timeout(dzscan, (caddr_t)0, 2*HZ);
442: }
443:
444: dztimer()
445: {
446:
447: dzrint(0);
448: }
449:
450: /*
451: * Reset state of driver if UBA reset was necessary.
452: * Reset parameters and restart transmission on open lines.
453: */
454: dzreset()
455: {
456: int d;
457: register struct tty *tp;
458:
459: printf(" dz");
460: for (d = 0; d < NDZ; d++) {
461: tp = &dz_tty[d];
462: if (tp->t_state & (ISOPEN|WOPEN)) {
463: dzparam(d);
464: dzmodem(d, ON);
465: tp->t_state &= ~BUSY;
466: dzstart(tp);
467: }
468: }
469: dztimer();
470: }
471: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.