more or less 4.3
authorMike Karels <karels@ucbvax.Berkeley.EDU>
Mon, 12 Jan 1987 13:23:54 +0000 (05:23 -0800)
committerMike Karels <karels@ucbvax.Berkeley.EDU>
Mon, 12 Jan 1987 13:23:54 +0000 (05:23 -0800)
SCCS-vsn: sys/tahoe/vba/vd.c 1.13
SCCS-vsn: sys/tahoe/vba/cy.c 1.9
SCCS-vsn: sys/tahoe/vba/cyreg.h 7.3
SCCS-vsn: sys/tahoe/vba/vdreg.h 1.7
SCCS-vsn: sys/tahoe/vba/vx.c 1.10
SCCS-vsn: sys/tahoe/vba/vxreg.h 1.5

usr/src/sys/tahoe/vba/cy.c
usr/src/sys/tahoe/vba/cyreg.h
usr/src/sys/tahoe/vba/vd.c
usr/src/sys/tahoe/vba/vdreg.h
usr/src/sys/tahoe/vba/vx.c
usr/src/sys/tahoe/vba/vxreg.h

index f7c5af6..e0867f1 100644 (file)
@@ -1,12 +1,17 @@
-/*     cy.c    1.8     86/12/15        */
+/*     cy.c    1.9     87/01/11        */
 
 #include "yc.h"
 #if NCY > 0
 /*
  * Cipher Tapemaster driver.
  */
 
 #include "yc.h"
 #if NCY > 0
 /*
  * Cipher Tapemaster driver.
  */
+#define CYDEBUG
+#ifdef CYDEBUG
 int    cydebug = 0;
 int    cydebug = 0;
-#define        dlog    if (cydebug) log
+#define        dlog(params)    if (cydebug) log params
+#else
+#define dlog(params)   /* */
+#endif
 
 #include "param.h"
 #include "systm.h"
 
 #include "param.h"
 #include "systm.h"
@@ -65,8 +70,8 @@ struct        vba_driver cydriver =
 #define        YCUNIT(dev)     (minor(dev)&03)
 #define        CYUNIT(dev)     (yctocy[YCUNIT(dev)])
 #define        T_NOREWIND      0x04
 #define        YCUNIT(dev)     (minor(dev)&03)
 #define        CYUNIT(dev)     (yctocy[YCUNIT(dev)])
 #define        T_NOREWIND      0x04
-#define        T_1600BPI       0x08
-#define        T_3200BPI       0x10
+#define        T_1600BPI       0x00            /* pseudo */
+#define        T_3200BPI       0x08            /* unused */
 
 #define        INF     1000000L                /* close to infinity */
 #define        CYMAXIO (32*NBPG)               /* max i/o size */
 
 #define        INF     1000000L                /* close to infinity */
 #define        CYMAXIO (32*NBPG)               /* max i/o size */
@@ -81,12 +86,12 @@ struct cy_softc {
        struct  pte *cy_map;    /* pte's for mapped buffer i/o */
        caddr_t cy_utl;         /* mapped virtual address */
        int     cy_bs;          /* controller's buffer size */
        struct  pte *cy_map;    /* pte's for mapped buffer i/o */
        caddr_t cy_utl;         /* mapped virtual address */
        int     cy_bs;          /* controller's buffer size */
-       char    cy_buf[CYMAXIO];/* intermediate buffer */
        struct  cyscp *cy_scp;  /* system configuration block address */
        struct  cyccb cy_ccb;   /* channel control block */
        struct  cyscb cy_scb;   /* system configuration block */
        struct  cytpb cy_tpb;   /* tape parameter block */
        struct  cytpb cy_nop;   /* nop parameter block for cyintr */
        struct  cyscp *cy_scp;  /* system configuration block address */
        struct  cyccb cy_ccb;   /* channel control block */
        struct  cyscb cy_scb;   /* system configuration block */
        struct  cytpb cy_tpb;   /* tape parameter block */
        struct  cytpb cy_nop;   /* nop parameter block for cyintr */
+       char    cy_buf[CYMAXIO];/* intermediate buffer */
 } cy_softc[NCY];
 
 /*
 } cy_softc[NCY];
 
 /*
@@ -104,6 +109,9 @@ struct      yc_softc {
        struct  tty *yc_ttyp;   /* user's tty for errors */
        daddr_t yc_blkno;       /* block number, for block device tape */
        daddr_t yc_nxrec;       /* position of end of tape, if known */
        struct  tty *yc_ttyp;   /* user's tty for errors */
        daddr_t yc_blkno;       /* block number, for block device tape */
        daddr_t yc_nxrec;       /* position of end of tape, if known */
+       int     yc_blksize;     /* current tape blocksize estimate */
+       int     yc_blks;        /* number of I/O operations since open */
+       int     yc_softerrs;    /* number of soft I/O errors since open */
 } yc_softc[NYC];
 
 /*
 } yc_softc[NYC];
 
 /*
@@ -127,6 +135,8 @@ cyprobe(reg, vm)
        struct vba_ctlr *vm;
 {
        register br, cvec;                      /* must be r12, r11 */
        struct vba_ctlr *vm;
 {
        register br, cvec;                      /* must be r12, r11 */
+       register struct cy_softc *cy;
+       int ctlr = vm->um_ctlr;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
@@ -134,16 +144,32 @@ cyprobe(reg, vm)
 #endif
        if (badcyaddr(reg+1))
                return (0);
 #endif
        if (badcyaddr(reg+1))
                return (0);
-       if (vm->um_ctlr > NCYSCP || cyscp[vm->um_ctlr] == 0)    /* XXX */
-               return (0);                                     /* XXX */
-       cy_softc[vm->um_ctlr].cy_scp = cyscp[vm->um_ctlr];      /* XXX */
+       if (ctlr > NCYSCP || cyscp[ctlr] == 0)          /* XXX */
+               return (0);
+       cy = &cy_softc[ctlr];
+       cy->cy_scp = cyscp[ctlr];                       /* XXX */
        /*
         * Tapemaster controller must have interrupt handler
         * disable interrupt, so we'll just kludge things
         * (stupid multibus non-vectored interrupt crud).
         */
        /*
         * Tapemaster controller must have interrupt handler
         * disable interrupt, so we'll just kludge things
         * (stupid multibus non-vectored interrupt crud).
         */
-       br = 0x13, cvec = 0x80;                                 /* XXX */
-       return (sizeof (struct cyccb));
+       if (cyinit(ctlr, reg)) {
+               uncache(&cy->cy_tpb.tpcount);
+               cy->cy_bs = htoms(cy->cy_tpb.tpcount);
+               /*
+                * Setup nop parameter block for clearing interrupts.
+                */
+               cy->cy_nop.tpcmd = CY_NOP;
+               cy->cy_nop.tpcontrol = 0;
+               /*
+                * Allocate page tables.
+                */
+               vbmapalloc(btoc(CYMAXIO)+1, &cy->cy_map, &cy->cy_utl);
+
+               br = 0x13, cvec = 0x80;                 /* XXX */
+               return (sizeof (struct cyccb));
+       } else
+               return (0);
 }
 
 /*
 }
 
 /*
@@ -170,20 +196,8 @@ cyattach(vi)
 
        yctocy[vi->ui_unit] = ctlr;
        cy = &cy_softc[ctlr];
 
        yctocy[vi->ui_unit] = ctlr;
        cy = &cy_softc[ctlr];
-       if (cy->cy_bs == 0 && cyinit(ctlr)) {
-               uncache(&cy->cy_tpb.tpcount);
-               cy->cy_bs = htoms(cy->cy_tpb.tpcount);
-               printf("cy%d: %dkb buffer\n", ctlr, cy->cy_bs/1024);
-               /*
-                * Setup nop parameter block for clearing interrupts.
-                */
-               cy->cy_nop.tpcmd = CY_NOP;
-               cy->cy_nop.tpcontrol = 0;
-               /*
-                * Allocate page tables.
-                */
-               vbmapalloc(btoc(CYMAXIO)+1, &cy->cy_map, &cy->cy_utl);
-       }
+       if (vi->ui_slave == 0 && cy->cy_bs)
+               printf("; %dkb buffer", cy->cy_bs/1024);
 }
 
 /*
 }
 
 /*
@@ -192,11 +206,11 @@ cyattach(vi)
  * are initialized and the controller is asked to configure
  * itself for later use.
  */
  * are initialized and the controller is asked to configure
  * itself for later use.
  */
-cyinit(ctlr)
+cyinit(ctlr, addr)
        int ctlr;
        int ctlr;
+       register caddr_t addr;
 {
        register struct cy_softc *cy = &cy_softc[ctlr];
 {
        register struct cy_softc *cy = &cy_softc[ctlr];
-       register caddr_t addr = cyminfo[ctlr]->um_addr;
        register int *pte;
 
        /*
        register int *pte;
 
        /*
@@ -216,7 +230,7 @@ cyinit(ctlr)
        /*
         * Init system configuration block.
         */
        /*
         * Init system configuration block.
         */
-       cy->cy_scb.csb_fixed = 0x3;
+       cy->cy_scb.csb_fixed = CSB_FIXED;
        /* set pointer to the channel control block */
        cyldmba(cy->cy_scb.csb_ccb, (caddr_t)&cy->cy_ccb);
 
        /* set pointer to the channel control block */
        cyldmba(cy->cy_scb.csb_ccb, (caddr_t)&cy->cy_ccb);
 
@@ -276,10 +290,16 @@ cyopen(dev, flag)
                return (ENXIO);
        if ((yc = &yc_softc[ycunit])->yc_openf)
                return (EBUSY);
                return (ENXIO);
        if ((yc = &yc_softc[ycunit])->yc_openf)
                return (EBUSY);
+       yc->yc_openf = 1;
 #define        PACKUNIT(vi) \
     (((vi->ui_slave&1)<<11)|((vi->ui_slave&2)<<9)|((vi->ui_slave&4)>>2))
        /* no way to select density */
        yc->yc_dens = PACKUNIT(vi)|CYCW_IE|CYCW_16BITS;
 #define        PACKUNIT(vi) \
     (((vi->ui_slave&1)<<11)|((vi->ui_slave&2)<<9)|((vi->ui_slave&4)>>2))
        /* no way to select density */
        yc->yc_dens = PACKUNIT(vi)|CYCW_IE|CYCW_16BITS;
+       if (yc->yc_tact == 0) {
+               yc->yc_timo = INF;
+               yc->yc_tact = 1;
+               timeout(cytimer, (caddr_t)dev, 5*hz);
+       }
        cycommand(dev, CY_SENSE, 1);
        if ((yc->yc_status&CYS_OL) == 0) {      /* not on-line */
                uprintf("yc%d: not online\n", ycunit);
        cycommand(dev, CY_SENSE, 1);
        if ((yc->yc_status&CYS_OL) == 0) {      /* not on-line */
                uprintf("yc%d: not online\n", ycunit);
@@ -289,18 +309,13 @@ cyopen(dev, flag)
                uprintf("yc%d: no write ring\n", ycunit);
                return (ENXIO);
        }
                uprintf("yc%d: no write ring\n", ycunit);
                return (ENXIO);
        }
-       yc->yc_openf = 1;
        yc->yc_blkno = (daddr_t)0;
        yc->yc_nxrec = INF;
        yc->yc_lastiow = 0;
        yc->yc_blkno = (daddr_t)0;
        yc->yc_nxrec = INF;
        yc->yc_lastiow = 0;
+       yc->yc_blksize = 1024;          /* guess > 0 */
+       yc->yc_blks = 0;
+       yc->yc_softerrs = 0;
        yc->yc_ttyp = u.u_ttyp;
        yc->yc_ttyp = u.u_ttyp;
-       s = splclock();
-       if (yc->yc_tact == 0) {
-               yc->yc_timo = INF;
-               yc->yc_tact = 1;
-               timeout(cytimer, (caddr_t)dev, 5*hz);
-       }
-       splx(s);
        return (0);
 }
 
        return (0);
 }
 
@@ -314,9 +329,9 @@ cyopen(dev, flag)
  */
 cyclose(dev, flag)
        dev_t dev;
  */
 cyclose(dev, flag)
        dev_t dev;
