check for revoked terminal (ttclosed)
[unix-history] / usr / src / sys / vax / uba / dhu.c
index 52ce85a..15de6c8 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)dhu.c       7.2 (Berkeley) %G%
+ *     @(#)dhu.c       7.11 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 /*
  * DHU-11 driver
  */
 /*
  * DHU-11 driver
  */
-#include "../machine/pte.h"
+#include "machine/pte.h"
 
 
-#include "bk.h"
 #include "param.h"
 #include "conf.h"
 #include "param.h"
 #include "conf.h"
-#include "dir.h"
 #include "user.h"
 #include "proc.h"
 #include "ioctl.h"
 #include "tty.h"
 #include "user.h"
 #include "proc.h"
 #include "ioctl.h"
 #include "tty.h"
+#include "ttydefaults.h"
 #include "map.h"
 #include "buf.h"
 #include "vm.h"
 #include "map.h"
 #include "buf.h"
 #include "vm.h"
@@ -59,11 +58,11 @@ struct      uba_driver dhudriver =
 #define        UNIT(x) (minor(x))
 
 #ifndef PORTSELECTOR
 #define        UNIT(x) (minor(x))
 
 #ifndef PORTSELECTOR
-#define ISPEED B9600
-#define IFLAGS (EVENP|ODDP|ECHO)
+#define SPEED  TTYDEF_SPEED
+#define LFLAG  TTYDEF_LFLAG
 #else
 #else
-#define ISPEED B4800
-#define IFLAGS (EVENP|ODDP)
+#define SPEED  B4800
+#define LFLAG  (TTYDEF_LFLAG & ~ECHO)
 #endif
 
 /*
 #endif
 
 /*
@@ -92,8 +91,25 @@ struct       uba_driver dhudriver =
  *     EXTA => 19200 baud
  *     EXTB => 2000 baud
  */
  *     EXTA => 19200 baud
  *     EXTB => 2000 baud
  */
-char   dhu_speeds[] =
-       { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
+struct speedtab dhuspeedtab[] = {
+       19200,  14,
+       9600,   13,
+       4800,   11,
+       2400,   10,
+       2000,   9,
+       1800,   8,
+       1200,   7,
+       600,    6,
+       300,    5,
+       150,    4,
+       134,    3,
+       110,    2,
+       75,     1,
+       0,      0,
+       EXTA,   14,
+       EXTB,   9,
+       -1,     -1,
+};
 
 short  dhusoftCAR[NDHU];
 
 
 short  dhusoftCAR[NDHU];
 
@@ -165,7 +181,7 @@ dhuattach(ui)
 
        dhusoftCAR[ui->ui_unit] = ui->ui_flags;
        cbase[ui->ui_ubanum] = -1;
 
        dhusoftCAR[ui->ui_unit] = ui->ui_flags;
        cbase[ui->ui_ubanum] = -1;
-       dhu_uballoc[ui->ui_unit] = -1;
+       dhu_uballoc[ui->ui_ubanum] = -1;
 }
 
 /*
 }
 
 /*
@@ -181,7 +197,8 @@ dhuopen(dev, flag)
        register int unit, dhu;
        register struct dhudevice *addr;
        register struct uba_device *ui;
        register int unit, dhu;
        register struct dhudevice *addr;
        register struct uba_device *ui;
-       int s;
+       int s, error = 0;
+       extern dhuparam();
 
        unit = UNIT(dev);
        dhu = unit >> 4;
 
        unit = UNIT(dev);
        dhu = unit >> 4;
@@ -193,6 +210,7 @@ dhuopen(dev, flag)
        addr = (struct dhudevice *)ui->ui_addr;
        tp->t_addr = (caddr_t)addr;
        tp->t_oproc = dhustart;
        addr = (struct dhudevice *)ui->ui_addr;
        tp->t_addr = (caddr_t)addr;
        tp->t_oproc = dhustart;
+       tp->t_param = dhuparam;
        /*
         * While setting up state for this uba and this dhu,
         * block uba resets which can clear the state.
        /*
         * While setting up state for this uba and this dhu,
         * block uba resets which can clear the state.
@@ -216,31 +234,41 @@ dhuopen(dev, flag)
        if ((tp->t_state&TS_ISOPEN) == 0) {
                ttychars(tp);
 #ifndef PORTSELECTOR
        if ((tp->t_state&TS_ISOPEN) == 0) {
                ttychars(tp);
 #ifndef PORTSELECTOR
-               if (tp->t_ispeed == 0) {
-#else
-                       tp->t_state |= TS_HUPCLS;
-#endif PORTSELECTOR
-                       tp->t_ispeed = ISPEED;
-                       tp->t_ospeed = ISPEED;
-                       tp->t_flags = IFLAGS;
-#ifndef PORTSELECTOR
+               if (tp->t_ospeed == 0) {
+#endif 
+                       tp->t_ispeed = SPEED;
+                       tp->t_ospeed = SPEED;
+                       ttsetwater(tp);
+                       tp->t_iflag = TTYDEF_IFLAG;
+                       tp->t_oflag = TTYDEF_OFLAG;
+                       tp->t_lflag = LFLAG;
+                       tp->t_cflag = TTYDEF_CFLAG;
+#ifdef PORTSELECTOR
+                       tp->t_cflag |= HUPCL;
+#else 
                }
                }
-#endif PORTSELECTOR
+#endif 
                tp->t_dev = dev;
                tp->t_dev = dev;
-               dhuparam(unit);
+               dhuparam(tp, &tp->t_termios);
        }
        /*
         * Wait for carrier, then process line discipline specific open.
         */
        }
        /*
         * Wait for carrier, then process line discipline specific open.
         */
