1*9787Ssam /* ht.c 4.35 82/12/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 */ 14*9787Ssam #include "../machine/pte.h" 15*9787Ssam 1622Sbill #include "../h/param.h" 1722Sbill #include "../h/systm.h" 1822Sbill #include "../h/buf.h" 1922Sbill #include "../h/conf.h" 2022Sbill #include "../h/dir.h" 2122Sbill #include "../h/file.h" 2222Sbill #include "../h/user.h" 2322Sbill #include "../h/map.h" 247636Ssam #include "../h/ioctl.h" 252926Swnj #include "../h/mtio.h" 261917Swnj #include "../h/cmap.h" 277739Sroot #include "../h/uio.h" 2822Sbill 298469Sroot #include "../vax/cpu.h" 308469Sroot #include "../vaxmba/mbareg.h" 318469Sroot #include "../vaxmba/mbavar.h" 328469Sroot #include "../vaxmba/htreg.h" 3322Sbill 342926Swnj struct buf rhtbuf[NHT]; 352926Swnj struct buf chtbuf[NHT]; 3622Sbill 372926Swnj short httypes[] = 383181Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 392980Swnj struct mba_device *htinfo[NHT]; 403103Swnj int htattach(), htslave(), htustart(), htndtint(), htdtint(); 412926Swnj struct mba_driver htdriver = 422980Swnj { htattach, htslave, htustart, 0, htdtint, htndtint, 432980Swnj httypes, "ht", "tu", htinfo }; 4422Sbill 452926Swnj #define MASKREG(r) ((r) & 0xffff) 4622Sbill 472926Swnj /* bits in minor device */ 482980Swnj #define TUUNIT(dev) (minor(dev)&03) 492926Swnj #define H_NOREWIND 04 502926Swnj #define H_1600BPI 08 5122Sbill 523094Swnj #define HTUNIT(dev) (tutoht[TUUNIT(dev)]) 532980Swnj 542926Swnj #define INF (daddr_t)1000000L /* a block number that wont exist */ 552926Swnj 563094Swnj struct tu_softc { 572926Swnj char sc_openf; 582926Swnj char sc_flags; 592926Swnj daddr_t sc_blkno; 602926Swnj daddr_t sc_nxrec; 612926Swnj u_short sc_erreg; 622926Swnj u_short sc_dsreg; 632926Swnj short sc_resid; 642926Swnj short sc_dens; 652980Swnj struct mba_device *sc_mi; 662980Swnj int sc_slave; 673094Swnj } tu_softc[NTU]; 683094Swnj short tutoht[NTU]; 692926Swnj 702926Swnj /* 712926Swnj * Bits for sc_flags. 722926Swnj */ 732926Swnj #define H_WRITTEN 1 /* last operation was a write */ 742926Swnj #define H_ERASED 2 /* last write retry was an erase gap */ 752926Swnj #define H_REWIND 4 /* last unit start was a rewind */ 7622Sbill 773204Swnj char hter_bits[] = HTER_BITS; 783204Swnj char htds_bits[] = HTDS_BITS; 793204Swnj 802926Swnj /*ARGSUSED*/ 812980Swnj htattach(mi) 822980Swnj struct mba_device *mi; 832926Swnj { 842926Swnj 852926Swnj } 862926Swnj 877430Skre htslave(mi, ms, sn) 882980Swnj struct mba_device *mi; 892980Swnj struct mba_slave *ms; 907430Skre int sn; 912980Swnj { 923094Swnj register struct tu_softc *sc = &tu_softc[ms->ms_unit]; 934756Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 942980Swnj 957430Skre htaddr->httc = sn; 964756Swnj if (htaddr->htdt & HTDT_SPR) { 974756Swnj sc->sc_mi = mi; 987430Skre sc->sc_slave = sn; 994756Swnj tutoht[ms->ms_unit] = mi->mi_unit; 1004756Swnj return (1); 1014756Swnj } else 1024756Swnj return (0); 1032980Swnj } 1042980Swnj 10522Sbill htopen(dev, flag) 1062926Swnj dev_t dev; 1072926Swnj int flag; 10822Sbill { 1093094Swnj register int tuunit; 1102980Swnj register struct mba_device *mi; 1113094Swnj register struct tu_softc *sc; 1123203Swnj int olddens, dens; 11322Sbill 1143094Swnj tuunit = TUUNIT(dev); 1153094Swnj if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf || 1168580Sroot (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) 1178580Sroot return (ENXIO); 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); 1268580Sroot return (EIO); 1272926Swnj } 1283707Sroot if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 1293717Sroot uprintf("tu%d: no write ring\n", tuunit); 1308580Sroot return (EIO); 1313707Sroot } 1323707Sroot if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) && 1333707Sroot dens != sc->sc_dens) { 1343717Sroot uprintf("tu%d: can't change density in mid-tape\n", tuunit); 1358580Sroot return (EIO); 1363707Sroot } 1372926Swnj sc->sc_openf = 1; 1382926Swnj sc->sc_blkno = (daddr_t)0; 1392926Swnj sc->sc_nxrec = INF; 1402926Swnj sc->sc_flags = 0; 1413094Swnj sc->sc_dens = dens; 1428580Sroot return (0); 14322Sbill } 14422Sbill 14522Sbill htclose(dev, flag) 1462926Swnj register dev_t dev; 1472926Swnj register flag; 14822Sbill { 1493094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 15022Sbill 1512926Swnj if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { 1522926Swnj htcommand(dev, HT_WEOF, 1); 1532926Swnj htcommand(dev, HT_WEOF, 1); 1542926Swnj htcommand(dev, HT_SREV, 1); 15522Sbill } 1562926Swnj if ((minor(dev)&H_NOREWIND) == 0) 1572926Swnj htcommand(dev, HT_REW, 0); 1582926Swnj sc->sc_openf = 0; 15922Sbill } 16022Sbill 1612926Swnj htcommand(dev, com, count) 1622926Swnj dev_t dev; 1632926Swnj int com, count; 16422Sbill { 16522Sbill register struct buf *bp; 1665436Sroot register int s; 16722Sbill 1682926Swnj bp = &chtbuf[HTUNIT(dev)]; 1695436Sroot s = 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; 1775436Sroot splx(s); 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; 1965436Sroot register int s; 19722Sbill 19822Sbill bp->av_forw = NULL; 1992926Swnj dp = &mi->mi_tab; 2005436Sroot s = spl5(); 2012926Swnj if (dp->b_actf == NULL) 2022926Swnj dp->b_actf = bp; 20322Sbill else 2042926Swnj dp->b_actl->av_forw = bp; 2052926Swnj dp->b_actl = bp; 2062926Swnj if (dp->b_active == 0) 2072926Swnj mbustart(mi); 2085436Sroot splx(s); 20922Sbill } 21022Sbill 2112926Swnj htustart(mi) 2122980Swnj register struct mba_device *mi; 21322Sbill { 2142926Swnj register struct htdevice *htaddr = 2152926Swnj (struct htdevice *)mi->mi_drv; 2162926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2173094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)]; 21822Sbill daddr_t blkno; 21922Sbill 2202926Swnj htaddr->httc = sc->sc_dens; 2213181Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) { 2223157Swnj htaddr->htcs1 = HT_SENSE|HT_GO; 2233157Swnj mbclrattn(mi); 2243157Swnj } 2252926Swnj sc->sc_dsreg = htaddr->htds; 2262926Swnj sc->sc_erreg = htaddr->hter; 2272926Swnj sc->sc_resid = htaddr->htfc; 2282926Swnj sc->sc_flags &= ~(H_WRITTEN|H_REWIND); 2292926Swnj if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) 2302926Swnj if (sc->sc_openf > 0) 2312926Swnj sc->sc_openf = -1; 2322926Swnj if (sc->sc_openf < 0) { 2332926Swnj bp->b_flags |= B_ERROR; 2342926Swnj return (MBU_NEXT); 2352926Swnj } 2363094Swnj if (bp != &chtbuf[HTUNIT(bp->b_dev)]) { 2377379Ssam if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 2382926Swnj bp->b_flags |= B_ERROR; 2392926Swnj bp->b_error = ENXIO; 2402961Swnj return (MBU_NEXT); 2413094Swnj } 2427379Ssam if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && 2432926Swnj bp->b_flags&B_READ) { 2442926Swnj bp->b_resid = bp->b_bcount; 2452926Swnj clrbuf(bp); 2462961Swnj return (MBU_NEXT); 2473094Swnj } 2483094Swnj if ((bp->b_flags&B_READ)==0) 2497379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 2502926Swnj } else { 2512961Swnj if (bp->b_command == HT_SENSE) 2522926Swnj return (MBU_NEXT); 2532926Swnj if (bp->b_command == HT_REW) 2542926Swnj sc->sc_flags |= H_REWIND; 2552926Swnj else 2562926Swnj htaddr->htfc = -bp->b_bcount; 2572926Swnj htaddr->htcs1 = bp->b_command|HT_GO; 2582926Swnj return (MBU_STARTED); 2592926Swnj } 2607379Ssam if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 2612926Swnj htaddr->htfc = -bp->b_bcount; 2622926Swnj if ((bp->b_flags&B_READ) == 0) { 2633094Swnj if (mi->mi_tab.b_errcnt) { 2643094Swnj if ((sc->sc_flags & H_ERASED) == 0) { 2652926Swnj sc->sc_flags |= H_ERASED; 2662926Swnj htaddr->htcs1 = HT_ERASE | HT_GO; 2672926Swnj return (MBU_STARTED); 2682926Swnj } 2693094Swnj sc->sc_flags &= ~H_ERASED; 2703094Swnj } 2712926Swnj if (htaddr->htds & HTDS_EOT) { 2722926Swnj bp->b_resid = bp->b_bcount; 2736812Swnj bp->b_flags |= B_ERROR; 2742926Swnj return (MBU_NEXT); 2752926Swnj } 27622Sbill } 2772926Swnj return (MBU_DODATA); 27822Sbill } 2797379Ssam if (blkno < bdbtofsb(bp->b_blkno)) { 2807379Ssam htaddr->htfc = blkno - bdbtofsb(bp->b_blkno); 2812926Swnj htaddr->htcs1 = HT_SFORW|HT_GO; 28222Sbill } else { 2837379Ssam htaddr->htfc = bdbtofsb(bp->b_blkno) - blkno; 2842926Swnj htaddr->htcs1 = HT_SREV|HT_GO; 28522Sbill } 2862926Swnj return (MBU_STARTED); 28722Sbill } 28822Sbill 2893094Swnj htdtint(mi, mbsr) 2902980Swnj register struct mba_device *mi; 2913094Swnj int mbsr; 29222Sbill { 2932926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 2942926Swnj register struct buf *bp = mi->mi_tab.b_actf; 2953094Swnj register struct tu_softc *sc; 2962961Swnj int ds, er, mbs; 29722Sbill 2983094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 2992926Swnj ds = sc->sc_dsreg = MASKREG(htaddr->htds); 3002926Swnj er = sc->sc_erreg = MASKREG(htaddr->hter); 3012926Swnj sc->sc_resid = MASKREG(htaddr->htfc); 3023094Swnj mbs = mbsr; 3032926Swnj sc->sc_blkno++; 3042926Swnj if((bp->b_flags & B_READ) == 0) 3052926Swnj sc->sc_flags |= H_WRITTEN; 3063094Swnj if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { 3072926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3082961Swnj mbclrattn(mi); 3092961Swnj if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { 3102926Swnj er &= ~HTER_FCE; 3113094Swnj mbs &= ~(MBSR_DTABT|MBSR_MBEXC); 3124276Sroot } 3132926Swnj if (bp->b_flags & B_READ && ds & HTDS_PES) 3142926Swnj er &= ~(HTER_CSITM|HTER_CORCRC); 3153094Swnj if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || 3162961Swnj er && ++mi->mi_tab.b_errcnt >= 7) { 3172926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3182926Swnj sc->sc_openf = -1; 3193157Swnj if ((er&HTER_HARD) == HTER_FCE && 3203157Swnj (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && 3213157Swnj (ds&HTDS_MOL)) 3223157Swnj goto noprint; 3233204Swnj printf("tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", 3242980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3253094Swnj mbsr, mbsr_bits, 3263204Swnj sc->sc_erreg, hter_bits, 3273204Swnj sc->sc_dsreg, htds_bits); 3283157Swnj noprint: 32922Sbill bp->b_flags |= B_ERROR; 3302926Swnj return (MBD_DONE); 33122Sbill } 3322926Swnj if (er) 3332926Swnj return (MBD_RETRY); 33422Sbill } 3352926Swnj bp->b_resid = 0; 3362926Swnj if (bp->b_flags & B_READ) 3372926Swnj if (ds&HTDS_TM) { /* must be a read, right? */ 3382926Swnj bp->b_resid = bp->b_bcount; 3397379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno); 3402926Swnj } else if(bp->b_bcount > MASKREG(htaddr->htfc)) 3412926Swnj bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); 3422926Swnj return (MBD_DONE); 3432926Swnj } 34422Sbill 3452926Swnj htndtint(mi) 3462980Swnj register struct mba_device *mi; 3472926Swnj { 3482926Swnj register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; 3492926Swnj register struct buf *bp = mi->mi_tab.b_actf; 3503094Swnj register struct tu_softc *sc; 3512926Swnj int er, ds, fc; 35222Sbill 3533094Swnj ds = MASKREG(htaddr->htds); 3543094Swnj er = MASKREG(htaddr->hter); 3553094Swnj fc = MASKREG(htaddr->htfc); 3563094Swnj if (er) { 3572926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 3582961Swnj mbclrattn(mi); 3592961Swnj } 3603094Swnj if (bp == 0) 3613094Swnj return (MBN_SKIP); 3623094Swnj sc = &tu_softc[TUUNIT(bp->b_dev)]; 3633094Swnj sc->sc_dsreg = ds; 3643094Swnj sc->sc_erreg = er; 3653094Swnj sc->sc_resid = fc; 3663094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3673094Swnj switch (bp->b_command) { 3683094Swnj case HT_REWOFFL: 3692926Swnj /* offline is on purpose; don't do anything special */ 3702926Swnj ds |= HTDS_MOL; 3713094Swnj break; 3723094Swnj case HT_SREV: 3733094Swnj /* if backspace file hit bot, its not an error */ 3743094Swnj if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && 3753094Swnj bp->b_repcnt == INF) 3763094Swnj er &= ~HTER_NEF; 3773094Swnj break; 3783094Swnj } 3792926Swnj er &= ~HTER_FCE; 3802926Swnj if (er == 0) 3812926Swnj ds &= ~HTDS_ERR; 38222Sbill } 3832926Swnj if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { 3842926Swnj if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) 3852926Swnj sc->sc_openf = -1; 3863204Swnj printf("tu%d: hard error bn%d er=%b ds=%b\n", 3872980Swnj TUUNIT(bp->b_dev), bp->b_blkno, 3883204Swnj sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); 3892926Swnj bp->b_flags |= B_ERROR; 3902926Swnj return (MBN_DONE); 3912926Swnj } 3923094Swnj if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { 3932926Swnj if (sc->sc_flags & H_REWIND) 3942926Swnj return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); 3952926Swnj bp->b_resid = -sc->sc_resid; 3962926Swnj return (MBN_DONE); 3972926Swnj } 3982926Swnj if (ds & HTDS_TM) 3997379Ssam if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 4007379Ssam sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; 4012926Swnj sc->sc_blkno = sc->sc_nxrec; 4023094Swnj } else { 4037379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno) + fc; 4042926Swnj sc->sc_nxrec = sc->sc_blkno - 1; 4052926Swnj } 4062926Swnj else 4077379Ssam sc->sc_blkno = bdbtofsb(bp->b_blkno); 4082926Swnj return (MBN_RETRY); 40922Sbill } 41022Sbill 4117739Sroot htread(dev, uio) 4122926Swnj dev_t dev; 4137739Sroot struct uio *uio; 41422Sbill { 4158157Sroot int errno; 4162926Swnj 4178157Sroot errno = htphys(dev, uio); 4188157Sroot if (errno) 4198157Sroot return (errno); 4208157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys, uio)); 42122Sbill } 42222Sbill 4238605Sroot htwrite(dev, uio) 4248605Sroot dev_t dev; 4258688Sroot struct uio *uio; 42622Sbill { 4278157Sroot int errno; 4282926Swnj 4298157Sroot errno = htphys(dev, uio); 4308157Sroot if (errno) 4318157Sroot return (errno); 4328157Sroot return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys, uio)); 43322Sbill } 43422Sbill 4357739Sroot htphys(dev, uio) 4362926Swnj dev_t dev; 4377739Sroot struct uio *uio; 43822Sbill { 4393094Swnj register int htunit; 4408688Sroot /*###439 [lint] htphys arg. 2 used inconsistently ht.c(439) :: ht.c(430)%%%*/ 4413094Swnj register struct tu_softc *sc; 4423094Swnj register struct mba_device *mi; 44322Sbill daddr_t a; 44422Sbill 4453094Swnj htunit = HTUNIT(dev); 4467832Sroot if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) 4477739Sroot return (ENXIO); 4487832Sroot a = uio->uio_offset >> 9; 4493094Swnj sc = &tu_softc[TUUNIT(dev)]; 4507379Ssam sc->sc_blkno = bdbtofsb(a); 4517379Ssam sc->sc_nxrec = bdbtofsb(a)+1; 4527739Sroot return (0); 45322Sbill } 4541917Swnj 4552926Swnj /*ARGSUSED*/ 4567636Ssam htioctl(dev, cmd, data, flag) 4572926Swnj dev_t dev; 4582926Swnj int cmd; 4597636Ssam caddr_t data; 4602926Swnj int flag; 4612926Swnj { 4623094Swnj register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; 4633094Swnj register struct buf *bp = &chtbuf[HTUNIT(dev)]; 4642926Swnj register callcount; 4652926Swnj int fcount; 4667636Ssam struct mtop *mtop; 4677636Ssam struct mtget *mtget; 4682926Swnj /* we depend of the values and order of the MT codes here */ 4692926Swnj static htops[] = 4702926Swnj {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; 4711917Swnj 4722926Swnj switch (cmd) { 4737636Ssam 4747636Ssam case MTIOCTOP: /* tape operation */ 4757636Ssam mtop = (struct mtop *)data; 4767636Ssam switch (mtop->mt_op) { 4777636Ssam 4782926Swnj case MTWEOF: 4797636Ssam callcount = mtop->mt_count; 4802926Swnj fcount = 1; 4812926Swnj break; 4827636Ssam 4832926Swnj case MTFSF: case MTBSF: 4847636Ssam callcount = mtop->mt_count; 4852926Swnj fcount = INF; 4862926Swnj break; 4877636Ssam 4882926Swnj case MTFSR: case MTBSR: 4892926Swnj callcount = 1; 4907636Ssam fcount = mtop->mt_count; 4912926Swnj break; 4927636Ssam 4932926Swnj case MTREW: case MTOFFL: 4942926Swnj callcount = 1; 4952926Swnj fcount = 1; 4962926Swnj break; 4977636Ssam 4982926Swnj default: 4998580Sroot return (ENXIO); 5002926Swnj } 5018580Sroot if (callcount <= 0 || fcount <= 0) 5028580Sroot return (EINVAL); 5032926Swnj while (--callcount >= 0) { 5047636Ssam htcommand(dev, htops[mtop->mt_op], fcount); 5057636Ssam if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 5068580Sroot bp->b_resid) 5078580Sroot return (EIO); 5083094Swnj if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) 5092926Swnj break; 5102926Swnj } 5118711Sroot return (geterror(bp)); 5127636Ssam 5132926Swnj case MTIOCGET: 5147636Ssam mtget = (struct mtget *)data; 5157636Ssam mtget->mt_dsreg = sc->sc_dsreg; 5167636Ssam mtget->mt_erreg = sc->sc_erreg; 5177636Ssam mtget->mt_resid = sc->sc_resid; 5187636Ssam mtget->mt_type = MT_ISHT; 5198580Sroot break; 5207636Ssam 5212926Swnj default: 5228580Sroot return (ENXIO); 5232926Swnj } 5248580Sroot return (0); 5252926Swnj } 5262926Swnj 5271917Swnj #define DBSIZE 20 5281917Swnj 5292926Swnj htdump() 5301917Swnj { 5312980Swnj register struct mba_device *mi; 5322926Swnj register struct mba_regs *mp; 5332926Swnj register struct htdevice *htaddr; 5342926Swnj int blk, num; 5352926Swnj int start; 5361917Swnj 5372926Swnj start = 0; 5382926Swnj num = maxfree; 5392926Swnj #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 5402926Swnj if (htinfo[0] == 0) 5412926Swnj return (ENXIO); 5422980Swnj mi = phys(htinfo[0], struct mba_device *); 5432926Swnj mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 5443157Swnj mp->mba_cr = MBCR_IE; 5452926Swnj htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; 5462926Swnj htaddr->httc = HTTC_PDP11|HTTC_1600BPI; 5472926Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 5481917Swnj while (num > 0) { 5491917Swnj blk = num > DBSIZE ? DBSIZE : num; 5502926Swnj htdwrite(start, blk, htaddr, mp); 5512926Swnj start += blk; 5521917Swnj num -= blk; 5531917Swnj } 5543157Swnj hteof(htaddr); 5553157Swnj hteof(htaddr); 5562926Swnj htwait(htaddr); 5573181Swnj if (htaddr->htds&HTDS_ERR) 5583157Swnj return (EIO); 5592926Swnj htaddr->htcs1 = HT_REW|HT_GO; 5603103Swnj return (0); 5611917Swnj } 5621917Swnj 5632926Swnj htdwrite(dbuf, num, htaddr, mp) 5642926Swnj register dbuf, num; 5652926Swnj register struct htdevice *htaddr; 5662926Swnj struct mba_regs *mp; 5671917Swnj { 5682926Swnj register struct pte *io; 5691917Swnj register int i; 5701917Swnj 5712926Swnj htwait(htaddr); 5722926Swnj io = mp->mba_map; 5731917Swnj for (i = 0; i < num; i++) 5742926Swnj *(int *)io++ = dbuf++ | PG_V; 5752926Swnj htaddr->htfc = -(num*NBPG); 5762926Swnj mp->mba_sr = -1; 5772926Swnj mp->mba_bcr = -(num*NBPG); 5782926Swnj mp->mba_var = 0; 5792926Swnj htaddr->htcs1 = HT_WCOM|HT_GO; 5801917Swnj } 5811917Swnj 5822926Swnj htwait(htaddr) 5832926Swnj struct htdevice *htaddr; 5841917Swnj { 5851917Swnj register s; 5861917Swnj 5871917Swnj do 5882926Swnj s = htaddr->htds; 5892926Swnj while ((s & HTDS_DRY) == 0); 5901917Swnj } 5911917Swnj 5922926Swnj hteof(htaddr) 5932926Swnj struct htdevice *htaddr; 5941917Swnj { 5951917Swnj 5962926Swnj htwait(htaddr); 5972926Swnj htaddr->htcs1 = HT_WEOF|HT_GO; 5981917Swnj } 5991563Sbill #endif 600