Annotation of 43BSD/sys/vaxmba/mt.c, revision 1.1.1.1

1.1       root        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) 6/5/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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.