1*18325Sralph /* ht.c 6.4 85/03/13 */ 22961Swnj 32980Swnj #include "tu.h" 41563Sbill #if NHT > 0 522Sbill /* 62926Swnj * TM03/TU?? tape driver 73094Swnj * 83094Swnj * TODO: 93204Swnj * cleanup messages on errors 103094Swnj * test ioctl's 113094Swnj * see how many rewind interrups we get if we kick when not at BOT 123204Swnj * fixup rle error on block tape code 1322Sbill */ 149787Ssam #include "../machine/pte.h" 159787Ssam 1617118Sbloom #include "param.h" 1717118Sbloom #include "systm.h" 1817118Sbloom #include "buf.h" 1917118Sbloom #include "conf.h" 2017118Sbloom #include "dir.h" 2117118Sbloom #include "file.h" 2217118Sbloom #include "user.h" 2317118Sbloom #include "map.h" 2417118Sbloom #include "ioctl.h" 2517118Sbloom #include "mtio.h" 2617118Sbloom #include "cmap.h" 2717118Sbloom #include "uio.h" 28*18325Sralph #include "tty.h" 2922Sbill 308469Sroot #include "../vax/cpu.h" 3117118Sbloom #include "mbareg.h" 3217118Sbloom #include "mbavar.h" 3317118Sbloom #include "htreg.h" 3422Sbill 352926Swnj struct buf rhtbuf[NHT]; 362926Swnj struct buf chtbuf[NHT]; 3722Sbill 382926Swnj short httypes[] = 393181Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 402980Swnj struct mba_device *htinfo[NHT]; 413103Swnj int htattach(), htslave(), htustart(), htndtint(), htdtint(); 422926Swnj struct mba_driver htdriver = 432980Swnj { htattach, htslave, htustart, 0, htdtint, htndtint, 442980Swnj httypes, "ht", "tu", htinfo }; 4522Sbill 462926Swnj #define MASKREG(r) ((r) & 0xffff) 4722Sbill 482926Swnj /* bits in minor device */ 492980Swnj #define TUUNIT(dev) (minor(dev)&03) 502926Swnj #define H_NOREWIND 04 512926Swnj #define H_1600BPI 08 5222Sbill 533094Swnj #define HTUNIT(dev) (tutoht[TUUNIT(dev)]) 542980Swnj 552926Swnj #define INF (daddr_t)1000000L /* a block number that wont exist */ 562926Swnj 573094Swnj struct tu_softc { 582926Swnj char sc_openf; 592926Swnj char sc_flags; 602926Swnj daddr_t sc_blkno; 612926Swnj daddr_t sc_nxrec; 622926Swnj u_short sc_erreg; 632926Swnj u_short sc_dsreg; 642926Swnj short sc_resid; 652926Swnj short sc_dens; 662980Swnj struct mba_device *sc_mi; 672980Swnj int sc_slave; 68*18325Sralph struct tty *sc_ttyp; /* record user's tty for errors */ 693094Swnj } tu_softc[NTU]; 703094Swnj short tutoht[NTU]; 712926Swnj 722926Swnj /* 732926Swnj * Bits for sc_flags. 742926Swnj */ 752926Swnj #define H_WRITTEN 1 /* last operation was a write */ 762926Swnj #define H_ERASED 2 /* last write retry was an erase gap */ 772926Swnj #define H_REWIND 4 /* last unit start was a rewind */ 7822Sbill 793204Swnj char hter_bits[] = HTER_BITS; 803204Swnj char htds_bits[] = HTDS_BITS; 813204Swnj 822926Swnj /*ARGSUSED*/ 832980Swnj htattach(mi) 842980Swnj struct mba_device *mi; 852926Swnj { 862926Swnj 872926Swnj } 882926Swnj 897430Skre htslave(mi, ms, sn) 902980Swnj struct mba_device *mi; 912980Swnj struct mba_slave *ms; 927430Skre int sn; 932980Swnj { 943094Swnj register struct tu_softc *sc = &tu_softc[ms->ms_unit]; 954756Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 962980Swnj 977430Skre htaddr->httc = sn; 984756Swnj if (htaddr->htdt & HTDT_SPR) { 994756Swnj sc->sc_mi = mi; 1007430Skre sc->sc_slave = sn; 1014756Swnj tutoht[ms->ms_unit] = mi->mi_unit; 1024756Swnj return (1); 1034756Swnj } else 1044756Swnj return (0); 1052980Swnj } 1062980Swnj 10722Sbill htopen(dev, flag) 1082926Swnj dev_t dev; 1092926Swnj int flag; 11022Sbill { 1113094Swnj register int tuunit; 1122980Swnj register struct mba_device *mi; 1133094Swnj register struct tu_softc *sc; 1143203Swnj int olddens, dens; 11522Sbill 1163094Swnj tuunit = TUUNIT(dev); 1173094Swnj if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf || 1188580Sroot (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) 1198580Sroot return (ENXIO); 1203203Swnj olddens = sc->sc_dens; 1213204Swnj dens = sc->sc_dens = 1223094Swnj ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)| 1233094Swnj HTTC_PDP11|sc->sc_slave; 1243203Swnj htcommand(dev, HT_SENSE, 1); 1253203Swnj sc->sc_dens = olddens; 1263707Sroot if ((sc->sc_dsreg & HTDS_MOL) == 0) { 1273717Sroot uprintf("tu%d: not online\n", tuunit); 1288580Sroot return (EIO); 1292926Swnj } 1303707Sroot if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 1313717Sroot uprintf("tu%d: no write ring\n", tuunit); 1328580Sroot return (EIO); 1333707Sroot } 1343707Sroot if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) && 1353707Sroot dens != sc->sc_dens) { 1363717Sroot uprintf("tu%d: can't change density in mid-tape\n", tuunit); 1378580Sroot return (EIO); 1383707Sroot } 1392926Swnj sc->sc_openf = 1; 1402926Swnj sc->sc_blkno = (daddr_t)0; 1412926Swnj sc->sc_nxrec = INF; 1422926Swnj sc->sc_flags = 0; 1433094Swnj sc->sc_dens = dens; 144*18325Sralph sc->sc_ttyp = u.u_ttyp; 1458580Sroot return (0); 14622Sbill } 14722Sbill 14822Sbill htclose(dev, flag) 1492926Swnj register dev_t dev; 1502926Swnj register flag; 15122Sbill { 1523094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 15322Sbill 1542926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1552926Swnj htcommand(dev, HT_WEOF, 1); 1562926Swnj htcommand(dev, HT_WEOF, 1); 1572926Swnj htcommand(dev, HT_SREV, 1); 15822Sbill } 1592926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1602926Swnj htcommand(dev, HT_REW, 0); 1612926Swnj sc->sc_openf = 0; 16222Sbill } 16322Sbill 1642926Swnj htcommand(dev, com, count) 1652926Swnj dev_t dev; 1662926Swnj int com, count; 16722Sbill { 16822Sbill register struct buf *bp; 1695436Sroot register int s; 17022Sbill 1712926Swnj bp = &chtbuf[HTUNIT(dev)]; 1725436Sroot s = spl5(); 1732926Swnj while (bp->b_flags&B_BUSY) { 1743157Swnj if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 1752980Swnj break; 17622Sbill bp->b_flags |= B_WANTED; 17722Sbill sleep((caddr_t)bp, PRIBIO); 17822Sbill } 1792943Swnj bp->b_flags = B_BUSY|B_READ; 1805436Sroot splx(s); 18122Sbill bp->b_dev = dev; 1822926Swnj bp->b_command = com; 1832926Swnj bp->b_repcnt = count; 18422Sbill bp->b_blkno = 0; 18522Sbill htstrategy(bp); 1862926Swnj if (count == 0) 1872926Swnj return; 18822Sbill iowait(bp); 1892926Swnj if (bp->b_flags&B_WANTED) 19022Sbill wakeup((caddr_t)bp); 1912926Swnj bp->b_flags &= B_ERROR; 19222Sbill } 19322Sbill 19422Sbill htstrategy(bp) 1952926Swnj register struct buf *bp; 19622Sbill { 1973094Swnj register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)]; 1982926Swnj register struct buf *dp; 1995436Sroot register int s; 20022Sbill 20122Sbill bp->av_forw = NULL; 2022926Swnj dp = &mi->mi_tab; 2035436Sroot s = spl5(); 2042926Swnj if (dp->b_actf == NULL) 2052926Swnj dp->b_actf = bp; 20622Sbill else 2072926Swnj dp->b_actl->av_forw = bp; 2082926Swnj dp->b_actl = bp; 2092926Swnj if (dp->b_active == 0) 2102926Swnj mbustart(mi); 2115436Sroot splx(s); 21222Sbill } 21322Sbill 2142926Swnj htustart(mi) 2152980Swnj register struct mba_device *mi; 21622Sbill { 2172926Swnj register struct htdevice *htaddr = 2182926Swnj (struct htdevice *)mi->mi_drv; 2192926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2203094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)]; 22122Sbill daddr_t blkno; 22222Sbill 2232926Swnj htaddr->httc = sc->sc_dens; 22415108Skarels #ifdef notdef 22515108Skarels /* unneeded, may hang controller */ 2263181Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) { 2273157Swnj htaddr->htcs1 = HT_SENSE|HT_GO; 2283157Swnj mbclrattn(mi); 2293157Swnj } 23015108Skarels #endif 2312926Swnj sc->sc_dsreg = htaddr->htds; 2322926Swnj sc->sc_erreg = htaddr->hter; 2332926Swnj sc->sc_resid = htaddr->htfc; 2342926Swnj sc->sc_flags &= ~(H_WRITTEN|H_REWIND); 2352926Swnj if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) 2362926Swnj if (sc->sc_openf > 0) 2372926Swnj sc->sc_openf = -1; 2382926Swnj if (sc->sc_openf < 0) { 2392926Swnj bp->b_flags |= B_ERROR; 2402926Swnj return (MBU_NEXT); 2412926Swnj } 2423094Swnj if (bp != &chtbuf[HTUNIT(bp->b_dev)]) { 2437379Ssam if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 2442926Swnj bp->b_flags |= B_ERROR; 2452926Swnj bp->b_error = ENXIO; 2462961Swnj return (MBU_NEXT); 2473094Swnj } 2487379Ssam if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && 2492926Swnj bp->b_flags&B_READ) { 2502926Swnj bp->b_resid = bp->b_bcount; 2512926Swnj clrbuf(bp); 2522961Swnj return (MBU_NEXT); 2533094Swnj } 2543094Swnj if ((bp->b_flags&B_READ)==0) 2557379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 2562926Swnj } else { 2572961Swnj if (bp->b_command == HT_SENSE) 2582926Swnj return (MBU_NEXT); 2592926Swnj if (bp->b_command == HT_REW) 2602926Swnj sc->sc_flags |= H_REWIND; 2612926Swnj else 2622926Swnj htaddr->htfc = -bp->b_bcount; 2632926Swnj htaddr->htcs1 = bp->b_command|HT_GO; 2642926Swnj return (MBU_STARTED); 2652926Swnj } 2667379Ssam if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 2672926Swnj htaddr->htfc = -bp->b_bcount; 2682926Swnj if ((bp->b_flags&B_READ) == 0) { 2693094Swnj if (mi->mi_tab.b_errcnt) { 2703094Swnj if ((sc->sc_flags & H_ERASED) == 0) { 2712926Swnj sc->sc_flags |= H_ERASED; 2722926Swnj htaddr->htcs1 = HT_ERASE | HT_GO; 2732926Swnj return (MBU_STARTED); 2742926Swnj } 2753094Swnj sc->sc_flags &= ~H_ERASED; 2763094Swnj } 2772926Swnj if (htaddr->htds & HTDS_EOT) { 2782926Swnj bp->b_resid = bp->b_bcount; 2796812Swnj bp->b_flags |= B_ERROR; 2802926Swnj return (MBU_NEXT); 2812926Swnj } 28222Sbill } 2832926Swnj return (MBU_DODATA); 28422Sbill } 2857379Ssam if (blkno < bdbtofsb(bp->b_blkno)) { 2867379Ssam htaddr->htfc = blkno - bdbtofsb(bp->b_blkno); 2872926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 28822Sbill } else { 2897379Ssam htaddr->htfc = bdbtofsb(bp->b_blkno) - blkno; 2902926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 29122Sbill } 2922926Swnj return (MBU_STARTED); 29322Sbill } 29422Sbill 2953094Swnj htdtint(mi, mbsr) 2962980Swnj register struct mba_device *mi; 2973094Swnj int mbsr; 29822Sbill { 2992926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3002926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3013094Swnj register struct tu_softc *sc; 3022961Swnj int ds, er, mbs; 30322Sbill 3043094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3052926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 3062926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 3072926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 3083094Swnj mbs = mbsr; 3092926Swnj sc->sc_blkno++; 3102926Swnj if((bp->b_flags & B_READ) == 0) 3112926Swnj sc->sc_flags |= H_WRITTEN; 3123094Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { 3132926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3142961Swnj mbclrattn(mi); 3152961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 3162926Swnj er &= ~HTER_FCE; 3173094Swnj mbs &= ~(MBSR_DTABT|MBSR_MBEXC); 3184276Sroot } 3192926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 3202926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 3213094Swnj if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || 3222961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 3232926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3242926Swnj sc->sc_openf = -1; 3253157Swnj if ((er&HTER_HARD) == HTER_FCE && 3263157Swnj (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && 3273157Swnj (ds&HTDS_MOL)) 3283157Swnj goto noprint; 329*18325Sralph tprintf(sc->sc_ttyp, "tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", 3302980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3313094Swnj mbsr, mbsr_bits, 3323204Swnj sc->sc_erreg, hter_bits, 3333204Swnj sc->sc_dsreg, htds_bits); 3343157Swnj noprint: 33522Sbill bp->b_flags |= B_ERROR; 3362926Swnj return (MBD_DONE); 33722Sbill } 3382926Swnj if (er) 3392926Swnj return (MBD_RETRY); 34022Sbill } 3412926Swnj bp->b_resid = 0; 3422926Swnj if (bp->b_flags & B_READ) 3432926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 3442926Swnj bp->b_resid = bp->b_bcount; 3457379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno); 3462926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 3472926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 3482926Swnj return (MBD_DONE); 3492926Swnj } 35022Sbill 3512926Swnj htndtint(mi) 3522980Swnj register struct mba_device *mi; 3532926Swnj { 3542926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3552926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3563094Swnj register struct tu_softc *sc; 3572926Swnj int er, ds, fc; 35822Sbill 3593094Swnj ds = MASKREG(htaddr->htds); 3603094Swnj er = MASKREG(htaddr->hter); 3613094Swnj fc = MASKREG(htaddr->htfc); 3623094Swnj if (er) { 3632926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3642961Swnj mbclrattn(mi); 3652961Swnj } 3663094Swnj if (bp == 0) 3673094Swnj return (MBN_SKIP); 3683094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3693094Swnj sc->sc_dsreg = ds; 3703094Swnj sc->sc_erreg = er; 3713094Swnj sc->sc_resid = fc; 3723094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3733094Swnj switch (bp->b_command) { 3743094Swnj case HT_REWOFFL: 3752926Swnj /* offline is on purpose; don't do anything special */ 3762926Swnj ds |= HTDS_MOL; 3773094Swnj break; 3783094Swnj case HT_SREV: 3793094Swnj /* if backspace file hit bot, its not an error */ 3803094Swnj if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && 3813094Swnj bp->b_repcnt == INF) 3823094Swnj er &= ~HTER_NEF; 3833094Swnj break; 3843094Swnj } 3852926Swnj er &= ~HTER_FCE; 3862926Swnj if (er == 0) 3872926Swnj ds &= ~HTDS_ERR; 38822Sbill } 3892926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3902926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3912926Swnj sc->sc_openf = -1; 392*18325Sralph tprintf(sc->sc_ttyp, "tu%d: hard error bn%d er=%b ds=%b\n", 3932980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3943204Swnj sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); 3952926Swnj bp->b_flags |= B_ERROR; 3962926Swnj return (MBN_DONE); 3972926Swnj } 3983094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3992926Swnj if (sc->sc_flags & H_REWIND) 4002926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 4012926Swnj bp->b_resid = -sc->sc_resid; 4022926Swnj return (MBN_DONE); 4032926Swnj } 4042926Swnj if (ds & HTDS_TM) 4057379Ssam if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 4067379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; 4072926Swnj sc->sc_blkno = sc->sc_nxrec; 4083094Swnj } else { 4097379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno) + fc; 4102926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 4112926Swnj } 4122926Swnj else 4137379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno); 4142926Swnj return (MBN_RETRY); 41522Sbill } 41622Sbill 4177739Sroot htread(dev, uio) 4182926Swnj dev_t dev; 4197739Sroot struct uio *uio; 42022Sbill { 4218157Sroot int errno; 4222926Swnj 4238157Sroot errno = htphys(dev, uio); 4248157Sroot if (errno) 4258157Sroot return (errno); 4268157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys, uio)); 42722Sbill } 42822Sbill 4298605Sroot htwrite(dev, uio) 4308605Sroot dev_t dev; 4318688Sroot struct uio *uio; 43222Sbill { 4338157Sroot int errno; 4342926Swnj 4358157Sroot errno = htphys(dev, uio); 4368157Sroot if (errno) 4378157Sroot return (errno); 4388157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys, uio)); 43922Sbill } 44022Sbill 4417739Sroot htphys(dev, uio) 4422926Swnj dev_t dev; 4437739Sroot struct uio *uio; 44422Sbill { 4453094Swnj register int htunit; 4463094Swnj register struct tu_softc *sc; 4473094Swnj register struct mba_device *mi; 44822Sbill daddr_t a; 44922Sbill 4503094Swnj htunit = HTUNIT(dev); 4517832Sroot if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) 4527739Sroot return (ENXIO); 4537832Sroot a = uio->uio_offset >> 9; 4543094Swnj sc = &tu_softc[TUUNIT(dev)]; 4557379Ssam sc->sc_blkno = bdbtofsb(a); 4567379Ssam sc->sc_nxrec = bdbtofsb(a)+1; 4577739Sroot return (0); 45822Sbill } 4591917Swnj 4602926Swnj /*ARGSUSED*/ 4617636Ssam htioctl(dev, cmd, data, flag) 4622926Swnj dev_t dev; 4632926Swnj int cmd; 4647636Ssam caddr_t data; 4652926Swnj int flag; 4662926Swnj { 4673094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 4683094Swnj register struct buf *bp = &chtbuf[HTUNIT(dev)]; 4692926Swnj register callcount; 4702926Swnj int fcount; 4717636Ssam struct mtop *mtop; 4727636Ssam struct mtget *mtget; 4732926Swnj /* we depend of the values and order of the MT codes here */ 4742926Swnj static htops[] = 4752926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4761917Swnj 4772926Swnj switch (cmd) { 4787636Ssam 4797636Ssam case MTIOCTOP: /* tape operation */ 4807636Ssam mtop = (struct mtop *)data; 4817636Ssam switch (mtop->mt_op) { 4827636Ssam 4832926Swnj case MTWEOF: 4847636Ssam callcount = mtop->mt_count; 4852926Swnj fcount = 1; 4862926Swnj break; 4877636Ssam 4882926Swnj case MTFSF: case MTBSF: 4897636Ssam callcount = mtop->mt_count; 4902926Swnj fcount = INF; 4912926Swnj break; 4927636Ssam 4932926Swnj case MTFSR: case MTBSR: 4942926Swnj callcount = 1; 4957636Ssam fcount = mtop->mt_count; 4962926Swnj break; 4977636Ssam 4982926Swnj case MTREW: case MTOFFL: 4992926Swnj callcount = 1; 5002926Swnj fcount = 1; 5012926Swnj break; 5027636Ssam 5032926Swnj default: 5048580Sroot return (ENXIO); 5052926Swnj } 5068580Sroot if (callcount <= 0 || fcount <= 0) 5078580Sroot return (EINVAL); 5082926Swnj while (--callcount >= 0) { 5097636Ssam htcommand(dev, htops[mtop->mt_op], fcount); 5107636Ssam if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 5118580Sroot bp->b_resid) 5128580Sroot return (EIO); 5133094Swnj if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) 5142926Swnj break; 5152926Swnj } 5168711Sroot return (geterror(bp)); 5177636Ssam 5182926Swnj case MTIOCGET: 5197636Ssam mtget = (struct mtget *)data; 5207636Ssam mtget->mt_dsreg = sc->sc_dsreg; 5217636Ssam mtget->mt_erreg = sc->sc_erreg; 5227636Ssam mtget->mt_resid = sc->sc_resid; 5237636Ssam mtget->mt_type = MT_ISHT; 5248580Sroot break; 5257636Ssam 5262926Swnj default: 5278580Sroot return (ENXIO); 5282926Swnj } 5298580Sroot return (0); 5302926Swnj } 5312926Swnj 5321917Swnj #define DBSIZE 20 5331917Swnj 5342926Swnj htdump() 5351917Swnj { 5362980Swnj register struct mba_device *mi; 5372926Swnj register struct mba_regs *mp; 5382926Swnj register struct htdevice *htaddr; 5392926Swnj int blk, num; 5402926Swnj int start; 5411917Swnj 5422926Swnj start = 0; 5432926Swnj num = maxfree; 5442926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 5452926Swnj if (htinfo[0] == 0) 5462926Swnj return (ENXIO); 5472980Swnj mi = phys(htinfo[0], struct mba_device *); 5482926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 5493157Swnj mp->mba_cr = MBCR_IE; 5502926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 5512926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 5522926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 5531917Swnj while (num > 0) { 5541917Swnj blk = num > DBSIZE ? DBSIZE : num; 5552926Swnj htdwrite(start, blk, htaddr, mp); 5562926Swnj start += blk; 5571917Swnj num -= blk; 5581917Swnj } 5593157Swnj hteof(htaddr); 5603157Swnj hteof(htaddr); 5612926Swnj htwait(htaddr); 5623181Swnj if (htaddr->htds&HTDS_ERR) 5633157Swnj return (EIO); 5642926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5653103Swnj return (0); 5661917Swnj } 5671917Swnj 5682926Swnj htdwrite(dbuf, num, htaddr, mp) 5692926Swnj register dbuf, num; 5702926Swnj register struct htdevice *htaddr; 5712926Swnj struct mba_regs *mp; 5721917Swnj { 5732926Swnj register struct pte *io; 5741917Swnj register int i; 5751917Swnj 5762926Swnj htwait(htaddr); 5772926Swnj io = mp->mba_map; 5781917Swnj for (i = 0; i < num; i++) 5792926Swnj *(int *)io++ = dbuf++ | PG_V; 5802926Swnj htaddr->htfc = -(num*NBPG); 5812926Swnj mp->mba_sr = -1; 5822926Swnj mp->mba_bcr = -(num*NBPG); 5832926Swnj mp->mba_var = 0; 5842926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5851917Swnj } 5861917Swnj 5872926Swnj htwait(htaddr) 5882926Swnj struct htdevice *htaddr; 5891917Swnj { 5901917Swnj register s; 5911917Swnj 5921917Swnj do 5932926Swnj s = htaddr->htds; 5942926Swnj while ((s & HTDS_DRY) == 0); 5951917Swnj } 5961917Swnj 5972926Swnj hteof(htaddr) 5982926Swnj struct htdevice *htaddr; 5991917Swnj { 6001917Swnj 6012926Swnj htwait(htaddr); 6022926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 6031917Swnj } 6041563Sbill #endif 605