new copyright notice
[unix-history] / usr / src / sys / tahoe / vba / vx.c
index 4a5a37e..bf2cc64 100644 (file)
@@ -1,4 +1,14 @@
-/*     vx.c    1.10    87/01/11        */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Computer Consoles Inc.
+ *
+ * %sccs.include.redist.c%
+ *
+ *     @(#)vx.c        7.11 (Berkeley) %G%
+ */
 
 #include "vx.h"
 #if NVX > 0
 
 #include "vx.h"
 #if NVX > 0
 #define        DOSCOPE
 #endif
 
 #define        DOSCOPE
 #endif
 
-#include "../tahoe/pte.h"
-
 #include "param.h"
 #include "ioctl.h"
 #include "tty.h"
 #include "param.h"
 #include "ioctl.h"
 #include "tty.h"
-#include "dir.h"
 #include "user.h"
 #include "map.h"
 #include "buf.h"
 #include "conf.h"
 #include "file.h"
 #include "user.h"
 #include "map.h"
 #include "buf.h"
 #include "conf.h"
 #include "file.h"
-#include "uio.h"
 #include "proc.h"
 #include "vm.h"
 #include "kernel.h"
 #include "syslog.h"
 
 #include "proc.h"
 #include "vm.h"
 #include "kernel.h"
 #include "syslog.h"
 
+#include "../tahoe/pte.h"
+
 #include "../tahoevba/vbavar.h"
 #include "../tahoevba/vbavar.h"
+#include "../tahoevba/vbaparam.h"
 #include "../tahoevba/vxreg.h"
 #include "../tahoevba/scope.h"
 
 #include "../tahoevba/vxreg.h"
 #include "../tahoevba/scope.h"
 
@@ -67,6 +76,7 @@ struct        vba_driver vxdriver =
     { vxprobe, 0, vxattach, 0, vxstd, "vx", vxinfo };
 
 struct vx_softc {
     { vxprobe, 0, vxattach, 0, vxstd, "vx", vxinfo };
 
 struct vx_softc {
+       struct  vxdevice *vs_addr;      /* H/W address */
        u_char  vs_type;        /* 0: viox-x/vioc-b, 1: vioc-bop */
        u_char  vs_bop;         /* bop board # for vioc-bop's */
        u_char  vs_loport;      /* low port nbr */
        u_char  vs_type;        /* 0: viox-x/vioc-b, 1: vioc-bop */
        u_char  vs_bop;         /* bop board # for vioc-bop's */
        u_char  vs_loport;      /* low port nbr */
@@ -77,32 +87,70 @@ struct      vx_softc {
        short   vs_vers;        /* vioc/pvioc version */
 #define        VXV_OLD 0               /* PVIOCX | VIOCX */
 #define        VXV_NEW 1               /* NPVIOCX | NVIOCX */
        short   vs_vers;        /* vioc/pvioc version */
 #define        VXV_OLD 0               /* PVIOCX | VIOCX */
 #define        VXV_NEW 1               /* NPVIOCX | NVIOCX */
-       short   vs_xmtcnt;      /* xmit commands pending */
-       short   vs_brkreq;      /* send break requests pending */
        short   vs_state;       /* controller state */
 #define        VXS_READY       0       /* ready for commands */
 #define        VXS_RESET       1       /* in process of reseting */
        u_short vs_softCAR;     /* soft carrier */
        short   vs_state;       /* controller state */
 #define        VXS_READY       0       /* ready for commands */
 #define        VXS_RESET       1       /* in process of reseting */
        u_short vs_softCAR;     /* soft carrier */
-       caddr_t vs_mricmd;      /* most recent issued cmd */
        u_int   vs_ivec;        /* interrupt vector base */
        u_int   vs_ivec;        /* interrupt vector base */
+       caddr_t vs_mricmd;      /* most recent issued cmd */
+       /* The remaining fields are zeroed on reset... */
+#define vs_zero vs_xmtcnt
+       int     vs_xmtcnt;      /* xmit commands pending */
        struct  vxcmd *vs_avail;/* next available command buffer */
        struct  vxcmd *vs_build;
        struct  vxcmd vs_lst[NVCXBUFS];
        struct  vcmds vs_cmds;
 } vx_softc[NVX];
 
        struct  vxcmd *vs_avail;/* next available command buffer */
        struct  vxcmd *vs_build;
        struct  vxcmd vs_lst[NVCXBUFS];
        struct  vcmds vs_cmds;
 } vx_softc[NVX];
 
+struct speedtab vxspeedtab[] = {
+       EXTA,   V19200,
+       EXTB,   V19200,
+       19200,  V19200,
+       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,      0,
+       -1,     -1,
+};
+
 vxprobe(reg, vi)
        caddr_t reg;
        struct vba_device *vi;
 {
        register int br, cvec;                  /* must be r12, r11 */
 vxprobe(reg, vi)
        caddr_t reg;
        struct vba_device *vi;
 {
        register int br, cvec;                  /* must be r12, r11 */
-       register struct vxdevice *vp = (struct vxdevice *)reg;
+       register struct vxdevice *vp;
        register struct vx_softc *vs;
        register struct vx_softc *vs;
+       struct pte *dummypte;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
-       vackint(0); vunsol(0); vcmdrsp(0); vxfreset(0);
+       vackint(0); vunsol(0); vcmdrsp(0);
+#ifdef VX_DEBUG
+       vxfreset(0);
 #endif
 #endif
+#endif /* lint */
+       /*
+        * If on an HCX-9, the device has a 32-bit address,
+        * and we receive that address so we can set up a map.
+        * On VERSAbus devices, the address is 24-bit, and is
+        * already mapped (into vmem[]) by autoconf.
+        */
+       if (!(reg >= vmem && reg < &vmem[ctob(VBIOSIZE)]) &&    /* XXX */
+           !vbmemalloc(16, reg, &dummypte, &reg)) {
+               printf("vx%d: vbmemalloc failed.\n", vi->ui_unit);
+               return(0);
+       }
+       vp = (struct vxdevice *)reg;
        if (badaddr((caddr_t)vp, 1))
                return (0);
        vp->v_fault = 0;
        if (badaddr((caddr_t)vp, 1))
                return (0);
        vp->v_fault = 0;
@@ -131,8 +179,10 @@ vxprobe(reg, vi)
 vxattach(vi)
        register struct vba_device *vi;
 {
 vxattach(vi)
        register struct vba_device *vi;
 {
+       register struct vx_softc *vs = &vx_softc[vi->ui_unit];
 
 
-       vx_softc[vi->ui_unit].vs_softCAR = vi->ui_flags;
+       vs->vs_softCAR = vi->ui_flags;
+       vs->vs_addr = (struct vxdevice *)vi->ui_addr;
        vxinit(vi->ui_unit, 1);
 }
 
        vxinit(vi->ui_unit, 1);
 }
 
@@ -147,7 +197,8 @@ vxopen(dev, flag)
        register struct tty *tp;        /* pointer to tty struct for port */
        register struct vx_softc *vs;
        register struct vba_device *vi;
        register struct tty *tp;        /* pointer to tty struct for port */
        register struct vx_softc *vs;
        register struct vba_device *vi;
-       int unit, vx, s, error;
+       int unit, vx, s, error = 0;
+       int vxparam();
 
        unit = minor(dev);
        vx = VXUNIT(unit);
 
        unit = minor(dev);
        vx = VXUNIT(unit);
@@ -162,22 +213,32 @@ vxopen(dev, flag)
                return (ENXIO);
        tp->t_addr = (caddr_t)vs;
        tp->t_oproc = vxstart;
                return (ENXIO);
        tp->t_addr = (caddr_t)vs;
        tp->t_oproc = vxstart;
+       tp->t_param = vxparam;
        tp->t_dev = dev;
        s = spl8();
        tp->t_dev = dev;
        s = spl8();
-       tp->t_state |= TS_WOPEN;
        if ((tp->t_state&TS_ISOPEN) == 0) {
        if ((tp->t_state&TS_ISOPEN) == 0) {
+               tp->t_state |= TS_WOPEN;
                ttychars(tp);
                if (tp->t_ispeed == 0) {
                ttychars(tp);
                if (tp->t_ispeed == 0) {
-                       tp->t_ispeed = SSPEED;
-                       tp->t_ospeed = SSPEED;
-                       tp->t_flags |= ODDP|EVENP|ECHO;
+                       tp->t_iflag = TTYDEF_IFLAG;
+                       tp->t_oflag = TTYDEF_OFLAG;
+                       tp->t_lflag = TTYDEF_LFLAG;
+                       tp->t_cflag = TTYDEF_CFLAG;
+                       tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
                }
                }
-               vxparam(dev);
+               vxparam(tp, &tp->t_termios);
+               ttsetwater(tp);
        }
        vcmodem(dev, VMOD_ON);
        }
        vcmodem(dev, VMOD_ON);
-       while ((tp->t_state&TS_CARR_ON) == 0)
-               sleep((caddr_t)&tp->t_rawq, TTIPRI);
-       error = (*linesw[tp->t_line].l_open)(dev,tp);
+       while (!(flag&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) && 
+             (tp->t_state&TS_CARR_ON) == 0) {
+               tp->t_state |= TS_WOPEN;
+               if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
+                   ttopen, 0))
+                       break;
+       }
+       if (error == 0)
+               error = (*linesw[tp->t_line].l_open)(dev,tp);
        splx(s);
        return (error);
 }
        splx(s);
        return (error);
 }
