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