|
|
1.1 ! root 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.5 (Berkeley) 5/7/88 ! 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_state = TS_ISOPEN|TS_CARR_ON; ! 57: tp->t_flags = EVENP|ECHO|XTABS|CRMOD; ! 58: } ! 59: if (tp->t_state&TS_XCLUDE && u.u_uid != 0) ! 60: return (EBUSY); ! 61: mtpr(RXCS, mfpr(RXCS)|RXCS_IE); ! 62: mtpr(TXCS, mfpr(TXCS)|TXCS_IE); ! 63: return ((*linesw[tp->t_line].l_open)(dev, tp)); ! 64: } ! 65: ! 66: /*ARGSUSED*/ ! 67: cnclose(dev) ! 68: dev_t dev; ! 69: { ! 70: register struct tty *tp = &cons; ! 71: ! 72: if (consops && minor(dev) == 0) ! 73: return ((*consops->d_close)(dev)); ! 74: (*linesw[tp->t_line].l_close)(tp); ! 75: ttyclose(tp); ! 76: return (0); ! 77: } ! 78: ! 79: /*ARGSUSED*/ ! 80: cnread(dev, uio) ! 81: dev_t dev; ! 82: struct uio *uio; ! 83: { ! 84: register struct tty *tp = &cons; ! 85: ! 86: if (consops && minor(dev) == 0) ! 87: return ((*consops->d_read)(dev, uio)); ! 88: return ((*linesw[tp->t_line].l_read)(tp, uio)); ! 89: } ! 90: ! 91: /*ARGSUSED*/ ! 92: cnwrite(dev, uio) ! 93: dev_t dev; ! 94: struct uio *uio; ! 95: { ! 96: register struct tty *tp = &cons; ! 97: ! 98: if (minor(dev) == 0) { ! 99: if (constty && (constty->t_state & (TS_CARR_ON | TS_ISOPEN)) == ! 100: (TS_CARR_ON | TS_ISOPEN)) ! 101: tp = constty; ! 102: else if (consops) ! 103: return ((*consops->d_write)(dev, uio)); ! 104: } ! 105: return ((*linesw[tp->t_line].l_write)(tp, uio)); ! 106: } ! 107: ! 108: static int cnpolling = 0; ! 109: /* ! 110: * Got a level-20 receive interrupt - ! 111: * the LSI wants to give us a character. ! 112: * Catch the character, and see who it goes to. ! 113: */ ! 114: /*ARGSUSED*/ ! 115: cnrint(dev) ! 116: dev_t dev; ! 117: { ! 118: register int c; ! 119: register struct tty *tp; ! 120: ! 121: if (cnpolling) ! 122: return; ! 123: c = mfpr(RXDB); ! 124: if (c&RXDB_ID) { ! 125: #if VAX780 ! 126: if (cpu == VAX_780) ! 127: cnrfl(c); ! 128: #endif ! 129: return; ! 130: } ! 131: tp = &cons; ! 132: #ifdef KADB ! 133: if (!kdbrintr(c, tp)) ! 134: #endif ! 135: (*linesw[tp->t_line].l_rint)(c, tp); ! 136: } ! 137: ! 138: /*ARGSUSED*/ ! 139: cnioctl(dev, cmd, addr, flag) ! 140: dev_t dev; ! 141: caddr_t addr; ! 142: { ! 143: register struct tty *tp = &cons; ! 144: int error; ! 145: ! 146: if (consops && minor(dev) == 0) ! 147: return ((*consops->d_ioctl)(dev, cmd, addr, flag)); ! 148: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); ! 149: if (error >= 0) ! 150: return (error); ! 151: error = ttioctl(tp, cmd, addr, flag); ! 152: if (error < 0) ! 153: error = ENOTTY; ! 154: return (error); ! 155: } ! 156: ! 157: int consdone = 1; ! 158: /* ! 159: * Got a level-20 transmission interrupt - ! 160: * the LSI wants another character. First, ! 161: * see if we can send something to the typewriter. ! 162: * If not, try the floppy. ! 163: */ ! 164: /*ARGSUSED*/ ! 165: cnxint(dev) ! 166: dev_t dev; ! 167: { ! 168: register struct tty *tp = &cons; ! 169: ! 170: consdone++; ! 171: tp->t_state &= ~TS_BUSY; ! 172: if (tp->t_line) ! 173: (*linesw[tp->t_line].l_start)(tp); ! 174: else ! 175: cnstart(tp); ! 176: #if VAX780 ! 177: if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0) ! 178: conxfl(); ! 179: #endif ! 180: } ! 181: ! 182: cnstart(tp) ! 183: register struct tty *tp; ! 184: { ! 185: register int c, s; ! 186: ! 187: s = spl5(); ! 188: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) ! 189: goto out; ! 190: if (tp->t_outq.c_cc <= TTLOWAT(tp)) { ! 191: if (tp->t_state&TS_ASLEEP) { ! 192: tp->t_state &= ~TS_ASLEEP; ! 193: wakeup((caddr_t)&tp->t_outq); ! 194: } ! 195: if (tp->t_wsel) { ! 196: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); ! 197: tp->t_wsel = 0; ! 198: tp->t_state &= ~TS_WCOLL; ! 199: } ! 200: } ! 201: if (tp->t_outq.c_cc == 0) ! 202: goto out; ! 203: if (consdone == 0) ! 204: goto out; ! 205: c = getc(&tp->t_outq) & 0xff; ! 206: if ((tp->t_flags & (RAW|LITOUT)) == 0) { ! 207: if (c <= 0177) ! 208: c |= (partab[c] & 0200); ! 209: else { ! 210: timeout(ttrstrt, (caddr_t)tp, (c&0177)); ! 211: tp->t_state |= TS_TIMEOUT; ! 212: goto out; ! 213: } ! 214: } ! 215: mtpr(TXDB, c); ! 216: consdone = 0; ! 217: tp->t_state |= TS_BUSY; ! 218: out: ! 219: splx(s); ! 220: } ! 221: ! 222: /* ! 223: * Print a character on console. ! 224: * Attempts to save and restore device ! 225: * status. ! 226: */ ! 227: cnputc(c) ! 228: register int c; ! 229: { ! 230: register int s, timo; ! 231: ! 232: timo = 30000; ! 233: /* ! 234: * Try waiting for the console tty to come ready, ! 235: * otherwise give up after a reasonable time. ! 236: */ ! 237: while ((mfpr(TXCS)&TXCS_RDY) == 0) ! 238: if(--timo == 0) ! 239: break; ! 240: if (c == 0) ! 241: return; ! 242: s = mfpr(TXCS); ! 243: mtpr(TXCS, 0); ! 244: mtpr(TXDB, c&0xff); ! 245: if (c == '\n') ! 246: cnputc('\r'); ! 247: cnputc(0); ! 248: mtpr(TXCS, s); ! 249: } ! 250: ! 251: #if (defined(KADB) || defined(GENERIC)) && !defined(lint) ! 252: /* ! 253: * Get character from console. ! 254: */ ! 255: cngetc() ! 256: { ! 257: register int c, s; ! 258: ! 259: s = splhigh(); ! 260: while ((mfpr(RXCS)&RXCS_DONE) == 0 || (c = mfpr(RXDB)&0177) <= 0) ! 261: ; ! 262: if (c == '\r') ! 263: c = '\n'; ! 264: (void) splx(s); ! 265: return (c); ! 266: } ! 267: #endif ! 268: ! 269: #ifdef KADB ! 270: cnpoll(onoff) ! 271: int onoff; ! 272: { ! 273: ! 274: cnpolling = onoff; ! 275: } ! 276: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.