fix to reeves fix of dgo handling (reset b_active to 1)
[unix-history] / usr / src / sys / vax / uba / tm.c
index 50d9557..ec16ede 100644 (file)
@@ -1,8 +1,8 @@
-/*     tm.c    4.35    81/04/14        */
+/*     tm.c    4.48    82/05/27        */
 
 #include "te.h"
 #include "ts.h"
 
 #include "te.h"
 #include "ts.h"
-#if NTM > 0
+#if NTE > 0
 /*
  * TM11/TE10 tape driver
  *
 /*
  * TM11/TE10 tape driver
  *
@@ -100,7 +100,7 @@ struct      te_softc {
        u_short sc_dens;        /* prototype command with density info */
        daddr_t sc_timo;        /* time until timeout expires */
        short   sc_tact;        /* timeout is active */
        u_short sc_dens;        /* prototype command with density info */
        daddr_t sc_timo;        /* time until timeout expires */
        short   sc_tact;        /* timeout is active */
-} te_softc[NTM];
+} te_softc[NTE];
 #ifdef unneeded
 int    tmgapsdcnt;             /* DEBUG */
 #endif
 #ifdef unneeded
 int    tmgapsdcnt;             /* DEBUG */
 #endif
@@ -114,15 +114,6 @@ int        tmgapsdcnt;             /* DEBUG */
 #define        SCOM    3               /* sending control command */
 #define        SREW    4               /* sending a drive rewind */
 
 #define        SCOM    3               /* sending control command */
 #define        SREW    4               /* sending a drive rewind */
 
-#if NTS > 0
-/*
- * Kludge to get around fact that we don't really
- * check if a ts is there... if there are both tm's and ts's
- * declared in the system, then this driver sets havetm to 1
- * if it finds a tm, and ts just pretends there isn't a ts.
- */
-int    havetm = 0;
-#endif
 /*
  * Determine if there is a controller for
  * a tm at address reg.  Our goal is to make the
 /*
  * Determine if there is a controller for
  * a tm at address reg.  Our goal is to make the
@@ -135,8 +126,9 @@ tmprobe(reg)
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
 
 #ifdef lint
        br = 0; cvec = br; br = cvec;
+       tmintr(0);
 #endif
 #endif
-       ((struct device *)reg)->tmcs = TM_IE;
+       ((struct tmdevice *)reg)->tmcs = TM_IE;
        /*
         * If this is a tm11, it ought to have interrupted
         * by now, if it isn't (ie: it is a ts04) then we just
        /*
         * If this is a tm11, it ought to have interrupted
         * by now, if it isn't (ie: it is a ts04) then we just
@@ -149,7 +141,7 @@ tmprobe(reg)
         * a uba error for a ts; but our caller will notice that
         * so we won't check for it.
         */
         * a uba error for a ts; but our caller will notice that
         * so we won't check for it.
         */
-       if (badaddr((caddr_t)&((struct device *)reg)->tmrd, 2))
+       if (badaddr((caddr_t)&((struct tmdevice *)reg)->tmrd, 2))
                return (0);
        return (1);
 }
                return (0);
        return (1);
 }
