1 /* ut.c 4.24 82/12/05 */ 2 3 #include "tj.h" 4 #if NUT > 0 5 /* 6 * System Industries Model 9700 Tape Drive 7 * emulates a TU45 on the UNIBUS 8 * 9 * TODO: 10 * check out attention processing 11 * try reset code and dump code 12 */ 13 #include "../h/param.h" 14 #include "../h/systm.h" 15 #include "../h/buf.h" 16 #include "../h/conf.h" 17 #include "../h/dir.h" 18 #include "../h/file.h" 19 #include "../h/user.h" 20 #include "../h/map.h" 21 #include "../h/pte.h" 22 #include "../h/ioctl.h" 23 #include "../h/mtio.h" 24 #include "../h/cmap.h" 25 #include "../h/uio.h" 26 #include "../h/kernel.h" 27 28 #include "../vax/cpu.h" 29 #include "../vaxuba/ubareg.h" 30 #include "../vaxuba/ubavar.h" 31 #include "../vaxuba/utreg.h" 32 33 struct buf rutbuf[NUT]; /* bufs for raw i/o */ 34 struct buf cutbuf[NUT]; /* bufs for control operations */ 35 struct buf tjutab[NTJ]; /* bufs for slave queue headers */ 36 37 struct uba_ctlr *utminfo[NUT]; 38 struct uba_device *tjdinfo[NTJ]; 39 int utprobe(), utslave(), utattach(), utdgo(), utintr(), uttimer(); 40 u_short utstd[] = { 0772440, 0 }; 41 struct uba_driver utdriver = 42 { utprobe, utslave, utattach, utdgo, utstd, "tj", tjdinfo, "ut", utminfo, 0 }; 43 44 /* bits in minor device */ 45 #define TJUNIT(dev) (minor(dev)&03) 46 #define T_NOREWIND 04 47 #define T_1600BPI 010 48 #define T_6250BPI 020 49 short utdens[] = { UT_NRZI, UT_PE, UT_GCR, UT_NRZI }; 50 51 /* slave to controller mapping table */ 52 short tjtout[NTJ]; 53 #define UTUNIT(dev) (tjtout[TJUNIT(dev)]) 54 55 #define INF (daddr_t)1000000L /* a block number that wont exist */ 56 57 struct tj_softc { 58 char sc_openf; /* exclusive open */ 59 char sc_lastiow; /* last I/O operation was a write */ 60 daddr_t sc_blkno; /* next block to transfer */ 61 daddr_t sc_nxrec; /* next record on tape */ 62 u_short sc_erreg; /* image of uter */ 63 u_short sc_dsreg; /* image of utds */ 64 u_short sc_resid; /* residual from transfer */ 65 u_short sc_dens; /* sticky selected density */ 66 daddr_t sc_timo; /* time until timeout expires */ 67 short sc_tact; /* timeout is active flag */ 68 } tj_softc[NTJ]; 69 70 /* 71 * Internal per/slave states found in sc_state 72 */ 73 #define SSEEK 1 /* seeking */ 74 #define SIO 2 /* doing sequential I/O */ 75 #define SCOM 3 /* sending a control command */ 76 #define SREW 4 /* doing a rewind op */ 77 #define SERASE 5 /* erase inter-record gap */ 78 #define SERASED 6 /* erased inter-record gap */ 79 80 /*ARGSUSED*/ 81 utprobe(reg) 82 caddr_t reg; 83 { 84 register int br, cvec; 85 #ifdef lint 86 br=0; cvec=br; br=cvec; 87 utintr(0); 88 #endif 89 /* 90 * The SI documentation says you must set the RDY bit 91 * (even though it's read-only) to force an interrupt. 92 */ 93 ((struct utdevice *) reg)->utcs1 = UT_IE|UT_NOP|UT_RDY; 94 DELAY(10000); 95 return (sizeof (struct utdevice)); 96 } 97 98 /*ARGSUSED*/ 99 utslave(ui, reg) 100 struct uba_device *ui; 101 caddr_t reg; 102 { 103 /* 104 * A real TU45 would support the slave present bit 105 * int the drive type register, but this thing doesn't, 106 * so there's no way to determine if a slave is present or not. 107 */ 108 return(1); 109 } 110 111 utattach(ui) 112 struct uba_device *ui; 113 { 114 tjtout[ui->ui_unit] = ui->ui_mi->um_ctlr; 115 } 116 117 /* 118 * Open the device with exclusive access. 119 */ 120 utopen(dev, flag) 121 dev_t dev; 122 int flag; 123 { 124 register int tjunit = TJUNIT(dev); 125 register struct uba_device *ui; 126 register struct tj_softc *sc; 127 int olddens, dens; 128 register int s; 129 130 if (tjunit >= NTJ || (sc = &tj_softc[tjunit])->sc_openf || 131 (ui = tjdinfo[tjunit]) == 0 || ui->ui_alive == 0) 132 return (ENXIO); 133 olddens = sc->sc_dens; 134 dens = sc->sc_dens = 135 utdens[(minor(dev)&(T_1600BPI|T_6250BPI))>>3]| 136 PDP11FMT|(ui->ui_slave&07); 137 get: 138 utcommand(dev, UT_SENSE, 1); 139 if (sc->sc_dsreg&UTDS_PIP) { 140 sleep((caddr_t)&lbolt, PZERO+1); 141 goto get; 142 } 143 sc->sc_dens = olddens; 144 if ((sc->sc_dsreg&UTDS_MOL) == 0) { 145 uprintf("tj%d: not online\n", tjunit); 146 return (EIO); 147 } 148 if ((flag&FWRITE) && (sc->sc_dsreg&UTDS_WRL)) { 149 uprintf("tj%d: no write ring\n", tjunit); 150 return (EIO); 151 } 152 if ((sc->sc_dsreg&UTDS_BOT) == 0 && (flag&FWRITE) && 153 dens != sc->sc_dens) { 154 uprintf("tj%d: can't change density in mid-tape\n", tjunit); 155 return (EIO); 156 } 157 sc->sc_openf = 1; 158 sc->sc_blkno = (daddr_t)0; 159 sc->sc_nxrec = INF; 160 sc->sc_lastiow = 0; 161 sc->sc_dens = dens; 162 /* 163 * For 6250 bpi take exclusive use of the UNIBUS. 164 */ 165 ui->ui_driver->ud_xclu = (dens&(T_1600BPI|T_6250BPI)) == T_6250BPI; 166 s = spl6(); 167 if (sc->sc_tact == 0) { 168 sc->sc_timo = INF; 169 sc->sc_tact = 1; 170 timeout(uttimer, (caddr_t)dev, 5*hz); 171 } 172 splx(s); 173 return (0); 174 } 175 176 utclose(dev, flag) 177 register dev_t dev; 178 register flag; 179 { 180 register struct tj_softc *sc = &tj_softc[TJUNIT(dev)]; 181 182 if (flag == FWRITE || ((flag&FWRITE) && sc->sc_lastiow)) { 183 utcommand(dev, UT_WEOF, 1); 184 utcommand(dev, UT_WEOF, 1); 185 utcommand(dev, UT_SREV, 1); 186 } 187 if ((minor(dev)&T_NOREWIND) == 0) 188 utcommand(dev, UT_REW, 0); 189 sc->sc_openf = 0; 190 } 191 192 utcommand(dev, com, count) 193 dev_t dev; 194 int com, count; 195 { 196 register struct buf *bp; 197 register int s; 198 199 bp = &cutbuf[UTUNIT(dev)]; 200 s = spl5(); 201 while (bp->b_flags&B_BUSY) { 202 if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 203 break; 204 bp->b_flags |= B_WANTED; 205 sleep((caddr_t)bp, PRIBIO); 206 } 207 bp->b_flags = B_BUSY|B_READ; 208 splx(s); 209 bp->b_dev = dev; 210 bp->b_command = com; 211 bp->b_repcnt = count; 212 bp->b_blkno = 0; 213 utstrategy(bp); 214 if (count == 0) 215 return; 216 iowait(bp); 217 if (bp->b_flags&B_WANTED) 218 wakeup((caddr_t)bp); 219 bp->b_flags &= B_ERROR; 220 } 221 222 /* 223 * Queue a tape operation. 224 */ 225 utstrategy(bp) 226 register struct buf *bp; 227 { 228 int tjunit = TJUNIT(bp->b_dev); 229 register struct uba_ctlr *um; 230 register struct buf *dp; 231 232 /* 233 * Put transfer at end of unit queue 234 */ 235 dp = &tjutab[tjunit]; 236 bp->av_forw = NULL; 237 (void) spl5(); 238 if (dp->b_actf == NULL) { 239 dp->b_actf = bp; 240 /* 241 * Transport not active, so... 242 * put at end of controller queue 243 */ 244 dp->b_forw = NULL; 245 um = tjdinfo[tjunit]->ui_mi; 246 if (um->um_tab.b_actf == NULL) 247 um->um_tab.b_actf = dp; 248 else 249 um->um_tab.b_actl->b_forw = dp; 250 um->um_tab.b_actl = dp; 251 } else 252 dp->b_actl->av_forw = bp; 253 dp->b_actl = bp; 254 /* 255 * If the controller is not busy, set it going. 256 */ 257 if (um->um_tab.b_state == 0) 258 utstart(um); 259 (void) spl0(); 260 } 261 262 utstart(um) 263 register struct uba_ctlr *um; 264 { 265 register struct utdevice *addr; 266 register struct buf *bp, *dp; 267 register struct tj_softc *sc; 268 struct uba_device *ui; 269 int tjunit; 270 daddr_t blkno; 271 272 loop: 273 /* 274 * Scan controller queue looking for units with 275 * transaction queues to dispatch 276 */ 277 if ((dp = um->um_tab.b_actf) == NULL) 278 return; 279 if ((bp = dp->b_actf) == NULL) { 280 um->um_tab.b_actf = dp->b_forw; 281 goto loop; 282 } 283 addr = (struct utdevice *)um->um_addr; 284 tjunit = TJUNIT(bp->b_dev); 285 ui = tjdinfo[tjunit]; 286 sc = &tj_softc[tjunit]; 287 /* note slave select, density, and format were merged on open */ 288 addr->uttc = sc->sc_dens; 289 sc->sc_dsreg = addr->utds; 290 sc->sc_erreg = addr->uter; 291 /* watch this, sports fans */ 292 sc->sc_resid = bp->b_flags&B_READ ? 293 bp->b_bcount - ((-addr->utfc)&0xffff) : -addr->utwc<<1; 294 /* 295 * Default is that last command was NOT a write command; 296 * if we do a write command we will notice this in utintr(). 297 */ 298 sc->sc_lastiow = 0; 299 if (sc->sc_openf < 0 || (addr->utds&UTDS_MOL) == 0) { 300 /* 301 * Have had a hard error on a non-raw tape 302 * or the tape unit is now unavailable 303 * (e.g. taken off line). 304 */ 305 bp->b_flags |= B_ERROR; 306 goto next; 307 } 308 if (bp == &cutbuf[UTUNIT(bp->b_dev)]) { 309 /* 310 * Execute a control operation with the specified 311 * count. 312 */ 313 if (bp->b_command == UT_SENSE) 314 goto next; 315 /* 316 * Set next state; handle timeouts 317 */ 318 if (bp->b_command == UT_REW) { 319 um->um_tab.b_state = SREW; 320 sc->sc_timo = 5*60; 321 } else { 322 um->um_tab.b_state = SCOM; 323 sc->sc_timo = imin(imax(10*(int)-bp->b_repcnt,60),5*60); 324 } 325 /* NOTE: this depends on the ut command values */ 326 if (bp->b_command >= UT_SFORW && bp->b_command <= UT_SREVF) 327 addr->utfc = -bp->b_repcnt; 328 goto dobpcmd; 329 } 330 /* 331 * The following checks boundary conditions for operations 332 * on non-raw tapes. On raw tapes the initialization of 333 * sc->sc_nxrec by utphys causes them to be skipped normally 334 * (except in the case of retries). 335 */ 336 if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 337 /* can't read past end of file */ 338 bp->b_flags |= B_ERROR; 339 bp->b_error = ENXIO; 340 goto next; 341 } 342 if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && (bp->b_flags&B_READ)) { 343 /* read at eof returns 0 count */ 344 bp->b_resid = bp->b_bcount; 345 clrbuf(bp); 346 goto next; 347 } 348 if ((bp->b_flags&B_READ) == 0) 349 sc->sc_nxrec = bdbtofsb(bp->b_blkno)+1; 350 /* 351 * If the tape is correctly positioned, set up all the 352 * registers but the csr, and give control over to the 353 * UNIBUS adaptor routines, to wait for resources to 354 * start I/O. 355 */ 356 if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) { 357 addr->utwc = -(((bp->b_bcount)+1)>>1); 358 addr->utfc = -bp->b_bcount; 359 if ((bp->b_flags&B_READ) == 0) { 360 /* 361 * On write error retries erase the 362 * inter-record gap before rewriting. 363 */ 364 if (um->um_tab.b_errcnt) { 365 if (um->um_tab.b_state != SERASED) { 366 um->um_tab.b_state = SERASE; 367 sc->sc_timo = 60; 368 addr->utcs1 = UT_ERASE|UT_IE|UT_GO; 369 return; 370 } 371 } 372 um->um_cmd = UT_WCOM; 373 } else 374 um->um_cmd = UT_RCOM; 375 sc->sc_timo = 60; 376 um->um_tab.b_state = SIO; 377 (void) ubago(ui); 378 return; 379 } 380 /* 381 * Tape positioned incorrectly; seek forwards or 382 * backwards to the correct spot. This happens for 383 * raw tapes only on error retries. 384 */ 385 um->um_tab.b_state = SSEEK; 386 if (blkno < bdbtofsb(bp->b_blkno)) { 387 addr->utfc = blkno - bdbtofsb(bp->b_blkno); 388 bp->b_command = UT_SFORW; 389 } else { 390 addr->utfc = bdbtofsb(bp->b_blkno) - blkno; 391 bp->b_command = UT_SREV; 392 } 393 sc->sc_timo = imin(imax(10 * -addr->utfc, 60), 5*60); 394 395 dobpcmd: 396 /* 397 * Perform the command setup in bp. 398 */ 399 addr->utcs1 = bp->b_command|UT_IE|UT_GO; 400 return; 401 next: 402 /* 403 * Advance to the next command in the slave queue, 404 * posting notice and releasing resources as needed. 405 */ 406 if (um->um_ubinfo) 407 ubadone(um); 408 um->um_tab.b_errcnt = 0; 409 dp->b_actf = bp->av_forw; 410 iodone(bp); 411 goto loop; 412 } 413 414 /* 415 * Start operation on controller -- 416 * UNIBUS resources have been allocated. 417 */ 418 utdgo(um) 419 register struct uba_ctlr *um; 420 { 421 register struct utdevice *addr = (struct utdevice *)um->um_addr; 422 423 addr->utba = (u_short) um->um_ubinfo; 424 addr->utcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x30)|UT_IE|UT_GO; 425 } 426 427 /* 428 * Ut interrupt handler 429 */ 430 /*ARGSUSED*/ 431 utintr(ut11) 432 int ut11; 433 { 434 struct buf *dp; 435 register struct buf *bp; 436 register struct uba_ctlr *um = utminfo[ut11]; 437 register struct utdevice *addr; 438 register struct tj_softc *sc; 439 u_short tjunit, cs2, cs1; 440 register state; 441 442 if ((dp = um->um_tab.b_actf) == NULL) 443 return; 444 bp = dp->b_actf; 445 tjunit = TJUNIT(bp->b_dev); 446 addr = (struct utdevice *)tjdinfo[tjunit]->ui_addr; 447 sc = &tj_softc[tjunit]; 448 /* 449 * Record status... 450 */ 451 sc->sc_timo = INF; 452 sc->sc_dsreg = addr->utds; 453 sc->sc_erreg = addr->uter; 454 sc->sc_resid = bp->b_flags&B_READ ? 455 bp->b_bcount - (-addr->utfc)&0xffff : -addr->utwc<<1; 456 if ((bp->b_flags&B_READ) == 0) 457 sc->sc_lastiow = 1; 458 state = um->um_tab.b_state; 459 um->um_tab.b_state = 0; 460 /* 461 * Check for errors... 462 */ 463 if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) { 464 /* 465 * To clear the ERR bit, we must issue a drive clear 466 * command, and to clear the TRE bit we must set the 467 * controller clear bit. 468 */ 469 cs2 = addr->utcs2; 470 if ((cs1 = addr->utcs1)&UT_TRE) 471 addr->utcs2 |= UTCS2_CLR; 472 /* is this dangerous ?? */ 473 while ((addr->utcs1&UT_RDY) == 0) 474 ; 475 addr->utcs1 = UT_CLEAR|UT_GO; 476 /* 477 * If we hit a tape mark or EOT update our position. 478 */ 479 if (sc->sc_dsreg&(UTDS_TM|UTDS_EOT)) { 480 /* 481 * Set blkno and nxrec 482 */ 483 if (bp == &cutbuf[UTUNIT(bp->b_dev)]) { 484 if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 485 sc->sc_nxrec = 486 bdbtofsb(bp->b_blkno) - addr->utfc; 487 sc->sc_blkno = sc->sc_nxrec; 488 } else { 489 sc->sc_blkno = 490 bdbtofsb(bp->b_blkno) + addr->utfc; 491 sc->sc_nxrec = sc->sc_blkno-1; 492 } 493 } else 494 sc->sc_nxrec = bdbtofsb(bp->b_blkno); 495 state = SCOM; /* force completion */ 496 /* 497 * Stuff so we can unstuff later 498 * to get the residual. 499 */ 500 addr->utwc = (-bp->b_bcount)>>1; 501 addr->utfc = -bp->b_bcount; 502 if (sc->sc_dsreg&UTDS_EOT) 503 goto harderror; 504 goto opdone; 505 } 506 /* 507 * If we were reading from a raw tape and the only error 508 * was that the record was too long, then we don't consider 509 * this an error. 510 */ 511 if (bp == &rutbuf[UTUNIT(bp->b_dev)] && (bp->b_flags&B_READ) && 512 (sc->sc_erreg&UTER_FCE)) 513 goto ignoreerr; 514 /* 515 * Fix up errors which occur due to backspacing "over" the 516 * front of the tape. 517 */ 518 if ((sc->sc_dsreg&UTDS_BOT) && 519 (bp->b_command == UT_SREV || bp->b_command == UT_SREV) && 520 ((sc->sc_erreg &= ~(UTER_NEF|UTER_FCE)) == 0)) 521 goto opdone; 522 /* 523 * Retry soft errors up to 8 times 524 */ 525 if ((sc->sc_erreg&UTER_HARD) == 0 && state == SIO) { 526 if (++um->um_tab.b_errcnt < 7) { 527 sc->sc_blkno++; 528 ubadone(um); 529 goto opcont; 530 } 531 } else 532 harderror: 533 /* 534 * Hard or non-I/O errors on non-raw tape 535 * cause it to close; also, reading off the 536 * end of the tape. 537 */ 538 if (sc->sc_openf > 0 && 539 bp != &rutbuf[UTUNIT(bp->b_dev)] || 540 sc->sc_dsreg&UTDS_EOT) 541 sc->sc_openf = -1; 542 /* 543 * Couldn't recover error. 544 */ 545 printf("ut%d: hard error bn%d cs1=%b er=%b cs2=%b ds=%b\n", 546 tjunit, bp->b_blkno, cs1, UT_BITS, sc->sc_erreg, 547 UTER_BITS, cs2, UTCS2_BITS, sc->sc_dsreg, UTDS_BITS); 548 bp->b_flags |= B_ERROR; 549 goto opdone; 550 } 551 ignoreerr: 552 /* 553 * Advance tape control FSM. 554 */ 555 switch (state) { 556 557 case SIO: /* read/write increments tape block # */ 558 sc->sc_blkno++; 559 break; 560 561 case SCOM: /* forw/rev space updates current position */ 562 if (bp == &cutbuf[UTUNIT(bp->b_dev)]) 563 switch (bp->b_command) { 564 565 case UT_SFORW: 566 sc->sc_blkno -= bp->b_repcnt; 567 break; 568 569 case UT_SREV: 570 sc->sc_blkno += bp->b_repcnt; 571 break; 572 } 573 break; 574 575 case SSEEK: 576 sc->sc_blkno = bdbtofsb(bp->b_blkno); 577 goto opcont; 578 579 case SERASE: 580 /* 581 * Completed erase of the inter-record gap due to a 582 * write error; now retry the write operation. 583 */ 584 um->um_tab.b_state = SERASED; 585 goto opcont; 586 587 case SREW: /* clear attention bit */ 588 addr->utcs1 = UT_CLEAR|UT_GO; 589 break; 590 591 default: 592 printf("bad state %d\n", state); 593 panic("utintr"); 594 } 595 596 opdone: 597 /* 598 * Reset error count and remove 599 * from device queue 600 */ 601 um->um_tab.b_errcnt = 0; 602 dp->b_actf = bp->av_forw; 603 bp->b_resid = bp->b_command&B_READ ? 604 bp->b_bcount - ((-addr->utfc)&0xffff) : -addr->utwc<<1; 605 ubadone(um); 606 iodone(bp); 607 /* 608 * Circulate slave to end of controller queue 609 * to give other slaves a chance 610 */ 611 um->um_tab.b_actf = dp->b_forw; 612 if (dp->b_actf) { 613 dp->b_forw = NULL; 614 if (um->um_tab.b_actf == NULL) 615 um->um_tab.b_actf = dp; 616 else 617 um->um_tab.b_actl->b_forw = dp; 618 um->um_tab.b_actl = dp; 619 } 620 if (um->um_tab.b_actf == 0) 621 return; 622 opcont: 623 utstart(um); 624 } 625 626 /* 627 * Watchdog timer routine. 628 */ 629 uttimer(dev) 630 int dev; 631 { 632 register struct tj_softc *sc = &tj_softc[TJUNIT(dev)]; 633 register short x; 634 635 if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) { 636 printf("tj%d: lost interrupt\n", TJUNIT(dev)); 637 sc->sc_timo = INF; 638 x = spl5(); 639 utintr(UTUNIT(dev)); 640 (void) splx(x); 641 } 642 timeout(uttimer, (caddr_t)dev, 5*hz); 643 } 644 645 /* 646 * Raw interface for a read 647 */ 648 utread(dev, uio) 649 dev_t dev; 650 struct uio *uio; 651 { 652 int errno; 653 654 errno = utphys(dev, uio); 655 if (errno) 656 return (errno); 657 return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_READ, minphys, uio)); 658 } 659 660 /* 661 * Raw interface for a write 662 */ 663 utwrite(dev, uio) 664 dev_t dev; 665 struct uio *uio; 666 { 667 int errno; 668 669 errno = utphys(dev, uio); 670 if (errno) 671 return (errno); 672 return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_WRITE, minphys, uio)); 673 } 674 675 /* 676 * Check for valid device number dev and update our notion 677 * of where we are on the tape 678 */ 679 utphys(dev, uio) 680 dev_t dev; 681 struct uio *uio; 682 { 683 register int tjunit = TJUNIT(dev); 684 register struct tj_softc *sc; 685 register struct uba_device *ui; 686 687 if (tjunit >= NTJ || (ui=tjdinfo[tjunit]) == 0 || ui->ui_alive == 0) 688 return (ENXIO); 689 sc = &tj_softc[tjunit]; 690 sc->sc_blkno = bdbtofsb(uio->uio_offset>>9); 691 sc->sc_nxrec = sc->sc_blkno+1; 692 return (0); 693 } 694 695 /*ARGSUSED*/ 696 utioctl(dev, cmd, data, flag) 697 dev_t dev; 698 caddr_t data; 699 { 700 register struct tj_softc *sc = &tj_softc[TJUNIT(dev)]; 701 register struct buf *bp = &cutbuf[UTUNIT(dev)]; 702 register callcount; 703 int fcount; 704 struct mtop *mtop; 705 struct mtget *mtget; 706 /* we depend of the values and order of the MT codes here */ 707 static utops[] = 708 {UT_WEOF,UT_SFORWF,UT_SREVF,UT_SFORW,UT_SREV,UT_REW,UT_REWOFFL,UT_SENSE}; 709 710 switch (cmd) { 711 712 case MTIOCTOP: 713 mtop = (struct mtop *)data; 714 switch(mtop->mt_op) { 715 716 case MTWEOF: 717 callcount = mtop->mt_count; 718 fcount = 1; 719 break; 720 721 case MTFSF: case MTBSF: 722 case MTFSR: case MTBSR: 723 callcount = 1; 724 fcount = mtop->mt_count; 725 break; 726 727 case MTREW: case MTOFFL: case MTNOP: 728 callcount = 1; 729 fcount = 1; 730 break; 731 732 default: 733 return (ENXIO); 734 } 735 if (callcount <= 0 || fcount <= 0) 736 return (EINVAL); 737 while (--callcount >= 0) { 738 utcommand(dev, utops[mtop->mt_op], fcount); 739 /* note this depends on the mtop values */ 740 if ((mtop->mt_op >= MTFSF || mtop->mt_op <= MTBSR) && 741 bp->b_resid) 742 return (EIO); 743 if ((bp->b_flags&B_ERROR) || (sc->sc_dsreg&UTDS_BOT)) 744 break; 745 } 746 return (geterror(bp)); 747 748 case MTIOCGET: 749 mtget = (struct mtget *)data; 750 mtget->mt_dsreg = sc->sc_dsreg; 751 mtget->mt_erreg = sc->sc_erreg; 752 mtget->mt_resid = sc->sc_resid; 753 mtget->mt_type = MT_ISUT; 754 break; 755 756 default: 757 return (ENXIO); 758 } 759 return (0); 760 } 761 762 utreset(uban) 763 int uban; 764 { 765 register struct uba_ctlr *um; 766 register ut11, tjunit; 767 register struct uba_device *ui; 768 register struct buf *dp; 769 770 for (ut11 = 0; ut11 < NUT; ut11++) { 771 if ((um = utminfo[ut11]) == 0 || um->um_alive == 0 || 772 um->um_ubanum != uban) 773 continue; 774 printf(" ut%d", ut11); 775 um->um_tab.b_state = 0; 776 um->um_tab.b_actf = um->um_tab.b_actl = 0; 777 if (um->um_ubinfo) { 778 printf("<%d>", (um->um_ubinfo>>28)&0xf); 779 um->um_ubinfo = 0; 780 } 781 ((struct utdevice *)(um->um_addr))->utcs1 = UT_CLEAR|UT_GO; 782 ((struct utdevice *)(um->um_addr))->utcs2 |= UTCS2_CLR; 783 for (tjunit = 0; tjunit < NTJ; tjunit++) { 784 if ((ui = tjdinfo[tjunit]) == 0 || ui->ui_mi != um || 785 ui->ui_alive == 0) 786 continue; 787 dp = &tjutab[tjunit]; 788 dp->b_state = 0; 789 dp->b_forw = 0; 790 if (um->um_tab.b_actf == NULL) 791 um->um_tab.b_actf = dp; 792 else 793 um->um_tab.b_actl->b_forw = dp; 794 um->um_tab.b_actl = dp; 795 if (tj_softc[tjunit].sc_openf > 0) 796 tj_softc[tjunit].sc_openf = -1; 797 } 798 utstart(um); 799 } 800 } 801 802 /* 803 * Do a stand-alone core dump to tape -- 804 * from here down, routines are used only in dump context 805 */ 806 #define DBSIZE 20 807 808 utdump() 809 { 810 register struct uba_device *ui; 811 register struct uba_regs *up; 812 register struct utdevice *addr; 813 int blk, num = maxfree; 814 int start = 0; 815 816 #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 817 if (tjdinfo[0] == 0) 818 return (ENXIO); 819 ui = phys(tjdinfo[0], struct uba_device *); 820 up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba; 821 ubainit(up); 822 DELAY(1000000); 823 addr = (struct utdevice *)ui->ui_physaddr; 824 utwait(addr); 825 /* 826 * Be sure to set the appropriate density here. We use 827 * 6250, but maybe it should be done at 1600 to insure the 828 * tape can be read by most any other tape drive available. 829 */ 830 addr->uttc = UT_GCR|PDP11FMT; /* implicit slave 0 or-ed in */ 831 addr->utcs1 = UT_CLEAR|UT_GO; 832 while (num > 0) { 833 blk = num > DBSIZE ? DBSIZE : num; 834 utdwrite(start, blk, addr, up); 835 if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) 836 return(EIO); 837 start += blk; 838 num -= blk; 839 } 840 uteof(addr); 841 uteof(addr); 842 utwait(addr); 843 if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) 844 return(EIO); 845 addr->utcs1 = UT_REW|UT_GO; 846 return (0); 847 } 848 849 utdwrite(dbuf, num, addr, up) 850 register dbuf, num; 851 register struct utdevice *addr; 852 struct uba_regs *up; 853 { 854 register struct pte *io; 855 register int npf; 856 857 utwait(addr); 858 io = up->uba_map; 859 npf = num + 1; 860 while (--npf != 0) 861 *(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) | UBAMR_MRV); 862 *(int *)io = 0; 863 addr->utwc = -((num*NBPG)>>1); 864 addr->utfc = -(num*NBPG); 865 addr->utba = 0; 866 addr->utcs1 = UT_WCOM|UT_GO; 867 } 868 869 utwait(addr) 870 struct utdevice *addr; 871 { 872 register s; 873 874 do 875 s = addr->utds; 876 while ((s&UTDS_DRY) == 0); 877 } 878 879 uteof(addr) 880 struct utdevice *addr; 881 { 882 883 utwait(addr); 884 addr->utcs1 = UT_WEOF|UT_GO; 885 } 886 #endif 887