XXXX introduce drv_sectohz

   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  *  Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  24  *  Copyright (c) 2011 Bayard G. Bell. All rights reserved.
  25  */
  26 
  27 /*
  28  * SCSI  SCSA-compliant and not-so-DDI-compliant Tape Driver
  29  */
  30 
  31 #if defined(lint) && !defined(DEBUG)
  32 #define DEBUG   1
  33 #endif
  34 
  35 #include <sys/modctl.h>
  36 #include <sys/scsi/scsi.h>
  37 #include <sys/mtio.h>
  38 #include <sys/scsi/targets/stdef.h>
  39 #include <sys/file.h>
  40 #include <sys/kstat.h>
  41 #include <sys/ddidmareq.h>
  42 #include <sys/ddi.h>
  43 #include <sys/sunddi.h>
  44 #include <sys/byteorder.h>
  45 
  46 #define IOSP    KSTAT_IO_PTR(un->un_stats)
  47 /*
  48  * stats maintained only for reads/writes as commands
  49  * like rewind etc skew the wait/busy times
  50  */
  51 #define IS_RW(bp)       ((bp)->b_bcount > 0)
  52 #define ST_DO_KSTATS(bp, kstat_function) \
  53         if ((bp != un->un_sbufp) && un->un_stats && IS_RW(bp)) { \
  54                 kstat_function(IOSP); \
  55         }
  56 
  57 #define ST_DO_ERRSTATS(un, x)  \
  58         if (un->un_errstats) { \
  59                 struct st_errstats *stp; \
  60                 stp = (struct st_errstats *)un->un_errstats->ks_data; \
  61                 stp->x.value.ul++; \
  62         }
  63 
  64 #define FILL_SCSI1_LUN(devp, pkt)                                       \
  65         if ((devp)->sd_inq->inq_ansi == 0x1) {                            \
  66                 int _lun;                                               \
  67                 _lun = ddi_prop_get_int(DDI_DEV_T_ANY, (devp)->sd_dev,       \
  68                     DDI_PROP_DONTPASS, SCSI_ADDR_PROP_LUN, 0);          \
  69                 if (_lun > 0) {                                              \
  70                         ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun =    \
  71                             _lun;                                       \
  72                 }                                                       \
  73         }
  74 
  75 /*
  76  * get an available contig mem header, cp.
  77  * when big_enough is true, we will return NULL, if no big enough
  78  * contig mem is found.
  79  * when big_enough is false, we will try to find cp containing big
  80  * enough contig mem. if not found, we will ruturn the last cp available.
  81  *
  82  * used by st_get_contig_mem()
  83  */
  84 #define ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough) {               \
  85         struct contig_mem *tmp_cp = NULL;                               \
  86         for ((cp) = (un)->un_contig_mem;                             \
  87             (cp) != NULL;                                               \
  88             tmp_cp = (cp), (cp) = (cp)->cm_next) {                   \
  89                 if (((cp)->cm_len >= (len)) ||                            \
  90                     (!(big_enough) && ((cp)->cm_next == NULL))) {    \
  91                         if (tmp_cp == NULL) {                           \
  92                                 (un)->un_contig_mem = (cp)->cm_next;      \
  93                         } else {                                        \
  94                                 tmp_cp->cm_next = (cp)->cm_next;  \
  95                         }                                               \
  96                         (cp)->cm_next = NULL;                                \
  97                         (un)->un_contig_mem_available_num--;                 \
  98                         break;                                          \
  99                 }                                                       \
 100         }                                                               \
 101 }
 102 
 103 #define ST_NUM_MEMBERS(array)   (sizeof (array) / sizeof (array[0]))
 104 #define COPY_POS(dest, source) bcopy(source, dest, sizeof (tapepos_t))
 105 #define ISALNUM(byte) \
 106         (((byte) >= 'a' && (byte) <= 'z') || \
 107         ((byte) >= 'A' && (byte) <= 'Z') || \
 108         ((byte) >= '0' && (byte) <= '9'))
 109 
 110 #define ONE_K   1024
 111 
 112 #define MAX_SPACE_CNT(cnt) if (cnt >= 0) { \
 113                 if (cnt > MIN(SP_CNT_MASK, INT32_MAX)) \
 114                         return (EINVAL); \
 115         } else { \
 116                 if (-(cnt) > MIN(SP_CNT_MASK, INT32_MAX)) \
 117                         return (EINVAL); \
 118         } \
 119 
 120 /*
 121  * Global External Data Definitions
 122  */
 123 extern struct scsi_key_strings scsi_cmds[];
 124 extern uchar_t  scsi_cdb_size[];
 125 
 126 /*
 127  * Local Static Data
 128  */
 129 static void *st_state;
 130 static char *const st_label = "st";
 131 static volatile int st_recov_sz = sizeof (recov_info);
 132 static const char mp_misconf[] = {
 133         "St Tape is misconfigured, MPxIO enabled and "
 134         "tape-command-recovery-disable set in st.conf\n"
 135 };
 136 
 137 #ifdef  __x86
 138 /*
 139  * We need to use below DMA attr to alloc physically contiguous
 140  * memory to do I/O in big block size
 141  */
 142 static ddi_dma_attr_t st_contig_mem_dma_attr = {
 143         DMA_ATTR_V0,    /* version number */
 144         0x0,            /* lowest usable address */
 145         0xFFFFFFFFull,  /* high DMA address range */
 146         0xFFFFFFFFull,  /* DMA counter register */
 147         1,              /* DMA address alignment */
 148         1,              /* DMA burstsizes */
 149         1,              /* min effective DMA size */
 150         0xFFFFFFFFull,  /* max DMA xfer size */
 151         0xFFFFFFFFull,  /* segment boundary */
 152         1,              /* s/g list length */
 153         1,              /* granularity of device */
 154         0               /* DMA transfer flags */
 155 };
 156 
 157 static ddi_device_acc_attr_t st_acc_attr = {
 158         DDI_DEVICE_ATTR_V0,
 159         DDI_NEVERSWAP_ACC,
 160         DDI_STRICTORDER_ACC
 161 };
 162 
 163 /* set limitation for the number of contig_mem */
 164 static int st_max_contig_mem_num = ST_MAX_CONTIG_MEM_NUM;
 165 #endif
 166 
 167 /*
 168  * Tunable parameters
 169  *
 170  * DISCLAIMER
 171  * ----------
 172  * These parameters are intended for use only in system testing; if you use
 173  * them in production systems, you do so at your own risk. Altering any
 174  * variable not listed below may cause unpredictable system behavior.
 175  *
 176  * st_check_media_time
 177  *
 178  *   Three second state check
 179  *
 180  * st_allow_large_xfer
 181  *
 182  *   Gated with ST_NO_RECSIZE_LIMIT
 183  *
 184  *   0 - Transfers larger than 64KB will not be allowed
 185  *       regardless of the setting of ST_NO_RECSIZE_LIMIT
 186  *   1 - Transfers larger than 64KB will be allowed
 187  *       if ST_NO_RECSIZE_LIMIT is TRUE for the drive
 188  *
 189  * st_report_soft_errors_on_close
 190  *
 191  *  Gated with ST_SOFT_ERROR_REPORTING
 192  *
 193  *  0 - Errors will not be reported on close regardless
 194  *      of the setting of ST_SOFT_ERROR_REPORTING
 195  *
 196  *  1 - Errors will be reported on close if
 197  *      ST_SOFT_ERROR_REPORTING is TRUE for the drive
 198  */
 199 static int st_selection_retry_count = ST_SEL_RETRY_COUNT;
 200 static int st_retry_count       = ST_RETRY_COUNT;
 201 
 202 static int st_io_time           = ST_IO_TIME;
 203 static int st_long_timeout_x    = ST_LONG_TIMEOUT_X;
 204 
 205 static int st_space_time        = ST_SPACE_TIME;
 206 static int st_long_space_time_x = ST_LONG_SPACE_TIME_X;
 207 
 208 static int st_error_level       = SCSI_ERR_RETRYABLE;
 209 static int st_check_media_time  = 3000000;      /* 3 Second State Check */
 210 
 211 static int st_max_throttle      = ST_MAX_THROTTLE;
 212 
 213 static clock_t st_wait_cmds_complete = ST_WAIT_CMDS_COMPLETE;
 214 
 215 static int st_allow_large_xfer = 1;
 216 static int st_report_soft_errors_on_close = 1;
 217 
 218 /*
 219  * End of tunable parameters list
 220  */
 221 
 222 
 223 
 224 /*
 225  * Asynchronous I/O and persistent errors, refer to PSARC/1995/228
 226  *
 227  * Asynchronous I/O's main offering is that it is a non-blocking way to do
 228  * reads and writes.  The driver will queue up all the requests it gets and
 229  * have them ready to transport to the HBA.  Unfortunately, we cannot always
 230  * just ship the I/O requests to the HBA, as there errors and exceptions
 231  * that may happen when we don't want the HBA to continue.  Therein comes
 232  * the flush-on-errors capability.  If the HBA supports it, then st will
 233  * send in st_max_throttle I/O requests at the same time.
 234  *
 235  * Persistent errors : This was also reasonably simple.  In the interrupt
 236  * routines, if there was an error or exception (FM, LEOT, media error,
 237  * transport error), the persistent error bits are set and shuts everything
 238  * down, but setting the throttle to zero.  If we hit and exception in the
 239  * HBA, and flush-on-errors were set, we wait for all outstanding I/O's to
 240  * come back (with CMD_ABORTED), then flush all bp's in the wait queue with
 241  * the appropriate error, and this will preserve order. Of course, depending
 242  * on the exception we have to show a zero read or write before we show
 243  * errors back to the application.
 244  */
 245 
 246 extern const int st_ndrivetypes;        /* defined in st_conf.c */
 247 extern const struct st_drivetype st_drivetypes[];
 248 extern const char st_conf_version[];
 249 
 250 #ifdef STDEBUG
 251 static int st_soft_error_report_debug = 0;
 252 volatile int st_debug = 0;
 253 static volatile dev_info_t *st_lastdev;
 254 static kmutex_t st_debug_mutex;
 255 #endif
 256 
 257 #define ST_MT02_NAME    "Emulex  MT02 QIC-11/24  "
 258 
 259 static const struct vid_drivetype {
 260         char    *vid;
 261         char    type;
 262 } st_vid_dt[] = {
 263         {"LTO-CVE ",    MT_LTO},
 264         {"QUANTUM ",    MT_ISDLT},
 265         {"SONY    ",    MT_ISAIT},
 266         {"STK     ",    MT_ISSTK9840}
 267 };
 268 
 269 static const struct driver_minor_data {
 270         char    *name;
 271         int     minor;
 272 } st_minor_data[] = {
 273         /*
 274          * The top 4 entries are for the default densities,
 275          * don't alter their position.
 276          */
 277         {"",    0},
 278         {"n",   MT_NOREWIND},
 279         {"b",   MT_BSD},
 280         {"bn",  MT_NOREWIND | MT_BSD},
 281         {"l",   MT_DENSITY1},
 282         {"m",   MT_DENSITY2},
 283         {"h",   MT_DENSITY3},
 284         {"c",   MT_DENSITY4},
 285         {"u",   MT_DENSITY4},
 286         {"ln",  MT_DENSITY1 | MT_NOREWIND},
 287         {"mn",  MT_DENSITY2 | MT_NOREWIND},
 288         {"hn",  MT_DENSITY3 | MT_NOREWIND},
 289         {"cn",  MT_DENSITY4 | MT_NOREWIND},
 290         {"un",  MT_DENSITY4 | MT_NOREWIND},
 291         {"lb",  MT_DENSITY1 | MT_BSD},
 292         {"mb",  MT_DENSITY2 | MT_BSD},
 293         {"hb",  MT_DENSITY3 | MT_BSD},
 294         {"cb",  MT_DENSITY4 | MT_BSD},
 295         {"ub",  MT_DENSITY4 | MT_BSD},
 296         {"lbn", MT_DENSITY1 | MT_NOREWIND | MT_BSD},
 297         {"mbn", MT_DENSITY2 | MT_NOREWIND | MT_BSD},
 298         {"hbn", MT_DENSITY3 | MT_NOREWIND | MT_BSD},
 299         {"cbn", MT_DENSITY4 | MT_NOREWIND | MT_BSD},
 300         {"ubn", MT_DENSITY4 | MT_NOREWIND | MT_BSD}
 301 };
 302 
 303 /* strings used in many debug and warning messages */
 304 static const char wr_str[]  = "write";
 305 static const char rd_str[]  = "read";
 306 static const char wrg_str[] = "writing";
 307 static const char rdg_str[] = "reading";
 308 static const char *space_strs[] = {
 309         "records",
 310         "filemarks",
 311         "sequential filemarks",
 312         "eod",
 313         "setmarks",
 314         "sequential setmarks",
 315         "Reserved",
 316         "Reserved"
 317 };
 318 static const char *load_strs[] = {
 319         "unload",               /* LD_UNLOAD            0 */
 320         "load",                 /* LD_LOAD              1 */
 321         "retension",            /* LD_RETEN             2 */
 322         "load reten",           /* LD_LOAD | LD_RETEN   3 */
 323         "eod",                  /* LD_EOT               4 */
 324         "load EOD",             /* LD_LOAD | LD_EOT     5 */
 325         "reten EOD",            /* LD_RETEN | LD_EOT    6 */
 326         "load reten EOD"        /* LD_LOAD|LD_RETEN|LD_EOT 7 */
 327         "hold",                 /* LD_HOLD              8 */
 328         "load and hold"         /* LD_LOAD | LD_HOLD    9 */
 329 };
 330 
 331 static const char *errstatenames[] = {
 332         "COMMAND_DONE",
 333         "COMMAND_DONE_ERROR",
 334         "COMMAND_DONE_ERROR_RECOVERED",
 335         "QUE_COMMAND",
 336         "QUE_BUSY_COMMAND",
 337         "QUE_SENSE",
 338         "JUST_RETURN",
 339         "COMMAND_DONE_EACCES",
 340         "QUE_LAST_COMMAND",
 341         "COMMAND_TIMEOUT",
 342         "PATH_FAILED",
 343         "DEVICE_RESET",
 344         "DEVICE_TAMPER",
 345         "ATTEMPT_RETRY"
 346 };
 347 
 348 const char *bogusID = "Unknown Media ID";
 349 
 350 /* default density offsets in the table above */
 351 #define DEF_BLANK       0
 352 #define DEF_NOREWIND    1
 353 #define DEF_BSD         2
 354 #define DEF_BSD_NR      3
 355 
 356 /* Sense Key, ASC/ASCQ for which tape ejection is needed */
 357 
 358 static struct tape_failure_code {
 359         uchar_t key;
 360         uchar_t add_code;
 361         uchar_t qual_code;
 362 } st_tape_failure_code[] = {
 363         { KEY_HARDWARE_ERROR, 0x15, 0x01},
 364         { KEY_HARDWARE_ERROR, 0x44, 0x00},
 365         { KEY_HARDWARE_ERROR, 0x53, 0x00},
 366         { KEY_HARDWARE_ERROR, 0x53, 0x01},
 367         { KEY_NOT_READY, 0x53, 0x00},
 368         { 0xff}
 369 };
 370 
 371 /*  clean bit position and mask */
 372 
 373 static struct cln_bit_position {
 374         ushort_t cln_bit_byte;
 375         uchar_t cln_bit_mask;
 376 } st_cln_bit_position[] = {
 377         { 21, 0x08},
 378         { 70, 0xc0},
 379         { 18, 0x81}  /* 80 bit indicates in bit mode, 1 bit clean light is on */
 380 };
 381 
 382 /*
 383  * architecture dependent allocation restrictions. For x86, we'll set
 384  * dma_attr_addr_hi to st_max_phys_addr and dma_attr_sgllen to
 385  * st_sgl_size during _init().
 386  */
 387 #if defined(__sparc)
 388 static ddi_dma_attr_t st_alloc_attr = {
 389         DMA_ATTR_V0,    /* version number */
 390         0x0,            /* lowest usable address */
 391         0xFFFFFFFFull,  /* high DMA address range */
 392         0xFFFFFFFFull,  /* DMA counter register */
 393         1,              /* DMA address alignment */
 394         1,              /* DMA burstsizes */
 395         1,              /* min effective DMA size */
 396         0xFFFFFFFFull,  /* max DMA xfer size */
 397         0xFFFFFFFFull,  /* segment boundary */
 398         1,              /* s/g list length */
 399         512,            /* granularity of device */
 400         0               /* DMA transfer flags */
 401 };
 402 #elif defined(__x86)
 403 static ddi_dma_attr_t st_alloc_attr = {
 404         DMA_ATTR_V0,    /* version number */
 405         0x0,            /* lowest usable address */
 406         0x0,            /* high DMA address range [set in _init()] */
 407         0xFFFFull,      /* DMA counter register */
 408         512,            /* DMA address alignment */
 409         1,              /* DMA burstsizes */
 410         1,              /* min effective DMA size */
 411         0xFFFFFFFFull,  /* max DMA xfer size */
 412         0xFFFFFFFFull,  /* segment boundary */
 413         0,              /* s/g list length */
 414         512,            /* granularity of device [set in _init()] */
 415         0               /* DMA transfer flags */
 416 };
 417 uint64_t st_max_phys_addr = 0xFFFFFFFFull;
 418 int st_sgl_size = 0xF;
 419 
 420 #endif
 421 
 422 /*
 423  * Configuration Data:
 424  *
 425  * Device driver ops vector
 426  */
 427 static int st_aread(dev_t dev, struct aio_req *aio, cred_t *cred_p);
 428 static int st_awrite(dev_t dev, struct aio_req *aio, cred_t *cred_p);
 429 static int st_read(dev_t  dev,  struct   uio   *uio_p,   cred_t *cred_p);
 430 static int st_write(dev_t  dev,  struct  uio   *uio_p,   cred_t *cred_p);
 431 static int st_open(dev_t  *devp,  int  flag,  int  otyp,  cred_t *cred_p);
 432 static int st_close(dev_t  dev,  int  flag,  int  otyp,  cred_t *cred_p);
 433 static int st_strategy(struct buf *bp);
 434 static int st_queued_strategy(buf_t *bp);
 435 static int st_ioctl(dev_t dev, int cmd, intptr_t arg, int  flag,
 436         cred_t *cred_p, int *rval_p);
 437 extern int nulldev(), nodev();
 438 
 439 static struct cb_ops st_cb_ops = {
 440         st_open,                /* open */
 441         st_close,               /* close */
 442         st_queued_strategy,     /* strategy Not Block device but async checks */
 443         nodev,                  /* print */
 444         nodev,                  /* dump */
 445         st_read,                /* read */
 446         st_write,               /* write */
 447         st_ioctl,               /* ioctl */
 448         nodev,                  /* devmap */
 449         nodev,                  /* mmap */
 450         nodev,                  /* segmap */
 451         nochpoll,               /* poll */
 452         ddi_prop_op,            /* cb_prop_op */
 453         0,                      /* streamtab  */
 454         D_64BIT | D_MP | D_NEW | D_HOTPLUG |
 455         D_OPEN_RETURNS_EINTR,   /* cb_flag */
 456         CB_REV,                 /* cb_rev */
 457         st_aread,               /* async I/O read entry point */
 458         st_awrite               /* async I/O write entry point */
 459 
 460 };
 461 
 462 static int st_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
 463                 void **result);
 464 static int st_probe(dev_info_t *dev);
 465 static int st_attach(dev_info_t *dev, ddi_attach_cmd_t cmd);
 466 static int st_detach(dev_info_t *dev, ddi_detach_cmd_t cmd);
 467 
 468 static struct dev_ops st_ops = {
 469         DEVO_REV,               /* devo_rev, */
 470         0,                      /* refcnt  */
 471         st_info,                /* info */
 472         nulldev,                /* identify */
 473         st_probe,               /* probe */
 474         st_attach,              /* attach */
 475         st_detach,              /* detach */
 476         nodev,                  /* reset */
 477         &st_cb_ops,         /* driver operations */
 478         (struct bus_ops *)0,    /* bus operations */
 479         nulldev,                /* power */
 480         ddi_quiesce_not_needed, /* devo_quiesce */
 481 };
 482 
 483 /*
 484  * Local Function Declarations
 485  */
 486 static char *st_print_scsi_cmd(char cmd);
 487 static void st_print_cdb(dev_info_t *dip, char *label, uint_t level,
 488     char *title, char *cdb);
 489 static void st_clean_print(dev_info_t *dev, char *label, uint_t level,
 490     char *title, char *data, int len);
 491 static int st_doattach(struct scsi_device *devp, int (*canwait)());
 492 static void st_known_tape_type(struct scsi_tape *un);
 493 static int st_get_conf_from_st_dot_conf(struct scsi_tape *, char *,
 494     struct st_drivetype *);
 495 static int st_get_conf_from_st_conf_dot_c(struct scsi_tape *, char *,
 496     struct st_drivetype *);
 497 static int st_get_conf_from_tape_drive(struct scsi_tape *, char *,
 498     struct st_drivetype *);
 499 static int st_get_densities_from_tape_drive(struct scsi_tape *,
 500     struct st_drivetype *);
 501 static int st_get_timeout_values_from_tape_drive(struct scsi_tape *,
 502     struct st_drivetype *);
 503 static int st_get_timeouts_value(struct scsi_tape *, uchar_t, ushort_t *,
 504     ushort_t);
 505 static int st_get_default_conf(struct scsi_tape *, char *,
 506     struct st_drivetype *);
 507 static int st_rw(dev_t dev, struct uio *uio, int flag);
 508 static int st_arw(dev_t dev, struct aio_req *aio, int flag);
 509 static int st_find_eod(struct scsi_tape *un);
 510 static int st_check_density_or_wfm(dev_t dev, int wfm, int mode, int stepflag);
 511 static int st_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *, int flag);
 512 static int st_mtioctop(struct scsi_tape *un, intptr_t arg, int flag);
 513 static int st_mtiocltop(struct scsi_tape *un, intptr_t arg, int flag);
 514 static int st_do_mtioctop(struct scsi_tape *un, struct mtlop *mtop);
 515 static void st_start(struct scsi_tape *un);
 516 static int st_handle_start_busy(struct scsi_tape *un, struct buf *bp,
 517     clock_t timeout_interval, int queued);
 518 static int st_handle_intr_busy(struct scsi_tape *un, struct buf *bp,
 519     clock_t timeout_interval);
 520 static int st_handle_intr_retry_lcmd(struct scsi_tape *un, struct buf *bp);
 521 static void st_done_and_mutex_exit(struct scsi_tape *un, struct buf *bp);
 522 static void st_init(struct scsi_tape *un);
 523 static void st_make_cmd(struct scsi_tape *un, struct buf *bp,
 524     int (*func)(caddr_t));
 525 static void st_make_uscsi_cmd(struct scsi_tape *, struct uscsi_cmd *,
 526     struct buf *bp, int (*func)(caddr_t));
 527 static void st_intr(struct scsi_pkt *pkt);
 528 static void st_set_state(struct scsi_tape *un, buf_t *bp);
 529 static void st_test_append(struct buf *bp);
 530 static int st_runout(caddr_t);
 531 static int st_cmd(struct scsi_tape *un, int com, int64_t count, int wait);
 532 static int st_setup_cmd(struct scsi_tape *un, buf_t *bp, int com,
 533     int64_t count);
 534 static int st_set_compression(struct scsi_tape *un);
 535 static int st_write_fm(dev_t dev, int wfm);
 536 static int st_determine_generic(struct scsi_tape *un);
 537 static int st_determine_density(struct scsi_tape *un, int rw);
 538 static int st_get_density(struct scsi_tape *un);
 539 static int st_set_density(struct scsi_tape *un);
 540 static int st_loadtape(struct scsi_tape *un);
 541 static int st_modesense(struct scsi_tape *un);
 542 static int st_modeselect(struct scsi_tape *un);
 543 static errstate st_handle_incomplete(struct scsi_tape *un, struct buf *bp);
 544 static int st_wrongtapetype(struct scsi_tape *un);
 545 static errstate st_check_error(struct scsi_tape *un, struct scsi_pkt *pkt);
 546 static errstate st_handle_sense(struct scsi_tape *un, struct buf *bp,
 547     tapepos_t *);
 548 static errstate st_handle_autosense(struct scsi_tape *un, struct buf *bp,
 549     tapepos_t *);
 550 static int st_get_error_entry(struct scsi_tape *un, intptr_t arg, int flag);
 551 static void st_update_error_stack(struct scsi_tape *un, struct scsi_pkt *pkt,
 552     struct scsi_arq_status *cmd);
 553 static void st_empty_error_stack(struct scsi_tape *un);
 554 static errstate st_decode_sense(struct scsi_tape *un, struct buf *bp, int amt,
 555     struct scsi_arq_status *, tapepos_t *);
 556 static int st_report_soft_errors(dev_t dev, int flag);
 557 static void st_delayed_cv_broadcast(void *arg);
 558 static int st_check_media(dev_t dev, enum mtio_state state);
 559 static int st_media_watch_cb(caddr_t arg, struct scsi_watch_result *resultp);
 560 static void st_intr_restart(void *arg);
 561 static void st_start_restart(void *arg);
 562 static int st_gen_mode_sense(struct scsi_tape *un, ubufunc_t ubf, int page,
 563     struct seq_mode *page_data, int page_size);
 564 static int st_change_block_size(struct scsi_tape *un, uint32_t nblksz);
 565 static int st_gen_mode_select(struct scsi_tape *un, ubufunc_t ubf,
 566     struct seq_mode *page_data, int page_size);
 567 static int st_read_block_limits(struct scsi_tape *un,
 568     struct read_blklim *read_blk);
 569 static int st_report_density_support(struct scsi_tape *un,
 570     uchar_t *density_data, size_t buflen);
 571 static int st_report_supported_operation(struct scsi_tape *un,
 572     uchar_t *oper_data, uchar_t option_code, ushort_t service_action);
 573 static int st_tape_init(struct scsi_tape *un);
 574 static void st_flush(struct scsi_tape *un);
 575 static void st_set_pe_errno(struct scsi_tape *un);
 576 static void st_hba_unflush(struct scsi_tape *un);
 577 static void st_turn_pe_on(struct scsi_tape *un);
 578 static void st_turn_pe_off(struct scsi_tape *un);
 579 static void st_set_pe_flag(struct scsi_tape *un);
 580 static void st_clear_pe(struct scsi_tape *un);
 581 static void st_wait_for_io(struct scsi_tape *un);
 582 static int st_set_devconfig_page(struct scsi_tape *un, int compression_on);
 583 static int st_set_datacomp_page(struct scsi_tape *un, int compression_on);
 584 static int st_reserve_release(struct scsi_tape *un, int command, ubufunc_t ubf);
 585 static int st_check_cdb_for_need_to_reserve(struct scsi_tape *un, uchar_t *cdb);
 586 static int st_check_cmd_for_need_to_reserve(struct scsi_tape *un, uchar_t cmd,
 587     int count);
 588 static int st_take_ownership(struct scsi_tape *un, ubufunc_t ubf);
 589 static int st_check_asc_ascq(struct scsi_tape *un);
 590 static int st_check_clean_bit(struct scsi_tape *un);
 591 static int st_check_alert_flags(struct scsi_tape *un);
 592 static int st_check_sequential_clean_bit(struct scsi_tape *un);
 593 static int st_check_sense_clean_bit(struct scsi_tape *un);
 594 static int st_clear_unit_attentions(dev_t dev_instance, int max_trys);
 595 static void st_calculate_timeouts(struct scsi_tape *un);
 596 static writablity st_is_drive_worm(struct scsi_tape *un);
 597 static int st_read_attributes(struct scsi_tape *un, uint16_t attribute,
 598     void *buf, size_t size, ubufunc_t bufunc);
 599 static int st_get_special_inquiry(struct scsi_tape *un, uchar_t size,
 600     caddr_t dest, uchar_t page);
 601 static int st_update_block_pos(struct scsi_tape *un, bufunc_t bf,
 602     int post_space);
 603 static int st_interpret_read_pos(struct scsi_tape const *un, tapepos_t *dest,
 604     read_p_types type, size_t data_sz, const caddr_t responce, int post_space);
 605 static int st_get_read_pos(struct scsi_tape *un, buf_t *bp);
 606 static int st_logical_block_locate(struct scsi_tape *un, ubufunc_t ubf,
 607     tapepos_t *pos, uint64_t lblk, uchar_t partition);
 608 static int st_mtfsf_ioctl(struct scsi_tape *un, int64_t files);
 609 static int st_mtfsr_ioctl(struct scsi_tape *un, int64_t count);
 610 static int st_mtbsf_ioctl(struct scsi_tape *un, int64_t files);
 611 static int st_mtnbsf_ioctl(struct scsi_tape *un, int64_t count);
 612 static int st_mtbsr_ioctl(struct scsi_tape *un, int64_t num);
 613 static int st_mtfsfm_ioctl(struct scsi_tape *un, int64_t cnt);
 614 static int st_mtbsfm_ioctl(struct scsi_tape *un, int64_t cnt);
 615 static int st_backward_space_files(struct scsi_tape *un, int64_t count,
 616     int infront);
 617 static int st_forward_space_files(struct scsi_tape *un, int64_t files);
 618 static int st_scenic_route_to_begining_of_file(struct scsi_tape *un,
 619     int32_t fileno);
 620 static int st_space_to_begining_of_file(struct scsi_tape *un);
 621 static int st_space_records(struct scsi_tape *un, int64_t records);
 622 static int st_get_media_identification(struct scsi_tape *un, ubufunc_t bufunc);
 623 static errstate st_command_recovery(struct scsi_tape *un, struct scsi_pkt *pkt,
 624     errstate onentry);
 625 static void st_recover(void *arg);
 626 static void st_recov_cb(struct scsi_pkt *pkt);
 627 static int st_rcmd(struct scsi_tape *un, int com, int64_t count, int wait);
 628 static int st_uscsi_rcmd(struct scsi_tape *un, struct uscsi_cmd *ucmd,
 629     int flag);
 630 static void st_add_recovery_info_to_pkt(struct scsi_tape *un, buf_t *bp,
 631     struct scsi_pkt *cmd);
 632 static int st_check_mode_for_change(struct scsi_tape *un, ubufunc_t ubf);
 633 static int st_test_path_to_device(struct scsi_tape *un);
 634 static int st_recovery_read_pos(struct scsi_tape *un, read_p_types type,
 635     read_pos_data_t *raw);
 636 static int st_recovery_get_position(struct scsi_tape *un, tapepos_t *read,
 637     read_pos_data_t *raw);
 638 static int st_compare_expected_position(struct scsi_tape *un, st_err_info *ei,
 639     cmd_attribute const * cmd_att, tapepos_t *read);
 640 static errstate st_recover_reissue_pkt(struct scsi_tape *us,
 641     struct scsi_pkt *pkt);
 642 static int st_transport(struct scsi_tape *un, struct scsi_pkt *pkt);
 643 static buf_t *st_remove_from_queue(buf_t **head, buf_t **tail, buf_t *bp);
 644 static void st_add_to_queue(buf_t **head, buf_t **tail, buf_t *end, buf_t *bp);
 645 static int st_reset(struct scsi_tape *un, int reset_type);
 646 static void st_reset_notification(caddr_t arg);
 647 static const cmd_attribute *st_lookup_cmd_attribute(unsigned char cmd);
 648 
 649 static int st_set_target_TLR_mode(struct scsi_tape *un, ubufunc_t ubf);
 650 static int st_make_sure_mode_data_is_correct(struct scsi_tape *un,
 651     ubufunc_t ubf);
 652 
 653 #ifdef  __x86
 654 /*
 655  * routines for I/O in big block size
 656  */
 657 static void st_release_contig_mem(struct scsi_tape *un, struct contig_mem *cp);
 658 static struct contig_mem *st_get_contig_mem(struct scsi_tape *un, size_t len,
 659     int alloc_flags);
 660 static int st_bigblk_xfer_done(struct buf *bp);
 661 static struct buf *st_get_bigblk_bp(struct buf *bp);
 662 #endif
 663 static void st_print_position(dev_info_t *dev, char *label, uint_t level,
 664     const char *comment, tapepos_t *pos);
 665 
 666 /*
 667  * error statistics create/update functions
 668  */
 669 static int st_create_errstats(struct scsi_tape *, int);
 670 static int st_validate_tapemarks(struct scsi_tape *un, ubufunc_t ubf,
 671     tapepos_t *pos);
 672 
 673 #ifdef STDEBUG
 674 static void st_debug_cmds(struct scsi_tape *un, int com, int count, int wait);
 675 #endif /* STDEBUG */
 676 static char *st_dev_name(dev_t dev);
 677 
 678 #if !defined(lint)
 679 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt",
 680     scsi_pkt buf uio scsi_cdb uscsi_cmd))
 681 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_extended_sense scsi_status))
 682 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", recov_info))
 683 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device))
 684 _NOTE(DATA_READABLE_WITHOUT_LOCK(st_drivetype scsi_address))
 685 #endif
 686 
 687 /*
 688  * autoconfiguration routines.
 689  */
 690 
 691 static struct modldrv modldrv = {
 692         &mod_driverops,             /* Type of module. This one is a driver */
 693         "SCSI tape Driver",     /* Name of the module. */
 694         &st_ops                     /* driver ops */
 695 };
 696 
 697 static struct modlinkage modlinkage = {
 698         MODREV_1, &modldrv, NULL
 699 };
 700 
 701 /*
 702  * Notes on Post Reset Behavior in the tape driver:
 703  *
 704  * When the tape drive is opened, the driver  attempts  to make sure that
 705  * the tape head is positioned exactly where it was left when it was last
 706  * closed  provided  the  medium  is not  changed.  If the tape  drive is
 707  * opened in O_NDELAY mode, the repositioning  (if necessary for any loss
 708  * of position due to reset) will happen when the first tape operation or
 709  * I/O occurs.  The repositioning (if required) may not be possible under
 710  * certain situations such as when the device firmware not able to report
 711  * the medium  change in the REQUEST  SENSE data  because of a reset or a
 712  * misbehaving  bus  not  allowing  the  reposition  to  happen.  In such
 713  * extraordinary  situations, where the driver fails to position the head
 714  * at its  original  position,  it will fail the open the first  time, to
 715  * save the applications from overwriting the data.  All further attempts
 716  * to open the tape device will result in the driver  attempting  to load
 717  * the  tape at BOT  (beginning  of  tape).  Also a  warning  message  to
 718  * indicate  that further  attempts to open the tape device may result in
 719  * the tape being  loaded at BOT will be printed on the  console.  If the
 720  * tape  device is opened  in  O_NDELAY  mode,  failure  to  restore  the
 721  * original tape head  position,  will result in the failure of the first
 722  * tape  operation  or I/O,  Further,  the  driver  will  invalidate  its
 723  * internal tape position  which will  necessitate  the  applications  to
 724  * validate the position by using either a tape  positioning  ioctl (such
 725  * as MTREW) or closing and reopening the tape device.
 726  *
 727  */
 728 
 729 int
 730 _init(void)
 731 {
 732         int e;
 733 
 734         if (((e = ddi_soft_state_init(&st_state,
 735             sizeof (struct scsi_tape), ST_MAXUNIT)) != 0)) {
 736                 return (e);
 737         }
 738 
 739         if ((e = mod_install(&modlinkage)) != 0) {
 740                 ddi_soft_state_fini(&st_state);
 741         } else {
 742 #ifdef STDEBUG
 743                 mutex_init(&st_debug_mutex, NULL, MUTEX_DRIVER, NULL);
 744 #endif
 745 
 746 #if defined(__x86)
 747                 /* set the max physical address for iob allocs on x86 */
 748                 st_alloc_attr.dma_attr_addr_hi = st_max_phys_addr;
 749 
 750                 /*
 751                  * set the sgllen for iob allocs on x86. If this is set less
 752                  * than the number of pages the buffer will take
 753                  * (taking into account alignment), it would force the
 754                  * allocator to try and allocate contiguous pages.
 755                  */
 756                 st_alloc_attr.dma_attr_sgllen = st_sgl_size;
 757 #endif
 758         }
 759 
 760         return (e);
 761 }
 762 
 763 int
 764 _fini(void)
 765 {
 766         int e;
 767 
 768         if ((e = mod_remove(&modlinkage)) != 0) {
 769                 return (e);
 770         }
 771 
 772 #ifdef STDEBUG
 773         mutex_destroy(&st_debug_mutex);
 774 #endif
 775 
 776         ddi_soft_state_fini(&st_state);
 777 
 778         return (e);
 779 }
 780 
 781 int
 782 _info(struct modinfo *modinfop)
 783 {
 784         return (mod_info(&modlinkage, modinfop));
 785 }
 786 
 787 
 788 static int
 789 st_probe(dev_info_t *devi)
 790 {
 791         int instance;
 792         struct scsi_device *devp;
 793         int rval;
 794 
 795 #if !defined(__sparc)
 796         char    *tape_prop;
 797         int     tape_prop_len;
 798 #endif
 799 
 800         ST_ENTR(devi, st_probe);
 801 
 802         /* If self identifying device */
 803         if (ddi_dev_is_sid(devi) == DDI_SUCCESS) {
 804                 return (DDI_PROBE_DONTCARE);
 805         }
 806 
 807 #if !defined(__sparc)
 808         /*
 809          * Since some x86 HBAs have devnodes that look like SCSI as
 810          * far as we can tell but aren't really SCSI (DADK, like mlx)
 811          * we check for the presence of the "tape" property.
 812          */
 813         if (ddi_prop_op(DDI_DEV_T_NONE, devi, PROP_LEN_AND_VAL_ALLOC,
 814             DDI_PROP_CANSLEEP, "tape",
 815             (caddr_t)&tape_prop, &tape_prop_len) != DDI_PROP_SUCCESS) {
 816                 return (DDI_PROBE_FAILURE);
 817         }
 818         if (strncmp(tape_prop, "sctp", tape_prop_len) != 0) {
 819                 kmem_free(tape_prop, tape_prop_len);
 820                 return (DDI_PROBE_FAILURE);
 821         }
 822         kmem_free(tape_prop, tape_prop_len);
 823 #endif
 824 
 825         devp = ddi_get_driver_private(devi);
 826         instance = ddi_get_instance(devi);
 827 
 828         if (ddi_get_soft_state(st_state, instance) != NULL) {
 829                 return (DDI_PROBE_PARTIAL);
 830         }
 831 
 832 
 833         /*
 834          * Turn around and call probe routine to see whether
 835          * we actually have a tape at this SCSI nexus.
 836          */
 837         if (scsi_probe(devp, NULL_FUNC) == SCSIPROBE_EXISTS) {
 838 
 839                 /*
 840                  * In checking the whole inq_dtype byte we are looking at both
 841                  * the Peripheral Qualifier and the Peripheral Device Type.
 842                  * For this driver we are only interested in sequential devices
 843                  * that are connected or capable if connecting to this logical
 844                  * unit.
 845                  */
 846                 if (devp->sd_inq->inq_dtype ==
 847                     (DTYPE_SEQUENTIAL | DPQ_POSSIBLE)) {
 848                         ST_DEBUG6(devi, st_label, SCSI_DEBUG,
 849                             "probe exists\n");
 850                         rval = DDI_PROBE_SUCCESS;
 851                 } else {
 852                         rval = DDI_PROBE_FAILURE;
 853                 }
 854         } else {
 855                 ST_DEBUG6(devi, st_label, SCSI_DEBUG,
 856                     "probe failure: nothing there\n");
 857                 rval = DDI_PROBE_FAILURE;
 858         }
 859         scsi_unprobe(devp);
 860         return (rval);
 861 }
 862 
 863 static int
 864 st_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
 865 {
 866         int     instance;
 867         int     wide;
 868         int     dev_instance;
 869         int     ret_status;
 870         struct  scsi_device *devp;
 871         int     node_ix;
 872         struct  scsi_tape *un;
 873 
 874         ST_ENTR(devi, st_attach);
 875 
 876         devp = ddi_get_driver_private(devi);
 877         instance = ddi_get_instance(devi);
 878 
 879         switch (cmd) {
 880                 case DDI_ATTACH:
 881                         if (ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
 882                             "tape-command-recovery-disable", 0) != 0) {
 883                                 st_recov_sz = sizeof (pkt_info);
 884                         }
 885                         if (st_doattach(devp, SLEEP_FUNC) == DDI_FAILURE) {
 886                                 return (DDI_FAILURE);
 887                         }
 888                         break;
 889                 case DDI_RESUME:
 890                         /*
 891                          * Suspend/Resume
 892                          *
 893                          * When the driver suspended, there might be
 894                          * outstanding cmds and therefore we need to
 895                          * reset the suspended flag and resume the scsi
 896                          * watch thread and restart commands and timeouts
 897                          */
 898 
 899                         if (!(un = ddi_get_soft_state(st_state, instance))) {
 900                                 return (DDI_FAILURE);
 901                         }
 902                         dev_instance = ((un->un_dev == 0) ? MTMINOR(instance) :
 903                             un->un_dev);
 904 
 905                         mutex_enter(ST_MUTEX);
 906 
 907                         un->un_throttle = un->un_max_throttle;
 908                         un->un_tids_at_suspend = 0;
 909                         un->un_pwr_mgmt = ST_PWR_NORMAL;
 910 
 911                         if (un->un_swr_token) {
 912                                 scsi_watch_resume(un->un_swr_token);
 913                         }
 914 
 915                         /*
 916                          * Restart timeouts
 917                          */
 918                         if ((un->un_tids_at_suspend & ST_DELAY_TID) != 0) {
 919                                 mutex_exit(ST_MUTEX);
 920                                 un->un_delay_tid = timeout(
 921                                     st_delayed_cv_broadcast, un,
 922                                     drv_usectohz((clock_t)
 923                                     MEDIA_ACCESS_DELAY));
 924                                 mutex_enter(ST_MUTEX);
 925                         }
 926 
 927                         if (un->un_tids_at_suspend & ST_HIB_TID) {
 928                                 mutex_exit(ST_MUTEX);
 929                                 un->un_hib_tid = timeout(st_intr_restart, un,
 930                                     ST_STATUS_BUSY_TIMEOUT);
 931                                 mutex_enter(ST_MUTEX);
 932                         }
 933 
 934                         ret_status = st_clear_unit_attentions(dev_instance, 5);
 935 
 936                         /*
 937                          * now check if we need to restore the tape position
 938                          */
 939                         if ((un->un_suspend_pos.pmode != invalid) &&
 940                             ((un->un_suspend_pos.fileno > 0) ||
 941                             (un->un_suspend_pos.blkno > 0)) ||
 942                             (un->un_suspend_pos.lgclblkno > 0)) {
 943                                 if (ret_status != 0) {
 944                                         /*
 945                                          * tape didn't get good TUR
 946                                          * just print out error messages
 947                                          */
 948                                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
 949                                             "st_attach-RESUME: tape failure "
 950                                             " tape position will be lost");
 951                                 } else {
 952                                         /* this prints errors */
 953                                         (void) st_validate_tapemarks(un,
 954                                             st_uscsi_cmd, &un->un_suspend_pos);
 955                                 }
 956                                 /*
 957                                  * there are no retries, if there is an error
 958                                  * we don't know if the tape has changed
 959                                  */
 960                                 un->un_suspend_pos.pmode = invalid;
 961                         }
 962 
 963                         /* now we are ready to start up any queued I/Os */
 964                         if (un->un_ncmds || un->un_quef) {
 965                                 st_start(un);
 966                         }
 967 
 968                         cv_broadcast(&un->un_suspend_cv);
 969                         mutex_exit(ST_MUTEX);
 970                         return (DDI_SUCCESS);
 971 
 972                 default:
 973                         return (DDI_FAILURE);
 974         }
 975 
 976         un = ddi_get_soft_state(st_state, instance);
 977 
 978         ST_DEBUG(devi, st_label, SCSI_DEBUG,
 979             "st_attach: instance=%x\n", instance);
 980 
 981         /*
 982          * Add a zero-length attribute to tell the world we support
 983          * kernel ioctls (for layered drivers)
 984          */
 985         (void) ddi_prop_create(DDI_DEV_T_NONE, devi, DDI_PROP_CANSLEEP,
 986             DDI_KERNEL_IOCTL, NULL, 0);
 987 
 988         ddi_report_dev((dev_info_t *)devi);
 989 
 990         /*
 991          * If it's a SCSI-2 tape drive which supports wide,
 992          * tell the host adapter to use wide.
 993          */
 994         wide = ((devp->sd_inq->inq_rdf == RDF_SCSI2) &&
 995             (devp->sd_inq->inq_wbus16 || devp->sd_inq->inq_wbus32)) ?  1 : 0;
 996 
 997         if (scsi_ifsetcap(ROUTE, "wide-xfer", wide, 1) == 1) {
 998                 ST_DEBUG(devi, st_label, SCSI_DEBUG,
 999                     "Wide Transfer %s\n", wide ? "enabled" : "disabled");
1000         }
1001 
1002         /*
1003          * enable autorequest sense; keep the rq packet around in case
1004          * the autorequest sense fails because of a busy condition
1005          * do a getcap first in case the capability is not variable
1006          */
1007         if (scsi_ifgetcap(ROUTE, "auto-rqsense", 1) == 1) {
1008                 un->un_arq_enabled = 1;
1009         } else {
1010                 un->un_arq_enabled =
1011                     ((scsi_ifsetcap(ROUTE, "auto-rqsense", 1, 1) == 1) ? 1 : 0);
1012         }
1013 
1014         ST_DEBUG(devi, st_label, SCSI_DEBUG, "auto request sense %s\n",
1015             (un->un_arq_enabled ? "enabled" : "disabled"));
1016 
1017         un->un_untagged_qing =
1018             (scsi_ifgetcap(ROUTE, "untagged-qing", 0) == 1);
1019 
1020         /*
1021          * XXX - This is just for 2.6.  to tell users that write buffering
1022          *      has gone away.
1023          */
1024         if (un->un_arq_enabled && un->un_untagged_qing) {
1025                 if (ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
1026                     "tape-driver-buffering", 0) != 0) {
1027                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
1028                             "Write Data Buffering has been depricated. Your "
1029                             "applications should continue to work normally.\n"
1030                             " But, they should  ported to use Asynchronous "
1031                             " I/O\n"
1032                             " For more information, read about "
1033                             " tape-driver-buffering "
1034                             "property in the st(7d) man page\n");
1035                 }
1036         }
1037 
1038         un->un_max_throttle = un->un_throttle = un->un_last_throttle = 1;
1039         un->un_flush_on_errors = 0;
1040         un->un_mkr_pkt = (struct scsi_pkt *)NULL;
1041 
1042         ST_DEBUG(devi, st_label, SCSI_DEBUG,
1043             "throttle=%x, max_throttle = %x\n",
1044             un->un_throttle, un->un_max_throttle);
1045 
1046         /* initialize persistent errors to nil */
1047         un->un_persistence = 0;
1048         un->un_persist_errors = 0;
1049 
1050         /*
1051          * Get dma-max from HBA driver. If it is not defined, use 64k
1052          */
1053         un->un_maxdma        = scsi_ifgetcap(&devp->sd_address, "dma-max", 1);
1054         if (un->un_maxdma == -1) {
1055                 ST_DEBUG(devi, st_label, SCSI_DEBUG,
1056                     "Received a value that looked like -1. Using 64k maxdma");
1057                 un->un_maxdma = (64 * ONE_K);
1058         }
1059 
1060 #ifdef  __x86
1061         /*
1062          * for x86, the device may be able to DMA more than the system will
1063          * allow under some circumstances. We need account for both the HBA's
1064          * and system's contraints.
1065          *
1066          * Get the maximum DMA under worse case conditions. e.g. looking at the
1067          * device constraints, the max copy buffer size, and the worse case
1068          * fragmentation. NOTE: this may differ from dma-max since dma-max
1069          * doesn't take the worse case framentation into account.
1070          *
1071          * e.g. a device may be able to DMA 16MBytes, but can only DMA 1MByte
1072          * if none of the pages are contiguous. Keeping track of both of these
1073          * values allows us to support larger tape block sizes on some devices.
1074          */
1075         un->un_maxdma_arch = scsi_ifgetcap(&devp->sd_address, "dma-max-arch",
1076             1);
1077 
1078         /*
1079          * If the dma-max-arch capability is not implemented, or the value
1080          * comes back higher than what was reported in dma-max, use dma-max.
1081          */
1082         if ((un->un_maxdma_arch == -1) ||
1083             ((uint_t)un->un_maxdma < (uint_t)un->un_maxdma_arch)) {
1084                 un->un_maxdma_arch = un->un_maxdma;
1085         }
1086 #endif
1087 
1088         /*
1089          * Get the max allowable cdb size
1090          */
1091         un->un_max_cdb_sz =
1092             scsi_ifgetcap(&devp->sd_address, "max-cdb-length", 1);
1093         if (un->un_max_cdb_sz < CDB_GROUP0) {
1094                 ST_DEBUG(devi, st_label, SCSI_DEBUG,
1095                     "HBA reported max-cdb-length as %d\n", un->un_max_cdb_sz);
1096                 un->un_max_cdb_sz = CDB_GROUP4; /* optimistic default */
1097         }
1098 
1099         if (strcmp(ddi_driver_name(ddi_get_parent(ST_DEVINFO)), "scsi_vhci")) {
1100                 un->un_multipath = 0;
1101         } else {
1102                 un->un_multipath = 1;
1103         }
1104 
1105         un->un_maxbsize = MAXBSIZE_UNKNOWN;
1106 
1107         un->un_mediastate = MTIO_NONE;
1108         un->un_HeadClean  = TAPE_ALERT_SUPPORT_UNKNOWN;
1109 
1110         /*
1111          * initialize kstats
1112          */
1113         un->un_stats = kstat_create("st", instance, NULL, "tape",
1114             KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT);
1115         if (un->un_stats) {
1116                 un->un_stats->ks_lock = ST_MUTEX;
1117                 kstat_install(un->un_stats);
1118         }
1119         (void) st_create_errstats(un, instance);
1120 
1121         /*
1122          * find the drive type for this target
1123          */
1124         mutex_enter(ST_MUTEX);
1125         un->un_dev = MTMINOR(instance);
1126         st_known_tape_type(un);
1127         un->un_dev = 0;
1128         mutex_exit(ST_MUTEX);
1129 
1130         for (node_ix = 0; node_ix < ST_NUM_MEMBERS(st_minor_data); node_ix++) {
1131                 int minor;
1132                 char *name;
1133 
1134                 name  = st_minor_data[node_ix].name;
1135                 minor = st_minor_data[node_ix].minor;
1136 
1137                 /*
1138                  * For default devices set the density to the
1139                  * preferred default density for this device.
1140                  */
1141                 if (node_ix <= DEF_BSD_NR) {
1142                         minor |= un->un_dp->default_density;
1143                 }
1144                 minor |= MTMINOR(instance);
1145 
1146                 if (ddi_create_minor_node(devi, name, S_IFCHR, minor,
1147                     DDI_NT_TAPE, NULL) == DDI_SUCCESS) {
1148                         continue;
1149                 }
1150 
1151                 ddi_remove_minor_node(devi, NULL);
1152 
1153                 (void) scsi_reset_notify(ROUTE, SCSI_RESET_CANCEL,
1154                     st_reset_notification, (caddr_t)un);
1155                 cv_destroy(&un->un_clscv);
1156                 cv_destroy(&un->un_sbuf_cv);
1157                 cv_destroy(&un->un_queue_cv);
1158                 cv_destroy(&un->un_state_cv);
1159 #ifdef  __x86
1160                 cv_destroy(&un->un_contig_mem_cv);
1161 #endif
1162                 cv_destroy(&un->un_suspend_cv);
1163                 cv_destroy(&un->un_tape_busy_cv);
1164                 cv_destroy(&un->un_recov_buf_cv);
1165                 if (un->un_recov_taskq) {
1166                         ddi_taskq_destroy(un->un_recov_taskq);
1167                 }
1168                 if (un->un_sbufp) {
1169                         freerbuf(un->un_sbufp);
1170                 }
1171                 if (un->un_recov_buf) {
1172                         freerbuf(un->un_recov_buf);
1173                 }
1174                 if (un->un_uscsi_rqs_buf) {
1175                         kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1176                 }
1177                 if (un->un_mspl) {
1178                         i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1179                 }
1180                 if (un->un_dp_size) {
1181                         kmem_free(un->un_dp, un->un_dp_size);
1182                 }
1183                 if (un->un_state) {
1184                         kstat_delete(un->un_stats);
1185                 }
1186                 if (un->un_errstats) {
1187                         kstat_delete(un->un_errstats);
1188                 }
1189 
1190                 scsi_destroy_pkt(un->un_rqs);
1191                 scsi_free_consistent_buf(un->un_rqs_bp);
1192                 ddi_soft_state_free(st_state, instance);
1193                 devp->sd_private = NULL;
1194                 devp->sd_sense = NULL;
1195 
1196                 ddi_prop_remove_all(devi);
1197                 return (DDI_FAILURE);
1198         }
1199 
1200         return (DDI_SUCCESS);
1201 }
1202 
1203 /*
1204  * st_detach:
1205  *
1206  * we allow a detach if and only if:
1207  *      - no tape is currently inserted
1208  *      - tape position is at BOT or unknown
1209  *              (if it is not at BOT then a no rewind
1210  *              device was opened and we have to preserve state)
1211  *      - it must be in a closed state : no timeouts or scsi_watch requests
1212  *              will exist if it is closed, so we don't need to check for
1213  *              them here.
1214  */
1215 /*ARGSUSED*/
1216 static int
1217 st_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1218 {
1219         int instance;
1220         int result;
1221         struct scsi_device *devp;
1222         struct scsi_tape *un;
1223         clock_t wait_cmds_complete;
1224 
1225         ST_ENTR(devi, st_detach);
1226 
1227         instance = ddi_get_instance(devi);
1228 
1229         if (!(un = ddi_get_soft_state(st_state, instance))) {
1230                 return (DDI_FAILURE);
1231         }
1232 
1233         mutex_enter(ST_MUTEX);
1234 
1235         /*
1236          * Clear error entry stack
1237          */
1238         st_empty_error_stack(un);
1239 
1240         mutex_exit(ST_MUTEX);
1241 
1242         switch (cmd) {
1243 
1244         case DDI_DETACH:
1245                 /*
1246                  * Undo what we did in st_attach & st_doattach,
1247                  * freeing resources and removing things we installed.
1248                  * The system framework guarantees we are not active
1249                  * with this devinfo node in any other entry points at
1250                  * this time.
1251                  */
1252 
1253                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1254                     "st_detach: instance=%x, un=%p\n", instance,
1255                     (void *)un);
1256 
1257                 if (((un->un_dp->options & ST_UNLOADABLE) == 0) ||
1258                     ((un->un_rsvd_status & ST_APPLICATION_RESERVATIONS) != 0) ||
1259                     (un->un_ncmds != 0) || (un->un_quef != NULL) ||
1260                     (un->un_state != ST_STATE_CLOSED)) {
1261                         /*
1262                          * we cannot unload some targets because the
1263                          * inquiry returns junk unless immediately
1264                          * after a reset
1265                          */
1266                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
1267                             "cannot unload instance %x\n", instance);
1268                         un->un_unit_attention_flags |= 4;
1269                         return (DDI_FAILURE);
1270                 }
1271 
1272                 /*
1273                  * if the tape has been removed then we may unload;
1274                  * do a test unit ready and if it returns NOT READY
1275                  * then we assume that it is safe to unload.
1276                  * as a side effect, pmode may be set to invalid if the
1277                  * the test unit ready fails;
1278                  * also un_state may be set to non-closed, so reset it
1279                  */
1280                 if ((un->un_dev) &&          /* Been opened since attach */
1281                     ((un->un_pos.pmode == legacy) &&
1282                     (un->un_pos.fileno > 0) ||    /* Known position not rewound */
1283                     (un->un_pos.blkno != 0)) ||      /* Or within first file */
1284                     ((un->un_pos.pmode == logical) &&
1285                     (un->un_pos.lgclblkno > 0))) {
1286                         mutex_enter(ST_MUTEX);
1287                         /*
1288                          * Send Test Unit Ready in the hopes that if
1289                          * the drive is not in the state we think it is.
1290                          * And the state will be changed so it can be detached.
1291                          * If the command fails to reach the device and
1292                          * the drive was not rewound or unloaded we want
1293                          * to fail the detach till a user command fails
1294                          * where after the detach will succead.
1295                          */
1296                         result = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
1297                         /*
1298                          * After TUR un_state may be set to non-closed,
1299                          * so reset it back.
1300                          */
1301                         un->un_state = ST_STATE_CLOSED;
1302                         mutex_exit(ST_MUTEX);
1303                 }
1304                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1305                     "un_status=%x, fileno=%x, blkno=%x\n",
1306                     un->un_status, un->un_pos.fileno, un->un_pos.blkno);
1307 
1308                 /*
1309                  * check again:
1310                  * if we are not at BOT then it is not safe to unload
1311                  */
1312                 if ((un->un_dev) &&          /* Been opened since attach */
1313                     (result != EACCES) &&       /* drive is use by somebody */
1314                     ((((un->un_pos.pmode == legacy) &&
1315                     (un->un_pos.fileno > 0) ||    /* Known position not rewound */
1316                     (un->un_pos.blkno != 0)) ||      /* Or within first file */
1317                     ((un->un_pos.pmode == logical) &&
1318                     (un->un_pos.lgclblkno > 0))) &&
1319                     ((un->un_state == ST_STATE_CLOSED) &&
1320                     (un->un_laststate == ST_STATE_CLOSING)))) {
1321 
1322                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1323                             "cannot detach: pmode=%d fileno=0x%x, blkno=0x%x"
1324                             " lgclblkno=0x%"PRIx64"\n", un->un_pos.pmode,
1325                             un->un_pos.fileno, un->un_pos.blkno,
1326                             un->un_pos.lgclblkno);
1327                         un->un_unit_attention_flags |= 4;
1328                         return (DDI_FAILURE);
1329                 }
1330 
1331                 /*
1332                  * Just To make sure that we have released the
1333                  * tape unit .
1334                  */
1335                 if (un->un_dev && (un->un_rsvd_status & ST_RESERVE) &&
1336                     !DEVI_IS_DEVICE_REMOVED(devi)) {
1337                         mutex_enter(ST_MUTEX);
1338                         (void) st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
1339                         mutex_exit(ST_MUTEX);
1340                 }
1341 
1342                 /*
1343                  * now remove other data structures allocated in st_doattach()
1344                  */
1345                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1346                     "destroying/freeing\n");
1347 
1348                 (void) scsi_reset_notify(ROUTE, SCSI_RESET_CANCEL,
1349                     st_reset_notification, (caddr_t)un);
1350                 cv_destroy(&un->un_clscv);
1351                 cv_destroy(&un->un_sbuf_cv);
1352                 cv_destroy(&un->un_queue_cv);
1353                 cv_destroy(&un->un_suspend_cv);
1354                 cv_destroy(&un->un_tape_busy_cv);
1355                 cv_destroy(&un->un_recov_buf_cv);
1356 
1357                 if (un->un_recov_taskq) {
1358                         ddi_taskq_destroy(un->un_recov_taskq);
1359                 }
1360 
1361                 if (un->un_hib_tid) {
1362                         (void) untimeout(un->un_hib_tid);
1363                         un->un_hib_tid = 0;
1364                 }
1365 
1366                 if (un->un_delay_tid) {
1367                         (void) untimeout(un->un_delay_tid);
1368                         un->un_delay_tid = 0;
1369                 }
1370                 cv_destroy(&un->un_state_cv);
1371 
1372 #ifdef  __x86
1373                 cv_destroy(&un->un_contig_mem_cv);
1374 
1375                 if (un->un_contig_mem_hdl != NULL) {
1376                         ddi_dma_free_handle(&un->un_contig_mem_hdl);
1377                 }
1378 #endif
1379                 if (un->un_sbufp) {
1380                         freerbuf(un->un_sbufp);
1381                 }
1382                 if (un->un_recov_buf) {
1383                         freerbuf(un->un_recov_buf);
1384                 }
1385                 if (un->un_uscsi_rqs_buf) {
1386                         kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1387                 }
1388                 if (un->un_mspl) {
1389                         i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1390                 }
1391                 if (un->un_rqs) {
1392                         scsi_destroy_pkt(un->un_rqs);
1393                         scsi_free_consistent_buf(un->un_rqs_bp);
1394                 }
1395                 if (un->un_mkr_pkt) {
1396                         scsi_destroy_pkt(un->un_mkr_pkt);
1397                 }
1398                 if (un->un_arq_enabled) {
1399                         (void) scsi_ifsetcap(ROUTE, "auto-rqsense", 0, 1);
1400                 }
1401                 if (un->un_dp_size) {
1402                         kmem_free(un->un_dp, un->un_dp_size);
1403                 }
1404                 if (un->un_stats) {
1405                         kstat_delete(un->un_stats);
1406                         un->un_stats = (kstat_t *)0;
1407                 }
1408                 if (un->un_errstats) {
1409                         kstat_delete(un->un_errstats);
1410                         un->un_errstats = (kstat_t *)0;
1411                 }
1412                 if (un->un_media_id_len) {
1413                         kmem_free(un->un_media_id, un->un_media_id_len);
1414                 }
1415                 devp = ST_SCSI_DEVP;
1416                 ddi_soft_state_free(st_state, instance);
1417                 devp->sd_private = NULL;
1418                 devp->sd_sense = NULL;
1419                 scsi_unprobe(devp);
1420                 ddi_prop_remove_all(devi);
1421                 ddi_remove_minor_node(devi, NULL);
1422                 ST_DEBUG(0, st_label, SCSI_DEBUG, "st_detach done\n");
1423                 return (DDI_SUCCESS);
1424 
1425         case DDI_SUSPEND:
1426 
1427                 /*
1428                  * Suspend/Resume
1429                  *
1430                  * To process DDI_SUSPEND, we must do the following:
1431                  *
1432                  *  - check ddi_removing_power to see if power will be turned
1433                  *    off. if so, return DDI_FAILURE
1434                  *  - check if we are already suspended,
1435                  *    if so, return DDI_FAILURE
1436                  *  - check if device state is CLOSED,
1437                  *    if not, return DDI_FAILURE.
1438                  *  - wait until outstanding operations complete
1439                  *  - save tape state
1440                  *  - block new operations
1441                  *  - cancel pending timeouts
1442                  *
1443                  */
1444 
1445                 if (ddi_removing_power(devi)) {
1446                         return (DDI_FAILURE);
1447                 }
1448 
1449                 if (un->un_dev == 0)
1450                         un->un_dev = MTMINOR(instance);
1451 
1452                 mutex_enter(ST_MUTEX);
1453 
1454                 /*
1455                  * Shouldn't already be suspended, if so return failure
1456                  */
1457                 if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
1458                         mutex_exit(ST_MUTEX);
1459                         return (DDI_FAILURE);
1460                 }
1461                 if (un->un_state != ST_STATE_CLOSED) {
1462                         mutex_exit(ST_MUTEX);
1463                         return (DDI_FAILURE);
1464                 }
1465 
1466                 /*
1467                  * Wait for all outstanding I/O's to complete
1468                  *
1469                  * we wait on both ncmds and the wait queue for times
1470                  * when we are flushing after persistent errors are
1471                  * flagged, which is when ncmds can be 0, and the
1472                  * queue can still have I/O's.  This way we preserve
1473                  * order of biodone's.
1474                  */
1475                 wait_cmds_complete = ddi_get_lbolt();
1476                 wait_cmds_complete +=
1477                     drv_sectohz(st_wait_cmds_complete);
1478                 while (un->un_ncmds || un->un_quef ||
1479                     (un->un_state == ST_STATE_RESOURCE_WAIT)) {
1480 
1481                         if (cv_timedwait(&un->un_tape_busy_cv, ST_MUTEX,
1482                             wait_cmds_complete) == -1) {
1483                                 /*
1484                                  * Time expired then cancel the command
1485                                  */
1486                                 if (st_reset(un, RESET_LUN) == 0) {
1487                                         if (un->un_last_throttle) {
1488                                                 un->un_throttle =
1489                                                     un->un_last_throttle;
1490                                         }
1491                                         mutex_exit(ST_MUTEX);
1492                                         return (DDI_FAILURE);
1493                                 } else {
1494                                         break;
1495                                 }
1496                         }
1497                 }
1498 
1499                 /*
1500                  * DDI_SUSPEND says that the system "may" power down, we
1501                  * remember the file and block number before rewinding.
1502                  * we also need to save state before issuing
1503                  * any WRITE_FILE_MARK command.
1504                  */
1505                 (void) st_update_block_pos(un, st_cmd, 0);
1506                 COPY_POS(&un->un_suspend_pos, &un->un_pos);
1507 
1508 
1509                 /*
1510                  * Issue a zero write file fmk command to tell the drive to
1511                  * flush any buffered tape marks
1512                  */
1513                 (void) st_cmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD);
1514 
1515                 /*
1516                  * Because not all tape drives correctly implement buffer
1517                  * flushing with the zero write file fmk command, issue a
1518                  * synchronous rewind command to force data flushing.
1519                  * st_validate_tapemarks() will do a rewind during DDI_RESUME
1520                  * anyway.
1521                  */
1522                 (void) st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
1523 
1524                 /* stop any new operations */
1525                 un->un_pwr_mgmt = ST_PWR_SUSPENDED;
1526                 un->un_throttle = 0;
1527 
1528                 /*
1529                  * cancel any outstanding timeouts
1530                  */
1531                 if (un->un_delay_tid) {
1532                         timeout_id_t temp_id = un->un_delay_tid;
1533                         un->un_delay_tid = 0;
1534                         un->un_tids_at_suspend |= ST_DELAY_TID;
1535                         mutex_exit(ST_MUTEX);
1536                         (void) untimeout(temp_id);
1537                         mutex_enter(ST_MUTEX);
1538                 }
1539 
1540                 if (un->un_hib_tid) {
1541                         timeout_id_t temp_id = un->un_hib_tid;
1542                         un->un_hib_tid = 0;
1543                         un->un_tids_at_suspend |= ST_HIB_TID;
1544                         mutex_exit(ST_MUTEX);
1545                         (void) untimeout(temp_id);
1546                         mutex_enter(ST_MUTEX);
1547                 }
1548 
1549                 /*
1550                  * Suspend the scsi_watch_thread
1551                  */
1552                 if (un->un_swr_token) {
1553                         opaque_t temp_token = un->un_swr_token;
1554                         mutex_exit(ST_MUTEX);
1555                         scsi_watch_suspend(temp_token);
1556                 } else {
1557                         mutex_exit(ST_MUTEX);
1558                 }
1559 
1560                 return (DDI_SUCCESS);
1561 
1562         default:
1563                 ST_DEBUG(0, st_label, SCSI_DEBUG, "st_detach failed\n");
1564                 return (DDI_FAILURE);
1565         }
1566 }
1567 
1568 
1569 /* ARGSUSED */
1570 static int
1571 st_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
1572 {
1573         dev_t dev;
1574         struct scsi_tape *un;
1575         int instance, error;
1576 
1577         ST_ENTR(dip, st_info);
1578 
1579         switch (infocmd) {
1580         case DDI_INFO_DEVT2DEVINFO:
1581                 dev = (dev_t)arg;
1582                 instance = MTUNIT(dev);
1583                 if ((un = ddi_get_soft_state(st_state, instance)) == NULL)
1584                         return (DDI_FAILURE);
1585                 *result = (void *) ST_DEVINFO;
1586                 error = DDI_SUCCESS;
1587                 break;
1588         case DDI_INFO_DEVT2INSTANCE:
1589                 dev = (dev_t)arg;
1590                 instance = MTUNIT(dev);
1591                 *result = (void *)(uintptr_t)instance;
1592                 error = DDI_SUCCESS;
1593                 break;
1594         default:
1595                 error = DDI_FAILURE;
1596         }
1597         return (error);
1598 }
1599 
1600 static int
1601 st_doattach(struct scsi_device *devp, int (*canwait)())
1602 {
1603         struct scsi_tape *un = NULL;
1604         recov_info *ri;
1605         int km_flags = (canwait != NULL_FUNC) ? KM_SLEEP : KM_NOSLEEP;
1606         int instance;
1607         size_t rlen;
1608 
1609         ST_FUNC(devp->sd_dev, st_doattach);
1610         /*
1611          * Call the routine scsi_probe to do some of the dirty work.
1612          * If the INQUIRY command succeeds, the field sd_inq in the
1613          * device structure will be filled in.
1614          */
1615         ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1616             "st_doattach(): probing\n");
1617 
1618         if (scsi_probe(devp, canwait) == SCSIPROBE_EXISTS) {
1619 
1620                 /*
1621                  * In checking the whole inq_dtype byte we are looking at both
1622                  * the Peripheral Qualifier and the Peripheral Device Type.
1623                  * For this driver we are only interested in sequential devices
1624                  * that are connected or capable if connecting to this logical
1625                  * unit.
1626                  */
1627                 if (devp->sd_inq->inq_dtype ==
1628                     (DTYPE_SEQUENTIAL | DPQ_POSSIBLE)) {
1629                         ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1630                             "probe exists\n");
1631                 } else {
1632                         /* Something there but not a tape device */
1633                         scsi_unprobe(devp);
1634                         return (DDI_FAILURE);
1635                 }
1636         } else {
1637                 /* Nothing there */
1638                 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1639                     "probe failure: nothing there\n");
1640                 scsi_unprobe(devp);
1641                 return (DDI_FAILURE);
1642         }
1643 
1644 
1645         /*
1646          * The actual unit is present.
1647          * Now is the time to fill in the rest of our info..
1648          */
1649         instance = ddi_get_instance(devp->sd_dev);
1650 
1651         if (ddi_soft_state_zalloc(st_state, instance) != DDI_SUCCESS) {
1652                 goto error;
1653         }
1654         un = ddi_get_soft_state(st_state, instance);
1655 
1656         ASSERT(un != NULL);
1657 
1658         un->un_rqs_bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL,
1659             MAX_SENSE_LENGTH, B_READ, canwait, NULL);
1660         if (un->un_rqs_bp == NULL) {
1661                 goto error;
1662         }
1663         un->un_rqs = scsi_init_pkt(&devp->sd_address, NULL, un->un_rqs_bp,
1664             CDB_GROUP0, 1, st_recov_sz, PKT_CONSISTENT, canwait, NULL);
1665         if (!un->un_rqs) {
1666                 goto error;
1667         }
1668         ASSERT(un->un_rqs->pkt_resid == 0);
1669         devp->sd_sense =
1670             (struct scsi_extended_sense *)un->un_rqs_bp->b_un.b_addr;
1671         ASSERT(geterror(un->un_rqs_bp) == NULL);
1672 
1673         (void) scsi_setup_cdb((union scsi_cdb *)un->un_rqs->pkt_cdbp,
1674             SCMD_REQUEST_SENSE, 0, MAX_SENSE_LENGTH, 0);
1675         FILL_SCSI1_LUN(devp, un->un_rqs);
1676         un->un_rqs->pkt_flags |= (FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON);
1677         un->un_rqs->pkt_time = st_io_time;
1678         un->un_rqs->pkt_comp = st_intr;
1679         ri = (recov_info *)un->un_rqs->pkt_private;
1680         if (st_recov_sz == sizeof (recov_info)) {
1681                 ri->privatelen = sizeof (recov_info);
1682         } else {
1683                 ri->privatelen = sizeof (pkt_info);
1684         }
1685 
1686         un->un_sbufp = getrbuf(km_flags);
1687         un->un_recov_buf = getrbuf(km_flags);
1688 
1689         un->un_uscsi_rqs_buf = kmem_alloc(SENSE_LENGTH, KM_SLEEP);
1690 
1691         /*
1692          * use i_ddi_mem_alloc() for now until we have an interface to allocate
1693          * memory for DMA which doesn't require a DMA handle.
1694          */
1695         (void) i_ddi_mem_alloc(devp->sd_dev, &st_alloc_attr,
1696             sizeof (struct seq_mode), ((km_flags == KM_SLEEP) ? 1 : 0), 0,
1697             NULL, (caddr_t *)&un->un_mspl, &rlen, NULL);
1698 
1699         (void) i_ddi_mem_alloc(devp->sd_dev, &st_alloc_attr,
1700             sizeof (read_pos_data_t), ((km_flags == KM_SLEEP) ? 1 : 0), 0,
1701             NULL, (caddr_t *)&un->un_read_pos_data, &rlen, NULL);
1702 
1703         if (!un->un_sbufp || !un->un_mspl || !un->un_read_pos_data) {
1704                 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG,
1705                     "probe partial failure: no space\n");
1706                 goto error;
1707         }
1708 
1709         bzero(un->un_mspl, sizeof (struct seq_mode));
1710 
1711         cv_init(&un->un_sbuf_cv, NULL, CV_DRIVER, NULL);
1712         cv_init(&un->un_queue_cv, NULL, CV_DRIVER, NULL);
1713         cv_init(&un->un_clscv, NULL, CV_DRIVER, NULL);
1714         cv_init(&un->un_state_cv, NULL, CV_DRIVER, NULL);
1715 #ifdef  __x86
1716         cv_init(&un->un_contig_mem_cv, NULL, CV_DRIVER, NULL);
1717 #endif
1718 
1719         /* Initialize power managemnet condition variable */
1720         cv_init(&un->un_suspend_cv, NULL, CV_DRIVER, NULL);
1721         cv_init(&un->un_tape_busy_cv, NULL, CV_DRIVER, NULL);
1722         cv_init(&un->un_recov_buf_cv, NULL, CV_DRIVER, NULL);
1723 
1724         un->un_recov_taskq = ddi_taskq_create(devp->sd_dev,
1725             "un_recov_taskq", 1, TASKQ_DEFAULTPRI, km_flags);
1726 
1727         ASSERT(un->un_recov_taskq != NULL);
1728 
1729         un->un_pos.pmode = invalid;
1730         un->un_sd    = devp;
1731         un->un_swr_token = (opaque_t)NULL;
1732         un->un_comp_page = ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE;
1733         un->un_wormable = st_is_drive_worm;
1734         un->un_media_id_method = st_get_media_identification;
1735         /*
1736          * setting long a initial as it contains logical file info.
1737          * support for long format is mandatory but many drive don't do it.
1738          */
1739         un->un_read_pos_type = LONG_POS;
1740 
1741         un->un_suspend_pos.pmode = invalid;
1742 
1743         st_add_recovery_info_to_pkt(un, un->un_rqs_bp, un->un_rqs);
1744 
1745 #ifdef  __x86
1746         if (ddi_dma_alloc_handle(ST_DEVINFO, &st_contig_mem_dma_attr,
1747             DDI_DMA_SLEEP, NULL, &un->un_contig_mem_hdl) != DDI_SUCCESS) {
1748                 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG,
1749                     "allocation of contiguous memory dma handle failed!");
1750                 un->un_contig_mem_hdl = NULL;
1751                 goto error;
1752         }
1753 #endif
1754 
1755         /*
1756          * Since this driver manages devices with "remote" hardware,
1757          * i.e. the devices themselves have no "reg" properties,
1758          * the SUSPEND/RESUME commands in detach/attach will not be
1759          * called by the power management framework unless we request
1760          * it by creating a "pm-hardware-state" property and setting it
1761          * to value "needs-suspend-resume".
1762          */
1763         if (ddi_prop_update_string(DDI_DEV_T_NONE, devp->sd_dev,
1764             "pm-hardware-state", "needs-suspend-resume") !=
1765             DDI_PROP_SUCCESS) {
1766 
1767                 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1768                     "ddi_prop_update(\"pm-hardware-state\") failed\n");
1769                 goto error;
1770         }
1771 
1772         if (ddi_prop_create(DDI_DEV_T_NONE, devp->sd_dev, DDI_PROP_CANSLEEP,
1773             "no-involuntary-power-cycles", NULL, 0) != DDI_PROP_SUCCESS) {
1774 
1775                 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1776                     "ddi_prop_create(\"no-involuntary-power-cycles\") "
1777                     "failed\n");
1778                 goto error;
1779         }
1780 
1781         (void) scsi_reset_notify(ROUTE, SCSI_RESET_NOTIFY,
1782             st_reset_notification, (caddr_t)un);
1783 
1784         ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG, "attach success\n");
1785         return (DDI_SUCCESS);
1786 
1787 error:
1788         devp->sd_sense = NULL;
1789 
1790         ddi_remove_minor_node(devp->sd_dev, NULL);
1791         if (un) {
1792                 if (un->un_mspl) {
1793                         i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1794                 }
1795                 if (un->un_read_pos_data) {
1796                         i_ddi_mem_free((caddr_t)un->un_read_pos_data, 0);
1797                 }
1798                 if (un->un_sbufp) {
1799                         freerbuf(un->un_sbufp);
1800                 }
1801                 if (un->un_recov_buf) {
1802                         freerbuf(un->un_recov_buf);
1803                 }
1804                 if (un->un_uscsi_rqs_buf) {
1805                         kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1806                 }
1807 #ifdef  __x86
1808                 if (un->un_contig_mem_hdl != NULL) {
1809                         ddi_dma_free_handle(&un->un_contig_mem_hdl);
1810                 }
1811 #endif
1812                 if (un->un_rqs) {
1813                         scsi_destroy_pkt(un->un_rqs);
1814                 }
1815 
1816                 if (un->un_rqs_bp) {
1817                         scsi_free_consistent_buf(un->un_rqs_bp);
1818                 }
1819 
1820                 ddi_soft_state_free(st_state, instance);
1821                 devp->sd_private = NULL;
1822         }
1823 
1824         if (devp->sd_inq) {
1825                 scsi_unprobe(devp);
1826         }
1827         return (DDI_FAILURE);
1828 }
1829 
1830 typedef int
1831 (*cfg_functp)(struct scsi_tape *, char *vidpid, struct st_drivetype *);
1832 
1833 static cfg_functp config_functs[] = {
1834         st_get_conf_from_st_dot_conf,
1835         st_get_conf_from_st_conf_dot_c,
1836         st_get_conf_from_tape_drive,
1837         st_get_default_conf
1838 };
1839 
1840 
1841 /*
1842  * determine tape type, using tape-config-list or built-in table or
1843  * use a generic tape config entry
1844  */
1845 static void
1846 st_known_tape_type(struct scsi_tape *un)
1847 {
1848         struct st_drivetype *dp;
1849         cfg_functp *config_funct;
1850         uchar_t reserved;
1851 
1852         ST_FUNC(ST_DEVINFO, st_known_tape_type);
1853 
1854         reserved = (un->un_rsvd_status & ST_RESERVE) ? ST_RESERVE
1855             : ST_RELEASE;
1856 
1857         /*
1858          * XXX:  Emulex MT-02 (and emulators) predates SCSI-1 and has
1859          *       no vid & pid inquiry data.  So, we provide one.
1860          */
1861         if (ST_INQUIRY->inq_len == 0 ||
1862             (bcmp("\0\0\0\0\0\0\0\0", ST_INQUIRY->inq_vid, 8) == 0)) {
1863                 (void) strcpy((char *)ST_INQUIRY->inq_vid, ST_MT02_NAME);
1864         }
1865 
1866         if (un->un_dp_size == 0) {
1867                 un->un_dp_size = sizeof (struct st_drivetype);
1868                 dp = kmem_zalloc((size_t)un->un_dp_size, KM_SLEEP);
1869                 un->un_dp = dp;
1870         } else {
1871                 dp = un->un_dp;
1872         }
1873 
1874         un->un_dp->non_motion_timeout = st_io_time;
1875         /*
1876          * Loop through the configuration methods till one works.
1877          */
1878         for (config_funct = &config_functs[0]; ; config_funct++) {
1879                 if ((*config_funct)(un, ST_INQUIRY->inq_vid, dp)) {
1880                         break;
1881                 }
1882         }
1883 
1884         /*
1885          * If we didn't just make up this configuration and
1886          * all the density codes are the same..
1887          * Set Auto Density over ride.
1888          */
1889         if (*config_funct != st_get_default_conf) {
1890                 /*
1891                  * If this device is one that is configured and all
1892                  * densities are the same, This saves doing gets and set
1893                  * that yield nothing.
1894                  */
1895                 if ((dp->densities[0]) == (dp->densities[1]) &&
1896                     (dp->densities[0]) == (dp->densities[2]) &&
1897                     (dp->densities[0]) == (dp->densities[3])) {
1898 
1899                         dp->options |= ST_AUTODEN_OVERRIDE;
1900                 }
1901         }
1902 
1903 
1904         /*
1905          * Store tape drive characteristics.
1906          */
1907         un->un_status = 0;
1908         un->un_attached = 1;
1909         un->un_init_options = dp->options;
1910 
1911         /* setup operation time-outs based on options */
1912         st_calculate_timeouts(un);
1913 
1914         /* TLR support */
1915         if (un->un_dp->type != ST_TYPE_INVALID) {
1916                 int result;
1917 
1918                 /* try and enable TLR */
1919                 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
1920                 result = st_set_target_TLR_mode(un, st_uscsi_cmd);
1921                 if (result == EACCES) {
1922                         /*
1923                          * From attach command failed.
1924                          * Set dp type so is run again on open.
1925                          */
1926                         un->un_dp->type = ST_TYPE_INVALID;
1927                         un->un_tlr_flag = TLR_NOT_KNOWN;
1928                 } else if (result == 0) {
1929                         if (scsi_ifgetcap(&un->un_sd->sd_address,
1930                             "tran-layer-retries", 1) == -1) {
1931                                 un->un_tlr_flag = TLR_NOT_SUPPORTED;
1932                                 (void) st_set_target_TLR_mode(un, st_uscsi_cmd);
1933                         } else {
1934                                 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
1935                         }
1936                 } else {
1937                         un->un_tlr_flag = TLR_NOT_SUPPORTED;
1938                 }
1939         }
1940 
1941         /* make sure if we are supposed to be variable, make it variable */
1942         if (dp->options & ST_VARIABLE) {
1943                 dp->bsize = 0;
1944         }
1945 
1946         if (reserved != ((un->un_rsvd_status & ST_RESERVE) ? ST_RESERVE
1947             : ST_RELEASE)) {
1948                 (void) st_reserve_release(un, reserved, st_uscsi_cmd);
1949         }
1950 
1951         un->un_unit_attention_flags |= 1;
1952 
1953         scsi_log(ST_DEVINFO, st_label, CE_NOTE, "?<%s>\n", dp->name);
1954 
1955 }
1956 
1957 
1958 typedef struct {
1959         int mask;
1960         int bottom;
1961         int top;
1962         char *name;
1963 } conf_limit;
1964 
1965 static const conf_limit conf_limits[] = {
1966 
1967         -1,             1,              2,              "conf version",
1968         -1,             MT_ISTS,        ST_LAST_TYPE,   "drive type",
1969         -1,             0,              0xffffff,       "block size",
1970         ST_VALID_OPTS,  0,              ST_VALID_OPTS,  "options",
1971         -1,             0,              4,              "number of densities",
1972         -1,             0,              UINT8_MAX,      "density code",
1973         -1,             0,              3,              "default density",
1974         -1,             0,              UINT16_MAX,     "non motion timeout",
1975         -1,             0,              UINT16_MAX,     "I/O timeout",
1976         -1,             0,              UINT16_MAX,     "space timeout",
1977         -1,             0,              UINT16_MAX,     "load timeout",
1978         -1,             0,              UINT16_MAX,     "unload timeout",
1979         -1,             0,              UINT16_MAX,     "erase timeout",
1980         0,              0,              0,              NULL
1981 };
1982 
1983 static int
1984 st_validate_conf_data(struct scsi_tape *un, int *list, int list_len,
1985     const char *conf_name)
1986 {
1987         int dens;
1988         int ndens;
1989         int value;
1990         int type;
1991         int count;
1992         const conf_limit *limit = &conf_limits[0];
1993 
1994         ST_FUNC(ST_DEVINFO, st_validate_conf_data);
1995 
1996         ST_DEBUG3(ST_DEVINFO, st_label, CE_NOTE,
1997             "Checking %d entrys total with %d densities\n", list_len, list[4]);
1998 
1999         count = list_len;
2000         type = *list;
2001         for (;  count && limit->name; count--, list++, limit++) {
2002 
2003                 value = *list;
2004                 if (value & ~limit->mask) {
2005                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2006                             "%s %s value invalid bits set: 0x%X\n",
2007                             conf_name, limit->name, value & ~limit->mask);
2008                         *list &= limit->mask;
2009                 } else if (value < limit->bottom) {
2010                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2011                             "%s %s value too low: value = %d limit %d\n",
2012                             conf_name, limit->name, value, limit->bottom);
2013                 } else if (value > limit->top) {
2014                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2015                             "%s %s value too high: value = %d limit %d\n",
2016                             conf_name, limit->name, value, limit->top);
2017                 } else {
2018                         ST_DEBUG3(ST_DEVINFO, st_label, CE_CONT,
2019                             "%s %s value = 0x%X\n",
2020                             conf_name, limit->name, value);
2021                 }
2022 
2023                 /* If not the number of densities continue */
2024                 if (limit != &conf_limits[4]) {
2025                         continue;
2026                 }
2027 
2028                 /* If number of densities is not in range can't use config */
2029                 if (value < limit->bottom || value > limit->top) {
2030                         return (-1);
2031                 }
2032 
2033                 ndens = min(value, NDENSITIES);
2034                 if ((type == 1) && (list_len - ndens) != 6) {
2035                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2036                             "%s conf version 1 with %d densities has %d items"
2037                             " should have %d",
2038                             conf_name, ndens, list_len, 6 + ndens);
2039                 } else if ((type == 2) && (list_len - ndens) != 13) {
2040                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2041                             "%s conf version 2 with %d densities has %d items"
2042                             " should have %d",
2043                             conf_name, ndens, list_len, 13 + ndens);
2044                 }
2045 
2046                 limit++;
2047                 for (dens = 0; dens < ndens && count; dens++) {
2048                         count--;
2049                         list++;
2050                         value = *list;
2051                         if (value < limit->bottom) {
2052                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2053                                     "%s density[%d] value too low: value ="
2054                                     " 0x%X limit 0x%X\n",
2055                                     conf_name, dens, value, limit->bottom);
2056                         } else if (value > limit->top) {
2057                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2058                                     "%s density[%d] value too high: value ="
2059                                     " 0x%X limit 0x%X\n",
2060                                     conf_name, dens, value, limit->top);
2061                         } else {
2062                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_CONT,
2063                                     "%s density[%d] value = 0x%X\n",
2064                                     conf_name, dens, value);
2065                         }
2066                 }
2067         }
2068 
2069         return (0);
2070 }
2071 
2072 static int
2073 st_get_conf_from_st_dot_conf(struct scsi_tape *un, char *vidpid,
2074     struct st_drivetype *dp)
2075 {
2076         caddr_t config_list = NULL;
2077         caddr_t data_list = NULL;
2078         int     *data_ptr;
2079         caddr_t vidptr, prettyptr, datanameptr;
2080         size_t  vidlen, prettylen, datanamelen, tripletlen = 0;
2081         int config_list_len, data_list_len, len, i;
2082         int version;
2083         int found = 0;
2084 
2085         ST_FUNC(ST_DEVINFO, st_get_conf_from_st_dot_conf);
2086 
2087         /*
2088          * Determine type of tape controller. Type is determined by
2089          * checking the vendor ids of the earlier inquiry command and
2090          * comparing those with vids in tape-config-list defined in st.conf
2091          */
2092         if (ddi_getlongprop(DDI_DEV_T_ANY, ST_DEVINFO, DDI_PROP_DONTPASS,
2093             "tape-config-list", (caddr_t)&config_list, &config_list_len)
2094             != DDI_PROP_SUCCESS) {
2095                 return (found);
2096         }
2097 
2098         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
2099             "st_get_conf_from_st_dot_conf(): st.conf has tape-config-list\n");
2100 
2101         /*
2102          * Compare vids in each triplet - if it matches, get value for
2103          * data_name and contruct a st_drivetype struct
2104          * tripletlen is not set yet!
2105          */
2106         for (len = config_list_len, vidptr = config_list;
2107             len > 0;
2108             vidptr += tripletlen, len -= tripletlen) {
2109 
2110                 vidlen = strlen(vidptr);
2111                 prettyptr = vidptr + vidlen + 1;
2112                 prettylen = strlen(prettyptr);
2113                 datanameptr = prettyptr + prettylen + 1;
2114                 datanamelen = strlen(datanameptr);
2115                 tripletlen = vidlen + prettylen + datanamelen + 3;
2116 
2117                 if (vidlen == 0) {
2118                         continue;
2119                 }
2120 
2121                 /*
2122                  * If inquiry vid dosen't match this triplets vid,
2123                  * try the next.
2124                  */
2125                 if (strncasecmp(vidpid, vidptr, vidlen)) {
2126                         continue;
2127                 }
2128 
2129                 /*
2130                  * if prettylen is zero then use the vid string
2131                  */
2132                 if (prettylen == 0) {
2133                         prettyptr = vidptr;
2134                         prettylen = vidlen;
2135                 }
2136 
2137                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2138                     "vid = %s, pretty=%s, dataname = %s\n",
2139                     vidptr, prettyptr, datanameptr);
2140 
2141                 /*
2142                  * get the data list
2143                  */
2144                 if (ddi_getlongprop(DDI_DEV_T_ANY, ST_DEVINFO, 0,
2145                     datanameptr, (caddr_t)&data_list,
2146                     &data_list_len) != DDI_PROP_SUCCESS) {
2147                         /*
2148                          * Error in getting property value
2149                          * print warning!
2150                          */
2151                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2152                             "data property (%s) has no value\n",
2153                             datanameptr);
2154                         continue;
2155                 }
2156 
2157                 /*
2158                  * now initialize the st_drivetype struct
2159                  */
2160                 (void) strncpy(dp->name, prettyptr, ST_NAMESIZE - 1);
2161                 dp->length = (int)min(vidlen, (VIDPIDLEN - 1));
2162                 (void) strncpy(dp->vid, vidptr, dp->length);
2163                 data_ptr = (int *)data_list;
2164                 /*
2165                  * check if data is enough for version, type,
2166                  * bsize, options, # of densities, density1,
2167                  * density2, ..., default_density
2168                  */
2169                 if ((data_list_len < 5 * sizeof (int)) ||
2170                     (data_list_len < 6 * sizeof (int) +
2171                     *(data_ptr + 4) * sizeof (int))) {
2172                         /*
2173                          * print warning and skip to next triplet.
2174                          */
2175                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2176                             "data property (%s) incomplete\n",
2177                             datanameptr);
2178                         kmem_free(data_list, data_list_len);
2179                         continue;
2180                 }
2181 
2182                 if (st_validate_conf_data(un, data_ptr,
2183                     data_list_len / sizeof (int), datanameptr)) {
2184                         kmem_free(data_list, data_list_len);
2185                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2186                             "data property (%s) rejected\n",
2187                             datanameptr);
2188                         continue;
2189                 }
2190 
2191                 /*
2192                  * check version
2193                  */
2194                 version = *data_ptr++;
2195                 if (version != 1 && version != 2) {
2196                         /* print warning but accept it */
2197                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2198                             "Version # for data property (%s) "
2199                             "not set to 1 or 2\n", datanameptr);
2200                 }
2201 
2202                 dp->type    = *data_ptr++;
2203                 dp->bsize   = *data_ptr++;
2204                 dp->options = *data_ptr++;
2205                 dp->options |= ST_DYNAMIC;
2206                 len = *data_ptr++;
2207                 for (i = 0; i < NDENSITIES; i++) {
2208                         if (i < len) {
2209                                 dp->densities[i] = *data_ptr++;
2210                         }
2211                 }
2212                 dp->default_density = *data_ptr << 3;
2213                 if (version == 2 &&
2214                     data_list_len >= (13 + len) * sizeof (int)) {
2215                         data_ptr++;
2216                         dp->non_motion_timeout       = *data_ptr++;
2217                         dp->io_timeout               = *data_ptr++;
2218                         dp->rewind_timeout   = *data_ptr++;
2219                         dp->space_timeout    = *data_ptr++;
2220                         dp->load_timeout     = *data_ptr++;
2221                         dp->unload_timeout   = *data_ptr++;
2222                         dp->erase_timeout    = *data_ptr++;
2223                 }
2224                 kmem_free(data_list, data_list_len);
2225                 found = 1;
2226                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2227                     "found in st.conf: vid = %s, pretty=%s\n",
2228                     dp->vid, dp->name);
2229                 break;
2230         }
2231 
2232         /*
2233          * free up the memory allocated by ddi_getlongprop
2234          */
2235         if (config_list) {
2236                 kmem_free(config_list, config_list_len);
2237         }
2238         return (found);
2239 }
2240 
2241 static int
2242 st_get_conf_from_st_conf_dot_c(struct scsi_tape *un, char *vidpid,
2243     struct st_drivetype *dp)
2244 {
2245         int i;
2246 
2247         ST_FUNC(ST_DEVINFO, st_get_conf_from_st_conf_dot_c);
2248         /*
2249          * Determine type of tape controller.  Type is determined by
2250          * checking the result of the earlier inquiry command and
2251          * comparing vendor ids with strings in a table declared in st_conf.c.
2252          */
2253         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2254             "st_get_conf_from_st_conf_dot_c(): looking at st_drivetypes\n");
2255 
2256         for (i = 0; i < st_ndrivetypes; i++) {
2257                 if (st_drivetypes[i].length == 0) {
2258                         continue;
2259                 }
2260                 if (strncasecmp(vidpid, st_drivetypes[i].vid,
2261                     st_drivetypes[i].length)) {
2262                         continue;
2263                 }
2264                 bcopy(&st_drivetypes[i], dp, sizeof (st_drivetypes[i]));
2265                 return (1);
2266         }
2267         return (0);
2268 }
2269 
2270 static int
2271 st_get_conf_from_tape_drive(struct scsi_tape *un, char *vidpid,
2272     struct st_drivetype *dp)
2273 {
2274         int bsize;
2275         ulong_t maxbsize;
2276         caddr_t buf;
2277         struct st_drivetype *tem_dp;
2278         struct read_blklim *blklim;
2279         int rval;
2280         int i;
2281 
2282         ST_FUNC(ST_DEVINFO, st_get_conf_from_tape_drive);
2283 
2284         /*
2285          * Determine the type of tape controller. Type is determined by
2286          * sending SCSI commands to tape drive and deriving the type from
2287          * the returned data.
2288          */
2289         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2290             "st_get_conf_from_tape_drive(): asking tape drive\n");
2291 
2292         tem_dp = kmem_zalloc(sizeof (struct st_drivetype), KM_SLEEP);
2293 
2294         /*
2295          * Make up a name
2296          */
2297         bcopy(vidpid, tem_dp->name, VIDPIDLEN);
2298         tem_dp->name[VIDPIDLEN] = '\0';
2299         tem_dp->length = min(strlen(ST_INQUIRY->inq_vid), (VIDPIDLEN - 1));
2300         (void) strncpy(tem_dp->vid, ST_INQUIRY->inq_vid, tem_dp->length);
2301         /*
2302          * 'clean' vendor and product strings of non-printing chars
2303          */
2304         for (i = 0; i < VIDPIDLEN - 1; i ++) {
2305                 if (tem_dp->name[i] < ' ' || tem_dp->name[i] > '~') {
2306                         tem_dp->name[i] = '.';
2307                 }
2308         }
2309 
2310         /*
2311          * MODE SENSE to determine block size.
2312          */
2313         un->un_dp->options |= ST_MODE_SEL_COMP | ST_UNLOADABLE;
2314         rval = st_modesense(un);
2315         if (rval) {
2316                 if (rval == EACCES) {
2317                         un->un_dp->type = ST_TYPE_INVALID;
2318                         rval = 1;
2319                 } else {
2320                         un->un_dp->options &= ~ST_MODE_SEL_COMP;
2321                         rval = 0;
2322                 }
2323                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2324                     "st_get_conf_from_tape_drive(): fail to mode sense\n");
2325                 goto exit;
2326         }
2327 
2328         /* Can mode sense page 0x10 or 0xf */
2329         tem_dp->options |= ST_MODE_SEL_COMP;
2330         bsize = (un->un_mspl->high_bl << 16)        |
2331             (un->un_mspl->mid_bl << 8)              |
2332             (un->un_mspl->low_bl);
2333 
2334         if (bsize == 0) {
2335                 tem_dp->options |= ST_VARIABLE;
2336                 tem_dp->bsize = 0;
2337         } else if (bsize > ST_MAXRECSIZE_FIXED) {
2338                 rval = st_change_block_size(un, 0);
2339                 if (rval) {
2340                         if (rval == EACCES) {
2341                                 un->un_dp->type = ST_TYPE_INVALID;
2342                                 rval = 1;
2343                         } else {
2344                                 rval = 0;
2345                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2346                                     "st_get_conf_from_tape_drive(): "
2347                                     "Fixed record size is too large and"
2348                                     "cannot switch to variable record size");
2349                         }
2350                         goto exit;
2351                 }
2352                 tem_dp->options |= ST_VARIABLE;
2353         } else {
2354                 rval = st_change_block_size(un, 0);
2355                 if (rval == 0) {
2356                         tem_dp->options |= ST_VARIABLE;
2357                         tem_dp->bsize = 0;
2358                 } else if (rval != EACCES) {
2359                         tem_dp->bsize = bsize;
2360                 } else {
2361                         un->un_dp->type = ST_TYPE_INVALID;
2362                         rval = 1;
2363                         goto exit;
2364                 }
2365         }
2366 
2367         /*
2368          * If READ BLOCk LIMITS works and upper block size limit is
2369          * more than 64K, ST_NO_RECSIZE_LIMIT is supported.
2370          */
2371         blklim = kmem_zalloc(sizeof (struct read_blklim), KM_SLEEP);
2372         rval = st_read_block_limits(un, blklim);
2373         if (rval) {
2374                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2375                     "st_get_conf_from_tape_drive(): "
2376                     "fail to read block limits.\n");
2377                 rval = 0;
2378                 kmem_free(blklim, sizeof (struct read_blklim));
2379                 goto exit;
2380         }
2381         maxbsize = (blklim->max_hi << 16) +
2382             (blklim->max_mid << 8) + blklim->max_lo;
2383         if (maxbsize > ST_MAXRECSIZE_VARIABLE) {
2384                 tem_dp->options |= ST_NO_RECSIZE_LIMIT;
2385         }
2386         kmem_free(blklim, sizeof (struct read_blklim));
2387 
2388         /*
2389          * Inquiry VPD page 0xb0 to see if the tape drive supports WORM
2390          */
2391         buf = kmem_zalloc(6, KM_SLEEP);
2392         rval = st_get_special_inquiry(un, 6, buf, 0xb0);
2393         if (rval) {
2394                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2395                     "st_get_conf_from_tape_drive(): "
2396                     "fail to read vitial inquiry.\n");
2397                 rval = 0;
2398                 kmem_free(buf, 6);
2399                 goto exit;
2400         }
2401         if (buf[4] & 1) {
2402                 tem_dp->options |= ST_WORMABLE;
2403         }
2404         kmem_free(buf, 6);
2405 
2406         /* Assume BSD BSR KNOWS_EOD */
2407         tem_dp->options |= ST_BSF | ST_BSR | ST_KNOWS_EOD | ST_UNLOADABLE;
2408         tem_dp->max_rretries = -1;
2409         tem_dp->max_wretries = -1;
2410 
2411         /*
2412          * Decide the densities supported by tape drive by sending
2413          * REPORT DENSITY SUPPORT command.
2414          */
2415         if (st_get_densities_from_tape_drive(un, tem_dp) == 0) {
2416                 goto exit;
2417         }
2418 
2419         /*
2420          * Decide the timeout values for several commands by sending
2421          * REPORT SUPPORTED OPERATION CODES command.
2422          */
2423         rval = st_get_timeout_values_from_tape_drive(un, tem_dp);
2424         if (rval == 0 || ((rval == 1) && (tem_dp->type == ST_TYPE_INVALID))) {
2425                 goto exit;
2426         }
2427 
2428         bcopy(tem_dp, dp, sizeof (struct st_drivetype));
2429         rval = 1;
2430 
2431 exit:
2432         un->un_status = KEY_NO_SENSE;
2433         kmem_free(tem_dp, sizeof (struct st_drivetype));
2434         return (rval);
2435 }
2436 
2437 static int
2438 st_get_densities_from_tape_drive(struct scsi_tape *un,
2439     struct st_drivetype *dp)
2440 {
2441         int i, p;
2442         size_t buflen;
2443         ushort_t des_len;
2444         uchar_t *den_header;
2445         uchar_t num_den;
2446         uchar_t den[NDENSITIES];
2447         uchar_t deflt[NDENSITIES];
2448         struct report_density_desc *den_desc;
2449 
2450         ST_FUNC(ST_DEVINFO, st_get_densities_from_type_drive);
2451 
2452         /*
2453          * Since we have no idea how many densitiy support entries
2454          * will be returned, we send the command firstly assuming
2455          * there is only one. Then we can decide the number of
2456          * entries by available density support length. If multiple
2457          * entries exist, we will resend the command with enough
2458          * buffer size.
2459          */
2460         buflen = sizeof (struct report_density_header) +
2461             sizeof (struct report_density_desc);
2462         den_header = kmem_zalloc(buflen, KM_SLEEP);
2463         if (st_report_density_support(un, den_header, buflen) != 0) {
2464                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2465                     "st_get_conf_from_tape_drive(): fail to report density.\n");
2466                 kmem_free(den_header, buflen);
2467                 return (0);
2468         }
2469         des_len =
2470             BE_16(((struct report_density_header *)den_header)->ava_dens_len);
2471         num_den = (des_len - 2) / sizeof (struct report_density_desc);
2472 
2473         if (num_den > 1) {
2474                 kmem_free(den_header, buflen);
2475                 buflen = sizeof (struct report_density_header) +
2476                     sizeof (struct report_density_desc) * num_den;
2477                 den_header = kmem_zalloc(buflen, KM_SLEEP);
2478                 if (st_report_density_support(un, den_header, buflen) != 0) {
2479                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2480                             "st_get_conf_from_tape_drive(): "
2481                             "fail to report density.\n");
2482                         kmem_free(den_header, buflen);
2483                         return (0);
2484                 }
2485         }
2486 
2487         den_desc = (struct report_density_desc *)(den_header
2488             + sizeof (struct report_density_header));
2489 
2490         /*
2491          * Decide the drive type by assigning organization
2492          */
2493         for (i = 0; i < ST_NUM_MEMBERS(st_vid_dt); i ++) {
2494                 if (strncmp(st_vid_dt[i].vid, (char *)(den_desc->ass_org),
2495                     8) == 0) {
2496                         dp->type = st_vid_dt[i].type;
2497                         break;
2498                 }
2499         }
2500         if (i == ST_NUM_MEMBERS(st_vid_dt)) {
2501                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2502                     "st_get_conf_from_tape_drive(): "
2503                     "can't find match of assigned ort.\n");
2504                 kmem_free(den_header, buflen);
2505                 return (0);
2506         }
2507 
2508         /*
2509          * The tape drive may support many tape formats, but the st driver
2510          * supports only the four highest densities. Since density code
2511          * values are returned by ascending sequence, we start from the
2512          * last entry of density support data block descriptor.
2513          */
2514         p = 0;
2515         den_desc += num_den - 1;
2516         for (i = 0; i < num_den && p < NDENSITIES; i ++, den_desc --) {
2517                 if ((den_desc->pri_den != 0) && (den_desc->wrtok)) {
2518                         if (p != 0) {
2519                                 if (den_desc->pri_den >= den[p - 1]) {
2520                                         continue;
2521                                 }
2522                         }
2523                         den[p] = den_desc->pri_den;
2524                         deflt[p] = den_desc->deflt;
2525                         p ++;
2526                 }
2527         }
2528 
2529         switch (p) {
2530         case 0:
2531                 bzero(dp->densities, NDENSITIES);
2532                 dp->options |= ST_AUTODEN_OVERRIDE;
2533                 dp->default_density = MT_DENSITY4;
2534                 break;
2535 
2536         case 1:
2537                 (void) memset(dp->densities, den[0], NDENSITIES);
2538                 dp->options |= ST_AUTODEN_OVERRIDE;
2539                 dp->default_density = MT_DENSITY4;
2540                 break;
2541 
2542         case 2:
2543                 dp->densities[0] = den[1];
2544                 dp->densities[1] = den[1];
2545                 dp->densities[2] = den[0];
2546                 dp->densities[3] = den[0];
2547                 if (deflt[0]) {
2548                         dp->default_density = MT_DENSITY4;
2549                 } else {
2550                         dp->default_density = MT_DENSITY2;
2551                 }
2552                 break;
2553 
2554         case 3:
2555                 dp->densities[0] = den[2];
2556                 dp->densities[1] = den[1];
2557                 dp->densities[2] = den[0];
2558                 dp->densities[3] = den[0];
2559                 if (deflt[0]) {
2560                         dp->default_density = MT_DENSITY4;
2561                 } else if (deflt[1]) {
2562                         dp->default_density = MT_DENSITY2;
2563                 } else {
2564                         dp->default_density = MT_DENSITY1;
2565                 }
2566                 break;
2567 
2568         default:
2569                 for (i = p; i > p - NDENSITIES; i --) {
2570                         dp->densities[i - 1] = den[p - i];
2571                 }
2572                 if (deflt[0]) {
2573                         dp->default_density = MT_DENSITY4;
2574                 } else if (deflt[1]) {
2575                         dp->default_density = MT_DENSITY3;
2576                 } else if (deflt[2]) {
2577                         dp->default_density = MT_DENSITY2;
2578                 } else {
2579                         dp->default_density = MT_DENSITY1;
2580                 }
2581                 break;
2582         }
2583 
2584         bzero(dp->mediatype, NDENSITIES);
2585 
2586         kmem_free(den_header, buflen);
2587         return (1);
2588 }
2589 
2590 static int
2591 st_get_timeout_values_from_tape_drive(struct scsi_tape *un,
2592     struct st_drivetype *dp)
2593 {
2594         ushort_t timeout;
2595         int rval;
2596 
2597         ST_FUNC(ST_DEVINFO, st_get_timeout_values_from_type_drive);
2598 
2599         rval = st_get_timeouts_value(un, SCMD_ERASE, &timeout, 0);
2600         if (rval) {
2601                 if (rval == EACCES) {
2602                         un->un_dp->type = ST_TYPE_INVALID;
2603                         dp->type = ST_TYPE_INVALID;
2604                         return (1);
2605                 }
2606                 return (0);
2607         }
2608         dp->erase_timeout = timeout;
2609 
2610         rval = st_get_timeouts_value(un, SCMD_READ, &timeout, 0);
2611         if (rval) {
2612                 if (rval == EACCES) {
2613                         un->un_dp->type = ST_TYPE_INVALID;
2614                         dp->type = ST_TYPE_INVALID;
2615                         return (1);
2616                 }
2617                 return (0);
2618         }
2619         dp->io_timeout = timeout;
2620 
2621         rval = st_get_timeouts_value(un, SCMD_WRITE, &timeout, 0);
2622         if (rval) {
2623                 if (rval == EACCES) {
2624                         un->un_dp->type = ST_TYPE_INVALID;
2625                         dp->type = ST_TYPE_INVALID;
2626                         return (1);
2627                 }
2628                 return (0);
2629         }
2630         dp->io_timeout = max(dp->io_timeout, timeout);
2631 
2632         rval = st_get_timeouts_value(un, SCMD_SPACE, &timeout, 0);
2633         if (rval) {
2634                 if (rval == EACCES) {
2635                         un->un_dp->type = ST_TYPE_INVALID;
2636                         dp->type = ST_TYPE_INVALID;
2637                         return (1);
2638                 }
2639                 return (0);
2640         }
2641         dp->space_timeout = timeout;
2642 
2643         rval = st_get_timeouts_value(un, SCMD_LOAD, &timeout, 0);
2644         if (rval) {
2645                 if (rval == EACCES) {
2646                         un->un_dp->type = ST_TYPE_INVALID;
2647                         dp->type = ST_TYPE_INVALID;
2648                         return (1);
2649                 }
2650                 return (0);
2651         }
2652         dp->load_timeout = timeout;
2653         dp->unload_timeout = timeout;
2654 
2655         rval = st_get_timeouts_value(un, SCMD_REWIND, &timeout, 0);
2656         if (rval) {
2657                 if (rval == EACCES) {
2658                         un->un_dp->type = ST_TYPE_INVALID;
2659                         dp->type = ST_TYPE_INVALID;
2660                         return (1);
2661                 }
2662                 return (0);
2663         }
2664         dp->rewind_timeout = timeout;
2665 
2666         rval = st_get_timeouts_value(un, SCMD_INQUIRY, &timeout, 0);
2667         if (rval) {
2668                 if (rval == EACCES) {
2669                         un->un_dp->type = ST_TYPE_INVALID;
2670                         dp->type = ST_TYPE_INVALID;
2671                         return (1);
2672                 }
2673                 return (0);
2674         }
2675         dp->non_motion_timeout = timeout;
2676 
2677         return (1);
2678 }
2679 
2680 static int
2681 st_get_timeouts_value(struct scsi_tape *un, uchar_t option_code,
2682     ushort_t *timeout_value, ushort_t service_action)
2683 {
2684         uchar_t *timeouts;
2685         uchar_t *oper;
2686         uchar_t support;
2687         uchar_t cdbsize;
2688         uchar_t ctdp;
2689         size_t buflen;
2690         int rval;
2691 
2692         ST_FUNC(ST_DEVINFO, st_get_timeouts_value);
2693 
2694         buflen = sizeof (struct one_com_des) +
2695             sizeof (struct com_timeout_des);
2696         oper = kmem_zalloc(buflen, KM_SLEEP);
2697         rval = st_report_supported_operation(un, oper, option_code,
2698             service_action);
2699 
2700         if (rval) {
2701                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2702                     "st_get_timeouts_value(): "
2703                     "fail to timeouts value for command %d.\n", option_code);
2704                 kmem_free(oper, buflen);
2705                 return (rval);
2706         }
2707 
2708         support = ((struct one_com_des *)oper)->support;
2709         if ((support != SUPPORT_VALUES_SUPPORT_SCSI) &&
2710             (support != SUPPORT_VALUES_SUPPORT_VENDOR)) {
2711                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2712                     "st_get_timeouts_value(): "
2713                     "command %d is not supported.\n", option_code);
2714                 kmem_free(oper, buflen);
2715                 return (ENOTSUP);
2716         }
2717 
2718         ctdp = ((struct one_com_des *)oper)->ctdp;
2719         if (!ctdp) {
2720                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2721                     "st_get_timeouts_value(): "
2722                     "command timeout is not included.\n");
2723                 kmem_free(oper, buflen);
2724                 return (ENOTSUP);
2725         }
2726 
2727         cdbsize = BE_16(((struct one_com_des *)oper)->cdb_size);
2728         timeouts = (uchar_t *)(oper + cdbsize + 4);
2729 
2730         /*
2731          * Timeout value in seconds is 4 bytes, but we only support the lower 2
2732          * bytes. If the higher 2 bytes are not zero, the timeout value is set
2733          * to 0xFFFF.
2734          */
2735         if (*(timeouts + 8) != 0 || *(timeouts + 9) != 0) {
2736                 *timeout_value = USHRT_MAX;
2737         } else {
2738                 *timeout_value = ((*(timeouts + 10)) << 8) |
2739                     (*(timeouts + 11));
2740         }
2741 
2742         kmem_free(oper, buflen);
2743         return (0);
2744 }
2745 
2746 static int
2747 st_get_default_conf(struct scsi_tape *un, char *vidpid, struct st_drivetype *dp)
2748 {
2749         int i;
2750 
2751         ST_FUNC(ST_DEVINFO, st_get_default_conf);
2752 
2753         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
2754             "st_get_default_conf(): making drivetype from INQ cmd\n");
2755 
2756         /*
2757          * Make up a name
2758          */
2759         bcopy("Vendor '", dp->name, 8);
2760         bcopy(vidpid, &dp->name[8], VIDLEN);
2761         bcopy("' Product '", &dp->name[16], 11);
2762         bcopy(&vidpid[8], &dp->name[27], PIDLEN);
2763         dp->name[ST_NAMESIZE - 2] = '\'';
2764         dp->name[ST_NAMESIZE - 1] = '\0';
2765         dp->length = min(strlen(ST_INQUIRY->inq_vid), (VIDPIDLEN - 1));
2766         (void) strncpy(dp->vid, ST_INQUIRY->inq_vid, dp->length);
2767         /*
2768          * 'clean' vendor and product strings of non-printing chars
2769          */
2770         for (i = 0; i < ST_NAMESIZE - 2; i++) {
2771                 if (dp->name[i] < ' ' || dp->name[i] > '~') {
2772                         dp->name[i] = '.';
2773                 }
2774         }
2775         dp->type = ST_TYPE_INVALID;
2776         dp->options |= (ST_DYNAMIC | ST_UNLOADABLE | ST_MODE_SEL_COMP);
2777 
2778         return (1); /* Can Not Fail */
2779 }
2780 
2781 /*
2782  * Regular Unix Entry points
2783  */
2784 
2785 
2786 
2787 /* ARGSUSED */
2788 static int
2789 st_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
2790 {
2791         dev_t dev = *dev_p;
2792         int rval = 0;
2793 
2794         GET_SOFT_STATE(dev);
2795 
2796         ST_ENTR(ST_DEVINFO, st_open);
2797 
2798         /*
2799          * validate that we are addressing a sensible unit
2800          */
2801         mutex_enter(ST_MUTEX);
2802 
2803         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2804             "st_open(node = %s dev = 0x%lx, flag = %d, otyp = %d)\n",
2805             st_dev_name(dev), *dev_p, flag, otyp);
2806 
2807         /*
2808          * All device accesss go thru st_strategy() where we check
2809          * suspend status
2810          */
2811 
2812         if (!un->un_attached) {
2813                 st_known_tape_type(un);
2814                 if (!un->un_attached) {
2815                         rval = ENXIO;
2816                         goto exit;
2817                 }
2818 
2819         }
2820 
2821         /*
2822          * Check for the case of the tape in the middle of closing.
2823          * This isn't simply a check of the current state, because
2824          * we could be in state of sensing with the previous state
2825          * that of closing.
2826          *
2827          * And don't allow multiple opens.
2828          */
2829         if (!(flag & (FNDELAY | FNONBLOCK)) && IS_CLOSING(un)) {
2830                 un->un_laststate = un->un_state;
2831                 un->un_state = ST_STATE_CLOSE_PENDING_OPEN;
2832                 while (IS_CLOSING(un) ||
2833                     un->un_state == ST_STATE_CLOSE_PENDING_OPEN) {
2834                         if (cv_wait_sig(&un->un_clscv, ST_MUTEX) == 0) {
2835                                 rval = EINTR;
2836                                 un->un_state = un->un_laststate;
2837                                 goto exit;
2838                         }
2839                 }
2840         } else if (un->un_state != ST_STATE_CLOSED) {
2841                 rval = EBUSY;
2842                 goto busy;
2843         }
2844 
2845         /*
2846          * record current dev
2847          */
2848         un->un_dev = dev;
2849         un->un_oflags = flag;        /* save for use in st_tape_init() */
2850         un->un_errno = 0;    /* no errors yet */
2851         un->un_restore_pos = 0;
2852         un->un_rqs_state = 0;
2853 
2854         /*
2855          * If we are opening O_NDELAY, or O_NONBLOCK, we don't check for
2856          * anything, leave internal states alone, if fileno >= 0
2857          */
2858         if (flag & (FNDELAY | FNONBLOCK)) {
2859                 switch (un->un_pos.pmode) {
2860 
2861                 case invalid:
2862                         un->un_state = ST_STATE_OFFLINE;
2863                         break;
2864 
2865                 case legacy:
2866                         /*
2867                          * If position is anything other than rewound.
2868                          */
2869                         if (un->un_pos.fileno != 0 || un->un_pos.blkno != 0) {
2870                                 /*
2871                                  * set un_read_only/write-protect status.
2872                                  *
2873                                  * If the tape is not bot we can assume
2874                                  * that mspl->wp_status is set properly.
2875                                  * else
2876                                  * we need to do a mode sense/Tur once
2877                                  * again to get the actual tape status.(since
2878                                  * user might have replaced the tape)
2879                                  * Hence make the st state OFFLINE so that
2880                                  * we re-intialize the tape once again.
2881                                  */
2882                                 un->un_read_only =
2883                                     (un->un_oflags & FWRITE) ? RDWR : RDONLY;
2884                                 un->un_state = ST_STATE_OPEN_PENDING_IO;
2885                         } else {
2886                                 un->un_state = ST_STATE_OFFLINE;
2887                         }
2888                         break;
2889                 case logical:
2890                         if (un->un_pos.lgclblkno == 0) {
2891                                 un->un_state = ST_STATE_OFFLINE;
2892                         } else {
2893                                 un->un_read_only =
2894                                     (un->un_oflags & FWRITE) ? RDWR : RDONLY;
2895                                 un->un_state = ST_STATE_OPEN_PENDING_IO;
2896                         }
2897                         break;
2898                 }
2899                 rval = 0;
2900         } else {
2901                 /*
2902                  * Not opening O_NDELAY.
2903                  */
2904                 un->un_state = ST_STATE_OPENING;
2905 
2906                 /*
2907                  * Clear error entry stack
2908                  */
2909                 st_empty_error_stack(un);
2910 
2911                 rval = st_tape_init(un);
2912                 if ((rval == EACCES) && (un->un_read_only & WORM)) {
2913                         un->un_state = ST_STATE_OPEN_PENDING_IO;
2914                         rval = 0; /* so open doesn't fail */
2915                 } else if (rval) {
2916                         /*
2917                          * Release the tape unit, if reserved and not
2918                          * preserve reserve.
2919                          */
2920                         if ((un->un_rsvd_status &
2921                             (ST_RESERVE | ST_PRESERVE_RESERVE)) == ST_RESERVE) {
2922                                 (void) st_reserve_release(un, ST_RELEASE,
2923                                     st_uscsi_cmd);
2924                         }
2925                 } else {
2926                         un->un_state = ST_STATE_OPEN_PENDING_IO;
2927                 }
2928         }
2929 
2930 exit:
2931         /*
2932          * we don't want any uninvited guests scrogging our data when we're
2933          * busy with something, so for successful opens or failed opens
2934          * (except for EBUSY), reset these counters and state appropriately.
2935          */
2936         if (rval != EBUSY) {
2937                 if (rval) {
2938                         un->un_state = ST_STATE_CLOSED;
2939                 }
2940                 un->un_err_resid = 0;
2941                 un->un_retry_ct = 0;
2942         }
2943 busy:
2944         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2945             "st_open: return val = %x, state = %d\n", rval, un->un_state);
2946         mutex_exit(ST_MUTEX);
2947         return (rval);
2948 
2949 }
2950 
2951 static int
2952 st_tape_init(struct scsi_tape *un)
2953 {
2954         int err;
2955         int rval = 0;
2956 
2957         ST_FUNC(ST_DEVINFO, st_tape_init);
2958 
2959         ASSERT(mutex_owned(ST_MUTEX));
2960 
2961         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2962             "st_tape_init(un = 0x%p, oflags = %d)\n", (void*)un, un->un_oflags);
2963 
2964         /*
2965          * Clean up after any errors left by 'last' close.
2966          * This also handles the case of the initial open.
2967          */
2968         if (un->un_state != ST_STATE_INITIALIZING) {
2969                 un->un_laststate = un->un_state;
2970                 un->un_state = ST_STATE_OPENING;
2971         }
2972 
2973         un->un_kbytes_xferred = 0;
2974 
2975         /*
2976          * do a throw away TUR to clear check condition
2977          */
2978         err = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
2979 
2980         /*
2981          * If test unit ready fails because the drive is reserved
2982          * by another host fail the open for no access.
2983          */
2984         if (err) {
2985                 if (un->un_rsvd_status & ST_RESERVATION_CONFLICT) {
2986                         un->un_state = ST_STATE_CLOSED;
2987                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2988                             "st_tape_init: RESERVATION CONFLICT\n");
2989                         rval = EACCES;
2990                         goto exit;
2991                 } else if ((un->un_rsvd_status &
2992                     ST_APPLICATION_RESERVATIONS) != 0) {
2993                         if ((ST_RQSENSE != NULL) &&
2994                             (ST_RQSENSE->es_add_code == 0x2a &&
2995                             ST_RQSENSE->es_qual_code == 0x03)) {
2996                                 un->un_state = ST_STATE_CLOSED;
2997                                 rval = EACCES;
2998                                 goto exit;
2999                         }
3000                 }
3001         }
3002 
3003         /*
3004          * Tape self identification could fail if the tape drive is used by
3005          * another host during attach time. We try to get the tape type
3006          * again. This is also applied to any posponed configuration methods.
3007          */
3008         if (un->un_dp->type == ST_TYPE_INVALID) {
3009                 un->un_comp_page = ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE;
3010                 st_known_tape_type(un);
3011         }
3012 
3013         /*
3014          * If the tape type is still invalid, try to determine the generic
3015          * configuration.
3016          */
3017         if (un->un_dp->type == ST_TYPE_INVALID) {
3018                 rval = st_determine_generic(un);
3019                 if (rval) {
3020                         if (rval != EACCES) {
3021                                 rval = EIO;
3022                         }
3023                         un->un_state = ST_STATE_CLOSED;
3024                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3025                             "st_tape_init: %s invalid type\n",
3026                             rval == EACCES ? "EACCES" : "EIO");
3027                         goto exit;
3028                 }
3029                 /*
3030                  * If this is a Unknown Type drive,
3031                  * Use the READ BLOCK LIMITS to determine if
3032                  * allow large xfer is approprate if not globally
3033                  * disabled with st_allow_large_xfer.
3034                  */
3035                 un->un_allow_large_xfer = (uchar_t)st_allow_large_xfer;
3036         } else {
3037 
3038                 /*
3039                  * If we allow_large_xfer (ie >64k) and have not yet found out
3040                  * the max block size supported by the drive,
3041                  * find it by issueing a READ_BLKLIM command.
3042                  * if READ_BLKLIM cmd fails, assume drive doesn't
3043                  * allow_large_xfer and min/max block sizes as 1 byte and 63k.
3044                  */
3045                 un->un_allow_large_xfer = st_allow_large_xfer &&
3046                     (un->un_dp->options & ST_NO_RECSIZE_LIMIT);
3047         }
3048         /*
3049          * if maxbsize is unknown, set the maximum block size.
3050          */
3051         if (un->un_maxbsize == MAXBSIZE_UNKNOWN) {
3052 
3053                 /*
3054                  * Get the Block limits of the tape drive.
3055                  * if un->un_allow_large_xfer = 0 , then make sure
3056                  * that maxbsize is <= ST_MAXRECSIZE_FIXED.
3057                  */
3058                 un->un_rbl = kmem_zalloc(RBLSIZE, KM_SLEEP);
3059 
3060                 err = st_cmd(un, SCMD_READ_BLKLIM, RBLSIZE, SYNC_CMD);
3061                 if (err) {
3062                         /* Retry */
3063                         err = st_cmd(un, SCMD_READ_BLKLIM, RBLSIZE, SYNC_CMD);
3064                 }
3065                 if (!err) {
3066 
3067                         /*
3068                          * if cmd successful, use limit returned
3069                          */
3070                         un->un_maxbsize = (un->un_rbl->max_hi << 16) +
3071                             (un->un_rbl->max_mid << 8) +
3072                             un->un_rbl->max_lo;
3073                         un->un_minbsize = (un->un_rbl->min_hi << 8) +
3074                             un->un_rbl->min_lo;
3075                         un->un_data_mod = 1 << un->un_rbl->granularity;
3076                         if ((un->un_maxbsize == 0) ||
3077                             (un->un_allow_large_xfer == 0 &&
3078                             un->un_maxbsize > ST_MAXRECSIZE_FIXED)) {
3079                                 un->un_maxbsize = ST_MAXRECSIZE_FIXED;
3080 
3081                         } else if (un->un_dp->type == ST_TYPE_DEFAULT) {
3082                                 /*
3083                                  * Drive is not one that is configured, But the
3084                                  * READ BLOCK LIMITS tells us it can do large
3085                                  * xfers.
3086                                  */
3087                                 if (un->un_maxbsize > ST_MAXRECSIZE_FIXED) {
3088                                         un->un_dp->options |=
3089                                             ST_NO_RECSIZE_LIMIT;
3090                                 }
3091                                 /*
3092                                  * If max and mimimum block limits are the
3093                                  * same this is a fixed block size device.
3094                                  */
3095                                 if (un->un_maxbsize == un->un_minbsize) {
3096                                         un->un_dp->options &= ~ST_VARIABLE;
3097                                 }
3098                         }
3099 
3100                         if (un->un_minbsize == 0) {
3101                                 un->un_minbsize = 1;
3102                         }
3103 
3104                 } else { /* error on read block limits */
3105 
3106                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
3107                             "!st_tape_init: Error on READ BLOCK LIMITS,"
3108                             " errno = %d un_rsvd_status = 0x%X\n",
3109                             err, un->un_rsvd_status);
3110 
3111                         /*
3112                          * since read block limits cmd failed,
3113                          * do not allow large xfers.
3114                          * use old values in st_minphys
3115                          */
3116                         if (un->un_rsvd_status & ST_RESERVATION_CONFLICT) {
3117                                 rval = EACCES;
3118                         } else {
3119                                 un->un_allow_large_xfer = 0;
3120                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
3121                                     "!Disabling large transfers\n");
3122 
3123                                 /*
3124                                  * we guess maxbsize and minbsize
3125                                  */
3126                                 if (un->un_bsize) {
3127                                         un->un_maxbsize = un->un_minbsize =
3128                                             un->un_bsize;
3129                                 } else {
3130                                         un->un_maxbsize = ST_MAXRECSIZE_FIXED;
3131                                         un->un_minbsize = 1;
3132                                 }
3133                                 /*
3134                                  * Data Mod must be set,
3135                                  * Even if read block limits fails.
3136                                  * Prevents Divide By Zero in st_rw().
3137                                  */
3138                                 un->un_data_mod = 1;
3139                         }
3140                 }
3141                 if (un->un_rbl) {
3142                         kmem_free(un->un_rbl, RBLSIZE);
3143                         un->un_rbl = NULL;
3144                 }
3145 
3146                 if (rval) {
3147                         goto exit;
3148                 }
3149         }
3150 
3151         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
3152             "maxdma = %d, maxbsize = %d, minbsize = %d, %s large xfer\n",
3153             un->un_maxdma, un->un_maxbsize, un->un_minbsize,
3154             (un->un_allow_large_xfer ? "ALLOW": "DON'T ALLOW"));
3155 
3156         err = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
3157 
3158         if (err != 0) {
3159                 if (err == EINTR) {
3160                         un->un_laststate = un->un_state;
3161                         un->un_state = ST_STATE_CLOSED;
3162                         rval = EINTR;
3163                         goto exit;
3164                 }
3165                 /*
3166                  * Make sure the tape is ready
3167                  */
3168                 un->un_pos.pmode = invalid;
3169                 if (un->un_status != KEY_UNIT_ATTENTION) {
3170                         /*
3171                          * allow open no media.  Subsequent MTIOCSTATE
3172                          * with media present will complete the open
3173                          * logic.
3174                          */
3175                         un->un_laststate = un->un_state;
3176                         if (un->un_oflags & (FNONBLOCK|FNDELAY)) {
3177                                 un->un_mediastate = MTIO_EJECTED;
3178                                 un->un_state = ST_STATE_OFFLINE;
3179                                 rval = 0;
3180                                 goto exit;
3181                         } else {
3182                                 un->un_state = ST_STATE_CLOSED;
3183                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3184                                     "st_tape_init EIO no media, not opened "
3185                                     "O_NONBLOCK|O_EXCL\n");
3186                                 rval = EIO;
3187                                 goto exit;
3188                         }
3189                 }
3190         }
3191 
3192         /*
3193          * On each open, initialize block size from drivetype struct,
3194          * as it could have been changed by MTSRSZ ioctl.
3195          * Now, ST_VARIABLE simply means drive is capable of variable
3196          * mode. All drives are assumed to support fixed records.
3197          * Hence, un_bsize tells what mode the drive is in.
3198          *      un_bsize        = 0     - variable record length
3199          *                      = x     - fixed record length is x
3200          */
3201         un->un_bsize = un->un_dp->bsize;
3202 
3203         /*
3204          * If saved position is valid go there
3205          */
3206         if (un->un_restore_pos) {
3207                 un->un_restore_pos = 0;
3208                 un->un_pos.fileno = un->un_save_fileno;
3209                 un->un_pos.blkno = un->un_save_blkno;
3210                 rval = st_validate_tapemarks(un, st_uscsi_cmd, &un->un_pos);
3211                 if (rval != 0) {
3212                         if (rval != EACCES) {
3213                                 rval = EIO;
3214                         }
3215                         un->un_laststate = un->un_state;
3216                         un->un_state = ST_STATE_CLOSED;
3217                         goto exit;
3218                 }
3219         }
3220 
3221         if (un->un_pos.pmode == invalid) {
3222                 rval = st_loadtape(un);
3223                 if (rval) {
3224                         if (rval != EACCES) {
3225                                 rval = EIO;
3226                         }
3227                         un->un_laststate = un->un_state;
3228                         un->un_state = ST_STATE_CLOSED;
3229                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3230                             "st_tape_init: %s can't open tape\n",
3231                             rval == EACCES ? "EACCES" : "EIO");
3232                         goto exit;
3233                 }
3234         }
3235 
3236         /*
3237          * do a mode sense to pick up state of current write-protect,
3238          * Could cause reserve and fail due to conflict.
3239          */
3240         if (un->un_unit_attention_flags) {
3241                 rval = st_modesense(un);
3242                 if (rval == EACCES) {
3243                         goto exit;
3244                 }
3245         }
3246 
3247         /*
3248          * If we are opening the tape for writing, check
3249          * to make sure that the tape can be written.
3250          */
3251         if (un->un_oflags & FWRITE) {
3252                 err = 0;
3253                 if (un->un_mspl->wp) {
3254                         un->un_status = KEY_WRITE_PROTECT;
3255                         un->un_laststate = un->un_state;
3256                         un->un_state = ST_STATE_CLOSED;
3257                         rval = EACCES;
3258                         /*
3259                          * STK sets the wp bit if volsafe tape is loaded.
3260                          */
3261                         if ((un->un_dp->type == MT_ISSTK9840) &&
3262                             (un->un_dp->options & ST_WORMABLE)) {
3263                                 un->un_read_only = RDONLY;
3264                         } else {
3265                                 goto exit;
3266                         }
3267                 } else {
3268                         un->un_read_only = RDWR;
3269                 }
3270         } else {
3271                 un->un_read_only = RDONLY;
3272         }
3273 
3274         if (un->un_dp->options & ST_WORMABLE &&
3275             un->un_unit_attention_flags) {
3276                 un->un_read_only |= un->un_wormable(un);
3277 
3278                 if (((un->un_read_only == WORM) ||
3279                     (un->un_read_only == RDWORM)) &&
3280                     ((un->un_oflags & FWRITE) == FWRITE)) {
3281                         un->un_status = KEY_DATA_PROTECT;
3282                         rval = EACCES;
3283                         ST_DEBUG4(ST_DEVINFO, st_label, CE_NOTE,
3284                             "read_only = %d eof = %d oflag = %d\n",
3285                             un->un_read_only, un->un_pos.eof, un->un_oflags);
3286                 }
3287         }
3288 
3289         /*
3290          * If we're opening the tape write-only, we need to
3291          * write 2 filemarks on the HP 1/2 inch drive, to
3292          * create a null file.
3293          */
3294         if ((un->un_read_only == RDWR) ||
3295             (un->un_read_only == WORM) && (un->un_oflags & FWRITE)) {
3296                 if (un->un_dp->options & ST_REEL) {
3297                         un->un_fmneeded = 2;
3298                 } else {
3299                         un->un_fmneeded = 1;
3300                 }
3301         } else {
3302                 un->un_fmneeded = 0;
3303         }
3304 
3305         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
3306             "fmneeded = %x\n", un->un_fmneeded);
3307 
3308         /*
3309          * Make sure the density can be selected correctly.
3310          * If WORM can only write at the append point which in most cases
3311          * isn't BOP. st_determine_density() with a B_WRITE only attempts
3312          * to set and try densities if a BOP.
3313          */
3314         if (st_determine_density(un,
3315             un->un_read_only == RDWR ? B_WRITE : B_READ)) {
3316                 un->un_status = KEY_ILLEGAL_REQUEST;
3317                 un->un_laststate = un->un_state;
3318                 un->un_state = ST_STATE_CLOSED;
3319                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
3320                     "st_tape_init: EIO can't determine density\n");
3321                 rval = EIO;
3322                 goto exit;
3323         }
3324 
3325         /*
3326          * Destroy the knowledge that we have 'determined'
3327          * density so that a later read at BOT comes along
3328          * does the right density determination.
3329          */
3330 
3331         un->un_density_known = 0;
3332 
3333 
3334         /*
3335          * Okay, the tape is loaded and either at BOT or somewhere past.
3336          * Mark the state such that any I/O or tape space operations
3337          * will get/set the right density, etc..
3338          */
3339         un->un_laststate = un->un_state;
3340         un->un_lastop = ST_OP_NIL;
3341         un->un_mediastate = MTIO_INSERTED;
3342         cv_broadcast(&un->un_state_cv);
3343 
3344         /*
3345          *  Set test append flag if writing.
3346          *  First write must check that tape is positioned correctly.
3347          */
3348         un->un_test_append = (un->un_oflags & FWRITE);
3349 
3350         /*
3351          * if there are pending unit attention flags.
3352          * Check that the media has not changed.
3353          */
3354         if (un->un_unit_attention_flags) {
3355                 rval = st_get_media_identification(un, st_uscsi_cmd);
3356                 if (rval != 0 && rval != EACCES) {
3357                         rval = EIO;
3358                 }
3359                 un->un_unit_attention_flags = 0;
3360         }
3361 
3362 exit:
3363         un->un_err_resid = 0;
3364         un->un_last_resid = 0;
3365         un->un_last_count = 0;
3366 
3367         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3368             "st_tape_init: return val = %x\n", rval);
3369         return (rval);
3370 
3371 }
3372 
3373 
3374 
3375 /* ARGSUSED */
3376 static int
3377 st_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
3378 {
3379         int err = 0;
3380         int count, last_state;
3381         minor_t minor = getminor(dev);
3382 #ifdef  __x86
3383         struct contig_mem *cp, *cp_temp;
3384 #endif
3385 
3386         GET_SOFT_STATE(dev);
3387 
3388         ST_ENTR(ST_DEVINFO, st_close);
3389 
3390         /*
3391          * wait till all cmds in the pipeline have been completed
3392          */
3393         mutex_enter(ST_MUTEX);
3394 
3395         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3396             "st_close(dev = 0x%lx, flag = %d, otyp = %d)\n", dev, flag, otyp);
3397 
3398         st_wait_for_io(un);
3399 
3400         /* turn off persistent errors on close, as we want close to succeed */
3401         st_turn_pe_off(un);
3402 
3403         /*
3404          * set state to indicate that we are in process of closing
3405          */
3406         last_state = un->un_laststate = un->un_state;
3407         un->un_state = ST_STATE_CLOSING;
3408 
3409         ST_POS(ST_DEVINFO, "st_close1:", &un->un_pos);
3410 
3411         /*
3412          * BSD behavior:
3413          * a close always causes a silent span to the next file if we've hit
3414          * an EOF (but not yet read across it).
3415          */
3416         if ((minor & MT_BSD) && (un->un_pos.eof == ST_EOF)) {
3417                 if (un->un_pos.pmode != invalid) {
3418                         un->un_pos.fileno++;
3419                         un->un_pos.blkno = 0;
3420                 }
3421                 un->un_pos.eof = ST_NO_EOF;
3422         }
3423 
3424         /*
3425          * SVR4 behavior for skipping to next file:
3426          *
3427          * If we have not seen a filemark, space to the next file
3428          *
3429          * If we have already seen the filemark we are physically in the next
3430          * file and we only increment the filenumber
3431          */
3432         if (((minor & (MT_BSD | MT_NOREWIND)) == MT_NOREWIND) &&
3433             (flag & FREAD) &&               /* reading or at least asked to */
3434             (un->un_mediastate == MTIO_INSERTED) &&  /* tape loaded */
3435             (un->un_pos.pmode != invalid) &&         /* XXX position known */
3436             ((un->un_pos.blkno != 0) &&              /* inside a file */
3437             (un->un_lastop != ST_OP_WRITE) &&                /* Didn't just write */
3438             (un->un_lastop != ST_OP_WEOF))) {                /* or write filemarks */
3439                 switch (un->un_pos.eof) {
3440                 case ST_NO_EOF:
3441                         /*
3442                          * if we were reading and did not read the complete file
3443                          * skip to the next file, leaving the tape correctly
3444                          * positioned to read the first record of the next file
3445                          * Check first for REEL if we are at EOT by trying to
3446                          * read a block
3447                          */
3448                         if ((un->un_dp->options & ST_REEL) &&
3449                             (!(un->un_dp->options & ST_READ_IGNORE_EOFS)) &&
3450                             (un->un_pos.blkno == 0)) {
3451                                 if (st_cmd(un, SCMD_SPACE, Blk(1), SYNC_CMD)) {
3452                                         ST_DEBUG2(ST_DEVINFO, st_label,
3453                                             SCSI_DEBUG,
3454                                             "st_close : EIO can't space\n");
3455                                         err = EIO;
3456                                         goto error_out;
3457                                 }
3458                                 if (un->un_pos.eof >= ST_EOF_PENDING) {
3459                                         un->un_pos.eof = ST_EOT_PENDING;
3460                                         un->un_pos.fileno += 1;
3461                                         un->un_pos.blkno   = 0;
3462                                         break;
3463                                 }
3464                         }
3465                         if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
3466                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3467                                     "st_close: EIO can't space #2\n");
3468                                 err = EIO;
3469                                 goto error_out;
3470                         } else {
3471                                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3472                                     "st_close2: fileno=%x,blkno=%x,eof=%x\n",
3473                                     un->un_pos.fileno, un->un_pos.blkno,
3474                                     un->un_pos.eof);
3475                                 un->un_pos.eof = ST_NO_EOF;
3476                         }
3477                         break;
3478 
3479                 case ST_EOF_PENDING:
3480                 case ST_EOF:
3481                         un->un_pos.fileno += 1;
3482                         un->un_pos.lgclblkno += 1;
3483                         un->un_pos.blkno   = 0;
3484                         un->un_pos.eof = ST_NO_EOF;
3485                         break;
3486 
3487                 case ST_EOT:
3488                 case ST_EOT_PENDING:
3489                 case ST_EOM:
3490                         /* nothing to do */
3491                         break;
3492                 default:
3493                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
3494                             "Undefined state 0x%x", un->un_pos.eof);
3495 
3496                 }
3497         }
3498 
3499 
3500         /*
3501          * For performance reasons (HP 88780), the driver should
3502          * postpone writing the second tape mark until just before a file
3503          * positioning ioctl is issued (e.g., rewind).  This means that
3504          * the user must not manually rewind the tape because the tape will
3505          * be missing the second tape mark which marks EOM.
3506          * However, this small performance improvement is not worth the risk.
3507          */
3508 
3509         /*
3510          * We need to back up over the filemark we inadvertently popped
3511          * over doing a read in between the two filemarks that constitute
3512          * logical eot for 1/2" tapes. Note that ST_EOT_PENDING is only
3513          * set while reading.
3514          *
3515          * If we happen to be at physical eot (ST_EOM) (writing case),
3516          * the writing of filemark(s) will clear the ST_EOM state, which
3517          * we don't want, so we save this state and restore it later.
3518          */
3519 
3520         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3521             "flag=%x, fmneeded=%x, lastop=%x, eof=%x\n",
3522             flag, un->un_fmneeded, un->un_lastop, un->un_pos.eof);
3523 
3524         if (un->un_pos.eof == ST_EOT_PENDING) {
3525                 if (minor & MT_NOREWIND) {
3526                         if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
3527                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3528                                     "st_close: EIO can't space #3\n");
3529                                 err = EIO;
3530                                 goto error_out;
3531                         } else {
3532                                 un->un_pos.blkno = 0;
3533                                 un->un_pos.eof = ST_EOT;
3534                         }
3535                 } else {
3536                         un->un_pos.eof = ST_NO_EOF;
3537                 }
3538 
3539         /*
3540          * Do we need to write a file mark?
3541          *
3542          * only write filemarks if there are fmks to be written and
3543          *   - open for write (possibly read/write)
3544          *   - the last operation was a write
3545          * or:
3546          *   -  opened for wronly
3547          *   -  no data was written
3548          */
3549         } else if ((un->un_pos.pmode != invalid) &&
3550             (un->un_fmneeded > 0) &&
3551             (((flag & FWRITE) &&
3552             ((un->un_lastop == ST_OP_WRITE)||(un->un_lastop == ST_OP_WEOF))) ||
3553             ((flag == FWRITE) && (un->un_lastop == ST_OP_NIL)))) {
3554 
3555                 /* save ST_EOM state */
3556                 int was_at_eom = (un->un_pos.eof == ST_EOM) ? 1 : 0;
3557 
3558                 /*
3559                  * Note that we will write a filemark if we had opened
3560                  * the tape write only and no data was written, thus
3561                  * creating a null file.
3562                  *
3563                  * If the user already wrote one, we only have to write 1 more.
3564                  * If they wrote two, we don't have to write any.
3565                  */
3566 
3567                 count = un->un_fmneeded;
3568                 if (count > 0) {
3569                         if (st_cmd(un, SCMD_WRITE_FILE_MARK, count, SYNC_CMD)) {
3570                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3571                                     "st_close : EIO can't wfm\n");
3572                                 err = EIO;
3573                                 goto error_out;
3574                         }
3575                         if ((un->un_dp->options & ST_REEL) &&
3576                             (minor & MT_NOREWIND)) {
3577                                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
3578                                         ST_DEBUG2(ST_DEVINFO, st_label,
3579                                             SCSI_DEBUG,
3580                                             "st_close : EIO space fmk(-1)\n");
3581                                         err = EIO;
3582                                         goto error_out;
3583                                 }
3584                                 un->un_pos.eof = ST_NO_EOF;
3585                                 /* fix up block number */
3586                                 un->un_pos.blkno = 0;
3587                         }
3588                 }
3589 
3590                 /*
3591                  * If we aren't going to be rewinding, and we were at
3592                  * physical eot, restore the state that indicates we
3593                  * are at physical eot. Once you have reached physical
3594                  * eot, and you close the tape, the only thing you can
3595                  * do on the next open is to rewind. Access to trailer
3596                  * records is only allowed without closing the device.
3597                  */
3598                 if ((minor & MT_NOREWIND) == 0 && was_at_eom) {
3599                         un->un_pos.eof = ST_EOM;
3600                 }
3601         }
3602 
3603         /*
3604          * report soft errors if enabled and available, if we never accessed
3605          * the drive, don't get errors. This will prevent some DAT error
3606          * messages upon LOG SENSE.
3607          */
3608         if (st_report_soft_errors_on_close &&
3609             (un->un_dp->options & ST_SOFT_ERROR_REPORTING) &&
3610             (last_state != ST_STATE_OFFLINE)) {
3611                 if (st_report_soft_errors(dev, flag)) {
3612                         err = EIO;
3613                         goto error_out;
3614                 }
3615         }
3616 
3617 
3618         /*
3619          * Do we need to rewind? Can we rewind?
3620          */
3621         if ((minor & MT_NOREWIND) == 0 &&
3622             un->un_pos.pmode != invalid && err == 0) {
3623                 /*
3624                  * We'd like to rewind with the
3625                  * 'immediate' bit set, but this
3626                  * causes problems on some drives
3627                  * where subsequent opens get a
3628                  * 'NOT READY' error condition
3629                  * back while the tape is rewinding,
3630                  * which is impossible to distinguish
3631                  * from the condition of 'no tape loaded'.
3632                  *
3633                  * Also, for some targets, if you disconnect
3634                  * with the 'immediate' bit set, you don't
3635                  * actually return right away, i.e., the
3636                  * target ignores your request for immediate
3637                  * return.
3638                  *
3639                  * Instead, we'll fire off an async rewind
3640                  * command. We'll mark the device as closed,
3641                  * and any subsequent open will stall on
3642                  * the first TEST_UNIT_READY until the rewind
3643                  * completes.
3644                  */
3645 
3646                 /*
3647                  * Used to be if reserve was not supported we'd send an
3648                  * asynchronious rewind. Comments above may be slightly invalid
3649                  * as the immediate bit was never set. Doing an immedate rewind
3650                  * makes sense, I think fixes to not ready status might handle
3651                  * the problems described above.
3652                  */
3653                 if (un->un_sd->sd_inq->inq_ansi < 2) {
3654                         if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
3655                                 err = EIO;
3656                         }
3657                 } else {
3658                         /* flush data for older drives per scsi spec. */
3659                         if (st_cmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD)) {
3660                                 err = EIO;
3661                         } else {
3662                                 /* release the drive before rewind immediate */
3663                                 if ((un->un_rsvd_status &
3664                                     (ST_RESERVE | ST_PRESERVE_RESERVE)) ==
3665                                     ST_RESERVE) {
3666                                         if (st_reserve_release(un, ST_RELEASE,
3667                                             st_uscsi_cmd)) {
3668                                                 err = EIO;
3669                                         }
3670                                 }
3671 
3672                                 /* send rewind with immediate bit set */
3673                                 if (st_cmd(un, SCMD_REWIND, 1, ASYNC_CMD)) {
3674                                         err = EIO;
3675                                 }
3676                         }
3677                 }
3678                 /*
3679                  * Setting positions invalid in case the rewind doesn't
3680                  * happen. Drives don't like to rewind if resets happen
3681                  * they will tend to move back to where the rewind was
3682                  * issued if a reset or something happens so that if a
3683                  * write happens the data doesn't get clobbered.
3684                  *
3685                  * Not a big deal if the position is invalid when the
3686                  * open occures it will do a read position.
3687                  */
3688                 un->un_pos.pmode = invalid;
3689                 un->un_running.pmode = invalid;
3690 
3691                 if (err == EIO) {
3692                         goto error_out;
3693                 }
3694         }
3695 
3696         /*
3697          * eject tape if necessary
3698          */
3699         if (un->un_eject_tape_on_failure) {
3700                 un->un_eject_tape_on_failure = 0;
3701                 if (st_cmd(un, SCMD_LOAD, LD_UNLOAD, SYNC_CMD)) {
3702                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3703                             "st_close : can't unload tape\n");
3704                         err = EIO;
3705                         goto error_out;
3706                 } else {
3707                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3708                             "st_close : tape unloaded \n");
3709                         un->un_pos.eof = ST_NO_EOF;
3710                         un->un_mediastate = MTIO_EJECTED;
3711                 }
3712         }
3713         /*
3714          * Release the tape unit, if default reserve/release
3715          * behaviour.
3716          */
3717         if ((un->un_rsvd_status &
3718             (ST_RESERVE | ST_PRESERVE_RESERVE |
3719             ST_APPLICATION_RESERVATIONS)) == ST_RESERVE) {
3720                 (void) st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
3721         }
3722 error_out:
3723         /*
3724          * clear up state
3725          */
3726         un->un_laststate = un->un_state;
3727         un->un_state = ST_STATE_CLOSED;
3728         un->un_lastop = ST_OP_NIL;
3729         un->un_throttle = 1; /* assume one request at time, for now */
3730         un->un_retry_ct = 0;
3731         un->un_errno = 0;
3732         un->un_swr_token = (opaque_t)NULL;
3733         un->un_rsvd_status &= ~(ST_INIT_RESERVE);
3734 
3735         /* Restore the options to the init time settings */
3736         if (un->un_init_options & ST_READ_IGNORE_ILI) {
3737                 un->un_dp->options |= ST_READ_IGNORE_ILI;
3738         } else {
3739                 un->un_dp->options &= ~ST_READ_IGNORE_ILI;
3740         }
3741 
3742         if (un->un_init_options & ST_READ_IGNORE_EOFS) {
3743                 un->un_dp->options |= ST_READ_IGNORE_EOFS;
3744         } else {
3745                 un->un_dp->options &= ~ST_READ_IGNORE_EOFS;
3746         }
3747 
3748         if (un->un_init_options & ST_SHORT_FILEMARKS) {
3749                 un->un_dp->options |= ST_SHORT_FILEMARKS;
3750         } else {
3751                 un->un_dp->options &= ~ST_SHORT_FILEMARKS;
3752         }
3753 
3754         ASSERT(mutex_owned(ST_MUTEX));
3755 
3756         /*
3757          * Signal anyone awaiting a close operation to complete.
3758          */
3759         cv_signal(&un->un_clscv);
3760 
3761         /*
3762          * any kind of error on closing causes all state to be tossed
3763          */
3764         if (err && un->un_status != KEY_ILLEGAL_REQUEST) {
3765                 /*
3766                  * note that st_intr has already set
3767                  * un_pos.pmode to invalid.
3768                  */
3769                 un->un_density_known = 0;
3770         }
3771 
3772 #ifdef  __x86
3773         /*
3774          * free any contiguous mem alloc'ed for big block I/O
3775          */
3776         cp = un->un_contig_mem;
3777         while (cp) {
3778                 if (cp->cm_addr) {
3779                         ddi_dma_mem_free(&cp->cm_acc_hdl);
3780                 }
3781                 cp_temp = cp;
3782                 cp = cp->cm_next;
3783                 kmem_free(cp_temp,
3784                     sizeof (struct contig_mem) + biosize());
3785         }
3786         un->un_contig_mem_total_num = 0;
3787         un->un_contig_mem_available_num = 0;
3788         un->un_contig_mem = NULL;
3789         un->un_max_contig_mem_len = 0;
3790 #endif
3791 
3792         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
3793             "st_close3: return val = %x, fileno=%x, blkno=%x, eof=%x\n",
3794             err, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
3795 
3796         mutex_exit(ST_MUTEX);
3797         return (err);
3798 }
3799 
3800 /*
3801  * These routines perform raw i/o operations.
3802  */
3803 
3804 /* ARGSUSED2 */
3805 static int
3806 st_aread(dev_t dev, struct aio_req *aio, cred_t *cred_p)
3807 {
3808 #ifdef STDEBUG
3809         GET_SOFT_STATE(dev);
3810         ST_ENTR(ST_DEVINFO, st_aread);
3811 #endif
3812         return (st_arw(dev, aio, B_READ));
3813 }
3814 
3815 
3816 /* ARGSUSED2 */
3817 static int
3818 st_awrite(dev_t dev, struct aio_req *aio, cred_t *cred_p)
3819 {
3820 #ifdef STDEBUG
3821         GET_SOFT_STATE(dev);
3822         ST_ENTR(ST_DEVINFO, st_awrite);
3823 #endif
3824         return (st_arw(dev, aio, B_WRITE));
3825 }
3826 
3827 
3828 
3829 /* ARGSUSED */
3830 static int
3831 st_read(dev_t dev, struct uio *uiop, cred_t *cred_p)
3832 {
3833 #ifdef STDEBUG
3834         GET_SOFT_STATE(dev);
3835         ST_ENTR(ST_DEVINFO, st_read);
3836 #endif
3837         return (st_rw(dev, uiop, B_READ));
3838 }
3839 
3840 /* ARGSUSED */
3841 static int
3842 st_write(dev_t dev, struct uio *uiop, cred_t *cred_p)
3843 {
3844 #ifdef STDEBUG
3845         GET_SOFT_STATE(dev);
3846         ST_ENTR(ST_DEVINFO, st_write);
3847 #endif
3848         return (st_rw(dev, uiop, B_WRITE));
3849 }
3850 
3851 /*
3852  * Due to historical reasons, old limits are: For variable-length devices:
3853  * if greater than 64KB - 1 (ST_MAXRECSIZE_VARIABLE), block into 64 KB - 2
3854  * ST_MAXRECSIZE_VARIABLE_LIMIT) requests; otherwise,
3855  * (let it through unmodified. For fixed-length record devices:
3856  * 63K (ST_MAXRECSIZE_FIXED) is max (default minphys).
3857  *
3858  * The new limits used are un_maxdma (retrieved using scsi_ifgetcap()
3859  * from the HBA) and un_maxbsize (retrieved by sending SCMD_READ_BLKLIM
3860  * command to the drive).
3861  *
3862  */
3863 static void
3864 st_minphys(struct buf *bp)
3865 {
3866         struct scsi_tape *un;
3867 
3868         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
3869 
3870         ST_FUNC(ST_DEVINFO, st_minphys);
3871 
3872         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3873             "st_minphys(bp = 0x%p): b_bcount = 0x%lx\n", (void *)bp,
3874             bp->b_bcount);
3875 
3876         if (un->un_allow_large_xfer) {
3877 
3878                 /*
3879                  * check un_maxbsize for variable length devices only
3880                  */
3881                 if (un->un_bsize == 0 && bp->b_bcount > un->un_maxbsize) {
3882                         bp->b_bcount = un->un_maxbsize;
3883                 }
3884                 /*
3885                  * can't go more that HBA maxdma limit in either fixed-length
3886                  * or variable-length tape drives.
3887                  */
3888                 if (bp->b_bcount > un->un_maxdma) {
3889                         bp->b_bcount = un->un_maxdma;
3890                 }
3891         } else {
3892 
3893                 /*
3894                  *  use old fixed limits
3895                  */
3896                 if (un->un_bsize == 0) {
3897                         if (bp->b_bcount > ST_MAXRECSIZE_VARIABLE) {
3898                                 bp->b_bcount = ST_MAXRECSIZE_VARIABLE_LIMIT;
3899                         }
3900                 } else {
3901                         if (bp->b_bcount > ST_MAXRECSIZE_FIXED) {
3902                                 bp->b_bcount = ST_MAXRECSIZE_FIXED;
3903                         }
3904                 }
3905         }
3906 
3907         /*
3908          * For regular raw I/O and Fixed Block length devices, make sure
3909          * the adjusted block count is a whole multiple of the device
3910          * block size.
3911          */
3912         if (bp != un->un_sbufp && un->un_bsize) {
3913                 bp->b_bcount -= (bp->b_bcount % un->un_bsize);
3914         }
3915 }
3916 
3917 static int
3918 st_rw(dev_t dev, struct uio *uio, int flag)
3919 {
3920         int rval = 0;
3921         long len;
3922 
3923         GET_SOFT_STATE(dev);
3924 
3925         ST_FUNC(ST_DEVINFO, st_rw);
3926 
3927         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3928             "st_rw(dev = 0x%lx, flag = %s)\n", dev,
3929             (flag == B_READ ? rd_str: wr_str));
3930 
3931         /* get local copy of transfer length */
3932         len = uio->uio_iov->iov_len;
3933 
3934         mutex_enter(ST_MUTEX);
3935 
3936         /*
3937          * Clear error entry stack
3938          */
3939         st_empty_error_stack(un);
3940 
3941         /*
3942          * If in fixed block size mode and requested read or write
3943          * is not an even multiple of that block size.
3944          */
3945         if ((un->un_bsize != 0) && (len % un->un_bsize != 0)) {
3946                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
3947                     "%s: not modulo %d block size\n",
3948                     (flag == B_WRITE) ? wr_str : rd_str, un->un_bsize);
3949                 rval = EINVAL;
3950         }
3951 
3952         /* If device has set granularity in the READ_BLKLIM we honor it. */
3953         if ((un->un_data_mod != 0) && (len % un->un_data_mod != 0)) {
3954                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
3955                     "%s: not modulo %d device granularity\n",
3956                     (flag == B_WRITE) ? wr_str : rd_str, un->un_data_mod);
3957                 rval = EINVAL;
3958         }
3959 
3960         if (st_recov_sz != sizeof (recov_info) && un->un_multipath) {
3961                 scsi_log(ST_DEVINFO, st_label, CE_WARN, mp_misconf);
3962                 rval = EFAULT;
3963         }
3964 
3965         if (rval != 0) {
3966                 un->un_errno = rval;
3967                 mutex_exit(ST_MUTEX);
3968                 return (rval);
3969         }
3970 
3971         /*
3972          * Reset this so it can be set if Berkeley and read over a filemark.
3973          */
3974         un->un_silent_skip = 0;
3975         mutex_exit(ST_MUTEX);
3976 
3977         len = uio->uio_resid;
3978 
3979         rval = physio(st_queued_strategy, (struct buf *)NULL,
3980             dev, flag, st_minphys, uio);
3981         /*
3982          * if we have hit logical EOT during this xfer and there is not a
3983          * full residue, then set eof back  to ST_EOM to make sure that
3984          * the user will see at least one zero write
3985          * after this short write
3986          */
3987         mutex_enter(ST_MUTEX);
3988         if (un->un_pos.eof > ST_NO_EOF) {
3989                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3990                 "eof=%d resid=%lx\n", un->un_pos.eof, uio->uio_resid);
3991         }
3992         if (un->un_pos.eof >= ST_EOM && (flag == B_WRITE)) {
3993                 if ((uio->uio_resid != len) && (uio->uio_resid != 0)) {
3994                         un->un_pos.eof = ST_EOM;
3995                 } else if (uio->uio_resid == len) {
3996                         un->un_pos.eof = ST_NO_EOF;
3997                 }
3998         }
3999 
4000         if (un->un_silent_skip && uio->uio_resid != len) {
4001                 un->un_pos.eof = ST_EOF;
4002                 un->un_pos.blkno = un->un_save_blkno;
4003                 un->un_pos.fileno--;
4004         }
4005 
4006         un->un_errno = rval;
4007 
4008         mutex_exit(ST_MUTEX);
4009 
4010         return (rval);
4011 }
4012 
4013 static int
4014 st_arw(dev_t dev, struct aio_req *aio, int flag)
4015 {
4016         struct uio *uio = aio->aio_uio;
4017         int rval = 0;
4018         long len;
4019 
4020         GET_SOFT_STATE(dev);
4021 
4022         ST_FUNC(ST_DEVINFO, st_arw);
4023 
4024         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4025             "st_arw(dev = 0x%lx, flag = %s)\n", dev,
4026             (flag == B_READ ? rd_str: wr_str));
4027 
4028         /* get local copy of transfer length */
4029         len = uio->uio_iov->iov_len;
4030 
4031         mutex_enter(ST_MUTEX);
4032 
4033         /*
4034          * If in fixed block size mode and requested read or write
4035          * is not an even multiple of that block size.
4036          */
4037         if ((un->un_bsize != 0) && (len % un->un_bsize != 0)) {
4038                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
4039                     "%s: not modulo %d block size\n",
4040                     (flag == B_WRITE) ? wr_str : rd_str, un->un_bsize);
4041                 rval = EINVAL;
4042         }
4043 
4044         /* If device has set granularity in the READ_BLKLIM we honor it. */
4045         if ((un->un_data_mod != 0) && (len % un->un_data_mod != 0)) {
4046                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
4047                     "%s: not modulo %d device granularity\n",
4048                     (flag == B_WRITE) ? wr_str : rd_str, un->un_data_mod);
4049                 rval = EINVAL;
4050         }
4051 
4052         if (st_recov_sz != sizeof (recov_info) && un->un_multipath) {
4053                 scsi_log(ST_DEVINFO, st_label, CE_WARN, mp_misconf);
4054                 rval = EFAULT;
4055         }
4056 
4057         if (rval != 0) {
4058                 un->un_errno = rval;
4059                 mutex_exit(ST_MUTEX);
4060                 return (rval);
4061         }
4062 
4063         mutex_exit(ST_MUTEX);
4064 
4065         len = uio->uio_resid;
4066 
4067         rval =
4068             aphysio(st_queued_strategy, anocancel, dev, flag, st_minphys, aio);
4069 
4070         /*
4071          * if we have hit logical EOT during this xfer and there is not a
4072          * full residue, then set eof back  to ST_EOM to make sure that
4073          * the user will see at least one zero write
4074          * after this short write
4075          *
4076          * we keep this here just in case the application is not using
4077          * persistent errors
4078          */
4079         mutex_enter(ST_MUTEX);
4080         if (un->un_pos.eof > ST_NO_EOF) {
4081                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4082                     "eof=%d resid=%lx\n", un->un_pos.eof, uio->uio_resid);
4083         }
4084         if (un->un_pos.eof >= ST_EOM && (flag == B_WRITE)) {
4085                 if ((uio->uio_resid != len) && (uio->uio_resid != 0)) {
4086                         un->un_pos.eof = ST_EOM;
4087                 } else if (uio->uio_resid == len &&
4088                     !(un->un_persistence && un->un_persist_errors)) {
4089                         un->un_pos.eof = ST_NO_EOF;
4090                 }
4091         }
4092         un->un_errno = rval;
4093         mutex_exit(ST_MUTEX);
4094 
4095         return (rval);
4096 }
4097 
4098 
4099 
4100 static int
4101 st_queued_strategy(buf_t *bp)
4102 {
4103         struct scsi_tape *un;
4104         char reading = bp->b_flags & B_READ;
4105         int wasopening = 0;
4106 
4107         /*
4108          * validate arguments
4109          */
4110         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
4111         if (un == NULL) {
4112                 bp->b_resid = bp->b_bcount;
4113                 bioerror(bp, ENXIO);
4114                 ST_DEBUG6(NULL, st_label, SCSI_DEBUG,
4115                     "st_queued_strategy: ENXIO error exit\n");
4116                 biodone(bp);
4117                 return (0);
4118         }
4119 
4120         ST_ENTR(ST_DEVINFO, st_queued_strategy);
4121 
4122         mutex_enter(ST_MUTEX);
4123 
4124         while (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
4125                 cv_wait(&un->un_suspend_cv, ST_MUTEX);
4126         }
4127 
4128         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4129             "st_queued_strategy(): bcount=0x%lx, fileno=%d, blkno=%x, eof=%d\n",
4130             bp->b_bcount, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
4131 
4132         /*
4133          * If persistent errors have been flagged, just nix this one. We wait
4134          * for any outstanding I/O's below, so we will be in order.
4135          */
4136         if (un->un_persistence && un->un_persist_errors) {
4137                 goto exit;
4138         }
4139 
4140         /*
4141          * If last command was non queued, wait till it finishes.
4142          */
4143         while (un->un_sbuf_busy) {
4144                 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
4145                 /* woke up because of an error */
4146                 if (un->un_persistence && un->un_persist_errors) {
4147                         goto exit;
4148                 }
4149         }
4150 
4151         /*
4152          * s_buf and recovery commands shouldn't come here.
4153          */
4154         ASSERT(bp != un->un_recov_buf);
4155         ASSERT(bp != un->un_sbufp);
4156 
4157         /*
4158          * If we haven't done/checked reservation on the tape unit
4159          * do it now.
4160          */
4161         if ((un->un_rsvd_status &
4162             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
4163                 if ((un->un_dp->options & ST_NO_RESERVE_RELEASE) == 0) {
4164                         if (st_reserve_release(un, ST_RESERVE, st_uscsi_cmd)) {
4165                                 st_bioerror(bp, un->un_errno);
4166                                 goto exit;
4167                         }
4168                 } else if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4169                         /*
4170                          * Enter here to restore position for possible
4171                          * resets when the device was closed and opened
4172                          * in O_NDELAY mode subsequently
4173                          */
4174                         un->un_state = ST_STATE_INITIALIZING;
4175                         (void) st_cmd(un, SCMD_TEST_UNIT_READY,
4176                             0, SYNC_CMD);
4177                         un->un_state = ST_STATE_OPEN_PENDING_IO;
4178                 }
4179                 un->un_rsvd_status |= ST_INIT_RESERVE;
4180         }
4181 
4182         /*
4183          * If we are offline, we have to initialize everything first.
4184          * This is to handle either when opened with O_NDELAY, or
4185          * we just got a new tape in the drive, after an offline.
4186          * We don't observe O_NDELAY past the open,
4187          * as it will not make sense for tapes.
4188          */
4189         if (un->un_state == ST_STATE_OFFLINE || un->un_restore_pos) {
4190                 /*
4191                  * reset state to avoid recursion
4192                  */
4193                 un->un_laststate = un->un_state;
4194                 un->un_state = ST_STATE_INITIALIZING;
4195                 if (st_tape_init(un)) {
4196                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4197                             "stioctl : OFFLINE init failure ");
4198                         un->un_state = ST_STATE_OFFLINE;
4199                         un->un_pos.pmode = invalid;
4200                         goto b_done_err;
4201                 }
4202                 /* un_restore_pos make invalid */
4203                 un->un_state = ST_STATE_OPEN_PENDING_IO;
4204                 un->un_restore_pos = 0;
4205         }
4206         /*
4207          * Check for legal operations
4208          */
4209         if (un->un_pos.pmode == invalid) {
4210                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4211                     "strategy with un->un_pos.pmode invalid\n");
4212                 goto b_done_err;
4213         }
4214 
4215         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4216             "st_queued_strategy(): regular io\n");
4217 
4218         /*
4219          * Process this first. If we were reading, and we're pending
4220          * logical eot, that means we've bumped one file mark too far.
4221          */
4222 
4223         /*
4224          * Recursion warning: st_cmd will route back through here.
4225          * Not anymore st_cmd will go through st_strategy()!
4226          */
4227         if (un->un_pos.eof == ST_EOT_PENDING) {
4228                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
4229                         un->un_pos.pmode = invalid;
4230                         un->un_density_known = 0;
4231                         goto b_done_err;
4232                 }
4233                 un->un_pos.blkno = 0; /* fix up block number.. */
4234                 un->un_pos.eof = ST_EOT;
4235         }
4236 
4237         /*
4238          * If we are in the process of opening, we may have to
4239          * determine/set the correct density. We also may have
4240          * to do a test_append (if QIC) to see whether we are
4241          * in a position to append to the end of the tape.
4242          *
4243          * If we're already at logical eot, we transition
4244          * to ST_NO_EOF. If we're at physical eot, we punt
4245          * to the switch statement below to handle.
4246          */
4247         if ((un->un_state == ST_STATE_OPEN_PENDING_IO) ||
4248             (un->un_test_append && (un->un_dp->options & ST_QIC))) {
4249 
4250                 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4251                         if (st_determine_density(un, (int)reading)) {
4252                                 goto b_done_err;
4253                         }
4254                 }
4255 
4256                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4257                     "pending_io@fileno %d rw %d qic %d eof %d\n",
4258                     un->un_pos.fileno, (int)reading,
4259                     (un->un_dp->options & ST_QIC) ? 1 : 0,
4260                     un->un_pos.eof);
4261 
4262                 if (!reading && un->un_pos.eof != ST_EOM) {
4263                         if (un->un_pos.eof == ST_EOT) {
4264                                 un->un_pos.eof = ST_NO_EOF;
4265                         } else if (un->un_pos.pmode != invalid &&
4266                             (un->un_dp->options & ST_QIC)) {
4267                                 /*
4268                                  * st_test_append() will do it all
4269                                  */
4270                                 st_test_append(bp);
4271                                 mutex_exit(ST_MUTEX);
4272                                 return (0);
4273                         }
4274                 }
4275                 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4276                         wasopening = 1;
4277                 }
4278                 un->un_laststate = un->un_state;
4279                 un->un_state = ST_STATE_OPEN;
4280         }
4281 
4282 
4283         /*
4284          * Process rest of END OF FILE and END OF TAPE conditions
4285          */
4286 
4287         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4288             "eof=%x, wasopening=%x\n",
4289             un->un_pos.eof, wasopening);
4290 
4291         switch (un->un_pos.eof) {
4292         case ST_EOM:
4293                 /*
4294                  * This allows writes to proceed past physical
4295                  * eot. We'll *really* be in trouble if the
4296                  * user continues blindly writing data too
4297                  * much past this point (unwind the tape).
4298                  * Physical eot really means 'early warning
4299                  * eot' in this context.
4300                  *
4301                  * Every other write from now on will succeed
4302                  * (if sufficient  tape left).
4303                  * This write will return with resid == count
4304                  * but the next one should be successful
4305                  *
4306                  * Note that we only transition to logical EOT
4307                  * if the last state wasn't the OPENING state.
4308                  * We explicitly prohibit running up to physical
4309                  * eot, closing the device, and then re-opening
4310                  * to proceed. Trailer records may only be gotten
4311                  * at by keeping the tape open after hitting eot.
4312                  *
4313                  * Also note that ST_EOM cannot be set by reading-
4314                  * this can only be set during writing. Reading
4315                  * up to the end of the tape gets a blank check
4316                  * or a double-filemark indication (ST_EOT_PENDING),
4317                  * and we prohibit reading after that point.
4318                  *
4319                  */
4320                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOM\n");
4321                 if (wasopening == 0) {
4322                         /*
4323                          * this allows st_rw() to reset it back to
4324                          * will see a zero write
4325                          */
4326                         un->un_pos.eof = ST_WRITE_AFTER_EOM;
4327                 }
4328                 un->un_status = SUN_KEY_EOT;
4329                 goto b_done;
4330 
4331         case ST_WRITE_AFTER_EOM:
4332         case ST_EOT:
4333                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOT\n");
4334                 un->un_status = SUN_KEY_EOT;
4335                 if (SVR4_BEHAVIOR && reading) {
4336                         goto b_done_err;
4337                 }
4338 
4339                 if (reading) {
4340                         goto b_done;
4341                 }
4342                 un->un_pos.eof = ST_NO_EOF;
4343                 break;
4344 
4345         case ST_EOF_PENDING:
4346                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4347                     "EOF PENDING\n");
4348                 un->un_status = SUN_KEY_EOF;
4349                 if (SVR4_BEHAVIOR) {
4350                         un->un_pos.eof = ST_EOF;
4351                         goto b_done;
4352                 }
4353                 /* FALLTHROUGH */
4354         case ST_EOF:
4355                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOF\n");
4356                 un->un_status = SUN_KEY_EOF;
4357                 if (SVR4_BEHAVIOR) {
4358                         goto b_done_err;
4359                 }
4360 
4361                 if (BSD_BEHAVIOR) {
4362                         un->un_pos.eof = ST_NO_EOF;
4363                         un->un_pos.fileno += 1;
4364                         un->un_pos.blkno   = 0;
4365                 }
4366 
4367                 if (reading) {
4368                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4369                             "now file %d (read)\n",
4370                             un->un_pos.fileno);
4371                         goto b_done;
4372                 }
4373                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4374                     "now file %d (write)\n", un->un_pos.fileno);
4375                 break;
4376         default:
4377                 un->un_status = 0;
4378                 break;
4379         }
4380 
4381         bp->b_flags &= ~(B_DONE);
4382         st_bioerror(bp, 0);
4383         bp->av_forw = NULL;
4384         bp->b_resid = 0;
4385         SET_BP_PKT(bp, 0);
4386 
4387 
4388         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4389             "st_queued_strategy: cmd=0x%p  count=%ld  resid=%ld flags=0x%x"
4390             " pkt=0x%p\n",
4391             (void *)bp->b_forw, bp->b_bcount,
4392             bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
4393 
4394 #ifdef  __x86
4395         /*
4396          * We will replace bp with a new bp that can do big blk xfer
4397          * if the requested xfer size is bigger than un->un_maxdma_arch
4398          *
4399          * Also, we need to make sure that we're handling real I/O
4400          * by checking group 0/1 SCSI I/O commands, if needed
4401          */
4402         if (bp->b_bcount > un->un_maxdma_arch &&
4403             ((uchar_t)(uintptr_t)bp->b_forw == SCMD_READ ||
4404             (uchar_t)(uintptr_t)bp->b_forw == SCMD_READ_G4 ||
4405             (uchar_t)(uintptr_t)bp->b_forw == SCMD_WRITE ||
4406             (uchar_t)(uintptr_t)bp->b_forw == SCMD_WRITE_G4)) {
4407                 mutex_exit(ST_MUTEX);
4408                 bp = st_get_bigblk_bp(bp);
4409                 mutex_enter(ST_MUTEX);
4410         }
4411 #endif
4412 
4413         /* put on wait queue */
4414         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4415             "st_queued_strategy: un->un_quef = 0x%p, bp = 0x%p\n",
4416             (void *)un->un_quef, (void *)bp);
4417 
4418         st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quel, bp);
4419 
4420         ST_DO_KSTATS(bp, kstat_waitq_enter);
4421 
4422         st_start(un);
4423 
4424         mutex_exit(ST_MUTEX);
4425         return (0);
4426 
4427 b_done_err:
4428         st_bioerror(bp, EIO);
4429         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4430             "st_queued_strategy : EIO b_done_err\n");
4431 
4432 b_done:
4433         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4434             "st_queued_strategy: b_done\n");
4435 
4436 exit:
4437         /*
4438          * make sure no commands are outstanding or waiting before closing,
4439          * so we can guarantee order
4440          */
4441         st_wait_for_io(un);
4442         un->un_err_resid = bp->b_resid = bp->b_bcount;
4443 
4444         /* override errno here, if persistent errors were flagged */
4445         if (un->un_persistence && un->un_persist_errors)
4446                 bioerror(bp, un->un_errno);
4447 
4448         mutex_exit(ST_MUTEX);
4449 
4450         biodone(bp);
4451         ASSERT(mutex_owned(ST_MUTEX) == 0);
4452         return (0);
4453 }
4454 
4455 
4456 static int
4457 st_strategy(struct buf *bp)
4458 {
4459         struct scsi_tape *un;
4460 
4461         /*
4462          * validate arguments
4463          */
4464         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
4465         if (un == NULL) {
4466                 bp->b_resid = bp->b_bcount;
4467                 bioerror(bp, ENXIO);
4468                 ST_DEBUG6(NULL, st_label, SCSI_DEBUG,
4469                     "st_strategy: ENXIO error exit\n");
4470 
4471                 biodone(bp);
4472                 return (0);
4473 
4474         }
4475 
4476         ST_ENTR(ST_DEVINFO, st_strategy);
4477 
4478         mutex_enter(ST_MUTEX);
4479 
4480         while (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
4481                 cv_wait(&un->un_suspend_cv, ST_MUTEX);
4482         }
4483 
4484         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4485             "st_strategy(): bcount=0x%lx, fileno=%d, blkno=%x, eof=%d\n",
4486             bp->b_bcount, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
4487 
4488         ASSERT((bp == un->un_recov_buf) || (bp == un->un_sbufp));
4489 
4490         bp->b_flags &= ~(B_DONE);
4491         st_bioerror(bp, 0);
4492         bp->av_forw = NULL;
4493         bp->b_resid = 0;
4494         SET_BP_PKT(bp, 0);
4495 
4496 
4497         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4498             "st_strategy: cmd=0x%x  count=%ld  resid=%ld flags=0x%x"
4499             " pkt=0x%p\n",
4500             (unsigned char)(uintptr_t)bp->b_forw, bp->b_bcount,
4501             bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
4502         ST_DO_KSTATS(bp, kstat_waitq_enter);
4503 
4504         st_start(un);
4505 
4506         mutex_exit(ST_MUTEX);
4507         return (0);
4508 }
4509 
4510 /*
4511  * this routine spaces forward over filemarks
4512  */
4513 static int
4514 st_space_fmks(struct scsi_tape *un, int64_t count)
4515 {
4516         int rval = 0;
4517 
4518         ST_FUNC(ST_DEVINFO, st_space_fmks);
4519 
4520         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4521             "st_space_fmks(dev = 0x%lx, count = %"PRIx64")\n",
4522             un->un_dev, count);
4523 
4524         ASSERT(mutex_owned(ST_MUTEX));
4525 
4526         /*
4527          * the risk with doing only one space operation is that we
4528          * may accidentily jump in old data
4529          * the exabyte 8500 reading 8200 tapes cannot use KNOWS_EOD
4530          * because the 8200 does not append a marker; in order not to
4531          * sacrifice the fast file skip, we do a slow skip if the low
4532          * density device has been opened
4533          */
4534 
4535         if ((un->un_dp->options & ST_KNOWS_EOD) &&
4536             !((un->un_dp->type == ST_TYPE_EXB8500 &&
4537             MT_DENSITY(un->un_dev) == 0))) {
4538                 if (st_cmd(un, SCMD_SPACE, Fmk(count), SYNC_CMD)) {
4539                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4540                             "space_fmks : EIO can't do space cmd #1\n");
4541                         rval = EIO;
4542                 }
4543         } else {
4544                 while (count > 0) {
4545                         if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
4546                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4547                                     "space_fmks : EIO can't do space cmd #2\n");
4548                                 rval = EIO;
4549                                 break;
4550                         }
4551                         count -= 1;
4552                         /*
4553                          * read a block to see if we have reached
4554                          * end of medium (double filemark for reel or
4555                          * medium error for others)
4556                          */
4557                         if (count > 0) {
4558                                 if (st_cmd(un, SCMD_SPACE, Blk(1), SYNC_CMD)) {
4559                                         ST_DEBUG2(ST_DEVINFO, st_label,
4560                                             SCSI_DEBUG,
4561                                             "space_fmks : EIO can't do "
4562                                             "space cmd #3\n");
4563                                         rval = EIO;
4564                                         break;
4565                                 }
4566                                 if ((un->un_pos.eof >= ST_EOF_PENDING) &&
4567                                     (un->un_dp->options & ST_REEL)) {
4568                                         un->un_status = SUN_KEY_EOT;
4569                                         ST_DEBUG2(ST_DEVINFO, st_label,
4570                                             SCSI_DEBUG,
4571                                             "space_fmks : EIO ST_REEL\n");
4572                                         rval = EIO;
4573                                         break;
4574                                 } else if (IN_EOF(un->un_pos)) {
4575                                         un->un_pos.eof = ST_NO_EOF;
4576                                         un->un_pos.fileno++;
4577                                         un->un_pos.blkno = 0;
4578                                         count--;
4579                                 } else if (un->un_pos.eof > ST_EOF) {
4580                                         ST_DEBUG2(ST_DEVINFO, st_label,
4581                                             SCSI_DEBUG,
4582                                             "space_fmks, EIO > ST_EOF\n");
4583                                         rval = EIO;
4584                                         break;
4585                                 }
4586 
4587                         }
4588                 }
4589                 un->un_err_resid = count;
4590                 COPY_POS(&un->un_pos, &un->un_err_pos);
4591         }
4592         ASSERT(mutex_owned(ST_MUTEX));
4593         return (rval);
4594 }
4595 
4596 /*
4597  * this routine spaces to EOD
4598  *
4599  * it keeps track of the current filenumber and returns the filenumber after
4600  * the last successful space operation, we keep the number high because as
4601  * tapes are getting larger, the possibility of more and more files exist,
4602  * 0x100000 (1 Meg of files) probably will never have to be changed any time
4603  * soon
4604  */
4605 #define MAX_SKIP        0x100000 /* somewhat arbitrary */
4606 
4607 static int
4608 st_find_eod(struct scsi_tape *un)
4609 {
4610         tapepos_t savepos;
4611         int64_t sp_type;
4612         int result;
4613 
4614         if (un == NULL) {
4615                 return (-1);
4616         }
4617 
4618         ST_FUNC(ST_DEVINFO, st_find_eod);
4619 
4620         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4621             "st_find_eod(dev = 0x%lx): fileno = %d\n", un->un_dev,
4622             un->un_pos.fileno);
4623 
4624         ASSERT(mutex_owned(ST_MUTEX));
4625 
4626         COPY_POS(&savepos, &un->un_pos);
4627 
4628         /*
4629          * see if the drive is smart enough to do the skips in
4630          * one operation; 1/2" use two filemarks
4631          * the exabyte 8500 reading 8200 tapes cannot use KNOWS_EOD
4632          * because the 8200 does not append a marker; in order not to
4633          * sacrifice the fast file skip, we do a slow skip if the low
4634          * density device has been opened
4635          */
4636         if ((un->un_dp->options & ST_KNOWS_EOD) != 0) {
4637                 if ((un->un_dp->type == ST_TYPE_EXB8500) &&
4638                     (MT_DENSITY(un->un_dev) == 0)) {
4639                         sp_type = Fmk(1);
4640                 } else if (un->un_pos.pmode == logical) {
4641                         sp_type = SPACE(SP_EOD, 0);
4642                 } else {
4643                         sp_type = Fmk(MAX_SKIP);
4644                 }
4645         } else {
4646                 sp_type = Fmk(1);
4647         }
4648 
4649         for (;;) {
4650                 result = st_cmd(un, SCMD_SPACE, sp_type, SYNC_CMD);
4651 
4652                 if (result == 0) {
4653                         COPY_POS(&savepos, &un->un_pos);
4654                 }
4655 
4656                 if (sp_type == SPACE(SP_EOD, 0)) {
4657                         if (result != 0) {
4658                                 sp_type = Fmk(MAX_SKIP);
4659                                 continue;
4660                         }
4661 
4662                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4663                             "st_find_eod: 0x%"PRIx64"\n",
4664                             savepos.lgclblkno);
4665                         /*
4666                          * What we return will become the current file position.
4667                          * After completing the space command with the position
4668                          * mode that is not invalid a read position command will
4669                          * be automaticly issued. If the drive support the long
4670                          * read position format a valid file position can be
4671                          * returned.
4672                          */
4673                         return (un->un_pos.fileno);
4674                 }
4675 
4676                 if (result != 0) {
4677                         break;
4678                 }
4679 
4680                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4681                     "count=%"PRIx64", eof=%x, status=%x\n",
4682                     SPACE_CNT(sp_type),  un->un_pos.eof, un->un_status);
4683 
4684                 /*
4685                  * If we're not EOM smart,  space a record
4686                  * to see whether we're now in the slot between
4687                  * the two sequential filemarks that logical
4688                  * EOM consists of (REEL) or hit nowhere land
4689                  * (8mm).
4690                  */
4691                 if (sp_type == Fmk(1)) {
4692                         /*
4693                          * no fast skipping, check a record
4694                          */
4695                         if (st_cmd(un, SCMD_SPACE, Blk((1)), SYNC_CMD)) {
4696                                 break;
4697                         }
4698                         if ((un->un_pos.eof >= ST_EOF_PENDING) &&
4699                             (un->un_dp->options & ST_REEL)) {
4700                                 un->un_status = KEY_BLANK_CHECK;
4701                                 un->un_pos.fileno++;
4702                                 un->un_pos.blkno = 0;
4703                                 break;
4704                         }
4705                         if (IN_EOF(un->un_pos)) {
4706                                 un->un_pos.eof = ST_NO_EOF;
4707                                 un->un_pos.fileno++;
4708                                 un->un_pos.blkno = 0;
4709                         }
4710                         if (un->un_pos.eof > ST_EOF) {
4711                                 break;
4712                         }
4713                 } else {
4714                         if (un->un_pos.eof > ST_EOF) {
4715                                 break;
4716                         }
4717                 }
4718         }
4719 
4720         if (un->un_dp->options & ST_KNOWS_EOD) {
4721                 COPY_POS(&savepos, &un->un_pos);
4722         }
4723 
4724         ASSERT(mutex_owned(ST_MUTEX));
4725 
4726         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4727             "st_find_eod: %x\n", savepos.fileno);
4728         return (savepos.fileno);
4729 }
4730 
4731 
4732 /*
4733  * this routine is frequently used in ioctls below;
4734  * it determines whether we know the density and if not will
4735  * determine it
4736  * if we have written the tape before, one or more filemarks are written
4737  *
4738  * depending on the stepflag, the head is repositioned to where it was before
4739  * the filemarks were written in order not to confuse step counts
4740  */
4741 #define STEPBACK    0
4742 #define NO_STEPBACK 1
4743 
4744 static int
4745 st_check_density_or_wfm(dev_t dev, int wfm, int mode, int stepflag)
4746 {
4747 
4748         GET_SOFT_STATE(dev);
4749 
4750         ST_FUNC(ST_DEVINFO, st_check_density_or_wfm);
4751 
4752         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4753             "st_check_density_or_wfm(dev= 0x%lx, wfm= %d, mode= %d, stpflg= %d)"
4754             "\n", dev, wfm, mode, stepflag);
4755 
4756         ASSERT(mutex_owned(ST_MUTEX));
4757 
4758         /*
4759          * If we don't yet know the density of the tape we have inserted,
4760          * we have to either unconditionally set it (if we're 'writing'),
4761          * or we have to determine it. As side effects, check for any
4762          * write-protect errors, and for the need to put out any file-marks
4763          * before positioning a tape.
4764          *
4765          * If we are going to be spacing forward, and we haven't determined
4766          * the tape density yet, we have to do so now...
4767          */
4768         if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4769                 if (st_determine_density(un, mode)) {
4770                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4771                             "check_density_or_wfm : EIO can't determine "
4772                             "density\n");
4773                         un->un_errno = EIO;
4774                         return (EIO);
4775                 }
4776                 /*
4777                  * Presumably we are at BOT. If we attempt to write, it will
4778                  * either work okay, or bomb. We don't do a st_test_append
4779                  * unless we're past BOT.
4780                  */
4781                 un->un_laststate = un->un_state;
4782                 un->un_state = ST_STATE_OPEN;
4783 
4784         } else if (un->un_pos.pmode != invalid && un->un_fmneeded > 0 &&
4785             ((un->un_lastop == ST_OP_WEOF && wfm) ||
4786             (un->un_lastop == ST_OP_WRITE && wfm))) {
4787 
4788                 tapepos_t spos;
4789 
4790                 COPY_POS(&spos, &un->un_pos);
4791 
4792                 /*
4793                  * We need to write one or two filemarks.
4794                  * In the case of the HP, we need to
4795                  * position the head between the two
4796                  * marks.
4797                  */
4798                 if ((un->un_fmneeded > 0) || (un->un_lastop == ST_OP_WEOF)) {
4799                         wfm = un->un_fmneeded;
4800                         un->un_fmneeded = 0;
4801                 }
4802 
4803                 if (st_write_fm(dev, wfm)) {
4804                         un->un_pos.pmode = invalid;
4805                         un->un_density_known = 0;
4806                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4807                             "check_density_or_wfm : EIO can't write fm\n");
4808                         un->un_errno = EIO;
4809                         return (EIO);
4810                 }
4811 
4812                 if (stepflag == STEPBACK) {
4813                         if (st_cmd(un, SCMD_SPACE, Fmk(-wfm), SYNC_CMD)) {
4814                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4815                                     "check_density_or_wfm : EIO can't space "
4816                                     "(-wfm)\n");
4817                                 un->un_errno = EIO;
4818                                 return (EIO);
4819                         }
4820                         COPY_POS(&un->un_pos, &spos);
4821                 }
4822         }
4823 
4824         /*
4825          * Whatever we do at this point clears the state of the eof flag.
4826          */
4827 
4828         un->un_pos.eof = ST_NO_EOF;
4829 
4830         /*
4831          * If writing, let's check that we're positioned correctly
4832          * at the end of tape before issuing the next write.
4833          */
4834         if (un->un_read_only == RDWR) {
4835                 un->un_test_append = 1;
4836         }
4837 
4838         ASSERT(mutex_owned(ST_MUTEX));
4839         return (0);
4840 }
4841 
4842 
4843 /*
4844  * Wait for all outstaning I/O's to complete
4845  *
4846  * we wait on both ncmds and the wait queue for times when we are flushing
4847  * after persistent errors are flagged, which is when ncmds can be 0, and the
4848  * queue can still have I/O's.  This way we preserve order of biodone's.
4849  */
4850 static void
4851 st_wait_for_io(struct scsi_tape *un)
4852 {
4853         ST_FUNC(ST_DEVINFO, st_wait_for_io);
4854         ASSERT(mutex_owned(ST_MUTEX));
4855         while ((un->un_ncmds) || (un->un_quef) || (un->un_runqf)) {
4856                 cv_wait(&un->un_queue_cv, ST_MUTEX);
4857         }
4858 }
4859 
4860 /*
4861  * This routine implements the ioctl calls.  It is called
4862  * from the device switch at normal priority.
4863  */
4864 /*ARGSUSED*/
4865 static int
4866 st_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p,
4867     int *rval_p)
4868 {
4869         int tmp, rval = 0;
4870 
4871         GET_SOFT_STATE(dev);
4872 
4873         ST_ENTR(ST_DEVINFO, st_ioctl);
4874 
4875         mutex_enter(ST_MUTEX);
4876 
4877         ASSERT(un->un_recov_buf_busy == 0);
4878 
4879         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4880             "st_ioctl(): fileno=%x, blkno=%x, eof=%x, state = %d, "
4881             "pe_flag = %d\n",
4882             un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof, un->un_state,
4883             un->un_persistence && un->un_persist_errors);
4884 
4885         /*
4886          * We don't want to block on these, so let them through
4887          * and we don't care about setting driver states here.
4888          */
4889         if ((cmd == MTIOCGETDRIVETYPE) ||
4890             (cmd == MTIOCGUARANTEEDORDER) ||
4891             (cmd == MTIOCPERSISTENTSTATUS)) {
4892                 goto check_commands;
4893         }
4894 
4895         /*
4896          * We clear error entry stack except command
4897          * MTIOCGETERROR and MTIOCGET
4898          */
4899         if ((cmd != MTIOCGETERROR) &&
4900             (cmd != MTIOCGET)) {
4901                 st_empty_error_stack(un);
4902         }
4903 
4904         /*
4905          * wait for all outstanding commands to complete, or be dequeued.
4906          * And because ioctl's are synchronous commands, any return value
4907          * after this,  will be in order
4908          */
4909         st_wait_for_io(un);
4910 
4911         /*
4912          * allow only a through clear errors and persistent status, and
4913          * status
4914          */
4915         if (un->un_persistence && un->un_persist_errors) {
4916                 if ((cmd == MTIOCLRERR) ||
4917                     (cmd == MTIOCPERSISTENT) ||
4918                     (cmd == MTIOCGET)) {
4919                         goto check_commands;
4920                 } else {
4921                         rval = un->un_errno;
4922                         goto exit;
4923                 }
4924         }
4925 
4926         ASSERT(un->un_throttle != 0);
4927         un->un_throttle = 1; /* > 1 will never happen here */
4928         un->un_errno = 0;    /* start clean from here */
4929 
4930         /*
4931          * first and foremost, handle any ST_EOT_PENDING cases.
4932          * That is, if a logical eot is pending notice, notice it.
4933          */
4934         if (un->un_pos.eof == ST_EOT_PENDING) {
4935                 int resid = un->un_err_resid;
4936                 uchar_t status = un->un_status;
4937                 uchar_t lastop = un->un_lastop;
4938 
4939                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
4940                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4941                             "stioctl : EIO can't space fmk(-1)\n");
4942                         rval = EIO;
4943                         goto exit;
4944                 }
4945                 un->un_lastop = lastop; /* restore last operation */
4946                 if (status == SUN_KEY_EOF) {
4947                         un->un_status = SUN_KEY_EOT;
4948                 } else {
4949                         un->un_status = status;
4950                 }
4951                 un->un_err_resid  = resid;
4952                 /* fix up block number */
4953                 un->un_err_pos.blkno = un->un_pos.blkno = 0;
4954                 /* now we're at logical eot */
4955                 un->un_pos.eof = ST_EOT;
4956         }
4957 
4958         /*
4959          * now, handle the rest of the situations
4960          */
4961 check_commands:
4962         switch (cmd) {
4963         case MTIOCGET:
4964         {
4965 #ifdef _MULTI_DATAMODEL
4966                 /*
4967                  * For use when a 32 bit app makes a call into a
4968                  * 64 bit ioctl
4969                  */
4970                 struct mtget32          mtg_local32;
4971                 struct mtget32          *mtget_32 = &mtg_local32;
4972 #endif /* _MULTI_DATAMODEL */
4973 
4974                         /* Get tape status */
4975                 struct mtget mtg_local;
4976                 struct mtget *mtget = &mtg_local;
4977                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
4978                     "st_ioctl: MTIOCGET\n");
4979 
4980                 bzero((caddr_t)mtget, sizeof (struct mtget));
4981                 mtget->mt_erreg = un->un_status;
4982                 mtget->mt_resid = un->un_err_resid;
4983                 mtget->mt_dsreg = un->un_retry_ct;
4984                 if (un->un_err_pos.pmode == legacy) {
4985                         mtget->mt_fileno = un->un_err_pos.fileno;
4986                 } else {
4987                         mtget->mt_fileno = -1;
4988                 }
4989                 /*
4990                  * If the value is positive fine.
4991                  * If its negative we need to return a value based on the
4992                  * old way if counting backwards from INF (1,000,000,000).
4993                  */
4994                 if (un->un_err_pos.blkno >= 0) {
4995                         mtget->mt_blkno = un->un_err_pos.blkno;
4996                 } else {
4997                         mtget->mt_blkno = INF + 1 - (-un->un_err_pos.blkno);
4998                 }
4999                 mtget->mt_type = un->un_dp->type;
5000                 mtget->mt_flags = MTF_SCSI | MTF_ASF;
5001                 if (un->un_read_pos_type != NO_POS) {
5002                         mtget->mt_flags |= MTF_LOGICAL_BLOCK;
5003                 }
5004                 if (un->un_dp->options & ST_REEL) {
5005                         mtget->mt_flags |= MTF_REEL;
5006                         mtget->mt_bf = 20;
5007                 } else {                /* 1/4" cartridges */
5008                         switch (mtget->mt_type) {
5009                         /* Emulex cartridge tape */
5010                         case MT_ISMT02:
5011                                 mtget->mt_bf = 40;
5012                                 break;
5013                         default:
5014                                 mtget->mt_bf = 126;
5015                                 break;
5016                         }
5017                 }
5018 
5019                 /*
5020                  * If large transfers are allowed and drive options
5021                  * has no record size limit set. Calculate blocking
5022                  * factor from the lesser of maxbsize and maxdma.
5023                  */
5024                 if ((un->un_allow_large_xfer) &&
5025                     (un->un_dp->options & ST_NO_RECSIZE_LIMIT)) {
5026                         mtget->mt_bf = min(un->un_maxbsize,
5027                             un->un_maxdma) / SECSIZE;
5028                 }
5029 
5030                 if (un->un_read_only == WORM ||
5031                     un->un_read_only == RDWORM) {
5032                         mtget->mt_flags |= MTF_WORM_MEDIA;
5033                 }
5034 
5035                 /*
5036                  * In persistent error mode sending a non-queued can hang
5037                  * because this ioctl gets to be run without turning off
5038                  * persistense. Fake the answer based on previous info.
5039                  */
5040                 if (un->un_persistence) {
5041                         rval = 0;
5042                 } else {
5043                         rval = st_check_clean_bit(un);
5044                 }
5045                 if (rval == 0) {
5046                         /*
5047                          * If zero is returned or in persistent mode,
5048                          * use the old data.
5049                          */
5050                         if ((un->un_HeadClean & (TAPE_ALERT_SUPPORTED |
5051                             TAPE_SEQUENTIAL_SUPPORTED|TAPE_ALERT_NOT_SUPPORTED))
5052                             != TAPE_ALERT_NOT_SUPPORTED) {
5053                                 mtget->mt_flags |= MTF_TAPE_CLN_SUPPORTED;
5054                         }
5055                         if (un->un_HeadClean & (TAPE_PREVIOUSLY_DIRTY |
5056                             TAPE_ALERT_STILL_DIRTY)) {
5057                                 mtget->mt_flags |= MTF_TAPE_HEAD_DIRTY;
5058                         }
5059                 } else {
5060                         mtget->mt_flags |= (ushort_t)rval;
5061                         rval = 0;
5062                 }
5063 
5064                 un->un_status = 0;           /* Reset status */
5065                 un->un_err_resid = 0;
5066                 tmp = sizeof (struct mtget);
5067 
5068 #ifdef _MULTI_DATAMODEL
5069 
5070                 switch (ddi_model_convert_from(flag & FMODELS)) {
5071                 case DDI_MODEL_ILP32:
5072                         /*
5073                          * Convert 64 bit back to 32 bit before doing
5074                          * copyout. This is what the ILP32 app expects.
5075                          */
5076                         mtget_32->mt_erreg =         mtget->mt_erreg;
5077                         mtget_32->mt_resid =         mtget->mt_resid;
5078                         mtget_32->mt_dsreg =         mtget->mt_dsreg;
5079                         mtget_32->mt_fileno =        (daddr32_t)mtget->mt_fileno;
5080                         mtget_32->mt_blkno =         (daddr32_t)mtget->mt_blkno;
5081                         mtget_32->mt_type =          mtget->mt_type;
5082                         mtget_32->mt_flags =         mtget->mt_flags;
5083                         mtget_32->mt_bf =    mtget->mt_bf;
5084 
5085                         if (ddi_copyout(mtget_32, (void *)arg,
5086                             sizeof (struct mtget32), flag)) {
5087                                 rval = EFAULT;
5088                         }
5089                         break;
5090 
5091                 case DDI_MODEL_NONE:
5092                         if (ddi_copyout(mtget, (void *)arg, tmp, flag)) {
5093                                 rval = EFAULT;
5094                         }
5095                         break;
5096                 }
5097 #else /* ! _MULTI_DATAMODE */
5098                 if (ddi_copyout(mtget, (void *)arg, tmp, flag)) {
5099                         rval = EFAULT;
5100                 }
5101 #endif /* _MULTI_DATAMODE */
5102 
5103                 break;
5104         }
5105         case MTIOCGETERROR:
5106                         /*
5107                          * get error entry from error stack
5108                          */
5109                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5110                             "st_ioctl: MTIOCGETERROR\n");
5111 
5112                         rval = st_get_error_entry(un, arg, flag);
5113 
5114                         break;
5115 
5116         case MTIOCSTATE:
5117                 {
5118                         /*
5119                          * return when media presence matches state
5120                          */
5121                         enum mtio_state state;
5122 
5123                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5124                             "st_ioctl: MTIOCSTATE\n");
5125 
5126                         if (ddi_copyin((void *)arg, &state, sizeof (int), flag))
5127                                 rval = EFAULT;
5128 
5129                         mutex_exit(ST_MUTEX);
5130 
5131                         rval = st_check_media(dev, state);
5132 
5133                         mutex_enter(ST_MUTEX);
5134 
5135                         if (rval != 0) {
5136                                 break;
5137                         }
5138 
5139                         if (ddi_copyout(&un->un_mediastate, (void *)arg,
5140                             sizeof (int), flag))
5141                                 rval = EFAULT;
5142                         break;
5143 
5144                 }
5145 
5146         case MTIOCGETDRIVETYPE:
5147                 {
5148 #ifdef _MULTI_DATAMODEL
5149                 /*
5150                  * For use when a 32 bit app makes a call into a
5151                  * 64 bit ioctl
5152                  */
5153                 struct mtdrivetype_request32    mtdtrq32;
5154 #endif /* _MULTI_DATAMODEL */
5155 
5156                         /*
5157                          * return mtdrivetype
5158                          */
5159                         struct mtdrivetype_request mtdtrq;
5160                         struct mtdrivetype mtdrtyp;
5161                         struct mtdrivetype *mtdt = &mtdrtyp;
5162                         struct st_drivetype *stdt = un->un_dp;
5163 
5164                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5165                             "st_ioctl: MTIOCGETDRIVETYPE\n");
5166 
5167 #ifdef _MULTI_DATAMODEL
5168                 switch (ddi_model_convert_from(flag & FMODELS)) {
5169                 case DDI_MODEL_ILP32:
5170                 {
5171                         if (ddi_copyin((void *)arg, &mtdtrq32,
5172                             sizeof (struct mtdrivetype_request32), flag)) {
5173                                 rval = EFAULT;
5174                                 break;
5175                         }
5176                         mtdtrq.size = mtdtrq32.size;
5177                         mtdtrq.mtdtp =
5178                             (struct  mtdrivetype *)(uintptr_t)mtdtrq32.mtdtp;
5179                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5180                             "st_ioctl: size 0x%x\n", mtdtrq.size);
5181                         break;
5182                 }
5183                 case DDI_MODEL_NONE:
5184                         if (ddi_copyin((void *)arg, &mtdtrq,
5185                             sizeof (struct mtdrivetype_request), flag)) {
5186                                 rval = EFAULT;
5187                                 break;
5188                         }
5189                         break;
5190                 }
5191 
5192 #else /* ! _MULTI_DATAMODEL */
5193                 if (ddi_copyin((void *)arg, &mtdtrq,
5194                     sizeof (struct mtdrivetype_request), flag)) {
5195                         rval = EFAULT;
5196                         break;
5197                 }
5198 #endif /* _MULTI_DATAMODEL */
5199 
5200                         /*
5201                          * if requested size is < 0 then return
5202                          * error.
5203                          */
5204                         if (mtdtrq.size < 0) {
5205                                 rval = EINVAL;
5206                                 break;
5207                         }
5208                         bzero(mtdt, sizeof (struct mtdrivetype));
5209                         (void) strncpy(mtdt->name, stdt->name, ST_NAMESIZE);
5210                         (void) strncpy(mtdt->vid, stdt->vid, VIDPIDLEN - 1);
5211                         mtdt->type = stdt->type;
5212                         mtdt->bsize = stdt->bsize;
5213                         mtdt->options = stdt->options;
5214                         mtdt->max_rretries = stdt->max_rretries;
5215                         mtdt->max_wretries = stdt->max_wretries;
5216                         for (tmp = 0; tmp < NDENSITIES; tmp++) {
5217                                 mtdt->densities[tmp] = stdt->densities[tmp];
5218                         }
5219                         mtdt->default_density = stdt->default_density;
5220                         /*
5221                          * Speed hasn't been used since the hayday of reel tape.
5222                          * For all drives not setting the option ST_KNOWS_MEDIA
5223                          * the speed member renamed to mediatype are zeros.
5224                          * Those drives that have ST_KNOWS_MEDIA set use the
5225                          * new mediatype member which is used to figure the
5226                          * type of media loaded.
5227                          *
5228                          * So as to not break applications speed in the
5229                          * mtdrivetype structure is not renamed.
5230                          */
5231                         for (tmp = 0; tmp < NDENSITIES; tmp++) {
5232                                 mtdt->speeds[tmp] = stdt->mediatype[tmp];
5233                         }
5234                         mtdt->non_motion_timeout = stdt->non_motion_timeout;
5235                         mtdt->io_timeout = stdt->io_timeout;
5236                         mtdt->rewind_timeout = stdt->rewind_timeout;
5237                         mtdt->space_timeout = stdt->space_timeout;
5238                         mtdt->load_timeout = stdt->load_timeout;
5239                         mtdt->unload_timeout = stdt->unload_timeout;
5240                         mtdt->erase_timeout = stdt->erase_timeout;
5241 
5242                         /*
5243                          * Limit the maximum length of the result to
5244                          * sizeof (struct mtdrivetype).
5245                          */
5246                         tmp = sizeof (struct mtdrivetype);
5247                         if (mtdtrq.size < tmp)
5248                                 tmp = mtdtrq.size;
5249                         if (ddi_copyout(mtdt, mtdtrq.mtdtp, tmp, flag)) {
5250                                 rval = EFAULT;
5251                         }
5252                         break;
5253                 }
5254         case MTIOCPERSISTENT:
5255 
5256                 if (ddi_copyin((void *)arg, &tmp, sizeof (tmp), flag)) {
5257                         rval = EFAULT;
5258                         break;
5259                 }
5260 
5261                 if (tmp) {
5262                         st_turn_pe_on(un);
5263                 } else {
5264                         st_turn_pe_off(un);
5265                 }
5266 
5267                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5268                     "st_ioctl: MTIOCPERSISTENT : persistence = %d\n",
5269                     un->un_persistence);
5270 
5271                 break;
5272 
5273         case MTIOCPERSISTENTSTATUS:
5274                 tmp = (int)un->un_persistence;
5275 
5276                 if (ddi_copyout(&tmp, (void *)arg, sizeof (tmp), flag)) {
5277                         rval = EFAULT;
5278                 }
5279                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5280                     "st_ioctl: MTIOCPERSISTENTSTATUS:persistence = %d\n",
5281                     un->un_persistence);
5282 
5283                 break;
5284 
5285         case MTIOCLRERR:
5286                 {
5287                         /* clear persistent errors */
5288 
5289                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5290                             "st_ioctl: MTIOCLRERR\n");
5291 
5292                         st_clear_pe(un);
5293 
5294                         break;
5295                 }
5296 
5297         case MTIOCGUARANTEEDORDER:
5298                 {
5299                         /*
5300                          * this is just a holder to make a valid ioctl and
5301                          * it won't be in any earlier release
5302                          */
5303                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5304                             "st_ioctl: MTIOCGUARANTEEDORDER\n");
5305 
5306                         break;
5307                 }
5308 
5309         case MTIOCRESERVE:
5310                 {
5311                         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5312                             "st_ioctl: MTIOCRESERVE\n");
5313 
5314                         /*
5315                          * Check if Reserve/Release is supported.
5316                          */
5317                         if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5318                                 rval = ENOTTY;
5319                                 break;
5320                         }
5321 
5322                         rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
5323 
5324                         if (rval == 0) {
5325                                 un->un_rsvd_status |= ST_PRESERVE_RESERVE;
5326                         }
5327                         break;
5328                 }
5329 
5330         case MTIOCRELEASE:
5331                 {
5332                         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5333                             "st_ioctl: MTIOCRELEASE\n");
5334 
5335                         /*
5336                          * Check if Reserve/Release is supported.
5337                          */
5338                         if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5339                                 rval = ENOTTY;
5340                                 break;
5341                         }
5342 
5343                         /*
5344                          * Used to just clear ST_PRESERVE_RESERVE which
5345                          * made the reservation release at next close.
5346                          * As the user may have opened and then done a
5347                          * persistant reservation we now need to drop
5348                          * the reservation without closing if the user
5349                          * attempts to do this.
5350                          */
5351                         rval = st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
5352 
5353                         un->un_rsvd_status &= ~ST_PRESERVE_RESERVE;
5354 
5355                         break;
5356                 }
5357 
5358         case MTIOCFORCERESERVE:
5359         {
5360                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5361                     "st_ioctl: MTIOCFORCERESERVE\n");
5362 
5363                 /*
5364                  * Check if Reserve/Release is supported.
5365                  */
5366                 if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5367                         rval = ENOTTY;
5368                         break;
5369                 }
5370                 /*
5371                  * allow only super user to run this.
5372                  */
5373                 if (drv_priv(cred_p) != 0) {
5374                         rval = EPERM;
5375                         break;
5376                 }
5377                 /*
5378                  * Throw away reserve,
5379                  * not using test-unit-ready
5380                  * since reserve can succeed without tape being
5381                  * present in the drive.
5382                  */
5383                 (void) st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
5384 
5385                 rval = st_take_ownership(un, st_uscsi_cmd);
5386 
5387                 break;
5388         }
5389 
5390         case USCSICMD:
5391         {
5392                 cred_t  *cr;
5393 
5394                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5395                     "st_ioctl: USCSICMD\n");
5396 
5397                 cr = ddi_get_cred();
5398                 if ((drv_priv(cred_p) != 0) && (drv_priv(cr) != 0)) {
5399                         rval = EPERM;
5400                 } else {
5401                         rval = st_uscsi_cmd(un, (struct uscsi_cmd *)arg, flag);
5402                 }
5403                 break;
5404         }
5405         case MTIOCTOP:
5406                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5407                     "st_ioctl: MTIOCTOP\n");
5408                 rval = st_mtioctop(un, arg, flag);
5409                 break;
5410 
5411         case MTIOCLTOP:
5412                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5413                     "st_ioctl: MTIOLCTOP\n");
5414                 rval = st_mtiocltop(un, arg, flag);
5415                 break;
5416 
5417         case MTIOCREADIGNOREILI:
5418                 {
5419                         int set_ili;
5420 
5421                         if (ddi_copyin((void *)arg, &set_ili,
5422                             sizeof (set_ili), flag)) {
5423                                 rval = EFAULT;
5424                                 break;
5425                         }
5426 
5427                         if (un->un_bsize) {
5428                                 rval = ENOTTY;
5429                                 break;
5430                         }
5431 
5432                         switch (set_ili) {
5433                         case 0:
5434                                 un->un_dp->options &= ~ST_READ_IGNORE_ILI;
5435                                 break;
5436 
5437                         case 1:
5438                                 un->un_dp->options |= ST_READ_IGNORE_ILI;
5439                                 break;
5440 
5441                         default:
5442                                 rval = EINVAL;
5443                                 break;
5444                         }
5445                         break;
5446                 }
5447 
5448         case MTIOCREADIGNOREEOFS:
5449                 {
5450                         int ignore_eof;
5451 
5452                         if (ddi_copyin((void *)arg, &ignore_eof,
5453                             sizeof (ignore_eof), flag)) {
5454                                 rval = EFAULT;
5455                                 break;
5456                         }
5457 
5458                         if (!(un->un_dp->options & ST_REEL)) {
5459                                 rval = ENOTTY;
5460                                 break;
5461                         }
5462 
5463                         switch (ignore_eof) {
5464                         case 0:
5465                                 un->un_dp->options &= ~ST_READ_IGNORE_EOFS;
5466                                 break;
5467 
5468                         case 1:
5469                                 un->un_dp->options |= ST_READ_IGNORE_EOFS;
5470                                 break;
5471 
5472                         default:
5473                                 rval = EINVAL;
5474                                 break;
5475                         }
5476                         break;
5477                 }
5478 
5479         case MTIOCSHORTFMK:
5480         {
5481                 int short_fmk;
5482 
5483                 if (ddi_copyin((void *)arg, &short_fmk,
5484                     sizeof (short_fmk), flag)) {
5485                         rval = EFAULT;
5486                         break;
5487                 }
5488 
5489                 switch (un->un_dp->type) {
5490                 case ST_TYPE_EXB8500:
5491                 case ST_TYPE_EXABYTE:
5492                         if (!short_fmk) {
5493                                 un->un_dp->options &= ~ST_SHORT_FILEMARKS;
5494                         } else if (short_fmk == 1) {
5495                                 un->un_dp->options |= ST_SHORT_FILEMARKS;
5496                         } else {
5497                                 rval = EINVAL;
5498                         }
5499                         break;
5500 
5501                 default:
5502                         rval = ENOTTY;
5503                         break;
5504                 }
5505                 break;
5506         }
5507 
5508         case MTIOCGETPOS:
5509                 rval = st_update_block_pos(un, st_cmd, 0);
5510                 if (rval == 0) {
5511                         if (ddi_copyout((void *)&un->un_pos, (void *)arg,
5512                             sizeof (tapepos_t), flag)) {
5513                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
5514                                     "MTIOCGETPOS copy out failed\n");
5515                                 rval = EFAULT;
5516                         }
5517                 }
5518                 break;
5519 
5520         case MTIOCRESTPOS:
5521         {
5522                 tapepos_t dest;
5523 
5524                 if (ddi_copyin((void *)arg, &dest, sizeof (tapepos_t),
5525                     flag) != 0) {
5526                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
5527                             "MTIOCRESTPOS copy in failed\n");
5528                         rval = EFAULT;
5529                         break;
5530                 }
5531                 rval = st_validate_tapemarks(un, st_uscsi_cmd, &dest);
5532                 if (rval != 0) {
5533                         rval = EIO;
5534                 }
5535                 break;
5536         }
5537         default:
5538                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5539                     "st_ioctl: unknown ioctl\n");
5540                 rval = ENOTTY;
5541         }
5542 
5543 exit:
5544         if (!(un->un_persistence && un->un_persist_errors)) {
5545                 un->un_errno = rval;
5546         }
5547 
5548         mutex_exit(ST_MUTEX);
5549 
5550         return (rval);
5551 }
5552 
5553 
5554 /*
5555  * do some MTIOCTOP tape operations
5556  */
5557 static int
5558 st_mtioctop(struct scsi_tape *un, intptr_t arg, int flag)
5559 {
5560 #ifdef _MULTI_DATAMODEL
5561         /*
5562          * For use when a 32 bit app makes a call into a
5563          * 64 bit ioctl
5564          */
5565         struct mtop32   mtop_32_for_64;
5566 #endif /* _MULTI_DATAMODEL */
5567         struct mtop passed;
5568         struct mtlop local;
5569         int rval = 0;
5570 
5571         ST_FUNC(ST_DEVINFO, st_mtioctop);
5572 
5573         ASSERT(mutex_owned(ST_MUTEX));
5574 
5575 #ifdef _MULTI_DATAMODEL
5576         switch (ddi_model_convert_from(flag & FMODELS)) {
5577         case DDI_MODEL_ILP32:
5578                 if (ddi_copyin((void *)arg, &mtop_32_for_64,
5579                     sizeof (struct mtop32), flag)) {
5580                         return (EFAULT);
5581                 }
5582                 local.mt_op = mtop_32_for_64.mt_op;
5583                 local.mt_count =  (int64_t)mtop_32_for_64.mt_count;
5584                 break;
5585 
5586         case DDI_MODEL_NONE:
5587                 if (ddi_copyin((void *)arg, &passed, sizeof (passed), flag)) {
5588                         return (EFAULT);
5589                 }
5590                 local.mt_op = passed.mt_op;
5591                 /* prevent sign extention */
5592                 local.mt_count = (UINT32_MAX & passed.mt_count);
5593                 break;
5594         }
5595 
5596 #else /* ! _MULTI_DATAMODEL */
5597         if (ddi_copyin((void *)arg, &passed, sizeof (passed), flag)) {
5598                 return (EFAULT);
5599         }
5600         local.mt_op = passed.mt_op;
5601         /* prevent sign extention */
5602         local.mt_count = (UINT32_MAX & passed.mt_count);
5603 #endif /* _MULTI_DATAMODEL */
5604 
5605         rval = st_do_mtioctop(un, &local);
5606 
5607 #ifdef _MULTI_DATAMODEL
5608         switch (ddi_model_convert_from(flag & FMODELS)) {
5609         case DDI_MODEL_ILP32:
5610                 if (((uint64_t)local.mt_count) > UINT32_MAX) {
5611                         rval = ERANGE;
5612                         break;
5613                 }
5614                 /*
5615                  * Convert 64 bit back to 32 bit before doing
5616                  * copyout. This is what the ILP32 app expects.
5617                  */
5618                 mtop_32_for_64.mt_op = local.mt_op;
5619                 mtop_32_for_64.mt_count = local.mt_count;
5620 
5621                 if (ddi_copyout(&mtop_32_for_64, (void *)arg,
5622                     sizeof (struct mtop32), flag)) {
5623                         rval = EFAULT;
5624                 }
5625                 break;
5626 
5627         case DDI_MODEL_NONE:
5628                 passed.mt_count = local.mt_count;
5629                 passed.mt_op = local.mt_op;
5630                 if (ddi_copyout(&passed, (void *)arg, sizeof (passed), flag)) {
5631                         rval = EFAULT;
5632                 }
5633                 break;
5634         }
5635 #else /* ! _MULTI_DATAMODE */
5636         if (((uint64_t)local.mt_count) > UINT32_MAX) {
5637                 rval = ERANGE;
5638         } else {
5639                 passed.mt_op = local.mt_op;
5640                 passed.mt_count = local.mt_count;
5641                 if (ddi_copyout(&passed, (void *)arg, sizeof (passed), flag)) {
5642                         rval = EFAULT;
5643                 }
5644         }
5645 #endif /* _MULTI_DATAMODE */
5646 
5647 
5648         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
5649             "st_ioctl: fileno=%x, blkno=%x, eof=%x\n", un->un_pos.fileno,
5650             un->un_pos.blkno, un->un_pos.eof);
5651 
5652         if (un->un_pos.pmode == invalid) {
5653                 un->un_density_known = 0;
5654         }
5655 
5656         ASSERT(mutex_owned(ST_MUTEX));
5657         return (rval);
5658 }
5659 
5660 static int
5661 st_mtiocltop(struct scsi_tape *un, intptr_t arg, int flag)
5662 {
5663         struct mtlop local;
5664         int rval;
5665 
5666         ST_FUNC(ST_DEVINFO, st_mtiocltop);
5667         if (ddi_copyin((void *)arg, &local, sizeof (local), flag)) {
5668                 return (EFAULT);
5669         }
5670 
5671         rval = st_do_mtioctop(un, &local);
5672 
5673         if (ddi_copyout(&local, (void *)arg, sizeof (local), flag)) {
5674                 rval = EFAULT;
5675         }
5676         return (rval);
5677 }
5678 
5679 
5680 static int
5681 st_do_mtioctop(struct scsi_tape *un, struct mtlop *mtop)
5682 {
5683         dev_t dev = un->un_dev;
5684         int savefile;
5685         int rval = 0;
5686 
5687         ST_FUNC(ST_DEVINFO, st_do_mtioctop);
5688 
5689         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5690             "st_do_mtioctop(): mt_op=%x\n", mtop->mt_op);
5691         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5692             "fileno=%x, blkno=%x, eof=%x\n",
5693             un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
5694 
5695         un->un_status = 0;
5696 
5697         /*
5698          * if we are going to mess with a tape, we have to make sure we have
5699          * one and are not offline (i.e. no tape is initialized).  We let
5700          * commands pass here that don't actually touch the tape, except for
5701          * loading and initialization (rewinding).
5702          */
5703         if (un->un_state == ST_STATE_OFFLINE) {
5704                 switch (mtop->mt_op) {
5705                 case MTLOAD:
5706                 case MTNOP:
5707                         /*
5708                          * We don't want strategy calling st_tape_init here,
5709                          * so, change state
5710                          */
5711                         un->un_state = ST_STATE_INITIALIZING;
5712                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5713                             "st_do_mtioctop : OFFLINE state = %d\n",
5714                             un->un_state);
5715                         break;
5716                 default:
5717                         /*
5718                          * reinitialize by normal means
5719                          */
5720                         rval = st_tape_init(un);
5721                         if (rval) {
5722                                 un->un_state = ST_STATE_INITIALIZING;
5723                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5724                                     "st_do_mtioctop : OFFLINE init failure ");
5725                                 un->un_state = ST_STATE_OFFLINE;
5726                                 un->un_pos.pmode = invalid;
5727                                 if (rval != EACCES) {
5728                                         rval = EIO;
5729                                 }
5730                                 return (rval);
5731                         }
5732                         un->un_state = ST_STATE_OPEN_PENDING_IO;
5733                         break;
5734                 }
5735         }
5736 
5737         /*
5738          * If the file position is invalid, allow only those
5739          * commands that properly position the tape and fail
5740          * the rest with EIO
5741          */
5742         if (un->un_pos.pmode == invalid) {
5743                 switch (mtop->mt_op) {
5744                 case MTWEOF:
5745                 case MTRETEN:
5746                 case MTERASE:
5747                 case MTEOM:
5748                 case MTFSF:
5749                 case MTFSR:
5750                 case MTBSF:
5751                 case MTNBSF:
5752                 case MTBSR:
5753                 case MTSRSZ:
5754                 case MTGRSZ:
5755                 case MTSEEK:
5756                 case MTBSSF:
5757                 case MTFSSF:
5758                         return (EIO);
5759                         /* NOTREACHED */
5760                 case MTREW:
5761                 case MTLOAD:
5762                 case MTOFFL:
5763                 case MTNOP:
5764                 case MTTELL:
5765                 case MTLOCK:
5766                 case MTUNLOCK:
5767                         break;
5768 
5769                 default:
5770                         return (ENOTTY);
5771                         /* NOTREACHED */
5772                 }
5773         }
5774 
5775         switch (mtop->mt_op) {
5776         case MTERASE:
5777                 /*
5778                  * MTERASE rewinds the tape, erase it completely, and returns
5779                  * to the beginning of the tape
5780                  */
5781                 if (un->un_mspl->wp || un->un_read_only & WORM) {
5782                         un->un_status = KEY_WRITE_PROTECT;
5783                         un->un_err_resid = mtop->mt_count;
5784                         COPY_POS(&un->un_err_pos, &un->un_pos);
5785                         return (EACCES);
5786                 }
5787                 if (un->un_dp->options & ST_REEL) {
5788                         un->un_fmneeded = 2;
5789                 } else {
5790                         un->un_fmneeded = 1;
5791                 }
5792                 mtop->mt_count = mtop->mt_count ? 1 : 0;
5793                 if (st_check_density_or_wfm(dev, 1, B_WRITE, NO_STEPBACK) ||
5794                     st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
5795                     st_cmd(un, SCMD_ERASE, mtop->mt_count, SYNC_CMD)) {
5796                         un->un_pos.pmode = invalid;
5797                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5798                             "st_do_mtioctop : EIO space or erase or "
5799                             "check den)\n");
5800                         rval = EIO;
5801                 } else {
5802                         /* QIC and helical scan rewind after erase */
5803                         if (un->un_dp->options & ST_REEL) {
5804                                 (void) st_cmd(un, SCMD_REWIND, 0, ASYNC_CMD);
5805                         }
5806                 }
5807                 break;
5808 
5809         case MTWEOF:
5810                 /*
5811                  * write an end-of-file record
5812                  */
5813                 if (un->un_mspl->wp || un->un_read_only & RDONLY) {
5814                         un->un_status = KEY_WRITE_PROTECT;
5815                         un->un_err_resid = mtop->mt_count;
5816                         COPY_POS(&un->un_err_pos, &un->un_pos);
5817                         return (EACCES);
5818                 }
5819 
5820                 /*
5821                  * zero count means just flush buffers
5822                  * negative count is not permitted
5823                  */
5824                 if (mtop->mt_count < 0) {
5825                         return (EINVAL);
5826                 }
5827 
5828                 /* Not on worm */
5829                 if (un->un_read_only == RDWR) {
5830                         un->un_test_append = 1;
5831                 }
5832 
5833                 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
5834                         if (st_determine_density(un, B_WRITE)) {
5835                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5836                                     "st_do_mtioctop : EIO : MTWEOF can't "
5837                                     "determine density");
5838                                 return (EIO);
5839                         }
5840                 }
5841 
5842                 rval = st_write_fm(dev, (int)mtop->mt_count);
5843                 if ((rval != 0) && (rval != EACCES)) {
5844                         /*
5845                          * Failure due to something other than illegal
5846                          * request results in loss of state (st_intr).
5847                          */
5848                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5849                             "st_do_mtioctop : EIO : MTWEOF can't write "
5850                             "file mark");
5851                         rval = EIO;
5852                 }
5853                 break;
5854 
5855         case MTRETEN:
5856                 /*
5857                  * retension the tape
5858                  */
5859                 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK) ||
5860                     st_cmd(un, SCMD_LOAD, LD_LOAD | LD_RETEN, SYNC_CMD)) {
5861                         un->un_pos.pmode = invalid;
5862                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5863                             "st_do_mtioctop : EIO : MTRETEN ");
5864                         rval = EIO;
5865                 }
5866                 break;
5867 
5868         case MTREW:
5869                 /*
5870                  * rewind  the tape
5871                  */
5872                 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK)) {
5873                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5874                             "st_do_mtioctop : EIO:MTREW check "
5875                             "density/wfm failed");
5876                         return (EIO);
5877                 }
5878                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
5879                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5880                             "st_do_mtioctop : EIO : MTREW ");
5881                         rval = EIO;
5882                 }
5883                 break;
5884 
5885         case MTOFFL:
5886                 /*
5887                  * rewinds, and, if appropriate, takes the device offline by
5888                  * unloading the tape
5889                  */
5890                 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK)) {
5891                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5892                             "st_do_mtioctop :EIO:MTOFFL check "
5893                             "density/wfm failed");
5894                         return (EIO);
5895                 }
5896                 (void) st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
5897                 if (st_cmd(un, SCMD_LOAD, LD_UNLOAD, SYNC_CMD)) {
5898                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5899                             "st_do_mtioctop : EIO : MTOFFL");
5900                         return (EIO);
5901                 }
5902                 un->un_pos.eof = ST_NO_EOF;
5903                 un->un_laststate = un->un_state;
5904                 un->un_state = ST_STATE_OFFLINE;
5905                 un->un_mediastate = MTIO_EJECTED;
5906                 break;
5907 
5908         case MTLOAD:
5909                 /*
5910                  * This is to load a tape into the drive
5911                  * Note that if the tape is not loaded, the device will have
5912                  * to be opened via O_NDELAY or O_NONBLOCK.
5913                  */
5914                 /*
5915                  * Let's try and clean things up, if we are not
5916                  * initializing, and then send in the load command, no
5917                  * matter what.
5918                  *
5919                  * load after a media change by the user.
5920                  */
5921 
5922                 if (un->un_state > ST_STATE_INITIALIZING) {
5923                         (void) st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK);
5924                 }
5925                 rval = st_cmd(un, SCMD_LOAD, LD_LOAD, SYNC_CMD);
5926                 /* Load command to a drive that doesn't support load */
5927                 if ((rval == EIO) &&
5928                     ((un->un_status == KEY_NOT_READY) &&
5929                         /* Medium not present */
5930                     (un->un_uscsi_rqs_buf->es_add_code == 0x3a) ||
5931                     ((un->un_status == KEY_ILLEGAL_REQUEST) &&
5932                     (un->un_dp->type == MT_ISSTK9840) &&
5933                         /* CSL not present */
5934                     (un->un_uscsi_rqs_buf->es_add_code == 0x80)))) {
5935                         rval = ENOTTY;
5936                         break;
5937                 } else if (rval != EACCES && rval != 0) {
5938                         rval = EIO;
5939                 }
5940                 if (rval) {
5941                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5942                             "st_do_mtioctop : %s : MTLOAD\n",
5943                             rval == EACCES ? "EACCES" : "EIO");
5944                         /*
5945                          * If load tape fails, who knows what happened...
5946                          */
5947                         un->un_pos.pmode = invalid;
5948                         break;
5949                 }
5950 
5951                 /*
5952                  * reset all counters appropriately using rewind, as if LOAD
5953                  * succeeds, we are at BOT
5954                  */
5955                 un->un_state = ST_STATE_INITIALIZING;
5956 
5957                 rval = st_tape_init(un);
5958                 if ((rval == EACCES) && (un->un_read_only & WORM)) {
5959                         rval = 0;
5960                         break;
5961                 }
5962 
5963                 if (rval != 0) {
5964                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5965                             "st_do_mtioctop : EIO : MTLOAD calls "
5966                             "st_tape_init\n");
5967                         rval = EIO;
5968                         un->un_state = ST_STATE_OFFLINE;
5969                 }
5970 
5971                 break;
5972 
5973         case MTNOP:
5974                 un->un_status = 0;           /* Reset status */
5975                 un->un_err_resid = 0;
5976                 mtop->mt_count = MTUNIT(dev);
5977                 break;
5978 
5979         case MTEOM:
5980                 /*
5981                  * positions the tape at a location just after the last file
5982                  * written on the tape. For cartridge and 8 mm, this after
5983                  * the last file mark; for reel, this is inbetween the two
5984                  * last 2 file marks
5985                  */
5986                 if ((un->un_pos.pmode == legacy && un->un_pos.eof >= ST_EOT) ||
5987                     (un->un_lastop == ST_OP_WRITE) ||
5988                     (un->un_lastop == ST_OP_WEOF)) {
5989                         /*
5990                          * If the command wants to move to logical end
5991                          * of media, and we're already there, we're done.
5992                          * If we were at logical eot, we reset the state
5993                          * to be *not* at logical eot.
5994                          *
5995                          * If we're at physical or logical eot, we prohibit
5996                          * forward space operations (unconditionally).
5997                          *
5998                          * Also if the last operation was a write of any
5999                          * kind the tape is at EOD.
6000                          */
6001                         return (0);
6002                 }
6003                 /*
6004                  * physical tape position may not be what we've been
6005                  * telling the user; adjust the request accordingly
6006                  */
6007                 if (IN_EOF(un->un_pos)) {
6008                         un->un_pos.fileno++;
6009                         un->un_pos.blkno = 0;
6010                 }
6011 
6012                 if (st_check_density_or_wfm(dev, 1, B_READ, NO_STEPBACK)) {
6013                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6014                             "st_do_mtioctop : EIO:MTEOM check density/wfm "
6015                             " failed");
6016                         return (EIO);
6017                 }
6018 
6019                 /*
6020                  * st_find_eod() returns the last fileno we knew about;
6021                  */
6022                 savefile = st_find_eod(un);
6023 
6024                 if ((un->un_status != KEY_BLANK_CHECK) &&
6025                     (un->un_status != SUN_KEY_EOT)) {
6026                         un->un_pos.pmode = invalid;
6027                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6028                             "st_do_mtioctop : EIO : MTEOM status check failed");
6029                         rval = EIO;
6030                 } else {
6031                         /*
6032                          * For 1/2" reel tapes assume logical EOT marked
6033                          * by two file marks or we don't care that we may
6034                          * be extending the last file on the tape.
6035                          */
6036                         if (un->un_dp->options & ST_REEL) {
6037                                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
6038                                         un->un_pos.pmode = invalid;
6039                                         ST_DEBUG2(ST_DEVINFO, st_label,
6040                                             SCSI_DEBUG,
6041                                             "st_do_mtioctop : EIO : MTEOM space"
6042                                             " cmd failed");
6043                                         rval = EIO;
6044                                         break;
6045                                 }
6046                                 /*
6047                                  * Fix up the block number.
6048                                  */
6049                                 un->un_pos.blkno = 0;
6050                                 un->un_err_pos.blkno = 0;
6051                         }
6052                         un->un_err_resid = 0;
6053                         un->un_pos.fileno = savefile;
6054                         un->un_pos.eof = ST_EOT;
6055                 }
6056                 un->un_status = 0;
6057                 break;
6058 
6059         case MTFSF:
6060                 MAX_SPACE_CNT(mtop->mt_count);
6061                 rval = st_mtfsf_ioctl(un, mtop->mt_count);
6062                 break;
6063 
6064         case MTFSR:
6065                 MAX_SPACE_CNT(mtop->mt_count);
6066                 rval = st_mtfsr_ioctl(un, mtop->mt_count);
6067                 break;
6068 
6069         case MTBSF:
6070                 MAX_SPACE_CNT(mtop->mt_count);
6071                 rval = st_mtbsf_ioctl(un, mtop->mt_count);
6072                 break;
6073 
6074         case MTNBSF:
6075                 MAX_SPACE_CNT(mtop->mt_count);
6076                 rval = st_mtnbsf_ioctl(un, mtop->mt_count);
6077                 break;
6078 
6079         case MTBSR:
6080                 MAX_SPACE_CNT(mtop->mt_count);
6081                 rval = st_mtbsr_ioctl(un, mtop->mt_count);
6082                 break;
6083 
6084         case MTBSSF:
6085                 MAX_SPACE_CNT(mtop->mt_count);
6086                 rval = st_mtbsfm_ioctl(un, mtop->mt_count);
6087                 break;
6088 
6089         case MTFSSF:
6090                 MAX_SPACE_CNT(mtop->mt_count);
6091                 rval = st_mtfsfm_ioctl(un, mtop->mt_count);
6092                 break;
6093 
6094         case MTSRSZ:
6095 
6096                 /*
6097                  * Set record-size to that sent by user
6098                  * Check to see if there is reason that the requested
6099                  * block size should not be set.
6100                  */
6101 
6102                 /* If requesting variable block size is it ok? */
6103                 if ((mtop->mt_count == 0) &&
6104                     ((un->un_dp->options & ST_VARIABLE) == 0)) {
6105                         return (ENOTTY);
6106                 }
6107 
6108                 /*
6109                  * If requested block size is not variable "0",
6110                  * is it less then minimum.
6111                  */
6112                 if ((mtop->mt_count != 0) &&
6113                     (mtop->mt_count < un->un_minbsize)) {
6114                         return (EINVAL);
6115                 }
6116 
6117                 /* Is the requested block size more then maximum */
6118                 if ((mtop->mt_count > min(un->un_maxbsize, un->un_maxdma)) &&
6119                     (un->un_maxbsize != 0)) {
6120                         return (EINVAL);
6121                 }
6122 
6123                 /* Is requested block size a modulus the device likes */
6124                 if ((mtop->mt_count % un->un_data_mod) != 0) {
6125                         return (EINVAL);
6126                 }
6127 
6128                 if (st_change_block_size(un, (uint32_t)mtop->mt_count) != 0) {
6129                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6130                             "st_ioctl : MTSRSZ : EIO : cant set block size");
6131                         return (EIO);
6132                 }
6133 
6134                 return (0);
6135 
6136         case MTGRSZ:
6137                 /*
6138                  * Get record-size to the user
6139                  */
6140                 mtop->mt_count = un->un_bsize;
6141                 rval = 0;
6142                 break;
6143 
6144         case MTTELL:
6145                 rval = st_update_block_pos(un, st_cmd, 0);
6146                 mtop->mt_count = un->un_pos.lgclblkno;
6147                 break;
6148 
6149         case MTSEEK:
6150                 rval = st_logical_block_locate(un, st_uscsi_cmd, &un->un_pos,
6151                     (uint64_t)mtop->mt_count, un->un_pos.partition);
6152                 /*
6153                  * This bit of magic make mt print the actual position if
6154                  * the resulting position was not what was asked for.
6155                  */
6156                 if (rval == ESPIPE) {
6157                         rval = EIO;
6158                         if ((uint64_t)mtop->mt_count != un->un_pos.lgclblkno) {
6159                                 mtop->mt_op = MTTELL;
6160                                 mtop->mt_count = un->un_pos.lgclblkno;
6161                         }
6162                 }
6163                 break;
6164 
6165         case MTLOCK:
6166                 if (st_cmd(un, SCMD_DOORLOCK, MR_LOCK, SYNC_CMD)) {
6167                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6168                             "st_do_mtioctop : EIO : MTLOCK");
6169                         rval = EIO;
6170                 }
6171                 break;
6172 
6173         case MTUNLOCK:
6174                 if (st_cmd(un, SCMD_DOORLOCK, MR_UNLOCK, SYNC_CMD)) {
6175                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6176                             "st_do_mtioctop : EIO : MTUNLOCK");
6177                         rval = EIO;
6178                 }
6179                 break;
6180 
6181         default:
6182                 rval = ENOTTY;
6183         }
6184 
6185         return (rval);
6186 }
6187 
6188 
6189 /*
6190  * Run a command for uscsi ioctl.
6191  */
6192 static int
6193 st_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *ucmd, int flag)
6194 {
6195         struct uscsi_cmd        *uscmd;
6196         struct buf      *bp;
6197         enum uio_seg    uioseg;
6198         int     offline_state = 0;
6199         int     err = 0;
6200         dev_t dev = un->un_dev;
6201 
6202         ST_FUNC(ST_DEVINFO, st_uscsi_cmd);
6203 
6204         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6205             "st_uscsi_cmd(dev = 0x%lx)\n", un->un_dev);
6206 
6207         ASSERT(mutex_owned(ST_MUTEX));
6208 
6209         /*
6210          * We really don't know what commands are coming in here and
6211          * we don't want to limit the commands coming in.
6212          *
6213          * If st_tape_init() gets called from st_strategy(), then we
6214          * will hang the process waiting for un->un_sbuf_busy to be cleared,
6215          * which it never will, as we set it below.  To prevent
6216          * st_tape_init() from getting called, we have to set state to other
6217          * than ST_STATE_OFFLINE, so we choose ST_STATE_INITIALIZING, which
6218          * achieves this purpose already.
6219          *
6220          * We use offline_state to preserve the OFFLINE state, if it exists,
6221          * so other entry points to the driver might have the chance to call
6222          * st_tape_init().
6223          */
6224         if (un->un_state == ST_STATE_OFFLINE) {
6225                 un->un_laststate = ST_STATE_OFFLINE;
6226                 un->un_state = ST_STATE_INITIALIZING;
6227                 offline_state = 1;
6228         }
6229 
6230         mutex_exit(ST_MUTEX);
6231         err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag, ROUTE, &uscmd);
6232         mutex_enter(ST_MUTEX);
6233         if (err != 0) {
6234                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6235                     "st_uscsi_cmd: scsi_uscsi_alloc_and_copyin failed\n");
6236                 goto exit;
6237         }
6238 
6239         uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
6240 
6241         /* check to see if this command requires the drive to be reserved */
6242         if (uscmd->uscsi_cdb != NULL) {
6243                 err = st_check_cdb_for_need_to_reserve(un,
6244                     (uchar_t *)uscmd->uscsi_cdb);
6245                 if (err) {
6246                         goto exit_free;
6247                 }
6248                 /*
6249                  * If this is a space command we need to save the starting
6250                  * point so we can retry from there if the command fails.
6251                  */
6252                 if ((uscmd->uscsi_cdb[0] == SCMD_SPACE) ||
6253                     (uscmd->uscsi_cdb[0] == (char)SCMD_SPACE_G4)) {
6254                         (void) st_update_block_pos(un, st_cmd, 0);
6255                 }
6256         }
6257 
6258         /*
6259          * Forground should not be doing anything while recovery is active.
6260          */
6261         ASSERT(un->un_recov_buf_busy == 0);
6262 
6263         /*
6264          * Get buffer resources...
6265          */
6266         while (un->un_sbuf_busy)
6267                 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
6268         un->un_sbuf_busy = 1;
6269 
6270 #ifdef STDEBUG
6271         if ((uscmd->uscsi_cdb != NULL) && (st_debug & 0x7) > 6) {
6272                 int rw = (uscmd->uscsi_flags & USCSI_READ) ? B_READ : B_WRITE;
6273                 st_print_cdb(ST_DEVINFO, st_label, SCSI_DEBUG,
6274                     "uscsi cdb", uscmd->uscsi_cdb);
6275                 if (uscmd->uscsi_buflen) {
6276                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6277                             "uscsi %s of %ld bytes %s %s space\n",
6278                             (rw == B_READ) ? rd_str : wr_str,
6279                             uscmd->uscsi_buflen,
6280                             (rw == B_READ) ? "to" : "from",
6281                             (uioseg == UIO_SYSSPACE) ? "system" : "user");
6282                 }
6283         }
6284 #endif /* STDEBUG */
6285 
6286         /*
6287          * Although st_uscsi_cmd() never makes use of these
6288          * now, we are just being safe and consistent.
6289          */
6290         uscmd->uscsi_flags &= ~(USCSI_NOINTR | USCSI_NOPARITY |
6291             USCSI_OTAG | USCSI_HTAG | USCSI_HEAD);
6292 
6293         un->un_srqbufp = uscmd->uscsi_rqbuf;
6294         bp = un->un_sbufp;
6295         bzero(bp, sizeof (buf_t));
6296         if (uscmd->uscsi_cdb != NULL) {
6297                 bp->b_forw = (struct buf *)(uintptr_t)uscmd->uscsi_cdb[0];
6298         }
6299         bp->b_back = (struct buf *)uscmd;
6300 
6301         mutex_exit(ST_MUTEX);
6302         err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, st_strategy, bp, NULL);
6303         mutex_enter(ST_MUTEX);
6304 
6305         /*
6306          * If scsi reset successful, don't write any filemarks.
6307          */
6308         if ((err == 0) && (uscmd->uscsi_flags &
6309             (USCSI_RESET_LUN | USCSI_RESET_TARGET | USCSI_RESET_ALL))) {
6310                 un->un_fmneeded = 0;
6311         }
6312 
6313 exit_free:
6314         /*
6315          * Free resources
6316          */
6317         un->un_sbuf_busy = 0;
6318         un->un_srqbufp = NULL;
6319 
6320         /*
6321          * If was a space command need to update logical block position.
6322          * If the command failed such that positioning is invalid, Don't
6323          * update the position as the user must do this to validate the
6324          * position for data protection.
6325          */
6326         if ((uscmd->uscsi_cdb != NULL) &&
6327             ((uscmd->uscsi_cdb[0] == SCMD_SPACE) ||
6328             (uscmd->uscsi_cdb[0] == (char)SCMD_SPACE_G4)) &&
6329             (un->un_pos.pmode != invalid)) {
6330                 un->un_running.pmode = invalid;
6331                 (void) st_update_block_pos(un, st_cmd, 1);
6332                 /*
6333                  * Set running position to invalid so it updates on the
6334                  * next command.
6335                  */
6336                 un->un_running.pmode = invalid;
6337         }
6338         cv_signal(&un->un_sbuf_cv);
6339         mutex_exit(ST_MUTEX);
6340         (void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd);
6341         mutex_enter(ST_MUTEX);
6342         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6343             "st_uscsi_cmd returns 0x%x\n", err);
6344 
6345 exit:
6346         /* don't lose offline state */
6347         if (offline_state) {
6348                 un->un_state = ST_STATE_OFFLINE;
6349         }
6350 
6351         ASSERT(mutex_owned(ST_MUTEX));
6352         return (err);
6353 }
6354 
6355 static int
6356 st_write_fm(dev_t dev, int wfm)
6357 {
6358         int i;
6359         int rval;
6360 
6361         GET_SOFT_STATE(dev);
6362 
6363         ST_FUNC(ST_DEVINFO, st_write_fm);
6364 
6365         ASSERT(mutex_owned(ST_MUTEX));
6366 
6367         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6368             "st_write_fm(dev = 0x%lx, wfm = %d)\n", dev, wfm);
6369 
6370         /*
6371          * write one filemark at the time after EOT
6372          */
6373         if (un->un_pos.eof >= ST_EOT) {
6374                 for (i = 0; i < wfm; i++) {
6375                         rval = st_cmd(un, SCMD_WRITE_FILE_MARK, 1, SYNC_CMD);
6376                         if (rval == EACCES) {
6377                                 return (rval);
6378                         }
6379                         if (rval != 0) {
6380                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6381                                     "st_write_fm : EIO : write EOT file mark");
6382                                 return (EIO);
6383                         }
6384                 }
6385         } else {
6386                 rval = st_cmd(un, SCMD_WRITE_FILE_MARK, wfm, SYNC_CMD);
6387                 if (rval == EACCES) {
6388                         return (rval);
6389                 }
6390                 if (rval) {
6391                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6392                             "st_write_fm : EIO : write file mark");
6393                         return (EIO);
6394                 }
6395         }
6396 
6397         ASSERT(mutex_owned(ST_MUTEX));
6398         return (0);
6399 }
6400 
6401 #ifdef STDEBUG
6402 static void
6403 st_start_dump(struct scsi_tape *un, struct buf *bp)
6404 {
6405         struct scsi_pkt *pkt = BP_PKT(bp);
6406         uchar_t *cdbp = (uchar_t *)pkt->pkt_cdbp;
6407 
6408         ST_FUNC(ST_DEVINFO, st_start_dump);
6409 
6410         if ((st_debug & 0x7) < 6)
6411                 return;
6412         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6413             "st_start: cmd=0x%p count=%ld resid=%ld flags=0x%x pkt=0x%p\n",
6414             (void *)bp->b_forw, bp->b_bcount,
6415             bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
6416         st_print_cdb(ST_DEVINFO, st_label, SCSI_DEBUG,
6417             "st_start: cdb",  (caddr_t)cdbp);
6418         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6419             "st_start: fileno=%d, blk=%d\n",
6420             un->un_pos.fileno, un->un_pos.blkno);
6421 }
6422 #endif
6423 
6424 
6425 /*
6426  * Command start && done functions
6427  */
6428 
6429 /*
6430  * st_start()
6431  *
6432  * Called from:
6433  *  st_strategy() to start a command.
6434  *  st_runout() to retry when scsi_pkt allocation fails on previous attempt(s).
6435  *  st_attach() when resuming from power down state.
6436  *  st_start_restart() to retry transport when device was previously busy.
6437  *  st_done_and_mutex_exit() to start the next command when previous is done.
6438  *
6439  * On entry:
6440  *  scsi_pkt may or may not be allocated.
6441  *
6442  */
6443 static void
6444 st_start(struct scsi_tape *un)
6445 {
6446         struct buf *bp;
6447         int status;
6448         int queued;
6449 
6450         ST_FUNC(ST_DEVINFO, st_start);
6451         ASSERT(mutex_owned(ST_MUTEX));
6452 
6453         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6454             "st_start(): dev = 0x%lx\n", un->un_dev);
6455 
6456         if (un->un_recov_buf_busy) {
6457                 /* recovery commands can happen anytime */
6458                 bp = un->un_recov_buf;
6459                 queued = 0;
6460         } else if (un->un_sbuf_busy) {
6461                 /* sbuf commands should only happen with an empty queue. */
6462                 ASSERT(un->un_quef == NULL);
6463                 ASSERT(un->un_runqf == NULL);
6464                 bp = un->un_sbufp;
6465                 queued = 0;
6466         } else if (un->un_quef != NULL) {
6467                 if (un->un_persistence && un->un_persist_errors) {
6468                         return;
6469                 }
6470                 bp = un->un_quef;
6471                 queued = 1;
6472         } else {
6473                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6474                     "st_start() returning no buf found\n");
6475                 return;
6476         }
6477 
6478         ASSERT((bp->b_flags & B_DONE) == 0);
6479 
6480         /*
6481          * Don't send more than un_throttle commands to the HBA
6482          */
6483         if ((un->un_throttle <= 0) || (un->un_ncmds >= un->un_throttle)) {
6484                 /*
6485                  * if doing recovery we know there is outstanding commands.
6486                  */
6487                 if (bp != un->un_recov_buf) {
6488                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6489                             "st_start returning throttle = %d or ncmds = %d\n",
6490                             un->un_throttle, un->un_ncmds);
6491                         if (un->un_ncmds == 0) {
6492                                 typedef void (*func)();
6493                                 func fnc = (func)st_runout;
6494 
6495                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6496                                     "Sending delayed start to st_runout()\n");
6497                                 mutex_exit(ST_MUTEX);
6498                                 (void) timeout(fnc, un, drv_sectohz(1));
6499                                 mutex_enter(ST_MUTEX);
6500                         }
6501                         return;
6502                 }
6503         }
6504 
6505         /*
6506          * If the buf has no scsi_pkt call st_make_cmd() to get one and
6507          * build the command.
6508          */
6509         if (BP_PKT(bp) == NULL) {
6510                 ASSERT((bp->b_flags & B_DONE) == 0);
6511                 st_make_cmd(un, bp, st_runout);
6512                 ASSERT((bp->b_flags & B_DONE) == 0);
6513                 status = geterror(bp);
6514 
6515                 /*
6516                  * Some HBA's don't call bioerror() to set an error.
6517                  * And geterror() returns zero if B_ERROR is not set.
6518                  * So if we get zero we must check b_error.
6519                  */
6520                 if (status == 0 && bp->b_error != 0) {
6521                         status = bp->b_error;
6522                         bioerror(bp, status);
6523                 }
6524 
6525                 /*
6526                  * Some HBA's convert DDI_DMA_NORESOURCES into ENOMEM.
6527                  * In tape ENOMEM has special meaning so we'll change it.
6528                  */
6529                 if (status == ENOMEM) {
6530                         status = 0;
6531                         bioerror(bp, status);
6532                 }
6533 
6534                 /*
6535                  * Did it fail and is it retryable?
6536                  * If so return and wait for the callback through st_runout.
6537                  * Also looks like scsi_init_pkt() will setup a callback even
6538                  * if it isn't retryable.
6539                  */
6540                 if (BP_PKT(bp) == NULL) {
6541                         if (status == 0) {
6542                                 /*
6543                                  * If first attempt save state.
6544                                  */
6545                                 if (un->un_state != ST_STATE_RESOURCE_WAIT) {
6546                                         un->un_laststate = un->un_state;
6547                                         un->un_state = ST_STATE_RESOURCE_WAIT;
6548                                 }
6549                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6550                                     "temp no resources for pkt\n");
6551                         } else if (status == EINVAL) {
6552                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6553                                     "scsi_init_pkt rejected pkt as too big\n");
6554                                 if (un->un_persistence) {
6555                                         st_set_pe_flag(un);
6556                                 }
6557                         } else {
6558                                 /*
6559                                  * Unlikely that it would be retryable then not.
6560                                  */
6561                                 if (un->un_state == ST_STATE_RESOURCE_WAIT) {
6562                                         un->un_state = un->un_laststate;
6563                                 }
6564                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6565                                     "perm no resources for pkt errno = 0x%x\n",
6566                                     status);
6567                         }
6568                         return;
6569                 }
6570                 /*
6571                  * Worked this time set the state back.
6572                  */
6573                 if (un->un_state == ST_STATE_RESOURCE_WAIT) {
6574                         un->un_state = un->un_laststate;
6575                 }
6576         }
6577 
6578         if (queued) {
6579                 /*
6580                  * move from waitq to runq
6581                  */
6582                 (void) st_remove_from_queue(&un->un_quef, &un->un_quel, bp);
6583                 st_add_to_queue(&un->un_runqf, &un->un_runql, un->un_runql, bp);
6584         }
6585 
6586 
6587 #ifdef STDEBUG
6588         st_start_dump(un, bp);
6589 #endif
6590 
6591         /* could not get here if throttle was zero */
6592         un->un_last_throttle = un->un_throttle;
6593         un->un_throttle = 0; /* so nothing else will come in here */
6594         un->un_ncmds++;
6595 
6596         ST_DO_KSTATS(bp, kstat_waitq_to_runq);
6597 
6598         status = st_transport(un, BP_PKT(bp));
6599 
6600         if (un->un_last_throttle) {
6601                 un->un_throttle = un->un_last_throttle;
6602         }
6603 
6604         if (status != TRAN_ACCEPT) {
6605                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
6606                 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
6607                     "Unhappy transport packet status 0x%x\n", status);
6608 
6609                 if (status == TRAN_BUSY) {
6610                         pkt_info *pkti = BP_PKT(bp)->pkt_private;
6611 
6612                         /*
6613                          * If command recovery is enabled and this isn't
6614                          * a recovery command try command recovery.
6615                          */
6616                         if (pkti->privatelen == sizeof (recov_info) &&
6617                             bp != un->un_recov_buf) {
6618                                 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
6619                                     "Command Recovery called on busy send\n");
6620                                 if (st_command_recovery(un, BP_PKT(bp),
6621                                     ATTEMPT_RETRY) == JUST_RETURN) {
6622                                         return;
6623                                 }
6624                         } else {
6625                                 mutex_exit(ST_MUTEX);
6626                                 if (st_handle_start_busy(un, bp,
6627                                     ST_TRAN_BUSY_TIMEOUT, queued) == 0) {
6628                                         mutex_enter(ST_MUTEX);
6629                                         return;
6630                                 }
6631                                 /*
6632                                  * if too many retries, fail the transport
6633                                  */
6634                                 mutex_enter(ST_MUTEX);
6635                         }
6636                 }
6637                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
6638                     "transport rejected %d\n", status);
6639                 bp->b_resid = bp->b_bcount;
6640 
6641                 ST_DO_KSTATS(bp, kstat_waitq_exit);
6642                 ST_DO_ERRSTATS(un, st_transerrs);
6643                 if ((bp == un->un_recov_buf) && (status == TRAN_BUSY)) {
6644                         st_bioerror(bp, EBUSY);
6645                 } else {
6646                         st_bioerror(bp, EIO);
6647                         st_set_pe_flag(un);
6648                 }
6649                 st_done_and_mutex_exit(un, bp);
6650                 mutex_enter(ST_MUTEX);
6651         }
6652 
6653         ASSERT(mutex_owned(ST_MUTEX));
6654 }
6655 
6656 /*
6657  * if the transport is busy, then put this bp back on the waitq
6658  */
6659 static int
6660 st_handle_start_busy(struct scsi_tape *un, struct buf *bp,
6661     clock_t timeout_interval, int queued)
6662 {
6663 
6664         pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
6665 
6666         ST_FUNC(ST_DEVINFO, st_handle_start_busy);
6667 
6668         mutex_enter(ST_MUTEX);
6669 
6670         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6671             "st_handle_start_busy()\n");
6672 
6673         /*
6674          * Check to see if we hit the retry timeout and one last check for
6675          * making sure this is the last on the runq, if it is not, we have
6676          * to fail
6677          */
6678         if ((pktinfo->str_retry_cnt++ > st_retry_count) ||
6679             ((queued) && (un->un_runql != bp))) {
6680                 mutex_exit(ST_MUTEX);
6681                 return (-1);
6682         }
6683 
6684         if (queued) {
6685                 /* put the bp back on the waitq */
6686                 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quef, bp);
6687         }
6688 
6689         /*
6690          * Decrement un_ncmds so that this
6691          * gets thru' st_start() again.
6692          */
6693         un->un_ncmds--;
6694 
6695         if (queued) {
6696                 /*
6697                  * since this is an error case, we won't have to do this list
6698                  * walking much. We've already made sure this bp was the
6699                  * last on the runq
6700                  */
6701                 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
6702 
6703                 /*
6704                  * send a marker pkt, if appropriate
6705                  */
6706                 st_hba_unflush(un);
6707 
6708         }
6709         /*
6710          * all queues are aligned, we are just waiting to
6711          * transport, don't alloc any more buf p's, when
6712          * st_start is reentered.
6713          */
6714         (void) timeout(st_start_restart, un, timeout_interval);
6715 
6716         mutex_exit(ST_MUTEX);
6717         return (0);
6718 }
6719 
6720 
6721 /*
6722  * st_runout a callback that is called what a resource allocatation failed
6723  */
6724 static int
6725 st_runout(caddr_t arg)
6726 {
6727         struct scsi_tape *un = (struct scsi_tape *)arg;
6728         struct buf *bp;
6729         int queued;
6730 
6731         ASSERT(un != NULL);
6732 
6733         ST_FUNC(ST_DEVINFO, st_runout);
6734 
6735         mutex_enter(ST_MUTEX);
6736 
6737         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_runout()\n");
6738 
6739         if (un->un_recov_buf_busy != 0) {
6740                 bp = un->un_recov_buf;
6741                 queued = 0;
6742         } else if (un->un_sbuf_busy != 0) {
6743                 /* sbuf commands should only happen with an empty queue. */
6744                 ASSERT(un->un_quef == NULL);
6745                 ASSERT(un->un_runqf == NULL);
6746                 bp = un->un_sbufp;
6747                 queued = 0;
6748         } else if (un->un_quef != NULL) {
6749                 bp = un->un_quef;
6750                 if (un->un_persistence && un->un_persist_errors) {
6751                         mutex_exit(ST_MUTEX);
6752                         bp->b_resid = bp->b_bcount;
6753                         biodone(bp);
6754                         return (1);
6755                 }
6756                 queued = 1;
6757         } else {
6758                 ASSERT(1 == 0);
6759                 mutex_exit(ST_MUTEX);
6760                 return (1);
6761         }
6762 
6763         /*
6764          * failed scsi_init_pkt(). If errno is zero its retryable.
6765          */
6766         if ((bp != NULL) && (geterror(bp) != 0)) {
6767 
6768                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
6769                     "errors after pkt alloc (b_flags=0x%x, b_error=0x%x)\n",
6770                     bp->b_flags, geterror(bp));
6771                 ASSERT((bp->b_flags & B_DONE) == 0);
6772 
6773                 if (queued) {
6774                         (void) st_remove_from_queue(&un->un_quef, &un->un_quel,
6775                             bp);
6776                 }
6777                 mutex_exit(ST_MUTEX);
6778 
6779                 ASSERT((bp->b_flags & B_DONE) == 0);
6780 
6781                 /*
6782                  * Set resid, Error already set, then unblock calling thread.
6783                  */
6784                 bp->b_resid = bp->b_bcount;
6785                 biodone(bp);
6786         } else {
6787                 /*
6788                  * Try Again
6789                  */
6790                 st_start(un);
6791                 mutex_exit(ST_MUTEX);
6792         }
6793 
6794         /*
6795          * Comments courtesy of sd.c
6796          * The scsi_init_pkt routine allows for the callback function to
6797          * return a 0 indicating the callback should be rescheduled or a 1
6798          * indicating not to reschedule. This routine always returns 1
6799          * because the driver always provides a callback function to
6800          * scsi_init_pkt. This results in a callback always being scheduled
6801          * (via the scsi_init_pkt callback implementation) if a resource
6802          * failure occurs.
6803          */
6804 
6805         return (1);
6806 }
6807 
6808 /*
6809  * st_done_and_mutex_exit()
6810  *      - remove bp from runq
6811  *      - start up the next request
6812  *      - if this was an asynch bp, clean up
6813  *      - exit with released mutex
6814  */
6815 static void
6816 st_done_and_mutex_exit(struct scsi_tape *un, struct buf *bp)
6817 {
6818         int pe_flagged = 0;
6819         struct scsi_pkt *pkt = BP_PKT(bp);
6820         pkt_info *pktinfo = pkt->pkt_private;
6821 
6822         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
6823 #if !defined(lint)
6824         _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&un->un_sd->sd_mutex))
6825 #endif
6826 
6827         ST_FUNC(ST_DEVINFO, st_done_and_mutex_exit);
6828 
6829         ASSERT(mutex_owned(ST_MUTEX));
6830 
6831         (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
6832 
6833         un->un_ncmds--;
6834         cv_signal(&un->un_queue_cv);
6835 
6836         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6837             "st_done_and_mutex_exit(): cmd=0x%x count=%ld resid=%ld  flags="
6838             "0x%x\n", pkt->pkt_cdbp[0], bp->b_bcount,
6839             bp->b_resid, bp->b_flags);
6840 
6841 
6842         /*
6843          * update kstats with transfer count info
6844          */
6845         if (un->un_stats && (bp != un->un_sbufp) && IS_RW(bp)) {
6846                 uint32_t n_done =  bp->b_bcount - bp->b_resid;
6847                 if (bp->b_flags & B_READ) {
6848                         IOSP->reads++;
6849                         IOSP->nread += n_done;
6850                 } else {
6851                         IOSP->writes++;
6852                         IOSP->nwritten += n_done;
6853                 }
6854         }
6855 
6856         /*
6857          * Start the next one before releasing resources on this one, if
6858          * there is something on the queue and persistent errors has not been
6859          * flagged
6860          */
6861 
6862         if ((pe_flagged = (un->un_persistence && un->un_persist_errors)) != 0) {
6863                 un->un_last_resid = bp->b_resid;
6864                 un->un_last_count = bp->b_bcount;
6865         }
6866 
6867         if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
6868                 cv_broadcast(&un->un_tape_busy_cv);
6869         } else if (un->un_quef && un->un_throttle && !pe_flagged &&
6870             (bp != un->un_recov_buf)) {
6871                 st_start(un);
6872         }
6873 
6874         un->un_retry_ct = max(pktinfo->pkt_retry_cnt, pktinfo->str_retry_cnt);
6875 
6876         if (bp == un->un_sbufp && (bp->b_flags & B_ASYNC)) {
6877                 /*
6878                  * Since we marked this ourselves as ASYNC,
6879                  * there isn't anybody around waiting for
6880                  * completion any more.
6881                  */
6882                 uchar_t *cmd = pkt->pkt_cdbp;
6883                 if (*cmd == SCMD_READ || *cmd == SCMD_WRITE) {
6884                         bp->b_un.b_addr = (caddr_t)0;
6885                 }
6886                 ST_DEBUG(ST_DEVINFO, st_label, CE_NOTE,
6887                     "st_done_and_mutex_exit(async): freeing pkt\n");
6888                 st_print_cdb(ST_DEVINFO, st_label, CE_NOTE,
6889                     "CDB sent with B_ASYNC",  (caddr_t)cmd);
6890                 if (pkt) {
6891                         scsi_destroy_pkt(pkt);
6892                 }
6893                 un->un_sbuf_busy = 0;
6894                 cv_signal(&un->un_sbuf_cv);
6895                 mutex_exit(ST_MUTEX);
6896                 return;
6897         }
6898 
6899         if (bp == un->un_sbufp && BP_UCMD(bp)) {
6900                 /*
6901                  * Copy status from scsi_pkt to uscsi_cmd
6902                  * since st_uscsi_cmd needs it
6903                  */
6904                 BP_UCMD(bp)->uscsi_status = SCBP_C(BP_PKT(bp));
6905         }
6906 
6907 
6908 #ifdef STDEBUG
6909         if (((st_debug & 0x7) >= 4) &&
6910             (((un->un_pos.blkno % 100) == 0) ||
6911             (un->un_persistence && un->un_persist_errors))) {
6912 
6913                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6914                     "st_d_a_m_exit(): ncmds = %d, thr = %d, "
6915                     "un_errno = %d, un_pe = %d\n",
6916                     un->un_ncmds, un->un_throttle, un->un_errno,
6917                     un->un_persist_errors);
6918         }
6919 
6920 #endif
6921 
6922         mutex_exit(ST_MUTEX);
6923         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6924             "st_done_and_mutex_exit: freeing pkt\n");
6925 
6926         if (pkt) {
6927                 scsi_destroy_pkt(pkt);
6928         }
6929 
6930         biodone(bp);
6931 
6932         /*
6933          * now that we biodoned that command, if persistent errors have been
6934          * flagged, flush the waitq
6935          */
6936         if (pe_flagged)
6937                 st_flush(un);
6938 }
6939 
6940 
6941 /*
6942  * Tape error, flush tape driver queue.
6943  */
6944 static void
6945 st_flush(struct scsi_tape *un)
6946 {
6947         struct buf *bp;
6948 
6949         ST_FUNC(ST_DEVINFO, st_flush);
6950 
6951         mutex_enter(ST_MUTEX);
6952 
6953         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6954             "st_flush(), ncmds = %d, quef = 0x%p\n",
6955             un->un_ncmds, (void *)un->un_quef);
6956 
6957         /*
6958          * if we still have commands outstanding, wait for them to come in
6959          * before flushing the queue, and make sure there is a queue
6960          */
6961         if (un->un_ncmds || !un->un_quef)
6962                 goto exit;
6963 
6964         /*
6965          * we have no more commands outstanding, so let's deal with special
6966          * cases in the queue for EOM and FM. If we are here, and un_errno
6967          * is 0, then we know there was no error and we return a 0 read or
6968          * write before showing errors
6969          */
6970 
6971         /* Flush the wait queue. */
6972         while ((bp = un->un_quef) != NULL) {
6973                 un->un_quef = bp->b_actf;
6974 
6975                 bp->b_resid = bp->b_bcount;
6976 
6977                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6978                     "st_flush() : blkno=%d, err=%d, b_bcount=%ld\n",
6979                     un->un_pos.blkno, un->un_errno, bp->b_bcount);
6980 
6981                 st_set_pe_errno(un);
6982 
6983                 bioerror(bp, un->un_errno);
6984 
6985                 mutex_exit(ST_MUTEX);
6986                 /* it should have one, but check anyway */
6987                 if (BP_PKT(bp)) {
6988                         scsi_destroy_pkt(BP_PKT(bp));
6989                 }
6990                 biodone(bp);
6991                 mutex_enter(ST_MUTEX);
6992         }
6993 
6994         /*
6995          * It's not a bad practice to reset the
6996          * waitq tail pointer to NULL.
6997          */
6998         un->un_quel = NULL;
6999 
7000 exit:
7001         /* we mucked with the queue, so let others know about it */
7002         cv_signal(&un->un_queue_cv);
7003         mutex_exit(ST_MUTEX);
7004 }
7005 
7006 
7007 /*
7008  * Utility functions
7009  */
7010 static int
7011 st_determine_generic(struct scsi_tape *un)
7012 {
7013         int bsize;
7014         static char *cart = "0.25 inch cartridge";
7015         char *sizestr;
7016 
7017         ST_FUNC(ST_DEVINFO, st_determine_generic);
7018 
7019         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7020             "st_determine_generic(un = 0x%p)\n", (void*)un);
7021 
7022         ASSERT(mutex_owned(ST_MUTEX));
7023 
7024         if (st_modesense(un)) {
7025                 return (-1);
7026         }
7027 
7028         bsize = (un->un_mspl->high_bl << 16)        |
7029             (un->un_mspl->mid_bl << 8)      |
7030             (un->un_mspl->low_bl);
7031 
7032         if (bsize == 0) {
7033                 un->un_dp->options |= ST_VARIABLE;
7034                 un->un_dp->bsize = 0;
7035                 un->un_bsize = 0;
7036         } else if (bsize > ST_MAXRECSIZE_FIXED) {
7037                 /*
7038                  * record size of this device too big.
7039                  * try and convert it to variable record length.
7040                  *
7041                  */
7042                 un->un_dp->options |= ST_VARIABLE;
7043                 if (st_change_block_size(un, 0) != 0) {
7044                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
7045                             "Fixed Record Size %d is too large\n", bsize);
7046                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
7047                             "Cannot switch to variable record size\n");
7048                         un->un_dp->options &= ~ST_VARIABLE;
7049                         return (-1);
7050                 }
7051         } else if (st_change_block_size(un, 0) == 0) {
7052                 /*
7053                  * If the drive was set to a non zero block size,
7054                  * See if it can be set to a zero block size.
7055                  * If it works, ST_VARIABLE so user can set it as they want.
7056                  */
7057                 un->un_dp->options |= ST_VARIABLE;
7058                 un->un_dp->bsize = 0;
7059                 un->un_bsize = 0;
7060         } else {
7061                 un->un_dp->bsize = bsize;
7062                 un->un_bsize = bsize;
7063         }
7064 
7065 
7066         switch (un->un_mspl->density) {
7067         default:
7068         case 0x0:
7069                 /*
7070                  * default density, cannot determine any other
7071                  * information.
7072                  */
7073                 sizestr = "Unknown type- assuming 0.25 inch cartridge";
7074                 un->un_dp->type = ST_TYPE_DEFAULT;
7075                 un->un_dp->options |= (ST_AUTODEN_OVERRIDE|ST_QIC);
7076                 break;
7077         case 0x1:
7078         case 0x2:
7079         case 0x3:
7080         case 0x6:
7081                 /*
7082                  * 1/2" reel
7083                  */
7084                 sizestr = "0.50 inch reel";
7085                 un->un_dp->type = ST_TYPE_REEL;
7086                 un->un_dp->options |= ST_REEL;
7087                 un->un_dp->densities[0] = 0x1;
7088                 un->un_dp->densities[1] = 0x2;
7089                 un->un_dp->densities[2] = 0x6;
7090                 un->un_dp->densities[3] = 0x3;
7091                 break;
7092         case 0x4:
7093         case 0x5:
7094         case 0x7:
7095         case 0x0b:
7096 
7097                 /*
7098                  * Quarter inch.
7099                  */
7100                 sizestr = cart;
7101                 un->un_dp->type = ST_TYPE_DEFAULT;
7102                 un->un_dp->options |= ST_QIC;
7103 
7104                 un->un_dp->densities[1] = 0x4;
7105                 un->un_dp->densities[2] = 0x5;
7106                 un->un_dp->densities[3] = 0x7;
7107                 un->un_dp->densities[0] = 0x0b;
7108                 break;
7109 
7110         case 0x0f:
7111         case 0x10:
7112         case 0x11:
7113         case 0x12:
7114                 /*
7115                  * QIC-120, QIC-150, QIC-320, QIC-600
7116                  */
7117                 sizestr = cart;
7118                 un->un_dp->type = ST_TYPE_DEFAULT;
7119                 un->un_dp->options |= ST_QIC;
7120                 un->un_dp->densities[0] = 0x0f;
7121                 un->un_dp->densities[1] = 0x10;
7122                 un->un_dp->densities[2] = 0x11;
7123                 un->un_dp->densities[3] = 0x12;
7124                 break;
7125 
7126         case 0x09:
7127         case 0x0a:
7128         case 0x0c:
7129         case 0x0d:
7130                 /*
7131                  * 1/2" cartridge tapes. Include HI-TC.
7132                  */
7133                 sizestr = cart;
7134                 sizestr[2] = '5';
7135                 sizestr[3] = '0';
7136                 un->un_dp->type = ST_TYPE_HIC;
7137                 un->un_dp->densities[0] = 0x09;
7138                 un->un_dp->densities[1] = 0x0a;
7139                 un->un_dp->densities[2] = 0x0c;
7140                 un->un_dp->densities[3] = 0x0d;
7141                 break;
7142 
7143         case 0x13:
7144                         /* DDS-2/DDS-3 scsi spec densities */
7145         case 0x24:
7146         case 0x25:
7147         case 0x26:
7148                 sizestr = "DAT Data Storage (DDS)";
7149                 un->un_dp->type = ST_TYPE_DAT;
7150                 un->un_dp->options |= ST_AUTODEN_OVERRIDE;
7151                 break;
7152 
7153         case 0x14:
7154                 /*
7155                  * Helical Scan (Exabyte) devices
7156                  */
7157                 sizestr = "8mm helical scan cartridge";
7158                 un->un_dp->type = ST_TYPE_EXABYTE;
7159                 un->un_dp->options |= ST_AUTODEN_OVERRIDE;
7160                 break;
7161         }
7162 
7163         /*
7164          * Assume LONG ERASE, BSF and BSR
7165          */
7166 
7167         un->un_dp->options |=
7168             (ST_LONG_ERASE | ST_UNLOADABLE | ST_BSF | ST_BSR | ST_KNOWS_EOD);
7169 
7170         /*
7171          * Only if mode sense data says no buffered write, set NOBUF
7172          */
7173         if (un->un_mspl->bufm == 0)
7174                 un->un_dp->options |= ST_NOBUF;
7175 
7176         /*
7177          * set up large read and write retry counts
7178          */
7179 
7180         un->un_dp->max_rretries = un->un_dp->max_wretries = 1000;
7181 
7182         /*
7183          * If this is a 0.50 inch reel tape, and
7184          * it is *not* variable mode, try and
7185          * set it to variable record length
7186          * mode.
7187          */
7188         if ((un->un_dp->options & ST_REEL) && un->un_bsize != 0 &&
7189             (un->un_dp->options & ST_VARIABLE)) {
7190                 if (st_change_block_size(un, 0) == 0) {
7191                         un->un_dp->bsize = 0;
7192                         un->un_mspl->high_bl = un->un_mspl->mid_bl =
7193                             un->un_mspl->low_bl = 0;
7194                 }
7195         }
7196 
7197         /*
7198          * Write to console about type of device found
7199          */
7200         ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
7201             "Generic Drive, Vendor=%s\n\t%s", un->un_dp->name,
7202             sizestr);
7203         if (un->un_dp->options & ST_VARIABLE) {
7204                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7205                     "!Variable record length I/O\n");
7206         } else {
7207                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7208                     "!Fixed record length (%d byte blocks) I/O\n",
7209                     un->un_dp->bsize);
7210         }
7211         ASSERT(mutex_owned(ST_MUTEX));
7212         return (0);
7213 }
7214 
7215 static int
7216 st_determine_density(struct scsi_tape *un, int rw)
7217 {
7218         int rval = 0;
7219 
7220         ST_FUNC(ST_DEVINFO, st_determine_density);
7221 
7222         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7223             "st_determine_density(un = 0x%p, rw = %s)\n",
7224             (void*)un, (rw == B_WRITE ? wr_str: rd_str));
7225 
7226         ASSERT(mutex_owned(ST_MUTEX));
7227 
7228         /*
7229          * If we're past BOT, density is determined already.
7230          */
7231         if (un->un_pos.pmode == logical) {
7232                 if (un->un_pos.lgclblkno != 0) {
7233                         goto exit;
7234                 }
7235         } else if (un->un_pos.pmode == legacy) {
7236                 if ((un->un_pos.fileno != 0) || (un->un_pos.blkno != 0)) {
7237                         /*
7238                          * XXX: put in a bitch message about attempting to
7239                          * XXX: change density past BOT.
7240                          */
7241                         goto exit;
7242                 }
7243         } else {
7244                 goto exit;
7245         }
7246         if ((un->un_pos.pmode == logical) &&
7247             (un->un_pos.lgclblkno != 0)) {
7248                 goto exit;
7249         }
7250 
7251 
7252         /*
7253          * If we're going to be writing, we set the density
7254          */
7255         if (rw == 0 || rw == B_WRITE) {
7256                 /* un_curdens is used as an index into densities table */
7257                 un->un_curdens = MT_DENSITY(un->un_dev);
7258                 if (st_set_density(un)) {
7259                         rval = -1;
7260                 }
7261                 goto exit;
7262         }
7263 
7264         /*
7265          * If density is known already,
7266          * we don't have to get it again.(?)
7267          */
7268         if (!un->un_density_known) {
7269                 if (st_get_density(un)) {
7270                         rval = -1;
7271                 }
7272         }
7273 
7274 exit:
7275         ASSERT(mutex_owned(ST_MUTEX));
7276         return (rval);
7277 }
7278 
7279 
7280 /*
7281  * Try to determine density. We do this by attempting to read the
7282  * first record off the tape, cycling through the available density
7283  * codes as we go.
7284  */
7285 
7286 static int
7287 st_get_density(struct scsi_tape *un)
7288 {
7289         int succes = 0, rval = -1, i;
7290         uint_t size;
7291         uchar_t dens, olddens;
7292 
7293         ST_FUNC(ST_DEVINFO, st_get_density);
7294 
7295         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7296             "st_get_density(un = 0x%p)\n", (void*)un);
7297 
7298         ASSERT(mutex_owned(ST_MUTEX));
7299 
7300         /*
7301          * If Auto Density override is enabled The drive has
7302          * only one density and there is no point in attempting
7303          * find the correct one.
7304          *
7305          * Since most modern drives auto detect the density
7306          * and format of the recorded media before they come
7307          * ready. What this function does is a legacy behavior
7308          * and modern drives not only don't need it, The backup
7309          * utilities that do positioning via uscsi find the un-
7310          * expected rewinds problematic.
7311          *
7312          * The drives that need this are old reel to reel devices.
7313          * I took a swag and said they must be scsi-1 or older.
7314          * I don't beleave there will any of the newer devices
7315          * that need this. There will be some scsi-1 devices that
7316          * don't need this but I don't think they will be using the
7317          * BIG aftermarket backup and restore utilitys.
7318          */
7319         if ((un->un_dp->options & ST_AUTODEN_OVERRIDE) ||
7320             (un->un_sd->sd_inq->inq_ansi > 1)) {
7321                 un->un_density_known = 1;
7322                 rval = 0;
7323                 goto exit;
7324         }
7325 
7326         /*
7327          * This will only work on variable record length tapes
7328          * if and only if all variable record length tapes autodensity
7329          * select.
7330          */
7331         size = (unsigned)(un->un_dp->bsize ? un->un_dp->bsize : SECSIZE);
7332         un->un_tmpbuf = kmem_alloc(size, KM_SLEEP);
7333 
7334         /*
7335          * Start at the specified density
7336          */
7337 
7338         dens = olddens = un->un_curdens = MT_DENSITY(un->un_dev);
7339 
7340         for (i = 0; i < NDENSITIES; i++, ((un->un_curdens == NDENSITIES - 1) ?
7341             (un->un_curdens = 0) : (un->un_curdens += 1))) {
7342                 /*
7343                  * If we've done this density before,
7344                  * don't bother to do it again.
7345                  */
7346                 dens = un->un_dp->densities[un->un_curdens];
7347                 if (i > 0 && dens == olddens)
7348                         continue;
7349                 olddens = dens;
7350                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7351                     "trying density 0x%x\n", dens);
7352                 if (st_set_density(un)) {
7353                         continue;
7354                 }
7355 
7356                 /*
7357                  * XXX - the creates lots of headaches and slowdowns - must
7358                  * fix.
7359                  */
7360                 succes = (st_cmd(un, SCMD_READ, (int)size, SYNC_CMD) == 0);
7361                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
7362                         break;
7363                 }
7364                 if (succes) {
7365                         st_init(un);
7366                         rval = 0;
7367                         un->un_density_known = 1;
7368                         break;
7369                 }
7370         }
7371         kmem_free(un->un_tmpbuf, size);
7372         un->un_tmpbuf = 0;
7373 
7374 exit:
7375         ASSERT(mutex_owned(ST_MUTEX));
7376         return (rval);
7377 }
7378 
7379 static int
7380 st_set_density(struct scsi_tape *un)
7381 {
7382         int rval = 0;
7383 
7384         ST_FUNC(ST_DEVINFO, st_set_density);
7385 
7386         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7387             "st_set_density(un = 0x%p): density = 0x%x\n", (void*)un,
7388             un->un_dp->densities[un->un_curdens]);
7389 
7390         ASSERT(mutex_owned(ST_MUTEX));
7391 
7392         un->un_mspl->density = un->un_dp->densities[un->un_curdens];
7393 
7394         if ((un->un_dp->options & ST_AUTODEN_OVERRIDE) == 0) {
7395                 /*
7396                  * If auto density override is not set, Use mode select
7397                  * to set density and compression.
7398                  */
7399                 if (st_modeselect(un)) {
7400                         rval = -1;
7401                 }
7402         } else if ((un->un_dp->options & ST_MODE_SEL_COMP) != 0) {
7403                 /*
7404                  * If auto density and mode select compression are set,
7405                  * This is a drive with one density code but compression
7406                  * can be enabled or disabled.
7407                  * Set compression but no need to set density.
7408                  */
7409                 rval = st_set_compression(un);
7410                 if ((rval != 0) && (rval != EALREADY)) {
7411                         rval = -1;
7412                 } else {
7413                         rval = 0;
7414                 }
7415         }
7416 
7417         /* If sucessful set density and/or compression, mark density known */
7418         if (rval == 0) {
7419                 un->un_density_known = 1;
7420         }
7421 
7422         ASSERT(mutex_owned(ST_MUTEX));
7423         return (rval);
7424 }
7425 
7426 static int
7427 st_loadtape(struct scsi_tape *un)
7428 {
7429         int rval;
7430 
7431         ST_FUNC(ST_DEVINFO, st_loadtape);
7432 
7433         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7434             "st_loadtape(un = 0x%p)\n", (void*) un);
7435 
7436         ASSERT(mutex_owned(ST_MUTEX));
7437 
7438         rval = st_update_block_pos(un, st_cmd, 0);
7439         if (rval == EACCES) {
7440                 return (rval);
7441         }
7442 
7443         /*
7444          * 'LOAD' the tape to BOT by rewinding
7445          */
7446         rval = st_cmd(un, SCMD_REWIND, 1, SYNC_CMD);
7447         if (rval == 0) {
7448                 st_init(un);
7449                 un->un_density_known = 0;
7450         }
7451 
7452         ASSERT(mutex_owned(ST_MUTEX));
7453         return (rval);
7454 }
7455 
7456 
7457 /*
7458  * Note: QIC devices aren't so smart.  If you try to append
7459  * after EOM, the write can fail because the device doesn't know
7460  * it's at EOM.  In that case, issue a read.  The read should fail
7461  * because there's no data, but the device knows it's at EOM,
7462  * so a subsequent write should succeed.  To further confuse matters,
7463  * the target returns the same error if the tape is positioned
7464  * such that a write would overwrite existing data.  That's why
7465  * we have to do the append test.  A read in the middle of
7466  * recorded data would succeed, thus indicating we're attempting
7467  * something illegal.
7468  */
7469 
7470 
7471 static void
7472 st_test_append(struct buf *bp)
7473 {
7474         dev_t dev = bp->b_edev;
7475         struct scsi_tape *un;
7476         uchar_t status;
7477         unsigned bcount;
7478 
7479         un = ddi_get_soft_state(st_state, MTUNIT(dev));
7480 
7481         ST_FUNC(ST_DEVINFO, st_test_append);
7482 
7483         ASSERT(mutex_owned(ST_MUTEX));
7484 
7485         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7486             "st_test_append(): fileno %d\n", un->un_pos.fileno);
7487 
7488         un->un_laststate = un->un_state;
7489         un->un_state = ST_STATE_APPEND_TESTING;
7490         un->un_test_append = 0;
7491 
7492         /*
7493          * first, map in the buffer, because we're doing a double write --
7494          * first into the kernel, then onto the tape.
7495          */
7496         bp_mapin(bp);
7497 
7498         /*
7499          * get a copy of the data....
7500          */
7501         un->un_tmpbuf = kmem_alloc((unsigned)bp->b_bcount, KM_SLEEP);
7502         bcopy(bp->b_un.b_addr, un->un_tmpbuf, (uint_t)bp->b_bcount);
7503 
7504         /*
7505          * attempt the write..
7506          */
7507 
7508         if (st_cmd(un, (int)SCMD_WRITE, (int)bp->b_bcount, SYNC_CMD) == 0) {
7509 success:
7510                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7511                     "append write succeeded\n");
7512                 bp->b_resid = un->un_sbufp->b_resid;
7513                 mutex_exit(ST_MUTEX);
7514                 bcount = (unsigned)bp->b_bcount;
7515                 biodone(bp);
7516                 mutex_enter(ST_MUTEX);
7517                 un->un_laststate = un->un_state;
7518                 un->un_state = ST_STATE_OPEN;
7519                 kmem_free(un->un_tmpbuf, bcount);
7520                 un->un_tmpbuf = NULL;
7521                 return;
7522         }
7523 
7524         /*
7525          * The append failed. Do a short read. If that fails,  we are at EOM
7526          * so we can retry the write command. If that succeeds, than we're
7527          * all screwed up (the controller reported a real error).
7528          *
7529          * XXX: should the dummy read be > SECSIZE? should it be the device's
7530          * XXX: block size?
7531          *
7532          */
7533         status = un->un_status;
7534         un->un_status = 0;
7535         (void) st_cmd(un, SCMD_READ, SECSIZE, SYNC_CMD);
7536         if (un->un_status == KEY_BLANK_CHECK) {
7537                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7538                     "append at EOM\n");
7539                 /*
7540                  * Okay- the read failed. We should actually have confused
7541                  * the controller enough to allow writing. In any case, the
7542                  * i/o is on its own from here on out.
7543                  */
7544                 un->un_laststate = un->un_state;
7545                 un->un_state = ST_STATE_OPEN;
7546                 bcopy(bp->b_un.b_addr, un->un_tmpbuf, (uint_t)bp->b_bcount);
7547                 if (st_cmd(un, (int)SCMD_WRITE, (int)bp->b_bcount,
7548                     SYNC_CMD) == 0) {
7549                         goto success;
7550                 }
7551         }
7552 
7553         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7554             "append write failed- not at EOM\n");
7555         bp->b_resid = bp->b_bcount;
7556         st_bioerror(bp, EIO);
7557 
7558         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
7559             "st_test_append : EIO : append write failed - not at EOM");
7560 
7561         /*
7562          * backspace one record to get back to where we were
7563          */
7564         if (st_cmd(un, SCMD_SPACE, Blk(-1), SYNC_CMD)) {
7565                 un->un_pos.pmode = invalid;
7566         }
7567 
7568         un->un_err_resid = bp->b_resid;
7569         un->un_status = status;
7570 
7571         /*
7572          * Note: biodone will do a bp_mapout()
7573          */
7574         mutex_exit(ST_MUTEX);
7575         bcount = (unsigned)bp->b_bcount;
7576         biodone(bp);
7577         mutex_enter(ST_MUTEX);
7578         un->un_laststate = un->un_state;
7579         un->un_state = ST_STATE_OPEN_PENDING_IO;
7580         kmem_free(un->un_tmpbuf, bcount);
7581         un->un_tmpbuf = NULL;
7582 }
7583 
7584 /*
7585  * Special command handler
7586  */
7587 
7588 /*
7589  * common st_cmd code. The fourth parameter states
7590  * whether the caller wishes to await the results
7591  * Note the release of the mutex during most of the function
7592  */
7593 static int
7594 st_cmd(struct scsi_tape *un, int com, int64_t count, int wait)
7595 {
7596         struct buf *bp;
7597         int err;
7598         uint_t last_err_resid;
7599 
7600         ST_FUNC(ST_DEVINFO, st_cmd);
7601 
7602         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7603             "st_cmd(dev = 0x%lx, com = 0x%x, count = %"PRIx64", wait = %d)\n",
7604             un->un_dev, com, count, wait);
7605 
7606         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
7607         ASSERT(mutex_owned(ST_MUTEX));
7608 
7609 #ifdef STDEBUG
7610         if ((st_debug & 0x7)) {
7611                 st_debug_cmds(un, com, count, wait);
7612         }
7613 #endif
7614 
7615         st_wait_for_io(un);
7616 
7617         /* check to see if this command requires the drive to be reserved */
7618         err = st_check_cmd_for_need_to_reserve(un, com, count);
7619 
7620         if (err) {
7621                 return (err);
7622         }
7623 
7624         /*
7625          * A space command is not recoverable if we don't know were we
7626          * were when it was issued.
7627          */
7628         if ((com == SCMD_SPACE) || (com == SCMD_SPACE_G4)) {
7629                 (void) st_update_block_pos(un, st_cmd, 0);
7630         }
7631 
7632         /*
7633          * Forground should not be doing anything while recovery is active.
7634          */
7635         ASSERT(un->un_recov_buf_busy == 0);
7636 
7637         while (un->un_sbuf_busy)
7638                 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
7639         un->un_sbuf_busy = 1;
7640 
7641         bp = un->un_sbufp;
7642         bzero(bp, sizeof (buf_t));
7643 
7644         bp->b_flags = (wait) ? B_BUSY : B_BUSY|B_ASYNC;
7645 
7646         err = st_setup_cmd(un, bp, com, count);
7647 
7648         un->un_sbuf_busy = 0;
7649 
7650         /*
7651          * If was a space command need to update logical block position.
7652          * Only do this if the command was sucessful or it will mask the fact
7653          * that the space command failed by promoting the pmode to logical.
7654          */
7655         if (((com == SCMD_SPACE) || (com == SCMD_SPACE_G4)) &&
7656             (un->un_pos.pmode != invalid)) {
7657                 un->un_running.pmode = invalid;
7658                 last_err_resid = un->un_err_resid;
7659                 (void) st_update_block_pos(un, st_cmd, 1);
7660                 /*
7661                  * Set running position to invalid so it updates on the
7662                  * next command.
7663                  */
7664                 un->un_running.pmode = invalid;
7665                 un->un_err_resid = last_err_resid;
7666         }
7667 
7668         cv_signal(&un->un_sbuf_cv);
7669 
7670         return (err);
7671 }
7672 
7673 static int
7674 st_setup_cmd(struct scsi_tape *un, buf_t *bp, int com, int64_t count)
7675 {
7676         int err;
7677         dev_t dev = un->un_dev;
7678 
7679         ST_FUNC(ST_DEVINFO, st_setup_cmd);
7680         /*
7681          * Set count to the actual size of the data tranfer.
7682          * For commands with no data transfer, set bp->b_bcount
7683          * to the value to be used when constructing the
7684          * cdb in st_make_cmd().
7685          */
7686         switch (com) {
7687         case SCMD_READ:
7688                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7689                     "special read %"PRId64"\n", count);
7690                 bp->b_flags |= B_READ;
7691                 bp->b_un.b_addr = un->un_tmpbuf;
7692                 break;
7693 
7694         case SCMD_WRITE:
7695                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7696                     "special write %"PRId64"\n", count);
7697                 bp->b_un.b_addr = un->un_tmpbuf;
7698                 break;
7699 
7700         case SCMD_WRITE_FILE_MARK:
7701                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7702                     "write %"PRId64" file marks\n", count);
7703                 bp->b_bcount = count;
7704                 count = 0;
7705                 break;
7706 
7707         case SCMD_REWIND:
7708                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "rewind\n");
7709                 bp->b_bcount = count;
7710                 count = 0;
7711                 break;
7712 
7713         case SCMD_SPACE:
7714                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "space\n");
7715                 /*
7716                  * If the user could have entered a number that will
7717                  * not fit in the 12 bit count field of space(8),
7718                  * use space(16).
7719                  */
7720                 if (((int64_t)SPACE_CNT(count) > 0x7fffff) ||
7721                     ((int64_t)SPACE_CNT(count) < -(0x7fffff))) {
7722                         com = SCMD_SPACE_G4;
7723                 }
7724                 bp->b_bcount = count;
7725                 count = 0;
7726                 break;
7727 
7728         case SCMD_RESERVE:
7729                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "reserve");
7730                 bp->b_bcount = 0;
7731                 count = 0;
7732                 break;
7733 
7734         case SCMD_RELEASE:
7735                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "release");
7736                 bp->b_bcount = 0;
7737                 count = 0;
7738                 break;
7739 
7740         case SCMD_LOAD:
7741                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7742                     "%s tape\n", (count & LD_LOAD) ? "load" : "unload");
7743                 bp->b_bcount = count;
7744                 count = 0;
7745                 break;
7746 
7747         case SCMD_ERASE:
7748                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7749                     "erase tape\n");
7750                 bp->b_bcount = count;
7751                 count = 0;
7752                 break;
7753 
7754         case SCMD_MODE_SENSE:
7755                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7756                     "mode sense\n");
7757                 bp->b_flags |= B_READ;
7758                 bp->b_un.b_addr = (caddr_t)(un->un_mspl);
7759                 break;
7760 
7761         case SCMD_MODE_SELECT:
7762                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7763                     "mode select\n");
7764                 bp->b_un.b_addr = (caddr_t)(un->un_mspl);
7765                 break;
7766 
7767         case SCMD_READ_BLKLIM:
7768                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7769                     "read block limits\n");
7770                 bp->b_bcount = count;
7771                 bp->b_flags |= B_READ;
7772                 bp->b_un.b_addr = (caddr_t)(un->un_rbl);
7773                 break;
7774 
7775         case SCMD_TEST_UNIT_READY:
7776                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7777                     "test unit ready\n");
7778                 bp->b_bcount = 0;
7779                 count = 0;
7780                 break;
7781 
7782         case SCMD_DOORLOCK:
7783                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7784                     "%s tape\n", (count & MR_LOCK) ? "lock" : "unlock");
7785                 bp->b_bcount = count = 0;
7786                 break;
7787 
7788         case SCMD_READ_POSITION:
7789                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7790                     "read position\n");
7791                 switch (un->un_read_pos_type) {
7792                 case LONG_POS:
7793                         count = sizeof (tape_position_long_t);
7794                         break;
7795                 case EXT_POS:
7796                         count = min(count, sizeof (tape_position_ext_t));
7797                         break;
7798                 case SHORT_POS:
7799                         count = sizeof (tape_position_t);
7800                         break;
7801                 default:
7802                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
7803                             "Unknown read position type 0x%x in "
7804                             "st_make_cmd()\n", un->un_read_pos_type);
7805                 }
7806                 bp->b_bcount = count;
7807                 bp->b_flags |= B_READ;
7808                 bp->b_un.b_addr = (caddr_t)un->un_read_pos_data;
7809                 break;
7810 
7811         default:
7812                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
7813                     "Unhandled scsi command 0x%x in st_setup_cmd()\n", com);
7814         }
7815 
7816         mutex_exit(ST_MUTEX);
7817 
7818         if (count > 0) {
7819                 int flg = (bp->b_flags & B_READ) ? B_READ : B_WRITE;
7820                 /*
7821                  * We're going to do actual I/O.
7822                  * Set things up for physio.
7823                  */
7824                 struct iovec aiov;
7825                 struct uio auio;
7826                 struct uio *uio = &auio;
7827 
7828                 bzero(&auio, sizeof (struct uio));
7829                 bzero(&aiov, sizeof (struct iovec));
7830                 aiov.iov_base = bp->b_un.b_addr;
7831                 aiov.iov_len = count;
7832 
7833                 uio->uio_iov = &aiov;
7834                 uio->uio_iovcnt = 1;
7835                 uio->uio_resid = aiov.iov_len;
7836                 uio->uio_segflg = UIO_SYSSPACE;
7837 
7838                 /*
7839                  * Let physio do the rest...
7840                  */
7841                 bp->b_forw = (struct buf *)(uintptr_t)com;
7842                 bp->b_back = NULL;
7843                 err = physio(st_strategy, bp, dev, flg, st_minphys, uio);
7844                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7845                     "st_setup_cmd: physio returns %d\n", err);
7846         } else {
7847                 /*
7848                  * Mimic physio
7849                  */
7850                 bp->b_forw = (struct buf *)(uintptr_t)com;
7851                 bp->b_back = NULL;
7852                 bp->b_edev = dev;
7853                 bp->b_dev = cmpdev(dev);
7854                 bp->b_blkno = 0;
7855                 bp->b_resid = 0;
7856                 (void) st_strategy(bp);
7857                 if (bp->b_flags & B_ASYNC) {
7858                         /*
7859                          * This is an async command- the caller won't wait
7860                          * and doesn't care about errors.
7861                          */
7862                         mutex_enter(ST_MUTEX);
7863                         return (0);
7864                 }
7865 
7866                 /*
7867                  * BugTraq #4260046
7868                  * ----------------
7869                  * Restore Solaris 2.5.1 behavior, namely call biowait
7870                  * unconditionally. The old comment said...
7871                  *
7872                  * "if strategy was flagged with  persistent errors, we would
7873                  *  have an error here, and the bp would never be sent, so we
7874                  *  don't want to wait on a bp that was never sent...or hang"
7875                  *
7876                  * The new rationale, courtesy of Chitrank...
7877                  *
7878                  * "we should unconditionally biowait() here because
7879                  *  st_strategy() will do a biodone() in the persistent error
7880                  *  case and the following biowait() will return immediately.
7881                  *  If not, in the case of "errors after pkt alloc" in
7882                  *  st_start(), we will not biowait here which will cause the
7883                  *  next biowait() to return immediately which will cause
7884                  *  us to send out the next command. In the case where both of
7885                  *  these use the sbuf, when the first command completes we'll
7886                  *  free the packet attached to sbuf and the same pkt will
7887                  *  get freed again when we complete the second command.
7888                  *  see esc 518987.  BTW, it is necessary to do biodone() in
7889                  *  st_start() for the pkt alloc failure case because physio()
7890                  *  does biowait() and will hang if we don't do biodone()"
7891                  */
7892 
7893                 err = biowait(bp);
7894                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7895                     "st_setup_cmd: biowait returns %d\n", err);
7896         }
7897 
7898         mutex_enter(ST_MUTEX);
7899 
7900         return (err);
7901 }
7902 
7903 static int
7904 st_set_compression(struct scsi_tape *un)
7905 {
7906         int rval;
7907         int turn_compression_on;
7908         minor_t minor;
7909 
7910         ST_FUNC(ST_DEVINFO, st_set_compression);
7911 
7912         /*
7913          * Drive either dosn't have compression or it is controlled with
7914          * special density codes. Return ENOTTY so caller
7915          * knows nothing was done.
7916          */
7917         if ((un->un_dp->options & ST_MODE_SEL_COMP) == 0) {
7918                 un->un_comp_page = 0;
7919                 return (ENOTTY);
7920         }
7921 
7922         /* set compression based on minor node opened */
7923         minor = MT_DENSITY(un->un_dev);
7924 
7925         /*
7926          * If this the compression density or
7927          * the drive has two densities and uses mode select for
7928          * control of compression turn on compression for MT_DENSITY2
7929          * as well.
7930          */
7931         if ((minor == ST_COMPRESSION_DENSITY) ||
7932             (minor == MT_DENSITY(MT_DENSITY2)) &&
7933             (un->un_dp->densities[0] == un->un_dp->densities[1]) &&
7934             (un->un_dp->densities[2] == un->un_dp->densities[3]) &&
7935             (un->un_dp->densities[0] != un->un_dp->densities[2])) {
7936 
7937                 turn_compression_on = 1;
7938         } else {
7939                 turn_compression_on = 0;
7940         }
7941 
7942         un->un_mspl->high_bl = (uchar_t)(un->un_bsize >> 16);
7943         un->un_mspl->mid_bl  = (uchar_t)(un->un_bsize >> 8);
7944         un->un_mspl->low_bl  = (uchar_t)(un->un_bsize);
7945 
7946         /*
7947          * Need to determine which page does the device use for compression.
7948          * First try the data compression page. If this fails try the device
7949          * configuration page
7950          */
7951 
7952         if ((un->un_comp_page & ST_DEV_DATACOMP_PAGE) == ST_DEV_DATACOMP_PAGE) {
7953                 rval = st_set_datacomp_page(un, turn_compression_on);
7954                 if (rval == EALREADY) {
7955                         return (rval);
7956                 }
7957                 if (rval != 0) {
7958                         if (un->un_status == KEY_ILLEGAL_REQUEST) {
7959                                 /*
7960                                  * This device does not support data
7961                                  * compression page
7962                                  */
7963                                 un->un_comp_page = ST_DEV_CONFIG_PAGE;
7964                         } else if (un->un_state >= ST_STATE_OPEN) {
7965                                 un->un_pos.pmode = invalid;
7966                                 rval = EIO;
7967                         } else {
7968                                 rval = -1;
7969                         }
7970                 } else {
7971                         un->un_comp_page = ST_DEV_DATACOMP_PAGE;
7972                 }
7973         }
7974 
7975         if ((un->un_comp_page & ST_DEV_CONFIG_PAGE) == ST_DEV_CONFIG_PAGE) {
7976                 rval = st_set_devconfig_page(un, turn_compression_on);
7977                 if (rval == EALREADY) {
7978                         return (rval);
7979                 }
7980                 if (rval != 0) {
7981                         if (un->un_status == KEY_ILLEGAL_REQUEST) {
7982                                 /*
7983                                  * This device does not support
7984                                  * compression at all advice the
7985                                  * user and unset ST_MODE_SEL_COMP
7986                                  */
7987                                 un->un_dp->options &= ~ST_MODE_SEL_COMP;
7988                                 un->un_comp_page = 0;
7989                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7990                                     "Device Does Not Support Compression\n");
7991                         } else if (un->un_state >= ST_STATE_OPEN) {
7992                                 un->un_pos.pmode = invalid;
7993                                 rval = EIO;
7994                         } else {
7995                                 rval = -1;
7996                         }
7997                 }
7998         }
7999 
8000         return (rval);
8001 }
8002 
8003 /*
8004  * set or unset compression thru device configuration page.
8005  */
8006 static int
8007 st_set_devconfig_page(struct scsi_tape *un, int compression_on)
8008 {
8009         unsigned char cflag;
8010         int rval = 0;
8011 
8012 
8013         ST_FUNC(ST_DEVINFO, st_set_devconfig_page);
8014 
8015         ASSERT(mutex_owned(ST_MUTEX));
8016 
8017         /*
8018          * if the mode sense page is not the correct one, load the correct one.
8019          */
8020         if (un->un_mspl->page_code != ST_DEV_CONFIG_PAGE) {
8021                 rval = st_gen_mode_sense(un, st_uscsi_cmd, ST_DEV_CONFIG_PAGE,
8022                     un->un_mspl, sizeof (struct seq_mode));
8023                 if (rval)
8024                         return (rval);
8025         }
8026 
8027         /*
8028          * Figure what to set compression flag to.
8029          */
8030         if (compression_on) {
8031                 /* They have selected a compression node */
8032                 if (un->un_dp->type == ST_TYPE_FUJI) {
8033                         cflag = 0x84;   /* use EDRC */
8034                 } else {
8035                         cflag = ST_DEV_CONFIG_DEF_COMP;
8036                 }
8037         } else {
8038                 cflag = ST_DEV_CONFIG_NO_COMP;
8039         }
8040 
8041         /*
8042          * If compression is already set the way it was requested.
8043          * And if this not the first time we has tried.
8044          */
8045         if ((cflag == un->un_mspl->page.dev.comp_alg) &&
8046             (un->un_comp_page == ST_DEV_CONFIG_PAGE)) {
8047                 return (EALREADY);
8048         }
8049 
8050         un->un_mspl->page.dev.comp_alg = cflag;
8051         /*
8052          * need to send mode select even if correct compression is
8053          * already set since need to set density code
8054          */
8055 
8056 #ifdef STDEBUG
8057         if ((st_debug & 0x7) >= 6) {
8058                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
8059                     "st_set_devconfig_page: sense data for mode select",
8060                     (char *)un->un_mspl, sizeof (struct seq_mode));
8061         }
8062 #endif
8063         rval = st_gen_mode_select(un, st_uscsi_cmd, un->un_mspl,
8064             sizeof (struct seq_mode));
8065 
8066         return (rval);
8067 }
8068 
8069 /*
8070  * set/reset compression bit thru data compression page
8071  */
8072 static int
8073 st_set_datacomp_page(struct scsi_tape *un, int compression_on)
8074 {
8075         int compression_on_already;
8076         int rval = 0;
8077 
8078 
8079         ST_FUNC(ST_DEVINFO, st_set_datacomp_page);
8080 
8081         ASSERT(mutex_owned(ST_MUTEX));
8082 
8083         /*
8084          * if the mode sense page is not the correct one, load the correct one.
8085          */
8086         if (un->un_mspl->page_code != ST_DEV_DATACOMP_PAGE) {
8087                 rval = st_gen_mode_sense(un, st_uscsi_cmd, ST_DEV_DATACOMP_PAGE,
8088                     un->un_mspl, sizeof (struct seq_mode));
8089                 if (rval)
8090                         return (rval);
8091         }
8092 
8093         /*
8094          * If drive is not capable of compression (at this time)
8095          * return EALREADY so caller doesn't think that this page
8096          * is not supported. This check is for drives that can
8097          * disable compression from the front panel or configuration.
8098          * I doubt that a drive that supports this page is not really
8099          * capable of compression.
8100          */
8101         if (un->un_mspl->page.comp.dcc == 0) {
8102                 return (EALREADY);
8103         }
8104 
8105         /* See if compression currently turned on */
8106         if (un->un_mspl->page.comp.dce) {
8107                 compression_on_already = 1;
8108         } else {
8109                 compression_on_already = 0;
8110         }
8111 
8112         /*
8113          * If compression is already set the way it was requested.
8114          * And if this not the first time we has tried.
8115          */
8116         if ((compression_on == compression_on_already) &&
8117             (un->un_comp_page == ST_DEV_DATACOMP_PAGE)) {
8118                 return (EALREADY);
8119         }
8120 
8121         /*
8122          * if we are already set to the appropriate compression
8123          * mode, don't set it again
8124          */
8125         if (compression_on) {
8126                 /* compression selected */
8127                 un->un_mspl->page.comp.dce = 1;
8128         } else {
8129                 un->un_mspl->page.comp.dce = 0;
8130         }
8131 
8132 
8133 #ifdef STDEBUG
8134         if ((st_debug & 0x7) >= 6) {
8135                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
8136                     "st_set_datacomp_page: sense data for mode select",
8137                     (char *)un->un_mspl, sizeof (struct seq_mode));
8138         }
8139 #endif
8140         rval = st_gen_mode_select(un, st_uscsi_cmd, un->un_mspl,
8141             sizeof (struct seq_mode));
8142 
8143         return (rval);
8144 }
8145 
8146 static int
8147 st_modesense(struct scsi_tape *un)
8148 {
8149         int rval;
8150         uchar_t page;
8151 
8152         ST_FUNC(ST_DEVINFO, st_modesense);
8153 
8154         page = un->un_comp_page;
8155 
8156         switch (page) {
8157         case ST_DEV_DATACOMP_PAGE:
8158         case ST_DEV_CONFIG_PAGE: /* FALLTHROUGH */
8159                 rval = st_gen_mode_sense(un, st_uscsi_cmd, page, un->un_mspl,
8160                     sizeof (struct seq_mode));
8161                 break;
8162 
8163         case ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE:
8164                 if (un->un_dp->options & ST_MODE_SEL_COMP) {
8165                         page = ST_DEV_DATACOMP_PAGE;
8166                         rval = st_gen_mode_sense(un, st_uscsi_cmd, page,
8167                             un->un_mspl, sizeof (struct seq_mode));
8168                         if (rval == 0 && un->un_mspl->page_code == page) {
8169                                 un->un_comp_page = page;
8170                                 break;
8171                         }
8172                         page = ST_DEV_CONFIG_PAGE;
8173                         rval = st_gen_mode_sense(un, st_uscsi_cmd, page,
8174                             un->un_mspl, sizeof (struct seq_mode));
8175                         if (rval == 0 && un->un_mspl->page_code == page) {
8176                                 un->un_comp_page = page;
8177                                 break;
8178                         }
8179                         un->un_dp->options &= ~ST_MODE_SEL_COMP;
8180                         un->un_comp_page = 0;
8181                 } else {
8182                         un->un_comp_page = 0;
8183                 }
8184 
8185         default:        /* FALLTHROUGH */
8186                 rval = st_cmd(un, SCMD_MODE_SENSE, MSIZE, SYNC_CMD);
8187         }
8188         return (rval);
8189 }
8190 
8191 static int
8192 st_modeselect(struct scsi_tape *un)
8193 {
8194         int rval = 0;
8195         int ix;
8196 
8197         ST_FUNC(ST_DEVINFO, st_modeselect);
8198 
8199         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8200             "st_modeselect(dev = 0x%lx): density = 0x%x\n",
8201             un->un_dev, un->un_mspl->density);
8202 
8203         ASSERT(mutex_owned(ST_MUTEX));
8204 
8205         /*
8206          * The parameter list should be the same for all of the
8207          * cases that follow so set them here
8208          *
8209          * Try mode select first if if fails set fields manually
8210          */
8211         rval = st_modesense(un);
8212         if (rval != 0) {
8213                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
8214                     "st_modeselect: First mode sense failed\n");
8215                 un->un_mspl->bd_len  = 8;
8216                 un->un_mspl->high_nb = 0;
8217                 un->un_mspl->mid_nb  = 0;
8218                 un->un_mspl->low_nb  = 0;
8219         }
8220         un->un_mspl->high_bl = (uchar_t)(un->un_bsize >> 16);
8221         un->un_mspl->mid_bl  = (uchar_t)(un->un_bsize >> 8);
8222         un->un_mspl->low_bl  = (uchar_t)(un->un_bsize);
8223 
8224 
8225         /*
8226          * If configured to use a specific density code for a media type.
8227          * curdens is previously set by the minor node opened.
8228          * If the media type doesn't match the minor node we change it so it
8229          * looks like the correct one was opened.
8230          */
8231         if (un->un_dp->options & ST_KNOWS_MEDIA) {
8232                 uchar_t best;
8233 
8234                 for (best = 0xff, ix = 0; ix < NDENSITIES; ix++) {
8235                         if (un->un_mspl->media_type ==
8236                             un->un_dp->mediatype[ix]) {
8237                                 best = ix;
8238                                 /*
8239                                  * It matches but it might not be the only one.
8240                                  * Use the highest matching media type but not
8241                                  * to exceed the density selected by the open.
8242                                  */
8243                                 if (ix < un->un_curdens) {
8244                                         continue;
8245                                 }
8246                                 un->un_curdens = ix;
8247                                 break;
8248                         }
8249                 }
8250                 /* If a match was found best will not be 0xff any more */
8251                 if (best < NDENSITIES) {
8252                         ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
8253                             "found media 0x%X using density 0x%X\n",
8254                             un->un_mspl->media_type,
8255                             un->un_dp->densities[best]);
8256                         un->un_mspl->density = un->un_dp->densities[best];
8257                 } else {
8258                         /* Otherwise set density based on minor node opened */
8259                         un->un_mspl->density =
8260                             un->un_dp->densities[un->un_curdens];
8261                 }
8262         } else {
8263                 un->un_mspl->density = un->un_dp->densities[un->un_curdens];
8264         }
8265 
8266         if (un->un_dp->options & ST_NOBUF) {
8267                 un->un_mspl->bufm = 0;
8268         } else {
8269                 un->un_mspl->bufm = 1;
8270         }
8271 
8272         rval = st_set_compression(un);
8273 
8274         /*
8275          * If st_set_compression returned invalid or already it
8276          * found no need to do the mode select.
8277          * So do it here.
8278          */
8279         if ((rval == ENOTTY) || (rval == EALREADY)) {
8280 
8281                 /* Zero non-writeable fields */
8282                 un->un_mspl->data_len = 0;
8283                 un->un_mspl->media_type = 0;
8284                 un->un_mspl->wp = 0;
8285 
8286                 /* need to set the density code */
8287                 rval = st_cmd(un, SCMD_MODE_SELECT, MSIZE, SYNC_CMD);
8288                 if (rval != 0) {
8289                         if (un->un_state >= ST_STATE_OPEN) {
8290                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
8291                                     "unable to set tape mode\n");
8292                                 un->un_pos.pmode = invalid;
8293                                 rval = EIO;
8294                         } else {
8295                                 rval = -1;
8296                         }
8297                 }
8298         }
8299 
8300         /*
8301          * The spec recommends to send a mode sense after a mode select
8302          */
8303         (void) st_modesense(un);
8304 
8305         ASSERT(mutex_owned(ST_MUTEX));
8306 
8307         return (rval);
8308 }
8309 
8310 /*
8311  * st_gen_mode_sense
8312  *
8313  * generic mode sense.. it allows for any page
8314  */
8315 static int
8316 st_gen_mode_sense(struct scsi_tape *un, ubufunc_t ubf, int page,
8317     struct seq_mode *page_data, int page_size)
8318 {
8319 
8320         int r;
8321         char    cdb[CDB_GROUP0];
8322         struct uscsi_cmd *com;
8323         struct scsi_arq_status status;
8324 
8325         ST_FUNC(ST_DEVINFO, st_gen_mode_sense);
8326 
8327         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8328 
8329         bzero(cdb, CDB_GROUP0);
8330         cdb[0] = SCMD_MODE_SENSE;
8331         cdb[2] = (char)page;
8332         cdb[4] = (char)page_size;
8333 
8334         com->uscsi_cdb = cdb;
8335         com->uscsi_cdblen = CDB_GROUP0;
8336         com->uscsi_bufaddr = (caddr_t)page_data;
8337         com->uscsi_buflen = page_size;
8338         com->uscsi_rqlen = sizeof (status);
8339         com->uscsi_rqbuf = (caddr_t)&status;
8340         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8341         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8342 
8343         r = ubf(un, com, FKIOCTL);
8344         kmem_free(com, sizeof (*com));
8345         return (r);
8346 }
8347 
8348 /*
8349  * st_gen_mode_select
8350  *
8351  * generic mode select.. it allows for any page
8352  */
8353 static int
8354 st_gen_mode_select(struct scsi_tape *un, ubufunc_t ubf,
8355     struct seq_mode *page_data, int page_size)
8356 {
8357 
8358         int r;
8359         char cdb[CDB_GROUP0];
8360         struct uscsi_cmd *com;
8361         struct scsi_arq_status status;
8362 
8363         ST_FUNC(ST_DEVINFO, st_gen_mode_select);
8364 
8365         /* Zero non-writeable fields */
8366         page_data->data_len = 0;
8367         page_data->media_type = 0;
8368         page_data->wp = 0;
8369 
8370         /*
8371          * If mode select has any page data, zero the ps (Page Savable) bit.
8372          */
8373         if (page_size > MSIZE) {
8374                 page_data->ps = 0;
8375         }
8376 
8377 
8378         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8379 
8380         /*
8381          * then, do a mode select to set what ever info
8382          */
8383         bzero(cdb, CDB_GROUP0);
8384         cdb[0] = SCMD_MODE_SELECT;
8385         cdb[1] = 0x10;          /* set PF bit for many third party drives */
8386         cdb[4] = (char)page_size;
8387 
8388         com->uscsi_cdb = cdb;
8389         com->uscsi_cdblen = CDB_GROUP0;
8390         com->uscsi_bufaddr = (caddr_t)page_data;
8391         com->uscsi_buflen = page_size;
8392         com->uscsi_rqlen = sizeof (status);
8393         com->uscsi_rqbuf = (caddr_t)&status;
8394         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8395         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_WRITE;
8396 
8397         r = ubf(un, com, FKIOCTL);
8398 
8399         kmem_free(com, sizeof (*com));
8400         return (r);
8401 }
8402 
8403 static int
8404 st_read_block_limits(struct scsi_tape *un, struct read_blklim *read_blk)
8405 {
8406         int rval;
8407         char cdb[CDB_GROUP0];
8408         struct uscsi_cmd *com;
8409         struct scsi_arq_status status;
8410 
8411         ST_FUNC(ST_DEVINFO, st_read_block_limits);
8412 
8413         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8414 
8415         bzero(cdb, CDB_GROUP0);
8416         cdb[0] = SCMD_READ_BLKLIM;
8417 
8418         com->uscsi_cdb = cdb;
8419         com->uscsi_cdblen = CDB_GROUP0;
8420         com->uscsi_bufaddr = (caddr_t)read_blk;
8421         com->uscsi_buflen = sizeof (struct read_blklim);
8422         com->uscsi_rqlen = sizeof (status);
8423         com->uscsi_rqbuf = (caddr_t)&status;
8424         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8425         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8426 
8427         rval = st_uscsi_cmd(un, com, FKIOCTL);
8428         if (com->uscsi_status || com->uscsi_resid) {
8429                 rval = -1;
8430         }
8431 
8432         kmem_free(com, sizeof (*com));
8433         return (rval);
8434 }
8435 
8436 static int
8437 st_report_density_support(struct scsi_tape *un, uchar_t *density_data,
8438     size_t buflen)
8439 {
8440         int rval;
8441         char cdb[CDB_GROUP1];
8442         struct uscsi_cmd *com;
8443         struct scsi_arq_status status;
8444 
8445         ST_FUNC(ST_DEVINFO, st_report_density_support);
8446 
8447         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8448 
8449         bzero(cdb, CDB_GROUP1);
8450         cdb[0] = SCMD_REPORT_DENSITIES;
8451         cdb[7] = (buflen & 0xff00) >> 8;
8452         cdb[8] = buflen & 0xff;
8453 
8454         com->uscsi_cdb = cdb;
8455         com->uscsi_cdblen = CDB_GROUP1;
8456         com->uscsi_bufaddr = (caddr_t)density_data;
8457         com->uscsi_buflen = buflen;
8458         com->uscsi_rqlen = sizeof (status);
8459         com->uscsi_rqbuf = (caddr_t)&status;
8460         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8461         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8462 
8463         rval = st_uscsi_cmd(un, com, FKIOCTL);
8464         if (com->uscsi_status || com->uscsi_resid) {
8465                 rval = -1;
8466         }
8467 
8468         kmem_free(com, sizeof (*com));
8469         return (rval);
8470 }
8471 
8472 static int
8473 st_report_supported_operation(struct scsi_tape *un, uchar_t *oper_data,
8474     uchar_t option_code, ushort_t service_action)
8475 {
8476         int rval;
8477         char cdb[CDB_GROUP5];
8478         struct uscsi_cmd *com;
8479         struct scsi_arq_status status;
8480         uint32_t allo_length;
8481 
8482         ST_FUNC(ST_DEVINFO, st_report_supported_operation);
8483 
8484         allo_length = sizeof (struct one_com_des) +
8485             sizeof (struct com_timeout_des);
8486         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8487 
8488         bzero(cdb, CDB_GROUP5);
8489         cdb[0] = (char)SCMD_MAINTENANCE_IN;
8490         cdb[1] = SSVC_ACTION_GET_SUPPORTED_OPERATIONS;
8491         if (service_action) {
8492                 cdb[2] = (char)(ONE_COMMAND_DATA_FORMAT | 0x80); /* RCTD */
8493                 cdb[4] = (service_action & 0xff00) >> 8;
8494                 cdb[5] = service_action & 0xff;
8495         } else {
8496                 cdb[2] = (char)(ONE_COMMAND_NO_SERVICE_DATA_FORMAT |
8497                     0x80); /* RCTD */
8498         }
8499         cdb[3] = option_code;
8500         cdb[6] = (allo_length & 0xff000000) >> 24;
8501         cdb[7] = (allo_length & 0xff0000) >> 16;
8502         cdb[8] = (allo_length & 0xff00) >> 8;
8503         cdb[9] = allo_length & 0xff;
8504 
8505         com->uscsi_cdb = cdb;
8506         com->uscsi_cdblen = CDB_GROUP5;
8507         com->uscsi_bufaddr = (caddr_t)oper_data;
8508         com->uscsi_buflen = allo_length;
8509         com->uscsi_rqlen = sizeof (status);
8510         com->uscsi_rqbuf = (caddr_t)&status;
8511         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8512         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8513 
8514         rval = st_uscsi_cmd(un, com, FKIOCTL);
8515         if (com->uscsi_status) {
8516                 rval = -1;
8517         }
8518 
8519         kmem_free(com, sizeof (*com));
8520         return (rval);
8521 }
8522 
8523 /*
8524  * Changes devices blocksize and bsize to requested blocksize nblksz.
8525  * Returns returned value from first failed call or zero on success.
8526  */
8527 static int
8528 st_change_block_size(struct scsi_tape *un, uint32_t nblksz)
8529 {
8530         struct seq_mode *current;
8531         int rval;
8532         uint32_t oldblksz;
8533 
8534         ST_FUNC(ST_DEVINFO, st_change_block_size);
8535 
8536         current = kmem_zalloc(MSIZE, KM_SLEEP);
8537 
8538         /*
8539          * If we haven't got the compression page yet, do that first.
8540          */
8541         if (un->un_comp_page == (ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE)) {
8542                 (void) st_modesense(un);
8543         }
8544 
8545         /* Read current settings */
8546         rval = st_gen_mode_sense(un, st_uscsi_cmd, 0, current, MSIZE);
8547         if (rval != 0) {
8548                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8549                     "mode sense for change block size failed: rval = %d", rval);
8550                 goto finish;
8551         }
8552 
8553         /* Figure the current block size */
8554         oldblksz =
8555             (current->high_bl << 16) |
8556             (current->mid_bl << 8) |
8557             (current->low_bl);
8558 
8559         /* If current block size is the same as requested were done */
8560         if (oldblksz == nblksz) {
8561                 un->un_bsize = nblksz;
8562                 rval = 0;
8563                 goto finish;
8564         }
8565 
8566         /* Change to requested block size */
8567         current->high_bl = (uchar_t)(nblksz >> 16);
8568         current->mid_bl  = (uchar_t)(nblksz >> 8);
8569         current->low_bl  = (uchar_t)(nblksz);
8570 
8571         /* Attempt to change block size */
8572         rval = st_gen_mode_select(un, st_uscsi_cmd, current, MSIZE);
8573         if (rval != 0) {
8574                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8575                     "Set new block size failed: rval = %d", rval);
8576                 goto finish;
8577         }
8578 
8579         /* Read back and verify setting */
8580         rval = st_modesense(un);
8581         if (rval == 0) {
8582                 un->un_bsize =
8583                     (un->un_mspl->high_bl << 16) |
8584                     (un->un_mspl->mid_bl << 8) |
8585                     (un->un_mspl->low_bl);
8586 
8587                 if (un->un_bsize != nblksz) {
8588                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8589                             "Blocksize set does not equal requested blocksize"
8590                             "(read: %u requested: %u)\n", nblksz, un->un_bsize);
8591                         rval = EIO;
8592                 }
8593         }
8594 finish:
8595         kmem_free(current, MSIZE);
8596         return (rval);
8597 }
8598 
8599 
8600 static void
8601 st_init(struct scsi_tape *un)
8602 {
8603         ST_FUNC(ST_DEVINFO, st_init);
8604 
8605         ASSERT(mutex_owned(ST_MUTEX));
8606 
8607         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8608             "st_init(): dev = 0x%lx, will reset fileno, blkno, eof\n",
8609             un->un_dev);
8610 
8611         un->un_pos.blkno = 0;
8612         un->un_pos.fileno = 0;
8613         un->un_lastop = ST_OP_NIL;
8614         un->un_pos.eof = ST_NO_EOF;
8615         un->un_pwr_mgmt = ST_PWR_NORMAL;
8616         if (st_error_level != SCSI_ERR_ALL) {
8617                 if (DEBUGGING) {
8618                         st_error_level = SCSI_ERR_ALL;
8619                 } else {
8620                         st_error_level = SCSI_ERR_RETRYABLE;
8621                 }
8622         }
8623 }
8624 
8625 
8626 static void
8627 st_make_cmd(struct scsi_tape *un, struct buf *bp, int (*func)(caddr_t))
8628 {
8629         struct scsi_pkt *pkt;
8630         struct uscsi_cmd *ucmd;
8631         recov_info *ri;
8632         int tval = 0;
8633         int64_t count;
8634         uint32_t additional = 0;
8635         uint32_t address = 0;
8636         union scsi_cdb *ucdb;
8637         int flags = 0;
8638         int cdb_len = CDB_GROUP0; /* default */
8639         uchar_t com;
8640         char fixbit;
8641         char short_fm = 0;
8642         optype prev_op = un->un_lastop;
8643         int stat_size =
8644             (un->un_arq_enabled ? sizeof (struct scsi_arq_status) : 1);
8645 
8646         ST_FUNC(ST_DEVINFO, st_make_cmd);
8647 
8648         ASSERT(mutex_owned(ST_MUTEX));
8649 
8650         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8651             "st_make_cmd(): dev = 0x%lx\n", un->un_dev);
8652 
8653 
8654         /*
8655          * fixbit is for setting the Fixed Mode and Suppress Incorrect
8656          * Length Indicator bits on read/write commands, for setting
8657          * the Long bit on erase commands, and for setting the Code
8658          * Field bits on space commands.
8659          */
8660 
8661         /* regular raw I/O */
8662         if ((bp != un->un_sbufp) && (bp != un->un_recov_buf)) {
8663                 pkt = scsi_init_pkt(ROUTE, NULL, bp,
8664                     CDB_GROUP0, stat_size, st_recov_sz, 0, func,
8665                     (caddr_t)un);
8666                 if (pkt == NULL) {
8667                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
8668                             "Read Write scsi_init_pkt() failure\n");
8669                         goto exit;
8670                 }
8671                 ASSERT(pkt->pkt_resid == 0);
8672 #ifdef STDEBUG
8673                 bzero(pkt->pkt_private, st_recov_sz);
8674                 bzero(pkt->pkt_scbp, stat_size);
8675 #endif
8676                 ri = (recov_info *)pkt->pkt_private;
8677                 ri->privatelen = st_recov_sz;
8678                 if (un->un_bsize == 0) {
8679                         count = bp->b_bcount;
8680                         fixbit = 0;
8681                 } else {
8682                         count = bp->b_bcount / un->un_bsize;
8683                         fixbit = 1;
8684                 }
8685                 if (bp->b_flags & B_READ) {
8686                         com = SCMD_READ;
8687                         un->un_lastop = ST_OP_READ;
8688                         if ((un->un_bsize == 0) && /* Not Fixed Block */
8689                             (un->un_dp->options & ST_READ_IGNORE_ILI)) {
8690                                 fixbit = 2;
8691                         }
8692                 } else {
8693                         com = SCMD_WRITE;
8694                         un->un_lastop = ST_OP_WRITE;
8695                 }
8696                 tval = un->un_dp->io_timeout;
8697 
8698                 /*
8699                  * For really large xfers, increase timeout
8700                  */
8701                 if (bp->b_bcount > (10 * ONE_MEG))
8702                         tval *= bp->b_bcount/(10 * ONE_MEG);
8703 
8704                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8705                     "%s %d amt 0x%lx\n", (com == SCMD_WRITE) ?
8706                     wr_str: rd_str, un->un_pos.blkno, bp->b_bcount);
8707 
8708         } else if ((ucmd = BP_UCMD(bp)) != NULL) {
8709                 /*
8710                  * uscsi - build command, allocate scsi resources
8711                  */
8712                 st_make_uscsi_cmd(un, ucmd, bp, func);
8713                 goto exit;
8714 
8715         } else {                                /* special I/O */
8716                 struct buf *allocbp = NULL;
8717                 com = (uchar_t)(uintptr_t)bp->b_forw;
8718                 count = bp->b_bcount;
8719 
8720                 switch (com) {
8721                 case SCMD_READ:
8722                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8723                             "special read %"PRId64"\n", count);
8724                         if (un->un_bsize == 0) {
8725                                 fixbit = 2;     /* suppress SILI */
8726                         } else {
8727                                 fixbit = 1;     /* Fixed Block Mode */
8728                                 count /= un->un_bsize;
8729                         }
8730                         allocbp = bp;
8731                         un->un_lastop = ST_OP_READ;
8732                         tval = un->un_dp->io_timeout;
8733                         break;
8734 
8735                 case SCMD_WRITE:
8736                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8737                             "special write %"PRId64"\n", count);
8738                         if (un->un_bsize != 0) {
8739                                 fixbit = 1;     /* Fixed Block Mode */
8740                                 count /= un->un_bsize;
8741                         } else {
8742                                 fixbit = 0;
8743                         }
8744                         allocbp = bp;
8745                         un->un_lastop = ST_OP_WRITE;
8746                         tval = un->un_dp->io_timeout;
8747                         break;
8748 
8749                 case SCMD_WRITE_FILE_MARK:
8750                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8751                             "write %"PRId64" file marks\n", count);
8752                         un->un_lastop = ST_OP_WEOF;
8753                         fixbit = 0;
8754                         tval = un->un_dp->io_timeout;
8755                         /*
8756                          * If ST_SHORT_FILEMARKS bit is ON for EXABYTE
8757                          * device, set the Vendor Unique bit to
8758                          * write Short File Mark.
8759                          */
8760                         if ((un->un_dp->options & ST_SHORT_FILEMARKS) &&
8761                             ((un->un_dp->type == ST_TYPE_EXB8500) ||
8762                             (un->un_dp->type == ST_TYPE_EXABYTE))) {
8763                                 /*
8764                                  * Now the Vendor Unique bit 7 in Byte 5 of CDB
8765                                  * is set to to write Short File Mark
8766                                  */
8767                                 short_fm = 1;
8768                         }
8769                         break;
8770 
8771                 case SCMD_REWIND:
8772                         /*
8773                          * In the case of rewind we're gona do the rewind with
8774                          * the immediate bit set so status will be retured when
8775                          * the command is accepted by the device. We clear the
8776                          * B_ASYNC flag so we wait for that acceptance.
8777                          */
8778                         fixbit = 0;
8779                         if (bp->b_flags & B_ASYNC) {
8780                                 allocbp = bp;
8781                                 if (count) {
8782                                         fixbit = 1;
8783                                         bp->b_flags &= ~B_ASYNC;
8784                                 }
8785                         }
8786                         count = 0;
8787                         bp->b_bcount = 0;
8788                         un->un_lastop = ST_OP_CTL;
8789                         tval = un->un_dp->rewind_timeout;
8790                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8791                             "rewind\n");
8792                         break;
8793 
8794                 case SCMD_SPACE_G4:
8795                         cdb_len = CDB_GROUP4;
8796                         fixbit = SPACE_TYPE(bp->b_bcount);
8797                         count = SPACE_CNT(bp->b_bcount);
8798                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
8799                             " %s space %s %"PRId64" from file %d blk %d\n",
8800                             bp->b_bcount & SP_BACKSP ? "backward" : "forward",
8801                             space_strs[fixbit & 7], count,
8802                             un->un_pos.fileno, un->un_pos.blkno);
8803                         address = (count >> 48) & 0x1fff;
8804                         additional = (count >> 16) & 0xffffffff;
8805                         count &= 0xffff;
8806                         count <<= 16;
8807                         un->un_lastop = ST_OP_CTL;
8808                         tval = un->un_dp->space_timeout;
8809                         break;
8810 
8811                 case SCMD_SPACE:
8812                         fixbit = SPACE_TYPE(bp->b_bcount);
8813                         count = SPACE_CNT(bp->b_bcount);
8814                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8815                             " %s space %s %"PRId64" from file %d blk %d\n",
8816                             bp->b_bcount & SP_BACKSP ? "backward" : "forward",
8817                             space_strs[fixbit & 7], count,
8818                             un->un_pos.fileno, un->un_pos.blkno);
8819                         count &= 0xffffffff;
8820                         un->un_lastop = ST_OP_CTL;
8821                         tval = un->un_dp->space_timeout;
8822                         break;
8823 
8824                 case SCMD_LOAD:
8825                         ASSERT(count < 10);
8826                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8827                             "%s tape\n", load_strs[count]);
8828                         fixbit = 0;
8829 
8830                         /* Loading or Unloading */
8831                         if (count & LD_LOAD) {
8832                                 tval = un->un_dp->load_timeout;
8833                         } else {
8834                                 tval = un->un_dp->unload_timeout;
8835                         }
8836                         /* Is Retension requested */
8837                         if (count & LD_RETEN) {
8838                                 tval += un->un_dp->rewind_timeout;
8839                         }
8840                         un->un_lastop = ST_OP_CTL;
8841                         break;
8842 
8843                 case SCMD_ERASE:
8844                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8845                             "erase tape\n");
8846                         ASSERT(count == 1); /* mt sets this */
8847                         if (count == 1) {
8848                                 /*
8849                                  * do long erase
8850                                  */
8851                                 fixbit = 1; /* Long */
8852 
8853                                 /* Drive might not honor immidiate bit */
8854                                 tval = un->un_dp->erase_timeout;
8855                         } else {
8856                                 /* Short Erase */
8857                                 tval = un->un_dp->erase_timeout;
8858                                 fixbit = 0;
8859                         }
8860                         un->un_lastop = ST_OP_CTL;
8861                         count = 0;
8862                         break;
8863 
8864                 case SCMD_MODE_SENSE:
8865                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8866                             "mode sense\n");
8867                         allocbp = bp;
8868                         fixbit = 0;
8869                         tval = un->un_dp->non_motion_timeout;
8870                         un->un_lastop = ST_OP_CTL;
8871                         break;
8872 
8873                 case SCMD_MODE_SELECT:
8874                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8875                             "mode select\n");
8876                         allocbp = bp;
8877                         fixbit = 0;
8878                         tval = un->un_dp->non_motion_timeout;
8879                         un->un_lastop = ST_OP_CTL;
8880                         break;
8881 
8882                 case SCMD_RESERVE:
8883                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8884                             "reserve\n");
8885                         fixbit = 0;
8886                         tval = un->un_dp->non_motion_timeout;
8887                         un->un_lastop = ST_OP_CTL;
8888                         break;
8889 
8890                 case SCMD_RELEASE:
8891                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8892                             "release\n");
8893                         fixbit = 0;
8894                         tval = un->un_dp->non_motion_timeout;
8895                         un->un_lastop = ST_OP_CTL;
8896                         break;
8897 
8898                 case SCMD_READ_BLKLIM:
8899                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8900                             "read block limits\n");
8901                         allocbp = bp;
8902                         fixbit = count = 0;
8903                         tval = un->un_dp->non_motion_timeout;
8904                         un->un_lastop = ST_OP_CTL;
8905                         break;
8906 
8907                 case SCMD_TEST_UNIT_READY:
8908                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8909                             "test unit ready\n");
8910                         fixbit = 0;
8911                         tval = un->un_dp->non_motion_timeout;
8912                         un->un_lastop = ST_OP_CTL;
8913                         break;
8914 
8915                 case SCMD_DOORLOCK:
8916                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8917                             "prevent/allow media removal\n");
8918                         fixbit = 0;
8919                         tval = un->un_dp->non_motion_timeout;
8920                         un->un_lastop = ST_OP_CTL;
8921                         break;
8922 
8923                 case SCMD_READ_POSITION:
8924                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8925                             "read position\n");
8926                         fixbit = un->un_read_pos_type;
8927                         cdb_len = CDB_GROUP1;
8928                         tval = un->un_dp->non_motion_timeout;
8929                         allocbp = bp;
8930                         un->un_lastop = ST_OP_CTL;
8931                         switch (un->un_read_pos_type) {
8932                         case LONG_POS:
8933                                 count = 0;
8934                                 break;
8935                         case EXT_POS:
8936                                 count = sizeof (tape_position_ext_t);
8937                                 break;
8938                         case SHORT_POS:
8939                                 count = 0;
8940                                 break;
8941                         default:
8942                                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
8943                                     "Unknown read position type 0x%x in "
8944                                     " st_make_cmd()\n", un->un_read_pos_type);
8945                         }
8946                         break;
8947 
8948                 default:
8949                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
8950                             "Unhandled scsi command 0x%x in st_make_cmd()\n",
8951                             com);
8952                 }
8953 
8954                 pkt = scsi_init_pkt(ROUTE, NULL, allocbp, cdb_len, stat_size,
8955                     st_recov_sz, 0, func, (caddr_t)un);
8956                 if (pkt == NULL) {
8957                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
8958                             "generic command scsi_init_pkt() failure\n");
8959                         goto exit;
8960                 }
8961 
8962                 ASSERT(pkt->pkt_resid == 0);
8963 #ifdef STDEBUG
8964                 bzero(pkt->pkt_private, st_recov_sz);
8965                 bzero(pkt->pkt_scbp, stat_size);
8966 #endif
8967                 ri = (recov_info *)pkt->pkt_private;
8968                 ri->privatelen = st_recov_sz;
8969                 if (allocbp) {
8970                         ASSERT(geterror(allocbp) == 0);
8971                 }
8972 
8973         }
8974 
8975         ucdb = (union scsi_cdb *)pkt->pkt_cdbp;
8976 
8977         (void) scsi_setup_cdb(ucdb, com, address, (uint_t)count, additional);
8978         FILL_SCSI1_LUN(un->un_sd, pkt);
8979         /*
8980          * Initialize the SILI/Fixed bits of the byte 1 of cdb.
8981          */
8982         ucdb->t_code = fixbit;
8983         ucdb->g0_vu_1 = short_fm;
8984         pkt->pkt_flags = flags;
8985 
8986         ASSERT(tval);
8987         pkt->pkt_time = tval;
8988         if (bp == un->un_recov_buf) {
8989                 pkt->pkt_comp = st_recov_cb;
8990         } else {
8991                 pkt->pkt_comp = st_intr;
8992         }
8993 
8994         st_add_recovery_info_to_pkt(un, bp, pkt);
8995 
8996         /*
8997          * If we just write data to tape and did a command that doesn't
8998          * change position, we still need to write a filemark.
8999          */
9000         if ((prev_op == ST_OP_WRITE) || (prev_op == ST_OP_WEOF)) {
9001                 recov_info *rcvi = pkt->pkt_private;
9002                 cmd_attribute const *atrib;
9003 
9004                 if (rcvi->privatelen == sizeof (recov_info)) {
9005                         atrib = rcvi->cmd_attrib;
9006                 } else {
9007                         atrib = st_lookup_cmd_attribute(com);
9008                 }
9009                 if (atrib->chg_tape_direction == DIR_NONE) {
9010                         un->un_lastop = prev_op;
9011                 }
9012         }
9013 
9014 exit:
9015         ASSERT(mutex_owned(ST_MUTEX));
9016 }
9017 
9018 
9019 /*
9020  * Build a command based on a uscsi command;
9021  */
9022 static void
9023 st_make_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *ucmd,
9024     struct buf *bp, int (*func)(caddr_t))
9025 {
9026         struct scsi_pkt *pkt;
9027         recov_info *ri;
9028         caddr_t cdb;
9029         int     cdblen;
9030         int     stat_size = 1;
9031         int     flags = 0;
9032 
9033         ST_FUNC(ST_DEVINFO, st_make_uscsi_cmd);
9034 
9035         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9036             "st_make_uscsi_cmd(): dev = 0x%lx\n", un->un_dev);
9037 
9038         if (ucmd->uscsi_flags & USCSI_RQENABLE) {
9039                 if (un->un_arq_enabled) {
9040                         if (ucmd->uscsi_rqlen > SENSE_LENGTH) {
9041                                 stat_size = (int)(ucmd->uscsi_rqlen) +
9042                                     sizeof (struct scsi_arq_status) -
9043                                     sizeof (struct scsi_extended_sense);
9044                                 flags = PKT_XARQ;
9045                         } else {
9046                                 stat_size = sizeof (struct scsi_arq_status);
9047                         }
9048                 }
9049         }
9050 
9051         ASSERT(mutex_owned(ST_MUTEX));
9052 
9053         cdb = ucmd->uscsi_cdb;
9054         cdblen = ucmd->uscsi_cdblen;
9055 
9056         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
9057             "st_make_uscsi_cmd: buflen=%ld bcount=%ld\n",
9058             ucmd->uscsi_buflen, bp->b_bcount);
9059         pkt = scsi_init_pkt(ROUTE, NULL,
9060             (bp->b_bcount > 0) ? bp : NULL,
9061             cdblen, stat_size, st_recov_sz, flags, func, (caddr_t)un);
9062         if (pkt == NULL) {
9063                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
9064                     "uscsi command scsi_init_pkt() failure\n");
9065                 goto exit;
9066         }
9067 
9068         ASSERT(pkt->pkt_resid == 0);
9069 #ifdef STDEBUG
9070         bzero(pkt->pkt_private, st_recov_sz);
9071         bzero(pkt->pkt_scbp, stat_size);
9072 #endif
9073         ri = (recov_info *)pkt->pkt_private;
9074         ri->privatelen = st_recov_sz;
9075 
9076         bcopy(cdb, pkt->pkt_cdbp, (uint_t)cdblen);
9077 
9078 #ifdef STDEBUG
9079         if ((st_debug & 0x7) >= 6) {
9080                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
9081                     "pkt_cdbp", (char *)cdb, cdblen);
9082         }
9083 #endif
9084 
9085         if (ucmd->uscsi_flags & USCSI_SILENT) {
9086                 pkt->pkt_flags |= FLAG_SILENT;
9087         }
9088 
9089         (void) scsi_uscsi_pktinit(ucmd, pkt);
9090 
9091         pkt->pkt_time = ucmd->uscsi_timeout;
9092         if (bp == un->un_recov_buf) {
9093                 pkt->pkt_comp = st_recov_cb;
9094         } else {
9095                 pkt->pkt_comp = st_intr;
9096         }
9097 
9098         st_add_recovery_info_to_pkt(un, bp, pkt);
9099 exit:
9100         ASSERT(mutex_owned(ST_MUTEX));
9101 }
9102 
9103 
9104 /*
9105  * restart cmd currently at the head of the runq
9106  *
9107  * If scsi_transport() succeeds or the retries
9108  * count exhausted, restore the throttle that was
9109  * zeroed out in st_handle_intr_busy().
9110  *
9111  */
9112 static void
9113 st_intr_restart(void *arg)
9114 {
9115         struct scsi_tape *un = arg;
9116         struct buf *bp;
9117         int queued;
9118         int status = TRAN_ACCEPT;
9119 
9120         mutex_enter(ST_MUTEX);
9121 
9122         ST_FUNC(ST_DEVINFO, st_intr_restart);
9123 
9124         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9125             "st_intr_restart(), un = 0x%p\n", (void *)un);
9126 
9127         un->un_hib_tid = 0;
9128 
9129         if (un->un_recov_buf_busy != 0) {
9130                 bp = un->un_recov_buf;
9131                 queued = 0;
9132         } else if (un->un_sbuf_busy != 0) {
9133                 bp = un->un_sbufp;
9134                 queued = 0;
9135         } else if (un->un_quef != NULL) {
9136                 bp = un->un_quef;
9137                 queued = 1;
9138         } else {
9139                 mutex_exit(ST_MUTEX);
9140                 return;
9141         }
9142 
9143         /*
9144          * Here we know :
9145          *      throttle = 0, via st_handle_intr_busy
9146          */
9147 
9148         if (queued) {
9149                 /*
9150                  * move from waitq to runq, if there is anything on the waitq
9151                  */
9152                 (void) st_remove_from_queue(&un->un_quef, &un->un_quef, bp);
9153 
9154                 if (un->un_runqf) {
9155                         /*
9156                          * not good, we don't want to requeue something after
9157                          * another.
9158                          */
9159                         goto done_error;
9160                 } else {
9161                         un->un_runqf = bp;
9162                         un->un_runql = bp;
9163                 }
9164         }
9165 
9166         ST_CDB(ST_DEVINFO, "Interrupt restart CDB",
9167             (char *)BP_PKT(bp)->pkt_cdbp);
9168 
9169         ST_DO_KSTATS(bp, kstat_waitq_to_runq);
9170 
9171         status = st_transport(un, BP_PKT(bp));
9172 
9173         if (status != TRAN_ACCEPT) {
9174                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9175 
9176                 if (status == TRAN_BUSY) {
9177                         pkt_info *pkti = BP_PKT(bp)->pkt_private;
9178 
9179                         if (pkti->privatelen == sizeof (recov_info) &&
9180                             un->un_unit_attention_flags &&
9181                             bp != un->un_recov_buf) {
9182                         un->un_unit_attention_flags = 0;
9183                                 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
9184                                     "Command Recovery called on busy resend\n");
9185                                 if (st_command_recovery(un, BP_PKT(bp),
9186                                     ATTEMPT_RETRY) == JUST_RETURN) {
9187                                         mutex_exit(ST_MUTEX);
9188                                         return;
9189                                 }
9190                         }
9191                         mutex_exit(ST_MUTEX);
9192                         if (st_handle_intr_busy(un, bp,
9193                             ST_TRAN_BUSY_TIMEOUT) == 0)
9194                                 return; /* timeout is setup again */
9195                         mutex_enter(ST_MUTEX);
9196                 }
9197 
9198 done_error:
9199                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
9200                     "restart transport rejected\n");
9201                 bp->b_resid = bp->b_bcount;
9202 
9203                 if (un->un_last_throttle) {
9204                         un->un_throttle = un->un_last_throttle;
9205                 }
9206                 if (status != TRAN_ACCEPT) {
9207                         ST_DO_ERRSTATS(un, st_transerrs);
9208                 }
9209                 ST_DO_KSTATS(bp, kstat_waitq_exit);
9210                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
9211                     "busy restart aborted\n");
9212                 st_set_pe_flag(un);
9213                 st_bioerror(bp, EIO);
9214                 st_done_and_mutex_exit(un, bp);
9215         } else {
9216                 if (un->un_last_throttle) {
9217                         un->un_throttle = un->un_last_throttle;
9218                 }
9219                 mutex_exit(ST_MUTEX);
9220         }
9221 }
9222 
9223 /*
9224  * st_check_media():
9225  * Periodically check the media state using scsi_watch service;
9226  * this service calls back after TUR and possibly request sense
9227  * the callback handler (st_media_watch_cb()) decodes the request sense
9228  * data (if any)
9229  */
9230 
9231 static int
9232 st_check_media(dev_t dev, enum mtio_state state)
9233 {
9234         int rval = 0;
9235         enum mtio_state prev_state;
9236         opaque_t token = NULL;
9237 
9238         GET_SOFT_STATE(dev);
9239 
9240         ST_FUNC(ST_DEVINFO, st_check_media);
9241 
9242         mutex_enter(ST_MUTEX);
9243 
9244         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9245             "st_check_media:state=%x, mediastate=%x\n",
9246             state, un->un_mediastate);
9247 
9248         prev_state = un->un_mediastate;
9249 
9250         /*
9251          * is there anything to do?
9252          */
9253 retry:
9254         if (state == un->un_mediastate || un->un_mediastate == MTIO_NONE) {
9255                 /*
9256                  * submit the request to the scsi_watch service;
9257                  * scsi_media_watch_cb() does the real work
9258                  */
9259                 mutex_exit(ST_MUTEX);
9260                 token = scsi_watch_request_submit(ST_SCSI_DEVP,
9261                     st_check_media_time, SENSE_LENGTH,
9262                     st_media_watch_cb, (caddr_t)dev);
9263                 if (token == NULL) {
9264                         rval = EAGAIN;
9265                         goto done;
9266                 }
9267                 mutex_enter(ST_MUTEX);
9268 
9269                 un->un_swr_token = token;
9270                 un->un_specified_mediastate = state;
9271 
9272                 /*
9273                  * now wait for media change
9274                  * we will not be signalled unless mediastate == state but it
9275                  * still better to test for this condition, since there
9276                  * is a 5 sec cv_broadcast delay when
9277                  *  mediastate == MTIO_INSERTED
9278                  */
9279                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9280                     "st_check_media:waiting for media state change\n");
9281                 while (un->un_mediastate == state) {
9282                         if (cv_wait_sig(&un->un_state_cv, ST_MUTEX) == 0) {
9283                                 mutex_exit(ST_MUTEX);
9284                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9285                                     "st_check_media:waiting for media state "
9286                                     "was interrupted\n");
9287                                 rval = EINTR;
9288                                 goto done;
9289                         }
9290                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9291                             "st_check_media:received signal, state=%x\n",
9292                             un->un_mediastate);
9293                 }
9294         }
9295 
9296         /*
9297          * if we transitioned to MTIO_INSERTED, media has really been
9298          * inserted.  If TUR fails, it is probably a exabyte slow spin up.
9299          * Reset and retry the state change.  If everything is ok, replay
9300          * the open() logic.
9301          */
9302         if ((un->un_mediastate == MTIO_INSERTED) &&
9303             (un->un_state == ST_STATE_OFFLINE)) {
9304                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9305                     "st_check_media: calling st_cmd to confirm inserted\n");
9306 
9307                 /*
9308                  * set this early so that TUR will make it through strategy
9309                  * without triggering a st_tape_init().  We needed it set
9310                  * before calling st_tape_init() ourselves anyway.  If TUR
9311                  * fails, set it back
9312                  */
9313                 un->un_state = ST_STATE_INITIALIZING;
9314 
9315                 /*
9316                  * If not reserved fail as getting reservation conflict
9317                  * will make this hang forever.
9318                  */
9319                 if ((un->un_rsvd_status &
9320                     (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
9321                         mutex_exit(ST_MUTEX);
9322                         rval = EACCES;
9323                         goto done;
9324                 }
9325                 rval = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
9326                 if (rval == EACCES) {
9327                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9328                             "st_check_media: TUR got Reservation Conflict\n");
9329                         mutex_exit(ST_MUTEX);
9330                         goto done;
9331                 }
9332                 if (rval) {
9333                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9334                             "st_check_media: TUR failed, going to retry\n");
9335                         un->un_mediastate = prev_state;
9336                         un->un_state = ST_STATE_OFFLINE;
9337                         goto retry;
9338                 }
9339                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9340                     "st_check_media: media inserted\n");
9341 
9342                 /* this also rewinds the tape */
9343                 rval = st_tape_init(un);
9344                 if (rval != 0) {
9345                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9346                             "st_check_media : OFFLINE init failure ");
9347                         un->un_state = ST_STATE_OFFLINE;
9348                         un->un_pos.pmode = invalid;
9349                 } else {
9350                         un->un_state = ST_STATE_OPEN_PENDING_IO;
9351                 }
9352         } else if ((un->un_mediastate == MTIO_EJECTED) &&
9353             (un->un_state != ST_STATE_OFFLINE)) {
9354                 /*
9355                  * supported devices must be rewound before ejection
9356                  * rewind resets fileno & blkno
9357                  */
9358                 un->un_laststate = un->un_state;
9359                 un->un_state = ST_STATE_OFFLINE;
9360         }
9361         mutex_exit(ST_MUTEX);
9362 done:
9363         if (token) {
9364                 (void) scsi_watch_request_terminate(token,
9365                     SCSI_WATCH_TERMINATE_WAIT);
9366                 mutex_enter(ST_MUTEX);
9367                 un->un_swr_token = (opaque_t)NULL;
9368                 mutex_exit(ST_MUTEX);
9369         }
9370 
9371         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG, "st_check_media: done\n");
9372 
9373         return (rval);
9374 }
9375 
9376 /*
9377  * st_media_watch_cb() is called by scsi_watch_thread for
9378  * verifying the request sense data (if any)
9379  */
9380 static int
9381 st_media_watch_cb(caddr_t arg, struct scsi_watch_result *resultp)
9382 {
9383         struct scsi_status *statusp = resultp->statusp;
9384         struct scsi_extended_sense *sensep = resultp->sensep;
9385         uchar_t actual_sense_length = resultp->actual_sense_length;
9386         struct scsi_tape *un;
9387         enum mtio_state state = MTIO_NONE;
9388         int instance;
9389         dev_t dev = (dev_t)arg;
9390 
9391         instance = MTUNIT(dev);
9392         if ((un = ddi_get_soft_state(st_state, instance)) == NULL) {
9393                 return (-1);
9394         }
9395 
9396         mutex_enter(ST_MUTEX);
9397         ST_FUNC(ST_DEVINFO, st_media_watch_cb);
9398         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9399             "st_media_watch_cb: status=%x, sensep=%p, len=%x\n",
9400             *((char *)statusp), (void *)sensep,
9401             actual_sense_length);
9402 
9403 
9404         /*
9405          * if there was a check condition then sensep points to valid
9406          * sense data
9407          * if status was not a check condition but a reservation or busy
9408          * status then the new state is MTIO_NONE
9409          */
9410         if (sensep) {
9411                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9412                     "st_media_watch_cb: KEY=%x, ASC=%x, ASCQ=%x\n",
9413                     sensep->es_key, sensep->es_add_code, sensep->es_qual_code);
9414 
9415                 switch (un->un_dp->type) {
9416                 default:
9417                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9418                             "st_media_watch_cb: unknown drive type %d, "
9419                             "default to ST_TYPE_HP\n", un->un_dp->type);
9420                 /* FALLTHROUGH */
9421 
9422                 case ST_TYPE_STC3490:   /* STK 4220 1/2" cartridge */
9423                 case ST_TYPE_FUJI:      /* 1/2" cartridge */
9424                 case ST_TYPE_HP:        /* HP 88780 1/2" reel */
9425                         if (un->un_dp->type == ST_TYPE_FUJI) {
9426                                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9427                                     "st_media_watch_cb: ST_TYPE_FUJI\n");
9428                         } else {
9429                                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9430                                     "st_media_watch_cb: ST_TYPE_HP\n");
9431                         }
9432                         switch (sensep->es_key) {
9433                         case KEY_UNIT_ATTENTION:
9434                                 /* not ready to ready transition */
9435                                 /* hp/es_qual_code == 80 on>off>on */
9436                                 /* hp/es_qual_code == 0 on>off>unld>ld>on */
9437                                 if (sensep->es_add_code == 0x28) {
9438                                         state = MTIO_INSERTED;
9439                                 }
9440                                 break;
9441                         case KEY_NOT_READY:
9442                                 /* in process, rewinding or loading */
9443                                 if ((sensep->es_add_code == 0x04) &&
9444                                     (sensep->es_qual_code == 0x00)) {
9445                                         state = MTIO_EJECTED;
9446                                 }
9447                                 break;
9448                         }
9449                         break;
9450 
9451                 case ST_TYPE_EXB8500:   /* Exabyte 8500 */
9452                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9453                             "st_media_watch_cb: ST_TYPE_EXB8500\n");
9454                         switch (sensep->es_key) {
9455                         case KEY_UNIT_ATTENTION:
9456                                 /* operator medium removal request */
9457                                 if ((sensep->es_add_code == 0x5a) &&
9458                                     (sensep->es_qual_code == 0x01)) {
9459                                         state = MTIO_EJECTED;
9460                                 /* not ready to ready transition */
9461                                 } else if ((sensep->es_add_code == 0x28) &&
9462                                     (sensep->es_qual_code == 0x00)) {
9463                                         state = MTIO_INSERTED;
9464                                 }
9465                                 break;
9466                         case KEY_NOT_READY:
9467                                 /* medium not present */
9468                                 if (sensep->es_add_code == 0x3a) {
9469                                         state = MTIO_EJECTED;
9470                                 }
9471                                 break;
9472                         }
9473                         break;
9474                 case ST_TYPE_EXABYTE:   /* Exabyte 8200 */
9475                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9476                             "st_media_watch_cb: ST_TYPE_EXABYTE\n");
9477                         switch (sensep->es_key) {
9478                         case KEY_NOT_READY:
9479                                 if ((sensep->es_add_code == 0x04) &&
9480                                     (sensep->es_qual_code == 0x00)) {
9481                                         /* volume not mounted? */
9482                                         state = MTIO_EJECTED;
9483                                 } else if (sensep->es_add_code == 0x3a) {
9484                                         state = MTIO_EJECTED;
9485                                 }
9486                                 break;
9487                         case KEY_UNIT_ATTENTION:
9488                                 state = MTIO_EJECTED;
9489                                 break;
9490                         }
9491                         break;
9492 
9493                 case ST_TYPE_DLT:               /* quantum DLT4xxx */
9494                         switch (sensep->es_key) {
9495                         case KEY_UNIT_ATTENTION:
9496                                 if (sensep->es_add_code == 0x28) {
9497                                         state = MTIO_INSERTED;
9498                                 }
9499                                 break;
9500                         case KEY_NOT_READY:
9501                                 if (sensep->es_add_code == 0x04) {
9502                                         /* in transition but could be either */
9503                                         state = un->un_specified_mediastate;
9504                                 } else if ((sensep->es_add_code == 0x3a) &&
9505                                     (sensep->es_qual_code == 0x00)) {
9506                                         state = MTIO_EJECTED;
9507                                 }
9508                                 break;
9509                         }
9510                         break;
9511                 }
9512         } else if (*((char *)statusp) == STATUS_GOOD) {
9513                 state = MTIO_INSERTED;
9514         }
9515 
9516         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9517             "st_media_watch_cb:state=%x, specified=%x\n",
9518             state, un->un_specified_mediastate);
9519 
9520         /*
9521          * now signal the waiting thread if this is *not* the specified state;
9522          * delay the signal if the state is MTIO_INSERTED
9523          * to allow the target to recover
9524          */
9525         if (state != un->un_specified_mediastate) {
9526                 un->un_mediastate = state;
9527                 if (state == MTIO_INSERTED) {
9528                         /*
9529                          * delay the signal to give the drive a chance
9530                          * to do what it apparently needs to do
9531                          */
9532                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9533                             "st_media_watch_cb:delayed cv_broadcast\n");
9534                         un->un_delay_tid = timeout(st_delayed_cv_broadcast,
9535                             un, drv_usectohz((clock_t)MEDIA_ACCESS_DELAY));
9536                 } else {
9537                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9538                             "st_media_watch_cb:immediate cv_broadcast\n");
9539                         cv_broadcast(&un->un_state_cv);
9540                 }
9541         }
9542         mutex_exit(ST_MUTEX);
9543         return (0);
9544 }
9545 
9546 /*
9547  * delayed cv_broadcast to allow for target to recover
9548  * from media insertion
9549  */
9550 static void
9551 st_delayed_cv_broadcast(void *arg)
9552 {
9553         struct scsi_tape *un = arg;
9554 
9555         ST_FUNC(ST_DEVINFO, st_delayed_cv_broadcast);
9556 
9557         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9558             "st_delayed_cv_broadcast:delayed cv_broadcast\n");
9559 
9560         mutex_enter(ST_MUTEX);
9561         cv_broadcast(&un->un_state_cv);
9562         mutex_exit(ST_MUTEX);
9563 }
9564 
9565 /*
9566  * restart cmd currently at the start of the waitq
9567  */
9568 static void
9569 st_start_restart(void *arg)
9570 {
9571         struct scsi_tape *un = arg;
9572 
9573         ST_FUNC(ST_DEVINFO, st_start_restart);
9574 
9575         ASSERT(un != NULL);
9576 
9577         mutex_enter(ST_MUTEX);
9578 
9579         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_tran_restart()\n");
9580 
9581         st_start(un);
9582 
9583         mutex_exit(ST_MUTEX);
9584 }
9585 
9586 
9587 /*
9588  * Command completion processing
9589  *
9590  */
9591 static void
9592 st_intr(struct scsi_pkt *pkt)
9593 {
9594         recov_info *rcv = pkt->pkt_private;
9595         struct buf *bp = rcv->cmd_bp;
9596         struct scsi_tape *un;
9597         errstate action = COMMAND_DONE;
9598         clock_t timout;
9599         int     status;
9600 
9601         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
9602 
9603         ST_FUNC(ST_DEVINFO, st_intr);
9604 
9605         ASSERT(un != NULL);
9606 
9607         mutex_enter(ST_MUTEX);
9608 
9609         ASSERT(bp != un->un_recov_buf);
9610 
9611         un->un_rqs_state &= ~(ST_RQS_ERROR);
9612 
9613         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_intr()\n");
9614 
9615         if (pkt->pkt_reason != CMD_CMPLT) {
9616                 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
9617                     "Unhappy packet status reason = %s statistics = 0x%x\n",
9618                     scsi_rname(pkt->pkt_reason), pkt->pkt_statistics);
9619 
9620                 /* If device has gone away not much else to do */
9621                 if (pkt->pkt_reason == CMD_DEV_GONE) {
9622                         action = COMMAND_DONE_ERROR;
9623                 } else if ((pkt == un->un_rqs) ||
9624                     (un->un_state == ST_STATE_SENSING)) {
9625                         ASSERT(pkt == un->un_rqs);
9626                         ASSERT(un->un_state == ST_STATE_SENSING);
9627                         un->un_state = un->un_laststate;
9628                         rcv->cmd_bp = un->un_rqs_bp;
9629                         ST_DO_ERRSTATS(un, st_transerrs);
9630                         action = COMMAND_DONE_ERROR;
9631                 } else {
9632                         action = st_handle_incomplete(un, bp);
9633                 }
9634         /*
9635          * At this point we know that the command was successfully
9636          * completed. Now what?
9637          */
9638         } else if ((pkt == un->un_rqs) || (un->un_state == ST_STATE_SENSING)) {
9639                 /*
9640                  * okay. We were running a REQUEST SENSE. Find
9641                  * out what to do next.
9642                  */
9643                 ASSERT(pkt == un->un_rqs);
9644                 ASSERT(un->un_state == ST_STATE_SENSING);
9645                 scsi_sync_pkt(pkt);
9646                 action = st_handle_sense(un, bp, &un->un_pos);
9647                 /*
9648                  * Make rqs isn't going to be retied.
9649                  */
9650                 if (action != QUE_BUSY_COMMAND && action != QUE_COMMAND) {
9651                         /*
9652                          * set pkt back to original packet in case we will have
9653                          * to requeue it
9654                          */
9655                         pkt = BP_PKT(bp);
9656                         rcv->cmd_bp = un->un_rqs_bp;
9657                         /*
9658                          * some actions are based on un_state, hence
9659                          * restore the state st was in before ST_STATE_SENSING.
9660                          */
9661                         un->un_state = un->un_laststate;
9662                 }
9663 
9664         } else if (un->un_arq_enabled && (pkt->pkt_state & STATE_ARQ_DONE)) {
9665                 /*
9666                  * the transport layer successfully completed an autorqsense
9667                  */
9668                 action = st_handle_autosense(un, bp, &un->un_pos);
9669 
9670         } else  if ((SCBP(pkt)->sts_busy) ||
9671             (SCBP(pkt)->sts_chk) ||
9672             (SCBP(pkt)->sts_vu7)) {
9673                 /*
9674                  * Okay, we weren't running a REQUEST SENSE. Call a routine
9675                  * to see if the status bits we're okay. If a request sense
9676                  * is to be run, that will happen.
9677                  */
9678                 action = st_check_error(un, pkt);
9679         }
9680 
9681         if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
9682                 switch (action) {
9683                         case QUE_COMMAND:
9684                                 /*
9685                                  * return cmd to head to the queue
9686                                  * since we are suspending so that
9687                                  * it gets restarted during resume
9688                                  */
9689                                 st_add_to_queue(&un->un_runqf, &un->un_runql,
9690                                     un->un_runqf, bp);
9691 
9692                                 action = JUST_RETURN;
9693                                 break;
9694 
9695                         case QUE_SENSE:
9696                                 action = COMMAND_DONE_ERROR;
9697                                 break;
9698 
9699                         default:
9700                                 break;
9701                 }
9702         }
9703 
9704         /*
9705          * check for undetected path failover.
9706          */
9707         if (un->un_multipath) {
9708 
9709                 struct uscsi_cmd *ucmd = BP_UCMD(bp);
9710                 int pkt_valid = 0;
9711 
9712                 if (ucmd) {
9713                         /*
9714                          * Also copies path instance to the uscsi structure.
9715                          */
9716                         pkt_valid = scsi_uscsi_pktfini(pkt, ucmd);
9717 
9718                         /*
9719                          * scsi_uscsi_pktfini() zeros pkt_path_instance.
9720                          */
9721                         pkt->pkt_path_instance = ucmd->uscsi_path_instance;
9722                 } else {
9723                         pkt_valid = scsi_pkt_allocated_correctly(pkt);
9724                 }
9725 
9726                 /*
9727                  * If the scsi_pkt was not allocated correctly the
9728                  * pkt_path_instance is not even there.
9729                  */
9730                 if ((pkt_valid != 0) &&
9731                     (un->un_last_path_instance != pkt->pkt_path_instance)) {
9732                         /*
9733                          * Don't recover the path change if it was done
9734                          * intentionally or if the device has not completely
9735                          * opened yet.
9736                          */
9737                         if (((pkt->pkt_flags & FLAG_PKT_PATH_INSTANCE) == 0) &&
9738                             (un->un_state > ST_STATE_OPENING)) {
9739                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
9740                                     "Failover detected, action is %s\n",
9741                                     errstatenames[action]);
9742                                 if (action == COMMAND_DONE) {
9743                                         action = PATH_FAILED;
9744                                 }
9745                         }
9746                         un->un_last_path_instance = pkt->pkt_path_instance;
9747                 }
9748         }
9749 
9750         /*
9751          * Restore old state if we were sensing.
9752          */
9753         if (un->un_state == ST_STATE_SENSING && action != QUE_SENSE) {
9754                 un->un_state = un->un_laststate;
9755         }
9756 
9757         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
9758             "st_intr: pkt=%p, bp=%p, action=%s, status=%x\n",
9759             (void *)pkt, (void *)bp, errstatenames[action], SCBP_C(pkt));
9760 
9761 again:
9762         switch (action) {
9763         case COMMAND_DONE_EACCES:
9764                 /* this is to report a reservation conflict */
9765                 st_bioerror(bp, EACCES);
9766                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9767                     "Reservation Conflict \n");
9768                 un->un_pos.pmode = invalid;
9769 
9770                 /*FALLTHROUGH*/
9771         case COMMAND_DONE_ERROR:
9772                 if (un->un_pos.eof < ST_EOT_PENDING &&
9773                     un->un_state >= ST_STATE_OPEN) {
9774                         /*
9775                          * all errors set state of the tape to 'unknown'
9776                          * unless we're at EOT or are doing append testing.
9777                          * If sense key was illegal request, preserve state.
9778                          */
9779                         if (un->un_status != KEY_ILLEGAL_REQUEST) {
9780                                 un->un_pos.pmode = invalid;
9781                         }
9782                 }
9783 
9784                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9785                 /*
9786                  * since we have an error (COMMAND_DONE_ERROR), we want to
9787                  * make sure an error ocurrs, so make sure at least EIO is
9788                  * returned
9789                  */
9790                 if (geterror(bp) == 0)
9791                         st_bioerror(bp, EIO);
9792 
9793                 st_set_pe_flag(un);
9794                 if (!(un->un_rqs_state & ST_RQS_ERROR) &&
9795                     (un->un_errno == EIO)) {
9796                         un->un_rqs_state &= ~(ST_RQS_VALID);
9797                 }
9798                 break;
9799 
9800         case COMMAND_DONE_ERROR_RECOVERED:
9801                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9802                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
9803                     "st_intr(): COMMAND_DONE_ERROR_RECOVERED");
9804                 if (geterror(bp) == 0) {
9805                         st_bioerror(bp, EIO);
9806                 }
9807                 st_set_pe_flag(un);
9808                 if (!(un->un_rqs_state & ST_RQS_ERROR) &&
9809                     (un->un_errno == EIO)) {
9810                         un->un_rqs_state &= ~(ST_RQS_VALID);
9811                 }
9812                 /*FALLTHROUGH*/
9813         case COMMAND_DONE:
9814                 st_set_state(un, bp);
9815                 break;
9816 
9817         case QUE_SENSE:
9818                 if ((un->un_ncmds > 1) && !un->un_flush_on_errors)
9819                         goto sense_error;
9820 
9821                 if (un->un_state != ST_STATE_SENSING) {
9822                         un->un_laststate = un->un_state;
9823                         un->un_state = ST_STATE_SENSING;
9824                 }
9825 
9826                 /*
9827                  * zero the sense data.
9828                  */
9829                 bzero(un->un_rqs->pkt_scbp, SENSE_LENGTH);
9830 
9831                 /*
9832                  * If this is not a retry on QUE_SENSE point to the original
9833                  * bp of the command that got us here.
9834                  */
9835                 if (pkt != un->un_rqs) {
9836                         ((recov_info *)un->un_rqs->pkt_private)->cmd_bp = bp;
9837                 }
9838 
9839                 if (un->un_throttle) {
9840                         un->un_last_throttle = un->un_throttle;
9841                         un->un_throttle = 0;
9842                 }
9843 
9844                 ST_CDB(ST_DEVINFO, "Queue sense CDB",
9845                     (char *)BP_PKT(bp)->pkt_cdbp);
9846 
9847                 /*
9848                  * never retry this, some other command will have nuked the
9849                  * sense, anyway
9850                  */
9851                 status = st_transport(un, un->un_rqs);
9852 
9853                 if (un->un_last_throttle) {
9854                         un->un_throttle = un->un_last_throttle;
9855                 }
9856 
9857                 if (status == TRAN_ACCEPT) {
9858                         mutex_exit(ST_MUTEX);
9859                         return;
9860                 }
9861                 if (status != TRAN_BUSY)
9862                         ST_DO_ERRSTATS(un, st_transerrs);
9863 sense_error:
9864                 un->un_pos.pmode = invalid;
9865                 st_bioerror(bp, EIO);
9866                 st_set_pe_flag(un);
9867                 break;
9868 
9869         case QUE_BUSY_COMMAND:
9870                 /* longish timeout */
9871                 timout = ST_STATUS_BUSY_TIMEOUT;
9872                 goto que_it_up;
9873 
9874         case QUE_COMMAND:
9875                 /* short timeout */
9876                 timout = ST_TRAN_BUSY_TIMEOUT;
9877 que_it_up:
9878                 /*
9879                  * let st_handle_intr_busy put this bp back on waitq and make
9880                  * checks to see if it is ok to requeue the command.
9881                  */
9882                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9883 
9884                 /*
9885                  * Save the throttle before setting up the timeout
9886                  */
9887                 if (un->un_throttle) {
9888                         un->un_last_throttle = un->un_throttle;
9889                 }
9890                 mutex_exit(ST_MUTEX);
9891                 if (st_handle_intr_busy(un, bp, timout) == 0)
9892                         return;         /* timeout is setup again */
9893 
9894                 mutex_enter(ST_MUTEX);
9895                 un->un_pos.pmode = invalid;
9896                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9897                 st_bioerror(bp, EIO);
9898                 st_set_pe_flag(un);
9899                 break;
9900 
9901         case QUE_LAST_COMMAND:
9902 
9903                 if ((un->un_ncmds > 1) && !un->un_flush_on_errors) {
9904                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
9905                             "un_ncmds: %d can't retry cmd \n", un->un_ncmds);
9906                         goto last_command_error;
9907                 }
9908                 mutex_exit(ST_MUTEX);
9909                 if (st_handle_intr_retry_lcmd(un, bp) == 0)
9910                         return;
9911                 mutex_enter(ST_MUTEX);
9912 last_command_error:
9913                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9914                 un->un_pos.pmode = invalid;
9915                 st_bioerror(bp, EIO);
9916                 st_set_pe_flag(un);
9917                 break;
9918 
9919         case COMMAND_TIMEOUT:
9920         case DEVICE_RESET:
9921         case DEVICE_TAMPER:
9922         case ATTEMPT_RETRY:
9923         case PATH_FAILED:
9924                 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
9925                     "Command Recovery called on %s status\n",
9926                     errstatenames[action]);
9927                 action = st_command_recovery(un, pkt, action);
9928                 goto again;
9929 
9930         default:
9931                 ASSERT(0);
9932                 /* FALLTHRU */
9933         case JUST_RETURN:
9934                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9935                 mutex_exit(ST_MUTEX);
9936                 return;
9937         }
9938 
9939         ST_DO_KSTATS(bp, kstat_runq_exit);
9940         st_done_and_mutex_exit(un, bp);
9941 }
9942 
9943 static errstate
9944 st_handle_incomplete(struct scsi_tape *un, struct buf *bp)
9945 {
9946         static char *fail = "SCSI transport failed: reason '%s': %s\n";
9947         recov_info *rinfo;
9948         errstate rval = COMMAND_DONE_ERROR;
9949         struct scsi_pkt *pkt = (un->un_state == ST_STATE_SENSING) ?
9950             un->un_rqs : BP_PKT(bp);
9951         int result;
9952 
9953         ST_FUNC(ST_DEVINFO, st_handle_incomplete);
9954 
9955         rinfo = (recov_info *)pkt->pkt_private;
9956 
9957         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9958             "st_handle_incomplete(): dev = 0x%lx\n", un->un_dev);
9959 
9960         ASSERT(mutex_owned(ST_MUTEX));
9961 
9962         /* prevent infinite number of retries */
9963         if (rinfo->pkt_retry_cnt++ > st_retry_count) {
9964                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
9965                     "Recovery stopped for incomplete %s command, "
9966                     "retries exhausted",
9967                     st_print_scsi_cmd(pkt->pkt_cdbp[0]));
9968                 return (COMMAND_DONE_ERROR);
9969         }
9970 
9971         switch (pkt->pkt_reason) {
9972         case CMD_INCOMPLETE:    /* tran stopped with not normal state */
9973                 /*
9974                  * this occurs when accessing a powered down drive, no
9975                  * need to complain; just fail the open
9976                  */
9977                 ST_CDB(ST_DEVINFO, "Incomplete CDB", (char *)pkt->pkt_cdbp);
9978 
9979                 /*
9980                  * if we have commands outstanding in HBA, and a command
9981                  * comes back incomplete, we're hosed, so reset target
9982                  * If we have the bus, but cmd_incomplete, we probably just
9983                  * have a failed selection, so don't reset the target, just
9984                  * requeue the command and try again
9985                  */
9986                 if ((un->un_ncmds > 1) || (pkt->pkt_state != STATE_GOT_BUS)) {
9987                         goto reset_target;
9988                 }
9989 
9990                 /*
9991                  * Retry selection a couple more times if we're
9992                  * open.  If opening, we only try just once to
9993                  * reduce probe time for nonexistant devices.
9994                  */
9995                 if ((un->un_laststate > ST_STATE_OPENING) &&
9996                     (rinfo->pkt_retry_cnt < st_selection_retry_count)) {
9997                         /* XXX check retriable? */
9998                         rval = QUE_COMMAND;
9999                 }
10000                 ST_DO_ERRSTATS(un, st_transerrs);
10001                 break;
10002 
10003         case CMD_ABORTED:
10004                 /*
10005                  * most likely this is caused by flush-on-error support. If
10006                  * it was not there, the we're in trouble.
10007                  */
10008                 if (!un->un_flush_on_errors) {
10009                         un->un_status = SUN_KEY_FATAL;
10010                         goto reset_target;
10011                 }
10012 
10013                 st_set_pe_errno(un);
10014                 bioerror(bp, un->un_errno);
10015                 if (un->un_errno)
10016                         return (COMMAND_DONE_ERROR);
10017                 else
10018                         return (COMMAND_DONE);
10019 
10020         case CMD_TIMEOUT:       /* Command timed out */
10021                 un->un_status = SUN_KEY_TIMEOUT;
10022                 return (COMMAND_TIMEOUT);
10023 
10024         case CMD_TRAN_ERR:
10025         case CMD_RESET:
10026                 if (pkt->pkt_statistics & (STAT_BUS_RESET | STAT_DEV_RESET)) {
10027                         if ((un->un_rsvd_status &
10028                             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
10029                             ST_RESERVE) {
10030                                 un->un_rsvd_status |= ST_LOST_RESERVE;
10031                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
10032                                     "Lost Reservation\n");
10033                         }
10034                         rval = DEVICE_RESET;
10035                         return (rval);
10036                 }
10037                 if (pkt->pkt_statistics & (STAT_ABORTED | STAT_TERMINATED)) {
10038                         rval = DEVICE_RESET;
10039                         return (rval);
10040                 }
10041                 /*FALLTHROUGH*/
10042         default:
10043                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10044                     "Unhandled packet status reason = %s statistics = 0x%x\n",
10045                     scsi_rname(pkt->pkt_reason), pkt->pkt_statistics);
10046 reset_target:
10047 
10048                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10049                     "transport completed with %s\n",
10050                     scsi_rname(pkt->pkt_reason));
10051                 ST_DO_ERRSTATS(un, st_transerrs);
10052                 if ((pkt->pkt_state & STATE_GOT_TARGET) &&
10053                     ((pkt->pkt_statistics & (STAT_BUS_RESET | STAT_DEV_RESET |
10054                     STAT_ABORTED)) == 0)) {
10055 
10056                         /*
10057                          * If we haven't reserved the drive don't reset it.
10058                          */
10059                         if ((un->un_rsvd_status &
10060                             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
10061                                 return (rval);
10062                         }
10063 
10064                         /*
10065                          * if we aren't lost yet we will be soon.
10066                          */
10067                         un->un_pos.pmode = invalid;
10068 
10069                         result = st_reset(un, RESET_LUN);
10070 
10071                         if ((result == 0) && (un->un_state >= ST_STATE_OPEN)) {
10072                                 /* no hope left to recover */
10073                                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10074                                     "recovery by resets failed\n");
10075                                 return (rval);
10076                         }
10077                 }
10078         }
10079 
10080 
10081         if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
10082                 rval = QUE_COMMAND;
10083         } else if (bp == un->un_sbufp) {
10084                 if (rinfo->privatelen == sizeof (recov_info)) {
10085                         if (rinfo->cmd_attrib->retriable) {
10086                                 /*
10087                                  * These commands can be rerun
10088                                  * with impunity
10089                                  */
10090                                 rval = QUE_COMMAND;
10091                         }
10092                 } else {
10093                         cmd_attribute const *attrib;
10094                         attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
10095                         if (attrib->retriable) {
10096                                 rval = QUE_COMMAND;
10097                         }
10098                 }
10099         }
10100 
10101         if (un->un_state >= ST_STATE_OPEN) {
10102                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10103                     fail, scsi_rname(pkt->pkt_reason),
10104                     (rval == COMMAND_DONE_ERROR)?
10105                     "giving up" : "retrying command");
10106         }
10107         return (rval);
10108 }
10109 
10110 /*
10111  * if the device is busy, then put this bp back on the waitq, on the
10112  * interrupt thread, where we want the head of the queue and not the
10113  * end
10114  *
10115  * The callers of this routine should take measures to save the
10116  * un_throttle in un_last_throttle which will be restored in
10117  * st_intr_restart(). The only exception should be st_intr_restart()
10118  * calling this routine for which the saving is already done.
10119  */
10120 static int
10121 st_handle_intr_busy(struct scsi_tape *un, struct buf *bp,
10122         clock_t timeout_interval)
10123 {
10124 
10125         int queued;
10126         int rval = 0;
10127         pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
10128 
10129         mutex_enter(ST_MUTEX);
10130 
10131         ST_FUNC(ST_DEVINFO, st_handle_intr_busy);
10132 
10133         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10134             "st_handle_intr_busy(), un = 0x%p\n", (void *)un);
10135 
10136         if ((bp != un->un_sbufp) && (bp != un->un_recov_buf)) {
10137                 queued = 1;
10138         } else {
10139                 queued = 0;
10140         }
10141 
10142         /*
10143          * Check to see if we hit the retry timeout. We check to make sure
10144          * this is the first one on the runq and make sure we have not
10145          * queued up any more, so this one has to be the last on the list
10146          * also. If it is not, we have to fail.  If it is not the first, but
10147          * is the last we are in trouble anyway, as we are in the interrupt
10148          * context here.
10149          */
10150         if ((pktinfo->str_retry_cnt++ > st_retry_count) ||
10151             ((un->un_runqf != bp) && (un->un_runql != bp) && (queued))) {
10152                 rval = -1;
10153                 goto exit;
10154         }
10155 
10156         /* put the bp back on the waitq */
10157         if (queued) {
10158                 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
10159                 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quef, bp);
10160         }
10161 
10162         /*
10163          * We don't want any other commands being started in the mean time.
10164          * If start had just released mutex after putting something on the
10165          * runq, we won't even get here.
10166          */
10167         un->un_throttle = 0;
10168 
10169         /*
10170          * send a marker pkt, if appropriate
10171          */
10172         st_hba_unflush(un);
10173 
10174         /*
10175          * all queues are aligned, we are just waiting to
10176          * transport
10177          */
10178         un->un_hib_tid = timeout(st_intr_restart, un, timeout_interval);
10179 
10180 exit:
10181         mutex_exit(ST_MUTEX);
10182         return (rval);
10183 }
10184 
10185 /*
10186  * To get one error entry from error stack
10187  */
10188 static int
10189 st_get_error_entry(struct scsi_tape *un, intptr_t arg, int flag)
10190 {
10191 #ifdef _MULTI_DATAMODEL
10192         /*
10193          * For use when a 32 bit app makes a call into a
10194          * 64 bit ioctl
10195          */
10196         struct mterror_entry32 err_entry32;
10197 #endif /* _MULTI_DATAMODEL */
10198 
10199         int rval = 0;
10200         struct mterror_entry err_entry;
10201         struct mterror_entry_stack *err_link_entry_p;
10202         size_t arq_status_len_in, arq_status_len_kr;
10203 
10204         ST_FUNC(ST_DEVINFO, st_get_error_entry);
10205 
10206         ASSERT(mutex_owned(ST_MUTEX));
10207 
10208         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10209             "st_get_error_entry()\n");
10210 
10211         /*
10212          * if error record stack empty, return ENXIO
10213          */
10214         if (un->un_error_entry_stk == NULL) {
10215                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10216                     "st_get_error_entry: Error Entry Stack Empty!\n");
10217                 rval = ENXIO;
10218                 goto ret;
10219         }
10220 
10221         /*
10222          * get the top entry from stack
10223          */
10224         err_link_entry_p = un->un_error_entry_stk;
10225         arq_status_len_kr =
10226             err_link_entry_p->mtees_entry.mtee_arq_status_len;
10227 
10228 #ifdef _MULTI_DATAMODEL
10229         switch (ddi_model_convert_from(flag & FMODELS)) {
10230         case DDI_MODEL_ILP32:
10231                 if (ddi_copyin((void *)arg, &err_entry32,
10232                     MTERROR_ENTRY_SIZE_32, flag)) {
10233                         rval = EFAULT;
10234                         goto ret;
10235                 }
10236 
10237                 arq_status_len_in =
10238                     (size_t)err_entry32.mtee_arq_status_len;
10239 
10240                 err_entry32.mtee_cdb_len =
10241                     (size32_t)err_link_entry_p->mtees_entry.mtee_cdb_len;
10242 
10243                 if (arq_status_len_in > arq_status_len_kr)
10244                         err_entry32.mtee_arq_status_len =
10245                             (size32_t)arq_status_len_kr;
10246 
10247                 if (ddi_copyout(
10248                     err_link_entry_p->mtees_entry.mtee_cdb_buf,
10249                     (void *)(uintptr_t)err_entry32.mtee_cdb_buf,
10250                     err_entry32.mtee_cdb_len, flag)) {
10251                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10252                             "st_get_error_entry: Copy cdb buffer error!");
10253                         rval = EFAULT;
10254                 }
10255 
10256                 if (ddi_copyout(
10257                     err_link_entry_p->mtees_entry.mtee_arq_status,
10258                     (void *)(uintptr_t)err_entry32.mtee_arq_status,
10259                     err_entry32.mtee_arq_status_len, flag)) {
10260                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10261                             "st_get_error_entry: copy arq status error!");
10262                         rval = EFAULT;
10263                 }
10264 
10265                 if (ddi_copyout(&err_entry32, (void *)arg,
10266                     MTERROR_ENTRY_SIZE_32, flag)) {
10267                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10268                             "st_get_error_entry: copy arq status out error!");
10269                         rval = EFAULT;
10270                 }
10271                 break;
10272 
10273         case DDI_MODEL_NONE:
10274                 if (ddi_copyin((void *)arg, &err_entry,
10275                     MTERROR_ENTRY_SIZE_64, flag)) {
10276                         rval = EFAULT;
10277                         goto ret;
10278                 }
10279                 arq_status_len_in = err_entry.mtee_arq_status_len;
10280 
10281                 err_entry.mtee_cdb_len =
10282                     err_link_entry_p->mtees_entry.mtee_cdb_len;
10283 
10284                 if (arq_status_len_in > arq_status_len_kr)
10285                         err_entry.mtee_arq_status_len =
10286                             arq_status_len_kr;
10287 
10288                 if (ddi_copyout(
10289                     err_link_entry_p->mtees_entry.mtee_cdb_buf,
10290                     err_entry.mtee_cdb_buf,
10291                     err_entry.mtee_cdb_len, flag)) {
10292                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10293                             "st_get_error_entry: Copy cdb buffer error!");
10294                         rval = EFAULT;
10295                 }
10296 
10297                 if (ddi_copyout(
10298                     err_link_entry_p->mtees_entry.mtee_arq_status,
10299                     err_entry.mtee_arq_status,
10300                     err_entry.mtee_arq_status_len, flag)) {
10301                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10302                             "st_get_error_entry: copy arq status error!");
10303                         rval = EFAULT;
10304                 }
10305 
10306                 if (ddi_copyout(&err_entry, (void *)arg,
10307                     MTERROR_ENTRY_SIZE_64, flag)) {
10308                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10309                             "st_get_error_entry: copy arq status out error!");
10310                         rval = EFAULT;
10311                 }
10312                 break;
10313         }
10314 #else /* _MULTI_DATAMODEL */
10315         if (ddi_copyin((void *)arg, &err_entry,
10316             MTERROR_ENTRY_SIZE_64, flag)) {
10317                 rval = EFAULT;
10318                 goto ret;
10319         }
10320         arq_status_len_in = err_entry.mtee_arq_status_len;
10321 
10322         err_entry.mtee_cdb_len =
10323             err_link_entry_p->mtees_entry.mtee_cdb_len;
10324 
10325         if (arq_status_len_in > arq_status_len_kr)
10326                 err_entry.mtee_arq_status_len =
10327                     arq_status_len_kr;
10328 
10329         if (ddi_copyout(
10330             err_link_entry_p->mtees_entry.mtee_cdb_buf,
10331             err_entry.mtee_cdb_buf,
10332             err_entry.mtee_cdb_len, flag)) {
10333                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10334                     "st_get_error_entry: Copy cdb buffer error!");
10335                 rval = EFAULT;
10336         }
10337 
10338         if (ddi_copyout(
10339             err_link_entry_p->mtees_entry.mtee_arq_status,
10340             err_entry.mtee_arq_status,
10341             err_entry.mtee_arq_status_len, flag)) {
10342                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10343                     "st_get_error_entry: copy arq status buffer error!");
10344                 rval = EFAULT;
10345         }
10346 
10347         if (ddi_copyout(&err_entry, (void *)arg,
10348             MTERROR_ENTRY_SIZE_64, flag)) {
10349                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10350                     "st_get_error_entry: copy arq status out error!");
10351                 rval = EFAULT;
10352         }
10353 #endif /* _MULTI_DATAMODEL */
10354 
10355         /*
10356          * update stack
10357          */
10358         un->un_error_entry_stk = err_link_entry_p->mtees_nextp;
10359 
10360         kmem_free(err_link_entry_p->mtees_entry.mtee_cdb_buf,
10361             err_link_entry_p->mtees_entry.mtee_cdb_len);
10362         err_link_entry_p->mtees_entry.mtee_cdb_buf = NULL;
10363 
10364         kmem_free(err_link_entry_p->mtees_entry.mtee_arq_status,
10365             SECMDS_STATUS_SIZE);
10366         err_link_entry_p->mtees_entry.mtee_arq_status = NULL;
10367 
10368         kmem_free(err_link_entry_p, MTERROR_LINK_ENTRY_SIZE);
10369         err_link_entry_p = NULL;
10370 ret:
10371         return (rval);
10372 }
10373 
10374 /*
10375  * MTIOCGETERROR ioctl needs to retrieve the current sense data along with
10376  * the scsi CDB command which causes the error and generates sense data and
10377  * the scsi status.
10378  *
10379  *      error-record stack
10380  *
10381  *
10382  *             TOP                                     BOTTOM
10383  *              ------------------------------------------
10384  *              |   0   |   1   |   2   |   ...  |   n   |
10385  *              ------------------------------------------
10386  *                  ^
10387  *                  |
10388  *       pointer to error entry
10389  *
10390  * when st driver generates one sense data record, it creates a error-entry
10391  * and pushes it onto the stack.
10392  *
10393  */
10394 
10395 static void
10396 st_update_error_stack(struct scsi_tape *un,
10397                         struct scsi_pkt *pkt,
10398                         struct scsi_arq_status *cmd)
10399 {
10400         struct mterror_entry_stack *err_entry_tmp;
10401         uchar_t *cdbp = (uchar_t *)pkt->pkt_cdbp;
10402         size_t cdblen = scsi_cdb_size[CDB_GROUPID(cdbp[0])];
10403 
10404         ST_FUNC(ST_DEVINFO, st_update_error_stack);
10405 
10406         ASSERT(mutex_owned(ST_MUTEX));
10407 
10408         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10409             "st_update_error_stack()\n");
10410 
10411         ASSERT(cmd);
10412         ASSERT(cdbp);
10413         if (cdblen == 0) {
10414                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10415                     "st_update_error_stack: CDB length error!\n");
10416                 return;
10417         }
10418 
10419         err_entry_tmp = kmem_alloc(MTERROR_LINK_ENTRY_SIZE, KM_SLEEP);
10420         ASSERT(err_entry_tmp != NULL);
10421 
10422         err_entry_tmp->mtees_entry.mtee_cdb_buf =
10423             kmem_alloc(cdblen, KM_SLEEP);
10424         ASSERT(err_entry_tmp->mtees_entry.mtee_cdb_buf != NULL);
10425 
10426         err_entry_tmp->mtees_entry.mtee_arq_status =
10427             kmem_alloc(SECMDS_STATUS_SIZE, KM_SLEEP);
10428         ASSERT(err_entry_tmp->mtees_entry.mtee_arq_status != NULL);
10429 
10430         /*
10431          * copy cdb command & length to current error entry
10432          */
10433         err_entry_tmp->mtees_entry.mtee_cdb_len = cdblen;
10434         bcopy(cdbp, err_entry_tmp->mtees_entry.mtee_cdb_buf, cdblen);
10435 
10436         /*
10437          * copy scsi status length to current error entry
10438          */
10439         err_entry_tmp->mtees_entry.mtee_arq_status_len =
10440             SECMDS_STATUS_SIZE;
10441 
10442         /*
10443          * copy sense data and scsi status to current error entry
10444          */
10445         bcopy(cmd, err_entry_tmp->mtees_entry.mtee_arq_status,
10446             SECMDS_STATUS_SIZE);
10447 
10448         err_entry_tmp->mtees_nextp = un->un_error_entry_stk;
10449         un->un_error_entry_stk = err_entry_tmp;
10450 
10451 }
10452 
10453 /*
10454  * Empty all the error entry in stack
10455  */
10456 static void
10457 st_empty_error_stack(struct scsi_tape *un)
10458 {
10459         struct mterror_entry_stack *linkp;
10460 
10461         ST_FUNC(ST_DEVINFO, st_empty_error_stack);
10462 
10463         ASSERT(mutex_owned(ST_MUTEX));
10464 
10465         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10466             "st_empty_entry_stack()\n");
10467 
10468         while (un->un_error_entry_stk != NULL) {
10469                 linkp = un->un_error_entry_stk;
10470                 un->un_error_entry_stk =
10471                     un->un_error_entry_stk->mtees_nextp;
10472 
10473                 if (linkp->mtees_entry.mtee_cdb_buf != NULL)
10474                         kmem_free(linkp->mtees_entry.mtee_cdb_buf,
10475                             linkp->mtees_entry.mtee_cdb_len);
10476 
10477                 if (linkp->mtees_entry.mtee_arq_status != NULL)
10478                         kmem_free(linkp->mtees_entry.mtee_arq_status,
10479                             linkp->mtees_entry.mtee_arq_status_len);
10480 
10481                 kmem_free(linkp, MTERROR_LINK_ENTRY_SIZE);
10482                 linkp = NULL;
10483         }
10484 }
10485 
10486 static errstate
10487 st_handle_sense(struct scsi_tape *un, struct buf *bp, tapepos_t *pos)
10488 {
10489         struct scsi_pkt *pkt = BP_PKT(bp);
10490         struct scsi_pkt *rqpkt = un->un_rqs;
10491         struct scsi_arq_status arqstat;
10492         recov_info *rcif = pkt->pkt_private;
10493 
10494         errstate rval = COMMAND_DONE_ERROR;
10495         int amt;
10496 
10497         ST_FUNC(ST_DEVINFO, st_handle_sense);
10498 
10499         ASSERT(mutex_owned(ST_MUTEX));
10500 
10501         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10502             "st_handle_sense()\n");
10503 
10504         if (SCBP(rqpkt)->sts_busy) {
10505                 if (rcif->privatelen == sizeof (recov_info)) {
10506                         ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
10507                             "Attempt recovery of busy unit on request sense\n");
10508                         rval = ATTEMPT_RETRY;
10509                 } else if (rcif->pkt_retry_cnt++ < st_retry_count) {
10510                         ST_DEBUG4(ST_DEVINFO, st_label, CE_WARN,
10511                             "Retry busy unit on request sense\n");
10512                         rval = QUE_BUSY_COMMAND;
10513                 }
10514                 return (rval);
10515         } else if (SCBP(rqpkt)->sts_chk) {
10516                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10517                     "Check Condition on REQUEST SENSE\n");
10518                 return (rval);
10519         }
10520 
10521         /*
10522          * Make sure there is sense data to look at.
10523          */
10524         if ((rqpkt->pkt_state & (STATE_GOT_BUS | STATE_GOT_TARGET |
10525             STATE_SENT_CMD | STATE_GOT_STATUS)) != (STATE_GOT_BUS |
10526             STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS)) {
10527                 return (rval);
10528         }
10529 
10530         /* was there enough data? */
10531         amt = (int)MAX_SENSE_LENGTH - rqpkt->pkt_resid;
10532         if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 ||
10533             (amt < SUN_MIN_SENSE_LENGTH)) {
10534                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10535                     "REQUEST SENSE couldn't get sense data\n");
10536                 return (rval);
10537         }
10538 
10539         bcopy(SCBP(pkt), &arqstat.sts_status,
10540             sizeof (struct scsi_status));
10541         bcopy(SCBP(rqpkt), &arqstat.sts_rqpkt_status,
10542             sizeof (struct scsi_status));
10543         arqstat.sts_rqpkt_reason = rqpkt->pkt_reason;
10544         arqstat.sts_rqpkt_resid = rqpkt->pkt_resid;
10545         arqstat.sts_rqpkt_state = rqpkt->pkt_state;
10546         arqstat.sts_rqpkt_statistics = rqpkt->pkt_statistics;
10547         bcopy(ST_RQSENSE, &arqstat.sts_sensedata, SENSE_LENGTH);
10548 
10549         /*
10550          * copy one arqstat entry in the sense data buffer
10551          */
10552         st_update_error_stack(un, pkt, &arqstat);
10553         return (st_decode_sense(un, bp, amt, &arqstat, pos));
10554 }
10555 
10556 static errstate
10557 st_handle_autosense(struct scsi_tape *un, struct buf *bp, tapepos_t *pos)
10558 {
10559         struct scsi_pkt *pkt = BP_PKT(bp);
10560         struct scsi_arq_status *arqstat =
10561             (struct scsi_arq_status *)pkt->pkt_scbp;
10562         errstate rval = COMMAND_DONE_ERROR;
10563         int amt;
10564 
10565         ST_FUNC(ST_DEVINFO, st_handle_autosense);
10566 
10567         ASSERT(mutex_owned(ST_MUTEX));
10568 
10569         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10570             "st_handle_autosense()\n");
10571 
10572         if (arqstat->sts_rqpkt_status.sts_busy) {
10573                 ST_DEBUG4(ST_DEVINFO, st_label, CE_WARN,
10574                     "busy unit on request sense\n");
10575                 /*
10576                  * we return QUE_SENSE so st_intr will setup the SENSE cmd.
10577                  * the disadvantage is that we do not have any delay for the
10578                  * second retry of rqsense and we have to keep a packet around
10579                  */
10580                 return (QUE_SENSE);
10581 
10582         } else if (arqstat->sts_rqpkt_reason != CMD_CMPLT) {
10583                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10584                     "transport error on REQUEST SENSE\n");
10585                 if ((arqstat->sts_rqpkt_state & STATE_GOT_TARGET) &&
10586                     ((arqstat->sts_rqpkt_statistics &
10587                     (STAT_BUS_RESET | STAT_DEV_RESET | STAT_ABORTED)) == 0)) {
10588                         if (st_reset(un, RESET_LUN) == 0) {
10589                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10590                                     "recovery by resets failed\n");
10591                         }
10592                 }
10593                 return (rval);
10594 
10595         } else if (arqstat->sts_rqpkt_status.sts_chk) {
10596                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10597                     "Check Condition on REQUEST SENSE\n");
10598                 return (rval);
10599         }
10600 
10601 
10602         /* was there enough data? */
10603         if (pkt->pkt_state & STATE_XARQ_DONE) {
10604                 amt = (int)MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10605         } else {
10606                 if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) {
10607                         amt = (int)MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10608                 } else {
10609                         amt = (int)SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10610                 }
10611         }
10612         if ((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0 ||
10613             (amt < SUN_MIN_SENSE_LENGTH)) {
10614                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10615                     "REQUEST SENSE couldn't get sense data\n");
10616                 return (rval);
10617         }
10618 
10619         if (pkt->pkt_state & STATE_XARQ_DONE) {
10620                 bcopy(&arqstat->sts_sensedata, ST_RQSENSE, MAX_SENSE_LENGTH);
10621         } else {
10622                 bcopy(&arqstat->sts_sensedata, ST_RQSENSE, SENSE_LENGTH);
10623         }
10624 
10625         /*
10626          * copy one arqstat entry in the sense data buffer
10627          */
10628         st_update_error_stack(un, pkt, arqstat);
10629 
10630         return (st_decode_sense(un, bp, amt, arqstat, pos));
10631 }
10632 
10633 static errstate
10634 st_decode_sense(struct scsi_tape *un, struct buf *bp, int amt,
10635     struct scsi_arq_status *statusp, tapepos_t *pos)
10636 {
10637         struct scsi_pkt *pkt = BP_PKT(bp);
10638         recov_info *ri = pkt->pkt_private;
10639         errstate rval = COMMAND_DONE_ERROR;
10640         cmd_attribute const *attrib;
10641         long resid;
10642         struct scsi_extended_sense *sensep = ST_RQSENSE;
10643         int severity;
10644         int get_error;
10645 
10646         ST_FUNC(ST_DEVINFO, st_decode_sense);
10647 
10648         ASSERT(mutex_owned(ST_MUTEX));
10649         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10650             "st_decode_sense()\n");
10651 
10652         /*
10653          * For uscsi commands, squirrel away a copy of the
10654          * results of the Request Sense.
10655          */
10656         if (USCSI_CMD(bp)) {
10657                 struct uscsi_cmd *ucmd = BP_UCMD(bp);
10658                 ucmd->uscsi_rqstatus = *(uchar_t *)statusp;
10659                 if (ucmd->uscsi_rqlen && un->un_srqbufp) {
10660                         uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
10661                         ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
10662                         bcopy(ST_RQSENSE, un->un_srqbufp, rqlen);
10663                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10664                             "st_decode_sense: stat=0x%x resid=0x%x\n",
10665                             ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
10666                 }
10667         }
10668 
10669         if (ri->privatelen == sizeof (recov_info)) {
10670                 attrib = ri->cmd_attrib;
10671         } else {
10672                 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
10673         }
10674 
10675         /*
10676          * If the drive is an MT-02, reposition the
10677          * secondary error code into the proper place.
10678          *
10679          * XXX  MT-02 is non-CCS tape, so secondary error code
10680          * is in byte 8.  However, in SCSI-2, tape has CCS definition
10681          * so it's in byte 12.
10682          */
10683         if (un->un_dp->type == ST_TYPE_EMULEX) {
10684                 sensep->es_code = sensep->es_add_info[0];
10685         }
10686 
10687         ST_CDB(ST_DEVINFO, "st_decode_sense failed CDB",
10688             (caddr_t)&CDBP(pkt)->scc_cmd);
10689 
10690         ST_SENSE(ST_DEVINFO, "st_decode_sense sense data", (caddr_t)statusp,
10691             sizeof (*statusp));
10692 
10693         /* for normal I/O check extract the resid values. */
10694         if (bp != un->un_sbufp && bp != un->un_recov_buf) {
10695                 if (sensep->es_valid) {
10696                         resid =
10697                             (sensep->es_info_1 << 24) |
10698                             (sensep->es_info_2 << 16) |
10699                             (sensep->es_info_3 << 8)  |
10700                             (sensep->es_info_4);
10701                         /* If fixed block */
10702                         if (un->un_bsize) {
10703                                 resid *= un->un_bsize;
10704                         }
10705                 } else if (pkt->pkt_state & STATE_XFERRED_DATA) {
10706                         resid = pkt->pkt_resid;
10707                 } else {
10708                         resid = bp->b_bcount;
10709                 }
10710                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10711                     "st_decode_sense (rw): xferred bit = %d, resid=%ld (%d), "
10712                     "pkt_resid=%ld\n", pkt->pkt_state & STATE_XFERRED_DATA,
10713                     resid,
10714                     (sensep->es_info_1 << 24) |
10715                     (sensep->es_info_2 << 16) |
10716                     (sensep->es_info_3 << 8)  |
10717                     (sensep->es_info_4),
10718                     pkt->pkt_resid);
10719                 /*
10720                  * The problem is, what should we believe?
10721                  */
10722                 if (resid && (pkt->pkt_resid == 0)) {
10723                         pkt->pkt_resid = resid;
10724                 }
10725         } else {
10726                 /*
10727                  * If the command is SCMD_SPACE, we need to get the
10728                  * residual as returned in the sense data, to adjust
10729                  * our idea of current tape position correctly
10730                  */
10731                 if ((sensep->es_valid) &&
10732                     (CDBP(pkt)->scc_cmd == SCMD_LOCATE) ||
10733                     (CDBP(pkt)->scc_cmd == SCMD_LOCATE_G4) ||
10734                     (CDBP(pkt)->scc_cmd == SCMD_SPACE) ||
10735                     (CDBP(pkt)->scc_cmd == SCMD_SPACE_G4) ||
10736                     (CDBP(pkt)->scc_cmd == SCMD_WRITE_FILE_MARK)) {
10737                         resid =
10738                             (sensep->es_info_1 << 24) |
10739                             (sensep->es_info_2 << 16) |
10740                             (sensep->es_info_3 << 8)  |
10741                             (sensep->es_info_4);
10742                         bp->b_resid = resid;
10743                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10744                             "st_decode_sense(other):    resid=%ld\n", resid);
10745                 } else {
10746                         /*
10747                          * If the special command is SCMD_READ,
10748                          * the correct resid will be set later.
10749                          */
10750                         if (attrib->get_cnt != NULL) {
10751                                 resid = attrib->get_cnt(pkt->pkt_cdbp);
10752                         } else {
10753                                 resid = bp->b_bcount;
10754                         }
10755                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10756                             "st_decode_sense(special read):  resid=%ld\n",
10757                             resid);
10758                 }
10759         }
10760 
10761         if ((un->un_state >= ST_STATE_OPEN) &&
10762             (DEBUGGING || st_error_level == SCSI_ERR_ALL)) {
10763                 st_print_cdb(ST_DEVINFO, st_label, CE_NOTE,
10764                     "Failed CDB", (char *)pkt->pkt_cdbp);
10765                 st_clean_print(ST_DEVINFO, st_label, CE_CONT,
10766                     "sense data", (char *)sensep, amt);
10767                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
10768                     "count 0x%lx resid 0x%lx pktresid 0x%lx\n",
10769                     bp->b_bcount, resid, pkt->pkt_resid);
10770         }
10771 
10772         switch (un->un_status = sensep->es_key) {
10773         case KEY_NO_SENSE:
10774                 severity = SCSI_ERR_INFO;
10775 
10776                 /*
10777                  * Erase, locate or rewind operation in progress, retry
10778                  * ASC  ASCQ
10779                  *  00   18    Erase operation in progress
10780                  *  00   19    Locate operation in progress
10781                  *  00   1A    Rewind operation in progress
10782                  */
10783                 if (sensep->es_add_code == 0 &&
10784                     ((sensep->es_qual_code == 0x18) ||
10785                     (sensep->es_qual_code == 0x19) ||
10786                     (sensep->es_qual_code == 0x1a))) {
10787                         rval = QUE_BUSY_COMMAND;
10788                         break;
10789                 }
10790 
10791                 goto common;
10792 
10793         case KEY_RECOVERABLE_ERROR:
10794                 severity = SCSI_ERR_RECOVERED;
10795                 if ((sensep->es_class == CLASS_EXTENDED_SENSE) &&
10796                     (sensep->es_code == ST_DEFERRED_ERROR)) {
10797                         if (un->un_dp->options &
10798                             ST_RETRY_ON_RECOVERED_DEFERRED_ERROR) {
10799                                 rval = QUE_LAST_COMMAND;
10800                                 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label,
10801                                     severity, pos->lgclblkno,
10802                                     un->un_err_pos.lgclblkno, scsi_cmds,
10803                                     sensep);
10804                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
10805                                     "Command will be retried\n");
10806                         } else {
10807                                 severity = SCSI_ERR_FATAL;
10808                                 rval = COMMAND_DONE_ERROR_RECOVERED;
10809                                 ST_DO_ERRSTATS(un, st_softerrs);
10810                                 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label,
10811                                     severity, pos->lgclblkno,
10812                                     un->un_err_pos.lgclblkno, scsi_cmds,
10813                                     sensep);
10814                         }
10815                         break;
10816                 }
10817 common:
10818                 /*
10819                  * XXX only want reads to be stopped by filemarks.
10820                  * Don't want them to be stopped by EOT.  EOT matters
10821                  * only on write.
10822                  */
10823                 if (sensep->es_filmk && !sensep->es_eom) {
10824                         rval = COMMAND_DONE;
10825                 } else if (sensep->es_eom) {
10826                         rval = COMMAND_DONE;
10827                 } else if (sensep->es_ili) {
10828                         /*
10829                          * Fun with variable length record devices:
10830                          * for specifying larger blocks sizes than the
10831                          * actual physical record size.
10832                          */
10833                         if (un->un_bsize == 0 && resid > 0) {
10834                                 /*
10835                                  * XXX! Ugly.
10836                                  * The requested blocksize is > tape blocksize,
10837                                  * so this is ok, so we just return the
10838                                  * actual size xferred.
10839                                  */
10840                                 pkt->pkt_resid = resid;
10841                                 rval = COMMAND_DONE;
10842                         } else if (un->un_bsize == 0 && resid < 0) {
10843                                 /*
10844                                  * The requested blocksize is < tape blocksize,
10845                                  * so this is not ok, so we err with ENOMEM
10846                                  */
10847                                 rval = COMMAND_DONE_ERROR_RECOVERED;
10848                                 st_bioerror(bp, ENOMEM);
10849                         } else {
10850                                 ST_DO_ERRSTATS(un, st_softerrs);
10851                                 severity = SCSI_ERR_FATAL;
10852                                 rval = COMMAND_DONE_ERROR;
10853                                 st_bioerror(bp, EINVAL);
10854                                 un->un_running.pmode = invalid;
10855                         }
10856                 } else {
10857                         /*
10858                          * we hope and pray for this just being
10859                          * something we can ignore (ie. a
10860                          * truly recoverable soft error)
10861                          */
10862                         rval = COMMAND_DONE;
10863                 }
10864                 if (sensep->es_filmk) {
10865                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10866                             "filemark\n");
10867                         un->un_status = SUN_KEY_EOF;
10868                         pos->eof = ST_EOF_PENDING;
10869                         st_set_pe_flag(un);
10870                 }
10871 
10872                 /*
10873                  * ignore eom when reading, a fmk should terminate reading
10874                  */
10875                 if ((sensep->es_eom) &&
10876                     (CDBP(pkt)->scc_cmd != SCMD_READ)) {
10877                         if ((sensep->es_add_code == 0) &&
10878                             (sensep->es_qual_code == 4)) {
10879                                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10880                                     "bot\n");
10881                                 un->un_status = SUN_KEY_BOT;
10882                                 pos->eof = ST_NO_EOF;
10883                                 pos->lgclblkno = 0;
10884                                 pos->fileno = 0;
10885                                 pos->blkno = 0;
10886                                 if (pos->pmode != legacy)
10887                                         pos->pmode = legacy;
10888                         } else {
10889                                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10890                                     "eom\n");
10891                                 un->un_status = SUN_KEY_EOT;
10892                                 pos->eof = ST_EOM;
10893                         }
10894                         st_set_pe_flag(un);
10895                 }
10896 
10897                 break;
10898 
10899         case KEY_ILLEGAL_REQUEST:
10900 
10901                 if (un->un_laststate >= ST_STATE_OPEN) {
10902                         ST_DO_ERRSTATS(un, st_softerrs);
10903                         severity = SCSI_ERR_FATAL;
10904                 } else {
10905                         severity = SCSI_ERR_INFO;
10906                 }
10907                 break;
10908 
10909         case KEY_MEDIUM_ERROR:
10910                 ST_DO_ERRSTATS(un, st_harderrs);
10911                 severity = SCSI_ERR_FATAL;
10912                 un->un_pos.pmode = invalid;
10913                 un->un_running.pmode = invalid;
10914 check_keys:
10915                 /*
10916                  * attempt to process the keys in the presence of
10917                  * other errors
10918                  */
10919                 if (sensep->es_ili && rval != COMMAND_DONE_ERROR) {
10920                         /*
10921                          * Fun with variable length record devices:
10922                          * for specifying larger blocks sizes than the
10923                          * actual physical record size.
10924                          */
10925                         if (un->un_bsize == 0 && resid > 0) {
10926                                 /*
10927                                  * XXX! Ugly
10928                                  */
10929                                 pkt->pkt_resid = resid;
10930                         } else if (un->un_bsize == 0 && resid < 0) {
10931                                 st_bioerror(bp, EINVAL);
10932                         } else {
10933                                 severity = SCSI_ERR_FATAL;
10934                                 rval = COMMAND_DONE_ERROR;
10935                                 st_bioerror(bp, EINVAL);
10936                         }
10937                 }
10938                 if (sensep->es_filmk) {
10939                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10940                             "filemark\n");
10941                         un->un_status = SUN_KEY_EOF;
10942                         pos->eof = ST_EOF_PENDING;
10943                         st_set_pe_flag(un);
10944                 }
10945 
10946                 /*
10947                  * ignore eom when reading, a fmk should terminate reading
10948                  */
10949                 if ((sensep->es_eom) &&
10950                     (CDBP(pkt)->scc_cmd != SCMD_READ)) {
10951                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "eom\n");
10952                         un->un_status = SUN_KEY_EOT;
10953                         pos->eof = ST_EOM;
10954                         st_set_pe_flag(un);
10955                 }
10956 
10957                 break;
10958 
10959         case KEY_VOLUME_OVERFLOW:
10960                 ST_DO_ERRSTATS(un, st_softerrs);
10961                 pos->eof = ST_EOM;
10962                 severity = SCSI_ERR_FATAL;
10963                 rval = COMMAND_DONE_ERROR;
10964                 goto check_keys;
10965 
10966         case KEY_HARDWARE_ERROR:
10967                 ST_DO_ERRSTATS(un, st_harderrs);
10968                 severity = SCSI_ERR_FATAL;
10969                 rval = COMMAND_DONE_ERROR;
10970                 if (un->un_dp->options & ST_EJECT_ON_CHANGER_FAILURE)
10971                         un->un_eject_tape_on_failure = st_check_asc_ascq(un);
10972                 break;
10973 
10974         case KEY_BLANK_CHECK:
10975                 ST_DO_ERRSTATS(un, st_softerrs);
10976                 severity = SCSI_ERR_INFO;
10977 
10978                 /*
10979                  * if not a special request and some data was xferred then it
10980                  * it is not an error yet
10981                  */
10982                 if (bp != un->un_sbufp && (bp->b_flags & B_READ)) {
10983                         /*
10984                          * no error for read with or without data xferred
10985                          */
10986                         un->un_status = SUN_KEY_EOT;
10987                         pos->eof = ST_EOT;
10988                         rval = COMMAND_DONE_ERROR;
10989                         un->un_running.pmode = invalid;
10990                         st_set_pe_flag(un);
10991                         goto check_keys;
10992                 } else if (bp != un->un_sbufp &&
10993                     (pkt->pkt_state & STATE_XFERRED_DATA)) {
10994                         rval = COMMAND_DONE;
10995                 } else {
10996                         rval = COMMAND_DONE_ERROR_RECOVERED;
10997                 }
10998 
10999                 if (un->un_laststate >= ST_STATE_OPEN) {
11000                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11001                             "blank check\n");
11002                         pos->eof = ST_EOM;
11003                 }
11004                 if ((CDBP(pkt)->scc_cmd == SCMD_LOCATE) ||
11005                     (CDBP(pkt)->scc_cmd == SCMD_LOCATE_G4) ||
11006                     (CDBP(pkt)->scc_cmd == SCMD_SPACE) &&
11007                     (un->un_dp->options & ST_KNOWS_EOD)) {
11008                         /*
11009                          * we were doing a fast forward by skipping
11010                          * multiple fmk at the time
11011                          */
11012                         st_bioerror(bp, EIO);
11013                         severity = SCSI_ERR_RECOVERED;
11014                         rval     = COMMAND_DONE;
11015                 }
11016                 st_set_pe_flag(un);
11017                 goto check_keys;
11018 
11019         case KEY_WRITE_PROTECT:
11020                 if (st_wrongtapetype(un)) {
11021                         un->un_status = SUN_KEY_WRONGMEDIA;
11022                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11023                             "wrong tape for writing- use DC6150 tape "
11024                             "(or equivalent)\n");
11025                         severity = SCSI_ERR_UNKNOWN;
11026                 } else {
11027                         severity = SCSI_ERR_FATAL;
11028                 }
11029                 ST_DO_ERRSTATS(un, st_harderrs);
11030                 rval = COMMAND_DONE_ERROR;
11031                 st_bioerror(bp, EACCES);
11032                 break;
11033 
11034         case KEY_UNIT_ATTENTION:
11035                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11036                     "KEY_UNIT_ATTENTION : un_state = %d\n", un->un_state);
11037 
11038                 un->un_unit_attention_flags |= 1;
11039                 /*
11040                  * If we have detected a Bus Reset and the tape
11041                  * drive has been reserved.
11042                  */
11043                 if (ST_RQSENSE->es_add_code == 0x29) {
11044                         rval = DEVICE_RESET;
11045                         if ((un->un_rsvd_status &
11046                             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
11047                             ST_RESERVE) {
11048                                 un->un_rsvd_status |= ST_LOST_RESERVE;
11049                                 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
11050                                     "st_decode_sense: Lost Reservation\n");
11051                         }
11052                 }
11053 
11054                 /*
11055                  * If this is a recovery command and retrable, retry.
11056                  */
11057                 if (bp == un->un_recov_buf) {
11058                         severity = SCSI_ERR_INFO;
11059                         if (attrib->retriable &&
11060                             ri->pkt_retry_cnt++ < st_retry_count) {
11061                                 rval = QUE_COMMAND;
11062                         } else {
11063                                 rval = COMMAND_DONE_ERROR;
11064                         }
11065                         break; /* Don't set position invalid */
11066                 }
11067 
11068                 /*
11069                  * If ST_APPLICATION_RESERVATIONS is set,
11070                  * If the asc/ascq indicates that the reservation
11071                  * has been cleared just allow the write to continue
11072                  * which would force a scsi 2 reserve.
11073                  * If preempted that persistent reservation
11074                  * the scsi 2 reserve would get a reservation conflict.
11075                  */
11076                 if ((un->un_rsvd_status &
11077                     ST_APPLICATION_RESERVATIONS) != 0) {
11078                         /*
11079                          * RESERVATIONS PREEMPTED
11080                          * With MPxIO this could be a fail over? XXX
11081                          */
11082                         if (ST_RQSENSE->es_add_code == 0x2a &&
11083                             ST_RQSENSE->es_qual_code == 0x03) {
11084                                 severity = SCSI_ERR_INFO;
11085                                 rval = COMMAND_DONE_ERROR;
11086                                 pos->pmode = invalid;
11087                                 break;
11088                         /*
11089                          * RESERVATIONS RELEASED
11090                          */
11091                         } else if (ST_RQSENSE->es_add_code == 0x2a &&
11092                             ST_RQSENSE->es_qual_code == 0x04) {
11093                                 severity = SCSI_ERR_INFO;
11094                                 rval = COMMAND_DONE;
11095                                 break;
11096                         }
11097                 }
11098 
11099                 if (un->un_state <= ST_STATE_OPENING) {
11100                         /*
11101                          * Look, the tape isn't open yet, now determine
11102                          * if the cause is a BUS RESET, Save the file
11103                          * and Block positions for the callers to
11104                          * recover from the loss of position.
11105                          */
11106                         severity = SCSI_ERR_INFO;
11107                         if ((pos->pmode != invalid) &&
11108                             (rval == DEVICE_RESET) &&
11109                             (un->un_restore_pos != 1)) {
11110                                 un->un_save_fileno = pos->fileno;
11111                                 un->un_save_blkno = pos->blkno;
11112                                 un->un_restore_pos = 1;
11113                         }
11114 
11115                         if (attrib->retriable &&
11116                             ri->pkt_retry_cnt++ < st_retry_count) {
11117                                 rval = QUE_COMMAND;
11118                         } else if (rval == DEVICE_RESET) {
11119                                 break;
11120                         } else {
11121                                 rval = COMMAND_DONE_ERROR;
11122                         }
11123                 /*
11124                  * Means it thinks the mode parameters have changed.
11125                  * This is the result of a reset clearing settings or
11126                  * another initiator changing what we set.
11127                  */
11128                 }
11129                 if (ST_RQSENSE->es_add_code == 0x2a) {
11130                         if (ST_RQSENSE->es_qual_code == 0x1) {
11131                                 /* Error recovery will modeselect and retry. */
11132                                 rval = DEVICE_TAMPER;
11133                                 severity = SCSI_ERR_INFO;
11134                                 break; /* don't set position invalid */
11135                         }
11136                         if (ST_RQSENSE->es_qual_code == 0x0 ||
11137                             ST_RQSENSE->es_qual_code == 0x2 ||
11138                             ST_RQSENSE->es_qual_code == 0x3 ||
11139                             ST_RQSENSE->es_qual_code == 0x4 ||
11140                             ST_RQSENSE->es_qual_code == 0x5 ||
11141                             ST_RQSENSE->es_qual_code == 0x6 ||
11142                             ST_RQSENSE->es_qual_code == 0x7) {
11143                                 rval = DEVICE_TAMPER;
11144                                 severity = SCSI_ERR_INFO;
11145                         }
11146                 } else if (ST_RQSENSE->es_add_code == 0x28 &&
11147                     ((ST_RQSENSE->es_qual_code == 0x0) ||
11148                     ST_RQSENSE->es_qual_code == 0x5)) {
11149                         /*
11150                          * Not Ready to Ready change, Media may have changed.
11151                          */
11152                         rval = DEVICE_TAMPER;
11153                         severity = SCSI_ERR_RETRYABLE;
11154                 } else {
11155                         if (rval != DEVICE_RESET) {
11156                                 rval = COMMAND_DONE_ERROR;
11157                         } else {
11158                                 /*
11159                                  * Returning DEVICE_RESET will call
11160                                  * error recovery.
11161                                  */
11162                                 severity = SCSI_ERR_INFO;
11163                                 break; /* don't set position invalid */
11164                         }
11165                         /*
11166                          * Check if it is an Unexpected Unit Attention.
11167                          * If state is >= ST_STATE_OPEN, we have
11168                          * already done the initialization .
11169                          * In this case it is Fatal Error
11170                          * since no further reading/writing
11171                          * can be done with fileno set to < 0.
11172                          */
11173                         if (un->un_state >= ST_STATE_OPEN) {
11174                                 ST_DO_ERRSTATS(un, st_harderrs);
11175                                 severity = SCSI_ERR_FATAL;
11176                         } else {
11177                                 severity = SCSI_ERR_INFO;
11178                         }
11179                 }
11180 
11181                 pos->pmode = invalid;
11182 
11183                 break;
11184 
11185         case KEY_NOT_READY:
11186                 /*
11187                  * If in process of getting ready retry.
11188                  */
11189                 if (sensep->es_add_code == 0x04) {
11190                         switch (sensep->es_qual_code) {
11191                         case 0x07:
11192                                 /*
11193                                  * We get here when the tape is rewinding.
11194                                  * QUE_BUSY_COMMAND retries every 10 seconds.
11195                                  */
11196                                 if (ri->pkt_retry_cnt++ <
11197                                     (un->un_dp->rewind_timeout / 10)) {
11198                                         rval = QUE_BUSY_COMMAND;
11199                                         severity = SCSI_ERR_INFO;
11200                                 } else {
11201                                         /* give up */
11202                                         rval = COMMAND_DONE_ERROR;
11203                                         severity = SCSI_ERR_FATAL;
11204                                 }
11205                                 break;
11206                         case 0x01:
11207                                 if (ri->pkt_retry_cnt++ < st_retry_count) {
11208                                         rval = QUE_COMMAND;
11209                                         severity = SCSI_ERR_INFO;
11210                                         break;
11211                                 }
11212                         default: /* FALLTHRU */
11213                                 /* give up */
11214                                 rval = COMMAND_DONE_ERROR;
11215                                 severity = SCSI_ERR_FATAL;
11216                         }
11217                 } else {
11218                         /* give up */
11219                         rval = COMMAND_DONE_ERROR;
11220                         severity = SCSI_ERR_FATAL;
11221                 }
11222 
11223                 /*
11224                  * If this was an error and after device opened
11225                  * do error stats.
11226                  */
11227                 if (rval == COMMAND_DONE_ERROR &&
11228                     un->un_state > ST_STATE_OPENING) {
11229                         ST_DO_ERRSTATS(un, st_harderrs);
11230                 }
11231 
11232                 if (ST_RQSENSE->es_add_code == 0x3a) {
11233                         if (st_error_level >= SCSI_ERR_FATAL)
11234                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
11235                                     "Tape not inserted in drive\n");
11236                         un->un_mediastate = MTIO_EJECTED;
11237                         cv_broadcast(&un->un_state_cv);
11238                 }
11239                 if ((un->un_dp->options & ST_EJECT_ON_CHANGER_FAILURE) &&
11240                     (rval != QUE_COMMAND))
11241                         un->un_eject_tape_on_failure = st_check_asc_ascq(un);
11242                 break;
11243 
11244         case KEY_ABORTED_COMMAND:
11245                 /* XXX Do drives return this when they see a lost light? */
11246                 /* Testing would say yes */
11247 
11248                 if (ri->pkt_retry_cnt++ < st_retry_count) {
11249                         rval = ATTEMPT_RETRY;
11250                         severity = SCSI_ERR_RETRYABLE;
11251                         goto check_keys;
11252                 }
11253                 /*
11254                  * Probably a parity error...
11255                  * if we retry here then this may cause data to be
11256                  * written twice or data skipped during reading
11257                  */
11258                 ST_DO_ERRSTATS(un, st_harderrs);
11259                 severity = SCSI_ERR_FATAL;
11260                 rval = COMMAND_DONE_ERROR;
11261                 goto check_keys;
11262 
11263         default:
11264                 /*
11265                  * Undecoded sense key.  Try retries and hope
11266                  * that will fix the problem.  Otherwise, we're
11267                  * dead.
11268                  */
11269                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11270                     "Unhandled Sense Key '%s'\n",
11271                     sense_keys[un->un_status]);
11272                 ST_DO_ERRSTATS(un, st_harderrs);
11273                 severity = SCSI_ERR_FATAL;
11274                 rval = COMMAND_DONE_ERROR;
11275                 goto check_keys;
11276         }
11277 
11278         if ((!(pkt->pkt_flags & FLAG_SILENT) &&
11279             un->un_state >= ST_STATE_OPEN) && (DEBUGGING ||
11280             (un->un_laststate > ST_STATE_OPENING) &&
11281             (severity >= st_error_level))) {
11282 
11283                 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label, severity,
11284                     pos->lgclblkno, un->un_err_pos.lgclblkno,
11285                     scsi_cmds, sensep);
11286                 if (sensep->es_filmk) {
11287                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
11288                             "File Mark Detected\n");
11289                 }
11290                 if (sensep->es_eom) {
11291                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
11292                             "End-of-Media Detected\n");
11293                 }
11294                 if (sensep->es_ili) {
11295                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
11296                             "Incorrect Length Indicator Set\n");
11297                 }
11298         }
11299         get_error = geterror(bp);
11300         if (((rval == COMMAND_DONE_ERROR) ||
11301             (rval == COMMAND_DONE_ERROR_RECOVERED)) &&
11302             ((get_error == EIO) || (get_error == 0))) {
11303                 un->un_rqs_state |= (ST_RQS_ERROR | ST_RQS_VALID);
11304                 bcopy(ST_RQSENSE, un->un_uscsi_rqs_buf, SENSE_LENGTH);
11305                 if (un->un_rqs_state & ST_RQS_READ) {
11306                         un->un_rqs_state &= ~(ST_RQS_READ);
11307                 } else {
11308                         un->un_rqs_state |= ST_RQS_OVR;
11309                 }
11310         }
11311 
11312         return (rval);
11313 }
11314 
11315 
11316 static int
11317 st_handle_intr_retry_lcmd(struct scsi_tape *un, struct buf *bp)
11318 {
11319         int status = TRAN_ACCEPT;
11320         pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
11321 
11322         mutex_enter(ST_MUTEX);
11323 
11324         ST_FUNC(ST_DEVINFO, st_handle_intr_retry_lcmd);
11325 
11326         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
11327             "st_handle_intr_rtr_lcmd(), un = 0x%p\n", (void *)un);
11328 
11329         /*
11330          * Check to see if we hit the retry timeout. We check to make sure
11331          * this is the first one on the runq and make sure we have not
11332          * queued up any more, so this one has to be the last on the list
11333          * also. If it is not, we have to fail.  If it is not the first, but
11334          * is the last we are in trouble anyway, as we are in the interrupt
11335          * context here.
11336          */
11337         if ((pktinfo->pkt_retry_cnt > st_retry_count) ||
11338             ((un->un_runqf != bp) && (un->un_runql != bp))) {
11339                 goto exit;
11340         }
11341 
11342         if (un->un_throttle) {
11343                 un->un_last_throttle = un->un_throttle;
11344                 un->un_throttle = 0;
11345         }
11346 
11347         /*
11348          * Here we know : bp is the first and last one on the runq
11349          * it is not necessary to put it back on the head of the
11350          * waitq and then move from waitq to runq. Save this queuing
11351          * and call scsi_transport.
11352          */
11353         ST_CDB(ST_DEVINFO, "Retry lcmd CDB", (char *)BP_PKT(bp)->pkt_cdbp);
11354 
11355         status = st_transport(un, BP_PKT(bp));
11356 
11357         if (status == TRAN_ACCEPT) {
11358                 if (un->un_last_throttle) {
11359                         un->un_throttle = un->un_last_throttle;
11360                 }
11361                 mutex_exit(ST_MUTEX);
11362 
11363                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11364                     "restart transport \n");
11365                 return (0);
11366         }
11367 
11368         ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
11369         mutex_exit(ST_MUTEX);
11370 
11371         if (status == TRAN_BUSY) {
11372                 if (st_handle_intr_busy(un, bp, ST_TRAN_BUSY_TIMEOUT) == 0) {
11373                         return (0);
11374                 }
11375         }
11376         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11377             "restart transport rejected\n");
11378         mutex_enter(ST_MUTEX);
11379         ST_DO_ERRSTATS(un, st_transerrs);
11380         if (un->un_last_throttle) {
11381                 un->un_throttle = un->un_last_throttle;
11382         }
11383 exit:
11384         mutex_exit(ST_MUTEX);
11385         return (-1);
11386 }
11387 
11388 static int
11389 st_wrongtapetype(struct scsi_tape *un)
11390 {
11391 
11392         ST_FUNC(ST_DEVINFO, st_wrongtapetype);
11393 
11394         ASSERT(mutex_owned(ST_MUTEX));
11395 
11396         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_wrongtapetype()\n");
11397 
11398         /*
11399          * Hack to handle  600A, 600XTD, 6150 && 660 vs. 300XL tapes...
11400          */
11401         if (un->un_dp && (un->un_dp->options & ST_QIC) && un->un_mspl) {
11402                 switch (un->un_dp->type) {
11403                 case ST_TYPE_WANGTEK:
11404                 case ST_TYPE_ARCHIVE:
11405                         /*
11406                          * If this really worked, we could go off of
11407                          * the density codes set in the modesense
11408                          * page. For this drive, 0x10 == QIC-120,
11409                          * 0xf == QIC-150, and 0x5 should be for
11410                          * both QIC-24 and, maybe, QIC-11. However,
11411                          * the h/w doesn't do what the manual says
11412                          * that it should, so we'll key off of
11413                          * getting a WRITE PROTECT error AND wp *not*
11414                          * set in the mode sense information.
11415                          */
11416                         /*
11417                          * XXX but we already know that status is
11418                          * write protect, so don't check it again.
11419                          */
11420 
11421                         if (un->un_status == KEY_WRITE_PROTECT &&
11422                             un->un_mspl->wp == 0) {
11423                                 return (1);
11424                         }
11425                         break;
11426                 default:
11427                         break;
11428                 }
11429         }
11430         return (0);
11431 }
11432 
11433 static errstate
11434 st_check_error(struct scsi_tape *un, struct scsi_pkt *pkt)
11435 {
11436         errstate action;
11437         recov_info *rcvi = pkt->pkt_private;
11438         buf_t *bp = rcvi->cmd_bp;
11439         struct scsi_arq_status *stat = (struct scsi_arq_status *)pkt->pkt_scbp;
11440 
11441         ST_FUNC(ST_DEVINFO, st_check_error);
11442 
11443         ASSERT(mutex_owned(ST_MUTEX));
11444 
11445         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_check_error()\n");
11446 
11447         switch (SCBP_C(pkt)) {
11448         case STATUS_RESERVATION_CONFLICT:
11449                 /*
11450                  * Command recovery is enabled, not just opening,
11451                  * we had the drive reserved and we thing its ours.
11452                  * Call recovery to attempt to take it back.
11453                  */
11454                 if ((rcvi->privatelen == sizeof (recov_info)) &&
11455                     (bp != un->un_recov_buf) &&
11456                     (un->un_state > ST_STATE_OPEN_PENDING_IO) &&
11457                     ((un->un_rsvd_status & (ST_RESERVE |
11458                     ST_APPLICATION_RESERVATIONS)) != 0)) {
11459                         action = ATTEMPT_RETRY;
11460                         un->un_rsvd_status |= ST_LOST_RESERVE;
11461                 } else {
11462                         action = COMMAND_DONE_EACCES;
11463                         un->un_rsvd_status |= ST_RESERVATION_CONFLICT;
11464                 }
11465                 break;
11466 
11467         case STATUS_BUSY:
11468                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG, "unit busy\n");
11469                 if (rcvi->privatelen == sizeof (recov_info) &&
11470                     un->un_multipath && (pkt->pkt_state == (STATE_GOT_BUS |
11471                     STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS))) {
11472                         /*
11473                          * Status returned by scsi_vhci indicating path
11474                          * has failed over.
11475                          */
11476                         action = PATH_FAILED;
11477                         break;
11478                 }
11479                 /* FALLTHRU */
11480         case STATUS_QFULL:
11481                 if (rcvi->privatelen == sizeof (recov_info)) {
11482                         /*
11483                          * If recovery is inabled use it instead of
11484                          * blind reties.
11485                          */
11486                         action = ATTEMPT_RETRY;
11487                 } else if (rcvi->pkt_retry_cnt++ < st_retry_count) {
11488                         action = QUE_BUSY_COMMAND;
11489                 } else if ((un->un_rsvd_status &
11490                     (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
11491                         /*
11492                          * If this is a command done before reserve is done
11493                          * don't reset.
11494                          */
11495                         action = COMMAND_DONE_ERROR;
11496                 } else {
11497                         ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11498                             "unit busy too long\n");
11499                         (void) st_reset(un, RESET_ALL);
11500                         action = COMMAND_DONE_ERROR;
11501                 }
11502                 break;
11503 
11504         case STATUS_CHECK:
11505         case STATUS_TERMINATED:
11506                 /*
11507                  * we should only get here if the auto rqsense failed
11508                  * thru a uscsi cmd without autorequest sense
11509                  * so we just try again
11510                  */
11511                 if (un->un_arq_enabled &&
11512                     stat->sts_rqpkt_reason == CMD_CMPLT &&
11513                     (stat->sts_rqpkt_state & (STATE_GOT_BUS |
11514                     STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS)) ==
11515                     (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
11516                     STATE_GOT_STATUS)) {
11517 
11518                         ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11519                             "Really got sense data\n");
11520                         action = st_decode_sense(un, bp, MAX_SENSE_LENGTH -
11521                             pkt->pkt_resid, stat, &un->un_pos);
11522                 } else {
11523                         ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11524                             "Trying to queue sense command\n");
11525                         action = QUE_SENSE;
11526                 }
11527                 break;
11528 
11529         case STATUS_TASK_ABORT:
11530                 /*
11531                  * This is an aborted task. This can be a reset on the other
11532                  * port of a multiport drive. Lets try and recover it.
11533                  */
11534                 action = DEVICE_RESET;
11535                 break;
11536 
11537         default:
11538                 action = COMMAND_DONE;
11539                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
11540                     "Unexpected scsi status byte 0x%x\n", SCBP_C(pkt));
11541         }
11542         return (action);
11543 }
11544 
11545 static void
11546 st_calc_bnum(struct scsi_tape *un, struct buf *bp, struct scsi_pkt *pkt)
11547 {
11548         int nblks;
11549         int nfiles;
11550         long count;
11551         recov_info *ri = pkt->pkt_private;
11552         cmd_attribute const *attrib;
11553 
11554         ST_FUNC(ST_DEVINFO, st_calc_bnum);
11555 
11556         ASSERT(mutex_owned(ST_MUTEX));
11557 
11558         if (ri->privatelen == sizeof (recov_info)) {
11559                 attrib = ri->cmd_attrib;
11560                 ASSERT(attrib->recov_pos_type == POS_EXPECTED);
11561                 ASSERT(attrib->chg_tape_pos);
11562         } else {
11563                 ri = NULL;
11564                 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
11565         }
11566 
11567         count = bp->b_bcount - bp->b_resid;
11568 
11569         /* Command reads or writes data */
11570         if (attrib->transfers_data != TRAN_NONE) {
11571                 if (count == 0) {
11572                         if (attrib->transfers_data == TRAN_WRTE) {
11573                                 ASSERT(un->un_pos.eof == ST_EOM);
11574                                 nblks = 0;
11575                                 nfiles = 0;
11576                         } else {
11577                                 ASSERT(un->un_pos.eof == ST_EOF_PENDING);
11578                                 nblks = 0;
11579                                 nfiles = 1;
11580                         }
11581                 } else if (un->un_bsize == 0) {
11582                         /*
11583                          * If variable block mode.
11584                          * Fixed bit in CBD should be zero.
11585                          */
11586                         ASSERT((pkt->pkt_cdbp[1] & 1) == 0);
11587                         nblks = 1;
11588                         un->un_kbytes_xferred += (count / ONE_K);
11589                         nfiles = 0;
11590                 } else {
11591                         /*
11592                          * If fixed block mode.
11593                          * Fixed bit in CBD should be one.
11594                          */
11595                         ASSERT((pkt->pkt_cdbp[1] & 1) == 1);
11596                         nblks = (count / un->un_bsize);
11597                         un->un_kbytes_xferred += (nblks * un->un_bsize) / ONE_K;
11598                         nfiles = 0;
11599                 }
11600                 /*
11601                  * So its possable to read some blocks and hit a filemark.
11602                  * Example reading in fixed block mode where more then one
11603                  * block at a time is requested. In this case because the
11604                  * filemark is hit something less then the requesed number
11605                  * of blocks is read.
11606                  */
11607                 if (un->un_pos.eof == ST_EOF_PENDING && bp->b_resid) {
11608                         nfiles = 1;
11609                 }
11610         } else {
11611                 nblks = 0;
11612                 nfiles = count;
11613         }
11614 
11615         /*
11616          * If some command failed after this one started and it seems
11617          * to have finshed without error count the position.
11618          */
11619         if (un->un_persistence && un->un_persist_errors) {
11620                 ASSERT(un->un_pos.pmode != invalid);
11621         }
11622 
11623         if (attrib->chg_tape_direction == DIR_FORW) {
11624                 un->un_pos.blkno += nblks;
11625                 un->un_pos.lgclblkno += nblks;
11626                 un->un_pos.lgclblkno += nfiles;
11627         } else if (attrib->chg_tape_direction == DIR_REVC) {
11628                 un->un_pos.blkno -= nblks;
11629                 un->un_pos.lgclblkno -= nblks;
11630                 un->un_pos.lgclblkno -= nfiles;
11631         } else {
11632                 ASSERT(0);
11633         }
11634 
11635         /* recovery disabled */
11636         if (ri == NULL) {
11637                 un->un_running.pmode = invalid;
11638                 return;
11639         }
11640 
11641         /*
11642          * If we didn't just read a filemark.
11643          */
11644         if (un->un_pos.eof != ST_EOF_PENDING) {
11645                 ASSERT(nblks != 0 && nfiles == 0);
11646                 /*
11647                  * If Previously calulated expected position does not match
11648                  * debug the expected position.
11649                  */
11650                 if ((ri->pos.pmode != invalid) && nblks &&
11651                     ((un->un_pos.blkno != ri->pos.blkno) ||
11652                     (un->un_pos.lgclblkno != ri->pos.lgclblkno))) {
11653 #ifdef STDEBUG
11654                         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
11655                             "Expected", &ri->pos);
11656                         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
11657                             "But Got", &un->un_pos);
11658 #endif
11659                         un->un_running.pmode = invalid;
11660                 }
11661         } else {
11662                 ASSERT(nfiles != 0);
11663                 if (un->un_running.pmode != invalid) {
11664                         /*
11665                          * blkno and lgclblkno already counted in
11666                          * st_add_recovery_info_to_pkt(). Since a block was not
11667                          * read and a filemark was.
11668                          */
11669                         if (attrib->chg_tape_direction == DIR_FORW) {
11670                                 un->un_running.fileno++;
11671                                 un->un_running.blkno = 0;
11672                         } else if (attrib->chg_tape_direction == DIR_REVC) {
11673                                 un->un_running.fileno--;
11674                                 un->un_running.blkno = LASTBLK;
11675                         }
11676                 }
11677         }
11678 }
11679 
11680 static void
11681 st_set_state(struct scsi_tape *un, struct buf *bp)
11682 {
11683         struct scsi_pkt *sp = BP_PKT(bp);
11684         struct uscsi_cmd *ucmd;
11685 
11686         ST_FUNC(ST_DEVINFO, st_set_state);
11687 
11688         ASSERT(mutex_owned(ST_MUTEX));
11689         ASSERT(bp != un->un_recov_buf);
11690 
11691         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
11692             "st_set_state(): eof=%x     fmneeded=%x  pkt_resid=0x%lx (%ld)\n",
11693             un->un_pos.eof, un->un_fmneeded, sp->pkt_resid, sp->pkt_resid);
11694 
11695         if (bp != un->un_sbufp) {
11696 #ifdef STDEBUG
11697                 if (DEBUGGING && sp->pkt_resid) {
11698                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11699                             "pkt_resid %ld bcount %ld\n",
11700                             sp->pkt_resid, bp->b_bcount);
11701                 }
11702 #endif
11703                 bp->b_resid = sp->pkt_resid;
11704                 if (geterror(bp) != EIO) {
11705                         st_calc_bnum(un, bp, sp);
11706                 }
11707                 if (bp->b_flags & B_READ) {
11708                         un->un_lastop = ST_OP_READ;
11709                         un->un_fmneeded = 0;
11710                 } else {
11711                         un->un_lastop = ST_OP_WRITE;
11712                         if (un->un_dp->options & ST_REEL) {
11713                                 un->un_fmneeded = 2;
11714                         } else {
11715                                 un->un_fmneeded = 1;
11716                         }
11717                 }
11718                 /*
11719                  * all is honky dory at this point, so let's
11720                  * readjust the throttle, to increase speed, if we
11721                  * have not throttled down.
11722                  */
11723                 if (un->un_throttle) {
11724                         un->un_throttle = un->un_max_throttle;
11725                 }
11726         } else {
11727                 optype new_lastop = ST_OP_NIL;
11728                 uchar_t cmd = (uchar_t)(intptr_t)bp->b_forw;
11729 
11730                 switch (cmd) {
11731                 case SCMD_WRITE:
11732                 case SCMD_WRITE_G4:
11733                         bp->b_resid = sp->pkt_resid;
11734                         new_lastop = ST_OP_WRITE;
11735                         if (geterror(bp) == EIO) {
11736                                 break;
11737                         }
11738                         st_calc_bnum(un, bp, sp);
11739                         if (un->un_dp->options & ST_REEL) {
11740                                 un->un_fmneeded = 2;
11741                         } else {
11742                                 un->un_fmneeded = 1;
11743                         }
11744                         break;
11745                 case SCMD_READ:
11746                 case SCMD_READ_G4:
11747                         bp->b_resid = sp->pkt_resid;
11748                         new_lastop = ST_OP_READ;
11749                         un->un_lastop = ST_OP_READ;
11750                         if (geterror(bp) == EIO) {
11751                                 break;
11752                         }
11753                         st_calc_bnum(un, bp, sp);
11754                         un->un_fmneeded = 0;
11755                         break;
11756                 case SCMD_WRITE_FILE_MARK_G4:
11757                 case SCMD_WRITE_FILE_MARK:
11758                 {
11759                         int fmdone;
11760 
11761                         if (un->un_pos.eof != ST_EOM) {
11762                                 un->un_pos.eof = ST_NO_EOF;
11763                         }
11764                         fmdone = (bp->b_bcount - bp->b_resid);
11765                         if (fmdone > 0) {
11766                                 un->un_lastop = new_lastop = ST_OP_WEOF;
11767                                 un->un_pos.lgclblkno += fmdone;
11768                                 un->un_pos.fileno += fmdone;
11769                                 un->un_pos.blkno = 0;
11770                         } else {
11771                                 new_lastop = ST_OP_CTL;
11772                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
11773                                     "Flushed buffer\n");
11774                         }
11775                         if (fmdone > un->un_fmneeded) {
11776                                 un->un_fmneeded = 0;
11777                         } else {
11778                                 un->un_fmneeded -= fmdone;
11779                         }
11780                         break;
11781                 }
11782                 case SCMD_REWIND:
11783                         un->un_pos.eof = ST_NO_EOF;
11784                         un->un_pos.fileno = 0;
11785                         un->un_pos.blkno = 0;
11786                         un->un_pos.lgclblkno = 0;
11787                         if (un->un_pos.pmode != legacy)
11788                                 un->un_pos.pmode = legacy;
11789                         new_lastop = ST_OP_CTL;
11790                         un->un_restore_pos = 0;
11791                         break;
11792 
11793                 case SCMD_SPACE:
11794                 case SCMD_SPACE_G4:
11795                 {
11796                         int64_t count;
11797                         int64_t resid;
11798                         int64_t done;
11799                         cmd_attribute const *attrib;
11800                         recov_info *ri = sp->pkt_private;
11801 
11802                         if (ri->privatelen == sizeof (recov_info)) {
11803                                 attrib = ri->cmd_attrib;
11804                         } else {
11805                                 attrib =
11806                                     st_lookup_cmd_attribute(sp->pkt_cdbp[0]);
11807                         }
11808 
11809                         resid = (int64_t)SPACE_CNT(bp->b_resid);
11810                         count = (int64_t)attrib->get_cnt(sp->pkt_cdbp);
11811 
11812                         if (count >= 0) {
11813                                 done = (count - resid);
11814                         } else {
11815                                 done = ((-count) - resid);
11816                         }
11817                         if (done > 0) {
11818                                 un->un_lastop = new_lastop = ST_OP_CTL;
11819                         } else {
11820                                 new_lastop = ST_OP_CTL;
11821                         }
11822 
11823                         ST_SPAC(ST_DEVINFO, st_label, CE_WARN,
11824                             "space cmd: cdb[1] = %s\n"
11825                             "space data:       = 0x%lx\n"
11826                             "space count:      = %"PRId64"\n"
11827                             "space resid:      = %"PRId64"\n"
11828                             "spaces done:      = %"PRId64"\n"
11829                             "fileno before     = %d\n"
11830                             "blkno before      = %d\n",
11831                             space_strs[sp->pkt_cdbp[1] & 7],
11832                             bp->b_bcount,
11833                             count, resid, done,
11834                             un->un_pos.fileno, un->un_pos.blkno);
11835 
11836                         switch (sp->pkt_cdbp[1]) {
11837                         case SPACE_TYPE(SP_FLM):
11838                                 /* Space file forward */
11839                                 if (count >= 0) {
11840                                         if (un->un_pos.eof <= ST_EOF) {
11841                                                 un->un_pos.eof = ST_NO_EOF;
11842                                         }
11843                                         un->un_pos.fileno += done;
11844                                         un->un_pos.blkno = 0;
11845                                         break;
11846                                 }
11847                                 /* Space file backward */
11848                                 if (done > un->un_pos.fileno) {
11849                                         un->un_pos.fileno = 0;
11850                                         un->un_pos.blkno = 0;
11851                                 } else {
11852                                         un->un_pos.fileno -= done;
11853                                         un->un_pos.blkno = LASTBLK;
11854                                         un->un_running.pmode = invalid;
11855                                 }
11856                                 break;
11857                         case SPACE_TYPE(SP_BLK):
11858                                 /* Space block forward */
11859                                 if (count >= 0) {
11860                                         un->un_pos.blkno += done;
11861                                         break;
11862                                 }
11863                                 /* Space block backward */
11864                                 if (un->un_pos.eof >= ST_EOF_PENDING) {
11865                                 /*
11866                                  * we stepped back into
11867                                  * a previous file; we are not
11868                                  * making an effort to pretend that
11869                                  * we are still in the current file
11870                                  * ie. logical == physical position
11871                                  * and leave it to st_ioctl to correct
11872                                  */
11873                                         if (done > un->un_pos.blkno) {
11874                                                 un->un_pos.blkno = 0;
11875                                         } else {
11876                                                 un->un_pos.fileno--;
11877                                                 un->un_pos.blkno = LASTBLK;
11878                                                 un->un_running.pmode = invalid;
11879                                         }
11880                                 } else {
11881                                         un->un_pos.blkno -= done;
11882                                 }
11883                                 break;
11884                         case SPACE_TYPE(SP_SQFLM):
11885                                 un->un_pos.pmode = logical;
11886                                 un->un_pos.blkno = 0;
11887                                 un->un_lastop = new_lastop = ST_OP_CTL;
11888                                 break;
11889                         case SPACE_TYPE(SP_EOD):
11890                                 un->un_pos.pmode = logical;
11891                                 un->un_pos.eof = ST_EOM;
11892                                 un->un_status = KEY_BLANK_CHECK;
11893                                 break;
11894                         default:
11895                                 un->un_pos.pmode = invalid;
11896                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
11897                                     "Unsupported space cmd: %s\n",
11898                                     space_strs[sp->pkt_cdbp[1] & 7]);
11899 
11900                                 un->un_lastop = new_lastop = ST_OP_CTL;
11901                         }
11902 
11903                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11904                             "after_space rs %"PRId64" fil %d blk %d\n",
11905                             resid, un->un_pos.fileno, un->un_pos.blkno);
11906 
11907                         break;
11908                 }
11909                 case SCMD_LOAD:
11910                         if ((bp->b_bcount & (LD_LOAD | LD_EOT)) == LD_LOAD) {
11911                                 un->un_pos.fileno = 0;
11912                                 if (un->un_pos.pmode != legacy)
11913                                         un->un_pos.pmode = legacy;
11914                         } else {
11915                                 un->un_state = ST_STATE_OFFLINE;
11916                                 un->un_pos.pmode = invalid;
11917 
11918                         }
11919                         /*
11920                          * If we are loading or unloading we expect the media id
11921                          * to change. Lets make it unknown.
11922                          */
11923                         if (un->un_media_id != bogusID && un->un_media_id_len) {
11924                                 kmem_free(un->un_media_id, un->un_media_id_len);
11925                                 un->un_media_id = NULL;
11926                                 un->un_media_id_len = 0;
11927                         }
11928                         un->un_density_known = 0;
11929                         un->un_pos.eof = ST_NO_EOF;
11930                         un->un_pos.blkno = 0;
11931                         un->un_lastop = new_lastop = ST_OP_CTL;
11932                         break;
11933                 case SCMD_ERASE:
11934                         un->un_pos.eof = ST_NO_EOF;
11935                         un->un_pos.blkno = 0;
11936                         un->un_pos.fileno = 0;
11937                         un->un_pos.lgclblkno = 0;
11938                         if (un->un_pos.pmode != legacy)
11939                                 un->un_pos.pmode = legacy;
11940                         new_lastop = ST_OP_CTL;
11941                         break;
11942                 case SCMD_RESERVE:
11943                         un->un_rsvd_status |= ST_RESERVE;
11944                         un->un_rsvd_status &=
11945                             ~(ST_RELEASE | ST_LOST_RESERVE |
11946                             ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
11947                         new_lastop = ST_OP_CTL;
11948                         break;
11949                 case SCMD_RELEASE:
11950                         un->un_rsvd_status |= ST_RELEASE;
11951                         un->un_rsvd_status &=
11952                             ~(ST_RESERVE | ST_LOST_RESERVE |
11953                             ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
11954                         new_lastop = ST_OP_CTL;
11955                         break;
11956                 case SCMD_PERSISTENT_RESERVE_IN:
11957                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11958                             "PGR_IN command\n");
11959                         new_lastop = ST_OP_CTL;
11960                         break;
11961                 case SCMD_PERSISTENT_RESERVE_OUT:
11962                         switch (sp->pkt_cdbp[1] & ST_SA_MASK) {
11963                         case ST_SA_SCSI3_RESERVE:
11964                         case ST_SA_SCSI3_PREEMPT:
11965                         case ST_SA_SCSI3_PREEMPTANDABORT:
11966                                 un->un_rsvd_status |=
11967                                     (ST_APPLICATION_RESERVATIONS | ST_RESERVE);
11968                                 un->un_rsvd_status &= ~(ST_RELEASE |
11969                                     ST_LOST_RESERVE | ST_RESERVATION_CONFLICT |
11970                                     ST_INITIATED_RESET);
11971                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11972                                     "PGR Reserve and set: entering"
11973                                     " ST_APPLICATION_RESERVATIONS mode");
11974                                 break;
11975                         case ST_SA_SCSI3_REGISTER:
11976                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11977                                     "PGR Reserve register key");
11978                                 un->un_rsvd_status |= ST_INIT_RESERVE;
11979                                 break;
11980                         case ST_SA_SCSI3_CLEAR:
11981                                 un->un_rsvd_status &= ~ST_INIT_RESERVE;
11982                                 /* FALLTHROUGH */
11983                         case ST_SA_SCSI3_RELEASE:
11984                                 un->un_rsvd_status &=
11985                                     ~(ST_APPLICATION_RESERVATIONS | ST_RESERVE |
11986                                     ST_LOST_RESERVE | ST_RESERVATION_CONFLICT |
11987                                     ST_INITIATED_RESET);
11988                                 un->un_rsvd_status |= ST_RELEASE;
11989                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11990                                     "PGR Release and reset: exiting"
11991                                     " ST_APPLICATION_RESERVATIONS mode");
11992                                 break;
11993                         }
11994                         new_lastop = ST_OP_CTL;
11995                         break;
11996                 case SCMD_TEST_UNIT_READY:
11997                 case SCMD_READ_BLKLIM:
11998                 case SCMD_REQUEST_SENSE:
11999                 case SCMD_INQUIRY:
12000                 case SCMD_RECOVER_BUF:
12001                 case SCMD_MODE_SELECT:
12002                 case SCMD_MODE_SENSE:
12003                 case SCMD_DOORLOCK:
12004                 case SCMD_READ_BUFFER:
12005                 case SCMD_REPORT_DENSITIES:
12006                 case SCMD_LOG_SELECT_G1:
12007                 case SCMD_LOG_SENSE_G1:
12008                 case SCMD_REPORT_LUNS:
12009                 case SCMD_READ_ATTRIBUTE:
12010                 case SCMD_WRITE_ATTRIBUTE:
12011                 case SCMD_SVC_ACTION_IN_G5:
12012                 case SCMD_SECURITY_PROTO_IN:
12013                 case SCMD_SECURITY_PROTO_OUT:
12014                         new_lastop = ST_OP_CTL;
12015                         break;
12016                 case SCMD_READ_POSITION:
12017                         new_lastop = ST_OP_CTL;
12018                         /*
12019                          * Only if the buf used was un_sbufp.
12020                          * Among other things the prevents read positions used
12021                          * as part of error recovery from messing up our
12022                          * current position as they will use un_recov_buf.
12023                          */
12024                         if (USCSI_CMD(bp)) {
12025                                 (void) st_get_read_pos(un, bp);
12026                         }
12027                         break;
12028                 case SCMD_LOCATE:
12029                 case SCMD_LOCATE_G4:
12030                         /* Locate makes position mode no longer legacy */
12031                         un->un_lastop = new_lastop = ST_OP_CTL;
12032                         break;
12033                 case SCMD_MAINTENANCE_IN:
12034                         switch (sp->pkt_cdbp[1]) {
12035                         case SSVC_ACTION_GET_SUPPORTED_OPERATIONS:
12036                         case SSVC_ACTION_SET_TARGET_PORT_GROUPS:
12037                                 new_lastop = ST_OP_CTL;
12038                                 break;
12039                         }
12040                         if (new_lastop != ST_OP_NIL) {
12041                                 break;
12042                         }
12043                 default:
12044                         /*
12045                          * Unknown command, If was USCSI and USCSI_SILENT
12046                          * flag was not set, set position to unknown.
12047                          */
12048                         if ((((ucmd = BP_UCMD(bp)) != NULL) &&
12049                             (ucmd->uscsi_flags & USCSI_SILENT) == 0)) {
12050                                 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
12051                                     "unknown cmd 0x%X caused loss of state\n",
12052                                     cmd);
12053                         } else {
12054                                 /*
12055                                  * keep the old agreement to allow unknown
12056                                  * commands with the USCSI_SILENT set.
12057                                  * This prevents ASSERT below.
12058                                  */
12059                                 new_lastop = ST_OP_CTL;
12060                                 break;
12061                         }
12062                         /* FALLTHROUGH */
12063                 case SCMD_WRITE_BUFFER: /* Writes new firmware to device */
12064                         un->un_pos.pmode = invalid;
12065                         un->un_lastop = new_lastop = ST_OP_CTL;
12066                         break;
12067                 }
12068 
12069                 /* new_lastop should have been changed */
12070                 ASSERT(new_lastop != ST_OP_NIL);
12071 
12072                 /* If un_lastop should copy new_lastop  */
12073                 if (((un->un_lastop == ST_OP_WRITE) ||
12074                     (un->un_lastop == ST_OP_WEOF)) &&
12075                     new_lastop != ST_OP_CTL) {
12076                         un->un_lastop = new_lastop;
12077                 }
12078         }
12079 
12080         /*
12081          * In the st driver we have a logical and physical file position.
12082          * Under BSD behavior, when you get a zero read, the logical position
12083          * is before the filemark but after the last record of the file.
12084          * The physical position is after the filemark. MTIOCGET should always
12085          * return the logical file position.
12086          *
12087          * The next read gives a silent skip to the next file.
12088          * Under SVR4, the logical file position remains before the filemark
12089          * until the file is closed or a space operation is performed.
12090          * Hence set err_resid and err_file before changing fileno if case
12091          * BSD Behaviour.
12092          */
12093         un->un_err_resid = bp->b_resid;
12094         COPY_POS(&un->un_err_pos, &un->un_pos);
12095 
12096 
12097         /*
12098          * If we've seen a filemark via the last read operation
12099          * advance the file counter, but mark things such that
12100          * the next read operation gets a zero count. We have
12101          * to put this here to handle the case of sitting right
12102          * at the end of a tape file having seen the file mark,
12103          * but the tape is closed and then re-opened without
12104          * any further i/o. That is, the position information
12105          * must be updated before a close.
12106          */
12107 
12108         if (un->un_lastop == ST_OP_READ && un->un_pos.eof == ST_EOF_PENDING) {
12109                 /*
12110                  * If we're a 1/2" tape, and we get a filemark
12111                  * right on block 0, *AND* we were not in the
12112                  * first file on the tape, and we've hit logical EOM.
12113                  * We'll mark the state so that later we do the
12114                  * right thing (in st_close(), st_strategy() or
12115                  * st_ioctl()).
12116                  *
12117                  */
12118                 if ((un->un_dp->options & ST_REEL) &&
12119                     !(un->un_dp->options & ST_READ_IGNORE_EOFS) &&
12120                     un->un_pos.blkno == 0 && un->un_pos.fileno > 0) {
12121                         un->un_pos.eof = ST_EOT_PENDING;
12122                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12123                             "eot pending\n");
12124                         un->un_pos.fileno++;
12125                         un->un_pos.blkno = 0;
12126                 } else if (BP_UCMD(bp)) {
12127                         /*
12128                          * Uscsi reads have no concept of Berkley ver System IV.
12129                          * Counts here must match raw device.
12130                          * A non-full resid implies fix block mode where an
12131                          * attempt to read X blocks resulted in less then X.
12132                          */
12133                         if (bp->b_resid != bp->b_bcount) {
12134                                 un->un_pos.eof = ST_EOF;
12135                         } else {
12136                                 /* Read over a file mark */
12137                                 un->un_pos.fileno++;
12138                                 /* logical block is counted up elsewhere */
12139                                 /* we're before the first block in next file */
12140                                 un->un_pos.blkno = 0;
12141                                 /* EOF is no longer pending */
12142                                 un->un_pos.eof = ST_NO_EOF;
12143                         }
12144                 } else if (BSD_BEHAVIOR) {
12145                         /*
12146                          * If the read of the filemark was a side effect
12147                          * of reading some blocks (i.e., data was actually
12148                          * read), then the EOF mark is pending and the
12149                          * bump into the next file awaits the next read
12150                          * operation (which will return a zero count), or
12151                          * a close or a space operation, else the bump
12152                          * into the next file occurs now.
12153                          */
12154                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12155                             "resid=%lx, bcount=%lx\n",
12156                             bp->b_resid, bp->b_bcount);
12157 
12158                         if (bp->b_resid != bp->b_bcount) {
12159                                 un->un_pos.eof = ST_EOF;
12160                         } else {
12161                                 un->un_silent_skip = 1;
12162                                 un->un_pos.eof = ST_NO_EOF;
12163                                 un->un_pos.fileno++;
12164                                 un->un_pos.lgclblkno++;
12165                                 un->un_save_blkno = un->un_pos.blkno;
12166                                 un->un_pos.blkno = 0;
12167                         }
12168                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12169                             "eof of file %d, eof=%d\n",
12170                             un->un_pos.fileno, un->un_pos.eof);
12171                 } else if (SVR4_BEHAVIOR) {
12172                         /*
12173                          * If the read of the filemark was a side effect
12174                          * of reading some blocks (i.e., data was actually
12175                          * read), then the next read should return 0
12176                          */
12177                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12178                             "resid=%lx, bcount=%lx\n",
12179                             bp->b_resid, bp->b_bcount);
12180                         if (bp->b_resid == bp->b_bcount) {
12181                                 un->un_pos.eof = ST_EOF;
12182                         }
12183                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12184                             "eof of file=%d, eof=%d\n",
12185                             un->un_pos.fileno, un->un_pos.eof);
12186                 }
12187         }
12188 }
12189 
12190 /*
12191  * set the correct un_errno, to take corner cases into consideration
12192  */
12193 static void
12194 st_set_pe_errno(struct scsi_tape *un)
12195 {
12196         ST_FUNC(ST_DEVINFO, st_set_pe_errno);
12197 
12198         ASSERT(mutex_owned(ST_MUTEX));
12199 
12200         /* if errno is already set, don't reset it */
12201         if (un->un_errno)
12202                 return;
12203 
12204         /* here un_errno == 0 */
12205         /*
12206          * if the last transfer before flushing all the
12207          * waiting I/O's, was 0 (resid = count), then we
12208          * want to give the user an error on all the rest,
12209          * so here.  If there was a transfer, we set the
12210          * resid and counts to 0, and let it drop through,
12211          * giving a zero return.  the next I/O will then
12212          * give an error.
12213          */
12214         if (un->un_last_resid == un->un_last_count) {
12215                 switch (un->un_pos.eof) {
12216                 case ST_EOM:
12217                         un->un_errno = ENOMEM;
12218                         break;
12219                 case ST_EOT:
12220                 case ST_EOF:
12221                         un->un_errno = EIO;
12222                         break;
12223                 }
12224         } else {
12225                 /*
12226                  * we know they did not have a zero, so make
12227                  * sure they get one
12228                  */
12229                 un->un_last_resid = un->un_last_count = 0;
12230         }
12231 }
12232 
12233 
12234 /*
12235  * send in a marker pkt to terminate flushing of commands by BBA (via
12236  * flush-on-errors) property.  The HBA will always return TRAN_ACCEPT
12237  */
12238 static void
12239 st_hba_unflush(struct scsi_tape *un)
12240 {
12241         ST_FUNC(ST_DEVINFO, st_hba_unflush);
12242 
12243         ASSERT(mutex_owned(ST_MUTEX));
12244 
12245         if (!un->un_flush_on_errors)
12246                 return;
12247 
12248 #ifdef FLUSH_ON_ERRORS
12249 
12250         if (!un->un_mkr_pkt) {
12251                 un->un_mkr_pkt = scsi_init_pkt(ROUTE, NULL, (struct buf *)NULL,
12252                     NULL, 0, 0, 0, SLEEP_FUNC, NULL);
12253 
12254                 /* we slept, so it must be there */
12255                 pkt->pkt_flags |= FLAG_FLUSH_MARKER;
12256         }
12257 
12258         st_transport(un, un->un_mkr_pkt);
12259 #endif
12260 }
12261 
12262 static char *
12263 st_print_scsi_cmd(char cmd)
12264 {
12265         char tmp[64];
12266         char *cpnt;
12267 
12268         cpnt = scsi_cmd_name(cmd, scsi_cmds, tmp);
12269         /* tmp goes out of scope on return and caller sees garbage */
12270         if (cpnt == tmp) {
12271                 cpnt = "Unknown Command";
12272         }
12273         return (cpnt);
12274 }
12275 
12276 static void
12277 st_print_cdb(dev_info_t *dip, char *label, uint_t level,
12278     char *title, char *cdb)
12279 {
12280         int len = scsi_cdb_size[CDB_GROUPID(cdb[0])];
12281         char buf[256];
12282         struct scsi_tape *un;
12283         int instance = ddi_get_instance(dip);
12284 
12285         un = ddi_get_soft_state(st_state, instance);
12286 
12287         ST_FUNC(dip, st_print_cdb);
12288 
12289         /* force one line output so repeated commands are printed once */
12290         if ((st_debug & 0x180) == 0x100) {
12291                 scsi_log(dip, label, level, "node %s cmd %s\n",
12292                     st_dev_name(un->un_dev), st_print_scsi_cmd(*cdb));
12293                 return;
12294         }
12295 
12296         /* force one line output so repeated CDB's are printed once */
12297         if ((st_debug & 0x180) == 0x80) {
12298                 st_clean_print(dip, label, level, NULL, cdb, len);
12299         } else {
12300                 (void) sprintf(buf, "%s for cmd(%s)", title,
12301                     st_print_scsi_cmd(*cdb));
12302                 st_clean_print(dip, label, level, buf, cdb, len);
12303         }
12304 }
12305 
12306 static void
12307 st_clean_print(dev_info_t *dev, char *label, uint_t level,
12308     char *title, char *data, int len)
12309 {
12310         int     i;
12311         int     c;
12312         char    *format;
12313         char    buf[256];
12314         uchar_t byte;
12315 
12316         ST_FUNC(dev, st_clean_print);
12317 
12318 
12319         if (title) {
12320                 (void) sprintf(buf, "%s:\n", title);
12321                 scsi_log(dev, label, level, "%s", buf);
12322                 level = CE_CONT;
12323         }
12324 
12325         for (i = 0; i < len; ) {
12326                 buf[0] = 0;
12327                 for (c = 0; c < 8 && i < len; c++, i++) {
12328                         byte = (uchar_t)data[i];
12329                         if (byte < 0x10)
12330                                 format = "0x0%x ";
12331                         else
12332                                 format = "0x%x ";
12333                         (void) sprintf(&buf[(int)strlen(buf)], format, byte);
12334                 }
12335                 (void) sprintf(&buf[(int)strlen(buf)], "\n");
12336 
12337                 scsi_log(dev, label, level, "%s\n", buf);
12338                 level = CE_CONT;
12339         }
12340 }
12341 
12342 /*
12343  * Conditionally enabled debugging
12344  */
12345 #ifdef  STDEBUG
12346 static void
12347 st_debug_cmds(struct scsi_tape *un, int com, int count, int wait)
12348 {
12349         char tmpbuf[64];
12350 
12351         ST_FUNC(ST_DEVINFO, st_debug_cmds);
12352 
12353         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12354             "cmd=%s count=0x%x (%d)      %ssync\n",
12355             scsi_cmd_name(com, scsi_cmds, tmpbuf),
12356             count, count,
12357             wait == ASYNC_CMD ? "a" : "");
12358 }
12359 #endif  /* STDEBUG */
12360 
12361 /*
12362  * Returns pointer to name of minor node name of device 'dev'.
12363  */
12364 static char *
12365 st_dev_name(dev_t dev)
12366 {
12367         struct scsi_tape *un;
12368         const char density[] = { 'l', 'm', 'h', 'c' };
12369         static char name[32];
12370         minor_t minor;
12371         int instance;
12372         int nprt = 0;
12373 
12374         minor = getminor(dev);
12375         instance = ((minor & 0xff80) >> 5) | (minor & 3);
12376         un = ddi_get_soft_state(st_state, instance);
12377         if (un) {
12378                 ST_FUNC(ST_DEVINFO, st_dev_name);
12379         }
12380 
12381         name[nprt] = density[(minor & MT_DENSITY_MASK) >> 3];
12382 
12383         if (minor & MT_BSD) {
12384                 name[++nprt] = 'b';
12385         }
12386 
12387         if (minor & MT_NOREWIND) {
12388                 name[++nprt] = 'n';
12389         }
12390 
12391         /* NULL terminator */
12392         name[++nprt] = 0;
12393 
12394         return (name);
12395 }
12396 
12397 /*
12398  * Soft error reporting, so far unique to each drive
12399  *
12400  * Currently supported: exabyte and DAT soft error reporting
12401  */
12402 static int
12403 st_report_exabyte_soft_errors(dev_t dev, int flag)
12404 {
12405         uchar_t *sensep;
12406         int amt;
12407         int rval = 0;
12408         char cdb[CDB_GROUP0], *c = cdb;
12409         struct uscsi_cmd *com;
12410 
12411         GET_SOFT_STATE(dev);
12412 
12413         ST_FUNC(ST_DEVINFO, st_report_exabyte_soft_errors);
12414 
12415         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12416             "st_report_exabyte_soft_errors(dev = 0x%lx, flag = %d)\n",
12417             dev, flag);
12418 
12419         ASSERT(mutex_owned(ST_MUTEX));
12420 
12421         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
12422         sensep = kmem_zalloc(TAPE_SENSE_LENGTH, KM_SLEEP);
12423 
12424         *c++ = SCMD_REQUEST_SENSE;
12425         *c++ = 0;
12426         *c++ = 0;
12427         *c++ = 0;
12428         *c++ = TAPE_SENSE_LENGTH;
12429         /*
12430          * set CLRCNT (byte 5, bit 7 which clears the error counts)
12431          */
12432         *c   = (char)0x80;
12433 
12434         com->uscsi_cdb = cdb;
12435         com->uscsi_cdblen = CDB_GROUP0;
12436         com->uscsi_bufaddr = (caddr_t)sensep;
12437         com->uscsi_buflen = TAPE_SENSE_LENGTH;
12438         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_READ;
12439         com->uscsi_timeout = un->un_dp->non_motion_timeout;
12440 
12441         rval = st_uscsi_cmd(un, com, FKIOCTL);
12442         if (rval || com->uscsi_status) {
12443                 goto done;
12444         }
12445 
12446         /*
12447          * was there enough data?
12448          */
12449         amt = (int)TAPE_SENSE_LENGTH - com->uscsi_resid;
12450 
12451         if ((amt >= 19) && un->un_kbytes_xferred) {
12452                 uint_t count, error_rate;
12453                 uint_t rate;
12454 
12455                 if (sensep[21] & CLN) {
12456                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
12457                             "Periodic head cleaning required");
12458                 }
12459                 if (un->un_kbytes_xferred < (EXABYTE_MIN_TRANSFER/ONE_K)) {
12460                         goto done;
12461                 }
12462                 /*
12463                  * check if soft error reporting needs to be done.
12464                  */
12465                 count = sensep[16] << 16 | sensep[17] << 8 | sensep[18];
12466                 count &= 0xffffff;
12467                 error_rate = (count * 100)/un->un_kbytes_xferred;
12468 
12469 #ifdef  STDEBUG
12470                 if (st_soft_error_report_debug) {
12471                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
12472                             "Exabyte Soft Error Report:\n");
12473                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12474                             "read/write error counter: %d\n", count);
12475                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12476                             "number of bytes transferred: %dK\n",
12477                             un->un_kbytes_xferred);
12478                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12479                             "error_rate: %d%%\n", error_rate);
12480 
12481                         if (amt >= 22) {
12482                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12483                                     "unit sense: 0x%b 0x%b 0x%b\n",
12484                                     sensep[19], SENSE_19_BITS,
12485                                     sensep[20], SENSE_20_BITS,
12486                                     sensep[21], SENSE_21_BITS);
12487                         }
12488                         if (amt >= 27) {
12489                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12490                                     "tracking retry counter: %d\n",
12491                                     sensep[26]);
12492                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12493                                     "read/write retry counter: %d\n",
12494                                     sensep[27]);
12495                         }
12496                 }
12497 #endif
12498 
12499                 if (flag & FWRITE) {
12500                         rate = EXABYTE_WRITE_ERROR_THRESHOLD;
12501                 } else {
12502                         rate = EXABYTE_READ_ERROR_THRESHOLD;
12503                 }
12504                 if (error_rate >= rate) {
12505                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
12506                             "Soft error rate (%d%%) during %s was too high",
12507                             error_rate,
12508                             ((flag & FWRITE) ? wrg_str : rdg_str));
12509                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12510                             "Please, replace tape cartridge\n");
12511                 }
12512         }
12513 
12514 done:
12515         kmem_free(com, sizeof (*com));
12516         kmem_free(sensep, TAPE_SENSE_LENGTH);
12517 
12518         if (rval != 0) {
12519                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12520                     "exabyte soft error reporting failed\n");
12521         }
12522         return (rval);
12523 }
12524 
12525 /*
12526  * this is very specific to Archive 4mm dat
12527  */
12528 #define ONE_GIG (ONE_K * ONE_K * ONE_K)
12529 
12530 static int
12531 st_report_dat_soft_errors(dev_t dev, int flag)
12532 {
12533         uchar_t *sensep;
12534         int amt, i;
12535         int rval = 0;
12536         char cdb[CDB_GROUP1], *c = cdb;
12537         struct uscsi_cmd *com;
12538         struct scsi_arq_status status;
12539 
12540         GET_SOFT_STATE(dev);
12541 
12542         ST_FUNC(ST_DEVINFO, st_report_dat_soft_errors);
12543 
12544         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12545             "st_report_dat_soft_errors(dev = 0x%lx, flag = %d)\n", dev, flag);
12546 
12547         ASSERT(mutex_owned(ST_MUTEX));
12548 
12549         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
12550         sensep = kmem_zalloc(LOG_SENSE_LENGTH, KM_SLEEP);
12551 
12552         *c++ = SCMD_LOG_SENSE_G1;
12553         *c++ = 0;
12554         *c++ = (flag & FWRITE) ? 0x42 : 0x43;
12555         *c++ = 0;
12556         *c++ = 0;
12557         *c++ = 0;
12558         *c++ = 2;
12559         *c++ = 0;
12560         *c++ = (char)LOG_SENSE_LENGTH;
12561         *c   = 0;
12562         com->uscsi_cdb    = cdb;
12563         com->uscsi_cdblen  = CDB_GROUP1;
12564         com->uscsi_bufaddr = (caddr_t)sensep;
12565         com->uscsi_buflen  = LOG_SENSE_LENGTH;
12566         com->uscsi_rqlen = sizeof (status);
12567         com->uscsi_rqbuf = (caddr_t)&status;
12568         com->uscsi_flags   = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
12569         com->uscsi_timeout = un->un_dp->non_motion_timeout;
12570         rval = st_uscsi_cmd(un, com, FKIOCTL);
12571         if (rval) {
12572                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12573                     "DAT soft error reporting failed\n");
12574         }
12575         if (rval || com->uscsi_status) {
12576                 goto done;
12577         }
12578 
12579         /*
12580          * was there enough data?
12581          */
12582         amt = (int)LOG_SENSE_LENGTH - com->uscsi_resid;
12583 
12584         if ((amt >= MIN_LOG_SENSE_LENGTH) && un->un_kbytes_xferred) {
12585                 int total, retries, param_code;
12586 
12587                 total = -1;
12588                 retries = -1;
12589                 amt = sensep[3] + 4;
12590 
12591 
12592 #ifdef STDEBUG
12593                 if (st_soft_error_report_debug) {
12594                         (void) printf("logsense:");
12595                         for (i = 0; i < MIN_LOG_SENSE_LENGTH; i++) {
12596                                 if (i % 16 == 0) {
12597                                         (void) printf("\t\n");
12598                                 }
12599                                 (void) printf(" %x", sensep[i]);
12600                         }
12601                         (void) printf("\n");
12602                 }
12603 #endif
12604 
12605                 /*
12606                  * parse the param_codes
12607                  */
12608                 if (sensep[0] == 2 || sensep[0] == 3) {
12609                         for (i = 4; i < amt; i++) {
12610                                 param_code = (sensep[i++] << 8);
12611                                 param_code += sensep[i++];
12612                                 i++; /* skip control byte */
12613                                 if (param_code == 5) {
12614                                         if (sensep[i++] == 4) {
12615                                                 total = (sensep[i++] << 24);
12616                                                 total += (sensep[i++] << 16);
12617                                                 total += (sensep[i++] << 8);
12618                                                 total += sensep[i];
12619                                         }
12620                                 } else if (param_code == 0x8007) {
12621                                         if (sensep[i++] == 2) {
12622                                                 retries = sensep[i++] << 8;
12623                                                 retries += sensep[i];
12624                                         }
12625                                 } else {
12626                                         i += sensep[i];
12627                                 }
12628                         }
12629                 }
12630 
12631                 /*
12632                  * if the log sense returned valid numbers then determine
12633                  * the read and write error thresholds based on the amount of
12634                  * data transferred
12635                  */
12636 
12637                 if (total > 0 && retries > 0) {
12638                         short normal_retries = 0;
12639                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
12640                             "total xferred (%s) =%x, retries=%x\n",
12641                             ((flag & FWRITE) ? wrg_str : rdg_str),
12642                             total, retries);
12643 
12644                         if (flag & FWRITE) {
12645                                 if (total <=
12646                                     WRITE_SOFT_ERROR_WARNING_THRESHOLD) {
12647                                         normal_retries =
12648                                             DAT_SMALL_WRITE_ERROR_THRESHOLD;
12649                                 } else {
12650                                         normal_retries =
12651                                             DAT_LARGE_WRITE_ERROR_THRESHOLD;
12652                                 }
12653                         } else {
12654                                 if (total <=
12655                                     READ_SOFT_ERROR_WARNING_THRESHOLD) {
12656                                         normal_retries =
12657                                             DAT_SMALL_READ_ERROR_THRESHOLD;
12658                                 } else {
12659                                         normal_retries =
12660                                             DAT_LARGE_READ_ERROR_THRESHOLD;
12661                                 }
12662                         }
12663 
12664                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
12665                         "normal retries=%d\n", normal_retries);
12666 
12667                         if (retries >= normal_retries) {
12668                                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12669                                     "Soft error rate (retries = %d) during "
12670                                     "%s was too high",  retries,
12671                                     ((flag & FWRITE) ? wrg_str : rdg_str));
12672                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12673                                     "Periodic head cleaning required "
12674                                     "and/or replace tape cartridge\n");
12675                         }
12676 
12677                 } else if (total == -1 || retries == -1) {
12678                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
12679                             "log sense parameter code does not make sense\n");
12680                 }
12681         }
12682 
12683         /*
12684          * reset all values
12685          */
12686         c = cdb;
12687         *c++ = SCMD_LOG_SELECT_G1;
12688         *c++ = 2;       /* this resets all values */
12689         *c++ = (char)0xc0;
12690         *c++ = 0;
12691         *c++ = 0;
12692         *c++ = 0;
12693         *c++ = 0;
12694         *c++ = 0;
12695         *c++ = 0;
12696         *c   = 0;
12697         com->uscsi_bufaddr = NULL;
12698         com->uscsi_buflen  = 0;
12699         com->uscsi_flags   = USCSI_DIAGNOSE | USCSI_SILENT;
12700         rval = st_uscsi_cmd(un, com, FKIOCTL);
12701         if (rval) {
12702                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12703                     "DAT soft error reset failed\n");
12704         }
12705 done:
12706         kmem_free(com, sizeof (*com));
12707         kmem_free(sensep, LOG_SENSE_LENGTH);
12708         return (rval);
12709 }
12710 
12711 static int
12712 st_report_soft_errors(dev_t dev, int flag)
12713 {
12714         GET_SOFT_STATE(dev);
12715 
12716         ST_FUNC(ST_DEVINFO, st_report_soft_errors);
12717 
12718         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12719             "st_report_soft_errors(dev = 0x%lx, flag = %d)\n", dev, flag);
12720 
12721         ASSERT(mutex_owned(ST_MUTEX));
12722 
12723         switch (un->un_dp->type) {
12724         case ST_TYPE_EXB8500:
12725         case ST_TYPE_EXABYTE:
12726                 return (st_report_exabyte_soft_errors(dev, flag));
12727                 /*NOTREACHED*/
12728         case ST_TYPE_PYTHON:
12729                 return (st_report_dat_soft_errors(dev, flag));
12730                 /*NOTREACHED*/
12731         default:
12732                 un->un_dp->options &= ~ST_SOFT_ERROR_REPORTING;
12733                 return (-1);
12734         }
12735 }
12736 
12737 /*
12738  * persistent error routines
12739  */
12740 
12741 /*
12742  * enable persistent errors, and set the throttle appropriately, checking
12743  * for flush-on-errors capability
12744  */
12745 static void
12746 st_turn_pe_on(struct scsi_tape *un)
12747 {
12748         ST_FUNC(ST_DEVINFO, st_turn_pe_on);
12749 
12750         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_on\n");
12751         ASSERT(mutex_owned(ST_MUTEX));
12752 
12753         un->un_persistence = 1;
12754 
12755         /*
12756          * only use flush-on-errors if auto-request-sense and untagged-qing are
12757          * enabled.  This will simplify the error handling for request senses
12758          */
12759 
12760         if (un->un_arq_enabled && un->un_untagged_qing) {
12761                 uchar_t f_o_e;
12762 
12763                 mutex_exit(ST_MUTEX);
12764                 f_o_e = (scsi_ifsetcap(ROUTE, "flush-on-errors", 1, 1) == 1) ?
12765                     1 : 0;
12766                 mutex_enter(ST_MUTEX);
12767 
12768                 un->un_flush_on_errors = f_o_e;
12769         } else {
12770                 un->un_flush_on_errors = 0;
12771         }
12772 
12773         if (un->un_flush_on_errors)
12774                 un->un_max_throttle = (uchar_t)st_max_throttle;
12775         else
12776                 un->un_max_throttle = 1;
12777 
12778         if (un->un_dp->options & ST_RETRY_ON_RECOVERED_DEFERRED_ERROR)
12779                 un->un_max_throttle = 1;
12780 
12781         /* this will send a marker pkt */
12782         st_clear_pe(un);
12783 }
12784 
12785 /*
12786  * This turns persistent errors permanently off
12787  */
12788 static void
12789 st_turn_pe_off(struct scsi_tape *un)
12790 {
12791         ST_FUNC(ST_DEVINFO, st_turn_pe_off);
12792         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_off\n");
12793         ASSERT(mutex_owned(ST_MUTEX));
12794 
12795         /* turn it off for good */
12796         un->un_persistence = 0;
12797 
12798         /* this will send a marker pkt */
12799         st_clear_pe(un);
12800 
12801         /* turn off flush on error capability, if enabled */
12802         if (un->un_flush_on_errors) {
12803                 mutex_exit(ST_MUTEX);
12804                 (void) scsi_ifsetcap(ROUTE, "flush-on-errors", 0, 1);
12805                 mutex_enter(ST_MUTEX);
12806         }
12807 
12808 
12809         un->un_flush_on_errors = 0;
12810 }
12811 
12812 /*
12813  * This clear persistent errors, allowing more commands through, and also
12814  * sending a marker packet.
12815  */
12816 static void
12817 st_clear_pe(struct scsi_tape *un)
12818 {
12819         ST_FUNC(ST_DEVINFO, st_clear_pe);
12820         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_clear\n");
12821         ASSERT(mutex_owned(ST_MUTEX));
12822 
12823         un->un_persist_errors = 0;
12824         un->un_throttle = un->un_last_throttle = 1;
12825         un->un_errno = 0;
12826         st_hba_unflush(un);
12827 }
12828 
12829 /*
12830  * This will flag persistent errors, shutting everything down, if the
12831  * application had enabled persistent errors via MTIOCPERSISTENT
12832  */
12833 static void
12834 st_set_pe_flag(struct scsi_tape *un)
12835 {
12836         ST_FUNC(ST_DEVINFO, st_set_pe_flag);
12837         ASSERT(mutex_owned(ST_MUTEX));
12838 
12839         if (un->un_persistence) {
12840                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_flag\n");
12841                 un->un_persist_errors = 1;
12842                 un->un_throttle = un->un_last_throttle = 0;
12843                 cv_broadcast(&un->un_sbuf_cv);
12844         }
12845 }
12846 
12847 static int
12848 st_do_reserve(struct scsi_tape *un)
12849 {
12850         int rval;
12851         int was_lost = un->un_rsvd_status & ST_LOST_RESERVE;
12852 
12853         ST_FUNC(ST_DEVINFO, st_do_reserve);
12854 
12855         /*
12856          * Issue a Throw-Away reserve command to clear the
12857          * check condition.
12858          * If the current behaviour of reserve/release is to
12859          * hold reservation across opens , and if a Bus reset
12860          * has been issued between opens then this command
12861          * would set the ST_LOST_RESERVE flags in rsvd_status.
12862          * In this case return an EACCES so that user knows that
12863          * reservation has been lost in between opens.
12864          * If this error is not returned and we continue with
12865          * successful open , then user may think position of the
12866          * tape is still the same but inreality we would rewind the
12867          * tape and continue from BOT.
12868          */
12869         rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
12870         if (rval) {
12871                 if ((un->un_rsvd_status & ST_LOST_RESERVE_BETWEEN_OPENS) ==
12872                     ST_LOST_RESERVE_BETWEEN_OPENS) {
12873                         un->un_rsvd_status &= ~(ST_LOST_RESERVE | ST_RESERVE);
12874                         un->un_errno = EACCES;
12875                         return (EACCES);
12876                 }
12877                 rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
12878         }
12879         if (rval == 0) {
12880                 un->un_rsvd_status |= ST_INIT_RESERVE;
12881         }
12882         if (was_lost) {
12883                 un->un_running.pmode = invalid;
12884         }
12885 
12886         return (rval);
12887 }
12888 
12889 static int
12890 st_check_cdb_for_need_to_reserve(struct scsi_tape *un, uchar_t *cdb)
12891 {
12892         int rval;
12893         cmd_attribute const *attrib;
12894 
12895         ST_FUNC(ST_DEVINFO, st_check_cdb_for_need_to_reserve);
12896 
12897         /*
12898          * If already reserved no need to do it again.
12899          * Also if Reserve and Release are disabled Just return.
12900          */
12901         if ((un->un_rsvd_status & (ST_APPLICATION_RESERVATIONS)) ||
12902             ((un->un_rsvd_status & (ST_RESERVE | ST_LOST_RESERVE)) ==
12903             ST_RESERVE) || (un->un_dp->options & ST_NO_RESERVE_RELEASE)) {
12904                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12905                     "st_check_cdb_for_need_to_reserve() reserve unneeded %s",
12906                     st_print_scsi_cmd((uchar_t)cdb[0]));
12907                 return (0);
12908         }
12909 
12910         /* See if command is on the list */
12911         attrib = st_lookup_cmd_attribute(cdb[0]);
12912 
12913         if (attrib == NULL) {
12914                 rval = 1; /* Not found, when in doubt reserve */
12915         } else if ((attrib->requires_reserve) != 0) {
12916                 rval = 1;
12917         } else if ((attrib->reserve_byte) != 0) {
12918                 /*
12919                  * cmd is on list.
12920                  * if byte is zero always allowed.
12921                  */
12922                 rval = 1;
12923         } else if (((cdb[attrib->reserve_byte]) &
12924             (attrib->reserve_mask)) != 0) {
12925                 rval = 1;
12926         } else {
12927                 rval = 0;
12928         }
12929 
12930         if (rval) {
12931                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12932                     "Command %s requires reservation",
12933                     st_print_scsi_cmd(cdb[0]));
12934 
12935                 rval = st_do_reserve(un);
12936         }
12937 
12938         return (rval);
12939 }
12940 
12941 static int
12942 st_check_cmd_for_need_to_reserve(struct scsi_tape *un, uchar_t cmd, int cnt)
12943 {
12944         int rval;
12945         cmd_attribute const *attrib;
12946 
12947         ST_FUNC(ST_DEVINFO, st_check_cmd_for_need_to_reserve);
12948 
12949         /*
12950          * Do not reserve when already reserved, when not supported or when
12951          * auto-rewinding on device closure.
12952          */
12953         if ((un->un_rsvd_status & (ST_APPLICATION_RESERVATIONS)) ||
12954             ((un->un_rsvd_status & (ST_RESERVE | ST_LOST_RESERVE)) ==
12955             ST_RESERVE) || (un->un_dp->options & ST_NO_RESERVE_RELEASE) ||
12956             ((un->un_state == ST_STATE_CLOSING) && (cmd == SCMD_REWIND))) {
12957                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12958                     "st_check_cmd_for_need_to_reserve() reserve unneeded %s",
12959                     st_print_scsi_cmd(cmd));
12960                 return (0);
12961         }
12962 
12963         /* search for this command on the list */
12964         attrib = st_lookup_cmd_attribute(cmd);
12965 
12966         if (attrib == NULL) {
12967                 rval = 1; /* Not found, when in doubt reserve */
12968         } else if ((attrib->requires_reserve) != 0) {
12969                 rval = 1;
12970         } else if ((attrib->reserve_byte) != 0) {
12971                 /*
12972                  * cmd is on list.
12973                  * if byte is zero always allowed.
12974                  */
12975                 rval = 1;
12976         } else if (((attrib->reserve_mask) & cnt) != 0) {
12977                 rval = 1;
12978         } else {
12979                 rval = 0;
12980         }
12981 
12982         if (rval) {
12983                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12984                     "Cmd %s requires reservation", st_print_scsi_cmd(cmd));
12985 
12986                 rval = st_do_reserve(un);
12987         }
12988 
12989         return (rval);
12990 }
12991 
12992 static int
12993 st_reserve_release(struct scsi_tape *un, int cmd, ubufunc_t ubf)
12994 {
12995         struct uscsi_cmd        uscsi_cmd;
12996         int                     rval;
12997         char                    cdb[CDB_GROUP0];
12998         struct scsi_arq_status  stat;
12999 
13000 
13001 
13002         ST_FUNC(ST_DEVINFO, st_reserve_release);
13003 
13004         ASSERT(mutex_owned(ST_MUTEX));
13005 
13006         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13007             "st_reserve_release: %s \n",
13008             (cmd == ST_RELEASE)?  "Releasing":"Reserving");
13009 
13010         bzero(&cdb, CDB_GROUP0);
13011         if (cmd == ST_RELEASE) {
13012                 cdb[0] = SCMD_RELEASE;
13013         } else {
13014                 cdb[0] = SCMD_RESERVE;
13015         }
13016         bzero(&uscsi_cmd, sizeof (struct uscsi_cmd));
13017         uscsi_cmd.uscsi_flags = USCSI_WRITE | USCSI_RQENABLE;
13018         uscsi_cmd.uscsi_cdb = cdb;
13019         uscsi_cmd.uscsi_cdblen = CDB_GROUP0;
13020         uscsi_cmd.uscsi_timeout = un->un_dp->non_motion_timeout;
13021         uscsi_cmd.uscsi_rqbuf = (caddr_t)&stat;
13022         uscsi_cmd.uscsi_rqlen = sizeof (stat);
13023 
13024         rval = ubf(un, &uscsi_cmd, FKIOCTL);
13025 
13026         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13027             "st_reserve_release: rval(1)=%d\n", rval);
13028 
13029         if (rval) {
13030                 if (uscsi_cmd.uscsi_status == STATUS_RESERVATION_CONFLICT) {
13031                         rval = EACCES;
13032                 }
13033                 /*
13034                  * dynamically turn off reserve/release support
13035                  * in case of drives which do not support
13036                  * reserve/release command(ATAPI drives).
13037                  */
13038                 if (un->un_status == KEY_ILLEGAL_REQUEST) {
13039                         if ((un->un_dp->options & ST_NO_RESERVE_RELEASE) == 0) {
13040                                 un->un_dp->options |= ST_NO_RESERVE_RELEASE;
13041                                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13042                                     "Tape unit does not support "
13043                                     "reserve/release \n");
13044                         }
13045                         rval = 0;
13046                 }
13047         }
13048         return (rval);
13049 }
13050 
13051 static int
13052 st_take_ownership(struct scsi_tape *un, ubufunc_t ubf)
13053 {
13054         int rval;
13055 
13056         ST_FUNC(ST_DEVINFO, st_take_ownership);
13057 
13058         ASSERT(mutex_owned(ST_MUTEX));
13059 
13060         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13061             "st_take_ownership: Entering ...\n");
13062 
13063 
13064         rval = st_reserve_release(un, ST_RESERVE, ubf);
13065         /*
13066          * XXX -> Should reset be done only if we get EACCES.
13067          * .
13068          */
13069         if (rval) {
13070                 if (st_reset(un, RESET_LUN) == 0) {
13071                         return (EIO);
13072                 }
13073                 un->un_rsvd_status &=
13074                     ~(ST_LOST_RESERVE | ST_RESERVATION_CONFLICT);
13075 
13076                 mutex_exit(ST_MUTEX);
13077                 delay(drv_usectohz(ST_RESERVATION_DELAY));
13078                 mutex_enter(ST_MUTEX);
13079                 /*
13080                  * remove the check condition.
13081                  */
13082                 (void) st_reserve_release(un, ST_RESERVE, ubf);
13083                 rval = st_reserve_release(un, ST_RESERVE, ubf);
13084                 if (rval != 0) {
13085                         if ((st_reserve_release(un, ST_RESERVE, ubf))
13086                             != 0) {
13087                                 rval = (un->un_rsvd_status &
13088                                     ST_RESERVATION_CONFLICT) ? EACCES : EIO;
13089                                 return (rval);
13090                         }
13091                 }
13092                 /*
13093                  * Set tape state to ST_STATE_OFFLINE , in case if
13094                  * the user wants to continue and start using
13095                  * the tape.
13096                  */
13097                 un->un_state = ST_STATE_OFFLINE;
13098                 un->un_rsvd_status |= ST_INIT_RESERVE;
13099         }
13100         return (rval);
13101 }
13102 
13103 static int
13104 st_create_errstats(struct scsi_tape *un, int instance)
13105 {
13106         char    kstatname[KSTAT_STRLEN];
13107 
13108         ST_FUNC(ST_DEVINFO, st_create_errstats);
13109 
13110         /*
13111          * Create device error kstats
13112          */
13113 
13114         if (un->un_errstats == (kstat_t *)0) {
13115                 (void) sprintf(kstatname, "st%d,err", instance);
13116                 un->un_errstats = kstat_create("sterr", instance, kstatname,
13117                     "device_error", KSTAT_TYPE_NAMED,
13118                     sizeof (struct st_errstats) / sizeof (kstat_named_t),
13119                     KSTAT_FLAG_PERSISTENT);
13120 
13121                 if (un->un_errstats) {
13122                         struct st_errstats      *stp;
13123 
13124                         stp = (struct st_errstats *)un->un_errstats->ks_data;
13125                         kstat_named_init(&stp->st_softerrs, "Soft Errors",
13126                             KSTAT_DATA_ULONG);
13127                         kstat_named_init(&stp->st_harderrs, "Hard Errors",
13128                             KSTAT_DATA_ULONG);
13129                         kstat_named_init(&stp->st_transerrs, "Transport Errors",
13130                             KSTAT_DATA_ULONG);
13131                         kstat_named_init(&stp->st_vid, "Vendor",
13132                             KSTAT_DATA_CHAR);
13133                         kstat_named_init(&stp->st_pid, "Product",
13134                             KSTAT_DATA_CHAR);
13135                         kstat_named_init(&stp->st_revision, "Revision",
13136                             KSTAT_DATA_CHAR);
13137                         kstat_named_init(&stp->st_serial, "Serial No",
13138                             KSTAT_DATA_CHAR);
13139                         un->un_errstats->ks_private = un;
13140                         un->un_errstats->ks_update = nulldev;
13141                         kstat_install(un->un_errstats);
13142                         /*
13143                          * Fill in the static data
13144                          */
13145                         (void) strncpy(&stp->st_vid.value.c[0],
13146                             ST_INQUIRY->inq_vid, 8);
13147                         /*
13148                          * XXX:  Emulex MT-02 (and emulators) predates
13149                          *       SCSI-1 and has no vid & pid inquiry data.
13150                          */
13151                         if (ST_INQUIRY->inq_len != 0) {
13152                                 (void) strncpy(&stp->st_pid.value.c[0],
13153                                     ST_INQUIRY->inq_pid, 16);
13154                                 (void) strncpy(&stp->st_revision.value.c[0],
13155                                     ST_INQUIRY->inq_revision, 4);
13156                         }
13157                 }
13158         }
13159         return (0);
13160 }
13161 
13162 static int
13163 st_validate_tapemarks(struct scsi_tape *un, ubufunc_t ubf, tapepos_t *pos)
13164 {
13165         int rval;
13166         bufunc_t bf = (ubf == st_uscsi_rcmd) ? st_rcmd : st_cmd;
13167 
13168         ST_FUNC(ST_DEVINFO, st_validate_tapemarks);
13169 
13170         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
13171         ASSERT(mutex_owned(ST_MUTEX));
13172 
13173         /* Can't restore an invalid position */
13174         if (pos->pmode == invalid) {
13175                 return (4);
13176         }
13177 
13178         /*
13179          * Assumtions:
13180          *      If a position was read and is in logical position mode.
13181          *      If a drive supports read position it supports locate.
13182          *      If the read position type is not NO_POS. even though
13183          *         a read position make not have been attemped yet.
13184          *
13185          *      The drive can locate to the position.
13186          */
13187         if (pos->pmode == logical || un->un_read_pos_type != NO_POS) {
13188                 /*
13189                  * If position mode is logical or legacy mode try
13190                  * to locate there as it is faster.
13191                  * If it fails try the old way.
13192                  */
13193                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
13194                     "Restoring tape position to lgclblkbo=0x%"PRIx64"....",
13195                     pos->lgclblkno);
13196 
13197                 if (st_logical_block_locate(un, st_uscsi_cmd, &un->un_pos,
13198                     pos->lgclblkno, pos->partition) == 0) {
13199                         /* Assume we are there copy rest of position back */
13200                         if (un->un_pos.lgclblkno == pos->lgclblkno) {
13201                                 COPY_POS(&un->un_pos, pos);
13202                         }
13203                         return (0);
13204                 }
13205 
13206                 /*
13207                  * If logical block locate failed to restore a logical
13208                  * position, can't recover.
13209                  */
13210                 if (pos->pmode == logical) {
13211                         return (-1);
13212                 }
13213         }
13214 
13215 
13216         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
13217             "Restoring tape position at fileno=%x, blkno=%x....",
13218             pos->fileno, pos->blkno);
13219 
13220         /*
13221          * Rewind ? Oh yeah, Fidelity has got the STK F/W changed
13222          * so as not to rewind tape on RESETS: Gee, Has life ever
13223          * been simple in tape land ?
13224          */
13225         rval = bf(un, SCMD_REWIND, 0, SYNC_CMD);
13226         if (rval) {
13227                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13228                     "Failed to restore the last file and block position: In"
13229                     " this state, Tape will be loaded at BOT during next open");
13230                 un->un_pos.pmode = invalid;
13231                 return (rval);
13232         }
13233 
13234         /* If the position was as the result of back space file */
13235         if (pos->blkno > (INF / 2)) {
13236                 /* Go one extra file forward */
13237                 pos->fileno++;
13238                 /* Figure how many blocks to back into the previous file */
13239                 pos->blkno = -(INF - pos->blkno);
13240         }
13241 
13242         /* Go to requested fileno */
13243         if (pos->fileno) {
13244                 rval = st_cmd(un, SCMD_SPACE, Fmk(pos->fileno), SYNC_CMD);
13245                 if (rval) {
13246                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
13247                             "Failed to restore the last file position: In this "
13248                             " state, Tape will be loaded at BOT during next"
13249                             " open %d", __LINE__);
13250                         un->un_pos.pmode = invalid;
13251                         pos->pmode = invalid;
13252                         return (rval);
13253                 }
13254         }
13255 
13256         /*
13257          * If backing into a file we already did an extra file forward.
13258          * Now we have to back over the filemark to get to the end of
13259          * the previous file. The blkno has been ajusted to a negative
13260          * value so we will get to the expected location.
13261          */
13262         if (pos->blkno) {
13263                 rval = bf(un, SCMD_SPACE, Fmk(-1), SYNC_CMD);
13264                 if (rval) {
13265                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
13266                             "Failed to restore the last file position: In this "
13267                             " state, Tape will be loaded at BOT during next"
13268                             " open %d", __LINE__);
13269                         un->un_pos.pmode = invalid;
13270                         pos->pmode = invalid;
13271                         return (rval);
13272                 }
13273         }
13274 
13275         /*
13276          * The position mode, block and fileno should be correct,
13277          * This updates eof and logical position information.
13278          */
13279         un->un_pos.eof = pos->eof;
13280         un->un_pos.lgclblkno = pos->lgclblkno;
13281 
13282         return (0);
13283 }
13284 
13285 /*
13286  * check sense key, ASC, ASCQ in order to determine if the tape needs
13287  * to be ejected
13288  */
13289 
13290 static int
13291 st_check_asc_ascq(struct scsi_tape *un)
13292 {
13293         struct scsi_extended_sense *sensep = ST_RQSENSE;
13294         struct tape_failure_code   *code;
13295 
13296         ST_FUNC(ST_DEVINFO, st_check_asc_ascq);
13297 
13298         for (code = st_tape_failure_code; code->key != 0xff; code++) {
13299                 if ((code->key  == sensep->es_key) &&
13300                     (code->add_code  == sensep->es_add_code) &&
13301                     (code->qual_code == sensep->es_qual_code))
13302                         return (1);
13303         }
13304         return (0);
13305 }
13306 
13307 /*
13308  * st_logpage_supported() sends a Log Sense command with
13309  * page code = 0 = Supported Log Pages Page to the device,
13310  * to see whether the page 'page' is supported.
13311  * Return values are:
13312  * -1 if the Log Sense command fails
13313  * 0 if page is not supported
13314  * 1 if page is supported
13315  */
13316 
13317 static int
13318 st_logpage_supported(struct scsi_tape *un, uchar_t page)
13319 {
13320         uchar_t *sp, *sensep;
13321         unsigned length;
13322         struct uscsi_cmd *com;
13323         struct scsi_arq_status status;
13324         int rval;
13325         char cdb[CDB_GROUP1] = {
13326                 SCMD_LOG_SENSE_G1,
13327                 0,
13328                 SUPPORTED_LOG_PAGES_PAGE,
13329                 0,
13330                 0,
13331                 0,
13332                 0,
13333                 0,
13334                 (char)LOG_SENSE_LENGTH,
13335                 0
13336         };
13337 
13338         ST_FUNC(ST_DEVINFO, st_logpage_supported);
13339 
13340         ASSERT(mutex_owned(ST_MUTEX));
13341 
13342         com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13343         sensep = kmem_zalloc(LOG_SENSE_LENGTH, KM_SLEEP);
13344 
13345         com->uscsi_cdb = cdb;
13346         com->uscsi_cdblen = CDB_GROUP1;
13347         com->uscsi_bufaddr = (caddr_t)sensep;
13348         com->uscsi_buflen = LOG_SENSE_LENGTH;
13349         com->uscsi_rqlen = sizeof (status);
13350         com->uscsi_rqbuf = (caddr_t)&status;
13351         com->uscsi_flags =
13352             USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13353         com->uscsi_timeout = un->un_dp->non_motion_timeout;
13354         rval = st_uscsi_cmd(un, com, FKIOCTL);
13355         if (rval || com->uscsi_status) {
13356                 /* uscsi-command failed */
13357                 rval = -1;
13358         } else {
13359 
13360                 sp = sensep + 3;
13361 
13362                 for (length = *sp++; length > 0; length--, sp++) {
13363 
13364                         if (*sp == page) {
13365                                 rval = 1;
13366                                 break;
13367                         }
13368                 }
13369         }
13370         kmem_free(com, sizeof (struct uscsi_cmd));
13371         kmem_free(sensep, LOG_SENSE_LENGTH);
13372         return (rval);
13373 }
13374 
13375 
13376 /*
13377  * st_check_clean_bit() gets the status of the tape's cleaning bit.
13378  *
13379  * If the device does support the TapeAlert log page, then the cleaning bit
13380  * information will be read from this page. Otherwise we will see if one of
13381  * ST_CLN_TYPE_1, ST_CLN_TYPE_2 or ST_CLN_TYPE_3 is set in the properties of
13382  * the device, which means, that we can get the cleaning bit information via
13383  * a RequestSense command.
13384  * If both methods of getting cleaning bit information are not supported
13385  * st_check_clean_bit() will return with 0. Otherwise st_check_clean_bit()
13386  * returns with
13387  * - MTF_TAPE_CLN_SUPPORTED if cleaning bit is not set or
13388  * - MTF_TAPE_CLN_SUPPORTED | MTF_TAPE_HEAD_DIRTY if cleaning bit is set.
13389  * If the call to st_uscsi_cmd() to do the Log Sense or the Request Sense
13390  * command fails, or if the amount of Request Sense data is not enough, then
13391  *  st_check_clean_bit() returns with -1.
13392  */
13393 
13394 static int
13395 st_check_clean_bit(struct scsi_tape *un)
13396 {
13397         int rval = 0;
13398 
13399         ST_FUNC(ST_DEVINFO, st_check_clean_bit);
13400 
13401         ASSERT(mutex_owned(ST_MUTEX));
13402 
13403         if (un->un_HeadClean & TAPE_ALERT_NOT_SUPPORTED) {
13404                 return (rval);
13405         }
13406 
13407         if (un->un_HeadClean == TAPE_ALERT_SUPPORT_UNKNOWN) {
13408 
13409                 rval = st_logpage_supported(un, TAPE_SEQUENTIAL_PAGE);
13410                 if (rval == -1) {
13411                         return (0);
13412                 }
13413                 if (rval == 1) {
13414 
13415                         un->un_HeadClean |= TAPE_SEQUENTIAL_SUPPORTED;
13416                 }
13417 
13418                 rval = st_logpage_supported(un, TAPE_ALERT_PAGE);
13419                 if (rval == -1) {
13420                         return (0);
13421                 }
13422                 if (rval == 1) {
13423 
13424                         un->un_HeadClean |= TAPE_ALERT_SUPPORTED;
13425                 }
13426 
13427                 if (un->un_HeadClean == TAPE_ALERT_SUPPORT_UNKNOWN) {
13428 
13429                         un->un_HeadClean = TAPE_ALERT_NOT_SUPPORTED;
13430                 }
13431         }
13432 
13433         rval = 0;
13434 
13435         if (un->un_HeadClean & TAPE_SEQUENTIAL_SUPPORTED) {
13436 
13437                 rval = st_check_sequential_clean_bit(un);
13438                 if (rval == -1) {
13439                         return (0);
13440                 }
13441         }
13442 
13443         if ((rval == 0) && (un->un_HeadClean & TAPE_ALERT_SUPPORTED)) {
13444 
13445                 rval = st_check_alert_flags(un);
13446                 if (rval == -1) {
13447                         return (0);
13448                 }
13449         }
13450 
13451         if ((rval == 0) && (un->un_dp->options & ST_CLN_MASK)) {
13452 
13453                 rval = st_check_sense_clean_bit(un);
13454                 if (rval == -1) {
13455                         return (0);
13456                 }
13457         }
13458 
13459         /*
13460          * If found a supported means to check need to clean.
13461          */
13462         if (rval & MTF_TAPE_CLN_SUPPORTED) {
13463 
13464                 /*
13465                  * head needs to be cleaned.
13466                  */
13467                 if (rval & MTF_TAPE_HEAD_DIRTY) {
13468 
13469                         /*
13470                          * Print log message only first time
13471                          * found needing cleaned.
13472                          */
13473                         if ((un->un_HeadClean & TAPE_PREVIOUSLY_DIRTY) == 0) {
13474 
13475                                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13476                                     "Periodic head cleaning required");
13477 
13478                                 un->un_HeadClean |= TAPE_PREVIOUSLY_DIRTY;
13479                         }
13480 
13481                 } else {
13482 
13483                         un->un_HeadClean &= ~TAPE_PREVIOUSLY_DIRTY;
13484                 }
13485         }
13486 
13487         return (rval);
13488 }
13489 
13490 
13491 static int
13492 st_check_sequential_clean_bit(struct scsi_tape *un)
13493 {
13494         int rval;
13495         int ix;
13496         ushort_t parameter;
13497         struct uscsi_cmd *cmd;
13498         struct log_sequential_page *sp;
13499         struct log_sequential_page_parameter *prm;
13500         struct scsi_arq_status status;
13501         char cdb[CDB_GROUP1] = {
13502                 SCMD_LOG_SENSE_G1,
13503                 0,
13504                 TAPE_SEQUENTIAL_PAGE | CURRENT_CUMULATIVE_VALUES,
13505                 0,
13506                 0,
13507                 0,
13508                 0,
13509                 (char)(sizeof (struct log_sequential_page) >> 8),
13510                 (char)(sizeof (struct log_sequential_page)),
13511                 0
13512         };
13513 
13514         ST_FUNC(ST_DEVINFO, st_check_sequential_clean_bit);
13515 
13516         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13517         sp  = kmem_zalloc(sizeof (struct log_sequential_page), KM_SLEEP);
13518 
13519         cmd->uscsi_flags   =
13520             USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13521         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
13522         cmd->uscsi_cdb          = cdb;
13523         cmd->uscsi_cdblen  = CDB_GROUP1;
13524         cmd->uscsi_bufaddr = (caddr_t)sp;
13525         cmd->uscsi_buflen  = sizeof (struct log_sequential_page);
13526         cmd->uscsi_rqlen   = sizeof (status);
13527         cmd->uscsi_rqbuf   = (caddr_t)&status;
13528 
13529         rval = st_uscsi_cmd(un, cmd, FKIOCTL);
13530 
13531         if (rval || cmd->uscsi_status || cmd->uscsi_resid) {
13532 
13533                 rval = -1;
13534 
13535         } else if (sp->log_page.code != TAPE_SEQUENTIAL_PAGE) {
13536 
13537                 rval = -1;
13538         }
13539 
13540         prm = &sp->param[0];
13541 
13542         for (ix = 0; rval == 0 && ix < TAPE_SEQUENTIAL_PAGE_PARA; ix++) {
13543 
13544                 if (prm->log_param.length == 0) {
13545                         break;
13546                 }
13547 
13548                 parameter = (((prm->log_param.pc_hi << 8) & 0xff00) +
13549                     (prm->log_param.pc_lo & 0xff));
13550 
13551                 if (parameter == SEQUENTIAL_NEED_CLN) {
13552 
13553                         rval = MTF_TAPE_CLN_SUPPORTED;
13554                         if (prm->param_value[prm->log_param.length - 1]) {
13555 
13556                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13557                                     "sequential log says head dirty\n");
13558                                 rval |= MTF_TAPE_HEAD_DIRTY;
13559                         }
13560                 }
13561                 prm = (struct log_sequential_page_parameter *)
13562                     &prm->param_value[prm->log_param.length];
13563         }
13564 
13565         kmem_free(cmd, sizeof (struct uscsi_cmd));
13566         kmem_free(sp,  sizeof (struct log_sequential_page));
13567 
13568         return (rval);
13569 }
13570 
13571 
13572 static int
13573 st_check_alert_flags(struct scsi_tape *un)
13574 {
13575         struct st_tape_alert *ta;
13576         struct uscsi_cmd *com;
13577         struct scsi_arq_status status;
13578         unsigned ix, length;
13579         int rval;
13580         tape_alert_flags flag;
13581         char cdb[CDB_GROUP1] = {
13582                 SCMD_LOG_SENSE_G1,
13583                 0,
13584                 TAPE_ALERT_PAGE | CURRENT_THRESHOLD_VALUES,
13585                 0,
13586                 0,
13587                 0,
13588                 0,
13589                 (char)(sizeof (struct st_tape_alert) >> 8),
13590                 (char)(sizeof (struct st_tape_alert)),
13591                 0
13592         };
13593 
13594         ST_FUNC(ST_DEVINFO, st_check_alert_clean_bit);
13595 
13596         com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13597         ta  = kmem_zalloc(sizeof (struct st_tape_alert), KM_SLEEP);
13598 
13599         com->uscsi_cdb = cdb;
13600         com->uscsi_cdblen = CDB_GROUP1;
13601         com->uscsi_bufaddr = (caddr_t)ta;
13602         com->uscsi_buflen = sizeof (struct st_tape_alert);
13603         com->uscsi_rqlen = sizeof (status);
13604         com->uscsi_rqbuf = (caddr_t)&status;
13605         com->uscsi_flags =
13606             USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13607         com->uscsi_timeout = un->un_dp->non_motion_timeout;
13608 
13609         rval = st_uscsi_cmd(un, com, FKIOCTL);
13610 
13611         if (rval || com->uscsi_status || com->uscsi_resid) {
13612 
13613                 rval = -1; /* uscsi-command failed */
13614 
13615         } else if (ta->log_page.code != TAPE_ALERT_PAGE) {
13616 
13617                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13618                 "Not Alert Log Page returned 0x%X\n", ta->log_page.code);
13619                 rval = -1;
13620         }
13621 
13622         length = (ta->log_page.length_hi << 8) + ta->log_page.length_lo;
13623 
13624 
13625         if (length != TAPE_ALERT_PARAMETER_LENGTH) {
13626 
13627                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13628                     "TapeAlert length %d\n", length);
13629         }
13630 
13631 
13632         for (ix = 0; ix < TAPE_ALERT_MAX_PARA; ix++) {
13633 
13634                 /*
13635                  * if rval is bad before the first pass don't bother
13636                  */
13637                 if (ix == 0 && rval != 0) {
13638 
13639                         break;
13640                 }
13641 
13642                 flag = ((ta->param[ix].log_param.pc_hi << 8) +
13643                     ta->param[ix].log_param.pc_lo);
13644 
13645                 if ((ta->param[ix].param_value & 1) == 0) {
13646                         continue;
13647                 }
13648                 /*
13649                  * check to see if current parameter is of interest.
13650                  * CLEAN_FOR_ERRORS is vendor specific to 9840 9940 stk's.
13651                  */
13652                 if ((flag == TAF_CLEAN_NOW) ||
13653                     (flag == TAF_CLEAN_PERIODIC) ||
13654                     ((flag == CLEAN_FOR_ERRORS) &&
13655                     (un->un_dp->type == ST_TYPE_STK9840))) {
13656 
13657                         rval = MTF_TAPE_CLN_SUPPORTED;
13658 
13659 
13660                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13661                             "alert_page drive needs clean %d\n", flag);
13662                         un->un_HeadClean |= TAPE_ALERT_STILL_DIRTY;
13663                         rval |= MTF_TAPE_HEAD_DIRTY;
13664 
13665                 } else if (flag == TAF_CLEANING_MEDIA) {
13666 
13667                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13668                             "alert_page drive was cleaned\n");
13669                         un->un_HeadClean &= ~TAPE_ALERT_STILL_DIRTY;
13670                 }
13671 
13672         }
13673 
13674         /*
13675          * Report it as dirty till we see it cleaned
13676          */
13677         if (un->un_HeadClean & TAPE_ALERT_STILL_DIRTY) {
13678 
13679                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13680                     "alert_page still dirty\n");
13681                 rval |= MTF_TAPE_HEAD_DIRTY;
13682         }
13683 
13684         kmem_free(com, sizeof (struct uscsi_cmd));
13685         kmem_free(ta,  sizeof (struct st_tape_alert));
13686 
13687         return (rval);
13688 }
13689 
13690 
13691 static int
13692 st_check_sense_clean_bit(struct scsi_tape *un)
13693 {
13694         uchar_t *sensep;
13695         char cdb[CDB_GROUP0];
13696         struct uscsi_cmd *com;
13697         ushort_t byte_pos;
13698         uchar_t bit_mask;
13699         unsigned length;
13700         int index;
13701         int rval;
13702 
13703         ST_FUNC(ST_DEVINFO, st_check_sense_clean_bit);
13704 
13705         /*
13706          * Since this tape does not support Tape Alert,
13707          * we now try to get the cleanbit status via
13708          * Request Sense.
13709          */
13710 
13711         if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_1) {
13712 
13713                 index = 0;
13714 
13715         } else if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_2) {
13716 
13717                 index = 1;
13718 
13719         } else if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_3) {
13720 
13721                 index = 2;
13722 
13723         } else {
13724 
13725                 return (-1);
13726         }
13727 
13728         byte_pos  = st_cln_bit_position[index].cln_bit_byte;
13729         bit_mask  = st_cln_bit_position[index].cln_bit_mask;
13730         length = byte_pos + 1;
13731 
13732         com    = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13733         sensep = kmem_zalloc(length, KM_SLEEP);
13734 
13735         cdb[0] = SCMD_REQUEST_SENSE;
13736         cdb[1] = 0;
13737         cdb[2] = 0;
13738         cdb[3] = 0;
13739         cdb[4] = (char)length;
13740         cdb[5] = 0;
13741 
13742         com->uscsi_cdb = cdb;
13743         com->uscsi_cdblen = CDB_GROUP0;
13744         com->uscsi_bufaddr = (caddr_t)sensep;
13745         com->uscsi_buflen = length;
13746         com->uscsi_flags =
13747             USCSI_DIAGNOSE | USCSI_SILENT | USCSI_READ;
13748         com->uscsi_timeout = un->un_dp->non_motion_timeout;
13749 
13750         rval = st_uscsi_cmd(un, com, FKIOCTL);
13751 
13752         if (rval || com->uscsi_status || com->uscsi_resid) {
13753 
13754                 rval = -1;
13755 
13756         } else {
13757 
13758                 rval = MTF_TAPE_CLN_SUPPORTED;
13759                 if ((sensep[byte_pos] & bit_mask) == bit_mask) {
13760 
13761                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13762                             "sense data says head dirty\n");
13763                         rval |= MTF_TAPE_HEAD_DIRTY;
13764                 }
13765         }
13766 
13767         kmem_free(com, sizeof (struct uscsi_cmd));
13768         kmem_free(sensep, length);
13769         return (rval);
13770 }
13771 
13772 /*
13773  * st_clear_unit_attention
13774  *
13775  *      run test unit ready's to clear out outstanding
13776  *      unit attentions.
13777  *      returns zero for SUCCESS or the errno from st_cmd call
13778  */
13779 static int
13780 st_clear_unit_attentions(dev_t dev_instance, int max_trys)
13781 {
13782         int     i    = 0;
13783         int     rval;
13784 
13785         GET_SOFT_STATE(dev_instance);
13786         ST_FUNC(ST_DEVINFO, st_clear_unit_attentions);
13787 
13788         do {
13789                 rval = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
13790         } while ((rval != 0) && (rval != ENXIO) && (++i < max_trys));
13791         return (rval);
13792 }
13793 
13794 static void
13795 st_calculate_timeouts(struct scsi_tape *un)
13796 {
13797         ST_FUNC(ST_DEVINFO, st_calculate_timeouts);
13798 
13799         if (un->un_dp->non_motion_timeout == 0) {
13800                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13801                         un->un_dp->non_motion_timeout =
13802                             st_io_time * st_long_timeout_x;
13803                 } else {
13804                         un->un_dp->non_motion_timeout = (ushort_t)st_io_time;
13805                 }
13806         }
13807 
13808         if (un->un_dp->io_timeout == 0) {
13809                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13810                         un->un_dp->io_timeout = st_io_time * st_long_timeout_x;
13811                 } else {
13812                         un->un_dp->io_timeout = (ushort_t)st_io_time;
13813                 }
13814         }
13815 
13816         if (un->un_dp->rewind_timeout == 0) {
13817                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13818                         un->un_dp->rewind_timeout =
13819                             st_space_time * st_long_timeout_x;
13820                 } else {
13821                         un->un_dp->rewind_timeout = (ushort_t)st_space_time;
13822                 }
13823         }
13824 
13825         if (un->un_dp->space_timeout == 0) {
13826                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13827                         un->un_dp->space_timeout =
13828                             st_space_time * st_long_timeout_x;
13829                 } else {
13830                         un->un_dp->space_timeout = (ushort_t)st_space_time;
13831                 }
13832         }
13833 
13834         if (un->un_dp->load_timeout == 0) {
13835                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13836                         un->un_dp->load_timeout =
13837                             st_space_time * st_long_timeout_x;
13838                 } else {
13839                         un->un_dp->load_timeout = (ushort_t)st_space_time;
13840                 }
13841         }
13842 
13843         if (un->un_dp->unload_timeout == 0) {
13844                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13845                         un->un_dp->unload_timeout =
13846                             st_space_time * st_long_timeout_x;
13847                 } else {
13848                         un->un_dp->unload_timeout = (ushort_t)st_space_time;
13849                 }
13850         }
13851 
13852         if (un->un_dp->erase_timeout == 0) {
13853                 if (un->un_dp->options & ST_LONG_ERASE) {
13854                         un->un_dp->erase_timeout =
13855                             st_space_time * st_long_space_time_x;
13856                 } else {
13857                         un->un_dp->erase_timeout = (ushort_t)st_space_time;
13858                 }
13859         }
13860 }
13861 
13862 
13863 static writablity
13864 st_is_not_wormable(struct scsi_tape *un)
13865 {
13866         ST_FUNC(ST_DEVINFO, st_is_not_wormable);
13867         return (RDWR);
13868 }
13869 
13870 static writablity
13871 st_is_hp_dat_tape_worm(struct scsi_tape *un)
13872 {
13873         writablity wrt;
13874 
13875         ST_FUNC(ST_DEVINFO, st_is_hp_dat_tape_worm);
13876 
13877         /* Mode sense should be current */
13878         if (un->un_mspl->media_type == 1) {
13879                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13880                     "Drive has WORM media loaded\n");
13881                 wrt = WORM;
13882         } else {
13883                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13884                     "Drive has non WORM media loaded\n");
13885                 wrt = RDWR;
13886         }
13887         return (wrt);
13888 }
13889 
13890 #define HP_DAT_INQUIRY 0x4A
13891 static writablity
13892 st_is_hp_dat_worm(struct scsi_tape *un)
13893 {
13894         char *buf;
13895         int result;
13896         writablity wrt;
13897 
13898         ST_FUNC(ST_DEVINFO, st_is_hp_dat_worm);
13899 
13900         buf = kmem_zalloc(HP_DAT_INQUIRY, KM_SLEEP);
13901 
13902         result = st_get_special_inquiry(un, HP_DAT_INQUIRY, buf, 0);
13903 
13904         if (result != 0) {
13905                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13906                     "Read Standard Inquiry for WORM support failed");
13907                 wrt = FAILED;
13908         } else if ((buf[40] & 1) == 0) {
13909                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13910                     "Drive is NOT WORMable\n");
13911                 /* This drive doesn't support it so don't check again */
13912                 un->un_dp->options &= ~ST_WORMABLE;
13913                 wrt = RDWR;
13914                 un->un_wormable = st_is_not_wormable;
13915         } else {
13916                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13917                     "Drive supports WORM version %d\n", buf[40] >> 1);
13918                 un->un_wormable = st_is_hp_dat_tape_worm;
13919                 wrt = un->un_wormable(un);
13920         }
13921 
13922         kmem_free(buf, HP_DAT_INQUIRY);
13923 
13924         /*
13925          * If drive doesn't support it no point in checking further.
13926          */
13927         return (wrt);
13928 }
13929 
13930 static writablity
13931 st_is_hp_lto_tape_worm(struct scsi_tape *un)
13932 {
13933         writablity wrt;
13934 
13935         ST_FUNC(ST_DEVINFO, st_is_hp_lto_tape_worm);
13936 
13937         /* Mode sense should be current */
13938         switch (un->un_mspl->media_type) {
13939         case 0x00:
13940                 switch (un->un_mspl->density) {
13941                 case 0x40:
13942                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13943                             "Drive has standard Gen I media loaded\n");
13944                         break;
13945                 case 0x42:
13946                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13947                             "Drive has standard Gen II media loaded\n");
13948                         break;
13949                 case 0x44:
13950                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13951                             "Drive has standard Gen III media loaded\n");
13952                         break;
13953                 case 0x46:
13954                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13955                             "Drive has standard Gen IV media loaded\n");
13956                         break;
13957                 default:
13958                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13959                             "Drive has standard unknown 0x%X media loaded\n",
13960                             un->un_mspl->density);
13961                 }
13962                 wrt = RDWR;
13963                 break;
13964         case 0x01:
13965                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13966                     "Drive has WORM medium loaded\n");
13967                 wrt = WORM;
13968                 break;
13969         case 0x80:
13970                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13971                     "Drive has CD-ROM emulation medium loaded\n");
13972                 wrt = WORM;
13973                 break;
13974         default:
13975                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13976                     "Drive has an unexpected medium type 0x%X loaded\n",
13977                     un->un_mspl->media_type);
13978                 wrt = RDWR;
13979         }
13980 
13981         return (wrt);
13982 }
13983 
13984 #define LTO_REQ_INQUIRY 44
13985 static writablity
13986 st_is_hp_lto_worm(struct scsi_tape *un)
13987 {
13988         char *buf;
13989         int result;
13990         writablity wrt;
13991 
13992         ST_FUNC(ST_DEVINFO, st_is_hp_lto_worm);
13993 
13994         buf = kmem_zalloc(LTO_REQ_INQUIRY, KM_SLEEP);
13995 
13996         result = st_get_special_inquiry(un, LTO_REQ_INQUIRY, buf, 0);
13997 
13998         if (result != 0) {
13999                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14000                     "Read Standard Inquiry for WORM support failed");
14001                 wrt = FAILED;
14002         } else if ((buf[40] & 1) == 0) {
14003                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14004                     "Drive is NOT WORMable\n");
14005                 /* This drive doesn't support it so don't check again */
14006                 un->un_dp->options &= ~ST_WORMABLE;
14007                 wrt = RDWR;
14008                 un->un_wormable = st_is_not_wormable;
14009         } else {
14010                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14011                     "Drive supports WORM version %d\n", buf[40] >> 1);
14012                 un->un_wormable = st_is_hp_lto_tape_worm;
14013                 wrt = un->un_wormable(un);
14014         }
14015 
14016         kmem_free(buf, LTO_REQ_INQUIRY);
14017 
14018         /*
14019          * If drive doesn't support it no point in checking further.
14020          */
14021         return (wrt);
14022 }
14023 
14024 static writablity
14025 st_is_t10_worm_device(struct scsi_tape *un)
14026 {
14027         writablity wrt;
14028 
14029         ST_FUNC(ST_DEVINFO, st_is_t10_worm_device);
14030 
14031         if (un->un_mspl->media_type == 0x3c) {
14032                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14033                     "Drive has WORM media loaded\n");
14034                 wrt = WORM;
14035         } else {
14036                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14037                     "Drive has non WORM media loaded\n");
14038                 wrt = RDWR;
14039         }
14040         return (wrt);
14041 }
14042 
14043 #define SEQ_CAP_PAGE    (char)0xb0
14044 static writablity
14045 st_is_t10_worm(struct scsi_tape *un)
14046 {
14047         char *buf;
14048         int result;
14049         writablity wrt;
14050 
14051         ST_FUNC(ST_DEVINFO, st_is_t10_worm);
14052 
14053         buf = kmem_zalloc(6, KM_SLEEP);
14054 
14055         result = st_get_special_inquiry(un, 6, buf, SEQ_CAP_PAGE);
14056 
14057         if (result != 0) {
14058                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14059                     "Read Vitial Inquiry for Sequental Capability"
14060                     " WORM support failed %x", result);
14061                 wrt = FAILED;
14062         } else if ((buf[4] & 1) == 0) {
14063                 ASSERT(buf[1] == SEQ_CAP_PAGE);
14064                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14065                     "Drive is NOT WORMable\n");
14066                 /* This drive doesn't support it so don't check again */
14067                 un->un_dp->options &= ~ST_WORMABLE;
14068                 wrt = RDWR;
14069                 un->un_wormable = st_is_not_wormable;
14070         } else {
14071                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14072                     "Drive supports WORM\n");
14073                 un->un_wormable = st_is_t10_worm_device;
14074                 wrt = un->un_wormable(un);
14075         }
14076 
14077         kmem_free(buf, 6);
14078 
14079         return (wrt);
14080 }
14081 
14082 
14083 #define STK_REQ_SENSE 26
14084 
14085 static writablity
14086 st_is_stk_worm(struct scsi_tape *un)
14087 {
14088         char cdb[CDB_GROUP0] = {SCMD_REQUEST_SENSE, 0, 0, 0, STK_REQ_SENSE, 0};
14089         struct scsi_extended_sense *sense;
14090         struct uscsi_cmd *cmd;
14091         char *buf;
14092         int result;
14093         writablity wrt;
14094 
14095         ST_FUNC(ST_DEVINFO, st_is_stk_worm);
14096 
14097         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14098         buf = kmem_alloc(STK_REQ_SENSE, KM_SLEEP);
14099         sense = (struct scsi_extended_sense *)buf;
14100 
14101         cmd->uscsi_flags = USCSI_READ;
14102         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14103         cmd->uscsi_cdb = &cdb[0];
14104         cmd->uscsi_bufaddr = buf;
14105         cmd->uscsi_buflen = STK_REQ_SENSE;
14106         cmd->uscsi_cdblen = CDB_GROUP0;
14107         cmd->uscsi_rqlen = 0;
14108         cmd->uscsi_rqbuf = NULL;
14109 
14110         result = st_uscsi_cmd(un, cmd, FKIOCTL);
14111 
14112         if (result != 0 || cmd->uscsi_status != 0) {
14113                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14114                     "Request Sense for WORM failed");
14115                 wrt = RDWR;
14116         } else if (sense->es_add_len + 8 < 24) {
14117                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14118                     "Drive didn't send enough sense data for WORM byte %d\n",
14119                     sense->es_add_len + 8);
14120                 wrt = RDWR;
14121                 un->un_wormable = st_is_not_wormable;
14122         } else if ((buf[24]) & 0x02) {
14123                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14124                     "Drive has WORM tape loaded\n");
14125                 wrt = WORM;
14126                 un->un_wormable = st_is_stk_worm;
14127         } else {
14128                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14129                     "Drive has normal tape loaded\n");
14130                 wrt = RDWR;
14131                 un->un_wormable = st_is_stk_worm;
14132         }
14133 
14134         kmem_free(buf, STK_REQ_SENSE);
14135         kmem_free(cmd, sizeof (struct uscsi_cmd));
14136         return (wrt);
14137 }
14138 
14139 #define DLT_INQ_SZ 44
14140 
14141 static writablity
14142 st_is_dlt_tape_worm(struct scsi_tape *un)
14143 {
14144         caddr_t buf;
14145         int result;
14146         writablity wrt;
14147 
14148         ST_FUNC(ST_DEVINFO, st_is_dlt_tape_worm);
14149 
14150         buf = kmem_alloc(DLT_INQ_SZ, KM_SLEEP);
14151 
14152         /* Read Attribute Media Type */
14153 
14154         result = st_read_attributes(un, 0x0408, buf, 10, st_uscsi_cmd);
14155 
14156         /*
14157          * If this quantum drive is attached via an HBA that cannot
14158          * support thr read attributes command return error in the
14159          * hope that someday they will support the t10 method.
14160          */
14161         if (result == EINVAL && un->un_max_cdb_sz < CDB_GROUP4) {
14162                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14163                     "Read Attribute Command for WORM Media detection is not "
14164                     "supported on the HBA that this drive is attached to.");
14165                 wrt = RDWR;
14166                 un->un_wormable = st_is_not_wormable;
14167                 goto out;
14168         }
14169 
14170         if (result != 0) {
14171                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14172                     "Read Attribute Command for WORM Media returned 0x%x",
14173                     result);
14174                 wrt = RDWR;
14175                 un->un_dp->options &= ~ST_WORMABLE;
14176                 goto out;
14177         }
14178 
14179         if ((uchar_t)buf[9] == 0x80) {
14180                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14181                     "Drive media is WORM\n");
14182                 wrt = WORM;
14183         } else {
14184                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14185                     "Drive media is not WORM Media 0x%x\n", (uchar_t)buf[9]);
14186                 wrt = RDWR;
14187         }
14188 
14189 out:
14190         kmem_free(buf, DLT_INQ_SZ);
14191         return (wrt);
14192 }
14193 
14194 static writablity
14195 st_is_dlt_worm(struct scsi_tape *un)
14196 {
14197         caddr_t buf;
14198         int result;
14199         writablity wrt;
14200 
14201         ST_FUNC(ST_DEVINFO, st_is_dlt_worm);
14202 
14203         buf = kmem_alloc(DLT_INQ_SZ, KM_SLEEP);
14204 
14205         result = st_get_special_inquiry(un, DLT_INQ_SZ, buf, 0xC0);
14206 
14207         if (result != 0) {
14208                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14209                     "Read Vendor Specific Inquiry for WORM support failed");
14210                 wrt = RDWR;
14211                 goto out;
14212         }
14213 
14214         if ((buf[2] & 1) == 0) {
14215                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14216                     "Drive is not WORMable\n");
14217                 wrt = RDWR;
14218                 un->un_dp->options &= ~ST_WORMABLE;
14219                 un->un_wormable = st_is_not_wormable;
14220                 goto out;
14221         } else {
14222                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14223                     "Drive is WORMable\n");
14224                 un->un_wormable = st_is_dlt_tape_worm;
14225                 wrt = un->un_wormable(un);
14226         }
14227 out:
14228         kmem_free(buf, DLT_INQ_SZ);
14229 
14230         return (wrt);
14231 }
14232 
14233 typedef struct {
14234         struct modeheader_seq header;
14235 #if defined(_BIT_FIELDS_LTOH) /* X86 */
14236         uchar_t pagecode        :6,
14237                                 :2;
14238         uchar_t page_len;
14239         uchar_t syslogalive     :2,
14240                 device          :1,
14241                 abs             :1,
14242                 ulpbot          :1,
14243                 prth            :1,
14244                 ponej           :1,
14245                 ait             :1;
14246         uchar_t span;
14247 
14248         uchar_t                 :6,
14249                 worm            :1,
14250                 mic             :1;
14251         uchar_t worm_cap        :1,
14252                                 :7;
14253         uint32_t                :32;
14254 #else /* SPARC */
14255         uchar_t                 :2,
14256                 pagecode        :6;
14257         uchar_t page_len;
14258         uchar_t ait             :1,
14259                 device          :1,
14260                 abs             :1,
14261                 ulpbot          :1,
14262                 prth            :1,
14263                 ponej           :1,
14264                 syslogalive     :2;
14265         uchar_t span;
14266         uchar_t mic             :1,
14267                 worm            :1,
14268                                 :6;
14269         uchar_t                 :7,
14270                 worm_cap        :1;
14271         uint32_t                :32;
14272 #endif
14273 }ait_dev_con;
14274 
14275 #define AIT_DEV_PAGE 0x31
14276 static writablity
14277 st_is_sony_worm(struct scsi_tape *un)
14278 {
14279         int result;
14280         writablity wrt;
14281         ait_dev_con *ait_conf;
14282 
14283         ST_FUNC(ST_DEVINFO, st_is_sony_worm);
14284 
14285         ait_conf = kmem_zalloc(sizeof (ait_dev_con), KM_SLEEP);
14286 
14287         result = st_gen_mode_sense(un, st_uscsi_cmd, AIT_DEV_PAGE,
14288             (struct seq_mode *)ait_conf, sizeof (ait_dev_con));
14289 
14290         if (result == 0) {
14291 
14292                 if (ait_conf->pagecode != AIT_DEV_PAGE) {
14293                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14294                             "returned page 0x%x not 0x%x AIT_DEV_PAGE\n",
14295                             ait_conf->pagecode, AIT_DEV_PAGE);
14296                         wrt = RDWR;
14297                         un->un_wormable = st_is_not_wormable;
14298 
14299                 } else if (ait_conf->worm_cap) {
14300 
14301                         un->un_wormable = st_is_sony_worm;
14302 
14303                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14304                             "Drives is WORMable\n");
14305                         if (ait_conf->worm) {
14306                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14307                                     "Media is WORM\n");
14308                                 wrt = WORM;
14309                         } else {
14310                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14311                                     "Media is not WORM\n");
14312                                 wrt = RDWR;
14313                         }
14314 
14315                 } else {
14316                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14317                             "Drives not is WORMable\n");
14318                         wrt = RDWR;
14319                         /* No further checking required */
14320                         un->un_dp->options &= ~ST_WORMABLE;
14321                 }
14322 
14323         } else {
14324 
14325                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14326                     "AIT device config mode sense page read command failed"
14327                     " result = %d ", result);
14328                 wrt = FAILED;
14329                 un->un_wormable = st_is_not_wormable;
14330         }
14331 
14332         kmem_free(ait_conf, sizeof (ait_dev_con));
14333         return (wrt);
14334 }
14335 
14336 static writablity
14337 st_is_drive_worm(struct scsi_tape *un)
14338 {
14339         writablity wrt;
14340 
14341         ST_FUNC(ST_DEVINFO, st_is_sony_worm);
14342 
14343         switch (un->un_dp->type) {
14344         case MT_ISDLT:
14345                 wrt = st_is_dlt_worm(un);
14346                 break;
14347 
14348         case MT_ISSTK9840:
14349                 wrt = st_is_stk_worm(un);
14350                 break;
14351 
14352         case MT_IS8MM:
14353         case MT_ISAIT:
14354                 wrt = st_is_sony_worm(un);
14355                 break;
14356 
14357         case MT_LTO:
14358                 if (strncmp("HP ", un->un_dp->vid, 3) == 0) {
14359                         wrt = st_is_hp_lto_worm(un);
14360                 } else {
14361                         wrt = st_is_t10_worm(un);
14362                 }
14363                 break;
14364 
14365         case MT_ISDAT:
14366                 if (strncmp("HP ", un->un_dp->vid, 3) == 0) {
14367                         wrt = st_is_hp_dat_worm(un);
14368                 } else {
14369                         wrt = st_is_t10_worm(un);
14370                 }
14371                 break;
14372 
14373         default:
14374                 wrt = FAILED;
14375                 break;
14376         }
14377 
14378         /*
14379          * If any of the above failed try the t10 standard method.
14380          */
14381         if (wrt == FAILED) {
14382                 wrt = st_is_t10_worm(un);
14383         }
14384 
14385         /*
14386          * Unknown method for detecting WORM media.
14387          */
14388         if (wrt == FAILED) {
14389                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14390                     "Unknown method for WORM media detection\n");
14391                 wrt = RDWR;
14392                 un->un_dp->options &= ~ST_WORMABLE;
14393         }
14394 
14395         return (wrt);
14396 }
14397 
14398 static int
14399 st_read_attributes(struct scsi_tape *un, uint16_t attribute, void *pnt,
14400     size_t size, ubufunc_t bufunc)
14401 {
14402         char cdb[CDB_GROUP4];
14403         int result;
14404         struct uscsi_cmd *cmd;
14405         struct scsi_arq_status status;
14406 
14407         caddr_t buf = (caddr_t)pnt;
14408 
14409         ST_FUNC(ST_DEVINFO, st_read_attributes);
14410 
14411         if (un->un_sd->sd_inq->inq_ansi < 3) {
14412                 return (ENOTTY);
14413         }
14414 
14415         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14416 
14417         cdb[0] = (char)SCMD_READ_ATTRIBUTE;
14418         cdb[1] = 0;
14419         cdb[2] = 0;
14420         cdb[3] = 0;
14421         cdb[4] = 0;
14422         cdb[5] = 0;
14423         cdb[6] = 0;
14424         cdb[7] = 0;
14425         cdb[8] = (char)(attribute >> 8);
14426         cdb[9] = (char)(attribute);
14427         cdb[10] = (char)(size >> 24);
14428         cdb[11] = (char)(size >> 16);
14429         cdb[12] = (char)(size >> 8);
14430         cdb[13] = (char)(size);
14431         cdb[14] = 0;
14432         cdb[15] = 0;
14433 
14434 
14435         cmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE | USCSI_DIAGNOSE;
14436         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14437         cmd->uscsi_cdb = &cdb[0];
14438         cmd->uscsi_bufaddr = (caddr_t)buf;
14439         cmd->uscsi_buflen = size;
14440         cmd->uscsi_cdblen = sizeof (cdb);
14441         cmd->uscsi_rqlen = sizeof (status);
14442         cmd->uscsi_rqbuf = (caddr_t)&status;
14443 
14444         result = bufunc(un, cmd, FKIOCTL);
14445 
14446         if (result != 0 || cmd->uscsi_status != 0) {
14447                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
14448                     "st_read_attribute failed: result %d status %d\n",
14449                     result, cmd->uscsi_status);
14450                 /*
14451                  * If this returns invalid operation code don't try again.
14452                  */
14453                 if (un->un_sd->sd_sense->es_key == KEY_ILLEGAL_REQUEST &&
14454                     un->un_sd->sd_sense->es_add_code == 0x20) {
14455                         result = ENOTTY;
14456                 } else if (result == 0) {
14457                         result = EIO;
14458                 }
14459 
14460         } else {
14461 
14462                 /*
14463                  * The attribute retured should match the attribute requested.
14464                  */
14465                 if (buf[4] != cdb[8] || buf[5] != cdb[9]) {
14466                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14467                             "st_read_attribute got wrong data back expected "
14468                             "0x%x got 0x%x\n", attribute, buf[6] << 8 | buf[7]);
14469                         st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
14470                             "bad? data", buf, size);
14471                         result = EIO;
14472                 }
14473         }
14474 
14475         kmem_free(cmd, sizeof (struct uscsi_cmd));
14476 
14477         return (result);
14478 }
14479 
14480 static int
14481 st_get_special_inquiry(struct scsi_tape *un, uchar_t size, caddr_t dest,
14482     uchar_t page)
14483 {
14484         char cdb[CDB_GROUP0];
14485         struct scsi_extended_sense *sense;
14486         struct uscsi_cmd *cmd;
14487         int result;
14488 
14489         ST_FUNC(ST_DEVINFO, st_get_special_inquiry);
14490 
14491         cdb[0] = SCMD_INQUIRY;
14492         cdb[1] = page ? 1 : 0;
14493         cdb[2] = page;
14494         cdb[3] = 0;
14495         cdb[4] = size;
14496         cdb[5] = 0;
14497 
14498         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14499         sense = kmem_alloc(sizeof (struct scsi_extended_sense), KM_SLEEP);
14500 
14501         cmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE;
14502         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14503         cmd->uscsi_cdb = &cdb[0];
14504         cmd->uscsi_bufaddr = dest;
14505         cmd->uscsi_buflen = size;
14506         cmd->uscsi_cdblen = CDB_GROUP0;
14507         cmd->uscsi_rqlen = sizeof (struct scsi_extended_sense);
14508         cmd->uscsi_rqbuf = (caddr_t)sense;
14509 
14510         result = st_uscsi_cmd(un, cmd, FKIOCTL);
14511 
14512         if (result != 0 || cmd->uscsi_status != 0) {
14513                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14514                     "st_get_special_inquiry() failed for page %x", page);
14515                 if (result == 0) {
14516                         result = EIO;
14517                 }
14518         }
14519 
14520         kmem_free(sense, sizeof (struct scsi_extended_sense));
14521         kmem_free(cmd, sizeof (struct uscsi_cmd));
14522 
14523         return (result);
14524 }
14525 
14526 
14527 static int
14528 st_update_block_pos(struct scsi_tape *un, bufunc_t bf, int post_space)
14529 {
14530         int rval = ENOTTY;
14531         uchar_t status = un->un_status;
14532         posmode previous_pmode = un->un_running.pmode;
14533 
14534         ST_FUNC(ST_DEVINFO, st_update_block_pos);
14535 
14536         while (un->un_read_pos_type != NO_POS) {
14537                 rval = bf(un, SCMD_READ_POSITION, 32, SYNC_CMD);
14538 
14539                 /*
14540                  * If read position command returned good status
14541                  * Parse the data to see if the position can be interpreted.
14542                  */
14543                 if ((rval == 0) &&
14544                     ((rval = st_interpret_read_pos(un, &un->un_pos,
14545                     un->un_read_pos_type, 32, (caddr_t)un->un_read_pos_data,
14546                     post_space)) == 0)) {
14547                         /*
14548                          * Update the running position as well if un_pos was
14549                          * ok. But only if recovery is enabled.
14550                          */
14551                         if (st_recov_sz != sizeof (recov_info)) {
14552                                 break;
14553                         }
14554                         rval = st_interpret_read_pos(un, &un->un_running,
14555                             un->un_read_pos_type, 32,
14556                             (caddr_t)un->un_read_pos_data, post_space);
14557                         un->un_status = status;
14558                         break;
14559                 } else if (un->un_status == KEY_UNIT_ATTENTION) {
14560                         un->un_running.pmode = previous_pmode;
14561                         continue;
14562                 } else if (un->un_status != KEY_ILLEGAL_REQUEST) {
14563                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
14564                             "st_update_block_pos() read position cmd 0x%x"
14565                             " returned 0x%x un_status = %d",
14566                             un->un_read_pos_type, rval, un->un_status);
14567                         /* ENOTTY means it read garbage. try something else. */
14568                         if (rval == ENOTTY) {
14569                                 rval = EIO; /* so ENOTTY is not final rval */
14570                         } else {
14571                                 break;
14572                         }
14573                 } else {
14574                         ST_DEBUG4(ST_DEVINFO, st_label, CE_NOTE,
14575                             "st_update_block_pos() read position cmd %x"
14576                             " returned %x", un->un_read_pos_type, rval);
14577                         un->un_running.pmode = previous_pmode;
14578                 }
14579 
14580                 switch (un->un_read_pos_type) {
14581                 case SHORT_POS:
14582                         un->un_read_pos_type = NO_POS;
14583                         break;
14584 
14585                 case LONG_POS:
14586                         un->un_read_pos_type = EXT_POS;
14587                         break;
14588 
14589                 case EXT_POS:
14590                         un->un_read_pos_type = SHORT_POS;
14591                         break;
14592 
14593                 default:
14594                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
14595                             "Unexpected read position type 0x%x",
14596                             un->un_read_pos_type);
14597                 }
14598                 un->un_status = KEY_NO_SENSE;
14599         }
14600 
14601         return (rval);
14602 }
14603 
14604 static int
14605 st_get_read_pos(struct scsi_tape *un, buf_t *bp)
14606 {
14607         int result;
14608         size_t d_sz;
14609         caddr_t pos_info;
14610         struct uscsi_cmd *cmd = (struct uscsi_cmd *)bp->b_back;
14611 
14612         ST_FUNC(ST_DEVINFO, st_get_read_pos);
14613 
14614         if (cmd->uscsi_bufaddr == NULL || cmd->uscsi_buflen <= 0) {
14615                 return (0);
14616         }
14617 
14618         if (bp_mapin_common(bp, VM_NOSLEEP) == NULL) {
14619 
14620                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14621                     "bp_mapin_common() failed");
14622 
14623                 return (EIO);
14624         }
14625 
14626         d_sz = bp->b_bcount - bp->b_resid;
14627         if (d_sz == 0) {
14628                 bp_mapout(bp);
14629                 return (EIO);
14630         }
14631 
14632         /*
14633          * Copy the buf to a double-word aligned memory that can hold the
14634          * tape_position_t data structure.
14635          */
14636         if ((pos_info = kmem_alloc(d_sz, KM_NOSLEEP)) == NULL) {
14637                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14638                     "kmem_alloc() failed");
14639                 bp_mapout(bp);
14640                 return (EIO);
14641         }
14642         bcopy(bp->b_un.b_addr, pos_info, d_sz);
14643 
14644 #ifdef STDEBUG
14645         if ((st_debug & 0x7) > 2) {
14646                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
14647                     "st_get_read_pos() position info",
14648                     pos_info, bp->b_bcount);
14649         }
14650 #endif
14651 
14652         result = st_interpret_read_pos(un, &un->un_pos, cmd->uscsi_cdb[1],
14653             d_sz, pos_info, 0);
14654 
14655         COPY_POS(&un->un_running, &un->un_pos);
14656 
14657         kmem_free(pos_info, d_sz);
14658         bp_mapout(bp);
14659 
14660         return (result);
14661 }
14662 
14663 #if defined(_BIG_ENDIAN)
14664 
14665 #define FIX_ENDIAN16(x)
14666 #define FIX_ENDIAN32(x)
14667 #define FIX_ENDIAN64(x)
14668 
14669 #elif defined(_LITTLE_ENDIAN)
14670 
14671 static void
14672 st_swap16(uint16_t *val)
14673 {
14674         uint16_t tmp;
14675 
14676         tmp = (*val >>  8) & 0xff;
14677         tmp |= (*val <<  8) & 0xff00;
14678 
14679         *val = tmp;
14680 }
14681 
14682 static void
14683 st_swap32(uint32_t *val)
14684 {
14685         uint32_t tmp;
14686 
14687         tmp =  (*val >> 24) & 0xff;
14688         tmp |= (*val >>  8) & 0xff00;
14689         tmp |= (*val <<  8) & 0xff0000;
14690         tmp |= (*val << 24) & 0xff000000;
14691 
14692         *val = tmp;
14693 }
14694 
14695 static void
14696 st_swap64(uint64_t *val)
14697 {
14698         uint32_t low;
14699         uint32_t high;
14700 
14701         low =  (uint32_t)(*val);
14702         high = (uint32_t)(*val >> 32);
14703 
14704         st_swap32(&low);
14705         st_swap32(&high);
14706 
14707         *val =  high;
14708         *val |= ((uint64_t)low << 32);
14709 }
14710 
14711 #define FIX_ENDIAN16(x) st_swap16(x)
14712 #define FIX_ENDIAN32(x) st_swap32(x)
14713 #define FIX_ENDIAN64(x) st_swap64(x)
14714 #endif
14715 
14716 /*
14717  * st_interpret_read_pos()
14718  *
14719  * Returns:
14720  *      0       If secsessful.
14721  *      EIO     If read postion responce data was unuseable or invalid.
14722  *      ERANGE  If the position of the drive is too large for the read_p_type.
14723  *      ENOTTY  If the responce data looks invalid for the read position type.
14724  */
14725 
14726 static int
14727 st_interpret_read_pos(struct scsi_tape const *un, tapepos_t *dest,
14728     read_p_types type, size_t data_sz, const caddr_t responce, int post_space)
14729 {
14730         int rval = 0;
14731         int flag = 0;
14732         tapepos_t org;
14733 
14734         ST_FUNC(ST_DEVINFO, st_interpret_read_pos);
14735 
14736         /*
14737          * We expect the position value to change after a space command.
14738          * So if post_space is set we don't print out what has changed.
14739          */
14740         if ((dest != &un->un_pos) && (post_space == 0) &&
14741             (st_recov_sz == sizeof (recov_info))) {
14742                 COPY_POS(&org, dest);
14743                 flag = 1;
14744         }
14745 
14746         /*
14747          * See what kind of read position was requested.
14748          */
14749         switch (type) {
14750 
14751         case SHORT_POS: /* Short data format */
14752         {
14753                 tape_position_t *pos_info = (tape_position_t *)responce;
14754                 uint32_t value;
14755 
14756                 /* If reserved fields are non zero don't use the data */
14757                 if (pos_info->reserved0 || pos_info->reserved1 ||
14758                     pos_info->reserved2[0] || pos_info->reserved2[1] ||
14759                     pos_info->reserved3) {
14760                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14761                             "Invalid Read Short Position Data returned\n");
14762                         rval = EIO;
14763                         break;
14764                 }
14765                 /*
14766                  * Position is to large to use this type of read position.
14767                  */
14768                 if (pos_info->posi_err == 1) {
14769                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14770                             "Drive reported position error\n");
14771                         rval = ERANGE;
14772                         break;
14773                 }
14774                 /*
14775                  * If your at the begining of partition and end at the same
14776                  * time it's very small partition or bad data.
14777                  */
14778                 if (pos_info->begin_of_part && pos_info->end_of_part) {
14779                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14780                             "SHORT_POS returned begin and end of"
14781                             " partition\n");
14782                         rval = EIO;
14783                         break;
14784                 }
14785 
14786                 if (pos_info->blk_posi_unkwn == 0) {
14787 
14788                         value = pos_info->host_block;
14789                         FIX_ENDIAN32(&value);
14790 
14791                         /*
14792                          * If the tape is rewound the host blcok should be 0.
14793                          */
14794                         if ((pos_info->begin_of_part == 1) &&
14795                             (value != 0)) {
14796                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14797                                     "SHORT_POS returned begin of partition"
14798                                     " but host block was 0x%x\n", value);
14799                                 rval = EIO;
14800                                 break;
14801                         }
14802 
14803                         if (dest->lgclblkno != value) {
14804                                 if (flag)
14805                                         flag++;
14806                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14807                                     "SHORT_POS current logical 0x%"PRIx64" read"
14808                                     " 0x%x\n", dest->lgclblkno, value);
14809                         }
14810 
14811                         dest->lgclblkno = (uint64_t)value;
14812 
14813                         /*
14814                          * If the begining of partition is true and the
14815                          * block number is zero we will beleive that it is
14816                          * rewound. Promote the pmode to legacy.
14817                          */
14818                         if ((pos_info->begin_of_part == 1) &&
14819                             (value == 0)) {
14820                                 dest->blkno = 0;
14821                                 dest->fileno = 0;
14822                                 if (dest->pmode != legacy)
14823                                         dest->pmode = legacy;
14824                         /*
14825                          * otherwise if the pmode was invalid,
14826                          * promote it to logical.
14827                          */
14828                         } else if (dest->pmode == invalid) {
14829                                 dest->pmode = logical;
14830                         }
14831 
14832                         if (dest->partition != pos_info->partition_number) {
14833                                 if (flag)
14834                                         flag++;
14835                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14836                                     "SHORT_POS current partition %d read %d\n",
14837                                     dest->partition,
14838                                     pos_info->partition_number);
14839                         }
14840 
14841                         dest->partition = pos_info->partition_number;
14842 
14843                 } else {
14844                         dest->pmode = invalid;
14845                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14846                             "Tape drive reported block position as unknown\n");
14847                 }
14848                 break;
14849         }
14850 
14851         case LONG_POS: /* Long data format */
14852         {
14853                 uint64_t value;
14854                 tape_position_long_t *long_pos_info =
14855                     (tape_position_long_t *)responce;
14856 
14857                 /* If reserved fields are non zero don't use the data */
14858                 if ((long_pos_info->reserved0) ||
14859                     (long_pos_info->reserved1) ||
14860                     (long_pos_info->reserved2)) {
14861                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14862                             "Invalid Read Long Position Data returned\n");
14863                         rval = ENOTTY;
14864                         break;
14865                 }
14866 
14867                 /* Is position Valid */
14868                 if (long_pos_info->blk_posi_unkwn == 0) {
14869                         uint32_t part;
14870 
14871                         value = long_pos_info->block_number;
14872                         FIX_ENDIAN64(&value);
14873 
14874                         /*
14875                          * If it says we are at the begining of partition
14876                          * the block value better be 0.
14877                          */
14878                         if ((long_pos_info->begin_of_part == 1) &&
14879                             (value != 0)) {
14880                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14881                                     "LONG_POS returned begin of partition but"
14882                                     " block number was 0x%"PRIx64"\n", value);
14883                                 rval = ENOTTY;
14884                                 break;
14885                         }
14886                         /*
14887                          * Can't be at the start and the end of the partition
14888                          * at the same time if the partition is larger the 0.
14889                          */
14890                         if (long_pos_info->begin_of_part &&
14891                             long_pos_info->end_of_part) {
14892                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14893                                     "LONG_POS returned begin and end of"
14894                                     " partition\n");
14895                                 rval = ENOTTY;
14896                                 break;
14897                         }
14898 
14899                         /*
14900                          * If the logical block number is not what we expected.
14901                          */
14902                         if (dest->lgclblkno != value) {
14903                                 if (flag)
14904                                         flag++;
14905                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14906                                     "LONG_POS current logical 0x%"PRIx64
14907                                     " read 0x%"PRIx64"\n",
14908                                     dest->lgclblkno, value);
14909                         }
14910                         dest->lgclblkno = value;
14911 
14912                         /*
14913                          * If the begining of partition is true and the
14914                          * block number is zero we will beleive that it is
14915                          * rewound. Promote the pmode to legacy.
14916                          */
14917                         if ((long_pos_info->begin_of_part == 1) &&
14918                             (long_pos_info->block_number == 0)) {
14919                                 dest->blkno = 0;
14920                                 dest->fileno = 0;
14921                                 if (dest->pmode != legacy)
14922                                         dest->pmode = legacy;
14923                         /*
14924                          * otherwise if the pmode was invalid,
14925                          * promote it to logical.
14926                          */
14927                         } else if (dest->pmode == invalid) {
14928                                 dest->pmode = logical;
14929                         }
14930 
14931                         part = long_pos_info->partition;
14932                         FIX_ENDIAN32(&part);
14933                         if (dest->partition != part) {
14934                                 if (flag)
14935                                         flag++;
14936                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14937                                     "LONG_POS current partition %d"
14938                                     " read %d\n", dest->partition, part);
14939                         }
14940                         dest->partition = part;
14941                 } else {
14942                         /*
14943                          * If the drive doesn't know location,
14944                          * we don't either.
14945                          */
14946                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14947                             "Tape drive reported block position as unknown\n");
14948                         dest->pmode = invalid;
14949                 }
14950 
14951                 /* Is file position valid */
14952                 if (long_pos_info->mrk_posi_unkwn == 0) {
14953                         value = long_pos_info->file_number;
14954                         FIX_ENDIAN64(&value);
14955                         /*
14956                          * If it says we are at the begining of partition
14957                          * the block value better be 0.
14958                          */
14959                         if ((long_pos_info->begin_of_part == 1) &&
14960                             (value != 0)) {
14961                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14962                                     "LONG_POS returned begin of partition but"
14963                                     " block number was 0x%"PRIx64"\n", value);
14964                                 rval = ENOTTY;
14965                                 break;
14966                         }
14967                         if (((dest->pmode == legacy) ||
14968                             (dest->pmode == logical)) &&
14969                             (dest->fileno != value)) {
14970                                 if (flag)
14971                                         flag++;
14972                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14973                                     "LONG_POS fileno 0x%"PRIx64
14974                                     " not un_pos %x\n", value,
14975                                     dest->fileno);
14976                         } else if (dest->pmode == invalid) {
14977                                 dest->pmode = logical;
14978                         }
14979                         dest->fileno = (int32_t)value;
14980                 }
14981 
14982                 if (dest->pmode != invalid && long_pos_info->end_of_part) {
14983                         dest->eof = ST_EOT;
14984                 }
14985 
14986                 break;
14987         }
14988 
14989         case EXT_POS: /* Extended data format */
14990         {
14991                 uint64_t value;
14992                 uint16_t len;
14993                 tape_position_ext_t *ext_pos_info =
14994                     (tape_position_ext_t *)responce;
14995 
14996                 /* Make sure that there is enough data there */
14997                 if (data_sz < 16) {
14998                         break;
14999                 }
15000 
15001                 /* If reserved fields are non zero don't use the data */
15002                 if (ext_pos_info->reserved0 || ext_pos_info->reserved1) {
15003                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15004                             "EXT_POS reserved fields not zero\n");
15005                         rval = ENOTTY;
15006                         break;
15007                 }
15008 
15009                 /*
15010                  * In the unlikely event of overflowing 64 bits of position.
15011                  */
15012                 if (ext_pos_info->posi_err != 0) {
15013                         rval = ERANGE;
15014                         break;
15015                 }
15016 
15017                 len = ext_pos_info->parameter_len;
15018                 FIX_ENDIAN16(&len);
15019 
15020                 if (len != 0x1c) {
15021                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15022                             "EXT_POS parameter_len should be 0x1c was 0x%x\n",
15023                             len);
15024                         rval = ENOTTY;
15025                         break;
15026                 }
15027 
15028                 /* Is block position information valid */
15029                 if (ext_pos_info->blk_posi_unkwn == 0) {
15030 
15031                         value = ext_pos_info->host_block;
15032                         FIX_ENDIAN64(&value);
15033                         if ((ext_pos_info->begin_of_part == 1) &&
15034                             (value != 0)) {
15035                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15036                                     "EXT_POS returned begining of partition but"
15037                                     " the host block was 0x%"PRIx64"\n", value);
15038                                 rval = ENOTTY;
15039                                 break;
15040                         }
15041 
15042                         if (dest->lgclblkno != value) {
15043                                 if (flag)
15044                                         flag++;
15045                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15046                                     "EXT_POS current logical 0x%"PRIx64
15047                                     " read 0x%"PRIx64"\n",
15048                                     dest->lgclblkno, value);
15049                         }
15050                         dest->lgclblkno = value;
15051 
15052                         /*
15053                          * If the begining of partition is true and the
15054                          * block number is zero we will beleive that it is
15055                          * rewound. Promote the pmode to legacy.
15056                          */
15057                         if ((ext_pos_info->begin_of_part == 1) &&
15058                             (ext_pos_info->host_block == 0)) {
15059                                 dest->blkno = 0;
15060                                 dest->fileno = 0;
15061                                 if (dest->pmode != legacy) {
15062                                         dest->pmode = legacy;
15063                                 }
15064                         /*
15065                          * otherwise if the pmode was invalid,
15066                          * promote it to logical.
15067                          */
15068                         } else if (dest->pmode == invalid) {
15069                                 dest->pmode = logical;
15070                         }
15071 
15072                         if (dest->partition != ext_pos_info->partition) {
15073                                 if (flag)
15074                                         flag++;
15075                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15076                                     "EXT_POS current partition %d read %d\n",
15077                                     dest->partition,
15078                                     ext_pos_info->partition);
15079                         }
15080                         dest->partition = ext_pos_info->partition;
15081 
15082                 } else {
15083                         dest->pmode = invalid;
15084                 }
15085                 break;
15086         }
15087 
15088         default:
15089                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
15090                     "Got unexpected SCMD_READ_POSITION type %d\n", type);
15091                 rval = EIO;
15092         }
15093 
15094         if ((flag > 1) && (rval == 0) && (org.pmode != invalid)) {
15095                 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
15096                     "position read in", &org);
15097                 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
15098                     "position read out", dest);
15099         }
15100 
15101         return (rval);
15102 }
15103 
15104 static int
15105 st_logical_block_locate(struct scsi_tape *un, ubufunc_t ubf, tapepos_t *pos,
15106     uint64_t lblk, uchar_t partition)
15107 {
15108         int rval;
15109         char cdb[CDB_GROUP4];
15110         struct uscsi_cmd *cmd;
15111         struct scsi_extended_sense sense;
15112         bufunc_t bf = (ubf == st_uscsi_cmd) ? st_cmd : st_rcmd;
15113 
15114         ST_FUNC(ST_DEVINFO, st_logical_block_locate);
15115         /*
15116          * Not sure what to do when doing recovery and not wanting
15117          * to update un_pos
15118          */
15119 
15120         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
15121 
15122         if (lblk <= INT32_MAX) {
15123                 cmd->uscsi_cdblen = CDB_GROUP1;
15124                 cdb[0] = SCMD_LOCATE;
15125                 cdb[1] = pos->partition == partition ? 0 : 2;
15126                 cdb[2] = 0;
15127                 cdb[3] = (char)(lblk >> 24);
15128                 cdb[4] = (char)(lblk >> 16);
15129                 cdb[5] = (char)(lblk >> 8);
15130                 cdb[6] = (char)(lblk);
15131                 cdb[7] = 0;
15132                 cdb[8] = partition;
15133                 cdb[9] = 0;
15134         } else {
15135                 /*
15136                  * If the drive doesn't give a 64 bit read position data
15137                  * it is unlikely it will accept 64 bit locates.
15138                  */
15139                 if (un->un_read_pos_type != LONG_POS) {
15140                         kmem_free(cmd, sizeof (struct uscsi_cmd));
15141                         return (ERANGE);
15142                 }
15143                 cmd->uscsi_cdblen = CDB_GROUP4;
15144                 cdb[0] = (char)SCMD_LOCATE_G4;
15145                 cdb[1] = pos->partition == partition ? 0 : 2;
15146                 cdb[2] = 0;
15147                 cdb[3] = partition;
15148                 cdb[4] = (char)(lblk >> 56);
15149                 cdb[5] = (char)(lblk >> 48);
15150                 cdb[6] = (char)(lblk >> 40);
15151                 cdb[7] = (char)(lblk >> 32);
15152                 cdb[8] = (char)(lblk >> 24);
15153                 cdb[9] = (char)(lblk >> 16);
15154                 cdb[10] = (char)(lblk >> 8);
15155                 cdb[11] = (char)(lblk);
15156                 cdb[12] = 0;
15157                 cdb[13] = 0;
15158                 cdb[14] = 0;
15159                 cdb[15] = 0;
15160         }
15161 
15162 
15163         cmd->uscsi_flags = USCSI_WRITE | USCSI_DIAGNOSE | USCSI_RQENABLE;
15164         cmd->uscsi_rqbuf = (caddr_t)&sense;
15165         cmd->uscsi_rqlen = sizeof (sense);
15166         cmd->uscsi_timeout = un->un_dp->space_timeout;
15167         cmd->uscsi_cdb = cdb;
15168 
15169         rval = ubf(un, cmd, FKIOCTL);
15170 
15171         pos->pmode = logical;
15172         pos->eof = ST_NO_EOF;
15173 
15174         if (lblk > INT32_MAX) {
15175                 /*
15176                  * XXX This is a work around till we handle Descriptor format
15177                  * sense data. Since we are sending a command where the standard
15178                  * sense data can not correctly represent a correct residual in
15179                  * 4 bytes.
15180                  */
15181                 if (un->un_status == KEY_ILLEGAL_REQUEST) {
15182                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15183                             "Big LOCATE ILLEGAL_REQUEST: rval = %d\n", rval);
15184                         /* Doesn't like big locate command */
15185                         un->un_status = 0;
15186                         rval = ERANGE;
15187                 } else if ((un->un_pos.pmode == invalid) || (rval != 0)) {
15188                         /* Aborted big locate command */
15189                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15190                             "Big LOCATE resulted in invalid pos: rval = %d\n",
15191                             rval);
15192                         un->un_status = 0;
15193                         rval = EIO;
15194                 } else if (st_update_block_pos(un, bf, 1)) {
15195                         /* read position failed */
15196                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15197                             "Big LOCATE and read pos: rval = %d\n", rval);
15198                         rval = EIO;
15199                 } else if (lblk > un->un_pos.lgclblkno) {
15200                         /* read position worked but position was not expected */
15201                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15202                             "Big LOCATE and recover read less then desired 0x%"
15203                             PRIx64"\n", un->un_pos.lgclblkno);
15204                         un->un_err_resid = lblk - un->un_pos.lgclblkno;
15205                         un->un_status = KEY_BLANK_CHECK;
15206                         rval = ESPIPE;
15207                 } else if (lblk == un->un_pos.lgclblkno) {
15208                         /* read position was what was expected */
15209                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15210                             "Big LOCATE and recover seems to have worked\n");
15211                         un->un_err_resid = 0;
15212                         rval = 0;
15213                 } else {
15214                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
15215                             "BIGLOCATE end up going backwards");
15216                         un->un_err_resid = lblk;
15217                         rval = EIO;
15218                 }
15219 
15220         } else if (rval == 0) {
15221                 /* Worked as requested */
15222                 pos->lgclblkno = lblk;
15223 
15224         } else if (((cmd->uscsi_status & ST_STATUS_MASK) == STATUS_CHECK) &&
15225             (cmd->uscsi_resid != 0)) {
15226                 /* Got part way there but wasn't enough blocks on tape */
15227                 pos->lgclblkno = lblk - cmd->uscsi_resid;
15228                 un->un_err_resid = cmd->uscsi_resid;
15229                 un->un_status = KEY_BLANK_CHECK;
15230                 rval = ESPIPE;
15231 
15232         } else if (st_update_block_pos(un, bf, 1) == 0) {
15233                 /* Got part way there but drive didn't tell what we missed by */
15234                 un->un_err_resid = lblk - pos->lgclblkno;
15235                 un->un_status = KEY_BLANK_CHECK;
15236                 rval = ESPIPE;
15237 
15238         } else {
15239                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15240                     "Failed LOCATE and recover pos: rval = %d status = %d\n",
15241                     rval, cmd->uscsi_status);
15242                 un->un_err_resid = lblk;
15243                 un->un_status = KEY_ILLEGAL_REQUEST;
15244                 pos->pmode = invalid;
15245                 rval = EIO;
15246         }
15247 
15248         kmem_free(cmd, sizeof (struct uscsi_cmd));
15249 
15250         return (rval);
15251 }
15252 
15253 static int
15254 st_mtfsf_ioctl(struct scsi_tape *un, int64_t files)
15255 {
15256         int rval;
15257 
15258         ST_FUNC(ST_DEVINFO, st_mtfsf_ioctl);
15259 
15260 
15261         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15262             "st_mtfsf_ioctl: count=%"PRIx64", eof=%x\n", files, un->un_pos.eof);
15263 #if 0
15264         if ((IN_EOF(un->un_pos)) && (files == 1)) {
15265                 un->un_pos.fileno++;
15266                 un->un_pos.blkno = 0;
15267                 return (0);
15268         }
15269 #endif
15270         /* pmode == invalid already handled */
15271         if (un->un_pos.pmode == legacy) {
15272                 /*
15273                  * forward space over filemark
15274                  *
15275                  * For ASF we allow a count of 0 on fsf which means
15276                  * we just want to go to beginning of current file.
15277                  * Equivalent to "nbsf(0)" or "bsf(1) + fsf".
15278                  * Allow stepping over double fmk with reel
15279                  */
15280                 if ((un->un_pos.eof >= ST_EOT) &&
15281                     (files > 0) &&
15282                     ((un->un_dp->options & ST_REEL) == 0)) {
15283                         /* we're at EOM */
15284                         un->un_err_resid = files;
15285                         un->un_status = KEY_BLANK_CHECK;
15286                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15287                             "st_mtfsf_ioctl: EIO : MTFSF at EOM");
15288                         return (EIO);
15289                 }
15290 
15291                 /*
15292                  * physical tape position may not be what we've been
15293                  * telling the user; adjust the request accordingly
15294                  */
15295                 if (IN_EOF(un->un_pos)) {
15296                         un->un_pos.fileno++;
15297                         un->un_pos.blkno = 0;
15298                         /*
15299                          * For positive direction case, we're now covered.
15300                          * For zero or negative direction, we're covered
15301                          * (almost)
15302                          */
15303                         files--;
15304                 }
15305 
15306         }
15307 
15308         if (st_check_density_or_wfm(un->un_dev, 1, B_READ, STEPBACK)) {
15309                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15310                     "st_mtfsf_ioctl: EIO : MTFSF density/wfm failed");
15311                 return (EIO);
15312         }
15313 
15314 
15315         /*
15316          * Forward space file marks.
15317          * We leave ourselves at block zero
15318          * of the target file number.
15319          */
15320         if (files < 0) {
15321                 rval = st_backward_space_files(un, -files, 0);
15322         } else {
15323                 rval = st_forward_space_files(un, files);
15324         }
15325 
15326         return (rval);
15327 }
15328 
15329 static int
15330 st_forward_space_files(struct scsi_tape *un, int64_t count)
15331 {
15332         int rval;
15333 
15334         ST_FUNC(ST_DEVINFO, st_forward_space_files);
15335 
15336         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15337             "fspace: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15338 
15339         ASSERT(count >= 0);
15340         ASSERT(un->un_pos.pmode != invalid);
15341 
15342         /*
15343          * A space with a count of zero means take me to the start of file.
15344          */
15345         if (count == 0) {
15346 
15347                 /* Hay look were already there */
15348                 if (un->un_pos.pmode == legacy && un->un_pos.blkno == 0) {
15349                         un->un_err_resid = 0;
15350                         COPY_POS(&un->un_err_pos, &un->un_pos);
15351                         return (0);
15352                 }
15353 
15354                 /*
15355                  * Well we are in the first file.
15356                  * A rewind will get to the start.
15357                  */
15358                 if (un->un_pos.pmode == legacy && un->un_pos.fileno == 0) {
15359                         rval = st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
15360 
15361                 /*
15362                  * Can we backspace to get there?
15363                  * This should work in logical mode.
15364                  */
15365                 } else if (un->un_dp->options & ST_BSF) {
15366                         rval = st_space_to_begining_of_file(un);
15367 
15368                 /*
15369                  * Can't back space but current file number is known,
15370                  * So rewind and space from the begining of the partition.
15371                  */
15372                 } else if (un->un_pos.pmode == legacy) {
15373                         rval = st_scenic_route_to_begining_of_file(un,
15374                             un->un_pos.fileno);
15375 
15376                 /*
15377                  * pmode is logical and ST_BSF is not set.
15378                  * The LONG_POS read position contains the fileno.
15379                  * If the read position works, rewind and space.
15380                  */
15381                 } else if (un->un_read_pos_type == LONG_POS) {
15382                         rval = st_cmd(un, SCMD_READ_POSITION, 0, SYNC_CMD);
15383                         if (rval) {
15384                                 /*
15385                                  * We didn't get the file position from the
15386                                  * read position command.
15387                                  * We are going to trust the drive to backspace
15388                                  * and then position after the filemark.
15389                                  */
15390                                 rval = st_space_to_begining_of_file(un);
15391                         }
15392                         rval = st_interpret_read_pos(un, &un->un_pos, LONG_POS,
15393                             32, (caddr_t)un->un_read_pos_data, 0);
15394                         if ((rval) && (un->un_pos.pmode == invalid)) {
15395                                 rval = st_space_to_begining_of_file(un);
15396                         } else {
15397                                 rval = st_scenic_route_to_begining_of_file(un,
15398                                     un->un_pos.fileno);
15399                         }
15400                 } else {
15401                         rval = EIO;
15402                 }
15403                 /*
15404                  * If something didn't work we are lost
15405                  */
15406                 if (rval != 0) {
15407                         un->un_pos.pmode = invalid;
15408                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15409                             "st_mtioctop : EIO : fspace pmode invalid");
15410 
15411                         rval = EIO;
15412                 }
15413 
15414         } else {
15415                 rval = st_space_fmks(un, count);
15416         }
15417 
15418         if (rval != EIO && count < 0) {
15419                 /*
15420                  * we came here with a count < 0; we now need
15421                  * to skip back to end up before the filemark
15422                  */
15423                 rval = st_backward_space_files(un, 1, 1);
15424         }
15425 
15426         return (rval);
15427 }
15428 
15429 static int
15430 st_scenic_route_to_begining_of_file(struct scsi_tape *un, int32_t fileno)
15431 {
15432         int rval;
15433 
15434         ST_FUNC(ST_DEVINFO, st_scenic_route_to_begining_of_file);
15435 
15436         if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15437                 rval = EIO;
15438         } else if (st_cmd(un, SCMD_SPACE, Fmk(fileno), SYNC_CMD)) {
15439                 rval = EIO;
15440         }
15441 
15442         return (rval);
15443 }
15444 
15445 static int
15446 st_space_to_begining_of_file(struct scsi_tape *un)
15447 {
15448         int rval;
15449 
15450         ST_FUNC(ST_DEVINFO, st_space_to_begining_of_file);
15451 
15452         /*
15453          * Back space of the file at the begining of the file.
15454          */
15455         rval = st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD);
15456         if (rval) {
15457                 rval = EIO;
15458                 return (rval);
15459         }
15460 
15461         /*
15462          * Other interesting answers might be crashed BOT which isn't bad.
15463          */
15464         if (un->un_status == SUN_KEY_BOT) {
15465                 return (rval);
15466         }
15467 
15468         un->un_running.pmode = invalid;
15469 
15470         /*
15471          * Now we are on the BOP side of the filemark. Forward space to
15472          * the EOM side and we are at the begining of the file.
15473          */
15474         rval = st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD);
15475         if (rval) {
15476                 rval = EIO;
15477         }
15478 
15479         return (rval);
15480 }
15481 
15482 static int
15483 st_mtfsr_ioctl(struct scsi_tape *un, int64_t count)
15484 {
15485 
15486         ST_FUNC(ST_DEVINFO, st_mtfsr_ioctl);
15487 
15488         /*
15489          * forward space to inter-record gap
15490          *
15491          */
15492 
15493         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15494             "st_ioctl_fsr: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15495 
15496         if (un->un_pos.pmode == legacy) {
15497                 /*
15498                  * If were are at end of tape and count is forward.
15499                  * Return blank check.
15500                  */
15501                 if ((un->un_pos.eof >= ST_EOT) && (count > 0)) {
15502                         /* we're at EOM */
15503                         un->un_err_resid = count;
15504                         un->un_status = KEY_BLANK_CHECK;
15505                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15506                             "st_mtfsr_ioctl: EIO : MTFSR eof > ST_EOT");
15507                         return (EIO);
15508                 }
15509 
15510                 /*
15511                  * If count is zero there is nothing to do.
15512                  */
15513                 if (count == 0) {
15514                         un->un_err_pos.fileno = un->un_pos.fileno;
15515                         un->un_err_pos.blkno = un->un_pos.blkno;
15516                         un->un_err_resid = 0;
15517                         if (IN_EOF(un->un_pos) && SVR4_BEHAVIOR) {
15518                                 un->un_status = SUN_KEY_EOF;
15519                         }
15520                         return (0);
15521                 }
15522 
15523                 /*
15524                  * physical tape position may not be what we've been
15525                  * telling the user; adjust the position accordingly
15526                  */
15527                 if (IN_EOF(un->un_pos)) {
15528                         daddr_t blkno = un->un_pos.blkno;
15529                         int fileno = un->un_pos.fileno;
15530 
15531                         optype lastop = un->un_lastop;
15532                         if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)
15533                             == -1) {
15534                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15535                                     "st_mtfsr_ioctl:EIO:MTFSR count && IN_EOF");
15536                                 return (EIO);
15537                         }
15538 
15539                         un->un_pos.blkno = blkno;
15540                         un->un_pos.fileno = fileno;
15541                         un->un_lastop = lastop;
15542                 }
15543         }
15544 
15545         if (st_check_density_or_wfm(un->un_dev, 1, B_READ, STEPBACK)) {
15546                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15547                     "st_mtfsr_ioctl: EIO : MTFSR st_check_den");
15548                 return (EIO);
15549         }
15550 
15551         return (st_space_records(un, count));
15552 }
15553 
15554 static int
15555 st_space_records(struct scsi_tape *un, int64_t count)
15556 {
15557         int64_t dblk;
15558         int rval = 0;
15559 
15560         ST_FUNC(ST_DEVINFO, st_space_records);
15561 
15562         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15563             "st_space_records: count=%"PRIx64", eof=%x\n",
15564             count, un->un_pos.eof);
15565 
15566         if (un->un_pos.pmode == logical) {
15567                 rval = st_cmd(un, SCMD_SPACE, Blk(count), SYNC_CMD);
15568                 if (rval != 0) {
15569                         rval = EIO;
15570                 }
15571                 return (rval);
15572         }
15573 
15574         dblk = count + un->un_pos.blkno;
15575 
15576         /* Already there */
15577         if (dblk == un->un_pos.blkno) {
15578                 un->un_err_resid = 0;
15579                 COPY_POS(&un->un_err_pos, &un->un_pos);
15580                 return (0);
15581         }
15582 
15583         /*
15584          * If the destination block is forward
15585          * or the drive will backspace records.
15586          */
15587         if (un->un_pos.blkno < dblk || (un->un_dp->options & ST_BSR)) {
15588                 /*
15589                  * If we're spacing forward, or the device can
15590                  * backspace records, we can just use the SPACE
15591                  * command.
15592                  */
15593                 dblk -= un->un_pos.blkno;
15594                 if (st_cmd(un, SCMD_SPACE, Blk(dblk), SYNC_CMD)) {
15595                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15596                             "st_space_records:EIO:space_records can't spc");
15597                         rval = EIO;
15598                 } else if (un->un_pos.eof >= ST_EOF_PENDING) {
15599                         /*
15600                          * check if we hit BOT/EOT
15601                          */
15602                         if (dblk < 0 && un->un_pos.eof == ST_EOM) {
15603                                 un->un_status = SUN_KEY_BOT;
15604                                 un->un_pos.eof = ST_NO_EOF;
15605                         } else if (dblk < 0 &&
15606                             un->un_pos.eof == ST_EOF_PENDING) {
15607                                 int residue = un->un_err_resid;
15608                                 /*
15609                                  * we skipped over a filemark
15610                                  * and need to go forward again
15611                                  */
15612                                 if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
15613                                         ST_DEBUG2(ST_DEVINFO, st_label,
15614                                             SCSI_DEBUG, "st_space_records: EIO"
15615                                             " : can't space #2");
15616                                         rval = EIO;
15617                                 }
15618                                 un->un_err_resid = residue;
15619                         }
15620                         if (rval == 0) {
15621                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15622                                     "st_space_records: EIO : space_rec rval"
15623                                     " == 0");
15624                                 rval = EIO;
15625                         }
15626                 }
15627         } else {
15628                 /*
15629                  * else we rewind, space forward across filemarks to
15630                  * the desired file, and then space records to the
15631                  * desired block.
15632                  */
15633 
15634                 int dfile = un->un_pos.fileno;       /* save current file */
15635 
15636                 if (dblk < 0) {
15637                         /*
15638                          * Wups - we're backing up over a filemark
15639                          */
15640                         if (un->un_pos.blkno != 0 &&
15641                             (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
15642                             st_cmd(un, SCMD_SPACE, Fmk(dfile), SYNC_CMD))) {
15643                                 un->un_pos.pmode = invalid;
15644                         }
15645                         un->un_err_resid = -dblk;
15646                         if (un->un_pos.fileno == 0 && un->un_pos.blkno == 0) {
15647                                 un->un_status = SUN_KEY_BOT;
15648                                 un->un_pos.eof = ST_NO_EOF;
15649                         } else if (un->un_pos.fileno > 0) {
15650                                 un->un_status = SUN_KEY_EOF;
15651                                 un->un_pos.eof = ST_NO_EOF;
15652                         }
15653                         COPY_POS(&un->un_err_pos, &un->un_pos);
15654                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15655                             "st_space_records:EIO:space_records : dblk < 0");
15656                         rval = EIO;
15657                 } else if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
15658                     st_cmd(un, SCMD_SPACE, Fmk(dfile), SYNC_CMD) ||
15659                     st_cmd(un, SCMD_SPACE, Blk(dblk), SYNC_CMD)) {
15660                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15661                             "st_space_records: EIO :space_records : rewind "
15662                             "and space failed");
15663                         un->un_pos.pmode = invalid;
15664                         rval = EIO;
15665                 }
15666         }
15667 
15668         return (rval);
15669 }
15670 
15671 static int
15672 st_mtbsf_ioctl(struct scsi_tape *un, int64_t files)
15673 {
15674         ST_FUNC(ST_DEVINFO, st_mtbsf_ioctl);
15675 
15676         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15677             "st_mtbsf_ioctl: count=%"PRIx64", eof=%x\n", files, un->un_pos.eof);
15678         /*
15679          * backward space of file filemark (1/2" and 8mm)
15680          * tape position will end on the beginning of tape side
15681          * of the desired file mark
15682          */
15683         if ((un->un_dp->options & ST_BSF) == 0) {
15684                 return (ENOTTY);
15685         }
15686 
15687         if (un->un_pos.pmode == legacy) {
15688 
15689                 /*
15690                  * If a negative count (which implies a forward space op)
15691                  * is specified, and we're at logical or physical eot,
15692                  * bounce the request.
15693                  */
15694 
15695                 if (un->un_pos.eof >= ST_EOT && files < 0) {
15696                         un->un_err_resid = files;
15697                         un->un_status = SUN_KEY_EOT;
15698                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15699                             "st_ioctl_mt_bsf : EIO : MTBSF : eof > ST_EOF");
15700                         return (EIO);
15701                 }
15702                 /*
15703                  * physical tape position may not be what we've been
15704                  * telling the user; adjust the request accordingly
15705                  */
15706                 if (IN_EOF(un->un_pos)) {
15707                         un->un_pos.fileno++;
15708                         un->un_pos.blkno = 0;
15709                         files++;
15710                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15711                             "st_mtbsf_ioctl in eof: count=%"PRIx64", op=%x\n",
15712                             files, MTBSF);
15713 
15714                 }
15715         }
15716 
15717         if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
15718                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15719                     "st_ioctl : EIO : MTBSF : check den wfm");
15720                 return (EIO);
15721         }
15722 
15723         if (files <= 0) {
15724                 /*
15725                  * for a negative count, we need to step forward
15726                  * first and then step back again
15727                  */
15728                 files = -files + 1;
15729                 return (st_forward_space_files(un, files));
15730         }
15731         return (st_backward_space_files(un, files, 1));
15732 }
15733 
15734 static int
15735 st_backward_space_files(struct scsi_tape *un, int64_t count, int infront)
15736 {
15737         int64_t end_fileno;
15738         int64_t skip_cnt;
15739         int rval = 0;
15740 
15741         ST_FUNC(ST_DEVINFO, st_backward_space_files);
15742 
15743         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15744             "st_backward_space_files: count=%"PRIx64" eof=%x\n",
15745             count, un->un_pos.eof);
15746         /*
15747          * Backspace files (MTNBSF): infront == 0
15748          *
15749          *      For tapes that can backspace, backspace
15750          *      count+1 filemarks and then run forward over
15751          *      a filemark
15752          *
15753          *      For tapes that can't backspace,
15754          *              calculate desired filenumber
15755          *              (un->un_pos.fileno - count), rewind,
15756          *              and then space forward this amount
15757          *
15758          * Backspace filemarks (MTBSF) infront == 1
15759          *
15760          *      For tapes that can backspace, backspace count
15761          *      filemarks
15762          *
15763          *      For tapes that can't backspace, calculate
15764          *      desired filenumber (un->un_pos.fileno - count),
15765          *      add 1, rewind, space forward this amount,
15766          *      and mark state as ST_EOF_PENDING appropriately.
15767          */
15768 
15769         if (un->un_pos.pmode == logical) {
15770 
15771                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15772                     "st_backward_space_files: mt_op=%x count=%"PRIx64
15773                     "lgclblkno=%"PRIx64"\n", infront?MTBSF:MTNBSF, count,
15774                     un->un_pos.lgclblkno);
15775 
15776 
15777                 /* In case a drive that won't back space gets in logical mode */
15778                 if ((un->un_dp->options & ST_BSF) == 0) {
15779                         rval = EIO;
15780                         return (rval);
15781                 }
15782                 if ((infront == 1) &&
15783                     (st_cmd(un, SCMD_SPACE, Fmk(-count), SYNC_CMD))) {
15784                         rval = EIO;
15785                         return (rval);
15786                 } else if ((infront == 0) &&
15787                     (st_cmd(un, SCMD_SPACE, Fmk((-count)-1), SYNC_CMD)) &&
15788                     (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD))) {
15789                         rval = EIO;
15790                         return (rval);
15791                 }
15792                 return (rval);
15793         }
15794 
15795         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15796             "st_backward_space_files: mt_op=%x count=%"PRIx64
15797             "fileno=%x blkno=%x\n",
15798             infront?MTBSF:MTNBSF, count, un->un_pos.fileno, un->un_pos.blkno);
15799 
15800 
15801 
15802         /*
15803          * Handle the simple case of BOT
15804          * playing a role in these cmds.
15805          * We do this by calculating the
15806          * ending file number. If the ending
15807          * file is < BOT, rewind and set an
15808          * error and mark resid appropriately.
15809          * If we're backspacing a file (not a
15810          * filemark) and the target file is
15811          * the first file on the tape, just
15812          * rewind.
15813          */
15814 
15815         /* figure expected destination of this SPACE command */
15816         end_fileno = un->un_pos.fileno - count;
15817 
15818         /*
15819          * Would the end effect of this SPACE be the same as rewinding?
15820          * If so just rewind instead.
15821          */
15822         if ((infront != 0) && (end_fileno < 0) ||
15823             (infront == 0) && (end_fileno <= 0)) {
15824                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15825                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15826                             "st_backward_space_files: EIO : "
15827                             "rewind in lou of BSF failed\n");
15828                         rval = EIO;
15829                 }
15830                 if (end_fileno < 0) {
15831                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15832                             "st_backward_space_files: EIO : "
15833                             "back space file greater then fileno\n");
15834                         rval = EIO;
15835                         un->un_err_resid = -end_fileno;
15836                         un->un_status = SUN_KEY_BOT;
15837                 }
15838                 return (rval);
15839         }
15840 
15841         if (un->un_dp->options & ST_BSF) {
15842                 skip_cnt = 1 - infront;
15843                 /*
15844                  * If we are going to end up at the beginning
15845                  * of the file, we have to space one extra file
15846                  * first, and then space forward later.
15847                  */
15848                 end_fileno = -(count + skip_cnt);
15849                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
15850                     "skip_cnt=%"PRIx64", tmp=%"PRIx64"\n",
15851                     skip_cnt, end_fileno);
15852                 if (st_cmd(un, SCMD_SPACE, Fmk(end_fileno), SYNC_CMD)) {
15853                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15854                             "st_backward_space_files:EIO:back space fm failed");
15855                         rval = EIO;
15856                 }
15857         } else {
15858                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15859                         rval = EIO;
15860                 } else {
15861                         skip_cnt = end_fileno + infront;
15862                 }
15863         }
15864 
15865         /*
15866          * If we have to space forward, do so...
15867          */
15868         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
15869             "space forward skip_cnt=%"PRIx64", rval=%x\n", skip_cnt, rval);
15870 
15871         if (rval == 0 && skip_cnt) {
15872                 if (st_cmd(un, SCMD_SPACE, Fmk(skip_cnt), SYNC_CMD)) {
15873                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15874                             "st_backward_space_files:EIO:space fm skip count");
15875                         rval = EIO;
15876                 } else if (infront) {
15877                         /*
15878                          * If we had to space forward, and we're
15879                          * not a tape that can backspace, mark state
15880                          * as if we'd just seen a filemark during a
15881                          * a read.
15882                          */
15883                         if ((un->un_dp->options & ST_BSF) == 0) {
15884                                 un->un_pos.eof = ST_EOF_PENDING;
15885                                 un->un_pos.fileno -= 1;
15886                                 un->un_pos.blkno = LASTBLK;
15887                                 un->un_running.pmode = invalid;
15888                         }
15889                 }
15890         }
15891 
15892         if (rval != 0) {
15893                 un->un_pos.pmode = invalid;
15894         }
15895 
15896         return (rval);
15897 }
15898 
15899 static int
15900 st_mtnbsf_ioctl(struct scsi_tape *un, int64_t count)
15901 {
15902         int rval;
15903 
15904         ST_FUNC(ST_DEVINFO, st_mtnbsf_ioctl);
15905 
15906         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15907             "nbsf: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15908 
15909         if (un->un_pos.pmode == legacy) {
15910                 /*
15911                  * backward space file to beginning of file
15912                  *
15913                  * If a negative count (which implies a forward space op)
15914                  * is specified, and we're at logical or physical eot,
15915                  * bounce the request.
15916                  */
15917 
15918                 if (un->un_pos.eof >= ST_EOT && count < 0) {
15919                         un->un_err_resid = count;
15920                         un->un_status = SUN_KEY_EOT;
15921                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15922                             "st_ioctl : EIO : > EOT and count < 0");
15923                         return (EIO);
15924                 }
15925                 /*
15926                  * physical tape position may not be what we've been
15927                  * telling the user; adjust the request accordingly
15928                  */
15929                 if (IN_EOF(un->un_pos)) {
15930                         un->un_pos.fileno++;
15931                         un->un_pos.blkno = 0;
15932                         count++;
15933                 }
15934         }
15935 
15936         if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
15937                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15938                     "st_ioctl : EIO : MTNBSF check den and wfm");
15939                 return (EIO);
15940         }
15941 
15942         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15943             "mtnbsf: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15944 
15945         if (count <= 0) {
15946                 rval = st_forward_space_files(un, -count);
15947         } else {
15948                 rval = st_backward_space_files(un, count, 0);
15949         }
15950         return (rval);
15951 }
15952 
15953 static int
15954 st_mtbsr_ioctl(struct scsi_tape *un, int64_t num)
15955 {
15956         ST_FUNC(ST_DEVINFO, st_mtbsr_ioctl);
15957 
15958         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15959             "bsr: count=%"PRIx64", eof=%x\n", num, un->un_pos.eof);
15960 
15961         if (un->un_pos.pmode == legacy) {
15962                 /*
15963                  * backward space into inter-record gap
15964                  *
15965                  * If a negative count (which implies a forward space op)
15966                  * is specified, and we're at logical or physical eot,
15967                  * bounce the request.
15968                  */
15969                 if (un->un_pos.eof >= ST_EOT && num < 0) {
15970                         un->un_err_resid = num;
15971                         un->un_status = SUN_KEY_EOT;
15972                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15973                             "st_ioctl : EIO : MTBSR > EOT");
15974                         return (EIO);
15975                 }
15976 
15977                 if (num == 0) {
15978                         COPY_POS(&un->un_err_pos, &un->un_pos);
15979                         un->un_err_resid = 0;
15980                         if (IN_EOF(un->un_pos) && SVR4_BEHAVIOR) {
15981                                 un->un_status = SUN_KEY_EOF;
15982                         }
15983                         return (0);
15984                 }
15985 
15986                 /*
15987                  * physical tape position may not be what we've been
15988                  * telling the user; adjust the position accordingly.
15989                  * bsr can not skip filemarks and continue to skip records
15990                  * therefore if we are logically before the filemark but
15991                  * physically at the EOT side of the filemark, we need to step
15992                  * back; this allows fsr N where N > number of blocks in file
15993                  * followed by bsr 1 to position at the beginning of last block
15994                  */
15995                 if (IN_EOF(un->un_pos)) {
15996                         tapepos_t save;
15997                         optype lastop = un->un_lastop;
15998 
15999                         COPY_POS(&save, &un->un_pos);
16000                         if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD) == -1) {
16001                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16002                                     "st_mtbsr_ioctl: EIO : MTBSR can't space");
16003                                 return (EIO);
16004                         }
16005 
16006                         COPY_POS(&un->un_pos, &save);
16007                         un->un_lastop = lastop;
16008                 }
16009         }
16010 
16011         un->un_pos.eof = ST_NO_EOF;
16012 
16013         if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
16014                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16015                     "st_ioctl : EIO : MTBSR : can't set density or wfm");
16016                 return (EIO);
16017         }
16018 
16019         num = -num;
16020         return (st_space_records(un, num));
16021 }
16022 
16023 static int
16024 st_mtfsfm_ioctl(struct scsi_tape *un, int64_t cnt)
16025 {
16026         int rval;
16027 
16028         ST_FUNC(ST_DEVINFO, st_mtfsfm_ioctl);
16029 
16030         rval = st_cmd(un, SCMD_SPACE, SPACE(SP_SQFLM, cnt), SYNC_CMD);
16031         if (rval == 0) {
16032                 un->un_pos.pmode = logical;
16033         } else if ((un->un_status == KEY_ILLEGAL_REQUEST) &&
16034             (un->un_sd->sd_sense->es_add_code == 0x24)) {
16035                 /*
16036                  * Drive says invalid field in cdb.
16037                  * Doesn't like space multiple. Position isn't lost.
16038                  */
16039                 un->un_err_resid = cnt;
16040                 un->un_status = 0;
16041                 rval = ENOTTY;
16042         } else {
16043                 un->un_err_resid = cnt;
16044                 un->un_pos.pmode = invalid;
16045         }
16046         return (rval);
16047 }
16048 
16049 static int
16050 st_mtbsfm_ioctl(struct scsi_tape *un, int64_t cnt)
16051 {
16052         int rval;
16053 
16054         ST_FUNC(ST_DEVINFO, st_mtbsfm_ioctl);
16055 
16056         rval = st_cmd(un, SCMD_SPACE, SPACE(SP_SQFLM, -cnt), SYNC_CMD);
16057         if (rval == 0) {
16058                 un->un_pos.pmode = logical;
16059         } else if ((un->un_status == KEY_ILLEGAL_REQUEST) &&
16060             (un->un_sd->sd_sense->es_add_code == 0x24)) {
16061                 /*
16062                  * Drive says invalid field in cdb.
16063                  * Doesn't like space multiple. Position isn't lost.
16064                  */
16065                 un->un_err_resid = cnt;
16066                 un->un_status = 0;
16067                 rval = ENOTTY;
16068         } else {
16069                 un->un_err_resid = cnt;
16070                 un->un_pos.pmode = invalid;
16071         }
16072         return (rval);
16073 }
16074 
16075 #ifdef  __x86
16076 
16077 /*
16078  * release contig_mem and wake up waiting thread, if any
16079  */
16080 static void
16081 st_release_contig_mem(struct scsi_tape *un, struct contig_mem *cp)
16082 {
16083         mutex_enter(ST_MUTEX);
16084 
16085         ST_FUNC(ST_DEVINFO, st_release_contig_mem);
16086 
16087         cp->cm_next = un->un_contig_mem;
16088         un->un_contig_mem = cp;
16089         un->un_contig_mem_available_num++;
16090         cv_broadcast(&un->un_contig_mem_cv);
16091 
16092         mutex_exit(ST_MUTEX);
16093 }
16094 
16095 /*
16096  * St_get_contig_mem will return a contig_mem if there is one available
16097  * in current system. Otherwise, it will try to alloc one, if the total
16098  * number of contig_mem is within st_max_contig_mem_num.
16099  * It will sleep, if allowed by caller or return NULL, if no contig_mem
16100  * is available for now.
16101  */
16102 static struct contig_mem *
16103 st_get_contig_mem(struct scsi_tape *un, size_t len, int alloc_flags)
16104 {
16105         size_t rlen;
16106         struct contig_mem *cp = NULL;
16107         ddi_acc_handle_t acc_hdl;
16108         caddr_t addr;
16109         int big_enough = 0;
16110         int (*dma_alloc_cb)() = (alloc_flags == KM_SLEEP) ?
16111             DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
16112 
16113         /* Try to get one available contig_mem */
16114         mutex_enter(ST_MUTEX);
16115 
16116         ST_FUNC(ST_DEVINFO, st_get_contig_mem);
16117 
16118         if (un->un_contig_mem_available_num > 0) {
16119                 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16120         } else if (un->un_contig_mem_total_num < st_max_contig_mem_num) {
16121                 /*
16122                  * we failed to get one. we're going to
16123                  * alloc one more contig_mem for this I/O
16124                  */
16125                 mutex_exit(ST_MUTEX);
16126                 cp = (struct contig_mem *)kmem_zalloc(
16127                     sizeof (struct contig_mem) + biosize(),
16128                     alloc_flags);
16129                 if (cp == NULL) {
16130                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16131                             "alloc contig_mem failure\n");
16132                         return (NULL); /* cannot get one */
16133                 }
16134                 cp->cm_bp = (struct buf *)
16135                     (((caddr_t)cp) + sizeof (struct contig_mem));
16136                 bioinit(cp->cm_bp);
16137                 mutex_enter(ST_MUTEX);
16138                 un->un_contig_mem_total_num++; /* one more available */
16139         } else {
16140                 /*
16141                  * we failed to get one and we're NOT allowed to
16142                  * alloc more contig_mem
16143                  */
16144                 if (alloc_flags == KM_SLEEP) {
16145                         while (un->un_contig_mem_available_num <= 0) {
16146                                 cv_wait(&un->un_contig_mem_cv, ST_MUTEX);
16147                         }
16148                         ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16149                 } else {
16150                         mutex_exit(ST_MUTEX);
16151                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16152                             "alloc contig_mem failure\n");
16153                         return (NULL); /* cannot get one */
16154                 }
16155         }
16156         mutex_exit(ST_MUTEX);
16157 
16158         /* We need to check if this block of mem is big enough for this I/O */
16159         if (cp->cm_len < len) {
16160                 /* not big enough, need to alloc a new one */
16161                 if (ddi_dma_mem_alloc(un->un_contig_mem_hdl, len, &st_acc_attr,
16162                     DDI_DMA_STREAMING, dma_alloc_cb, NULL,
16163                     &addr, &rlen, &acc_hdl) != DDI_SUCCESS) {
16164                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16165                             "alloc contig_mem failure: not enough mem\n");
16166                         st_release_contig_mem(un, cp);
16167                         cp = NULL;
16168                 } else {
16169                         if (cp->cm_addr) {
16170                                 /* release previous one before attach new one */
16171                                 ddi_dma_mem_free(&cp->cm_acc_hdl);
16172                         }
16173                         mutex_enter(ST_MUTEX);
16174                         un->un_max_contig_mem_len =
16175                             un->un_max_contig_mem_len >= len ?
16176                             un->un_max_contig_mem_len : len;
16177                         mutex_exit(ST_MUTEX);
16178 
16179                         /* attach new mem to this cp */
16180                         cp->cm_addr = addr;
16181                         cp->cm_acc_hdl = acc_hdl;
16182                         cp->cm_len = len;
16183 
16184                         goto alloc_ok; /* get one usable cp */
16185                 }
16186         } else {
16187                 goto alloc_ok; /* get one usable cp */
16188         }
16189 
16190         /* cannot find/alloc a usable cp, when we get here */
16191 
16192         mutex_enter(ST_MUTEX);
16193         if ((un->un_max_contig_mem_len < len) ||
16194             (alloc_flags != KM_SLEEP)) {
16195                 mutex_exit(ST_MUTEX);
16196                 return (NULL);
16197         }
16198 
16199         /*
16200          * we're allowed to sleep, and there is one big enough
16201          * contig mem in the system, which is currently in use,
16202          * wait for it...
16203          */
16204         big_enough = 1;
16205         do {
16206                 cv_wait(&un->un_contig_mem_cv, ST_MUTEX);
16207                 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16208         } while (cp == NULL);
16209         mutex_exit(ST_MUTEX);
16210 
16211         /* we get the big enough contig mem, finally */
16212 
16213 alloc_ok:
16214         /* init bp attached to this cp */
16215         bioreset(cp->cm_bp);
16216         cp->cm_bp->b_un.b_addr = cp->cm_addr;
16217         cp->cm_bp->b_private = (void *)cp;
16218 
16219         return (cp);
16220 }
16221 
16222 /*
16223  * this is the biodone func for the bp used in big block I/O
16224  */
16225 static int
16226 st_bigblk_xfer_done(struct buf *bp)
16227 {
16228         struct contig_mem *cp;
16229         struct buf *orig_bp;
16230         int ioerr;
16231         struct scsi_tape *un;
16232 
16233         /* sanity check */
16234         if (bp == NULL) {
16235                 return (DDI_FAILURE);
16236         }
16237 
16238         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16239         if (un == NULL) {
16240                 return (DDI_FAILURE);
16241         }
16242 
16243         ST_FUNC(ST_DEVINFO, st_bigblk_xfer_done);
16244 
16245         cp = (struct contig_mem *)bp->b_private;
16246         orig_bp = cp->cm_bp; /* get back the bp we have replaced */
16247         cp->cm_bp = bp;
16248 
16249         /* special handling for special I/O */
16250         if (cp->cm_use_sbuf) {
16251 #ifndef __lock_lint
16252                 ASSERT(un->un_sbuf_busy);
16253 #endif
16254                 un->un_sbufp = orig_bp;
16255                 cp->cm_use_sbuf = 0;
16256         }
16257 
16258         orig_bp->b_resid = bp->b_resid;
16259         ioerr = geterror(bp);
16260         if (ioerr != 0) {
16261                 bioerror(orig_bp, ioerr);
16262         } else if (orig_bp->b_flags & B_READ) {
16263                 /* copy data back to original bp */
16264                 (void) bp_copyout(bp->b_un.b_addr, orig_bp, 0,
16265                     bp->b_bcount - bp->b_resid);
16266         }
16267 
16268         st_release_contig_mem(un, cp);
16269 
16270         biodone(orig_bp);
16271 
16272         return (DDI_SUCCESS);
16273 }
16274 
16275 /*
16276  * We use this func to replace original bp that may not be able to do I/O
16277  * in big block size with one that can
16278  */
16279 static struct buf *
16280 st_get_bigblk_bp(struct buf *bp)
16281 {
16282         struct contig_mem *cp;
16283         struct scsi_tape *un;
16284         struct buf *cont_bp;
16285 
16286         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16287         if (un == NULL) {
16288                 return (bp);
16289         }
16290 
16291         ST_FUNC(ST_DEVINFO, st_get_bigblk_bp);
16292 
16293         /* try to get one contig_mem */
16294         cp = st_get_contig_mem(un, bp->b_bcount, KM_SLEEP);
16295         if (!cp) {
16296                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
16297                     "Cannot alloc contig buf for I/O for %lu blk size",
16298                     bp->b_bcount);
16299                 return (bp);
16300         }
16301         cont_bp = cp->cm_bp;
16302         cp->cm_bp = bp;
16303 
16304         /* make sure that we "are" using un_sbufp for special I/O */
16305         if (bp == un->un_sbufp) {
16306 #ifndef __lock_lint
16307                 ASSERT(un->un_sbuf_busy);
16308 #endif
16309                 un->un_sbufp = cont_bp;
16310                 cp->cm_use_sbuf = 1;
16311         }
16312 
16313         /* clone bp */
16314         cont_bp->b_bcount = bp->b_bcount;
16315         cont_bp->b_resid = bp->b_resid;
16316         cont_bp->b_iodone = st_bigblk_xfer_done;
16317         cont_bp->b_file = bp->b_file;
16318         cont_bp->b_offset = bp->b_offset;
16319         cont_bp->b_dip = bp->b_dip;
16320         cont_bp->b_error = 0;
16321         cont_bp->b_proc = NULL;
16322         cont_bp->b_flags = bp->b_flags & ~(B_PAGEIO | B_PHYS | B_SHADOW);
16323         cont_bp->b_shadow = NULL;
16324         cont_bp->b_pages = NULL;
16325         cont_bp->b_edev = bp->b_edev;
16326         cont_bp->b_dev = bp->b_dev;
16327         cont_bp->b_lblkno = bp->b_lblkno;
16328         cont_bp->b_forw = bp->b_forw;
16329         cont_bp->b_back = bp->b_back;
16330         cont_bp->av_forw = bp->av_forw;
16331         cont_bp->av_back = bp->av_back;
16332         cont_bp->b_bufsize = bp->b_bufsize;
16333 
16334         /* get data in original bp */
16335         if (bp->b_flags & B_WRITE) {
16336                 (void) bp_copyin(bp, cont_bp->b_un.b_addr, 0, bp->b_bcount);
16337         }
16338 
16339         return (cont_bp);
16340 }
16341 #else
16342 #ifdef __lock_lint
16343 static int
16344 st_bigblk_xfer_done(struct buf *bp)
16345 {
16346         return (0);
16347 }
16348 #endif
16349 #endif
16350 
16351 static const char *eof_status[] =
16352 {
16353         "NO_EOF",
16354         "EOF_PENDING",
16355         "EOF",
16356         "EOT_PENDING",
16357         "EOT",
16358         "EOM",
16359         "AFTER_EOM"
16360 };
16361 static const char *mode[] = {
16362         "invalid",
16363         "legacy",
16364         "logical"
16365 };
16366 
16367 static void
16368 st_print_position(dev_info_t *dev, char *label, uint_t level,
16369 const char *comment, tapepos_t *pos)
16370 {
16371         ST_FUNC(dev, st_print_position);
16372 
16373         scsi_log(dev, label, level,
16374             "%s Position data:\n", comment);
16375         scsi_log(dev, label, CE_CONT,
16376             "Positioning mode = %s", mode[pos->pmode]);
16377         scsi_log(dev, label, CE_CONT,
16378             "End Of File/Tape = %s", eof_status[pos->eof]);
16379         scsi_log(dev, label, CE_CONT,
16380             "File Number      = 0x%x", pos->fileno);
16381         scsi_log(dev, label, CE_CONT,
16382             "Block Number     = 0x%x", pos->blkno);
16383         scsi_log(dev, label, CE_CONT,
16384             "Logical Block    = 0x%"PRIx64, pos->lgclblkno);
16385         scsi_log(dev, label, CE_CONT,
16386             "Partition Number = 0x%x", pos->partition);
16387 }
16388 static int
16389 st_check_if_media_changed(struct scsi_tape *un, caddr_t data, int size)
16390 {
16391 
16392         int result = 0;
16393         int i;
16394         ST_FUNC(ST_DEVINFO, st_check_if_media_changed);
16395 
16396         /*
16397          * find non alpha numeric working from the end.
16398          */
16399         for (i = size - 1; i >= 0; i--) {
16400                 if (ISALNUM(data[i]) == 0 || data[i] == ' ') {
16401                         data[i] = 0;
16402                         size = i;
16403                 }
16404         }
16405 
16406         if (size == 1) {
16407                 /*
16408                  * Drive seems to think its returning useful data
16409                  * but it looks like all junk
16410                  */
16411                 return (result);
16412         }
16413 
16414         size++;
16415 
16416         /*
16417          * Actually got a valid serial number.
16418          * If never stored one before alloc space for it.
16419          */
16420         if (un->un_media_id_len == 0) {
16421                 un->un_media_id = kmem_zalloc(size, KM_SLEEP);
16422                 un->un_media_id_len = size;
16423                 (void) strncpy(un->un_media_id, data, min(size, strlen(data)));
16424                 un->un_media_id[min(size, strlen(data))] = 0;
16425                 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16426                     "Found Media Id %s length = %d\n", un->un_media_id, size);
16427         } else if (size > un->un_media_id_len) {
16428                 if (strncmp(un->un_media_id, data, size) != 0) {
16429                         result = ESPIPE;
16430                 }
16431                 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16432                     "Longer Media Id old ID:%s new ID:%s\n",
16433                     un->un_media_id, data);
16434                 kmem_free(un->un_media_id, un->un_media_id_len);
16435                 un->un_media_id = kmem_zalloc(size, KM_SLEEP);
16436                 un->un_media_id_len = size;
16437                 (void) strncpy(un->un_media_id, data, size);
16438                 un->un_media_id[size] = 0;
16439         } else if (strncmp(data, un->un_media_id,
16440             min(size, un->un_media_id_len)) != 0) {
16441                 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16442                     "Old Media Id %s length = %d New %s length = %d\n",
16443                     un->un_media_id, un->un_media_id_len, data, size);
16444                 bzero(un->un_media_id, un->un_media_id_len);
16445                 (void) strncpy(un->un_media_id, data, min(size, strlen(data)));
16446                 un->un_media_id[min(size, strlen(data))] = 0;
16447                 result = ESPIPE;
16448         } else {
16449                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
16450                     "Media Id still %s\n", un->un_media_id);
16451         }
16452 
16453         ASSERT(strlen(un->un_media_id) <= size);
16454 
16455         return (result);
16456 }
16457 #define ID_SIZE 32
16458 typedef struct
16459 {
16460         uchar_t avilable_data0;
16461         uchar_t avilable_data1;
16462         uchar_t avilable_data2;
16463         uchar_t avilable_data3;
16464         uchar_t attribute_msb;
16465         uchar_t attribute_lsb;
16466 #ifdef _BIT_FIELDS_LTOH
16467         uchar_t format          : 2,
16468                                 : 5,
16469                 read_only       : 1;
16470 #else
16471         uchar_t read_only       : 1,
16472                                 : 5,
16473                 format          : 2;
16474 #endif
16475         uchar_t attribute_len_msb;
16476         uchar_t attribute_len_lsb;
16477 }attribute_header;
16478 
16479 typedef struct {
16480         attribute_header header;
16481         char data[1];
16482 }mam_attribute;
16483 
16484 static int
16485 st_handle_hex_media_id(struct scsi_tape *un, void *pnt, int size)
16486 {
16487         int result;
16488         int newsize = (size << 1) + 3; /* extra for leading 0x and null term */
16489         int i;
16490         uchar_t byte;
16491         char *format;
16492         uchar_t *data = (uchar_t *)pnt;
16493         char *buf = kmem_alloc(newsize, KM_SLEEP);
16494 
16495         ST_FUNC(ST_DEVINFO, st_handle_hex_media_id);
16496 
16497         (void) sprintf(buf, "0x");
16498         for (i = 0; i < size; i++) {
16499                 byte = data[i];
16500                 if (byte < 0x10)
16501                         format = "0%x";
16502                 else
16503                         format = "%x";
16504                 (void) sprintf(&buf[(int)strlen(buf)], format, byte);
16505         }
16506         result = st_check_if_media_changed(un, buf, newsize);
16507 
16508         kmem_free(buf, newsize);
16509 
16510         return (result);
16511 }
16512 
16513 
16514 static int
16515 st_get_media_id_via_read_attribute(struct scsi_tape *un, ubufunc_t bufunc)
16516 {
16517         int result;
16518         mam_attribute *buffer;
16519         int size;
16520         int newsize;
16521 
16522         ST_FUNC(ST_DEVINFO, st_get_media_id_via_read_attribute);
16523         size = sizeof (attribute_header) + max(un->un_media_id_len, ID_SIZE);
16524 again:
16525         buffer = kmem_zalloc(size, KM_SLEEP);
16526         result = st_read_attributes(un, 0x0401, buffer, size, bufunc);
16527         if (result == 0) {
16528 
16529                 newsize = (buffer->header.attribute_len_msb << 8) |
16530                     buffer->header.attribute_len_lsb;
16531 
16532                 if (newsize + sizeof (attribute_header) > size) {
16533                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
16534                             "resizing read attribute data from %d to %d format"
16535                             " %d\n", size, (int)sizeof (attribute_header) +
16536                             newsize, buffer->header.format);
16537                         kmem_free(buffer, size);
16538                         size = newsize + sizeof (attribute_header);
16539                         goto again;
16540                 }
16541 
16542                 un->un_media_id_method = st_get_media_id_via_read_attribute;
16543                 if (buffer->header.format == 0) {
16544                         result =
16545                             st_handle_hex_media_id(un, buffer->data, newsize);
16546                 } else {
16547                         result = st_check_if_media_changed(un, buffer->data,
16548                             newsize);
16549                 }
16550         } else if (result == EINVAL && un->un_max_cdb_sz < CDB_GROUP4) {
16551                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
16552                     "Read Attribute Command for Media Identification is not "
16553                     "supported on the HBA that this drive is attached to.");
16554                 result = ENOTTY;
16555         }
16556 
16557         kmem_free(buffer, size);
16558         un->un_status = 0;
16559 
16560         return (result);
16561 }
16562 
16563 
16564 static int
16565 st_get_media_id_via_media_serial_cmd(struct scsi_tape *un, ubufunc_t bufunc)
16566 {
16567         char cdb[CDB_GROUP5];
16568         struct uscsi_cmd *ucmd;
16569         struct scsi_extended_sense sense;
16570         int rval;
16571         int size = max(un->un_media_id_len, ID_SIZE);
16572         caddr_t buf;
16573 
16574         ST_FUNC(ST_DEVINFO, st_get_media_id_via_media_serial_cmd);
16575 
16576         if (un->un_sd->sd_inq->inq_ansi < 3) {
16577                 return (ENOTTY);
16578         }
16579 
16580         ucmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
16581 upsize:
16582         buf = kmem_alloc(size, KM_SLEEP);
16583 
16584         cdb[0] = (char)SCMD_SVC_ACTION_IN_G5;
16585         cdb[1] = SSVC_ACTION_READ_MEDIA_SERIAL;
16586         cdb[2] = 0;
16587         cdb[3] = 0;
16588         cdb[4] = 0;
16589         cdb[5] = 0;
16590         cdb[6] = (char)(size >> 24);
16591         cdb[7] = (char)(size >> 16);
16592         cdb[8] = (char)(size >> 8);
16593         cdb[9] = (char)(size);
16594         cdb[10] = 0;
16595         cdb[11] = 0;
16596 
16597         ucmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE;
16598         ucmd->uscsi_timeout = un->un_dp->non_motion_timeout;
16599         ucmd->uscsi_cdb = &cdb[0];
16600         ucmd->uscsi_cdblen = sizeof (cdb);
16601         ucmd->uscsi_bufaddr = buf;
16602         ucmd->uscsi_buflen = size;
16603         ucmd->uscsi_rqbuf = (caddr_t)&sense;
16604         ucmd->uscsi_rqlen = sizeof (sense);
16605 
16606         rval = bufunc(un, ucmd, FKIOCTL);
16607 
16608         if (rval || ucmd->uscsi_status != 0) {
16609                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
16610                     "media serial command returned %d scsi_status %d"
16611                     " rqstatus %d", rval, ucmd->uscsi_status,
16612                     ucmd->uscsi_rqstatus);
16613                 /*
16614                  * If this returns invalid operation code don't try again.
16615                  */
16616                 if (sense.es_key == KEY_ILLEGAL_REQUEST &&
16617                     sense.es_add_code == 0x20) {
16618                         rval = ENOTTY;
16619                 } else if (rval == 0) {
16620                         rval = EIO;
16621                 }
16622                 un->un_status = 0;
16623         } else {
16624                 int act_size;
16625 
16626                 /*
16627                  * get reported size.
16628                  */
16629                 act_size = (int)buf[3] | (int)(buf[2] << 8) |
16630                     (int)(buf[1] << 16) | (int)(buf[0] << 24);
16631 
16632                 /* documentation says mod 4. */
16633                 while (act_size & 3) {
16634                         act_size++;
16635                 }
16636 
16637                 /*
16638                  * If reported size is larger that we our buffer.
16639                  * Free the old one and allocate one that is larger
16640                  * enough and re-issuse the command.
16641                  */
16642                 if (act_size + 4 > size) {
16643                         kmem_free(buf, size);
16644                         size = act_size + 4;
16645                         goto upsize;
16646                 }
16647 
16648                 if (act_size == 0) {
16649                         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
16650                             "media serial number is not available");
16651                         un->un_status = 0;
16652                         rval = 0;
16653                 } else {
16654                         /*
16655                          * set data pointer to point to the start
16656                          * of that serial number.
16657                          */
16658                         un->un_media_id_method =
16659                             st_get_media_id_via_media_serial_cmd;
16660                         rval =
16661                             st_check_if_media_changed(un, &buf[4], act_size);
16662                 }
16663         }
16664 
16665         kmem_free(ucmd, sizeof (struct uscsi_cmd));
16666         kmem_free(buf, size);
16667 
16668         return (rval);
16669 }
16670 
16671 
16672 /* ARGSUSED */
16673 static int
16674 st_bogus_media_id(struct scsi_tape *un, ubufunc_t bufunc)
16675 {
16676         ST_FUNC(ST_DEVINFO, st_bogus_media_id);
16677 
16678         ASSERT(un->un_media_id == NULL || un->un_media_id == bogusID);
16679         ASSERT(un->un_media_id_len == 0);
16680         un->un_media_id = (char *)bogusID;
16681         un->un_media_id_len = 0;
16682         return (0);
16683 }
16684 
16685 typedef int (*media_chk_function)(struct scsi_tape *, ubufunc_t bufunc);
16686 
16687 media_chk_function media_chk_functions[] = {
16688         st_get_media_id_via_media_serial_cmd,
16689         st_get_media_id_via_read_attribute,
16690         st_bogus_media_id
16691 };
16692 
16693 static int
16694 st_get_media_identification(struct scsi_tape *un, ubufunc_t bufunc)
16695 {
16696         int result = 0;
16697         int i;
16698 
16699         ST_FUNC(ST_DEVINFO, st_get_media_identification);
16700 
16701         for (i = 0; i < ST_NUM_MEMBERS(media_chk_functions); i++) {
16702                 if (result == ENOTTY) {
16703                         /*
16704                          * Last operation type not supported by this device.
16705                          * Make so next time it doesn`t do that again.
16706                          */
16707                         un->un_media_id_method = media_chk_functions[i];
16708                 } else if (un->un_media_id_method != media_chk_functions[i] &&
16709                     un->un_media_id_method != st_get_media_identification) {
16710                         continue;
16711                 }
16712                 result = media_chk_functions[i](un, bufunc);
16713                 /*
16714                  * If result indicates the function was successful or
16715                  * that the media is not the same as last known, break.
16716                  */
16717                 if (result == 0 || result == ESPIPE) {
16718                         break;
16719                 }
16720         }
16721 
16722         return (result);
16723 }
16724 
16725 static errstate
16726 st_command_recovery(struct scsi_tape *un, struct scsi_pkt *pkt,
16727     errstate onentry)
16728 {
16729 
16730         int ret;
16731         st_err_info *errinfo;
16732         recov_info *ri = (recov_info *)pkt->pkt_private;
16733 
16734         ST_FUNC(ST_DEVINFO, st_command_recovery);
16735 
16736         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
16737 
16738         ASSERT(un->un_recov_buf_busy == 0);
16739 
16740         /*
16741          * Don't try and recover a reset that this device sent.
16742          */
16743         if (un->un_rsvd_status & ST_INITIATED_RESET &&
16744             onentry == DEVICE_RESET) {
16745                 return (COMMAND_DONE_ERROR);
16746         }
16747 
16748         /*
16749          * See if expected position was passed with scsi_pkt.
16750          */
16751         if (ri->privatelen == sizeof (recov_info)) {
16752 
16753                 /*
16754                  * Not for this command.
16755                  */
16756                 if (ri->cmd_attrib->do_not_recover) {
16757                         return (COMMAND_DONE_ERROR);
16758                 }
16759 
16760                 /*
16761                  * Create structure to hold all error state info.
16762                  */
16763                 errinfo = kmem_zalloc(ST_ERR_INFO_SIZE, KM_SLEEP);
16764                 errinfo->ei_error_type = onentry;
16765                 errinfo->ei_failing_bp = ri->cmd_bp;
16766                 COPY_POS(&errinfo->ei_expected_pos, &ri->pos);
16767         } else {
16768                 /* disabled */
16769                 return (COMMAND_DONE_ERROR);
16770         }
16771 
16772         bcopy(pkt, &errinfo->ei_failed_pkt, scsi_pkt_size());
16773         bcopy(pkt->pkt_scbp, &errinfo->ei_failing_status, SECMDS_STATUS_SIZE);
16774         ret = ddi_taskq_dispatch(un->un_recov_taskq, st_recover, errinfo,
16775             DDI_NOSLEEP);
16776         ASSERT(ret == DDI_SUCCESS);
16777         if (ret != DDI_SUCCESS) {
16778                 kmem_free(errinfo, ST_ERR_INFO_SIZE);
16779                 return (COMMAND_DONE_ERROR);
16780         }
16781         return (JUST_RETURN); /* release calling thread */
16782 }
16783 
16784 
16785 static void
16786 st_recov_ret(struct scsi_tape *un, st_err_info *errinfo, errstate err)
16787 {
16788         int error_number;
16789         buf_t *bp;
16790 
16791 
16792         ST_FUNC(ST_DEVINFO, st_recov_ret);
16793 
16794         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
16795 #if !defined(lint)
16796         _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&un->un_sd->sd_mutex))
16797 #endif
16798 
16799         bp = errinfo->ei_failing_bp;
16800         kmem_free(errinfo, ST_ERR_INFO_SIZE);
16801 
16802         switch (err) {
16803         case JUST_RETURN:
16804                 mutex_exit(&un->un_sd->sd_mutex);
16805                 return;
16806 
16807         case COMMAND_DONE:
16808         case COMMAND_DONE_ERROR_RECOVERED:
16809                 ST_DO_KSTATS(bp, kstat_runq_exit);
16810                 error_number = 0;
16811                 break;
16812 
16813         default:
16814                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
16815                     "st_recov_ret with unhandled errstat %d\n", err);
16816                 /* FALLTHROUGH */
16817         case COMMAND_DONE_ERROR:
16818                 un->un_pos.pmode = invalid;
16819                 un->un_running.pmode = invalid;
16820                 /* FALLTHROUGH */
16821         case COMMAND_DONE_EACCES:
16822                 ST_DO_KSTATS(bp, kstat_waitq_exit);
16823                 ST_DO_ERRSTATS(un, st_transerrs);
16824                 error_number = EIO;
16825                 st_set_pe_flag(un);
16826                 break;
16827 
16828         }
16829 
16830         st_bioerror(bp, error_number);
16831         st_done_and_mutex_exit(un, bp);
16832 }
16833 
16834 
16835 static void
16836 st_recover(void *arg)
16837 {
16838         st_err_info *const errinfo = (st_err_info *)arg;
16839         uchar_t com = errinfo->ei_failed_pkt.pkt_cdbp[0];
16840         struct scsi_tape *un;
16841         tapepos_t cur_pos;
16842         int rval;
16843         errstate status = COMMAND_DONE_ERROR;
16844         recov_info *rcv;
16845         buf_t *bp;
16846 
16847 
16848         rcv = errinfo->ei_failed_pkt.pkt_private;
16849         ASSERT(rcv->privatelen == sizeof (recov_info));
16850         bp = rcv->cmd_bp;
16851 
16852         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16853 
16854         ASSERT(un != NULL);
16855 
16856         mutex_enter(ST_MUTEX);
16857 
16858         ST_FUNC(ST_DEVINFO, st_recover);
16859 
16860         ST_CDB(ST_DEVINFO, "Recovering command",
16861             (caddr_t)errinfo->ei_failed_pkt.pkt_cdbp);
16862         ST_SENSE(ST_DEVINFO, "sense status for failed command",
16863             (caddr_t)&errinfo->ei_failing_status,
16864             sizeof (struct scsi_arq_status));
16865         ST_POS(ST_DEVINFO, rcv->cmd_attrib->recov_pos_type == POS_STARTING ?
16866             "starting position for recovery command" :
16867             "expected position for recovery command",
16868             &errinfo->ei_expected_pos);
16869 
16870         rval = st_test_path_to_device(un);
16871 
16872         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
16873             "st_recover called with %s, TUR returned %d\n",
16874             errstatenames[errinfo->ei_error_type], rval);
16875         /*
16876          * If the drive responed to the TUR lets try and get it to sync
16877          * any data it might have in the buffer.
16878          */
16879         if (rval == 0 && rcv->cmd_attrib->chg_tape_data) {
16880                 rval = st_rcmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD);
16881                 if (rval) {
16882                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
16883                             "st_recover failed to flush, returned %d\n", rval);
16884                         st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16885                         return;
16886                 }
16887         }
16888         switch (errinfo->ei_error_type) {
16889         case ATTEMPT_RETRY:
16890         case COMMAND_TIMEOUT:
16891         case DEVICE_RESET:
16892         case PATH_FAILED:
16893                 /*
16894                  * For now if we can't talk to the device we are done.
16895                  * If the drive is reserved we can try to get it back.
16896                  */
16897                 if (rval != 0 && rval != EACCES) {
16898                         st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16899                         return;
16900                 }
16901 
16902                 /*
16903                  * If reservation conflict and do a preempt, fail it.
16904                  */
16905                 if ((un->un_rsvd_status &
16906                     (ST_APPLICATION_RESERVATIONS | ST_RESERVE)) != 0) {
16907                         if ((errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16908                             SCMD_PERSISTENT_RESERVE_OUT) &&
16909                             (errinfo->ei_failed_pkt.pkt_cdbp[1] ==
16910                             ST_SA_SCSI3_PREEMPT) &&
16911                             (SCBP_C(&errinfo->ei_failed_pkt) ==
16912                             STATUS_RESERVATION_CONFLICT)) {
16913                                 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16914                                 return;
16915                         }
16916                 }
16917 
16918                 /*
16919                  * If we have already set a scsi II reserve and get a
16920                  * conflict on a scsi III type reserve fail without
16921                  * any attempt to recover.
16922                  */
16923                 if ((un->un_rsvd_status & ST_RESERVE | ST_PRESERVE_RESERVE) &&
16924                     (errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16925                     SCMD_PERSISTENT_RESERVE_OUT) ||
16926                     (errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16927                     SCMD_PERSISTENT_RESERVE_IN)) {
16928                         st_recov_ret(un, errinfo, COMMAND_DONE_EACCES);
16929                         return;
16930                 }
16931 
16932                 /*
16933                  * If scsi II lost reserve try and get it back.
16934                  */
16935                 if ((((un->un_rsvd_status &
16936                     (ST_LOST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
16937                     ST_LOST_RESERVE)) &&
16938                     (errinfo->ei_failed_pkt.pkt_cdbp[0] != SCMD_RELEASE)) {
16939                         rval = st_reserve_release(un, ST_RESERVE,
16940                             st_uscsi_rcmd);
16941                         if (rval != 0) {
16942                                 if (st_take_ownership(un, st_uscsi_rcmd) != 0) {
16943                                         st_recov_ret(un, errinfo,
16944                                             COMMAND_DONE_EACCES);
16945                                         return;
16946                                 }
16947                         }
16948                         un->un_rsvd_status |= ST_RESERVE;
16949                         un->un_rsvd_status &= ~(ST_RELEASE | ST_LOST_RESERVE |
16950                             ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
16951                 }
16952                 rval = st_make_sure_mode_data_is_correct(un, st_uscsi_rcmd);
16953                 if (rval) {
16954                         st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16955                         return;
16956                 }
16957                 break;
16958         case DEVICE_TAMPER:
16959                 /*
16960                  * Check if the ASC/ASCQ says mode data has changed.
16961                  */
16962                 if ((errinfo->ei_failing_status.sts_sensedata.es_add_code ==
16963                     0x2a) &&
16964                     (errinfo->ei_failing_status.sts_sensedata.es_qual_code ==
16965                     0x01)) {
16966                         /*
16967                          * See if mode sense changed.
16968                          */
16969                         rval = st_make_sure_mode_data_is_correct(un,
16970                             st_uscsi_rcmd);
16971                         if (rval) {
16972                                 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16973                                 return;
16974                         }
16975                 }
16976                 /*
16977                  * if we have a media id and its not bogus.
16978                  * Check to see if it the same.
16979                  */
16980                 if (un->un_media_id != NULL && un->un_media_id != bogusID) {
16981                         rval = st_get_media_identification(un, st_uscsi_rcmd);
16982                         if (rval == ESPIPE) {
16983                                 st_recov_ret(un, errinfo, COMMAND_DONE_EACCES);
16984                                 return;
16985                         }
16986                 }
16987                 break;
16988         default:
16989                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
16990                     "Unhandled error type %s in st_recover() 0x%x\n",
16991                     errstatenames[errinfo->ei_error_type], com);
16992         }
16993 
16994         /*
16995          * if command is retriable retry it.
16996          * Special case here. The command attribute for SCMD_REQUEST_SENSE
16997          * does not say that it is retriable. That because if you reissue a
16998          * request sense and the target responds the sense data will have
16999          * been consumed and no long be valid. If we get a busy status on
17000          * request sense while the state is ST_STATE_SENSING this will
17001          * reissue that pkt.
17002          *
17003          * XXX If this request sense gets sent to a different port then
17004          * the original command that failed was sent on it will not get
17005          * valid sense data for that command.
17006          */
17007         if (rcv->cmd_attrib->retriable || un->un_rqs_bp == bp) {
17008                 status = st_recover_reissue_pkt(un, &errinfo->ei_failed_pkt);
17009 
17010         /*
17011          * if drive doesn't support read position we are done
17012          */
17013         } else if (un->un_read_pos_type == NO_POS) {
17014                 status = COMMAND_DONE_ERROR;
17015         /*
17016          * If this command results in a changed tape position,
17017          * lets see where we are.
17018          */
17019         } else if (rcv->cmd_attrib->chg_tape_pos) {
17020                 /*
17021                  * XXX May be a reason to choose a different type here.
17022                  * Long format has file position information.
17023                  * Short and Extended have information about whats
17024                  * in the buffer. St's positioning assumes in the buffer
17025                  * to be the same as on tape.
17026                  */
17027                 rval = st_compare_expected_position(un, errinfo,
17028                     rcv->cmd_attrib, &cur_pos);
17029                 if (rval == 0) {
17030                         status = COMMAND_DONE;
17031                 } else if (rval == EAGAIN) {
17032                         status = st_recover_reissue_pkt(un,
17033                             &errinfo->ei_failed_pkt);
17034                 } else {
17035                         status = COMMAND_DONE_ERROR;
17036                 }
17037         } else {
17038                 ASSERT(0);
17039         }
17040 
17041         st_recov_ret(un, errinfo, status);
17042 }
17043 
17044 static void
17045 st_recov_cb(struct scsi_pkt *pkt)
17046 {
17047         struct scsi_tape *un;
17048         struct buf *bp;
17049         recov_info *rcv;
17050         errstate action = COMMAND_DONE_ERROR;
17051         int timout = ST_TRAN_BUSY_TIMEOUT; /* short (default) timeout */
17052 
17053         /*
17054          * Get the buf from the packet.
17055          */
17056         rcv = pkt->pkt_private;
17057         ASSERT(rcv->privatelen == sizeof (recov_info));
17058         bp = rcv->cmd_bp;
17059 
17060         /*
17061          * get the unit from the buf.
17062          */
17063         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
17064         ASSERT(un != NULL);
17065 
17066         ST_FUNC(ST_DEVINFO, st_recov_cb);
17067 
17068         mutex_enter(ST_MUTEX);
17069 
17070         ASSERT(bp == un->un_recov_buf);
17071 
17072 
17073         switch (pkt->pkt_reason) {
17074         case CMD_CMPLT:
17075                 if (un->un_arq_enabled && pkt->pkt_state & STATE_ARQ_DONE) {
17076                         action = st_handle_autosense(un, bp, &rcv->pos);
17077                 } else  if ((SCBP(pkt)->sts_busy) ||
17078                     (SCBP(pkt)->sts_chk) ||
17079                     (SCBP(pkt)->sts_vu7)) {
17080                         action = st_check_error(un, pkt);
17081                 } else {
17082                         action = COMMAND_DONE;
17083                 }
17084                 break;
17085         case CMD_TIMEOUT:
17086                 action = COMMAND_TIMEOUT;
17087                 break;
17088         case CMD_TRAN_ERR:
17089                 action = QUE_COMMAND;
17090                 break;
17091         case CMD_DEV_GONE:
17092                 if (un->un_multipath)
17093                         action = PATH_FAILED;
17094                 else
17095                         action = COMMAND_DONE_ERROR;
17096                 break;
17097         default:
17098                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
17099                     "pkt_reason not handled yet %s",
17100                     scsi_rname(pkt->pkt_reason));
17101                 action = COMMAND_DONE_ERROR;
17102         }
17103 
17104         /*
17105          * check for undetected path failover.
17106          */
17107         if (un->un_multipath) {
17108                 if (scsi_pkt_allocated_correctly(pkt) &&
17109                     (un->un_last_path_instance != pkt->pkt_path_instance)) {
17110                         if (un->un_state > ST_STATE_OPENING) {
17111                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17112                                     "Failover detected in recovery, action is "
17113                                     "%s\n", errstatenames[action]);
17114                         }
17115                         un->un_last_path_instance = pkt->pkt_path_instance;
17116                 }
17117         }
17118 
17119         ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
17120             "Recovery call back got %s status on %s\n",
17121             errstatenames[action], st_print_scsi_cmd(pkt->pkt_cdbp[0]));
17122 
17123         switch (action) {
17124         case COMMAND_DONE:
17125                 break;
17126 
17127         case COMMAND_DONE_EACCES:
17128                 bioerror(bp, EACCES);
17129                 break;
17130 
17131         case COMMAND_DONE_ERROR_RECOVERED: /* XXX maybe wrong */
17132                 ASSERT(0);
17133                 break;
17134 
17135         case COMMAND_TIMEOUT:
17136         case COMMAND_DONE_ERROR:
17137                 bioerror(bp, EIO);
17138                 break;
17139 
17140         case DEVICE_RESET:
17141         case QUE_BUSY_COMMAND:
17142         case PATH_FAILED:
17143                 /* longish timeout */
17144                 timout = ST_STATUS_BUSY_TIMEOUT;
17145                 /* FALLTHRU */
17146         case QUE_COMMAND:
17147         case DEVICE_TAMPER:
17148         case ATTEMPT_RETRY:
17149                 /*
17150                  * let st_handle_intr_busy put this bp back on waitq and make
17151                  * checks to see if it is ok to requeue the command.
17152                  */
17153                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
17154 
17155                 /*
17156                  * Save the throttle before setting up the timeout
17157                  */
17158                 if (un->un_throttle) {
17159                         un->un_last_throttle = un->un_throttle;
17160                 }
17161                 mutex_exit(ST_MUTEX);
17162                 if (st_handle_intr_busy(un, bp, timout) == 0) {
17163                         return;         /* timeout is setup again */
17164                 }
17165                 mutex_enter(ST_MUTEX);
17166                 un->un_pos.pmode = invalid;
17167                 un->un_err_resid = bp->b_resid = bp->b_bcount;
17168                 st_bioerror(bp, EIO);
17169                 st_set_pe_flag(un);
17170                 break;
17171 
17172         default:
17173                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
17174                     "Unhandled recovery state 0x%x\n", action);
17175                 un->un_pos.pmode = invalid;
17176                 un->un_err_resid = bp->b_resid = bp->b_bcount;
17177                 st_bioerror(bp, EIO);
17178                 st_set_pe_flag(un);
17179                 break;
17180         }
17181 
17182         st_done_and_mutex_exit(un, bp);
17183 }
17184 
17185 static int
17186 st_rcmd(struct scsi_tape *un, int com, int64_t count, int wait)
17187 {
17188         struct buf *bp;
17189         int err;
17190 
17191         ST_FUNC(ST_DEVINFO, st_rcmd);
17192 
17193         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
17194             "st_rcmd(un = 0x%p, com = 0x%x, count = %"PRIx64", wait = %d)\n",
17195             (void *)un, com, count, wait);
17196 
17197         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
17198         ASSERT(mutex_owned(ST_MUTEX));
17199 
17200 #ifdef STDEBUG
17201         if ((st_debug & 0x7)) {
17202                 st_debug_cmds(un, com, count, wait);
17203         }
17204 #endif
17205 
17206         while (un->un_recov_buf_busy)
17207                 cv_wait(&un->un_recov_buf_cv, ST_MUTEX);
17208         un->un_recov_buf_busy = 1;
17209 
17210         bp = un->un_recov_buf;
17211         bzero(bp, sizeof (buf_t));
17212 
17213         bp->b_flags = (wait) ? B_BUSY : B_BUSY|B_ASYNC;
17214 
17215         err = st_setup_cmd(un, bp, com, count);
17216 
17217         un->un_recov_buf_busy = 0;
17218 
17219         cv_signal(&un->un_recov_buf_cv);
17220 
17221         return (err);
17222 }
17223 
17224 /* args used */
17225 static int
17226 st_uscsi_rcmd(struct scsi_tape *un, struct uscsi_cmd *ucmd, int flag)
17227 {
17228         int rval;
17229         buf_t *bp;
17230 
17231         ST_FUNC(ST_DEVINFO, st_uscsi_rcmd);
17232         ASSERT(flag == FKIOCTL);
17233 
17234         /*
17235          * Get buffer resources...
17236          */
17237         while (un->un_recov_buf_busy)
17238                 cv_wait(&un->un_recov_buf_cv, ST_MUTEX);
17239         un->un_recov_buf_busy = 1;
17240 
17241         bp = un->un_recov_buf;
17242         bzero(bp, sizeof (buf_t));
17243 
17244         bp->b_forw = (struct buf *)(uintptr_t)ucmd->uscsi_cdb[0];
17245         bp->b_back = (struct buf *)ucmd;
17246 
17247         mutex_exit(ST_MUTEX);
17248         rval = scsi_uscsi_handle_cmd(un->un_dev, UIO_SYSSPACE, ucmd,
17249             st_strategy, bp, NULL);
17250         mutex_enter(ST_MUTEX);
17251 
17252         ucmd->uscsi_resid = bp->b_resid;
17253 
17254         /*
17255          * Free resources
17256          */
17257         un->un_recov_buf_busy = 0;
17258         cv_signal(&un->un_recov_buf_cv);
17259 
17260         return (rval);
17261 }
17262 
17263 /*
17264  * Add data to scsi_pkt to help know what to do if the command fails.
17265  */
17266 static void
17267 st_add_recovery_info_to_pkt(struct scsi_tape *un, buf_t *bp,
17268     struct scsi_pkt *pkt)
17269 {
17270         uint64_t count;
17271         recov_info *rinfo = (recov_info *)pkt->pkt_private;
17272 
17273         ST_FUNC(ST_DEVINFO, st_add_recovery_info_to_pkt);
17274 
17275         ASSERT(rinfo->privatelen == sizeof (pkt_info) ||
17276             rinfo->privatelen == sizeof (recov_info));
17277 
17278         SET_BP_PKT(bp, pkt);
17279         rinfo->cmd_bp = bp;
17280 
17281         if (rinfo->privatelen != sizeof (recov_info)) {
17282                 return;
17283         }
17284 
17285         rinfo->cmd_bp = bp;
17286 
17287         rinfo->cmd_attrib = NULL;
17288 
17289         /*
17290          * lookup the command attributes and add them to the recovery info.
17291          */
17292         rinfo->cmd_attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
17293 
17294         ASSERT(rinfo->cmd_attrib);
17295 
17296         /*
17297          * For commands that there is no way to figure the expected position
17298          * once completed, we save the position the command was started from
17299          * so that if they fail we can position back and try again.
17300          * This has already been done in st_cmd() or st_iscsi_cmd().
17301          */
17302         if (rinfo->cmd_attrib->recov_pos_type == POS_STARTING) {
17303                 /* save current position as the starting position. */
17304                 COPY_POS(&rinfo->pos, &un->un_pos);
17305                 un->un_running.pmode = invalid;
17306                 return;
17307         }
17308 
17309         /*
17310          * Don't want to update the running position for recovery.
17311          */
17312         if (bp == un->un_recov_buf) {
17313                 rinfo->pos.pmode = un->un_running.pmode;
17314                 return;
17315         }
17316         /*
17317          * If running position is invalid copy the current position.
17318          * Running being set invalid means we are not in a read, write
17319          * or write filemark sequence.
17320          * We'll copy the current position and start from there.
17321          */
17322         if (un->un_running.pmode == invalid) {
17323                 COPY_POS(&un->un_running, &un->un_pos);
17324                 COPY_POS(&rinfo->pos, &un->un_running);
17325         } else {
17326                 COPY_POS(&rinfo->pos, &un->un_running);
17327                 if (rinfo->pos.pmode == legacy) {
17328                         /*
17329                          * Always should be more logical blocks then
17330                          * data blocks and files marks.
17331                          */
17332                         ASSERT((rinfo->pos.blkno >= 0) ?
17333                             rinfo->pos.lgclblkno >=
17334                             (rinfo->pos.blkno + rinfo->pos.fileno) : 1);
17335                 }
17336         }
17337 
17338         /*
17339          * If the command is not expected to change the drive position
17340          * then the running position should be the expected position.
17341          */
17342         if (rinfo->cmd_attrib->chg_tape_pos == 0) {
17343                 ASSERT(rinfo->cmd_attrib->chg_tape_direction == DIR_NONE);
17344                 return;
17345         }
17346 
17347         if (rinfo->cmd_attrib->explicit_cmd_set) {
17348                 ASSERT(rinfo->pos.pmode != invalid);
17349                 ASSERT(rinfo->cmd_attrib->get_cnt);
17350                 count = rinfo->cmd_attrib->get_cnt(pkt->pkt_cdbp);
17351                 /*
17352                  * This is a user generated CDB.
17353                  */
17354                 if (bp == un->un_sbufp) {
17355                         uint64_t lbn;
17356 
17357                         lbn = rinfo->cmd_attrib->get_lba(pkt->pkt_cdbp);
17358 
17359                         /*
17360                          * See if this CDB will generate a locate or change
17361                          * partition.
17362                          */
17363                         if ((lbn != un->un_running.lgclblkno) ||
17364                             (pkt->pkt_cdbp[3] != un->un_running.partition)) {
17365                                 rinfo->pos.partition = pkt->pkt_cdbp[3];
17366                                 rinfo->pos.pmode = logical;
17367                                 rinfo->pos.lgclblkno = lbn;
17368                                 un->un_running.partition = pkt->pkt_cdbp[3];
17369                                 un->un_running.pmode = logical;
17370                                 un->un_running.lgclblkno = lbn;
17371                         }
17372                 } else {
17373                         uint64_t lbn = un->un_running.lgclblkno;
17374 
17375                         pkt->pkt_cdbp[3]  = (uchar_t)un->un_running.partition;
17376 
17377                         pkt->pkt_cdbp[4]  = (uchar_t)(lbn >> 56);
17378                         pkt->pkt_cdbp[5]  = (uchar_t)(lbn >> 48);
17379                         pkt->pkt_cdbp[6]  = (uchar_t)(lbn >> 40);
17380                         pkt->pkt_cdbp[7]  = (uchar_t)(lbn >> 32);
17381                         pkt->pkt_cdbp[8]  = (uchar_t)(lbn >> 24);
17382                         pkt->pkt_cdbp[9]  = (uchar_t)(lbn >> 16);
17383                         pkt->pkt_cdbp[10] = (uchar_t)(lbn >> 8);
17384                         pkt->pkt_cdbp[11] = (uchar_t)(lbn);
17385                 }
17386                 rinfo->pos.lgclblkno += count;
17387                 rinfo->pos.blkno += count;
17388                 un->un_running.lgclblkno += count;
17389                 return;
17390         }
17391 
17392         if (rinfo->cmd_attrib->chg_tape_pos) {
17393 
17394                 /* should not have got an invalid position from running. */
17395                 if (un->un_mediastate == MTIO_INSERTED) {
17396                         ASSERT(rinfo->pos.pmode != invalid);
17397                 }
17398 
17399                 /* should have either a get count or or get lba function */
17400                 ASSERT(rinfo->cmd_attrib->get_cnt != NULL ||
17401                     rinfo->cmd_attrib->get_lba != NULL);
17402 
17403                 /* only explicit commands have both and they're handled above */
17404                 ASSERT(!(rinfo->cmd_attrib->get_cnt != NULL &&
17405                     rinfo->cmd_attrib->get_lba != NULL));
17406 
17407                 /* if it has a get count function */
17408                 if (rinfo->cmd_attrib->get_cnt != NULL) {
17409                         count = rinfo->cmd_attrib->get_cnt(pkt->pkt_cdbp);
17410                         if (count == 0) {
17411                                 return;
17412                         }
17413                         /*
17414                          * Changes position but doesn't transfer data.
17415                          * i.e. rewind, write_file_mark and load.
17416                          */
17417                         if (rinfo->cmd_attrib->transfers_data == TRAN_NONE) {
17418                                 switch (rinfo->cmd_attrib->chg_tape_direction) {
17419                                 case DIR_NONE: /* Erase */
17420                                         ASSERT(rinfo->cmd_attrib->cmd ==
17421                                             SCMD_ERASE);
17422                                         break;
17423                                 case DIR_FORW: /* write_file_mark */
17424                                         rinfo->pos.fileno += count;
17425                                         rinfo->pos.lgclblkno += count;
17426                                         rinfo->pos.blkno = 0;
17427                                         un->un_running.fileno += count;
17428                                         un->un_running.lgclblkno += count;
17429                                         un->un_running.blkno = 0;
17430                                         break;
17431                                 case DIR_REVC: /* rewind */
17432                                         rinfo->pos.fileno = 0;
17433                                         rinfo->pos.lgclblkno = 0;
17434                                         rinfo->pos.blkno = 0;
17435                                         rinfo->pos.eof = ST_NO_EOF;
17436                                         rinfo->pos.pmode = legacy;
17437                                         un->un_running.fileno = 0;
17438                                         un->un_running.lgclblkno = 0;
17439                                         un->un_running.blkno = 0;
17440                                         un->un_running.eof = ST_NO_EOF;
17441                                         if (un->un_running.pmode != legacy)
17442                                                 un->un_running.pmode = legacy;
17443                                         break;
17444                                 case DIR_EITH: /* Load unload */
17445                                         ASSERT(rinfo->cmd_attrib->cmd ==
17446                                             SCMD_LOAD);
17447                                         switch (count & (LD_LOAD | LD_RETEN |
17448                                             LD_RETEN | LD_HOLD)) {
17449                                         case LD_UNLOAD:
17450                                         case LD_RETEN:
17451                                         case LD_HOLD:
17452                                         case LD_LOAD | LD_HOLD:
17453                                         case LD_EOT | LD_HOLD:
17454                                         case LD_RETEN | LD_HOLD:
17455                                                 rinfo->pos.pmode = invalid;
17456                                                 un->un_running.pmode = invalid;
17457                                                 break;
17458                                         case LD_EOT:
17459                                         case LD_LOAD | LD_EOT:
17460                                                 rinfo->pos.eof = ST_EOT;
17461                                                 rinfo->pos.pmode = invalid;
17462                                                 un->un_running.eof = ST_EOT;
17463                                                 un->un_running.pmode = invalid;
17464                                                 break;
17465                                         case LD_LOAD:
17466                                         case LD_RETEN | LD_LOAD:
17467                                                 rinfo->pos.fileno = 0;
17468                                                 rinfo->pos.lgclblkno = 0;
17469                                                 rinfo->pos.blkno = 0;
17470                                                 rinfo->pos.eof = ST_NO_EOF;
17471                                                 rinfo->pos.pmode = legacy;
17472                                                 un->un_running.fileno = 0;
17473                                                 un->un_running.lgclblkno = 0;
17474                                                 un->un_running.blkno = 0;
17475                                                 un->un_running.eof = ST_NO_EOF;
17476                                                 break;
17477                                         default:
17478                                                 ASSERT(0);
17479                                         }
17480                                         break;
17481                                 default:
17482                                         ASSERT(0);
17483                                         break;
17484                                 }
17485                         } else {
17486                                 /*
17487                                  * Changes position and does transfer data.
17488                                  * i.e. read or write.
17489                                  */
17490                                 switch (rinfo->cmd_attrib->chg_tape_direction) {
17491                                 case DIR_FORW:
17492                                         rinfo->pos.lgclblkno += count;
17493                                         rinfo->pos.blkno += count;
17494                                         un->un_running.lgclblkno += count;
17495                                         un->un_running.blkno += count;
17496                                         break;
17497                                 case DIR_REVC:
17498                                         rinfo->pos.lgclblkno -= count;
17499                                         rinfo->pos.blkno -= count;
17500                                         un->un_running.lgclblkno -= count;
17501                                         un->un_running.blkno -= count;
17502                                         break;
17503                                 default:
17504                                         ASSERT(0);
17505                                         break;
17506                                 }
17507                         }
17508                 } else if (rinfo->cmd_attrib->get_lba != NULL) {
17509                         /* Have a get LBA fuction. i.e. Locate */
17510                         ASSERT(rinfo->cmd_attrib->chg_tape_direction ==
17511                             DIR_EITH);
17512                         count = rinfo->cmd_attrib->get_lba(pkt->pkt_cdbp);
17513                         un->un_running.lgclblkno = count;
17514                         un->un_running.blkno = 0;
17515                         un->un_running.fileno = 0;
17516                         un->un_running.pmode = logical;
17517                         rinfo->pos.lgclblkno = count;
17518                         rinfo->pos.pmode = invalid;
17519                 } else {
17520                         ASSERT(0);
17521                 }
17522                 return;
17523         }
17524 
17525         ST_CDB(ST_DEVINFO, "Unhanded CDB for position prediction",
17526             (char *)pkt->pkt_cdbp);
17527 
17528 }
17529 
17530 static int
17531 st_make_sure_mode_data_is_correct(struct scsi_tape *un, ubufunc_t ubf)
17532 {
17533         int rval;
17534 
17535         ST_FUNC(ST_DEVINFO, st_make_sure_mode_data_is_correct);
17536 
17537         /*
17538          * check to see if mode data has changed.
17539          */
17540         rval = st_check_mode_for_change(un, ubf);
17541         if (rval) {
17542                 rval = st_gen_mode_select(un, ubf, un->un_mspl,
17543                     sizeof (struct seq_mode));
17544         }
17545         if (un->un_tlr_flag != TLR_NOT_SUPPORTED) {
17546                 rval |= st_set_target_TLR_mode(un, ubf);
17547         }
17548         return (rval);
17549 }
17550 
17551 static int
17552 st_check_mode_for_change(struct scsi_tape *un, ubufunc_t ubf)
17553 {
17554         struct seq_mode *current;
17555         int rval;
17556         int i;
17557         caddr_t this;
17558         caddr_t that;
17559 
17560         ST_FUNC(ST_DEVINFO, st_check_mode_for_change);
17561 
17562         /* recovery called with mode tamper before mode selection */
17563         if (un->un_comp_page == (ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE)) {
17564                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17565                     "Mode Select not done yet");
17566                 return (0);
17567         }
17568 
17569         current = kmem_zalloc(sizeof (struct seq_mode), KM_SLEEP);
17570 
17571         rval = st_gen_mode_sense(un, ubf, un->un_comp_page, current,
17572             sizeof (struct seq_mode));
17573         if (rval != 0) {
17574                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17575                     "Mode Sense for mode verification failed");
17576                 kmem_free(current, sizeof (struct seq_mode));
17577                 return (rval);
17578         }
17579 
17580         this = (caddr_t)current;
17581         that = (caddr_t)un->un_mspl;
17582 
17583         rval = bcmp(this, that, sizeof (struct seq_mode));
17584         if (rval == 0) {
17585                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17586                     "Found no changes in mode data");
17587         }
17588 #ifdef STDEBUG
17589         else {
17590                 for (i = 1; i < sizeof (struct seq_mode); i++) {
17591                         if (this[i] != that[i]) {
17592                                 ST_RECOV(ST_DEVINFO, st_label, CE_CONT,
17593                                     "sense data changed at byte %d was "
17594                                     "0x%x now 0x%x", i,
17595                                     (uchar_t)that[i], (uchar_t)this[i]);
17596                         }
17597                 }
17598         }
17599 #endif
17600         kmem_free(current, sizeof (struct seq_mode));
17601 
17602         return (rval);
17603 }
17604 
17605 static int
17606 st_test_path_to_device(struct scsi_tape *un)
17607 {
17608         int rval = 0;
17609         int limit = st_retry_count;
17610 
17611         ST_FUNC(ST_DEVINFO, st_test_path_to_device);
17612 
17613         /*
17614          * XXX Newer drives may not RESEVATION CONFLICT a TUR.
17615          */
17616         do {
17617                 if (rval != 0) {
17618                         mutex_exit(ST_MUTEX);
17619                         delay(drv_sectohz(1));
17620                         mutex_enter(ST_MUTEX);
17621                 }
17622                 rval = st_rcmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
17623                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17624                     "ping TUR returned 0x%x", rval);
17625                 limit--;
17626         } while (((rval == EACCES) || (rval == EBUSY)) && limit);
17627 
17628         if (un->un_status == KEY_NOT_READY || un->un_mediastate == MTIO_EJECTED)
17629                 rval = 0;
17630 
17631         return (rval);
17632 }
17633 
17634 /*
17635  * Does read position using recov_buf and doesn't update un_pos.
17636  * Does what ever kind of read position you want.
17637  */
17638 static int
17639 st_recovery_read_pos(struct scsi_tape *un, read_p_types type,
17640     read_pos_data_t *raw)
17641 {
17642         int rval;
17643         struct uscsi_cmd cmd;
17644         struct scsi_arq_status status;
17645         char cdb[CDB_GROUP1];
17646 
17647         ST_FUNC(ST_DEVINFO, st_recovery_read_pos);
17648         bzero(&cmd, sizeof (cmd));
17649 
17650         cdb[0] = SCMD_READ_POSITION;
17651         cdb[1] = type;
17652         cdb[2] = 0;
17653         cdb[3] = 0;
17654         cdb[4] = 0;
17655         cdb[5] = 0;
17656         cdb[6] = 0;
17657         cdb[7] = 0;
17658         cdb[8] = (type == EXT_POS) ? 28 : 0;
17659         cdb[9] = 0;
17660 
17661         cmd.uscsi_flags = USCSI_READ | USCSI_RQENABLE;
17662         cmd.uscsi_timeout = un->un_dp->non_motion_timeout;
17663         cmd.uscsi_cdb = cdb;
17664         cmd.uscsi_cdblen = sizeof (cdb);
17665         cmd.uscsi_rqlen = sizeof (status);
17666         cmd.uscsi_rqbuf = (caddr_t)&status;
17667         cmd.uscsi_bufaddr = (caddr_t)raw;
17668         switch (type) {
17669         case SHORT_POS:
17670                 cmd.uscsi_buflen = sizeof (tape_position_t);
17671                 break;
17672         case LONG_POS:
17673                 cmd.uscsi_buflen = sizeof (tape_position_long_t);
17674                 break;
17675         case EXT_POS:
17676                 cmd.uscsi_buflen = sizeof (tape_position_ext_t);
17677                 break;
17678         default:
17679                 ASSERT(0);
17680         }
17681 
17682         rval = st_uscsi_rcmd(un, &cmd, FKIOCTL);
17683         if (cmd.uscsi_status) {
17684                 rval = EIO;
17685         }
17686         return (rval);
17687 }
17688 
17689 static int
17690 st_recovery_get_position(struct scsi_tape *un, tapepos_t *read,
17691     read_pos_data_t *raw)
17692 {
17693         int rval;
17694         read_p_types type = un->un_read_pos_type;
17695 
17696         ST_FUNC(ST_DEVINFO, st_recovery_get_position);
17697 
17698         do {
17699                 rval = st_recovery_read_pos(un, type, raw);
17700                 if (rval != 0) {
17701                         switch (type) {
17702                         case SHORT_POS:
17703                                 type = NO_POS;
17704                                 break;
17705 
17706                         case LONG_POS:
17707                                 type = EXT_POS;
17708                                 break;
17709 
17710                         case EXT_POS:
17711                                 type = SHORT_POS;
17712                                 break;
17713 
17714                         default:
17715                                 type = LONG_POS;
17716                                 break;
17717 
17718                         }
17719                 } else {
17720                         if (type != un->un_read_pos_type) {
17721                                 un->un_read_pos_type = type;
17722                         }
17723                         break;
17724                 }
17725         } while (type != NO_POS);
17726 
17727         if (rval == 0) {
17728                 rval = st_interpret_read_pos(un, read, type,
17729                     sizeof (read_pos_data_t), (caddr_t)raw, 1);
17730         }
17731         return (rval);
17732 }
17733 
17734 /*
17735  * based on the command do we retry, continue or give up?
17736  * possable return values?
17737  *      zero do nothing looks fine.
17738  *      EAGAIN retry.
17739  *      EIO failed makes no sense.
17740  */
17741 static int
17742 st_compare_expected_position(struct scsi_tape *un, st_err_info *ei,
17743     cmd_attribute const * cmd_att, tapepos_t *read)
17744 {
17745         int rval;
17746         read_pos_data_t *readp_datap;
17747 
17748         ST_FUNC(ST_DEVINFO, st_compare_expected_position);
17749 
17750         ASSERT(un != NULL);
17751         ASSERT(ei != NULL);
17752         ASSERT(read != NULL);
17753         ASSERT(cmd_att->chg_tape_pos);
17754 
17755         COPY_POS(read, &ei->ei_expected_pos);
17756 
17757         readp_datap = kmem_zalloc(sizeof (read_pos_data_t), KM_SLEEP);
17758 
17759         rval = st_recovery_get_position(un, read, readp_datap);
17760 
17761         kmem_free(readp_datap, sizeof (read_pos_data_t));
17762 
17763         if (rval != 0) {
17764                 return (EIO);
17765         }
17766 
17767         ST_POS(ST_DEVINFO, "st_compare_expected_position", read);
17768 
17769         if ((read->pmode == invalid) ||
17770             (ei->ei_expected_pos.pmode == invalid)) {
17771                 return (EIO);
17772         }
17773 
17774         /*
17775          * Command that changes tape position and have an expected position
17776          * if it were to chave completed sucessfully.
17777          */
17778         if (cmd_att->recov_pos_type == POS_EXPECTED) {
17779                 uint32_t count;
17780                 int64_t difference;
17781                 uchar_t reposition = 0;
17782 
17783                 ASSERT(cmd_att->get_cnt);
17784                 count = cmd_att->get_cnt(ei->ei_failed_pkt.pkt_cdbp);
17785 
17786                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17787                     "Got count from CDB and it was %d\n", count);
17788 
17789                 /*
17790                  * At expected?
17791                  */
17792                 if (read->lgclblkno == ei->ei_expected_pos.lgclblkno) {
17793                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17794                             "Found drive to be at expected position\n");
17795 
17796                         /*
17797                          * If the command should move tape and it got a busy
17798                          * it shouldn't be in the expected position.
17799                          */
17800                         if (ei->ei_failing_status.sts_status.sts_busy != 0) {
17801                                 reposition = 1;
17802 
17803                         /*
17804                          * If the command doesn't transfer data should be good.
17805                          */
17806                         } else if (cmd_att->transfers_data == TRAN_NONE) {
17807                                 return (0); /* Good */
17808 
17809                         /*
17810                          * Command transfers data, should have done so.
17811                          */
17812                         } else if (ei->ei_failed_pkt.pkt_state &
17813                             STATE_XFERRED_DATA) {
17814                                 return (0); /* Good */
17815                         } else {
17816                                 reposition = 1;
17817                         }
17818                 }
17819 
17820                 if (cmd_att->chg_tape_direction == DIR_FORW) {
17821                         difference =
17822                             ei->ei_expected_pos.lgclblkno - read->lgclblkno;
17823 
17824                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17825                             "difference between expected and actual is %"
17826                             PRId64"\n", difference);
17827                         if (count == difference && reposition == 0) {
17828                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17829                                     "Found failed FORW command, retrying\n");
17830                                 return (EAGAIN);
17831                         }
17832 
17833                         /*
17834                          * If rewound or somewhere between the starting position
17835                          * and the expected position (partial read or write).
17836                          * Locate to the starting position and try the whole
17837                          * thing over again.
17838                          */
17839                         if ((read->lgclblkno == 0) ||
17840                             ((difference > 0) && (difference < count))) {
17841                                 rval = st_logical_block_locate(un,
17842                                     st_uscsi_rcmd, read,
17843                                     ei->ei_expected_pos.lgclblkno - count,
17844                                     ei->ei_expected_pos.partition);
17845                                 if (rval == 0) {
17846                                         ST_RECOV(ST_DEVINFO, st_label,
17847                                             CE_NOTE, "reestablished FORW"
17848                                             " command retrying\n");
17849                                         return (EAGAIN);
17850                                 }
17851                         /*
17852                          * This handles flushed read ahead on the drive or
17853                          * an aborted read that presents as a busy and advanced
17854                          * the tape position.
17855                          */
17856                         } else if ((cmd_att->transfers_data == TRAN_READ) &&
17857                             ((difference < 0) || (reposition == 1))) {
17858                                 rval = st_logical_block_locate(un,
17859                                     st_uscsi_rcmd, read,
17860                                     ei->ei_expected_pos.lgclblkno - count,
17861                                     ei->ei_expected_pos.partition);
17862                                 if (rval == 0) {
17863                                         ST_RECOV(ST_DEVINFO, st_label,
17864                                             CE_NOTE, "reestablished FORW"
17865                                             " read command retrying\n");
17866                                         return (EAGAIN);
17867                                 }
17868                         /*
17869                          * XXX swag seeing difference of 2 on write filemark.
17870                          * If the space to the starting position works on a
17871                          * write that means the previous write made it to tape.
17872                          * If not we lost data and have to give up.
17873                          *
17874                          * The plot thickens. Now I am attempting to cover a
17875                          * count of 1 and a differance of 2 on a write.
17876                          */
17877                         } else if ((difference > count) || (reposition == 1)) {
17878                                 rval = st_logical_block_locate(un,
17879                                     st_uscsi_rcmd, read,
17880                                     ei->ei_expected_pos.lgclblkno - count,
17881                                     ei->ei_expected_pos.partition);
17882                                 if (rval == 0) {
17883                                         ST_RECOV(ST_DEVINFO, st_label,
17884                                             CE_NOTE, "reestablished FORW"
17885                                             " write command retrying\n");
17886                                         return (EAGAIN);
17887                                 }
17888                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17889                                     "Seek to block %"PRId64" returned %d\n",
17890                                     ei->ei_expected_pos.lgclblkno - count,
17891                                     rval);
17892                         } else {
17893                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17894                                     "Not expected transfers_data = %d "
17895                                     "difference = %"PRId64,
17896                                     cmd_att->transfers_data, difference);
17897                         }
17898 
17899                         return (EIO);
17900 
17901                 } else if (cmd_att->chg_tape_direction == DIR_REVC) {
17902                         /* Don't think we can write backwards */
17903                         ASSERT(cmd_att->transfers_data != TRAN_WRTE);
17904                         difference =
17905                             read->lgclblkno - ei->ei_expected_pos.lgclblkno;
17906                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17907                             "difference between expected and actual is %"
17908                             PRId64"\n", difference);
17909                         if (count == difference && reposition == 0) {
17910                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17911                                     "Found failed REVC command, retrying\n");
17912                                 return (EAGAIN);
17913                         }
17914                         if ((read->lgclblkno == 0) ||
17915                             ((difference > 0) && (difference < count))) {
17916                                 rval = st_logical_block_locate(un,
17917                                     st_uscsi_rcmd, read,
17918                                     ei->ei_expected_pos.lgclblkno + count,
17919                                     ei->ei_expected_pos.partition);
17920                                 if (rval == 0) {
17921                                         ST_RECOV(ST_DEVINFO, st_label,
17922                                             CE_NOTE, "reestablished REVC"
17923                                             " command retrying\n");
17924                                         return (EAGAIN);
17925                                 }
17926                         /* This handles read ahead in reverse direction */
17927                         } else if ((cmd_att->transfers_data == TRAN_READ) &&
17928                             (difference < 0) || (reposition == 1)) {
17929                                 rval = st_logical_block_locate(un,
17930                                     st_uscsi_rcmd, read,
17931                                     ei->ei_expected_pos.lgclblkno - count,
17932                                     ei->ei_expected_pos.partition);
17933                                 if (rval == 0) {
17934                                         ST_RECOV(ST_DEVINFO, st_label,
17935                                             CE_NOTE, "reestablished REVC"
17936                                             " read command retrying\n");
17937                                         return (EAGAIN);
17938                                 }
17939                         } else {
17940                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17941                                     "Not expected transfers_data = %d "
17942                                     "difference = %"PRId64,
17943                                     cmd_att->transfers_data, difference);
17944                         }
17945                         return (EIO);
17946 
17947                 } else {
17948                         /*
17949                          * Commands that change tape position either
17950                          * direction or don't change position should not
17951                          * get here.
17952                          */
17953                         ASSERT(0);
17954                 }
17955                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17956                     "Didn't find a recoverable position, Failing\n");
17957 
17958         /*
17959          * Command that changes tape position and can only be recovered
17960          * by going back to the point of origin and retrying.
17961          *
17962          * Example SCMD_SPACE.
17963          */
17964         } else if (cmd_att->recov_pos_type == POS_STARTING) {
17965                 /*
17966                  * This type of command stores the starting position.
17967                  * If the read position is the starting position,
17968                  * reissue the command.
17969                  */
17970                 if (ei->ei_expected_pos.lgclblkno == read->lgclblkno) {
17971                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17972                             "Found Space command at starting position, "
17973                             "Reissuing\n");
17974                         return (EAGAIN);
17975                 }
17976                 /*
17977                  * Not in the position that the command was originally issued,
17978                  * Attempt to locate to that position.
17979                  */
17980                 rval = st_logical_block_locate(un, st_uscsi_rcmd, read,
17981                     ei->ei_expected_pos.lgclblkno,
17982                     ei->ei_expected_pos.partition);
17983                 if (rval) {
17984                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17985                             "Found Space at an unexpected position and locate "
17986                             "back to starting position failed\n");
17987                         return (EIO);
17988                 }
17989                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17990                     "Found Space at an unexpected position and locate "
17991                     "back to starting position worked, Reissuing\n");
17992                 return (EAGAIN);
17993         }
17994         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
17995             "Unhandled attribute/expected position", &ei->ei_expected_pos);
17996         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
17997             "Read position above did not make sense", read);
17998         ASSERT(0);
17999         return (EIO);
18000 }
18001 
18002 static errstate
18003 st_recover_reissue_pkt(struct scsi_tape *un, struct scsi_pkt *oldpkt)
18004 {
18005         buf_t *bp;
18006         buf_t *pkt_bp;
18007         struct scsi_pkt *newpkt;
18008         cmd_attribute const *attrib;
18009         recov_info *rcv = oldpkt->pkt_private;
18010         uint_t cdblen;
18011         int queued = 0;
18012         int rval;
18013         int flags = 0;
18014         int stat_size =
18015             (un->un_arq_enabled ? sizeof (struct scsi_arq_status) : 1);
18016 
18017         ST_FUNC(ST_DEVINFO, st_recover_reissue_pkt);
18018 
18019         bp = rcv->cmd_bp;
18020 
18021         if (rcv->privatelen == sizeof (recov_info)) {
18022                 attrib = rcv->cmd_attrib;
18023         } else {
18024                 attrib = st_lookup_cmd_attribute(oldpkt->pkt_cdbp[0]);
18025         }
18026 
18027         /*
18028          * Some non-uscsi commands use the b_bcount for values that
18029          * have nothing to do with how much data is transfered.
18030          * In those cases we need to hide the buf_t from scsi_init_pkt().
18031          */
18032         if ((BP_UCMD(bp)) && (bp->b_bcount)) {
18033                 pkt_bp = bp;
18034         } else if (attrib->transfers_data == TRAN_NONE) {
18035                 pkt_bp = NULL;
18036         } else {
18037                 pkt_bp = bp;
18038         }
18039 
18040         /*
18041          * if this is a queued command make sure it the only one in the
18042          * run queue.
18043          */
18044         if (bp != un->un_sbufp && bp != un->un_recov_buf) {
18045                 ASSERT(un->un_runqf == un->un_runql);
18046                 ASSERT(un->un_runqf == bp);
18047                 queued = 1;
18048         }
18049 
18050         cdblen = scsi_cdb_size[CDB_GROUPID(oldpkt->pkt_cdbp[0])];
18051 
18052         if (pkt_bp == un->un_rqs_bp) {
18053                 flags |= PKT_CONSISTENT;
18054                 stat_size = 1;
18055         }
18056 
18057         newpkt = scsi_init_pkt(ROUTE, NULL, pkt_bp, cdblen,
18058             stat_size, rcv->privatelen, flags, NULL_FUNC, NULL);
18059         if (newpkt == NULL) {
18060                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
18061                     "Reissue pkt scsi_init_pkt() failure\n");
18062                 return (COMMAND_DONE_ERROR);
18063         }
18064 
18065         ASSERT(newpkt->pkt_resid == 0);
18066         bp->b_flags &= ~(B_DONE);
18067         bp->b_resid = 0;
18068         st_bioerror(bp, 0);
18069 
18070         bcopy(oldpkt->pkt_private, newpkt->pkt_private, rcv->privatelen);
18071 
18072         newpkt->pkt_comp = oldpkt->pkt_comp;
18073         newpkt->pkt_time = oldpkt->pkt_time;
18074 
18075         bzero(newpkt->pkt_scbp, stat_size);
18076         bcopy(oldpkt->pkt_cdbp, newpkt->pkt_cdbp, cdblen);
18077 
18078         newpkt->pkt_state = 0;
18079         newpkt->pkt_statistics = 0;
18080 
18081         /*
18082          * oldpkt passed in was a copy of the original.
18083          * to distroy we need the address of the original.
18084          */
18085         oldpkt = BP_PKT(bp);
18086 
18087         if (oldpkt == un->un_rqs) {
18088                 ASSERT(bp == un->un_rqs_bp);
18089                 un->un_rqs = newpkt;
18090         }
18091 
18092         SET_BP_PKT(bp, newpkt);
18093 
18094         scsi_destroy_pkt(oldpkt);
18095 
18096         rval = st_transport(un, newpkt);
18097         if (rval == TRAN_ACCEPT) {
18098                 return (JUST_RETURN);
18099         }
18100         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
18101             "Reissue pkt st_transport(0x%x) failure\n", rval);
18102         if (rval != TRAN_BUSY) {
18103                 return (COMMAND_DONE_ERROR);
18104         }
18105         mutex_exit(ST_MUTEX);
18106         rval = st_handle_start_busy(un, bp, ST_TRAN_BUSY_TIMEOUT, queued);
18107         mutex_enter(ST_MUTEX);
18108         if (rval) {
18109                 return (COMMAND_DONE_ERROR);
18110         }
18111 
18112         return (JUST_RETURN);
18113 }
18114 
18115 static int
18116 st_transport(struct scsi_tape *un, struct scsi_pkt *pkt)
18117 {
18118         int status;
18119 
18120         ST_FUNC(ST_DEVINFO, st_transport);
18121 
18122         ST_CDB(ST_DEVINFO, "transport CDB", (caddr_t)pkt->pkt_cdbp);
18123 
18124         mutex_exit(ST_MUTEX);
18125 
18126         status = scsi_transport(pkt);
18127 
18128         mutex_enter(ST_MUTEX);
18129 
18130         return (status);
18131 }
18132 
18133 /*
18134  * Removed the buf_t bp from the queue referenced to by head and tail.
18135  * Returns the buf_t pointer if it is found in the queue.
18136  * Returns NULL if it is not found.
18137  */
18138 static buf_t *
18139 st_remove_from_queue(buf_t **head, buf_t **tail, buf_t *bp)
18140 {
18141         buf_t *runqbp;
18142         buf_t *prevbp = NULL;
18143 
18144         for (runqbp = *head; runqbp != 0; runqbp = runqbp->av_forw) {
18145                 if (runqbp == bp) {
18146                         /* found it, is it at the head? */
18147                         if (runqbp == *head) {
18148                                 *head = bp->av_forw;
18149                         } else {
18150                                 prevbp->av_forw = bp->av_forw;
18151                         }
18152                         if (*tail == bp) {
18153                                 *tail = prevbp;
18154                         }
18155                         bp->av_forw = NULL;
18156                         return (bp); /* found and removed */
18157                 }
18158                 prevbp = runqbp;
18159         }
18160         return (NULL);
18161 }
18162 
18163 /*
18164  * Adds a buf_t to the queue pointed to by head and tail.
18165  * Adds it either to the head end or the tail end based on which
18166  * the passed variable end (head or tail) points at.
18167  */
18168 static void
18169 st_add_to_queue(buf_t **head, buf_t **tail, buf_t *end, buf_t *bp)
18170 {
18171 
18172         bp->av_forw = NULL;
18173         if (*head) {
18174                 /* Queue is not empty */
18175                 if (end == *head) {
18176                         /* Add at front of queue */
18177                         bp->av_forw = *head;
18178                         *head = bp;
18179                 } else if (end == *tail) {
18180                         /* Add at end of queue */
18181                         (*tail)->av_forw = bp;
18182                         *tail = bp;
18183                 } else {
18184                         ASSERT(0);
18185                 }
18186         } else {
18187                 /* Queue is empty */
18188                 *head = bp;
18189                 *tail = bp;
18190         }
18191 }
18192 
18193 
18194 static uint64_t
18195 st_get_cdb_g0_rw_count(uchar_t *cdb)
18196 {
18197         uint64_t count;
18198 
18199         if ((cdb[1]) & 1) {
18200                 /* fixed block mode, the count is the number of blocks */
18201                 count =
18202                     cdb[2] << 16 |
18203                     cdb[3] << 8 |
18204                     cdb[4];
18205         } else {
18206                 /* variable block mode, the count is the block size */
18207                 count = 1;
18208         }
18209         return (count);
18210 }
18211 
18212 static uint64_t
18213 st_get_cdb_g0_sign_count(uchar_t *cdb)
18214 {
18215         uint64_t count;
18216 
18217         count =
18218             cdb[2] << 16 |
18219             cdb[3] << 8 |
18220             cdb[4];
18221         /*
18222          * If the sign bit of the 3 byte value is set, extended it.
18223          */
18224         if (count & 0x800000) {
18225                 count |= 0xffffffffff000000;
18226         }
18227         return (count);
18228 }
18229 
18230 static uint64_t
18231 st_get_cdb_g0_count(uchar_t *cdb)
18232 {
18233         uint64_t count;
18234 
18235         count =
18236             cdb[2] << 16 |
18237             cdb[3] << 8 |
18238             cdb[4];
18239         return (count);
18240 }
18241 
18242 static uint64_t
18243 st_get_cdb_g5_rw_cnt(uchar_t *cdb)
18244 {
18245         uint64_t count;
18246 
18247         if ((cdb[1]) & 1) {
18248                 /* fixed block mode */
18249                 count =
18250                     cdb[12] << 16 |
18251                     cdb[13] << 8 |
18252                     cdb[14];
18253         } else {
18254                 /* variable block mode */
18255                 count = 1;
18256         }
18257         return (count);
18258 }
18259 
18260 static uint64_t
18261 st_get_no_count(uchar_t *cdb)
18262 {
18263         ASSERT(cdb[0] == SCMD_REWIND);
18264         return ((uint64_t)cdb[0]);
18265 }
18266 
18267 static uint64_t
18268 st_get_load_options(uchar_t *cdb)
18269 {
18270         return ((uint64_t)(cdb[4] | (LD_HOLD << 1)));
18271 }
18272 
18273 static uint64_t
18274 st_get_erase_options(uchar_t *cdb)
18275 {
18276         return (cdb[1] | (cdb[0] << 8));
18277 }
18278 
18279 static uint64_t
18280 st_get_cdb_g1_lba(uchar_t *cdb)
18281 {
18282         uint64_t lba;
18283 
18284         lba =
18285             cdb[3] << 24 |
18286             cdb[4] << 16 |
18287             cdb[5] << 8 |
18288             cdb[6];
18289         return (lba);
18290 }
18291 
18292 static uint64_t
18293 st_get_cdb_g5_count(uchar_t *cdb)
18294 {
18295         uint64_t count =
18296             cdb[12] << 16 |
18297             cdb[13] << 8 |
18298             cdb[14];
18299 
18300         return (count);
18301 }
18302 
18303 static uint64_t
18304 st_get_cdb_g4g5_cnt(uchar_t *cdb)
18305 {
18306         uint64_t lba;
18307 
18308         lba =
18309             (uint64_t)cdb[4] << 56 |
18310             (uint64_t)cdb[5] << 48 |
18311             (uint64_t)cdb[6] << 40 |
18312             (uint64_t)cdb[7] << 32 |
18313             (uint64_t)cdb[8] << 24 |
18314             (uint64_t)cdb[9] << 16 |
18315             (uint64_t)cdb[10] << 8 |
18316             (uint64_t)cdb[11];
18317         return (lba);
18318 }
18319 
18320 static const cmd_attribute cmd_attributes[] = {
18321         { SCMD_READ,
18322             1, 0, 1, 0, 0, DIR_FORW, TRAN_READ, POS_EXPECTED,
18323             0, 0, 0, st_get_cdb_g0_rw_count },
18324         { SCMD_WRITE,
18325             1, 0, 1, 1, 0, DIR_FORW, TRAN_WRTE, POS_EXPECTED,
18326             0, 0, 0, st_get_cdb_g0_rw_count },
18327         { SCMD_TEST_UNIT_READY,
18328             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18329             0, 0, 0 },
18330         { SCMD_REWIND,
18331             1, 1, 1, 0, 0, DIR_REVC, TRAN_NONE, POS_EXPECTED,
18332             0, 0, 0, st_get_no_count },
18333         { SCMD_REQUEST_SENSE,
18334             0, 0, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18335             0, 0, 0 },
18336         { SCMD_READ_BLKLIM,
18337             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18338             0, 0, 0 },
18339         { SCMD_READ_G4,
18340             1, 0, 1, 0, 1, DIR_FORW, TRAN_READ, POS_EXPECTED,
18341             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18342         { SCMD_WRITE_G4,
18343             1, 0, 1, 1, 1, DIR_FORW, TRAN_WRTE, POS_EXPECTED,
18344             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18345         { SCMD_READ_REVERSE,
18346             1, 0, 1, 1, 0, DIR_REVC, TRAN_READ, POS_EXPECTED,
18347             0, 0, 0, st_get_cdb_g0_rw_count },
18348         { SCMD_READ_REVERSE_G4,
18349             1, 0, 1, 1, 1, DIR_REVC, TRAN_READ, POS_EXPECTED,
18350             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18351         { SCMD_WRITE_FILE_MARK,
18352             1, 0, 1, 1, 0, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18353             0, 0, 0, st_get_cdb_g0_count },
18354         { SCMD_WRITE_FILE_MARK_G4,
18355             1, 0, 1, 1, 1, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18356             0, 0, 0, st_get_cdb_g5_count, st_get_cdb_g4g5_cnt },
18357         { SCMD_SPACE,
18358             1, 0, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_STARTING,
18359             0, 0, 0, st_get_cdb_g0_sign_count },
18360         { SCMD_SPACE_G4,
18361             1, 0, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_STARTING,
18362             0, 0, 0, st_get_cdb_g4g5_cnt },
18363         { SCMD_INQUIRY,
18364             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18365             0, 0, 0 },
18366         { SCMD_VERIFY_G0,
18367             1, 0, 1, 0, 0, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18368             0, 0, 0, st_get_cdb_g0_rw_count },
18369         { SCMD_VERIFY_G4,
18370             1, 0, 1, 0, 1, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18371             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18372         { SCMD_RECOVER_BUF,
18373             1, 0, 1, 1, 0, DIR_REVC, TRAN_READ, POS_EXPECTED,
18374             0, 0, 0 },
18375         { SCMD_MODE_SELECT,
18376             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18377             0, 0, 0 },
18378         { SCMD_RESERVE,
18379             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18380             0, 0, 0 },
18381         { SCMD_RELEASE,
18382             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18383             0, 0, 0 },
18384         { SCMD_ERASE,
18385             1, 0, 1, 1, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18386             0, 0, 0, st_get_erase_options },
18387         { SCMD_MODE_SENSE,
18388             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18389             0, 0, 0 },
18390         { SCMD_LOAD,
18391             1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18392             0, 0, 0, st_get_load_options },
18393         { SCMD_GDIAG,
18394             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18395             1, 0, 0 },
18396         { SCMD_SDIAG,
18397             1, 0, 1, 1, 0, DIR_EITH, TRAN_WRTE, POS_EXPECTED,
18398             1, 0, 0 },
18399         { SCMD_DOORLOCK,
18400             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18401             0, 4, 3 },
18402         { SCMD_LOCATE,
18403             1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18404             0, 0, 0, NULL, st_get_cdb_g1_lba },
18405         { SCMD_READ_POSITION,
18406             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18407             0, 0, 0 },
18408         { SCMD_WRITE_BUFFER,
18409             1, 0, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18410             1, 0, 0 },
18411         { SCMD_READ_BUFFER,
18412             1, 0, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18413             1, 0, 0 },
18414         { SCMD_REPORT_DENSITIES,
18415             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18416             0, 0, 0 },
18417         { SCMD_LOG_SELECT_G1,
18418             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18419             0, 0, 0 },
18420         { SCMD_LOG_SENSE_G1,
18421             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18422             0, 0, 0 },
18423         { SCMD_PRIN,
18424             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18425             0, 0, 0 },
18426         { SCMD_PROUT,
18427             0, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18428             0, 0, 0 },
18429         { SCMD_READ_ATTRIBUTE,
18430             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18431             0, 0, 0 },
18432         { SCMD_WRITE_ATTRIBUTE,
18433             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18434             0, 0, 0 },
18435         { SCMD_LOCATE_G4,
18436             1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18437             0, 0, 0, NULL, st_get_cdb_g4g5_cnt },
18438         { SCMD_REPORT_LUNS,
18439             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18440             0, 0, 0 },
18441         { SCMD_SVC_ACTION_IN_G5,
18442             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18443             0, 0, 0 },
18444         { SCMD_MAINTENANCE_IN,
18445             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18446             0, 0, 0 },
18447         { SCMD_MAINTENANCE_OUT,
18448             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18449             0, 0, 0 },
18450         { 0xff, /* Default attribute for unsupported commands */
18451             1, 0, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_STARTING,
18452             1, 0, 0, NULL, NULL }
18453 };
18454 
18455 static const cmd_attribute *
18456 st_lookup_cmd_attribute(unsigned char cmd)
18457 {
18458         int i;
18459         cmd_attribute const *attribute;
18460 
18461         for (i = 0; i < ST_NUM_MEMBERS(cmd_attributes); i++) {
18462                 attribute = &cmd_attributes[i];
18463                 if (attribute->cmd == cmd) {
18464                         return (attribute);
18465                 }
18466         }
18467         ASSERT(attribute);
18468         return (attribute);
18469 }
18470 
18471 static int
18472 st_reset(struct scsi_tape *un, int reset_type)
18473 {
18474         int rval;
18475 
18476         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
18477 
18478         ST_FUNC(ST_DEVINFO, st_reset);
18479         un->un_rsvd_status |= ST_INITIATED_RESET;
18480         mutex_exit(ST_MUTEX);
18481         do {
18482                 rval = scsi_reset(&un->un_sd->sd_address, reset_type);
18483                 if (rval == 0) {
18484                         switch (reset_type) {
18485                         case RESET_LUN:
18486                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18487                                     "LUN reset failed trying target reset");
18488                                 reset_type = RESET_TARGET;
18489                                 break;
18490                         case RESET_TARGET:
18491                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18492                                     "target reset failed trying bus reset");
18493                                 reset_type = RESET_BUS;
18494                                 break;
18495                         case RESET_BUS:
18496                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18497                                     "bus reset failed trying all reset");
18498                                 reset_type = RESET_ALL;
18499                         default:
18500                                 mutex_enter(ST_MUTEX);
18501                                 return (rval);
18502                         }
18503                 }
18504         } while (rval == 0);
18505         mutex_enter(ST_MUTEX);
18506         return (rval);
18507 }
18508 
18509 #define SAS_TLR_MOD_LEN sizeof (struct seq_mode)
18510 static int
18511 st_set_target_TLR_mode(struct scsi_tape *un, ubufunc_t ubf)
18512 {
18513         int ret;
18514         int amount = SAS_TLR_MOD_LEN;
18515         struct seq_mode *mode_data;
18516 
18517         ST_FUNC(ST_DEVINFO, st_set_target_TLR_mode);
18518 
18519         mode_data = kmem_zalloc(SAS_TLR_MOD_LEN, KM_SLEEP);
18520         ret = st_gen_mode_sense(un, ubf, 0x18, mode_data, amount);
18521         if (ret != DDI_SUCCESS) {
18522                 if (ret != EACCES)
18523                         un->un_tlr_flag = TLR_NOT_SUPPORTED;
18524                 goto out;
18525         }
18526         if (mode_data->data_len != amount + 1) {
18527                 amount = mode_data->data_len + 1;
18528         }
18529         /* Must be SAS protocol */
18530         if (mode_data->page.saslun.protocol_id != 6) {
18531                 un->un_tlr_flag = TLR_NOT_SUPPORTED;
18532                 ret = ENOTSUP;
18533                 goto out;
18534         }
18535         if (un->un_tlr_flag == TLR_SAS_ONE_DEVICE) {
18536                 if (mode_data->page.saslun.tran_layer_ret == 1)
18537                         goto out;
18538                 mode_data->page.saslun.tran_layer_ret = 1;
18539         } else {
18540                 if (mode_data->page.saslun.tran_layer_ret == 0)
18541                         goto out;
18542                 mode_data->page.saslun.tran_layer_ret = 0;
18543         }
18544         ret = st_gen_mode_select(un, ubf, mode_data, amount);
18545         if (ret != DDI_SUCCESS) {
18546                 if (ret != EACCES)
18547                         un->un_tlr_flag = TLR_NOT_SUPPORTED;
18548         } else {
18549                 if (mode_data->page.saslun.tran_layer_ret == 0)
18550                         un->un_tlr_flag = TLR_NOT_KNOWN;
18551                 else
18552                         un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
18553         }
18554 #ifdef STDEBUG
18555         st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG, "TLR data sent",
18556             (char *)mode_data, amount);
18557 #endif
18558 out:
18559         kmem_free(mode_data, SAS_TLR_MOD_LEN);
18560         return (ret);
18561 }
18562 
18563 
18564 static void
18565 st_reset_notification(caddr_t arg)
18566 {
18567         struct scsi_tape *un = (struct scsi_tape *)arg;
18568 
18569         ST_FUNC(ST_DEVINFO, st_reset_notification);
18570         mutex_enter(ST_MUTEX);
18571 
18572         un->un_unit_attention_flags |= 2;
18573         if ((un->un_rsvd_status & (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
18574             ST_RESERVE) {
18575                 un->un_rsvd_status |= ST_LOST_RESERVE;
18576                 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
18577                     "Lost Reservation notification");
18578         } else {
18579                 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
18580                     "reset notification");
18581         }
18582 
18583         if ((un->un_restore_pos == 0) &&
18584             (un->un_state == ST_STATE_CLOSED) ||
18585             (un->un_state == ST_STATE_OPEN_PENDING_IO) ||
18586             (un->un_state == ST_STATE_CLOSING)) {
18587                 un->un_restore_pos = 1;
18588         }
18589         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
18590             "reset and state was %d\n", un->un_state);
18591         mutex_exit(ST_MUTEX);
18592 }
--- EOF ---