@@ -176,10 +168,6 @@ tmslave(ui, reg)
 tmattach(ui)
        struct uba_device *ui;
 {
 tmattach(ui)
        struct uba_device *ui;
 {
-
-#if NTS > 0
-       havetm = 1;
-#endif
        /*
         * Tetotm is used in TMUNIT to index the ctmbuf and rtmbuf
         * arrays given a te unit number.
        /*
         * Tetotm is used in TMUNIT to index the ctmbuf and rtmbuf
         * arrays given a te unit number.
@@ -203,6 +191,7 @@ tmopen(dev, flag)
        register struct uba_device *ui;
        register struct te_softc *sc;
        int olddens, dens;
        register struct uba_device *ui;
        register struct te_softc *sc;
        int olddens, dens;
+       int s;
 
        teunit = TEUNIT(dev);
        if (teunit>=NTE || (sc = &te_softc[teunit])->sc_openf ||
 
        teunit = TEUNIT(dev);
        if (teunit>=NTE || (sc = &te_softc[teunit])->sc_openf ||
@@ -222,13 +211,19 @@ get:
                goto get;
        }
        sc->sc_dens = olddens;
                goto get;
        }
        sc->sc_dens = olddens;
-       if ((sc->sc_erreg&(TMER_SELR|TMER_TUR)) != (TMER_SELR|TMER_TUR) ||
-           (flag&FWRITE) && (sc->sc_erreg&TMER_WRL) ||
-           (sc->sc_erreg&TMER_BOT) == 0 && (flag&FWRITE) &&
-               dens != sc->sc_dens) {
-               /*
-                * Not online or density switch in mid-tape or write locked.
-                */
+       if ((sc->sc_erreg&(TMER_SELR|TMER_TUR)) != (TMER_SELR|TMER_TUR)) {
+               uprintf("te%d: not online\n", teunit);
+               u.u_error = EIO;
+               return;
+       }
+       if ((flag&FWRITE) && (sc->sc_erreg&TMER_WRL)) {
+               uprintf("te%d: no write ring\n", teunit);
+               u.u_error = EIO;
+               return;
+       }
+       if ((sc->sc_erreg&TMER_BOT) == 0 && (flag&FWRITE) &&
+           dens != sc->sc_dens) {
+               uprintf("te%d: can't change density in mid-tape\n", teunit);
                u.u_error = EIO;
                return;
        }
                u.u_error = EIO;
                return;
        }
@@ -237,13 +232,13 @@ get:
        sc->sc_nxrec = INF;
        sc->sc_lastiow = 0;
        sc->sc_dens = dens;
        sc->sc_nxrec = INF;
        sc->sc_lastiow = 0;
        sc->sc_dens = dens;
-       (void) spl6();
+       s = spl6();
        if (sc->sc_tact == 0) {
                sc->sc_timo = INF;
                sc->sc_tact = 1;
        if (sc->sc_tact == 0) {
                sc->sc_timo = INF;
                sc->sc_tact = 1;
-               timeout(tmtimer, dev, 5*hz);
+               timeout(tmtimer, (caddr_t)dev, 5*hz);
        }
        }
-       (void) spl0();
+       splx(s);
 }
 
 /*
 }
 
 /*
@@ -285,9 +280,10 @@ tmcommand(dev, com, count)
        int com, count;
 {
        register struct buf *bp;
        int com, count;
 {
        register struct buf *bp;
+       register int s;
 
        bp = &ctmbuf[TMUNIT(dev)];
 
        bp = &ctmbuf[TMUNIT(dev)];
-       (void) spl5();
+       s = spl5();
        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
@@ -299,7 +295,7 @@ tmcommand(dev, com, count)
                sleep((caddr_t)bp, PRIBIO);
        }
        bp->b_flags = B_BUSY|B_READ;
                sleep((caddr_t)bp, PRIBIO);
        }
        bp->b_flags = B_BUSY|B_READ;
-       (void) spl0();
+       splx(s);
        bp->b_dev = dev;
        bp->b_repcnt = -count;
        bp->b_command = com;
        bp->b_dev = dev;
        bp->b_repcnt = -count;
        bp->b_command = com;
@@ -326,13 +322,15 @@ tmstrategy(bp)
        int teunit = TEUNIT(bp->b_dev);
        register struct uba_ctlr *um;
        register struct buf *dp;
        int teunit = TEUNIT(bp->b_dev);
        register struct uba_ctlr *um;
        register struct buf *dp;
+       int s;
 
        /*
         * Put transfer at end of unit queue
         */
        dp = &teutab[teunit];
        bp->av_forw = NULL;
 
        /*
         * Put transfer at end of unit queue
         */
        dp = &teutab[teunit];
        bp->av_forw = NULL;
-       (void) spl5();
+       s = spl5();
+       um = tedinfo[teunit]->ui_mi;
        if (dp->b_actf == NULL) {
                dp->b_actf = bp;
                /*
        if (dp->b_actf == NULL) {
                dp->b_actf = bp;
                /*
@@ -340,7 +338,6 @@ tmstrategy(bp)
                 * put at end of controller queue.
                 */
                dp->b_forw = NULL;
                 * put at end of controller queue.
                 */
                dp->b_forw = NULL;
-               um = tedinfo[teunit]->ui_mi;
                if (um->um_tab.b_actf == NULL)
                        um->um_tab.b_actf = dp;
                else
                if (um->um_tab.b_actf == NULL)
                        um->um_tab.b_actf = dp;
                else
@@ -355,7 +352,7 @@ tmstrategy(bp)
         */
        if (um->um_tab.b_active == 0)
                tmstart(um);
         */
        if (um->um_tab.b_active == 0)
                tmstart(um);
-       (void) spl0();
+       splx(s);
 }
 
 /*
 }
 
 /*
@@ -365,7 +362,7 @@ tmstart(um)
        register struct uba_ctlr *um;
 {
        register struct buf *bp, *dp;
        register struct uba_ctlr *um;
 {
        register struct buf *bp, *dp;
-       register struct device *addr = (struct device *)um->um_addr;
+       register struct tmdevice *addr = (struct tmdevice *)um->um_addr;
        register struct te_softc *sc;
        register struct uba_device *ui;
        int teunit, cmd;
        register struct te_softc *sc;
        register struct uba_device *ui;
        int teunit, cmd;
@@ -387,7 +384,7 @@ loop:
         * Record pre-transfer status (e.g. for TM_SENSE)
         */
        sc = &te_softc[teunit];
         * Record pre-transfer status (e.g. for TM_SENSE)
         */
        sc = &te_softc[teunit];