-       s = spl5();
+       s = spltty();
        if ((dhumctl(dev, DHU_ON, DMSET) & DHU_CAR) ||
            (dhusoftCAR[dhu] & (1<<(unit&0xf))))
                tp->t_state |= TS_CARR_ON;
        if ((dhumctl(dev, DHU_ON, DMSET) & DHU_CAR) ||
            (dhusoftCAR[dhu] & (1<<(unit&0xf))))
                tp->t_state |= TS_CARR_ON;
-       while ((tp->t_state & TS_CARR_ON) == 0) {
+       while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
+           (tp->t_state & TS_CARR_ON) == 0) {
                tp->t_state |= TS_WOPEN;
                tp->t_state |= TS_WOPEN;
-               sleep((caddr_t)&tp->t_rawq, TTIPRI);
+               if ((error = tsleep((caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
+                                   ttopen, 0)) ||
+                   (error = ttclosed(tp)))
+                       break;
        }
        (void) splx(s);
        }
        (void) splx(s);
+       if (error)
+               return (error);
        return ((*linesw[tp->t_line].l_open)(dev, tp));
 }
 
        return ((*linesw[tp->t_line].l_open)(dev, tp));
 }
 
@@ -259,38 +287,35 @@ dhuclose(dev, flag)
        tp = &dhu_tty[unit];
        (*linesw[tp->t_line].l_close)(tp);
        (void) dhumctl(unit, DHU_BRK, DMBIC);
        tp = &dhu_tty[unit];
        (*linesw[tp->t_line].l_close)(tp);
        (void) dhumctl(unit, DHU_BRK, DMBIC);
