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