1*4756Swnj /* ht.c 4.20 81/11/07 */ 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" 252926Swnj #include "../h/mtio.h" 262926Swnj #include "../h/ioctl.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 852980Swnj htslave(mi, ms) 862980Swnj struct mba_device *mi; 872980Swnj struct mba_slave *ms; 882980Swnj { 893094Swnj register struct tu_softc *sc = &tu_softc[ms->ms_unit]; 90*4756Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 912980Swnj 92*4756Swnj htaddr->httc = ms->ms_slave; 93*4756Swnj if (htaddr->htdt & HTDT_SPR) { 94*4756Swnj sc->sc_mi = mi; 95*4756Swnj sc->sc_slave = ms->ms_slave; 96*4756Swnj tutoht[ms->ms_unit] = mi->mi_unit; 97*4756Swnj return (1); 98*4756Swnj } else 99*4756Swnj return (0); 1002980Swnj } 1012980Swnj 10222Sbill htopen(dev, flag) 1032926Swnj dev_t dev; 1042926Swnj int flag; 10522Sbill { 1063094Swnj register int tuunit; 1072980Swnj register struct mba_device *mi; 1083094Swnj register struct tu_softc *sc; 1093203Swnj int olddens, dens; 11022Sbill 1113094Swnj tuunit = TUUNIT(dev); 1123094Swnj if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf || 1132980Swnj (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) { 11422Sbill u.u_error = ENXIO; 11522Sbill return; 11622Sbill } 1173203Swnj olddens = sc->sc_dens; 1183204Swnj dens = sc->sc_dens = 1193094Swnj ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)| 1203094Swnj HTTC_PDP11|sc->sc_slave; 1213203Swnj htcommand(dev, HT_SENSE, 1); 1223203Swnj sc->sc_dens = olddens; 1233707Sroot if ((sc->sc_dsreg & HTDS_MOL) == 0) { 1243717Sroot uprintf("tu%d: not online\n", tuunit); 1252926Swnj u.u_error = EIO; 1262926Swnj return; 1272926Swnj } 1283707Sroot if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 1293717Sroot uprintf("tu%d: no write ring\n", tuunit); 1303707Sroot u.u_error = EIO; 1313707Sroot return; 1323707Sroot } 1333707Sroot if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) && 1343707Sroot dens != sc->sc_dens) { 1353717Sroot uprintf("tu%d: can't change density in mid-tape\n", tuunit); 1363707Sroot u.u_error = EIO; 1373707Sroot return; 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; 14422Sbill } 14522Sbill 14622Sbill htclose(dev, flag) 1472926Swnj register dev_t dev; 1482926Swnj register flag; 14922Sbill { 1503094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 15122Sbill 1522926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1532926Swnj htcommand(dev, HT_WEOF, 1); 1542926Swnj htcommand(dev, HT_WEOF, 1); 1552926Swnj htcommand(dev, HT_SREV, 1); 15622Sbill } 1572926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1582926Swnj htcommand(dev, HT_REW, 0); 1592926Swnj sc->sc_openf = 0; 16022Sbill } 16122Sbill 1622926Swnj htcommand(dev, com, count) 1632926Swnj dev_t dev; 1642926Swnj int com, count; 16522Sbill { 16622Sbill register struct buf *bp; 16722Sbill 1682926Swnj bp = &chtbuf[HTUNIT(dev)]; 169128Sbill (void) spl5(); 1702926Swnj while (bp->b_flags&B_BUSY) { 1713157Swnj if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 1722980Swnj break; 17322Sbill bp->b_flags |= B_WANTED; 17422Sbill sleep((caddr_t)bp, PRIBIO); 17522Sbill } 1762943Swnj bp->b_flags = B_BUSY|B_READ; 177128Sbill (void) spl0(); 17822Sbill bp->b_dev = dev; 1792926Swnj bp->b_command = com; 1802926Swnj bp->b_repcnt = count; 18122Sbill bp->b_blkno = 0; 18222Sbill htstrategy(bp); 1832926Swnj if (count == 0) 1842926Swnj return; 18522Sbill iowait(bp); 1862926Swnj if (bp->b_flags&B_WANTED) 18722Sbill wakeup((caddr_t)bp); 1882926Swnj bp->b_flags &= B_ERROR; 18922Sbill } 19022Sbill 19122Sbill htstrategy(bp) 1922926Swnj register struct buf *bp; 19322Sbill { 1943094Swnj register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)]; 1952926Swnj register struct buf *dp; 19622Sbill 19722Sbill bp->av_forw = NULL; 1982926Swnj dp = &mi->mi_tab; 199128Sbill (void) spl5(); 2002926Swnj if (dp->b_actf == NULL) 2012926Swnj dp->b_actf = bp; 20222Sbill else 2032926Swnj dp->b_actl->av_forw = bp; 2042926Swnj dp->b_actl = bp; 2052926Swnj if (dp->b_active == 0) 2062926Swnj mbustart(mi); 207128Sbill (void) spl0(); 20822Sbill } 20922Sbill 2102926Swnj htustart(mi) 2112980Swnj register struct mba_device *mi; 21222Sbill { 2132926Swnj register struct htdevice *htaddr = 2142926Swnj (struct htdevice *)mi->mi_drv; 2152926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2163094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)]; 21722Sbill daddr_t blkno; 21822Sbill 2192926Swnj htaddr->httc = sc->sc_dens; 2203181Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) { 2213157Swnj htaddr->htcs1 = HT_SENSE|HT_GO; 2223157Swnj mbclrattn(mi); 2233157Swnj } 2242926Swnj sc->sc_dsreg = htaddr->htds; 2252926Swnj sc->sc_erreg = htaddr->hter; 2262926Swnj sc->sc_resid = htaddr->htfc; 2272926Swnj sc->sc_flags &= ~(H_WRITTEN|H_REWIND); 2282926Swnj if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) 2292926Swnj if (sc->sc_openf > 0) 2302926Swnj sc->sc_openf = -1; 2312926Swnj if (sc->sc_openf < 0) { 2322926Swnj bp->b_flags |= B_ERROR; 2332926Swnj return (MBU_NEXT); 2342926Swnj } 2353094Swnj if (bp != &chtbuf[HTUNIT(bp->b_dev)]) { 2362926Swnj if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) { 2372926Swnj bp->b_flags |= B_ERROR; 2382926Swnj bp->b_error = ENXIO; 2392961Swnj return (MBU_NEXT); 2403094Swnj } 2413094Swnj if (dbtofsb(bp->b_blkno) == sc->sc_nxrec && 2422926Swnj bp->b_flags&B_READ) { 2432926Swnj bp->b_resid = bp->b_bcount; 2442926Swnj clrbuf(bp); 2452961Swnj return (MBU_NEXT); 2463094Swnj } 2473094Swnj if ((bp->b_flags&B_READ)==0) 2482926Swnj sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1; 2492926Swnj } else { 2502961Swnj if (bp->b_command == HT_SENSE) 2512926Swnj return (MBU_NEXT); 2522926Swnj if (bp->b_command == HT_REW) 2532926Swnj sc->sc_flags |= H_REWIND; 2542926Swnj else 2552926Swnj htaddr->htfc = -bp->b_bcount; 2562926Swnj htaddr->htcs1 = bp->b_command|HT_GO; 2572926Swnj return (MBU_STARTED); 2582926Swnj } 2592926Swnj if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) { 2602926Swnj htaddr->htfc = -bp->b_bcount; 2612926Swnj if ((bp->b_flags&B_READ) == 0) { 2623094Swnj if (mi->mi_tab.b_errcnt) { 2633094Swnj if ((sc->sc_flags & H_ERASED) == 0) { 2642926Swnj sc->sc_flags |= H_ERASED; 2652926Swnj htaddr->htcs1 = HT_ERASE | HT_GO; 2662926Swnj return (MBU_STARTED); 2672926Swnj } 2683094Swnj sc->sc_flags &= ~H_ERASED; 2693094Swnj } 2702926Swnj if (htaddr->htds & HTDS_EOT) { 2712926Swnj bp->b_resid = bp->b_bcount; 2722926Swnj return (MBU_NEXT); 2732926Swnj } 27422Sbill } 2752926Swnj return (MBU_DODATA); 27622Sbill } 2772926Swnj if (blkno < dbtofsb(bp->b_blkno)) { 2782926Swnj htaddr->htfc = blkno - dbtofsb(bp->b_blkno); 2792926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 28022Sbill } else { 2812926Swnj htaddr->htfc = dbtofsb(bp->b_blkno) - blkno; 2822926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 28322Sbill } 2842926Swnj return (MBU_STARTED); 28522Sbill } 28622Sbill 2873094Swnj htdtint(mi, mbsr) 2882980Swnj register struct mba_device *mi; 2893094Swnj int mbsr; 29022Sbill { 2912926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 2922926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2933094Swnj register struct tu_softc *sc; 2942961Swnj int ds, er, mbs; 29522Sbill 2963094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 2972926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 2982926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 2992926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 3003094Swnj mbs = mbsr; 3012926Swnj sc->sc_blkno++; 3022926Swnj if((bp->b_flags & B_READ) == 0) 3032926Swnj sc->sc_flags |= H_WRITTEN; 3043094Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { 3052926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3062961Swnj mbclrattn(mi); 3072961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 3082926Swnj er &= ~HTER_FCE; 3093094Swnj mbs &= ~(MBSR_DTABT|MBSR_MBEXC); 3104276Sroot } 3112926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 3122926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 3133094Swnj if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || 3142961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 3152926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3162926Swnj sc->sc_openf = -1; 3173157Swnj if ((er&HTER_HARD) == HTER_FCE && 3183157Swnj (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && 3193157Swnj (ds&HTDS_MOL)) 3203157Swnj goto noprint; 3213204Swnj printf("tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", 3222980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3233094Swnj mbsr, mbsr_bits, 3243204Swnj sc->sc_erreg, hter_bits, 3253204Swnj sc->sc_dsreg, htds_bits); 3263157Swnj noprint: 32722Sbill bp->b_flags |= B_ERROR; 3282926Swnj return (MBD_DONE); 32922Sbill } 3302926Swnj if (er) 3312926Swnj return (MBD_RETRY); 33222Sbill } 3332926Swnj bp->b_resid = 0; 3342926Swnj if (bp->b_flags & B_READ) 3352926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 3362926Swnj bp->b_resid = bp->b_bcount; 3372926Swnj sc->sc_nxrec = dbtofsb(bp->b_blkno); 3382926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 3392926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 3402926Swnj return (MBD_DONE); 3412926Swnj } 34222Sbill 3432926Swnj htndtint(mi) 3442980Swnj register struct mba_device *mi; 3452926Swnj { 3462926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3472926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3483094Swnj register struct tu_softc *sc; 3492926Swnj int er, ds, fc; 35022Sbill 3513094Swnj ds = MASKREG(htaddr->htds); 3523094Swnj er = MASKREG(htaddr->hter); 3533094Swnj fc = MASKREG(htaddr->htfc); 3543094Swnj if (er) { 3552926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3562961Swnj mbclrattn(mi); 3572961Swnj } 3583094Swnj if (bp == 0) 3593094Swnj return (MBN_SKIP); 3603094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3613094Swnj sc->sc_dsreg = ds; 3623094Swnj sc->sc_erreg = er; 3633094Swnj sc->sc_resid = fc; 3643094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3653094Swnj switch (bp->b_command) { 3663094Swnj case HT_REWOFFL: 3672926Swnj /* offline is on purpose; don't do anything special */ 3682926Swnj ds |= HTDS_MOL; 3693094Swnj break; 3703094Swnj case HT_SREV: 3713094Swnj /* if backspace file hit bot, its not an error */ 3723094Swnj if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && 3733094Swnj bp->b_repcnt == INF) 3743094Swnj er &= ~HTER_NEF; 3753094Swnj break; 3763094Swnj } 3772926Swnj er &= ~HTER_FCE; 3782926Swnj if (er == 0) 3792926Swnj ds &= ~HTDS_ERR; 38022Sbill } 3812926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3822926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3832926Swnj sc->sc_openf = -1; 3843204Swnj printf("tu%d: hard error bn%d er=%b ds=%b\n", 3852980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3863204Swnj sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); 3872926Swnj bp->b_flags |= B_ERROR; 3882926Swnj return (MBN_DONE); 3892926Swnj } 3903094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3912926Swnj if (sc->sc_flags & H_REWIND) 3922926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 3932926Swnj bp->b_resid = -sc->sc_resid; 3942926Swnj return (MBN_DONE); 3952926Swnj } 3962926Swnj if (ds & HTDS_TM) 3973094Swnj if (sc->sc_blkno > dbtofsb(bp->b_blkno)) { 3982926Swnj sc->sc_nxrec = dbtofsb(bp->b_blkno) - fc; 3992926Swnj sc->sc_blkno = sc->sc_nxrec; 4003094Swnj } else { 4012926Swnj sc->sc_blkno = dbtofsb(bp->b_blkno) + fc; 4022926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 4032926Swnj } 4042926Swnj else 4052926Swnj sc->sc_blkno = dbtofsb(bp->b_blkno); 4062926Swnj return (MBN_RETRY); 40722Sbill } 40822Sbill 40922Sbill htread(dev) 4102926Swnj dev_t dev; 41122Sbill { 4122926Swnj 41322Sbill htphys(dev); 4142926Swnj if (u.u_error) 4152926Swnj return; 4162926Swnj physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys); 41722Sbill } 41822Sbill 41922Sbill htwrite(dev) 42022Sbill { 4212926Swnj 42222Sbill htphys(dev); 4232926Swnj if (u.u_error) 4242926Swnj return; 4252926Swnj physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys); 42622Sbill } 42722Sbill 42822Sbill htphys(dev) 4292926Swnj dev_t dev; 43022Sbill { 4313094Swnj register int htunit; 4323094Swnj register struct tu_softc *sc; 4333094Swnj register struct mba_device *mi; 43422Sbill daddr_t a; 43522Sbill 4363094Swnj htunit = HTUNIT(dev); 4373094Swnj if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) { 4382926Swnj u.u_error = ENXIO; 4392926Swnj return; 44022Sbill } 4412926Swnj a = u.u_offset >> 9; 4423094Swnj sc = &tu_softc[TUUNIT(dev)]; 4432926Swnj sc->sc_blkno = dbtofsb(a); 4442926Swnj sc->sc_nxrec = dbtofsb(a)+1; 44522Sbill } 4461917Swnj 4472926Swnj /*ARGSUSED*/ 4482926Swnj htioctl(dev, cmd, addr, flag) 4492926Swnj dev_t dev; 4502926Swnj int cmd; 4512926Swnj caddr_t addr; 4522926Swnj int flag; 4532926Swnj { 4543094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 4553094Swnj register struct buf *bp = &chtbuf[HTUNIT(dev)]; 4562926Swnj register callcount; 4572926Swnj int fcount; 4582926Swnj struct mtop mtop; 4592926Swnj struct mtget mtget; 4602926Swnj /* we depend of the values and order of the MT codes here */ 4612926Swnj static htops[] = 4622926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4631917Swnj 4642926Swnj switch (cmd) { 4652926Swnj case MTIOCTOP: /* tape operation */ 4662926Swnj if (copyin((caddr_t)addr, (caddr_t)&mtop, sizeof(mtop))) { 4672926Swnj u.u_error = EFAULT; 4682926Swnj return; 4692926Swnj } 4702926Swnj switch(mtop.mt_op) { 4712926Swnj case MTWEOF: 4722926Swnj callcount = mtop.mt_count; 4732926Swnj fcount = 1; 4742926Swnj break; 4752926Swnj case MTFSF: case MTBSF: 4762926Swnj callcount = mtop.mt_count; 4772926Swnj fcount = INF; 4782926Swnj break; 4792926Swnj case MTFSR: case MTBSR: 4802926Swnj callcount = 1; 4812926Swnj fcount = mtop.mt_count; 4822926Swnj break; 4832926Swnj case MTREW: case MTOFFL: 4842926Swnj callcount = 1; 4852926Swnj fcount = 1; 4862926Swnj break; 4872926Swnj default: 4882926Swnj u.u_error = ENXIO; 4892926Swnj return; 4902926Swnj } 4912926Swnj if (callcount <= 0 || fcount <= 0) { 4922926Swnj u.u_error = ENXIO; 4932926Swnj return; 4942926Swnj } 4952926Swnj while (--callcount >= 0) { 4962926Swnj htcommand(dev, htops[mtop.mt_op], fcount); 4972926Swnj if ((mtop.mt_op == MTFSR || mtop.mt_op == MTBSR) && 4982926Swnj bp->b_resid) { 4992926Swnj u.u_error = EIO; 5002926Swnj break; 5012926Swnj } 5023094Swnj if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) 5032926Swnj break; 5042926Swnj } 5052926Swnj geterror(bp); 5062926Swnj return; 5072926Swnj case MTIOCGET: 5082926Swnj mtget.mt_dsreg = sc->sc_dsreg; 5092926Swnj mtget.mt_erreg = sc->sc_erreg; 5102926Swnj mtget.mt_resid = sc->sc_resid; 5113480Stoy mtget.mt_type = MT_ISHT; 5122926Swnj if (copyout((caddr_t)&mtget, addr, sizeof(mtget))) 5132926Swnj u.u_error = EFAULT; 5142926Swnj return; 5152926Swnj default: 5162926Swnj u.u_error = ENXIO; 5172926Swnj } 5182926Swnj } 5192926Swnj 5201917Swnj #define DBSIZE 20 5211917Swnj 5222926Swnj htdump() 5231917Swnj { 5242980Swnj register struct mba_device *mi; 5252926Swnj register struct mba_regs *mp; 5262926Swnj register struct htdevice *htaddr; 5272926Swnj int blk, num; 5282926Swnj int start; 5291917Swnj 5302926Swnj start = 0; 5312926Swnj num = maxfree; 5322926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 5332926Swnj if (htinfo[0] == 0) 5342926Swnj return (ENXIO); 5352980Swnj mi = phys(htinfo[0], struct mba_device *); 5362926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 5373157Swnj mp->mba_cr = MBCR_IE; 5382926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 5392926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 5402926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 5411917Swnj while (num > 0) { 5421917Swnj blk = num > DBSIZE ? DBSIZE : num; 5432926Swnj htdwrite(start, blk, htaddr, mp); 5442926Swnj start += blk; 5451917Swnj num -= blk; 5461917Swnj } 5473157Swnj hteof(htaddr); 5483157Swnj hteof(htaddr); 5492926Swnj htwait(htaddr); 5503181Swnj if (htaddr->htds&HTDS_ERR) 5513157Swnj return (EIO); 5522926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5533103Swnj return (0); 5541917Swnj } 5551917Swnj 5562926Swnj htdwrite(dbuf, num, htaddr, mp) 5572926Swnj register dbuf, num; 5582926Swnj register struct htdevice *htaddr; 5592926Swnj struct mba_regs *mp; 5601917Swnj { 5612926Swnj register struct pte *io; 5621917Swnj register int i; 5631917Swnj 5642926Swnj htwait(htaddr); 5652926Swnj io = mp->mba_map; 5661917Swnj for (i = 0; i < num; i++) 5672926Swnj *(int *)io++ = dbuf++ | PG_V; 5682926Swnj htaddr->htfc = -(num*NBPG); 5692926Swnj mp->mba_sr = -1; 5702926Swnj mp->mba_bcr = -(num*NBPG); 5712926Swnj mp->mba_var = 0; 5722926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5731917Swnj } 5741917Swnj 5752926Swnj htwait(htaddr) 5762926Swnj struct htdevice *htaddr; 5771917Swnj { 5781917Swnj register s; 5791917Swnj 5801917Swnj do 5812926Swnj s = htaddr->htds; 5822926Swnj while ((s & HTDS_DRY) == 0); 5831917Swnj } 5841917Swnj 5852926Swnj hteof(htaddr) 5862926Swnj struct htdevice *htaddr; 5871917Swnj { 5881917Swnj 5892926Swnj htwait(htaddr); 5902926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 5911917Swnj } 5921563Sbill #endif 593