@@ -191,43 +252,46 @@ vxclose(dev, flag)
        int flag;
 {
        register struct tty *tp;
        int flag;
 {
        register struct tty *tp;
-       int unit, s;
+       int unit, s, error = 0;
 
        unit = minor(dev);
        tp = &vx_tty[unit];
        s = spl8();
        (*linesw[tp->t_line].l_close)(tp);
 
        unit = minor(dev);
        tp = &vx_tty[unit];
        s = spl8();
        (*linesw[tp->t_line].l_close)(tp);
-       if (tp->t_state & TS_HUPCLS || (tp->t_state & TS_ISOPEN) == 0)
+       if (tp->t_cflag & HUPCL || (tp->t_state & TS_ISOPEN) == 0)
                vcmodem(dev, VMOD_OFF);
        /* wait for the last response */
                vcmodem(dev, VMOD_OFF);
        /* wait for the last response */
-       while (tp->t_state&TS_FLUSH)
-               sleep((caddr_t)&tp->t_state, TTOPRI);
-       ttyclose(tp);
+       while (tp->t_state&TS_FLUSH && error == 0)
+               error = tsleep((caddr_t)&tp->t_state, TTOPRI | PCATCH,
+                   ttclos, 0);
        splx(s);
        splx(s);
+       if (error)
+               return (error);
+       return (ttyclose(tp));
 }
 
 /*
  * Read from a VX line.
  */
 }
 
 /*
  * Read from a VX line.
  */
