pass flags from device close to l_close
[unix-history] / usr / src / sys / tahoe / tahoe / cons.c
index 9e9e891..ab4179a 100644 (file)
@@ -1,4 +1,4 @@
-/*     cons.c  1.4     86/11/25        */
+/*     cons.c  7.9     91/05/16        */
 
 /*
  * Tahoe console processor driver
 
 /*
  * Tahoe console processor driver
  * Minor 1 is the console terminal.
  * Minor 2 is the remote line trminal.
  */
  * Minor 1 is the console terminal.
  * Minor 2 is the remote line trminal.
  */
-#include "param.h"
-#include "conf.h"
-#include "dir.h"
-#include "ioctl.h"
-#include "user.h"
-#include "proc.h"
-#include "tty.h"
-#include "uio.h"
-#include "callout.h"
-#include "systm.h"
-
-#include "../tahoe/cp.h"
-#include "../tahoe/cpu.h"
-#include "../tahoe/mtpr.h"
+#include "sys/param.h"
+#include "sys/conf.h"
+#include "sys/file.h"
+#include "sys/ioctl.h"
+#include "sys/user.h"
+#include "sys/proc.h"
+#include "sys/tty.h"
+#include "sys/callout.h"
+#include "sys/systm.h"
+#include "sys/kernel.h"
+#include "sys/syslog.h"
+
+#include "cp.h"
+#include "../include/cpu.h"
+#include "../include/mtpr.h"
 
 int    cnrestart();
 int    timeout();
 
 
 int    cnrestart();
 int    timeout();
 
-struct tty cons;
 struct tty CPtty;
 struct tty CPtty;
+struct tty cons;
 struct tty RLtty;
 struct tty RLtty;
-struct tty *constty[3] = { &CPtty, &cons, &RLtty };
+struct tty *cntty[3] = { &CPtty, &cons, &RLtty };
+
+struct tty *constty = 0;       /* virtual console */
+
 struct consoftc {
 struct consoftc {
-       char    cs_lastc;       /* last char sent */
-       int     cs_flags;
+       char    cs_flags;
 #define        CSF_ACTIVE      0x1     /* timeout active */
 #define        CSF_ACTIVE      0x1     /* timeout active */
-#define        CSF_RETRY       0x2     /* try again at a later time */
-#define        CSF_POLLING     0x4     /* polling for input */
+#define        CSF_POLLING     0x2     /* polling for input */
+       char    cs_lastc;       /* last char sent */
+       int     cs_timo;        /* timeouts since interrupt */
+       u_long  cs_wedgecnt;    /* times restarted */
 } consoftc[3];
 } consoftc[3];
+
+struct speedtab cnspeedtab[] = {
+       9600,   13,
+       4800,   12,
+       2400,   11,
+       1800,   10,
+       1200,   9,
+       600,    8,
+       300,    7,
+       200,    6,
+       150,    5,
+       134,    4,
+       110,    3,
+       75,     2,
+       50,     1,
+       0,      13,
+       -1,     -1,
+};
+
+/*
+ * We check the console periodically to make sure
+ * that it hasn't wedged.  Unfortunately, if an XOFF
+ * is typed on the console, that can't be distinguished
+ * from more catastrophic failure.
+ */
+#define        CN_TIMERVAL     (hz)            /* frequency at which to check cons */
+#define        CN_TIMO         (2*60)          /* intervals to allow for output char */
+
 struct cpdcb_o consout[3] = { 
 struct cpdcb_o consout[3] = { 
-       /*      unit,           cmd,count, buf */
-       { (char)(CPTAKE | CPDONE),0,   0 },
-       { (char)(CPTAKE | CPDONE),0,   0 },
-       { (char)(CPTAKE | CPDONE),0,   0 }
+       { CPTAKE|CPDONE }, { CPTAKE|CPDONE }, { CPTAKE|CPDONE }
 };
 struct cpdcb_i consin[3] = {
 };
 struct cpdcb_i consin[3] = {
-       /*      unit,           cmd,count, buf */
-       { (char)(CPTAKE | CPDONE),0,   0 },
-       { (char)(CPTAKE | CPDONE),0,   0 },
-       { (char)(CPTAKE | CPDONE),0,   0 }
+       { CPTAKE|CPDONE }, { CPTAKE|CPDONE }, { CPTAKE|CPDONE }
 };
 };
