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