use shorts to move data
[unix-history] / usr / src / sys / vax / mba / ht.c
index 4d2e001..7cd25ba 100644 (file)
@@ -1,4 +1,4 @@
-/*     ht.c    4.11    81/03/09        */
+/*     ht.c    4.22    82/05/12        */
 
 #include "tu.h"
 #if NHT > 0
 
 #include "tu.h"
 #if NHT > 0
@@ -6,14 +6,10 @@
  * TM03/TU?? tape driver
  *
  * TODO:
  * TM03/TU?? tape driver
  *
  * TODO:
- *     test tape writing
- *     test error handling
- *     test 2 tapes
- *     test tape with disk on same mba
- *     test dump code
- *     try a mounted filesys on tape to check positioning code
+ *     cleanup messages on errors
  *     test ioctl's
  *     see how many rewind interrups we get if we kick when not at BOT
  *     test ioctl's
  *     see how many rewind interrups we get if we kick when not at BOT
+ *     fixup rle error on block tape code
  */
 #include "../h/param.h"
 #include "../h/systm.h"
  */
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -37,7 +33,7 @@ struct        buf     rhtbuf[NHT];
 struct buf     chtbuf[NHT];
 
 short  httypes[] =
 struct buf     chtbuf[NHT];
 
 short  httypes[] =
-       { MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
+       { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
 struct mba_device *htinfo[NHT];
 int    htattach(), htslave(), htustart(), htndtint(), htdtint();
 struct mba_driver htdriver =
 struct mba_device *htinfo[NHT];
 int    htattach(), htslave(), htustart(), htndtint(), htdtint();
 struct mba_driver htdriver =
@@ -76,6 +72,9 @@ short tutoht[NTU];
 #define H_ERASED  2    /* last write retry was an erase gap */
 #define H_REWIND  4    /* last unit start was a rewind */
 
 #define H_ERASED  2    /* last write retry was an erase gap */
 #define H_REWIND  4    /* last unit start was a rewind */
 
+char   hter_bits[] = HTER_BITS;
+char   htds_bits[] = HTDS_BITS;
+
 /*ARGSUSED*/
 htattach(mi)
        struct mba_device *mi;
 /*ARGSUSED*/
 htattach(mi)
        struct mba_device *mi;
@@ -88,10 +87,16 @@ htslave(mi, ms)
        struct mba_slave *ms;
 {
        register struct tu_softc *sc = &tu_softc[ms->ms_unit];
        struct mba_slave *ms;
 {
        register struct tu_softc *sc = &tu_softc[ms->ms_unit];
+       register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv;
 
 
-       sc->sc_mi = mi;
-       sc->sc_slave = ms->ms_slave;
-       tutoht[ms->ms_unit] = mi->mi_unit;
+       htaddr->httc = ms->ms_slave;
+       if (htaddr->htdt & HTDT_SPR) {
+               sc->sc_mi = mi;
+               sc->sc_slave = ms->ms_slave;
+               tutoht[ms->ms_unit] = mi->mi_unit;
+               return (1);
+       } else
+               return (0);
 }
 
 htopen(dev, flag)
 }
 
 htopen(dev, flag)
@@ -101,7 +106,7 @@ htopen(dev, flag)
        register int tuunit;
        register struct mba_device *mi;
        register struct tu_softc *sc;
        register int tuunit;
        register struct mba_device *mi;
        register struct tu_softc *sc;
-       int dens;
+       int olddens, dens;
 
        tuunit = TUUNIT(dev);
        if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf ||
 
        tuunit = TUUNIT(dev);
        if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf ||
@@ -109,14 +114,25 @@ htopen(dev, flag)
                u.u_error = ENXIO;
                return;
        }
                u.u_error = ENXIO;
                return;
        }
-       htcommand(dev, HT_SENSE, 1);
-       dens =
+       olddens = sc->sc_dens;
+       dens = sc->sc_dens =
            ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)|
                HTTC_PDP11|sc->sc_slave;
            ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)|
                HTTC_PDP11|sc->sc_slave;
