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