LCOV - code coverage report
Current view: top level - scsi - st.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 884 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: st.c,v 1.134 2017/09/08 05:36:53 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/param.h>
      58             : #include <sys/systm.h>
      59             : #include <sys/timeout.h>
      60             : #include <sys/fcntl.h>
      61             : #include <sys/errno.h>
      62             : #include <sys/ioctl.h>
      63             : #include <sys/stat.h>
      64             : #include <sys/pool.h>
      65             : #include <sys/buf.h>
      66             : #include <sys/mtio.h>
      67             : #include <sys/device.h>
      68             : #include <sys/conf.h>
      69             : #include <sys/vnode.h>
      70             : 
      71             : #include <scsi/scsi_all.h>
      72             : #include <scsi/scsi_tape.h>
      73             : #include <scsi/scsiconf.h>
      74             : 
      75             : /* Defines for device specific stuff */
      76             : #define DEF_FIXED_BSIZE  512
      77             : 
      78             : #define STMODE(z)       ( minor(z)       & 0x03)
      79             : #define STUNIT(z)       ((minor(z) >> 4)       )
      80             : 
      81             : #define STMINOR(unit, mode)     (((unit) << 4) + (mode))
      82             : #define MAXSTMODES      16
      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             : 
     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             : 
     198             :         struct scsi_link *sc_link;      /* our link to the adpter etc.        */
     199             : 
     200             :         int blkmin;             /* min blk size                       */
     201             :         int blkmax;             /* max blk size                       */
     202             :         const struct quirkdata *quirkdata;      /* if we have a rogue entry */
     203             : 
     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             :         int media_eom;                  /* relative to BOT. -1 means unknown. */
     210             : 
     211             :         u_int drive_quirks;     /* quirks of this drive               */
     212             : 
     213             :         struct modes modes;     /* plus more for each mode            */
     214             :         u_int8_t  modeflags;    /* flags for the modes                */
     215             : #define DENSITY_SET_BY_USER     0x01
     216             : #define DENSITY_SET_BY_QUIRK    0x02
     217             : #define BLKSIZE_SET_BY_USER     0x04
     218             : #define BLKSIZE_SET_BY_QUIRK    0x08
     219             : 
     220             :         struct bufq sc_bufq;
     221             :         struct timeout sc_timeout;
     222             :         struct scsi_xshandler sc_xsh;
     223             : };
     224             : 
     225             : 
     226             : int     stmatch(struct device *, void *, void *);
     227             : void    stattach(struct device *, struct device *, void *);
     228             : int     stactivate(struct device *, int);
     229             : int     stdetach(struct device *, int);
     230             : 
     231             : void    stminphys(struct buf *);
     232             : void    st_identify_drive(struct st_softc *, struct scsi_inquiry_data *);
     233             : void    st_loadquirks(struct st_softc *);
     234             : int     st_mount_tape(dev_t, int);
     235             : void    st_unmount(struct st_softc *, int, int);
     236             : int     st_decide_mode(struct st_softc *, int);
     237             : void    ststart(struct scsi_xfer *);
     238             : void    st_buf_done(struct scsi_xfer *);
     239             : int     st_read(struct st_softc *, char *, int, int);
     240             : int     st_read_block_limits(struct st_softc *, int);
     241             : int     st_mode_sense(struct st_softc *, int);
     242             : int     st_mode_select(struct st_softc *, int);
     243             : int     st_space(struct st_softc *, int, u_int, int);
     244             : int     st_write_filemarks(struct st_softc *, int, int);
     245             : int     st_check_eod(struct st_softc *, int, int *, int);
     246             : int     st_load(struct st_softc *, u_int, int);
     247             : int     st_rewind(struct st_softc *, u_int, int);
     248             : int     st_interpret_sense(struct scsi_xfer *);
     249             : int     st_touch_tape(struct st_softc *);
     250             : int     st_erase(struct st_softc *, int, int);
     251             : 
     252             : struct cfattach st_ca = {
     253             :         sizeof(struct st_softc), stmatch, stattach,
     254             :         stdetach, stactivate
     255             : };
     256             : 
     257             : struct cfdriver st_cd = {
     258             :         NULL, "st", DV_TAPE
     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_EOM_PENDING  0x0040  /* we couldn't report it then (had data) */
     268             : #define ST_EOD_DETECTED 0x0080
     269             : #define ST_FM_WRITTEN   0x0100  /*
     270             :                                  * EOF file mark written  -- used with
     271             :                                  * ~ST_WRITTEN to indicate that multiple file
     272             :                                  * marks have been written
     273             :                                  */
     274             : #define ST_BLANK_READ   0x0200  /* BLANK CHECK encountered already */
     275             : #define ST_2FM_AT_EOD   0x0400  /* write 2 file marks at EOD */
     276             : #define ST_MOUNTED      0x0800  /* Device is presently mounted */
     277             : #define ST_DONTBUFFER   0x1000  /* Disable buffering/caching */
     278             : #define ST_WAITING      0x2000
     279             : #define ST_DYING        0x4000  /* dying, when deactivated */
     280             : #define ST_BOD_DETECTED 0x8000
     281             : 
     282             : #define ST_PER_ACTION   (ST_AT_FILEMARK | ST_EIO_PENDING | ST_EOM_PENDING | \
     283             :                          ST_BLANK_READ)
     284             : 
     285             : #define stlookup(unit) (struct st_softc *)device_lookup(&st_cd, (unit))
     286             : 
     287             : const struct scsi_inquiry_pattern st_patterns[] = {
     288             :         {T_SEQUENTIAL, T_REMOV,
     289             :          "",         "",                 ""},
     290             : };
     291             : 
     292             : int
     293           0 : stmatch(struct device *parent, void *match, void *aux)
     294             : {
     295           0 :         struct scsi_attach_args *sa = aux;
     296           0 :         int priority;
     297             : 
     298           0 :         (void)scsi_inqmatch(sa->sa_inqbuf,
     299             :             st_patterns, nitems(st_patterns),
     300             :             sizeof(st_patterns[0]), &priority);
     301           0 :         return (priority);
     302           0 : }
     303             : 
     304             : /*
     305             :  * The routine called by the low level scsi routine when it discovers
     306             :  * A device suitable for this driver
     307             :  */
     308             : void
     309           0 : stattach(struct device *parent, struct device *self, void *aux)
     310             : {
     311           0 :         struct st_softc *st = (void *)self;
     312           0 :         struct scsi_attach_args *sa = aux;
     313           0 :         struct scsi_link *link = sa->sa_sc_link;
     314             : 
     315             :         SC_DEBUG(link, SDEV_DB2, ("stattach:\n"));
     316             : 
     317             :         /*
     318             :          * Store information needed to contact our base driver
     319             :          */
     320           0 :         st->sc_link = link;
     321           0 :         link->interpret_sense = st_interpret_sense;
     322           0 :         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           0 :         st_identify_drive(st, sa->sa_inqbuf);
     329           0 :         printf("\n");
     330             : 
     331           0 :         scsi_xsh_set(&st->sc_xsh, link, ststart);
     332           0 :         timeout_set(&st->sc_timeout, (void (*)(void *))scsi_xsh_set,
     333           0 :             &st->sc_xsh);
     334             : 
     335             :         /* Set up the buf queue for this device. */
     336           0 :         bufq_init(&st->sc_bufq, BUFQ_FIFO);
     337             : 
     338             :         /* Start up with media position unknown. */
     339           0 :         st->media_fileno = -1;
     340           0 :         st->media_blkno = -1;
     341           0 :         st->media_eom = -1;
     342             : 
     343             :         /*
     344             :          * Reset the media loaded flag, sometimes the data
     345             :          * acquired at boot time is not quite accurate.  This
     346             :          * will be checked again at the first open.
     347             :          */
     348           0 :         link->flags &= ~SDEV_MEDIA_LOADED;
     349           0 : }
     350             : 
     351             : int
     352           0 : stactivate(struct device *self, int act)
     353             : {
     354           0 :         struct st_softc *st = (struct st_softc *)self;
     355             :         int rv = 0;
     356             : 
     357           0 :         switch (act) {
     358             :         case DVACT_DEACTIVATE:
     359           0 :                 st->flags |= ST_DYING;
     360           0 :                 scsi_xsh_del(&st->sc_xsh);
     361           0 :                 break;
     362             :         }
     363             : 
     364           0 :         return (rv);
     365             : }
     366             : 
     367             : int
     368           0 : stdetach(struct device *self, int flags)
     369             : {
     370           0 :         struct st_softc *st = (struct st_softc *)self;
     371             :         int cmaj, mn;
     372             : 
     373           0 :         bufq_drain(&st->sc_bufq);
     374             : 
     375             :         /* Locate the lowest minor number to be detached. */
     376           0 :         mn = STMINOR(self->dv_unit, 0);
     377             : 
     378           0 :         for (cmaj = 0; cmaj < nchrdev; cmaj++)
     379           0 :                 if (cdevsw[cmaj].d_open == stopen)
     380           0 :                         vdevgone(cmaj, mn, mn + MAXSTMODES - 1, VCHR);
     381             : 
     382           0 :         bufq_destroy(&st->sc_bufq);
     383             : 
     384           0 :         return (0);
     385             : }
     386             : 
     387             : /*
     388             :  * Use the inquiry routine in 'scsi_base' to get drive info so we can
     389             :  * Further tailor our behaviour.
     390             :  */
     391             : void
     392           0 : st_identify_drive(struct st_softc *st, struct scsi_inquiry_data *inqbuf)
     393             : {
     394             :         const struct st_quirk_inquiry_pattern *finger;
     395           0 :         int priority;
     396             : 
     397           0 :         finger = (const struct st_quirk_inquiry_pattern *)scsi_inqmatch(inqbuf,
     398             :             st_quirk_patterns,
     399             :             nitems(st_quirk_patterns),
     400             :             sizeof(st_quirk_patterns[0]), &priority);
     401           0 :         if (priority != 0) {
     402           0 :                 st->quirkdata = &finger->quirkdata;
     403           0 :                 st->drive_quirks = finger->quirkdata.quirks;
     404           0 :                 st->quirks = finger->quirkdata.quirks;    /* start value */
     405           0 :                 st_loadquirks(st);
     406           0 :         }
     407           0 : }
     408             : 
     409             : /*
     410             :  * initialise the subdevices to the default (QUIRK) state.
     411             :  * this will remove any setting made by the system operator or previous
     412             :  * operations.
     413             :  */
     414             : void
     415           0 : st_loadquirks(struct st_softc *st)
     416             : {
     417             :         const struct    modes *mode;
     418             :         struct  modes *mode2;
     419             : 
     420           0 :         mode = &st->quirkdata->modes;
     421           0 :         mode2 = &st->modes;
     422           0 :         bzero(mode2, sizeof(struct modes));
     423           0 :         st->modeflags &= ~(BLKSIZE_SET_BY_QUIRK |
     424             :             DENSITY_SET_BY_QUIRK | BLKSIZE_SET_BY_USER |
     425             :             DENSITY_SET_BY_USER);
     426           0 :         if ((mode->quirks | st->drive_quirks) & ST_Q_FORCE_BLKSIZE) {
     427           0 :                 mode2->blksize = mode->blksize;
     428           0 :                 st->modeflags |= BLKSIZE_SET_BY_QUIRK;
     429           0 :         }
     430           0 :         if (mode->density) {
     431           0 :                 mode2->density = mode->density;
     432           0 :                 st->modeflags |= DENSITY_SET_BY_QUIRK;
     433           0 :         }
     434           0 : }
     435             : 
     436             : /*
     437             :  * open the device.
     438             :  */
     439             : int
     440           0 : stopen(dev_t dev, int flags, int fmt, struct proc *p)
     441             : {
     442             :         struct scsi_link *link;
     443             :         struct st_softc *st;
     444             :         int error = 0;
     445             : 
     446           0 :         st = stlookup(STUNIT(dev));
     447           0 :         if (st == NULL)
     448           0 :                 return (ENXIO);
     449           0 :         link = st->sc_link;
     450             : 
     451           0 :         if (st->flags & ST_DYING) {
     452             :                 error = ENXIO;
     453           0 :                 goto done;
     454             :         }
     455           0 :         if (ISSET(flags, FWRITE) && ISSET(link->flags, SDEV_READONLY)) {
     456             :                 error = EACCES;
     457           0 :                 goto done;
     458             :         }
     459             : 
     460             :         SC_DEBUG(link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
     461             :             STUNIT(dev), st_cd.cd_ndevs));
     462             : 
     463             :         /*
     464             :          * Tape is an exclusive media. Only one open at a time.
     465             :          */
     466           0 :         if (link->flags & SDEV_OPEN) {
     467             :                 SC_DEBUG(link, SDEV_DB4, ("already open\n"));
     468             :                 error = EBUSY;
     469           0 :                 goto done;
     470             :         }
     471             : 
     472             :         /* Use st_interpret_sense() now. */
     473           0 :         link->flags |= SDEV_OPEN;
     474             : 
     475             :         /*
     476             :          * Check the unit status. This clears any outstanding errors and
     477             :          * will ensure that media is present.
     478             :          */
     479           0 :         error = scsi_test_unit_ready(link, TEST_READY_RETRIES,
     480             :             SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE |
     481             :             SCSI_IGNORE_ILLEGAL_REQUEST);
     482             : 
     483             :         /*
     484             :          * Terminate any exising mount session if there is no media.
     485             :          */
     486           0 :         if ((link->flags & SDEV_MEDIA_LOADED) == 0)
     487           0 :                 st_unmount(st, NOEJECT, DOREWIND);
     488             : 
     489           0 :         if (error) {
     490           0 :                 link->flags &= ~SDEV_OPEN;
     491           0 :                 goto done;
     492             :         }
     493             : 
     494           0 :         if ((st->flags & ST_MOUNTED) == 0) {
     495           0 :                 error = st_mount_tape(dev, flags);
     496           0 :                 if (error) {
     497           0 :                         link->flags &= ~SDEV_OPEN;
     498           0 :                         goto done;
     499             :                 }
     500             :         }
     501             : 
     502             :         /*
     503             :          * Make sure that a tape opened in write-only mode will have
     504             :          * file marks written on it when closed, even if not written to.
     505             :          * This is for SUN compatibility
     506             :          */
     507           0 :         if ((flags & O_ACCMODE) == FWRITE)
     508           0 :                 st->flags |= ST_WRITTEN;
     509             : 
     510             : done:
     511             :         SC_DEBUG(link, SDEV_DB2, ("open complete\n"));
     512           0 :         device_unref(&st->sc_dev);
     513           0 :         return (error);
     514           0 : }
     515             : 
     516             : /*
     517             :  * close the device.. only called if we are the LAST
     518             :  * occurrence of an open device
     519             :  */
     520             : int
     521           0 : stclose(dev_t dev, int flags, int mode, struct proc *p)
     522             : {
     523             :         struct scsi_link *link;
     524             :         struct st_softc *st;
     525             :         int error = 0;
     526             : 
     527           0 :         st = stlookup(STUNIT(dev));
     528           0 :         if (st == NULL)
     529           0 :                 return (ENXIO);
     530           0 :         if (st->flags & ST_DYING) {
     531             :                 error = ENXIO;
     532           0 :                 goto done;
     533             :         }
     534           0 :         link = st->sc_link;
     535             : 
     536             :         SC_DEBUG(link, SDEV_DB1, ("closing\n"));
     537             : 
     538           0 :         if ((st->flags & (ST_WRITTEN | ST_FM_WRITTEN)) == ST_WRITTEN)
     539           0 :                 st_write_filemarks(st, 1, 0);
     540             : 
     541           0 :         switch (STMODE(dev)) {
     542             :         case 0:         /* normal */
     543           0 :                 st_unmount(st, NOEJECT, DOREWIND);
     544           0 :                 break;
     545             :         case 3:         /* eject, no rewind */
     546           0 :                 st_unmount(st, EJECT, NOREWIND);
     547           0 :                 break;
     548             :         case 1:         /* no rewind */
     549             :                 /* leave mounted unless media seems to have been removed */
     550           0 :                 if (!(link->flags & SDEV_MEDIA_LOADED))
     551           0 :                         st_unmount(st, NOEJECT, NOREWIND);
     552             :                 break;
     553             :         case 2:         /* rewind, eject */
     554           0 :                 st_unmount(st, EJECT, DOREWIND);
     555           0 :                 break;
     556             :         }
     557           0 :         link->flags &= ~SDEV_OPEN;
     558           0 :         timeout_del(&st->sc_timeout);
     559           0 :         scsi_xsh_del(&st->sc_xsh);
     560             : 
     561             : done:
     562           0 :         device_unref(&st->sc_dev);
     563           0 :         return (error);
     564           0 : }
     565             : 
     566             : /*
     567             :  * Start a new mount session.
     568             :  * Copy in all the default parameters from the selected device mode.
     569             :  * and try guess any that seem to be defaulted.
     570             :  */
     571             : int
     572           0 : st_mount_tape(dev_t dev, int flags)
     573             : {
     574             :         struct st_softc *st;
     575             :         struct scsi_link *link;
     576             :         int error = 0;
     577             : 
     578           0 :         st = stlookup(STUNIT(dev));
     579           0 :         if (st == NULL)
     580           0 :                 return (ENXIO);
     581           0 :         if (st->flags & ST_DYING) {
     582             :                 error = ENXIO;
     583           0 :                 goto done;
     584             :         }
     585           0 :         link = st->sc_link;
     586             : 
     587             :         SC_DEBUG(link, SDEV_DB1, ("mounting\n"));
     588             : 
     589           0 :         if (st->flags & ST_MOUNTED)
     590             :                 goto done;
     591             : 
     592           0 :         st->quirks = st->drive_quirks | st->modes.quirks;
     593             :         /*
     594             :          * If the media is new, then make sure we give it a chance to
     595             :          * to do a 'load' instruction.  (We assume it is new.)
     596             :          */
     597           0 :         if ((error = st_load(st, LD_LOAD, 0)) != 0)
     598             :                 goto done;
     599             : 
     600             :         /*
     601             :          * Throw another dummy instruction to catch
     602             :          * 'Unit attention' errors. Some drives appear to give
     603             :          * these after doing a Load instruction.
     604             :          * (noteably some DAT drives)
     605             :          */
     606             :         /* XXX */
     607           0 :         scsi_test_unit_ready(link, TEST_READY_RETRIES, SCSI_SILENT);
     608             : 
     609             :         /*
     610             :          * Some devices can't tell you much until they have been
     611             :          * asked to look at the media. This quirk does this.
     612             :          */
     613           0 :         if (st->quirks & ST_Q_SENSE_HELP)
     614           0 :                 if ((error = st_touch_tape(st)) != 0)
     615           0 :                         return error;
     616             :         /*
     617             :          * Load the physical device parameters
     618             :          * loads: blkmin, blkmax
     619             :          */
     620           0 :         if (!(link->flags & SDEV_ATAPI) &&
     621           0 :             (error = st_read_block_limits(st, 0)) != 0)
     622             :                 goto done;
     623             : 
     624             :         /*
     625             :          * Load the media dependent parameters
     626             :          * includes: media_blksize,media_density,numblks
     627             :          * As we have a tape in, it should be reflected here.
     628             :          * If not you may need the "quirk" above.
     629             :          */
     630           0 :         if ((error = st_mode_sense(st, 0)) != 0)
     631             :                 goto done;
     632             : 
     633             :         /*
     634             :          * If we have gained a permanent density from somewhere,
     635             :          * then use it in preference to the one supplied by
     636             :          * default by the driver.
     637             :          */
     638           0 :         if (st->modeflags & (DENSITY_SET_BY_QUIRK | DENSITY_SET_BY_USER))
     639           0 :                 st->density = st->modes.density;
     640             :         else
     641           0 :                 st->density = st->media_density;
     642             :         /*
     643             :          * If we have gained a permanent blocksize
     644             :          * then use it in preference to the one supplied by
     645             :          * default by the driver.
     646             :          */
     647           0 :         st->flags &= ~ST_FIXEDBLOCKS;
     648           0 :         if (st->modeflags & (BLKSIZE_SET_BY_QUIRK | BLKSIZE_SET_BY_USER)) {
     649           0 :                 st->blksize = st->modes.blksize;
     650           0 :                 if (st->blksize)
     651           0 :                         st->flags |= ST_FIXEDBLOCKS;
     652             :         } else {
     653           0 :                 if ((error = st_decide_mode(st, 0)) != 0)
     654             :                         goto done;
     655             :         }
     656           0 :         if ((error = st_mode_select(st, 0)) != 0) {
     657           0 :                 printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
     658           0 :                 goto done;
     659             :         }
     660           0 :         scsi_prevent(link, PR_PREVENT,
     661             :             SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
     662           0 :         st->flags |= ST_MOUNTED;
     663           0 :         link->flags |= SDEV_MEDIA_LOADED;    /* move earlier? */
     664           0 :         st->media_fileno = 0;
     665           0 :         st->media_blkno = 0;
     666           0 :         st->media_eom = -1;
     667             : 
     668             : done:
     669           0 :         device_unref(&st->sc_dev);
     670           0 :         return (error);
     671           0 : }
     672             : 
     673             : /*
     674             :  * End the present mount session.
     675             :  * Rewind, and optionally eject the tape.
     676             :  * Reset various flags to indicate that all new
     677             :  * operations require another mount operation
     678             :  */
     679             : void
     680           0 : st_unmount(struct st_softc *st, int eject, int rewind)
     681             : {
     682           0 :         struct scsi_link *link = st->sc_link;
     683           0 :         int nmarks;
     684             : 
     685           0 :         st->media_fileno = -1;
     686           0 :         st->media_blkno = -1;
     687             : 
     688           0 :         if (!(st->flags & ST_MOUNTED))
     689           0 :                 return;
     690             :         SC_DEBUG(link, SDEV_DB1, ("unmounting\n"));
     691           0 :         st_check_eod(st, 0, &nmarks, SCSI_IGNORE_NOT_READY);
     692           0 :         if (rewind)
     693           0 :                 st_rewind(st, 0, SCSI_IGNORE_NOT_READY);
     694           0 :         scsi_prevent(link, PR_ALLOW,
     695             :             SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
     696           0 :         if (eject)
     697           0 :                 st_load(st, LD_UNLOAD, SCSI_IGNORE_NOT_READY);
     698           0 :         st->flags &= ~ST_MOUNTED;
     699           0 :         link->flags &= ~SDEV_MEDIA_LOADED;
     700           0 : }
     701             : 
     702             : /*
     703             :  * Given all we know about the device, media, mode, 'quirks' and
     704             :  * initial operation, make a decision as to how we should be set
     705             :  * to run (regarding blocking and EOD marks)
     706             :  */
     707             : int
     708           0 : st_decide_mode(struct st_softc *st, int first_read)
     709             : {
     710           0 :         struct scsi_link *link = st->sc_link;
     711             : 
     712             :         SC_DEBUG(link, SDEV_DB2, ("starting block mode decision\n"));
     713             : 
     714             :         /* ATAPI tapes are always fixed blocksize. */
     715           0 :         if (link->flags & SDEV_ATAPI) {
     716           0 :                 st->flags |= ST_FIXEDBLOCKS;
     717           0 :                 if (st->media_blksize > 0)
     718           0 :                         st->blksize = st->media_blksize;
     719             :                 else
     720           0 :                         st->blksize = DEF_FIXED_BSIZE;
     721             :                 goto done;
     722             :         }
     723             : 
     724             :         /*
     725             :          * If the drive can only handle fixed-length blocks and only at
     726             :          * one size, perhaps we should just do that.
     727             :          */
     728           0 :         if (st->blkmin && (st->blkmin == st->blkmax)) {
     729           0 :                 st->flags |= ST_FIXEDBLOCKS;
     730           0 :                 st->blksize = st->blkmin;
     731             :                 SC_DEBUG(link, SDEV_DB3,
     732             :                     ("blkmin == blkmax of %d\n", st->blkmin));
     733           0 :                 goto done;
     734             :         }
     735             :         /*
     736             :          * If the tape density mandates (or even suggests) use of fixed
     737             :          * or variable-length blocks, comply.
     738             :          */
     739           0 :         switch (st->density) {
     740             :         case HALFINCH_800:
     741             :         case HALFINCH_1600:
     742             :         case HALFINCH_6250:
     743             :         case DDS:
     744           0 :                 st->flags &= ~ST_FIXEDBLOCKS;
     745           0 :                 st->blksize = 0;
     746             :                 SC_DEBUG(link, SDEV_DB3, ("density specified variable\n"));
     747           0 :                 goto done;
     748             :         case QIC_11:
     749             :         case QIC_24:
     750             :         case QIC_120:
     751             :         case QIC_150:
     752             :         case QIC_525:
     753             :         case QIC_1320:
     754           0 :                 st->flags |= ST_FIXEDBLOCKS;
     755           0 :                 if (st->media_blksize > 0)
     756           0 :                         st->blksize = st->media_blksize;
     757             :                 else
     758           0 :                         st->blksize = DEF_FIXED_BSIZE;
     759             :                 SC_DEBUG(link, SDEV_DB3, ("density specified fixed\n"));
     760             :                 goto done;
     761             :         }
     762             :         /*
     763             :          * If we're about to read the tape, perhaps we should choose
     764             :          * fixed or variable-length blocks and block size according to
     765             :          * what the drive found on the tape.
     766             :          */
     767           0 :         if (first_read &&
     768           0 :             (!(st->quirks & ST_Q_BLKSIZE) || (st->media_blksize == 0) ||
     769           0 :             (st->media_blksize == DEF_FIXED_BSIZE) ||
     770           0 :             (st->media_blksize == 1024))) {
     771           0 :                 if (st->media_blksize > 0)
     772           0 :                         st->flags |= ST_FIXEDBLOCKS;
     773             :                 else
     774           0 :                         st->flags &= ~ST_FIXEDBLOCKS;
     775           0 :                 st->blksize = st->media_blksize;
     776             :                 SC_DEBUG(link, SDEV_DB3,
     777             :                     ("Used media_blksize of %d\n", st->media_blksize));
     778           0 :                 goto done;
     779             :         }
     780             :         /*
     781             :          * We're getting no hints from any direction.  Choose variable-
     782             :          * length blocks arbitrarily.
     783             :          */
     784           0 :         st->flags &= ~ST_FIXEDBLOCKS;
     785           0 :         st->blksize = 0;
     786             :         SC_DEBUG(link, SDEV_DB3,
     787             :             ("Give up and default to variable mode\n"));
     788             : 
     789             : done:
     790             :         /*
     791             :          * Decide whether or not to write two file marks to signify end-
     792             :          * of-data.  Make the decision as a function of density.  If
     793             :          * the decision is not to use a second file mark, the SCSI BLANK
     794             :          * CHECK condition code will be recognized as end-of-data when
     795             :          * first read.
     796             :          * (I think this should be a by-product of fixed/variable..julian)
     797             :          */
     798           0 :         switch (st->density) {
     799             : /*      case 8 mm:   What is the SCSI density code for 8 mm, anyway? */
     800             :         case QIC_11:
     801             :         case QIC_24:
     802             :         case QIC_120:
     803             :         case QIC_150:
     804             :         case QIC_525:
     805             :         case QIC_1320:
     806           0 :                 st->flags &= ~ST_2FM_AT_EOD;
     807           0 :                 break;
     808             :         default:
     809           0 :                 st->flags |= ST_2FM_AT_EOD;
     810           0 :         }
     811           0 :         return 0;
     812             : }
     813             : 
     814             : /*
     815             :  * Actually translate the requested transfer into
     816             :  * one the physical driver can understand
     817             :  * The transfer is described by a buf and will include
     818             :  * only one physical transfer.
     819             :  */
     820             : void
     821           0 : ststrategy(struct buf *bp)
     822             : {
     823             :         struct scsi_link *link;
     824             :         struct st_softc *st;
     825             :         int s;
     826             : 
     827           0 :         st = stlookup(STUNIT(bp->b_dev));
     828           0 :         if (st == NULL) {
     829           0 :                 bp->b_error = ENXIO;
     830           0 :                 goto bad;
     831             :         }
     832           0 :         if (st->flags & ST_DYING) {
     833           0 :                 bp->b_error = ENXIO;
     834           0 :                 goto bad;
     835             :         }
     836             : 
     837           0 :         link = st->sc_link;
     838             : 
     839             :         SC_DEBUG(link, SDEV_DB2, ("ststrategy: %ld bytes @ blk %lld\n",
     840             :             bp->b_bcount, (long long)bp->b_blkno));
     841             : 
     842             :         /*
     843             :          * If it's a null transfer, return immediately.
     844             :          */
     845           0 :         if (bp->b_bcount == 0)
     846             :                 goto done;
     847             :         /*
     848             :          * Odd sized request on fixed drives are verboten
     849             :          */
     850           0 :         if (st->flags & ST_FIXEDBLOCKS) {
     851           0 :                 if (bp->b_bcount % st->blksize) {
     852           0 :                         printf("%s: bad request, must be multiple of %d\n",
     853           0 :                             st->sc_dev.dv_xname, st->blksize);
     854           0 :                         bp->b_error = EIO;
     855           0 :                         goto bad;
     856             :                 }
     857             :         }
     858             :         /*
     859             :          * as are out-of-range requests on variable drives.
     860             :          */
     861           0 :         else if (bp->b_bcount < st->blkmin ||
     862           0 :                  (st->blkmax && bp->b_bcount > st->blkmax)) {
     863           0 :                 printf("%s: bad request, must be between %d and %d\n",
     864           0 :                     st->sc_dev.dv_xname, st->blkmin, st->blkmax);
     865           0 :                 bp->b_error = EIO;
     866           0 :                 goto bad;
     867             :         }
     868             : 
     869             :         /*
     870             :          * Place it in the queue of activities for this tape
     871             :          * at the end (a bit silly because we only have on user..
     872             :          * (but it could fork()))
     873             :          */
     874           0 :         bufq_queue(&st->sc_bufq, bp);
     875             : 
     876             :         /*
     877             :          * Tell the device to get going on the transfer if it's
     878             :          * not doing anything, otherwise just wait for completion
     879             :          * (All a bit silly if we're only allowing 1 open but..)
     880             :          */
     881           0 :         scsi_xsh_add(&st->sc_xsh);
     882             : 
     883           0 :         device_unref(&st->sc_dev);
     884           0 :         return;
     885             : bad:
     886           0 :         bp->b_flags |= B_ERROR;
     887             : done:
     888             :         /* Set b_resid to indicate no xfer was done. */
     889           0 :         bp->b_resid = bp->b_bcount;
     890           0 :         s = splbio();
     891           0 :         biodone(bp);
     892           0 :         splx(s);
     893           0 :         if (st)
     894           0 :                 device_unref(&st->sc_dev);
     895           0 : }
     896             : 
     897             : void
     898           0 : ststart(struct scsi_xfer *xs)
     899             : {
     900           0 :         struct scsi_link *link = xs->sc_link;
     901           0 :         struct st_softc *st = link->device_softc;
     902             :         struct buf *bp;
     903             :         struct scsi_rw_tape *cmd;
     904             :         int s;
     905             : 
     906             :         SC_DEBUG(link, SDEV_DB2, ("ststart\n"));
     907             : 
     908           0 :         if (st->flags & ST_DYING) {
     909           0 :                 scsi_xs_put(xs);
     910           0 :                 return;
     911             :         }
     912             : 
     913             :         /*
     914             :          * if the device has been unmounted by the user
     915             :          * then throw away all requests until done
     916             :          */
     917           0 :         if (!(st->flags & ST_MOUNTED) ||
     918           0 :             !(link->flags & SDEV_MEDIA_LOADED)) {
     919             :                 /* make sure that one implies the other.. */
     920           0 :                 link->flags &= ~SDEV_MEDIA_LOADED;
     921           0 :                 bufq_drain(&st->sc_bufq);
     922           0 :                 scsi_xs_put(xs);
     923           0 :                 return;
     924             :         }
     925             : 
     926           0 :         for (;;) {
     927           0 :                 bp = bufq_dequeue(&st->sc_bufq);
     928           0 :                 if (bp == NULL) {
     929           0 :                         scsi_xs_put(xs);
     930           0 :                         return;
     931             :                 }
     932             : 
     933             :                 /*
     934             :                  * Only FIXEDBLOCK devices have pending I/O or space
     935             :                  * operations.
     936             :                  */
     937           0 :                 if (st->flags & ST_FIXEDBLOCKS) {
     938             :                         /*
     939             :                          * If we are at a filemark but have not reported it yet
     940             :                          * then we should report it now
     941             :                          */
     942           0 :                         if (st->flags & ST_AT_FILEMARK) {
     943           0 :                                 if ((bp->b_flags & B_READ) == B_WRITE) {
     944             :                                         /*
     945             :                                          * Handling of ST_AT_FILEMARK in
     946             :                                          * st_space will fill in the right file
     947             :                                          * mark count.
     948             :                                          * Back up over filemark
     949             :                                          */
     950           0 :                                         if (st_space(st, 0, SP_FILEMARKS, 0)) {
     951           0 :                                                 bp->b_flags |= B_ERROR;
     952           0 :                                                 bp->b_resid = bp->b_bcount;
     953           0 :                                                 bp->b_error = EIO;
     954           0 :                                                 s = splbio();
     955           0 :                                                 biodone(bp);
     956           0 :                                                 splx(s);
     957           0 :                                                 continue;
     958             :                                         }
     959             :                                 } else {
     960           0 :                                         bp->b_resid = bp->b_bcount;
     961           0 :                                         bp->b_error = 0;
     962           0 :                                         bp->b_flags &= ~B_ERROR;
     963           0 :                                         st->flags &= ~ST_AT_FILEMARK;
     964           0 :                                         s = splbio();
     965           0 :                                         biodone(bp);
     966           0 :                                         splx(s);
     967           0 :                                         continue;       /* seek more work */
     968             :                                 }
     969             :                         }
     970             :                 }
     971             : 
     972             :                 /*
     973             :                  * If we are at EIO or EOM but have not reported it
     974             :                  * yet then we should report it now.
     975             :                  */
     976           0 :                 if (st->flags & (ST_EOM_PENDING | ST_EIO_PENDING)) {
     977           0 :                         bp->b_resid = bp->b_bcount;
     978           0 :                         if (st->flags & ST_EIO_PENDING) {
     979           0 :                                 bp->b_error = EIO;
     980           0 :                                 bp->b_flags |= B_ERROR;
     981           0 :                         }
     982           0 :                         st->flags &= ~(ST_EOM_PENDING | ST_EIO_PENDING);
     983           0 :                         s = splbio();
     984           0 :                         biodone(bp);
     985           0 :                         splx(s);
     986           0 :                         continue;       /* seek more work */
     987             :                 }
     988             :                 break;
     989             :         }
     990             : 
     991             :         /*
     992             :          *  Fill out the scsi command
     993             :          */
     994           0 :         cmd = (struct scsi_rw_tape *)xs->cmd;
     995           0 :         bzero(cmd, sizeof(*cmd));
     996           0 :         if ((bp->b_flags & B_READ) == B_WRITE) {
     997           0 :                 cmd->opcode = WRITE;
     998           0 :                 st->flags &= ~ST_FM_WRITTEN;
     999           0 :                 st->flags |= ST_WRITTEN;
    1000           0 :                 xs->flags |= SCSI_DATA_OUT;
    1001           0 :         } else {
    1002           0 :                 cmd->opcode = READ;
    1003           0 :                 xs->flags |= SCSI_DATA_IN;
    1004             :         }
    1005             : 
    1006             :         /*
    1007             :          * Handle "fixed-block-mode" tape drives by using the
    1008             :          * block count instead of the length.
    1009             :          */
    1010           0 :         if (st->flags & ST_FIXEDBLOCKS) {
    1011           0 :                 cmd->byte2 |= SRW_FIXED;
    1012           0 :                 _lto3b(bp->b_bcount / st->blksize, cmd->len);
    1013           0 :         } else
    1014           0 :                 _lto3b(bp->b_bcount, cmd->len);
    1015             : 
    1016           0 :         if (st->media_blkno != -1) {
    1017             :                 /* Update block count now, errors will set it to -1. */
    1018           0 :                 if (st->flags & ST_FIXEDBLOCKS)
    1019           0 :                         st->media_blkno += _3btol(cmd->len);
    1020           0 :                 else if (_3btol(cmd->len) != 0)
    1021           0 :                         st->media_blkno++;
    1022             :         }
    1023             : 
    1024           0 :         xs->cmdlen = sizeof(*cmd);
    1025           0 :         xs->timeout = ST_IO_TIME;
    1026           0 :         xs->data = bp->b_data;
    1027           0 :         xs->datalen = bp->b_bcount;
    1028           0 :         xs->done = st_buf_done;
    1029           0 :         xs->cookie = bp;
    1030           0 :         xs->bp = bp;
    1031             : 
    1032             :         /*
    1033             :          * go ask the adapter to do all this for us
    1034             :          */
    1035           0 :         scsi_xs_exec(xs);
    1036             : 
    1037             :         /*
    1038             :          * should we try do more work now?
    1039             :          */
    1040           0 :         if (ISSET(st->flags, ST_WAITING))
    1041           0 :                 CLR(st->flags, ST_WAITING);
    1042           0 :         else if (bufq_peek(&st->sc_bufq))
    1043           0 :                 scsi_xsh_add(&st->sc_xsh);
    1044           0 : }
    1045             : 
    1046             : void
    1047           0 : st_buf_done(struct scsi_xfer *xs)
    1048             : {
    1049           0 :         struct buf *bp = xs->cookie;
    1050             :         int error, s;
    1051             : 
    1052           0 :         switch (xs->error) {
    1053             :         case XS_NOERROR:
    1054           0 :                 bp->b_error = 0;
    1055           0 :                 bp->b_resid = xs->resid;
    1056           0 :                 break;
    1057             : 
    1058             :         case XS_SENSE:
    1059             :         case XS_SHORTSENSE:
    1060             : #ifdef SCSIDEBUG
    1061             :                 scsi_sense_print_debug(xs);
    1062             : #endif
    1063           0 :                 error = st_interpret_sense(xs);
    1064           0 :                 if (error == 0) {
    1065           0 :                         bp->b_error = 0;
    1066           0 :                         bp->b_resid = xs->resid;
    1067           0 :                         break;
    1068             :                 }
    1069           0 :                 if (error != ERESTART)
    1070           0 :                         xs->retries = 0;
    1071             :                 goto retry;
    1072             : 
    1073             :         case XS_BUSY:
    1074           0 :                 if (xs->retries) {
    1075           0 :                         if (scsi_delay(xs, 1) != ERESTART)
    1076           0 :                                 xs->retries = 0;
    1077             :                 }
    1078             :                 goto retry;
    1079             : 
    1080             :         case XS_TIMEOUT:
    1081             : retry:
    1082           0 :                 if (xs->retries--) {
    1083           0 :                         scsi_xs_exec(xs);
    1084           0 :                         return;
    1085             :                 }
    1086             :                 /* FALLTHROUGH */
    1087             : 
    1088             :         default:
    1089           0 :                 bp->b_error = EIO;
    1090           0 :                 bp->b_flags |= B_ERROR;
    1091           0 :                 bp->b_resid = bp->b_bcount;
    1092           0 :                 break;
    1093             :         }
    1094             : 
    1095           0 :         s = splbio();
    1096           0 :         biodone(bp);
    1097           0 :         splx(s);
    1098           0 :         scsi_xs_put(xs);
    1099           0 : }
    1100             : 
    1101             : void
    1102           0 : stminphys(struct buf *bp)
    1103             : {
    1104             :         struct st_softc *st;
    1105             : 
    1106           0 :         st = stlookup(STUNIT(bp->b_dev));
    1107           0 :         if (st == NULL)
    1108           0 :                 return;
    1109             : 
    1110           0 :         (*st->sc_link->adapter->scsi_minphys)(bp, st->sc_link);
    1111             : 
    1112           0 :         device_unref(&st->sc_dev);
    1113           0 : }
    1114             : 
    1115             : int
    1116           0 : stread(dev_t dev, struct uio *uio, int iomode)
    1117             : {
    1118           0 :         return (physio(ststrategy, dev, B_READ, stminphys, uio));
    1119             : }
    1120             : 
    1121             : int
    1122           0 : stwrite(dev_t dev, struct uio *uio, int iomode)
    1123             : {
    1124           0 :         return (physio(ststrategy, dev, B_WRITE, stminphys, uio));
    1125             : }
    1126             : 
    1127             : /*
    1128             :  * Perform special action on behalf of the user;
    1129             :  * knows about the internals of this device
    1130             :  */
    1131             : int
    1132           0 : stioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
    1133             : {
    1134             :         int error = 0;
    1135           0 :         int nmarks;
    1136             :         int flags = 0;
    1137             :         struct st_softc *st;
    1138             :         int hold_blksize;
    1139             :         u_int8_t hold_density;
    1140           0 :         struct mtop *mt = (struct mtop *) arg;
    1141             :         int number;
    1142             : 
    1143             :         /*
    1144             :          * Find the device that the user is talking about
    1145             :          */
    1146           0 :         st = stlookup(STUNIT(dev));
    1147           0 :         if (st == NULL)
    1148           0 :                 return (ENXIO);
    1149             : 
    1150           0 :         if (st->flags & ST_DYING) {
    1151             :                 error = ENXIO;
    1152           0 :                 goto done;
    1153             :         }
    1154             : 
    1155           0 :         hold_blksize = st->blksize;
    1156           0 :         hold_density = st->density;
    1157             : 
    1158           0 :         switch (cmd) {
    1159             : 
    1160             :         case MTIOCGET: {
    1161           0 :                 struct mtget *g = (struct mtget *) arg;
    1162             : 
    1163             :                 /*
    1164             :                  * (to get the current state of READONLY)
    1165             :                  */
    1166           0 :                 error = st_mode_sense(st, SCSI_SILENT);
    1167           0 :                 if (error)
    1168           0 :                         break;
    1169             : 
    1170             :                 SC_DEBUG(st->sc_link, SDEV_DB1, ("[ioctl: get status]\n"));
    1171           0 :                 bzero(g, sizeof(struct mtget));
    1172           0 :                 g->mt_type = 0x7;    /* Ultrix compat *//*? */
    1173           0 :                 g->mt_blksiz = st->blksize;
    1174           0 :                 g->mt_density = st->density;
    1175           0 :                 g->mt_mblksiz = st->modes.blksize;
    1176           0 :                 g->mt_mdensity = st->modes.density;
    1177           0 :                 if (st->sc_link->flags & SDEV_READONLY)
    1178           0 :                         g->mt_dsreg |= MT_DS_RDONLY;
    1179           0 :                 if (st->flags & ST_MOUNTED)
    1180           0 :                         g->mt_dsreg |= MT_DS_MOUNTED;
    1181           0 :                 g->mt_resid = st->mt_resid;
    1182           0 :                 g->mt_erreg = st->mt_erreg;
    1183           0 :                 g->mt_fileno = st->media_fileno;
    1184           0 :                 g->mt_blkno = st->media_blkno;
    1185             :                 /*
    1186             :                  * clear latched errors.
    1187             :                  */
    1188           0 :                 st->mt_resid = 0;
    1189           0 :                 st->mt_erreg = 0;
    1190           0 :                 break;
    1191             :         }
    1192             :         case MTIOCTOP: {
    1193             : 
    1194             :                 SC_DEBUG(st->sc_link, SDEV_DB1,
    1195             :                     ("[ioctl: op=0x%x count=0x%x]\n", mt->mt_op, mt->mt_count));
    1196             : 
    1197           0 :                 number = mt->mt_count;
    1198           0 :                 switch (mt->mt_op) {
    1199             :                 case MTWEOF:    /* write an end-of-file record */
    1200           0 :                         error = st_write_filemarks(st, number, flags);
    1201           0 :                         break;
    1202             :                 case MTBSF:     /* backward space file */
    1203           0 :                         number = -number;
    1204             :                 case MTFSF:     /* forward space file */
    1205           0 :                         error = st_check_eod(st, 0, &nmarks, flags);
    1206           0 :                         if (!error)
    1207           0 :                                 error = st_space(st, number - nmarks,
    1208             :                                     SP_FILEMARKS, flags);
    1209             :                         break;
    1210             :                 case MTBSR:     /* backward space record */
    1211           0 :                         number = -number;
    1212             :                 case MTFSR:     /* forward space record */
    1213           0 :                         error = st_check_eod(st, 1, &nmarks, flags);
    1214           0 :                         if (!error)
    1215           0 :                                 error = st_space(st, number, SP_BLKS, flags);
    1216             :                         break;
    1217             :                 case MTREW:     /* rewind */
    1218           0 :                         error = st_rewind(st, 0, flags);
    1219           0 :                         break;
    1220             :                 case MTOFFL:    /* rewind and put the drive offline */
    1221           0 :                         st_unmount(st, EJECT, DOREWIND);
    1222           0 :                         break;
    1223             :                 case MTNOP:     /* no operation, sets status only */
    1224             :                         break;
    1225             :                 case MTRETEN:   /* retension the tape */
    1226           0 :                         error = st_load(st, LD_RETENSION, flags);
    1227           0 :                         if (!error)
    1228           0 :                                 error = st_load(st, LD_LOAD, flags);
    1229             :                         break;
    1230             :                 case MTEOM:     /* forward space to end of media */
    1231           0 :                         error = st_check_eod(st, 0, &nmarks, flags);
    1232           0 :                         if (!error)
    1233           0 :                                 error = st_space(st, 1, SP_EOM, flags);
    1234             :                         break;
    1235             :                 case MTCACHE:   /* enable controller cache */
    1236           0 :                         st->flags &= ~ST_DONTBUFFER;
    1237           0 :                         goto try_new_value;
    1238             :                 case MTNOCACHE: /* disable controller cache */
    1239           0 :                         st->flags |= ST_DONTBUFFER;
    1240           0 :                         goto try_new_value;
    1241             :                 case MTERASE:   /* erase volume */
    1242           0 :                         error = st_erase(st, number, flags);
    1243           0 :                         break;
    1244             :                 case MTSETBSIZ: /* Set block size for device */
    1245           0 :                         if (number == 0) {
    1246           0 :                                 st->flags &= ~ST_FIXEDBLOCKS;
    1247           0 :                         } else {
    1248           0 :                                 if ((st->blkmin || st->blkmax) &&
    1249           0 :                                     (number < st->blkmin ||
    1250           0 :                                     number > st->blkmax)) {
    1251             :                                         error = EINVAL;
    1252           0 :                                         break;
    1253             :                                 }
    1254           0 :                                 st->flags |= ST_FIXEDBLOCKS;
    1255             :                         }
    1256           0 :                         st->blksize = number;
    1257           0 :                         st->flags |= ST_BLOCK_SET;   /*XXX */
    1258           0 :                         goto try_new_value;
    1259             : 
    1260             :                 case MTSETDNSTY:        /* Set density for device and mode */
    1261           0 :                         if (number < 0 || number > SCSI_MAX_DENSITY_CODE) {
    1262             :                                 error = EINVAL;
    1263           0 :                                 break;
    1264             :                         } else
    1265           0 :                                 st->density = number;
    1266           0 :                         goto try_new_value;
    1267             : 
    1268             :                 default:
    1269             :                         error = EINVAL;
    1270           0 :                 }
    1271             :                 break;
    1272             :         }
    1273             :         case MTIOCIEOT:
    1274             :         case MTIOCEEOT:
    1275             :                 break;
    1276             : 
    1277             : #if 0
    1278             :         case MTIOCRDSPOS:
    1279             :                 error = st_rdpos(st, 0, (u_int32_t *) arg);
    1280             :                 break;
    1281             : 
    1282             :         case MTIOCRDHPOS:
    1283             :                 error = st_rdpos(st, 1, (u_int32_t *) arg);
    1284             :                 break;
    1285             : 
    1286             :         case MTIOCSLOCATE:
    1287             :                 error = st_setpos(st, 0, (u_int32_t *) arg);
    1288             :                 break;
    1289             : 
    1290             :         case MTIOCHLOCATE:
    1291             :                 error = st_setpos(st, 1, (u_int32_t *) arg);
    1292             :                 break;
    1293             : #endif
    1294             : 
    1295             :         default:
    1296           0 :                 error = scsi_do_ioctl(st->sc_link, cmd, arg, flag);
    1297           0 :                 break;
    1298             :         }
    1299             :         goto done;
    1300             : 
    1301             : try_new_value:
    1302             :         /*
    1303             :          * Check that the mode being asked for is aggreeable to the
    1304             :          * drive. If not, put it back the way it was.
    1305             :          */
    1306           0 :         if ((error = st_mode_select(st, 0)) != 0) {/* put it back as it was */
    1307           0 :                 printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
    1308           0 :                 st->density = hold_density;
    1309           0 :                 st->blksize = hold_blksize;
    1310           0 :                 if (st->blksize)
    1311           0 :                         st->flags |= ST_FIXEDBLOCKS;
    1312             :                 else
    1313           0 :                         st->flags &= ~ST_FIXEDBLOCKS;
    1314             :                 goto done;
    1315             :         }
    1316             :         /*
    1317             :          * As the drive liked it, if we are setting a new default,
    1318             :          * set it into the structures as such.
    1319             :          */
    1320           0 :         switch (mt->mt_op) {
    1321             :         case MTSETBSIZ:
    1322           0 :                 st->modes.blksize = st->blksize;
    1323           0 :                 st->modeflags |= BLKSIZE_SET_BY_USER;
    1324           0 :                 break;
    1325             :         case MTSETDNSTY:
    1326           0 :                 st->modes.density = st->density;
    1327           0 :                 st->modeflags |= DENSITY_SET_BY_USER;
    1328           0 :                 break;
    1329             :         }
    1330             : 
    1331             : done:
    1332           0 :         device_unref(&st->sc_dev);
    1333           0 :         return (error);
    1334           0 : }
    1335             : 
    1336             : /*
    1337             :  * Do a synchronous read.
    1338             :  */
    1339             : int
    1340           0 : st_read(struct st_softc *st, char *buf, int size, int flags)
    1341             : {
    1342             :         struct scsi_rw_tape *cmd;
    1343             :         struct scsi_xfer *xs;
    1344             :         int error;
    1345             : 
    1346           0 :         if (size == 0)
    1347           0 :                 return 0;
    1348             : 
    1349           0 :         xs = scsi_xs_get(st->sc_link, flags | SCSI_DATA_IN);
    1350           0 :         if (xs == NULL)
    1351           0 :                 return (ENOMEM);
    1352           0 :         xs->cmdlen = sizeof(*cmd);
    1353           0 :         xs->data = buf;
    1354           0 :         xs->datalen = size;
    1355           0 :         xs->retries = 0;
    1356           0 :         xs->timeout = ST_IO_TIME;
    1357             : 
    1358           0 :         cmd = (struct scsi_rw_tape *)xs->cmd;
    1359           0 :         cmd->opcode = READ;
    1360           0 :         if (st->flags & ST_FIXEDBLOCKS) {
    1361           0 :                 cmd->byte2 |= SRW_FIXED;
    1362           0 :                 _lto3b(size / (st->blksize ? st->blksize : DEF_FIXED_BSIZE),
    1363           0 :                     cmd->len);
    1364           0 :         } else
    1365           0 :                 _lto3b(size, cmd->len);
    1366             : 
    1367           0 :         error = scsi_xs_sync(xs);
    1368           0 :         scsi_xs_put(xs);
    1369             : 
    1370           0 :         return (error);
    1371           0 : }
    1372             : 
    1373             : /*
    1374             :  * Ask the drive what its min and max blk sizes are.
    1375             :  */
    1376             : int
    1377           0 : st_read_block_limits(struct st_softc *st, int flags)
    1378             : {
    1379             :         struct scsi_block_limits_data *block_limits = NULL;
    1380             :         struct scsi_block_limits *cmd;
    1381           0 :         struct scsi_link *link = st->sc_link;
    1382             :         struct scsi_xfer *xs;
    1383             :         int error = 0;
    1384             : 
    1385           0 :         if ((link->flags & SDEV_MEDIA_LOADED))
    1386           0 :                 return (0);
    1387             : 
    1388           0 :         block_limits = dma_alloc(sizeof(*block_limits), PR_NOWAIT);
    1389           0 :         if (block_limits == NULL)
    1390           0 :                 return (ENOMEM);
    1391             : 
    1392           0 :         xs = scsi_xs_get(link, flags | SCSI_DATA_IN);
    1393           0 :         if (xs == NULL) {
    1394             :                 error = ENOMEM;
    1395           0 :                 goto done;
    1396             :         }
    1397             : 
    1398           0 :         xs->cmdlen = sizeof(*cmd);
    1399           0 :         xs->data = (void *)block_limits;
    1400           0 :         xs->datalen = sizeof(*block_limits);
    1401           0 :         xs->timeout = ST_CTL_TIME;
    1402             : 
    1403           0 :         cmd = (struct scsi_block_limits *)xs->cmd;
    1404           0 :         cmd->opcode = READ_BLOCK_LIMITS;
    1405             : 
    1406           0 :         error = scsi_xs_sync(xs);
    1407           0 :         scsi_xs_put(xs);
    1408             : 
    1409           0 :         if (error == 0) {
    1410           0 :                 st->blkmin = _2btol(block_limits->min_length);
    1411           0 :                 st->blkmax = _3btol(block_limits->max_length);
    1412             :                 SC_DEBUG(link, SDEV_DB3,
    1413             :                     ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax));
    1414           0 :         }
    1415             : 
    1416             : done:
    1417           0 :         if (block_limits)
    1418           0 :                 dma_free(block_limits, sizeof(*block_limits));
    1419           0 :         return (error);
    1420           0 : }
    1421             : 
    1422             : /*
    1423             :  * Get the scsi driver to send a full inquiry to the
    1424             :  * device and use the results to fill out the global
    1425             :  * parameter structure.
    1426             :  *
    1427             :  * called from:
    1428             :  * attach
    1429             :  * open
    1430             :  * ioctl (to reset original blksize)
    1431             :  */
    1432             : int
    1433           0 : st_mode_sense(struct st_softc *st, int flags)
    1434             : {
    1435             :         union scsi_mode_sense_buf *data = NULL;
    1436           0 :         struct scsi_link *link = st->sc_link;
    1437           0 :         u_int64_t block_count;
    1438           0 :         u_int32_t density, block_size;
    1439           0 :         u_char *page0 = NULL;
    1440             :         u_int8_t dev_spec;
    1441           0 :         int error = 0, big;
    1442             : 
    1443           0 :         data = dma_alloc(sizeof(*data), PR_NOWAIT);
    1444           0 :         if (data == NULL)
    1445           0 :                 return (ENOMEM);
    1446             : 
    1447             :         /*
    1448             :          * Ask for page 0 (vendor specific) mode sense data.
    1449             :          */
    1450           0 :         error = scsi_do_mode_sense(link, 0, data, (void **)&page0,
    1451           0 :             &density, &block_count, &block_size, 1, flags | SCSI_SILENT, &big);
    1452           0 :         if (error != 0)
    1453             :                 goto done;
    1454             : 
    1455             :         /* It is valid for no page0 to be available. */
    1456             : 
    1457           0 :         if (big)
    1458           0 :                 dev_spec = data->hdr_big.dev_spec;
    1459             :         else
    1460           0 :                 dev_spec = data->hdr.dev_spec;
    1461             : 
    1462           0 :         if (dev_spec & SMH_DSP_WRITE_PROT)
    1463           0 :                 SET(link->flags, SDEV_READONLY);
    1464             :         else
    1465           0 :                 CLR(link->flags, SDEV_READONLY);
    1466             : 
    1467           0 :         st->numblks = block_count;
    1468           0 :         st->media_blksize = block_size;
    1469           0 :         st->media_density = density;
    1470             : 
    1471             :         SC_DEBUG(link, SDEV_DB3,
    1472             :             ("density code 0x%x, %d-byte blocks, write-%s, ",
    1473             :             st->media_density, st->media_blksize,
    1474             :             link->flags & SDEV_READONLY ? "protected" : "enabled"));
    1475             :         SC_DEBUGN(link, SDEV_DB3,
    1476             :             ("%sbuffered\n", dev_spec & SMH_DSP_BUFF_MODE ? "" : "un"));
    1477             : 
    1478           0 :         link->flags |= SDEV_MEDIA_LOADED;
    1479             : 
    1480             : done:
    1481           0 :         if (data)
    1482           0 :                 dma_free(data, sizeof(*data));
    1483           0 :         return (error);
    1484           0 : }
    1485             : 
    1486             : /*
    1487             :  * Send a filled out parameter structure to the drive to
    1488             :  * set it into the desire modes etc.
    1489             :  */
    1490             : int
    1491           0 : st_mode_select(struct st_softc *st, int flags)
    1492             : {
    1493             :         union scsi_mode_sense_buf *inbuf = NULL, *outbuf = NULL;
    1494           0 :         struct scsi_blk_desc general;
    1495           0 :         struct scsi_link *link = st->sc_link;
    1496           0 :         u_int8_t *page0 = NULL;
    1497           0 :         int error = 0, big, page0_size;
    1498             : 
    1499           0 :         inbuf = dma_alloc(sizeof(*inbuf), PR_NOWAIT);
    1500           0 :         if (inbuf == NULL) {
    1501             :                 error = ENOMEM;
    1502           0 :                 goto done;
    1503             :         }
    1504           0 :         outbuf = dma_alloc(sizeof(*outbuf), PR_NOWAIT | PR_ZERO);
    1505           0 :         if (outbuf == NULL) {
    1506             :                 error = ENOMEM;
    1507           0 :                 goto done;
    1508             :         }
    1509             : 
    1510             :         /*
    1511             :          * This quirk deals with drives that have only one valid mode and think
    1512             :          * this gives them license to reject all mode selects, even if the
    1513             :          * selected mode is the one that is supported.
    1514             :          */
    1515           0 :         if (st->quirks & ST_Q_UNIMODAL) {
    1516             :                 SC_DEBUG(link, SDEV_DB3,
    1517             :                     ("not setting density 0x%x blksize 0x%x\n",
    1518             :                     st->density, st->blksize));
    1519             :                 error = 0;
    1520           0 :                 goto done;
    1521             :         }
    1522             : 
    1523           0 :         if (link->flags & SDEV_ATAPI) {
    1524             :                 error = 0;
    1525           0 :                 goto done;
    1526             :         }
    1527             : 
    1528           0 :         bzero(&general, sizeof(general));
    1529             : 
    1530           0 :         general.density = st->density;
    1531           0 :         if (st->flags & ST_FIXEDBLOCKS)
    1532           0 :                 _lto3b(st->blksize, general.blklen);
    1533             : 
    1534             :         /*
    1535             :          * Ask for page 0 (vendor specific) mode sense data.
    1536             :          */
    1537           0 :         error = scsi_do_mode_sense(link, 0, inbuf, (void **)&page0, NULL,
    1538           0 :             NULL, NULL, 1, flags | SCSI_SILENT, &big);
    1539           0 :         if (error != 0)
    1540             :                 goto done;
    1541             : 
    1542           0 :         if (page0 == NULL) {
    1543             :                 page0_size = 0;
    1544           0 :         } else if (big == 0) {
    1545           0 :                 page0_size = inbuf->hdr.data_length +
    1546           0 :                     sizeof(inbuf->hdr.data_length) - sizeof(inbuf->hdr) -
    1547           0 :                     inbuf->hdr.blk_desc_len;
    1548           0 :                 memcpy(&outbuf->buf[sizeof(outbuf->hdr)+ sizeof(general)],
    1549             :                     page0, page0_size);
    1550           0 :         } else {
    1551           0 :                 page0_size = _2btol(inbuf->hdr_big.data_length) +
    1552           0 :                     sizeof(inbuf->hdr_big.data_length) -
    1553           0 :                     sizeof(inbuf->hdr_big) -
    1554           0 :                    _2btol(inbuf->hdr_big.blk_desc_len);
    1555           0 :                 memcpy(&outbuf->buf[sizeof(outbuf->hdr_big) + sizeof(general)],
    1556             :                     page0, page0_size);
    1557             :         }
    1558             : 
    1559             :         /*
    1560             :          * Set up for a mode select.
    1561             :          */
    1562           0 :         if (big == 0) {
    1563           0 :                 outbuf->hdr.data_length = sizeof(outbuf->hdr) +
    1564           0 :                     sizeof(general) + page0_size -
    1565             :                     sizeof(outbuf->hdr.data_length);
    1566           0 :                 if ((st->flags & ST_DONTBUFFER) == 0)
    1567           0 :                         outbuf->hdr.dev_spec = SMH_DSP_BUFF_MODE_ON;
    1568           0 :                 outbuf->hdr.blk_desc_len = sizeof(general);
    1569           0 :                 memcpy(&outbuf->buf[sizeof(outbuf->hdr)],
    1570             :                     &general, sizeof(general));
    1571           0 :                 error = scsi_mode_select(st->sc_link, 0, &outbuf->hdr,
    1572             :                     flags, ST_CTL_TIME);
    1573           0 :                 goto done;
    1574             :         }
    1575             : 
    1576             :         /* MODE SENSE (10) header was returned, so use MODE SELECT (10). */
    1577           0 :         _lto2b((sizeof(outbuf->hdr_big) + sizeof(general) + page0_size -
    1578           0 :             sizeof(outbuf->hdr_big.data_length)), outbuf->hdr_big.data_length);
    1579           0 :         if ((st->flags & ST_DONTBUFFER) == 0)
    1580           0 :                 outbuf->hdr_big.dev_spec = SMH_DSP_BUFF_MODE_ON;
    1581           0 :         _lto2b(sizeof(general), outbuf->hdr_big.blk_desc_len);
    1582           0 :         memcpy(&outbuf->buf[sizeof(outbuf->hdr_big)], &general,
    1583             :             sizeof(general));
    1584             : 
    1585           0 :         error = scsi_mode_select_big(st->sc_link, 0, &outbuf->hdr_big,
    1586             :             flags, ST_CTL_TIME);
    1587             : done:
    1588           0 :         if (inbuf)
    1589           0 :                 dma_free(inbuf, sizeof(*inbuf));
    1590           0 :         if (outbuf)
    1591           0 :                 dma_free(outbuf, sizeof(*outbuf));
    1592           0 :         return (error);
    1593           0 : }
    1594             : 
    1595             : /*
    1596             :  * issue an erase command
    1597             :  */
    1598             : int
    1599           0 : st_erase(struct st_softc *st, int full, int flags)
    1600             : {
    1601             :         struct scsi_erase *cmd;
    1602             :         struct scsi_xfer *xs;
    1603             :         int error;
    1604             : 
    1605           0 :         xs = scsi_xs_get(st->sc_link, flags);
    1606           0 :         if (xs == NULL)
    1607           0 :                 return (ENOMEM);
    1608           0 :         xs->cmdlen = sizeof(*cmd);
    1609             : 
    1610             :         /*
    1611             :          * Full erase means set LONG bit in erase command, which asks
    1612             :          * the drive to erase the entire unit.  Without this bit, we're
    1613             :          * asking the drive to write an erase gap.
    1614             :          */
    1615           0 :         cmd = (struct scsi_erase *)xs->cmd;
    1616           0 :         cmd->opcode = ERASE;
    1617           0 :         if (full) {
    1618           0 :                 cmd->byte2 = SE_IMMED|SE_LONG;
    1619           0 :                 xs->timeout = ST_SPC_TIME;
    1620           0 :         } else {
    1621           0 :                 cmd->byte2 = SE_IMMED;
    1622           0 :                 xs->timeout = ST_IO_TIME;
    1623             :         }
    1624             : 
    1625             :         /*
    1626             :          * XXX We always do this asynchronously, for now.  How long should
    1627             :          * we wait if we want to (eventually) to it synchronously?
    1628             :          */
    1629           0 :         error = scsi_xs_sync(xs);
    1630           0 :         scsi_xs_put(xs);
    1631             : 
    1632           0 :         return (error);
    1633           0 : }
    1634             : 
    1635             : /*
    1636             :  * skip N blocks/filemarks/seq filemarks/eom
    1637             :  */
    1638             : int
    1639           0 : st_space(struct st_softc *st, int number, u_int what, int flags)
    1640             : {
    1641             :         struct scsi_space *cmd;
    1642             :         struct scsi_xfer *xs;
    1643             :         int error;
    1644             : 
    1645           0 :         switch (what) {
    1646             :         case SP_BLKS:
    1647           0 :                 if (st->flags & ST_PER_ACTION) {
    1648           0 :                         if (number > 0) {
    1649           0 :                                 st->flags &= ~ST_PER_ACTION;
    1650           0 :                                 return EIO;
    1651           0 :                         } else if (number < 0) {
    1652           0 :                                 if (st->flags & ST_AT_FILEMARK) {
    1653             :                                         /*
    1654             :                                          * Handling of ST_AT_FILEMARK
    1655             :                                          * in st_space will fill in the
    1656             :                                          * right file mark count.
    1657             :                                          */
    1658           0 :                                         error = st_space(st, 0, SP_FILEMARKS,
    1659             :                                                 flags);
    1660           0 :                                         if (error)
    1661           0 :                                                 return error;
    1662             :                                 }
    1663           0 :                                 if (st->flags & ST_BLANK_READ) {
    1664           0 :                                         st->flags &= ~ST_BLANK_READ;
    1665           0 :                                         return EIO;
    1666             :                                 }
    1667           0 :                                 st->flags &= ~(ST_EIO_PENDING | ST_EOM_PENDING);
    1668           0 :                         }
    1669             :                 }
    1670             :                 break;
    1671             :         case SP_FILEMARKS:
    1672           0 :                 if (st->flags & ST_EIO_PENDING) {
    1673           0 :                         if (number > 0) {
    1674             :                                 /* pretend we just discovered the error */
    1675           0 :                                 st->flags &= ~ST_EIO_PENDING;
    1676           0 :                                 return EIO;
    1677           0 :                         } else if (number < 0) {
    1678             :                                 /* back away from the error */
    1679           0 :                                 st->flags &= ~ST_EIO_PENDING;
    1680           0 :                         }
    1681             :                 }
    1682           0 :                 if (st->flags & ST_AT_FILEMARK) {
    1683           0 :                         st->flags &= ~ST_AT_FILEMARK;
    1684           0 :                         number--;
    1685           0 :                 }
    1686           0 :                 if ((st->flags & ST_BLANK_READ) && (number < 0)) {
    1687             :                         /* back away from unwritten tape */
    1688           0 :                         st->flags &= ~ST_BLANK_READ;
    1689           0 :                         number++;       /* XXX dubious */
    1690           0 :                 }
    1691             :                 break;
    1692             :         case SP_EOM:
    1693           0 :                 if (st->flags & ST_EOM_PENDING) {
    1694             :                         /* We are already there. */
    1695           0 :                         st->flags &= ~ST_EOM_PENDING;
    1696           0 :                         return (0);
    1697             :                 }
    1698           0 :                 if (st->flags & ST_EIO_PENDING) {
    1699             :                         /* pretend we just discovered the error */
    1700           0 :                         st->flags &= ~ST_EIO_PENDING;
    1701           0 :                         return EIO;
    1702             :                 }
    1703           0 :                 if (st->flags & ST_AT_FILEMARK)
    1704           0 :                         st->flags &= ~ST_AT_FILEMARK;
    1705             :                 break;
    1706             :         }
    1707           0 :         if (number == 0)
    1708           0 :                 return 0;
    1709             : 
    1710           0 :         xs = scsi_xs_get(st->sc_link, flags);
    1711           0 :         if (xs == NULL)
    1712           0 :                 return (ENOMEM);
    1713             : 
    1714           0 :         cmd = (struct scsi_space *)xs->cmd;
    1715           0 :         cmd->opcode = SPACE;
    1716           0 :         cmd->byte2 = what;
    1717           0 :         _lto3b(number, cmd->number);
    1718           0 :         xs->cmdlen = sizeof(*cmd);
    1719           0 :         xs->timeout = ST_SPC_TIME;
    1720             : 
    1721           0 :         CLR(st->flags, ST_EOD_DETECTED);
    1722             : 
    1723           0 :         error = scsi_xs_sync(xs);
    1724           0 :         scsi_xs_put(xs);
    1725             : 
    1726           0 :         if (error != 0) {
    1727           0 :                 st->media_fileno = -1;
    1728           0 :                 st->media_blkno = -1;
    1729           0 :         } else {
    1730           0 :                 switch (what) {
    1731             :                 case SP_BLKS:
    1732           0 :                         if (st->media_blkno != -1) {
    1733           0 :                                 st->media_blkno += number;
    1734           0 :                                 if (st->media_blkno < 0)
    1735           0 :                                         st->media_blkno = -1;
    1736             :                         }
    1737             :                         break;
    1738             :                 case SP_FILEMARKS:
    1739           0 :                         if (st->media_fileno != -1) {
    1740           0 :                                 if (!ISSET(st->flags, ST_EOD_DETECTED))
    1741           0 :                                         st->media_fileno += number;
    1742           0 :                                 if (st->media_fileno > st->media_eom)
    1743           0 :                                         st->media_eom = st->media_fileno;
    1744           0 :                                 st->media_blkno = 0;
    1745           0 :                         }
    1746             :                         break;
    1747             :                 case SP_EOM:
    1748           0 :                         if (st->media_eom != -1) {
    1749           0 :                                 st->media_fileno = st->media_eom;
    1750           0 :                                 st->media_blkno = 0;
    1751           0 :                         } else {
    1752           0 :                                 st->media_fileno = -1;
    1753           0 :                                 st->media_blkno = -1;
    1754             :                         }
    1755             :                         break;
    1756             :                 default:
    1757           0 :                         st->media_fileno = -1;
    1758           0 :                         st->media_blkno = -1;
    1759           0 :                         break;
    1760             :                 }
    1761             :         }
    1762             : 
    1763           0 :         return (error);
    1764           0 : }
    1765             : 
    1766             : /*
    1767             :  * write N filemarks
    1768             :  */
    1769             : int
    1770           0 : st_write_filemarks(struct st_softc *st, int number, int flags)
    1771             : {
    1772             :         struct scsi_write_filemarks *cmd;
    1773             :         struct scsi_xfer *xs;
    1774             :         int error;
    1775             : 
    1776           0 :         if (number < 0)
    1777           0 :                 return (EINVAL);
    1778             : 
    1779           0 :         xs = scsi_xs_get(st->sc_link, flags);
    1780           0 :         if (xs == NULL)
    1781           0 :                 return (ENOMEM);
    1782             : 
    1783           0 :         xs->cmdlen = sizeof(*cmd);
    1784           0 :         xs->timeout = ST_IO_TIME * 4;
    1785             : 
    1786           0 :         switch (number) {
    1787             :         case 0:         /* really a command to sync the drive's buffers */
    1788             :                 break;
    1789             :         case 1:
    1790           0 :                 if (st->flags & ST_FM_WRITTEN)   /* already have one down */
    1791           0 :                         st->flags &= ~ST_WRITTEN;
    1792             :                 else
    1793           0 :                         st->flags |= ST_FM_WRITTEN;
    1794           0 :                 st->flags &= ~ST_PER_ACTION;
    1795           0 :                 break;
    1796             :         default:
    1797           0 :                 st->flags &= ~(ST_PER_ACTION | ST_WRITTEN);
    1798           0 :                 break;
    1799             :         }
    1800             : 
    1801           0 :         cmd = (struct scsi_write_filemarks *)xs->cmd;
    1802           0 :         cmd->opcode = WRITE_FILEMARKS;
    1803           0 :         _lto3b(number, cmd->number);
    1804             : 
    1805           0 :         error = scsi_xs_sync(xs);
    1806           0 :         scsi_xs_put(xs);
    1807             : 
    1808           0 :         if (error != 0) {
    1809           0 :                 st->media_fileno = -1;
    1810           0 :                 st->media_blkno = -1;
    1811           0 :                 st->media_eom = -1;
    1812           0 :         } else if (st->media_fileno != -1) {
    1813           0 :                 st->media_fileno += number;
    1814           0 :                 st->media_eom = st->media_fileno;
    1815           0 :                 st->media_blkno = 0;
    1816           0 :         }
    1817             : 
    1818           0 :         return (error);
    1819           0 : }
    1820             : 
    1821             : /*
    1822             :  * Make sure the right number of file marks is on tape if the
    1823             :  * tape has been written.  If the position argument is true,
    1824             :  * leave the tape positioned where it was originally.
    1825             :  *
    1826             :  * nmarks returns the number of marks to skip (or, if position
    1827             :  * true, which were skipped) to get back original position.
    1828             :  */
    1829             : int
    1830           0 : st_check_eod(struct st_softc *st, int position, int *nmarks, int flags)
    1831             : {
    1832             :         int error;
    1833             : 
    1834           0 :         switch (st->flags & (ST_WRITTEN | ST_FM_WRITTEN | ST_2FM_AT_EOD)) {
    1835             :         default:
    1836           0 :                 *nmarks = 0;
    1837           0 :                 return 0;
    1838             :         case ST_WRITTEN:
    1839             :         case ST_WRITTEN | ST_FM_WRITTEN | ST_2FM_AT_EOD:
    1840           0 :                 *nmarks = 1;
    1841           0 :                 break;
    1842             :         case ST_WRITTEN | ST_2FM_AT_EOD:
    1843           0 :                 *nmarks = 2;
    1844           0 :         }
    1845           0 :         error = st_write_filemarks(st, *nmarks, flags);
    1846           0 :         if (position && !error)
    1847           0 :                 error = st_space(st, -*nmarks, SP_FILEMARKS, flags);
    1848           0 :         return error;
    1849           0 : }
    1850             : 
    1851             : /*
    1852             :  * load/unload/retension
    1853             :  */
    1854             : int
    1855           0 : st_load(struct st_softc *st, u_int type, int flags)
    1856             : {
    1857             :         struct scsi_load *cmd;
    1858             :         struct scsi_xfer *xs;
    1859           0 :         int error, nmarks;
    1860             : 
    1861           0 :         st->media_fileno = -1;
    1862           0 :         st->media_blkno = -1;
    1863           0 :         st->media_eom = -1;
    1864             : 
    1865           0 :         if (type != LD_LOAD) {
    1866           0 :                 error = st_check_eod(st, 0, &nmarks, flags);
    1867           0 :                 if (error)
    1868           0 :                         return (error);
    1869             :         }
    1870             : 
    1871           0 :         if (st->quirks & ST_Q_IGNORE_LOADS) {
    1872           0 :                 if (type == LD_LOAD) {
    1873             :                         /*
    1874             :                          * If we ignore loads, at least we should try a rewind.
    1875             :                          */
    1876           0 :                         return (st_rewind(st, 0, flags));
    1877             :                 }
    1878           0 :                 return (0);
    1879             :         }
    1880             : 
    1881             : 
    1882           0 :         xs = scsi_xs_get(st->sc_link, flags);
    1883           0 :         if (xs == NULL)
    1884           0 :                 return (ENOMEM);
    1885           0 :         xs->cmdlen = sizeof(*cmd);
    1886           0 :         xs->timeout = ST_SPC_TIME;
    1887             : 
    1888           0 :         cmd = (struct scsi_load *)xs->cmd;
    1889           0 :         cmd->opcode = LOAD;
    1890           0 :         cmd->how = type;
    1891             : 
    1892           0 :         error = scsi_xs_sync(xs);
    1893           0 :         scsi_xs_put(xs);
    1894             : 
    1895           0 :         return (error);
    1896           0 : }
    1897             : 
    1898             : /*
    1899             :  *  Rewind the device
    1900             :  */
    1901             : int
    1902           0 : st_rewind(struct st_softc *st, u_int immediate, int flags)
    1903             : {
    1904             :         struct scsi_rewind *cmd;
    1905             :         struct scsi_xfer *xs;
    1906           0 :         int error, nmarks;
    1907             : 
    1908           0 :         error = st_check_eod(st, 0, &nmarks, flags);
    1909           0 :         if (error)
    1910           0 :                 return (error);
    1911           0 :         st->flags &= ~ST_PER_ACTION;
    1912             : 
    1913           0 :         xs = scsi_xs_get(st->sc_link, flags);
    1914           0 :         if (xs == NULL)
    1915           0 :                 return (ENOMEM);
    1916           0 :         xs->cmdlen = sizeof(*cmd);
    1917           0 :         xs->timeout = immediate ? ST_CTL_TIME : ST_SPC_TIME;
    1918             : 
    1919           0 :         cmd = (struct scsi_rewind *)xs->cmd;
    1920           0 :         cmd->opcode = REWIND;
    1921           0 :         cmd->byte2 = immediate;
    1922             : 
    1923           0 :         error = scsi_xs_sync(xs);
    1924           0 :         scsi_xs_put(xs);
    1925             : 
    1926           0 :         if (error == 0) {
    1927           0 :                 st->media_fileno = 0;
    1928           0 :                 st->media_blkno = 0;
    1929           0 :         }
    1930             : 
    1931           0 :         return (error);
    1932           0 : }
    1933             : 
    1934             : /*
    1935             :  * Look at the returned sense and act on the error and detirmine
    1936             :  * The unix error number to pass back... (0 = report no error)
    1937             :  *                            (-1 = continue processing)
    1938             :  */
    1939             : int
    1940           0 : st_interpret_sense(struct scsi_xfer *xs)
    1941             : {
    1942           0 :         struct scsi_sense_data *sense = &xs->sense;
    1943           0 :         struct scsi_link *link = xs->sc_link;
    1944             :         struct scsi_space *space;
    1945           0 :         struct st_softc *st = link->device_softc;
    1946           0 :         u_int8_t serr = sense->error_code & SSD_ERRCODE;
    1947           0 :         u_int8_t skey = sense->flags & SSD_KEY;
    1948             :         int32_t resid, info, number;
    1949             :         int datalen;
    1950             : 
    1951           0 :         if (((link->flags & SDEV_OPEN) == 0) ||
    1952           0 :             (serr != SSD_ERRCODE_CURRENT && serr != SSD_ERRCODE_DEFERRED))
    1953           0 :                 return (scsi_interpret_sense(xs));
    1954             : 
    1955           0 :         info = (int32_t)_4btol(sense->info);
    1956             : 
    1957           0 :         switch (skey) {
    1958             : 
    1959             :         /*
    1960             :          * We do custom processing in st for the unit becoming ready case.
    1961             :          * in this case we do not allow xs->retries to be decremented
    1962             :          * only on the "Unit Becoming Ready" case. This is because tape
    1963             :          * drives report "Unit Becoming Ready" when loading media, etc.
    1964             :          * and can take a long time.  Rather than having a massive timeout
    1965             :          * for all operations (which would cause other problems) we allow
    1966             :          * operations to wait (but be interruptable with Ctrl-C) forever
    1967             :          * as long as the drive is reporting that it is becoming ready.
    1968             :          * all other cases are handled as per the default.
    1969             :          */
    1970             : 
    1971             :         case SKEY_NOT_READY:
    1972           0 :                 if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
    1973           0 :                         return (0);
    1974           0 :                 switch (ASC_ASCQ(sense)) {
    1975             :                 case SENSE_NOT_READY_BECOMING_READY:
    1976             :                         SC_DEBUG(link, SDEV_DB1, ("not ready: busy (%#x)\n",
    1977             :                             sense->add_sense_code_qual));
    1978             :                         /* don't count this as a retry */
    1979           0 :                         xs->retries++;
    1980           0 :                         return (scsi_delay(xs, 1));
    1981             :                 default:
    1982           0 :                         return (scsi_interpret_sense(xs));
    1983             :                 }
    1984             :                 break;
    1985             :         case SKEY_BLANK_CHECK:
    1986           0 :                 if (sense->error_code & SSD_ERRCODE_VALID &&
    1987           0 :                     xs->cmd->opcode == SPACE) {
    1988           0 :                         switch (ASC_ASCQ(sense)) {
    1989             :                         case SENSE_END_OF_DATA_DETECTED:
    1990           0 :                                 st->flags |= ST_EOD_DETECTED;
    1991           0 :                                 space = (struct scsi_space *)xs->cmd;
    1992           0 :                                 number = _3btol(space->number);
    1993           0 :                                 st->media_fileno = number - info;
    1994           0 :                                 st->media_eom = st->media_fileno;
    1995           0 :                                 return (0);
    1996             :                         case SENSE_BEGINNING_OF_MEDIUM_DETECTED:
    1997             :                                 /* Standard says: Position is undefined! */
    1998           0 :                                 st->flags |= ST_BOD_DETECTED;
    1999           0 :                                 st->media_fileno = -1;
    2000           0 :                                 st->media_blkno = -1;
    2001           0 :                                 return (0);
    2002             :                         }
    2003             :                 }
    2004             :                 break;
    2005             :         case SKEY_NO_SENSE:
    2006             :         case SKEY_RECOVERED_ERROR:
    2007             :         case SKEY_MEDIUM_ERROR:
    2008             :         case SKEY_VOLUME_OVERFLOW:
    2009             :                 break;
    2010             :         default:
    2011           0 :                 return (scsi_interpret_sense(xs));
    2012             :         }
    2013             : 
    2014             :         /*
    2015             :          * 'resid' can be in units of st->blksize or bytes. xs->resid and
    2016             :          * xs->datalen are always in units of bytes. So we need a variable
    2017             :          * to store datalen in the same units as resid and to adjust
    2018             :          * xs->resid to be in bytes.
    2019             :          */
    2020           0 :         if (sense->error_code & SSD_ERRCODE_VALID) {
    2021           0 :                 if (st->flags & ST_FIXEDBLOCKS)
    2022           0 :                         resid = info * st->blksize; /* XXXX overflow? */
    2023             :                 else
    2024             :                         resid = info;
    2025             :         } else {
    2026           0 :                 resid = xs->datalen;
    2027             :         }
    2028             : 
    2029           0 :         if (resid < 0 || resid > xs->datalen)
    2030           0 :                 xs->resid = xs->datalen;
    2031             :         else
    2032           0 :                 xs->resid = resid;
    2033             : 
    2034           0 :         datalen = xs->datalen;
    2035           0 :         if (st->flags & ST_FIXEDBLOCKS) {
    2036           0 :                 resid /= st->blksize;
    2037           0 :                 datalen /= st->blksize;
    2038           0 :         }
    2039             : 
    2040           0 :         if (sense->flags & SSD_FILEMARK) {
    2041           0 :                 if (st->media_fileno != -1) {
    2042           0 :                         st->media_fileno++;
    2043           0 :                         if (st->media_fileno > st->media_eom)
    2044           0 :                                 st->media_eom = st->media_fileno;
    2045           0 :                         st->media_blkno = 0;
    2046           0 :                 }
    2047           0 :                 if ((st->flags & ST_FIXEDBLOCKS) == 0)
    2048           0 :                         return 0;
    2049           0 :                 st->flags |= ST_AT_FILEMARK;
    2050           0 :         }
    2051             : 
    2052           0 :         if (sense->flags & SSD_EOM) {
    2053           0 :                 st->flags |= ST_EOM_PENDING;
    2054           0 :                 xs->resid = 0;
    2055           0 :                 if (st->flags & ST_FIXEDBLOCKS)
    2056           0 :                         return (0);
    2057             :         }
    2058             : 
    2059           0 :         if (sense->flags & SSD_ILI) {
    2060           0 :                 if ((st->flags & ST_FIXEDBLOCKS) == 0) {
    2061           0 :                         if (resid >= 0 && resid <= datalen)
    2062           0 :                                 return (0);
    2063           0 :                         if ((xs->flags & SCSI_SILENT) == 0)
    2064           0 :                                 printf( "%s: bad residual %d out of "
    2065           0 :                                     "%d\n", st->sc_dev.dv_xname, resid,
    2066             :                                     datalen);
    2067           0 :                         return (EIO);
    2068             :                 }
    2069             : 
    2070             :                 /* Fixed size blocks. */
    2071           0 :                 if (sense->error_code & SSD_ERRCODE_VALID)
    2072           0 :                         if ((xs->flags & SCSI_SILENT) == 0)
    2073           0 :                                 printf("%s: block wrong size, %d blocks "
    2074           0 :                                     "residual\n", st->sc_dev.dv_xname, resid);
    2075           0 :                 st->flags |= ST_EIO_PENDING;
    2076             :                 /*
    2077             :                  * This quirk code helps the drive read the first tape block,
    2078             :                  * regardless of format.  That is required for these drives to
    2079             :                  * return proper MODE SENSE information.
    2080             :                  */
    2081           0 :                 if ((st->quirks & ST_Q_SENSE_HELP) &&
    2082           0 :                     !(link->flags & SDEV_MEDIA_LOADED))
    2083           0 :                         st->blksize -= 512;
    2084             :         }
    2085             : 
    2086           0 :         if ((st->flags & ST_FIXEDBLOCKS) && xs->resid == xs->datalen) {
    2087           0 :                 if (st->flags & ST_EIO_PENDING)
    2088           0 :                         return EIO;
    2089           0 :                 if (st->flags & ST_AT_FILEMARK)
    2090           0 :                         return 0;
    2091             :         }
    2092             : 
    2093           0 :         if (skey == SKEY_BLANK_CHECK) {
    2094             :                 /*
    2095             :                  * This quirk code helps the drive read the first tape block,
    2096             :                  * regardless of format.  That is required for these drives to
    2097             :                  * return proper MODE SENSE information.
    2098             :                  */
    2099           0 :                 if ((st->quirks & ST_Q_SENSE_HELP) &&
    2100           0 :                     !(link->flags & SDEV_MEDIA_LOADED)) {
    2101             :                         /* still starting */
    2102           0 :                         st->blksize -= 512;
    2103           0 :                 } else if (!(st->flags & (ST_2FM_AT_EOD | ST_BLANK_READ))) {
    2104           0 :                         st->flags |= ST_BLANK_READ;
    2105           0 :                         st->flags |= ST_EOM_PENDING;
    2106           0 :                         xs->resid = xs->datalen;
    2107           0 :                         return (0);
    2108             :                 }
    2109             :         }
    2110             : 
    2111           0 :         return (scsi_interpret_sense(xs));
    2112           0 : }
    2113             : 
    2114             : /*
    2115             :  * The quirk here is that the drive returns some value to st_mode_sense
    2116             :  * incorrectly until the tape has actually passed by the head.
    2117             :  *
    2118             :  * The method is to set the drive to large fixed-block state (user-specified
    2119             :  * density and 1024-byte blocks), then read and rewind to get it to sense the
    2120             :  * tape.  If that doesn't work, try 512-byte fixed blocks.  If that doesn't
    2121             :  * work, as a last resort, try variable- length blocks.  The result will be
    2122             :  * the ability to do an accurate st_mode_sense.
    2123             :  *
    2124             :  * We know we can do a rewind because we just did a load, which implies rewind.
    2125             :  * Rewind seems preferable to space backward if we have a virgin tape.
    2126             :  *
    2127             :  * The rest of the code for this quirk is in ILI processing and BLANK CHECK
    2128             :  * error processing, both part of st_interpret_sense.
    2129             :  */
    2130             : int
    2131           0 : st_touch_tape(struct st_softc *st)
    2132             : {
    2133             :         char *buf = NULL;
    2134             :         int readsize, maxblksize = 1024;
    2135             :         int error = 0;
    2136             : 
    2137           0 :         if ((error = st_mode_sense(st, 0)) != 0)
    2138             :                 goto done;
    2139           0 :         buf = dma_alloc(maxblksize, PR_NOWAIT);
    2140           0 :         if (!buf) {
    2141             :                 error = ENOMEM;
    2142           0 :                 goto done;
    2143             :         }
    2144             : 
    2145           0 :         st->blksize = 1024;
    2146           0 :         do {
    2147           0 :                 switch (st->blksize) {
    2148             :                 case 512:
    2149             :                 case 1024:
    2150           0 :                         readsize = st->blksize;
    2151           0 :                         st->flags |= ST_FIXEDBLOCKS;
    2152           0 :                         break;
    2153             :                 default:
    2154             :                         readsize = 1;
    2155           0 :                         st->flags &= ~ST_FIXEDBLOCKS;
    2156           0 :                 }
    2157           0 :                 if ((error = st_mode_select(st, 0)) != 0)
    2158             :                         goto done;
    2159           0 :                 st_read(st, buf, readsize, SCSI_SILENT);        /* XXX */
    2160           0 :                 if ((error = st_rewind(st, 0, 0)) != 0)
    2161             :                         goto done;
    2162           0 :         } while (readsize != 1 && readsize > st->blksize);
    2163             : done:
    2164           0 :         dma_free(buf, maxblksize);
    2165           0 :         return (error);
    2166             : }

Generated by: LCOV version 1.13