-       if ((sc->sc_dsreg & HTDS_MOL) == 0 || 
-          (sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) &&
-               dens != sc->sc_dens ||
-          (flag & (FREAD|FWRITE)) == FWRITE && sc->sc_dsreg&HTDS_WRL) {
+       htcommand(dev, HT_SENSE, 1);
+       sc->sc_dens = olddens;
+       if ((sc->sc_dsreg & HTDS_MOL) == 0) {
+               uprintf("tu%d: not online\n", tuunit);
+               u.u_error = EIO;
+               return;
+       }
+       if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) {
+               uprintf("tu%d: no write ring\n", tuunit);
+               u.u_error = EIO;
+               return;
+       }
+       if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) &&
+           dens != sc->sc_dens) {
+               uprintf("tu%d: can't change density in mid-tape\n", tuunit);
                u.u_error = EIO;
                return;
        }
                u.u_error = EIO;
                return;
        }
@@ -148,18 +164,18 @@ htcommand(dev, com, count)
        int com, count;
 {
        register struct buf *bp;
        int com, count;
 {
        register struct buf *bp;
+       register int s;
 
        bp = &chtbuf[HTUNIT(dev)];
 
        bp = &chtbuf[HTUNIT(dev)];
-       (void) spl5();
+       s = spl5();
        while (bp->b_flags&B_BUSY) {
        while (bp->b_flags&B_BUSY) {
-               if (bp->b_command == H_REWIND && bp->b_repcnt == 0 &&
-                   (bp->b_flags&B_DONE))
+               if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE))
                        break;
                bp->b_flags |= B_WANTED;
                sleep((caddr_t)bp, PRIBIO);
        }
        bp->b_flags = B_BUSY|B_READ;
                        break;
                bp->b_flags |= B_WANTED;
                sleep((caddr_t)bp, PRIBIO);
        }
        bp->b_flags = B_BUSY|B_READ;
-       (void) spl0();
+       splx(s);
        bp->b_dev = dev;
        bp->b_command = com;
        bp->b_repcnt = count;
        bp->b_dev = dev;
        bp->b_command = com;
        bp->b_repcnt = count;
@@ -178,10 +194,11 @@ htstrategy(bp)
 {
        register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)];
        register struct buf *dp;
 {
        register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)];
        register struct buf *dp;
+       register int s;
 
        bp->av_forw = NULL;
        dp = &mi->mi_tab;
 
        bp->av_forw = NULL;
        dp = &mi->mi_tab;
-       (void) spl5();
+       s = spl5();
        if (dp->b_actf == NULL)
                dp->b_actf = bp;
        else
        if (dp->b_actf == NULL)
                dp->b_actf = bp;
        else
@@ -189,7 +206,7 @@ htstrategy(bp)
        dp->b_actl = bp;
        if (dp->b_active == 0)
                mbustart(mi);
        dp->b_actl = bp;
        if (dp->b_active == 0)
                mbustart(mi);
-       (void) spl0();
+       splx(s);
 }
 
 htustart(mi)
 }
 
 htustart(mi)
@@ -202,6 +219,10 @@ htustart(mi)
        daddr_t blkno;
 
        htaddr->httc = sc->sc_dens;
        daddr_t blkno;
 
        htaddr->httc = sc->sc_dens;
+       if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) {
+               htaddr->htcs1 = HT_SENSE|HT_GO;
+               mbclrattn(mi);
+       }
        sc->sc_dsreg = htaddr->htds;
        sc->sc_erreg = htaddr->hter;
        sc->sc_resid = htaddr->htfc;
        sc->sc_dsreg = htaddr->htds;
        sc->sc_erreg = htaddr->hter;
        sc->sc_resid = htaddr->htfc;
@@ -250,6 +271,7 @@ htustart(mi)
                        }
                        if (htaddr->htds & HTDS_EOT) {
                                bp->b_resid = bp->b_bcount;
                        }
                        if (htaddr->htds & HTDS_EOT) {
                                bp->b_resid = bp->b_bcount;
+                               bp->b_flags |= B_ERROR;
                                return (MBU_NEXT);
                        }
                }
                                return (MBU_NEXT);
                        }
                }