-struct cphdr *lasthdr;
+struct cphdr *cnlast;
 
 int    cnstart();
 int    ttrstrt();
 char   partab[];
 
 
 int    cnstart();
 int    ttrstrt();
 char   partab[];
 
+/*
+ * Wait for CP to accept last CP command sent
+ * before setting up next command.
+ */
+#define        waitforlast(timo) { \
+       if (cnlast) { \
+               (timo) = 10000; \
+               do \
+                       uncache((char *)&cnlast->cp_unit); \
+               while ((cnlast->cp_unit&CPTAKE) == 0 && --(timo)); \
+       } \
+}
+
 /*ARGSUSED*/
 cnopen(dev, flag)
        dev_t dev;
 {
        register struct tty *tp;
        int unit = minor(dev);
 /*ARGSUSED*/
 cnopen(dev, flag)
        dev_t dev;
 {
        register struct tty *tp;
        int unit = minor(dev);
+       int cnparams();
 
        if (unit > CPREMOT) 
 
        if (unit > CPREMOT) 
-               return (EEXIST);
-       tp = constty[unit];
+               return (ENXIO);
+       tp = cntty[unit];
        if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
                return (EBUSY);
        cnpostread(unit);               /* post request for input */
        tp->t_oproc = cnstart;
        if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
                return (EBUSY);
        cnpostread(unit);               /* post request for input */
        tp->t_oproc = cnstart;
+       tp->t_param = cnparams;
        tp->t_dev = dev;
        if ((tp->t_state&TS_ISOPEN) == 0) {
                ttychars(tp);
        tp->t_dev = dev;
        if ((tp->t_state&TS_ISOPEN) == 0) {
                ttychars(tp);
+               tp->t_iflag = TTYDEF_IFLAG|ICRNL;
+               tp->t_oflag = TTYDEF_OFLAG|OPOST|ONLCR;
+               tp->t_lflag = TTYDEF_LFLAG;
+               tp->t_cflag = CS8|CREAD;
+               tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
                tp->t_state = TS_ISOPEN|TS_CARR_ON;
                tp->t_state = TS_ISOPEN|TS_CARR_ON;
-               tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
+               cnparams(tp, &tp->t_termios);
+               ttsetwater(tp);
        }
        return ((*linesw[tp->t_line].l_open)(dev, tp));
 }
        }
        return ((*linesw[tp->t_line].l_open)(dev, tp));
 }
@@ -82,50 +130,50 @@ cnpostread(unit)
        int unit;
 {
        register struct cpdcb_i *cin;
        int unit;
 {
        register struct cpdcb_i *cin;
+       register int timo;
 
 
-       if (lasthdr != (struct cphdr *)0) {
-               register int timo;
-
-               timo = 10000;
-               uncache(&lasthdr->cp_unit);
-               while ((lasthdr->cp_unit&CPTAKE) == 0 && --timo)
-                       uncache(&lasthdr->cp_unit);
-       }
+       waitforlast(timo);
        cin = &consin[unit];
        cin->cp_hdr.cp_unit = unit;
        cin->cp_hdr.cp_comm = CPREAD;
        cin->cp_hdr.cp_count = 1;       /* Get ready for input */
        cin = &consin[unit];
        cin->cp_hdr.cp_unit = unit;
        cin->cp_hdr.cp_comm = CPREAD;
        cin->cp_hdr.cp_count = 1;       /* Get ready for input */
-       mtpr(CPMDCB, cin);
-       lasthdr = (struct cphdr *)cin;
+       mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)cin));
+       cnlast = &cin->cp_hdr;
 }
 
 }
 
-cnclose(dev)
+cnclose(dev, flag, mode, p)
        dev_t dev;
        dev_t dev;
