BSD 4_4 release
[unix-history] / usr / src / sys / vax / vax / cons.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
ad787160 6 * @(#)cons.c 7.12 (Berkeley) 5/16/91
da7c5cc6 7 */
9989d3ae
BJ
8
9/*
2660059c 10 * VAX console driver (and floppy interface)
9989d3ae 11 */
b28b3a13
KB
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"
cd3da95f 19
b28b3a13 20#include "../include/cpu.h"
1884f3f6 21#include "cons.h"
b28b3a13 22#include "../include/mtpr.h"
9989d3ae 23
233e2ac3
MK
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 */
36struct cdevsw *consops = 0;
37struct tty *constty = 0;
9989d3ae
BJ
38struct tty cons;
39int cnstart();
40int ttrstrt();
41char partab[];
42
43/*ARGSUSED*/
44cnopen(dev, flag)
cd3da95f 45 dev_t dev;
9989d3ae 46{
cd3da95f 47 register struct tty *tp = &cons;
9989d3ae 48
233e2ac3
MK
49 if (consops && minor(dev) == 0)
50 return ((*consops->d_open)(dev, flag));
9989d3ae 51 tp->t_oproc = cnstart;
941944c9 52 if ((tp->t_state&TS_ISOPEN) == 0) {
9989d3ae 53 ttychars(tp);
388009d0
KM
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;
941944c9 59 tp->t_state = TS_ISOPEN|TS_CARR_ON;
388009d0 60 ttsetwater(tp);
9989d3ae 61 }
2d876e2a
BJ
62 if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
63 return (EBUSY);
9989d3ae
BJ
64 mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
65 mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
2d876e2a 66 return ((*linesw[tp->t_line].l_open)(dev, tp));
9989d3ae
BJ
67}
68
69/*ARGSUSED*/
6af8803c 70cnclose(dev, flag, mode, p)
cd3da95f 71 dev_t dev;
6af8803c
MT
72 int flag, mode;
73 struct proc *p;
9989d3ae 74{
cd3da95f 75 register struct tty *tp = &cons;
9989d3ae 76
233e2ac3 77 if (consops && minor(dev) == 0)
6af8803c
MT
78 return ((*consops->d_close)(dev, flag, mode, p));
79 (*linesw[tp->t_line].l_close)(tp, flag);
404358a8 80 ttyclose(tp);
011ca463 81 return (0);
9989d3ae
BJ
82}
83
84/*ARGSUSED*/
388009d0 85cnread(dev, uio, flag)
cd3da95f
BJ
86 dev_t dev;
87 struct uio *uio;
388009d0 88 int flag;
9989d3ae 89{
cd3da95f 90 register struct tty *tp = &cons;
9989d3ae 91
233e2ac3 92 if (consops && minor(dev) == 0)
388009d0
KM
93 return ((*consops->d_read)(dev, uio, flag));
94 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
9989d3ae
BJ
95}
96
97/*ARGSUSED*/
388009d0 98cnwrite(dev, uio, flag)
406ddcbe
BJ
99 dev_t dev;
100 struct uio *uio;
388009d0 101 int flag;
9989d3ae 102{
cd3da95f 103 register struct tty *tp = &cons;
9989d3ae 104
233e2ac3 105 if (minor(dev) == 0) {
6aa1dcc9
MK
106 if (constty && (constty->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
107 (TS_CARR_ON | TS_ISOPEN))
233e2ac3
MK
108 tp = constty;
109 else if (consops)
388009d0 110 return ((*consops->d_write)(dev, uio, flag));
233e2ac3 111 }
388009d0 112 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
9989d3ae
BJ
113}
114
233e2ac3 115static int cnpolling = 0;
9989d3ae
BJ
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*/
122cnrint(dev)
cd3da95f 123 dev_t dev;
9989d3ae
BJ
124{
125 register int c;
404358a8 126 register struct tty *tp;
9989d3ae 127
233e2ac3
MK
128 if (cnpolling)
129 return;
bfb151c8 130 c = mfpr(RXDB);
404358a8 131 if (c&RXDB_ID) {
58c63952
BJ
132#if VAX780
133 if (cpu == VAX_780)
134 cnrfl(c);
194dae1d 135#endif
404358a8
BJ
136 return;
137 }
bfb151c8 138 c &= 0xff;
404358a8 139 tp = &cons;
9a0de372 140#ifdef KADB
233e2ac3
MK
141 if (!kdbrintr(c, tp))
142#endif
388009d0 143 if ((tp->t_cflag&CSIZE) == CS7) {
de47fa58 144#ifdef notyet
388009d0
KM
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 }
de47fa58 152#endif
388009d0
KM
153 c &= ~0200;
154 }
404358a8 155 (*linesw[tp->t_line].l_rint)(c, tp);
9989d3ae
BJ
156}
157
158/*ARGSUSED*/
159cnioctl(dev, cmd, addr, flag)
cd3da95f
BJ
160 dev_t dev;
161 caddr_t addr;
9989d3ae 162{
cd3da95f 163 register struct tty *tp = &cons;
2d876e2a 164 int error;
9989d3ae 165
233e2ac3
MK
166 if (consops && minor(dev) == 0)
167 return ((*consops->d_ioctl)(dev, cmd, addr, flag));
2d876e2a
BJ
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);
9989d3ae
BJ
175}
176
194dae1d 177int consdone = 1;
404358a8
BJ
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*/
185cnxint(dev)
cd3da95f 186 dev_t dev;
404358a8 187{
cd3da95f 188 register struct tty *tp = &cons;
404358a8 189
194dae1d 190 consdone++;
941944c9 191 tp->t_state &= ~TS_BUSY;
404358a8
BJ
192 if (tp->t_line)
193 (*linesw[tp->t_line].l_start)(tp);
194 else
195 cnstart(tp);
58c63952 196#if VAX780
941944c9 197 if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0)
404358a8 198 conxfl();
194dae1d 199#endif
404358a8
BJ
200}
201
9989d3ae 202cnstart(tp)
cd3da95f 203 register struct tty *tp;
9989d3ae 204{
cd3da95f 205 register int c, s;
404358a8
BJ
206
207 s = spl5();
941944c9 208 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
404358a8 209 goto out;
5646916d 210 if (tp->t_outq.c_cc <= tp->t_lowat) {
941944c9
BJ
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 }
404358a8
BJ
220 }
221 if (tp->t_outq.c_cc == 0)
222 goto out;
194dae1d 223 if (consdone == 0)
30a4fcb9 224 goto out;
233e2ac3 225 c = getc(&tp->t_outq) & 0xff;
388009d0
KM
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;
233e2ac3 230 }
388009d0
KM
231#else
232 if ((tp->t_cflag&CSIZE) == CS7) {
de47fa58 233#ifdef notyet
388009d0
KM
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
de47fa58 240#endif
388009d0 241 c &= 0177;
9989d3ae 242 }
388009d0 243#endif
233e2ac3 244 mtpr(TXDB, c);
30a4fcb9 245 consdone = 0;
941944c9 246 tp->t_state |= TS_BUSY;
2660059c 247out:
404358a8 248 splx(s);
9989d3ae
BJ
249}
250
9989d3ae
BJ
251/*
252 * Print a character on console.
253 * Attempts to save and restore device
254 * status.
9989d3ae 255 */
ec91f161 256cnputc(c)
cd3da95f 257 register int c;
9989d3ae 258{
cd3da95f 259 register int s, timo;
9989d3ae 260
9989d3ae
BJ
261 timo = 30000;
262 /*
263 * Try waiting for the console tty to come ready,
264 * otherwise give up after a reasonable time.
265 */
cd3da95f 266 while ((mfpr(TXCS)&TXCS_RDY) == 0)
9989d3ae
BJ
267 if(--timo == 0)
268 break;
cd3da95f 269 if (c == 0)
9989d3ae
BJ
270 return;
271 s = mfpr(TXCS);
ec91f161 272 mtpr(TXCS, 0);
9989d3ae 273 mtpr(TXDB, c&0xff);
cd3da95f 274 if (c == '\n')
ec91f161
BJ
275 cnputc('\r');
276 cnputc(0);
9989d3ae
BJ
277 mtpr(TXCS, s);
278}
233e2ac3 279
9a0de372 280#if (defined(KADB) || defined(GENERIC)) && !defined(lint)
233e2ac3
MK
281/*
282 * Get character from console.
283 */
284cngetc()
285{
286 register int c, s;
287
288 s = splhigh();
011ca463 289 while ((mfpr(RXCS)&RXCS_DONE) == 0 || (c = mfpr(RXDB)&0177) <= 0)
233e2ac3
MK
290 ;
291 if (c == '\r')
292 c = '\n';
293 (void) splx(s);
294 return (c);
295}
296#endif
297
9a0de372 298#ifdef KADB
233e2ac3
MK
299cnpoll(onoff)
300 int onoff;
301{
302
303 cnpolling = onoff;
304}
305#endif