[BACK]Return to mt.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / dev

Annotation of sys/arch/hp300/dev/mt.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mt.c,v 1.18 2007/06/06 17:15:11 deraadt Exp $ */
                      2: /*     $NetBSD: mt.c,v 1.8 1997/03/31 07:37:29 scottr Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (c) 1996, 1997 Jason R. Thorpe.  All rights reserved.
                      6:  * Copyright (c) 1992, The University of Utah and
                      7:  * the Computer Systems Laboratory at the University of Utah (CSL).
                      8:  * All rights reserved.
                      9:  *
                     10:  * Permission to use, copy, modify and distribute this software is hereby
                     11:  * granted provided that (1) source code retains these copyright, permission,
                     12:  * and disclaimer notices, and (2) redistributions including binaries
                     13:  * reproduce the notices in supporting documentation, and (3) all advertising
                     14:  * materials mentioning features or use of this software display the following
                     15:  * acknowledgement: ``This product includes software developed by the
                     16:  * Computer Systems Laboratory at the University of Utah.''
                     17:  *
                     18:  * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
                     19:  * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
                     20:  * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     21:  *
                     22:  * CSL requests users of this software to return to csl-dist@cs.utah.edu any
                     23:  * improvements that they make and grant CSL redistribution rights.
                     24:  *
                     25:  *     Utah $Hdr: mt.c 1.8 95/09/12$
                     26:  */
                     27: /*     @(#)mt.c        3.9     90/07/10        mt Xinu
                     28:  *
                     29:  * Magnetic tape driver (7974a, 7978a/b, 7979a, 7980a, 7980xc)
                     30:  * Original version contributed by Mt. Xinu.
                     31:  * Modified for 4.4BSD by Mark Davies and Andrew Vignaux, Department of
                     32:  * Computer Science, Victoria University of Wellington
                     33:  */
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/buf.h>
                     38: #include <sys/ioctl.h>
                     39: #include <sys/mtio.h>
                     40: #include <sys/file.h>
                     41: #include <sys/proc.h>
                     42: #include <sys/errno.h>
                     43: #include <sys/syslog.h>
                     44: #include <sys/tty.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/device.h>
                     47: #include <sys/conf.h>
                     48:
                     49: #include <hp300/dev/hpibvar.h>
                     50:
                     51: #include <hp300/dev/mtreg.h>
                     52:
                     53: struct mtinfo {
                     54:        u_short hwid;
                     55:        char    *desc;
                     56: } mtinfo[] = {
                     57:        { MT7978ID,     "7978"  },
                     58:        { MT7979AID,    "7979A" },
                     59:        { MT7980ID,     "7980"  },
                     60:        { MT7974AID,    "7974A" },
                     61: };
                     62: int    nmtinfo = sizeof(mtinfo) / sizeof(mtinfo[0]);
                     63:
                     64: struct mt_softc {
                     65:        struct  device sc_dev;
                     66:        int     sc_hpibno;      /* logical HPIB this slave it attached to */
                     67:        int     sc_slave;       /* HPIB slave address (0-6) */
                     68:        short   sc_flags;       /* see below */
                     69:        u_char  sc_lastdsj;     /* place for DSJ in mtreaddsj() */
                     70:        u_char  sc_lastecmd;    /* place for End Command in mtreaddsj() */
                     71:        short   sc_recvtimeo;   /* count of hpibsend timeouts to prevent hang */
                     72:        short   sc_statindex;   /* index for next sc_stat when MTF_STATTIMEO */
                     73:        struct  mt_stat sc_stat;/* status bytes last read from device */
                     74:        short   sc_density;     /* current density of tape (mtio.h format) */
                     75:        short   sc_type;        /* tape drive model (hardware IDs) */
                     76:        struct  hpibqueue sc_hq; /* HPIB device queue member */
                     77:        struct buf sc_tab;      /* buf queue */
                     78:        struct buf sc_bufstore; /* XXX buffer storage */
                     79:        struct timeout sc_start_to; /* spl_mtstart timeout */
                     80:        struct timeout sc_intr_to; /* spl_mtintr timeout */
                     81: };
                     82:
                     83: #ifdef DEBUG
                     84: int    mtdebug = 0;
                     85: #define        dlog    if (mtdebug) log
                     86: #else
                     87: #define        dlog    if (0) log
                     88: #endif
                     89:
                     90: #define        UNIT(x)         (minor(x) & 3)
                     91:
                     92: #define B_CMD          B_XXX           /* command buf instead of data */
                     93: #define        b_cmd           b_blkno         /* blkno holds cmd when B_CMD */
                     94:
                     95: int    mtmatch(struct device *, void *, void *);
                     96: void   mtattach(struct device *, struct device *, void *);
                     97:
                     98: struct cfattach mt_ca = {
                     99:        sizeof(struct mt_softc), mtmatch, mtattach
                    100: };
                    101:
                    102: struct cfdriver mt_cd = {
                    103:        NULL, "mt", DV_TAPE
                    104: };
                    105:
                    106: int    mtident(struct mt_softc *, struct hpibbus_attach_args *);
                    107: void   mtustart(struct mt_softc *);
                    108: int    mtreaddsj(struct mt_softc *, int);
                    109: int    mtcommand(dev_t, int, int);
                    110: void   spl_mtintr(void *);
                    111: void   spl_mtstart(void *);
                    112:
                    113: void   mtstart(void *);
                    114: void   mtgo(void *);
                    115: void   mtintr(void *);
                    116:
                    117: bdev_decl(mt);
                    118: cdev_decl(mt);
                    119:
                    120: int
                    121: mtmatch(parent, match, aux)
                    122:        struct device *parent;
                    123:        void *match, *aux;
                    124: {
                    125:        struct hpibbus_attach_args *ha = aux;
                    126:
                    127:        return (mtident(NULL, ha));
                    128: }
                    129:
                    130: void
                    131: mtattach(parent, self, aux)
                    132:        struct device *parent, *self;
                    133:        void *aux;
                    134: {
                    135:        struct mt_softc *sc = (struct mt_softc *)self;
                    136:        struct hpibbus_attach_args *ha = aux;
                    137:        int unit, hpibno, slave;
                    138:
                    139:        if (mtident(sc, ha) == 0) {
                    140:                printf("\n%s: impossible!\n", sc->sc_dev.dv_xname);
                    141:                return;
                    142:        }
                    143:
                    144:        unit = self->dv_unit;
                    145:        hpibno = parent->dv_unit;
                    146:        slave = ha->ha_slave;
                    147:
                    148:        sc->sc_tab.b_actb = &sc->sc_tab.b_actf;
                    149:
                    150:        sc->sc_hpibno = hpibno;
                    151:        sc->sc_slave = slave;
                    152:        sc->sc_flags = MTF_EXISTS;
                    153:
                    154:        /* Initialize hpib job queue entry. */
                    155:        sc->sc_hq.hq_softc = sc;
                    156:        sc->sc_hq.hq_slave = sc->sc_slave;
                    157:        sc->sc_hq.hq_start = mtstart;
                    158:        sc->sc_hq.hq_go = mtgo;
                    159:        sc->sc_hq.hq_intr = mtintr;
                    160:
                    161:        /* Initialize timeout structures */
                    162:        timeout_set(&sc->sc_start_to, spl_mtstart, sc);
                    163:        timeout_set(&sc->sc_intr_to, spl_mtintr, sc);
                    164: }
                    165:
                    166: int
                    167: mtident(sc, ha)
                    168:        struct mt_softc *sc;
                    169:        struct hpibbus_attach_args *ha;
                    170: {
                    171:        int i;
                    172:
                    173:        for (i = 0; i < nmtinfo; i++) {
                    174:                if (ha->ha_id == mtinfo[i].hwid &&
                    175:                    ha->ha_punit == 0) {
                    176:                        if (sc != NULL) {
                    177:                                sc->sc_type = mtinfo[i].hwid;
                    178:                                printf(": %s tape\n", mtinfo[i].desc);
                    179:                        }
                    180:                        return (1);
                    181:                }
                    182:        }
                    183:        return (0);
                    184: }
                    185:
                    186: /*
                    187:  * Perform a read of "Device Status Jump" register and update the
                    188:  * status if necessary.  If status is read, the given "ecmd" is also
                    189:  * performed, unless "ecmd" is zero.  Returns DSJ value, -1 on failure
                    190:  * and -2 on "temporary" failure.
                    191:  */
                    192: int
                    193: mtreaddsj(sc, ecmd)
                    194:        struct mt_softc *sc;
                    195:        int ecmd;
                    196: {
                    197:        int retval;
                    198:
                    199:        if (sc->sc_flags & MTF_STATTIMEO)
                    200:                goto getstats;
                    201:        retval = hpibrecv(sc->sc_hpibno,
                    202:            (sc->sc_flags & MTF_DSJTIMEO) ? -1 : sc->sc_slave,
                    203:            MTT_DSJ, &(sc->sc_lastdsj), 1);
                    204:        sc->sc_flags &= ~MTF_DSJTIMEO;
                    205:        if (retval != 1) {
                    206:                dlog(LOG_DEBUG, "%s can't hpibrecv DSJ",
                    207:                    sc->sc_dev.dv_xname);
                    208:                if (sc->sc_recvtimeo == 0)
                    209:                        sc->sc_recvtimeo = hz;
                    210:                if (--sc->sc_recvtimeo == 0)
                    211:                        return (-1);
                    212:                if (retval == 0)
                    213:                        sc->sc_flags |= MTF_DSJTIMEO;
                    214:                return (-2);
                    215:        }
                    216:        sc->sc_recvtimeo = 0;
                    217:        sc->sc_statindex = 0;
                    218:        dlog(LOG_DEBUG, "%s readdsj: 0x%x", sc->sc_dev.dv_xname,
                    219:            sc->sc_lastdsj);
                    220:        sc->sc_lastecmd = ecmd;
                    221:        switch (sc->sc_lastdsj) {
                    222:            case 0:
                    223:                if (ecmd & MTE_DSJ_FORCE)
                    224:                        break;
                    225:                return (0);
                    226:
                    227:            case 2:
                    228:                sc->sc_lastecmd = MTE_COMPLETE;
                    229:            case 1:
                    230:                break;
                    231:
                    232:            default:
                    233:                log(LOG_ERR, "%s readdsj: DSJ 0x%x\n", sc->sc_dev.dv_xname,
                    234:                    sc->sc_lastdsj);
                    235:                return (-1);
                    236:        }
                    237:     getstats:
                    238:        retval = hpibrecv(sc->sc_hpibno,
                    239:            (sc->sc_flags & MTF_STATCONT) ? -1 : sc->sc_slave,
                    240:            MTT_STAT, ((char *)&(sc->sc_stat)) + sc->sc_statindex,
                    241:            sizeof(sc->sc_stat) - sc->sc_statindex);
                    242:        sc->sc_flags &= ~(MTF_STATTIMEO | MTF_STATCONT);
                    243:        if (retval != sizeof(sc->sc_stat) - sc->sc_statindex) {
                    244:                if (sc->sc_recvtimeo == 0)
                    245:                        sc->sc_recvtimeo = hz;
                    246:                if (--sc->sc_recvtimeo != 0) {
                    247:                        if (retval >= 0) {
                    248:                                sc->sc_statindex += retval;
                    249:                                sc->sc_flags |= MTF_STATCONT;
                    250:                        }
                    251:                        sc->sc_flags |= MTF_STATTIMEO;
                    252:                        return (-2);
                    253:                }
                    254:                log(LOG_ERR, "%s readdsj: can't read status",
                    255:                    sc->sc_dev.dv_xname);
                    256:                return (-1);
                    257:        }
                    258:        sc->sc_recvtimeo = 0;
                    259:        sc->sc_statindex = 0;
                    260:        dlog(LOG_DEBUG, "%s readdsj: status is %x %x %x %x %x %x",
                    261:            sc->sc_dev.dv_xname,
                    262:            sc->sc_stat1, sc->sc_stat2, sc->sc_stat3,
                    263:            sc->sc_stat4, sc->sc_stat5, sc->sc_stat6);
                    264:        if (sc->sc_lastecmd)
                    265:                (void) hpibsend(sc->sc_hpibno, sc->sc_slave,
                    266:                    MTL_ECMD, &(sc->sc_lastecmd), 1);
                    267:        return ((int) sc->sc_lastdsj);
                    268: }
                    269:
                    270: int
                    271: mtopen(dev, flag, mode, p)
                    272:        dev_t dev;
                    273:        int flag, mode;
                    274:        struct proc *p;
                    275: {
                    276:        int unit = UNIT(dev);
                    277:        struct mt_softc *sc;
                    278:        int req_den;
                    279:        int error;
                    280:
                    281:        if (unit >= mt_cd.cd_ndevs ||
                    282:            (sc = mt_cd.cd_devs[unit]) == NULL ||
                    283:            (sc->sc_flags & MTF_EXISTS) == 0)
                    284:                return (ENXIO);
                    285:
                    286:        dlog(LOG_DEBUG, "%s open: flags 0x%x", sc->sc_dev.dv_xname,
                    287:            sc->sc_flags);
                    288:        if (sc->sc_flags & MTF_OPEN)
                    289:                return (EBUSY);
                    290:        sc->sc_flags |= MTF_OPEN;
                    291:        if ((sc->sc_flags & MTF_ALIVE) == 0) {
                    292:                error = mtcommand(dev, MTRESET, 0);
                    293:                if (error != 0 || (sc->sc_flags & MTF_ALIVE) == 0)
                    294:                        goto errout;
                    295:                if ((sc->sc_stat1 & (SR1_BOT | SR1_ONLINE)) == SR1_ONLINE)
                    296:                        (void) mtcommand(dev, MTREW, 0);
                    297:        }
                    298:        for (;;) {
                    299:                if ((error = mtcommand(dev, MTNOP, 0)) != 0)
                    300:                        goto errout;
                    301:                if (!(sc->sc_flags & MTF_REW))
                    302:                        break;
                    303:                if (tsleep((caddr_t) &lbolt, PCATCH | (PZERO + 1),
                    304:                    "mt", 0) != 0) {
                    305:                        error = EINTR;
                    306:                        goto errout;
                    307:                }
                    308:        }
                    309:        if ((flag & FWRITE) && (sc->sc_stat1 & SR1_RO)) {
                    310:                error = EROFS;
                    311:                goto errout;
                    312:        }
                    313:        if (!(sc->sc_stat1 & SR1_ONLINE)) {
                    314:                uprintf("%s: not online\n", sc->sc_dev.dv_xname);
                    315:                error = EIO;
                    316:                goto errout;
                    317:        }
                    318:        /*
                    319:         * Select density:
                    320:         *  - find out what density the drive is set to
                    321:         *      (i.e. the density of the current tape)
                    322:         *  - if we are going to write
                    323:         *    - if we're not at the beginning of the tape
                    324:         *      - complain if we want to change densities
                    325:         *    - otherwise, select the mtcommand to set the density
                    326:         *
                    327:         * If the drive doesn't support it then don't change the recorded
                    328:         * density.
                    329:         *
                    330:         * The original MOREbsd code had these additional conditions
                    331:         * for the mid-tape change
                    332:         *
                    333:         *      req_den != T_BADBPI &&
                    334:         *      sc->sc_density != T_6250BPI
                    335:         *
                    336:         * which suggests that it would be possible to write multiple
                    337:         * densities if req_den == T_BAD_BPI or the current tape
                    338:         * density was 6250.  Testing of our 7980 suggests that the
                    339:         * device cannot change densities mid-tape.
                    340:         *
                    341:         * ajv@comp.vuw.ac.nz
                    342:         */
                    343:        sc->sc_density = (sc->sc_stat2 & SR2_6250) ? T_6250BPI : (
                    344:                         (sc->sc_stat3 & SR3_1600) ? T_1600BPI : (
                    345:                         (sc->sc_stat3 & SR3_800) ? T_800BPI : -1));
                    346:        req_den = (dev & T_DENSEL);
                    347:
                    348:        if (flag & FWRITE) {
                    349:                if (!(sc->sc_stat1 & SR1_BOT)) {
                    350:                        if (sc->sc_density != req_den) {
                    351:                                uprintf("%s: can't change density mid-tape\n",
                    352:                                    sc->sc_dev.dv_xname);
                    353:                                error = EIO;
                    354:                                goto errout;
                    355:                        }
                    356:                }
                    357:                else {
                    358:                        int mtset_density =
                    359:                            (req_den == T_800BPI  ? MTSET800BPI : (
                    360:                             req_den == T_1600BPI ? MTSET1600BPI : (
                    361:                             req_den == T_6250BPI ? MTSET6250BPI : (
                    362:                             sc->sc_type == MT7980ID
                    363:                                                  ? MTSET6250DC
                    364:                                                  : MTSET6250BPI))));
                    365:                        if (mtcommand(dev, mtset_density, 0) == 0)
                    366:                                sc->sc_density = req_den;
                    367:                }
                    368:        }
                    369:        return (0);
                    370: errout:
                    371:        sc->sc_flags &= ~MTF_OPEN;
                    372:        return (error);
                    373: }
                    374:
                    375: int
                    376: mtclose(dev, flag, fmt, p)
                    377:        dev_t dev;
                    378:        int flag, fmt;
                    379:        struct proc *p;
                    380: {
                    381:        struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)];
                    382:
                    383:        if (sc->sc_flags & MTF_WRT) {
                    384:                (void) mtcommand(dev, MTWEOF, 2);
                    385:                (void) mtcommand(dev, MTBSF, 0);
                    386:        }
                    387:        if ((minor(dev) & T_NOREWIND) == 0)
                    388:                (void) mtcommand(dev, MTREW, 0);
                    389:        sc->sc_flags &= ~MTF_OPEN;
                    390:        return (0);
                    391: }
                    392:
                    393: int
                    394: mtcommand(dev, cmd, cnt)
                    395:        dev_t dev;
                    396:        int cmd;
                    397:        int cnt;
                    398: {
                    399:        struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)];
                    400:        struct buf *bp = &sc->sc_bufstore;
                    401:        int error = 0;
                    402:
                    403: #if 1
                    404:        if (bp->b_flags & B_BUSY)
                    405:                return (EBUSY);
                    406: #endif
                    407:        bp->b_cmd = cmd;
                    408:        bp->b_dev = dev;
                    409:        do {
                    410:                bp->b_flags = B_BUSY | B_CMD;
                    411:                mtstrategy(bp);
                    412:                biowait(bp);
                    413:                if (bp->b_flags & B_ERROR) {
                    414:                        error = (int) (unsigned) bp->b_error;
                    415:                        break;
                    416:                }
                    417:        } while (--cnt > 0);
                    418: #if 0
                    419:        bp->b_flags = 0 /*&= ~B_BUSY*/;
                    420: #else
                    421:        bp->b_flags &= ~B_BUSY;
                    422: #endif
                    423:        return (error);
                    424: }
                    425:
                    426: /*
                    427:  * Only thing to check here is for legal record lengths (writes only).
                    428:  */
                    429: void
                    430: mtstrategy(bp)
                    431:        struct buf *bp;
                    432: {
                    433:        struct mt_softc *sc;
                    434:        struct buf *dp;
                    435:        int unit;
                    436:        int s;
                    437:
                    438:        unit = UNIT(bp->b_dev);
                    439:        sc = mt_cd.cd_devs[unit];
                    440:        dlog(LOG_DEBUG, "%s strategy", sc->sc_dev.dv_xname);
                    441:        if ((bp->b_flags & (B_CMD | B_READ)) == 0) {
                    442: #define WRITE_BITS_IGNORED     8
                    443: #if 0
                    444:                if (bp->b_bcount & ((1 << WRITE_BITS_IGNORED) - 1)) {
                    445:                        printf("%s: write record must be multiple of %d\n",
                    446:                                sc->sc_dev.dv_xname, 1 << WRITE_BITS_IGNORED);
                    447:                        goto error;
                    448:                }
                    449: #endif
                    450:                s = 16 * 1024;
                    451:                if (sc->sc_stat2 & SR2_LONGREC) {
                    452:                        switch (sc->sc_density) {
                    453:                            case T_1600BPI:
                    454:                                s = 32 * 1024;
                    455:                                break;
                    456:
                    457:                            case T_6250BPI:
                    458:                            case T_BADBPI:
                    459:                                s = 60 * 1024;
                    460:                                break;
                    461:                        }
                    462:                }
                    463:                if (bp->b_bcount > s) {
                    464:                        printf("%s: write record (%ld) too big: limit (%d)\n",
                    465:                                sc->sc_dev.dv_xname, bp->b_bcount, s);
                    466: #if 0 /* XXX see above */
                    467:            error:
                    468: #endif
                    469:                        bp->b_flags |= B_ERROR;
                    470:                        bp->b_error = EIO;
                    471:                        s = splbio();
                    472:                        biodone(bp);
                    473:                        splx(s);
                    474:                        return;
                    475:                }
                    476:        }
                    477:        dp = &sc->sc_tab;
                    478:        bp->b_actf = NULL;
                    479:        s = splbio();
                    480:        bp->b_actb = dp->b_actb;
                    481:        *dp->b_actb = bp;
                    482:        dp->b_actb = &bp->b_actf;
                    483:        if (dp->b_active == 0) {
                    484:                dp->b_active = 1;
                    485:                mtustart(sc);
                    486:        }
                    487:        splx(s);
                    488: }
                    489:
                    490: void
                    491: mtustart(sc)
                    492:        struct mt_softc *sc;
                    493: {
                    494:
                    495:        dlog(LOG_DEBUG, "%s ustart", sc->sc_dev.dv_xname);
                    496:        if (hpibreq(sc->sc_dev.dv_parent, &sc->sc_hq))
                    497:                mtstart(sc);
                    498: }
                    499:
                    500: void
                    501: spl_mtintr(arg)
                    502:        void *arg;
                    503: {
                    504:        struct mt_softc *sc = arg;
                    505:        int s = splbio();
                    506:
                    507:        hpibppclear(sc->sc_hpibno);
                    508:        mtintr(sc);
                    509:        splx(s);
                    510: }
                    511:
                    512: void
                    513: spl_mtstart(arg)
                    514:        void *arg;
                    515: {
                    516:        int s = splbio();
                    517:
                    518:        mtstart(arg);
                    519:        splx(s);
                    520: }
                    521:
                    522: void
                    523: mtstart(arg)
                    524:        void *arg;
                    525: {
                    526:        struct mt_softc *sc = arg;
                    527:        struct buf *bp, *dp;
                    528:        short   cmdcount = 1;
                    529:        u_char  cmdbuf[2];
                    530:        int s;
                    531:
                    532:        dlog(LOG_DEBUG, "%s start", sc->sc_dev.dv_xname);
                    533:        sc->sc_flags &= ~MTF_WRT;
                    534:        bp = sc->sc_tab.b_actf;
                    535:        if ((sc->sc_flags & MTF_ALIVE) == 0 &&
                    536:            ((bp->b_flags & B_CMD) == 0 || bp->b_cmd != MTRESET))
                    537:                goto fatalerror;
                    538:
                    539:        if (sc->sc_flags & MTF_REW) {
                    540:                if (!hpibpptest(sc->sc_hpibno, sc->sc_slave))
                    541:                        goto stillrew;
                    542:                switch (mtreaddsj(sc, MTE_DSJ_FORCE|MTE_COMPLETE|MTE_IDLE)) {
                    543:                    case 0:
                    544:                    case 1:
                    545:                stillrew:
                    546:                        if ((sc->sc_stat1 & SR1_BOT) ||
                    547:                            !(sc->sc_stat1 & SR1_ONLINE)) {
                    548:                                sc->sc_flags &= ~MTF_REW;
                    549:                                break;
                    550:                        }
                    551:                    case -2:
                    552:                        /*
                    553:                         * -2 means "timeout" reading DSJ, which is probably
                    554:                         * temporary.  This is considered OK when doing a NOP,
                    555:                         * but not otherwise.
                    556:                         */
                    557:                        if (sc->sc_flags & (MTF_DSJTIMEO | MTF_STATTIMEO)) {
                    558:                                timeout_add(&sc->sc_start_to, hz >> 5);
                    559:                                return;
                    560:                        }
                    561:                    case 2:
                    562:                        if (bp->b_cmd != MTNOP || !(bp->b_flags & B_CMD)) {
                    563:                                bp->b_error = EBUSY;
                    564:                                goto errdone;
                    565:                        }
                    566:                        goto done;
                    567:
                    568:                    default:
                    569:                        goto fatalerror;
                    570:                }
                    571:        }
                    572:        if (bp->b_flags & B_CMD) {
                    573:                if (sc->sc_flags & MTF_PASTEOT) {
                    574:                        switch(bp->b_cmd) {
                    575:                            case MTFSF:
                    576:                            case MTWEOF:
                    577:                            case MTFSR:
                    578:                                bp->b_error = ENOSPC;
                    579:                                goto errdone;
                    580:
                    581:                            case MTBSF:
                    582:                            case MTOFFL:
                    583:                            case MTBSR:
                    584:                            case MTREW:
                    585:                                sc->sc_flags &= ~(MTF_PASTEOT | MTF_ATEOT);
                    586:                                break;
                    587:                        }
                    588:                }
                    589:                switch(bp->b_cmd) {
                    590:                    case MTFSF:
                    591:                        if (sc->sc_flags & MTF_HITEOF)
                    592:                                goto done;
                    593:                        cmdbuf[0] = MTTC_FSF;
                    594:                        break;
                    595:
                    596:                    case MTBSF:
                    597:                        if (sc->sc_flags & MTF_HITBOF)
                    598:                                goto done;
                    599:                        cmdbuf[0] = MTTC_BSF;
                    600:                        break;
                    601:
                    602:                    case MTOFFL:
                    603:                        sc->sc_flags |= MTF_REW;
                    604:                        cmdbuf[0] = MTTC_REWOFF;
                    605:                        break;
                    606:
                    607:                    case MTWEOF:
                    608:                        cmdbuf[0] = MTTC_WFM;
                    609:                        break;
                    610:
                    611:                    case MTBSR:
                    612:                        cmdbuf[0] = MTTC_BSR;
                    613:                        break;
                    614:
                    615:                    case MTFSR:
                    616:                        cmdbuf[0] = MTTC_FSR;
                    617:                        break;
                    618:
                    619:                    case MTREW:
                    620:                        sc->sc_flags |= MTF_REW;
                    621:                        cmdbuf[0] = MTTC_REW;
                    622:                        break;
                    623:
                    624:                    case MTNOP:
                    625:                        /*
                    626:                         * NOP is supposed to set status bits.
                    627:                         * Force readdsj to do it.
                    628:                         */
                    629:                        switch (mtreaddsj(sc,
                    630:                          MTE_DSJ_FORCE | MTE_COMPLETE | MTE_IDLE)) {
                    631:                            default:
                    632:                                goto done;
                    633:
                    634:                            case -1:
                    635:                                /*
                    636:                                 * If this fails, perform a device clear
                    637:                                 * to fix any protocol problems and (most
                    638:                                 * likely) get the status.
                    639:                                 */
                    640:                                bp->b_cmd = MTRESET;
                    641:                                break;
                    642:
                    643:                            case -2:
                    644:                                timeout_add(&sc->sc_start_to, hz >> 5);
                    645:                                return;
                    646:                        }
                    647:
                    648:                    case MTRESET:
                    649:                        /*
                    650:                         * 1) selected device clear (send with "-2" secondary)
                    651:                         * 2) set timeout, then wait for "service request"
                    652:                         * 3) interrupt will read DSJ (and END COMPLETE-IDLE)
                    653:                         */
                    654:                        if (hpibsend(sc->sc_hpibno, sc->sc_slave, -2, NULL, 0)){
                    655:                                log(LOG_ERR, "%s can't reset",
                    656:                                    sc->sc_dev.dv_xname);
                    657:                                goto fatalerror;
                    658:                        }
                    659:                        timeout_add(&sc->sc_intr_to, 4 * hz);
                    660:                        hpibawait(sc->sc_hpibno);
                    661:                        return;
                    662:
                    663:                    case MTSET800BPI:
                    664:                        cmdbuf[0] = MTTC_800;
                    665:                        break;
                    666:
                    667:                    case MTSET1600BPI:
                    668:                        cmdbuf[0] = MTTC_1600;
                    669:                        break;
                    670:
                    671:                    case MTSET6250BPI:
                    672:                        cmdbuf[0] = MTTC_6250;
                    673:                        break;
                    674:
                    675:                    case MTSET6250DC:
                    676:                        cmdbuf[0] = MTTC_DC6250;
                    677:                        break;
                    678:                }
                    679:        } else {
                    680:                if (sc->sc_flags & MTF_PASTEOT) {
                    681:                        bp->b_error = ENOSPC;
                    682:                        goto errdone;
                    683:                }
                    684:                if (bp->b_flags & B_READ) {
                    685:                        sc->sc_flags |= MTF_IO;
                    686:                        cmdbuf[0] = MTTC_READ;
                    687:                } else {
                    688:                        sc->sc_flags |= MTF_WRT | MTF_IO;
                    689:                        cmdbuf[0] = MTTC_WRITE;
                    690:                        cmdbuf[1] = (bp->b_bcount + ((1 << WRITE_BITS_IGNORED) - 1)) >> WRITE_BITS_IGNORED;
                    691:                        cmdcount = 2;
                    692:                }
                    693:        }
                    694:        if (hpibsend(sc->sc_hpibno, sc->sc_slave, MTL_TCMD, cmdbuf, cmdcount)
                    695:            == cmdcount) {
                    696:                if (sc->sc_flags & MTF_REW)
                    697:                        goto done;
                    698:                hpibawait(sc->sc_hpibno);
                    699:                return;
                    700:        }
                    701: fatalerror:
                    702:        /*
                    703:         * If anything fails, the drive is probably hosed, so mark it not
                    704:         * "ALIVE" (but it EXISTS and is OPEN or we wouldn't be here, and
                    705:         * if, last we heard, it was REWinding, remember that).
                    706:         */
                    707:        sc->sc_flags &= MTF_EXISTS | MTF_OPEN | MTF_REW;
                    708:        bp->b_error = EIO;
                    709: errdone:
                    710:        bp->b_flags |= B_ERROR;
                    711: done:
                    712:        sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF);
                    713:        s = splbio();
                    714:        biodone(bp);
                    715:        splx(s);
                    716:        if ((dp = bp->b_actf))
                    717:                dp->b_actb = bp->b_actb;
                    718:        else
                    719:                sc->sc_tab.b_actb = bp->b_actb;
                    720:        *bp->b_actb = dp;
                    721:        hpibfree(sc->sc_dev.dv_parent, &sc->sc_hq);
                    722:        if ((bp = dp) == NULL)
                    723:                sc->sc_tab.b_active = 0;
                    724:        else
                    725:                mtustart(sc);
                    726: }
                    727:
                    728: /*
                    729:  * The Utah code had a bug which meant that the driver was unable to read.
                    730:  * "rw" was initialized to bp->b_flags & B_READ before "bp" was initialized.
                    731:  *   -- ajv@comp.vuw.ac.nz
                    732:  */
                    733: void
                    734: mtgo(arg)
                    735:        void *arg;
                    736: {
                    737:        struct mt_softc *sc = arg;
                    738:        struct buf *bp;
                    739:        int rw;
                    740:
                    741:        dlog(LOG_DEBUG, "%s go", sc->sc_dev.dv_xname);
                    742:        bp = sc->sc_tab.b_actf;
                    743:        rw = bp->b_flags & B_READ;
                    744:        hpibgo(sc->sc_hpibno, sc->sc_slave, rw ? MTT_READ : MTL_WRITE,
                    745:            bp->b_data, bp->b_bcount, rw, rw != 0);
                    746: }
                    747:
                    748: void
                    749: mtintr(arg)
                    750:        void *arg;
                    751: {
                    752:        struct mt_softc *sc = arg;
                    753:        struct buf *bp, *dp;
                    754:        int i;
                    755:        u_char cmdbuf[4];
                    756:
                    757:        bp = sc->sc_tab.b_actf;
                    758:        if (bp == NULL) {
                    759:                log(LOG_ERR, "%s intr: bp == NULL", sc->sc_dev.dv_xname);
                    760:                return;
                    761:        }
                    762:
                    763:        dlog(LOG_DEBUG, "%s intr", sc->sc_dev.dv_xname);
                    764:
                    765:        /*
                    766:         * Some operation completed.  Read status bytes and report errors.
                    767:         * Clear EOF flags here `cause they're set once on specific conditions
                    768:         * below when a command succeeds.
                    769:         * A DSJ of 2 always means keep waiting.  If the command was READ
                    770:         * (and we're in data DMA phase) stop data transfer first.
                    771:         */
                    772:        sc->sc_flags &= ~(MTF_HITEOF | MTF_HITBOF);
                    773:        if ((bp->b_flags & (B_CMD|B_READ)) == B_READ &&
                    774:            !(sc->sc_flags & (MTF_IO | MTF_STATTIMEO | MTF_DSJTIMEO))){
                    775:                cmdbuf[0] = MTE_STOP;
                    776:                (void) hpibsend(sc->sc_hpibno, sc->sc_slave, MTL_ECMD,cmdbuf,1);
                    777:        }
                    778:        switch (mtreaddsj(sc, 0)) {
                    779:            case 0:
                    780:                break;
                    781:
                    782:            case 1:
                    783:                /*
                    784:                 * If we're in the middle of a READ/WRITE and have yet to
                    785:                 * start the data transfer, a DSJ of one should terminate it.
                    786:                 */
                    787:                sc->sc_flags &= ~MTF_IO;
                    788:                break;
                    789:
                    790:            case 2:
                    791:                (void) hpibawait(sc->sc_hpibno);
                    792:                return;
                    793:
                    794:            case -2:
                    795:                /*
                    796:                 * -2 means that the drive failed to respond quickly enough
                    797:                 * to the request for DSJ.  It's probably just "busy" figuring
                    798:                 * it out and will know in a little bit...
                    799:                 */
                    800:                timeout_add(&sc->sc_intr_to, hz >> 5);
                    801:                return;
                    802:
                    803:            default:
                    804:                log(LOG_ERR, "%s intr: can't get drive stat",
                    805:                    sc->sc_dev.dv_xname);
                    806:                goto error;
                    807:        }
                    808:        if (sc->sc_stat1 & (SR1_ERR | SR1_REJECT)) {
                    809:                i = sc->sc_stat4 & SR4_ERCLMASK;
                    810:                log(LOG_ERR, "%s: %s error, retry %d, SR2/3 %x/%x, code %d",
                    811:                        sc->sc_dev.dv_xname, i == SR4_DEVICE ? "device" :
                    812:                        (i == SR4_PROTOCOL ? "protocol" :
                    813:                        (i == SR4_SELFTEST ? "selftest" : "unknown")),
                    814:                        sc->sc_stat4 & SR4_RETRYMASK, sc->sc_stat2,
                    815:                        sc->sc_stat3, sc->sc_stat5);
                    816:
                    817:                if ((bp->b_flags & B_CMD) && bp->b_cmd == MTRESET)
                    818:                        timeout_del(&sc->sc_intr_to);
                    819:                if (sc->sc_stat3 & SR3_POWERUP)
                    820:                        sc->sc_flags &= MTF_OPEN | MTF_EXISTS;
                    821:                goto error;
                    822:        }
                    823:        /*
                    824:         * Report and clear any soft errors.
                    825:         */
                    826:        if (sc->sc_stat1 & SR1_SOFTERR) {
                    827:                log(LOG_WARNING, "%s: soft error, retry %d\n",
                    828:                        sc->sc_dev.dv_xname, sc->sc_stat4 & SR4_RETRYMASK);
                    829:                sc->sc_stat1 &= ~SR1_SOFTERR;
                    830:        }
                    831:        /*
                    832:         * We've initiated a read or write, but haven't actually started to
                    833:         * DMA the data yet.  At this point, the drive's ready.
                    834:         */
                    835:        if (sc->sc_flags & MTF_IO) {
                    836:                sc->sc_flags &= ~MTF_IO;
                    837:                if (hpibustart(sc->sc_hpibno))
                    838:                        mtgo(sc);
                    839:                return;
                    840:        }
                    841:        /*
                    842:         * Check for End Of Tape - we're allowed to hit EOT and then write (or
                    843:         * read) one more record.  If we get here and have not already hit EOT,
                    844:         * return ENOSPC to inform the process that it's hit it.  If we get
                    845:         * here and HAVE already hit EOT, don't allow any more operations that
                    846:         * move the tape forward.
                    847:         */
                    848:        if (sc->sc_stat1 & SR1_EOT) {
                    849:                if (sc->sc_flags & MTF_ATEOT)
                    850:                        sc->sc_flags |= MTF_PASTEOT;
                    851:                else {
                    852:                        bp->b_flags |= B_ERROR;
                    853:                        bp->b_error = ENOSPC;
                    854:                        sc->sc_flags |= MTF_ATEOT;
                    855:                }
                    856:        }
                    857:        /*
                    858:         * If a motion command was being executed, check for Tape Marks.
                    859:         * If we were doing data, make sure we got the right amount, and
                    860:         * check for hitting tape marks on reads.
                    861:         */
                    862:        if (bp->b_flags & B_CMD) {
                    863:                if (sc->sc_stat1 & SR1_EOF) {
                    864:                        if (bp->b_cmd == MTFSR)
                    865:                                sc->sc_flags |= MTF_HITEOF;
                    866:                        if (bp->b_cmd == MTBSR)
                    867:                                sc->sc_flags |= MTF_HITBOF;
                    868:                }
                    869:                if (bp->b_cmd == MTRESET) {
                    870:                        timeout_del(&sc->sc_intr_to);
                    871:                        sc->sc_flags |= MTF_ALIVE;
                    872:                }
                    873:        } else {
                    874:                i = hpibrecv(sc->sc_hpibno, sc->sc_slave, MTT_BCNT, cmdbuf, 2);
                    875:                if (i != 2) {
                    876:                        log(LOG_ERR, "%s intr: can't get xfer length\n",
                    877:                            sc->sc_dev.dv_xname);
                    878:                        goto error;
                    879:                }
                    880:                i = (int) *((u_short *) cmdbuf);
                    881:                if (i <= bp->b_bcount) {
                    882:                        if (i == 0)
                    883:                                sc->sc_flags |= MTF_HITEOF;
                    884:                        bp->b_resid = bp->b_bcount - i;
                    885:                        dlog(LOG_DEBUG, "%s intr: bcount %ld, resid %d",
                    886:                            sc->sc_dev.dv_xname, bp->b_bcount, bp->b_resid);
                    887:                } else {
                    888:                        printf("%s: record (%d) larger than wanted (%ld)\n",
                    889:                                sc->sc_dev.dv_xname, i, bp->b_bcount);
                    890:     error:
                    891:                        sc->sc_flags &= ~MTF_IO;
                    892:                        bp->b_error = EIO;
                    893:                        bp->b_flags |= B_ERROR;
                    894:                }
                    895:        }
                    896:        /*
                    897:         * The operation is completely done.
                    898:         * Let the drive know with an END command.
                    899:         */
                    900:        cmdbuf[0] = MTE_COMPLETE | MTE_IDLE;
                    901:        (void) hpibsend(sc->sc_hpibno, sc->sc_slave, MTL_ECMD, cmdbuf, 1);
                    902:        bp->b_flags &= ~B_CMD;
                    903:        biodone(bp);
                    904:        if ((dp = bp->b_actf))
                    905:                dp->b_actb = bp->b_actb;
                    906:        else
                    907:                sc->sc_tab.b_actb = bp->b_actb;
                    908:        *bp->b_actb = dp;
                    909:        hpibfree(sc->sc_dev.dv_parent, &sc->sc_hq);
                    910: #if 0
                    911:        if (bp /*sc->sc_tab.b_actf*/ == NULL)
                    912: #else
                    913:        if (sc->sc_tab.b_actf == NULL)
                    914: #endif
                    915:                sc->sc_tab.b_active = 0;
                    916:        else
                    917:                mtustart(sc);
                    918: }
                    919:
                    920: int
                    921: mtread(dev, uio, flags)
                    922:        dev_t dev;
                    923:        struct uio *uio;
                    924:        int flags;
                    925: {
                    926:        struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)];
                    927:
                    928:        return(physio(mtstrategy, &sc->sc_bufstore,
                    929:            dev, B_READ, minphys, uio));
                    930: }
                    931:
                    932: int
                    933: mtwrite(dev, uio, flags)
                    934:        dev_t dev;
                    935:        struct uio *uio;
                    936:        int flags;
                    937: {
                    938:        struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)];
                    939:
                    940:        return(physio(mtstrategy, &sc->sc_bufstore,
                    941:            dev, B_WRITE, minphys, uio));
                    942: }
                    943:
                    944: int
                    945: mtioctl(dev, cmd, data, flag, p)
                    946:        dev_t dev;
                    947:        u_long cmd;
                    948:        caddr_t data;
                    949:        int flag;
                    950:        struct proc *p;
                    951: {
                    952:        struct mtop *op;
                    953:        int cnt;
                    954:
                    955:        switch (cmd) {
                    956:            case MTIOCTOP:
                    957:                op = (struct mtop *)data;
                    958:                switch(op->mt_op) {
                    959:                    case MTWEOF:
                    960:                    case MTFSF:
                    961:                    case MTBSR:
                    962:                    case MTBSF:
                    963:                    case MTFSR:
                    964:                        cnt = op->mt_count;
                    965:                        break;
                    966:
                    967:                    case MTOFFL:
                    968:                    case MTREW:
                    969:                    case MTNOP:
                    970:                        cnt = 0;
                    971:                        break;
                    972:
                    973:                    default:
                    974:                        return (EINVAL);
                    975:                }
                    976:                return (mtcommand(dev, op->mt_op, cnt));
                    977:
                    978:            case MTIOCGET:
                    979:                break;
                    980:
                    981:            default:
                    982:                return (EINVAL);
                    983:        }
                    984:        return (0);
                    985: }
                    986:
                    987: /*ARGSUSED*/
                    988: int
                    989: mtdump(dev, blkno, va, size)
                    990:        dev_t dev;
                    991:        daddr64_t blkno;
                    992:        caddr_t va;
                    993:        size_t size;
                    994: {
                    995:        return (ENODEV);
                    996: }

CVSweb