+       int flag, mode;
+       struct proc *p;
 {
 {
-       register struct tty *tp = constty[minor(dev)];
+       register struct tty *tp = cntty[minor(dev)];
 
 
-       (*linesw[tp->t_line].l_close)(tp);
+       (*linesw[tp->t_line].l_close)(tp, flag);
        ttyclose(tp);
 }
 
 /*ARGSUSED*/
        ttyclose(tp);
 }
 
 /*ARGSUSED*/
-cnread(dev, uio)
+cnread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 {
        dev_t dev;
        struct uio *uio;
 {
-       struct tty *tp = constty[minor(dev)];
+       struct tty *tp = cntty[minor(dev)];
 
 
-       return ((*linesw[tp->t_line].l_read)(tp, uio));
+       return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-cnwrite(dev, uio)
+cnwrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 {
        dev_t dev;
        struct uio *uio;
 {
-       struct tty *tp = constty[minor(dev)];
+       register struct tty *tp = cntty[minor(dev)];
 
 
-       return ((*linesw[tp->t_line].l_write)(tp, uio));
+       if (tp == &cons && constty &&
+           (constty->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
+           (TS_CARR_ON | TS_ISOPEN))
+               tp = constty;
+       return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
 
 /*
 }
 
 /*
@@ -136,9 +184,9 @@ cnwrite(dev, uio)
 cnrint(dev)
        dev_t dev;
 {
 cnrint(dev)
        dev_t dev;
 {
-       register int c, timo;
+       register int unit, timo;
        register struct tty *tp;
        register struct tty *tp;
-       int unit;
+       int c;
 
        unit = minor(dev);
        if (!intenable || consoftc[unit].cs_flags&CSF_POLLING)
 
        unit = minor(dev);
        if (!intenable || consoftc[unit].cs_flags&CSF_POLLING)
@@ -146,34 +194,28 @@ cnrint(dev)
        /* make sure we dont take it from cache */
        uncache(&consin[unit].cpi_buf[0]);
        c = consin[unit].cpi_buf[0];
        /* make sure we dont take it from cache */
        uncache(&consin[unit].cpi_buf[0]);
        c = consin[unit].cpi_buf[0];
-       /*
-        * Wait about 5 milli for last CPMDCB to be read by CP,
-        * otherwise give up
-        */
-       timo = 10000;
-       uncache(&lasthdr->cp_unit);
-       while ((lasthdr->cp_unit&CPTAKE) == 0  && --timo)
-               uncache(&lasthdr->cp_unit);
-       uncache(&lasthdr->cp_unit);
-       if (lasthdr->cp_unit&CPTAKE) {
-               consin[unit].cp_hdr.cp_unit = unit;
-                       /* This resets status bits */
-               mtpr(CPMDCB, &consin[unit]); /* Ready for new character */
-               lasthdr = (struct cphdr *)&consin[unit];
-               tp = constty[unit];
-#ifdef KDB
-               if (unit == CPCONS && kdbrintr(c, tp))
-                       return;
+       waitforlast(timo);
+       /* This resets status bits */
+       consin[unit].cp_hdr.cp_unit = unit;
+       /* Ready for new character */
+       mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)&consin[unit]));
+       cnlast = &consin[unit].cp_hdr;
+
+       tp = cntty[unit];
+       if ((tp->t_cflag&CSIZE) != CS8)
+               c &= 0177;
+#ifdef KADB
+       if (unit == CPCONS && kdbrintr(c, tp))
+               return;
 #endif
 #endif
-               (*linesw[tp->t_line].l_rint)(c, tp);
-       }
+       (*linesw[tp->t_line].l_rint)(c & 0377, tp);
 }
 
 cnioctl(dev, cmd, addr, flag)
        dev_t dev;
        caddr_t addr;
 {
 }
 
 cnioctl(dev, cmd, addr, flag)
        dev_t dev;
        caddr_t addr;
 {
-       register struct tty *tp = constty[minor(dev)];
+       register struct tty *tp = cntty[minor(dev)];
        register error;
  
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        register error;
  
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
@@ -181,12 +223,10 @@ cnioctl(dev, cmd, addr, flag)
                return error;
        if ((error = ttioctl(tp, cmd, addr, flag)) < 0)
                error = ENOTTY;
                return error;
        if ((error = ttioctl(tp, cmd, addr, flag)) < 0)
                error = ENOTTY;
-       else if (cmd == TIOCSETP || cmd == TIOCSETN)
-               cnparams(tp);
        return (error);
 }
 
        return (error);
 }
 
