|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)ht.c 7.1 (Berkeley) 6/5/86 ! 7: */ ! 8: ! 9: #include "tu.h" ! 10: #if NHT > 0 ! 11: /* ! 12: * TM03/TU?? tape driver ! 13: * ! 14: * TODO: ! 15: * cleanup messages on errors ! 16: * test ioctl's ! 17: * see how many rewind interrups we get if we kick when not at BOT ! 18: * fixup rle error on block tape code ! 19: */ ! 20: #include "../machine/pte.h" ! 21: ! 22: #include "param.h" ! 23: #include "systm.h" ! 24: #include "buf.h" ! 25: #include "conf.h" ! 26: #include "dir.h" ! 27: #include "file.h" ! 28: #include "user.h" ! 29: #include "map.h" ! 30: #include "ioctl.h" ! 31: #include "mtio.h" ! 32: #include "cmap.h" ! 33: #include "uio.h" ! 34: #include "tty.h" ! 35: ! 36: #include "../vax/cpu.h" ! 37: #include "mbareg.h" ! 38: #include "mbavar.h" ! 39: #include "htreg.h" ! 40: ! 41: struct buf rhtbuf[NHT]; ! 42: struct buf chtbuf[NHT]; ! 43: ! 44: short httypes[] = ! 45: { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; ! 46: struct mba_device *htinfo[NHT]; ! 47: int htattach(), htslave(), htustart(), htndtint(), htdtint(); ! 48: struct mba_driver htdriver = ! 49: { htattach, htslave, htustart, 0, htdtint, htndtint, ! 50: httypes, "ht", "tu", htinfo }; ! 51: ! 52: #define MASKREG(r) ((r) & 0xffff) ! 53: ! 54: /* bits in minor device */ ! 55: #define TUUNIT(dev) (minor(dev)&03) ! 56: #define H_NOREWIND 04 ! 57: #define H_1600BPI 08 ! 58: ! 59: #define HTUNIT(dev) (tutoht[TUUNIT(dev)]) ! 60: ! 61: #define INF (daddr_t)1000000L /* a block number that wont exist */ ! 62: ! 63: struct tu_softc { ! 64: char sc_openf; ! 65: char sc_flags; ! 66: daddr_t sc_blkno; ! 67: daddr_t sc_nxrec; ! 68: u_short sc_erreg; ! 69: u_short sc_dsreg; ! 70: short sc_resid; ! 71: short sc_dens; ! 72: struct mba_device *sc_mi; ! 73: int sc_slave; ! 74: struct tty *sc_ttyp; /* record user's tty for errors */ ! 75: } tu_softc[NTU]; ! 76: short tutoht[NTU]; ! 77: ! 78: /* ! 79: * Bits for sc_flags. ! 80: */ ! 81: #define H_WRITTEN 1 /* last operation was a write */ ! 82: #define H_ERASED 2 /* last write retry was an erase gap */ ! 83: #define H_REWIND 4 /* last unit start was a rewind */ ! 84: ! 85: char hter_bits[] = HTER_BITS; ! 86: char htds_bits[] = HTDS_BITS; ! 87: ! 88: /*ARGSUSED*/ ! 89: htattach(mi) ! 90: struct mba_device *mi; ! 91: { ! 92: ! 93: } ! 94: ! 95: htslave(mi, ms, sn) ! 96: struct mba_device *mi; ! 97: struct mba_slave *ms; ! 98: int sn; ! 99: { ! 100: register struct tu_softc *sc = &tu_softc[ms->ms_unit]; ! 101: register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; ! 102: ! 103: htaddr->httc = sn; ! 104: if (htaddr->htdt & HTDT_SPR) { ! 105: sc->sc_mi = mi; ! 106: sc->sc_slave = sn; ! 107: tutoht[ms->ms_unit] = mi->mi_unit; ! 108: return (1); ! 109: } else ! 110: return (0); ! 111: } ! 112: ! 113: htopen(dev, flag) ! 114: dev_t dev; ! 115: int flag; ! 116: { ! 117: register int tuunit; ! 118: register struct mba_device *mi; ! 119: register struct tu_softc *sc; ! 120: int olddens, dens; ! 121: ! 122: tuunit = TUUNIT(dev); ! 123: if (tuunit >= NTU || (mi = htinfo[HTUNIT(dev)]) == 0 || ! 124: mi->mi_alive == 0) ! 125: return (ENXIO); ! 126: if ((sc = &tu_softc[tuunit])->sc_openf) ! 127: return (EBUSY); ! 128: olddens = sc->sc_dens; ! 129: dens = sc->sc_dens = ! 130: ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)| ! 131: HTTC_PDP11|sc->sc_slave; ! 132: htcommand(dev, HT_SENSE, 1); ! 133: sc->sc_dens = olddens; ! 134: if ((sc->sc_dsreg & HTDS_MOL) == 0) { ! 135: uprintf("tu%d: not online\n", tuunit); ! 136: return (EIO); ! 137: } ! 138: if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { ! 139: uprintf("tu%d: no write ring\n", tuunit); ! 140: return (EIO); ! 141: } ! 142: if ((sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) && ! 143: dens != sc->sc_dens) { ! 144: uprintf("tu%d: can't change density in mid-tape\n", tuunit); ! 145: return (EIO); ! 146: } ! 147: sc->sc_openf = 1; ! 148: sc->sc_blkno = (daddr_t)0; ! 149: sc->sc_nxrec = INF; ! 150: sc->sc_flags = 0; ! 151: sc->sc_dens = dens; ! 152: sc->sc_ttyp = u.u_ttyp; ! 153: return (0); ! 154: } ! 155: ! 156: htclose(dev, flag) ! 157: register dev_t dev; ! 158: register flag; ! 159: { ! 160: register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; ! 161: ! 162: if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) { ! 163: htcommand(dev, HT_WEOF, 1); ! 164: htcommand(dev, HT_WEOF, 1); ! 165: htcommand(dev, HT_SREV, 1); ! 166: } ! 167: if ((minor(dev)&H_NOREWIND) == 0) ! 168: htcommand(dev, HT_REW, 0); ! 169: sc->sc_openf = 0; ! 170: } ! 171: ! 172: htcommand(dev, com, count) ! 173: dev_t dev; ! 174: int com, count; ! 175: { ! 176: register struct buf *bp; ! 177: register int s; ! 178: ! 179: bp = &chtbuf[HTUNIT(dev)]; ! 180: s = spl5(); ! 181: while (bp->b_flags&B_BUSY) { ! 182: if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) ! 183: break; ! 184: bp->b_flags |= B_WANTED; ! 185: sleep((caddr_t)bp, PRIBIO); ! 186: } ! 187: bp->b_flags = B_BUSY|B_READ; ! 188: splx(s); ! 189: bp->b_dev = dev; ! 190: bp->b_command = com; ! 191: bp->b_repcnt = count; ! 192: bp->b_blkno = 0; ! 193: htstrategy(bp); ! 194: if (count == 0) ! 195: return; ! 196: iowait(bp); ! 197: if (bp->b_flags&B_WANTED) ! 198: wakeup((caddr_t)bp); ! 199: bp->b_flags &= B_ERROR; ! 200: } ! 201: ! 202: htstrategy(bp) ! 203: register struct buf *bp; ! 204: { ! 205: register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)]; ! 206: register struct buf *dp; ! 207: register int s; ! 208: ! 209: bp->av_forw = NULL; ! 210: dp = &mi->mi_tab; ! 211: s = spl5(); ! 212: if (dp->b_actf == NULL) ! 213: dp->b_actf = bp; ! 214: else ! 215: dp->b_actl->av_forw = bp; ! 216: dp->b_actl = bp; ! 217: if (dp->b_active == 0) ! 218: mbustart(mi); ! 219: splx(s); ! 220: } ! 221: ! 222: htustart(mi) ! 223: register struct mba_device *mi; ! 224: { ! 225: register struct htdevice *htaddr = ! 226: (struct htdevice *)mi->mi_drv; ! 227: register struct buf *bp = mi->mi_tab.b_actf; ! 228: register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)]; ! 229: daddr_t blkno; ! 230: ! 231: htaddr->httc = sc->sc_dens; ! 232: #ifdef notdef ! 233: /* unneeded, may hang controller */ ! 234: if (bp == &chtbuf[HTUNIT(bp->b_dev)] && bp->b_command == HT_SENSE) { ! 235: htaddr->htcs1 = HT_SENSE|HT_GO; ! 236: mbclrattn(mi); ! 237: } ! 238: #endif ! 239: sc->sc_dsreg = htaddr->htds; ! 240: sc->sc_erreg = htaddr->hter; ! 241: sc->sc_resid = htaddr->htfc; ! 242: sc->sc_flags &= ~(H_WRITTEN|H_REWIND); ! 243: if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0) ! 244: if (sc->sc_openf > 0) ! 245: sc->sc_openf = -1; ! 246: if (sc->sc_openf < 0) { ! 247: bp->b_flags |= B_ERROR; ! 248: return (MBU_NEXT); ! 249: } ! 250: if (bp != &chtbuf[HTUNIT(bp->b_dev)]) { ! 251: if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { ! 252: bp->b_flags |= B_ERROR; ! 253: bp->b_error = ENXIO; ! 254: return (MBU_NEXT); ! 255: } ! 256: if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && ! 257: bp->b_flags&B_READ) { ! 258: bp->b_resid = bp->b_bcount; ! 259: clrbuf(bp); ! 260: return (MBU_NEXT); ! 261: } ! 262: if ((bp->b_flags&B_READ)==0) ! 263: sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; ! 264: } else { ! 265: if (bp->b_command == HT_SENSE) ! 266: return (MBU_NEXT); ! 267: if (bp->b_command == HT_REW) ! 268: sc->sc_flags |= H_REWIND; ! 269: else ! 270: htaddr->htfc = -bp->b_bcount; ! 271: htaddr->htcs1 = bp->b_command|HT_GO; ! 272: return (MBU_STARTED); ! 273: } ! 274: if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { ! 275: htaddr->htfc = -bp->b_bcount; ! 276: if ((bp->b_flags&B_READ) == 0) { ! 277: if (mi->mi_tab.b_errcnt) { ! 278: if ((sc->sc_flags & H_ERASED) == 0) { ! 279: sc->sc_flags |= H_ERASED; ! 280: htaddr->htcs1 = HT_ERASE | HT_GO; ! 281: return (MBU_STARTED); ! 282: } ! 283: sc->sc_flags &= ~H_ERASED; ! 284: } ! 285: if (htaddr->htds & HTDS_EOT) { ! 286: bp->b_resid = bp->b_bcount; ! 287: bp->b_flags |= B_ERROR; ! 288: return (MBU_NEXT); ! 289: } ! 290: } ! 291: return (MBU_DODATA); ! 292: } ! 293: if (blkno < bdbtofsb(bp->b_blkno)) { ! 294: htaddr->htfc = blkno - bdbtofsb(bp->b_blkno); ! 295: htaddr->htcs1 = HT_SFORW|HT_GO; ! 296: } else { ! 297: htaddr->htfc = bdbtofsb(bp->b_blkno) - blkno; ! 298: htaddr->htcs1 = HT_SREV|HT_GO; ! 299: } ! 300: return (MBU_STARTED); ! 301: } ! 302: ! 303: htdtint(mi, mbsr) ! 304: register struct mba_device *mi; ! 305: int mbsr; ! 306: { ! 307: register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; ! 308: register struct buf *bp = mi->mi_tab.b_actf; ! 309: register struct tu_softc *sc; ! 310: int ds, er, mbs; ! 311: ! 312: sc = &tu_softc[TUUNIT(bp->b_dev)]; ! 313: ds = sc->sc_dsreg = MASKREG(htaddr->htds); ! 314: er = sc->sc_erreg = MASKREG(htaddr->hter); ! 315: sc->sc_resid = MASKREG(htaddr->htfc); ! 316: mbs = mbsr; ! 317: sc->sc_blkno++; ! 318: if((bp->b_flags & B_READ) == 0) ! 319: sc->sc_flags |= H_WRITTEN; ! 320: if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) { ! 321: htaddr->htcs1 = HT_DCLR|HT_GO; ! 322: mbclrattn(mi); ! 323: if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) { ! 324: er &= ~HTER_FCE; ! 325: mbs &= ~(MBSR_DTABT|MBSR_MBEXC); ! 326: } ! 327: if (bp->b_flags & B_READ && ds & HTDS_PES) ! 328: er &= ~(HTER_CSITM|HTER_CORCRC); ! 329: if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 || ! 330: er && ++mi->mi_tab.b_errcnt >= 7) { ! 331: if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) ! 332: sc->sc_openf = -1; ! 333: if ((er&HTER_HARD) == HTER_FCE && ! 334: (mbs&MBSR_EBITS) == (MBSR_DTABT|MBSR_MBEXC) && ! 335: (ds&HTDS_MOL)) ! 336: goto noprint; ! 337: tprintf(sc->sc_ttyp, "tu%d: hard error bn%d mbsr=%b er=%b ds=%b\n", ! 338: TUUNIT(bp->b_dev), bp->b_blkno, ! 339: mbsr, mbsr_bits, ! 340: sc->sc_erreg, hter_bits, ! 341: sc->sc_dsreg, htds_bits); ! 342: noprint: ! 343: bp->b_flags |= B_ERROR; ! 344: return (MBD_DONE); ! 345: } ! 346: if (er) ! 347: return (MBD_RETRY); ! 348: } ! 349: bp->b_resid = 0; ! 350: if (bp->b_flags & B_READ) ! 351: if (ds&HTDS_TM) { /* must be a read, right? */ ! 352: bp->b_resid = bp->b_bcount; ! 353: sc->sc_nxrec = bdbtofsb(bp->b_blkno); ! 354: } else if(bp->b_bcount > MASKREG(htaddr->htfc)) ! 355: bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc); ! 356: return (MBD_DONE); ! 357: } ! 358: ! 359: htndtint(mi) ! 360: register struct mba_device *mi; ! 361: { ! 362: register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv; ! 363: register struct buf *bp = mi->mi_tab.b_actf; ! 364: register struct tu_softc *sc; ! 365: int er, ds, fc; ! 366: ! 367: ds = MASKREG(htaddr->htds); ! 368: er = MASKREG(htaddr->hter); ! 369: fc = MASKREG(htaddr->htfc); ! 370: if (er) { ! 371: htaddr->htcs1 = HT_DCLR|HT_GO; ! 372: mbclrattn(mi); ! 373: } ! 374: if (bp == 0) ! 375: return (MBN_SKIP); ! 376: sc = &tu_softc[TUUNIT(bp->b_dev)]; ! 377: sc->sc_dsreg = ds; ! 378: sc->sc_erreg = er; ! 379: sc->sc_resid = fc; ! 380: if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { ! 381: switch ((int)bp->b_command) { ! 382: case HT_REWOFFL: ! 383: /* offline is on purpose; don't do anything special */ ! 384: ds |= HTDS_MOL; ! 385: break; ! 386: case HT_SREV: ! 387: /* if backspace file hit bot, its not an error */ ! 388: if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT && ! 389: bp->b_repcnt == INF) ! 390: er &= ~HTER_NEF; ! 391: break; ! 392: } ! 393: er &= ~HTER_FCE; ! 394: if (er == 0) ! 395: ds &= ~HTDS_ERR; ! 396: } ! 397: if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) { ! 398: if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0) ! 399: sc->sc_openf = -1; ! 400: tprintf(sc->sc_ttyp, "tu%d: hard error bn%d er=%b ds=%b\n", ! 401: TUUNIT(bp->b_dev), bp->b_blkno, ! 402: sc->sc_erreg, hter_bits, sc->sc_dsreg, htds_bits); ! 403: bp->b_flags |= B_ERROR; ! 404: return (MBN_DONE); ! 405: } ! 406: if (bp == &chtbuf[HTUNIT(bp->b_dev)]) { ! 407: if (sc->sc_flags & H_REWIND) ! 408: return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY); ! 409: bp->b_resid = -sc->sc_resid; ! 410: return (MBN_DONE); ! 411: } ! 412: if (ds & HTDS_TM) ! 413: if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { ! 414: sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; ! 415: sc->sc_blkno = sc->sc_nxrec; ! 416: } else { ! 417: sc->sc_blkno = bdbtofsb(bp->b_blkno) + fc; ! 418: sc->sc_nxrec = sc->sc_blkno - 1; ! 419: } ! 420: else ! 421: sc->sc_blkno = bdbtofsb(bp->b_blkno); ! 422: return (MBN_RETRY); ! 423: } ! 424: ! 425: htread(dev, uio) ! 426: dev_t dev; ! 427: struct uio *uio; ! 428: { ! 429: int errno; ! 430: ! 431: errno = htphys(dev, uio); ! 432: if (errno) ! 433: return (errno); ! 434: return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys, uio)); ! 435: } ! 436: ! 437: htwrite(dev, uio) ! 438: dev_t dev; ! 439: struct uio *uio; ! 440: { ! 441: int errno; ! 442: ! 443: errno = htphys(dev, uio); ! 444: if (errno) ! 445: return (errno); ! 446: return (physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys, uio)); ! 447: } ! 448: ! 449: htphys(dev, uio) ! 450: dev_t dev; ! 451: struct uio *uio; ! 452: { ! 453: register int htunit; ! 454: register struct tu_softc *sc; ! 455: register struct mba_device *mi; ! 456: daddr_t a; ! 457: ! 458: htunit = HTUNIT(dev); ! 459: if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) ! 460: return (ENXIO); ! 461: a = uio->uio_offset >> 9; ! 462: sc = &tu_softc[TUUNIT(dev)]; ! 463: sc->sc_blkno = bdbtofsb(a); ! 464: sc->sc_nxrec = bdbtofsb(a)+1; ! 465: return (0); ! 466: } ! 467: ! 468: /*ARGSUSED*/ ! 469: htioctl(dev, cmd, data, flag) ! 470: dev_t dev; ! 471: int cmd; ! 472: caddr_t data; ! 473: int flag; ! 474: { ! 475: register struct tu_softc *sc = &tu_softc[TUUNIT(dev)]; ! 476: register struct buf *bp = &chtbuf[HTUNIT(dev)]; ! 477: register callcount; ! 478: int fcount; ! 479: struct mtop *mtop; ! 480: struct mtget *mtget; ! 481: /* we depend of the values and order of the MT codes here */ ! 482: static htops[] = ! 483: {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE}; ! 484: ! 485: switch (cmd) { ! 486: ! 487: case MTIOCTOP: /* tape operation */ ! 488: mtop = (struct mtop *)data; ! 489: switch (mtop->mt_op) { ! 490: ! 491: case MTWEOF: ! 492: callcount = mtop->mt_count; ! 493: fcount = 1; ! 494: break; ! 495: ! 496: case MTFSF: case MTBSF: ! 497: callcount = mtop->mt_count; ! 498: fcount = INF; ! 499: break; ! 500: ! 501: case MTFSR: case MTBSR: ! 502: callcount = 1; ! 503: fcount = mtop->mt_count; ! 504: break; ! 505: ! 506: case MTREW: case MTOFFL: ! 507: callcount = 1; ! 508: fcount = 1; ! 509: break; ! 510: ! 511: default: ! 512: return (ENXIO); ! 513: } ! 514: if (callcount <= 0 || fcount <= 0) ! 515: return (EINVAL); ! 516: while (--callcount >= 0) { ! 517: htcommand(dev, htops[mtop->mt_op], fcount); ! 518: if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && ! 519: bp->b_resid) ! 520: return (EIO); ! 521: if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT) ! 522: break; ! 523: } ! 524: return (geterror(bp)); ! 525: ! 526: case MTIOCGET: ! 527: mtget = (struct mtget *)data; ! 528: mtget->mt_dsreg = sc->sc_dsreg; ! 529: mtget->mt_erreg = sc->sc_erreg; ! 530: mtget->mt_resid = sc->sc_resid; ! 531: mtget->mt_type = MT_ISHT; ! 532: break; ! 533: ! 534: default: ! 535: return (ENXIO); ! 536: } ! 537: return (0); ! 538: } ! 539: ! 540: #define DBSIZE 20 ! 541: ! 542: htdump() ! 543: { ! 544: register struct mba_device *mi; ! 545: register struct mba_regs *mp; ! 546: register struct htdevice *htaddr; ! 547: int blk, num; ! 548: int start; ! 549: ! 550: start = 0; ! 551: num = maxfree; ! 552: #define phys(a,b) ((b)((int)(a)&0x7fffffff)) ! 553: if (htinfo[0] == 0) ! 554: return (ENXIO); ! 555: mi = phys(htinfo[0], struct mba_device *); ! 556: mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; ! 557: mp->mba_cr = MBCR_IE; ! 558: htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive]; ! 559: htaddr->httc = HTTC_PDP11|HTTC_1600BPI; ! 560: htaddr->htcs1 = HT_DCLR|HT_GO; ! 561: while (num > 0) { ! 562: blk = num > DBSIZE ? DBSIZE : num; ! 563: htdwrite(start, blk, htaddr, mp); ! 564: start += blk; ! 565: num -= blk; ! 566: } ! 567: hteof(htaddr); ! 568: hteof(htaddr); ! 569: htwait(htaddr); ! 570: if (htaddr->htds&HTDS_ERR) ! 571: return (EIO); ! 572: htaddr->htcs1 = HT_REW|HT_GO; ! 573: return (0); ! 574: } ! 575: ! 576: htdwrite(dbuf, num, htaddr, mp) ! 577: register dbuf, num; ! 578: register struct htdevice *htaddr; ! 579: struct mba_regs *mp; ! 580: { ! 581: register struct pte *io; ! 582: register int i; ! 583: ! 584: htwait(htaddr); ! 585: io = mp->mba_map; ! 586: for (i = 0; i < num; i++) ! 587: *(int *)io++ = dbuf++ | PG_V; ! 588: htaddr->htfc = -(num*NBPG); ! 589: mp->mba_sr = -1; ! 590: mp->mba_bcr = -(num*NBPG); ! 591: mp->mba_var = 0; ! 592: htaddr->htcs1 = HT_WCOM|HT_GO; ! 593: } ! 594: ! 595: htwait(htaddr) ! 596: struct htdevice *htaddr; ! 597: { ! 598: register s; ! 599: ! 600: do ! 601: s = htaddr->htds; ! 602: while ((s & HTDS_DRY) == 0); ! 603: } ! 604: ! 605: hteof(htaddr) ! 606: struct htdevice *htaddr; ! 607: { ! 608: ! 609: htwait(htaddr); ! 610: htaddr->htcs1 = HT_WEOF|HT_GO; ! 611: } ! 612: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.