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