-       addr = (struct device *)um->um_addr;
+       addr = (struct tmdevice *)um->um_addr;
        addr->tmcs = (ui->ui_slave << 8);
        sc->sc_dsreg = addr->tmcs;
        sc->sc_erreg = addr->tmer;
        addr->tmcs = (ui->ui_slave << 8);
        sc->sc_dsreg = addr->tmcs;
        sc->sc_erreg = addr->tmer;
@@ -415,14 +412,15 @@ loop:
                /*
                 * Set next state; give 5 minutes to complete
                 * rewind, or 10 seconds per iteration (minimum 60
                /*
                 * Set next state; give 5 minutes to complete
                 * rewind, or 10 seconds per iteration (minimum 60
-                * seconds and max 5 minute) to complete other ops.
+                * seconds and max 5 minutes) to complete other ops.
                 */
                if (bp->b_command == TM_REW) {
                        um->um_tab.b_active = SREW;
                        sc->sc_timo = 5 * 60;
                } else {
                        um->um_tab.b_active = SCOM;
                 */
                if (bp->b_command == TM_REW) {
                        um->um_tab.b_active = SREW;
                        sc->sc_timo = 5 * 60;
                } else {
                        um->um_tab.b_active = SCOM;
-                       sc->sc_timo = min(max(10 * bp->b_repcnt, 60), 5 * 60);
+                       sc->sc_timo =
+                           imin(imax(10*(int)-bp->b_repcnt,60),5*60);
                }
                if (bp->b_command == TM_SFORW || bp->b_command == TM_SREV)
                        addr->tmbc = bp->b_repcnt;
                }
                if (bp->b_command == TM_SFORW || bp->b_command == TM_SREV)
                        addr->tmbc = bp->b_repcnt;
@@ -496,7 +494,7 @@ loop:
                bp->b_command = TM_SREV;
                addr->tmbc = dbtofsb(bp->b_blkno) - blkno;
        }
                bp->b_command = TM_SREV;
                addr->tmbc = dbtofsb(bp->b_blkno) - blkno;
        }
-       sc->sc_timo = min(max(10 * -addr->tmbc, 60), 5 * 60);
+       sc->sc_timo = imin(imax(10 * -addr->tmbc, 60), 5 * 60);
 dobpcmd:
 #ifdef notdef
        /*
 dobpcmd:
 #ifdef notdef
        /*
@@ -537,7 +535,7 @@ next:
 tmdgo(um)
        register struct uba_ctlr *um;
 {
 tmdgo(um)
        register struct uba_ctlr *um;
 {
-       register struct device *addr = (struct device *)um->um_addr;
+       register struct tmdevice *addr = (struct tmdevice *)um->um_addr;
 
        addr->tmba = um->um_ubinfo;
        addr->tmcs = um->um_cmd | ((um->um_ubinfo >> 12) & 0x30);
 
        addr->tmba = um->um_ubinfo;
        addr->tmcs = um->um_cmd | ((um->um_ubinfo >> 12) & 0x30);
@@ -553,7 +551,7 @@ tmintr(tm11)
        struct buf *dp;
        register struct buf *bp;
        register struct uba_ctlr *um = tmminfo[tm11];
        struct buf *dp;
        register struct buf *bp;
        register struct uba_ctlr *um = tmminfo[tm11];
-       register struct device *addr;
+       register struct tmdevice *addr;
        register struct te_softc *sc;
        int teunit;
        register state;
        register struct te_softc *sc;
        int teunit;
        register state;
@@ -562,20 +560,22 @@ tmintr(tm11)
                return;
        bp = dp->b_actf;
        teunit = TEUNIT(bp->b_dev);
                return;
        bp = dp->b_actf;
        teunit = TEUNIT(bp->b_dev);
-       addr = (struct device *)tedinfo[teunit]->ui_addr;
+       addr = (struct tmdevice *)tedinfo[teunit]->ui_addr;
+       sc = &te_softc[teunit];
        /*
         * If last command was a rewind, and tape is still
         * rewinding, wait for the rewind complete interrupt.
         */
        if (um->um_tab.b_active == SREW) {
                um->um_tab.b_active = SCOM;
        /*
         * If last command was a rewind, and tape is still
         * rewinding, wait for the rewind complete interrupt.
         */
        if (um->um_tab.b_active == SREW) {
                um->um_tab.b_active = SCOM;
-               if (addr->tmer&TMER_RWS)
+               if (addr->tmer&TMER_RWS) {
+                       sc->sc_timo = 5*60;             /* 5 minutes */
                        return;
                        return;
+               }
        }
        /*
         * An operation completed... record status
         */
        }
        /*
         * An operation completed... record status
         */
