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