-       register int flag;
+       int flag;
 {
 {
-       register struct yc_softc *yc = &yc_softc[YCUNIT(dev)];
+       struct yc_softc *yc = &yc_softc[YCUNIT(dev)];
 
        if (flag == FWRITE || (flag&FWRITE) && yc->yc_lastiow) {
                cycommand(dev, CY_WEOF, 2);
 
        if (flag == FWRITE || (flag&FWRITE) && yc->yc_lastiow) {
                cycommand(dev, CY_WEOF, 2);
@@ -330,6 +345,11 @@ cyclose(dev, flag)
                 * a CY_SENSE from completing.
                 */
                cycommand(dev, CY_REW, 0);
                 * a CY_SENSE from completing.
                 */
                cycommand(dev, CY_REW, 0);
+       if (yc->yc_blks > 10 && yc->yc_softerrs > yc->yc_blks / 10)
+               log(LOG_INFO, "yc%d: %d soft errors in %d blocks\n",
+                   YCUNIT(dev), yc->yc_softerrs, yc->yc_blks);
+       dlog((LOG_INFO, "%d soft errors in %d blocks\n",
+           yc->yc_softerrs, yc->yc_blks));
        yc->yc_openf = 0;
 }
 
        yc->yc_openf = 0;
 }
 
@@ -345,8 +365,8 @@ cycommand(dev, com, count)
        
        bp = &ccybuf[CYUNIT(dev)];
        s = spl3();
        
        bp = &ccybuf[CYUNIT(dev)];
        s = spl3();
-       dlog(LOG_INFO, "cycommand(%o, %x, %d), b_flags %x\n",
-           dev, com, count, bp->b_flags);
+       dlog((LOG_INFO, "cycommand(%o, %x, %d), b_flags %x\n",
+           dev, com, count, bp->b_flags));
        while (bp->b_flags&B_BUSY) {
                /*
                 * This special check is because B_BUSY never
        while (bp->b_flags&B_BUSY) {
                /*
                 * This special check is because B_BUSY never
@@ -370,7 +390,7 @@ cycommand(dev, com, count)
         */
        if (count == 0)
                return;
         */
        if (count == 0)
                return;
-       iowait(bp);
+       biowait(bp);
        if (bp->b_flags&B_WANTED)
                wakeup((caddr_t)bp);
        bp->b_flags &= B_ERROR;
        if (bp->b_flags&B_WANTED)
                wakeup((caddr_t)bp);
        bp->b_flags &= B_ERROR;
@@ -387,9 +407,10 @@ cystrategy(bp)
        /*
         * Put transfer at end of unit queue.
         */
        /*
         * Put transfer at end of unit queue.
         */
-       dlog(LOG_INFO, "cystrategy(%o, %x)\n", bp->b_dev, bp->b_command);
+       dlog((LOG_INFO, "cystrategy(%o, %x)\n", bp->b_dev, bp->b_command));
        dp = &ycutab[ycunit];
        bp->av_forw = NULL;
        dp = &ycutab[ycunit];
        bp->av_forw = NULL;
+       bp->b_errcnt = 0;
        vm = ycdinfo[ycunit]->ui_mi;
        /* BEGIN GROT */
        if (bp == &rcybuf[CYUNIT(bp->b_dev)]) {
        vm = ycdinfo[ycunit]->ui_mi;
        /* BEGIN GROT */
        if (bp == &rcybuf[CYUNIT(bp->b_dev)]) {
@@ -398,7 +419,7 @@ cystrategy(bp)
                        bp->b_error = EIO;
                        bp->b_resid = bp->b_bcount;
                        bp->b_flags |= B_ERROR;
                        bp->b_error = EIO;
                        bp->b_resid = bp->b_bcount;
                        bp->b_flags |= B_ERROR;
-                       iodone(bp);
+                       biodone(bp);
                        return;
                }
                vbasetup(bp, CYMAXIO);
                        return;
                }
                vbasetup(bp, CYMAXIO);
@@ -439,7 +460,7 @@ cystart(vm)
        int ycunit;
        daddr_t blkno;
 
        int ycunit;
        daddr_t blkno;
 
-       dlog(LOG_INFO, "cystart()\n");
+       dlog((LOG_INFO, "cystart()\n"));
        /*
         * Look for an idle transport on the controller.
         */
        /*
         * Look for an idle transport on the controller.
         */
@@ -465,8 +486,8 @@ loop:
                 * or the tape unit is now unavailable (e.g.
                 * taken off line).
                 */
                 * or the tape unit is now unavailable (e.g.
                 * taken off line).
                 */
-               dlog(LOG_INFO, "openf %d command %x status %b\n",
-                   yc->yc_openf, bp->b_command, cy->cy_tpb.tpstatus, CYS_BITS);
+               dlog((LOG_INFO, "openf %d command %x status %b\n",
+                  yc->yc_openf, bp->b_command, cy->cy_tpb.tpstatus, CYS_BITS));
                bp->b_flags |= B_ERROR;
                goto next;
        }
                bp->b_flags |= B_ERROR;
                goto next;
        }
@@ -522,14 +543,16 @@ loop:
 
                /*
                 * Choose the appropriate i/o command based on the
 
                /*
                 * Choose the appropriate i/o command based on the
-                * transfer size and the controller's internal buffer.
+                * transfer size, the estimated block size,
+                * and the controller's internal buffer size.
                 * If we're retrying a read on a raw device because
                 * the original try was a buffer request which failed
                 * due to a record length error, then we force the use
                 * of the raw controller read (YECH!!!!).
                 */
                if (bp->b_flags&B_READ) {
                 * If we're retrying a read on a raw device because
                 * the original try was a buffer request which failed
                 * due to a record length error, then we force the use
                 * of the raw controller read (YECH!!!!).
                 */
                if (bp->b_flags&B_READ) {
-                       if (bp->b_bcount > cy->cy_bs || bp->b_errcnt)
+                       if ((bp->b_bcount > cy->cy_bs &&
+                           yc->yc_blksize > cy->cy_bs) || bp->b_errcnt)
                                cmd = CY_RCOM;
                        else
                                cmd = CY_BRCOM;
                                cmd = CY_RCOM;
                        else
                                cmd = CY_BRCOM;
@@ -558,7 +581,10 @@ loop:
                cy->cy_tpb.tpcount = 0;
                cyldmba(cy->cy_tpb.tpdata, (caddr_t)addr);
                cy->cy_tpb.tprec = 0;
                cy->cy_tpb.tpcount = 0;
                cyldmba(cy->cy_tpb.tpdata, (caddr_t)addr);
                cy->cy_tpb.tprec = 0;
-               cy->cy_tpb.tpsize = htoms(bp->b_bcount);
+               if (cmd == CY_BRCOM && bp->b_bcount > cy->cy_bs)
+                       cy->cy_tpb.tpsize = htoms(cy->cy_bs);
+               else
+                       cy->cy_tpb.tpsize = htoms(bp->b_bcount);
                cyldmba(cy->cy_tpb.tplink, (caddr_t)0);
                do
                        uncache(&cy->cy_ccb.cbgate);
                cyldmba(cy->cy_tpb.tplink, (caddr_t)0);
                do
                        uncache(&cy->cy_ccb.cbgate);
@@ -566,9 +592,9 @@ loop:
                cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb);
                cy->cy_ccb.cbcw = CBCW_IE;
                cy->cy_ccb.cbgate = GATE_CLOSED;
                cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb);
                cy->cy_ccb.cbcw = CBCW_IE;
                cy->cy_ccb.cbgate = GATE_CLOSED;
-               dlog(LOG_INFO, "CY_GO(%x) cmd %x control %x size %d\n",
+               dlog((LOG_INFO, "CY_GO(%x) cmd %x control %x size %d\n",
                    vm->um_addr, cy->cy_tpb.tpcmd, cy->cy_tpb.tpcontrol,
                    vm->um_addr, cy->cy_tpb.tpcmd, cy->cy_tpb.tpcontrol,
-                   htoms(cy->cy_tpb.tpsize));
+                   htoms(cy->cy_tpb.tpsize)));
                CY_GO(vm->um_addr);
                return;
        }
                CY_GO(vm->um_addr);
                return;
        }
@@ -609,9 +635,9 @@ dobpcmd:
        cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb);
        cy->cy_ccb.cbcw = CBCW_IE;
        cy->cy_ccb.cbgate = GATE_CLOSED;
        cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb);
        cy->cy_ccb.cbcw = CBCW_IE;
        cy->cy_ccb.cbgate = GATE_CLOSED;
-       dlog(LOG_INFO, "CY_GO(%x) cmd %x control %x rec %d\n",
+       dlog((LOG_INFO, "CY_GO(%x) cmd %x control %x rec %d\n",
            vm->um_addr, cy->cy_tpb.tpcmd, cy->cy_tpb.tpcontrol,
            vm->um_addr, cy->cy_tpb.tpcmd, cy->cy_tpb.tpcontrol,
-           htoms(cy->cy_tpb.tprec));
+           htoms(cy->cy_tpb.tprec)));
        CY_GO(vm->um_addr);
        return;
 next:
        CY_GO(vm->um_addr);
        return;
 next:
@@ -625,7 +651,7 @@ next:
                vbadone(bp, cy->cy_buf, (long *)cy->cy_map, cy->cy_utl);
        vm->um_tab.b_errcnt = 0;
        dp->b_actf = bp->av_forw;
                vbadone(bp, cy->cy_buf, (long *)cy->cy_map, cy->cy_utl);
        vm->um_tab.b_errcnt = 0;
        dp->b_actf = bp->av_forw;
-       iodone(bp);
+       biodone(bp);
        goto loop;
 }
 
        goto loop;
 }
 
@@ -643,7 +669,7 @@ cyintr(cipher)
        int cyunit, err;
        register state;
 
        int cyunit, err;
        register state;
 
-       dlog(LOG_INFO, "cyintr(%d)\n", cipher);
+       dlog((LOG_INFO, "cyintr(%d)\n", cipher));
        /*
         * First, turn off the interrupt from the controller
         * (device uses Multibus non-vectored interrupts...yech).
        /*
         * First, turn off the interrupt from the controller
         * (device uses Multibus non-vectored interrupts...yech).
@@ -654,7 +680,7 @@ cyintr(cipher)
        cy->cy_ccb.cbgate = GATE_CLOSED;
        CY_GO(vm->um_addr);
        if ((dp = vm->um_tab.b_actf) == NULL) {
        cy->cy_ccb.cbgate = GATE_CLOSED;
        CY_GO(vm->um_addr);
        if ((dp = vm->um_tab.b_actf) == NULL) {
-               dlog(LOG_ERR, "cy%d: stray interrupt", vm->um_ctlr);
+               dlog((LOG_ERR, "cy%d: stray interrupt", vm->um_ctlr));
                return;
        }
        bp = dp->b_actf;
                return;
        }
        bp = dp->b_actf;
@@ -680,9 +706,9 @@ cyintr(cipher)
        yc->yc_control = cy->cy_tpb.tpcontrol;
        yc->yc_status = cy->cy_tpb.tpstatus;
        yc->yc_resid = bp->b_bcount - htoms(cy->cy_tpb.tpcount);
        yc->yc_control = cy->cy_tpb.tpcontrol;
        yc->yc_status = cy->cy_tpb.tpstatus;
        yc->yc_resid = bp->b_bcount - htoms(cy->cy_tpb.tpcount);
-       dlog(LOG_INFO, "cmd %x control %b status %b resid %d\n",
+       dlog((LOG_INFO, "cmd %x control %b status %b resid %d\n",
            cy->cy_tpb.tpcmd, yc->yc_control, CYCW_BITS,
            cy->cy_tpb.tpcmd, yc->yc_control, CYCW_BITS,
-           yc->yc_status, CYS_BITS, yc->yc_resid);
+           yc->yc_status, CYS_BITS, yc->yc_resid));
        if ((bp->b_flags&B_READ) == 0)
                yc->yc_lastiow = 1;
        state = vm->um_tab.b_active;
        if ((bp->b_flags&B_READ) == 0)
                yc->yc_lastiow = 1;
        state = vm->um_tab.b_active;
@@ -692,7 +718,7 @@ cyintr(cipher)
         */
        if (cy->cy_tpb.tpstatus&CYS_ERR) {
                err = cy->cy_tpb.tpstatus&CYS_ERR;
         */
        if (cy->cy_tpb.tpstatus&CYS_ERR) {
                err = cy->cy_tpb.tpstatus&CYS_ERR;
-               dlog(LOG_INFO, "error %d\n", err);
+               dlog((LOG_INFO, "error %d\n", err));
                /*
                 * If we hit the end of tape file, update our position.
                 */
                /*
                 * If we hit the end of tape file, update our position.
                 */
@@ -717,14 +743,18 @@ cyintr(cipher)
                if (bp == &rcybuf[cyunit] && (bp->b_flags&B_READ) &&
                    err == CYER_STROBE) {
                        /*
                if (bp == &rcybuf[cyunit] && (bp->b_flags&B_READ) &&
                    err == CYER_STROBE) {
                        /*
-                        * Retry reads once with the command changed to
-                        * a raw read (if possible).  Setting b_errcnt
+                        * Retry reads with the command changed to
+                        * a raw read if necessary.  Setting b_errcnt
                         * here causes cystart (above) to force a CY_RCOM.
                         */
                         * here causes cystart (above) to force a CY_RCOM.
                         */
-                       if (bp->b_errcnt++ != 0)
+                       if (htoms(cy->cy_tpb.tprec) > cy->cy_bs &&
+                           bp->b_bcount > cy->cy_bs && 
+                           yc->yc_blksize <= cy->cy_bs &&
+                           bp->b_errcnt++ == 0) {
+                               yc->yc_blkno++;
+                               goto opcont;
+                       } else
                                goto ignoreerr;
                                goto ignoreerr;
-                       yc->yc_blkno++;
-                       goto opcont;
                }
                /*
                 * If error is not hard, and this was an i/o operation
                }
                /*
                 * If error is not hard, and this was an i/o operation
@@ -740,17 +770,15 @@ cyintr(cipher)
                         * Hard or non-i/o errors on non-raw tape
                         * cause it to close.
                         */
                         * Hard or non-i/o errors on non-raw tape
                         * cause it to close.
                         */
-                       if (yc->yc_openf>0 && bp != &rcybuf[cyunit])
+                       if (yc->yc_openf > 0 && bp != &rcybuf[cyunit])
                                yc->yc_openf = -1;
                /*
                 * Couldn't recover from error.
                 */
                tprintf(yc->yc_ttyp,
                                yc->yc_openf = -1;
                /*
                 * Couldn't recover from error.
                 */
                tprintf(yc->yc_ttyp,
-                   "yc%d: hard error bn%d status=%b", YCUNIT(bp->b_dev),
-                   bp->b_blkno, yc->yc_status, CYS_BITS);
-               if (err < NCYERROR)
-                       tprintf(yc->yc_ttyp, ", %s", cyerror[err]);
-               tprintf(yc->yc_ttyp, "\n");
+                   "yc%d: hard error bn%d status=%b, %s\n", YCUNIT(bp->b_dev),
+                   bp->b_blkno, yc->yc_status, CYS_BITS,
+                   (err < NCYERROR) ? cyerror[err] : "");
                bp->b_flags |= B_ERROR;
                goto opdone;
        }
                bp->b_flags |= B_ERROR;
                goto opdone;
        }
