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