-       if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
+       if ((tp->t_state&TS_WOPEN) || (tp->t_cflag&HUPCL) || 
+           (tp->t_state&TS_ISOPEN) == 0) {
 #ifdef PORTSELECTOR
 #ifdef PORTSELECTOR
-       {
-               extern int wakeup();
-
                (void) dhumctl(unit, DHU_OFF, DMSET);
                /* Hold DTR low for 0.5 seconds */
                (void) dhumctl(unit, DHU_OFF, DMSET);
                /* Hold DTR low for 0.5 seconds */
-               timeout(wakeup, (caddr_t) &tp->t_dev, hz/2);
-               sleep((caddr_t) &tp->t_dev, PZERO);
-       }
+               (void) tsleep((caddr_t) &tp->t_dev, PZERO, ttclos, hz/2);
 #else
                (void) dhumctl(unit, DHU_OFF, DMSET);
 #endif PORTSELECTOR
 #else
                (void) dhumctl(unit, DHU_OFF, DMSET);
 #endif PORTSELECTOR
-       ttyclose(tp);
+       }
+       return (ttyclose(tp));
 }
 
 }
 
-dhuread(dev, uio)
+dhuread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 {
        register struct tty *tp = &dhu_tty[UNIT(dev)];
 
        dev_t dev;
        struct uio *uio;
 {
        register struct tty *tp = &dhu_tty[UNIT(dev)];
 
-       return ((*linesw[tp->t_line].l_read)(tp, uio));
+       return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
 }
 
 }
 