@@ -772,6 +800,11 @@ ignoreerr:
                 * Read/write increments tape block number.
                 */
                yc->yc_blkno++;
                 * Read/write increments tape block number.
                 */
                yc->yc_blkno++;
+               yc->yc_blks++;
+               if (vm->um_tab.b_errcnt || yc->yc_status & CYS_CR)
+                       yc->yc_softerrs++;
+               yc->yc_blksize = htoms(cy->cy_tpb.tpcount);
+               dlog((LOG_ERR, "blocksize %d", yc->yc_blksize));
                goto opdone;
 
        case SCOM:
                goto opdone;
 
        case SCOM:
@@ -816,7 +849,7 @@ opdone:
        bp->b_resid = bp->b_bcount - htoms(cy->cy_tpb.tpcount);
        if (bp == &rcybuf[CYUNIT(bp->b_dev)])
                vbadone(bp, cy->cy_buf, (long *)cy->cy_map, cy->cy_utl);
        bp->b_resid = bp->b_bcount - htoms(cy->cy_tpb.tpcount);
        if (bp == &rcybuf[CYUNIT(bp->b_dev)])
                vbadone(bp, cy->cy_buf, (long *)cy->cy_map, cy->cy_utl);
-       iodone(bp);
+       biodone(bp);
        /*
         * Circulate slave to end of controller
         * queue to give other slaves a chance.
        /*
         * Circulate slave to end of controller
         * queue to give other slaves a chance.
@@ -841,6 +874,10 @@ cytimer(dev)
        register struct yc_softc *yc = &yc_softc[YCUNIT(dev)];
        int s;
 
        register struct yc_softc *yc = &yc_softc[YCUNIT(dev)];
        int s;
 
+       if (yc->yc_openf == 0 && yc->yc_timo == INF) {
+               yc->yc_tact = 0;
+               return;
+       }
        if (yc->yc_timo != INF && (yc->yc_timo -= 5) < 0) {
                printf("yc%d: lost interrupt\n", YCUNIT(dev));
                yc->yc_timo = INF;
        if (yc->yc_timo != INF && (yc->yc_timo -= 5) < 0) {
                printf("yc%d: lost interrupt\n", YCUNIT(dev));
                yc->yc_timo = INF;
@@ -936,7 +973,7 @@ cyioctl(dev, cmd, data, flag)
        struct mtget *mtget;
        /* we depend of the values and order of the MT codes here */
        static cyops[] =
        struct mtget *mtget;
        /* we depend of the values and order of the MT codes here */
        static cyops[] =
