/* * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)cons.c 7.1 (Berkeley) 6/5/86 */ /* * VAX console driver (and floppy interface) */ #include "param.h" #include "conf.h" #include "dir.h" #include "user.h" #include "proc.h" #include "ioctl.h" #include "tty.h" #include "systm.h" #include "uio.h" #include "cpu.h" #include "cons.h" #include "mtpr.h" struct tty cons; int cnstart(); int ttrstrt(); char partab[]; /*ARGSUSED*/ cnopen(dev, flag) dev_t dev; { register struct tty *tp = &cons; tp->t_oproc = cnstart; if ((tp->t_state&TS_ISOPEN) == 0) { ttychars(tp); tp->t_state = TS_ISOPEN|TS_CARR_ON; tp->t_flags = EVENP|ECHO|XTABS|CRMOD; } if (tp->t_state&TS_XCLUDE && u.u_uid != 0) return (EBUSY); mtpr(RXCS, mfpr(RXCS)|RXCS_IE); mtpr(TXCS, mfpr(TXCS)|TXCS_IE); return ((*linesw[tp->t_line].l_open)(dev, tp)); } /*ARGSUSED*/ cnclose(dev) dev_t dev; { register struct tty *tp = &cons; (*linesw[tp->t_line].l_close)(tp); ttyclose(tp); } /*ARGSUSED*/ cnread(dev, uio) dev_t dev; struct uio *uio; { register struct tty *tp = &cons; return ((*linesw[tp->t_line].l_read)(tp, uio)); } /*ARGSUSED*/ cnwrite(dev, uio) dev_t dev; struct uio *uio; { register struct tty *tp = &cons; return ((*linesw[tp->t_line].l_write)(tp, uio)); } /* * Got a level-20 receive interrupt - * the LSI wants to give us a character. * Catch the character, and see who it goes to. */ /*ARGSUSED*/ cnrint(dev) dev_t dev; { register int c; register struct tty *tp; c = mfpr(RXDB); if (c&RXDB_ID) { #if VAX780 if (cpu == VAX_780) cnrfl(c); #endif return; } tp = &cons; (*linesw[tp->t_line].l_rint)(c, tp); } /*ARGSUSED*/ cnioctl(dev, cmd, addr, flag) dev_t dev; caddr_t addr; { register struct tty *tp = &cons; int error; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); if (error >= 0) return (error); error = ttioctl(tp, cmd, addr, flag); if (error < 0) error = ENOTTY; return (error); } int consdone = 1; /* * Got a level-20 transmission interrupt - * the LSI wants another character. First, * see if we can send something to the typewriter. * If not, try the floppy. */ /*ARGSUSED*/ cnxint(dev) dev_t dev; { register struct tty *tp = &cons; consdone++; tp->t_state &= ~TS_BUSY; if (tp->t_line) (*linesw[tp->t_line].l_start)(tp); else cnstart(tp); #if VAX780 if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0) conxfl(); #endif } cnstart(tp) register struct tty *tp; { register int c, s; s = spl5(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; if (tp->t_outq.c_cc <= TTLOWAT(tp)) { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } if (tp->t_wsel) { selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); tp->t_wsel = 0; tp->t_state &= ~TS_WCOLL; } } if (tp->t_outq.c_cc == 0) goto out; if (consdone == 0) return; c = getc(&tp->t_outq); if (tp->t_flags&(RAW|LITOUT)) mtpr(TXDB, c&0xff); else if (c <= 0177) mtpr(TXDB, (c | (partab[c]&0200))&0xff); else { timeout(ttrstrt, (caddr_t)tp, (c&0177)); tp->t_state |= TS_TIMEOUT; goto out; } consdone = 0; tp->t_state |= TS_BUSY; out: splx(s); } /* * Print a character on console. * Attempts to save and restore device * status. */ cnputc(c) register int c; { register int s, timo; timo = 30000; /* * Try waiting for the console tty to come ready, * otherwise give up after a reasonable time. */ while ((mfpr(TXCS)&TXCS_RDY) == 0) if(--timo == 0) break; if (c == 0) return; s = mfpr(TXCS); mtpr(TXCS, 0); mtpr(TXDB, c&0xff); if (c == '\n') cnputc('\r'); cnputc(0); mtpr(TXCS, s); }