1: /* 2: * Copyright (c) 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: * @(#)ts.c 2.3 (2.11BSD GTE) 11/26/94 7: */ 8: 9: /* 10: * TS11 tape driver 11: */ 12: 13: #include "ts.h" 14: #if NTS > 0 15: #include "param.h" 16: #include "buf.h" 17: #include "conf.h" 18: #include "file.h" 19: #include "user.h" 20: #include "ioctl.h" 21: #include "fs.h" 22: #include "tsreg.h" 23: #include "mtio.h" 24: #include "map.h" 25: #include "uba.h" 26: 27: /* 28: * Software state per tape transport: 29: * 30: * 1. A tape drive is a unique-open device: we refuse opens when it is already 31: * 2. We keep track of the current position on a block tape and seek 32: * before operations by forward/back spacing if necessary. 33: * 3. We remember if the last operation was a write on a tape, so if a tape 34: * is open read write and the last thing done is a write we can 35: * write a standard end of tape mark (two eofs). 36: * 4. We remember the status registers after the last command, using 37: * them internally and returning them to the SENSE ioctl. 38: */ 39: 40: struct ts_softc { 41: struct tsdevice *sc_addr; /* CSR of controller */ 42: char sc_openf; /* lock against multiple opens */ 43: char sc_lastiow; /* last op was a write */ 44: short sc_resid; /* copy of last bc */ 45: daddr_t sc_blkno; /* block number, for block device tape */ 46: daddr_t sc_nxrec; /* position of end of tape, if known */ 47: struct ts_cmd sc_cmd; /* the command packet */ 48: struct ts_char sc_char;/* status packet, for returned status */ 49: struct ts_sts sc_sts; /* characteristics packet */ 50: u_short sc_uba; /* Unibus addr of cmd pkt for tsdb */ 51: ubadr_t sc_uadr; /* actual unibus address */ 52: struct tty *sc_ttyp; /* record user's tty for errors */ 53: } *ts_softc[NTS]; 54: 55: static ubadr_t TS_ubadr; 56: 57: struct buf tstab[NTS]; 58: 59: /* 60: * There is a ctsbuf per tape controller. 61: * It is used as the token to pass to the internal routines 62: * to execute tape ioctls. 63: * In particular, when the tape is rewinding on close we release 64: * the user process but any further attempts to use the tape drive 65: * before the rewind completes will hang waiting for ctsbuf. 66: */ 67: struct buf ctsbuf[NTS]; 68: 69: #define INF ((daddr_t) ((u_short) 65535)) 70: 71: /* bits in minor device */ 72: #define TSUNIT(dev) (minor(dev)&03) /* not used */ 73: #define TSCTLR(dev) ((minor(dev) >> 6) & 3) 74: #define T_NOREWIND 04 75: 76: /* 77: * States for tstab.b_active, the state flag. 78: * This is used to sequence control in the driver. 79: */ 80: #define SSEEK 1 /* seeking */ 81: #define SIO 2 /* doing seq. i/o */ 82: #define SCOM 3 /* sending a control command */ 83: #define SREW 4 /* sending a drive rewind */ 84: 85: u_short softspace[NTS][(sizeof(struct ts_softc)/2) + 1]; 86: 87: static char *tsmsg1 = "ts%d: not online\n"; 88: static char *tsmsg2 = "ts%d: no write ring\n"; 89: 90: tsattach(addr, unit) 91: struct tsdevice *addr; 92: register int unit; 93: { 94: register u_short sp = (u_short)softspace[unit]; 95: register struct ts_softc *sc; 96: struct buf tbuf; 97: 98: if (unit >= NTS) 99: return(0); 100: /* 101: * We want space for an array of NTS ts_softc structures, 102: * where the sc_cmd field of each is long-aligned, i.e. the 103: * core address is a 4-byte multiple. The compiler only 104: * guarantees word alignment. We reserve and extra 3 bytes 105: * so that we can slide the array down by 2 if the compiler 106: * gets it wrong. Only allocate 1 UMR to map all of the 107: * communication area instead of a UMR per controller. 108: * 109: * On a UNIBUS system the ts_softc structure is aligned so 110: * that the UNIBUS virtual address of sc_cmd falls on a 4 111: * byte boundary - the physical address may be on a 2 byte bound. 112: * 113: * On non-UNIBUS systems the ts_softc structure is aligned so 114: * that sc_cmd falls on a physical 4 byte boundary. 115: */ 116: sc = (struct ts_softc *)sp; 117: if (((u_short)&sc->sc_cmd - (ubmap ? (u_short)softspace : 0)) & 3) 118: sp += 2; 119: if (ubmap && TS_ubadr == 0) { 120: tbuf.b_xmem = 0; /* won't work above 64k any way */ 121: tbuf.b_un.b_addr = (caddr_t) softspace; 122: tbuf.b_flags = B_PHYS; 123: tbuf.b_bcount = sizeof (softspace); 124: mapalloc(&tbuf); 125: TS_ubadr = ((long)((unsigned)tbuf.b_xmem)) << 16 126: | ((long)((unsigned)tbuf.b_un.b_addr)); 127: } 128: sc = ts_softc[unit] = (struct ts_softc *) sp; 129: sc->sc_addr = addr; 130: sc->sc_uadr = TS_ubadr + ((u_short)&sc->sc_cmd - 131: (ubmap ? (u_short)softspace : 0)); 132: sc->sc_uba = loint(sc->sc_uadr) 133: | hiint(sc->sc_uadr); /* register format */ 134: return(1); 135: } 136: 137: /* 138: * Open the device. Tapes are unique open 139: * devices so we refuse if it is already open. 140: * We also check that a tape is available and 141: * don't block waiting here: if you want to wait 142: * for a tape you should timeout in user code. 143: */ 144: tsopen(dev, flag) 145: dev_t dev; 146: int flag; 147: { 148: register ts11 = TSCTLR(dev); 149: register struct ts_softc *sc = ts_softc[ts11]; 150: 151: if (ts11 >= NTS || !sc || sc->sc_openf) 152: return(ENXIO); 153: if (tsinit(ts11)) { 154: printf("ts%d: init failure tssr=%b\n", 155: ts11, sc->sc_addr->tssr, TSSR_BITS); 156: return(ENXIO); 157: } 158: tstab[ts11].b_flags |= B_TAPE; 159: tscommand(dev, TS_SENSE, 1); 160: if ((sc->sc_sts.s_xs0 & TS_ONL) == 0) { 161: uprintf(tsmsg1, ts11); 162: return(EIO); 163: } 164: if ((flag & (FREAD | FWRITE)) == FWRITE 165: && (sc->sc_sts.s_xs0 & TS_WLK)) { 166: uprintf(tsmsg2, ts11); 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_ttyp = u.u_ttyp; 174: return(0); 175: } 176: 177: /* 178: * Close tape device. 179: * 180: * If tape was open for writing or last operation was 181: * a write, then write two EOF's and backspace over the last one. 182: * Unless his is a non-rewinding special file, rewind the tape. 183: * Make the tape available to others. 184: */ 185: tsclose(dev, flag) 186: register dev_t dev; 187: register int flag; 188: { 189: register struct ts_softc *sc = ts_softc[TSCTLR(dev)]; 190: 191: if (flag == FWRITE || ((flag & FWRITE) && sc->sc_lastiow)) { 192: tscommand(dev, TS_WEOF, 1); 193: tscommand(dev, TS_WEOF, 1); 194: tscommand(dev, TS_SREV, 1); 195: } 196: if ((minor(dev) & T_NOREWIND) == 0 ) 197: /* 198: * 0 count means don't hang waiting for rewind complete. 199: * Rather ctsbuf stays busy until the operation completes 200: * preventing further opens from completing by 201: * preventing a TS_SENSE from completing. 202: */ 203: tscommand(dev, TS_REW, 0); 204: sc->sc_openf = 0; 205: } 206: 207: /* 208: * Execute a command on the tape drive 209: * a specified number of times. 210: */ 211: tscommand(dev, com, count) 212: dev_t dev; 213: register u_short count; 214: { 215: register int s; 216: register struct buf *bp; 217: 218: bp = &ctsbuf[TSCTLR(dev)]; 219: s = splbio(); 220: while(bp->b_flags & B_BUSY) { 221: /* 222: * This special check is because B_BUSY never 223: * gets cleared in the non-waiting rewind case. 224: */ 225: if (bp->b_repcnt == 0 && (bp->b_flags & B_DONE)) 226: break; 227: bp->b_flags |= B_WANTED; 228: sleep((caddr_t) bp, PRIBIO); 229: } 230: bp->b_flags = B_BUSY | B_READ; 231: splx(s); 232: bp->b_dev = dev; 233: bp->b_repcnt = count; 234: bp->b_command = com; 235: bp->b_blkno = (daddr_t) 0; 236: tsstrategy(bp); 237: /* 238: * In case of rewind from close, don't wait. 239: * This is the only case where count can be 0. 240: */ 241: if (count == 0) 242: return; 243: iowait(bp); 244: if(bp->b_flags & B_WANTED) 245: wakeup((caddr_t) bp); 246: bp->b_flags &= B_ERROR; 247: } 248: 249: /* 250: * Queue a tape operation. 251: */ 252: tsstrategy(bp) 253: register struct buf *bp; 254: { 255: register int s; 256: int ts11 = TSCTLR(bp->b_dev); 257: struct ts_softc *sc = ts_softc[ts11]; 258: register struct buf *dp = &tstab[ts11]; 259: 260: if (bp->b_flags & B_PHYS) { /* if RAW I/O call */ 261: mapalloc(bp); 262: sc->sc_blkno = sc->sc_nxrec = dbtofsb(bp->b_blkno); 263: sc->sc_nxrec++; 264: } 265: bp->av_forw = NULL; 266: s = splbio(); 267: if (dp->b_actf == NULL) 268: dp->b_actf = bp; 269: else 270: dp->b_actl->av_forw = bp; 271: dp->b_actl = bp; 272: /* 273: * If the controller is not busy, get 274: * it going. 275: */ 276: if (dp->b_active == 0) 277: tsstart(ts11); 278: splx(s); 279: } 280: 281: /* 282: * Start activity on a ts controller. 283: */ 284: tsstart(ts11) 285: int ts11; 286: { 287: daddr_t blkno; 288: int cmd; 289: register struct ts_softc *sc; 290: register struct ts_cmd *tc; 291: register struct buf *bp; 292: struct buf *um = &tstab[ts11]; 293: 294: /* 295: * Start the controller if there is something for it to do. 296: */ 297: loop: 298: if ((bp = um->b_actf) == NULL) 299: return; 300: sc = ts_softc[ts11]; 301: tc = &sc->sc_cmd; 302: /* 303: * Default is that last command was NOT a write command; 304: * if we do a write command we will notice this in tsintr(). 305: */ 306: sc->sc_lastiow = 0; 307: if (sc->sc_openf < 0 || (sc->sc_addr->tssr & TS_OFL)) { 308: /* 309: * Have had a hard error on a non-raw tape 310: * or the tape unit is now unavailable 311: * (e.g. taken off line). 312: */ 313: bp->b_flags |= B_ERROR; 314: goto next; 315: } 316: if (bp == &ctsbuf[ts11]) { 317: /* 318: * Execute control operation with the specified count. 319: */ 320: um->b_active = bp->b_command == TS_REW ? SREW : SCOM; 321: goto dobpcmd; 322: } 323: /* 324: * The following checks handle boundary cases for operation 325: * on non-raw tapes. On raw tapes the initialization of 326: * sc->sc_nxrec by tsphys causes them to be skipped normally 327: * (except in the case of retries). 328: */ 329: if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) { 330: /* 331: * Can't read past known end-of-file. 332: */ 333: bp->b_flags |= B_ERROR; 334: bp->b_error = ENXIO; 335: goto next; 336: } 337: if (dbtofsb(bp->b_blkno) == sc->sc_nxrec && bp->b_flags & B_READ) { 338: /* 339: * Reading at end of file returns 0 bytes. 340: * Buffer will be cleared (if written) in rwip. 341: */ 342: bp->b_resid = bp->b_bcount; 343: goto next; 344: } 345: if((bp->b_flags & B_READ) == 0) 346: /* 347: * Writing sets EOF 348: */ 349: sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1; 350: /* 351: * If the data transfer command is in the correct place, 352: * set up all registers and do the transfer. 353: */ 354: if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) { 355: um->b_active = SIO; 356: tc->c_loba = (u_short)bp->b_un.b_addr; 357: tc->c_hiba = bp->b_xmem; 358: tc->c_size = bp->b_bcount; 359: if ((bp->b_flags & B_READ) == 0) 360: cmd = TS_WCOM; 361: else 362: cmd = TS_RCOM; 363: if (um->b_errcnt) 364: cmd |= TS_RETRY; 365: tc->c_cmd = TS_ACK | TS_CVC | TS_IE | cmd; 366: sc->sc_addr->tsdb = sc->sc_uba; 367: return; 368: } 369: /* 370: * Tape positioned incorrectly; 371: * set to seek forward or backward to the correct spot. 372: * This happens for raw tapes only on error retries. 373: */ 374: um->b_active = SSEEK; 375: if (blkno < dbtofsb(bp->b_blkno)) { 376: bp->b_command = TS_SFORW; 377: bp->b_repcnt = dbtofsb(bp->b_blkno) - blkno; 378: } else 379: { 380: bp->b_command = TS_SREV; 381: bp->b_repcnt = blkno - dbtofsb(bp->b_blkno); 382: } 383: dobpcmd: 384: tc->c_repcnt = bp->b_repcnt; 385: /* 386: * Do the command in bp. 387: */ 388: tc->c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command; 389: sc->sc_addr->tsdb = sc->sc_uba; 390: return; 391: 392: next: 393: /* 394: * Done with this operation due to error or 395: * the fact that it doesn't do anything. 396: * Dequeue the transfer and continue processing this slave. 397: */ 398: um->b_errcnt = 0; 399: um->b_actf = bp->av_forw; 400: iodone(bp); 401: goto loop; 402: } 403: 404: /* 405: * TS interrupt routine 406: */ 407: tsintr(dev) 408: int dev; 409: { 410: int state; 411: register struct buf *bp, *um = &tstab[dev]; 412: register struct ts_softc *sc = ts_softc[dev]; 413: 414: if ((bp = um->b_actf) == NULL) 415: return; 416: 417: /* 418: * If last command was a rewind, and tape is still 419: * rewinding, wait for the rewind complete interrupt. 420: * 421: * SHOULD NEVER GET AN INTERRUPT IN THIS STATE, but it 422: * happens when a rewind completes. 423: */ 424: if (um->b_active == SREW) { 425: um->b_active = SCOM; 426: if ((sc->sc_addr->tssr & TS_SSR) == 0) 427: return; 428: } 429: /* 430: * An operation completed... record status 431: */ 432: if ((bp->b_flags & B_READ) == 0) 433: sc->sc_lastiow = 1; 434: state = um->b_active; 435: um->b_active = 0; 436: 437: /* 438: * Check for errors. 439: */ 440: if (sc->sc_addr->tssr & TS_SC) { 441: switch (sc->sc_addr->tssr & TS_TC) { 442: case TS_UNREC: /* unrecoverable */ 443: case TS_FATAL: /* fatal error */ 444: case TS_ATTN: /* attention (shouldn't happen) */ 445: case TS_RECNM: /* recoverable, no motion */ 446: break; 447: 448: case TS_SUCC: /* successful termination */ 449: goto ignoreerr; 450: /*NOTREACHED*/ 451: 452: case TS_ALERT: /* tape status alert */ 453: /* 454: * If we hit the end of the tape file, 455: * update our position. 456: */ 457: if (sc->sc_sts.s_xs0 & (TS_TMK | TS_EOT)) { 458: tsseteof(bp); /* set blkno and nxrec */ 459: state = SCOM; /* force completion */ 460: /* 461: * Stuff bc so it will be unstuffed 462: * correctly later to get resid. 463: */ 464: sc->sc_sts.s_rbpcr = bp->b_bcount; 465: goto opdone; 466: /*NOTREACHED*/ 467: } 468: /* 469: * If we were reading raw tape and the record 470: * was too long or too short, then we don't 471: * consider this an error. 472: */ 473: if ((bp->b_flags & B_PHYS) && (bp->b_flags & B_READ) 474: && sc->sc_sts.s_xs0 & (TS_RLS | TS_RLL)) 475: goto ignoreerr; 476: /*NOTREACHED*/ 477: 478: case TS_RECOV: /* recoverable, tape moved */ 479: /* 480: * If this was an i/o operation, 481: * retry up to 8 times. 482: */ 483: if (state == SIO) { 484: if (++(um->b_errcnt) < 7) 485: goto opcont; 486: else 487: sc->sc_blkno++; 488: } else 489: { 490: /* 491: * Non-i/o errors on non-raw tape 492: * cause it to close. 493: */ 494: if (sc->sc_openf > 0 && !(bp->b_flags & B_PHYS)) 495: sc->sc_openf = -1; 496: } 497: break; 498: 499: case TS_REJECT: 500: if (state == SIO && sc->sc_sts.s_xs0 & TS_WLE) 501: tprintf(sc->sc_ttyp, tsmsg2, dev); 502: if ((sc->sc_sts.s_xs0 & TS_ONL) == 0) 503: tprintf(sc->sc_ttyp, tsmsg1, dev); 504: break; 505: } 506: /* 507: * Couldn't recover error. 508: */ 509: tprintf(sc->sc_ttyp,"ts%d: hard error bn%D xs0=%b", dev, 510: bp->b_blkno, sc->sc_sts.s_xs0, TSXS0_BITS); 511: if (sc->sc_sts.s_xs1) 512: tprintf(sc->sc_ttyp," xs1=%b", sc->sc_sts.s_xs1, TSXS1_BITS); 513: if (sc->sc_sts.s_xs2) 514: tprintf(sc->sc_ttyp," xs2=%b", sc->sc_sts.s_xs2, TSXS2_BITS); 515: if (sc->sc_sts.s_xs3) 516: tprintf(sc->sc_ttyp," xs3=%b", sc->sc_sts.s_xs3, TSXS3_BITS); 517: tprintf(sc->sc_ttyp,"\n"); 518: bp->b_flags |= B_ERROR; 519: goto opdone; 520: /*NOTREACHED*/ 521: } 522: /* 523: * Advance tape control finite state machine. 524: */ 525: ignoreerr: 526: switch (state) { 527: case SIO: 528: /* 529: * Read/write increments tape block number. 530: */ 531: sc->sc_blkno++; 532: goto opdone; 533: /*NOTREACHED*/ 534: 535: case SCOM: 536: /* 537: * For forward/backward space record 538: * update current position. 539: */ 540: if (bp == &ctsbuf[dev]) 541: switch (bp->b_command) { 542: case TS_SFORW: 543: sc->sc_blkno += bp->b_repcnt; 544: break; 545: 546: case TS_SREV: 547: sc->sc_blkno -= bp->b_repcnt; 548: break; 549: } 550: goto opdone; 551: /*NOTREACHED*/ 552: 553: case SSEEK: 554: sc->sc_blkno = dbtofsb(bp->b_blkno); 555: goto opcont; 556: /*NOTREACHED*/ 557: 558: default: 559: panic("tsintr"); 560: /*NOTREACHED*/ 561: } 562: 563: opdone: 564: /* 565: * Reset error count and remove 566: * from device queue. 567: */ 568: um->b_errcnt = 0; 569: um->b_actf = bp->av_forw; 570: bp->b_resid = sc->sc_sts.s_rbpcr; 571: iodone(bp); 572: if (um->b_actf == NULL) 573: return; 574: opcont: 575: tsstart(dev); 576: } 577: 578: tsseteof(bp) 579: register struct buf *bp; 580: { 581: register int ts11 = TSCTLR(bp->b_dev); 582: register struct ts_softc *sc = ts_softc[ts11]; 583: 584: if (bp == &ctsbuf[ts11]) { 585: if (sc->sc_blkno > dbtofsb(bp->b_blkno)) { 586: /* reversing */ 587: sc->sc_nxrec = dbtofsb(bp->b_blkno) - sc->sc_sts.s_rbpcr; 588: sc->sc_blkno = sc->sc_nxrec; 589: } 590: else 591: { 592: /* spacing forward */ 593: sc->sc_blkno = dbtofsb(bp->b_blkno) + sc->sc_sts.s_rbpcr; 594: sc->sc_nxrec = sc->sc_blkno - 1; 595: } 596: return; 597: } 598: /* eof on read */ 599: sc->sc_nxrec = dbtofsb(bp->b_blkno); 600: } 601: 602: /* 603: * Initialize the TS11. 604: */ 605: tsinit(ts11) 606: { 607: register struct ts_softc *sc = ts_softc[ts11]; 608: register struct ts_cmd *tcmd = &sc->sc_cmd; 609: register struct ts_char *tchar = &sc->sc_char; 610: int cnt; 611: /* 612: * Now initialize the TS11 controller. 613: * Set the characteristics. 614: */ 615: if (sc->sc_addr->tssr & (TS_NBA | TS_OFL)) { 616: tcmd->c_cmd = TS_ACK | TS_CVC | TS_INIT; 617: sc->sc_addr->tsdb = sc->sc_uba; 618: for (cnt = 0; cnt < 10000; cnt++) { 619: if (sc->sc_addr->tssr & TS_SSR) 620: break; 621: } 622: if (cnt >= 10000) 623: return (1); 624: tchar->char_bptr = (u_short)loint(sc->sc_uadr)+ 625: ((u_short)&sc->sc_sts-(u_short)tcmd); 626: tchar->char_bae = hiint(sc->sc_uadr); 627: tchar->char_size = sizeof(struct ts_sts); 628: tchar->char_mode = TS_ESS; 629: tcmd->c_cmd = TS_ACK | TS_CVC | TS_SETCHR; 630: tcmd->c_loba = (u_short)loint(sc->sc_uadr)+ 631: ((u_short)tchar-(u_short)tcmd); 632: tcmd->c_hiba = hiint(sc->sc_uadr); 633: tcmd->c_size = sizeof(struct ts_char); 634: sc->sc_addr->tsdb = sc->sc_uba; 635: for (cnt = 0; cnt < 10000; cnt++) { 636: if (sc->sc_addr->tssr & TS_SSR) 637: break; 638: } 639: if (sc->sc_addr->tssr & TS_NBA) { 640: printf("ts%d: set char. failure\n", ts11); 641: return (1); 642: } 643: } 644: return(0); 645: } 646: 647: /*ARGSUSED*/ 648: tsioctl(dev, cmd, data, flag) 649: dev_t dev; 650: u_int cmd; 651: caddr_t data; 652: { 653: int ts11 = TSCTLR(dev); 654: register struct ts_softc *sc = ts_softc[ts11]; 655: register struct buf *bp = &ctsbuf[ts11]; 656: register callcount; 657: u_short fcount; 658: struct mtop *mtop; 659: struct mtget *mtget; 660: /* we depend on the values and order of the MT codes here */ 661: static tsops[] = 662: {TS_WEOF,TS_SFORWF,TS_SREVF,TS_SFORW,TS_SREV,TS_REW,TS_OFFL,TS_SENSE}; 663: 664: switch (cmd) { 665: 666: case MTIOCTOP: /* tape operation */ 667: mtop = (struct mtop *)data; 668: switch(mtop->mt_op) { 669: case MTWEOF: 670: callcount = mtop->mt_count; 671: fcount = 1; 672: break; 673: case MTFSF: case MTBSF: 674: case MTFSR: case MTBSR: 675: callcount = 1; 676: fcount = mtop->mt_count; 677: break; 678: case MTREW: case MTOFFL: case MTNOP: 679: callcount = 1; 680: fcount = 1; 681: break; 682: default: 683: return (ENXIO); 684: } 685: if (callcount <= 0 || fcount <= 0) 686: return (EINVAL); 687: while (--callcount >= 0) { 688: tscommand(dev, tsops[mtop->mt_op], fcount); 689: if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 690: bp->b_resid) 691: return (EIO); 692: if ((bp->b_flags&B_ERROR) || sc->sc_sts.s_xs0&TS_BOT) 693: break; 694: } 695: return (geterror(bp)); 696: case MTIOCGET: 697: mtget = (struct mtget *)data; 698: mtget->mt_dsreg = 0; 699: mtget->mt_erreg = sc->sc_sts.s_xs0; 700: mtget->mt_resid = sc->sc_resid; 701: mtget->mt_type = MT_ISTS; 702: break; 703: default: 704: return (ENXIO); 705: } 706: return (0); 707: } 708: #endif NTS