X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/5722969997a6833f9eb92817b4d35ddfa93ae019..6a476a42bd6303b75aac197c0c148da13c182913:/usr/src/sys/vax/uba/tm.c diff --git a/usr/src/sys/vax/uba/tm.c b/usr/src/sys/vax/uba/tm.c index 7ead61e8ac..0474635af1 100644 --- a/usr/src/sys/vax/uba/tm.c +++ b/usr/src/sys/vax/uba/tm.c @@ -1,6 +1,7 @@ -/* tm.c 4.30 81/03/21 */ +/* tm.c 4.36 81/04/15 */ #include "te.h" +#include "ts.h" #if NTM > 0 /* * TM11/TE10 tape driver @@ -97,6 +98,8 @@ struct te_softc { short sc_lastcmd; /* last command to handle direction changes */ #endif 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]; #ifdef unneeded int tmgapsdcnt; /* DEBUG */ @@ -111,6 +114,15 @@ int tmgapsdcnt; /* DEBUG */ #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 @@ -165,6 +177,9 @@ 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. @@ -172,6 +187,7 @@ tmattach(ui) tetotm[ui->ui_unit] = ui->ui_mi->um_ctlr; } +int tmtimer(); /* * Open the device. Tapes are unique open * devices, so we refuse if it is already open. @@ -221,6 +237,13 @@ get: sc->sc_nxrec = INF; sc->sc_lastiow = 0; sc->sc_dens = dens; + (void) spl6(); + if (sc->sc_tact == 0) { + sc->sc_timo = INF; + sc->sc_tact = 1; + timeout(tmtimer, dev, 5*hz); + } + (void) spl0(); } /* @@ -373,7 +396,7 @@ loop: * Default is that last command was NOT a write command; * if we do a write command we will notice this in tmintr(). */ - sc->sc_lastiow = 1; + sc->sc_lastiow = 0; if (sc->sc_openf < 0 || (addr->tmcs&TM_CUR) == 0) { /* * Have had a hard error on a non-raw tape @@ -389,8 +412,18 @@ loop: */ if (bp->b_command == TM_SENSE) goto next; - um->um_tab.b_active = - bp->b_command == TM_REW ? SREW : SCOM; + /* + * 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. + */ + 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); + } if (bp->b_command == TM_SFORW || bp->b_command == TM_SREV) addr->tmbc = bp->b_repcnt; goto dobpcmd; @@ -446,6 +479,7 @@ loop: tmgapsdcnt++; sc->sc_lastcmd = TM_RCOM; /* will serve */ #endif + sc->sc_timo = 60; /* premature, but should serve */ (void) ubago(ui); return; } @@ -462,6 +496,7 @@ loop: bp->b_command = TM_SREV; addr->tmbc = dbtofsb(bp->b_blkno) - blkno; } + sc->sc_timo = min(max(10 * -addr->tmbc, 60), 5 * 60); dobpcmd: #ifdef notdef /* @@ -528,19 +563,22 @@ tmintr(tm11) bp = dp->b_actf; teunit = TEUNIT(bp->b_dev); addr = (struct device *)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 (addr->tmer&TMER_RWS) + if (addr->tmer&TMER_RWS) { + sc->sc_timo = 5*60; /* 5 minutes */ return; + } } /* * 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_resid = addr->tmbc; @@ -665,6 +703,21 @@ opcont: tmstart(um); } +tmtimer(dev) + int dev; +{ + register struct te_softc *sc = &te_softc[TEUNIT(dev)]; + + if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) { + printf("te%d: lost interrupt\n"); + sc->sc_timo = INF; + (void) spl5(); + tmintr(TMUNIT(dev)); + (void) spl0(); + } + timeout(tmtimer, dev, 5*hz); +} + tmseteof(bp) register struct buf *bp; { @@ -764,7 +817,8 @@ tmreset(uban) else um->um_tab.b_actl->b_forw = dp; um->um_tab.b_actl = dp; - te_softc[teunit].sc_openf = -1; + if (te_softc[teunit].sc_openf > 0) + te_softc[teunit].sc_openf = -1; } tmstart(um); } @@ -833,6 +887,7 @@ tmioctl(dev, cmd, addr, flag) mtget.mt_dsreg = sc->sc_dsreg; mtget.mt_erreg = sc->sc_erreg; mtget.mt_resid = sc->sc_resid; + mtget.mt_type = MT_ISTM; if (copyout((caddr_t)&mtget, addr, sizeof(mtget))) u.u_error = EFAULT; return;