-int    consintr = 1;
+extern int consintr;
 /*
  * Got a console transmission interrupt -
  * the console processor wants another character.
 /*
  * Got a console transmission interrupt -
  * the console processor wants another character.
@@ -203,9 +243,9 @@ cnxint(dev)
 #ifdef CPPERF
        scope_in(unit == CPCONS ? 1 : 2);
 #endif
 #ifdef CPPERF
        scope_in(unit == CPCONS ? 1 : 2);
 #endif
-       tp = constty[unit];
+       tp = cntty[unit];
        tp->t_state &= ~TS_BUSY;
        tp->t_state &= ~TS_BUSY;
-       consoftc[unit].cs_lastc = (char)0;
+       consoftc[unit].cs_timo = 0;
        if (tp->t_line)
                (*linesw[tp->t_line].l_start)(tp);
        else
        if (tp->t_line)
                (*linesw[tp->t_line].l_start)(tp);
        else
@@ -223,7 +263,7 @@ cnstart(tp)
        s = spl8();
        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                goto out;
        s = spl8();
        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                goto out;
-       if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
+       if (tp->t_outq.c_cc <= tp->t_lowat) {
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
                        wakeup((caddr_t)&tp->t_outq);
                if (tp->t_state&TS_ASLEEP) {
                        tp->t_state &= ~TS_ASLEEP;
                        wakeup((caddr_t)&tp->t_outq);
@@ -237,15 +277,11 @@ cnstart(tp)
        if (tp->t_outq.c_cc == 0)
                goto out;
        c = getc(&tp->t_outq) & 0xff;
        if (tp->t_outq.c_cc == 0)
                goto out;
        c = getc(&tp->t_outq) & 0xff;
-       if (tp->t_flags&(RAW|LITOUT))
-               cnputchar(c, tp);
-       else if (c <= 0177)
-               cnputchar((c | (partab[c]&0200))&0xff, tp);
-       else {
-               timeout(ttrstrt, (caddr_t)tp, (c&0177));
-               tp->t_state |= TS_TIMEOUT;
-               goto out;
+       if (tp->t_cflag&PARENB && ((tp->t_cflag&CSIZE)==CS7)) {
+               c &= 0177;
+               c |= (tp->t_cflag&PARODD ? ~partab[c] : partab[c]) & 0200;
        }
        }
+       cnputchar(c, tp);
        tp->t_state |= TS_BUSY;
 out:
        splx(s);
        tp->t_state |= TS_BUSY;
 out:
        splx(s);
@@ -264,66 +300,64 @@ cnputc(c)
  * Print a character on console.
  */
 cnputchar(c, tp)
  * Print a character on console.
  */
 cnputchar(c, tp)