-       {CY_WEOF,CY_SFORW,CY_SREV,CY_SFORW,CY_SREV,CY_REW,CY_OFFL,CY_SENSE};
+       {CY_WEOF,CY_FSF,CY_BSF,CY_SFORW,CY_SREV,CY_REW,CY_OFFL,CY_SENSE};
 
        switch (cmd) {
 
 
        switch (cmd) {
 
@@ -945,7 +982,15 @@ cyioctl(dev, cmd, data, flag)
                switch (op = mtop->mt_op) {
 
                case MTWEOF:
                switch (op = mtop->mt_op) {
 
                case MTWEOF:
+                       callcount = mtop->mt_count;
+                       fcount = 1;
+                       break;
+
                case MTFSR: case MTBSR:
                case MTFSR: case MTBSR:
+                       callcount = 1;
+                       fcount = mtop->mt_count;
+                       break;
+
                case MTFSF: case MTBSF:
                        callcount = mtop->mt_count;
                        fcount = 1;
                case MTFSF: case MTBSF:
                        callcount = mtop->mt_count;
                        fcount = 1;
@@ -962,6 +1007,7 @@ cyioctl(dev, cmd, data, flag)
                if (callcount <= 0 || fcount <= 0)
                        return (EINVAL);
                while (--callcount >= 0) {
                if (callcount <= 0 || fcount <= 0)
                        return (EINVAL);
                while (--callcount >= 0) {
+#ifdef notdef
                        /*
                         * Gagh, this controller is the pits...
                         */
                        /*
                         * Gagh, this controller is the pits...
                         */
@@ -971,7 +1017,11 @@ cyioctl(dev, cmd, data, flag)
                                while ((bp->b_flags&B_ERROR) == 0 &&
                                 (yc->yc_status&(CYS_EOT|CYS_BOT|CYS_FM)) == 0);
                        } else
                                while ((bp->b_flags&B_ERROR) == 0 &&
                                 (yc->yc_status&(CYS_EOT|CYS_BOT|CYS_FM)) == 0);
                        } else
+#endif
                                cycommand(dev, cyops[op], fcount);
                                cycommand(dev, cyops[op], fcount);
+                       dlog((LOG_INFO,
+                           "cyioctl: status %x, b_flags %x, resid %d\n",
+                           yc->yc_status, bp->b_flags, bp->b_resid));
                        if ((bp->b_flags&B_ERROR) ||
                            (yc->yc_status&(CYS_BOT|CYS_EOT)))
                                break;
                        if ((bp->b_flags&B_ERROR) ||
                            (yc->yc_status&(CYS_BOT|CYS_EOT)))
                                break;
@@ -1011,14 +1061,13 @@ cywait(cp)
 }
 
 /*
 }
 
 /*
- * Load a 20 bit pointer into an i/o register.
+ * Load a 20 bit pointer into a Tapemaster pointer.
  */
  */
-cyldmba(wreg, value)
-       short *wreg;
+cyldmba(reg, value)
+       register caddr_t reg;
        caddr_t value;
 {
        register int v = (int)value;
        caddr_t value;
 {
        register int v = (int)value;
-       register caddr_t reg = (caddr_t)wreg;
 
        *reg++ = v;
        *reg++ = v >> 8;
 
        *reg++ = v;
        *reg++ = v >> 8;
@@ -1039,7 +1088,7 @@ cyreset(vba)
                if (cyminfo[ctlr] && cyminfo[ctlr]->um_vbanum == vba) {
                        addr = cyminfo[ctlr]->um_addr;
                        CY_RESET(addr);
                if (cyminfo[ctlr] && cyminfo[ctlr]->um_vbanum == vba) {
                        addr = cyminfo[ctlr]->um_addr;
                        CY_RESET(addr);
-                       if (!cyinit(ctlr)) {
+                       if (!cyinit(ctlr, addr)) {
                                printf("cy%d: reset failed\n", ctlr);
                                cyminfo[ctlr] = NULL;
                        }
                                printf("cy%d: reset failed\n", ctlr);
                                cyminfo[ctlr] = NULL;
                        }
index ef14205..5ef5b01 100644 (file)
@@ -1,4 +1,4 @@
-/*     cyreg.h 7.2     86/01/26        */
+/*     cyreg.h 7.3     87/01/11        */
 
 /*
  * Tapemaster controller definitions.
 
 /*
  * Tapemaster controller definitions.
 #define        b_repcnt  b_bcount
 #define        b_command b_resid
 
 #define        b_repcnt  b_bcount
 #define        b_command b_resid
 
+/*
+ * System configuration pointer.
+ * Memory address is jumpered on controller.
+ */
+struct cyscp {
+       char    csp_buswidth;   /* system bus width */
+#define        CSP_16BITS      1       /* 16-bit system bus */
+#define        CSP_8BITS       0       /* 8-bit system bus */
+       char    csp_unused;
+       u_char  csp_scb[4];     /* point to system config block */
+};
+
+/*
+ * System configuration block
+ */
+struct cyscb {
+       char    csb_fixed;      /* fixed value code (must be 3) */
+       char    csb_unused;     /* unused */
+       u_char  csb_ccb[4];     /* pointer to channel control block */
+};
+
+#define        CSB_FIXED       0x3
+
 /*
  * Channel control block definitions
  */
 struct cyccb {
        char    cbcw;           /* channel control word */
        char    cbgate;         /* tpb access gate */
 /*
  * Channel control block definitions
  */
 struct cyccb {
        char    cbcw;           /* channel control word */
        char    cbgate;         /* tpb access gate */
-       short   cbtpb[2];       /* first tape parameter block */
+       u_char  cbtpb[4];       /* first tape parameter block */
 };
 
 #define        GATE_OPEN       (char)(0x00)
 };
 
 #define        GATE_OPEN       (char)(0x00)
@@ -37,9 +60,9 @@ struct        cytpb {
        short   tpcount;        /* return count */
        short   tpsize;         /* buffer size */
        short   tprec;          /* records/overrun */
        short   tpcount;        /* return count */
        short   tpsize;         /* buffer size */
        short   tprec;          /* records/overrun */
-       short   tpdata[2];      /* pointer to source/dest */
+       u_char  tpdata[4];      /* pointer to source/dest */
        short   tpstatus;       /* status */
        short   tpstatus;       /* status */
-       short   tplink[2];      /* pointer to next parameter block */
+       u_char  tplink[4];      /* pointer to next parameter block */
 };
 
 /* control field bit definitions */
 };
 
 /* control field bit definitions */
@@ -63,6 +86,7 @@ struct        cytpb {
 /* control status/commands */
 #define        CY_CONFIG       (0x00<<24)      /* configure */
 #define        CY_NOP          (0x20<<24)      /* no operation */
 /* control status/commands */
 #define        CY_CONFIG       (0x00<<24)      /* configure */
 #define        CY_NOP          (0x20<<24)      /* no operation */
+#define        CY_SETPAGE      (0x08<<24)      /* set page (addr bits 20-23) */
 #define        CY_SENSE        (0x28<<24)      /* drive status */
 #define        CY_CLRINT       (0x9c<<24)      /* clear Multibus interrupt */
 
 #define        CY_SENSE        (0x28<<24)      /* drive status */
 #define        CY_CLRINT       (0x9c<<24)      /* clear Multibus interrupt */
 
@@ -71,7 +95,9 @@ struct        cytpb {
 #define        CY_OFFL         (0x38<<24)      /* off_line and unload */
 #define        CY_WEOF         (0x40<<24)      /* write end-of-file mark */
 #define        CY_SFORW        (0x70<<24)      /* space record forward */
 #define        CY_OFFL         (0x38<<24)      /* off_line and unload */
 #define        CY_WEOF         (0x40<<24)      /* write end-of-file mark */
 #define        CY_SFORW        (0x70<<24)      /* space record forward */
-#define        CY_SREV         (CY_SFORW|CYCW_REV)/* space record backwords */
+#define        CY_SREV         (CY_SFORW|CYCW_REV) /* space record backwards */
+#define        CY_FSF          (0x44<<24)      /* space file forward */
+#define        CY_BSF          (CY_FSF|CYCW_REV) /* space file backwards */
 #define        CY_ERASE        (0x4c<<24)      /* erase record */
 
 /* data transfer commands */
 #define        CY_ERASE        (0x4c<<24)      /* erase record */
 
 /* data transfer commands */
@@ -122,28 +148,30 @@ struct    cytpb {
 
 #ifdef CYERROR
 char   *cyerror[] = {
 
 #ifdef CYERROR
 char   *cyerror[] = {
+       "no error",
        "timeout",
        "timeout1",
        "timeout2",
        "timeout3",
        "timeout4", 
        "timeout",
        "timeout1",
        "timeout2",
        "timeout3",
        "timeout4", 
-       "non-existant memory",
+       "non-existent memory",
        "blank tape",
        "micro-diagnostic",
        "eot/bot detected",
        "retry unsuccessful",
        "fifo over/under-flow",
        "blank tape",
        "micro-diagnostic",
        "eot/bot detected",
        "retry unsuccessful",
        "fifo over/under-flow",
-       "#12",
+       "#0xc",
        "drive to controller parity error",
        "prom checksum",
        "time out tape strobe (record length error)",
        "tape not ready",
        "write protected",
        "drive to controller parity error",
        "prom checksum",
        "time out tape strobe (record length error)",
        "tape not ready",
        "write protected",
-       "#18",
+       "#0x12",
        "missing diagnostic jumper",
        "invalid link pointer",
        "unexpected file mark",
        "missing diagnostic jumper",
        "invalid link pointer",
        "unexpected file mark",
-       "invalid byte count",
+       "invalid byte count/parameter",
+       "#0x17",
        "unidentified hardware error",
        "streaming terminated"
 };
        "unidentified hardware error",
        "streaming terminated"
 };
@@ -158,23 +186,3 @@ char       *cyerror[] = {
     CYMASK(TIMOUT3)|CYMASK(TIMOUT4)|CYMASK(NXM)|CYMASK(DIAG)|CYMASK(JUMPER)|\
     CYMASK(STROBE)|CYMASK(PROT)|CYMASK(CKSUM)|CYMASK(HERR)|CYMASK(BLANK))
 #define        CYER_SOFT       (CYMASK(FIFO)|CYMASK(NOTRDY)|CYMASK(PARITY))
     CYMASK(TIMOUT3)|CYMASK(TIMOUT4)|CYMASK(NXM)|CYMASK(DIAG)|CYMASK(JUMPER)|\
     CYMASK(STROBE)|CYMASK(PROT)|CYMASK(CKSUM)|CYMASK(HERR)|CYMASK(BLANK))
 #define        CYER_SOFT       (CYMASK(FIFO)|CYMASK(NOTRDY)|CYMASK(PARITY))
-
-/*
- * System configuration block
- */
-struct cyscb {
-       char    csb_fixed;      /* fixed value code (must be 3) */
-       char    csb_unused;     /* unused */
-       short   csb_ccb[2];     /* pointer to channel control block */
-};
-
-/*
- * System configuration pointer
- */
-struct cyscp {
-       char    csp_buswidth;   /* system bus width */
-#define        CSP_16BITS      1       /* 16-bit system bus */
-#define        CSP_8BITS       0       /* 8-bit system bus */
-       char    csp_unused;
-       short   csp_scb[2];     /* point to system config block */
-};
index b8ef72a..b9d3356 100644 (file)
@@ -1,4 +1,4 @@
-/*     vd.c    1.12    86/11/03        */
+/*     vd.c    1.13    87/01/11        */
 
 #include "dk.h"
 #if NVD > 0
 
 #include "dk.h"
 #if NVD > 0
@@ -21,6 +21,8 @@
 #include "vmmac.h"
 #include "proc.h"
 #include "uio.h"
 #include "vmmac.h"
 #include "proc.h"
 #include "uio.h"
+#include "syslog.h"
+#include "kernel.h"
 
 #include "../tahoe/cpu.h"
 #include "../tahoe/mtpr.h"
 
 #include "../tahoe/cpu.h"
 #include "../tahoe/mtpr.h"
@@ -105,6 +107,10 @@ vdprobe(reg, vm)
        register ctlr_tab *ci;
        int i;
 
        register ctlr_tab *ci;
        int i;
 
+#ifdef lint
+       br = 0; cvec = br; br = cvec;
+       vdintr(0);
+#endif
        if (badaddr((caddr_t)reg, 2))
                return (0);
        ci = &vdctlr_info[vm->um_ctlr];
        if (badaddr((caddr_t)reg, 2))
                return (0);
        ci = &vdctlr_info[vm->um_ctlr];
@@ -158,7 +164,7 @@ vdslave(vi, addr)
 
        if (!ci->initdone) {
                printf("vd%d: %s controller\n", vi->ui_ctlr,
 
        if (!ci->initdone) {
                printf("vd%d: %s controller\n", vi->ui_ctlr,
-                   ci->ctlr_type == SMDCTLR ? "smd" : "smde");
+                   ci->ctlr_type == SMDCTLR ? "VDDC" : "SMDE");
                if (vdnotrailer(addr, vi->ui_ctlr, vi->ui_slave, INIT, 10) &
                    HRDERR) {
                        printf("vd%d: init error\n", vi->ui_ctlr);
                if (vdnotrailer(addr, vi->ui_ctlr, vi->ui_slave, INIT, 10) &
                    HRDERR) {
                        printf("vd%d: init error\n", vi->ui_ctlr);
@@ -181,7 +187,7 @@ vdslave(vi, addr)
                if (ci->ctlr_type == SMDCTLR && vdst[type].nsec != 32)
                        continue;
                /* XXX */
                if (ci->ctlr_type == SMDCTLR && vdst[type].nsec != 32)
                        continue;
                /* XXX */
-               if (!vdconfigure_drive(addr, vi->ui_ctlr, vi->ui_slave, type,0))
+               if (!vdconfigure_drive(addr, vi->ui_ctlr, vi->ui_slave, type))
                        return (0);
                dcb->opcode = (short)RD;
                dcb->intflg = NOINT;
                        return (0);
                dcb->opcode = (short)RD;
                dcb->intflg = NOINT;
@@ -218,9 +224,9 @@ vdslave(vi, addr)
        return (1);
 }
 
        return (1);
 }
 
-vdconfigure_drive(addr, ctlr, slave, type, pass)
+vdconfigure_drive(addr, ctlr, slave, type)
        register cdr *addr;
        register cdr *addr;
-       int ctlr, slave, type, pass;
+       int ctlr, slave, type;
 {
        register ctlr_tab *ci = &vdctlr_info[ctlr];
 
 {
        register ctlr_tab *ci = &vdctlr_info[ctlr];
 
@@ -246,47 +252,38 @@ vdconfigure_drive(addr, ctlr, slave, type, pass)
                return (0);
        }
        if (ci->ctlr_dcb.operrsta & HRDERR) {
                return (0);
        }
        if (ci->ctlr_dcb.operrsta & HRDERR) {
+               if (ci->ctlr_type == SMD_ECTLR &&
+                   (addr->cdr_status[slave] & STA_US) == 0) /* not selected */
+                       return (0);
                if ((ci->ctlr_dcb.operrsta & (NOTCYLERR|DRVNRDY)) == 0)
                        printf("vd%d: drive %d: config error\n", ctlr, slave);
                if ((ci->ctlr_dcb.operrsta & (NOTCYLERR|DRVNRDY)) == 0)
                        printf("vd%d: drive %d: config error\n", ctlr, slave);
-               else if (pass == 0) {
-                       vdstart_drive(addr, ctlr, slave);
-                       return (vdconfigure_drive(addr, ctlr, slave, type, 1));
-               } else if (pass == 2)
-                       return (vdconfigure_drive(addr, ctlr, slave, type, 3));
+               else if (vdctlr_info[ctlr].ctlr_started == 0)
+                       return (vdstart_drives(addr, ctlr) &&
+                           vdconfigure_drive(addr, ctlr, slave, type));
                return (0);
        }
        return (1);
 }
 
                return (0);
        }
        return (1);
 }
 
-vdstart_drive(addr, ctlr, slave)
+vdstart_drives(addr, ctlr)
        cdr *addr;
        cdr *addr;
-       register int ctlr, slave;
+       register int ctlr;
 {
        int error = 0;
 
 {
        int error = 0;
 
-       printf("vd%d: starting drive %d, wait...", ctlr, slave);
-       if (vdctlr_info[ctlr].ctlr_started) {
-#ifdef notdef
-printf("DELAY(5500000)...");
-               DELAY(5500000);
-#endif
-               goto done;
-       }
-       vdctlr_info[ctlr].ctlr_started = 1;
-       error = vdnotrailer(addr, ctlr, 0, VDSTART, (slave*6)+62) & HRDERR;
-       if (!error) {
-#ifdef notdef
-               DELAY((slave * 5500000) + 62000000);
-#endif
+       if (vdctlr_info[ctlr].ctlr_started == 0) {
+               printf("vd%d: starting drives, wait ... ", ctlr);
+               vdctlr_info[ctlr].ctlr_started = 1;
+               error = (vdnotrailer(addr, ctlr, 0, VDSTART, 10) & HRDERR);
+               DELAY(62000000);
+               printf("\n");
        }
        }
-done:
-       printf("\n");
        return (error == 0);
 }
 
        return (error == 0);
 }
 
-vdnotrailer(addr, ctlr, unit, function, time)
+vdnotrailer(addr, ctlr, unit, function, t)
        register cdr *addr;
        register cdr *addr;
-       int ctlr, unit, function, time;
+       int ctlr, unit, function, t;
 {
        register ctlr_tab *ci = &vdctlr_info[ctlr];
        fmt_mdcb *mdcb = &ci->ctlr_mdcb;
 {
        register ctlr_tab *ci = &vdctlr_info[ctlr];
        fmt_mdcb *mdcb = &ci->ctlr_mdcb;
@@ -301,7 +298,7 @@ vdnotrailer(addr, ctlr, unit, function, time)
        mdcb->firstdcb = (fmt_dcb *)(PHYS(dcb));
        mdcb->vddcstat = 0;
        VDDC_ATTENTION(addr, (fmt_mdcb *)(PHYS(mdcb)), ci->ctlr_type);
        mdcb->firstdcb = (fmt_dcb *)(PHYS(dcb));
        mdcb->vddcstat = 0;
        VDDC_ATTENTION(addr, (fmt_mdcb *)(PHYS(mdcb)), ci->ctlr_type);
-       if (!vdpoll(ci, addr, time)) {
+       if (!vdpoll(ci, addr, t)) {
                printf(" during init\n");
                return (DCBCMP|ANYERR|HRDERR|OPABRT);
        }
                printf(" during init\n");
                return (DCBCMP|ANYERR|HRDERR|OPABRT);
        }
@@ -336,9 +333,8 @@ vdattach(vi)
                uq->b_forw = &ui->xfer_queue;
                start_queue->b_back = &ui->xfer_queue;
        }
                uq->b_forw = &ui->xfer_queue;
                start_queue->b_back = &ui->xfer_queue;
        }
-       printf("dk%d: %s <ntrak %d, ncyl %d, nsec %d>\n",
-           vi->ui_unit, fs->type_name,
-           ui->info.ntrak, ui->info.ncyl, ui->info.nsec);
+       printf(": %s <ntrak %d, ncyl %d, nsec %d>",
+           fs->type_name, ui->info.ntrak, ui->info.ncyl, ui->info.nsec);
        /*
         * (60 / rpm) / (number of sectors per track * (bytes per sector / 2))
         */
        /*
         * (60 / rpm) / (number of sectors per track * (bytes per sector / 2))
         */
@@ -375,20 +371,12 @@ vdstrategy(bp)
                        bp->b_resid = bp->b_bcount;
                        goto done;
                }
                        bp->b_resid = bp->b_bcount;
                        goto done;
                }
-#ifdef notdef
-               /*
-                * I'm not sure I want to smash bp->b_bcount.
-                */
                blks = par->par_len - bp->b_blkno;
                if (blks <= 0) {
                        bp->b_error = EINVAL;
                        goto bad;
                }
                bp->b_bcount = blks * DEV_BSIZE;
                blks = par->par_len - bp->b_blkno;
                if (blks <= 0) {
                        bp->b_error = EINVAL;
                        goto bad;
                }
                bp->b_bcount = blks * DEV_BSIZE;
-#else
-               bp->b_error = EINVAL;
-               goto bad;
-#endif
        }
        bn = bp->b_blkno + par->par_start;
        bn *= ui->sec_per_blk;
        }
        bn = bp->b_blkno + par->par_start;
        bn *= ui->sec_per_blk;
@@ -540,7 +528,7 @@ vdexecute(controller_info, uq)
        mdcb->vddcstat = 0;
        dk_wds[unit] += bp->b_bcount / 32;
        ci->int_expected = 1;
        mdcb->vddcstat = 0;
        dk_wds[unit] += bp->b_bcount / 32;
        ci->int_expected = 1;
-       timeout(vd_int_timeout, (caddr_t)ctlr, 20*60);
+       timeout(vd_int_timeout, (caddr_t)ctlr, 20*hz);
        dk_busy |= 1 << unit;
        scope_out(1);
        VDDC_ATTENTION((cdr *)(vdminfo[ctlr]->um_addr),
        dk_busy |= 1 << unit;
        scope_out(1);
        VDDC_ATTENTION((cdr *)(vdminfo[ctlr]->um_addr),
@@ -610,23 +598,25 @@ vdintr(ctlr)
 
        case CTLR_ERROR:
        case DRIVE_ERROR:
 
        case CTLR_ERROR:
        case DRIVE_ERROR:
-               if (cq->b_errcnt >= 2)
-                       vdhard_error(ci, bp, dcb);
                if (code == CTLR_ERROR)
                        vdreset_ctlr((cdr *)vdminfo[ctlr]->um_addr, ctlr);
                if (code == CTLR_ERROR)
                        vdreset_ctlr((cdr *)vdminfo[ctlr]->um_addr, ctlr);
-               else
-                       reset_drive((cdr *)vdminfo[ctlr]->um_addr, ctlr,
-                           slave, 2);
-               if (cq->b_errcnt++ < 2) {       /* retry error */
+               else if (reset_drive((cdr *)vdminfo[ctlr]->um_addr,
+                   ctlr, slave) == 0)
+                       vddinfo[unit]->ui_alive = 0;
+               /*
+                * Retry transfer once, unless reset failed.
+                */
+               if (vddinfo[unit]->ui_alive && cq->b_errcnt++ < 2) {
                        cq->b_forw = uq->b_back;
                        vdstart(vdminfo[ctlr]);
                        return;
                }
                        cq->b_forw = uq->b_back;
                        vdstart(vdminfo[ctlr]);
                        return;
                }
-               bp->b_resid = bp->b_bcount;
+               vdhard_error(ci, bp, dcb);
                break;
 
        case HARD_DATA_ERROR:
        case WRITE_PROTECT:
                break;
 
        case HARD_DATA_ERROR:
        case WRITE_PROTECT:
+       default:                                /* shouldn't happen */
                vdhard_error(ci, bp, dcb);
                bp->b_resid = 0;
                break;
                vdhard_error(ci, bp, dcb);
                bp->b_resid = 0;
                break;
@@ -635,7 +625,7 @@ vdintr(ctlr)
                vdsoft_error(ci, bp, dcb);
                /* fall thru... */
 
                vdsoft_error(ci, bp, dcb);
                /* fall thru... */
 
-       default:                        /* operation completed */
+       case 0:                 /* operation completed */
                bp->b_error = 0;
                bp->b_resid = 0;
                break;
                bp->b_error = 0;
                bp->b_resid = 0;
                break;
@@ -679,8 +669,11 @@ vddecode_error(dcb)
        if (dcb->operrsta & HRDERR) {
                if (dcb->operrsta & WPTERR)
                        return (WRITE_PROTECT);
        if (dcb->operrsta & HRDERR) {
                if (dcb->operrsta & WPTERR)
                        return (WRITE_PROTECT);
+       /* this looks wrong...
                if (dcb->operrsta & (HCRCERR | HCMPERR | UCDATERR |
                if (dcb->operrsta & (HCRCERR | HCMPERR | UCDATERR |
-                   DSEEKERR | NOTCYLERR |DRVNRDY | INVDADR))
+                   DSEEKERR | NOTCYLERR | DRVNRDY | INVDADR))
+       */
+               if (dcb->operrsta & (DSEEKERR | NOTCYLERR | DRVNRDY | INVDADR))
                        return (DRIVE_ERROR);
                if (dcb->operrsta & (CTLRERR | OPABRT | INVCMD | DNEMEM))
                        return (CTLR_ERROR);
                        return (DRIVE_ERROR);
                if (dcb->operrsta & (CTLRERR | OPABRT | INVCMD | DNEMEM))
                        return (CTLR_ERROR);
@@ -699,14 +692,16 @@ vdhard_error(ci, bp, dcb)
        register struct buf *bp;
        register fmt_dcb *dcb;
 {
        register struct buf *bp;
        register fmt_dcb *dcb;
 {
-       unit_tab *ui = &vdunit_info[VDUNIT(bp->b_dev)];
 
        bp->b_flags |= B_ERROR;
 
        bp->b_flags |= B_ERROR;
-       harderr(bp, ui->info.type_name);
+       /* NEED TO ADJUST b_blkno to failed sector */
+       harderr(bp, "dk");
        if (dcb->operrsta & WPTERR)
                printf("write protected");
        else {
        if (dcb->operrsta & WPTERR)
                printf("write protected");
        else {
-               printf("status %b", dcb->operrsta, ERRBITS);
+               printf("status %x (%b)", dcb->operrsta,
+                  dcb->operrsta & ~(DSERLY|DSLATE|TOPLUS|TOMNUS|DCBUSC|DCBCMP),
+                  ERRBITS);
                if (ci->ctlr_type == SMD_ECTLR)
                        printf(" ecode %x", dcb->err_code);
        }
                if (ci->ctlr_type == SMD_ECTLR)
                        printf(" ecode %x", dcb->err_code);
        }
@@ -721,13 +716,16 @@ vdsoft_error(ci, bp, dcb)
        register struct buf *bp;
        register fmt_dcb *dcb;
 {
        register struct buf *bp;
        register fmt_dcb *dcb;
 {
-       unit_tab *ui = &vdunit_info[VDUNIT(bp->b_dev)];
-
-       printf("dk%d%c: soft error sn%d status %b", minor(bp->b_dev) >> 3,
-           'a'+(minor(bp->b_dev)&07), bp->b_blkno, dcb->operrsta, ERRBITS);
-       if (ci->ctlr_type == SMD_ECTLR)
-               printf(" ecode %x", dcb->err_code);
-       printf("\n");
+       int unit = VDUNIT(bp->b_dev);
+       char part = 'a' + FILSYS(bp->b_dev);
+
+       if (dcb->operrsta == (DCBCMP | CPDCRT | SFTERR | ANYERR))
+               log(LOG_WARNING, "dk%d%c: soft ecc sn%d\n",
+                   unit, part, bp->b_blkno);
+       else
+               log(LOG_WARNING, "dk%d%c: soft error sn%d status %b ecode %x\n",
+                   unit, part, bp->b_blkno, dcb->operrsta, ERRBITS,
+                   ci->ctlr_type == SMD_ECTLR ? dcb->err_code : 0);
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
@@ -740,6 +738,13 @@ vdopen(dev, flag)
 
        if (vi == 0 || vi->ui_alive == 0 || vi->ui_type >= nvddrv)
                return (ENXIO);
 
        if (vi == 0 || vi->ui_alive == 0 || vi->ui_type >= nvddrv)
                return (ENXIO);
+       if (vi->ui_alive == 0) {
+               if (vdconfigure_drive((cdr *)vdminfo[vi->ui_ctlr]->um_addr,
+                   vi->ui_ctlr, vi->ui_slave, vi->ui_type))
+                       vi->ui_alive = 1;
+               else
+                       return (ENXIO);
+       }
        if (vdunit_info[unit].info.partition[FILSYS(dev)].par_len == 0)
                return (ENXIO);
        return (0);
        if (vdunit_info[unit].info.partition[FILSYS(dev)].par_len == 0)
                return (ENXIO);
        return (0);
@@ -791,7 +796,7 @@ vddump(dev)
        blkcount = maxfree - 2;         /* In 1k byte pages */
        if (dumplo + blkcount > fs->partition[filsys].par_len) {
                blkcount = fs->partition[filsys].par_len - dumplo;
        blkcount = maxfree - 2;         /* In 1k byte pages */
        if (dumplo + blkcount > fs->partition[filsys].par_len) {
                blkcount = fs->partition[filsys].par_len - dumplo;
-               printf("vd%d: Dump truncated to %dMB\n", unit, blkcount/1024);
+               printf("truncated to %dMB ", blkcount/1024);
        }
        cur_blk = fs->partition[filsys].par_start + dumplo;
        memaddr = 0;
        }
        cur_blk = fs->partition[filsys].par_start + dumplo;
        memaddr = 0;
@@ -882,34 +887,36 @@ vdreset_ctlr(addr, ctlr)
        }
        if (vdnotrailer(addr, ctlr, 0, INIT, 10) & HRDERR) {
                printf("failed to init\n");
        }
        if (vdnotrailer(addr, ctlr, 0, INIT, 10) & HRDERR) {
                printf("failed to init\n");
-               return (0);
+               return;
        }
        if (vdnotrailer(addr, ctlr, 0, DIAG, 10) & HRDERR) {
                printf("diagnostic error\n");
        }
        if (vdnotrailer(addr, ctlr, 0, DIAG, 10) & HRDERR) {
                printf("diagnostic error\n");
-               return (0);
+               return;
        }
        /*  reset all units attached to controller */
        uq = cq->b_forw;
        do {
        }
        /*  reset all units attached to controller */
        uq = cq->b_forw;
        do {
-               reset_drive(addr, ctlr, uq->b_dev, 0);
+               (void) reset_drive(addr, ctlr, uq->b_dev);
                uq = uq->b_forw;
        } while (uq != cq->b_forw);
                uq = uq->b_forw;
        } while (uq != cq->b_forw);
-       return (1);
 }
 
 /*
  * Perform a reset on a drive.
  */
 }
 
 /*
  * Perform a reset on a drive.
  */
-reset_drive(addr, ctlr, slave, start)
-       register cdr *addr;
-       register int ctlr, slave, start;
+reset_drive(addr, ctlr, slave)
+       cdr *addr;
+       int ctlr, slave;
 {
 {
-       register int type = vdctlr_info[ctlr].unit_type[slave];
+       int type = vdctlr_info[ctlr].unit_type[slave];
 
        if (type == UNKNOWN)
 
        if (type == UNKNOWN)
-               return;
-       if (!vdconfigure_drive(addr, ctlr, slave, type, start))
+               return (0);
+       if (!vdconfigure_drive(addr, ctlr, slave, type)) {
                printf("vd%d: drive %d: couldn't reset\n", ctlr, slave);
                printf("vd%d: drive %d: couldn't reset\n", ctlr, slave);
+               return (0);
+       }
+       return (1);
 }
 
 /*
 }
 
 /*
@@ -924,10 +931,10 @@ vdpoll(ci, addr, t)
        register fmt_dcb *dcb = &ci->ctlr_dcb;
 
        t *= 1000;
        register fmt_dcb *dcb = &ci->ctlr_dcb;
 
        t *= 1000;
-       uncache(&dcb->operrsta);
-       while ((dcb->operrsta&(DCBCMP|DCBABT)) == 0) {
-               DELAY(1000);
+       for (;;) {
                uncache(&dcb->operrsta);
                uncache(&dcb->operrsta);
+               if (dcb->operrsta & (DCBCMP|DCBABT))
+                       break;
                if (--t <= 0) {
                        printf("vd%d: controller timeout", ci-vdctlr_info);
                        VDDC_ABORT(addr, ci->ctlr_type);
                if (--t <= 0) {
                        printf("vd%d: controller timeout", ci-vdctlr_info);
                        VDDC_ABORT(addr, ci->ctlr_type);
@@ -935,12 +942,14 @@ vdpoll(ci, addr, t)
                        uncache(&dcb->operrsta);
                        return (0);
                }
                        uncache(&dcb->operrsta);
                        return (0);
                }
+               DELAY(1000);
        }
        if (ci->ctlr_type == SMD_ECTLR) {
        }
        if (ci->ctlr_type == SMD_ECTLR) {
-               uncache(&addr->cdr_csr);
-               while (addr->cdr_csr&CS_GO) {
-                       DELAY(50);
+               for (;;) {
                        uncache(&addr->cdr_csr);
                        uncache(&addr->cdr_csr);
+                       if ((addr->cdr_csr & CS_GO) == 0)
+                               break;
+                       DELAY(50);
                }
                DELAY(300);
        }
                }
                DELAY(300);
        }
index 1ade2ec..ca50d76 100644 (file)
@@ -1,4 +1,4 @@
-/*     vdreg.h 1.6     86/10/28        */
+/*     vdreg.h 1.7     87/01/11        */
 
 /*
  * VDDC (Versabus Direct Disk Controller) definitions.
 
 /*
  * VDDC (Versabus Direct Disk Controller) definitions.
 #define        SFTERR          0x400000        /* Soft Error (retry succesful) */
 #define        ANYERR          0x800000        /* Any Error */
 #define INVCMD         0x1000000       /* Programmer error */
 #define        SFTERR          0x400000        /* Soft Error (retry succesful) */
 #define        ANYERR          0x800000        /* Any Error */
 #define INVCMD         0x1000000       /* Programmer error */
+/*
+ * DCB status codes.
+ */
+#define        DCBABT          0x10000000      /* DCB Aborted */
+#define        DCBUSC          0x20000000      /* DCB Unsuccesfully Completed */
+#define        DCBCMP          0x40000000      /* DCB Complete */
+#define        DCBSTR          0x80000000      /* DCB Started */
 
 /* hard error */
 #define        HTYPES \
 
 /* hard error */
 #define        HTYPES \
 #define        ERRBITS "\20\1HCRC\2HCMP\3WPT\4CTLR\5DSEEK\6UCDATA\7NOTCYL\10DRVNRDY\
 \11ALTACC\12SEEKSTRT\13INVDADR\14DNEMEM\15PAR\16DCOMP\17DDIRDY\20OPABRT\
 \21DSERLY\22DSLATE\23TOPLUS\24TOPMNUS\25CPDCRT\26HRDERR\27SFTERR\30ANYERR\
 #define        ERRBITS "\20\1HCRC\2HCMP\3WPT\4CTLR\5DSEEK\6UCDATA\7NOTCYL\10DRVNRDY\
 \11ALTACC\12SEEKSTRT\13INVDADR\14DNEMEM\15PAR\16DCOMP\17DDIRDY\20OPABRT\
 \21DSERLY\22DSLATE\23TOPLUS\24TOPMNUS\25CPDCRT\26HRDERR\27SFTERR\30ANYERR\
-\31INVCMD"
-
-/*
- * DCB status codes.
- */
-#define        DCBABT          0x10000000      /* DCB Aborted */
-#define        DCBUSC          0x20000000      /* DCB Unsuccesfully Completed */
-#define        DCBCMP          0x40000000      /* DCB Complete */
-#define        DCBSTR          0x80000000      /* DCB Started */
+\31INVCMD\35ABORTED\36FAIL\37COMPLETE\40STARTED"
 
 /*
  * MDCB status codes.
 
 /*
  * MDCB status codes.
@@ -386,8 +385,8 @@ typedef struct {
 /* physical information for known disk drives.  */
 #ifdef VDGENDATA
 long   vddcaddr[] =
 /* physical information for known disk drives.  */
 #ifdef VDGENDATA
 long   vddcaddr[] =
-  { 0xf2000, 0xf2100, 0xf2200, 0xf2300, 0xf2400, 0xf2500, 0xf2600, 0xf2700, 0 };
-long   vdtimeout = 0;
+  { 0xffff2000, 0xffff2100, 0xffff2200, 0xffff2300, 0xffff2400, 0xffff2500,
+    0xffff2600, 0xffff2700, 0 };
 
 fs_tab vdst[] = {
        {512, 48, 24, 711, 0, 3600, 30240,      "CDC xsd",
 
 fs_tab vdst[] = {
        {512, 48, 24, 711, 0, 3600, 30240,      "CDC xsd",
@@ -476,8 +475,8 @@ fs_tab      vdst[] = {
                {177232, 71440},        /* g cyl 583 - 817 */
                {213104, 35568}}        /* h cyl 701 - 817 */
        },
                {177232, 71440},        /* g cyl 583 - 817 */
                {213104, 35568}}        /* h cyl 701 - 817 */
        },
-       {512, 32, 10, 823, 0, 3600, 20160, "CDC fsd",   /* 160 Mb FSD */
-           "160 Mb Control Data Winchester drive",
+       {512, 32, 10, 823, 0, 3600, 20160, "fsd",       /* 160 Mb FSD */
+           "160 Mb Winchester drive",
                { 0x0d9b366c, 0x1b366cd8, 0x366cd9b0, 0x6cd9b360,
                  0xd9b366c0, 0xb366cd80, 0x66cd9b00, 0xcd9b3600,
                  0x9b366300, 0x366cd800, 0x6cd9b000, 0xd9b36000,
                { 0x0d9b366c, 0x1b366cd8, 0x366cd9b0, 0x6cd9b360,
                  0xd9b366c0, 0xb366cd80, 0x66cd9b00, 0xcd9b3600,
                  0x9b366300, 0x366cd800, 0x6cd9b000, 0xd9b36000,
@@ -498,7 +497,6 @@ int nvddrv = (sizeof (vdst) / sizeof (fs_tab));
 #else
 #ifdef STANDALONE
 extern long    vddcaddr[];
 #else
 #ifdef STANDALONE
 extern long    vddcaddr[];
-extern long    vdtimeout;
 extern fs_tab  vdst[];
 extern int     nvddrv;
 #endif
 extern fs_tab  vdst[];
 extern int     nvddrv;
 #endif
index 741bd75..4a5a37e 100644 (file)
@@ -1,4 +1,4 @@
-/*     vx.c    1.9     86/11/03        */
+/*     vx.c    1.10    87/01/11        */
 
 #include "vx.h"
 #if NVX > 0
 
 #include "vx.h"
 #if NVX > 0
@@ -38,7 +38,6 @@ long  vxdebug = 0;
 #define        VXVCM   1
 #define        VXVCC   2
 #define        VXVCX   4
 #define        VXVCM   1
 #define        VXVCC   2
 #define        VXVCX   4
-#include "../tahoesna/snadebug.h"
 #endif
 
 /*
 #endif
 
 /*
@@ -48,6 +47,9 @@ long  vxdebug = 0;
 #define        RSPquals 1              /* command response interrupt */
 #define        UNSquals 2              /* unsolicited interrupt */
 
 #define        RSPquals 1              /* command response interrupt */
 #define        UNSquals 2              /* unsolicited interrupt */
 
+#define        VXUNIT(n)       ((n) >> 4)
+#define        VXPORT(n)       ((n) & 0xf)
+
 struct tty vx_tty[NVX*16];
 #ifndef lint
 int    nvx = NVX*16;
 struct tty vx_tty[NVX*16];
 #ifndef lint
 int    nvx = NVX*16;
@@ -77,10 +79,10 @@ struct      vx_softc {
 #define        VXV_NEW 1               /* NPVIOCX | NVIOCX */
        short   vs_xmtcnt;      /* xmit commands pending */
        short   vs_brkreq;      /* send break requests pending */
 #define        VXV_NEW 1               /* NPVIOCX | NVIOCX */
        short   vs_xmtcnt;      /* xmit commands pending */
        short   vs_brkreq;      /* send break requests pending */
-       short   vs_active;      /* active port bit array or flag */
        short   vs_state;       /* controller state */
 #define        VXS_READY       0       /* ready for commands */
 #define        VXS_RESET       1       /* in process of reseting */
        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 */
        struct  vxcmd *vs_avail;/* next available command buffer */
        caddr_t vs_mricmd;      /* most recent issued cmd */
        u_int   vs_ivec;        /* interrupt vector base */
        struct  vxcmd *vs_avail;/* next available command buffer */
@@ -130,6 +132,7 @@ vxattach(vi)
        register struct vba_device *vi;
 {
 
        register struct vba_device *vi;
 {
 
+       vx_softc[vi->ui_unit].vs_softCAR = vi->ui_flags;
        vxinit(vi->ui_unit, 1);
 }
 
        vxinit(vi->ui_unit, 1);
 }
 
@@ -147,17 +150,16 @@ vxopen(dev, flag)
        int unit, vx, s, error;
 
        unit = minor(dev);
        int unit, vx, s, error;
 
        unit = minor(dev);
-       vx = unit >> 4;
-       if (unit >= NVX*16 || (vi = vxinfo[vx])== 0 || vi->ui_alive == 0)
+       vx = VXUNIT(unit);
+       if (vx >= NVX || (vi = vxinfo[vx])== 0 || vi->ui_alive == 0)
                return (ENXIO);
                return (ENXIO);
+       vs = &vx_softc[vx];
        tp = &vx_tty[unit];
        tp = &vx_tty[unit];
+       unit = VXPORT(unit);
        if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
                return (EBUSY);
        if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
                return (EBUSY);
-       vs = &vx_softc[vx];
-#ifdef notdef
-       if (unit < vs->vs_loport || vs->vs_hiport < unit)       /* ??? */
+       if (unit < vs->vs_loport || unit > vs->vs_hiport)
                return (ENXIO);
                return (ENXIO);
-#endif
        tp->t_addr = (caddr_t)vs;
        tp->t_oproc = vxstart;
        tp->t_dev = dev;
        tp->t_addr = (caddr_t)vs;
        tp->t_oproc = vxstart;
        tp->t_dev = dev;
@@ -172,9 +174,9 @@ vxopen(dev, flag)
                }
                vxparam(dev);
        }
                }
                vxparam(dev);
        }
-       if (!vcmodem(dev, VMOD_ON))
-               while ((tp->t_state&TS_CARR_ON) == 0)
-                       sleep((caddr_t)&tp->t_rawq, TTIPRI);
+       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);
        splx(s);
        return (error);
        error = (*linesw[tp->t_line].l_open)(dev,tp);
        splx(s);
        return (error);
@@ -195,10 +197,8 @@ vxclose(dev, flag)
        tp = &vx_tty[unit];
        s = spl8();
        (*linesw[tp->t_line].l_close)(tp);
        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 (!vcmodem(dev, VMOD_OFF))
-                       tp->t_state &= ~TS_CARR_ON;
-       }
+       if (tp->t_state & TS_HUPCLS || (tp->t_state & TS_ISOPEN) == 0)
+               vcmodem(dev, VMOD_OFF);
        /* wait for the last response */
        while (tp->t_state&TS_FLUSH)
                sleep((caddr_t)&tp->t_state, TTOPRI);
        /* wait for the last response */
        while (tp->t_state&TS_FLUSH)
                sleep((caddr_t)&tp->t_state, TTOPRI);
@@ -255,18 +255,18 @@ vxrint(vx)
        case 0:
                break;
        case 2:
        case 0:
                break;
        case 2:
-               printf("vx%d: vc proc err, ustat %x\n", addr->v_ustat);
+               printf("vx%d: vc proc err, ustat %x\n", vx, addr->v_ustat);
                vxstreset(vx);
                vxstreset(vx);
-               return (0);
+               return;
        case 3:
                vcmintr(vx);
        case 3:
                vcmintr(vx);
-               return (1);
+               return;
        case 4:
        case 4:
-               return (1);
+               return;
        default:
        default:
-               printf("vx%d: vc uqual err, uqual %x\n", addr->v_uqual);
+               printf("vx%d: vc uqual err, uqual %x\n", vx, addr->v_uqual);
                vxstreset(vx);
                vxstreset(vx);
-               return (0);
+               return;
        }
        vs = &vx_softc[vx];
        if (vs->vs_vers == VXV_NEW)
        }
        vs = &vx_softc[vx];
        if (vs->vs_vers == VXV_NEW)
@@ -275,7 +275,7 @@ vxrint(vx)
                sp = (struct silo *)((caddr_t)addr+VX_SILO+(addr->v_usdata[0]<<6));
        nc = *(osp = (short *)sp);
        if (nc == 0)
                sp = (struct silo *)((caddr_t)addr+VX_SILO+(addr->v_usdata[0]<<6));
        nc = *(osp = (short *)sp);
        if (nc == 0)
-               return (1);
+               return;
        if (vs->vs_vers == VXV_NEW && nc > vs->vs_silosiz) {
                printf("vx%d: %d exceeds silo size\n", nc);
                nc = vs->vs_silosiz;
        if (vs->vs_vers == VXV_NEW && nc > vs->vs_silosiz) {
                printf("vx%d: %d exceeds silo size\n", nc);
                nc = vs->vs_silosiz;
@@ -301,6 +301,8 @@ vxrint(vx)
                        if ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
                            (tp->t_flags&(EVENP|ODDP)) == ODDP)
                                continue;
                        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
                if (sp->port&VX_FE) {
                        /*
                         * At framing error (break) generate
@@ -315,7 +317,6 @@ vxrint(vx)
                (*linesw[tp->t_line].l_rint)(c, tp);
        }
        *osp = 0;
                (*linesw[tp->t_line].l_rint)(c, tp);
        }
        *osp = 0;
-       return (1);
 }
 
 /*
 }
 
 /*
@@ -363,6 +364,11 @@ vxcparam(dev, wait)
        int s, unit = minor(dev);
 
        tp = &vx_tty[unit];
        int s, unit = minor(dev);
 
        tp = &vx_tty[unit];
+       if ((tp->t_ispeed)==0) {
+               tp->t_state |= TS_HUPCLS;
+               vcmodem(dev, VMOD_OFF);
+               return;
+       }
        vs = (struct vx_softc *)tp->t_addr;
        cp = vobtain(vs);
        s = spl8();
        vs = (struct vx_softc *)tp->t_addr;
        cp = vobtain(vs);
        s = spl8();
@@ -372,22 +378,32 @@ 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] = unit & 017;        /* port number */
+       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[2] = (tp->t_flags&RAW) ? 0 : tp->t_startc;
        cp->par[3] = (tp->t_flags&RAW) ? 0 : tp->t_stopc;
+#ifdef notnow
        if (tp->t_flags & (RAW|LITOUT|PASS8)) {
        if (tp->t_flags & (RAW|LITOUT|PASS8)) {
-               cp->par[4] = 0xc0;      /* 8 bits of data */
-               cp->par[7] = 0;         /* no parity */
+#endif
+               cp->par[4] = BITS8;             /* 8 bits of data */
+               cp->par[7] = VNOPARITY;         /* no parity */
+#ifdef notnow
        } else {
        } else {
-               cp->par[4] = 0x40;      /* 7 bits of data */
+               cp->par[4] = BITS7;             /* 7 bits of data */
                if ((tp->t_flags&(EVENP|ODDP)) == ODDP)
                if ((tp->t_flags&(EVENP|ODDP)) == ODDP)
-                       cp->par[7] = 1;         /* odd parity */
+                       cp->par[7] = VODDP;     /* odd parity */
                else
                else
-                       cp->par[7] = 3;         /* even parity */
+                       cp->par[7] = VEVENP;    /* even parity */
        }
        }
-       cp->par[5] = 0x4;                       /* 1 stop bit - XXX */
-       cp->par[6] = tp->t_ospeed;
-       if (vcmd(vs->vs_nbr, (caddr_t)&cp->cmd) && wait)
+#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;
+       else
+               cp->par[6] = tp->t_ospeed;
+       if (vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd) && wait)
                sleep((caddr_t)cp,TTIPRI);
        splx(s);
 }
                sleep((caddr_t)cp,TTIPRI);
        splx(s);
 }
@@ -401,10 +417,9 @@ vxxint(vx, cp)
        register int vx;
        register struct vxcmd *cp;
 {
        register int vx;
        register struct vxcmd *cp;
 {
-       register struct vxmit *vp, *pvp;
+       register struct vxmit *vp;
        register struct tty *tp, *tp0;
        register struct vx_softc *vs;
        register struct tty *tp, *tp0;
        register struct vx_softc *vs;
-       register struct tty *hp;
 
        vs = &vx_softc[vx];
        cp = (struct vxcmd *)((long *)cp-1);
 
        vs = &vx_softc[vx];
        cp = (struct vxcmd *)((long *)cp-1);
@@ -436,7 +451,6 @@ vxxint(vx, cp)
        vp = (struct vxmit *)(cp->par + (cp->cmd & 07)*sizeof (struct vxmit));
        for (; vp >= (struct vxmit *)cp->par; vp--) {
                tp = tp0 + (vp->line & 017);
        vp = (struct vxmit *)(cp->par + (cp->cmd & 07)*sizeof (struct vxmit));
        for (; vp >= (struct vxmit *)cp->par; vp--) {
                tp = tp0 + (vp->line & 017);
-               pvp = vp;
                tp->t_state &= ~TS_BUSY;
                if (tp->t_state & TS_FLUSH) {
                        tp->t_state &= ~TS_FLUSH;
                tp->t_state &= ~TS_BUSY;
                if (tp->t_state & TS_FLUSH) {
                        tp->t_state &= ~TS_FLUSH;
@@ -444,31 +458,19 @@ vxxint(vx, cp)
                } else
                        ndflush(&tp->t_outq, vp->bcount+1);
        }
                } else
                        ndflush(&tp->t_outq, vp->bcount+1);
        }
-       vs->vs_xmtcnt--;
        vrelease(vs, cp);
        vrelease(vs, cp);
-       if (vs->vs_vers == VXV_NEW) {
-               vp = pvp;
-               vs->vs_active |= 1 << ((vp->line & 017) - vs->vs_loport);
-               if (vxstart(tp) && (cp = nextcmd(vs)) != NULL) {
-                       vs->vs_xmtcnt++;
-                       vcmd(vx, (caddr_t)&cp->cmd);
-                       return;
-               }
-               vs->vs_active &= ~(1 << ((vp->line & 017) - vs->vs_loport));
-       } else {
-               vs->vs_active = -1;
+       if (vs->vs_vers == VXV_NEW)
+               vxstart(tp);
+       else {
                tp0 = &vx_tty[vx*16 + vs->vs_hiport];
                for(tp = &vx_tty[vx*16 + vs->vs_loport]; tp <= tp0; tp++)
                tp0 = &vx_tty[vx*16 + vs->vs_hiport];
                for(tp = &vx_tty[vx*16 + vs->vs_loport]; tp <= tp0; tp++)
-                       if (vxstart(tp) && (cp = nextcmd(vs)) != NULL) {
-                               vs->vs_xmtcnt++;
-                               vcmd(vx, (caddr_t)&cp->cmd);
-                       }
+                       vxstart(tp);
                if ((cp = nextcmd(vs)) != NULL) {       /* command to send? */
                        vs->vs_xmtcnt++;
                if ((cp = nextcmd(vs)) != NULL) {       /* command to send? */
                        vs->vs_xmtcnt++;
-                       vcmd(vx, (caddr_t)&cp->cmd);
+                       (void) vcmd(vx, (caddr_t)&cp->cmd);
                }
                }
-               vs->vs_active = 0;
        }
        }
+       vs->vs_xmtcnt--;
 }
 
 /*
 }
 
 /*
@@ -483,7 +485,7 @@ vxforce(vs)
        s = spl8();
        if ((cp = nextcmd(vs)) != NULL) {
                vs->vs_xmtcnt++;
        s = spl8();
        if ((cp = nextcmd(vs)) != NULL) {
                vs->vs_xmtcnt++;
-               vcmd(vs->vs_nbr, (caddr_t)&cp->cmd);
+               (void) vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd);
        }
        splx(s);
 }
        }
        splx(s);
 }
@@ -496,7 +498,6 @@ vxstart(tp)
 {
        register short n;
        register struct vx_softc *vs;
 {
        register short n;
        register struct vx_softc *vs;
-       register full;
        int s, port;
 
        s = spl8();
        int s, port;
 
        s = spl8();
@@ -516,43 +517,26 @@ vxstart(tp)
                }
                if (tp->t_outq.c_cc == 0) {
                        splx(s);
                }
                if (tp->t_outq.c_cc == 0) {
                        splx(s);
-                       return (0);
+                       return;
                }
                scope_out(3);
                if (tp->t_flags & (RAW|LITOUT))
                }
                scope_out(3);
                if (tp->t_flags & (RAW|LITOUT))
-                       full = 0;
-               else
-                       full = 0200;
-               if ((n = ndqb(&tp->t_outq, full)) == 0) {
-                       if (full) {
+                       n = ndqb(&tp->t_outq, 0);
+               else {
+                       n = ndqb(&tp->t_outq, 0200);
+                       if (n == 0) {
                                n = getc(&tp->t_outq);
                                timeout(ttrstrt, (caddr_t)tp, (n&0177)+6);
                                tp->t_state |= TS_TIMEOUT;
                                n = getc(&tp->t_outq);
                                timeout(ttrstrt, (caddr_t)tp, (n&0177)+6);
                                tp->t_state |= TS_TIMEOUT;
-                               full = 0;
+                               n = 0;
                        }
                        }
-               } else {
-                       char *cp = (char *)tp->t_outq.c_cf;
-
+               }
+               if (n) {
                        tp->t_state |= TS_BUSY;
                        tp->t_state |= TS_BUSY;
-                       full = vsetq(vs, port, cp, n);
-                       /*
-                        * If the port is not currently active, try to
-                        * send the data.  We send it immediately if the
-                        * command buffer is full, or if we've nothing
-                        * currently outstanding.  If we don't send it,
-                        * set a timeout to force the data to be sent soon.
-                        */
-                       if ((vs->vs_active & (1 << (port-vs->vs_loport))) == 0)
-                               if (full || vs->vs_xmtcnt == 0) {
-                                       cp = (char *)&nextcmd(vs)->cmd;
-                                       vs->vs_xmtcnt++;
-                                       vcmd(vs->vs_nbr, cp);
-                               } else
-                                       timeout(vxforce, (caddr_t)vs, 3);
+                       vsetq(vs, port, (char *)tp->t_outq.c_cf, n);
                }
        }
        splx(s);
                }
        }
        splx(s);
-       return (full);  /* indicate if max commands or not */
 }
 
 /*
 }
 
 /*
@@ -585,7 +569,7 @@ vxinit(vx, wait)
        register struct vxcmd *cp;
        register char *resp;
        register int j;
        register struct vxcmd *cp;
        register char *resp;
        register int j;
-       char type;
+       char type, *typestring;
 
        vs = &vx_softc[vx];
        vs->vs_type = 0;                /* vioc-x by default */
 
        vs = &vx_softc[vx];
        vs->vs_type = 0;                /* vioc-x by default */
@@ -598,14 +582,18 @@ vxinit(vx, wait)
 
        case VXT_VIOCX:
        case VXT_VIOCX|VXT_NEW:
 
        case VXT_VIOCX:
        case VXT_VIOCX|VXT_NEW:
-               /* set dcd for printer ports */
-               for (j = 0; j < 16;j++)
-                       if (addr->v_portyp[j] == 4)
+               typestring = "VIOC-X";
+               /* set soft carrier for printer ports */
+               for (j = 0; j < 16; j++)
+                       if (addr->v_portyp[j] == VXT_PARALLEL) {
+                               vs->vs_softCAR |= 1 << j;
                                addr->v_dcd |= 1 << j;
                                addr->v_dcd |= 1 << j;
+                       }
                break;
 
        case VXT_PVIOCX:
        case VXT_PVIOCX|VXT_NEW:
                break;
 
        case VXT_PVIOCX:
        case VXT_PVIOCX|VXT_NEW:
+               typestring = "VIOC-X (old connector panel)";
                break;
        case VXT_VIOCBOP:               /* VIOC-BOP */
                vs->vs_type = 1;
                break;
        case VXT_VIOCBOP:               /* VIOC-BOP */
                vs->vs_type = 1;
@@ -614,6 +602,7 @@ vxinit(vx, wait)
 
        default:
                printf("vx%d: unknown type %x\n", vx, type);
 
        default:
                printf("vx%d: unknown type %x\n", vx, type);
+               vxinfo[vx]->ui_alive = 0;
                return;
        }
        vs->vs_nbr = -1;
                return;
        }
        vs->vs_nbr = -1;
