xref: /original-bsd/sys/vax/vax/cons.c (revision 35d77a20)
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.12 (Berkeley) 05/16/91
7  */
8 
9 /*
10  * VAX console driver (and floppy interface)
11  */
12 #include "sys/param.h"
13 #include "sys/conf.h"
14 #include "sys/user.h"
15 #include "sys/proc.h"
16 #include "sys/ioctl.h"
17 #include "sys/tty.h"
18 #include "sys/systm.h"
19 
20 #include "../include/cpu.h"
21 #include "cons.h"
22 #include "../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, flag, mode, p)
71 	dev_t dev;
72 	int flag, mode;
73 	struct proc *p;
74 {
75 	register struct tty *tp = &cons;
76 
77 	if (consops && minor(dev) == 0)
78 		return ((*consops->d_close)(dev, flag, mode, p));
79 	(*linesw[tp->t_line].l_close)(tp, flag);
80 	ttyclose(tp);
81 	return (0);
82 }
83 
84 /*ARGSUSED*/
85 cnread(dev, uio, flag)
86 	dev_t dev;
87 	struct uio *uio;
88 	int flag;
89 {
90 	register struct tty *tp = &cons;
91 
92 	if (consops && minor(dev) == 0)
93 		return ((*consops->d_read)(dev, uio, flag));
94 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
95 }
96 
97 /*ARGSUSED*/
98 cnwrite(dev, uio, flag)
99 	dev_t dev;
100 	struct uio *uio;
101 	int flag;
102 {
103 	register struct tty *tp = &cons;
104 
105 	if (minor(dev) == 0) {
106 		if (constty && (constty->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
107 		    (TS_CARR_ON | TS_ISOPEN))
108 			tp = constty;
109 		else if (consops)
110 			return ((*consops->d_write)(dev, uio, flag));
111 	}
112 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
113 }
114 
115 static	int cnpolling = 0;
116 /*
117  * Got a level-20 receive interrupt -
118  * the LSI wants to give us a character.
119  * Catch the character, and see who it goes to.
120  */
121 /*ARGSUSED*/
122 cnrint(dev)
123 	dev_t dev;
124 {
125 	register int c;
126 	register struct tty *tp;
127 
128 	if (cnpolling)
129 		return;
130 	c = mfpr(RXDB);
131 	if (c&RXDB_ID) {
132 #if VAX780
133 		if (cpu == VAX_780)
134 			cnrfl(c);
135 #endif
136 		return;
137 	}
138 	c &= 0xff;
139 	tp = &cons;
140 #ifdef KADB
141 	if (!kdbrintr(c, tp))
142 #endif
143 	if ((tp->t_cflag&CSIZE) == CS7) {
144 #ifdef notyet
145 		if (tp->t_cflag&PARENB) {
146 			if ((tp->t_cflag&PARODD) &&
147 			    (partab[c&0177]&0200) == (c&0200))
148 				c |= TTY_PE;
149 			else if ((partab[c&0177]&0200) != (c&0200))
150 				c |= TTY_PE;
151 		}
152 #endif
153 		c &= ~0200;
154 	}
155 	(*linesw[tp->t_line].l_rint)(c, tp);
156 }
157 
158 /*ARGSUSED*/
159 cnioctl(dev, cmd, addr, flag)
160 	dev_t dev;
161 	caddr_t addr;
162 {
163 	register struct tty *tp = &cons;
164 	int error;
165 
166 	if (consops && minor(dev) == 0)
167 		return ((*consops->d_ioctl)(dev, cmd, addr, flag));
168 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
169 	if (error >= 0)
170 		return (error);
171 	error = ttioctl(tp, cmd, addr, flag);
172 	if (error < 0)
173 		error = ENOTTY;
174 	return (error);
175 }
176 
177 int	consdone = 1;
178 /*
179  * Got a level-20 transmission interrupt -
180  * the LSI wants another character.  First,
181  * see if we can send something to the typewriter.
182  * If not, try the floppy.
183  */
184 /*ARGSUSED*/
185 cnxint(dev)
186 	dev_t dev;
187 {
188 	register struct tty *tp = &cons;
189 
190 	consdone++;
191 	tp->t_state &= ~TS_BUSY;
192 	if (tp->t_line)
193 		(*linesw[tp->t_line].l_start)(tp);
194 	else
195 		cnstart(tp);
196 #if VAX780
197 	if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0)
198 		conxfl();
199 #endif
200 }
201 
202 cnstart(tp)
203 	register struct tty *tp;
204 {
205 	register int c, s;
206 
207 	s = spl5();
208 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
209 		goto out;
210 	if (tp->t_outq.c_cc <= tp->t_lowat) {
211 		if (tp->t_state&TS_ASLEEP) {
212 			tp->t_state &= ~TS_ASLEEP;
213 			wakeup((caddr_t)&tp->t_outq);
214 		}
215 		if (tp->t_wsel) {
216 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
217 			tp->t_wsel = 0;
218 			tp->t_state &= ~TS_WCOLL;
219 		}
220 	}
221 	if (tp->t_outq.c_cc == 0)
222 		goto out;
223 	if (consdone == 0)
224 		goto out;
225 	c = getc(&tp->t_outq) & 0xff;
226 #ifdef notdef
227 	if (tp->t_cflag&PARENB && ((tp->t_cflag&CSIZE)==CS7)) {
228 		c &= 0177;
229 		c |= (tp->t_cflag&PARODD ? ~partab[c] : partab[c]) & 0200;
230 		}
231 #else
232 	if ((tp->t_cflag&CSIZE) == CS7) {
233 #ifdef notyet
234 		if (tp->t_cflag&PARENB) {
235 			if (tp->t_cflag&PARODD)
236 				c = (~(partab[c&0177])&0200)|(c&0177);
237 			else
238 				c = (partab[c&0177]&0200)|(c&0177);
239 		} else
240 #endif
241 			c &= 0177;
242 	}
243 #endif
244 	mtpr(TXDB, c);
245 	consdone = 0;
246 	tp->t_state |= TS_BUSY;
247 out:
248 	splx(s);
249 }
250 
251 /*
252  * Print a character on console.
253  * Attempts to save and restore device
254  * status.
255  */
256 cnputc(c)
257 	register int c;
258 {
259 	register int s, timo;
260 
261 	timo = 30000;
262 	/*
263 	 * Try waiting for the console tty to come ready,
264 	 * otherwise give up after a reasonable time.
265 	 */
266 	while ((mfpr(TXCS)&TXCS_RDY) == 0)
267 		if(--timo == 0)
268 			break;
269 	if (c == 0)
270 		return;
271 	s = mfpr(TXCS);
272 	mtpr(TXCS, 0);
273 	mtpr(TXDB, c&0xff);
274 	if (c == '\n')
275 		cnputc('\r');
276 	cnputc(0);
277 	mtpr(TXCS, s);
278 }
279 
280 #if (defined(KADB) || defined(GENERIC)) && !defined(lint)
281 /*
282  * Get character from console.
283  */
284 cngetc()
285 {
286 	register int c, s;
287 
288 	s = splhigh();
289 	while ((mfpr(RXCS)&RXCS_DONE) == 0 || (c = mfpr(RXDB)&0177) <= 0)
290 		;
291 	if (c == '\r')
292 		c = '\n';
293 	(void) splx(s);
294 	return (c);
295 }
296 #endif
297 
298 #ifdef KADB
299 cnpoll(onoff)
300 	int onoff;
301 {
302 
303 	cnpolling = onoff;
304 }
305 #endif
306