-       register char c;
+       char c;
        register struct tty *tp;
 {
        register struct tty *tp;
 {
-       register timo, unit;
+       register timo;
        register struct cpdcb_o *current;
        register struct cpdcb_o *current;
+       register struct consoftc *cs;
+       int unit;
 
        /* tp == 0 only in system error messages */
        if (tp == 0) {
 
        /* tp == 0 only in system error messages */
        if (tp == 0) {
-               current = &consout[CPCONS];
-               unit = CPCONS;
-               if (lasthdr == 0)       /* not done anythig yet */
-                       lasthdr = (struct cphdr *)current;
+               tp = &cons;
+               tp->t_dev = CPCONS;             /* may not be open */
                c |= partab[c&0177]&0200;
                c |= partab[c&0177]&0200;
-       } else {
-               current = &consout[minor(tp->t_dev)];
-               unit = minor(tp->t_dev);
        }
        }
+       unit = minor(tp->t_dev);
+       current = &consout[unit];
        timo = 30000;
        /*
        timo = 30000;
        /*
-        * Try waiting for the console tty to come ready,
-        * otherwise give up after a reasonable time.
-        * make sure we dont test this bit in cache!
+        * Try waiting for the console tty to finish previous command
+        * on this unit, otherwise give up after a reasonable time.
         */
         */
-       uncache(&current->cp_hdr.cp_unit);
-       while ((current->cp_hdr.cp_unit&CPDONE) == 0 && --timo)
+       do
                uncache(&current->cp_hdr.cp_unit);
                uncache(&current->cp_hdr.cp_unit);
+       while ((current->cp_hdr.cp_unit&CPDONE) == 0 && --timo);
+
        current->cp_hdr.cp_comm = CPWRITE;
        current->cp_hdr.cp_count = 1;
        current->cp_hdr.cp_comm = CPWRITE;
        current->cp_hdr.cp_count = 1;
-       current->cp_buf[0] = c & 0xff;
-       timo = 10000;
+       current->cp_buf[0] = c;
        /*
        /*
-        * Try waiting for the console tty to come ready,
-        * otherwise give up after a reasonable time.
+        * Try waiting for the console tty
+        * to accept previous command.
         */
         */
-       uncache(&lasthdr->cp_unit);
-       while ((lasthdr->cp_unit&CPTAKE) == 0 && --timo)
-               uncache(&lasthdr->cp_unit);
+       waitforlast(timo);
+
        /* Reset done bit */
        current->cp_hdr.cp_unit = (char)unit;
        /* Reset done bit */
        current->cp_hdr.cp_unit = (char)unit;
-       lasthdr = (struct cphdr *)current;
 #ifdef CPPERF
        if (intenable != 0)
                scope_in(5);
 #endif
 #ifdef CPPERF
        if (intenable != 0)
                scope_in(5);
 #endif
-       consoftc[unit].cs_lastc = c;
-       if ((consoftc[unit].cs_flags&CSF_ACTIVE) == 0 && clk_enable) {
-               consoftc[unit].cs_flags |= CSF_ACTIVE;
-               timeout(cnrestart, (caddr_t)tp, 10);
+       cs = &consoftc[unit];
+       cs->cs_lastc = c;
+       cs->cs_timo = CN_TIMO;
+       if ((cs->cs_flags&CSF_ACTIVE) == 0 && clk_enable) {
+               cs->cs_flags |= CSF_ACTIVE;
+               timeout(cnrestart, (caddr_t)tp, CN_TIMERVAL);
        }
        }
-       consoftc[unit].cs_flags |= CSF_RETRY;   /* wait some more */
-       mtpr(CPMDCB, current);
+       mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)current));
+       cnlast = &current->cp_hdr;
 }
 
 }
 
