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