1*7636Ssam /* ht.c 4.25 82/08/01 */ 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 */ 1422Sbill #include "../h/param.h" 1522Sbill #include "../h/systm.h" 1622Sbill #include "../h/buf.h" 1722Sbill #include "../h/conf.h" 1822Sbill #include "../h/dir.h" 1922Sbill #include "../h/file.h" 2022Sbill #include "../h/user.h" 2122Sbill #include "../h/map.h" 22420Sbill #include "../h/pte.h" 232980Swnj #include "../h/mbareg.h" 242980Swnj #include "../h/mbavar.h" 25*7636Ssam #include "../h/ioctl.h" 262926Swnj #include "../h/mtio.h" 271917Swnj #include "../h/cmap.h" 282961Swnj #include "../h/cpu.h" 2922Sbill 302926Swnj #include "../h/htreg.h" 3122Sbill 322926Swnj struct buf rhtbuf[NHT]; 332926Swnj struct buf chtbuf[NHT]; 3422Sbill 352926Swnj short httypes[] = 363181Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 372980Swnj struct mba_device *htinfo[NHT]; 383103Swnj int htattach(), htslave(), htustart(), htndtint(), htdtint(); 392926Swnj struct mba_driver htdriver = 402980Swnj { htattach, htslave, htustart, 0, htdtint, htndtint, 412980Swnj httypes, "ht", "tu", htinfo }; 4222Sbill 432926Swnj #define MASKREG(r) ((r) & 0xffff) 4422Sbill 452926Swnj /* bits in minor device */ 462980Swnj #define TUUNIT(dev) (minor(dev)&03) 472926Swnj #define H_NOREWIND 04 482926Swnj #define H_1600BPI 08 4922Sbill 503094Swnj #define HTUNIT(dev) (tutoht[TUUNIT(dev)]) 512980Swnj 522926Swnj #define INF (daddr_t)1000000L /* a block number that wont exist */ 532926Swnj 543094Swnj struct tu_softc { 552926Swnj char sc_openf; 562926Swnj char sc_flags; 572926Swnj daddr_t sc_blkno; 582926Swnj daddr_t sc_nxrec; 592926Swnj u_short sc_erreg; 602926Swnj u_short sc_dsreg; 612926Swnj short sc_resid; 622926Swnj short sc_dens; 632980Swnj struct mba_device *sc_mi; 642980Swnj int sc_slave; 653094Swnj } tu_softc[NTU]; 663094Swnj short tutoht[NTU]; 672926Swnj 682926Swnj /* 692926Swnj * Bits for sc_flags. 702926Swnj */ 712926Swnj #define H_WRITTEN 1 /* last operation was a write */ 722926Swnj #define H_ERASED 2 /* last write retry was an erase gap */ 732926Swnj #define H_REWIND 4 /* last unit start was a rewind */ 7422Sbill 753204Swnj char hter_bits[] = HTER_BITS; 763204Swnj char htds_bits[] = HTDS_BITS; 773204Swnj 782926Swnj /*ARGSUSED*/ 792980Swnj htattach(mi) 802980Swnj struct mba_device *mi; 812926Swnj { 822926Swnj 832926Swnj } 842926Swnj 857430Skre htslave(mi, ms, sn) 862980Swnj struct mba_device *mi; 872980Swnj struct mba_slave *ms; 887430Skre int sn; 892980Swnj { 903094Swnj register struct tu_softc *sc = &tu_softc[ms->ms_unit]; 914756Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 922980Swnj 937430Skre htaddr->httc = sn; 944756Swnj if (htaddr->htdt & HTDT_SPR) { 954756Swnj sc->sc_mi = mi; 967430Skre sc->sc_slave = sn; 974756Swnj tutoht[ms->ms_unit] = mi->mi_unit; 984756Swnj return (1); 994756Swnj } else 1004756Swnj return (0); 1012980Swnj } 1022980Swnj 10322Sbill htopen(dev, flag) 1042926Swnj dev_t dev; 1052926Swnj int flag; 10622Sbill { 1073094Swnj register int tuunit; 1082980Swnj register struct mba_device *mi; 1093094Swnj register struct tu_softc *sc; 1103203Swnj int olddens, dens; 11122Sbill 1123094Swnj tuunit = TUUNIT(dev); 1133094Swnj if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf || 1142980Swnj (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) { 11522Sbill u.u_error = ENXIO; 11622Sbill return; 11722Sbill } 1183203Swnj olddens = sc->sc_dens; 1193204Swnj dens = sc->sc_dens = 1203094Swnj ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)| 1213094Swnj HTTC_PDP11|sc->sc_slave; 1223203Swnj htcommand(dev, HT_SENSE, 1); 1233203Swnj sc->sc_dens = olddens; 1243707Sroot if ((sc->sc_dsreg & HTDS_MOL) == 0) { 1253717Sroot uprintf("tu%d: not online\n", tuunit); 1262926Swnj u.u_error = EIO; 1272926Swnj return; 1282926Swnj } 1293707Sroot if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 1303717Sroot uprintf("tu%d: no write ring\n", tuunit); 1313707Sroot u.u_error = EIO; 1323707Sroot return; 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); 1373707Sroot u.u_error = EIO; 1383707Sroot return; 1393707Sroot } 1402926Swnj sc->sc_openf = 1; 1412926Swnj sc->sc_blkno = (daddr_t)0; 1422926Swnj sc->sc_nxrec = INF; 1432926Swnj sc->sc_flags = 0; 1443094Swnj sc->sc_dens = dens; 14522Sbill } 14622Sbill 14722Sbill htclose(dev, flag) 1482926Swnj register dev_t dev; 1492926Swnj register flag; 15022Sbill { 1513094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 15222Sbill 1532926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1542926Swnj htcommand(dev, HT_WEOF, 1); 1552926Swnj htcommand(dev, HT_WEOF, 1); 1562926Swnj htcommand(dev, HT_SREV, 1); 15722Sbill } 1582926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1592926Swnj htcommand(dev, HT_REW, 0); 1602926Swnj sc->sc_openf = 0; 16122Sbill } 16222Sbill 1632926Swnj htcommand(dev, com, count) 1642926Swnj dev_t dev; 1652926Swnj int com, count; 16622Sbill { 16722Sbill register struct buf *bp; 1685436Sroot register int s; 16922Sbill 1702926Swnj bp = &chtbuf[HTUNIT(dev)]; 1715436Sroot s = spl5(); 1722926Swnj while (bp->b_flags&B_BUSY) { 1733157Swnj if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 1742980Swnj break; 17522Sbill bp->b_flags |= B_WANTED; 17622Sbill sleep((caddr_t)bp, PRIBIO); 17722Sbill } 1782943Swnj bp->b_flags = B_BUSY|B_READ; 1795436Sroot splx(s); 18022Sbill bp->b_dev = dev; 1812926Swnj bp->b_command = com; 1822926Swnj bp->b_repcnt = count; 18322Sbill bp->b_blkno = 0; 18422Sbill htstrategy(bp); 1852926Swnj if (count == 0) 1862926Swnj return; 18722Sbill iowait(bp); 1882926Swnj if (bp->b_flags&B_WANTED) 18922Sbill wakeup((caddr_t)bp); 1902926Swnj bp->b_flags &= B_ERROR; 19122Sbill } 19222Sbill 19322Sbill htstrategy(bp) 1942926Swnj register struct buf *bp; 19522Sbill { 1963094Swnj register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)]; 1972926Swnj register struct buf *dp; 1985436Sroot register int s; 19922Sbill 20022Sbill bp->av_forw = NULL; 2012926Swnj dp = &mi->mi_tab; 2025436Sroot s = spl5(); 2032926Swnj if (dp->b_actf == NULL) 2042926Swnj dp->b_actf = bp; 20522Sbill else 2062926Swnj dp->b_actl->av_forw = bp; 2072926Swnj dp->b_actl = bp; 2082926Swnj if (dp->b_active == 0) 2092926Swnj mbustart(mi); 2105436Sroot splx(s); 21122Sbill } 21222Sbill 2132926Swnj htustart(mi) 2142980Swnj register struct mba_device *mi; 21522Sbill { 2162926Swnj register struct htdevice *htaddr = 2172926Swnj (struct htdevice *)mi->mi_drv; 2182926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2193094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)]; 22022Sbill daddr_t blkno; 22122Sbill 2222926Swnj htaddr->httc = sc->sc_dens; 2233181Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) { 2243157Swnj htaddr->htcs1 = HT_SENSE|HT_GO; 2253157Swnj mbclrattn(mi); 2263157Swnj } 2272926Swnj sc->sc_dsreg = htaddr->htds; 2282926Swnj sc->sc_erreg = htaddr->hter; 2292926Swnj sc->sc_resid = htaddr->htfc; 2302926Swnj sc->sc_flags &= ~(H_WRITTEN|H_REWIND); 2312926Swnj if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) 2322926Swnj if (sc->sc_openf > 0) 2332926Swnj sc->sc_openf = -1; 2342926Swnj if (sc->sc_openf < 0) { 2352926Swnj bp->b_flags |= B_ERROR; 2362926Swnj return (MBU_NEXT); 2372926Swnj } 2383094Swnj if (bp != &chtbuf[HTUNIT(bp->b_dev)]) { 2397379Ssam if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 2402926Swnj bp->b_flags |= B_ERROR; 2412926Swnj bp->b_error = ENXIO; 2422961Swnj return (MBU_NEXT); 2433094Swnj } 2447379Ssam if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && 2452926Swnj bp->b_flags&B_READ) { 2462926Swnj bp->b_resid = bp->b_bcount; 2472926Swnj clrbuf(bp); 2482961Swnj return (MBU_NEXT); 2493094Swnj } 2503094Swnj if ((bp->b_flags&B_READ)==0) 2517379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 2522926Swnj } else { 2532961Swnj if (bp->b_command == HT_SENSE) 2542926Swnj return (MBU_NEXT); 2552926Swnj if (bp->b_command == HT_REW) 2562926Swnj sc->sc_flags |= H_REWIND; 2572926Swnj else 2582926Swnj htaddr->htfc = -bp->b_bcount; 2592926Swnj htaddr->htcs1 = bp->b_command|HT_GO; 2602926Swnj return (MBU_STARTED); 2612926Swnj } 2627379Ssam if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 2632926Swnj htaddr->htfc = -bp->b_bcount; 2642926Swnj if ((bp->b_flags&B_READ) == 0) { 2653094Swnj if (mi->mi_tab.b_errcnt) { 2663094Swnj if ((sc->sc_flags & H_ERASED) == 0) { 2672926Swnj sc->sc_flags |= H_ERASED; 2682926Swnj htaddr->htcs1 = HT_ERASE | HT_GO; 2692926Swnj return (MBU_STARTED); 2702926Swnj } 2713094Swnj sc->sc_flags &= ~H_ERASED; 2723094Swnj } 2732926Swnj if (htaddr->htds & HTDS_EOT) { 2742926Swnj bp->b_resid = bp->b_bcount; 2756812Swnj bp->b_flags |= B_ERROR; 2762926Swnj return (MBU_NEXT); 2772926Swnj } 27822Sbill } 2792926Swnj return (MBU_DODATA); 28022Sbill } 2817379Ssam if (blkno < bdbtofsb(bp->b_blkno)) { 2827379Ssam htaddr->htfc = blkno - bdbtofsb(bp->b_blkno); 2832926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 28422Sbill } else { 2857379Ssam htaddr->htfc = bdbtofsb(bp->b_blkno) - blkno; 2862926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 28722Sbill } 2882926Swnj return (MBU_STARTED); 28922Sbill } 29022Sbill 2913094Swnj htdtint(mi, mbsr) 2922980Swnj register struct mba_device *mi; 2933094Swnj int mbsr; 29422Sbill { 2952926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 2962926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2973094Swnj register struct tu_softc *sc; 2982961Swnj int ds, er, mbs; 29922Sbill 3003094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3012926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 3022926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 3032926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 3043094Swnj mbs = mbsr; 3052926Swnj sc->sc_blkno++; 3062926Swnj if((bp->b_flags & B_READ) == 0) 3072926Swnj sc->sc_flags |= H_WRITTEN; 3083094Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { 3092926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3102961Swnj mbclrattn(mi); 3112961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 3122926Swnj er &= ~HTER_FCE; 3133094Swnj mbs &= ~(MBSR_DTABT|MBSR_MBEXC); 3144276Sroot } 3152926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 3162926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 3173094Swnj if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || 3182961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 3192926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3202926Swnj sc->sc_openf = -1; 3213157Swnj if ((er&HTER_HARD) == HTER_FCE && 3223157Swnj (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && 3233157Swnj (ds&HTDS_MOL)) 3243157Swnj goto noprint; 3253204Swnj printf("tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", 3262980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3273094Swnj mbsr, mbsr_bits, 3283204Swnj sc->sc_erreg, hter_bits, 3293204Swnj sc->sc_dsreg, htds_bits); 3303157Swnj noprint: 33122Sbill bp->b_flags |= B_ERROR; 3322926Swnj return (MBD_DONE); 33322Sbill } 3342926Swnj if (er) 3352926Swnj return (MBD_RETRY); 33622Sbill } 3372926Swnj bp->b_resid = 0; 3382926Swnj if (bp->b_flags & B_READ) 3392926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 3402926Swnj bp->b_resid = bp->b_bcount; 3417379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno); 3422926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 3432926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 3442926Swnj return (MBD_DONE); 3452926Swnj } 34622Sbill 3472926Swnj htndtint(mi) 3482980Swnj register struct mba_device *mi; 3492926Swnj { 3502926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3512926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3523094Swnj register struct tu_softc *sc; 3532926Swnj int er, ds, fc; 35422Sbill 3553094Swnj ds = MASKREG(htaddr->htds); 3563094Swnj er = MASKREG(htaddr->hter); 3573094Swnj fc = MASKREG(htaddr->htfc); 3583094Swnj if (er) { 3592926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3602961Swnj mbclrattn(mi); 3612961Swnj } 3623094Swnj if (bp == 0) 3633094Swnj return (MBN_SKIP); 3643094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3653094Swnj sc->sc_dsreg = ds; 3663094Swnj sc->sc_erreg = er; 3673094Swnj sc->sc_resid = fc; 3683094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3693094Swnj switch (bp->b_command) { 3703094Swnj case HT_REWOFFL: 3712926Swnj /* offline is on purpose; don't do anything special */ 3722926Swnj ds |= HTDS_MOL; 3733094Swnj break; 3743094Swnj case HT_SREV: 3753094Swnj /* if backspace file hit bot, its not an error */ 3763094Swnj if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && 3773094Swnj bp->b_repcnt == INF) 3783094Swnj er &= ~HTER_NEF; 3793094Swnj break; 3803094Swnj } 3812926Swnj er &= ~HTER_FCE; 3822926Swnj if (er == 0) 3832926Swnj ds &= ~HTDS_ERR; 38422Sbill } 3852926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3862926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3872926Swnj sc->sc_openf = -1; 3883204Swnj printf("tu%d: hard error bn%d er=%b ds=%b\n", 3892980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3903204Swnj sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); 3912926Swnj bp->b_flags |= B_ERROR; 3922926Swnj return (MBN_DONE); 3932926Swnj } 3943094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3952926Swnj if (sc->sc_flags & H_REWIND) 3962926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 3972926Swnj bp->b_resid = -sc->sc_resid; 3982926Swnj return (MBN_DONE); 3992926Swnj } 4002926Swnj if (ds & HTDS_TM) 4017379Ssam if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 4027379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; 4032926Swnj sc->sc_blkno = sc->sc_nxrec; 4043094Swnj } else { 4057379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno) + fc; 4062926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 4072926Swnj } 4082926Swnj else 4097379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno); 4102926Swnj return (MBN_RETRY); 41122Sbill } 41222Sbill 41322Sbill htread(dev) 4142926Swnj dev_t dev; 41522Sbill { 4162926Swnj 41722Sbill htphys(dev); 4182926Swnj if (u.u_error) 4192926Swnj return; 4202926Swnj physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys); 42122Sbill } 42222Sbill 42322Sbill htwrite(dev) 42422Sbill { 4252926Swnj 42622Sbill htphys(dev); 4272926Swnj if (u.u_error) 4282926Swnj return; 4292926Swnj physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys); 43022Sbill } 43122Sbill 43222Sbill htphys(dev) 4332926Swnj dev_t dev; 43422Sbill { 4353094Swnj register int htunit; 4363094Swnj register struct tu_softc *sc; 4373094Swnj register struct mba_device *mi; 43822Sbill daddr_t a; 43922Sbill 4403094Swnj htunit = HTUNIT(dev); 4413094Swnj if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) { 4422926Swnj u.u_error = ENXIO; 4432926Swnj return; 44422Sbill } 4452926Swnj a = u.u_offset >> 9; 4463094Swnj sc = &tu_softc[TUUNIT(dev)]; 4477379Ssam sc->sc_blkno = bdbtofsb(a); 4487379Ssam sc->sc_nxrec = bdbtofsb(a)+1; 44922Sbill } 4501917Swnj 4512926Swnj /*ARGSUSED*/ 452*7636Ssam htioctl(dev, cmd, data, flag) 4532926Swnj dev_t dev; 4542926Swnj int cmd; 455*7636Ssam caddr_t data; 4562926Swnj int flag; 4572926Swnj { 4583094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 4593094Swnj register struct buf *bp = &chtbuf[HTUNIT(dev)]; 4602926Swnj register callcount; 4612926Swnj int fcount; 462*7636Ssam struct mtop *mtop; 463*7636Ssam struct mtget *mtget; 4642926Swnj /* we depend of the values and order of the MT codes here */ 4652926Swnj static htops[] = 4662926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4671917Swnj 4682926Swnj switch (cmd) { 469*7636Ssam 470*7636Ssam case MTIOCTOP: /* tape operation */ 471*7636Ssam mtop = (struct mtop *)data; 472*7636Ssam switch (mtop->mt_op) { 473*7636Ssam 4742926Swnj case MTWEOF: 475*7636Ssam callcount = mtop->mt_count; 4762926Swnj fcount = 1; 4772926Swnj break; 478*7636Ssam 4792926Swnj case MTFSF: case MTBSF: 480*7636Ssam callcount = mtop->mt_count; 4812926Swnj fcount = INF; 4822926Swnj break; 483*7636Ssam 4842926Swnj case MTFSR: case MTBSR: 4852926Swnj callcount = 1; 486*7636Ssam fcount = mtop->mt_count; 4872926Swnj break; 488*7636Ssam 4892926Swnj case MTREW: case MTOFFL: 4902926Swnj callcount = 1; 4912926Swnj fcount = 1; 4922926Swnj break; 493*7636Ssam 4942926Swnj default: 4952926Swnj u.u_error = ENXIO; 4962926Swnj return; 4972926Swnj } 4982926Swnj if (callcount <= 0 || fcount <= 0) { 4992926Swnj u.u_error = ENXIO; 5002926Swnj return; 5012926Swnj } 5022926Swnj while (--callcount >= 0) { 503*7636Ssam htcommand(dev, htops[mtop->mt_op], fcount); 504*7636Ssam if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 5052926Swnj bp->b_resid) { 5062926Swnj u.u_error = EIO; 5072926Swnj break; 5082926Swnj } 5093094Swnj if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) 5102926Swnj break; 5112926Swnj } 5122926Swnj geterror(bp); 5132926Swnj return; 514*7636Ssam 5152926Swnj case MTIOCGET: 516*7636Ssam mtget = (struct mtget *)data; 517*7636Ssam mtget->mt_dsreg = sc->sc_dsreg; 518*7636Ssam mtget->mt_erreg = sc->sc_erreg; 519*7636Ssam mtget->mt_resid = sc->sc_resid; 520*7636Ssam mtget->mt_type = MT_ISHT; 5212926Swnj return; 522*7636Ssam 5232926Swnj default: 5242926Swnj u.u_error = ENXIO; 5252926Swnj } 5262926Swnj } 5272926Swnj 5281917Swnj #define DBSIZE 20 5291917Swnj 5302926Swnj htdump() 5311917Swnj { 5322980Swnj register struct mba_device *mi; 5332926Swnj register struct mba_regs *mp; 5342926Swnj register struct htdevice *htaddr; 5352926Swnj int blk, num; 5362926Swnj int start; 5371917Swnj 5382926Swnj start = 0; 5392926Swnj num = maxfree; 5402926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 5412926Swnj if (htinfo[0] == 0) 5422926Swnj return (ENXIO); 5432980Swnj mi = phys(htinfo[0], struct mba_device *); 5442926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 5453157Swnj mp->mba_cr = MBCR_IE; 5462926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 5472926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 5482926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 5491917Swnj while (num > 0) { 5501917Swnj blk = num > DBSIZE ? DBSIZE : num; 5512926Swnj htdwrite(start, blk, htaddr, mp); 5522926Swnj start += blk; 5531917Swnj num -= blk; 5541917Swnj } 5553157Swnj hteof(htaddr); 5563157Swnj hteof(htaddr); 5572926Swnj htwait(htaddr); 5583181Swnj if (htaddr->htds&HTDS_ERR) 5593157Swnj return (EIO); 5602926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5613103Swnj return (0); 5621917Swnj } 5631917Swnj 5642926Swnj htdwrite(dbuf, num, htaddr, mp) 5652926Swnj register dbuf, num; 5662926Swnj register struct htdevice *htaddr; 5672926Swnj struct mba_regs *mp; 5681917Swnj { 5692926Swnj register struct pte *io; 5701917Swnj register int i; 5711917Swnj 5722926Swnj htwait(htaddr); 5732926Swnj io = mp->mba_map; 5741917Swnj for (i = 0; i < num; i++) 5752926Swnj *(int *)io++ = dbuf++ | PG_V; 5762926Swnj htaddr->htfc = -(num*NBPG); 5772926Swnj mp->mba_sr = -1; 5782926Swnj mp->mba_bcr = -(num*NBPG); 5792926Swnj mp->mba_var = 0; 5802926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5811917Swnj } 5821917Swnj 5832926Swnj htwait(htaddr) 5842926Swnj struct htdevice *htaddr; 5851917Swnj { 5861917Swnj register s; 5871917Swnj 5881917Swnj do 5892926Swnj s = htaddr->htds; 5902926Swnj while ((s & HTDS_DRY) == 0); 5911917Swnj } 5921917Swnj 5932926Swnj hteof(htaddr) 5942926Swnj struct htdevice *htaddr; 5951917Swnj { 5961917Swnj 5972926Swnj htwait(htaddr); 5982926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 5991917Swnj } 6001563Sbill #endif 601