1*23310Smckusick /* 2*23310Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23310Smckusick * All rights reserved. The Berkeley software License Agreement 4*23310Smckusick * specifies the terms and conditions for redistribution. 5*23310Smckusick * 6*23310Smckusick * @(#)ht.c 6.5 (Berkeley) 06/08/85 7*23310Smckusick */ 82961Swnj 92980Swnj #include "tu.h" 101563Sbill #if NHT > 0 1122Sbill /* 122926Swnj * TM03/TU?? tape driver 133094Swnj * 143094Swnj * TODO: 153204Swnj * cleanup messages on errors 163094Swnj * test ioctl's 173094Swnj * see how many rewind interrups we get if we kick when not at BOT 183204Swnj * fixup rle error on block tape code 1922Sbill */ 209787Ssam #include "../machine/pte.h" 219787Ssam 2217118Sbloom #include "param.h" 2317118Sbloom #include "systm.h" 2417118Sbloom #include "buf.h" 2517118Sbloom #include "conf.h" 2617118Sbloom #include "dir.h" 2717118Sbloom #include "file.h" 2817118Sbloom #include "user.h" 2917118Sbloom #include "map.h" 3017118Sbloom #include "ioctl.h" 3117118Sbloom #include "mtio.h" 3217118Sbloom #include "cmap.h" 3317118Sbloom #include "uio.h" 3418325Sralph #include "tty.h" 3522Sbill 368469Sroot #include "../vax/cpu.h" 3717118Sbloom #include "mbareg.h" 3817118Sbloom #include "mbavar.h" 3917118Sbloom #include "htreg.h" 4022Sbill 412926Swnj struct buf rhtbuf[NHT]; 422926Swnj struct buf chtbuf[NHT]; 4322Sbill 442926Swnj short httypes[] = 453181Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 462980Swnj struct mba_device *htinfo[NHT]; 473103Swnj int htattach(), htslave(), htustart(), htndtint(), htdtint(); 482926Swnj struct mba_driver htdriver = 492980Swnj { htattach, htslave, htustart, 0, htdtint, htndtint, 502980Swnj httypes, "ht", "tu", htinfo }; 5122Sbill 522926Swnj #define MASKREG(r) ((r) & 0xffff) 5322Sbill 542926Swnj /* bits in minor device */ 552980Swnj #define TUUNIT(dev) (minor(dev)&03) 562926Swnj #define H_NOREWIND 04 572926Swnj #define H_1600BPI 08 5822Sbill 593094Swnj #define HTUNIT(dev) (tutoht[TUUNIT(dev)]) 602980Swnj 612926Swnj #define INF (daddr_t)1000000L /* a block number that wont exist */ 622926Swnj 633094Swnj struct tu_softc { 642926Swnj char sc_openf; 652926Swnj char sc_flags; 662926Swnj daddr_t sc_blkno; 672926Swnj daddr_t sc_nxrec; 682926Swnj u_short sc_erreg; 692926Swnj u_short sc_dsreg; 702926Swnj short sc_resid; 712926Swnj short sc_dens; 722980Swnj struct mba_device *sc_mi; 732980Swnj int sc_slave; 7418325Sralph struct tty *sc_ttyp; /* record user's tty for errors */ 753094Swnj } tu_softc[NTU]; 763094Swnj short tutoht[NTU]; 772926Swnj 782926Swnj /* 792926Swnj * Bits for sc_flags. 802926Swnj */ 812926Swnj #define H_WRITTEN 1 /* last operation was a write */ 822926Swnj #define H_ERASED 2 /* last write retry was an erase gap */ 832926Swnj #define H_REWIND 4 /* last unit start was a rewind */ 8422Sbill 853204Swnj char hter_bits[] = HTER_BITS; 863204Swnj char htds_bits[] = HTDS_BITS; 873204Swnj 882926Swnj /*ARGSUSED*/ 892980Swnj htattach(mi) 902980Swnj struct mba_device *mi; 912926Swnj { 922926Swnj 932926Swnj } 942926Swnj 957430Skre htslave(mi, ms, sn) 962980Swnj struct mba_device *mi; 972980Swnj struct mba_slave *ms; 987430Skre int sn; 992980Swnj { 1003094Swnj register struct tu_softc *sc = &tu_softc[ms->ms_unit]; 1014756Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 1022980Swnj 1037430Skre htaddr->httc = sn; 1044756Swnj if (htaddr->htdt & HTDT_SPR) { 1054756Swnj sc->sc_mi = mi; 1067430Skre sc->sc_slave = sn; 1074756Swnj tutoht[ms->ms_unit] = mi->mi_unit; 1084756Swnj return (1); 1094756Swnj } else 1104756Swnj return (0); 1112980Swnj } 1122980Swnj 11322Sbill htopen(dev, flag) 1142926Swnj dev_t dev; 1152926Swnj int flag; 11622Sbill { 1173094Swnj register int tuunit; 1182980Swnj register struct mba_device *mi; 1193094Swnj register struct tu_softc *sc; 1203203Swnj int olddens, dens; 12122Sbill 1223094Swnj tuunit = TUUNIT(dev); 1233094Swnj if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf || 1248580Sroot (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) 1258580Sroot return (ENXIO); 1263203Swnj olddens = sc->sc_dens; 1273204Swnj dens = sc->sc_dens = 1283094Swnj ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)| 1293094Swnj HTTC_PDP11|sc->sc_slave; 1303203Swnj htcommand(dev, HT_SENSE, 1); 1313203Swnj sc->sc_dens = olddens; 1323707Sroot if ((sc->sc_dsreg & HTDS_MOL) == 0) { 1333717Sroot uprintf("tu%d: not online\n", tuunit); 1348580Sroot return (EIO); 1352926Swnj } 1363707Sroot if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 1373717Sroot uprintf("tu%d: no write ring\n", tuunit); 1388580Sroot return (EIO); 1393707Sroot } 1403707Sroot if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) && 1413707Sroot dens != sc->sc_dens) { 1423717Sroot uprintf("tu%d: can't change density in mid-tape\n", tuunit); 1438580Sroot return (EIO); 1443707Sroot } 1452926Swnj sc->sc_openf = 1; 1462926Swnj sc->sc_blkno = (daddr_t)0; 1472926Swnj sc->sc_nxrec = INF; 1482926Swnj sc->sc_flags = 0; 1493094Swnj sc->sc_dens = dens; 15018325Sralph sc->sc_ttyp = u.u_ttyp; 1518580Sroot return (0); 15222Sbill } 15322Sbill 15422Sbill htclose(dev, flag) 1552926Swnj register dev_t dev; 1562926Swnj register flag; 15722Sbill { 1583094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 15922Sbill 1602926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1612926Swnj htcommand(dev, HT_WEOF, 1); 1622926Swnj htcommand(dev, HT_WEOF, 1); 1632926Swnj htcommand(dev, HT_SREV, 1); 16422Sbill } 1652926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1662926Swnj htcommand(dev, HT_REW, 0); 1672926Swnj sc->sc_openf = 0; 16822Sbill } 16922Sbill 1702926Swnj htcommand(dev, com, count) 1712926Swnj dev_t dev; 1722926Swnj int com, count; 17322Sbill { 17422Sbill register struct buf *bp; 1755436Sroot register int s; 17622Sbill 1772926Swnj bp = &chtbuf[HTUNIT(dev)]; 1785436Sroot s = spl5(); 1792926Swnj while (bp->b_flags&B_BUSY) { 1803157Swnj if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 1812980Swnj break; 18222Sbill bp->b_flags |= B_WANTED; 18322Sbill sleep((caddr_t)bp, PRIBIO); 18422Sbill } 1852943Swnj bp->b_flags = B_BUSY|B_READ; 1865436Sroot splx(s); 18722Sbill bp->b_dev = dev; 1882926Swnj bp->b_command = com; 1892926Swnj bp->b_repcnt = count; 19022Sbill bp->b_blkno = 0; 19122Sbill htstrategy(bp); 1922926Swnj if (count == 0) 1932926Swnj return; 19422Sbill iowait(bp); 1952926Swnj if (bp->b_flags&B_WANTED) 19622Sbill wakeup((caddr_t)bp); 1972926Swnj bp->b_flags &= B_ERROR; 19822Sbill } 19922Sbill 20022Sbill htstrategy(bp) 2012926Swnj register struct buf *bp; 20222Sbill { 2033094Swnj register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)]; 2042926Swnj register struct buf *dp; 2055436Sroot register int s; 20622Sbill 20722Sbill bp->av_forw = NULL; 2082926Swnj dp = &mi->mi_tab; 2095436Sroot s = spl5(); 2102926Swnj if (dp->b_actf == NULL) 2112926Swnj dp->b_actf = bp; 21222Sbill else 2132926Swnj dp->b_actl->av_forw = bp; 2142926Swnj dp->b_actl = bp; 2152926Swnj if (dp->b_active == 0) 2162926Swnj mbustart(mi); 2175436Sroot splx(s); 21822Sbill } 21922Sbill 2202926Swnj htustart(mi) 2212980Swnj register struct mba_device *mi; 22222Sbill { 2232926Swnj register struct htdevice *htaddr = 2242926Swnj (struct htdevice *)mi->mi_drv; 2252926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2263094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)]; 22722Sbill daddr_t blkno; 22822Sbill 2292926Swnj htaddr->httc = sc->sc_dens; 23015108Skarels #ifdef notdef 23115108Skarels /* unneeded, may hang controller */ 2323181Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) { 2333157Swnj htaddr->htcs1 = HT_SENSE|HT_GO; 2343157Swnj mbclrattn(mi); 2353157Swnj } 23615108Skarels #endif 2372926Swnj sc->sc_dsreg = htaddr->htds; 2382926Swnj sc->sc_erreg = htaddr->hter; 2392926Swnj sc->sc_resid = htaddr->htfc; 2402926Swnj sc->sc_flags &= ~(H_WRITTEN|H_REWIND); 2412926Swnj if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) 2422926Swnj if (sc->sc_openf > 0) 2432926Swnj sc->sc_openf = -1; 2442926Swnj if (sc->sc_openf < 0) { 2452926Swnj bp->b_flags |= B_ERROR; 2462926Swnj return (MBU_NEXT); 2472926Swnj } 2483094Swnj if (bp != &chtbuf[HTUNIT(bp->b_dev)]) { 2497379Ssam if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 2502926Swnj bp->b_flags |= B_ERROR; 2512926Swnj bp->b_error = ENXIO; 2522961Swnj return (MBU_NEXT); 2533094Swnj } 2547379Ssam if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && 2552926Swnj bp->b_flags&B_READ) { 2562926Swnj bp->b_resid = bp->b_bcount; 2572926Swnj clrbuf(bp); 2582961Swnj return (MBU_NEXT); 2593094Swnj } 2603094Swnj if ((bp->b_flags&B_READ)==0) 2617379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 2622926Swnj } else { 2632961Swnj if (bp->b_command == HT_SENSE) 2642926Swnj return (MBU_NEXT); 2652926Swnj if (bp->b_command == HT_REW) 2662926Swnj sc->sc_flags |= H_REWIND; 2672926Swnj else 2682926Swnj htaddr->htfc = -bp->b_bcount; 2692926Swnj htaddr->htcs1 = bp->b_command|HT_GO; 2702926Swnj return (MBU_STARTED); 2712926Swnj } 2727379Ssam if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 2732926Swnj htaddr->htfc = -bp->b_bcount; 2742926Swnj if ((bp->b_flags&B_READ) == 0) { 2753094Swnj if (mi->mi_tab.b_errcnt) { 2763094Swnj if ((sc->sc_flags & H_ERASED) == 0) { 2772926Swnj sc->sc_flags |= H_ERASED; 2782926Swnj htaddr->htcs1 = HT_ERASE | HT_GO; 2792926Swnj return (MBU_STARTED); 2802926Swnj } 2813094Swnj sc->sc_flags &= ~H_ERASED; 2823094Swnj } 2832926Swnj if (htaddr->htds & HTDS_EOT) { 2842926Swnj bp->b_resid = bp->b_bcount; 2856812Swnj bp->b_flags |= B_ERROR; 2862926Swnj return (MBU_NEXT); 2872926Swnj } 28822Sbill } 2892926Swnj return (MBU_DODATA); 29022Sbill } 2917379Ssam if (blkno < bdbtofsb(bp->b_blkno)) { 2927379Ssam htaddr->htfc = blkno - bdbtofsb(bp->b_blkno); 2932926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 29422Sbill } else { 2957379Ssam htaddr->htfc = bdbtofsb(bp->b_blkno) - blkno; 2962926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 29722Sbill } 2982926Swnj return (MBU_STARTED); 29922Sbill } 30022Sbill 3013094Swnj htdtint(mi, mbsr) 3022980Swnj register struct mba_device *mi; 3033094Swnj int mbsr; 30422Sbill { 3052926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3062926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3073094Swnj register struct tu_softc *sc; 3082961Swnj int ds, er, mbs; 30922Sbill 3103094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3112926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 3122926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 3132926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 3143094Swnj mbs = mbsr; 3152926Swnj sc->sc_blkno++; 3162926Swnj if((bp->b_flags & B_READ) == 0) 3172926Swnj sc->sc_flags |= H_WRITTEN; 3183094Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { 3192926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3202961Swnj mbclrattn(mi); 3212961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 3222926Swnj er &= ~HTER_FCE; 3233094Swnj mbs &= ~(MBSR_DTABT|MBSR_MBEXC); 3244276Sroot } 3252926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 3262926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 3273094Swnj if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || 3282961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 3292926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3302926Swnj sc->sc_openf = -1; 3313157Swnj if ((er&HTER_HARD) == HTER_FCE && 3323157Swnj (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && 3333157Swnj (ds&HTDS_MOL)) 3343157Swnj goto noprint; 33518325Sralph tprintf(sc->sc_ttyp, "tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", 3362980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3373094Swnj mbsr, mbsr_bits, 3383204Swnj sc->sc_erreg, hter_bits, 3393204Swnj sc->sc_dsreg, htds_bits); 3403157Swnj noprint: 34122Sbill bp->b_flags |= B_ERROR; 3422926Swnj return (MBD_DONE); 34322Sbill } 3442926Swnj if (er) 3452926Swnj return (MBD_RETRY); 34622Sbill } 3472926Swnj bp->b_resid = 0; 3482926Swnj if (bp->b_flags & B_READ) 3492926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 3502926Swnj bp->b_resid = bp->b_bcount; 3517379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno); 3522926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 3532926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 3542926Swnj return (MBD_DONE); 3552926Swnj } 35622Sbill 3572926Swnj htndtint(mi) 3582980Swnj register struct mba_device *mi; 3592926Swnj { 3602926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3612926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3623094Swnj register struct tu_softc *sc; 3632926Swnj int er, ds, fc; 36422Sbill 3653094Swnj ds = MASKREG(htaddr->htds); 3663094Swnj er = MASKREG(htaddr->hter); 3673094Swnj fc = MASKREG(htaddr->htfc); 3683094Swnj if (er) { 3692926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3702961Swnj mbclrattn(mi); 3712961Swnj } 3723094Swnj if (bp == 0) 3733094Swnj return (MBN_SKIP); 3743094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3753094Swnj sc->sc_dsreg = ds; 3763094Swnj sc->sc_erreg = er; 3773094Swnj sc->sc_resid = fc; 3783094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3793094Swnj switch (bp->b_command) { 3803094Swnj case HT_REWOFFL: 3812926Swnj /* offline is on purpose; don't do anything special */ 3822926Swnj ds |= HTDS_MOL; 3833094Swnj break; 3843094Swnj case HT_SREV: 3853094Swnj /* if backspace file hit bot, its not an error */ 3863094Swnj if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && 3873094Swnj bp->b_repcnt == INF) 3883094Swnj er &= ~HTER_NEF; 3893094Swnj break; 3903094Swnj } 3912926Swnj er &= ~HTER_FCE; 3922926Swnj if (er == 0) 3932926Swnj ds &= ~HTDS_ERR; 39422Sbill } 3952926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3962926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3972926Swnj sc->sc_openf = -1; 39818325Sralph tprintf(sc->sc_ttyp, "tu%d: hard error bn%d er=%b ds=%b\n", 3992980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 4003204Swnj sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); 4012926Swnj bp->b_flags |= B_ERROR; 4022926Swnj return (MBN_DONE); 4032926Swnj } 4043094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 4052926Swnj if (sc->sc_flags & H_REWIND) 4062926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 4072926Swnj bp->b_resid = -sc->sc_resid; 4082926Swnj return (MBN_DONE); 4092926Swnj } 4102926Swnj if (ds & HTDS_TM) 4117379Ssam if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 4127379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; 4132926Swnj sc->sc_blkno = sc->sc_nxrec; 4143094Swnj } else { 4157379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno) + fc; 4162926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 4172926Swnj } 4182926Swnj else 4197379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno); 4202926Swnj return (MBN_RETRY); 42122Sbill } 42222Sbill 4237739Sroot htread(dev, uio) 4242926Swnj dev_t dev; 4257739Sroot struct uio *uio; 42622Sbill { 4278157Sroot int errno; 4282926Swnj 4298157Sroot errno = htphys(dev, uio); 4308157Sroot if (errno) 4318157Sroot return (errno); 4328157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys, uio)); 43322Sbill } 43422Sbill 4358605Sroot htwrite(dev, uio) 4368605Sroot dev_t dev; 4378688Sroot struct uio *uio; 43822Sbill { 4398157Sroot int errno; 4402926Swnj 4418157Sroot errno = htphys(dev, uio); 4428157Sroot if (errno) 4438157Sroot return (errno); 4448157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys, uio)); 44522Sbill } 44622Sbill 4477739Sroot htphys(dev, uio) 4482926Swnj dev_t dev; 4497739Sroot struct uio *uio; 45022Sbill { 4513094Swnj register int htunit; 4523094Swnj register struct tu_softc *sc; 4533094Swnj register struct mba_device *mi; 45422Sbill daddr_t a; 45522Sbill 4563094Swnj htunit = HTUNIT(dev); 4577832Sroot if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) 4587739Sroot return (ENXIO); 4597832Sroot a = uio->uio_offset >> 9; 4603094Swnj sc = &tu_softc[TUUNIT(dev)]; 4617379Ssam sc->sc_blkno = bdbtofsb(a); 4627379Ssam sc->sc_nxrec = bdbtofsb(a)+1; 4637739Sroot return (0); 46422Sbill } 4651917Swnj 4662926Swnj /*ARGSUSED*/ 4677636Ssam htioctl(dev, cmd, data, flag) 4682926Swnj dev_t dev; 4692926Swnj int cmd; 4707636Ssam caddr_t data; 4712926Swnj int flag; 4722926Swnj { 4733094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 4743094Swnj register struct buf *bp = &chtbuf[HTUNIT(dev)]; 4752926Swnj register callcount; 4762926Swnj int fcount; 4777636Ssam struct mtop *mtop; 4787636Ssam struct mtget *mtget; 4792926Swnj /* we depend of the values and order of the MT codes here */ 4802926Swnj static htops[] = 4812926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4821917Swnj 4832926Swnj switch (cmd) { 4847636Ssam 4857636Ssam case MTIOCTOP: /* tape operation */ 4867636Ssam mtop = (struct mtop *)data; 4877636Ssam switch (mtop->mt_op) { 4887636Ssam 4892926Swnj case MTWEOF: 4907636Ssam callcount = mtop->mt_count; 4912926Swnj fcount = 1; 4922926Swnj break; 4937636Ssam 4942926Swnj case MTFSF: case MTBSF: 4957636Ssam callcount = mtop->mt_count; 4962926Swnj fcount = INF; 4972926Swnj break; 4987636Ssam 4992926Swnj case MTFSR: case MTBSR: 5002926Swnj callcount = 1; 5017636Ssam fcount = mtop->mt_count; 5022926Swnj break; 5037636Ssam 5042926Swnj case MTREW: case MTOFFL: 5052926Swnj callcount = 1; 5062926Swnj fcount = 1; 5072926Swnj break; 5087636Ssam 5092926Swnj default: 5108580Sroot return (ENXIO); 5112926Swnj } 5128580Sroot if (callcount <= 0 || fcount <= 0) 5138580Sroot return (EINVAL); 5142926Swnj while (--callcount >= 0) { 5157636Ssam htcommand(dev, htops[mtop->mt_op], fcount); 5167636Ssam if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 5178580Sroot bp->b_resid) 5188580Sroot return (EIO); 5193094Swnj if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) 5202926Swnj break; 5212926Swnj } 5228711Sroot return (geterror(bp)); 5237636Ssam 5242926Swnj case MTIOCGET: 5257636Ssam mtget = (struct mtget *)data; 5267636Ssam mtget->mt_dsreg = sc->sc_dsreg; 5277636Ssam mtget->mt_erreg = sc->sc_erreg; 5287636Ssam mtget->mt_resid = sc->sc_resid; 5297636Ssam mtget->mt_type = MT_ISHT; 5308580Sroot break; 5317636Ssam 5322926Swnj default: 5338580Sroot return (ENXIO); 5342926Swnj } 5358580Sroot return (0); 5362926Swnj } 5372926Swnj 5381917Swnj #define DBSIZE 20 5391917Swnj 5402926Swnj htdump() 5411917Swnj { 5422980Swnj register struct mba_device *mi; 5432926Swnj register struct mba_regs *mp; 5442926Swnj register struct htdevice *htaddr; 5452926Swnj int blk, num; 5462926Swnj int start; 5471917Swnj 5482926Swnj start = 0; 5492926Swnj num = maxfree; 5502926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 5512926Swnj if (htinfo[0] == 0) 5522926Swnj return (ENXIO); 5532980Swnj mi = phys(htinfo[0], struct mba_device *); 5542926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 5553157Swnj mp->mba_cr = MBCR_IE; 5562926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 5572926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 5582926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 5591917Swnj while (num > 0) { 5601917Swnj blk = num > DBSIZE ? DBSIZE : num; 5612926Swnj htdwrite(start, blk, htaddr, mp); 5622926Swnj start += blk; 5631917Swnj num -= blk; 5641917Swnj } 5653157Swnj hteof(htaddr); 5663157Swnj hteof(htaddr); 5672926Swnj htwait(htaddr); 5683181Swnj if (htaddr->htds&HTDS_ERR) 5693157Swnj return (EIO); 5702926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5713103Swnj return (0); 5721917Swnj } 5731917Swnj 5742926Swnj htdwrite(dbuf, num, htaddr, mp) 5752926Swnj register dbuf, num; 5762926Swnj register struct htdevice *htaddr; 5772926Swnj struct mba_regs *mp; 5781917Swnj { 5792926Swnj register struct pte *io; 5801917Swnj register int i; 5811917Swnj 5822926Swnj htwait(htaddr); 5832926Swnj io = mp->mba_map; 5841917Swnj for (i = 0; i < num; i++) 5852926Swnj *(int *)io++ = dbuf++ | PG_V; 5862926Swnj htaddr->htfc = -(num*NBPG); 5872926Swnj mp->mba_sr = -1; 5882926Swnj mp->mba_bcr = -(num*NBPG); 5892926Swnj mp->mba_var = 0; 5902926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5911917Swnj } 5921917Swnj 5932926Swnj htwait(htaddr) 5942926Swnj struct htdevice *htaddr; 5951917Swnj { 5961917Swnj register s; 5971917Swnj 5981917Swnj do 5992926Swnj s = htaddr->htds; 6002926Swnj while ((s & HTDS_DRY) == 0); 6011917Swnj } 6021917Swnj 6032926Swnj hteof(htaddr) 6042926Swnj struct htdevice *htaddr; 6051917Swnj { 6061917Swnj 6072926Swnj htwait(htaddr); 6082926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 6091917Swnj } 6101563Sbill #endif 611