-dhuwrite(dev, uio)
+dhuwrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 {
        register struct tty *tp = &dhu_tty[UNIT(dev)];
 
        dev_t dev;
        struct uio *uio;
 {
        register struct tty *tp = &dhu_tty[UNIT(dev)];
 
-       return ((*linesw[tp->t_line].l_write)(tp, uio));
+       return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
 
 /*
 }
 
 /*
@@ -300,15 +325,15 @@ dhurint(dhu)
        int dhu;
 {
        register struct tty *tp;
        int dhu;
 {
        register struct tty *tp;
-       register c;
+       register creg, c;
        register struct dhudevice *addr;
        register struct tty *tp0;
        register struct uba_device *ui;
        register line;
        int overrun = 0;
 
        register struct dhudevice *addr;
        register struct tty *tp0;
        register struct uba_device *ui;
        register line;
        int overrun = 0;
 
-#ifdef VAX630
-       (void) spl5();
+#ifdef QBA
+       (void) spltty();
 #endif
        ui = dhuinfo[dhu];
        if (ui == 0 || ui->ui_alive == 0)
 #endif
        ui = dhuinfo[dhu];
        if (ui == 0 || ui->ui_alive == 0)
@@ -319,18 +344,19 @@ dhurint(dhu)
         * Loop fetching characters from the silo for this
         * dhu until there are no more in the silo.
         */
         * Loop fetching characters from the silo for this
         * dhu until there are no more in the silo.
         */
-       while ((c = addr->dhurbuf) < 0) {       /* (c & DHU_RB_VALID) == on */
-               line = DHU_RX_LINE(c);
+       while ((creg = addr->dhurbuf) < 0) {    /* (c & DHU_RB_VALID) == on */
+               line = DHU_RX_LINE(creg);
                tp = tp0 + line;
                tp = tp0 + line;
-               if ((c & DHU_RB_STAT) == DHU_RB_STAT) {
+               c = creg & 0xff;
+               if ((creg & DHU_RB_STAT) == DHU_RB_STAT) {
                        /*
                         * modem changed or diag info
                         */
                        /*
                         * modem changed or diag info
                         */
-                       if (c & DHU_RB_DIAG) {
+                       if (creg & DHU_RB_DIAG) {
                                /* decode diagnostic messages */
                                continue;
                        }
                                /* decode diagnostic messages */
                                continue;
                        }
-                       if (c & DHU_ST_DCD)
+                       if (creg & DHU_ST_DCD)
                                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
                        else if ((dhusoftCAR[dhu] & (1<<line)) == 0 &&
                            (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
                                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
                        else if ((dhusoftCAR[dhu] & (1<<line)) == 0 &&
                            (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
@@ -344,31 +370,16 @@ dhurint(dhu)
 #endif
                                continue;
                }
 #endif
                                continue;
                }
-               if (c & DHU_RB_PE)
-                       if ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
-                           (tp->t_flags&(EVENP|ODDP)) == ODDP)
-                               continue;
-               if ((c & DHU_RB_DO) && overrun == 0) {
+               if (creg & DHU_RB_PE)
+                       c |= TTY_PE;
+               if (creg & DHU_RB_DO && overrun == 0) {
                        log(LOG_WARNING, "dhu%d: silo overflow\n", dhu);
                        overrun = 1;
                }
                        log(LOG_WARNING, "dhu%d: silo overflow\n", dhu);
                        overrun = 1;
                }
-               if (c & DHU_RB_FE)
-                       /*
-                        * At framing error (break) generate
-                        * a null (in raw mode, for getty), or a
-                        * interrupt (in cooked/cbreak mode).
-                        */
-                       if (tp->t_flags&RAW)
-                               c = 0;
-                       else
-                               c = tp->t_intrc;
-#if NBK > 0
-               if (tp->t_line == NETLDISC) {
-                       c &= 0x7f;
-                       BKINPUT(c, tp);
-               } else
-#endif
-                       (*linesw[tp->t_line].l_rint)(c, tp);
+               if (creg & DHU_RB_FE)
+                       c |= TTY_FE;
+
+               (*linesw[tp->t_line].l_rint)(c, tp);
        }
 }
 
        }
 }
 
@@ -388,12 +399,8 @@ dhuioctl(dev, cmd, data, flag)
        if (error >= 0)
                return (error);
        error = ttioctl(tp, cmd, data, flag);
        if (error >= 0)
                return (error);
        error = ttioctl(tp, cmd, data, flag);
-       if (error >= 0) {
-               if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLSET ||
-                   cmd == TIOCLBIC || cmd == TIOCLBIS)
-                       dhuparam(unit);
+       if (error >= 0)
                return (error);
                return (error);
-       }
 
        switch (cmd) {
        case TIOCSBRK:
 
        switch (cmd) {
        case TIOCSBRK:
@@ -462,40 +469,77 @@ dhutodm(bits)
 
 /*
  * Set parameters from open or stty into the DHU hardware
 
 /*
  * Set parameters from open or stty into the DHU hardware
- * registers.
+ * registers.  Impossible values for speed or character
+ * size are ignored and not copied back into tp.
  */
  */
-dhuparam(unit)
-       register int unit;
-{
+dhuparam(tp, want)
        register struct tty *tp;
        register struct tty *tp;
-       register struct dhudevice *addr;
+       register struct termios *want;
+{
+       register int unit = UNIT(tp->t_dev);
+       register struct dhudevice *addr = (struct dhudevice *)tp->t_addr;
        register int lpar;
        register int lpar;
+       register long cflag;
+       register int incode, outcode;
        int s;
        int s;
-
-       tp = &dhu_tty[unit];
-       addr = (struct dhudevice *)tp->t_addr;
+       
        /*
         * Block interrupts so parameters will be set
         * before the line interrupts.
         */
        /*
         * Block interrupts so parameters will be set
         * before the line interrupts.
         */
-       s = spl5();
-       if ((tp->t_ispeed) == 0) {
-               tp->t_state |= TS_HUPCLS;
+       s = spltty();
+
+       if (want->c_ospeed == 0) {
+               tp->t_ospeed = 0;
+               tp->t_cflag |= HUPCL;
                (void)dhumctl(unit, DHU_OFF, DMSET);
                splx(s);
                return;
        }
                (void)dhumctl(unit, DHU_OFF, DMSET);
                splx(s);
                return;
        }
-       lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8);
-       if ((tp->t_ispeed) == B134)
-               lpar |= DHU_LP_BITS6|DHU_LP_PENABLE;
-       else if (tp->t_flags & (RAW|LITOUT|PASS8))
-               lpar |= DHU_LP_BITS8;
+
+       if ((outcode = ttspeedtab(want->c_ospeed, dhuspeedtab)) >= 0)
+               tp->t_ospeed = want->c_ospeed;
+       else
+               outcode = ttspeedtab(tp->t_ospeed, dhuspeedtab);
+
+       if (want->c_ispeed == 0) {
+               tp->t_ispeed = 0;
+               incode = outcode;
+       } else if ((incode = ttspeedtab(want->c_ispeed, dhuspeedtab)) >= 0)
+               tp->t_ispeed = want->c_ispeed;
        else
        else
-               lpar |= DHU_LP_BITS7|DHU_LP_PENABLE;
-       if (tp->t_flags&EVENP)
-               lpar |= DHU_LP_EPAR;
-       if ((tp->t_ospeed) == B110)
+               incode = ttspeedtab(tp->t_ispeed, dhuspeedtab);
+
+       lpar = ((char)outcode<<12) | ((char)incode<<8);
+
+       switch (want->c_cflag&CSIZE) {
+       case CS6: case CS7: case CS8:
+               tp->t_cflag =  want->c_cflag;
+               break;
+       default:
+               tp->t_cflag = (tp->t_cflag&CSIZE) | (want->c_cflag & ~CSIZE);
+       }
+       cflag = tp->t_cflag;
+
+       switch(cflag&CSIZE) {
+       case CS6:
+               lpar |= DHU_LP_BITS6;
+               break;
+       case CS7:
+               lpar |= DHU_LP_BITS7;
+               break;
+       case CS8:
+               lpar |= DHU_LP_BITS8;
+               break;
+       }
+       if (cflag&PARENB) {
+               lpar |= DHU_LP_PENABLE;
+               if ((cflag&PARODD) == 0)
+                       lpar |= DHU_LP_EPAR;
+       }
+       if (cflag&CSTOPB)
                lpar |= DHU_LP_TWOSB;
                lpar |= DHU_LP_TWOSB;
+
        addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
        addr->dhulpr = lpar;
        splx(s);
        addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
        addr->dhulpr = lpar;
        splx(s);
@@ -516,7 +560,7 @@ dhuxint(dhu)
        register int line, t;
        u_short cntr;
 
        register int line, t;
        u_short cntr;
 
-#ifdef VAX630
+#ifdef QBA
        (void) spl5();
 #endif
        ui = dhuinfo[dhu];
        (void) spl5();
 #endif
        ui = dhuinfo[dhu];
@@ -578,7 +622,7 @@ dhustart(tp)
         * If there are sleepers, and output has drained below low
         * water mark, wake up the sleepers..
         */
         * If there are sleepers, and output has drained below low
         * water mark, wake up the sleepers..
         */
-       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);
@@ -595,7 +639,7 @@ dhustart(tp)
         */
        if (tp->t_outq.c_cc == 0)
                goto out;
         */
        if (tp->t_outq.c_cc == 0)
                goto out;
-       if (tp->t_flags & (RAW|LITOUT))
+       if (1 || !(tp->t_oflag & OPOST))        /*XXX*/
                nch = ndqb(&tp->t_outq, 0);
        else {
                nch = ndqb(&tp->t_outq, 0200);
                nch = ndqb(&tp->t_outq, 0);
        else {
                nch = ndqb(&tp->t_outq, 0200);
@@ -742,7 +786,7 @@ dhureset(uban)
                for (i = 0; i < 16; i++) {
                        tp = &dhu_tty[unit];
                        if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
                for (i = 0; i < 16; i++) {
                        tp = &dhu_tty[unit];
                        if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
-                               dhuparam(unit);
+                               dhuparam(tp, &tp->t_termios);
                                (void)dhumctl(unit, DHU_ON, DMSET);
                                tp->t_state &= ~TS_BUSY;
                                dhustart(tp);
                                (void)dhumctl(unit, DHU_ON, DMSET);
                                tp->t_state &= ~TS_BUSY;
                                dhustart(tp);