-vxread(dev, uio)
+vxread(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 {
        struct tty *tp = &vx_tty[minor(dev)];
 
        dev_t dev;
        struct uio *uio;
 {
        struct tty *tp = &vx_tty[minor(dev)];
 
-       return ((*linesw[tp->t_line].l_read)(tp, uio));
+       return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
 }
 
 /*
  * write on a VX line
  */
 }
 
 /*
  * write on a VX line
  */
-vxwrite(dev, uio)
+vxwrite(dev, uio, flag)
        dev_t dev;
        struct uio *uio;
 {
        register struct tty *tp = &vx_tty[minor(dev)];
 
        dev_t dev;
        struct uio *uio;
 {
        register struct tty *tp = &vx_tty[minor(dev)];
 
-       return ((*linesw[tp->t_line].l_write)(tp, uio));
+       return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
 }
 
 /*
 }
 
 /*
@@ -242,7 +306,7 @@ vxrint(vx)
        struct vba_device *vi;
        register int nc, c;
        register struct silo {
        struct vba_device *vi;
        register int nc, c;
        register struct silo {
-               char    data, port;
+               u_char  data, port;
        } *sp;
        short *osp;
        int overrun = 0;
        } *sp;
        short *osp;
        int overrun = 0;
@@ -255,8 +319,13 @@ vxrint(vx)
        case 0:
                break;
        case 2:
        case 0:
                break;
        case 2:
-               printf("vx%d: vc proc err, ustat %x\n", vx, addr->v_ustat);
-               vxstreset(vx);
+               if (addr->v_ustat == VP_SILO_OFLOW)
+                       log(LOG_ERR, "vx%d: input silo overflow\n", vx);
+               else {
+                       printf("vx%d: vc proc err, ustat %x\n",
+                           vx, addr->v_ustat);
+                       vxstreset(vx);
+               }
                return;
        case 3:
                vcmintr(vx);
                return;
        case 3:
                vcmintr(vx);
@@ -291,29 +360,16 @@ vxrint(vx)
                        wakeup((caddr_t)&tp->t_rawq);
                        continue;
                }
                        wakeup((caddr_t)&tp->t_rawq);
                        continue;
                }
-               c = sp->data;
+               c = sp->data&((tp->t_cflag&CSIZE)==CS8 ? 0xff : 0x7f);
                if ((sp->port&VX_RO) == VX_RO && !overrun) {
                        log(LOG_ERR, "vx%d: receiver overrun\n", vi->ui_unit);
                        overrun = 1;
                        continue;
                }
                if (sp->port&VX_PE)
                if ((sp->port&VX_RO) == VX_RO && !overrun) {
                        log(LOG_ERR, "vx%d: receiver overrun\n", vi->ui_unit);
                        overrun = 1;
                        continue;
                }
                if (sp->port&VX_PE)
-                       if ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
-                           (tp->t_flags&(EVENP|ODDP)) == ODDP)
-                               continue;
-               if ((tp->t_flags & (RAW | PASS8)) == 0)
-                       c &= 0177;
-               if (sp->port&VX_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;
-               }
+                       c |= TTY_PE;
+               if (sp->port&VX_FE) 
+                       c |= TTY_FE;
                (*linesw[tp->t_line].l_rint)(c, tp);
        }
        *osp = 0;
                (*linesw[tp->t_line].l_rint)(c, tp);
        }
        *osp = 0;
@@ -331,44 +387,38 @@ vxioctl(dev, cmd, data, flag)
 
        tp = &vx_tty[minor(dev)];
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
 
        tp = &vx_tty[minor(dev)];
        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
-       if (error == 0)
+       if (error >= 0)
                return (error);
        error = ttioctl(tp, cmd, data, flag);
                return (error);
        error = ttioctl(tp, cmd, data, flag);
-       if (error >= 0) {
-               if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS ||
-                   cmd == TIOCLBIC || cmd == TIOCLSET)
-                       vxparam(dev);
+       if (error >= 0) 
                return (error);
                return (error);
-       }
        return (ENOTTY);
 }
 
        return (ENOTTY);
 }
 
-vxparam(dev)
-       dev_t dev;
+vxparam(tp, t)
+       struct tty *tp;
+       struct termios *t;
 {
 
 {
 
-       vxcparam(dev, 1);
+       return (vxcparam(tp, t, 1));
 }
 
 /*
  * Set parameters from open or stty into the VX hardware
  * registers.
  */
 }
 
 /*
  * Set parameters from open or stty into the VX hardware
  * registers.
  */
-vxcparam(dev, wait)
-       dev_t dev;
+vxcparam(tp, t, wait)
+       struct tty *tp;
+       struct termios *t;
        int wait;
 {
        int wait;
 {
-       register struct tty *tp;
        register struct vx_softc *vs;
        register struct vxcmd *cp;
        register struct vx_softc *vs;
        register struct vxcmd *cp;
-       int s, unit = minor(dev);
+       int s, error = 0;
+       int speedcode = ttspeedtab(t->c_ospeed, vxspeedtab);
 
 
-       tp = &vx_tty[unit];
-       if ((tp->t_ispeed)==0) {
-               tp->t_state |= TS_HUPCLS;
-               vcmodem(dev, VMOD_OFF);
-               return;
-       }
+       if (speedcode < 0 || (t->c_ispeed != t->c_ospeed && t->c_ispeed))
+               return (EINVAL);
        vs = (struct vx_softc *)tp->t_addr;
        cp = vobtain(vs);
        s = spl8();
        vs = (struct vx_softc *)tp->t_addr;
        cp = vobtain(vs);
        s = spl8();
@@ -378,34 +428,58 @@ vxcparam(dev, wait)
         * and stop bits for the specified port.
         */
        cp->cmd = VXC_LPARAX;
         * and stop bits for the specified port.
         */
        cp->cmd = VXC_LPARAX;
-       cp->par[1] = VXPORT(unit);
-       cp->par[2] = (tp->t_flags&RAW) ? 0 : tp->t_startc;
-       cp->par[3] = (tp->t_flags&RAW) ? 0 : tp->t_stopc;
+       cp->par[1] = VXPORT(minor(tp->t_dev));
+       /*
+        * note: if the hardware does flow control, ^V doesn't work
+        * to escape ^S
+        */
+       if (t->c_iflag&IXON) {
+               if (t->c_cc[VSTART] == _POSIX_VDISABLE)
+                       cp->par[2] = 0;
+               else
+                       cp->par[2] = t->c_cc[VSTART];
+               if (t->c_cc[VSTOP] == _POSIX_VDISABLE)
+                       cp->par[3] = 0;
+               else
+                       cp->par[3] = t->c_cc[VSTOP];
+       } else 
+               cp->par[2] = cp->par[3] = 0;
 #ifdef notnow
 #ifdef notnow
-       if (tp->t_flags & (RAW|LITOUT|PASS8)) {
+       switch (t->c_cflag & CSIZE) {   /* XXX */
+       case CS8:
 #endif
                cp->par[4] = BITS8;             /* 8 bits of data */
 #endif
                cp->par[4] = BITS8;             /* 8 bits of data */
-               cp->par[7] = VNOPARITY;         /* no parity */
 #ifdef notnow
 #ifdef notnow
-       } else {
+               break;
+       case CS7:
                cp->par[4] = BITS7;             /* 7 bits of data */
                cp->par[4] = BITS7;             /* 7 bits of data */
-               if ((tp->t_flags&(EVENP|ODDP)) == ODDP)
-                       cp->par[7] = VODDP;     /* odd parity */
-               else
-                       cp->par[7] = VEVENP;    /* even parity */
+               break;
+       case CS6:
+               cp->par[4] = BITS6;             /* 6 bits of data */
+               break;
+       case CS5:
+               cp->par[4] = BITS5;             /* 5 bits of data */
+               break;
        }
        }
+       if ((t->c_cflag & PARENB) == 0)         /* XXX */
 #endif
 #endif
-       if (tp->t_ospeed == B110)
-               cp->par[5] = VSTOP2;            /* 2 stop bits */
-       else
-               cp->par[5] = VSTOP1;            /* 1 stop bit */
-       if (tp->t_ospeed == EXTA || tp->t_ospeed == EXTB)
-               cp->par[6] = V19200;
+               cp->par[7] = VNOPARITY;         /* no parity */
+#ifdef notnow
+       else if (t->c_cflag&PARODD)
+               cp->par[7] = VODDP;     /* odd parity */
        else
        else
-               cp->par[6] = tp->t_ospeed;
+               cp->par[7] = VEVENP;    /* even parity */
+#endif
+       cp->par[5] = (t->c_cflag&CSTOPB) ? VSTOP2 : VSTOP1;
+       cp->par[6] = speedcode;
        if (vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd) && wait)
        if (vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd) && wait)
-               sleep((caddr_t)cp,TTIPRI);
+               error = tsleep((caddr_t)cp, TTIPRI | PCATCH, ttyout, 0);
+       if ((t->c_ospeed)==0) {
+               tp->t_cflag |= HUPCL;
+               vcmodem(tp->t_dev, VMOD_OFF);
+       }
        splx(s);
        splx(s);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -460,11 +534,11 @@ vxxint(vx, cp)
        }
        vrelease(vs, cp);
        if (vs->vs_vers == VXV_NEW)
        }
        vrelease(vs, cp);
        if (vs->vs_vers == VXV_NEW)
