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