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.11 (Berkeley) 12/16/90 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) 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