-#if defined(KDB) || defined(GENERIC)
+#if defined(KADB) || defined(GENERIC)
 cngetc()
 {
        register int c, s;
 
        s = spl8();             /* block cnrint while we poll */
 cngetc()
 {
        register int c, s;
 
        s = spl8();             /* block cnrint while we poll */
-       c = cngetchar((struct tty *)0);
+       c = cngetchar(&cons);
        if (c == '\r')
                c = '\n';
        splx(s);
        if (c == '\r')
                c = '\n';
        splx(s);
@@ -337,106 +371,129 @@ cngetchar(tp)
        register struct cpdcb_i *current;
        char c;
 
        register struct cpdcb_i *current;
        char c;
 
-       /* tp == 0 only in system error messages */
-       if (tp == 0) {
-               current = &consin[CPCONS];
-               unit = CPCONS;
-               if (lasthdr == 0)       /* not done anything yet */
-                       lasthdr = (struct cphdr *)current;
-       } else {
-               current = &consin[minor(tp->t_dev)];
-               unit = minor(tp->t_dev);
-       }
-       timo = 10000;
-       uncache((char *)&lasthdr->cp_unit);
-       while ((lasthdr->cp_unit&CPTAKE) == 0 && --timo)
-               uncache(&lasthdr->cp_unit);
+       unit = minor(tp->t_dev);
+       current = &consin[unit];
+       waitforlast(timo);
        current->cp_hdr.cp_unit = unit;         /* Resets done bit */
        current->cp_hdr.cp_comm = CPREAD;
        current->cp_hdr.cp_count = 1;
        current->cp_hdr.cp_unit = unit;         /* Resets done bit */
        current->cp_hdr.cp_comm = CPREAD;
        current->cp_hdr.cp_count = 1;
-       mtpr(CPMDCB, current);
-       while ((current->cp_hdr.cp_unit & CPDONE) == 0) 
+       mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)current));
+       while ((current->cp_hdr.cp_unit&CPDONE) == 0) 
                uncache(&current->cp_hdr.cp_unit);
        uncache(&current->cpi_buf[0]);
        c = current->cpi_buf[0] & 0x7f;
                uncache(&current->cp_hdr.cp_unit);
        uncache(&current->cpi_buf[0]);
        c = current->cpi_buf[0] & 0x7f;
