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