[BACK]Return to st.c CVS log [TXT][DIR] Up to [local] / sys / scsi

Annotation of sys/scsi/st.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: st.c,v 1.75 2007/06/06 17:15:14 deraadt Exp $ */
        !             2: /*     $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *     This product includes software developed by Charles Hannum.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  */
        !            32:
        !            33: /*
        !            34:  * Originally written by Julian Elischer (julian@tfs.com)
        !            35:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
        !            36:  *
        !            37:  * TRW Financial Systems, in accordance with their agreement with Carnegie
        !            38:  * Mellon University, makes this software available to CMU to distribute
        !            39:  * or use in any manner that they see fit as long as this message is kept with
        !            40:  * the software. For this reason TFS also grants any other persons or
        !            41:  * organisations permission to use or modify this software.
        !            42:  *
        !            43:  * TFS supplies this software to be publicly redistributed
        !            44:  * on the understanding that TFS is not responsible for the correct
        !            45:  * functioning of this software in any circumstances.
        !            46:  *
        !            47:  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
        !            48:  * major changes by Julian Elischer (julian@jules.dialix.oz.au) May 1993
        !            49:  */
        !            50:
        !            51: /*
        !            52:  * To do:
        !            53:  * work out some better way of guessing what a good timeout is going
        !            54:  * to be depending on whether we expect to retension or not.
        !            55:  */
        !            56:
        !            57: #include <sys/types.h>
        !            58: #include <sys/param.h>
        !            59: #include <sys/systm.h>
        !            60: #include <sys/timeout.h>
        !            61: #include <sys/fcntl.h>
        !            62: #include <sys/errno.h>
        !            63: #include <sys/ioctl.h>
        !            64: #include <sys/stat.h>
        !            65: #include <sys/malloc.h>
        !            66: #include <sys/buf.h>
        !            67: #include <sys/proc.h>
        !            68: #include <sys/user.h>
        !            69: #include <sys/mtio.h>
        !            70: #include <sys/device.h>
        !            71: #include <sys/conf.h>
        !            72:
        !            73: #include <scsi/scsi_all.h>
        !            74: #include <scsi/scsi_tape.h>
        !            75: #include <scsi/scsiconf.h>
        !            76:
        !            77: /* Defines for device specific stuff */
        !            78: #define DEF_FIXED_BSIZE  512
        !            79: #define        ST_RETRIES      4       /* only on non IO commands */
        !            80:
        !            81: #define STMODE(z)      ( minor(z)       & 0x03)
        !            82: #define STUNIT(z)      ((minor(z) >> 4)       )
        !            83:
        !            84: #define        ST_IO_TIME      (3 * 60 * 1000)         /* 3 minutes */
        !            85: #define        ST_CTL_TIME     (30 * 1000)             /* 30 seconds */
        !            86: #define        ST_SPC_TIME     (4 * 60 * 60 * 1000)    /* 4 hours */
        !            87:
        !            88: /*
        !            89:  * Maximum density code allowed in SCSI spec (SSC2R08f, Section 8.3).
        !            90:  */
        !            91: #define SCSI_MAX_DENSITY_CODE          0xff
        !            92:
        !            93: /*
        !            94:  * Define various devices that we know mis-behave in some way,
        !            95:  * and note how they are bad, so we can correct for them
        !            96:  */
        !            97: struct modes {
        !            98:        u_int quirks;                   /* same definitions as in quirkdata */
        !            99:        int blksize;
        !           100:        u_int8_t density;
        !           101: };
        !           102:
        !           103: struct quirkdata {
        !           104:        u_int quirks;
        !           105: #define        ST_Q_FORCE_BLKSIZE      0x0001
        !           106: #define        ST_Q_SENSE_HELP         0x0002  /* must do READ for good MODE SENSE */
        !           107: #define        ST_Q_IGNORE_LOADS       0x0004
        !           108: #define        ST_Q_BLKSIZE            0x0008  /* variable-block media_blksize > 0 */
        !           109: #define        ST_Q_UNIMODAL           0x0010  /* unimode drive rejects mode select */
        !           110:        struct modes modes;
        !           111: };
        !           112:
        !           113: struct st_quirk_inquiry_pattern {
        !           114:        struct scsi_inquiry_pattern pattern;
        !           115:        struct quirkdata quirkdata;
        !           116: };
        !           117:
        !           118: const struct st_quirk_inquiry_pattern st_quirk_patterns[] = {
        !           119:        {{T_SEQUENTIAL, T_REMOV,
        !           120:         "        ", "                ", "    "}, {0,
        !           121:                {ST_Q_FORCE_BLKSIZE, 512, 0}}},         /* minor 0-3 */
        !           122:        {{T_SEQUENTIAL, T_REMOV,
        !           123:         "TANDBERG", " TDC 3600       ", ""},     {0,
        !           124:                {0, 0, 0}}},                            /* minor 0-3 */
        !           125:        {{T_SEQUENTIAL, T_REMOV,
        !           126:         "TANDBERG", " TDC 3800       ", ""},     {0,
        !           127:                {ST_Q_FORCE_BLKSIZE, 512, 0}}},         /* minor 0-3 */
        !           128:        /*
        !           129:         * At least -005 and -007 need this.  I'll assume they all do unless I
        !           130:         * hear otherwise.  - mycroft, 31MAR1994
        !           131:         */
        !           132:        {{T_SEQUENTIAL, T_REMOV,
        !           133:         "ARCHIVE ", "VIPER 2525 25462", ""},     {0,
        !           134:                {ST_Q_SENSE_HELP, 0, 0}}},              /* minor 0-3 */
        !           135:        /*
        !           136:         * One user reports that this works for his tape drive.  It probably
        !           137:         * needs more work.  - mycroft, 09APR1994
        !           138:         */
        !           139:        {{T_SEQUENTIAL, T_REMOV,
        !           140:         "SANKYO  ", "CP525           ", ""},    {0,
        !           141:                {ST_Q_FORCE_BLKSIZE, 512, 0}}},         /* minor 0-3 */
        !           142:        {{T_SEQUENTIAL, T_REMOV,
        !           143:         "ANRITSU ", "DMT780          ", ""},     {0,
        !           144:                {ST_Q_FORCE_BLKSIZE, 512, 0}}},         /* minor 0-3 */
        !           145:        {{T_SEQUENTIAL, T_REMOV,
        !           146:         "ARCHIVE ", "VIPER 150  21247", ""},     {0,
        !           147:                {0, 0, 0}}},                            /* minor 0-3 */
        !           148:        {{T_SEQUENTIAL, T_REMOV,
        !           149:         "ARCHIVE ", "VIPER 150  21531", ""},     {0,
        !           150:                {ST_Q_SENSE_HELP, 0, 0}}},              /* minor 0-3 */
        !           151:        {{T_SEQUENTIAL, T_REMOV,
        !           152:         "WANGTEK ", "5099ES SCSI", ""},          {0,
        !           153:                {ST_Q_FORCE_BLKSIZE, 512, 0}}},         /* minor 0-3 */
        !           154:        {{T_SEQUENTIAL, T_REMOV,
        !           155:         "WANGTEK ", "5150ES SCSI", ""},          {0,
        !           156:                {ST_Q_FORCE_BLKSIZE, 512, 0}}},         /* minor 0-3 */
        !           157:        {{T_SEQUENTIAL, T_REMOV,
        !           158:         "WANGTEK ", "5525ES SCSI REV7", ""},     {0,
        !           159:                {0, 0, 0}}},                            /* minor 0-3 */
        !           160:        {{T_SEQUENTIAL, T_REMOV,
        !           161:         "WangDAT ", "Model 1300      ", ""},     {0,
        !           162:                {0, 0, 0}}},                            /* minor 0-3 */
        !           163:        {{T_SEQUENTIAL, T_REMOV,
        !           164:         "EXABYTE ", "EXB-8200        ", "263H"}, {0,
        !           165:                {0, 0, 0}}},                            /* minor 0-3 */
        !           166:        {{T_SEQUENTIAL, T_REMOV,
        !           167:         "HP      ", "T4000s          ", ""},     {ST_Q_UNIMODAL,
        !           168:                {0, 0, QIC_3095}}},                     /* minor 0-3 */
        !           169: #if 0
        !           170:        {{T_SEQUENTIAL, T_REMOV,
        !           171:         "EXABYTE ", "EXB-8200        ", ""},     {0,
        !           172:                {0, 0, 0}}},                            /* minor 0-3 */
        !           173: #endif
        !           174:        {{T_SEQUENTIAL, T_REMOV,
        !           175:         "WANGTEK ", "5150ES SCSI FA15\0""01 A", "????"}, {0,
        !           176:                {ST_Q_IGNORE_LOADS, 0, 0}}},            /* minor 0-3 */
        !           177:        {{T_SEQUENTIAL, T_REMOV,
        !           178:         "TEAC    ", "MT-2ST/N50      ", ""},     {ST_Q_IGNORE_LOADS,
        !           179:                {0, 0, 0}}},                            /* minor 0-3 */
        !           180: };
        !           181:
        !           182: #define NOEJECT 0
        !           183: #define EJECT 1
        !           184:
        !           185: #define NOREWIND 0
        !           186: #define DOREWIND 1
        !           187:
        !           188: struct st_softc {
        !           189:        struct device sc_dev;
        !           190: /*--------------------present operating parameters, flags etc.----------------*/
        !           191:        int flags;              /* see below                          */
        !           192:        u_int quirks;           /* quirks for the open mode           */
        !           193:        int blksize;            /* blksize we are using               */
        !           194:        u_int8_t density;       /* present density                    */
        !           195:        short mt_resid;         /* last (short) resid                 */
        !           196:        short mt_erreg;         /* last error (sense key) seen        */
        !           197: /*--------------------device/scsi parameters----------------------------------*/
        !           198:        struct scsi_link *sc_link;      /* our link to the adpter etc.        */
        !           199: /*--------------------parameters reported by the device ----------------------*/
        !           200:        int blkmin;             /* min blk size                       */
        !           201:        int blkmax;             /* max blk size                       */
        !           202:        const struct quirkdata *quirkdata;      /* if we have a rogue entry */
        !           203: /*--------------------parameters reported by the device for this media--------*/
        !           204:        u_int64_t numblks;              /* nominal blocks capacity            */
        !           205:        u_int32_t media_blksize;        /* 0 if not ST_FIXEDBLOCKS            */
        !           206:        u_int32_t media_density;        /* this is what it said when asked    */
        !           207:        int media_fileno;               /* relative to BOT. -1 means unknown. */
        !           208:        int media_blkno;                /* relative to BOF. -1 means unknown. */
        !           209: /*--------------------quirks for the whole drive------------------------------*/
        !           210:        u_int drive_quirks;     /* quirks of this drive               */
        !           211: /*--------------------How we should set up when opening each minor device----*/
        !           212:        struct modes modes;     /* plus more for each mode            */
        !           213:        u_int8_t  modeflags;    /* flags for the modes                */
        !           214: #define DENSITY_SET_BY_USER    0x01
        !           215: #define DENSITY_SET_BY_QUIRK   0x02
        !           216: #define BLKSIZE_SET_BY_USER    0x04
        !           217: #define BLKSIZE_SET_BY_QUIRK   0x08
        !           218: /*--------------------storage for sense data returned by the drive------------*/
        !           219:        struct buf buf_queue;           /* the queue of pending IO operations */
        !           220:        struct timeout sc_timeout;
        !           221: };
        !           222:
        !           223:
        !           224: int    stmatch(struct device *, void *, void *);
        !           225: void   stattach(struct device *, struct device *, void *);
        !           226: void   st_identify_drive(struct st_softc *, struct scsi_inquiry_data *);
        !           227: void   st_loadquirks(struct st_softc *);
        !           228: int    st_mount_tape(dev_t, int);
        !           229: void   st_unmount(struct st_softc *, int, int);
        !           230: int    st_decide_mode(struct st_softc *, int);
        !           231: void   ststart(void *);
        !           232: void   strestart(void *);
        !           233: int    st_read(struct st_softc *, char *, int, int);
        !           234: int    st_read_block_limits(struct st_softc *, int);
        !           235: int    st_mode_sense(struct st_softc *, int);
        !           236: int    st_mode_select(struct st_softc *, int);
        !           237: int    st_space(struct st_softc *, int, u_int, int);
        !           238: int    st_write_filemarks(struct st_softc *, int, int);
        !           239: int    st_check_eod(struct st_softc *, int, int *, int);
        !           240: int    st_load(struct st_softc *, u_int, int);
        !           241: int    st_rewind(struct st_softc *, u_int, int);
        !           242: int    st_interpret_sense(struct scsi_xfer *);
        !           243: int    st_touch_tape(struct st_softc *);
        !           244: int    st_erase(struct st_softc *, int, int);
        !           245:
        !           246: struct cfattach st_ca = {
        !           247:        sizeof(struct st_softc), stmatch, stattach
        !           248: };
        !           249:
        !           250: struct cfdriver st_cd = {
        !           251:        NULL, "st", DV_TAPE
        !           252: };
        !           253:
        !           254: struct scsi_device st_switch = {
        !           255:        st_interpret_sense,
        !           256:        ststart,
        !           257:        NULL,
        !           258:        NULL,
        !           259: };
        !           260:
        !           261: #define        ST_INFO_VALID   0x0001
        !           262: #define        ST_BLOCK_SET    0x0002  /* block size, mode set by ioctl      */
        !           263: #define        ST_WRITTEN      0x0004  /* data have been written, EOD needed */
        !           264: #define        ST_FIXEDBLOCKS  0x0008
        !           265: #define        ST_AT_FILEMARK  0x0010
        !           266: #define        ST_EIO_PENDING  0x0020  /* we couldn't report it then (had data) */
        !           267: #define        ST_READONLY     0x0080  /* st_mode_sense says write protected */
        !           268: #define        ST_FM_WRITTEN   0x0100  /*
        !           269:                                 * EOF file mark written  -- used with
        !           270:                                 * ~ST_WRITTEN to indicate that multiple file
        !           271:                                 * marks have been written
        !           272:                                 */
        !           273: #define        ST_BLANK_READ   0x0200  /* BLANK CHECK encountered already */
        !           274: #define        ST_2FM_AT_EOD   0x0400  /* write 2 file marks at EOD */
        !           275: #define        ST_MOUNTED      0x0800  /* Device is presently mounted */
        !           276: #define        ST_DONTBUFFER   0x1000  /* Disable buffering/caching */
        !           277:
        !           278: #define        ST_PER_ACTION   (ST_AT_FILEMARK | ST_EIO_PENDING | ST_BLANK_READ)
        !           279: #define        ST_PER_MOUNT    (ST_INFO_VALID | ST_BLOCK_SET | ST_WRITTEN | \
        !           280:                         ST_FIXEDBLOCKS | ST_READONLY | ST_FM_WRITTEN | \
        !           281:                         ST_2FM_AT_EOD | ST_PER_ACTION)
        !           282:
        !           283: const struct scsi_inquiry_pattern st_patterns[] = {
        !           284:        {T_SEQUENTIAL, T_REMOV,
        !           285:         "",         "",                 ""},
        !           286: };
        !           287:
        !           288: int
        !           289: stmatch(parent, match, aux)
        !           290:        struct device *parent;
        !           291:        void *match, *aux;
        !           292: {
        !           293:        struct scsi_attach_args *sa = aux;
        !           294:        int priority;
        !           295:
        !           296:        (void)scsi_inqmatch(sa->sa_inqbuf,
        !           297:            st_patterns, sizeof(st_patterns)/sizeof(st_patterns[0]),
        !           298:            sizeof(st_patterns[0]), &priority);
        !           299:        return (priority);
        !           300: }
        !           301:
        !           302: /*
        !           303:  * The routine called by the low level scsi routine when it discovers
        !           304:  * A device suitable for this driver
        !           305:  */
        !           306: void
        !           307: stattach(parent, self, aux)
        !           308:        struct device *parent, *self;
        !           309:        void *aux;
        !           310: {
        !           311:        struct st_softc *st = (void *)self;
        !           312:        struct scsi_attach_args *sa = aux;
        !           313:        struct scsi_link *sc_link = sa->sa_sc_link;
        !           314:
        !           315:        SC_DEBUG(sc_link, SDEV_DB2, ("stattach:\n"));
        !           316:
        !           317:        /*
        !           318:         * Store information needed to contact our base driver
        !           319:         */
        !           320:        st->sc_link = sc_link;
        !           321:        sc_link->device = &st_switch;
        !           322:        sc_link->device_softc = st;
        !           323:
        !           324:        /*
        !           325:         * Check if the drive is a known criminal and take
        !           326:         * Any steps needed to bring it into line
        !           327:         */
        !           328:        st_identify_drive(st, sa->sa_inqbuf);
        !           329:        printf("\n");
        !           330:
        !           331:        timeout_set(&st->sc_timeout, strestart, st);
        !           332:
        !           333:        /*
        !           334:         * Set up the buf queue for this device
        !           335:         */
        !           336:        st->buf_queue.b_active = 0;
        !           337:        st->buf_queue.b_actf = 0;
        !           338:        st->buf_queue.b_actb = &st->buf_queue.b_actf;
        !           339:
        !           340:        /* Start up with media position unknown. */
        !           341:        st->media_fileno = -1;
        !           342:        st->media_blkno = -1;
        !           343:
        !           344:        /*
        !           345:         * Reset the media loaded flag, sometimes the data
        !           346:         * acquired at boot time is not quite accurate.  This
        !           347:         * will be checked again at the first open.
        !           348:         */
        !           349:        sc_link->flags &= ~SDEV_MEDIA_LOADED;
        !           350: }
        !           351:
        !           352: /*
        !           353:  * Use the inquiry routine in 'scsi_base' to get drive info so we can
        !           354:  * Further tailor our behaviour.
        !           355:  */
        !           356: void
        !           357: st_identify_drive(st, inqbuf)
        !           358:        struct st_softc *st;
        !           359:        struct scsi_inquiry_data *inqbuf;
        !           360: {
        !           361:        const struct st_quirk_inquiry_pattern *finger;
        !           362:        int priority;
        !           363:
        !           364:        finger = (const struct st_quirk_inquiry_pattern *)scsi_inqmatch(inqbuf,
        !           365:            st_quirk_patterns,
        !           366:            sizeof(st_quirk_patterns)/sizeof(st_quirk_patterns[0]),
        !           367:            sizeof(st_quirk_patterns[0]), &priority);
        !           368:        if (priority != 0) {
        !           369:                st->quirkdata = &finger->quirkdata;
        !           370:                st->drive_quirks = finger->quirkdata.quirks;
        !           371:                st->quirks = finger->quirkdata.quirks;  /* start value */
        !           372:                st_loadquirks(st);
        !           373:        }
        !           374: }
        !           375:
        !           376: /*
        !           377:  * initialise the subdevices to the default (QUIRK) state.
        !           378:  * this will remove any setting made by the system operator or previous
        !           379:  * operations.
        !           380:  */
        !           381: void
        !           382: st_loadquirks(st)
        !           383:        struct st_softc *st;
        !           384: {
        !           385:        const struct    modes *mode;
        !           386:        struct  modes *mode2;
        !           387:
        !           388:        mode = &st->quirkdata->modes;
        !           389:        mode2 = &st->modes;
        !           390:        bzero(mode2, sizeof(struct modes));
        !           391:        st->modeflags &= ~(BLKSIZE_SET_BY_QUIRK |
        !           392:            DENSITY_SET_BY_QUIRK | BLKSIZE_SET_BY_USER |
        !           393:            DENSITY_SET_BY_USER);
        !           394:        if ((mode->quirks | st->drive_quirks) & ST_Q_FORCE_BLKSIZE) {
        !           395:                mode2->blksize = mode->blksize;
        !           396:                st->modeflags |= BLKSIZE_SET_BY_QUIRK;
        !           397:        }
        !           398:        if (mode->density) {
        !           399:                mode2->density = mode->density;
        !           400:                st->modeflags |= DENSITY_SET_BY_QUIRK;
        !           401:        }
        !           402: }
        !           403:
        !           404: /*
        !           405:  * open the device.
        !           406:  */
        !           407: int
        !           408: stopen(dev, flags, fmt, p)
        !           409:        dev_t dev;
        !           410:        int flags;
        !           411:        int fmt;
        !           412:        struct proc *p;
        !           413: {
        !           414:        struct scsi_link *sc_link;
        !           415:        struct st_softc *st;
        !           416:        int error = 0, unit;
        !           417:
        !           418:        unit = STUNIT(dev);
        !           419:        if (unit >= st_cd.cd_ndevs)
        !           420:                return (ENXIO);
        !           421:        st = st_cd.cd_devs[unit];
        !           422:        if (!st)
        !           423:                return (ENXIO);
        !           424:
        !           425:        sc_link = st->sc_link;
        !           426:
        !           427:        SC_DEBUG(sc_link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
        !           428:            unit, st_cd.cd_ndevs));
        !           429:
        !           430:        /*
        !           431:         * Tape is an exclusive media. Only one open at a time.
        !           432:         */
        !           433:        if (sc_link->flags & SDEV_OPEN) {
        !           434:                SC_DEBUG(sc_link, SDEV_DB4, ("already open\n"));
        !           435:                return (EBUSY);
        !           436:        }
        !           437:
        !           438:        /* Use st_interpret_sense() now. */
        !           439:        sc_link->flags |= SDEV_OPEN;
        !           440:
        !           441:        /*
        !           442:         * Check the unit status. This clears any outstanding errors and
        !           443:         * will ensure that media is present.
        !           444:         */
        !           445:        error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
        !           446:            SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE |
        !           447:            SCSI_IGNORE_ILLEGAL_REQUEST);
        !           448:
        !           449:        /*
        !           450:         * Terminate any exising mount session if there is no media.
        !           451:         */
        !           452:        if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0)
        !           453:                st_unmount(st, NOEJECT, DOREWIND);
        !           454:
        !           455:        if (error) {
        !           456:                sc_link->flags &= ~SDEV_OPEN;
        !           457:                return (error);
        !           458:        }
        !           459:
        !           460:        if ((st->flags & ST_MOUNTED) == 0) {
        !           461:                error = st_mount_tape(dev, flags);
        !           462:                if (error) {
        !           463:                        sc_link->flags &= ~SDEV_OPEN;
        !           464:                        return (error);
        !           465:                }
        !           466:        }
        !           467:
        !           468:        /*
        !           469:         * Make sure that a tape opened in write-only mode will have
        !           470:         * file marks written on it when closed, even if not written to.
        !           471:         * This is for SUN compatibility
        !           472:         */
        !           473:        if ((flags & O_ACCMODE) == FWRITE)
        !           474:                st->flags |= ST_WRITTEN;
        !           475:
        !           476:        SC_DEBUG(sc_link, SDEV_DB2, ("open complete\n"));
        !           477:        return (0);
        !           478: }
        !           479:
        !           480: /*
        !           481:  * close the device.. only called if we are the LAST
        !           482:  * occurence of an open device
        !           483:  */
        !           484: int
        !           485: stclose(dev, flags, mode, p)
        !           486:        dev_t dev;
        !           487:        int flags;
        !           488:        int mode;
        !           489:        struct proc *p;
        !           490: {
        !           491:        struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];
        !           492:
        !           493:        SC_DEBUG(st->sc_link, SDEV_DB1, ("closing\n"));
        !           494:        if ((st->flags & (ST_WRITTEN | ST_FM_WRITTEN)) == ST_WRITTEN)
        !           495:                st_write_filemarks(st, 1, 0);
        !           496:        switch (STMODE(dev)) {
        !           497:        case 0:         /* normal */
        !           498:                st_unmount(st, NOEJECT, DOREWIND);
        !           499:                break;
        !           500:        case 3:         /* eject, no rewind */
        !           501:                st_unmount(st, EJECT, NOREWIND);
        !           502:                break;
        !           503:        case 1:         /* no rewind */
        !           504:                /* leave mounted unless media seems to have been removed */
        !           505:                if (!(st->sc_link->flags & SDEV_MEDIA_LOADED))
        !           506:                        st_unmount(st, NOEJECT, NOREWIND);
        !           507:                break;
        !           508:        case 2:         /* rewind, eject */
        !           509:                st_unmount(st, EJECT, DOREWIND);
        !           510:                break;
        !           511:        }
        !           512:        st->sc_link->flags &= ~SDEV_OPEN;
        !           513:        timeout_del(&st->sc_timeout);
        !           514:
        !           515:        return 0;
        !           516: }
        !           517:
        !           518: /*
        !           519:  * Start a new mount session.
        !           520:  * Copy in all the default parameters from the selected device mode.
        !           521:  * and try guess any that seem to be defaulted.
        !           522:  */
        !           523: int
        !           524: st_mount_tape(dev, flags)
        !           525:        dev_t dev;
        !           526:        int flags;
        !           527: {
        !           528:        int unit;
        !           529:        u_int mode;
        !           530:        struct st_softc *st;
        !           531:        struct scsi_link *sc_link;
        !           532:        int error = 0;
        !           533:
        !           534:        unit = STUNIT(dev);
        !           535:        mode = STMODE(dev);
        !           536:        st = st_cd.cd_devs[unit];
        !           537:        sc_link = st->sc_link;
        !           538:
        !           539:        if (st->flags & ST_MOUNTED)
        !           540:                return 0;
        !           541:
        !           542:        SC_DEBUG(sc_link, SDEV_DB1, ("mounting\n"));
        !           543:        st->quirks = st->drive_quirks | st->modes.quirks;
        !           544:        /*
        !           545:         * If the media is new, then make sure we give it a chance to
        !           546:         * to do a 'load' instruction.  (We assume it is new.)
        !           547:         */
        !           548:        if ((error = st_load(st, LD_LOAD, 0)) != 0)
        !           549:                return error;
        !           550:        /*
        !           551:         * Throw another dummy instruction to catch
        !           552:         * 'Unit attention' errors. Some drives appear to give
        !           553:         * these after doing a Load instruction.
        !           554:         * (noteably some DAT drives)
        !           555:         */
        !           556:        /* XXX */
        !           557:        scsi_test_unit_ready(sc_link, TEST_READY_RETRIES, SCSI_SILENT);
        !           558:
        !           559:        /*
        !           560:         * Some devices can't tell you much until they have been
        !           561:         * asked to look at the media. This quirk does this.
        !           562:         */
        !           563:        if (st->quirks & ST_Q_SENSE_HELP)
        !           564:                if ((error = st_touch_tape(st)) != 0)
        !           565:                        return error;
        !           566:        /*
        !           567:         * Load the physical device parameters
        !           568:         * loads: blkmin, blkmax
        !           569:         */
        !           570:        if (!(sc_link->flags & SDEV_ATAPI) &&
        !           571:            (error = st_read_block_limits(st, 0)) != 0) {
        !           572:                return error;
        !           573:        }
        !           574:
        !           575:        /*
        !           576:         * Load the media dependent parameters
        !           577:         * includes: media_blksize,media_density,numblks
        !           578:         * As we have a tape in, it should be reflected here.
        !           579:         * If not you may need the "quirk" above.
        !           580:         */
        !           581:        if ((error = st_mode_sense(st, 0)) != 0)
        !           582:                return error;
        !           583:
        !           584:        /*
        !           585:         * If we have gained a permanent density from somewhere,
        !           586:         * then use it in preference to the one supplied by
        !           587:         * default by the driver.
        !           588:         */
        !           589:        if (st->modeflags & (DENSITY_SET_BY_QUIRK | DENSITY_SET_BY_USER))
        !           590:                st->density = st->modes.density;
        !           591:        else
        !           592:                st->density = st->media_density;
        !           593:        /*
        !           594:         * If we have gained a permanent blocksize
        !           595:         * then use it in preference to the one supplied by
        !           596:         * default by the driver.
        !           597:         */
        !           598:        st->flags &= ~ST_FIXEDBLOCKS;
        !           599:        if (st->modeflags & (BLKSIZE_SET_BY_QUIRK | BLKSIZE_SET_BY_USER)) {
        !           600:                st->blksize = st->modes.blksize;
        !           601:                if (st->blksize)
        !           602:                        st->flags |= ST_FIXEDBLOCKS;
        !           603:        } else {
        !           604:                if ((error = st_decide_mode(st, FALSE)) != 0)
        !           605:                        return error;
        !           606:        }
        !           607:        if ((error = st_mode_select(st, 0)) != 0) {
        !           608:                printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
        !           609:                return error;
        !           610:        }
        !           611:        scsi_prevent(sc_link, PR_PREVENT,
        !           612:            SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
        !           613:        st->flags |= ST_MOUNTED;
        !           614:        sc_link->flags |= SDEV_MEDIA_LOADED;    /* move earlier? */
        !           615:
        !           616:        return 0;
        !           617: }
        !           618:
        !           619: /*
        !           620:  * End the present mount session.
        !           621:  * Rewind, and optionally eject the tape.
        !           622:  * Reset various flags to indicate that all new
        !           623:  * operations require another mount operation
        !           624:  */
        !           625: void
        !           626: st_unmount(st, eject, rewind)
        !           627:        struct st_softc *st;
        !           628:        int eject, rewind;
        !           629: {
        !           630:        struct scsi_link *sc_link = st->sc_link;
        !           631:        int nmarks;
        !           632:
        !           633:        st->media_fileno = -1;
        !           634:        st->media_blkno = -1;
        !           635:
        !           636:        if (!(st->flags & ST_MOUNTED))
        !           637:                return;
        !           638:        SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n"));
        !           639:        st_check_eod(st, FALSE, &nmarks, SCSI_IGNORE_NOT_READY);
        !           640:        if (rewind)
        !           641:                st_rewind(st, 0, SCSI_IGNORE_NOT_READY);
        !           642:        scsi_prevent(sc_link, PR_ALLOW,
        !           643:            SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
        !           644:        if (eject)
        !           645:                st_load(st, LD_UNLOAD, SCSI_IGNORE_NOT_READY);
        !           646:        st->flags &= ~ST_MOUNTED;
        !           647:        sc_link->flags &= ~SDEV_MEDIA_LOADED;
        !           648: }
        !           649:
        !           650: /*
        !           651:  * Given all we know about the device, media, mode, 'quirks' and
        !           652:  * initial operation, make a decision as to how we should be set
        !           653:  * to run (regarding blocking and EOD marks)
        !           654:  */
        !           655: int
        !           656: st_decide_mode(st, first_read)
        !           657:        struct st_softc *st;
        !           658:        int     first_read;
        !           659: {
        !           660:        struct scsi_link *sc_link = st->sc_link;
        !           661:
        !           662:        SC_DEBUG(sc_link, SDEV_DB2, ("starting block mode decision\n"));
        !           663:
        !           664:        /* ATAPI tapes are always fixed blocksize. */
        !           665:        if (sc_link->flags & SDEV_ATAPI) {
        !           666:                st->flags |= ST_FIXEDBLOCKS;
        !           667:                if (st->media_blksize > 0)
        !           668:                        st->blksize = st->media_blksize;
        !           669:                else
        !           670:                        st->blksize = DEF_FIXED_BSIZE;
        !           671:                goto done;
        !           672:        }
        !           673:
        !           674:        /*
        !           675:         * If the drive can only handle fixed-length blocks and only at
        !           676:         * one size, perhaps we should just do that.
        !           677:         */
        !           678:        if (st->blkmin && (st->blkmin == st->blkmax)) {
        !           679:                st->flags |= ST_FIXEDBLOCKS;
        !           680:                st->blksize = st->blkmin;
        !           681:                SC_DEBUG(sc_link, SDEV_DB3,
        !           682:                    ("blkmin == blkmax of %d\n", st->blkmin));
        !           683:                goto done;
        !           684:        }
        !           685:        /*
        !           686:         * If the tape density mandates (or even suggests) use of fixed
        !           687:         * or variable-length blocks, comply.
        !           688:         */
        !           689:        switch (st->density) {
        !           690:        case HALFINCH_800:
        !           691:        case HALFINCH_1600:
        !           692:        case HALFINCH_6250:
        !           693:        case DDS:
        !           694:                st->flags &= ~ST_FIXEDBLOCKS;
        !           695:                st->blksize = 0;
        !           696:                SC_DEBUG(sc_link, SDEV_DB3, ("density specified variable\n"));
        !           697:                goto done;
        !           698:        case QIC_11:
        !           699:        case QIC_24:
        !           700:        case QIC_120:
        !           701:        case QIC_150:
        !           702:        case QIC_525:
        !           703:        case QIC_1320:
        !           704:                st->flags |= ST_FIXEDBLOCKS;
        !           705:                if (st->media_blksize > 0)
        !           706:                        st->blksize = st->media_blksize;
        !           707:                else
        !           708:                        st->blksize = DEF_FIXED_BSIZE;
        !           709:                SC_DEBUG(sc_link, SDEV_DB3, ("density specified fixed\n"));
        !           710:                goto done;
        !           711:        }
        !           712:        /*
        !           713:         * If we're about to read the tape, perhaps we should choose
        !           714:         * fixed or variable-length blocks and block size according to
        !           715:         * what the drive found on the tape.
        !           716:         */
        !           717:        if (first_read &&
        !           718:            (!(st->quirks & ST_Q_BLKSIZE) || (st->media_blksize == 0) ||
        !           719:            (st->media_blksize == DEF_FIXED_BSIZE) ||
        !           720:            (st->media_blksize == 1024))) {
        !           721:                if (st->media_blksize > 0)
        !           722:                        st->flags |= ST_FIXEDBLOCKS;
        !           723:                else
        !           724:                        st->flags &= ~ST_FIXEDBLOCKS;
        !           725:                st->blksize = st->media_blksize;
        !           726:                SC_DEBUG(sc_link, SDEV_DB3,
        !           727:                    ("Used media_blksize of %d\n", st->media_blksize));
        !           728:                goto done;
        !           729:        }
        !           730:        /*
        !           731:         * We're getting no hints from any direction.  Choose variable-
        !           732:         * length blocks arbitrarily.
        !           733:         */
        !           734:        st->flags &= ~ST_FIXEDBLOCKS;
        !           735:        st->blksize = 0;
        !           736:        SC_DEBUG(sc_link, SDEV_DB3,
        !           737:            ("Give up and default to variable mode\n"));
        !           738:
        !           739: done:
        !           740:        /*
        !           741:         * Decide whether or not to write two file marks to signify end-
        !           742:         * of-data.  Make the decision as a function of density.  If
        !           743:         * the decision is not to use a second file mark, the SCSI BLANK
        !           744:         * CHECK condition code will be recognized as end-of-data when
        !           745:         * first read.
        !           746:         * (I think this should be a by-product of fixed/variable..julian)
        !           747:         */
        !           748:        switch (st->density) {
        !           749: /*      case 8 mm:   What is the SCSI density code for 8 mm, anyway? */
        !           750:        case QIC_11:
        !           751:        case QIC_24:
        !           752:        case QIC_120:
        !           753:        case QIC_150:
        !           754:        case QIC_525:
        !           755:        case QIC_1320:
        !           756:                st->flags &= ~ST_2FM_AT_EOD;
        !           757:                break;
        !           758:        default:
        !           759:                st->flags |= ST_2FM_AT_EOD;
        !           760:        }
        !           761:        return 0;
        !           762: }
        !           763:
        !           764: /*
        !           765:  * Actually translate the requested transfer into
        !           766:  * one the physical driver can understand
        !           767:  * The transfer is described by a buf and will include
        !           768:  * only one physical transfer.
        !           769:  */
        !           770: void
        !           771: ststrategy(bp)
        !           772:        struct buf *bp;
        !           773: {
        !           774:        struct st_softc *st = st_cd.cd_devs[STUNIT(bp->b_dev)];
        !           775:        struct buf *dp;
        !           776:        int s;
        !           777:
        !           778:        SC_DEBUG(st->sc_link, SDEV_DB2, ("ststrategy: %ld bytes @ blk %d\n",
        !           779:            bp->b_bcount, bp->b_blkno));
        !           780:        /*
        !           781:         * If it's a null transfer, return immediately.
        !           782:         */
        !           783:        if (bp->b_bcount == 0)
        !           784:                goto done;
        !           785:        /*
        !           786:         * Odd sized request on fixed drives are verboten
        !           787:         */
        !           788:        if (st->flags & ST_FIXEDBLOCKS) {
        !           789:                if (bp->b_bcount % st->blksize) {
        !           790:                        printf("%s: bad request, must be multiple of %d\n",
        !           791:                            st->sc_dev.dv_xname, st->blksize);
        !           792:                        bp->b_error = EIO;
        !           793:                        goto bad;
        !           794:                }
        !           795:        }
        !           796:        /*
        !           797:         * as are out-of-range requests on variable drives.
        !           798:         */
        !           799:        else if (bp->b_bcount < st->blkmin ||
        !           800:                 (st->blkmax && bp->b_bcount > st->blkmax)) {
        !           801:                printf("%s: bad request, must be between %d and %d\n",
        !           802:                    st->sc_dev.dv_xname, st->blkmin, st->blkmax);
        !           803:                bp->b_error = EIO;
        !           804:                goto bad;
        !           805:        }
        !           806:        s = splbio();
        !           807:
        !           808:        /*
        !           809:         * Place it in the queue of activities for this tape
        !           810:         * at the end (a bit silly because we only have on user..
        !           811:         * (but it could fork()))
        !           812:         */
        !           813:        dp = &st->buf_queue;
        !           814:        bp->b_actf = NULL;
        !           815:        bp->b_actb = dp->b_actb;
        !           816:        *dp->b_actb = bp;
        !           817:        dp->b_actb = &bp->b_actf;
        !           818:
        !           819:        /*
        !           820:         * Tell the device to get going on the transfer if it's
        !           821:         * not doing anything, otherwise just wait for completion
        !           822:         * (All a bit silly if we're only allowing 1 open but..)
        !           823:         */
        !           824:        ststart(st);
        !           825:
        !           826:        splx(s);
        !           827:        return;
        !           828: bad:
        !           829:        bp->b_flags |= B_ERROR;
        !           830: done:
        !           831:        /*
        !           832:         * Correctly set the buf to indicate a completed xfer
        !           833:         */
        !           834:        bp->b_resid = bp->b_bcount;
        !           835:        s = splbio();
        !           836:        biodone(bp);
        !           837:        splx(s);
        !           838: }
        !           839:
        !           840: /*
        !           841:  * ststart looks to see if there is a buf waiting for the device
        !           842:  * and that the device is not already busy. If both are true,
        !           843:  * It dequeues the buf and creates a scsi command to perform the
        !           844:  * transfer required. The transfer request will call scsi_done
        !           845:  * on completion, which will in turn call this routine again
        !           846:  * so that the next queued transfer is performed.
        !           847:  * The bufs are queued by the strategy routine (ststrategy)
        !           848:  *
        !           849:  * This routine is also called after other non-queued requests
        !           850:  * have been made of the scsi driver, to ensure that the queue
        !           851:  * continues to be drained.
        !           852:  * ststart() is called at splbio from ststrategy, strestart and scsi_done()
        !           853:  */
        !           854: void
        !           855: ststart(v)
        !           856:        void *v;
        !           857: {
        !           858:        struct st_softc *st = v;
        !           859:        struct scsi_link *sc_link = st->sc_link;
        !           860:        struct buf *bp, *dp;
        !           861:        struct scsi_rw_tape cmd;
        !           862:        int flags, error;
        !           863:
        !           864:        SC_DEBUG(sc_link, SDEV_DB2, ("ststart\n"));
        !           865:
        !           866:        splassert(IPL_BIO);
        !           867:
        !           868:        /*
        !           869:         * See if there is a buf to do and we are not already
        !           870:         * doing one
        !           871:         */
        !           872:        while (sc_link->openings > 0) {
        !           873:                /* if a special awaits, let it proceed first */
        !           874:                if (sc_link->flags & SDEV_WAITING) {
        !           875:                        sc_link->flags &= ~SDEV_WAITING;
        !           876:                        wakeup((caddr_t)sc_link);
        !           877:                        return;
        !           878:                }
        !           879:
        !           880:                dp = &st->buf_queue;
        !           881:                if ((bp = dp->b_actf) == NULL)
        !           882:                        return;
        !           883:                if ((dp = bp->b_actf) != NULL)
        !           884:                        dp->b_actb = bp->b_actb;
        !           885:                else
        !           886:                        st->buf_queue.b_actb = bp->b_actb;
        !           887:                *bp->b_actb = dp;
        !           888:
        !           889:                /*
        !           890:                 * if the device has been unmounted by the user
        !           891:                 * then throw away all requests until done
        !           892:                 */
        !           893:                if (!(st->flags & ST_MOUNTED) ||
        !           894:                    !(sc_link->flags & SDEV_MEDIA_LOADED)) {
        !           895:                        /* make sure that one implies the other.. */
        !           896:                        sc_link->flags &= ~SDEV_MEDIA_LOADED;
        !           897:                        bp->b_flags |= B_ERROR;
        !           898:                        bp->b_resid = bp->b_bcount;
        !           899:                        bp->b_error = EIO;
        !           900:                        biodone(bp);
        !           901:                        continue;
        !           902:                }
        !           903:                /*
        !           904:                 * only FIXEDBLOCK devices have pending operations
        !           905:                 */
        !           906:                if (st->flags & ST_FIXEDBLOCKS) {
        !           907:                        /*
        !           908:                         * If we are at a filemark but have not reported it yet
        !           909:                         * then we should report it now
        !           910:                         */
        !           911:                        if (st->flags & ST_AT_FILEMARK) {
        !           912:                                if ((bp->b_flags & B_READ) == B_WRITE) {
        !           913:                                        /*
        !           914:                                         * Handling of ST_AT_FILEMARK in
        !           915:                                         * st_space will fill in the right file
        !           916:                                         * mark count.
        !           917:                                         * Back up over filemark
        !           918:                                         */
        !           919:                                        if (st_space(st, 0, SP_FILEMARKS, 0)) {
        !           920:                                                bp->b_flags |= B_ERROR;
        !           921:                                                bp->b_resid = bp->b_bcount;
        !           922:                                                bp->b_error = EIO;
        !           923:                                                biodone(bp);
        !           924:                                                continue;
        !           925:                                        }
        !           926:                                } else {
        !           927:                                        bp->b_resid = bp->b_bcount;
        !           928:                                        bp->b_error = 0;
        !           929:                                        bp->b_flags &= ~B_ERROR;
        !           930:                                        st->flags &= ~ST_AT_FILEMARK;
        !           931:                                        biodone(bp);
        !           932:                                        continue;       /* seek more work */
        !           933:                                }
        !           934:                        }
        !           935:                        /*
        !           936:                         * If we are at EIO (e.g. EOM) but have not reported it
        !           937:                         * yet then we should report it now
        !           938:                         */
        !           939:                        if (st->flags & ST_EIO_PENDING) {
        !           940:                                bp->b_resid = bp->b_bcount;
        !           941:                                bp->b_error = EIO;
        !           942:                                bp->b_flags |= B_ERROR;
        !           943:                                st->flags &= ~ST_EIO_PENDING;
        !           944:                                biodone(bp);
        !           945:                                continue;       /* seek more work */
        !           946:                        }
        !           947:                }
        !           948:
        !           949:                /*
        !           950:                 *  Fill out the scsi command
        !           951:                 */
        !           952:                bzero(&cmd, sizeof(cmd));
        !           953:                if ((bp->b_flags & B_READ) == B_WRITE) {
        !           954:                        cmd.opcode = WRITE;
        !           955:                        st->flags &= ~ST_FM_WRITTEN;
        !           956:                        st->flags |= ST_WRITTEN;
        !           957:                        flags = SCSI_DATA_OUT;
        !           958:                } else {
        !           959:                        cmd.opcode = READ;
        !           960:                        flags = SCSI_DATA_IN;
        !           961:                }
        !           962:
        !           963:                /*
        !           964:                 * Handle "fixed-block-mode" tape drives by using the
        !           965:                 * block count instead of the length.
        !           966:                 */
        !           967:                if (st->flags & ST_FIXEDBLOCKS) {
        !           968:                        cmd.byte2 |= SRW_FIXED;
        !           969:                        _lto3b(bp->b_bcount / st->blksize, cmd.len);
        !           970:                } else
        !           971:                        _lto3b(bp->b_bcount, cmd.len);
        !           972:
        !           973:                if (st->media_blkno != -1) {
        !           974:                        /* Update block count now, errors will set it to -1. */
        !           975:                        if (st->flags & ST_FIXEDBLOCKS)
        !           976:                                st->media_blkno += _3btol(cmd.len);
        !           977:                        else if (cmd.len != 0)
        !           978:                                st->media_blkno++;
        !           979:                }
        !           980:
        !           981:                /*
        !           982:                 * go ask the adapter to do all this for us
        !           983:                 */
        !           984:                error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
        !           985:                    sizeof(cmd), (u_char *) bp->b_data, bp->b_bcount, 0,
        !           986:                    ST_IO_TIME, bp, flags | SCSI_NOSLEEP);
        !           987:                switch (error) {
        !           988:                case 0:
        !           989:                        timeout_del(&st->sc_timeout);
        !           990:                        break;
        !           991:                case EAGAIN:
        !           992:                        /*
        !           993:                         * The device can't start another i/o. Try again later.
        !           994:                         */
        !           995:                        dp->b_actf = bp;
        !           996:                        timeout_add(&st->sc_timeout, 1);
        !           997:                        return;
        !           998:                default:
        !           999:                        printf("%s: not queued\n", st->sc_dev.dv_xname);
        !          1000:                        break;
        !          1001:                }
        !          1002:        } /* go back and see if we can cram more work in.. */
        !          1003: }
        !          1004:
        !          1005: void
        !          1006: strestart(v)
        !          1007:        void *v;
        !          1008: {
        !          1009:        int s;
        !          1010:
        !          1011:        s = splbio();
        !          1012:        ststart(v);
        !          1013:        splx(s);
        !          1014: }
        !          1015:
        !          1016: int
        !          1017: stread(dev, uio, iomode)
        !          1018:        dev_t dev;
        !          1019:        struct uio *uio;
        !          1020:        int iomode;
        !          1021: {
        !          1022:        struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];
        !          1023:
        !          1024:        return (physio(ststrategy, NULL, dev, B_READ,
        !          1025:            st->sc_link->adapter->scsi_minphys, uio));
        !          1026: }
        !          1027:
        !          1028: int
        !          1029: stwrite(dev, uio, iomode)
        !          1030:        dev_t dev;
        !          1031:        struct uio *uio;
        !          1032:        int iomode;
        !          1033: {
        !          1034:        struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];
        !          1035:
        !          1036:        return (physio(ststrategy, NULL, dev, B_WRITE,
        !          1037:            st->sc_link->adapter->scsi_minphys, uio));
        !          1038: }
        !          1039:
        !          1040: /*
        !          1041:  * Perform special action on behalf of the user;
        !          1042:  * knows about the internals of this device
        !          1043:  */
        !          1044: int
        !          1045: stioctl(dev, cmd, arg, flag, p)
        !          1046:        dev_t dev;
        !          1047:        u_long cmd;
        !          1048:        caddr_t arg;
        !          1049:        int flag;
        !          1050:        struct proc *p;
        !          1051: {
        !          1052:        int error = 0;
        !          1053:        int unit;
        !          1054:        int nmarks;
        !          1055:        int flags;
        !          1056:        struct st_softc *st;
        !          1057:        int hold_blksize;
        !          1058:        u_int8_t hold_density;
        !          1059:        struct mtop *mt = (struct mtop *) arg;
        !          1060:        int number;
        !          1061:
        !          1062:        /*
        !          1063:         * Find the device that the user is talking about
        !          1064:         */
        !          1065:        flags = 0;              /* give error messages, act on errors etc. */
        !          1066:        unit = STUNIT(dev);
        !          1067:        st = st_cd.cd_devs[unit];
        !          1068:        hold_blksize = st->blksize;
        !          1069:        hold_density = st->density;
        !          1070:
        !          1071:        switch (cmd) {
        !          1072:
        !          1073:        case MTIOCGET: {
        !          1074:                struct mtget *g = (struct mtget *) arg;
        !          1075:
        !          1076:                /*
        !          1077:                 * (to get the current state of READONLY)
        !          1078:                 */
        !          1079:                error = st_mode_sense(st, SCSI_SILENT);
        !          1080:                if (error)
        !          1081:                        break;
        !          1082:
        !          1083:                SC_DEBUG(st->sc_link, SDEV_DB1, ("[ioctl: get status]\n"));
        !          1084:                bzero(g, sizeof(struct mtget));
        !          1085:                g->mt_type = 0x7;       /* Ultrix compat *//*? */
        !          1086:                g->mt_blksiz = st->blksize;
        !          1087:                g->mt_density = st->density;
        !          1088:                g->mt_mblksiz = st->modes.blksize;
        !          1089:                g->mt_mdensity = st->modes.density;
        !          1090:                if (st->flags & ST_READONLY)
        !          1091:                        g->mt_dsreg |= MT_DS_RDONLY;
        !          1092:                if (st->flags & ST_MOUNTED)
        !          1093:                        g->mt_dsreg |= MT_DS_MOUNTED;
        !          1094:                g->mt_resid = st->mt_resid;
        !          1095:                g->mt_erreg = st->mt_erreg;
        !          1096:                g->mt_fileno = st->media_fileno;
        !          1097:                g->mt_blkno = st->media_blkno;
        !          1098:                /*
        !          1099:                 * clear latched errors.
        !          1100:                 */
        !          1101:                st->mt_resid = 0;
        !          1102:                st->mt_erreg = 0;
        !          1103:                break;
        !          1104:        }
        !          1105:        case MTIOCTOP: {
        !          1106:
        !          1107:                SC_DEBUG(st->sc_link, SDEV_DB1,
        !          1108:                    ("[ioctl: op=0x%x count=0x%x]\n", mt->mt_op, mt->mt_count));
        !          1109:
        !          1110:                number = mt->mt_count;
        !          1111:                switch (mt->mt_op) {
        !          1112:                case MTWEOF:    /* write an end-of-file record */
        !          1113:                        error = st_write_filemarks(st, number, flags);
        !          1114:                        break;
        !          1115:                case MTBSF:     /* backward space file */
        !          1116:                        number = -number;
        !          1117:                case MTFSF:     /* forward space file */
        !          1118:                        error = st_check_eod(st, FALSE, &nmarks, flags);
        !          1119:                        if (!error)
        !          1120:                                error = st_space(st, number - nmarks,
        !          1121:                                    SP_FILEMARKS, flags);
        !          1122:                        break;
        !          1123:                case MTBSR:     /* backward space record */
        !          1124:                        number = -number;
        !          1125:                case MTFSR:     /* forward space record */
        !          1126:                        error = st_check_eod(st, TRUE, &nmarks, flags);
        !          1127:                        if (!error)
        !          1128:                                error = st_space(st, number, SP_BLKS, flags);
        !          1129:                        break;
        !          1130:                case MTREW:     /* rewind */
        !          1131:                        error = st_rewind(st, 0, flags);
        !          1132:                        break;
        !          1133:                case MTOFFL:    /* rewind and put the drive offline */
        !          1134:                        st_unmount(st, EJECT, DOREWIND);
        !          1135:                        break;
        !          1136:                case MTNOP:     /* no operation, sets status only */
        !          1137:                        break;
        !          1138:                case MTRETEN:   /* retension the tape */
        !          1139:                        error = st_load(st, LD_RETENSION, flags);
        !          1140:                        if (!error)
        !          1141:                                error = st_load(st, LD_LOAD, flags);
        !          1142:                        break;
        !          1143:                case MTEOM:     /* forward space to end of media */
        !          1144:                        error = st_check_eod(st, FALSE, &nmarks, flags);
        !          1145:                        if (!error)
        !          1146:                                error = st_space(st, 1, SP_EOM, flags);
        !          1147:                        break;
        !          1148:                case MTCACHE:   /* enable controller cache */
        !          1149:                        st->flags &= ~ST_DONTBUFFER;
        !          1150:                        goto try_new_value;
        !          1151:                case MTNOCACHE: /* disable controller cache */
        !          1152:                        st->flags |= ST_DONTBUFFER;
        !          1153:                        goto try_new_value;
        !          1154:                case MTERASE:   /* erase volume */
        !          1155:                        error = st_erase(st, number, flags);
        !          1156:                        break;
        !          1157:                case MTSETBSIZ: /* Set block size for device */
        !          1158:                        if (number == 0) {
        !          1159:                                st->flags &= ~ST_FIXEDBLOCKS;
        !          1160:                        } else {
        !          1161:                                if ((st->blkmin || st->blkmax) &&
        !          1162:                                    (number < st->blkmin ||
        !          1163:                                    number > st->blkmax)) {
        !          1164:                                        error = EINVAL;
        !          1165:                                        break;
        !          1166:                                }
        !          1167:                                st->flags |= ST_FIXEDBLOCKS;
        !          1168:                        }
        !          1169:                        st->blksize = number;
        !          1170:                        st->flags |= ST_BLOCK_SET;      /*XXX */
        !          1171:                        goto try_new_value;
        !          1172:
        !          1173:                case MTSETDNSTY:        /* Set density for device and mode */
        !          1174:                        if (number < 0 || number > SCSI_MAX_DENSITY_CODE) {
        !          1175:                                error = EINVAL;
        !          1176:                                break;
        !          1177:                        } else
        !          1178:                                st->density = number;
        !          1179:                        goto try_new_value;
        !          1180:
        !          1181:                default:
        !          1182:                        error = EINVAL;
        !          1183:                }
        !          1184:                break;
        !          1185:        }
        !          1186:        case MTIOCIEOT:
        !          1187:        case MTIOCEEOT:
        !          1188:                break;
        !          1189:
        !          1190: #if 0
        !          1191:        case MTIOCRDSPOS:
        !          1192:                error = st_rdpos(st, 0, (u_int32_t *) arg);
        !          1193:                break;
        !          1194:
        !          1195:        case MTIOCRDHPOS:
        !          1196:                error = st_rdpos(st, 1, (u_int32_t *) arg);
        !          1197:                break;
        !          1198:
        !          1199:        case MTIOCSLOCATE:
        !          1200:                error = st_setpos(st, 0, (u_int32_t *) arg);
        !          1201:                break;
        !          1202:
        !          1203:        case MTIOCHLOCATE:
        !          1204:                error = st_setpos(st, 1, (u_int32_t *) arg);
        !          1205:                break;
        !          1206: #endif
        !          1207:
        !          1208:        default:
        !          1209:                error = scsi_do_ioctl(st->sc_link, dev, cmd, arg, flag, p);
        !          1210:                break;
        !          1211:        }
        !          1212:        return error;
        !          1213: /*-----------------------------*/
        !          1214: try_new_value:
        !          1215:        /*
        !          1216:         * Check that the mode being asked for is aggreeable to the
        !          1217:         * drive. If not, put it back the way it was.
        !          1218:         */
        !          1219:        if ((error = st_mode_select(st, 0)) != 0) {/* put it back as it was */
        !          1220:                printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
        !          1221:                st->density = hold_density;
        !          1222:                st->blksize = hold_blksize;
        !          1223:                if (st->blksize)
        !          1224:                        st->flags |= ST_FIXEDBLOCKS;
        !          1225:                else
        !          1226:                        st->flags &= ~ST_FIXEDBLOCKS;
        !          1227:                return error;
        !          1228:        }
        !          1229:        /*
        !          1230:         * As the drive liked it, if we are setting a new default,
        !          1231:         * set it into the structures as such.
        !          1232:         */
        !          1233:        switch (mt->mt_op) {
        !          1234:        case MTSETBSIZ:
        !          1235:                st->modes.blksize = st->blksize;
        !          1236:                st->modeflags |= BLKSIZE_SET_BY_USER;
        !          1237:                break;
        !          1238:        case MTSETDNSTY:
        !          1239:                st->modes.density = st->density;
        !          1240:                st->modeflags |= DENSITY_SET_BY_USER;
        !          1241:                break;
        !          1242:        }
        !          1243:
        !          1244:        return 0;
        !          1245: }
        !          1246:
        !          1247: /*
        !          1248:  * Do a synchronous read.
        !          1249:  */
        !          1250: int
        !          1251: st_read(st, buf, size, flags)
        !          1252:        struct st_softc *st;
        !          1253:        int size;
        !          1254:        int flags;
        !          1255:        char *buf;
        !          1256: {
        !          1257:        struct scsi_rw_tape cmd;
        !          1258:
        !          1259:        /*
        !          1260:         * If it's a null transfer, return immediately
        !          1261:         */
        !          1262:        if (size == 0)
        !          1263:                return 0;
        !          1264:        bzero(&cmd, sizeof(cmd));
        !          1265:        cmd.opcode = READ;
        !          1266:        if (st->flags & ST_FIXEDBLOCKS) {
        !          1267:                cmd.byte2 |= SRW_FIXED;
        !          1268:                _lto3b(size / (st->blksize ? st->blksize : DEF_FIXED_BSIZE),
        !          1269:                    cmd.len);
        !          1270:        } else
        !          1271:                _lto3b(size, cmd.len);
        !          1272:        return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
        !          1273:            sizeof(cmd), (u_char *) buf, size, 0, ST_IO_TIME, NULL,
        !          1274:            flags | SCSI_DATA_IN);
        !          1275: }
        !          1276:
        !          1277: /*
        !          1278:  * Ask the drive what its min and max blk sizes are.
        !          1279:  */
        !          1280: int
        !          1281: st_read_block_limits(st, flags)
        !          1282:        struct st_softc *st;
        !          1283:        int flags;
        !          1284: {
        !          1285:        struct scsi_block_limits cmd;
        !          1286:        struct scsi_block_limits_data block_limits;
        !          1287:        struct scsi_link *sc_link = st->sc_link;
        !          1288:        int error;
        !          1289:
        !          1290:        /*
        !          1291:         * First check if we have it all loaded
        !          1292:         */
        !          1293:        if ((sc_link->flags & SDEV_MEDIA_LOADED))
        !          1294:                return 0;
        !          1295:
        !          1296:        /*
        !          1297:         * do a 'Read Block Limits'
        !          1298:         */
        !          1299:        bzero(&cmd, sizeof(cmd));
        !          1300:        cmd.opcode = READ_BLOCK_LIMITS;
        !          1301:
        !          1302:        /*
        !          1303:         * do the command, update the global values
        !          1304:         */
        !          1305:        error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
        !          1306:            sizeof(cmd), (u_char *) &block_limits, sizeof(block_limits),
        !          1307:            ST_RETRIES, ST_CTL_TIME, NULL, flags | SCSI_DATA_IN);
        !          1308:        if (error)
        !          1309:                return error;
        !          1310:
        !          1311:        st->blkmin = _2btol(block_limits.min_length);
        !          1312:        st->blkmax = _3btol(block_limits.max_length);
        !          1313:
        !          1314:        SC_DEBUG(sc_link, SDEV_DB3,
        !          1315:            ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax));
        !          1316:        return 0;
        !          1317: }
        !          1318:
        !          1319: /*
        !          1320:  * Get the scsi driver to send a full inquiry to the
        !          1321:  * device and use the results to fill out the global
        !          1322:  * parameter structure.
        !          1323:  *
        !          1324:  * called from:
        !          1325:  * attach
        !          1326:  * open
        !          1327:  * ioctl (to reset original blksize)
        !          1328:  */
        !          1329: int
        !          1330: st_mode_sense(st, flags)
        !          1331:        struct st_softc *st;
        !          1332:        int flags;
        !          1333: {
        !          1334:        union scsi_mode_sense_buf *data;
        !          1335:        struct scsi_link *sc_link = st->sc_link;
        !          1336:        u_int64_t block_count;
        !          1337:        u_int32_t density, block_size;
        !          1338:        u_char *page0 = NULL;
        !          1339:        u_int8_t dev_spec;
        !          1340:        int error, big;
        !          1341:
        !          1342:        data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
        !          1343:        if (data == NULL)
        !          1344:                return (ENOMEM);
        !          1345:
        !          1346:        /*
        !          1347:         * Ask for page 0 (vendor specific) mode sense data.
        !          1348:         */
        !          1349:        error = scsi_do_mode_sense(sc_link, 0, data, (void **)&page0,
        !          1350:            &density, &block_count, &block_size, 1, flags | SCSI_SILENT, &big);
        !          1351:        if (error != 0) {
        !          1352:                free(data, M_TEMP);
        !          1353:                return (error);
        !          1354:        }
        !          1355:
        !          1356:        /* It is valid for no page0 to be available. */
        !          1357:
        !          1358:        if (big)
        !          1359:                dev_spec = data->hdr_big.dev_spec;
        !          1360:        else
        !          1361:                dev_spec = data->hdr.dev_spec;
        !          1362:
        !          1363:        if (dev_spec & SMH_DSP_WRITE_PROT)
        !          1364:                st->flags |= ST_READONLY;
        !          1365:        else
        !          1366:                st->flags &= ~ST_READONLY;
        !          1367:
        !          1368:        st->numblks = block_count;
        !          1369:        st->media_blksize = block_size;
        !          1370:        st->media_density = density;
        !          1371:
        !          1372:        SC_DEBUG(sc_link, SDEV_DB3,
        !          1373:            ("density code 0x%x, %d-byte blocks, write-%s, ",
        !          1374:            st->media_density, st->media_blksize,
        !          1375:            st->flags & ST_READONLY ? "protected" : "enabled"));
        !          1376:        SC_DEBUGN(sc_link, SDEV_DB3,
        !          1377:            ("%sbuffered\n", dev_spec & SMH_DSP_BUFF_MODE ? "" : "un"));
        !          1378:
        !          1379:        sc_link->flags |= SDEV_MEDIA_LOADED;
        !          1380:
        !          1381:        free(data, M_TEMP);
        !          1382:        return (0);
        !          1383: }
        !          1384:
        !          1385: /*
        !          1386:  * Send a filled out parameter structure to the drive to
        !          1387:  * set it into the desire modes etc.
        !          1388:  */
        !          1389: int
        !          1390: st_mode_select(st, flags)
        !          1391:        struct st_softc *st;
        !          1392:        int flags;
        !          1393: {
        !          1394:        union scsi_mode_sense_buf *inbuf, *outbuf;
        !          1395:        struct scsi_blk_desc general;
        !          1396:        struct scsi_link *sc_link = st->sc_link;
        !          1397:        u_int8_t *page0 = NULL;
        !          1398:        int error, big, page0_size;
        !          1399:
        !          1400:        inbuf = malloc(sizeof(*inbuf), M_TEMP, M_NOWAIT);
        !          1401:        if (inbuf == NULL)
        !          1402:                return (ENOMEM);
        !          1403:        outbuf = malloc(sizeof(*outbuf), M_TEMP, M_NOWAIT);
        !          1404:        if (outbuf == NULL) {
        !          1405:                free(inbuf, M_TEMP);
        !          1406:                return (ENOMEM);
        !          1407:        }
        !          1408:
        !          1409:        /*
        !          1410:         * This quirk deals with drives that have only one valid mode and think
        !          1411:         * this gives them license to reject all mode selects, even if the
        !          1412:         * selected mode is the one that is supported.
        !          1413:         */
        !          1414:        if (st->quirks & ST_Q_UNIMODAL) {
        !          1415:                SC_DEBUG(sc_link, SDEV_DB3,
        !          1416:                    ("not setting density 0x%x blksize 0x%x\n",
        !          1417:                    st->density, st->blksize));
        !          1418:                free(inbuf, M_TEMP);
        !          1419:                free(outbuf, M_TEMP);
        !          1420:                return (0);
        !          1421:        }
        !          1422:
        !          1423:        if (sc_link->flags & SDEV_ATAPI) {
        !          1424:                free(inbuf, M_TEMP);
        !          1425:                free(outbuf, M_TEMP);
        !          1426:                return (0);
        !          1427:        }
        !          1428:
        !          1429:        bzero(outbuf, sizeof(*outbuf));
        !          1430:        bzero(&general, sizeof(general));
        !          1431:
        !          1432:        general.density = st->density;
        !          1433:        if (st->flags & ST_FIXEDBLOCKS)
        !          1434:                _lto3b(st->blksize, general.blklen);
        !          1435:
        !          1436:        /*
        !          1437:         * Ask for page 0 (vendor specific) mode sense data.
        !          1438:         */
        !          1439:        error = scsi_do_mode_sense(sc_link, 0, inbuf, (void **)&page0, NULL,
        !          1440:            NULL, NULL, 1, flags | SCSI_SILENT, &big);
        !          1441:        if (error != 0) {
        !          1442:                free(inbuf, M_TEMP);
        !          1443:                free(outbuf, M_TEMP);
        !          1444:                return (error);
        !          1445:        }
        !          1446:
        !          1447:        if (page0 == NULL) {
        !          1448:                page0_size = 0;
        !          1449:        } else if (big == 0) {
        !          1450:                page0_size = inbuf->hdr.data_length +
        !          1451:                    sizeof(inbuf->hdr.data_length) - sizeof(inbuf->hdr) -
        !          1452:                    inbuf->hdr.blk_desc_len;
        !          1453:                memcpy(&outbuf->buf[sizeof(outbuf->hdr)+ sizeof(general)],
        !          1454:                    page0, page0_size);
        !          1455:        } else {
        !          1456:                page0_size = _2btol(inbuf->hdr_big.data_length) +
        !          1457:                    sizeof(inbuf->hdr_big.data_length) -
        !          1458:                    sizeof(inbuf->hdr_big) -
        !          1459:                   _2btol(inbuf->hdr_big.blk_desc_len);
        !          1460:                memcpy(&outbuf->buf[sizeof(outbuf->hdr_big) + sizeof(general)],
        !          1461:                    page0, page0_size);
        !          1462:        }
        !          1463:
        !          1464:        /*
        !          1465:         * Set up for a mode select.
        !          1466:         */
        !          1467:        if (big == 0) {
        !          1468:                outbuf->hdr.data_length = sizeof(outbuf->hdr) +
        !          1469:                    sizeof(general) + page0_size -
        !          1470:                    sizeof(outbuf->hdr.data_length);
        !          1471:                if ((st->flags & ST_DONTBUFFER) == 0)
        !          1472:                        outbuf->hdr.dev_spec = SMH_DSP_BUFF_MODE_ON;
        !          1473:                outbuf->hdr.blk_desc_len = sizeof(general);
        !          1474:                memcpy(&outbuf->buf[sizeof(outbuf->hdr)],
        !          1475:                    &general, sizeof(general));
        !          1476:                error = scsi_mode_select(st->sc_link, 0, &outbuf->hdr,
        !          1477:                    flags, ST_CTL_TIME);
        !          1478:                free(inbuf, M_TEMP);
        !          1479:                free(outbuf, M_TEMP);
        !          1480:                return (error);
        !          1481:        }
        !          1482:
        !          1483:        /* MODE SENSE (10) header was returned, so use MODE SELECT (10). */
        !          1484:        _lto2b((sizeof(outbuf->hdr_big) + sizeof(general) + page0_size -
        !          1485:            sizeof(outbuf->hdr_big.data_length)), outbuf->hdr_big.data_length);
        !          1486:        if ((st->flags & ST_DONTBUFFER) == 0)
        !          1487:                outbuf->hdr_big.dev_spec = SMH_DSP_BUFF_MODE_ON;
        !          1488:        _lto2b(sizeof(general), outbuf->hdr_big.blk_desc_len);
        !          1489:        memcpy(&outbuf->buf[sizeof(outbuf->hdr_big)], &general,
        !          1490:            sizeof(general));
        !          1491:
        !          1492:        error = scsi_mode_select_big(st->sc_link, 0, &outbuf->hdr_big,
        !          1493:            flags, ST_CTL_TIME);
        !          1494:        free(inbuf, M_TEMP);
        !          1495:        free(outbuf, M_TEMP);
        !          1496:        return (error);
        !          1497: }
        !          1498:
        !          1499: /*
        !          1500:  * issue an erase command
        !          1501:  */
        !          1502: int
        !          1503: st_erase(st, full, flags)
        !          1504:        struct st_softc *st;
        !          1505:        int full, flags;
        !          1506: {
        !          1507:        struct scsi_erase cmd;
        !          1508:        int tmo;
        !          1509:
        !          1510:        /*
        !          1511:         * Full erase means set LONG bit in erase command, which asks
        !          1512:         * the drive to erase the entire unit.  Without this bit, we're
        !          1513:         * asking the drive to write an erase gap.
        !          1514:         */
        !          1515:        bzero(&cmd, sizeof(cmd));
        !          1516:        cmd.opcode = ERASE;
        !          1517:        if (full) {
        !          1518:                cmd.byte2 = SE_IMMED|SE_LONG;
        !          1519:                tmo = ST_SPC_TIME;
        !          1520:        } else {
        !          1521:                cmd.byte2 = SE_IMMED;
        !          1522:                tmo = ST_IO_TIME;
        !          1523:        }
        !          1524:
        !          1525:        /*
        !          1526:         * XXX We always do this asynchronously, for now.  How long should
        !          1527:         * we wait if we want to (eventually) to it synchronously?
        !          1528:         */
        !          1529:        return (scsi_scsi_cmd(st->sc_link, (struct scsi_generic *)&cmd,
        !          1530:            sizeof(cmd), 0, 0, ST_RETRIES, tmo, NULL, flags));
        !          1531: }
        !          1532:
        !          1533: /*
        !          1534:  * skip N blocks/filemarks/seq filemarks/eom
        !          1535:  */
        !          1536: int
        !          1537: st_space(st, number, what, flags)
        !          1538:        struct st_softc *st;
        !          1539:        u_int what;
        !          1540:        int flags;
        !          1541:        int number;
        !          1542: {
        !          1543:        struct scsi_space cmd;
        !          1544:        int error;
        !          1545:
        !          1546:        switch (what) {
        !          1547:        case SP_BLKS:
        !          1548:                if (st->flags & ST_PER_ACTION) {
        !          1549:                        if (number > 0) {
        !          1550:                                st->flags &= ~ST_PER_ACTION;
        !          1551:                                return EIO;
        !          1552:                        } else if (number < 0) {
        !          1553:                                if (st->flags & ST_AT_FILEMARK) {
        !          1554:                                        /*
        !          1555:                                         * Handling of ST_AT_FILEMARK
        !          1556:                                         * in st_space will fill in the
        !          1557:                                         * right file mark count.
        !          1558:                                         */
        !          1559:                                        error = st_space(st, 0, SP_FILEMARKS,
        !          1560:                                                flags);
        !          1561:                                        if (error)
        !          1562:                                                return error;
        !          1563:                                }
        !          1564:                                if (st->flags & ST_BLANK_READ) {
        !          1565:                                        st->flags &= ~ST_BLANK_READ;
        !          1566:                                        return EIO;
        !          1567:                                }
        !          1568:                                st->flags &= ~ST_EIO_PENDING;
        !          1569:                        }
        !          1570:                }
        !          1571:                break;
        !          1572:        case SP_FILEMARKS:
        !          1573:                if (st->flags & ST_EIO_PENDING) {
        !          1574:                        if (number > 0) {
        !          1575:                                /* pretend we just discovered the error */
        !          1576:                                st->flags &= ~ST_EIO_PENDING;
        !          1577:                                return EIO;
        !          1578:                        } else if (number < 0) {
        !          1579:                                /* back away from the error */
        !          1580:                                st->flags &= ~ST_EIO_PENDING;
        !          1581:                        }
        !          1582:                }
        !          1583:                if (st->flags & ST_AT_FILEMARK) {
        !          1584:                        st->flags &= ~ST_AT_FILEMARK;
        !          1585:                        number--;
        !          1586:                }
        !          1587:                if ((st->flags & ST_BLANK_READ) && (number < 0)) {
        !          1588:                        /* back away from unwritten tape */
        !          1589:                        st->flags &= ~ST_BLANK_READ;
        !          1590:                        number++;       /* XXX dubious */
        !          1591:                }
        !          1592:                break;
        !          1593:        case SP_EOM:
        !          1594:                if (st->flags & ST_EIO_PENDING) {
        !          1595:                        /* pretend we just discovered the error */
        !          1596:                        st->flags &= ~ST_EIO_PENDING;
        !          1597:                        return EIO;
        !          1598:                }
        !          1599:                if (st->flags & ST_AT_FILEMARK)
        !          1600:                        st->flags &= ~ST_AT_FILEMARK;
        !          1601:                break;
        !          1602:        }
        !          1603:        if (number == 0)
        !          1604:                return 0;
        !          1605:
        !          1606:        bzero(&cmd, sizeof(cmd));
        !          1607:        cmd.opcode = SPACE;
        !          1608:        cmd.byte2 = what;
        !          1609:        _lto3b(number, cmd.number);
        !          1610:
        !          1611:        error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
        !          1612:            sizeof(cmd), 0, 0, 0, ST_SPC_TIME, NULL, flags);
        !          1613:
        !          1614:        if (error != 0) {
        !          1615:                st->media_fileno = -1;
        !          1616:                st->media_blkno = -1;
        !          1617:        } else {
        !          1618:                switch (what) {
        !          1619:                case SP_BLKS:
        !          1620:                        if (st->media_blkno != -1) {
        !          1621:                                st->media_blkno += number;
        !          1622:                                if (st->media_blkno < 0)
        !          1623:                                        st->media_blkno = -1;
        !          1624:                        }
        !          1625:                        break;
        !          1626:                case SP_FILEMARKS:
        !          1627:                        if (st->media_fileno != -1) {
        !          1628:                                st->media_fileno += number;
        !          1629:                                st->media_blkno = 0;
        !          1630:                        }
        !          1631:                        break;
        !          1632:                default:
        !          1633:                        st->media_fileno = -1;
        !          1634:                        st->media_blkno = -1;
        !          1635:                        break;
        !          1636:                }
        !          1637:        }
        !          1638:
        !          1639:        return (error);
        !          1640: }
        !          1641:
        !          1642: /*
        !          1643:  * write N filemarks
        !          1644:  */
        !          1645: int
        !          1646: st_write_filemarks(st, number, flags)
        !          1647:        struct st_softc *st;
        !          1648:        int flags;
        !          1649:        int number;
        !          1650: {
        !          1651:        struct scsi_write_filemarks cmd;
        !          1652:        int error;
        !          1653:
        !          1654:        /*
        !          1655:         * It's hard to write a negative number of file marks.
        !          1656:         * Don't try.
        !          1657:         */
        !          1658:        if (number < 0)
        !          1659:                return EINVAL;
        !          1660:        switch (number) {
        !          1661:        case 0:         /* really a command to sync the drive's buffers */
        !          1662:                break;
        !          1663:        case 1:
        !          1664:                if (st->flags & ST_FM_WRITTEN)  /* already have one down */
        !          1665:                        st->flags &= ~ST_WRITTEN;
        !          1666:                else
        !          1667:                        st->flags |= ST_FM_WRITTEN;
        !          1668:                st->flags &= ~ST_PER_ACTION;
        !          1669:                break;
        !          1670:        default:
        !          1671:                st->flags &= ~(ST_PER_ACTION | ST_WRITTEN);
        !          1672:        }
        !          1673:
        !          1674:        bzero(&cmd, sizeof(cmd));
        !          1675:        cmd.opcode = WRITE_FILEMARKS;
        !          1676:        _lto3b(number, cmd.number);
        !          1677:
        !          1678:        error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
        !          1679:            sizeof(cmd), 0, 0, 0, ST_IO_TIME * 4, NULL, flags);
        !          1680:
        !          1681:        if (error != 0) {
        !          1682:                st->media_fileno = -1;
        !          1683:                st->media_blkno = -1;
        !          1684:        } else if (st->media_fileno != -1) {
        !          1685:                st->media_fileno += number;
        !          1686:                st->media_blkno = 0;
        !          1687:        }
        !          1688:
        !          1689:        return (error);
        !          1690: }
        !          1691:
        !          1692: /*
        !          1693:  * Make sure the right number of file marks is on tape if the
        !          1694:  * tape has been written.  If the position argument is true,
        !          1695:  * leave the tape positioned where it was originally.
        !          1696:  *
        !          1697:  * nmarks returns the number of marks to skip (or, if position
        !          1698:  * true, which were skipped) to get back original position.
        !          1699:  */
        !          1700: int
        !          1701: st_check_eod(st, position, nmarks, flags)
        !          1702:        struct st_softc *st;
        !          1703:        int position;
        !          1704:        int *nmarks;
        !          1705:        int flags;
        !          1706: {
        !          1707:        int error;
        !          1708:
        !          1709:        switch (st->flags & (ST_WRITTEN | ST_FM_WRITTEN | ST_2FM_AT_EOD)) {
        !          1710:        default:
        !          1711:                *nmarks = 0;
        !          1712:                return 0;
        !          1713:        case ST_WRITTEN:
        !          1714:        case ST_WRITTEN | ST_FM_WRITTEN | ST_2FM_AT_EOD:
        !          1715:                *nmarks = 1;
        !          1716:                break;
        !          1717:        case ST_WRITTEN | ST_2FM_AT_EOD:
        !          1718:                *nmarks = 2;
        !          1719:        }
        !          1720:        error = st_write_filemarks(st, *nmarks, flags);
        !          1721:        if (position && !error)
        !          1722:                error = st_space(st, -*nmarks, SP_FILEMARKS, flags);
        !          1723:        return error;
        !          1724: }
        !          1725:
        !          1726: /*
        !          1727:  * load/unload/retension
        !          1728:  */
        !          1729: int
        !          1730: st_load(st, type, flags)
        !          1731:        struct st_softc *st;
        !          1732:        u_int type;
        !          1733:        int flags;
        !          1734: {
        !          1735:        struct scsi_load cmd;
        !          1736:
        !          1737:        st->media_fileno = -1;
        !          1738:        st->media_blkno = -1;
        !          1739:
        !          1740:        if (type != LD_LOAD) {
        !          1741:                int error;
        !          1742:                int nmarks;
        !          1743:
        !          1744:                error = st_check_eod(st, FALSE, &nmarks, flags);
        !          1745:                if (error)
        !          1746:                        return error;
        !          1747:        }
        !          1748:        if (st->quirks & ST_Q_IGNORE_LOADS) {
        !          1749:                if (type == LD_LOAD) {
        !          1750:                        /*
        !          1751:                         * If we ignore loads, at least we should try a rewind.
        !          1752:                         */
        !          1753:                        return st_rewind(st, 0, flags);
        !          1754:                }
        !          1755:                return (0);
        !          1756:        }
        !          1757:
        !          1758:
        !          1759:        bzero(&cmd, sizeof(cmd));
        !          1760:        cmd.opcode = LOAD;
        !          1761:        cmd.how = type;
        !          1762:
        !          1763:        return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
        !          1764:            sizeof(cmd), 0, 0, ST_RETRIES, ST_SPC_TIME, NULL, flags);
        !          1765: }
        !          1766:
        !          1767: /*
        !          1768:  *  Rewind the device
        !          1769:  */
        !          1770: int
        !          1771: st_rewind(st, immediate, flags)
        !          1772:        struct st_softc *st;
        !          1773:        u_int immediate;
        !          1774:        int flags;
        !          1775: {
        !          1776:        struct scsi_rewind cmd;
        !          1777:        int error;
        !          1778:        int nmarks;
        !          1779:
        !          1780:        error = st_check_eod(st, FALSE, &nmarks, flags);
        !          1781:        if (error)
        !          1782:                return error;
        !          1783:        st->flags &= ~ST_PER_ACTION;
        !          1784:
        !          1785:        bzero(&cmd, sizeof(cmd));
        !          1786:        cmd.opcode = REWIND;
        !          1787:        cmd.byte2 = immediate;
        !          1788:
        !          1789:        error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
        !          1790:            sizeof(cmd), 0, 0, ST_RETRIES,
        !          1791:            immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags);
        !          1792:
        !          1793:        if (error == 0) {
        !          1794:                st->media_fileno = 0;
        !          1795:                st->media_blkno = 0;
        !          1796:        }
        !          1797:
        !          1798:        return (error);
        !          1799: }
        !          1800:
        !          1801: /*
        !          1802:  * Look at the returned sense and act on the error and detirmine
        !          1803:  * The unix error number to pass back... (0 = report no error)
        !          1804:  *                            (-1 = continue processing)
        !          1805:  */
        !          1806: int
        !          1807: st_interpret_sense(xs)
        !          1808:        struct scsi_xfer *xs;
        !          1809: {
        !          1810:        struct scsi_sense_data *sense = &xs->sense;
        !          1811:        struct scsi_link *sc_link = xs->sc_link;
        !          1812:        struct st_softc *st = sc_link->device_softc;
        !          1813:        struct buf *bp = xs->bp;
        !          1814:        u_int8_t serr = sense->error_code & SSD_ERRCODE;
        !          1815:        u_int8_t skey = sense->flags & SSD_KEY;
        !          1816:        int32_t info;
        !          1817:
        !          1818:        if (((sc_link->flags & SDEV_OPEN) == 0) ||
        !          1819:            (serr != SSD_ERRCODE_CURRENT && serr != SSD_ERRCODE_DEFERRED))
        !          1820:                return (EJUSTRETURN); /* let the generic code handle it */
        !          1821:
        !          1822:        switch (skey) {
        !          1823:
        !          1824:        /*
        !          1825:         * We do custom processing in st for the unit becoming ready case.
        !          1826:         * in this case we do not allow xs->retries to be decremented
        !          1827:         * only on the "Unit Becoming Ready" case. This is because tape
        !          1828:         * drives report "Unit Becoming Ready" when loading media, etc.
        !          1829:         * and can take a long time.  Rather than having a massive timeout
        !          1830:         * for all operations (which would cause other problems) we allow
        !          1831:         * operations to wait (but be interruptable with Ctrl-C) forever
        !          1832:         * as long as the drive is reporting that it is becoming ready.
        !          1833:         * all other cases are handled as per the default.
        !          1834:         */
        !          1835:
        !          1836:        case SKEY_NOT_READY:
        !          1837:                if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
        !          1838:                        return (0);
        !          1839:                switch (ASC_ASCQ(sense)) {
        !          1840:                case SENSE_NOT_READY_BECOMING_READY:
        !          1841:                        SC_DEBUG(sc_link, SDEV_DB1, ("not ready: busy (%#x)\n",
        !          1842:                            sense->add_sense_code_qual));
        !          1843:                        /* don't count this as a retry */
        !          1844:                        xs->retries++;
        !          1845:                        return (scsi_delay(xs, 1));
        !          1846:                default:
        !          1847:                        return (EJUSTRETURN);
        !          1848:        }
        !          1849:        case SKEY_NO_SENSE:
        !          1850:        case SKEY_RECOVERED_ERROR:
        !          1851:        case SKEY_MEDIUM_ERROR:
        !          1852:        case SKEY_VOLUME_OVERFLOW:
        !          1853:        case SKEY_BLANK_CHECK:
        !          1854:                break;
        !          1855:        default:
        !          1856:                return (EJUSTRETURN);
        !          1857:        }
        !          1858:
        !          1859:        /*
        !          1860:         * Get the sense fields and work out what code
        !          1861:         */
        !          1862:        if (sense->error_code & SSD_ERRCODE_VALID)
        !          1863:                info = _4btol(sense->info);
        !          1864:        else
        !          1865:                info = xs->datalen;     /* bad choice if fixed blocks */
        !          1866:        if (st->flags & ST_FIXEDBLOCKS) {
        !          1867:                xs->resid = info * st->blksize;
        !          1868:                if (sense->flags & SSD_EOM) {
        !          1869:                        st->flags |= ST_EIO_PENDING;
        !          1870:                        if (bp)
        !          1871:                                bp->b_resid = xs->resid;
        !          1872:                }
        !          1873:                if (sense->flags & SSD_FILEMARK) {
        !          1874:                        st->flags |= ST_AT_FILEMARK;
        !          1875:                        if (st->media_fileno != -1) {
        !          1876:                                st->media_fileno++;
        !          1877:                                st->media_blkno = 0;
        !          1878:                        }
        !          1879:                        if (bp)
        !          1880:                                bp->b_resid = xs->resid;
        !          1881:                }
        !          1882:                if (sense->flags & SSD_ILI) {
        !          1883:                        st->flags |= ST_EIO_PENDING;
        !          1884:                        if (bp)
        !          1885:                                bp->b_resid = xs->resid;
        !          1886:                        if (sense->error_code & SSD_ERRCODE_VALID &&
        !          1887:                            (xs->flags & SCSI_SILENT) == 0)
        !          1888:                                printf("%s: block wrong size, %d blocks residual\n",
        !          1889:                                    st->sc_dev.dv_xname, info);
        !          1890:
        !          1891:                        /*
        !          1892:                         * This quirk code helps the drive read
        !          1893:                         * the first tape block, regardless of
        !          1894:                         * format.  That is required for these
        !          1895:                         * drives to return proper MODE SENSE
        !          1896:                         * information.
        !          1897:                         */
        !          1898:                        if ((st->quirks & ST_Q_SENSE_HELP) &&
        !          1899:                            !(sc_link->flags & SDEV_MEDIA_LOADED))
        !          1900:                                st->blksize -= 512;
        !          1901:                }
        !          1902:                /*
        !          1903:                 * If no data was transferred, return immediately
        !          1904:                 */
        !          1905:                if (xs->resid >= xs->datalen) {
        !          1906:                        if (st->flags & ST_EIO_PENDING)
        !          1907:                                return EIO;
        !          1908:                        if (st->flags & ST_AT_FILEMARK) {
        !          1909:                                if (bp)
        !          1910:                                        bp->b_resid = xs->resid;
        !          1911:                                return 0;
        !          1912:                        }
        !          1913:                }
        !          1914:        } else {                /* must be variable mode */
        !          1915:                xs->resid = xs->datalen;        /* to be sure */
        !          1916:                if (sense->flags & SSD_EOM)
        !          1917:                        return EIO;
        !          1918:                if (sense->flags & SSD_FILEMARK) {
        !          1919:                        if (st->media_fileno != -1) {
        !          1920:                                st->media_fileno++;
        !          1921:                                st->media_blkno = 0;
        !          1922:                        }
        !          1923:                        if (bp)
        !          1924:                                bp->b_resid = bp->b_bcount;
        !          1925:                        return 0;
        !          1926:                }
        !          1927:                if (sense->flags & SSD_ILI) {
        !          1928:                        if (info < 0) {
        !          1929:                                /*
        !          1930:                                 * the record was bigger than the read
        !          1931:                                 */
        !          1932:                                if ((xs->flags & SCSI_SILENT) == 0)
        !          1933:                                        printf("%s: %d-byte record too big\n",
        !          1934:                                            st->sc_dev.dv_xname,
        !          1935:                                            xs->datalen - info);
        !          1936:                                return (EIO);
        !          1937:                        } else if (info > xs->datalen) {
        !          1938:                                /*
        !          1939:                                 * huh? the residual is bigger than the request
        !          1940:                                 */
        !          1941:                                if ((xs->flags & SCSI_SILENT) == 0) {
        !          1942:                                        printf(
        !          1943:                                            "%s: bad residual %d out of %d\n",
        !          1944:                                            st->sc_dev.dv_xname, info,
        !          1945:                                            xs->datalen);
        !          1946:                                        return (EIO);
        !          1947:                                }
        !          1948:                        }
        !          1949:                        xs->resid = info;
        !          1950:                        if (bp)
        !          1951:                                bp->b_resid = info;
        !          1952:                        return (0);
        !          1953:                }
        !          1954:        }
        !          1955:
        !          1956:        if (skey == SKEY_BLANK_CHECK) {
        !          1957:                /*
        !          1958:                 * This quirk code helps the drive read the first tape block,
        !          1959:                 * regardless of format.  That is required for these drives to
        !          1960:                 * return proper MODE SENSE information.
        !          1961:                 */
        !          1962:                if ((st->quirks & ST_Q_SENSE_HELP) &&
        !          1963:                    !(sc_link->flags & SDEV_MEDIA_LOADED)) {
        !          1964:                        /* still starting */
        !          1965:                        st->blksize -= 512;
        !          1966:                } else if (!(st->flags & (ST_2FM_AT_EOD | ST_BLANK_READ))) {
        !          1967:                        st->flags |= ST_BLANK_READ;
        !          1968:                        xs->resid = xs->datalen;
        !          1969:                        if (bp) {
        !          1970:                                bp->b_resid = xs->resid;
        !          1971:                                /* return an EOF */
        !          1972:                        }
        !          1973:                        return (0);
        !          1974:                }
        !          1975:        }
        !          1976:
        !          1977:        return (EJUSTRETURN);
        !          1978: }
        !          1979:
        !          1980: /*
        !          1981:  * The quirk here is that the drive returns some value to st_mode_sense
        !          1982:  * incorrectly until the tape has actually passed by the head.
        !          1983:  *
        !          1984:  * The method is to set the drive to large fixed-block state (user-specified
        !          1985:  * density and 1024-byte blocks), then read and rewind to get it to sense the
        !          1986:  * tape.  If that doesn't work, try 512-byte fixed blocks.  If that doesn't
        !          1987:  * work, as a last resort, try variable- length blocks.  The result will be
        !          1988:  * the ability to do an accurate st_mode_sense.
        !          1989:  *
        !          1990:  * We know we can do a rewind because we just did a load, which implies rewind.
        !          1991:  * Rewind seems preferable to space backward if we have a virgin tape.
        !          1992:  *
        !          1993:  * The rest of the code for this quirk is in ILI processing and BLANK CHECK
        !          1994:  * error processing, both part of st_interpret_sense.
        !          1995:  */
        !          1996: int
        !          1997: st_touch_tape(st)
        !          1998:        struct st_softc *st;
        !          1999: {
        !          2000:        char *buf;
        !          2001:        int readsize;
        !          2002:        int error;
        !          2003:
        !          2004:        buf = malloc(1024, M_TEMP, M_NOWAIT);
        !          2005:        if (!buf)
        !          2006:                return ENOMEM;
        !          2007:
        !          2008:        if ((error = st_mode_sense(st, 0)) != 0)
        !          2009:                goto bad;
        !          2010:        st->blksize = 1024;
        !          2011:        do {
        !          2012:                switch (st->blksize) {
        !          2013:                case 512:
        !          2014:                case 1024:
        !          2015:                        readsize = st->blksize;
        !          2016:                        st->flags |= ST_FIXEDBLOCKS;
        !          2017:                        break;
        !          2018:                default:
        !          2019:                        readsize = 1;
        !          2020:                        st->flags &= ~ST_FIXEDBLOCKS;
        !          2021:                }
        !          2022:                if ((error = st_mode_select(st, 0)) != 0)
        !          2023:                        goto bad;
        !          2024:                st_read(st, buf, readsize, SCSI_SILENT);        /* XXX */
        !          2025:                if ((error = st_rewind(st, 0, 0)) != 0) {
        !          2026: bad:                   free(buf, M_TEMP);
        !          2027:                        return error;
        !          2028:                }
        !          2029:        } while (readsize != 1 && readsize > st->blksize);
        !          2030:
        !          2031:        free(buf, M_TEMP);
        !          2032:        return 0;
        !          2033: }
        !          2034:
        !          2035: int
        !          2036: stdump(dev, blkno, va, size)
        !          2037:        dev_t dev;
        !          2038:        daddr64_t blkno;
        !          2039:        caddr_t va;
        !          2040:        size_t size;
        !          2041: {
        !          2042:
        !          2043:        /* Not implemented. */
        !          2044:        return ENXIO;
        !          2045: }

CVSweb