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.3 (Berkeley) 11/03/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 return; 432 tsunit = TSUNIT(bp->b_dev); 433 ui = tsdinfo[tsunit]; 434 sc = &ts_softc[tsunit]; 435 /* 436 * Default is that last command was NOT a write command; 437 * if we finish a write command we will notice this in tsintr(). 438 */ 439 sc->sc_lastiow = 0; 440 if (sc->sc_openf < 0 || (addr->tssr&TS_OFL)) { 441 /* 442 * Have had a hard error on a non-raw tape 443 * or the tape unit is now unavailable 444 * (e.g. taken off line). 445 */ 446 bp->b_flags |= B_ERROR; 447 goto next; 448 } 449 if (bp == &ctsbuf[tsunit]) { 450 /* 451 * Execute control operation with the specified count. 452 */ 453 um->um_tab.b_active = 454 bp->b_command == TS_REW ? SREW : SCOM; 455 sc->sc_ts.t_cmd.c_repcnt = bp->b_repcnt; 456 goto dobpcmd; 457 } 458 /* 459 * For raw I/O, save the current block 460 * number in case we have to retry. 461 */ 462 if (bp == &rtsbuf[tsunit]) { 463 if (um->um_tab.b_errcnt == 0) 464 sc->sc_blkno = bdbtofsb(bp->b_blkno); 465 } else { 466 /* 467 * Handle boundary cases for operation 468 * on non-raw tapes. 469 */ 470 if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 471 /* 472 * Can't read past known end-of-file. 473 */ 474 bp->b_flags |= B_ERROR; 475 bp->b_error = ENXIO; 476 goto next; 477 } 478 if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && 479 bp->b_flags&B_READ) { 480 /* 481 * Reading at end of file returns 0 bytes. 482 */ 483 bp->b_resid = bp->b_bcount; 484 clrbuf(bp); 485 goto next; 486 } 487 if ((bp->b_flags&B_READ) == 0) 488 /* 489 * Writing sets EOF 490 */ 491 sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 492 } 493 494 /* 495 * If the data transfer command is in the correct place, 496 * set up all the registers except the csr, and give 497 * control over to the UNIBUS adapter routines, to 498 * wait for resources to start the i/o. 499 */ 500 if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 501 sc->sc_ts.t_cmd.c_size = bp->b_bcount; 502 if ((bp->b_flags&B_READ) == 0) 503 cmd = TS_WCOM; 504 else 505 cmd = TS_RCOM; 506 if (um->um_tab.b_errcnt) 507 cmd |= TS_RETRY; 508 um->um_tab.b_active = SIO; 509 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | cmd; 510 (void) ubago(ui); 511 return; 512 } 513 /* 514 * Tape positioned incorrectly; 515 * set to seek forwards or backwards to the correct spot. 516 * This happens for raw tapes only on error retries. 517 */ 518 um->um_tab.b_active = SSEEK; 519 if (blkno < bdbtofsb(bp->b_blkno)) { 520 bp->b_command = TS_SFORW; 521 sc->sc_ts.t_cmd.c_repcnt = bdbtofsb(bp->b_blkno) - blkno; 522 } else { 523 bp->b_command = TS_SREV; 524 sc->sc_ts.t_cmd.c_repcnt = blkno - bdbtofsb(bp->b_blkno); 525 } 526 dobpcmd: 527 /* 528 * Do the command in bp. 529 */ 530 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command; 531 addr->tsdb = sc->sc_uba; 532 return; 533 534 next: 535 /* 536 * Done with this operation due to error or 537 * the fact that it doesn't do anything. 538 * Release UBA resources (if any), dequeue 539 * the transfer and continue processing this slave. 540 */ 541 if (um->um_ubinfo) 542 ubadone(um); 543 um->um_tab.b_errcnt = 0; 544 um->um_tab.b_actf->b_actf = bp->av_forw; 545 biodone(bp); 546 goto loop; 547 } 548 549 /* 550 * The UNIBUS resources we needed have been 551 * allocated to us; start the device. 552 */ 553 tsdgo(um) 554 register struct uba_ctlr *um; 555 { 556 register struct ts_softc *sc = &ts_softc[um->um_ctlr]; 557 register int i; 558 559 /* 560 * The uba code uses byte-offset mode if using bdp; 561 * mask off the low bit here. 562 */ 563 i = UBAI_ADDR(um->um_ubinfo); 564 if (UBAI_BDP(um->um_ubinfo)) 565 i &= ~1; 566 sc->sc_ts.t_cmd.c_loba = i; 567 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3; 568 ((struct tsdevice *)um->um_addr)->tsdb = sc->sc_uba; 569 } 570 571 /* 572 * Ts interrupt routine. 573 */ 574 /*ARGSUSED*/ 575 tsintr(tsunit) 576 register int tsunit; 577 { 578 register struct buf *bp; 579 register struct uba_ctlr *um; 580 register struct tsdevice *addr; 581 register struct ts_softc *sc; 582 register int state; 583 584 #if VAX630 585 (void) spl5(); 586 #endif 587 um = tsdinfo[tsunit]->ui_mi; 588 if ((bp = um->um_tab.b_actf->b_actf) == NULL) 589 return; 590 addr = (struct tsdevice *)um->um_addr; 591 /* 592 * If last command was a rewind, and tape is still 593 * rewinding, wait for the rewind complete interrupt. 594 * 595 * SHOULD NEVER GET AN INTERRUPT IN THIS STATE. 596 */ 597 if (um->um_tab.b_active == SREW) { 598 um->um_tab.b_active = SCOM; 599 if ((addr->tssr&TS_SSR) == 0) 600 return; 601 } 602 /* 603 * An operation completed... record status 604 */ 605 sc = &ts_softc[um->um_ctlr]; 606 if ((bp->b_flags & B_READ) == 0) 607 sc->sc_lastiow = 1; 608 state = um->um_tab.b_active; 609 /* 610 * Check for errors. 611 */ 612 if (addr->tssr&TS_SC) { 613 switch (addr->tssr & TS_TC) { 614 case TS_UNREC: /* unrecoverable */ 615 case TS_FATAL: /* fatal error */ 616 case TS_RECNM: /* recoverable, no motion */ 617 break; 618 case TS_ATTN: /* attention */ 619 if (sc->sc_ts.t_sts.s_xs0 & TS_VCK) { 620 /* volume check - may have changed tapes */ 621 bp->b_flags |= B_ERROR; 622 goto ignoreerr; 623 } 624 break; 625 626 case TS_SUCC: /* success termination */ 627 printf("ts%d: success\n", tsunit); 628 goto ignoreerr; 629 630 case TS_ALERT: /* tape status alert */ 631 /* 632 * If we hit the end of the tape file, 633 * update our position. 634 */ 635 if (sc->sc_ts.t_sts.s_xs0 & (TS_TMK|TS_EOT)) { 636 tsseteof(bp); /* set blkno and nxrec */ 637 state = SCOM; /* force completion */ 638 /* 639 * Stuff bc so it will be unstuffed correctly 640 * later to get resid. 641 */ 642 sc->sc_ts.t_sts.s_rbpcr = bp->b_bcount; 643 goto opdone; 644 } 645 /* 646 * If we were reading raw tape and the record was too 647 * long or too short, we don't consider this an error. 648 */ 649 if (bp == &rtsbuf[tsunit] && bp->b_flags&B_READ && 650 sc->sc_ts.t_sts.s_xs0&(TS_RLS|TS_RLL)) 651 goto ignoreerr; 652 /* FALLTHROUGH */ 653 654 case TS_RECOV: /* recoverable, tape moved */ 655 /* 656 * If this was an i/o operation retry up to 8 times. 657 */ 658 if (state == SIO) { 659 if (++um->um_tab.b_errcnt < 7) { 660 ubadone(um); 661 goto opcont; 662 } else 663 sc->sc_blkno++; 664 } else { 665 /* 666 * Non-i/o errors on non-raw tape 667 * cause it to close. 668 */ 669 if (sc->sc_openf > 0 && bp != &rtsbuf[tsunit]) 670 sc->sc_openf = -1; 671 } 672 break; 673 674 case TS_REJECT: /* function reject */ 675 if (state == SIO && sc->sc_ts.t_sts.s_xs0 & TS_WLE) 676 tprintf(sc->sc_ttyp, "ts%d: write locked\n", 677 tsunit); 678 if ((sc->sc_ts.t_sts.s_xs0 & TS_ONL) == 0) 679 tprintf(sc->sc_ttyp, "ts%d: offline\n", 680 tsunit); 681 break; 682 } 683 /* 684 * Couldn't recover error 685 */ 686 tprintf(sc->sc_ttyp, "ts%d: hard error bn%d tssr=%b xs0=%b", 687 tsunit, bp->b_blkno, addr->tssr, TSSR_BITS, 688 sc->sc_ts.t_sts.s_xs0, TSXS0_BITS); 689 if (sc->sc_ts.t_sts.s_xs1) 690 tprintf(sc->sc_ttyp, " xs1=%b", sc->sc_ts.t_sts.s_xs1, 691 TSXS1_BITS); 692 if (sc->sc_ts.t_sts.s_xs2) 693 tprintf(sc->sc_ttyp, " xs2=%b", sc->sc_ts.t_sts.s_xs2, 694 TSXS2_BITS); 695 if (sc->sc_ts.t_sts.s_xs3) 696 tprintf(sc->sc_ttyp, " xs3=%b", sc->sc_ts.t_sts.s_xs3, 697 TSXS3_BITS); 698 tprintf(sc->sc_ttyp, "\n"); 699 bp->b_flags |= B_ERROR; 700 goto opdone; 701 } 702 /* 703 * Advance tape control FSM. 704 */ 705 ignoreerr: 706 switch (state) { 707 708 case SIO: 709 /* 710 * Read/write increments tape block number 711 */ 712 sc->sc_blkno++; 713 sc->sc_blks++; 714 if (um->um_tab.b_errcnt) 715 sc->sc_softerrs++; 716 goto opdone; 717 718 case SCOM: 719 /* 720 * For forward/backward space record update current position. 721 */ 722 if (bp == &ctsbuf[tsunit]) 723 switch ((int)bp->b_command) { 724 725 case TS_SFORW: 726 sc->sc_blkno += bp->b_repcnt; 727 break; 728 729 case TS_SREV: 730 sc->sc_blkno -= bp->b_repcnt; 731 break; 732 } 733 goto opdone; 734 735 case SSEEK: 736 sc->sc_blkno = bdbtofsb(bp->b_blkno); 737 goto opcont; 738 739 default: 740 panic("tsintr"); 741 } 742 opdone: 743 /* 744 * Reset error count and remove 745 * from device queue. 746 */ 747 um->um_tab.b_errcnt = 0; 748 um->um_tab.b_actf->b_actf = bp->av_forw; 749 bp->b_resid = sc->sc_ts.t_sts.s_rbpcr; 750 ubadone(um); 751 biodone(bp); 752 if (um->um_tab.b_actf->b_actf == 0) { 753 um->um_tab.b_active = 0; 754 return; 755 } 756 opcont: 757 tsstart(um); 758 } 759 760 tsseteof(bp) 761 register struct buf *bp; 762 { 763 register int tsunit = TSUNIT(bp->b_dev); 764 register struct ts_softc *sc = &ts_softc[tsdinfo[tsunit]->ui_ctlr]; 765 766 if (bp == &ctsbuf[tsunit]) { 767 if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 768 /* reversing */ 769 sc->sc_nxrec = bdbtofsb(bp->b_blkno) - 770 sc->sc_ts.t_sts.s_rbpcr; 771 sc->sc_blkno = sc->sc_nxrec; 772 } else { 773 /* spacing forward */ 774 sc->sc_blkno = bdbtofsb(bp->b_blkno) + 775 sc->sc_ts.t_sts.s_rbpcr; 776 sc->sc_nxrec = sc->sc_blkno - 1; 777 } 778 return; 779 } 780 /* eof on read */ 781 sc->sc_nxrec = bdbtofsb(bp->b_blkno); 782 } 783 784 tsread(dev, uio) 785 dev_t dev; 786 struct uio *uio; 787 { 788 789 return (physio(tsstrategy, &rtsbuf[TSUNIT(dev)], dev, B_READ, minphys, uio)); 790 } 791 792 tswrite(dev, uio) 793 dev_t dev; 794 struct uio *uio; 795 { 796 797 return (physio(tsstrategy, &rtsbuf[TSUNIT(dev)], dev, B_WRITE, minphys, uio)); 798 } 799 800 tsreset(uban) 801 int uban; 802 { 803 register struct uba_ctlr *um; 804 register struct uba_device *ui; 805 register struct buf *dp; 806 register int ts11, i; 807 808 for (ts11 = 0; ts11 < NTS; ts11++) { 809 if ((um = tsminfo[ts11]) == 0 || um->um_alive == 0 || 810 um->um_ubanum != uban) 811 continue; 812 printf(" ts%d", ts11); 813 um->um_tab.b_active = 0; 814 um->um_tab.b_actf = um->um_tab.b_actl = 0; 815 if (ts_softc[ts11].sc_openf > 0) 816 ts_softc[ts11].sc_openf = -1; 817 if (um->um_ubinfo) { 818 printf("<%d>", UBAI_BDP(um->um_ubinfo)); 819 um->um_ubinfo = 0; 820 } 821 /* 822 * tsdinfo should be 1-to-1 with tsminfo, but someone 823 * might have screwed up the config file: 824 */ 825 for (i = 0; i < NTS; i++) { 826 if ((ui = tsdinfo[i]) != NULL && 827 ui->ui_alive && ui->ui_mi == um) { 828 um->um_tab.b_actf = um->um_tab.b_actl = 829 &tsutab[i]; 830 break; 831 } 832 } 833 tsmap(&ts_softc[ts11], uban, (int *)NULL); 834 (void) tsinit(ts11); 835 tsstart(um); 836 } 837 } 838 839 /*ARGSUSED*/ 840 tsioctl(dev, cmd, data, flag) 841 caddr_t data; 842 dev_t dev; 843 { 844 int tsunit = TSUNIT(dev); 845 register struct ts_softc *sc = &ts_softc[tsdinfo[tsunit]->ui_ctlr]; 846 register struct buf *bp = &ctsbuf[TSUNIT(dev)]; 847 register int callcount; 848 int fcount; 849 struct mtop *mtop; 850 struct mtget *mtget; 851 /* we depend of the values and order of the MT codes here */ 852 static int tsops[] = 853 {TS_WEOF,TS_SFORWF,TS_SREVF,TS_SFORW,TS_SREV,TS_REW,TS_OFFL,TS_SENSE}; 854 855 switch (cmd) { 856 857 case MTIOCTOP: /* tape operation */ 858 mtop = (struct mtop *)data; 859 switch (mtop->mt_op) { 860 861 case MTWEOF: 862 callcount = mtop->mt_count; 863 fcount = 1; 864 break; 865 866 case MTFSF: case MTBSF: 867 case MTFSR: case MTBSR: 868 callcount = 1; 869 fcount = mtop->mt_count; 870 break; 871 872 case MTREW: case MTOFFL: case MTNOP: 873 callcount = 1; 874 fcount = 1; 875 break; 876 877 default: 878 return (ENXIO); 879 } 880 if (callcount <= 0 || fcount <= 0) 881 return (EINVAL); 882 while (--callcount >= 0) { 883 tscommand(dev, tsops[mtop->mt_op], fcount); 884 if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) && 885 bp->b_resid) 886 return (EIO); 887 if ((bp->b_flags&B_ERROR) || 888 sc->sc_ts.t_sts.s_xs0&TS_BOT) 889 break; 890 } 891 return (geterror(bp)); 892 893 case MTIOCGET: 894 mtget = (struct mtget *)data; 895 mtget->mt_dsreg = 0; 896 mtget->mt_erreg = sc->sc_ts.t_sts.s_xs0; 897 mtget->mt_resid = sc->sc_resid; 898 mtget->mt_type = MT_ISTS; 899 break; 900 901 default: 902 return (ENXIO); 903 } 904 return (0); 905 } 906 907 #define DBSIZE 20 908 909 tsdump(dev) 910 dev_t dev; 911 { 912 register struct uba_device *ui; 913 register struct uba_regs *uba; 914 register struct tsdevice *addr; 915 register int i; 916 register struct pte *io; 917 int blk, num, unit, reg, start; 918 u_short db; 919 struct ts_tsdata *tc, *tc_ubaddr; 920 921 unit = TSUNIT(dev); 922 if (unit >= NTS) 923 return (ENXIO); 924 #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 925 ui = phys(tsdinfo[unit], struct uba_device *); 926 if (ui->ui_alive == 0) 927 return (ENXIO); 928 uba = phys(ui->ui_hd, struct uba_hd *)->uh_physuba; 929 ubainit(uba); 930 addr = (struct tsdevice *)ui->ui_physaddr; 931 932 /* map a ts_tsdata structure */ 933 tc = phys(&ts_softc[0].sc_ts, struct ts_tsdata *); 934 num = btoc(sizeof(struct ts_tsdata)) + 1; 935 io = &uba->uba_map[reg = NUBMREG - num]; 936 for (i = 0; i < num; i++) 937 *(int *)io++ = UBAMR_MRV | (btop(tc) + i); 938 i = (((int)tc & PGOFSET) | (reg << 9)); 939 tc_ubaddr = (struct ts_tsdata *)i; 940 db = i + ((i >> 16) & 3); 941 942 /* init the drive */ 943 addr->tssr = 0; 944 tswait(addr); 945 if ((addr->tssr & (TS_NBA|TS_OFL)) != TS_NBA) 946 return (EFAULT); 947 948 /* set characteristics */ 949 i = (int)&tc_ubaddr->t_char; 950 tc->t_cmd.c_loba = i; 951 tc->t_cmd.c_hiba = (i >> 16) & 3; 952 tc->t_cmd.c_size = sizeof(struct ts_char); 953 tc->t_cmd.c_cmd = TS_ACK | TS_CVC | TS_SETCHR; 954 tc->t_char.char_addr = (int)&tc_ubaddr->t_sts; 955 tc->t_char.char_size = sizeof(struct ts_sts); 956 tc->t_char.char_mode = TS_ESS; 957 addr->tsdb = db; 958 tswait(addr); 959 if (addr->tssr & TS_NBA) 960 return (ENXIO); 961 962 /* dump */ 963 tc->t_cmd.c_cmd = TS_ACK | TS_WCOM; 964 tc->t_cmd.c_repcnt = 1; 965 num = maxfree; 966 for (start = 0, num = maxfree; num > 0; start += blk, num -= blk) { 967 blk = num > DBSIZE ? DBSIZE : num; 968 io = uba->uba_map; 969 for (i = 0; i < blk; i++) 970 *(int *)io++ = UBAMR_MRV | (1 << UBAMR_DPSHIFT) | 971 (start + i); 972 *(int *)io = 0; 973 addr->tsdb = db; 974 tswait(addr); 975 } 976 977 /* eof */ 978 tc->t_cmd.c_cmd = TS_WEOF; 979 addr->tsdb = db; 980 tswait(addr); 981 addr->tsdb = db; 982 tswait(addr); 983 984 if (addr->tssr&TS_SC) 985 return (EIO); 986 addr->tssr = 0; 987 tswait(addr); 988 return (0); 989 } 990 991 tswait(addr) 992 register struct tsdevice *addr; 993 { 994 995 while ((addr->tssr & TS_SSR) == 0) 996 /* void */; 997 } 998 999 #endif /* NTS > 0 */ 1000