1*2961Swnj /* ht.c 4.7 81/03/07 */ 2*2961Swnj 31936Swnj #include "ht.h" 41563Sbill #if NHT > 0 522Sbill /* 62926Swnj * TM03/TU?? tape driver 722Sbill */ 822Sbill #include "../h/param.h" 922Sbill #include "../h/systm.h" 1022Sbill #include "../h/buf.h" 1122Sbill #include "../h/conf.h" 1222Sbill #include "../h/dir.h" 1322Sbill #include "../h/file.h" 1422Sbill #include "../h/user.h" 1522Sbill #include "../h/map.h" 16420Sbill #include "../h/pte.h" 1722Sbill #include "../h/mba.h" 182926Swnj #include "../h/mtio.h" 192926Swnj #include "../h/ioctl.h" 201917Swnj #include "../h/cmap.h" 21*2961Swnj #include "../h/cpu.h" 2222Sbill 232926Swnj #include "../h/htreg.h" 2422Sbill 252926Swnj struct buf rhtbuf[NHT]; 262926Swnj struct buf chtbuf[NHT]; 2722Sbill 282926Swnj short httypes[] = 292926Swnj { MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 302926Swnj struct mba_info *htinfo[NHT]; 312926Swnj int htdkinit(), htustart(), htndtint(), htdtint(); 322926Swnj struct mba_driver htdriver = 332926Swnj { htdkinit, htustart, 0, htdtint, htndtint, httypes, htinfo }; 3422Sbill 352926Swnj #define MASKREG(r) ((r) & 0xffff) 3622Sbill 372926Swnj /* bits in minor device */ 382926Swnj #define HTUNIT(dev) (minor(dev)&03) 392926Swnj #define H_NOREWIND 04 402926Swnj #define H_1600BPI 08 4122Sbill 422926Swnj #define INF (daddr_t)1000000L /* a block number that wont exist */ 432926Swnj 442926Swnj struct ht_softc { 452926Swnj char sc_openf; 462926Swnj char sc_flags; 472926Swnj daddr_t sc_blkno; 482926Swnj daddr_t sc_nxrec; 492926Swnj u_short sc_erreg; 502926Swnj u_short sc_dsreg; 512926Swnj short sc_resid; 522926Swnj short sc_dens; 532926Swnj } ht_softc[NHT]; 542926Swnj 552926Swnj /* 562926Swnj * Bits for sc_flags. 572926Swnj */ 582926Swnj #define H_WRITTEN 1 /* last operation was a write */ 592926Swnj #define H_ERASED 2 /* last write retry was an erase gap */ 602926Swnj #define H_REWIND 4 /* last unit start was a rewind */ 6122Sbill 622926Swnj /*ARGSUSED*/ 632926Swnj htdkinit(mi) 642926Swnj struct mba_info *mi; 652926Swnj { 662926Swnj 672926Swnj } 682926Swnj 6922Sbill htopen(dev, flag) 702926Swnj dev_t dev; 712926Swnj int flag; 7222Sbill { 732926Swnj register int unit; 742926Swnj register struct mba_info *mi; 752926Swnj register struct ht_softc *sc; 7622Sbill 772926Swnj unit = HTUNIT(dev); 782926Swnj if (unit >= NHT || (sc = &ht_softc[unit])->sc_openf || 792926Swnj (mi = htinfo[unit]) == 0 || mi->mi_alive == 0) { 8022Sbill u.u_error = ENXIO; 8122Sbill return; 8222Sbill } 832926Swnj /* 842926Swnj * The NOP below serves two purposes: 852926Swnj * 1. To get a recent copy of the status registers. 862926Swnj * 2. To ensure that any outstanding rewinds are truly finished 872926Swnj */ 882926Swnj htcommand(dev, HT_SENSE, 1); 892926Swnj if ((sc->sc_dsreg & HTDS_MOL) == 0 || 902926Swnj (flag & (FREAD|FWRITE)) == FWRITE && sc->sc_dsreg&HTDS_WRL) { 912926Swnj u.u_error = EIO; 922926Swnj return; 932926Swnj } 942926Swnj sc->sc_dens = 95*2961Swnj ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)| 96*2961Swnj HTTC_PDP11|mi->mi_slave; 972926Swnj sc->sc_openf = 1; 982926Swnj sc->sc_blkno = (daddr_t)0; 992926Swnj sc->sc_nxrec = INF; 1002926Swnj sc->sc_flags = 0; 10122Sbill } 10222Sbill 10322Sbill htclose(dev, flag) 1042926Swnj register dev_t dev; 1052926Swnj register flag; 10622Sbill { 1072926Swnj register struct ht_softc *sc = &ht_softc[HTUNIT(dev)]; 10822Sbill 1092926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1102926Swnj htcommand(dev, HT_WEOF, 1); 1112926Swnj htcommand(dev, HT_WEOF, 1); 1122926Swnj htcommand(dev, HT_SREV, 1); 11322Sbill } 1142926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1152926Swnj /* 0 as third arg means don't wait */ 1162926Swnj htcommand(dev, HT_REW, 0); 1172926Swnj sc->sc_openf = 0; 11822Sbill } 11922Sbill 1202926Swnj /* 1212926Swnj * Do a non-data-transfer command. 1222926Swnj * 1232926Swnj * N.B.: Count should be zero ONLY for rewind during close. 1242926Swnj */ 1252926Swnj htcommand(dev, com, count) 1262926Swnj dev_t dev; 1272926Swnj int com, count; 12822Sbill { 12922Sbill register struct buf *bp; 13022Sbill 1312926Swnj bp = &chtbuf[HTUNIT(dev)]; 132128Sbill (void) spl5(); 1332926Swnj while (bp->b_flags&B_BUSY) { 13422Sbill bp->b_flags |= B_WANTED; 13522Sbill sleep((caddr_t)bp, PRIBIO); 13622Sbill } 1372943Swnj bp->b_flags = B_BUSY|B_READ; 138128Sbill (void) spl0(); 13922Sbill bp->b_dev = dev; 1402926Swnj bp->b_command = com; 1412926Swnj bp->b_repcnt = count; 14222Sbill bp->b_blkno = 0; 14322Sbill htstrategy(bp); 1442926Swnj if (count == 0) 1452926Swnj return; 14622Sbill iowait(bp); 1472926Swnj if (bp->b_flags&B_WANTED) 14822Sbill wakeup((caddr_t)bp); 1492926Swnj bp->b_flags &= B_ERROR; 15022Sbill } 15122Sbill 15222Sbill htstrategy(bp) 1532926Swnj register struct buf *bp; 15422Sbill { 1552926Swnj register int unit = HTUNIT(bp->b_dev); 1562943Swnj register struct mba_info *mi = htinfo[unit]; 1572926Swnj register struct buf *dp; 15822Sbill 15922Sbill bp->av_forw = NULL; 1602926Swnj dp = &mi->mi_tab; 161128Sbill (void) spl5(); 1622926Swnj if (dp->b_actf == NULL) 1632926Swnj dp->b_actf = bp; 16422Sbill else 1652926Swnj dp->b_actl->av_forw = bp; 1662926Swnj dp->b_actl = bp; 1672926Swnj if (dp->b_active == 0) 1682926Swnj mbustart(mi); 169128Sbill (void) spl0(); 17022Sbill } 17122Sbill 1722926Swnj htustart(mi) 1732926Swnj register struct mba_info *mi; 17422Sbill { 1752926Swnj register struct htdevice *htaddr = 1762926Swnj (struct htdevice *)mi->mi_drv; 1772926Swnj register struct buf *bp = mi->mi_tab.b_actf; 1782926Swnj int unit = HTUNIT(bp->b_dev); 1792926Swnj register struct ht_softc *sc = &ht_softc[unit]; 18022Sbill daddr_t blkno; 18122Sbill 1822926Swnj htaddr->httc = sc->sc_dens; 1832926Swnj sc->sc_dsreg = htaddr->htds; 1842926Swnj sc->sc_erreg = htaddr->hter; 1852926Swnj sc->sc_resid = htaddr->htfc; 1862926Swnj sc->sc_flags &= ~(H_WRITTEN|H_REWIND); 1872926Swnj if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) 1882926Swnj if (sc->sc_openf > 0) 1892926Swnj sc->sc_openf = -1; 1902926Swnj if (sc->sc_openf < 0) { 1912926Swnj bp->b_flags |= B_ERROR; 1922926Swnj return (MBU_NEXT); 1932926Swnj } 1942926Swnj if (bp != &chtbuf[unit]) { 1952926Swnj if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) { 1962926Swnj bp->b_flags |= B_ERROR; 1972926Swnj bp->b_error = ENXIO; 198*2961Swnj return (MBU_NEXT); 1992926Swnj } else if (dbtofsb(bp->b_blkno) == sc->sc_nxrec && 2002926Swnj bp->b_flags&B_READ) { 2012926Swnj bp->b_resid = bp->b_bcount; 2022926Swnj clrbuf(bp); 203*2961Swnj return (MBU_NEXT); 2042926Swnj } else if ((bp->b_flags&B_READ)==0) 2052926Swnj sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1; 2062926Swnj } else { 207*2961Swnj if (bp->b_command == HT_SENSE) 2082926Swnj return (MBU_NEXT); 2092926Swnj if (bp->b_command == HT_REW) 2102926Swnj sc->sc_flags |= H_REWIND; 2112926Swnj else 2122926Swnj htaddr->htfc = -bp->b_bcount; 2132926Swnj htaddr->htcs1 = bp->b_command|HT_GO; 2142926Swnj return (MBU_STARTED); 2152926Swnj } 2162926Swnj if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) { 2172926Swnj htaddr->htfc = -bp->b_bcount; 2182926Swnj if ((bp->b_flags&B_READ) == 0) { 2192926Swnj if (mi->mi_tab.b_errcnt) 2202926Swnj if (sc->sc_flags & H_ERASED) 2212926Swnj sc->sc_flags &= ~H_ERASED; 2222926Swnj else { 2232926Swnj sc->sc_flags |= H_ERASED; 2242926Swnj htaddr->htcs1 = HT_ERASE | HT_GO; 2252926Swnj return (MBU_STARTED); 2262926Swnj } 2272926Swnj if (htaddr->htds & HTDS_EOT) { 2282926Swnj bp->b_resid = bp->b_bcount; 2292926Swnj return (MBU_NEXT); 2302926Swnj } 23122Sbill } 2322926Swnj return (MBU_DODATA); 23322Sbill } 2342926Swnj if (blkno < dbtofsb(bp->b_blkno)) { 2352926Swnj htaddr->htfc = blkno - dbtofsb(bp->b_blkno); 2362926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 23722Sbill } else { 2382926Swnj htaddr->htfc = dbtofsb(bp->b_blkno) - blkno; 2392926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 24022Sbill } 2412926Swnj return (MBU_STARTED); 24222Sbill } 24322Sbill 2442926Swnj /* 2452926Swnj * data transfer interrupt - must be read or write 2462926Swnj */ 24722Sbill /*ARGSUSED*/ 2482926Swnj htdtint(mi, mbasr) 2492926Swnj register struct mba_info *mi; 2502926Swnj int mbasr; 25122Sbill { 2522926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 2532926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2542926Swnj register struct ht_softc *sc; 255*2961Swnj int ds, er, mbs; 25622Sbill 2572926Swnj sc = &ht_softc[HTUNIT(bp->b_dev)]; 2582926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 2592926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 2602926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 261*2961Swnj mbs = mbasr; 2622926Swnj sc->sc_blkno++; 2632926Swnj if((bp->b_flags & B_READ) == 0) 2642926Swnj sc->sc_flags |= H_WRITTEN; 2652926Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || 266*2961Swnj mbs & MBAEBITS) { 2672926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 268*2961Swnj mbclrattn(mi); 269*2961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 2702926Swnj er &= ~HTER_FCE; 271*2961Swnj mbs &= ~(MBS_DTABT|MBS_MBEXC); 272*2961Swnj } 2732926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 2742926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 2752926Swnj if (er&HTER_HARD || 276*2961Swnj mbs&MBAEBITS || (ds&HTDS_MOL) == 0 || 277*2961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 2782926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 2792926Swnj sc->sc_openf = -1; 2802926Swnj printf("ht%d: hard error bn%d mbasr=%b er=%b\n", 2812926Swnj HTUNIT(bp->b_dev), bp->b_blkno, 2822926Swnj mbasr, mbasr_bits, 2832926Swnj MASKREG(htaddr->hter), HTER_BITS); 28422Sbill bp->b_flags |= B_ERROR; 2852926Swnj return (MBD_DONE); 28622Sbill } 2872926Swnj if (er) 2882926Swnj return (MBD_RETRY); 28922Sbill } 2902926Swnj bp->b_resid = 0; 2912926Swnj if (bp->b_flags & B_READ) 2922926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 2932926Swnj bp->b_resid = bp->b_bcount; 2942926Swnj sc->sc_nxrec = dbtofsb(bp->b_blkno); 2952926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 2962926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 2972926Swnj return (MBD_DONE); 2982926Swnj } 29922Sbill 3002926Swnj /* 3012926Swnj * non-data-transfer interrupt 3022926Swnj */ 3032926Swnj htndtint(mi) 3042926Swnj register struct mba_info *mi; 3052926Swnj { 3062926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3072926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3082926Swnj register struct ht_softc *sc; 3092926Swnj int er, ds, fc; 31022Sbill 3112926Swnj sc = &ht_softc[HTUNIT(bp->b_dev)]; 3122926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 3132926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 314*2961Swnj fc = sc->sc_resid = MASKREG(htaddr->htfc); 315*2961Swnj if (sc->sc_erreg) { 3162926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 317*2961Swnj mbclrattn(mi); 318*2961Swnj } 3192926Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3202926Swnj if (bp->b_command == HT_REWOFFL) 3212926Swnj /* offline is on purpose; don't do anything special */ 3222926Swnj ds |= HTDS_MOL; 3232926Swnj else if (bp->b_resid == HT_SREV && 3242926Swnj er == (HTER_NEF|HTER_FCE) && 3252926Swnj ds&HTDS_BOT && bp->b_bcount == INF) 3262926Swnj er &= ~HTER_NEF; 3272926Swnj er &= ~HTER_FCE; 3282926Swnj if (er == 0) 3292926Swnj ds &= ~HTDS_ERR; 33022Sbill } 3312926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3322926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3332926Swnj sc->sc_openf = -1; 3342926Swnj printf("ht%d: hard error bn%d er=%b ds=%b\n", 3352926Swnj HTUNIT(bp->b_dev), bp->b_blkno, 3362926Swnj sc->sc_erreg, HTER_BITS, sc->sc_dsreg, HTDS_BITS); 3372926Swnj bp->b_flags |= B_ERROR; 3382926Swnj return (MBN_DONE); 3392926Swnj } 3402926Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3412926Swnj if (sc->sc_flags & H_REWIND) 3422926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 3432926Swnj bp->b_resid = -sc->sc_resid; 3442926Swnj return (MBN_DONE); 3452926Swnj } 3462926Swnj if (ds & HTDS_TM) 3472926Swnj if (sc->sc_blkno > dbtofsb(bp->b_blkno)) {/* reversing */ 3482926Swnj sc->sc_nxrec = dbtofsb(bp->b_blkno) - fc; 3492926Swnj sc->sc_blkno = sc->sc_nxrec; 3502926Swnj } else { /* spacing forward */ 3512926Swnj sc->sc_blkno = dbtofsb(bp->b_blkno) + fc; 3522926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 3532926Swnj } 3542926Swnj else 3552926Swnj sc->sc_blkno = dbtofsb(bp->b_blkno); 3562926Swnj return (MBN_RETRY); 35722Sbill } 35822Sbill 35922Sbill htread(dev) 3602926Swnj dev_t dev; 36122Sbill { 3622926Swnj 36322Sbill htphys(dev); 3642926Swnj if (u.u_error) 3652926Swnj return; 3662926Swnj physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys); 36722Sbill } 36822Sbill 36922Sbill htwrite(dev) 37022Sbill { 3712926Swnj 37222Sbill htphys(dev); 3732926Swnj if (u.u_error) 3742926Swnj return; 3752926Swnj physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys); 37622Sbill } 37722Sbill 37822Sbill htphys(dev) 3792926Swnj dev_t dev; 38022Sbill { 3812926Swnj register int unit; 3822926Swnj register struct ht_softc *sc; 38322Sbill daddr_t a; 38422Sbill 3852926Swnj unit = HTUNIT(dev); 3862926Swnj if (unit >= NHT) { 3872926Swnj u.u_error = ENXIO; 3882926Swnj return; 38922Sbill } 3902926Swnj a = u.u_offset >> 9; 3912926Swnj sc = &ht_softc[unit]; 3922926Swnj sc->sc_blkno = dbtofsb(a); 3932926Swnj sc->sc_nxrec = dbtofsb(a)+1; 39422Sbill } 3951917Swnj 3962926Swnj /*ARGSUSED*/ 3972926Swnj htioctl(dev, cmd, addr, flag) 3982926Swnj dev_t dev; 3992926Swnj int cmd; 4002926Swnj caddr_t addr; 4012926Swnj int flag; 4022926Swnj { 4032926Swnj register unit = HTUNIT(dev); 4042926Swnj register struct ht_softc *sc = &ht_softc[unit]; 4052926Swnj register struct buf *bp = &chtbuf[unit]; 4062926Swnj register callcount; 4072926Swnj int fcount; 4082926Swnj struct mtop mtop; 4092926Swnj struct mtget mtget; 4102926Swnj /* we depend of the values and order of the MT codes here */ 4112926Swnj static htops[] = 4122926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4131917Swnj 4142926Swnj switch (cmd) { 4152926Swnj case MTIOCTOP: /* tape operation */ 4162926Swnj if (copyin((caddr_t)addr, (caddr_t)&mtop, sizeof(mtop))) { 4172926Swnj u.u_error = EFAULT; 4182926Swnj return; 4192926Swnj } 4202926Swnj switch(mtop.mt_op) { 4212926Swnj case MTWEOF: 4222926Swnj callcount = mtop.mt_count; 4232926Swnj fcount = 1; 4242926Swnj break; 4252926Swnj case MTFSF: case MTBSF: 4262926Swnj callcount = mtop.mt_count; 4272926Swnj fcount = INF; 4282926Swnj break; 4292926Swnj case MTFSR: case MTBSR: 4302926Swnj callcount = 1; 4312926Swnj fcount = mtop.mt_count; 4322926Swnj break; 4332926Swnj case MTREW: case MTOFFL: 4342926Swnj callcount = 1; 4352926Swnj fcount = 1; 4362926Swnj break; 4372926Swnj default: 4382926Swnj u.u_error = ENXIO; 4392926Swnj return; 4402926Swnj } 4412926Swnj if (callcount <= 0 || fcount <= 0) { 4422926Swnj u.u_error = ENXIO; 4432926Swnj return; 4442926Swnj } 4452926Swnj while (--callcount >= 0) { 4462926Swnj htcommand(dev, htops[mtop.mt_op], fcount); 4472926Swnj if ((mtop.mt_op == MTFSR || mtop.mt_op == MTBSR) && 4482926Swnj bp->b_resid) { 4492926Swnj u.u_error = EIO; 4502926Swnj break; 4512926Swnj } 4522926Swnj if ((chtbuf[HTUNIT(bp->b_dev)].b_flags&B_ERROR) || 4532926Swnj sc->sc_dsreg&HTDS_BOT) 4542926Swnj break; 4552926Swnj } 4562926Swnj geterror(bp); 4572926Swnj return; 4582926Swnj case MTIOCGET: 4592926Swnj mtget.mt_dsreg = sc->sc_dsreg; 4602926Swnj mtget.mt_erreg = sc->sc_erreg; 4612926Swnj mtget.mt_resid = sc->sc_resid; 4622926Swnj if (copyout((caddr_t)&mtget, addr, sizeof(mtget))) 4632926Swnj u.u_error = EFAULT; 4642926Swnj return; 4652926Swnj default: 4662926Swnj u.u_error = ENXIO; 4672926Swnj } 4682926Swnj } 4692926Swnj 4701917Swnj #define DBSIZE 20 4711917Swnj 4722926Swnj htdump() 4731917Swnj { 4742926Swnj register struct mba_info *mi; 4752926Swnj register struct mba_regs *mp; 4762926Swnj register struct htdevice *htaddr; 4772926Swnj int blk, num; 4782926Swnj int start; 4791917Swnj 4802926Swnj start = 0; 4812926Swnj num = maxfree; 4822926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 4832926Swnj if (htinfo[0] == 0) 4842926Swnj return (ENXIO); 4852926Swnj mi = phys(htinfo[0], struct mba_info *); 4862926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 4872926Swnj #if VAX780 488*2961Swnj if (cpu == VAX780) 489*2961Swnj mbainit(mp); 490*2961Swnj #endif 4912926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 4922926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 4932926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 4941917Swnj while (num > 0) { 4951917Swnj blk = num > DBSIZE ? DBSIZE : num; 4962926Swnj htdwrite(start, blk, htaddr, mp); 4972926Swnj start += blk; 4981917Swnj num -= blk; 4991917Swnj } 5002926Swnj htwait(htaddr); 5012926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5022926Swnj hteof(htaddr); 5032926Swnj hteof(htaddr); 5041917Swnj } 5051917Swnj 5062926Swnj htdwrite(dbuf, num, htaddr, mp) 5072926Swnj register dbuf, num; 5082926Swnj register struct htdevice *htaddr; 5092926Swnj struct mba_regs *mp; 5101917Swnj { 5112926Swnj register struct pte *io; 5121917Swnj register int i; 5131917Swnj 5142926Swnj htwait(htaddr); 5152926Swnj io = mp->mba_map; 5161917Swnj for (i = 0; i < num; i++) 5172926Swnj *(int *)io++ = dbuf++ | PG_V; 5182926Swnj htaddr->htfc = -(num*NBPG); 5192926Swnj mp->mba_sr = -1; 5202926Swnj mp->mba_bcr = -(num*NBPG); 5212926Swnj mp->mba_var = 0; 5222926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5231917Swnj } 5241917Swnj 5252926Swnj htwait(htaddr) 5262926Swnj struct htdevice *htaddr; 5271917Swnj { 5281917Swnj register s; 5291917Swnj 5301917Swnj do 5312926Swnj s = htaddr->htds; 5322926Swnj while ((s & HTDS_DRY) == 0); 5331917Swnj } 5341917Swnj 5352926Swnj hteof(htaddr) 5362926Swnj struct htdevice *htaddr; 5371917Swnj { 5381917Swnj 5392926Swnj htwait(htaddr); 5402926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 5411917Swnj } 5421563Sbill #endif 543