BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / vaxuba / ut.c
index 6d2e27f..ed7b3a9 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.
  *
- *     @(#)ut.c        7.1 (Berkeley) 6/5/86
+ *     @(#)ut.c        7.3 (Berkeley) 5/6/88
  */
 
 #include "tj.h"
  */
 
 #include "tj.h"
@@ -16,8 +16,6 @@
  *     check out attention processing
  *     try reset code and dump code
  */
  *     check out attention processing
  *     try reset code and dump code
  */
-#include "../machine/pte.h"
-
 #include "param.h"
 #include "systm.h"
 #include "buf.h"
 #include "param.h"
 #include "systm.h"
 #include "buf.h"
 #include "uio.h"
 #include "kernel.h"
 #include "tty.h"
 #include "uio.h"
 #include "kernel.h"
 #include "tty.h"
+#include "syslog.h"
 
 
+#include "../machine/pte.h"
 #include "../vax/cpu.h"
 #include "ubareg.h"
 #include "ubavar.h"
 #include "utreg.h"
 
 #include "../vax/cpu.h"
 #include "ubareg.h"
 #include "ubavar.h"
 #include "utreg.h"
 
-struct buf     rutbuf[NUT];    /* bufs for raw i/o */
 struct buf     cutbuf[NUT];    /* bufs for control operations */
 struct buf     tjutab[NTJ];    /* bufs for slave queue headers */
 
 struct buf     cutbuf[NUT];    /* bufs for control operations */
 struct buf     tjutab[NTJ];    /* bufs for slave queue headers */
 
@@ -76,6 +75,8 @@ struct        tj_softc {
        daddr_t sc_timo;        /* time until timeout expires */
        short   sc_tact;        /* timeout is active flag */
        struct  tty *sc_ttyp;   /* record user's tty for errors */
        daddr_t sc_timo;        /* time until timeout expires */
        short   sc_tact;        /* timeout is active flag */
        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 */
 } tj_softc[NTJ];
 
 /*
 } tj_softc[NTJ];
 
 /*
@@ -142,6 +143,7 @@ utopen(dev, flag)
                return (ENXIO);
        if ((sc = &tj_softc[tjunit])->sc_openf)
                return (EBUSY);
                return (ENXIO);
        if ((sc = &tj_softc[tjunit])->sc_openf)
                return (EBUSY);
+       sc->sc_openf = 1;
        olddens = sc->sc_dens;
        dens = sc->sc_dens =
            utdens[(minor(dev)&(T_1600BPI|T_6250BPI))>>3]|
        olddens = sc->sc_dens;
        dens = sc->sc_dens =
            utdens[(minor(dev)&(T_1600BPI|T_6250BPI))>>3]|
@@ -154,22 +156,26 @@ get:
        }
        sc->sc_dens = olddens;
        if ((sc->sc_dsreg&UTDS_MOL) == 0) {
        }
        sc->sc_dens = olddens;
        if ((sc->sc_dsreg&UTDS_MOL) == 0) {
+               sc->sc_openf = 0;
                uprintf("tj%d: not online\n", tjunit);
                return (EIO);
        }
        if ((flag&FWRITE) && (sc->sc_dsreg&UTDS_WRL)) {
                uprintf("tj%d: not online\n", tjunit);
                return (EIO);
        }
        if ((flag&FWRITE) && (sc->sc_dsreg&UTDS_WRL)) {
+               sc->sc_openf = 0;
                uprintf("tj%d: no write ring\n", tjunit);
                return (EIO);
        }
        if ((sc->sc_dsreg&UTDS_BOT) == 0 && (flag&FWRITE) &&
            dens != sc->sc_dens) {
                uprintf("tj%d: no write ring\n", tjunit);
                return (EIO);
        }
        if ((sc->sc_dsreg&UTDS_BOT) == 0 && (flag&FWRITE) &&
            dens != sc->sc_dens) {
+               sc->sc_openf = 0;
                uprintf("tj%d: can't change density in mid-tape\n", tjunit);
                return (EIO);
        }
                uprintf("tj%d: can't change density in mid-tape\n", tjunit);
                return (EIO);
        }
-       sc->sc_openf = 1;
        sc->sc_blkno = (daddr_t)0;
        sc->sc_nxrec = INF;
        sc->sc_lastiow = 0;
        sc->sc_blkno = (daddr_t)0;
        sc->sc_nxrec = INF;
        sc->sc_lastiow = 0;
+       sc->sc_blks = 0;
+       sc->sc_softerrs = 0;
        sc->sc_dens = dens;
        sc->sc_ttyp = u.u_ttyp;
        /*
        sc->sc_dens = dens;
        sc->sc_ttyp = u.u_ttyp;
        /*
@@ -199,6 +205,9 @@ utclose(dev, flag)
        }
        if ((minor(dev)&T_NOREWIND) == 0)
                utcommand(dev, UT_REW, 0);
        }
        if ((minor(dev)&T_NOREWIND) == 0)
                utcommand(dev, UT_REW, 0);
+       if (sc->sc_blks > 100 && sc->sc_softerrs > sc->sc_blks / 100)
+               log(LOG_INFO, "tj%d: %d soft errors in %d blocks\n",
+                   TJUNIT(dev), sc->sc_softerrs, sc->sc_blks);
        sc->sc_openf = 0;
 }
 
        sc->sc_openf = 0;
 }
 
@@ -241,6 +250,7 @@ utstrategy(bp)
        int tjunit = TJUNIT(bp->b_dev);
        register struct uba_ctlr *um;
        register struct buf *dp;
        int tjunit = TJUNIT(bp->b_dev);
        register struct uba_ctlr *um;
        register struct buf *dp;
+       int s;
 
        /*
         * Put transfer at end of unit queue
 
        /*
         * Put transfer at end of unit queue
@@ -248,7 +258,7 @@ utstrategy(bp)
        dp = &tjutab[tjunit];
        bp->av_forw = NULL;
        um = tjdinfo[tjunit]->ui_mi;
        dp = &tjutab[tjunit];
        bp->av_forw = NULL;
        um = tjdinfo[tjunit]->ui_mi;
-       (void) spl5();
+       s = spl5();
        if (dp->b_actf == NULL) {
                dp->b_actf = bp;
                /*
        if (dp->b_actf == NULL) {
                dp->b_actf = bp;
                /*
@@ -269,7 +279,7 @@ utstrategy(bp)
         */
        if (um->um_tab.b_state == 0)
                utstart(um);
         */
        if (um->um_tab.b_state == 0)
                utstart(um);
-       (void) spl0();
+       splx(s);
 }
 
 utstart(um)
 }
 
 utstart(um)