@@ -639,7 +628,7 @@ vxinit(vx, wait)
        cp->par[3] = cp->par[0]+2;      /* unsol intr vector */
        cp->par[4] = 15;                /* max ports, no longer used */
        cp->par[5] = 0;                 /* set 1st port number */
        cp->par[3] = cp->par[0]+2;      /* unsol intr vector */
        cp->par[4] = 15;                /* max ports, no longer used */
        cp->par[5] = 0;                 /* set 1st port number */
-       vcmd(vx, (caddr_t)&cp->cmd);
+       (void) vcmd(vx, (caddr_t)&cp->cmd);
        if (!wait)
                return;
        for (j = 0; cp->cmd == VXC_LIDENT && j < 4000000; j++)
        if (!wait)
                return;
        for (j = 0; cp->cmd == VXC_LIDENT && j < 4000000; j++)
@@ -655,6 +644,9 @@ vxinit(vx, wait)
        }
        vs->vs_loport = cp->par[5];
        vs->vs_hiport = cp->par[7];
        }
        vs->vs_loport = cp->par[5];
        vs->vs_hiport = cp->par[7];
+       printf("vx%d: %s%s, ports %d-%d\n", vx,
+           (vs->vs_vers == VXV_NEW) ? "" : "old ", typestring,
+           vs->vs_loport, vs->vs_hiport);
        vrelease(vs, cp);
        vs->vs_nbr = vx;                /* assign board number */
 }
        vrelease(vs, cp);
        vs->vs_nbr = vx;                /* assign board number */
 }
