1 /* tm.c 4.20 02/28/81 */ 2 3 #include "te.h" 4 #if NTM > 0 5 int tmgapsdcnt; /* DEBUG */ 6 /* 7 * TM11/TE10 tape driver 8 * 9 * THIS DRIVER HAS NOT BEEN TESTED WITH MORE THAN ONE TRANSPORT. 10 */ 11 #define DELAY(N) { register int d = N; while (--d > 0); } 12 #include "../h/param.h" 13 #include "../h/buf.h" 14 #include "../h/dir.h" 15 #include "../h/conf.h" 16 #include "../h/user.h" 17 #include "../h/file.h" 18 #include "../h/map.h" 19 #include "../h/pte.h" 20 #include "../h/vm.h" 21 #include "../h/uba.h" 22 #include "../h/mtio.h" 23 #include "../h/ioctl.h" 24 #include "../h/cmap.h" 25 #include "../h/cpu.h" 26 27 #include "../h/tmreg.h" 28 29 struct buf ctmbuf[NTE]; 30 struct buf rtmbuf[NTE]; 31 32 int tmprobe(), tmslave(), tmattach(), tmdgo(), tmintr(); 33 struct uba_minfo *tmminfo[NTM]; 34 struct uba_dinfo *tmdinfo[NTE]; 35 struct buf tmutab[NTE]; 36 #ifdef notyet 37 struct uba_dinfo *tmip[NTM][4]; 38 #endif 39 u_short tmstd[] = { 0772520, 0 }; 40 struct uba_driver tmdriver = 41 { tmprobe, tmslave, tmattach, tmdgo, tmstd, "te", tmdinfo, "tm", tmminfo, 0 }; 42 43 /* bits in minor device */ 44 #define TMUNIT(dev) (minor(dev)&03) 45 #define T_NOREWIND 04 46 #define T_1600BPI 08 47 48 #define INF (daddr_t)1000000L 49 50 /* 51 * Software state per tape transport. 52 */ 53 struct tm_softc { 54 char sc_openf; /* lock against multiple opens */ 55 char sc_lastiow; /* last op was a write */ 56 daddr_t sc_blkno; /* block number, for block device tape */ 57 daddr_t sc_nxrec; /* desired block position */ 58 u_short sc_erreg; /* copy of last erreg */ 59 u_short sc_dsreg; /* copy of last dsreg */ 60 short sc_resid; /* copy of last bc */ 61 short sc_lastcmd; /* last command to handle direction changes */ 62 } tm_softc[NTM]; 63 64 /* 65 * States for um->um_tab.b_active, the 66 * per controller state flag. 67 */ 68 #define SSEEK 1 /* seeking */ 69 #define SIO 2 /* doing seq i/o */ 70 #define SCOM 3 /* sending control command */ 71 #define SREW 4 /* sending a drive rewind */ 72 73 /* WE CURRENTLY HANDLE REWINDS PRIMITIVELY, BUSYING OUT THE CONTROLLER */ 74 /* DURING THE REWIND... IF WE EVER GET TWO TRANSPORTS, WE CAN DEBUG MORE */ 75 /* SOPHISTICATED LOGIC... THIS SIMPLE CODE AT LEAST MAY WORK. */ 76 77 /* 78 * Determine if there is a controller for 79 * a tm at address reg. Our goal is to make the 80 * device interrupt. 81 */ 82 tmprobe(reg) 83 caddr_t reg; 84 { 85 register int br, cvec; 86 87 #ifdef lint 88 br = 0; br = cvec; cvec = br; 89 #endif 90 ((struct device *)reg)->tmcs = TM_IE; 91 /* 92 * If this is a tm11, it ought to have interrupted 93 * by now, if it isn't (ie: it is a ts04) then we just 94 * hope that it didn't interrupt, so autoconf will ignore it. 95 * Just in case, we will reference one 96 * of the more distant registers, and hope for a machine 97 * check, or similar disaster if this is a ts. 98 * 99 * Note: on an 11/780, badaddr will just generate 100 * a uba error for a ts; but our caller will notice that 101 * so we won't check for it. 102 */ 103 if (badaddr(&((struct device *)reg)->tmrd, 2)) 104 return (0); 105 return (1); 106 } 107 108 /* 109 * Due to a design flaw, we cannot ascertain if the tape 110 * exists or not unless it is on line - ie: unless a tape is 111 * mounted. This is too servere a restriction to bear, 112 * so all units are assumed to exist. 113 */ 114 /*ARGSUSED*/ 115 tmslave(ui, reg) 116 struct uba_dinfo *ui; 117 caddr_t reg; 118 { 119 120 return (1); 121 } 122 123 /* 124 * Record attachment of the unit to the controller port. 125 */ 126 /*ARGSUSED*/ 127 tmattach(ui) 128 struct uba_dinfo *ui; 129 { 130 131 #ifdef notyet 132 tmip[ui->ui_ctlr][ui->ui_slave] = ui; 133 #endif 134 } 135 136 /* 137 * Open the device. Tapes are unique open 138 * devices, so we refuse if it is already open. 139 * We also check that a tape is available, and 140 * don't block waiting here. 141 */ 142 tmopen(dev, flag) 143 dev_t dev; 144 int flag; 145 { 146 register int unit; 147 register struct uba_dinfo *ui; 148 register struct tm_softc *sc; 149 150 unit = TMUNIT(dev); 151 if (unit>=NTE || (sc = &tm_softc[unit])->sc_openf || 152 (ui = tmdinfo[unit]) == 0 || ui->ui_alive == 0) { 153 u.u_error = ENXIO; 154 return; 155 } 156 tmcommand(dev, TM_SENSE, 1); 157 if ((sc->sc_erreg&(TM_SELR|TM_TUR)) != (TM_SELR|TM_TUR)) { 158 uprintf("tape not online\n"); 159 u.u_error = EIO; 160 return; 161 } 162 if ((flag&(FREAD|FWRITE)) == FWRITE && sc->sc_erreg&TM_WRL) { 163 uprintf("tape write protected\n"); 164 u.u_error = EIO; 165 return; 166 } 167 sc->sc_openf = 1; 168 sc->sc_blkno = (daddr_t)0; 169 sc->sc_nxrec = INF; 170 sc->sc_lastiow = 0; 171 sc->sc_openf = 1; 172 return; 173 } 174 175 /* 176 * Close tape device. 177 * 178 * If tape was open for writing or last operation was 179 * a write, then write two EOF's and backspace over the last one. 180 * Unless this is a non-rewinding special file, rewind the tape. 181 * Make the tape available to others. 182 */ 183 tmclose(dev, flag) 184 register dev_t dev; 185 register flag; 186 { 187 register struct tm_softc *sc = &tm_softc[TMUNIT(dev)]; 188 189 if (flag == FWRITE || (flag&FWRITE) && sc->sc_lastiow) { 190 tmcommand(dev, TM_WEOF, 1); 191 tmcommand(dev, TM_WEOF, 1); 192 tmcommand(dev, TM_SREV, 1); 193 } 194 if ((minor(dev)&T_NOREWIND) == 0) 195 tmcommand(dev, TM_REW, 1); 196 sc->sc_openf = 0; 197 } 198 199 /* 200 * Execute a command on the tape drive 201 * a specified number of times. 202 */ 203 tmcommand(dev, com, count) 204 dev_t dev; 205 int com, count; 206 { 207 register struct buf *bp; 208 209 bp = &ctmbuf[TMUNIT(dev)]; 210 (void) spl5(); 211 while (bp->b_flags&B_BUSY) { 212 bp->b_flags |= B_WANTED; 213 sleep((caddr_t)bp, PRIBIO); 214 } 215 bp->b_flags = B_BUSY|B_READ; 216 (void) spl0(); 217 bp->b_dev = dev; 218 bp->b_repcnt = -count; 219 bp->b_command = com; 220 bp->b_blkno = 0; 221 tmstrategy(bp); 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 * Decipher a tape operation and do what is needed 230 * to see that it happens. 231 */ 232 tmstrategy(bp) 233 register struct buf *bp; 234 { 235 int unit = TMUNIT(bp->b_dev); 236 register struct uba_minfo *um; 237 register struct buf *dp; 238 register struct tm_softc *sc = &tm_softc[unit]; 239 240 /* 241 * Put transfer at end of unit queue 242 */ 243 dp = &tmutab[unit]; 244 bp->av_forw = NULL; 245 (void) spl5(); 246 if (dp->b_actf == NULL) { 247 dp->b_actf = bp; 248 /* 249 * Transport not already active... 250 * put at end of controller queue. 251 */ 252 dp->b_forw = NULL; 253 um = tmdinfo[unit]->ui_mi; 254 if (um->um_tab.b_actf == NULL) 255 um->um_tab.b_actf = dp; 256 else 257 um->um_tab.b_actl->b_forw = dp; 258 um->um_tab.b_actl = dp; 259 } else 260 dp->b_actl->av_forw = bp; 261 dp->b_actl = bp; 262 /* 263 * If the controller is not busy, get 264 * it going. 265 */ 266 if (um->um_tab.b_active == 0) 267 tmstart(um); 268 (void) spl0(); 269 } 270 271 /* 272 * Start activity on a tm controller. 273 */ 274 tmstart(um) 275 register struct uba_minfo *um; 276 { 277 register struct buf *bp, *dp; 278 register struct device *addr = (struct device *)um->um_addr; 279 register struct tm_softc *sc; 280 register struct uba_dinfo *ui; 281 int unit, cmd; 282 daddr_t blkno; 283 284 /* 285 * Look for an idle transport on the controller. 286 */ 287 loop: 288 if ((dp = um->um_tab.b_actf) == NULL) 289 return; 290 if ((bp = dp->b_actf) == NULL) { 291 um->um_tab.b_actf = dp->b_forw; 292 goto loop; 293 } 294 unit = TMUNIT(bp->b_dev); 295 ui = tmdinfo[unit]; 296 /* 297 * Record pre-transfer status (e.g. for TM_SENSE) 298 */ 299 sc = &tm_softc[unit]; 300 addr = (struct device *)um->um_addr; 301 addr->tmcs = (ui->ui_slave << 8); 302 sc->sc_dsreg = addr->tmcs; 303 sc->sc_erreg = addr->tmer; 304 sc->sc_resid = addr->tmbc; 305 /* 306 * Default is that last command was NOT a write command; 307 * if we do a write command we will notice this in tmintr(). 308 */ 309 sc->sc_lastiow = 1; 310 if (sc->sc_openf < 0 || (addr->tmcs&TM_CUR) == 0) { 311 /* 312 * Have had a hard error on this (non-raw) tape, 313 * or the tape unit is now unavailable (e.g. taken off 314 * line). 315 */ 316 bp->b_flags |= B_ERROR; 317 goto next; 318 } 319 /* 320 * If operation is not a control operation, 321 * check for boundary conditions. 322 */ 323 if (bp != &ctmbuf[unit]) { 324 if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) { 325 bp->b_flags |= B_ERROR; 326 bp->b_error = ENXIO; /* past EOF */ 327 goto next; 328 } 329 if (dbtofsb(bp->b_blkno) == sc->sc_nxrec && 330 bp->b_flags&B_READ) { 331 bp->b_resid = bp->b_bcount; 332 clrbuf(bp); /* at EOF */ 333 goto next; 334 } 335 if ((bp->b_flags&B_READ) == 0) 336 /* write sets EOF */ 337 sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1; 338 } 339 /* 340 * Set up the command, and then if this is a mt ioctl, 341 * do the operation using, for TM_SFORW and TM_SREV, the specified 342 * operation count. 343 */ 344 cmd = TM_IE | TM_GO | (ui->ui_slave << 8); 345 if ((minor(bp->b_dev) & T_1600BPI) == 0) 346 cmd |= TM_D800; 347 if (bp == &ctmbuf[unit]) { 348 if (bp->b_command == TM_SENSE) 349 goto next; 350 um->um_tab.b_active = 351 bp->b_command == TM_REW ? SREW : SCOM; 352 if (bp->b_command == TM_SFORW || bp->b_command == TM_SREV) 353 addr->tmbc = bp->b_repcnt; 354 goto dobpcmd; 355 } 356 /* 357 * If the data transfer command is in the correct place, 358 * set up all the registers except the csr, and give 359 * control over to the UNIBUS adapter routines, to 360 * wait for resources to start the i/o. 361 */ 362 if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) { 363 addr->tmbc = -bp->b_bcount; 364 if ((bp->b_flags&B_READ) == 0) { 365 if (um->um_tab.b_errcnt) 366 cmd |= TM_WIRG; 367 else 368 cmd |= TM_WCOM; 369 } else 370 cmd |= TM_RCOM; 371 um->um_tab.b_active = SIO; 372 um->um_cmd = cmd; 373 /* 374 if (tmreverseop(sc->sc_lastcmd)) 375 while (addr->tmer & TM_SDWN) 376 tmgapsdcnt++; 377 */ 378 sc->sc_lastcmd = TM_RCOM; /* will serve */ 379 ubago(ui); 380 return; 381 } 382 /* 383 * Block tape positioned incorrectly; 384 * seek forwards or backwards to the correct spot. 385 */ 386 um->um_tab.b_active = SSEEK; 387 if (blkno < dbtofsb(bp->b_blkno)) { 388 bp->b_command = TM_SFORW; 389 addr->tmbc = blkno - dbtofsb(bp->b_blkno); 390 } else { 391 bp->b_command = TM_SREV; 392 addr->tmbc = dbtofsb(bp->b_blkno) - blkno; 393 } 394 dobpcmd: 395 /* 396 if (tmreverseop(sc->sc_lastcmd) != tmreverseop(bp->b_command)) 397 while (addr->tmer & TM_SDWN) 398 tmgapsdcnt++; 399 */ 400 sc->sc_lastcmd = bp->b_command; 401 addr->tmcs = (cmd | bp->b_command); 402 return; 403 404 next: 405 /* 406 * Done with this operation due to error or 407 * the fact that it doesn't do anything. 408 * Release UBA resources (if any), dequeue 409 * the transfer and continue processing this slave. 410 */ 411 if (um->um_ubinfo) 412 ubadone(um); 413 um->um_tab.b_errcnt = 0; 414 dp->b_actf = bp->av_forw; 415 iodone(bp); 416 goto loop; 417 } 418 419 /* 420 * The UNIBUS resources we needed have been 421 * allocated to us; start the device. 422 */ 423 tmdgo(um) 424 register struct uba_minfo *um; 425 { 426 register struct device *addr = (struct device *)um->um_addr; 427 428 addr->tmba = um->um_ubinfo; 429 addr->tmcs = um->um_cmd | ((um->um_ubinfo >> 12) & 0x30); 430 } 431 432 /* 433 * Tm interrupt routine. 434 */ 435 /*ARGSUSED*/ 436 tmintr(tm11) 437 int tm11; 438 { 439 struct buf *dp; 440 register struct buf *bp; 441 register struct uba_minfo *um = tmminfo[tm11]; 442 register struct device *addr = (struct device *)tmdinfo[tm11]->ui_addr; 443 register struct tm_softc *sc; 444 int unit; 445 register state; 446 447 /* 448 * If last command was a rewind, and tape is still 449 * rewinding, wait for the rewind complete interrupt. 450 */ 451 if (um->um_tab.b_active == SREW) { 452 um->um_tab.b_active = SCOM; 453 if (addr->tmer&TM_RWS) 454 return; 455 } 456 /* 457 * An operation completed... record status 458 */ 459 if ((dp = um->um_tab.b_actf) == NULL) 460 return; 461 bp = dp->b_actf; 462 unit = TMUNIT(bp->b_dev); 463 sc = &tm_softc[unit]; 464 sc->sc_dsreg = addr->tmcs; 465 sc->sc_erreg = addr->tmer; 466 sc->sc_resid = addr->tmbc; 467 if ((bp->b_flags & B_READ) == 0) 468 sc->sc_lastiow = 1; 469 state = um->um_tab.b_active; 470 um->um_tab.b_active = 0; 471 /* 472 * Check for errors. 473 */ 474 if (addr->tmcs&TM_ERR) { 475 while (addr->tmer & TM_SDWN) 476 ; /* await settle down */ 477 /* 478 * If we hit the end of the tape update our position. 479 */ 480 if (addr->tmer&TM_EOF) { 481 tmseteof(bp); /* set blkno and nxrec */ 482 state = SCOM; /* force completion */ 483 /* 484 * Stuff bc so it will be unstuffed correctly 485 * later to get resid. 486 */ 487 addr->tmbc = -bp->b_bcount; 488 goto opdone; 489 } 490 /* 491 * If we were reading and the only error was that the 492 * record was to long, then we don't consider this an error. 493 */ 494 if ((bp->b_flags&B_READ) && 495 (addr->tmer&(TM_HARD|TM_SOFT)) == TM_RLE) 496 goto ignoreerr; 497 /* 498 * If error is not hard, and this was an i/o operation 499 * retry up to 8 times. 500 */ 501 if ((addr->tmer&TM_HARD)==0 && state==SIO) { 502 if (++um->um_tab.b_errcnt < 7) { 503 /* SHOULD CHECK THAT RECOVERY WORKS IN THIS CASE */ 504 /* AND THEN ONLY PRINT IF errcnt==7 */ 505 if((addr->tmer&TM_SOFT) == TM_NXM) 506 printf("TM UBA late error\n"); 507 sc->sc_blkno++; 508 ubadone(um); 509 goto opcont; 510 } 511 } else 512 /* 513 * Hard or non-i/o errors on non-raw tape 514 * cause it to close. 515 */ 516 if (sc->sc_openf>0 && bp != &rtmbuf[unit]) 517 sc->sc_openf = -1; 518 /* 519 * Couldn't recover error 520 */ 521 harderr(bp); 522 printf("tm%d er=%b\n", dkunit(bp), 523 sc->sc_erreg, TMEREG_BITS); 524 bp->b_flags |= B_ERROR; 525 goto opdone; 526 } 527 /* 528 * Advance tape control FSM. 529 */ 530 ignoreerr: 531 switch (state) { 532 533 case SIO: 534 /* 535 * Read/write increments tape block number 536 */ 537 sc->sc_blkno++; 538 goto opdone; 539 540 case SCOM: 541 /* 542 * Unless special operation, op completed. 543 */ 544 if (bp != &ctmbuf[unit]) 545 goto opdone; 546 /* 547 * Operation on block device... 548 * iterate operations which don't repeat 549 * for themselves in the hardware; for forward/ 550 * backward space record update the current position. 551 */ 552 switch (bp->b_command) { 553 554 case TM_SFORW: 555 sc->sc_blkno -= bp->b_repcnt; 556 goto opdone; 557 558 case TM_SREV: 559 sc->sc_blkno += bp->b_repcnt; 560 goto opdone; 561 562 default: 563 if (++bp->b_repcnt < 0) 564 goto opcont; 565 goto opdone; 566 } 567 568 case SSEEK: 569 sc->sc_blkno = dbtofsb(bp->b_blkno); 570 goto opcont; 571 572 default: 573 panic("tmintr"); 574 } 575 opdone: 576 /* 577 * Reset error count and remove 578 * from device queue. 579 */ 580 um->um_tab.b_errcnt = 0; 581 dp->b_actf = bp->av_forw; 582 bp->b_resid = -addr->tmbc; 583 ubadone(um); 584 iodone(bp); 585 /* 586 * Circulate slave to end of controller 587 * queue to give other slaves a chance. 588 */ 589 um->um_tab.b_actf = dp->b_forw; 590 if (dp->b_actf) { 591 dp->b_forw = NULL; 592 if (um->um_tab.b_actf == NULL) 593 um->um_tab.b_actf = dp; 594 else 595 um->um_tab.b_actl->b_forw = dp; 596 um->um_tab.b_actl = dp; 597 } 598 if (um->um_tab.b_actf == 0) 599 return; 600 opcont: 601 tmstart(um); 602 } 603 604 tmseteof(bp) 605 register struct buf *bp; 606 { 607 register int unit = TMUNIT(bp->b_dev); 608 register struct device *addr = 609 (struct device *)tmdinfo[unit]->ui_addr; 610 register struct tm_softc *sc = &tm_softc[unit]; 611 612 if (bp == &ctmbuf[unit]) { 613 if (sc->sc_blkno > dbtofsb(bp->b_blkno)) { 614 /* reversing */ 615 sc->sc_nxrec = dbtofsb(bp->b_blkno) - addr->tmbc; 616 sc->sc_blkno = sc->sc_nxrec; 617 } else { 618 /* spacing forward */ 619 sc->sc_blkno = dbtofsb(bp->b_blkno) + addr->tmbc; 620 sc->sc_nxrec = sc->sc_blkno - 1; 621 } 622 return; 623 } 624 /* eof on read */ 625 sc->sc_nxrec = dbtofsb(bp->b_blkno); 626 } 627 628 tmread(dev) 629 dev_t dev; 630 { 631 632 tmphys(dev); 633 physio(tmstrategy, &rtmbuf[TMUNIT(dev)], dev, B_READ, minphys); 634 } 635 636 tmwrite(dev) 637 dev_t dev; 638 { 639 640 tmphys(dev); 641 physio(tmstrategy, &rtmbuf[TMUNIT(dev)], dev, B_WRITE, minphys); 642 } 643 644 tmphys(dev) 645 dev_t dev; 646 { 647 register daddr_t a; 648 register struct tm_softc *sc = &tm_softc[TMUNIT(dev)]; 649 650 a = dbtofsb(u.u_offset >> 9); 651 sc->sc_blkno = a; 652 sc->sc_nxrec = a + 1; 653 } 654 655 tmreset(uban) 656 int uban; 657 { 658 int printed = 0; 659 register struct uba_minfo *um; 660 register tm11, unit; 661 register struct uba_dinfo *ui; 662 register struct buf *dp; 663 664 for (tm11 = 0; tm11 < NTM; tm11++) { 665 if ((um = tmminfo[tm11]) == 0 || um->um_alive == 0 || 666 um->um_ubanum != uban) 667 continue; 668 if (printed == 0) { 669 printf(" tm"); 670 DELAY(2000000); /* time to self test */ 671 printed = 1; 672 } 673 um->um_tab.b_active = 0; 674 um->um_tab.b_actf = um->um_tab.b_actl = 0; 675 if (um->um_ubinfo) { 676 printf("<%d>", (um->um_ubinfo>>28)&0xf); 677 ubadone(um); 678 } 679 ((struct device *)(um->um_addr))->tmcs = TM_DCLR; 680 for (unit = 0; unit < NTE; unit++) { 681 if ((ui = tmdinfo[unit]) == 0) 682 continue; 683 if (ui->ui_alive == 0) 684 continue; 685 dp = &tmutab[unit]; 686 dp->b_active = 0; 687 dp->b_forw = 0; 688 if (um->um_tab.b_actf == NULL) 689 um->um_tab.b_actf = dp; 690 else 691 um->um_tab.b_actl->b_forw = dp; 692 um->um_tab.b_actl = dp; 693 tm_softc[unit].sc_openf = -1; 694 } 695 tmstart(um); 696 } 697 } 698 699 /*ARGSUSED*/ 700 tmioctl(dev, cmd, addr, flag) 701 caddr_t addr; 702 dev_t dev; 703 { 704 int unit = TMUNIT(dev); 705 register struct tm_softc *sc = &tm_softc[unit]; 706 register struct buf *bp = &ctmbuf[unit]; 707 register callcount; 708 int fcount; 709 struct mtop mtop; 710 struct mtget mtget; 711 /* we depend of the values and order of the MT codes here */ 712 static tmops[] = 713 {TM_WEOF,TM_SFORW,TM_SREV,TM_SFORW,TM_SREV,TM_REW,TM_OFFL,TM_SENSE}; 714 715 switch (cmd) { 716 case MTIOCTOP: /* tape operation */ 717 if (copyin((caddr_t)addr, (caddr_t)&mtop, sizeof(mtop))) { 718 u.u_error = EFAULT; 719 return; 720 } 721 switch(mtop.mt_op) { 722 case MTWEOF: 723 callcount = mtop.mt_count; 724 fcount = 1; 725 break; 726 case MTFSF: case MTBSF: 727 callcount = mtop.mt_count; 728 fcount = INF; 729 break; 730 case MTFSR: case MTBSR: 731 callcount = 1; 732 fcount = mtop.mt_count; 733 break; 734 case MTREW: case MTOFFL: case MTNOP: 735 callcount = 1; 736 fcount = 1; 737 break; 738 default: 739 u.u_error = ENXIO; 740 return; 741 } 742 if (callcount <= 0 || fcount <= 0) { 743 u.u_error = ENXIO; 744 return; 745 } 746 while (--callcount >= 0) { 747 tmcommand(dev, tmops[mtop.mt_op], fcount); 748 if ((mtop.mt_op == MTFSR || mtop.mt_op == MTBSR) && 749 bp->b_resid) { 750 u.u_error = EIO; 751 break; 752 } 753 if ((bp->b_flags&B_ERROR) || sc->sc_erreg&TM_BOT) 754 break; 755 } 756 geterror(bp); 757 return; 758 case MTIOCGET: 759 mtget.mt_dsreg = sc->sc_dsreg; 760 mtget.mt_erreg = sc->sc_erreg; 761 mtget.mt_resid = sc->sc_resid; 762 if (copyout((caddr_t)&mtget, addr, sizeof(mtget))) 763 u.u_error = EFAULT; 764 return; 765 default: 766 u.u_error = ENXIO; 767 } 768 } 769 770 #define DBSIZE 20 771 772 tmdump() 773 { 774 register struct uba_dinfo *ui; 775 register struct uba_regs *up; 776 register struct device *addr; 777 int blk, num; 778 int start; 779 780 start = 0; 781 num = maxfree; 782 #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 783 if (tmdinfo[0] == 0) { 784 printf("dna\n"); 785 return (-1); 786 } 787 ui = phys(tmdinfo[0], struct uba_dinfo *); 788 up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba; 789 #if VAX780 790 if (cpu == VAX_780) 791 ubainit(up); 792 #endif 793 DELAY(1000000); 794 addr = (struct device *)ui->ui_physaddr; 795 tmwait(addr); 796 addr->tmcs = TM_DCLR | TM_GO; 797 while (num > 0) { 798 blk = num > DBSIZE ? DBSIZE : num; 799 tmdwrite(start, blk, addr, up); 800 start += blk; 801 num -= blk; 802 } 803 tmeof(addr); 804 tmeof(addr); 805 tmwait(addr); 806 addr->tmcs = TM_REW | TM_GO; 807 tmwait(addr); 808 return (0); 809 } 810 811 tmdwrite(dbuf, num, addr, up) 812 register dbuf, num; 813 register struct device *addr; 814 struct uba_regs *up; 815 { 816 register struct pte *io; 817 register int npf; 818 819 tmwait(addr); 820 io = up->uba_map; 821 npf = num+1; 822 while (--npf != 0) 823 *(int *)io++ = (dbuf++ | (1<<UBA_DPSHIFT) | UBA_MRV); 824 *(int *)io = 0; 825 addr->tmbc = -(num*NBPG); 826 addr->tmba = 0; 827 addr->tmcs = TM_WCOM | TM_GO; 828 } 829 830 tmwait(addr) 831 register struct device *addr; 832 { 833 register s; 834 835 do 836 s = addr->tmcs; 837 while ((s & TM_CUR) == 0); 838 } 839 840 tmeof(addr) 841 struct device *addr; 842 { 843 844 tmwait(addr); 845 addr->tmcs = TM_WEOF | TM_GO; 846 } 847 #endif 848