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