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.8 (Berkeley) 09/05/89 7 */ 8 9 /* 10 * VAX console driver (and floppy interface) 11 */ 12 #include "param.h" 13 #include "conf.h" 14 #include "dir.h" 15 #include "user.h" 16 #include "proc.h" 17 #include "ioctl.h" 18 #include "tty.h" 19 #include "systm.h" 20 #include "uio.h" 21 22 #include "cpu.h" 23 #include "cons.h" 24 #include "mtpr.h" 25 26 /* 27 * On some machines (e.g. MicroVAX), a secondary console 28 * such as a display may supercede the standard serial console. 29 * On such machines, consops will be set to point to the cdevsw 30 * entry for the secondary console, and the standard console device 31 * (minor number 0) will be redirected. Other minor numbers still 32 * refer to the standard console serial line. 33 * 34 * Also, console output may be redirected to another tty 35 * (e.g. a window); if so, constty will point to the current 36 * virtual console. 37 */ 38 struct cdevsw *consops = 0; 39 struct tty *constty = 0; 40 struct tty cons; 41 int cnstart(); 42 int ttrstrt(); 43 char partab[]; 44 45 /*ARGSUSED*/ 46 cnopen(dev, flag) 47 dev_t dev; 48 { 49 register struct tty *tp = &cons; 50 51 if (consops && minor(dev) == 0) 52 return ((*consops->d_open)(dev, flag)); 53 tp->t_oproc = cnstart; 54 if ((tp->t_state&TS_ISOPEN) == 0) { 55 ttychars(tp); 56 tp->t_iflag = TTYDEF_IFLAG|ICRNL; 57 tp->t_oflag = TTYDEF_OFLAG|OPOST|ONLCR; 58 tp->t_lflag = TTYDEF_LFLAG; 59 tp->t_cflag = CS8|CREAD; 60 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 61 tp->t_state = TS_ISOPEN|TS_CARR_ON; 62 ttsetwater(tp); 63 } 64 if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 65 return (EBUSY); 66 mtpr(RXCS, mfpr(RXCS)|RXCS_IE); 67 mtpr(TXCS, mfpr(TXCS)|TXCS_IE); 68 return ((*linesw[tp->t_line].l_open)(dev, tp)); 69 } 70 71 /*ARGSUSED*/ 72 cnclose(dev) 73 dev_t dev; 74 { 75 register struct tty *tp = &cons; 76 77 if (consops && minor(dev) == 0) 78 return ((*consops->d_close)(dev)); 79 (*linesw[tp->t_line].l_close)(tp); 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)&0xff; 131 if (c&RXDB_ID) { 132 #if VAX780 133 if (cpu == VAX_780) 134 cnrfl(c); 135 #endif 136 return; 137 } 138 tp = &cons; 139 #ifdef KADB 140 if (!kdbrintr(c, tp)) 141 #endif 142 if ((tp->t_cflag&CSIZE) == CS7) { 143 #ifdef notyet 144 if (tp->t_cflag&PARENB) { 145 if ((tp->t_cflag&PARODD) && 146 (partab[c&0177]&0200) == (c&0200)) 147 c |= TTY_PE; 148 else if ((partab[c&0177]&0200) != (c&0200)) 149 c |= TTY_PE; 150 } 151 #endif 152 c &= ~0200; 153 } 154 (*linesw[tp->t_line].l_rint)(c, tp); 155 } 156 157 /*ARGSUSED*/ 158 cnioctl(dev, cmd, addr, flag) 159 dev_t dev; 160 caddr_t addr; 161 { 162 register struct tty *tp = &cons; 163 int error; 164 165 if (consops && minor(dev) == 0) 166 return ((*consops->d_ioctl)(dev, cmd, addr, flag)); 167 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 168 if (error >= 0) 169 return (error); 170 error = ttioctl(tp, cmd, addr, flag); 171 if (error < 0) 172 error = ENOTTY; 173 return (error); 174 } 175 176 int consdone = 1; 177 /* 178 * Got a level-20 transmission interrupt - 179 * the LSI wants another character. First, 180 * see if we can send something to the typewriter. 181 * If not, try the floppy. 182 */ 183 /*ARGSUSED*/ 184 cnxint(dev) 185 dev_t dev; 186 { 187 register struct tty *tp = &cons; 188 189 consdone++; 190 tp->t_state &= ~TS_BUSY; 191 if (tp->t_line) 192 (*linesw[tp->t_line].l_start)(tp); 193 else 194 cnstart(tp); 195 #if VAX780 196 if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0) 197 conxfl(); 198 #endif 199 } 200 201 cnstart(tp) 202 register struct tty *tp; 203 { 204 register int c, s; 205 206 s = spl5(); 207 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 208 goto out; 209 if (tp->t_outq.c_cc <= tp->t_lowat) { 210 if (tp->t_state&TS_ASLEEP) { 211 tp->t_state &= ~TS_ASLEEP; 212 wakeup((caddr_t)&tp->t_outq); 213 } 214 if (tp->t_wsel) { 215 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 216 tp->t_wsel = 0; 217 tp->t_state &= ~TS_WCOLL; 218 } 219 } 220 if (tp->t_outq.c_cc == 0) 221 goto out; 222 if (consdone == 0) 223 goto out; 224 c = getc(&tp->t_outq) & 0xff; 225 #ifdef notdef 226 if (tp->t_cflag&PARENB && ((tp->t_cflag&CSIZE)==CS7)) { 227 c &= 0177; 228 c |= (tp->t_cflag&PARODD ? ~partab[c] : partab[c]) & 0200; 229 } 230 #else 231 if ((tp->t_cflag&CSIZE) == CS7) { 232 #ifdef notyet 233 if (tp->t_cflag&PARENB) { 234 if (tp->t_cflag&PARODD) 235 c = (~(partab[c&0177])&0200)|(c&0177); 236 else 237 c = (partab[c&0177]&0200)|(c&0177); 238 } else 239 #endif 240 c &= 0177; 241 } 242 #endif 243 mtpr(TXDB, c); 244 consdone = 0; 245 tp->t_state |= TS_BUSY; 246 out: 247 splx(s); 248 } 249 250 /* 251 * Print a character on console. 252 * Attempts to save and restore device 253 * status. 254 */ 255 cnputc(c) 256 register int c; 257 { 258 register int s, timo; 259 260 timo = 30000; 261 /* 262 * Try waiting for the console tty to come ready, 263 * otherwise give up after a reasonable time. 264 */ 265 while ((mfpr(TXCS)&TXCS_RDY) == 0) 266 if(--timo == 0) 267 break; 268 if (c == 0) 269 return; 270 s = mfpr(TXCS); 271 mtpr(TXCS, 0); 272 mtpr(TXDB, c&0xff); 273 if (c == '\n') 274 cnputc('\r'); 275 cnputc(0); 276 mtpr(TXCS, s); 277 } 278 279 #if (defined(KADB) || defined(GENERIC)) && !defined(lint) 280 /* 281 * Get character from console. 282 */ 283 cngetc() 284 { 285 register int c, s; 286 287 s = splhigh(); 288 while ((mfpr(RXCS)&RXCS_DONE) == 0 || (c = mfpr(RXDB)&0177) <= 0) 289 ; 290 if (c == '\r') 291 c = '\n'; 292 (void) splx(s); 293 return (c); 294 } 295 #endif 296 297 #ifdef KADB 298 cnpoll(onoff) 299 int onoff; 300 { 301 302 cnpolling = onoff; 303 } 304 #endif 305