Commit | Line | Data |
---|---|---|
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 | */ | |
36 | struct cdevsw *consops = 0; | |
37 | struct tty *constty = 0; | |
9989d3ae BJ |
38 | struct tty cons; |
39 | int cnstart(); | |
40 | int ttrstrt(); | |
41 | char partab[]; | |
42 | ||
43 | /*ARGSUSED*/ | |
44 | cnopen(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 | 70 | cnclose(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 | 85 | cnread(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 | 98 | cnwrite(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 | 115 | static 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*/ | |
122 | cnrint(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*/ | |
159 | cnioctl(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 | 177 | int 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*/ | |
185 | cnxint(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 | 202 | cnstart(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 | 247 | out: |
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 | 256 | cnputc(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 | */ | |
284 | cngetc() | |
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 |
299 | cnpoll(onoff) |
300 | int onoff; | |
301 | { | |
302 | ||
303 | cnpolling = onoff; | |
304 | } | |
305 | #endif |