|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)cons.c 7.9 (Berkeley) 2/17/90
7: */
8:
9: /*
10: * VAX console driver (and floppy interface)
11: */
12: #include "param.h"
13: #include "conf.h"
14: #include "user.h"
15: #include "proc.h"
16: #include "ioctl.h"
17: #include "tty.h"
18: #include "systm.h"
19:
20: #include "cpu.h"
21: #include "cons.h"
22: #include "mtpr.h"
23:
24: /*
25: * On some machines (e.g. MicroVAX), a secondary console
26: * such as a display may supercede the standard serial console.
27: * On such machines, consops will be set to point to the cdevsw
28: * entry for the secondary console, and the standard console device
29: * (minor number 0) will be redirected. Other minor numbers still
30: * refer to the standard console serial line.
31: *
32: * Also, console output may be redirected to another tty
33: * (e.g. a window); if so, constty will point to the current
34: * virtual console.
35: */
36: struct cdevsw *consops = 0;
37: struct tty *constty = 0;
38: struct tty cons;
39: int cnstart();
40: int ttrstrt();
41: char partab[];
42:
43: /*ARGSUSED*/
44: cnopen(dev, flag)
45: dev_t dev;
46: {
47: register struct tty *tp = &cons;
48:
49: if (consops && minor(dev) == 0)
50: return ((*consops->d_open)(dev, flag));
51: tp->t_oproc = cnstart;
52: if ((tp->t_state&TS_ISOPEN) == 0) {
53: ttychars(tp);
54: tp->t_iflag = TTYDEF_IFLAG|ICRNL;
55: tp->t_oflag = TTYDEF_OFLAG|OPOST|ONLCR;
56: tp->t_lflag = TTYDEF_LFLAG;
57: tp->t_cflag = CS8|CREAD;
58: tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
59: tp->t_state = TS_ISOPEN|TS_CARR_ON;
60: ttsetwater(tp);
61: }
62: if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
63: return (EBUSY);
64: mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
65: mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
66: return ((*linesw[tp->t_line].l_open)(dev, tp));
67: }
68:
69: /*ARGSUSED*/
70: cnclose(dev)
71: dev_t dev;
72: {
73: register struct tty *tp = &cons;
74:
75: if (consops && minor(dev) == 0)
76: return ((*consops->d_close)(dev));
77: (*linesw[tp->t_line].l_close)(tp);
78: ttyclose(tp);
79: return (0);
80: }
81:
82: /*ARGSUSED*/
83: cnread(dev, uio, flag)
84: dev_t dev;
85: struct uio *uio;
86: int flag;
87: {
88: register struct tty *tp = &cons;
89:
90: if (consops && minor(dev) == 0)
91: return ((*consops->d_read)(dev, uio, flag));
92: return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
93: }
94:
95: /*ARGSUSED*/
96: cnwrite(dev, uio, flag)
97: dev_t dev;
98: struct uio *uio;
99: int flag;
100: {
101: register struct tty *tp = &cons;
102:
103: if (minor(dev) == 0) {
104: if (constty && (constty->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
105: (TS_CARR_ON | TS_ISOPEN))
106: tp = constty;
107: else if (consops)
108: return ((*consops->d_write)(dev, uio, flag));
109: }
110: return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
111: }
112:
113: static int cnpolling = 0;
114: /*
115: * Got a level-20 receive interrupt -
116: * the LSI wants to give us a character.
117: * Catch the character, and see who it goes to.
118: */
119: /*ARGSUSED*/
120: cnrint(dev)
121: dev_t dev;
122: {
123: register int c;
124: register struct tty *tp;
125:
126: if (cnpolling)
127: return;
128: c = mfpr(RXDB)&0xff;
129: if (c&RXDB_ID) {
130: #if VAX780
131: if (cpu == VAX_780)
132: cnrfl(c);
133: #endif
134: return;
135: }
136: tp = &cons;
137: #ifdef KADB
138: if (!kdbrintr(c, tp))
139: #endif
140: if ((tp->t_cflag&CSIZE) == CS7) {
141: #ifdef notyet
142: if (tp->t_cflag&PARENB) {
143: if ((tp->t_cflag&PARODD) &&
144: (partab[c&0177]&0200) == (c&0200))
145: c |= TTY_PE;
146: else if ((partab[c&0177]&0200) != (c&0200))
147: c |= TTY_PE;
148: }
149: #endif
150: c &= ~0200;
151: }
152: (*linesw[tp->t_line].l_rint)(c, tp);
153: }
154:
155: /*ARGSUSED*/
156: cnioctl(dev, cmd, addr, flag)
157: dev_t dev;
158: caddr_t addr;
159: {
160: register struct tty *tp = &cons;
161: int error;
162:
163: if (consops && minor(dev) == 0)
164: return ((*consops->d_ioctl)(dev, cmd, addr, flag));
165: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
166: if (error >= 0)
167: return (error);
168: error = ttioctl(tp, cmd, addr, flag);
169: if (error < 0)
170: error = ENOTTY;
171: return (error);
172: }
173:
174: int consdone = 1;
175: /*
176: * Got a level-20 transmission interrupt -
177: * the LSI wants another character. First,
178: * see if we can send something to the typewriter.
179: * If not, try the floppy.
180: */
181: /*ARGSUSED*/
182: cnxint(dev)
183: dev_t dev;
184: {
185: register struct tty *tp = &cons;
186:
187: consdone++;
188: tp->t_state &= ~TS_BUSY;
189: if (tp->t_line)
190: (*linesw[tp->t_line].l_start)(tp);
191: else
192: cnstart(tp);
193: #if VAX780
194: if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0)
195: conxfl();
196: #endif
197: }
198:
199: cnstart(tp)
200: register struct tty *tp;
201: {
202: register int c, s;
203:
204: s = spl5();
205: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
206: goto out;
207: if (tp->t_outq.c_cc <= tp->t_lowat) {
208: if (tp->t_state&TS_ASLEEP) {
209: tp->t_state &= ~TS_ASLEEP;
210: wakeup((caddr_t)&tp->t_outq);
211: }
212: if (tp->t_wsel) {
213: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
214: tp->t_wsel = 0;
215: tp->t_state &= ~TS_WCOLL;
216: }
217: }
218: if (tp->t_outq.c_cc == 0)
219: goto out;
220: if (consdone == 0)
221: goto out;
222: c = getc(&tp->t_outq) & 0xff;
223: #ifdef notdef
224: if (tp->t_cflag&PARENB && ((tp->t_cflag&CSIZE)==CS7)) {
225: c &= 0177;
226: c |= (tp->t_cflag&PARODD ? ~partab[c] : partab[c]) & 0200;
227: }
228: #else
229: if ((tp->t_cflag&CSIZE) == CS7) {
230: #ifdef notyet
231: if (tp->t_cflag&PARENB) {
232: if (tp->t_cflag&PARODD)
233: c = (~(partab[c&0177])&0200)|(c&0177);
234: else
235: c = (partab[c&0177]&0200)|(c&0177);
236: } else
237: #endif
238: c &= 0177;
239: }
240: #endif
241: mtpr(TXDB, c);
242: consdone = 0;
243: tp->t_state |= TS_BUSY;
244: out:
245: splx(s);
246: }
247:
248: /*
249: * Print a character on console.
250: * Attempts to save and restore device
251: * status.
252: */
253: cnputc(c)
254: register int c;
255: {
256: register int s, timo;
257:
258: timo = 30000;
259: /*
260: * Try waiting for the console tty to come ready,
261: * otherwise give up after a reasonable time.
262: */
263: while ((mfpr(TXCS)&TXCS_RDY) == 0)
264: if(--timo == 0)
265: break;
266: if (c == 0)
267: return;
268: s = mfpr(TXCS);
269: mtpr(TXCS, 0);
270: mtpr(TXDB, c&0xff);
271: if (c == '\n')
272: cnputc('\r');
273: cnputc(0);
274: mtpr(TXCS, s);
275: }
276:
277: #if (defined(KADB) || defined(GENERIC)) && !defined(lint)
278: /*
279: * Get character from console.
280: */
281: cngetc()
282: {
283: register int c, s;
284:
285: s = splhigh();
286: while ((mfpr(RXCS)&RXCS_DONE) == 0 || (c = mfpr(RXDB)&0177) <= 0)
287: ;
288: if (c == '\r')
289: c = '\n';
290: (void) splx(s);
291: return (c);
292: }
293: #endif
294:
295: #ifdef KADB
296: cnpoll(onoff)
297: int onoff;
298: {
299:
300: cnpolling = onoff;
301: }
302: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.