1 /* mt.c 6.4 85/03/13 */ 2 3 #include "mu.h" 4 #if NMT > 0 5 /* 6 * TM78/TU78 tape driver 7 * 8 * Original author - ? 9 * Most error recovery bug fixes - ggs (ulysses!ggs) 10 * 11 * OPTIONS: 12 * MTLERRM - Long error message text - twd, Brown University 13 * MTRDREV - `read reverse' error recovery - ggs (ulysses!ggs) 14 * 15 * TODO: 16 * Add odd byte count kludge from VMS driver (?) 17 * Write dump routine 18 */ 19 20 #include "../machine/pte.h" 21 22 #include "param.h" 23 #include "systm.h" 24 #include "buf.h" 25 #include "conf.h" 26 #include "dir.h" 27 #include "file.h" 28 #include "user.h" 29 #include "map.h" 30 #include "ioctl.h" 31 #include "mtio.h" 32 #include "cmap.h" 33 #include "uio.h" 34 #include "tty.h" 35 36 #include "../vax/cpu.h" 37 #include "mbareg.h" 38 #include "mbavar.h" 39 #include "mtreg.h" 40 41 #define MTTIMEOUT 10000 /* loop limit for controller test */ 42 #define INF 1000000L /* a block number that won't exist */ 43 #define MASKREG(r) ((r) & 0xffff) /* the control registers have 16 bits */ 44 45 /* Bits for sc_flags */ 46 47 #define H_WRITTEN 01 /* last operation was a write */ 48 #define H_EOT 02 /* end of tape encountered */ 49 #define H_IEOT 04 /* ignore EOT condition */ 50 51 /* Bits in minor device */ 52 53 #define MUUNIT(dev) (minor(dev)&03) 54 #define H_NOREWIND 04 55 #define H_6250BPI 010 56 57 #define MTUNIT(dev) (mutomt[MUUNIT(dev)]) 58 59 #ifdef MTRDREV 60 int mt_do_readrev = 1; 61 #else 62 int mt_do_readrev = 0; 63 #endif 64 65 /* Per unit status information */ 66 67 struct mu_softc { 68 char sc_openf; /* unit is open if != 0 */ 69 char sc_flags; /* state flags */ 70 daddr_t sc_blkno; /* current physical block number */ 71 daddr_t sc_nxrec; /* firewall input block number */ 72 u_short sc_erreg; /* copy of mter or mtner */ 73 u_short sc_dsreg; /* copy of mtds */ 74 short sc_resid; /* residual function count for ioctl */ 75 short sc_dens; /* density code - MT_GCR or zero */ 76 struct mba_device *sc_mi; /* massbus structure for unit */ 77 int sc_slave; /* slave number for unit */ 78 int sc_i_mtas; /* mtas at slave attach time */ 79 int sc_i_mtner; /* mtner at slave attach time */ 80 int sc_i_mtds; /* mtds at slave attach time */ 81 #ifdef MTLERRM 82 char *sc_mesg; /* text for interrupt type code */ 83 char *sc_fmesg; /* text for tape error code */ 84 #endif 85 struct tty *sc_ttyp; /* record user's tty for errors */ 86 } mu_softc[NMU]; 87 88 struct buf rmtbuf[NMT]; /* data transfer buffer structures */ 89 struct buf cmtbuf[NMT]; /* tape command buffer structures */ 90 91 struct mba_device *mtinfo[NMT]; /* unit massbus structure pointers */ 92 short mutomt[NMU]; /* tape unit to controller number map */ 93 char mtds_bits[] = MTDS_BITS; /* mtds bit names for error messages */ 94 short mttypes[] = { MBDT_TU78, 0 }; 95 96 int mtattach(), mtslave(), mtustart(), mtstart(), mtndtint(), mtdtint(); 97 struct mba_driver mtdriver = 98 { mtattach, mtslave, mtustart, mtstart, mtdtint, mtndtint, 99 mttypes, "mt", "mu", mtinfo }; 100 101 void mtcreset(); 102 103 /*ARGSUSED*/ 104 mtattach(mi) 105 struct mba_device *mi; 106 { 107 #ifdef lint 108 mtread(0); mtwrite(0); mtioctl(0, 0, 0, 0); 109 #endif 110 } 111 112 mtslave(mi, ms, sn) 113 struct mba_device *mi; 114 struct mba_slave *ms; 115 int sn; 116 { 117 register struct mu_softc *sc = &mu_softc[ms->ms_unit]; 118 register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv; 119 int s = spl7(), rtn = 0, i; 120 121 /* Just in case the controller is ill, reset it. Then issue */ 122 /* a sense operation and wait about a second for it to respond. */ 123 124 mtcreset(mtaddr); 125 mtaddr->mtas = -1; 126 mtaddr->mtncs[sn] = MT_SENSE|MT_GO; 127 for (i = MTTIMEOUT; i> 0; i--) { 128 DELAY(50); 129 if (MASKREG(mtaddr->mtas) != 0) 130 break; 131 } 132 sc->sc_i_mtas = mtaddr->mtas; 133 sc->sc_i_mtner = mtaddr->mtner; 134 sc->sc_i_mtds = mtaddr->mtds; 135 136 /* If no response, whimper. If wrong response, call it an */ 137 /* unsolicited interrupt and use mtndtint to log and correct. */ 138 /* Otherwise, note whether this slave exists. */ 139 140 if (i <= 0) { 141 printf("mt: controller hung\n"); 142 } else if ((mtaddr->mtner & MTER_INTCODE) != MTER_DONE) { 143 (void) mtndtint(mi); 144 } else if (mtaddr->mtds & MTDS_PRES) { 145 sc->sc_mi = mi; 146 sc->sc_slave = sn; 147 mutomt[ms->ms_unit] = mi->mi_unit; 148 rtn = 1; 149 } 150 151 /* Cancel the interrupt, then wait a little while for it to go away. */ 152 153 mtaddr->mtas = mtaddr->mtas; 154 DELAY(10); 155 splx(s); 156 return (rtn); 157 } 158 159 mtopen(dev, flag) 160 dev_t dev; 161 int flag; 162 { 163 register int muunit; 164 register struct mba_device *mi; 165 register struct mu_softc *sc; 166 167 muunit = MUUNIT(dev); 168 if ( (muunit >= NMU) 169 || ((mi = mtinfo[MTUNIT(dev)]) == 0) 170 || (mi->mi_alive == 0) ) 171 return (ENXIO); 172 if ((sc = &mu_softc[muunit])->sc_openf) 173 return (EBUSY); 174 sc->sc_dens = (minor(dev) & H_6250BPI) ? MT_GCR : 0; 175 mtcommand(dev, MT_SENSE, 1); 176 if ((sc->sc_dsreg & MTDS_ONL) == 0) { 177 uprintf("mu%d: not online\n", muunit); 178 return (EIO); 179 } 180 if ((sc->sc_dsreg & MTDS_AVAIL) == 0) { 181 uprintf("mu%d: not online (port selector)\n", muunit); 182 return (EIO); 183 } 184 if ((flag & FWRITE) && (sc->sc_dsreg & MTDS_FPT)) { 185 uprintf("mu%d: no write ring\n", muunit); 186 return (EIO); 187 } 188 if ( ((sc->sc_dsreg & MTDS_BOT) == 0) 189 && (flag & FWRITE) 190 && ( ( (sc->sc_dens == MT_GCR) 191 && (sc->sc_dsreg & MTDS_PE) ) 192 || ( (sc->sc_dens != MT_GCR) 193 && ((sc->sc_dsreg & MTDS_PE) == 0)))) { 194 uprintf("mu%d: can't change density in mid-tape\n", muunit); 195 return (EIO); 196 } 197 sc->sc_openf = 1; 198 sc->sc_blkno = (daddr_t)0; 199 200 /* Since cooked I/O may do a read-ahead before a write, trash */ 201 /* on a tape can make the first write fail. Suppress the first */ 202 /* read-ahead unless definitely doing read-write */ 203 204 sc->sc_nxrec = ((flag & (FTRUNC | FWRITE)) == (FTRUNC | FWRITE)) 205 ? (daddr_t)0 206 : (daddr_t)INF; 207 sc->sc_flags = 0; 208 sc->sc_ttyp = u.u_ttyp; 209 return (0); 210 } 211 212 mtclose(dev, flag) 213 register dev_t dev; 214 register int flag; 215 { 216 register struct mu_softc *sc = &mu_softc[MUUNIT(dev)]; 217 218 if ( ((flag & (FREAD | FWRITE)) == FWRITE) 219 || ( (flag & FWRITE) 220 && (sc->sc_flags & H_WRITTEN) )) 221 mtcommand(dev, MT_CLS|sc->sc_dens, 1); 222 if ((minor(dev) & H_NOREWIND) == 0) 223 mtcommand(dev, MT_REW, 0); 224 sc->sc_openf = 0; 225 } 226 227 mtcommand(dev, com, count) 228 dev_t dev; 229 int com, count; 230 { 231 register struct buf *bp; 232 register int s; 233 234 bp = &cmtbuf[MTUNIT(dev)]; 235 s = spl5(); 236 while (bp->b_flags & B_BUSY) { 237 if((bp->b_repcnt == 0) && (bp->b_flags & B_DONE)) 238 break; 239 bp->b_flags |= B_WANTED; 240 sleep((caddr_t)bp, PRIBIO); 241 } 242 bp->b_flags = B_BUSY|B_READ; 243 splx(s); 244 bp->b_dev = dev; 245 bp->b_command = com; 246 bp->b_repcnt = count; 247 bp->b_blkno = 0; 248 bp->b_error = 0; 249 mtstrategy(bp); 250 if (count == 0) 251 return; 252 iowait(bp); 253 if (bp->b_flags & B_WANTED) 254 wakeup((caddr_t)bp); 255 bp->b_flags &= B_ERROR; 256 } 257 258 mtstrategy(bp) 259 register struct buf *bp; 260 { 261 register struct mba_device *mi = mtinfo[MTUNIT(bp->b_dev)]; 262 register struct buf *dp; 263 register int s; 264 265 /* If this is a data transfer operation, set the resid to a */ 266 /* default value (EOF) to simplify getting it right during */ 267 /* error recovery or bail out. */ 268 269 if (bp != &cmtbuf[MTUNIT(bp->b_dev)]) 270 bp->b_resid = bp->b_bcount; 271 272 /* Link this request onto the end of the queue for this */ 273 /* controller, then start I/O if not already active. */ 274 275 bp->av_forw = NULL; 276 dp = &mi->mi_tab; 277 s = spl5(); 278 if (dp->b_actf == NULL) 279 dp->b_actf = bp; 280 else 281 dp->b_actl->av_forw = bp; 282 dp->b_actl = bp; 283 if (dp->b_active == 0) 284 mbustart(mi); 285 splx(s); 286 } 287 288 mtustart(mi) 289 register struct mba_device *mi; 290 { 291 register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv; 292 register struct buf *bp = mi->mi_tab.b_actf; 293 register struct mu_softc *sc = &mu_softc[MUUNIT(bp->b_dev)]; 294 daddr_t blkno; 295 296 if (sc->sc_openf < 0) { 297 bp->b_flags |= B_ERROR; 298 return (MBU_NEXT); 299 } 300 if (bp != &cmtbuf[MTUNIT(bp->b_dev)]) { 301 302 /* Signal "no space" if out of tape unless suppressed */ 303 /* by MTIOCIEOT. */ 304 305 if ( ((sc->sc_flags & (H_EOT | H_IEOT)) == H_EOT) 306 && ((bp->b_flags & B_READ) == 0) ) { 307 bp->b_flags |= B_ERROR; 308 bp->b_error = ENOSPC; 309 return (MBU_NEXT); 310 } 311 312 /* special case tests for cooked mode */ 313 314 if (bp != &rmtbuf[MTUNIT(bp->b_dev)]) { 315 316 /* seek beyond end of file */ 317 318 if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) { 319 bp->b_flags |= B_ERROR; 320 bp->b_error = ENXIO; 321 return (MBU_NEXT); 322 } 323 324 /* This should be end of file, but the buffer */ 325 /* system wants a one-block look-ahead. Humor it. */ 326 327 if ( (bdbtofsb(bp->b_blkno) == sc->sc_nxrec) 328 && (bp->b_flags & B_READ) ) { 329 clrbuf(bp); 330 return (MBU_NEXT); 331 } 332 333 /* If writing, mark the next block invalid. */ 334 335 if ((bp->b_flags & B_READ) == 0) 336 sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1; 337 } 338 } else { 339 340 /* It's a command, do it now. */ 341 342 mtaddr->mtncs[MUUNIT(bp->b_dev)] = 343 (bp->b_repcnt<<8)|bp->b_command|MT_GO; 344 return (MBU_STARTED); 345 } 346 347 /* If raw I/O, or if the tape is positioned correctly for */ 348 /* cooked I/O, set the byte count, unit number and repeat count */ 349 /* then tell the MASSBUS to proceed. Note that a negative */ 350 /* bcount tells mbstart to map the buffer for "read backwards". */ 351 352 if ( (bp == &rmtbuf[MTUNIT(bp->b_dev)]) 353 || ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) ) { 354 if (mi->mi_tab.b_errcnt == 2) { 355 mtaddr->mtbc = -(bp->b_bcount); 356 mtaddr->mtca = MUUNIT(bp->b_dev); 357 } else { 358 mtaddr->mtbc = bp->b_bcount; 359 mtaddr->mtca = (1<<2)|MUUNIT(bp->b_dev); 360 } 361 return (MBU_DODATA); 362 } 363 364 /* Issue skip operations to position the next block for cooked I/O. */ 365 366 if (blkno < bdbtofsb(bp->b_blkno)) 367 mtaddr->mtncs[MUUNIT(bp->b_dev)] = 368 (min((unsigned)(bdbtofsb(bp->b_blkno) - blkno), 0377) << 8) | 369 MT_SFORW|MT_GO; 370 else 371 mtaddr->mtncs[MUUNIT(bp->b_dev)] = 372 (min((unsigned)(blkno - bdbtofsb(bp->b_blkno)), 0377) << 8) | 373 MT_SREV|MT_GO; 374 return (MBU_STARTED); 375 } 376 377 mtstart(mi) 378 register struct mba_device *mi; 379 { 380 register struct buf *bp = mi->mi_tab.b_actf; 381 register struct mu_softc *sc = &mu_softc[MUUNIT(bp->b_dev)]; 382 383 if (bp->b_flags & B_READ) 384 if (mi->mi_tab.b_errcnt == 2) 385 return(MT_READREV|MT_GO); 386 else 387 return(MT_READ|MT_GO); 388 else 389 return(MT_WRITE|sc->sc_dens|MT_GO); 390 } 391 392 mtdtint(mi, mbsr) 393 register struct mba_device *mi; 394 int mbsr; 395 { 396 register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv; 397 register struct buf *bp = mi->mi_tab.b_actf; 398 register struct mu_softc *sc; 399 register int er; 400 401 /* I'M still NOT SURE IF THIS SHOULD ALWAYS BE THE CASE SO FOR NOW... */ 402 403 if ((mtaddr->mtca & 3) != MUUNIT(bp->b_dev)) { 404 printf("mt: wrong unit!\n"); 405 mtaddr->mtca = MUUNIT(bp->b_dev); 406 } 407 408 er = MASKREG(mtaddr->mter); 409 sc = &mu_softc[MUUNIT(bp->b_dev)]; 410 sc->sc_erreg = er; 411 if (bp->b_flags & B_READ) 412 sc->sc_flags &= ~H_WRITTEN; 413 else 414 sc->sc_flags |= H_WRITTEN; 415 switch (er & MTER_INTCODE) { 416 417 case MTER_EOT: 418 sc->sc_flags |= H_EOT; 419 420 /* fall into MTER_DONE */ 421 422 case MTER_DONE: 423 sc->sc_blkno++; 424 if (mi->mi_tab.b_errcnt == 2) { 425 bp->b_bcount = bp->b_resid; 426 bp->b_resid -= MASKREG(mtaddr->mtbc); 427 if ( (bp->b_resid > 0) 428 && (bp != &rmtbuf[MTUNIT(bp->b_dev)]) ) 429 bp->b_flags |= B_ERROR; 430 } else { 431 bp->b_resid = 0; 432 } 433 break; 434 435 case MTER_SHRTREC: 436 sc->sc_blkno++; 437 bp->b_bcount = bp->b_resid; 438 bp->b_resid -= MASKREG(mtaddr->mtbc); 439 if (bp != &rmtbuf[MTUNIT(bp->b_dev)]) 440 bp->b_flags |= B_ERROR; 441 break; 442 443 case MTER_RETRY: 444 445 /* Simple re-try. Since resid is always a copy of the */ 446 /* original byte count, use it to restore the count. */ 447 448 mi->mi_tab.b_errcnt = 1; 449 bp->b_bcount = bp->b_resid; 450 return(MBD_RETRY); 451 452 case MTER_RDOPP: 453 454 /* The controller just decided to read it backwards. */ 455 /* If the controller returns a byte count of zero, */ 456 /* change it to 1, since zero encodes 65536, which */ 457 /* isn't quite what we had in mind. The byte count */ 458 /* may be larger than the size of the input buffer, so */ 459 /* limit the count to the buffer size. After */ 460 /* making the byte count reasonable, set bcount to the */ 461 /* negative of the controller's version of the byte */ 462 /* count so that the start address for the transfer is */ 463 /* set up correctly. */ 464 465 if (mt_do_readrev) { 466 mi->mi_tab.b_errcnt = 2; 467 if ((bp->b_bcount = MASKREG(mtaddr->mtbc)) == 0) 468 bp->b_bcount = 1; 469 if (bp->b_bcount > bp->b_resid) 470 bp->b_bcount = bp->b_resid; 471 bp->b_bcount = -(bp->b_bcount); 472 return(MBD_RETRY); 473 } else if (MASKREG(mtaddr->mtbc) <= bp->b_resid) { 474 sc->sc_blkno++; 475 bp->b_bcount = bp->b_resid; 476 bp->b_resid -= MASKREG(mtaddr->mtbc); 477 bp->b_flags |= B_ERROR; 478 break; 479 } 480 bp->b_flags |= B_ERROR; 481 482 /* fall into MTER_LONGREC */ 483 484 case MTER_LONGREC: 485 sc->sc_blkno++; 486 bp->b_bcount = bp->b_resid; 487 bp->b_resid = 0; 488 bp->b_error = ENOMEM; 489 bp->b_flags |= B_ERROR; 490 break; 491 492 case MTER_NOTCAP: 493 printf("mu%d: blank tape\n", MUUNIT(bp->b_dev)); 494 goto err; 495 496 case MTER_TM: 497 498 /* End of file. Since the default byte count has */ 499 /* already been set, just count the block and proceed. */ 500 501 sc->sc_blkno++; 502 err: 503 if (bp != &rmtbuf[MTUNIT(bp->b_dev)]) 504 sc->sc_nxrec = bdbtofsb(bp->b_blkno); 505 break; 506 507 case MTER_OFFLINE: 508 if (sc->sc_openf > 0) { 509 sc->sc_openf = -1; 510 tprintf(sc->sc_ttyp, "mu%d: offline\n", MUUNIT(bp->b_dev)); 511 } 512 bp->b_flags |= B_ERROR; 513 break; 514 515 case MTER_NOTAVL: 516 if (sc->sc_openf > 0) { 517 sc->sc_openf = -1; 518 tprintf(sc->sc_ttyp, "mu%d: offline (port selector)\n", 519 MUUNIT(bp->b_dev)); 520 } 521 bp->b_flags |= B_ERROR; 522 break; 523 524 case MTER_FPT: 525 tprintf(sc->sc_ttyp, "mu%d: no write ring\n", MUUNIT(bp->b_dev)); 526 bp->b_flags |= B_ERROR; 527 break; 528 529 case MTER_UNREAD: 530 sc->sc_blkno++; 531 bp->b_bcount = bp->b_resid; 532 bp->b_resid -= MIN(MASKREG(mtaddr->mtbc), bp->b_bcount); 533 534 /* Code 010 means a garbage record, nothing serious. */ 535 536 if (((er & MTER_FAILCODE) >> 10) == 010) { 537 tprintf(sc->sc_ttyp, "mu%d: rn=%d bn=%d unreadable record\n", 538 MUUNIT(bp->b_dev), sc->sc_blkno, bp->b_blkno); 539 bp->b_flags |= B_ERROR; 540 break; 541 } 542 543 /* Anything else might be a hardware problem, */ 544 /* fall into the error report. */ 545 546 default: 547 548 /* The bits in sc->sc_dsreg are from the last sense */ 549 /* command. To get the most recent copy, you have to */ 550 /* do a sense at interrupt level, which requires nested */ 551 /* error processing. This is a bit messy, so leave */ 552 /* well enough alone. */ 553 554 tprintf(sc->sc_ttyp, "mu%d: hard error (data transfer) rn=%d bn=%d mbsr=%b er=%o (octal) ds=%b\n", 555 MUUNIT(bp->b_dev), sc->sc_blkno, bp->b_blkno, 556 mbsr, mbsr_bits, er, 557 MASKREG(sc->sc_dsreg), mtds_bits); 558 #ifdef MTLERRM 559 mtintfail(sc); 560 printf(" interrupt code = %o (octal) <%s>\n failure code = %o (octal) <%s>\n", 561 er & MTER_INTCODE, sc->sc_mesg, 562 (er & MTER_FAILCODE) >> 10, sc->sc_fmesg); 563 #endif 564 bp->b_flags |= B_ERROR; 565 566 /* The TM78 manual says to reset the controller after */ 567 /* TM fault B or MASSBUS fault. */ 568 569 if ( ((er & MTER_INTCODE) == MTER_TMFLTB) 570 || ((er & MTER_INTCODE) == MTER_MBFLT) ) { 571 mtcreset(mtaddr); 572 } 573 } 574 575 /* Just in case some strange error slipped through, (drive off */ 576 /* line during read-reverse error recovery comes to mind) make */ 577 /* sure the byte count is reasonable. */ 578 579 if (bp->b_bcount < 0) 580 bp->b_bcount = bp->b_resid; 581 return (MBD_DONE); 582 } 583 584 mtndtint(mi) 585 register struct mba_device *mi; 586 { 587 register struct mtdevice *mtaddr = (struct mtdevice *)mi->mi_drv; 588 register struct buf *bp = mi->mi_tab.b_actf; 589 register struct mu_softc *sc; 590 register int er, fc; 591 int unit; 592 593 unit = (mtaddr->mtner >> 8) & 3; 594 er = MASKREG(mtaddr->mtner); 595 sc = &mu_softc[unit]; 596 sc->sc_erreg = er; 597 598 /* Check for unsolicited interrupts. */ 599 600 if (bp == 0 || unit != MUUNIT(bp->b_dev)) { /* consistency check */ 601 if ((er & MTER_INTCODE) != MTER_ONLINE) { 602 printf("mt: unit %d unexpected interrupt (non data transfer) er=%o (octal) ds=%b\n", 603 unit, er, MASKREG(sc->sc_dsreg), mtds_bits); 604 #ifdef MTLERRM 605 mtintfail(sc); 606 printf(" interrupt code = %o (octal) <%s>\n failure code = %o (octal) <%s>\n", 607 er & MTER_INTCODE, sc->sc_mesg, 608 (er & MTER_FAILCODE) >> 10, sc->sc_fmesg); 609 #endif 610 if ( ((er & MTER_INTCODE) == MTER_TMFLTB) 611 || ((er & MTER_INTCODE) == MTER_MBFLT) ) { 612 613 /* Reset the controller, then set error */ 614 /* status if there was anything active */ 615 /* when the fault occurred. This may */ 616 /* shoot an innocent bystander, but */ 617 /* it's better than letting an error */ 618 /* slip through. */ 619 620 mtcreset(mtaddr); 621 if (bp != 0) { 622 bp->b_flags |= B_ERROR; 623 return (MBN_DONE); 624 } 625 } 626 } 627 return (MBN_SKIP); 628 } 629 if (bp == 0) 630 return (MBN_SKIP); 631 632 fc = (mtaddr->mtncs[unit] >> 8) & 0xff; 633 sc->sc_resid = fc; 634 635 /* Clear the "written" flag after any operation that changes */ 636 /* the position of the tape. */ 637 638 if ( (bp != &cmtbuf[MTUNIT(bp->b_dev)]) 639 || (bp->b_command != MT_SENSE) ) 640 sc->sc_flags &= ~H_WRITTEN; 641 642 switch (er & MTER_INTCODE) { 643 644 case MTER_EOT: 645 sc->sc_flags |= H_EOT; 646 647 /* fall into MTER_DONE */ 648 649 case MTER_DONE: 650 651 /* If this is a command buffer, just update the status. */ 652 653 if (bp == &cmtbuf[MTUNIT(bp->b_dev)]) { 654 done: 655 if (bp->b_command == MT_SENSE) 656 sc->sc_dsreg = MASKREG(mtaddr->mtds); 657 return (MBN_DONE); 658 } 659 660 /* It's not a command buffer, must be a cooked I/O */ 661 /* skip operation (perhaps a shaky assumption, but it */ 662 /* wasn't my idea). */ 663 664 if ((fc = bdbtofsb(bp->b_blkno) - sc->sc_blkno) < 0) 665 sc->sc_blkno -= MIN(0377, -fc); 666 else 667 sc->sc_blkno += MIN(0377, fc); 668 return (MBN_RETRY); 669 670 case MTER_ONLINE: /* ddj -- shouldn't happen but did */ 671 case MTER_RWDING: 672 return (MBN_SKIP); /* ignore "rewind started" interrupt */ 673 674 case MTER_NOTCAP: 675 tprintf(sc->sc_ttyp, "mu%d: blank tape\n", MUUNIT(bp->b_dev)); 676 bp->b_flags |= B_ERROR; 677 return (MBN_DONE); 678 679 case MTER_TM: 680 case MTER_LEOT: 681 682 /* For an ioctl skip operation, count a tape mark as */ 683 /* a record. If there's anything left to do, update */ 684 /* the repeat count and re-start the command. */ 685 686 if (bp == &cmtbuf[MTUNIT(bp->b_dev)]) { 687 if ((sc->sc_resid = bp->b_repcnt = fc - 1) == 0) 688 return (MBN_DONE); 689 else 690 return (MBN_RETRY); 691 692 /* Cooked I/O again. Just update the books and wait */ 693 /* for someone else to return end of file or complain */ 694 /* about a bad seek. */ 695 696 } else if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) { 697 sc->sc_nxrec = bdbtofsb(bp->b_blkno) + fc - 1; 698 sc->sc_blkno = sc->sc_nxrec; 699 } else { 700 sc->sc_nxrec = bdbtofsb(bp->b_blkno) - fc; 701 sc->sc_blkno = sc->sc_nxrec + 1; 702 } 703 return (MBN_RETRY); 704 705 case MTER_FPT: 706 tprintf(sc->sc_ttyp, "mu%d: no write ring\n", MUUNIT(bp->b_dev)); 707 bp->b_flags |= B_ERROR; 708 return (MBN_DONE); 709 710 case MTER_OFFLINE: 711 712 /* If `off line' was intentional, don't complain. */ 713 714 if ( (bp == &cmtbuf[MTUNIT(bp->b_dev)]) 715 && (bp->b_command == MT_UNLOAD) ) 716 return(MBN_DONE); 717 if (sc->sc_openf > 0) { 718 sc->sc_openf = -1; 719 tprintf(sc->sc_ttyp, "mu%d: offline\n", MUUNIT(bp->b_dev)); 720 } 721 bp->b_flags |= B_ERROR; 722 return (MBN_DONE); 723 724 case MTER_NOTAVL: 725 if (sc->sc_openf > 0) { 726 sc->sc_openf = -1; 727 tprintf(sc->sc_ttyp, "mu%d: offline (port selector)\n", MUUNIT(bp->b_dev)); 728 } 729 bp->b_flags |= B_ERROR; 730 return (MBN_DONE); 731 732 case MTER_BOT: 733 if (bp == &cmtbuf[MTUNIT(bp->b_dev)]) 734 goto done; 735 736 /* fall through */ 737 738 default: 739 tprintf(sc->sc_ttyp, "mu%d: hard error (non data transfer) rn=%d bn=%d er=%o (octal) ds=%b\n", 740 MUUNIT(bp->b_dev), sc->sc_blkno, bp->b_blkno, 741 er, MASKREG(sc->sc_dsreg), mtds_bits); 742 #ifdef MTLERRM 743 mtintfail(sc); 744 printf(" interrupt code = %o (octal) <%s>\n failure code = %o (octal) <%s>\n", 745 (er & MTER_INTCODE), sc->sc_mesg, 746 (er & MTER_FAILCODE) >> 10, sc->sc_fmesg); 747 #endif 748 if ( ((er & MTER_INTCODE) == MTER_TMFLTB) 749 || ((er & MTER_INTCODE) == MTER_MBFLT) ) { 750 mtcreset(mtaddr); /* reset the controller */ 751 } 752 bp->b_flags |= B_ERROR; 753 return (MBN_DONE); 754 } 755 /* NOTREACHED */ 756 } 757 758 void mtcreset(mtaddr) 759 register struct mtdevice *mtaddr; 760 { 761 register int i; 762 763 mtaddr->mtid = MTID_CLR; /* reset the TM78 */ 764 DELAY(200); 765 for (i = MTTIMEOUT; i > 0; i--) { 766 DELAY(50); /* don't nag */ 767 if ((mtaddr->mtid & MTID_RDY) != 0) 768 return; /* exit when ready */ 769 } 770 printf("mt: controller hung\n"); 771 } 772 773 mtread(dev, uio) 774 dev_t dev; 775 struct uio *uio; 776 { 777 int errno; 778 779 errno = mtphys(dev, uio); 780 if (errno) 781 return (errno); 782 return (physio(mtstrategy, &rmtbuf[MTUNIT(dev)], dev, B_READ, minphys, uio)); 783 } 784 785 786 mtwrite(dev, uio) 787 dev_t dev; 788 struct uio *uio; 789 { 790 int errno; 791 792 errno = mtphys(dev, uio); 793 if (errno) 794 return (errno); 795 return (physio(mtstrategy, &rmtbuf[MTUNIT(dev)], dev, B_WRITE, minphys, uio)); 796 } 797 798 mtphys(dev, uio) 799 dev_t dev; 800 struct uio *uio; 801 { 802 register int mtunit; 803 struct mba_device *mi; 804 register int bsize = uio->uio_iov->iov_len; 805 806 mtunit = MTUNIT(dev); 807 if ( (mtunit >= NMT) 808 || ((mi = mtinfo[mtunit]) == 0) 809 || (mi->mi_alive == 0) ) 810 return (ENXIO); 811 if ( (bsize > 0xffff) /* controller limit */ 812 || (bsize <= 0) ) /* ambiguous */ 813 return (EINVAL); 814 return (0); 815 } 816 817 /*ARGSUSED*/ 818 mtioctl(dev, cmd, data, flag) 819 dev_t dev; 820 int cmd; 821 caddr_t data; 822 int flag; 823 { 824 register struct mu_softc *sc = &mu_softc[MUUNIT(dev)]; 825 register struct buf *bp = &cmtbuf[MTUNIT(dev)]; 826 register struct mtop *mtop; 827 register struct mtget *mtget; 828 int callcount, fcount; 829 int op; 830 831 /* We depend on the values and order of the MT codes here. */ 832 833 static mtops[] = 834 {MT_WTM,MT_SFORWF,MT_SREVF,MT_SFORW,MT_SREV,MT_REW,MT_UNLOAD,MT_SENSE}; 835 836 switch (cmd) { 837 838 /* tape operation */ 839 840 case MTIOCTOP: 841 mtop = (struct mtop *)data; 842 switch (mtop->mt_op) { 843 844 case MTWEOF: 845 callcount = mtop->mt_count; 846 fcount = 1; 847 break; 848 849 case MTFSF: case MTBSF: 850 callcount = mtop->mt_count; 851 fcount = 1; 852 break; 853 854 case MTFSR: case MTBSR: 855 callcount = 1; 856 fcount = mtop->mt_count; 857 break; 858 859 case MTREW: case MTOFFL: 860 callcount = 1; 861 fcount = 1; 862 break; 863 864 default: 865 return (ENXIO); 866 } 867 if ((callcount <= 0) || (fcount <= 0)) 868 return (EINVAL); 869 op = mtops[mtop->mt_op]; 870 if (op == MT_WTM) 871 op |= sc->sc_dens; 872 while (--callcount >= 0) { 873 register int n, fc = fcount; 874 875 do { 876 n = MIN(fc, 0xff); 877 mtcommand(dev, op, n); 878 n -= sc->sc_resid; 879 fc -= n; 880 switch (mtop->mt_op) { 881 882 case MTWEOF: 883 sc->sc_blkno += (daddr_t)n; 884 sc->sc_nxrec = sc->sc_blkno - 1; 885 break; 886 887 case MTOFFL: 888 case MTREW: 889 case MTFSF: 890 sc->sc_blkno = (daddr_t)0; 891 sc->sc_nxrec = (daddr_t)INF; 892 break; 893 894 case MTBSF: 895 if (sc->sc_resid) { 896 sc->sc_blkno = (daddr_t)0; 897 sc->sc_nxrec = (daddr_t)INF; 898 } else { 899 sc->sc_blkno = (daddr_t)(-1); 900 sc->sc_nxrec = (daddr_t)(-1); 901 } 902 break; 903 904 case MTFSR: 905 sc->sc_blkno += (daddr_t)n; 906 break; 907 908 case MTBSR: 909 sc->sc_blkno -= (daddr_t)n; 910 break; 911 } 912 if (sc->sc_resid) 913 break; 914 } while (fc); 915 if (fc) { 916 sc->sc_resid = callcount + fc; 917 if ( (mtop->mt_op == MTFSR) 918 || (mtop->mt_op == MTBSR) ) 919 return (EIO); 920 else 921 break; 922 } 923 if (bp->b_flags & B_ERROR) 924 break; 925 } 926 return (geterror(bp)); 927 928 /* tape status */ 929 930 case MTIOCGET: 931 mtget = (struct mtget *)data; 932 mtget->mt_erreg = sc->sc_erreg; 933 mtget->mt_resid = sc->sc_resid; 934 mtcommand(dev, MT_SENSE, 1); /* update drive status */ 935 mtget->mt_dsreg = sc->sc_dsreg; 936 mtget->mt_type = MT_ISMT; 937 break; 938 939 /* ignore EOT condition */ 940 941 case MTIOCIEOT: 942 sc->sc_flags |= H_IEOT; 943 break; 944 945 /* enable EOT condition */ 946 947 case MTIOCEEOT: 948 sc->sc_flags &= ~H_IEOT; 949 break; 950 951 default: 952 return (ENXIO); 953 } 954 return (0); 955 } 956 957 #define DBSIZE 20 958 959 mtdump() 960 { 961 register struct mba_device *mi; 962 register struct mba_regs *mp; 963 int blk, num; 964 int start; 965 966 start = 0; 967 num = maxfree; 968 #define phys(a,b) ((b)((int)(a)&0x7fffffff)) 969 if (mtinfo[0] == 0) 970 return (ENXIO); 971 mi = phys(mtinfo[0], struct mba_device *); 972 mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; 973 mp->mba_cr = MBCR_IE; 974 #if lint 975 blk = 0; num = blk; start = num; blk = start; 976 return (0); 977 #endif 978 #ifdef notyet 979 mtaddr = (struct mtdevice *)&mp->mba_drv[mi->mi_drive]; 980 mtaddr->mttc = MTTC_PDP11|MTTC_1600BPI; 981 mtaddr->mtcs1 = MT_DCLR|MT_GO; 982 while (num > 0) { 983 blk = num > DBSIZE ? DBSIZE : num; 984 mtdwrite(start, blk, mtaddr, mp); 985 start += blk; 986 num -= blk; 987 } 988 mteof(mtaddr); 989 mteof(mtaddr); 990 mtwait(mtaddr); 991 if (mtaddr->mtds&MTDS_ERR) 992 return (EIO); 993 mtaddr->mtcs1 = MT_REW|MT_GO; 994 return (0); 995 } 996 997 mtdwrite(dbuf, num, mtaddr, mp) 998 register dbuf, num; 999 register struct mtdevice *mtaddr; 1000 struct mba_regs *mp; 1001 { 1002 register struct pte *io; 1003 register int i; 1004 1005 mtwait(mtaddr); 1006 io = mp->mba_map; 1007 for (i = 0; i < num; i++) 1008 *(int *)io++ = dbuf++ | PG_V; 1009 mtaddr->mtfc = -(num*NBPG); 1010 mp->mba_sr = -1; 1011 mp->mba_bcr = -(num*NBPG); 1012 mp->mba_var = 0; 1013 mtaddr->mtcs1 = MT_WCOM|MT_GO; 1014 } 1015 1016 mtwait(mtaddr) 1017 struct mtdevice *mtaddr; 1018 { 1019 register s; 1020 1021 do 1022 s = mtaddr->mtds; 1023 while ((s & MTDS_DRY) == 0); 1024 } 1025 1026 mteof(mtaddr) 1027 struct mtdevice *mtaddr; 1028 { 1029 1030 mtwait(mtaddr); 1031 mtaddr->mtcs1 = MT_WEOF|MT_GO; 1032 #endif notyet 1033 } 1034 1035 #ifdef MTLERRM 1036 mtintfail(sc) 1037 register struct mu_softc *sc; 1038 { 1039 switch (sc->sc_erreg & MTER_INTCODE) { 1040 1041 /* unexpected BOT detected */ 1042 1043 case MTER_BOT: 1044 sc->sc_mesg = "unexpected BOT"; 1045 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1046 case 01: 1047 sc->sc_fmesg = "tape was at BOT"; 1048 break; 1049 case 02: 1050 sc->sc_fmesg = "BOT seen after tape started"; 1051 break; 1052 case 03: 1053 sc->sc_fmesg = "ARA ID detected"; 1054 break; 1055 default: 1056 sc->sc_fmesg = "unclassified failure code"; 1057 } 1058 break; 1059 1060 /* unexpected LEOT detected */ 1061 1062 case MTER_LEOT: 1063 sc->sc_mesg = "unexpected LEOT"; 1064 sc->sc_fmesg = ""; 1065 break; 1066 1067 /* rewinding */ 1068 1069 case MTER_RWDING: 1070 sc->sc_mesg = "tape rewinding"; 1071 sc->sc_fmesg = ""; 1072 break; 1073 1074 /* not ready */ 1075 1076 case MTER_NOTRDY: 1077 sc->sc_mesg = "drive not ready"; 1078 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1079 case 01: 1080 sc->sc_fmesg = "TU on-line but not ready"; 1081 break; 1082 case 02: 1083 sc->sc_fmesg = "fatal error has occurred"; 1084 break; 1085 case 03: 1086 sc->sc_fmesg = "access allowed but not really"; 1087 break; 1088 default: 1089 sc->sc_fmesg = "unclassified failure code"; 1090 } 1091 break; 1092 1093 /* not available */ 1094 1095 case MTER_NOTAVL: 1096 sc->sc_mesg = "drive not available"; 1097 sc->sc_fmesg = ""; 1098 break; 1099 1100 /* unit does not exist */ 1101 1102 case MTER_NONEX: 1103 sc->sc_mesg = "unit does not exist"; 1104 sc->sc_fmesg = ""; 1105 break; 1106 1107 /* not capable */ 1108 1109 case MTER_NOTCAP: 1110 sc->sc_mesg = "not capable"; 1111 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1112 case 01: 1113 sc->sc_fmesg = "no record found within 25 feet"; 1114 break; 1115 case 02: 1116 sc->sc_fmesg = "ID burst neither PE nor GCR"; 1117 break; 1118 case 03: 1119 sc->sc_fmesg = "ARA ID not found"; 1120 break; 1121 case 04: 1122 sc->sc_fmesg = "no gap found after ID burst"; 1123 break; 1124 default: 1125 sc->sc_fmesg = "unclassified failure code"; 1126 } 1127 break; 1128 1129 /* long tape record */ 1130 1131 case MTER_LONGREC: 1132 sc->sc_mesg = "long record"; 1133 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1134 case 00: 1135 sc->sc_fmesg = "extended sense data not found"; 1136 break; 1137 case 01: 1138 sc->sc_fmesg = "extended sense data updated"; 1139 break; 1140 default: 1141 sc->sc_fmesg = "unclassified failure code"; 1142 } 1143 break; 1144 1145 /* unreadable */ 1146 1147 case MTER_UNREAD: 1148 sc->sc_mesg = "unreadable record"; 1149 goto code22; 1150 1151 /* error */ 1152 1153 case MTER_ERROR: 1154 sc->sc_mesg = "error"; 1155 goto code22; 1156 1157 /* EOT error */ 1158 1159 case MTER_EOTERR: 1160 sc->sc_mesg = "EOT error"; 1161 goto code22; 1162 1163 /* tape position lost */ 1164 1165 case MTER_BADTAPE: 1166 sc->sc_mesg = "bad tape"; 1167 code22: 1168 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1169 case 01: 1170 sc->sc_fmesg = "GCR write error"; 1171 break; 1172 case 02: 1173 sc->sc_fmesg = "GCR read error"; 1174 break; 1175 case 03: 1176 sc->sc_fmesg = "PE read error"; 1177 break; 1178 case 04: 1179 sc->sc_fmesg = "PE write error"; 1180 break; 1181 case 05: 1182 sc->sc_fmesg = "at least 1 bit set in ECCSTA"; 1183 break; 1184 case 06: 1185 sc->sc_fmesg = "PE write error"; 1186 break; 1187 case 07: 1188 sc->sc_fmesg = "GCR write error"; 1189 break; 1190 case 010: 1191 sc->sc_fmesg = "RSTAT contains bad code"; 1192 break; 1193 case 011: 1194 sc->sc_fmesg = "PE write error"; 1195 break; 1196 case 012: 1197 sc->sc_fmesg = "MASSBUS parity error"; 1198 break; 1199 case 013: 1200 sc->sc_fmesg = "invalid data transferred"; 1201 break; 1202 default: 1203 sc->sc_fmesg = "unclassified failure code"; 1204 } 1205 break; 1206 1207 /* TM fault A */ 1208 1209 case MTER_TMFLTA: 1210 sc->sc_mesg = "TM fault A"; 1211 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1212 case 01: 1213 sc->sc_fmesg = "illegal command code"; 1214 break; 1215 case 02: 1216 sc->sc_fmesg = "DT command issued when NDT command active"; 1217 break; 1218 case 03: 1219 sc->sc_fmesg = "WMC error"; 1220 break; 1221 case 04: 1222 sc->sc_fmesg = "RUN not received from MASSBUS controller"; 1223 break; 1224 case 05: 1225 sc->sc_fmesg = "mismatch in command read - function routine"; 1226 break; 1227 case 06: 1228 sc->sc_fmesg = "ECC ROM parity error"; 1229 break; 1230 case 07: 1231 sc->sc_fmesg = "XMC ROM parity error"; 1232 break; 1233 case 010: 1234 sc->sc_fmesg = "mismatch in command read - ID burst command"; 1235 break; 1236 case 011: 1237 sc->sc_fmesg = "mismatch in command read - verify ARA burst command"; 1238 break; 1239 case 012: 1240 sc->sc_fmesg = "mismatch in command read - verify ARA ID command"; 1241 break; 1242 case 013: 1243 sc->sc_fmesg = "mismatch in command read - verify gap command"; 1244 break; 1245 case 014: 1246 sc->sc_fmesg = "mismatch in command read - read id burst command"; 1247 break; 1248 case 015: 1249 sc->sc_fmesg = "mismatch in command read - verify ARA ID command"; 1250 break; 1251 case 016: 1252 sc->sc_fmesg = "mismatch in command read - verify gap command"; 1253 break; 1254 case 017: 1255 sc->sc_fmesg = "mismatch in command read - find gap command"; 1256 break; 1257 case 020: 1258 sc->sc_fmesg = "WMC LEFT failed to set"; 1259 break; 1260 case 021: 1261 sc->sc_fmesg = "XL PE set in INTSTA register"; 1262 break; 1263 case 022: 1264 sc->sc_fmesg = "XMC DONE did not set"; 1265 break; 1266 case 023: 1267 sc->sc_fmesg = "WMC ROM PE or RD PE set in WMCERR register"; 1268 break; 1269 default: 1270 sc->sc_fmesg = "unclassified failure code"; 1271 } 1272 break; 1273 1274 /* TU fault A */ 1275 1276 case MTER_TUFLTA: 1277 sc->sc_mesg = "TU fault A"; 1278 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1279 case 01: 1280 sc->sc_fmesg = "TU status parity error"; 1281 break; 1282 case 02: 1283 sc->sc_fmesg = "TU command parity error"; 1284 break; 1285 case 03: 1286 sc->sc_fmesg = "rewinding tape went offline"; 1287 break; 1288 case 04: 1289 sc->sc_fmesg = "tape went not ready during DSE"; 1290 break; 1291 case 05: 1292 sc->sc_fmesg = "TU CMD status changed during DSE"; 1293 break; 1294 case 06: 1295 sc->sc_fmesg = "TU never came up to speed"; 1296 break; 1297 case 07: 1298 sc->sc_fmesg = "TU velocity changed"; 1299 break; 1300 case 010: 1301 sc->sc_fmesg = "TU CMD did not load correctly to start tape motion"; 1302 break; 1303 case 011: 1304 sc->sc_fmesg = "TU CMD did not load correctly to set drive density"; 1305 break; 1306 case 012: 1307 sc->sc_fmesg = "TU CMD did not load correctly to start tape motion to write BOT ID"; 1308 break; 1309 case 013: 1310 sc->sc_fmesg = "TU CMD did not load correctly to backup tape to BOT after failing to write BOT ID"; 1311 break; 1312 case 014: 1313 sc->sc_fmesg = "failed to write density ID burst"; 1314 break; 1315 case 015: 1316 sc->sc_fmesg = "failed to write ARA burst"; 1317 break; 1318 case 016: 1319 sc->sc_fmesg = "failed to write ARA ID"; 1320 break; 1321 case 017: 1322 sc->sc_fmesg = "ARA error bit set in MTA status B register"; 1323 break; 1324 case 021: 1325 sc->sc_fmesg = "could not find a gap after ID code was written correctly"; 1326 break; 1327 case 022: 1328 sc->sc_fmesg = "TU CMD did not load correctly to start tape motion to read ID burst"; 1329 break; 1330 case 023: 1331 sc->sc_fmesg = "timeout looking for BOT after detecting ARA ID burst"; 1332 break; 1333 case 024: 1334 sc->sc_fmesg = "failed to write tape mark"; 1335 break; 1336 case 025: 1337 sc->sc_fmesg = "tape never came up to speed while trying to reposition for retry of writing tape mark"; 1338 break; 1339 case 026: 1340 sc->sc_fmesg = "TU CMD did not load correctly to start tape motion in erase gap routine"; 1341 break; 1342 case 027: 1343 sc->sc_fmesg = "could not detect a gap in in erase gap routine"; 1344 break; 1345 case 030: 1346 sc->sc_fmesg = "could not detect a gap after writing record"; 1347 break; 1348 case 031: 1349 sc->sc_fmesg = "read path terminated before entire record was written"; 1350 break; 1351 case 032: 1352 sc->sc_fmesg = "could not find a gap after writing record and read path terminated early"; 1353 break; 1354 case 033: 1355 sc->sc_fmesg = "TU CMD did not load correctly to backup for retry of write tape mark"; 1356 break; 1357 case 034: 1358 sc->sc_fmesg = "TU velocity changed after up to speed while trying to reposition for retry of writing tape mark"; 1359 break; 1360 case 035: 1361 sc->sc_fmesg = "TU CMD did not load correctly to backup to retry a load of BOT ID"; 1362 break; 1363 case 036: 1364 sc->sc_fmesg = "timeout looking for BOT after failing to write BOT ID"; 1365 break; 1366 case 037: 1367 sc->sc_fmesg = "TU velocity changed while writing PE gap before starting to write record"; 1368 break; 1369 case 040: 1370 sc->sc_fmesg = "TU CMD did not load correctly to set PE tape density at start of write BOT ID burst"; 1371 break; 1372 case 041: 1373 sc->sc_fmesg = "TU CMD did not load correctly to set GCR tape density after writing Density ID"; 1374 break; 1375 case 042: 1376 sc->sc_fmesg = "TU CMD did not load correctly to set PE tape density at start of read from BOT"; 1377 break; 1378 case 043: 1379 sc->sc_fmesg = "TU CMD did not load correctly to set GCR tape density after reading a GCR Density ID burst"; 1380 break; 1381 default: 1382 sc->sc_fmesg = "unclassified failure code"; 1383 } 1384 break; 1385 1386 /* TM fault B */ 1387 1388 case MTER_TMFLTB: 1389 sc->sc_mesg = "TM fault B"; 1390 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1391 case 00: 1392 sc->sc_fmesg = "RST0 interrupt occurred with TM RDY set"; 1393 break; 1394 case 01: 1395 sc->sc_fmesg = "power failed to interrupt"; 1396 break; 1397 case 02: 1398 sc->sc_fmesg = "unknown interrupt on channel 5.5"; 1399 break; 1400 case 03: 1401 sc->sc_fmesg = "unknown interrupt on channel 6.5"; 1402 break; 1403 case 04: 1404 sc->sc_fmesg = "unknown interrupt on channel 7"; 1405 break; 1406 case 05: 1407 sc->sc_fmesg = "unknown interrupt on channel 7.5"; 1408 break; 1409 case 06: 1410 sc->sc_fmesg = "CAS contention retry count expired"; 1411 break; 1412 case 07: 1413 sc->sc_fmesg = "CAS contention error not retryable"; 1414 break; 1415 case 010: 1416 sc->sc_fmesg = "queue error, could not find queue entry"; 1417 break; 1418 case 011: 1419 sc->sc_fmesg = "queue entry already full"; 1420 break; 1421 case 012: 1422 sc->sc_fmesg = "8085 ROM parity error"; 1423 break; 1424 case 013: 1425 case 014: 1426 case 015: 1427 case 016: 1428 case 017: 1429 case 020: 1430 case 021: 1431 case 022: 1432 case 023: 1433 case 024: 1434 case 025: 1435 case 026: 1436 case 027: 1437 case 030: 1438 case 031: 1439 case 032: 1440 case 033: 1441 case 034: 1442 case 035: 1443 case 036: 1444 case 037: 1445 case 040: 1446 case 041: 1447 case 042: 1448 case 043: 1449 case 044: 1450 case 045: 1451 case 046: 1452 case 047: 1453 case 050: 1454 case 051: 1455 case 052: 1456 case 053: 1457 case 054: 1458 case 055: 1459 case 056: 1460 case 057: 1461 sc->sc_fmesg = "inline test failed"; 1462 break; 1463 default: 1464 sc->sc_fmesg = "unclassified failure code"; 1465 } 1466 break; 1467 1468 /* MASSBUS fault */ 1469 1470 case MTER_MBFLT: 1471 sc->sc_mesg = "MB fault"; 1472 switch ((sc->sc_erreg & MTER_FAILCODE) >> 10) { 1473 case 01: 1474 sc->sc_fmesg = "control bus parity error"; 1475 break; 1476 case 02: 1477 sc->sc_fmesg = "illegal register referenced"; 1478 break; 1479 default: 1480 sc->sc_fmesg = "unclassified failure code"; 1481 } 1482 break; 1483 1484 /* keypad entry error */ 1485 1486 case MTER_KEYFAIL: 1487 sc->sc_mesg = "keypad entry error"; 1488 sc->sc_fmesg = ""; 1489 break; 1490 default: 1491 sc->sc_mesg = "unclassified error"; 1492 sc->sc_fmesg = ""; 1493 break; 1494 } 1495 } 1496 #endif MTLERRM 1497 #endif 1498