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: * @(#)ut.c 7.1 (Berkeley) 6/5/86 7: */ 8: 9: #include "tj.h" 10: #if NUT > 0 11: /* 12: * System Industries Model 9700 Tape Drive 13: * emulates a TU45 on the UNIBUS 14: * 15: * TODO: 16: * check out attention processing 17: * try reset code and dump code 18: */ 19: #include "../machine/pte.h" 20: 21: #include "param.h" 22: #include "systm.h" 23: #include "buf.h" 24: #include "conf.h" 25: #include "dir.h" 26: #include "file.h" 27: #include "user.h" 28: #include "map.h" 29: #include "ioctl.h" 30: #include "mtio.h" 31: #include "cmap.h" 32: #include "uio.h" 33: #include "kernel.h" 34: #include "tty.h" 35: 36: #include "../vax/cpu.h" 37: #include "ubareg.h" 38: #include "ubavar.h" 39: #include "utreg.h" 40: 41: struct buf rutbuf[NUT]; /* bufs for raw i/o */ 42: struct buf cutbuf[NUT]; /* bufs for control operations */ 43: struct buf tjutab[NTJ]; /* bufs for slave queue headers */ 44: 45: struct uba_ctlr *utminfo[NUT]; 46: struct uba_device *tjdinfo[NTJ]; 47: int utprobe(), utslave(), utattach(), utdgo(), utintr(), uttimer(); 48: u_short utstd[] = { 0772440, 0 }; 49: struct uba_driver utdriver = 50: { utprobe, utslave, utattach, utdgo, utstd, "tj", tjdinfo, "ut", utminfo, 0 }; 51: 52: #define MASKREG(reg) ((reg)&0xffff) 53: 54: /* bits in minor device */ 55: #define TJUNIT(dev) (minor(dev)&03) 56: #define T_NOREWIND 04 57: #define T_1600BPI 010 58: #define T_6250BPI 020 59: short utdens[] = { UT_NRZI, UT_PE, UT_GCR, UT_NRZI }; 60: 61: /* slave to controller mapping table */ 62: short tjtout[NTJ]; 63: #define UTUNIT(dev) (tjtout[TJUNIT(dev)]) 64: 65: #define INF (daddr_t)1000000L /* a block number that wont exist */ 66: 67: struct tj_softc { 68: char sc_openf; /* exclusive open */ 69: char sc_lastiow; /* last I/O operation was a write */ 70: daddr_t sc_blkno; /* next block to transfer */ 71: daddr_t sc_nxrec; /* next record on tape */ 72: u_short sc_erreg; /* image of uter */ 73: u_short sc_dsreg; /* image of utds */ 74: u_short sc_resid; /* residual from transfer */ 75: u_short sc_dens; /* sticky selected density */ 76: daddr_t sc_timo; /* time until timeout expires */ 77: short sc_tact; /* timeout is active flag */ 78: struct tty *sc_ttyp; /* record user's tty for errors */ 79: } tj_softc[NTJ]; 80: 81: /* 82: * Internal per/slave states found in sc_state 83: */ 84: #define SSEEK 1 /* seeking */ 85: #define SIO 2 /* doing sequential I/O */ 86: #define SCOM 3 /* sending a control command */ 87: #define SREW 4 /* doing a rewind op */ 88: #define SERASE 5 /* erase inter-record gap */ 89: #define SERASED 6 /* erased inter-record gap */ 90: 91: /*ARGSUSED*/ 92: utprobe(reg) 93: caddr_t reg; 94: { 95: register int br, cvec; 96: #ifdef lint 97: br=0; cvec=br; br=cvec; 98: utintr(0); 99: #endif 100: /* 101: * The SI documentation says you must set the RDY bit 102: * (even though it's read-only) to force an interrupt. 103: */ 104: ((struct utdevice *) reg)->utcs1 = UT_IE|UT_NOP|UT_RDY; 105: DELAY(10000); 106: return (sizeof (struct utdevice)); 107: } 108: 109: /*ARGSUSED*/ 110: utslave(ui, reg) 111: struct uba_device *ui; 112: caddr_t reg; 113: { 114: /* 115: * A real TU45 would support the slave present bit 116: * int the drive type register, but this thing doesn't, 117: * so there's no way to determine if a slave is present or not. 118: */ 119: return(1); 120: } 121: 122: utattach(ui) 123: struct uba_device *ui; 124: { 125: tjtout[ui->ui_unit] = ui->ui_mi->um_ctlr; 126: } 127: 128: /* 129: * Open the device with exclusive access. 130: */ 131: utopen(dev, flag) 132: dev_t dev; 133: int flag; 134: { 135: register int tjunit = TJUNIT(dev); 136: register struct uba_device *ui; 137: register struct tj_softc *sc; 138: int olddens, dens; 139: register int s; 140: 141: if (tjunit >= NTJ || (ui = tjdinfo[tjunit]) == 0 || ui->ui_alive == 0) 142: return (ENXIO); 143: if ((sc = &tj_softc[tjunit])->sc_openf) 144: return (EBUSY); 145: olddens = sc->sc_dens; 146: dens = sc->sc_dens = 147: utdens[(minor(dev)&(T_1600BPI|T_6250BPI))>>3]| 148: PDP11FMT|(ui->ui_slave&07); 149: get: 150: utcommand(dev, UT_SENSE, 1); 151: if (sc->sc_dsreg&UTDS_PIP) { 152: sleep((caddr_t)&lbolt, PZERO+1); 153: goto get; 154: } 155: sc->sc_dens = olddens; 156: if ((sc->sc_dsreg&UTDS_MOL) == 0) { 157: uprintf("tj%d: not online\n", tjunit); 158: return (EIO); 159: } 160: if ((flag&FWRITE) && (sc->sc_dsreg&UTDS_WRL)) { 161: uprintf("tj%d: no write ring\n", tjunit); 162: return (EIO); 163: } 164: if ((sc->sc_dsreg&UTDS_BOT) == 0 && (flag&FWRITE) && 165: dens != sc->sc_dens) { 166: uprintf("tj%d: can't change density in mid-tape\n", tjunit); 167: return (EIO); 168: } 169: sc->sc_openf = 1; 170: sc->sc_blkno = (daddr_t)0; 171: sc->sc_nxrec = INF; 172: sc->sc_lastiow = 0; 173: sc->sc_dens = dens; 174: sc->sc_ttyp = u.u_ttyp; 175: /* 176: * For 6250 bpi take exclusive use of the UNIBUS. 177: */ 178: ui->ui_driver->ud_xclu = (dens&(T_1600BPI|T_6250BPI)) == T_6250BPI; 179: s = splclock(); 180: if (sc->sc_tact == 0) { 181: sc->sc_timo = INF; 182: sc->sc_tact = 1; 183: timeout(uttimer, (caddr_t)dev, 5*hz); 184: } 185: splx(s); 186: return (0); 187: } 188: 189: utclose(dev, flag) 190: register dev_t dev; 191: register flag; 192: { 193: register struct tj_softc *sc = &tj_softc[TJUNIT(dev)]; 194: 195: if (flag == FWRITE || ((flag&FWRITE) && sc->sc_lastiow)) { 196: utcommand(dev, UT_WEOF, 1); 197: utcommand(dev, UT_WEOF, 1); 198: utcommand(dev, UT_SREV, 1); 199: } 200: if ((minor(dev)&T_NOREWIND) == 0) 201: utcommand(dev, UT_REW, 0); 202: sc->sc_openf = 0; 203: } 204: 205: utcommand(dev, com, count) 206: dev_t dev; 207: int com, count; 208: { 209: register struct buf *bp; 210: register int s; 211: 212: bp = &cutbuf[UTUNIT(dev)]; 213: s = spl5(); 214: while (bp->b_flags&B_BUSY) { 215: if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 216: break; 217: bp->b_flags |= B_WANTED; 218: sleep((caddr_t)bp, PRIBIO); 219: } 220: bp->b_flags = B_BUSY|B_READ; 221: splx(s); 222: bp->b_dev = dev; 223: bp->b_command = com; 224: bp->b_repcnt = count; 225: bp->b_blkno = 0; 226: utstrategy(bp); 227: if (count == 0) 228: return; 229: iowait(bp); 230: if (bp->b_flags&B_WANTED) 231: wakeup((caddr_t)bp); 232: bp->b_flags &= B_ERROR; 233: } 234: 235: /* 236: * Queue a tape operation. 237: */ 238: utstrategy(bp) 239: register struct buf *bp; 240: { 241: int tjunit = TJUNIT(bp->b_dev); 242: register struct uba_ctlr *um; 243: register struct buf *dp; 244: 245: /* 246: * Put transfer at end of unit queue 247: */ 248: dp = &tjutab[tjunit]; 249: bp->av_forw = NULL; 250: um = tjdinfo[tjunit]->ui_mi; 251: (void) spl5(); 252: if (dp->b_actf == NULL) { 253: dp->b_actf = bp; 254: /* 255: * Transport not active, so... 256: * put at end of controller queue 257: */ 258: dp->b_forw = NULL; 259: if (um->um_tab.b_actf == NULL) 260: um->um_tab.b_actf = dp; 261: else 262: um->um_tab.b_actl->b_forw = dp; 263: um->um_tab.b_actl = dp; 264: } else 265: dp->b_actl->av_forw = bp; 266: dp->b_actl = bp; 267: /* 268: * If the controller is not busy, set it going. 269: */ 270: if (um->um_tab.b_state == 0) 271: utstart(um); 272: (void) spl0(); 273: } 274: 275: utstart(um) 276: register struct uba_ctlr *um; 277: { 278: register struct utdevice *addr; 279: register struct buf *bp, *dp; 280: register struct tj_softc *sc; 281: struct uba_device *ui; 282: int tjunit; 283: daddr_t blkno; 284: 285: loop: 286: /* 287: * Scan controller queue looking for units with 288: * transaction queues to dispatch 289: */ 290: if ((dp = um->um_tab.b_actf) == NULL) 291: return; 292: if ((bp = dp->b_actf) == NULL) { 293: um->um_tab.b_actf = dp->b_forw; 294: goto loop; 295: } 296: addr = (struct utdevice *)um->um_addr; 297: tjunit = TJUNIT(bp->b_dev); 298: ui = tjdinfo[tjunit]; 299: sc = &tj_softc[tjunit]; 300: /* note slave select, density, and format were merged on open */ 301: addr->uttc = sc->sc_dens; 302: sc->sc_dsreg = addr->utds; 303: sc->sc_erreg = addr->uter; 304: sc->sc_resid = MASKREG(addr->utfc); 305: /* 306: * Default is that last command was NOT a write command; 307: * if we do a write command we will notice this in utintr(). 308: */ 309: sc->sc_lastiow = 0; 310: if (sc->sc_openf < 0 || (addr->utds&UTDS_MOL) == 0) { 311: /* 312: * Have had a hard error on a non-raw tape 313: * or the tape unit is now unavailable 314: * (e.g. taken off line). 315: */ 316: bp->b_flags |= B_ERROR; 317: goto next; 318: } 319: if (bp == &cutbuf[UTUNIT(bp->b_dev)]) { 320: /* 321: * Execute a control operation with the specified 322: * count. 323: */ 324: if (bp->b_command == UT_SENSE) 325: goto next; 326: if (bp->b_command == UT_SFORW && (addr->utds & UTDS_EOT)) { 327: bp->b_resid = bp->b_bcount; 328: goto next; 329: } 330: /* 331: * Set next state; handle timeouts 332: */ 333: if (bp->b_command == UT_REW) { 334: um->um_tab.b_state = SREW; 335: sc->sc_timo = 5*60; 336: } else { 337: um->um_tab.b_state = SCOM; 338: sc->sc_timo = imin(imax(10*(int)-bp->b_repcnt,60),5*60); 339: } 340: /* NOTE: this depends on the ut command values */ 341: if (bp->b_command >= UT_SFORW && bp->b_command <= UT_SREVF) 342: addr->utfc = -bp->b_repcnt; 343: goto dobpcmd; 344: } 345: /* 346: * The following checks boundary conditions for operations 347: * on non-raw tapes. On raw tapes the initialization of 348: * sc->sc_nxrec by utphys causes them to be skipped normally 349: * (except in the case of retries). 350: */ 351: if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 352: /* can't read past end of file */ 353: bp->b_flags |= B_ERROR; 354: bp->b_error = ENXIO; 355: goto next; 356: } 357: if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && (bp->b_flags&B_READ)) { 358: /* read at eof returns 0 count */ 359: bp->b_resid = bp->b_bcount; 360: clrbuf(bp); 361: goto next; 362: } 363: if ((bp->b_flags&B_READ) == 0) 364: sc->sc_nxrec = bdbtofsb(bp->b_blkno)+1; 365: /* 366: * If the tape is correctly positioned, set up all the 367: * registers but the csr, and give control over to the 368: * UNIBUS adaptor routines, to wait for resources to 369: * start I/O. 370: */ 371: if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 372: addr->utwc = -(((bp->b_bcount)+1)>>1); 373: addr->utfc = -bp->b_bcount; 374: if ((bp->b_flags&B_READ) == 0) { 375: /* 376: * On write error retries erase the 377: * inter-record gap before rewriting. 378: */ 379: if (um->um_tab.b_errcnt) { 380: if (um->um_tab.b_state != SERASED) { 381: um->um_tab.b_state = SERASE; 382: sc->sc_timo = 60; 383: addr->utcs1 = UT_ERASE|UT_IE|UT_GO; 384: return; 385: } 386: } 387: if (addr->utds & UTDS_EOT) { 388: bp->b_resid = bp->b_bcount; 389: um->um_tab.b_state = 0; 390: goto next; 391: } 392: um->um_cmd = UT_WCOM; 393: } else 394: um->um_cmd = UT_RCOM; 395: sc->sc_timo = 60; 396: um->um_tab.b_state = SIO; 397: (void) ubago(ui); 398: return; 399: } 400: /* 401: * Tape positioned incorrectly; seek forwards or 402: * backwards to the correct spot. This happens for 403: * raw tapes only on error retries. 404: */ 405: um->um_tab.b_state = SSEEK; 406: if (blkno < bdbtofsb(bp->b_blkno)) { 407: addr->utfc = blkno - bdbtofsb(bp->b_blkno); 408: bp->b_command = UT_SFORW; 409: } else { 410: addr->utfc = bdbtofsb(bp->b_blkno) - blkno; 411: bp->b_command = UT_SREV; 412: } 413: sc->sc_timo = imin(imax(10 * -addr->utfc, 60), 5*60); 414: 415: dobpcmd: 416: /* 417: * Perform the command setup in bp. 418: */ 419: addr->utcs1 = bp->b_command|UT_IE|UT_GO; 420: return; 421: next: 422: /* 423: * Advance to the next command in the slave queue, 424: * posting notice and releasing resources as needed. 425: */ 426: if (um->um_ubinfo) 427: ubadone(um); 428: um->um_tab.b_errcnt = 0; 429: dp->b_actf = bp->av_forw; 430: iodone(bp); 431: goto loop; 432: } 433: 434: /* 435: * Start operation on controller -- 436: * UNIBUS resources have been allocated. 437: */ 438: utdgo(um) 439: register struct uba_ctlr *um; 440: { 441: register struct utdevice *addr = (struct utdevice *)um->um_addr; 442: 443: addr->utba = (u_short) um->um_ubinfo; 444: addr->utcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300)|UT_IE|UT_GO; 445: } 446: 447: /* 448: * Ut interrupt handler 449: */ 450: /*ARGSUSED*/ 451: utintr(ut11) 452: int ut11; 453: { 454: struct buf *dp; 455: register struct buf *bp; 456: register struct uba_ctlr *um = utminfo[ut11]; 457: register struct utdevice *addr; 458: register struct tj_softc *sc; 459: u_short tjunit, cs2, cs1; 460: register state; 461: 462: if ((dp = um->um_tab.b_actf) == NULL) 463: return; 464: bp = dp->b_actf; 465: tjunit = TJUNIT(bp->b_dev); 466: addr = (struct utdevice *)tjdinfo[tjunit]->ui_addr; 467: sc = &tj_softc[tjunit]; 468: /* 469: * Record status... 470: */ 471: sc->sc_timo = INF; 472: sc->sc_dsreg = addr->utds; 473: sc->sc_erreg = addr->uter; 474: sc->sc_resid = MASKREG(addr->utfc); 475: if ((bp->b_flags&B_READ) == 0) 476: sc->sc_lastiow = 1; 477: state = um->um_tab.b_state; 478: um->um_tab.b_state = 0; 479: /* 480: * Check for errors... 481: */ 482: if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) { 483: /* 484: * To clear the ERR bit, we must issue a drive clear 485: * command, and to clear the TRE bit we must set the 486: * controller clear bit. 487: */ 488: cs2 = addr->utcs2; 489: if ((cs1 = addr->utcs1)&UT_TRE) 490: addr->utcs2 |= UTCS2_CLR; 491: /* is this dangerous ?? */ 492: while ((addr->utcs1&UT_RDY) == 0) 493: ; 494: addr->utcs1 = UT_CLEAR|UT_GO; 495: /* 496: * If we were reading at 1600 or 6250 bpi and the error 497: * was corrected, then don't consider this an error. 498: */ 499: if (sc->sc_erreg & UTER_COR && (bp->b_flags & B_READ) && 500: (addr->uttc & UTTC_DEN) != UT_NRZI) { 501: tprintf(sc->sc_ttyp, 502: "ut%d: soft error bn%d cs1=%b er=%b cs2=%b ds=%b\n", 503: tjunit, bp->b_blkno, cs1, UT_BITS, sc->sc_erreg, 504: UTER_BITS, cs2, UTCS2_BITS, sc->sc_dsreg, UTDS_BITS); 505: sc->sc_erreg &= ~UTER_COR; 506: } 507: /* 508: * If we were reading from a raw tape and the only error 509: * was that the record was too long, then we don't consider 510: * this an error. 511: */ 512: if (bp == &rutbuf[UTUNIT(bp->b_dev)] && (bp->b_flags&B_READ) && 513: (sc->sc_erreg&UTER_FCE)) 514: sc->sc_erreg &= ~UTER_FCE; 515: if (sc->sc_erreg == 0) 516: goto ignoreerr; 517: /* 518: * Fix up errors which occur due to backspacing 519: * "over" the front of the tape. 520: */ 521: if ((sc->sc_dsreg & UTDS_BOT) && bp->b_command == UT_SREV && 522: ((sc->sc_erreg &= ~(UTER_NEF|UTER_FCE)) == 0)) 523: goto opdone; 524: /* 525: * Retry soft errors up to 8 times 526: */ 527: if ((sc->sc_erreg&UTER_HARD) == 0 && state == SIO) { 528: if (++um->um_tab.b_errcnt < 7) { 529: sc->sc_blkno++; 530: ubadone(um); 531: goto opcont; 532: } 533: } 534: /* 535: * Hard or non-I/O errors on non-raw tape 536: * cause it to close. 537: */ 538: if (sc->sc_openf > 0 && bp != &rutbuf[UTUNIT(bp->b_dev)]) 539: sc->sc_openf = -1; 540: /* 541: * Couldn't recover error. 542: */ 543: tprintf(sc->sc_ttyp, 544: "ut%d: hard error bn%d cs1=%b er=%b cs2=%b ds=%b\n", 545: tjunit, bp->b_blkno, cs1, UT_BITS, sc->sc_erreg, 546: UTER_BITS, cs2, UTCS2_BITS, sc->sc_dsreg, UTDS_BITS); 547: bp->b_flags |= B_ERROR; 548: goto opdone; 549: } 550: 551: ignoreerr: 552: /* 553: * If we hit a tape mark update our position. 554: */ 555: if (sc->sc_dsreg & UTDS_TM && bp->b_flags & B_READ) { 556: /* 557: * Set blkno and nxrec 558: */ 559: if (bp == &cutbuf[UTUNIT(bp->b_dev)]) { 560: if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 561: sc->sc_nxrec = 562: bdbtofsb(bp->b_blkno) - addr->utfc; 563: sc->sc_blkno = sc->sc_nxrec; 564: } else { 565: sc->sc_blkno = 566: bdbtofsb(bp->b_blkno) + addr->utfc; 567: sc->sc_nxrec = sc->sc_blkno-1; 568: } 569: } else 570: sc->sc_nxrec = bdbtofsb(bp->b_blkno); 571: /* 572: * Note: if we get a tape mark on a read, the 573: * frame count register will be zero, so b_resid 574: * will be calculated correctly below. 575: */ 576: goto opdone; 577: } 578: /* 579: * Advance tape control FSM. 580: */ 581: switch (state) { 582: 583: case SIO: /* read/write increments tape block # */ 584: sc->sc_blkno++; 585: break; 586: 587: case SCOM: /* motion commands update current position */ 588: if (bp == &cutbuf[UTUNIT(bp->b_dev)]) 589: switch ((int)bp->b_command) { 590: 591: case UT_SFORW: 592: sc->sc_blkno -= bp->b_repcnt; 593: break; 594: 595: case UT_SREV: 596: sc->sc_blkno += bp->b_repcnt; 597: break; 598: 599: case UT_REWOFFL: 600: addr->utcs1 = UT_CLEAR|UT_GO; 601: break; 602: } 603: break; 604: 605: case SSEEK: 606: sc->sc_blkno = bdbtofsb(bp->b_blkno); 607: goto opcont; 608: 609: case SERASE: 610: /* 611: * Completed erase of the inter-record gap due to a 612: * write error; now retry the write operation. 613: */ 614: um->um_tab.b_state = SERASED; 615: goto opcont; 616: 617: case SREW: /* clear attention bit */ 618: addr->utcs1 = UT_CLEAR|UT_GO; 619: break; 620: 621: default: 622: printf("bad state %d\n", state); 623: panic("utintr"); 624: } 625: 626: opdone: 627: /* 628: * Reset error count and remove 629: * from device queue 630: */ 631: um->um_tab.b_errcnt = 0; 632: dp->b_actf = bp->av_forw; 633: /* 634: * For read command, frame count register contains 635: * actual length of tape record. Otherwise, it 636: * holds negative residual count. 637: */ 638: if (state == SIO && um->um_cmd == UT_RCOM) { 639: bp->b_resid = 0; 640: if (bp->b_bcount > MASKREG(addr->utfc)) 641: bp->b_resid = bp->b_bcount - MASKREG(addr->utfc); 642: } else 643: bp->b_resid = MASKREG(-addr->utfc); 644: ubadone(um); 645: iodone(bp); 646: /* 647: * Circulate slave to end of controller queue 648: * to give other slaves a chance 649: */ 650: um->um_tab.b_actf = dp->b_forw; 651: if (dp->b_actf) { 652: dp->b_forw = NULL; 653: if (um->um_tab.b_actf == NULL) 654: um->um_tab.b_actf = dp; 655: else 656: um->um_tab.b_actl->b_forw = dp; 657: um->um_tab.b_actl = dp; 658: } 659: if (um->um_tab.b_actf == 0) 660: return; 661: opcont: 662: utstart(um); 663: } 664: 665: /* 666: * Watchdog timer routine. 667: */ 668: uttimer(dev) 669: int dev; 670: { 671: register struct tj_softc *sc = &tj_softc[TJUNIT(dev)]; 672: register short x; 673: 674: if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) { 675: printf("tj%d: lost interrupt\n", TJUNIT(dev)); 676: sc->sc_timo = INF; 677: x = spl5(); 678: utintr(UTUNIT(dev)); 679: (void) splx(x); 680: } 681: timeout(uttimer, (caddr_t)dev, 5*hz); 682: } 683: 684: /* 685: * Raw interface for a read 686: */ 687: utread(dev, uio) 688: dev_t dev; 689: struct uio *uio; 690: { 691: int errno; 692: 693: errno = utphys(dev, uio); 694: if (errno) 695: return (errno); 696: return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_READ, minphys, uio)); 697: } 698: 699: /* 700: * Raw interface for a write 701: */ 702: utwrite(dev, uio) 703: dev_t dev; 704: struct uio *uio; 705: { 706: int errno; 707: 708: errno = utphys(dev, uio); 709: if (errno) 710: return (errno); 711: return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_WRITE, minphys, uio)); 712: } 713: 714: /* 715: * Check for valid device number dev and update our notion 716: * of where we are on the tape 717: */ 718: utphys(dev, uio) 719: dev_t dev; 720: struct uio *uio; 721: { 722: register int tjunit = TJUNIT(dev); 723: register struct tj_softc *sc; 724: register struct uba_device *ui; 725: 726: if (tjunit >= NTJ || (ui=tjdinfo[tjunit]) == 0 || ui->ui_alive == 0) 727: return (ENXIO); 728: sc = &tj_softc[tjunit]; 729: sc->sc_blkno = bdbtofsb(uio->uio_offset>>9); 730: sc->sc_nxrec = sc->sc_blkno+1; 731: return (0); 732: } 733: 734: /*ARGSUSED*/ 735: utioctl(dev, cmd, data, flag) 736: dev_t dev; 737: caddr_t data; 738: { 739: register struct tj_softc *sc = &tj_softc[TJUNIT(dev)]; 740: register struct buf *bp = &cutbuf[UTUNIT(dev)]; 741: register callcount; 742: int fcount; 743: struct mtop *mtop; 744: struct mtget *mtget; 745: /* we depend of the values and order of the MT codes here */ 746: static utops[] = 747: {UT_WEOF,UT_SFORWF,UT_SREVF,UT_SFORW,UT_SREV,UT_REW,UT_REWOFFL,UT_SENSE}; 748: 749: switch (cmd) { 750: 751: case MTIOCTOP: 752: mtop = (struct mtop *)data; 753: switch(mtop->mt_op) { 754: 755: case MTWEOF: 756: case MTFSF: case MTBSF: 757: case MTFSR: case MTBSR: 758: callcount = mtop->mt_count; 759: fcount = 1; 760: break; 761: 762: case MTREW: case MTOFFL: case MTNOP: 763: callcount = 1; 764: fcount = 1; 765: break; 766: 767: default: 768: return (ENXIO); 769: } 770: if (callcount <= 0 || fcount <= 0) 771: return (EINVAL); 772: while (--callcount >= 0) { 773: utcommand(dev, utops[mtop->mt_op], fcount); 774: if ((bp->b_flags&B_ERROR) || (sc->sc_dsreg&UTDS_BOT)) 775: break; 776: } 777: return (geterror(bp)); 778: 779: case MTIOCGET: 780: mtget = (struct mtget *)data; 781: mtget->mt_dsreg = sc->sc_dsreg; 782: mtget->mt_erreg = sc->sc_erreg; 783: mtget->mt_resid = sc->sc_resid; 784: mtget->mt_type = MT_ISUT; 785: break; 786: 787: default: 788: return (ENXIO); 789: } 790: return (0); 791: } 792: 793: utreset(uban) 794: int uban; 795: { 796: register struct uba_ctlr *um; 797: register ut11, tjunit; 798: register struct uba_device *ui; 799: register struct buf *dp; 800: 801: for (ut11 = 0; ut11 < NUT; ut11++) { 802: if ((um = utminfo[ut11]) == 0 || um->um_alive == 0 || 803: um->um_ubanum != uban) 804: continue; 805: printf(" ut%d", ut11); 806: um->um_tab.b_state = 0; 807: um->um_tab.b_actf = um->um_tab.b_actl = 0; 808: if (um->um_ubinfo) { 809: printf("<%d>", (um->um_ubinfo>>28)&0xf); 810: um->um_ubinfo = 0; 811: } 812: ((struct utdevice *)(um->um_addr))->utcs1 = UT_CLEAR|UT_GO; 813: ((struct utdevice *)(um->um_addr))->utcs2 |= UTCS2_CLR; 814: for (tjunit = 0; tjunit < NTJ; tjunit++) { 815: if ((ui = tjdinfo[tjunit]) == 0 || ui->ui_mi != um || 816: ui->ui_alive == 0) 817: continue; 818: dp = &tjutab[tjunit]; 819: dp->b_state = 0; 820: dp->b_forw = 0; 821: if (um->um_tab.b_actf == NULL) 822: um->um_tab.b_actf = dp; 823: else 824: um->um_tab.b_actl->b_forw = dp; 825: um->um_tab.b_actl = dp; 826: if (tj_softc[tjunit].sc_openf > 0) 827: tj_softc[tjunit].sc_openf = -1; 828: } 829: utstart(um); 830: } 831: } 832: 833: /* 834: * Do a stand-alone core dump to tape -- 835: * from here down, routines are used only in dump context 836: */ 837: #define DBSIZE 20 838: 839: utdump() 840: { 841: register struct uba_device *ui; 842: register struct uba_regs *up; 843: register struct utdevice *addr; 844: int blk, num = maxfree; 845: int start = 0; 846: 847: #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 848: if (tjdinfo[0] == 0) 849: return (ENXIO); 850: ui = phys(tjdinfo[0], struct uba_device *); 851: up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba; 852: ubainit(up); 853: DELAY(1000000); 854: addr = (struct utdevice *)ui->ui_physaddr; 855: utwait(addr); 856: /* 857: * Be sure to set the appropriate density here. We use 858: * 6250, but maybe it should be done at 1600 to insure the 859: * tape can be read by most any other tape drive available. 860: */ 861: addr->uttc = UT_GCR|PDP11FMT; /* implicit slave 0 or-ed in */ 862: addr->utcs1 = UT_CLEAR|UT_GO; 863: while (num > 0) { 864: blk = num > DBSIZE ? DBSIZE : num; 865: utdwrite(start, blk, addr, up); 866: if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) 867: return(EIO); 868: start += blk; 869: num -= blk; 870: } 871: uteof(addr); 872: uteof(addr); 873: utwait(addr); 874: if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) 875: return(EIO); 876: addr->utcs1 = UT_REW|UT_GO; 877: return (0); 878: } 879: 880: utdwrite(dbuf, num, addr, up) 881: register dbuf, num; 882: register struct utdevice *addr; 883: struct uba_regs *up; 884: { 885: register struct pte *io; 886: register int npf; 887: 888: utwait(addr); 889: io = up->uba_map; 890: npf = num + 1; 891: while (--npf != 0) 892: *(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) | UBAMR_MRV); 893: *(int *)io = 0; 894: addr->utwc = -((num*NBPG)>>1); 895: addr->utfc = -(num*NBPG); 896: addr->utba = 0; 897: addr->utcs1 = UT_WCOM|UT_GO; 898: } 899: 900: utwait(addr) 901: struct utdevice *addr; 902: { 903: register s; 904: 905: do 906: s = addr->utds; 907: while ((s&UTDS_DRY) == 0); 908: } 909: 910: uteof(addr) 911: struct utdevice *addr; 912: { 913: 914: utwait(addr); 915: addr->utcs1 = UT_WEOF|UT_GO; 916: } 917: #endif