@@ -295,10 +317,16 @@ htdtint(mi, mbsr)
                    er && ++mi->mi_tab.b_errcnt >= 7) {
                        if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0)
                                sc->sc_openf = -1;
                    er && ++mi->mi_tab.b_errcnt >= 7) {
                        if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0)
                                sc->sc_openf = -1;
-                       printf("tu%d: hard error bn%d mbsr=%b er=%b\n",
+                       if ((er&HTER_HARD) == HTER_FCE &&
+                           (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) &&
+                           (ds&HTDS_MOL))
+                               goto noprint;
+                       printf("tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n",
                            TUUNIT(bp->b_dev), bp->b_blkno,
                            mbsr, mbsr_bits,
                            TUUNIT(bp->b_dev), bp->b_blkno,
                            mbsr, mbsr_bits,
-                           MASKREG(htaddr->hter), HTER_BITS);
+                           sc->sc_erreg, hter_bits,
+                           sc->sc_dsreg, htds_bits);
+noprint:
                        bp->b_flags |= B_ERROR;
                        return (MBD_DONE);
                }
                        bp->b_flags |= B_ERROR;
                        return (MBD_DONE);
                }
@@ -358,7 +386,7 @@ htndtint(mi)
                        sc->sc_openf = -1;
                printf("tu%d: hard error bn%d er=%b ds=%b\n",
                    TUUNIT(bp->b_dev), bp->b_blkno,
                        sc->sc_openf = -1;
                printf("tu%d: hard error bn%d er=%b ds=%b\n",
                    TUUNIT(bp->b_dev), bp->b_blkno,
-                   sc->sc_erreg, HTER_BITS, sc->sc_dsreg, HTDS_BITS);
+                   sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits);
                bp->b_flags |= B_ERROR;
                return (MBN_DONE);
        }
                bp->b_flags |= B_ERROR;
                return (MBN_DONE);
        }
@@ -483,6 +511,7 @@ htioctl(dev, cmd, addr, flag)
                mtget.mt_dsreg = sc->sc_dsreg;
                mtget.mt_erreg = sc->sc_erreg;
                mtget.mt_resid = sc->sc_resid;
                mtget.mt_dsreg = sc->sc_dsreg;
                mtget.mt_erreg = sc->sc_erreg;
                mtget.mt_resid = sc->sc_resid;
+               mtget.mt_type = MT_ISHT;
                if (copyout((caddr_t)&mtget, addr, sizeof(mtget)))
                        u.u_error = EFAULT;
                return;
                if (copyout((caddr_t)&mtget, addr, sizeof(mtget)))
                        u.u_error = EFAULT;
                return;
@@ -508,7 +537,7 @@ htdump()
                return (ENXIO);
        mi = phys(htinfo[0], struct mba_device *);
        mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
                return (ENXIO);
        mi = phys(htinfo[0], struct mba_device *);
        mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
-       mbainit(mp);
+       mp->mba_cr = MBCR_IE;
        htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive];
        htaddr->httc = HTTC_PDP11|HTTC_1600BPI;
        htaddr->htcs1 = HT_DCLR|HT_GO;
        htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive];
        htaddr->httc = HTTC_PDP11|HTTC_1600BPI;
        htaddr->htcs1 = HT_DCLR|HT_GO;
@@ -518,10 +547,12 @@ htdump()
                start += blk;
                num -= blk;
        }
                start += blk;
                num -= blk;
        }
-       htwait(htaddr);
-       htaddr->htcs1 = HT_REW|HT_GO;
        hteof(htaddr);
        hteof(htaddr);
        hteof(htaddr);
        hteof(htaddr);
+       htwait(htaddr);
+       if (htaddr->htds&HTDS_ERR)
+               return (EIO);
+       htaddr->htcs1 = HT_REW|HT_GO;
        return (0);
 }
 
        return (0);
 }