@@ -681,7 +673,7 @@ vobtain(vs)
                splx(s);
                return (vobtain(vs));
        }
                splx(s);
                return (vobtain(vs));
        }
-       vs->vs_avail = vs->vs_avail->c_fwd;
+       vs->vs_avail = p->c_fwd;
        splx(s);
        return ((struct vxcmd *)p);
 }
        splx(s);
        return ((struct vxcmd *)p);
 }
@@ -721,7 +713,8 @@ nextcmd(vs)
 
 /*
  * Assemble transmits into a multiple command;
 
 /*
  * Assemble transmits into a multiple command;
- * up to 8 transmits to 8 lines can be assembled together.
+ * up to 8 transmits to 8 lines can be assembled together
+ * (on PVIOCX only).
  */
 vsetq(vs, line, addr, n)
        register struct vx_softc *vs;
  */
 vsetq(vs, line, addr, n)
        register struct vx_softc *vs;
@@ -740,10 +733,10 @@ vsetq(vs, line, addr, n)
                vs->vs_build = cp;
                cp->cmd = VXC_XMITDTA;
        } else {
                vs->vs_build = cp;
                cp->cmd = VXC_XMITDTA;
        } else {
-               if ((cp->cmd & 07) == 07) {
+               if ((cp->cmd & 07) == 07 || vs->vs_vers == VXV_NEW) {
                        printf("vx%d: setq overflow\n", vs-vx_softc);
                        printf("vx%d: setq overflow\n", vs-vx_softc);
-                       vxstreset(vs->vs_nbr);
-                       return (0);
+                       vxstreset((int)vs->vs_nbr);
+                       return;
                }
                cp->cmd++;
        }
                }
                cp->cmd++;
        }
