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