-       sc = &te_softc[teunit];
        sc->sc_timo = INF;
        sc->sc_dsreg = addr->tmcs;
        sc->sc_erreg = addr->tmer;
        sc->sc_timo = INF;
        sc->sc_dsreg = addr->tmcs;
        sc->sc_erreg = addr->tmer;
@@ -705,23 +705,24 @@ tmtimer(dev)
        int dev;
 {
        register struct te_softc *sc = &te_softc[TEUNIT(dev)];
        int dev;
 {
        register struct te_softc *sc = &te_softc[TEUNIT(dev)];
+       register short x;
 
        if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) {
 
        if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) {
-               printf("te%d: lost interrupt\n");
+               printf("te%d: lost interrupt\n", TEUNIT(dev));
                sc->sc_timo = INF;
                sc->sc_timo = INF;
-               (void) spl5();
+               x = spl5();
                tmintr(TMUNIT(dev));
                tmintr(TMUNIT(dev));
-               (void) spl0();
+               (void) splx(x);
        }
        }
-       timeout(tmtimer, dev, 5*hz);
+       timeout(tmtimer, (caddr_t)dev, 5*hz);
 }
 
 tmseteof(bp)
        register struct buf *bp;
 {
        register int teunit = TEUNIT(bp->b_dev);
 }
 
 tmseteof(bp)
        register struct buf *bp;
 {
        register int teunit = TEUNIT(bp->b_dev);
-       register struct device *addr = 
-           (struct device *)tedinfo[teunit]->ui_addr;
+       register struct tmdevice *addr = 
+           (struct tmdevice *)tedinfo[teunit]->ui_addr;
        register struct te_softc *sc = &te_softc[teunit];
 
        if (bp == &ctmbuf[TMUNIT(bp->b_dev)]) {
        register struct te_softc *sc = &te_softc[teunit];
 
        if (bp == &ctmbuf[TMUNIT(bp->b_dev)]) {
@@ -802,7 +803,7 @@ tmreset(uban)
                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                        ubadone(um);
                }
                        printf("<%d>", (um->um_ubinfo>>28)&0xf);
                        ubadone(um);
                }
-               ((struct device *)(um->um_addr))->tmcs = TM_DCLR;
+               ((struct tmdevice *)(um->um_addr))->tmcs = TM_DCLR;
                for (teunit = 0; teunit < NTE; teunit++) {
                        if ((ui = tedinfo[teunit]) == 0 || ui->ui_mi != um ||
                            ui->ui_alive == 0)
                for (teunit = 0; teunit < NTE; teunit++) {
                        if ((ui = tedinfo[teunit]) == 0 || ui->ui_mi != um ||
                            ui->ui_alive == 0)
@@ -900,7 +901,7 @@ tmdump()
 {
        register struct uba_device *ui;
        register struct uba_regs *up;
 {
        register struct uba_device *ui;
        register struct uba_regs *up;
-       register struct device *addr;
+       register struct tmdevice *addr;
        int blk, num;
        int start;
 
        int blk, num;
        int start;
 
@@ -913,7 +914,7 @@ tmdump()
        up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
        ubainit(up);
        DELAY(1000000);
        up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
        ubainit(up);
        DELAY(1000000);
-       addr = (struct device *)ui->ui_physaddr;
+       addr = (struct tmdevice *)ui->ui_physaddr;
        tmwait(addr);
        addr->tmcs = TM_DCLR | TM_GO;
        while (num > 0) {
        tmwait(addr);
        addr->tmcs = TM_DCLR | TM_GO;
        while (num > 0) {
@@ -934,7 +935,7 @@ tmdump()
 
 tmdwrite(dbuf, num, addr, up)
        register dbuf, num;
 
 tmdwrite(dbuf, num, addr, up)
        register dbuf, num;
-       register struct device *addr;
+       register struct tmdevice *addr;
        struct uba_regs *up;
 {
        register struct pte *io;
        struct uba_regs *up;
 {
        register struct pte *io;
@@ -952,7 +953,7 @@ tmdwrite(dbuf, num, addr, up)
 }
 
 tmwait(addr)
 }
 
 tmwait(addr)
-       register struct device *addr;
+       register struct tmdevice *addr;
 {
        register s;
 
 {
        register s;
 
@@ -962,7 +963,7 @@ tmwait(addr)
 }
 
 tmeof(addr)
 }
 
 tmeof(addr)
-       struct device *addr;
+       struct tmdevice *addr;
 {
 
        tmwait(addr);
 {
 
        tmwait(addr);