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