BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / vaxmba / ht.c
index 0c61a72..8181b5f 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)ht.c        7.1 (Berkeley) 6/5/86
+ *     @(#)ht.c        7.6 (Berkeley) 5/6/88
  */
 
 #include "tu.h"
  */
 
 #include "tu.h"
@@ -17,8 +17,6 @@
  *     see how many rewind interrups we get if we kick when not at BOT
  *     fixup rle error on block tape code
  */
  *     see how many rewind interrups we get if we kick when not at BOT
  *     fixup rle error on block tape code
  */
-#include "../machine/pte.h"
-
 #include "param.h"
 #include "systm.h"
 #include "buf.h"
 #include "param.h"
 #include "systm.h"
 #include "buf.h"
 #include "cmap.h"
 #include "uio.h"
 #include "tty.h"
 #include "cmap.h"
 #include "uio.h"
 #include "tty.h"
+#include "syslog.h"
 
 
+#include "../machine/pte.h"
 #include "../vax/cpu.h"
 #include "mbareg.h"
 #include "mbavar.h"
 #include "htreg.h"
 
 #include "../vax/cpu.h"
 #include "mbareg.h"
 #include "mbavar.h"
 #include "htreg.h"
 
-struct buf     rhtbuf[NHT];
 struct buf     chtbuf[NHT];
 
 short  httypes[] =
        { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
 struct mba_device *htinfo[NHT];
 struct buf     chtbuf[NHT];
 
 short  httypes[] =
        { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
 struct mba_device *htinfo[NHT];
+struct mba_slave *tuinfo[NTU];
 int    htattach(), htslave(), htustart(), htndtint(), htdtint();
 struct mba_driver htdriver =
     { htattach, htslave, htustart, 0, htdtint, htndtint,
 int    htattach(), htslave(), htustart(), htndtint(), htdtint();
 struct mba_driver htdriver =
     { htattach, htslave, htustart, 0, htdtint, htndtint,
@@ -54,9 +54,9 @@ struct        mba_driver htdriver =
 /* bits in minor device */
 #define        TUUNIT(dev)     (minor(dev)&03)
 #define        H_NOREWIND      04
 /* bits in minor device */
 #define        TUUNIT(dev)     (minor(dev)&03)
 #define        H_NOREWIND      04
-#define        H_1600BPI       08
+#define        H_DENS(dev)     ((minor(dev) >> 3) & 03)
 
 
-#define HTUNIT(dev)    (tutoht[TUUNIT(dev)])
+#define HTUNIT(dev)    (tuinfo[TUUNIT(dev)]->ms_ctlr)
 
 #define        INF     (daddr_t)1000000L       /* a block number that wont exist */
 
 
 #define        INF     (daddr_t)1000000L       /* a block number that wont exist */
 
@@ -69,11 +69,10 @@ struct      tu_softc {
        u_short sc_dsreg;
        short   sc_resid;
        short   sc_dens;
        u_short sc_dsreg;
        short   sc_resid;
        short   sc_dens;
-       struct  mba_device *sc_mi;
-       int     sc_slave;
        struct  tty *sc_ttyp;           /* record user's tty for errors */
        struct  tty *sc_ttyp;           /* record user's tty for errors */
+       int     sc_blks;        /* number of I/O operations since open */
+       int     sc_softerrs;    /* number of soft I/O errors since open */
 } tu_softc[NTU];
 } tu_softc[NTU];
-short  tutoht[NTU];
 
 /*
  * Bits for sc_flags.
 
 /*
  * Bits for sc_flags.
@@ -97,58 +96,60 @@ htslave(mi, ms, sn)
        struct mba_slave *ms;
        int sn;
 {
        struct mba_slave *ms;
        int sn;
 {
-       register struct tu_softc *sc = &tu_softc[ms->ms_unit];
        register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv;
 
        htaddr->httc = sn;
        if (htaddr->htdt & HTDT_SPR) {
        register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv;
 
        htaddr->httc = sn;
        if (htaddr->htdt & HTDT_SPR) {
-               sc->sc_mi = mi;
-               sc->sc_slave = sn;
-               tutoht[ms->ms_unit] = mi->mi_unit;
+               tuinfo[ms->ms_unit] = ms;
                return (1);
        } else
                return (0);
 }
 
                return (1);
        } else
                return (0);
 }
 
+int    htdens[4] = { HTTC_800BPI, HTTC_1600BPI, HTTC_6250BPI, HTTC_800BPI };
+
 htopen(dev, flag)
        dev_t dev;
        int flag;
 {
        register int tuunit;
 htopen(dev, flag)
        dev_t dev;
        int flag;
 {
        register int tuunit;
-       register struct mba_device *mi;
        register struct tu_softc *sc;
        register struct tu_softc *sc;
+       register struct mba_slave *ms;
        int olddens, dens;
 
        tuunit = TUUNIT(dev);
        int olddens, dens;
 
        tuunit = TUUNIT(dev);
-       if (tuunit >= NTU || (mi = htinfo[HTUNIT(dev)]) == 0 ||
-           mi->mi_alive == 0)
+       if (tuunit >= NTU || (ms = tuinfo[tuunit]) == NULL ||
+           ms->ms_alive == 0 || htinfo[ms->ms_ctlr]->mi_alive == 0)
                return (ENXIO);
        if ((sc = &tu_softc[tuunit])->sc_openf)
                return (EBUSY);
                return (ENXIO);
        if ((sc = &tu_softc[tuunit])->sc_openf)
                return (EBUSY);
+       sc->sc_openf = 1;
        olddens = sc->sc_dens;
        olddens = sc->sc_dens;
-       dens = sc->sc_dens =
-           ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)|
-               HTTC_PDP11|sc->sc_slave;
+       dens = sc->sc_dens = htdens[H_DENS(dev)] | HTTC_PDP11 | ms->ms_slave;
        htcommand(dev, HT_SENSE, 1);
        sc->sc_dens = olddens;
        if ((sc->sc_dsreg & HTDS_MOL) == 0) {
        htcommand(dev, HT_SENSE, 1);
        sc->sc_dens = olddens;
        if ((sc->sc_dsreg & HTDS_MOL) == 0) {
+               sc->sc_openf = 0;
                uprintf("tu%d: not online\n", tuunit);
                return (EIO);
        }
        if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) {
                uprintf("tu%d: not online\n", tuunit);
                return (EIO);
        }
        if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) {
+               sc->sc_openf = 0;
                uprintf("tu%d: no write ring\n", tuunit);
                return (EIO);
        }
        if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) &&
            dens != sc->sc_dens) {
                uprintf("tu%d: no write ring\n", tuunit);
                return (EIO);
        }
        if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) &&
            dens != sc->sc_dens) {
+               sc->sc_openf = 0;
                uprintf("tu%d: can't change density in mid-tape\n", tuunit);
                return (EIO);
        }
                uprintf("tu%d: can't change density in mid-tape\n", tuunit);
                return (EIO);
        }
-       sc->sc_openf = 1;
        sc->sc_blkno = (daddr_t)0;
        sc->sc_nxrec = INF;
        sc->sc_flags = 0;
        sc->sc_dens = dens;
        sc->sc_blkno = (daddr_t)0;
        sc->sc_nxrec = INF;
        sc->sc_flags = 0;
        sc->sc_dens = dens;
+       sc->sc_blks = 0;
+       sc->sc_softerrs = 0;
        sc->sc_ttyp = u.u_ttyp;
        return (0);
 }
        sc->sc_ttyp = u.u_ttyp;
        return (0);
 }
@@ -166,6 +167,9 @@ htclose(dev, flag)
        }
        if ((minor(dev)&H_NOREWIND) == 0)
                htcommand(dev, HT_REW, 0);
        }
        if ((minor(dev)&H_NOREWIND) == 0)
                htcommand(dev, HT_REW, 0);
+       if (sc->sc_blks > 100 && sc->sc_softerrs > sc->sc_blks / 100)
+               log(LOG_INFO, "tu%d: %d soft errors in %d blocks\n",
+                   TUUNIT(dev), sc->sc_softerrs, sc->sc_blks);
        sc->sc_openf = 0;
 }
 
        sc->sc_openf = 0;
 }
 
@@ -248,19 +252,28 @@ htustart(mi)
                return (MBU_NEXT);
        }
        if (bp != &chtbuf[HTUNIT(bp->b_dev)]) {
                return (MBU_NEXT);
        }
        if (bp != &chtbuf[HTUNIT(bp->b_dev)]) {
-               if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
-                       bp->b_flags |= B_ERROR;
-                       bp->b_error = ENXIO;
-                       return (MBU_NEXT);
-               }
-               if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec &&
-                   bp->b_flags&B_READ) {
-                       bp->b_resid = bp->b_bcount;
-                       clrbuf(bp);
-                       return (MBU_NEXT);
+               /* transfer: check positioning */
+               if (bp->b_flags & B_RAW) {
+                       /* raw transfer: record position for retry */
+                       if (mi->mi_tab.b_errcnt == 0) {
+                               sc->sc_blkno = bdbtofsb(bp->b_blkno);
+                               sc->sc_nxrec = sc->sc_blkno + 1;
+                       }
+               } else {
+                       if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
+                               bp->b_flags |= B_ERROR;
+                               bp->b_error = ENXIO;
+                               return (MBU_NEXT);
+                       }
+                       if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec &&
+                           bp->b_flags&B_READ) {
+                               bp->b_resid = bp->b_bcount;
+                               clrbuf(bp);
+                               return (MBU_NEXT);
+                       }
+                       if ((bp->b_flags&B_READ)==0)
+                               sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1;
                }
                }
-               if ((bp->b_flags&B_READ)==0)
-                       sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1;
        } else {
                if (bp->b_command == HT_SENSE)
                        return (MBU_NEXT);
        } else {
                if (bp->b_command == HT_SENSE)
                        return (MBU_NEXT);
@@ -320,7 +333,7 @@ htdtint(mi, mbsr)
        if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) {
                htaddr->htcs1 = HT_DCLR|HT_GO;
                mbclrattn(mi);
        if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) {
                htaddr->htcs1 = HT_DCLR|HT_GO;
                mbclrattn(mi);
-               if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) {
+               if (bp->b_flags & B_RAW) {
                        er &= ~HTER_FCE;
                        mbs &= ~(MBSR_DTABT|MBSR_MBEXC);
                }
                        er &= ~HTER_FCE;
                        mbs &= ~(MBSR_DTABT|MBSR_MBEXC);
                }