@@ -343,25 +353,38 @@ loop:
                goto dobpcmd;
        }
        /*
                goto dobpcmd;
        }
        /*
-        * The following checks boundary conditions for operations
-        * on non-raw tapes.  On raw tapes the initialization of
-        * sc->sc_nxrec by utphys causes them to be skipped normally
-        * (except in the case of retries).
+        * For raw I/O, save the current block
+        * number in case we have to retry.
         */
         */
-       if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
-               /* can't read past end of file */
-               bp->b_flags |= B_ERROR;
-               bp->b_error = ENXIO;
-               goto next;
+       if (bp->b_flags & B_RAW) {
+               if (um->um_tab.b_errcnt == 0) {
+                       sc->sc_blkno = bdbtofsb(bp->b_blkno);
+                       sc->sc_nxrec = sc->sc_blkno + 1;
+               }
        }
        }
-       if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && (bp->b_flags&B_READ)) {
-               /* read at eof returns 0 count */
-               bp->b_resid = bp->b_bcount;
-               clrbuf(bp);
-               goto next;
+       else {
+               /*
+                * Handle boundary cases for operation
+                * on non-raw tapes.
+                */
+               if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
+                       /* can't read past end of file */
+                       bp->b_flags |= B_ERROR;
+                       bp->b_error = ENXIO;
+                       goto next;
+               }
+               if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec &&
+                   (bp->b_flags&B_READ)) {
+                       /*
+                        * Reading at end of file returns 0 bytes.
+                        */
+                       bp->b_resid = bp->b_bcount;
+                       clrbuf(bp);
+                       goto 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;
        /*
         * If the tape is correctly positioned, set up all the
         * registers but the csr, and give control over to the
        /*
         * If the tape is correctly positioned, set up all the
         * registers but the csr, and give control over to the
@@ -509,7 +532,7 @@ utintr(ut11)
                 * was that the record was too long, then we don't consider
                 * this an error.
                 */
                 * was that the record was too long, then we don't consider
                 * this an error.
                 */
-               if (bp == &rutbuf[UTUNIT(bp->b_dev)] && (bp->b_flags&B_READ) &&
+               if ((bp->b_flags & (B_READ|B_RAW)) == (B_READ|B_RAW) &&
                    (sc->sc_erreg&UTER_FCE))
                        sc->sc_erreg &= ~UTER_FCE;
                if (sc->sc_erreg == 0)
                    (sc->sc_erreg&UTER_FCE))
                        sc->sc_erreg &= ~UTER_FCE;
                if (sc->sc_erreg == 0)
@@ -535,7 +558,7 @@ utintr(ut11)
                 * 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 (sc->sc_openf > 0 && bp != &rutbuf[UTUNIT(bp->b_dev)])
+               if ((bp->b_flags&B_RAW) == 0 && sc->sc_openf > 0)
                        sc->sc_openf = -1;
                /*
                 * Couldn't recover error.
                        sc->sc_openf = -1;
                /*
                 * Couldn't recover error.
@@ -582,6 +605,9 @@ ignoreerr:
 
        case SIO:               /* read/write increments tape block # */
                sc->sc_blkno++;
 
        case SIO:               /* read/write increments tape block # */
                sc->sc_blkno++;
+               sc->sc_blks++;
+               if (um->um_tab.b_errcnt)
+                       sc->sc_softerrs++;
                break;
 
        case SCOM:              /* motion commands update current position */
                break;
 
        case SCOM:              /* motion commands update current position */
@@ -681,56 +707,6 @@ uttimer(dev)
        timeout(uttimer, (caddr_t)dev, 5*hz);
 }
 
        timeout(uttimer, (caddr_t)dev, 5*hz);
 }
 