-               vxstart(tp);
+               (*linesw[tp->t_line].l_start)(tp);
        else {
                tp0 = &vx_tty[vx*16 + vs->vs_hiport];
                for(tp = &vx_tty[vx*16 + vs->vs_loport]; tp <= tp0; tp++)
        else {
                tp0 = &vx_tty[vx*16 + vs->vs_hiport];
                for(tp = &vx_tty[vx*16 + vs->vs_loport]; tp <= tp0; tp++)
-                       vxstart(tp);
+                       (*linesw[tp->t_line].l_start)(tp);
                if ((cp = nextcmd(vs)) != NULL) {       /* command to send? */
                        vs->vs_xmtcnt++;
                        (void) vcmd(vx, (caddr_t)&cp->cmd);
                if ((cp = nextcmd(vs)) != NULL) {       /* command to send? */
                        vs->vs_xmtcnt++;
                        (void) vcmd(vx, (caddr_t)&cp->cmd);
@@ -501,10 +575,10 @@ vxstart(tp)
        int s, port;
 
        s = spl8();
        int s, port;
 
        s = spl8();
-       port = minor(tp->t_dev) & 017;
+       port = VXPORT(minor(tp->t_dev));
        vs = (struct vx_softc *)tp->t_addr;
        if ((tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) == 0) {
        vs = (struct vx_softc *)tp->t_addr;
        if ((tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) == 0) {
-               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);
@@ -520,7 +594,7 @@ vxstart(tp)
                        return;
                }
                scope_out(3);
                        return;
                }
                scope_out(3);
-               if (tp->t_flags & (RAW|LITOUT))
+               if (1 || !(tp->t_oflag&OPOST))  /* XXX */
                        n = ndqb(&tp->t_outq, 0);
                else {
                        n = ndqb(&tp->t_outq, 0200);
                        n = ndqb(&tp->t_outq, 0);
                else {
                        n = ndqb(&tp->t_outq, 0200);
@@ -560,7 +634,7 @@ static      int vxbbno = -1;
  * Resets all viocx's.  Issues a LIDENT command to each
  * viocx to establish interrupt vectors and logical port numbers.
  */
  * Resets all viocx's.  Issues a LIDENT command to each
  * viocx to establish interrupt vectors and logical port numbers.
  */
-vxinit(vx, wait) 
+vxinit(vx, wait)
        register int vx;
        int wait;
 {
        register int vx;
        int wait;
 {
@@ -572,8 +646,7 @@ vxinit(vx, wait)
        char type, *typestring;
 
        vs = &vx_softc[vx];
        char type, *typestring;
 
        vs = &vx_softc[vx];
-       vs->vs_type = 0;                /* vioc-x by default */
-       addr = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       addr = vs->vs_addr;
        type = addr->v_ident;
        vs->vs_vers = (type&VXT_NEW) ? VXV_NEW : VXV_OLD;
        if (vs->vs_vers == VXV_NEW)
        type = addr->v_ident;
        vs->vs_vers = (type&VXT_NEW) ? VXV_NEW : VXV_OLD;
        if (vs->vs_vers == VXV_NEW)
@@ -585,7 +658,8 @@ vxinit(vx, wait)
                typestring = "VIOC-X";
                /* set soft carrier for printer ports */
                for (j = 0; j < 16; j++)
                typestring = "VIOC-X";
                /* set soft carrier for printer ports */
                for (j = 0; j < 16; j++)
-                       if (addr->v_portyp[j] == VXT_PARALLEL) {
+                       if (vs->vs_softCAR & (1 << j) ||
+                           addr->v_portyp[j] == VXT_PARALLEL) {
                                vs->vs_softCAR |= 1 << j;
                                addr->v_dcd |= 1 << j;
                        }
                                vs->vs_softCAR |= 1 << j;
                                addr->v_dcd |= 1 << j;
                        }
@@ -599,13 +673,14 @@ vxinit(vx, wait)
                vs->vs_type = 1;
                vs->vs_bop = ++vxbbno;
                printf("VIOC-BOP no. %d at %x\n", vs->vs_bop, addr);
                vs->vs_type = 1;
                vs->vs_bop = ++vxbbno;
                printf("VIOC-BOP no. %d at %x\n", vs->vs_bop, addr);
-
+               goto unsup;
        default:
                printf("vx%d: unknown type %x\n", vx, type);
        default:
                printf("vx%d: unknown type %x\n", vx, type);
+       unsup:
                vxinfo[vx]->ui_alive = 0;
                return;
        }
                vxinfo[vx]->ui_alive = 0;
                return;
        }
-       vs->vs_nbr = -1;
+       vs->vs_nbr = vx;                /* assign board number */
        vs->vs_maxcmd = (vs->vs_vers == VXV_NEW) ? 24 : 4;
        /*
         * Initialize all cmd buffers by linking them
        vs->vs_maxcmd = (vs->vs_vers == VXV_NEW) ? 24 : 4;
        /*
         * Initialize all cmd buffers by linking them
@@ -631,6 +706,7 @@ vxinit(vx, wait)
        (void) vcmd(vx, (caddr_t)&cp->cmd);
        if (!wait)
                return;
        (void) vcmd(vx, (caddr_t)&cp->cmd);
        if (!wait)
                return;
+
        for (j = 0; cp->cmd == VXC_LIDENT && j < 4000000; j++)
                ;
        if (j >= 4000000)
        for (j = 0; cp->cmd == VXC_LIDENT && j < 4000000; j++)
                ;
        if (j >= 4000000)
@@ -648,7 +724,6 @@ vxinit(vx, wait)
            (vs->vs_vers == VXV_NEW) ? "" : "old ", typestring,
            vs->vs_loport, vs->vs_hiport);
        vrelease(vs, cp);
            (vs->vs_vers == VXV_NEW) ? "" : "old ", typestring,
            vs->vs_loport, vs->vs_hiport);
        vrelease(vs, cp);
-       vs->vs_nbr = vx;                /* assign board number */
 }
 
 /*
 }
 
 /*
@@ -668,8 +743,8 @@ vobtain(vs)
                if (vxintr4&VXNOBUF)
                        vxintr4 &= ~VXNOBUF;
 #endif
                if (vxintr4&VXNOBUF)
                        vxintr4 &= ~VXNOBUF;
 #endif
-               printf("vx%d: no buffers\n", vs - vx_softc);
-               vxstreset(vs - vx_softc);
+               printf("vx%d: no buffers\n", vs->vs_nbr);
+               vxstreset(vs->vs_nbr);
                splx(s);
                return (vobtain(vs));
        }
                splx(s);
                return (vobtain(vs));
        }
@@ -780,11 +855,10 @@ vcmd(vx, cmdad)
        register caddr_t cmdad;
 {
        register struct vcmds *cp;
        register caddr_t cmdad;
 {
        register struct vcmds *cp;
-       register struct vx_softc *vs;
+       register struct vx_softc *vs = &vx_softc[vx];
        int s;
 
        s = spl8();
        int s;
 
        s = spl8();
-       vs = &vx_softc[vx];
        /*
         * When the vioc is resetting, don't process
         * anything other than VXC_LIDENT commands.
        /*
         * When the vioc is resetting, don't process
         * anything other than VXC_LIDENT commands.
@@ -837,7 +911,7 @@ vackint(vx)
        if (vs->vs_type)        /* Its a BOP */
                return;
        s = spl8();
        if (vs->vs_type)        /* Its a BOP */
                return;
        s = spl8();
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vp = vs->vs_addr;
        cp = &vs->vs_cmds;
        if (vp->v_vcid&V_ERR) {
                register char *resp;
        cp = &vs->vs_cmds;
        if (vp->v_vcid&V_ERR) {
                register char *resp;
@@ -902,7 +976,7 @@ vcmdrsp(vx)
                return;
        }
        s = spl8();
                return;
        }
        s = spl8();
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vp = vs->vs_addr;
        cp = &vs->vs_cmds;
        resp = (char *)vp + (vp->v_rspoff&0x7fff);
        if (((k = resp[1])&V_UNBSY) == 0) {
        cp = &vs->vs_cmds;
        resp = (char *)vp + (vp->v_rspoff&0x7fff);
        if (((k = resp[1])&V_UNBSY) == 0) {
@@ -943,7 +1017,7 @@ vunsol(vx)
                return;
        }
        s = spl8();
                return;
        }
        s = spl8();
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vp = vs->vs_addr;
        if (vp->v_uqual&V_UNBSY) {
                vxrint(vx);
                vinthandl(vx, ((V_BSY|UNSquals) << 8)|V_INTR);
        if (vp->v_uqual&V_UNBSY) {
                vxrint(vx);
                vinthandl(vx, ((V_BSY|UNSquals) << 8)|V_INTR);
@@ -980,17 +1054,19 @@ vinthandl(vx, item)
 }
 
 vintempt(vx)
 }
 
 vintempt(vx)
-       register int vx;
+       int vx;
 {
        register struct vcmds *cp;
        register struct vxdevice *vp;
 {
        register struct vcmds *cp;
        register struct vxdevice *vp;
+       register struct vx_softc *vs;
        register short item;
        register short *intr;
 
        register short item;
        register short *intr;
 
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vs = &vx_softc[vx];
+       vp = vs->vs_addr;
        if (vp->v_vioc&V_BSY)
                return;
        if (vp->v_vioc&V_BSY)
                return;
-       cp = &vx_softc[vx].vs_cmds;
+       cp = &vs->vs_cmds;
        if (cp->v_itrempt == cp->v_itrfill)
                return;
        item = cp->v_itrqueu[cp->v_itrempt];
        if (cp->v_itrempt == cp->v_itrfill)
                return;
        item = cp->v_itrqueu[cp->v_itrempt];
@@ -1002,7 +1078,7 @@ vintempt(vx)
 
                if (cp->v_empty == cp->v_fill || vp->v_vcbsy&V_BSY)
                        break;
 
                if (cp->v_empty == cp->v_fill || vp->v_vcbsy&V_BSY)
                        break;
-               vx_softc[vx].vs_mricmd = (caddr_t)cp->cmdbuf[cp->v_empty];
+               vs->vs_mricmd = (caddr_t)cp->cmdbuf[cp->v_empty];
                phys = vtoph((struct proc *)0, 
                    (unsigned)cp->cmdbuf[cp->v_empty]);
                vp->v_vcp[0] = ((short *)&phys)[0];
                phys = vtoph((struct proc *)0, 
                    (unsigned)cp->cmdbuf[cp->v_empty]);
                vp->v_vcp[0] = ((short *)&phys)[0];
@@ -1030,7 +1106,7 @@ vintempt(vx)
  * Start a reset on a vioc after error (hopefully)
  */
 vxstreset(vx)
  * Start a reset on a vioc after error (hopefully)
  */
 vxstreset(vx)
-       register vx;
+       register int vx;
 {
        register struct vx_softc *vs;
        register struct vxdevice *vp;
 {
        register struct vx_softc *vs;
        register struct vxdevice *vp;
@@ -1039,19 +1115,20 @@ vxstreset(vx)
        extern int vxinreset();
        int s;
 
        extern int vxinreset();
        int s;
 
-       s = spl8() ;
        vs = &vx_softc[vx];
        vs = &vx_softc[vx];
+       s = spl8();
        if (vs->vs_state == VXS_RESET) {        /* avoid recursion */
                splx(s);
                return;
        }
        if (vs->vs_state == VXS_RESET) {        /* avoid recursion */
                splx(s);
                return;
        }
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vp = vs->vs_addr;
        /*
         * Zero out the vioc structures, mark the vioc as being
         * reset, reinitialize the free command list, reset the vioc
         * and start a timer to check on the progress of the reset.
         */
        /*
         * Zero out the vioc structures, mark the vioc as being
         * reset, reinitialize the free command list, reset the vioc
         * and start a timer to check on the progress of the reset.
         */
-       bzero((caddr_t)vs, (unsigned)sizeof (*vs));
+       bzero((caddr_t)&vs->vs_zero,
+           (unsigned)((caddr_t)(vs + 1) - (caddr_t)&vs->vs_zero));
 
        /*
         * Setting VXS_RESET prevents others from issuing
 
        /*
         * Setting VXS_RESET prevents others from issuing
@@ -1081,12 +1158,12 @@ vxinreset(vx)
        register struct vxdevice *vp;
        int s = spl8();
 
        register struct vxdevice *vp;
        int s = spl8();
 
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vp = vx_softc[vx].vs_addr;
        /*
         * See if the vioc has reset.
         */
        if (vp->v_fault != VXF_READY) {
        /*
         * See if the vioc has reset.
         */
        if (vp->v_fault != VXF_READY) {
-               printf("failed\n");
+               printf(" vxreset failed\n");
                splx(s);
                return;
        }
                splx(s);
                return;
        }
@@ -1111,7 +1188,7 @@ vxfnreset(vx, cp)
        register struct vxcmd *cp;
 {
        register struct vx_softc *vs;
        register struct vxcmd *cp;
 {
        register struct vx_softc *vs;
-       register struct vxdevice *vp ;
+       register struct vxdevice *vp;
        register struct tty *tp, *tp0;
        register int i;
 #ifdef notdef
        register struct tty *tp, *tp0;
        register int i;
 #ifdef notdef
@@ -1121,13 +1198,10 @@ vxfnreset(vx, cp)
        int s = spl8();
 
        vs = &vx_softc[vx];
        int s = spl8();
 
        vs = &vx_softc[vx];
-       vs->vs_loport = cp->par[5];
-       vs->vs_hiport = cp->par[7];
        vrelease(vs, cp);
        vrelease(vs, cp);
-       vs->vs_nbr = vx;                        /* assign VIOC-X board number */
        vs->vs_state = VXS_READY;
 
        vs->vs_state = VXS_READY;
 
-       vp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vp = vs->vs_addr;
        vp->v_vcid = 0;
 
        /*
        vp->v_vcid = 0;
 
        /*
@@ -1185,14 +1259,14 @@ vxrestart(vx)
                                vxstart(tp);    /* restart pending output */
                } else {
                        if (tp->t_state&(TS_WOPEN|TS_ISOPEN))
                                vxstart(tp);    /* restart pending output */
                } else {
                        if (tp->t_state&(TS_WOPEN|TS_ISOPEN))
-                               vxcparam(tp->t_dev, 0);
+                               vxcparam(tp, &tp->t_termios, 0);
                }
        }
        if (count == 0) {
                vs->vs_state = VXS_RESET;
                timeout(vxrestart, (caddr_t)(vx + 1*256), hz);
        } else
                }
        }
        if (count == 0) {
                vs->vs_state = VXS_RESET;
                timeout(vxrestart, (caddr_t)(vx + 1*256), hz);
        } else
-               printf("done\n");
+               printf(" vx reset done\n");
        splx(s);
 }
 
        splx(s);
 }
 
@@ -1203,7 +1277,7 @@ vxreset(dev)
        vxstreset((int)VXUNIT(minor(dev)));     /* completes asynchronously */
 }
 
        vxstreset((int)VXUNIT(minor(dev)));     /* completes asynchronously */
 }
 
-#ifdef notdef
+#ifdef VX_DEBUG
 vxfreset(vx)
        register int vx;
 {
 vxfreset(vx)
        register int vx;
 {
@@ -1233,30 +1307,29 @@ vcmodem(dev, flag)
        if (vs->vs_state != VXS_READY)
                return;
        cp = vobtain(vs);
        if (vs->vs_state != VXS_READY)
                return;
        cp = vobtain(vs);
-       kp = (struct vxdevice *)((struct vba_device *)vxinfo[vs->vs_nbr])->ui_addr;
+       kp = vs->vs_addr;
 
 
-       port = unit & 017;
+       port = VXPORT(unit);
        /*
         * Issue MODEM command
         */
        cp->cmd = VXC_MDMCTL;
        if (flag == VMOD_ON) {
        /*
         * Issue MODEM command
         */
        cp->cmd = VXC_MDMCTL;
        if (flag == VMOD_ON) {
-               if (vs->vs_softCAR & (1 << port))
+               if (vs->vs_softCAR & (1 << port)) {
                        cp->par[0] = V_MANUAL | V_DTR_ON | V_RTS;
                        cp->par[0] = V_MANUAL | V_DTR_ON | V_RTS;
-               else
-                       cp->par[0] = V_AUTO | V_DTR_ON | V_RTS;
+                       kp->v_dcd |= (1 << port);
+               } else
+                       cp->par[0] = V_AUTO | V_DTR_ON;
        } else
                cp->par[0] = V_DTR_OFF;
        cp->par[1] = port;
        (void) vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd);
        } else
                cp->par[0] = V_DTR_OFF;
        cp->par[1] = port;
        (void) vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd);
-       if (vs->vs_softCAR & (1 << port))
-               kp->v_dcd |= (1 << port);
        if ((kp->v_dcd | vs->vs_softCAR) & (1 << port) && flag == VMOD_ON)
                tp->t_state |= TS_CARR_ON;
 }
 
 /*
        if ((kp->v_dcd | vs->vs_softCAR) & (1 << port) && flag == VMOD_ON)
                tp->t_state |= TS_CARR_ON;
 }
 
 /*
- * VCMINTR called when an unsolicited interrup occurs signaling
+ * VCMINTR called when an unsolicited interrupt occurs signaling
  * some change of modem control state.
  */
 vcmintr(vx)
  * some change of modem control state.
  */
 vcmintr(vx)
@@ -1267,10 +1340,10 @@ vcmintr(vx)
        register port;
        register struct vx_softc *vs;
 
        register port;
        register struct vx_softc *vs;
 
-       kp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
+       vs = &vx_softc[vx];
+       kp = vs->vs_addr;
        port = kp->v_usdata[0] & 017;
        tp = &vx_tty[vx*16+port];
        port = kp->v_usdata[0] & 017;
        tp = &vx_tty[vx*16+port];
-       vs = &vx_softc[vx];
 
        if (kp->v_ustat & DCD_ON)
                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
 
        if (kp->v_ustat & DCD_ON)
                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
@@ -1309,8 +1382,7 @@ vcmintr(vx)
                        }
                }
        } else if ((kp->v_ustat&BRK_CHR) && (tp->t_state&TS_ISOPEN)) {
                        }
                }
        } else if ((kp->v_ustat&BRK_CHR) && (tp->t_state&TS_ISOPEN)) {
-               (*linesw[tp->t_line].l_rint)((tp->t_flags & RAW) ?
-                   0 : tp->t_intrc, tp);
+               (*linesw[tp->t_line].l_rint)(TTY_FE, tp);
                return;
        }
 }
                return;
        }
 }