@@ -758,13 +751,25 @@ vsetq(vs, line, addr, n)
        mp->line = line;
        if (vs->vs_vers == VXV_NEW && n <= sizeof (mp->ostream)) {
                cp->cmd = VXC_XMITIMM;
        mp->line = line;
        if (vs->vs_vers == VXV_NEW && n <= sizeof (mp->ostream)) {
                cp->cmd = VXC_XMITIMM;
-               bcopy(addr, mp->ostream, n);
+               bcopy(addr, mp->ostream, (unsigned)n);
        } else {
                /* get system address of clist block */
                addr = (caddr_t)vtoph((struct proc *)0, (unsigned)addr);
        } else {
                /* get system address of clist block */
                addr = (caddr_t)vtoph((struct proc *)0, (unsigned)addr);
-               bcopy(&addr, mp->ostream, sizeof (addr));
+               bcopy((caddr_t)&addr, mp->ostream, sizeof (addr));
        }
        }
-       return (vs->vs_vers == VXV_NEW ? 1 : (cp->cmd&07) == 7);
+       /*
+        * We send the data immediately if a VIOCX,
+        * the command buffer is full, or if we've nothing
+        * currently outstanding.  If we don't send it,
+        * set a timeout to force the data to be sent soon.
+        */
+       if (vs->vs_vers == VXV_NEW || (cp->cmd & 07) == 7 ||
+           vs->vs_xmtcnt == 0) {
+               vs->vs_xmtcnt++;
+               (void) vcmd((int)vs->vs_nbr, (char *)&cp->cmd);
+               vs->vs_build = 0;
+       } else
+               timeout(vxforce, (caddr_t)vs, 3);
 }
 
 /*
 }
 
 /*
@@ -838,7 +843,7 @@ vackint(vx)
                register char *resp;
                register i;
 
                register char *resp;
                register i;
 
-               printf("vx%d INTR ERR type %x v_dcd %x\n", vx,
+               printf("vx%d: ackint error type %x v_dcd %x\n", vx,
                    vp->v_vcid & 07, vp->v_dcd & 0xff);
                resp = (char *)vs->vs_mricmd;
                for (i = 0; i < 16; i++)
                    vp->v_vcid & 07, vp->v_dcd & 0xff);
                resp = (char *)vs->vs_mricmd;
                for (i = 0; i < 16; i++)
@@ -1164,17 +1169,17 @@ vxrestart(vx)
 {
        register struct tty *tp, *tp0;
        register struct vx_softc *vs;
 {
        register struct tty *tp, *tp0;
        register struct vx_softc *vs;
-       register int i, cnt;
+       register int i, count;
        int s = spl8();
 
        int s = spl8();
 
-       cnt = vx >> 8;
+       count = vx >> 8;
        vx &= 0xff;
        vs = &vx_softc[vx];
        vs->vs_state = VXS_READY;
        tp0 = &vx_tty[vx*16];
        for (i = vs->vs_loport; i <= vs->vs_hiport; i++) {
                tp = tp0 + i;
        vx &= 0xff;
        vs = &vx_softc[vx];
        vs->vs_state = VXS_READY;
        tp0 = &vx_tty[vx*16];
        for (i = vs->vs_loport; i <= vs->vs_hiport; i++) {
                tp = tp0 + i;
-               if (cnt != 0) {
+               if (count != 0) {
                        tp->t_state &= ~(TS_BUSY|TS_TIMEOUT);
                        if (tp->t_state&(TS_ISOPEN|TS_WOPEN))
                                vxstart(tp);    /* restart pending output */
                        tp->t_state &= ~(TS_BUSY|TS_TIMEOUT);
                        if (tp->t_state&(TS_ISOPEN|TS_WOPEN))
                                vxstart(tp);    /* restart pending output */
