xref: /original-bsd/sys/vax/vax/cons.c (revision 6ab384a1)
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.10 (Berkeley) 08/27/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);
129 	if (c&RXDB_ID) {
130 #if VAX780
131 		if (cpu == VAX_780)
132 			cnrfl(c);
133 #endif
134 		return;
135 	}
136 	c &= 0xff;
137 	tp = &cons;
138 #ifdef KADB
139 	if (!kdbrintr(c, tp))
140 #endif
141 	if ((tp->t_cflag&CSIZE) == CS7) {
142 #ifdef notyet
143 		if (tp->t_cflag&PARENB) {
144 			if ((tp->t_cflag&PARODD) &&
145 			    (partab[c&0177]&0200) == (c&0200))
146 				c |= TTY_PE;
147 			else if ((partab[c&0177]&0200) != (c&0200))
148 				c |= TTY_PE;
149 		}
150 #endif
151 		c &= ~0200;
152 	}
153 	(*linesw[tp->t_line].l_rint)(c, tp);
154 }
155 
156 /*ARGSUSED*/
157 cnioctl(dev, cmd, addr, flag)
158 	dev_t dev;
159 	caddr_t addr;
160 {
161 	register struct tty *tp = &cons;
162 	int error;
163 
164 	if (consops && minor(dev) == 0)
165 		return ((*consops->d_ioctl)(dev, cmd, addr, flag));
166 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
167 	if (error >= 0)
168 		return (error);
169 	error = ttioctl(tp, cmd, addr, flag);
170 	if (error < 0)
171 		error = ENOTTY;
172 	return (error);
173 }
174 
175 int	consdone = 1;
176 /*
177  * Got a level-20 transmission interrupt -
178  * the LSI wants another character.  First,
179  * see if we can send something to the typewriter.
180  * If not, try the floppy.
181  */
182 /*ARGSUSED*/
183 cnxint(dev)
184 	dev_t dev;
185 {
186 	register struct tty *tp = &cons;
187 
188 	consdone++;
189 	tp->t_state &= ~TS_BUSY;
190 	if (tp->t_line)
191 		(*linesw[tp->t_line].l_start)(tp);
192 	else
193 		cnstart(tp);
194 #if VAX780
195 	if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0)
196 		conxfl();
197 #endif
198 }
199 
200 cnstart(tp)
201 	register struct tty *tp;
202 {
203 	register int c, s;
204 
205 	s = spl5();
206 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
207 		goto out;
208 	if (tp->t_outq.c_cc <= tp->t_lowat) {
209 		if (tp->t_state&TS_ASLEEP) {
210 			tp->t_state &= ~TS_ASLEEP;
211 			wakeup((caddr_t)&tp->t_outq);
212 		}
213 		if (tp->t_wsel) {
214 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
215 			tp->t_wsel = 0;
216 			tp->t_state &= ~TS_WCOLL;
217 		}
218 	}
219 	if (tp->t_outq.c_cc == 0)
220 		goto out;
221 	if (consdone == 0)
222 		goto out;
223 	c = getc(&tp->t_outq) & 0xff;
224 #ifdef notdef
225 	if (tp->t_cflag&PARENB && ((tp->t_cflag&CSIZE)==CS7)) {
226 		c &= 0177;
227 		c |= (tp->t_cflag&PARODD ? ~partab[c] : partab[c]) & 0200;
228 		}
229 #else
230 	if ((tp->t_cflag&CSIZE) == CS7) {
231 #ifdef notyet
232 		if (tp->t_cflag&PARENB) {
233 			if (tp->t_cflag&PARODD)
234 				c = (~(partab[c&0177])&0200)|(c&0177);
235 			else
236 				c = (partab[c&0177]&0200)|(c&0177);
237 		} else
238 #endif
239 			c &= 0177;
240 	}
241 #endif
242 	mtpr(TXDB, c);
243 	consdone = 0;
244 	tp->t_state |= TS_BUSY;
245 out:
246 	splx(s);
247 }
248 
249 /*
250  * Print a character on console.
251  * Attempts to save and restore device
252  * status.
253  */
254 cnputc(c)
255 	register int c;
256 {
257 	register int s, timo;
258 
259 	timo = 30000;
260 	/*
261 	 * Try waiting for the console tty to come ready,
262 	 * otherwise give up after a reasonable time.
263 	 */
264 	while ((mfpr(TXCS)&TXCS_RDY) == 0)
265 		if(--timo == 0)
266 			break;
267 	if (c == 0)
268 		return;
269 	s = mfpr(TXCS);
270 	mtpr(TXCS, 0);
271 	mtpr(TXDB, c&0xff);
272 	if (c == '\n')
273 		cnputc('\r');
274 	cnputc(0);
275 	mtpr(TXCS, s);
276 }
277 
278 #if (defined(KADB) || defined(GENERIC)) && !defined(lint)
279 /*
280  * Get character from console.
281  */
282 cngetc()
283 {
284 	register int c, s;
285 
286 	s = splhigh();
287 	while ((mfpr(RXCS)&RXCS_DONE) == 0 || (c = mfpr(RXDB)&0177) <= 0)
288 		;
289 	if (c == '\r')
290 		c = '\n';
291 	(void) splx(s);
292 	return (c);
293 }
294 #endif
295 
296 #ifdef KADB
297 cnpoll(onoff)
298 	int onoff;
299 {
300 
301 	cnpolling = onoff;
302 }
303 #endif
304