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 * @(#)ts.c 7.8 (Berkeley) 02/17/90 7 */ 8 9 #include "ts.h" 10 #if NTS > 0 11 /* 12 * TS11 tape driver 13 * 14 * NB: This driver takes advantage of the fact that there is only one 15 * drive per controller. 16 * 17 * TODO: 18 * test dump code 19 */ 20 #include "param.h" 21 #include "systm.h" 22 #include "buf.h" 23 #include "conf.h" 24 #include "user.h" 25 #include "file.h" 26 #include "map.h" 27 #include "vm.h" 28 #include "ioctl.h" 29 #include "mtio.h" 30 #include "cmap.h" 31 #include "uio.h" 32 #include "tty.h" 33 #include "syslog.h" 34 35 #include "machine/pte.h" 36 #include "../vax/cpu.h" 37 #include "ubareg.h" 38 #include "ubavar.h" 39 #include "tsreg.h" 40 41 /* 42 * There is a ctsbuf per tape controller. 43 * It is used as the token to pass to the internal routines 44 * to execute tape ioctls. 45 * In particular, when the tape is rewinding on close we release 46 * the user process but any further attempts to use the tape drive 47 * before the rewind completes will hang waiting for ctsbuf. 48 */ 49 struct buf ctsbuf[NTS]; 50 51 /* 52 * Driver unibus interface routines and variables. 53 */ 54 int tsprobe(), tsslave(), tsattach(), tsdgo(), tsintr(); 55 struct uba_ctlr *tsminfo[NTS]; 56 struct uba_device *tsdinfo[NTS]; 57 struct buf tsutab[NTS]; 58 u_short tsstd[] = { 0772520, 0 }; 59 /* need all these even though controller == drive */ 60 struct uba_driver zsdriver = 61 { tsprobe, tsslave, tsattach, tsdgo, tsstd, "ts", tsdinfo, "zs", tsminfo }; 62 63 /* bits in minor device */ 64 #define TSUNIT(dev) (minor(dev)&03) 65 #define T_NOREWIND 04 66 #define T_1600BPI 010 67 68 #define INF (daddr_t)1000000L 69 70 /* 71 * Software state per tape transport. 72 * Also contains hardware state in message packets. 73 * 74 * 1. A tape drive is a unique-open device; we refuse opens when it is already. 75 * 2. We keep track of the current position on a block tape and seek 76 * before operations by forward/back spacing if necessary. 77 * 3. We remember if the last operation was a write on a tape, so if a tape 78 * is open read write and the last thing done is a write we can 79 * write a standard end of tape mark (two eofs). 80 * 4. We remember the status registers after the last command, using 81 * then internally and returning them to the SENSE ioctl. 82 */ 83 struct ts_tsdata { /* data shared with ts11 controller */ 84 struct ts_cmd t_cmd; /* the command packet (must be first) */ 85 struct ts_sts t_sts; /* status packet, for returned status */ 86 struct ts_char t_char; /* characteristics packet */ 87 }; 88 struct ts_softc { 89 char sc_openf; /* lock against multiple opens */ 90 char sc_lastiow; /* last op was a write */ 91 short sc_resid; /* copy of last bc */ 92 daddr_t sc_blkno; /* block number, for block device tape */ 93 daddr_t sc_nxrec; /* position of end of tape, if known */ 94 struct ts_tsdata sc_ts;/* command and status packets */ 95 struct ts_tsdata *sc_ubaddr; /* Unibus address of tsdata structure */ 96 u_short sc_uba; /* Unibus addr of cmd pkt for tsdb */ 97 short sc_density; /* value |'ed into char_mode for TC13 density */ 98 struct tty *sc_ttyp; /* record user's tty for errors */ 99 int sc_blks; /* number of I/O operations since open */ 100 int sc_softerrs; /* number of soft I/O errors since open */ 101 } ts_softc[NTS]; 102 103 /* 104 * States for um->um_tab.b_active, the per controller state flag. 105 * This is used to sequence control in the driver. 106 */ 107 #define SSEEK 1 /* seeking */ 108 #define SIO 2 /* doing seq i/o */ 109 #define SCOM 3 /* sending control command */ 110 #define SREW 4 /* sending a drive rewind */ 111 112 /* 113 * Determine if there is a controller for 114 * a ts at address reg. Our goal is to make the 115 * device interrupt. 116 */ 117 /*ARGSUSED*/ 118 tsprobe(reg, ctlr, um) 119 caddr_t reg; 120 int ctlr; 121 struct uba_ctlr *um; 122 { 123 register int br, cvec; /* must be r11,r10; value-result */ 124 register struct tsdevice *addr = (struct tsdevice *)reg; 125 register struct ts_softc *sc; 126 register int i; 127 int a; 128 129 #ifdef lint 130 br = 0; cvec = br; br = cvec; 131 tsintr(0); 132 #endif 133 addr->tssr = 0; /* initialize subsystem */ 134 DELAY(100); 135 if ((addr->tssr & TS_NBA) == 0) 136 return (0); 137 138 /* 139 * Make it interrupt. 140 * TS_SETCHR|TS_IE alone refuses to interrupt for me. 141 */ 142 sc = &ts_softc[ctlr]; 143 tsmap(sc, numuba, &a); 144 i = (int)&sc->sc_ubaddr->t_char; 145 sc->sc_ts.t_cmd.c_loba = i; 146 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3; 147 sc->sc_ts.t_cmd.c_size = sizeof(struct ts_char); 148 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_SETCHR; 149 sc->sc_ts.t_char.char_addr = (int)&sc->sc_ubaddr->t_sts; 150 sc->sc_ts.t_char.char_size = sizeof(struct ts_sts); 151 sc->sc_ts.t_char.char_mode = 0; /* mode is unimportant */ 152 addr->tsdb = sc->sc_uba; 153 DELAY(20000); 154 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | TS_SENSE; 155 sc->sc_ts.t_cmd.c_repcnt = 1; 156 addr->tsdb = sc->sc_uba; 157 DELAY(20000); 158 /* should have interrupted by now */ 159 160 if (cvec == 0 || cvec == 0x200) /* no interrupt */ 161 ubarelse(numuba, &a); 162 163 return (sizeof (struct tsdevice)); 164 } 165 166 /* 167 * Map in the command, status, and characteristics packet. We 168 * make them contiguous to keep overhead down. This also sets 169 * sc_uba (which then never changes). 170 */ 171 tsmap(sc, uban, a) 172 register struct ts_softc *sc; 173 int uban, *a; 174 { 175 register int i; 176 177 i = uballoc(uban, (caddr_t)&sc->sc_ts, sizeof(sc->sc_ts), 0); 178 if (a != NULL) 179 *a = i; 180 i = UBAI_ADDR(i); 181 sc->sc_ubaddr = (struct ts_tsdata *)i; 182 /* 183 * Note that i == the Unibus address of the command packet, 184 * and that it is a multiple of 4 (guaranteed by the compiler). 185 */ 186 sc->sc_uba = i + ((i >> 16) & 3); 187 } 188 189 /* 190 * TS11 only supports one drive per controller; 191 * check for ui_slave == 0. 192 */ 193 /*ARGSUSED*/ 194 tsslave(ui, reg) 195 struct uba_device *ui; 196 caddr_t reg; 197 { 198 199 return (ui->ui_slave == 0); /* non-zero slave not allowed */ 200 } 201 202 /* 203 * Record attachment of the unit to the controller. 204 */ 205 /*ARGSUSED*/ 206 tsattach(ui) 207 struct uba_device *ui; 208 { 209 210 /* void */ 211 } 212 213 /* 214 * Open the device. Tapes are unique open 215 * devices, so we refuse if it is already open. 216 */ 217 tsopen(dev, flag) 218 dev_t dev; 219 int flag; 220 { 221 register int tsunit = TSUNIT(dev); 222 register struct uba_device *ui; 223 register struct ts_softc *sc; 224 225 if (tsunit >= NTS || (ui = tsdinfo[tsunit]) == 0 || ui->ui_alive == 0) 226 return (ENXIO); 227 if ((sc = &ts_softc[ui->ui_ctlr])->sc_openf) 228 return (EBUSY); 229 sc->sc_openf = 1; 230 sc->sc_density = (minor(dev) & T_1600BPI) ? TS_NRZI : 0; 231 tscommand(dev, TS_SENSE, 1); 232 if (ctsbuf[tsunit].b_flags & B_ERROR) 233 /* 234 * Try it again in case it went off-line 235 */ 236 tscommand(dev, TS_SENSE, 1); 237 if (tsinit(ui->ui_ctlr)) { 238 sc->sc_openf = 0; 239 return (ENXIO); 240 } 241 if ((sc->sc_ts.t_sts.s_xs0&TS_ONL) == 0) { 242 sc->sc_openf = 0; 243 uprintf("ts%d: not online\n", tsunit); 244 return (EIO); 245 } 246 if ((flag&FWRITE) && (sc->sc_ts.t_sts.s_xs0&TS_WLK)) { 247 sc->sc_openf = 0; 248 uprintf("ts%d: no write ring\n", tsunit); 249 return (EIO); 250 } 251 sc->sc_blkno = (daddr_t)0; 252 sc->sc_nxrec = INF; 253 sc->sc_lastiow = 0; 254 sc->sc_blks = 0; 255 sc->sc_softerrs = 0; 256 sc->sc_ttyp = u.u_ttyp; 257 return (0); 258 } 259 260 /* 261 * Close tape device. 262 * 263 * If tape was open for writing or last operation was 264 * a write, then write two EOF's and backspace over the last one. 265 * Unless this is a non-rewinding special file, rewind the tape. 266 * Make the tape available to others. 267 */ 268 tsclose(dev, flag) 269 register dev_t dev; 270 register int flag; 271 { 272 register struct ts_softc *sc = &ts_softc[TSUNIT(dev)]; 273 274 if (flag == FWRITE || (flag&FWRITE) && sc->sc_lastiow) { 275 tscommand(dev, TS_WEOF, 1); 276 tscommand(dev, TS_WEOF, 1); 277 tscommand(dev, TS_SREV, 1); 278 } 279 if ((minor(dev)&T_NOREWIND) == 0) 280 /* 281 * 0 count means don't hang waiting for rewind complete 282 * rather ctsbuf stays busy until the operation completes 283 * preventing further opens from completing by 284 * preventing a TS_SENSE from completing. 285 */ 286 tscommand(dev, TS_REW, 0); 287 if (sc->sc_blks > 100 && sc->sc_softerrs > sc->sc_blks / 100) 288 log(LOG_INFO, "ts%d: %d soft errors in %d blocks\n", 289 TSUNIT(dev), sc->sc_softerrs, sc->sc_blks); 290 sc->sc_openf = 0; 291 } 292 293 /* 294 * Initialize a TS11. Set device characteristics. 295 */ 296 tsinit(ctlr) 297 register int ctlr; 298 { 299 register struct ts_softc *sc = &ts_softc[ctlr]; 300 register struct uba_ctlr *um = tsminfo[ctlr]; 301 register struct tsdevice *addr = (struct tsdevice *)um->um_addr; 302 register int i; 303 304 if (addr->tssr & (TS_NBA|TS_OFL) || sc->sc_ts.t_sts.s_xs0 & TS_BOT) { 305 addr->tssr = 0; /* subsystem initialize */ 306 tswait(addr); 307 i = (int)&sc->sc_ubaddr->t_char; 308 sc->sc_ts.t_cmd.c_loba = i; 309 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3; 310 sc->sc_ts.t_cmd.c_size = sizeof(struct ts_char); 311 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_SETCHR; 312 sc->sc_ts.t_char.char_addr = (int)&sc->sc_ubaddr->t_sts; 313 sc->sc_ts.t_char.char_size = sizeof(struct ts_sts); 314 sc->sc_ts.t_char.char_mode = TS_ESS | TS_EAI | TS_ERI | 315 /* TS_ENB | */ sc->sc_density; 316 addr->tsdb = sc->sc_uba; 317 tswait(addr); 318 if (addr->tssr & TS_NBA) 319 return(1); 320 } 321 return(0); 322 } 323 324 /* 325 * Execute a command on the tape drive 326 * a specified number of times. 327 */ 328 tscommand(dev, com, count) 329 dev_t dev; 330 int com, count; 331 { 332 register struct buf *bp; 333 register int s; 334 int didsleep = 0; 335 336 bp = &ctsbuf[TSUNIT(dev)]; 337 s = spl5(); 338 while (bp->b_flags&B_BUSY) { 339 /* 340 * This special check is because B_BUSY never 341 * gets cleared in the non-waiting rewind case. 342 */ 343 if (bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 344 break; 345 bp->b_flags |= B_WANTED; 346 sleep((caddr_t)bp, PRIBIO); 347 didsleep = 1; 348 } 349 bp->b_flags = B_BUSY|B_READ; 350 splx(s); 351 if (didsleep) 352 (void) tsinit(tsdinfo[TSUNIT(dev)]->ui_ctlr); 353 bp->b_dev = dev; 354 bp->b_repcnt = count; 355 bp->b_command = com; 356 bp->b_blkno = 0; 357 tsstrategy(bp); 358 /* 359 * In case of rewind from close, don't wait. 360 * This is the only case where count can be 0. 361 */ 362 if (count == 0) 363 return; 364 biowait(bp); 365 if (bp->b_flags&B_WANTED) 366 wakeup((caddr_t)bp); 367 bp->b_flags &= B_ERROR; 368 } 369 370 /* 371 * Queue a tape operation. 372 */ 373 tsstrategy(bp) 374 register struct buf *bp; 375 { 376 register int tsunit = TSUNIT(bp->b_dev); 377 register struct uba_ctlr *um; 378 register struct buf *dp; 379 int s; 380 381 /* 382 * Put transfer at end of controller queue 383 */ 384 bp->av_forw = NULL; 385 um = tsdinfo[tsunit]->ui_mi; 386 dp = &tsutab[tsunit]; 387 s = spl5(); 388 if (dp->b_actf == NULL) 389 dp->b_actf = bp; 390 else 391 dp->b_actl->av_forw = bp; 392 dp->b_actl = bp; 393 um->um_tab.b_actf = um->um_tab.b_actl = dp; 394 /* 395 * If the controller is not busy, get 396 * it going. 397 */ 398 if (um->um_tab.b_active == 0) 399 tsstart(um); 400 splx(s); 401 } 402 403 /* 404 * Start activity on a ts controller. 405 */ 406 tsstart(um) 407 register struct uba_ctlr *um; 408 { 409 register struct buf *bp; 410 register struct tsdevice *addr = (struct tsdevice *)um->um_addr; 411 register struct ts_softc *sc; 412 register struct uba_device *ui; 413 register int tsunit; 414 int cmd; 415 daddr_t blkno; 416 417 /* 418 * Start the controller if there is something for it to do. 419 */ 420 loop: 421 if ((bp = um->um_tab.b_actf->b_actf) == NULL) { 422 um->um_tab.b_active = 0; 423 return; 424 } 425 tsunit = TSUNIT(bp->b_dev); 426 ui = tsdinfo[tsunit]; 427 sc = &ts_softc[tsunit]; 428 /* 429 * Default is that last command was NOT a write command; 430 * if we finish a write command we will notice this in tsintr(). 431 */ 432 sc->sc_lastiow = 0; 433 if (sc->sc_openf < 0 || (addr->tssr&TS_OFL)) { 434 /* 435 * Have had a hard error on a non-raw tape 436 * or the tape unit is now unavailable 437 * (e.g. taken off line). 438 */ 439 bp->b_flags |= B_ERROR; 440 goto next; 441 } 442 if (bp == &ctsbuf[tsunit]) { 443 /* 444 * Execute control operation with the specified count. 445 */ 446 um->um_tab.b_active = 447 bp->b_command == TS_REW ? SREW : SCOM; 448 sc->sc_ts.t_cmd.c_repcnt = bp->b_repcnt; 449 goto dobpcmd; 450 } 451 /* 452 * For raw I/O, save the current block 453 * number in case we have to retry. 454 */ 455 if (bp->b_flags & B_RAW) { 456 if (um->um_tab.b_errcnt == 0) 457 sc->sc_blkno = bdbtofsb(bp->b_blkno); 458 } else { 459 /* 460 * Handle boundary cases for operation 461 * on non-raw tapes. 462 */ 463 if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 464 /* 465 * Can't read past known end-of-file. 466 */ 467 bp->b_flags |= B_ERROR; 468 bp->b_error = ENXIO; 469 goto next; 470 } 471 if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && 472 bp->b_flags&B_READ) { 473 /* 474 * Reading at end of file returns 0 bytes. 475 */ 476 bp->b_resid = bp->b_bcount; 477 clrbuf(bp); 478 goto next; 479 } 480 if ((bp->b_flags&B_READ) == 0) 481 /* 482 * Writing sets EOF 483 */ 484 sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 485 } 486 487 /* 488 * If the data transfer command is in the correct place, 489 * set up all the registers except the csr, and give 490 * control over to the UNIBUS adapter routines, to 491 * wait for resources to start the i/o. 492 */ 493 if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 494 sc->sc_ts.t_cmd.c_size = bp->b_bcount; 495 if ((bp->b_flags&B_READ) == 0) 496 cmd = TS_WCOM; 497 else 498 cmd = TS_RCOM; 499 if (um->um_tab.b_errcnt) 500 cmd |= TS_RETRY; 501 um->um_tab.b_active = SIO; 502 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | cmd; 503 (void) ubago(ui); 504 return; 505 } 506 /* 507 * Tape positioned incorrectly; 508 * set to seek forwards or backwards to the correct spot. 509 * This happens for raw tapes only on error retries. 510 */ 511 um->um_tab.b_active = SSEEK; 512 if (blkno < bdbtofsb(bp->b_blkno)) { 513 bp->b_command = TS_SFORW; 514 sc->sc_ts.t_cmd.c_repcnt = bdbtofsb(bp->b_blkno) - blkno; 515 } else { 516 bp->b_command = TS_SREV; 517 sc->sc_ts.t_cmd.c_repcnt = blkno - bdbtofsb(bp->b_blkno); 518 } 519 dobpcmd: 520 /* 521 * Do the command in bp. 522 */ 523 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command; 524 addr->tsdb = sc->sc_uba; 525 return; 526 527 next: 528 /* 529 * Done with this operation due to error or 530 * the fact that it doesn't do anything. 531 * Release UBA resources (if any), dequeue 532 * the transfer and continue processing this slave. 533 */ 534 if (um->um_ubinfo) 535 ubadone(um); 536 um->um_tab.b_errcnt = 0; 537 um->um_tab.b_actf->b_actf = bp->av_forw; 538 biodone(bp); 539 goto loop; 540 } 541 542 /* 543 * The UNIBUS resources we needed have been 544 * allocated to us; start the device. 545 */ 546 tsdgo(um) 547 register struct uba_ctlr *um; 548 { 549 register struct ts_softc *sc = &ts_softc[um->um_ctlr]; 550 register int i; 551 552 /* 553 * The uba code uses byte-offset mode if using bdp; 554 * mask off the low bit here. 555 */ 556 i = UBAI_ADDR(um->um_ubinfo); 557 if (UBAI_BDP(um->um_ubinfo)) 558 i &= ~1; 559 sc->sc_ts.t_cmd.c_loba = i; 560 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3; 561 ((struct tsdevice *)um->um_addr)->tsdb = sc->sc_uba; 562 } 563 564 /* 565 * Ts interrupt routine. 566 */ 567 /*ARGSUSED*/ 568 tsintr(tsunit) 569 register int tsunit; 570 { 571 register struct buf *bp; 572 register struct uba_ctlr *um; 573 register struct tsdevice *addr; 574 register struct ts_softc *sc; 575 register int state; 576 577 #ifdef QBA 578 (void) spl5(); 579 #endif 580 um = tsdinfo[tsunit]->ui_mi; 581 if ((bp = um->um_tab.b_actf->b_actf) == NULL) 582 return; 583 addr = (struct tsdevice *)um->um_addr; 584 /* 585 * If last command was a rewind, and tape is still 586 * rewinding, wait for the rewind complete interrupt. 587 * 588 * SHOULD NEVER GET AN INTERRUPT IN THIS STATE. 589 */ 590 if (um->um_tab.b_active == SREW) { 591 um->um_tab.b_active = SCOM; 592 if ((addr->tssr&TS_SSR) == 0) 593 return; 594 } 595 /* 596 * An operation completed... record status 597 */ 598 sc = &ts_softc[um->um_ctlr]; 599 if ((bp->b_flags & B_READ) == 0) 600 sc->sc_lastiow = 1; 601 state = um->um_tab.b_active; 602 /* 603 * Check for errors. 604 */ 605 if (addr->tssr&TS_SC) { 606 switch (addr->tssr & TS_TC) { 607 case TS_UNREC: /* unrecoverable */ 608 case TS_FATAL: /* fatal error */ 609 case TS_RECNM: /* recoverable, no motion */ 610 break; 611 case TS_ATTN: /* attention */ 612 if (sc->sc_ts.t_sts.s_xs0 & TS_VCK) { 613 /* volume check - may have changed tapes */ 614 bp->b_flags |= B_ERROR; 615 goto ignoreerr; 616 } 617 break; 618 619 case TS_SUCC: /* success termination */ 620 printf("ts%d: success\n", tsunit); 621 goto ignoreerr; 622 623 case TS_ALERT: /* tape status alert */ 624 /* 625 * If we hit the end of the tape file, 626 * update our position. 627 */ 628 if (sc->sc_ts.t_sts.s_xs0 & (TS_TMK|TS_EOT)) { 629 tsseteof(bp); /* set blkno and nxrec */ 630 state = SCOM; /* force completion */ 631 /* 632 * Stuff bc so it will be unstuffed correctly 633 * later to get resid. 634 */ 635 sc->sc_ts.t_sts.s_rbpcr = bp->b_bcount; 636 goto opdone; 637 } 638 /* 639 * If we were reading raw tape and the record was too 640 * long or too short, we don't consider this an error. 641 */ 642 if ((bp->b_flags & (B_READ|B_RAW)) == (B_READ|B_RAW) && 643 sc->sc_ts.t_sts.s_xs0&(TS_RLS|TS_RLL)) 644 goto ignoreerr; 645 /* FALLTHROUGH */ 646 647 case TS_RECOV: /* recoverable, tape moved */ 648 /* 649 * If this was an i/o operation retry up to 8 times. 650 */ 651 if (state == SIO) { 652 if (++um->um_tab.b_errcnt < 7) { 653 ubadone(um); 654 goto opcont; 655 } else 656 sc->sc_blkno++; 657 } else { 658 /* 659 * Non-i/o errors on non-raw tape 660 * cause it to close. 661 */ 662 if ((bp->b_flags&B_RAW) == 0 && 663 sc->sc_openf > 0) 664 sc->sc_openf = -1; 665 } 666 break; 667 668 case TS_REJECT: /* function reject */ 669 if (state == SIO && sc->sc_ts.t_sts.s_xs0 & TS_WLE) 670 tprintf(sc->sc_ttyp, "ts%d: write locked\n", 671 tsunit); 672 if ((sc->sc_ts.t_sts.s_xs0 & TS_ONL) == 0) 673 tprintf(sc->sc_ttyp, "ts%d: offline\n", 674 tsunit); 675 break; 676 } 677 /* 678 * Couldn't recover error 679 */ 680 tprintf(sc->sc_ttyp, "ts%d: hard error bn%d tssr=%b xs0=%b", 681 tsunit, bp->b_blkno, addr->tssr, TSSR_BITS, 682 sc->sc_ts.t_sts.s_xs0, TSXS0_BITS); 683 if (sc->sc_ts.t_sts.s_xs1) 684 tprintf(sc->sc_ttyp, " xs1=%b", sc->sc_ts.t_sts.s_xs1, 685 TSXS1_BITS); 686 if (sc->sc_ts.t_sts.s_xs2) 687 tprintf(sc->sc_ttyp, " xs2=%b", sc->sc_ts.t_sts.s_xs2, 688 TSXS2_BITS); 689 if (sc->sc_ts.t_sts.s_xs3) 690 tprintf(sc->sc_ttyp, " xs3=%b", sc->sc_ts.t_sts.s_xs3, 691 TSXS3_BITS); 692 tprintf(sc->sc_ttyp, "\n"); 693 bp->b_flags |= B_ERROR; 694 goto opdone; 695 } 696 /* 697 * Advance tape control FSM. 698 */ 699 ignoreerr: 700 switch (state) { 701 702 case SIO: 703 /* 704 * Read/write increments tape block number 705 */ 706 sc->sc_blkno++; 707 sc->sc_blks++; 708 if (um->um_tab.b_errcnt) 709 sc->sc_softerrs++; 710 goto opdone; 711 712 case SCOM: 713 /* 714 * For forward/backward space record update current position. 715 */ 716 if (bp == &ctsbuf[tsunit]) 717 switch ((int)bp->b_command) { 718 719 case TS_SFORW: 720 sc->sc_blkno += bp->b_repcnt; 721 break; 722 723 case TS_SREV: 724 sc->sc_blkno -= bp->b_repcnt; 725 break; 726 } 727 goto opdone; 728 729 case SSEEK: 730 sc->sc_blkno = bdbtofsb(bp->b_blkno); 731 goto opcont; 732 733 default: 734 panic("tsintr"); 735 } 736 opdone: 737 /* 738 * Reset error count and remove 739 * from device queue. 740 */ 741 um->um_tab.b_errcnt = 0; 742 um->um_tab.b_actf->b_actf = bp->av_forw; 743 bp->b_resid = sc->sc_ts.t_sts.s_rbpcr; 744 ubadone(um); 745 biodone(bp); 746 if (um->um_tab.b_actf->b_actf == 0) { 747 um->um_tab.b_active = 0; 748 return; 749 } 750 opcont: 751 tsstart(um); 752 } 753 754 tsseteof(bp) 755 register struct buf *bp; 756 { 757 register int tsunit = TSUNIT(bp->b_dev); 758 register struct ts_softc *sc = &ts_softc[tsdinfo[tsunit]->ui_ctlr]; 759 760 if (bp == &ctsbuf[tsunit]) { 761 if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 762 /* reversing */ 763 sc->sc_nxrec = bdbtofsb(bp->b_blkno) - 764 sc->sc_ts.t_sts.s_rbpcr; 765 sc->sc_blkno = sc->sc_nxrec; 766 } else { 767 /* spacing forward */ 768 sc->sc_blkno = bdbtofsb(bp->b_blkno) + 769 sc->sc_ts.t_sts.s_rbpcr; 770 sc->sc_nxrec = sc->sc_blkno - 1; 771 } 772 return; 773 } 774 /* eof on read */ 775 sc->sc_nxrec = bdbtofsb(bp->b_blkno); 776 } 777 778 tsreset(uban) 779 int uban; 780 { 781 register struct uba_ctlr *um; 782 register struct uba_device *ui; 783 register int ts11, i; 784 785 for (ts11 = 0; ts11 < NTS; ts11++) { 786 if ((um = tsminfo[ts11]) == 0 || um->um_alive == 0 || 787 um->um_ubanum != uban) 788 continue; 789 printf(" ts%d", ts11); 790 um->um_tab.b_active = 0; 791 um->um_tab.b_actf = um->um_tab.b_actl = 0; 792 if (ts_softc[ts11].sc_openf > 0) 793 ts_softc[ts11].sc_openf = -1; 794 if (um->um_ubinfo) { 795 printf("<%d>", UBAI_BDP(um->um_ubinfo)); 796 um->um_ubinfo = 0; 797 } 798 /* 799 * tsdinfo should be 1-to-1 with tsminfo, but someone 800 * might have screwed up the config file: 801 */ 802 for (i = 0; i < NTS; i++) { 803 if ((ui = tsdinfo[i]) != NULL && 804 ui->ui_alive && ui->ui_mi == um) { 805 um->um_tab.b_actf = um->um_tab.b_actl = 806 &tsutab[i]; 807 break; 808 } 809 } 810 tsmap(&ts_softc[ts11], uban, (int *)NULL); 811 (void) tsinit(ts11); 812 tsstart(um); 813 } 814 } 815 816 /*ARGSUSED*/ 817 tsioctl(dev, cmd, data, flag) 818 caddr_t data; 819 dev_t dev; 820 { 821 int tsunit = TSUNIT(dev); 822 register struct ts_softc *sc = &ts_softc[tsdinfo[tsunit]->ui_ctlr]; 823 register struct buf *bp = &ctsbuf[TSUNIT(dev)]; 824 register int callcount; 825 int fcount; 826 struct mtop *mtop; 827 struct mtget *mtget; 828 /* we depend of the values and order of the MT codes here */ 829 static int tsops[] = 830 {TS_WEOF,TS_SFORWF,TS_SREVF,TS_SFORW,TS_SREV,TS_REW,TS_OFFL,TS_SENSE}; 831 832 switch (cmd) { 833 834 case MTIOCTOP: /* tape operation */ 835 mtop = (struct mtop *)data; 836 switch (mtop->mt_op) { 837 838 case MTWEOF: 839 callcount = mtop->mt_count; 840 fcount = 1; 841 break; 842 843 case MTFSF: case MTBSF: 844 case MTFSR: case MTBSR: 845 callcount = 1; 846 fcount = mtop->mt_count; 847 break; 848 849 case MTREW: case MTOFFL: case MTNOP: 850 callcount = 1; 851 fcount = 1; 852 break; 853 854 default: 855 return (ENXIO); 856 } 857 if (callcount <= 0 || fcount <= 0) 858 return (EINVAL); 859 while (--callcount >= 0) { 860 tscommand(dev, tsops[mtop->mt_op], fcount); 861 if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 862 bp->b_resid) 863 return (EIO); 864 if ((bp->b_flags&B_ERROR) || 865 sc->sc_ts.t_sts.s_xs0&TS_BOT) 866 break; 867 } 868 return (geterror(bp)); 869 870 case MTIOCGET: 871 mtget = (struct mtget *)data; 872 mtget->mt_dsreg = 0; 873 mtget->mt_erreg = sc->sc_ts.t_sts.s_xs0; 874 mtget->mt_resid = sc->sc_resid; 875 mtget->mt_type = MT_ISTS; 876 break; 877 878 default: 879 return (ENXIO); 880 } 881 return (0); 882 } 883 884 #define DBSIZE 20 885 886 tsdump(dev) 887 dev_t dev; 888 { 889 register struct uba_device *ui; 890 register struct uba_regs *uba; 891 register struct tsdevice *addr; 892 register int i; 893 register struct pte *io; 894 int blk, num, unit, reg, start; 895 u_short db; 896 struct ts_tsdata *tc, *tc_ubaddr; 897 898 unit = TSUNIT(dev); 899 if (unit >= NTS) 900 return (ENXIO); 901 #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 902 ui = phys(tsdinfo[unit], struct uba_device *); 903 if (ui->ui_alive == 0) 904 return (ENXIO); 905 uba = phys(ui->ui_hd, struct uba_hd *)->uh_physuba; 906 ubainit(uba); 907 addr = (struct tsdevice *)ui->ui_physaddr; 908 909 /* map a ts_tsdata structure */ 910 tc = phys(&ts_softc[0].sc_ts, struct ts_tsdata *); 911 num = btoc(sizeof(struct ts_tsdata)) + 1; 912 io = &uba->uba_map[reg = NUBMREG - num]; 913 for (i = 0; i < num; i++) 914 *(int *)io++ = UBAMR_MRV | (btop(tc) + i); 915 i = (((int)tc & PGOFSET) | (reg << 9)); 916 tc_ubaddr = (struct ts_tsdata *)i; 917 db = i + ((i >> 16) & 3); 918 919 /* init the drive */ 920 addr->tssr = 0; 921 tswait(addr); 922 if ((addr->tssr & (TS_NBA|TS_OFL)) != TS_NBA) 923 return (EFAULT); 924 925 /* set characteristics */ 926 i = (int)&tc_ubaddr->t_char; 927 tc->t_cmd.c_loba = i; 928 tc->t_cmd.c_hiba = (i >> 16) & 3; 929 tc->t_cmd.c_size = sizeof(struct ts_char); 930 tc->t_cmd.c_cmd = TS_ACK | TS_CVC | TS_SETCHR; 931 tc->t_char.char_addr = (int)&tc_ubaddr->t_sts; 932 tc->t_char.char_size = sizeof(struct ts_sts); 933 tc->t_char.char_mode = TS_ESS; 934 addr->tsdb = db; 935 tswait(addr); 936 if (addr->tssr & TS_NBA) 937 return (ENXIO); 938 939 /* dump */ 940 tc->t_cmd.c_cmd = TS_ACK | TS_WCOM; 941 tc->t_cmd.c_repcnt = 1; 942 num = maxfree; 943 for (start = 0, num = maxfree; num > 0; start += blk, num -= blk) { 944 blk = num > DBSIZE ? DBSIZE : num; 945 io = uba->uba_map; 946 for (i = 0; i < blk; i++) 947 *(int *)io++ = UBAMR_MRV | (1 << UBAMR_DPSHIFT) | 948 (start + i); 949 *(int *)io = 0; 950 addr->tsdb = db; 951 tswait(addr); 952 } 953 954 /* eof */ 955 tc->t_cmd.c_cmd = TS_WEOF; 956 addr->tsdb = db; 957 tswait(addr); 958 addr->tsdb = db; 959 tswait(addr); 960 961 if (addr->tssr&TS_SC) 962 return (EIO); 963 addr->tssr = 0; 964 tswait(addr); 965 return (0); 966 } 967 968 tswait(addr) 969 register struct tsdevice *addr; 970 { 971 972 while ((addr->tssr & TS_SSR) == 0) 973 /* void */; 974 } 975 976 #endif /* NTS > 0 */ 977