@@ -1183,7 +1188,7 @@ vxrestart(vx)
                                vxcparam(tp->t_dev, 0);
                }
        }
                                vxcparam(tp->t_dev, 0);
                }
        }
-       if (cnt == 0) {
+       if (count == 0) {
                vs->vs_state = VXS_RESET;
                timeout(vxrestart, (caddr_t)(vx + 1*256), hz);
        } else
                vs->vs_state = VXS_RESET;
                timeout(vxrestart, (caddr_t)(vx + 1*256), hz);
        } else
@@ -1195,9 +1200,10 @@ vxreset(dev)
        dev_t dev;
 {
 
        dev_t dev;
 {
 
-       vxstreset(minor(dev) >> 4);     /* completes asynchronously */
+       vxstreset((int)VXUNIT(minor(dev)));     /* completes asynchronously */
 }
 
 }
 
+#ifdef notdef
 vxfreset(vx)
        register int vx;
 {
 vxfreset(vx)
        register int vx;
 {
@@ -1209,6 +1215,7 @@ vxfreset(vx)
        vxstreset(vx);
        return (0);             /* completes asynchronously */
 }
        vxstreset(vx);
        return (0);             /* completes asynchronously */
 }
+#endif
 
 vcmodem(dev, flag)
        dev_t dev;
 
 vcmodem(dev, flag)
        dev_t dev;
@@ -1223,6 +1230,8 @@ vcmodem(dev, flag)
        unit = minor(dev);
        tp = &vx_tty[unit];
        vs = (struct vx_softc *)tp->t_addr;
        unit = minor(dev);
        tp = &vx_tty[unit];
        vs = (struct vx_softc *)tp->t_addr;
+       if (vs->vs_state != VXS_READY)
+               return;
        cp = vobtain(vs);
        kp = (struct vxdevice *)((struct vba_device *)vxinfo[vs->vs_nbr])->ui_addr;
 
        cp = vobtain(vs);
        kp = (struct vxdevice *)((struct vba_device *)vxinfo[vs->vs_nbr])->ui_addr;
 
@@ -1231,16 +1240,19 @@ vcmodem(dev, flag)
         * Issue MODEM command
         */
        cp->cmd = VXC_MDMCTL;
         * Issue MODEM command
         */
        cp->cmd = VXC_MDMCTL;
-       cp->par[0] = (flag == VMOD_ON) ? V_ENAB : V_DISAB;
+       if (flag == VMOD_ON) {
+               if (vs->vs_softCAR & (1 << port))
+                       cp->par[0] = V_MANUAL | V_DTR_ON | V_RTS;
+               else
+                       cp->par[0] = V_AUTO | V_DTR_ON | V_RTS;
+       } else
+               cp->par[0] = V_DTR_OFF;
        cp->par[1] = port;
        cp->par[1] = port;
-       vcmd(vs->vs_nbr, (caddr_t)&cp->cmd);
-       port -= vs->vs_loport;
-       if ((kp->v_dcd >> port) & 1) {
-               if (flag == VMOD_ON)
-                       tp->t_state |= TS_CARR_ON;
-               return (1);
-       }
-       return (0);
+       (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;
 }
 
 /*
 }
 
 /*
@@ -1253,21 +1265,22 @@ vcmintr(vx)
        register struct vxdevice *kp;
        register struct tty *tp;
        register port;
        register struct vxdevice *kp;
        register struct tty *tp;
        register port;
+       register struct vx_softc *vs;
 
        kp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
        port = kp->v_usdata[0] & 017;
        tp = &vx_tty[vx*16+port];
 
        kp = (struct vxdevice *)((struct vba_device *)vxinfo[vx])->ui_addr;
        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);
        else if ((kp->v_ustat & DCD_OFF) &&
 
        if (kp->v_ustat & DCD_ON)
                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        else if ((kp->v_ustat & DCD_OFF) &&
+           ((vs->vs_softCAR & (1 << port))) == 0 &&
            (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
            (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
-               register struct vx_softc *vs;
                register struct vcmds *cp;
                register struct vxcmd *cmdp;
 
                register struct vcmds *cp;
                register struct vxcmd *cmdp;
 
-               /* clear all pending trnansmits */
-               vs = &vx_softc[vx];
+               /* clear all pending transmits */
                if (tp->t_state&(TS_BUSY|TS_FLUSH) &&
                    vs->vs_vers == VXV_NEW) {
                        int i, cmdfound = 0;
                if (tp->t_state&(TS_BUSY|TS_FLUSH) &&
                    vs->vs_vers == VXV_NEW) {
                        int i, cmdfound = 0;
@@ -1292,11 +1305,12 @@ vcmintr(vx)
                                cmdp = vobtain(vs);
                                cmdp->cmd = VXC_FDTATOX;
                                cmdp->par[1] = port;
                                cmdp = vobtain(vs);
                                cmdp->cmd = VXC_FDTATOX;
                                cmdp->par[1] = port;
-                               vcmd(vx, (caddr_t)&cmdp->cmd);
+                               (void) vcmd(vx, (caddr_t)&cmdp->cmd);
                        }
                }
        } 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_intrc & 0377, tp);
+               (*linesw[tp->t_line].l_rint)((tp->t_flags & RAW) ?
+                   0 : tp->t_intrc, tp);
                return;
        }
 }
                return;
        }
 }
index 46cc6c7..ac923f1 100644 (file)
@@ -1,4 +1,4 @@
-/*     vxreg.h 1.4     86/01/23        */
+/*     vxreg.h 1.5     87/01/11        */
 
 /*
  * Vioc hardware interface structure.
 
 /*
  * Vioc hardware interface structure.
@@ -56,15 +56,40 @@ struct      vxdevice {
 
 #define        VX_BISYNC       0x1             /* bisync flag indicator for bscport */
 
 
 #define        VX_BISYNC       0x1             /* bisync flag indicator for bscport */
 
+/* connector panel types (per port) */
+#define        VXT_NONE        0               /* no connector panel */
+#define        VXT_8PORT       1               /* 8 port RS-232C */
+#define        VXT_RS422       2               /* 8 port RS-422 (nonexistent) */
+#define        VXT_4PORT       3               /* 4 port RS-232 (with DSR/RING) */
+#define        VXT_PARALLEL    4               /* 4 port panel parallel port */
+
 /* v_fault status values */
 #define        VXF_READY       0x55            /* no err in vioc self-initializaton */
 
 /* v_fault status values */
 #define        VXF_READY       0x55            /* no err in vioc self-initializaton */
 
+/* line parameters, set with VXC_LPARAX */
+#define        BITS5           0x00            /* 5 bits per character */
+#define        BITS6           0x80            /* 6 bits per character */
+#define        BITS7           0x40            /* 7 bits per character */
+#define        BITS8           0xc0            /* 8 bits per character */
+
+#define        VNOPARITY       0x00            /* no parity bit */
+#define        VODDP           0x01            /* odd parity bit */
+#define        VEVENP          0x03            /* even parity bit */
+
+#define        VSTOP1          0x04            /* 1 stop bit */
+#define        VSTOP2          0x0c            /* 2 stop bit */
+
+#define        V19200          0x13            /* 19.2 kbaud */
+
 /* modem control flags */
 #define        VMOD_ON         1
 #define        VMOD_OFF        0
 
 /* modem control flags */
 #define        VMOD_ON         1
 #define        VMOD_OFF        0
 
-#define        V_ENAB  0002                    /* auto + DTR */
-#define        V_DISAB 0000                    /* auto + disable DTR */
+#define        V_AUTO          0x00            /* auto control of RTS, uses CTS */
+#define        V_MANUAL        0x80            /* manual control of RTS, ignore CTS */
+#define        V_DTR_ON        0x02            /* set DTR output */
+#define        V_DTR_OFF       0x00            /* drop DTR output */
+#define        V_RTS           0x01            /* set RTS output (manual only) */
 
 #define        BRK_CHR 040                     /* break character */
 #define        DCD_ON  020                     /* */
 
 #define        BRK_CHR 040                     /* break character */
 #define        DCD_ON  020                     /* */