-       lasthdr = (struct cphdr *)current;
+       cnlast = &current->cp_hdr;
        return (c);
 }
 #endif
 
 /*
  * Restart (if necessary) transfer to CP line.
        return (c);
 }
 #endif
 
 /*
  * Restart (if necessary) transfer to CP line.
- * This way, lost 'transmit' interrupts don't break the chain.
+ * This way, lost transmit interrupts don't wedge output.
  */
 cnrestart(tp)
        struct tty *tp;
 {
        register struct consoftc *cs;
 
  */
 cnrestart(tp)
        struct tty *tp;
 {
        register struct consoftc *cs;
 
-       cs = &consoftc[tp == 0 ? CPCONS : minor(tp->t_dev)];
-       if (cs->cs_flags&CSF_RETRY) {
-               cs->cs_flags &= ~CSF_RETRY;
-               timeout(cnrestart, (caddr_t)tp, 10);
-               return;
-       }
+       cs = &consoftc[minor(tp->t_dev)];
        cs->cs_flags &= ~CSF_ACTIVE;
        cs->cs_flags &= ~CSF_ACTIVE;
-       if (cs->cs_lastc != (char)0)
-               cnputchar(cs->cs_lastc, tp);
+       if (cs->cs_timo) {
+               if (--cs->cs_timo == 0) {
+                       cs->cs_wedgecnt++;
+                       cnreset(tp);
+                       cnputchar(cs->cs_lastc, tp);
+               } else {
+                       cs->cs_flags |= CSF_ACTIVE;
+                       timeout(cnrestart, (caddr_t)tp, CN_TIMERVAL);
+               }
+       }
 }
 
 /*
 }
 
 /*
- * Set line parameters
+ * Reset console.
  */
  */
-cnparams(tp)
+cnreset(tp)
        register struct tty *tp;
 {
        register timo;
        register struct cpdcb_o *current;
        register struct tty *tp;
 {
        register timo;
        register struct cpdcb_o *current;
-       register struct cpdcb_i *cin;
+       register unit;
+       static int failed;
+
+       unit = minor(tp->t_dev);
+       current = &consout[unit];
+       current->cp_hdr.cp_comm = CPRESET;
+       current->cp_hdr.cp_count = 0;
+       current->cp_hdr.cp_unit = unit; 
+       mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)current));
+       cnlast = &current->cp_hdr;
+       timo = 10000;
+       do
+               uncache(&current->cp_hdr.cp_unit);
+       while ((current->cp_hdr.cp_unit&CPTAKE) == 0 && --timo);
+       if (current->cp_hdr.cp_unit & CPTAKE) {
+               cnparams(tp, &tp->t_termios);
+               failed = 0;
+       } else {
+               if (failed++ == 0)
+                       log(LOG_ERR, "Console wedged, reset failed.\n");
+               ttyflush(tp, FWRITE);
+       }
+}
 
 
-       current = &consout[minor(tp->t_dev)];
-       timo = 30000;
+/*
+ * Set line parameters
+ */
+cnparams(tp, t)
+       register struct tty *tp;
+       register struct termios *t;
+{
+       register timo = 30000;
+       int unit = minor(tp->t_dev);
+       register struct cpdcb_o *current = &consout[unit];
+       register cflag = t->c_cflag;
+       int speedcode, csize;
+
+       if (((speedcode == ttspeedtab(t->c_ospeed, cnspeedtab)) < 0) ||
+          (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
+          ((csize = (cflag&CSIZE)) != CS7 && csize != CS8))
+               return (EINVAL);
+       /*XXX*/return (0);
        /*
        /*
-        * Try waiting for the console tty to come ready,
+        * Try waiting for the console tty to finish any output,
         * otherwise give up after a reasonable time.
         * otherwise give up after a reasonable time.
-        * make sure we dont test this bit in cache!
         */
         */
-       uncache(&current->cp_hdr.cp_unit);
-       while ((current->cp_hdr.cp_unit&CPDONE) == 0 && --timo)
+       do
                uncache(&current->cp_hdr.cp_unit);
                uncache(&current->cp_hdr.cp_unit);
+       while ((current->cp_hdr.cp_unit&CPDONE) == 0 && --timo);
        current->cp_hdr.cp_comm = CPSTTY;
        current->cp_hdr.cp_count = 4;
        current->cp_hdr.cp_comm = CPSTTY;
        current->cp_hdr.cp_count = 4;
-       current->cp_buf[0] = tp->t_ispeed;
-       /* the rest are defaults */
+       current->cp_buf[0] = speedcode;
+#ifdef notyet
+       /* parity */
+       current->cp_buf[1] = (cflag&PARENB) ? ((cflag&PARODD) ? 2 : 1) : 0;     
+       /* stop bits */
+       current->cp_buf[2] = (cflag&CSTOPB) ? 2 : 0;
+       /* data bits */
+       current->cp_buf[3] = (csize==CS8) ? 8 : 7;
+#else
        current->cp_buf[1] = 0; /* no parity */
        current->cp_buf[2] = 0; /* stop bits */
        current->cp_buf[3] = 8; /* data bits */
        current->cp_buf[1] = 0; /* no parity */
        current->cp_buf[2] = 0; /* stop bits */
        current->cp_buf[3] = 8; /* data bits */
-       timo = 10000;
-       /*
-        * Try waiting for the console tty to come ready,
-        * otherwise give up after a reasonable time.
-        */
-       uncache(&lasthdr->cp_unit);
-       while ((lasthdr->cp_unit&CPTAKE) == 0 && --timo)
-               uncache(&lasthdr->cp_unit);
+#endif
+
        /* Reset done bit */
        /* Reset done bit */
-       current->cp_hdr.cp_unit = (char)minor(tp->t_dev); 
-       lasthdr = (struct cphdr *)current;
-       mtpr(CPMDCB, current);
+       current->cp_hdr.cp_unit = unit; 
 
 
-       timo = 10000;
-       uncache(&lasthdr->cp_unit);
-       while ((lasthdr->cp_unit&CPTAKE) == 0 && --timo)
-               uncache(&lasthdr->cp_unit);
-       cin = &consin[minor(tp->t_dev)];
-       cin->cp_hdr.cp_unit = minor(tp->t_dev);
-       cin->cp_hdr.cp_comm = CPREAD;
-       cin->cp_hdr.cp_count = 1;       /* Get ready for input */
-       mtpr(CPMDCB, cin);
-       lasthdr = (struct cphdr *)cin;
+       waitforlast(timo);
+       mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)current));
+       cnlast = &current->cp_hdr;
+       cnpostread(unit);
+       return (0);
 }
 
 }
 
-#ifdef KDB
+#ifdef KADB
 /*
  * Turn input polling on/off (used by debugger).
  */
 /*
  * Turn input polling on/off (used by debugger).
  */