@@ -347,6 +360,9 @@ noprint:
                        return (MBD_RETRY);
        }
        bp->b_resid = 0;
                        return (MBD_RETRY);
        }
        bp->b_resid = 0;
+       sc->sc_blks++;
+       if (mi->mi_tab.b_errcnt)
+               sc->sc_softerrs++;
        if (bp->b_flags & B_READ)
                if (ds&HTDS_TM) {               /* must be a read, right? */
                        bp->b_resid = bp->b_bcount;
        if (bp->b_flags & B_READ)
                if (ds&HTDS_TM) {               /* must be a read, right? */
                        bp->b_resid = bp->b_bcount;
@@ -422,49 +438,6 @@ htndtint(mi)
        return (MBN_RETRY);
 }
 
        return (MBN_RETRY);
 }
 
-htread(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       int errno;
-
-       errno = htphys(dev, uio);
-       if (errno)
-               return (errno);
-       return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys, uio));
-}
-
-htwrite(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       int errno;
-
-       errno = htphys(dev, uio);
-       if (errno)
-               return (errno);
-       return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys, uio));
-}
-
-htphys(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       register int htunit;
-       register struct tu_softc *sc;
-       register struct mba_device *mi;
-       daddr_t a;
-
-       htunit = HTUNIT(dev);
-       if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0)
-               return (ENXIO);
-       a = uio->uio_offset >> 9;
-       sc = &tu_softc[TUUNIT(dev)];
-       sc->sc_blkno = bdbtofsb(a);
-       sc->sc_nxrec = bdbtofsb(a)+1;
-       return (0);
-}
-
 /*ARGSUSED*/
 htioctl(dev, cmd, data, flag)
        dev_t dev;
 /*ARGSUSED*/
 htioctl(dev, cmd, data, flag)
        dev_t dev;