-/*
- * Raw interface for a read
- */
-utread(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       int errno;
-
-       errno = utphys(dev, uio);
-       if (errno)
-               return (errno);
-       return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_READ, minphys, uio));
-}
-
-/*
- * Raw interface for a write
- */
-utwrite(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       int errno;
-
-       errno = utphys(dev, uio);
-       if (errno)
-               return (errno);
-       return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_WRITE, minphys, uio));
-}
-
-/*
- * Check for valid device number dev and update our notion
- * of where we are on the tape
- */
-utphys(dev, uio)
-       dev_t dev;
-       struct uio *uio;
-{
-       register int tjunit = TJUNIT(dev);
-       register struct tj_softc *sc;
-       register struct uba_device *ui;
-
-       if (tjunit >= NTJ || (ui=tjdinfo[tjunit]) == 0 || ui->ui_alive == 0)
-               return (ENXIO);
-       sc = &tj_softc[tjunit];
-       sc->sc_blkno = bdbtofsb(uio->uio_offset>>9);
-       sc->sc_nxrec = sc->sc_blkno+1;
-       return (0);
-}
-
 /*ARGSUSED*/
 utioctl(dev, cmd, data, flag)
        dev_t dev;
 /*ARGSUSED*/
 utioctl(dev, cmd, data, flag)
        dev_t dev;