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