1*8605Sroot /* ht.c 4.31 82/10/17 */ 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" 237636Ssam #include "../h/ioctl.h" 242926Swnj #include "../h/mtio.h" 251917Swnj #include "../h/cmap.h" 267739Sroot #include "../h/uio.h" 2722Sbill 288469Sroot #include "../vax/cpu.h" 298469Sroot #include "../vaxmba/mbareg.h" 308469Sroot #include "../vaxmba/mbavar.h" 318469Sroot #include "../vaxmba/htreg.h" 3222Sbill 332926Swnj struct buf rhtbuf[NHT]; 342926Swnj struct buf chtbuf[NHT]; 3522Sbill 362926Swnj short httypes[] = 373181Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 382980Swnj struct mba_device *htinfo[NHT]; 393103Swnj int htattach(), htslave(), htustart(), htndtint(), htdtint(); 402926Swnj struct mba_driver htdriver = 412980Swnj { htattach, htslave, htustart, 0, htdtint, htndtint, 422980Swnj httypes, "ht", "tu", htinfo }; 4322Sbill 442926Swnj #define MASKREG(r) ((r) & 0xffff) 4522Sbill 462926Swnj /* bits in minor device */ 472980Swnj #define TUUNIT(dev) (minor(dev)&03) 482926Swnj #define H_NOREWIND 04 492926Swnj #define H_1600BPI 08 5022Sbill 513094Swnj #define HTUNIT(dev) (tutoht[TUUNIT(dev)]) 522980Swnj 532926Swnj #define INF (daddr_t)1000000L /* a block number that wont exist */ 542926Swnj 553094Swnj struct tu_softc { 562926Swnj char sc_openf; 572926Swnj char sc_flags; 582926Swnj daddr_t sc_blkno; 592926Swnj daddr_t sc_nxrec; 602926Swnj u_short sc_erreg; 612926Swnj u_short sc_dsreg; 622926Swnj short sc_resid; 632926Swnj short sc_dens; 642980Swnj struct mba_device *sc_mi; 652980Swnj int sc_slave; 663094Swnj } tu_softc[NTU]; 673094Swnj short tutoht[NTU]; 682926Swnj 692926Swnj /* 702926Swnj * Bits for sc_flags. 712926Swnj */ 722926Swnj #define H_WRITTEN 1 /* last operation was a write */ 732926Swnj #define H_ERASED 2 /* last write retry was an erase gap */ 742926Swnj #define H_REWIND 4 /* last unit start was a rewind */ 7522Sbill 763204Swnj char hter_bits[] = HTER_BITS; 773204Swnj char htds_bits[] = HTDS_BITS; 783204Swnj 792926Swnj /*ARGSUSED*/ 802980Swnj htattach(mi) 812980Swnj struct mba_device *mi; 822926Swnj { 832926Swnj 842926Swnj } 852926Swnj 867430Skre htslave(mi, ms, sn) 872980Swnj struct mba_device *mi; 882980Swnj struct mba_slave *ms; 897430Skre int sn; 902980Swnj { 913094Swnj register struct tu_softc *sc = &tu_softc[ms->ms_unit]; 924756Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 932980Swnj 947430Skre htaddr->httc = sn; 954756Swnj if (htaddr->htdt & HTDT_SPR) { 964756Swnj sc->sc_mi = mi; 977430Skre sc->sc_slave = sn; 984756Swnj tutoht[ms->ms_unit] = mi->mi_unit; 994756Swnj return (1); 1004756Swnj } else 1014756Swnj return (0); 1022980Swnj } 1032980Swnj 10422Sbill htopen(dev, flag) 1052926Swnj dev_t dev; 1062926Swnj int flag; 10722Sbill { 1083094Swnj register int tuunit; 1092980Swnj register struct mba_device *mi; 1103094Swnj register struct tu_softc *sc; 1113203Swnj int olddens, dens; 11222Sbill 1133094Swnj tuunit = TUUNIT(dev); 1143094Swnj if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf || 1158580Sroot (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) 1168580Sroot return (ENXIO); 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); 1258580Sroot return (EIO); 1262926Swnj } 1273707Sroot if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 1283717Sroot uprintf("tu%d: no write ring\n", tuunit); 1298580Sroot return (EIO); 1303707Sroot } 1313707Sroot if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) && 1323707Sroot dens != sc->sc_dens) { 1333717Sroot uprintf("tu%d: can't change density in mid-tape\n", tuunit); 1348580Sroot return (EIO); 1353707Sroot } 1362926Swnj sc->sc_openf = 1; 1372926Swnj sc->sc_blkno = (daddr_t)0; 1382926Swnj sc->sc_nxrec = INF; 1392926Swnj sc->sc_flags = 0; 1403094Swnj sc->sc_dens = dens; 1418580Sroot return (0); 14222Sbill } 14322Sbill 14422Sbill htclose(dev, flag) 1452926Swnj register dev_t dev; 1462926Swnj register flag; 14722Sbill { 1483094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 14922Sbill 1502926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1512926Swnj htcommand(dev, HT_WEOF, 1); 1522926Swnj htcommand(dev, HT_WEOF, 1); 1532926Swnj htcommand(dev, HT_SREV, 1); 15422Sbill } 1552926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1562926Swnj htcommand(dev, HT_REW, 0); 1572926Swnj sc->sc_openf = 0; 15822Sbill } 15922Sbill 1602926Swnj htcommand(dev, com, count) 1612926Swnj dev_t dev; 1622926Swnj int com, count; 16322Sbill { 16422Sbill register struct buf *bp; 1655436Sroot register int s; 16622Sbill 1672926Swnj bp = &chtbuf[HTUNIT(dev)]; 1685436Sroot s = spl5(); 1692926Swnj while (bp->b_flags&B_BUSY) { 1703157Swnj if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 1712980Swnj break; 17222Sbill bp->b_flags |= B_WANTED; 17322Sbill sleep((caddr_t)bp, PRIBIO); 17422Sbill } 1752943Swnj bp->b_flags = B_BUSY|B_READ; 1765436Sroot splx(s); 17722Sbill bp->b_dev = dev; 1782926Swnj bp->b_command = com; 1792926Swnj bp->b_repcnt = count; 18022Sbill bp->b_blkno = 0; 18122Sbill htstrategy(bp); 1822926Swnj if (count == 0) 1832926Swnj return; 18422Sbill iowait(bp); 1852926Swnj if (bp->b_flags&B_WANTED) 18622Sbill wakeup((caddr_t)bp); 1872926Swnj bp->b_flags &= B_ERROR; 18822Sbill } 18922Sbill 19022Sbill htstrategy(bp) 1912926Swnj register struct buf *bp; 19222Sbill { 1933094Swnj register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)]; 1942926Swnj register struct buf *dp; 1955436Sroot register int s; 19622Sbill 19722Sbill bp->av_forw = NULL; 1982926Swnj dp = &mi->mi_tab; 1995436Sroot s = 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); 2075436Sroot splx(s); 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)]) { 2367379Ssam if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 2372926Swnj bp->b_flags |= B_ERROR; 2382926Swnj bp->b_error = ENXIO; 2392961Swnj return (MBU_NEXT); 2403094Swnj } 2417379Ssam if (bdbtofsb(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) 2487379Ssam sc->sc_nxrec = bdbtofsb(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 } 2597379Ssam if ((blkno = sc->sc_blkno) == bdbtofsb(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; 2726812Swnj bp->b_flags |= B_ERROR; 2732926Swnj return (MBU_NEXT); 2742926Swnj } 27522Sbill } 2762926Swnj return (MBU_DODATA); 27722Sbill } 2787379Ssam if (blkno < bdbtofsb(bp->b_blkno)) { 2797379Ssam htaddr->htfc = blkno - bdbtofsb(bp->b_blkno); 2802926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 28122Sbill } else { 2827379Ssam htaddr->htfc = bdbtofsb(bp->b_blkno) - blkno; 2832926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 28422Sbill } 2852926Swnj return (MBU_STARTED); 28622Sbill } 28722Sbill 2883094Swnj htdtint(mi, mbsr) 2892980Swnj register struct mba_device *mi; 2903094Swnj int mbsr; 29122Sbill { 2922926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 2932926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2943094Swnj register struct tu_softc *sc; 2952961Swnj int ds, er, mbs; 29622Sbill 2973094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 2982926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 2992926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 3002926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 3013094Swnj mbs = mbsr; 3022926Swnj sc->sc_blkno++; 3032926Swnj if((bp->b_flags & B_READ) == 0) 3042926Swnj sc->sc_flags |= H_WRITTEN; 3053094Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { 3062926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3072961Swnj mbclrattn(mi); 3082961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 3092926Swnj er &= ~HTER_FCE; 3103094Swnj mbs &= ~(MBSR_DTABT|MBSR_MBEXC); 3114276Sroot } 3122926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 3132926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 3143094Swnj if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || 3152961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 3162926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3172926Swnj sc->sc_openf = -1; 3183157Swnj if ((er&HTER_HARD) == HTER_FCE && 3193157Swnj (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && 3203157Swnj (ds&HTDS_MOL)) 3213157Swnj goto noprint; 3223204Swnj printf("tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", 3232980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3243094Swnj mbsr, mbsr_bits, 3253204Swnj sc->sc_erreg, hter_bits, 3263204Swnj sc->sc_dsreg, htds_bits); 3273157Swnj noprint: 32822Sbill bp->b_flags |= B_ERROR; 3292926Swnj return (MBD_DONE); 33022Sbill } 3312926Swnj if (er) 3322926Swnj return (MBD_RETRY); 33322Sbill } 3342926Swnj bp->b_resid = 0; 3352926Swnj if (bp->b_flags & B_READ) 3362926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 3372926Swnj bp->b_resid = bp->b_bcount; 3387379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno); 3392926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 3402926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 3412926Swnj return (MBD_DONE); 3422926Swnj } 34322Sbill 3442926Swnj htndtint(mi) 3452980Swnj register struct mba_device *mi; 3462926Swnj { 3472926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3482926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3493094Swnj register struct tu_softc *sc; 3502926Swnj int er, ds, fc; 35122Sbill 3523094Swnj ds = MASKREG(htaddr->htds); 3533094Swnj er = MASKREG(htaddr->hter); 3543094Swnj fc = MASKREG(htaddr->htfc); 3553094Swnj if (er) { 3562926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3572961Swnj mbclrattn(mi); 3582961Swnj } 3593094Swnj if (bp == 0) 3603094Swnj return (MBN_SKIP); 3613094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3623094Swnj sc->sc_dsreg = ds; 3633094Swnj sc->sc_erreg = er; 3643094Swnj sc->sc_resid = fc; 3653094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3663094Swnj switch (bp->b_command) { 3673094Swnj case HT_REWOFFL: 3682926Swnj /* offline is on purpose; don't do anything special */ 3692926Swnj ds |= HTDS_MOL; 3703094Swnj break; 3713094Swnj case HT_SREV: 3723094Swnj /* if backspace file hit bot, its not an error */ 3733094Swnj if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && 3743094Swnj bp->b_repcnt == INF) 3753094Swnj er &= ~HTER_NEF; 3763094Swnj break; 3773094Swnj } 3782926Swnj er &= ~HTER_FCE; 3792926Swnj if (er == 0) 3802926Swnj ds &= ~HTDS_ERR; 38122Sbill } 3822926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3832926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3842926Swnj sc->sc_openf = -1; 3853204Swnj printf("tu%d: hard error bn%d er=%b ds=%b\n", 3862980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3873204Swnj sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); 3882926Swnj bp->b_flags |= B_ERROR; 3892926Swnj return (MBN_DONE); 3902926Swnj } 3913094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3922926Swnj if (sc->sc_flags & H_REWIND) 3932926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 3942926Swnj bp->b_resid = -sc->sc_resid; 3952926Swnj return (MBN_DONE); 3962926Swnj } 3972926Swnj if (ds & HTDS_TM) 3987379Ssam if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 3997379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; 4002926Swnj sc->sc_blkno = sc->sc_nxrec; 4013094Swnj } else { 4027379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno) + fc; 4032926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 4042926Swnj } 4052926Swnj else 4067379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno); 4072926Swnj return (MBN_RETRY); 40822Sbill } 40922Sbill 4107739Sroot htread(dev, uio) 4112926Swnj dev_t dev; 4127739Sroot struct uio *uio; 41322Sbill { 4148157Sroot int errno; 4152926Swnj 4168157Sroot errno = htphys(dev, uio); 4178157Sroot if (errno) 4188157Sroot return (errno); 4198157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys, uio)); 42022Sbill } 42122Sbill 422*8605Sroot htwrite(dev, uio) 423*8605Sroot dev_t dev; 424*8605Sroot struct uio uio; 42522Sbill { 4268157Sroot int errno; 4272926Swnj 4288157Sroot errno = htphys(dev, uio); 4298157Sroot if (errno) 4308157Sroot return (errno); 4318157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys, uio)); 43222Sbill } 43322Sbill 4347739Sroot htphys(dev, uio) 4352926Swnj dev_t dev; 4367739Sroot struct uio *uio; 43722Sbill { 4383094Swnj register int htunit; 4393094Swnj register struct tu_softc *sc; 4403094Swnj register struct mba_device *mi; 44122Sbill daddr_t a; 44222Sbill 4433094Swnj htunit = HTUNIT(dev); 4447832Sroot if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) 4457739Sroot return (ENXIO); 4467832Sroot a = uio->uio_offset >> 9; 4473094Swnj sc = &tu_softc[TUUNIT(dev)]; 4487379Ssam sc->sc_blkno = bdbtofsb(a); 4497379Ssam sc->sc_nxrec = bdbtofsb(a)+1; 4507739Sroot return (0); 45122Sbill } 4521917Swnj 4532926Swnj /*ARGSUSED*/ 4547636Ssam htioctl(dev, cmd, data, flag) 4552926Swnj dev_t dev; 4562926Swnj int cmd; 4577636Ssam caddr_t data; 4582926Swnj int flag; 4592926Swnj { 4603094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 4613094Swnj register struct buf *bp = &chtbuf[HTUNIT(dev)]; 4622926Swnj register callcount; 4632926Swnj int fcount; 4647636Ssam struct mtop *mtop; 4657636Ssam struct mtget *mtget; 4662926Swnj /* we depend of the values and order of the MT codes here */ 4672926Swnj static htops[] = 4682926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4691917Swnj 4702926Swnj switch (cmd) { 4717636Ssam 4727636Ssam case MTIOCTOP: /* tape operation */ 4737636Ssam mtop = (struct mtop *)data; 4747636Ssam switch (mtop->mt_op) { 4757636Ssam 4762926Swnj case MTWEOF: 4777636Ssam callcount = mtop->mt_count; 4782926Swnj fcount = 1; 4792926Swnj break; 4807636Ssam 4812926Swnj case MTFSF: case MTBSF: 4827636Ssam callcount = mtop->mt_count; 4832926Swnj fcount = INF; 4842926Swnj break; 4857636Ssam 4862926Swnj case MTFSR: case MTBSR: 4872926Swnj callcount = 1; 4887636Ssam fcount = mtop->mt_count; 4892926Swnj break; 4907636Ssam 4912926Swnj case MTREW: case MTOFFL: 4922926Swnj callcount = 1; 4932926Swnj fcount = 1; 4942926Swnj break; 4957636Ssam 4962926Swnj default: 4978580Sroot return (ENXIO); 4982926Swnj } 4998580Sroot if (callcount <= 0 || fcount <= 0) 5008580Sroot return (EINVAL); 5012926Swnj while (--callcount >= 0) { 5027636Ssam htcommand(dev, htops[mtop->mt_op], fcount); 5037636Ssam if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 5048580Sroot bp->b_resid) 5058580Sroot return (EIO); 5063094Swnj if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) 5072926Swnj break; 5082926Swnj } 5098580Sroot geterror(bp); /* XXX */ 5108580Sroot return (u.u_error); /* XXX */ 5117636Ssam 5122926Swnj case MTIOCGET: 5137636Ssam mtget = (struct mtget *)data; 5147636Ssam mtget->mt_dsreg = sc->sc_dsreg; 5157636Ssam mtget->mt_erreg = sc->sc_erreg; 5167636Ssam mtget->mt_resid = sc->sc_resid; 5177636Ssam mtget->mt_type = MT_ISHT; 5188580Sroot break; 5197636Ssam 5202926Swnj default: 5218580Sroot return (ENXIO); 5222926Swnj } 5238580Sroot return (0); 5242926Swnj } 5252926Swnj 5261917Swnj #define DBSIZE 20 5271917Swnj 5282926Swnj htdump() 5291917Swnj { 5302980Swnj register struct mba_device *mi; 5312926Swnj register struct mba_regs *mp; 5322926Swnj register struct htdevice *htaddr; 5332926Swnj int blk, num; 5342926Swnj int start; 5351917Swnj 5362926Swnj start = 0; 5372926Swnj num = maxfree; 5382926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 5392926Swnj if (htinfo[0] == 0) 5402926Swnj return (ENXIO); 5412980Swnj mi = phys(htinfo[0], struct mba_device *); 5422926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 5433157Swnj mp->mba_cr = MBCR_IE; 5442926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 5452926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 5462926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 5471917Swnj while (num > 0) { 5481917Swnj blk = num > DBSIZE ? DBSIZE : num; 5492926Swnj htdwrite(start, blk, htaddr, mp); 5502926Swnj start += blk; 5511917Swnj num -= blk; 5521917Swnj } 5533157Swnj hteof(htaddr); 5543157Swnj hteof(htaddr); 5552926Swnj htwait(htaddr); 5563181Swnj if (htaddr->htds&HTDS_ERR) 5573157Swnj return (EIO); 5582926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5593103Swnj return (0); 5601917Swnj } 5611917Swnj 5622926Swnj htdwrite(dbuf, num, htaddr, mp) 5632926Swnj register dbuf, num; 5642926Swnj register struct htdevice *htaddr; 5652926Swnj struct mba_regs *mp; 5661917Swnj { 5672926Swnj register struct pte *io; 5681917Swnj register int i; 5691917Swnj 5702926Swnj htwait(htaddr); 5712926Swnj io = mp->mba_map; 5721917Swnj for (i = 0; i < num; i++) 5732926Swnj *(int *)io++ = dbuf++ | PG_V; 5742926Swnj htaddr->htfc = -(num*NBPG); 5752926Swnj mp->mba_sr = -1; 5762926Swnj mp->mba_bcr = -(num*NBPG); 5772926Swnj mp->mba_var = 0; 5782926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5791917Swnj } 5801917Swnj 5812926Swnj htwait(htaddr) 5822926Swnj struct htdevice *htaddr; 5831917Swnj { 5841917Swnj register s; 5851917Swnj 5861917Swnj do 5872926Swnj s = htaddr->htds; 5882926Swnj while ((s & HTDS_DRY) == 0); 5891917Swnj } 5901917Swnj 5912926Swnj hteof(htaddr) 5922926Swnj struct htdevice *htaddr; 5931917Swnj { 5941917Swnj 5952926Swnj htwait(htaddr); 5962926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 5971917Swnj } 5981563Sbill #endif 599