Annotation of researchv8dc/sys/dev/mt.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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