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                     st_wait_cmds_complete * drv_usectohz(1000000);
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. ddi_iopb_alloc()
1694          * is obsolete and we want more flexibility in controlling the DMA
1695          * address constraints.
1696          */
1697         (void) i_ddi_mem_alloc(devp->sd_dev, &st_alloc_attr,
1698             sizeof (struct seq_mode), ((km_flags == KM_SLEEP) ? 1 : 0), 0,
1699             NULL, (caddr_t *)&un->un_mspl, &rlen, NULL);
1700 
1701         (void) i_ddi_mem_alloc(devp->sd_dev, &st_alloc_attr,
1702             sizeof (read_pos_data_t), ((km_flags == KM_SLEEP) ? 1 : 0), 0,
1703             NULL, (caddr_t *)&un->un_read_pos_data, &rlen, NULL);
1704 
1705         if (!un->un_sbufp || !un->un_mspl || !un->un_read_pos_data) {
1706                 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG,
1707                     "probe partial failure: no space\n");
1708                 goto error;
1709         }
1710 
1711         bzero(un->un_mspl, sizeof (struct seq_mode));
1712 
1713         cv_init(&un->un_sbuf_cv, NULL, CV_DRIVER, NULL);
1714         cv_init(&un->un_queue_cv, NULL, CV_DRIVER, NULL);
1715         cv_init(&un->un_clscv, NULL, CV_DRIVER, NULL);
1716         cv_init(&un->un_state_cv, NULL, CV_DRIVER, NULL);
1717 #ifdef  __x86
1718         cv_init(&un->un_contig_mem_cv, NULL, CV_DRIVER, NULL);
1719 #endif
1720 
1721         /* Initialize power managemnet condition variable */
1722         cv_init(&un->un_suspend_cv, NULL, CV_DRIVER, NULL);
1723         cv_init(&un->un_tape_busy_cv, NULL, CV_DRIVER, NULL);
1724         cv_init(&un->un_recov_buf_cv, NULL, CV_DRIVER, NULL);
1725 
1726         un->un_recov_taskq = ddi_taskq_create(devp->sd_dev,
1727             "un_recov_taskq", 1, TASKQ_DEFAULTPRI, km_flags);
1728 
1729         ASSERT(un->un_recov_taskq != NULL);
1730 
1731         un->un_pos.pmode = invalid;
1732         un->un_sd    = devp;
1733         un->un_swr_token = (opaque_t)NULL;
1734         un->un_comp_page = ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE;
1735         un->un_wormable = st_is_drive_worm;
1736         un->un_media_id_method = st_get_media_identification;
1737         /*
1738          * setting long a initial as it contains logical file info.
1739          * support for long format is mandatory but many drive don't do it.
1740          */
1741         un->un_read_pos_type = LONG_POS;
1742 
1743         un->un_suspend_pos.pmode = invalid;
1744 
1745         st_add_recovery_info_to_pkt(un, un->un_rqs_bp, un->un_rqs);
1746 
1747 #ifdef  __x86
1748         if (ddi_dma_alloc_handle(ST_DEVINFO, &st_contig_mem_dma_attr,
1749             DDI_DMA_SLEEP, NULL, &un->un_contig_mem_hdl) != DDI_SUCCESS) {
1750                 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG,
1751                     "allocation of contiguous memory dma handle failed!");
1752                 un->un_contig_mem_hdl = NULL;
1753                 goto error;
1754         }
1755 #endif
1756 
1757         /*
1758          * Since this driver manages devices with "remote" hardware,
1759          * i.e. the devices themselves have no "reg" properties,
1760          * the SUSPEND/RESUME commands in detach/attach will not be
1761          * called by the power management framework unless we request
1762          * it by creating a "pm-hardware-state" property and setting it
1763          * to value "needs-suspend-resume".
1764          */
1765         if (ddi_prop_update_string(DDI_DEV_T_NONE, devp->sd_dev,
1766             "pm-hardware-state", "needs-suspend-resume") !=
1767             DDI_PROP_SUCCESS) {
1768 
1769                 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1770                     "ddi_prop_update(\"pm-hardware-state\") failed\n");
1771                 goto error;
1772         }
1773 
1774         if (ddi_prop_create(DDI_DEV_T_NONE, devp->sd_dev, DDI_PROP_CANSLEEP,
1775             "no-involuntary-power-cycles", NULL, 0) != DDI_PROP_SUCCESS) {
1776 
1777                 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1778                     "ddi_prop_create(\"no-involuntary-power-cycles\") "
1779                     "failed\n");
1780                 goto error;
1781         }
1782 
1783         (void) scsi_reset_notify(ROUTE, SCSI_RESET_NOTIFY,
1784             st_reset_notification, (caddr_t)un);
1785 
1786         ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG, "attach success\n");
1787         return (DDI_SUCCESS);
1788 
1789 error:
1790         devp->sd_sense = NULL;
1791 
1792         ddi_remove_minor_node(devp->sd_dev, NULL);
1793         if (un) {
1794                 if (un->un_mspl) {
1795                         i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1796                 }
1797                 if (un->un_read_pos_data) {
1798                         i_ddi_mem_free((caddr_t)un->un_read_pos_data, 0);
1799                 }
1800                 if (un->un_sbufp) {
1801                         freerbuf(un->un_sbufp);
1802                 }
1803                 if (un->un_recov_buf) {
1804                         freerbuf(un->un_recov_buf);
1805                 }
1806                 if (un->un_uscsi_rqs_buf) {
1807                         kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1808                 }
1809 #ifdef  __x86
1810                 if (un->un_contig_mem_hdl != NULL) {
1811                         ddi_dma_free_handle(&un->un_contig_mem_hdl);
1812                 }
1813 #endif
1814                 if (un->un_rqs) {
1815                         scsi_destroy_pkt(un->un_rqs);
1816                 }
1817 
1818                 if (un->un_rqs_bp) {
1819                         scsi_free_consistent_buf(un->un_rqs_bp);
1820                 }
1821 
1822                 ddi_soft_state_free(st_state, instance);
1823                 devp->sd_private = NULL;
1824         }
1825 
1826         if (devp->sd_inq) {
1827                 scsi_unprobe(devp);
1828         }
1829         return (DDI_FAILURE);
1830 }
1831 
1832 typedef int
1833 (*cfg_functp)(struct scsi_tape *, char *vidpid, struct st_drivetype *);
1834 
1835 static cfg_functp config_functs[] = {
1836         st_get_conf_from_st_dot_conf,
1837         st_get_conf_from_st_conf_dot_c,
1838         st_get_conf_from_tape_drive,
1839         st_get_default_conf
1840 };
1841 
1842 
1843 /*
1844  * determine tape type, using tape-config-list or built-in table or
1845  * use a generic tape config entry
1846  */
1847 static void
1848 st_known_tape_type(struct scsi_tape *un)
1849 {
1850         struct st_drivetype *dp;
1851         cfg_functp *config_funct;
1852         uchar_t reserved;
1853 
1854         ST_FUNC(ST_DEVINFO, st_known_tape_type);
1855 
1856         reserved = (un->un_rsvd_status & ST_RESERVE) ? ST_RESERVE
1857             : ST_RELEASE;
1858 
1859         /*
1860          * XXX:  Emulex MT-02 (and emulators) predates SCSI-1 and has
1861          *       no vid & pid inquiry data.  So, we provide one.
1862          */
1863         if (ST_INQUIRY->inq_len == 0 ||
1864             (bcmp("\0\0\0\0\0\0\0\0", ST_INQUIRY->inq_vid, 8) == 0)) {
1865                 (void) strcpy((char *)ST_INQUIRY->inq_vid, ST_MT02_NAME);
1866         }
1867 
1868         if (un->un_dp_size == 0) {
1869                 un->un_dp_size = sizeof (struct st_drivetype);
1870                 dp = kmem_zalloc((size_t)un->un_dp_size, KM_SLEEP);
1871                 un->un_dp = dp;
1872         } else {
1873                 dp = un->un_dp;
1874         }
1875 
1876         un->un_dp->non_motion_timeout = st_io_time;
1877         /*
1878          * Loop through the configuration methods till one works.
1879          */
1880         for (config_funct = &config_functs[0]; ; config_funct++) {
1881                 if ((*config_funct)(un, ST_INQUIRY->inq_vid, dp)) {
1882                         break;
1883                 }
1884         }
1885 
1886         /*
1887          * If we didn't just make up this configuration and
1888          * all the density codes are the same..
1889          * Set Auto Density over ride.
1890          */
1891         if (*config_funct != st_get_default_conf) {
1892                 /*
1893                  * If this device is one that is configured and all
1894                  * densities are the same, This saves doing gets and set
1895                  * that yield nothing.
1896                  */
1897                 if ((dp->densities[0]) == (dp->densities[1]) &&
1898                     (dp->densities[0]) == (dp->densities[2]) &&
1899                     (dp->densities[0]) == (dp->densities[3])) {
1900 
1901                         dp->options |= ST_AUTODEN_OVERRIDE;
1902                 }
1903         }
1904 
1905 
1906         /*
1907          * Store tape drive characteristics.
1908          */
1909         un->un_status = 0;
1910         un->un_attached = 1;
1911         un->un_init_options = dp->options;
1912 
1913         /* setup operation time-outs based on options */
1914         st_calculate_timeouts(un);
1915 
1916         /* TLR support */
1917         if (un->un_dp->type != ST_TYPE_INVALID) {
1918                 int result;
1919 
1920                 /* try and enable TLR */
1921                 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
1922                 result = st_set_target_TLR_mode(un, st_uscsi_cmd);
1923                 if (result == EACCES) {
1924                         /*
1925                          * From attach command failed.
1926                          * Set dp type so is run again on open.
1927                          */
1928                         un->un_dp->type = ST_TYPE_INVALID;
1929                         un->un_tlr_flag = TLR_NOT_KNOWN;
1930                 } else if (result == 0) {
1931                         if (scsi_ifgetcap(&un->un_sd->sd_address,
1932                             "tran-layer-retries", 1) == -1) {
1933                                 un->un_tlr_flag = TLR_NOT_SUPPORTED;
1934                                 (void) st_set_target_TLR_mode(un, st_uscsi_cmd);
1935                         } else {
1936                                 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
1937                         }
1938                 } else {
1939                         un->un_tlr_flag = TLR_NOT_SUPPORTED;
1940                 }
1941         }
1942 
1943         /* make sure if we are supposed to be variable, make it variable */
1944         if (dp->options & ST_VARIABLE) {
1945                 dp->bsize = 0;
1946         }
1947 
1948         if (reserved != ((un->un_rsvd_status & ST_RESERVE) ? ST_RESERVE
1949             : ST_RELEASE)) {
1950                 (void) st_reserve_release(un, reserved, st_uscsi_cmd);
1951         }
1952 
1953         un->un_unit_attention_flags |= 1;
1954 
1955         scsi_log(ST_DEVINFO, st_label, CE_NOTE, "?<%s>\n", dp->name);
1956 
1957 }
1958 
1959 
1960 typedef struct {
1961         int mask;
1962         int bottom;
1963         int top;
1964         char *name;
1965 } conf_limit;
1966 
1967 static const conf_limit conf_limits[] = {
1968 
1969         -1,             1,              2,              "conf version",
1970         -1,             MT_ISTS,        ST_LAST_TYPE,   "drive type",
1971         -1,             0,              0xffffff,       "block size",
1972         ST_VALID_OPTS,  0,              ST_VALID_OPTS,  "options",
1973         -1,             0,              4,              "number of densities",
1974         -1,             0,              UINT8_MAX,      "density code",
1975         -1,             0,              3,              "default density",
1976         -1,             0,              UINT16_MAX,     "non motion timeout",
1977         -1,             0,              UINT16_MAX,     "I/O timeout",
1978         -1,             0,              UINT16_MAX,     "space timeout",
1979         -1,             0,              UINT16_MAX,     "load timeout",
1980         -1,             0,              UINT16_MAX,     "unload timeout",
1981         -1,             0,              UINT16_MAX,     "erase timeout",
1982         0,              0,              0,              NULL
1983 };
1984 
1985 static int
1986 st_validate_conf_data(struct scsi_tape *un, int *list, int list_len,
1987     const char *conf_name)
1988 {
1989         int dens;
1990         int ndens;
1991         int value;
1992         int type;
1993         int count;
1994         const conf_limit *limit = &conf_limits[0];
1995 
1996         ST_FUNC(ST_DEVINFO, st_validate_conf_data);
1997 
1998         ST_DEBUG3(ST_DEVINFO, st_label, CE_NOTE,
1999             "Checking %d entrys total with %d densities\n", list_len, list[4]);
2000 
2001         count = list_len;
2002         type = *list;
2003         for (;  count && limit->name; count--, list++, limit++) {
2004 
2005                 value = *list;
2006                 if (value & ~limit->mask) {
2007                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2008                             "%s %s value invalid bits set: 0x%X\n",
2009                             conf_name, limit->name, value & ~limit->mask);
2010                         *list &= limit->mask;
2011                 } else if (value < limit->bottom) {
2012                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2013                             "%s %s value too low: value = %d limit %d\n",
2014                             conf_name, limit->name, value, limit->bottom);
2015                 } else if (value > limit->top) {
2016                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2017                             "%s %s value too high: value = %d limit %d\n",
2018                             conf_name, limit->name, value, limit->top);
2019                 } else {
2020                         ST_DEBUG3(ST_DEVINFO, st_label, CE_CONT,
2021                             "%s %s value = 0x%X\n",
2022                             conf_name, limit->name, value);
2023                 }
2024 
2025                 /* If not the number of densities continue */
2026                 if (limit != &conf_limits[4]) {
2027                         continue;
2028                 }
2029 
2030                 /* If number of densities is not in range can't use config */
2031                 if (value < limit->bottom || value > limit->top) {
2032                         return (-1);
2033                 }
2034 
2035                 ndens = min(value, NDENSITIES);
2036                 if ((type == 1) && (list_len - ndens) != 6) {
2037                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2038                             "%s conf version 1 with %d densities has %d items"
2039                             " should have %d",
2040                             conf_name, ndens, list_len, 6 + ndens);
2041                 } else if ((type == 2) && (list_len - ndens) != 13) {
2042                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2043                             "%s conf version 2 with %d densities has %d items"
2044                             " should have %d",
2045                             conf_name, ndens, list_len, 13 + ndens);
2046                 }
2047 
2048                 limit++;
2049                 for (dens = 0; dens < ndens && count; dens++) {
2050                         count--;
2051                         list++;
2052                         value = *list;
2053                         if (value < limit->bottom) {
2054                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2055                                     "%s density[%d] value too low: value ="
2056                                     " 0x%X limit 0x%X\n",
2057                                     conf_name, dens, value, limit->bottom);
2058                         } else if (value > limit->top) {
2059                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2060                                     "%s density[%d] value too high: value ="
2061                                     " 0x%X limit 0x%X\n",
2062                                     conf_name, dens, value, limit->top);
2063                         } else {
2064                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_CONT,
2065                                     "%s density[%d] value = 0x%X\n",
2066                                     conf_name, dens, value);
2067                         }
2068                 }
2069         }
2070 
2071         return (0);
2072 }
2073 
2074 static int
2075 st_get_conf_from_st_dot_conf(struct scsi_tape *un, char *vidpid,
2076     struct st_drivetype *dp)
2077 {
2078         caddr_t config_list = NULL;
2079         caddr_t data_list = NULL;
2080         int     *data_ptr;
2081         caddr_t vidptr, prettyptr, datanameptr;
2082         size_t  vidlen, prettylen, datanamelen, tripletlen = 0;
2083         int config_list_len, data_list_len, len, i;
2084         int version;
2085         int found = 0;
2086 
2087         ST_FUNC(ST_DEVINFO, st_get_conf_from_st_dot_conf);
2088 
2089         /*
2090          * Determine type of tape controller. Type is determined by
2091          * checking the vendor ids of the earlier inquiry command and
2092          * comparing those with vids in tape-config-list defined in st.conf
2093          */
2094         if (ddi_getlongprop(DDI_DEV_T_ANY, ST_DEVINFO, DDI_PROP_DONTPASS,
2095             "tape-config-list", (caddr_t)&config_list, &config_list_len)
2096             != DDI_PROP_SUCCESS) {
2097                 return (found);
2098         }
2099 
2100         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
2101             "st_get_conf_from_st_dot_conf(): st.conf has tape-config-list\n");
2102 
2103         /*
2104          * Compare vids in each triplet - if it matches, get value for
2105          * data_name and contruct a st_drivetype struct
2106          * tripletlen is not set yet!
2107          */
2108         for (len = config_list_len, vidptr = config_list;
2109             len > 0;
2110             vidptr += tripletlen, len -= tripletlen) {
2111 
2112                 vidlen = strlen(vidptr);
2113                 prettyptr = vidptr + vidlen + 1;
2114                 prettylen = strlen(prettyptr);
2115                 datanameptr = prettyptr + prettylen + 1;
2116                 datanamelen = strlen(datanameptr);
2117                 tripletlen = vidlen + prettylen + datanamelen + 3;
2118 
2119                 if (vidlen == 0) {
2120                         continue;
2121                 }
2122 
2123                 /*
2124                  * If inquiry vid dosen't match this triplets vid,
2125                  * try the next.
2126                  */
2127                 if (strncasecmp(vidpid, vidptr, vidlen)) {
2128                         continue;
2129                 }
2130 
2131                 /*
2132                  * if prettylen is zero then use the vid string
2133                  */
2134                 if (prettylen == 0) {
2135                         prettyptr = vidptr;
2136                         prettylen = vidlen;
2137                 }
2138 
2139                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2140                     "vid = %s, pretty=%s, dataname = %s\n",
2141                     vidptr, prettyptr, datanameptr);
2142 
2143                 /*
2144                  * get the data list
2145                  */
2146                 if (ddi_getlongprop(DDI_DEV_T_ANY, ST_DEVINFO, 0,
2147                     datanameptr, (caddr_t)&data_list,
2148                     &data_list_len) != DDI_PROP_SUCCESS) {
2149                         /*
2150                          * Error in getting property value
2151                          * print warning!
2152                          */
2153                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2154                             "data property (%s) has no value\n",
2155                             datanameptr);
2156                         continue;
2157                 }
2158 
2159                 /*
2160                  * now initialize the st_drivetype struct
2161                  */
2162                 (void) strncpy(dp->name, prettyptr, ST_NAMESIZE - 1);
2163                 dp->length = (int)min(vidlen, (VIDPIDLEN - 1));
2164                 (void) strncpy(dp->vid, vidptr, dp->length);
2165                 data_ptr = (int *)data_list;
2166                 /*
2167                  * check if data is enough for version, type,
2168                  * bsize, options, # of densities, density1,
2169                  * density2, ..., default_density
2170                  */
2171                 if ((data_list_len < 5 * sizeof (int)) ||
2172                     (data_list_len < 6 * sizeof (int) +
2173                     *(data_ptr + 4) * sizeof (int))) {
2174                         /*
2175                          * print warning and skip to next triplet.
2176                          */
2177                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2178                             "data property (%s) incomplete\n",
2179                             datanameptr);
2180                         kmem_free(data_list, data_list_len);
2181                         continue;
2182                 }
2183 
2184                 if (st_validate_conf_data(un, data_ptr,
2185                     data_list_len / sizeof (int), datanameptr)) {
2186                         kmem_free(data_list, data_list_len);
2187                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2188                             "data property (%s) rejected\n",
2189                             datanameptr);
2190                         continue;
2191                 }
2192 
2193                 /*
2194                  * check version
2195                  */
2196                 version = *data_ptr++;
2197                 if (version != 1 && version != 2) {
2198                         /* print warning but accept it */
2199                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
2200                             "Version # for data property (%s) "
2201                             "not set to 1 or 2\n", datanameptr);
2202                 }
2203 
2204                 dp->type    = *data_ptr++;
2205                 dp->bsize   = *data_ptr++;
2206                 dp->options = *data_ptr++;
2207                 dp->options |= ST_DYNAMIC;
2208                 len = *data_ptr++;
2209                 for (i = 0; i < NDENSITIES; i++) {
2210                         if (i < len) {
2211                                 dp->densities[i] = *data_ptr++;
2212                         }
2213                 }
2214                 dp->default_density = *data_ptr << 3;
2215                 if (version == 2 &&
2216                     data_list_len >= (13 + len) * sizeof (int)) {
2217                         data_ptr++;
2218                         dp->non_motion_timeout       = *data_ptr++;
2219                         dp->io_timeout               = *data_ptr++;
2220                         dp->rewind_timeout   = *data_ptr++;
2221                         dp->space_timeout    = *data_ptr++;
2222                         dp->load_timeout     = *data_ptr++;
2223                         dp->unload_timeout   = *data_ptr++;
2224                         dp->erase_timeout    = *data_ptr++;
2225                 }
2226                 kmem_free(data_list, data_list_len);
2227                 found = 1;
2228                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2229                     "found in st.conf: vid = %s, pretty=%s\n",
2230                     dp->vid, dp->name);
2231                 break;
2232         }
2233 
2234         /*
2235          * free up the memory allocated by ddi_getlongprop
2236          */
2237         if (config_list) {
2238                 kmem_free(config_list, config_list_len);
2239         }
2240         return (found);
2241 }
2242 
2243 static int
2244 st_get_conf_from_st_conf_dot_c(struct scsi_tape *un, char *vidpid,
2245     struct st_drivetype *dp)
2246 {
2247         int i;
2248 
2249         ST_FUNC(ST_DEVINFO, st_get_conf_from_st_conf_dot_c);
2250         /*
2251          * Determine type of tape controller.  Type is determined by
2252          * checking the result of the earlier inquiry command and
2253          * comparing vendor ids with strings in a table declared in st_conf.c.
2254          */
2255         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2256             "st_get_conf_from_st_conf_dot_c(): looking at st_drivetypes\n");
2257 
2258         for (i = 0; i < st_ndrivetypes; i++) {
2259                 if (st_drivetypes[i].length == 0) {
2260                         continue;
2261                 }
2262                 if (strncasecmp(vidpid, st_drivetypes[i].vid,
2263                     st_drivetypes[i].length)) {
2264                         continue;
2265                 }
2266                 bcopy(&st_drivetypes[i], dp, sizeof (st_drivetypes[i]));
2267                 return (1);
2268         }
2269         return (0);
2270 }
2271 
2272 static int
2273 st_get_conf_from_tape_drive(struct scsi_tape *un, char *vidpid,
2274     struct st_drivetype *dp)
2275 {
2276         int bsize;
2277         ulong_t maxbsize;
2278         caddr_t buf;
2279         struct st_drivetype *tem_dp;
2280         struct read_blklim *blklim;
2281         int rval;
2282         int i;
2283 
2284         ST_FUNC(ST_DEVINFO, st_get_conf_from_tape_drive);
2285 
2286         /*
2287          * Determine the type of tape controller. Type is determined by
2288          * sending SCSI commands to tape drive and deriving the type from
2289          * the returned data.
2290          */
2291         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2292             "st_get_conf_from_tape_drive(): asking tape drive\n");
2293 
2294         tem_dp = kmem_zalloc(sizeof (struct st_drivetype), KM_SLEEP);
2295 
2296         /*
2297          * Make up a name
2298          */
2299         bcopy(vidpid, tem_dp->name, VIDPIDLEN);
2300         tem_dp->name[VIDPIDLEN] = '\0';
2301         tem_dp->length = min(strlen(ST_INQUIRY->inq_vid), (VIDPIDLEN - 1));
2302         (void) strncpy(tem_dp->vid, ST_INQUIRY->inq_vid, tem_dp->length);
2303         /*
2304          * 'clean' vendor and product strings of non-printing chars
2305          */
2306         for (i = 0; i < VIDPIDLEN - 1; i ++) {
2307                 if (tem_dp->name[i] < ' ' || tem_dp->name[i] > '~') {
2308                         tem_dp->name[i] = '.';
2309                 }
2310         }
2311 
2312         /*
2313          * MODE SENSE to determine block size.
2314          */
2315         un->un_dp->options |= ST_MODE_SEL_COMP | ST_UNLOADABLE;
2316         rval = st_modesense(un);
2317         if (rval) {
2318                 if (rval == EACCES) {
2319                         un->un_dp->type = ST_TYPE_INVALID;
2320                         rval = 1;
2321                 } else {
2322                         un->un_dp->options &= ~ST_MODE_SEL_COMP;
2323                         rval = 0;
2324                 }
2325                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2326                     "st_get_conf_from_tape_drive(): fail to mode sense\n");
2327                 goto exit;
2328         }
2329 
2330         /* Can mode sense page 0x10 or 0xf */
2331         tem_dp->options |= ST_MODE_SEL_COMP;
2332         bsize = (un->un_mspl->high_bl << 16)        |
2333             (un->un_mspl->mid_bl << 8)              |
2334             (un->un_mspl->low_bl);
2335 
2336         if (bsize == 0) {
2337                 tem_dp->options |= ST_VARIABLE;
2338                 tem_dp->bsize = 0;
2339         } else if (bsize > ST_MAXRECSIZE_FIXED) {
2340                 rval = st_change_block_size(un, 0);
2341                 if (rval) {
2342                         if (rval == EACCES) {
2343                                 un->un_dp->type = ST_TYPE_INVALID;
2344                                 rval = 1;
2345                         } else {
2346                                 rval = 0;
2347                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2348                                     "st_get_conf_from_tape_drive(): "
2349                                     "Fixed record size is too large and"
2350                                     "cannot switch to variable record size");
2351                         }
2352                         goto exit;
2353                 }
2354                 tem_dp->options |= ST_VARIABLE;
2355         } else {
2356                 rval = st_change_block_size(un, 0);
2357                 if (rval == 0) {
2358                         tem_dp->options |= ST_VARIABLE;
2359                         tem_dp->bsize = 0;
2360                 } else if (rval != EACCES) {
2361                         tem_dp->bsize = bsize;
2362                 } else {
2363                         un->un_dp->type = ST_TYPE_INVALID;
2364                         rval = 1;
2365                         goto exit;
2366                 }
2367         }
2368 
2369         /*
2370          * If READ BLOCk LIMITS works and upper block size limit is
2371          * more than 64K, ST_NO_RECSIZE_LIMIT is supported.
2372          */
2373         blklim = kmem_zalloc(sizeof (struct read_blklim), KM_SLEEP);
2374         rval = st_read_block_limits(un, blklim);
2375         if (rval) {
2376                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2377                     "st_get_conf_from_tape_drive(): "
2378                     "fail to read block limits.\n");
2379                 rval = 0;
2380                 kmem_free(blklim, sizeof (struct read_blklim));
2381                 goto exit;
2382         }
2383         maxbsize = (blklim->max_hi << 16) +
2384             (blklim->max_mid << 8) + blklim->max_lo;
2385         if (maxbsize > ST_MAXRECSIZE_VARIABLE) {
2386                 tem_dp->options |= ST_NO_RECSIZE_LIMIT;
2387         }
2388         kmem_free(blklim, sizeof (struct read_blklim));
2389 
2390         /*
2391          * Inquiry VPD page 0xb0 to see if the tape drive supports WORM
2392          */
2393         buf = kmem_zalloc(6, KM_SLEEP);
2394         rval = st_get_special_inquiry(un, 6, buf, 0xb0);
2395         if (rval) {
2396                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2397                     "st_get_conf_from_tape_drive(): "
2398                     "fail to read vitial inquiry.\n");
2399                 rval = 0;
2400                 kmem_free(buf, 6);
2401                 goto exit;
2402         }
2403         if (buf[4] & 1) {
2404                 tem_dp->options |= ST_WORMABLE;
2405         }
2406         kmem_free(buf, 6);
2407 
2408         /* Assume BSD BSR KNOWS_EOD */
2409         tem_dp->options |= ST_BSF | ST_BSR | ST_KNOWS_EOD | ST_UNLOADABLE;
2410         tem_dp->max_rretries = -1;
2411         tem_dp->max_wretries = -1;
2412 
2413         /*
2414          * Decide the densities supported by tape drive by sending
2415          * REPORT DENSITY SUPPORT command.
2416          */
2417         if (st_get_densities_from_tape_drive(un, tem_dp) == 0) {
2418                 goto exit;
2419         }
2420 
2421         /*
2422          * Decide the timeout values for several commands by sending
2423          * REPORT SUPPORTED OPERATION CODES command.
2424          */
2425         rval = st_get_timeout_values_from_tape_drive(un, tem_dp);
2426         if (rval == 0 || ((rval == 1) && (tem_dp->type == ST_TYPE_INVALID))) {
2427                 goto exit;
2428         }
2429 
2430         bcopy(tem_dp, dp, sizeof (struct st_drivetype));
2431         rval = 1;
2432 
2433 exit:
2434         un->un_status = KEY_NO_SENSE;
2435         kmem_free(tem_dp, sizeof (struct st_drivetype));
2436         return (rval);
2437 }
2438 
2439 static int
2440 st_get_densities_from_tape_drive(struct scsi_tape *un,
2441     struct st_drivetype *dp)
2442 {
2443         int i, p;
2444         size_t buflen;
2445         ushort_t des_len;
2446         uchar_t *den_header;
2447         uchar_t num_den;
2448         uchar_t den[NDENSITIES];
2449         uchar_t deflt[NDENSITIES];
2450         struct report_density_desc *den_desc;
2451 
2452         ST_FUNC(ST_DEVINFO, st_get_densities_from_type_drive);
2453 
2454         /*
2455          * Since we have no idea how many densitiy support entries
2456          * will be returned, we send the command firstly assuming
2457          * there is only one. Then we can decide the number of
2458          * entries by available density support length. If multiple
2459          * entries exist, we will resend the command with enough
2460          * buffer size.
2461          */
2462         buflen = sizeof (struct report_density_header) +
2463             sizeof (struct report_density_desc);
2464         den_header = kmem_zalloc(buflen, KM_SLEEP);
2465         if (st_report_density_support(un, den_header, buflen) != 0) {
2466                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2467                     "st_get_conf_from_tape_drive(): fail to report density.\n");
2468                 kmem_free(den_header, buflen);
2469                 return (0);
2470         }
2471         des_len =
2472             BE_16(((struct report_density_header *)den_header)->ava_dens_len);
2473         num_den = (des_len - 2) / sizeof (struct report_density_desc);
2474 
2475         if (num_den > 1) {
2476                 kmem_free(den_header, buflen);
2477                 buflen = sizeof (struct report_density_header) +
2478                     sizeof (struct report_density_desc) * num_den;
2479                 den_header = kmem_zalloc(buflen, KM_SLEEP);
2480                 if (st_report_density_support(un, den_header, buflen) != 0) {
2481                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2482                             "st_get_conf_from_tape_drive(): "
2483                             "fail to report density.\n");
2484                         kmem_free(den_header, buflen);
2485                         return (0);
2486                 }
2487         }
2488 
2489         den_desc = (struct report_density_desc *)(den_header
2490             + sizeof (struct report_density_header));
2491 
2492         /*
2493          * Decide the drive type by assigning organization
2494          */
2495         for (i = 0; i < ST_NUM_MEMBERS(st_vid_dt); i ++) {
2496                 if (strncmp(st_vid_dt[i].vid, (char *)(den_desc->ass_org),
2497                     8) == 0) {
2498                         dp->type = st_vid_dt[i].type;
2499                         break;
2500                 }
2501         }
2502         if (i == ST_NUM_MEMBERS(st_vid_dt)) {
2503                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2504                     "st_get_conf_from_tape_drive(): "
2505                     "can't find match of assigned ort.\n");
2506                 kmem_free(den_header, buflen);
2507                 return (0);
2508         }
2509 
2510         /*
2511          * The tape drive may support many tape formats, but the st driver
2512          * supports only the four highest densities. Since density code
2513          * values are returned by ascending sequence, we start from the
2514          * last entry of density support data block descriptor.
2515          */
2516         p = 0;
2517         den_desc += num_den - 1;
2518         for (i = 0; i < num_den && p < NDENSITIES; i ++, den_desc --) {
2519                 if ((den_desc->pri_den != 0) && (den_desc->wrtok)) {
2520                         if (p != 0) {
2521                                 if (den_desc->pri_den >= den[p - 1]) {
2522                                         continue;
2523                                 }
2524                         }
2525                         den[p] = den_desc->pri_den;
2526                         deflt[p] = den_desc->deflt;
2527                         p ++;
2528                 }
2529         }
2530 
2531         switch (p) {
2532         case 0:
2533                 bzero(dp->densities, NDENSITIES);
2534                 dp->options |= ST_AUTODEN_OVERRIDE;
2535                 dp->default_density = MT_DENSITY4;
2536                 break;
2537 
2538         case 1:
2539                 (void) memset(dp->densities, den[0], NDENSITIES);
2540                 dp->options |= ST_AUTODEN_OVERRIDE;
2541                 dp->default_density = MT_DENSITY4;
2542                 break;
2543 
2544         case 2:
2545                 dp->densities[0] = den[1];
2546                 dp->densities[1] = den[1];
2547                 dp->densities[2] = den[0];
2548                 dp->densities[3] = den[0];
2549                 if (deflt[0]) {
2550                         dp->default_density = MT_DENSITY4;
2551                 } else {
2552                         dp->default_density = MT_DENSITY2;
2553                 }
2554                 break;
2555 
2556         case 3:
2557                 dp->densities[0] = den[2];
2558                 dp->densities[1] = den[1];
2559                 dp->densities[2] = den[0];
2560                 dp->densities[3] = den[0];
2561                 if (deflt[0]) {
2562                         dp->default_density = MT_DENSITY4;
2563                 } else if (deflt[1]) {
2564                         dp->default_density = MT_DENSITY2;
2565                 } else {
2566                         dp->default_density = MT_DENSITY1;
2567                 }
2568                 break;
2569 
2570         default:
2571                 for (i = p; i > p - NDENSITIES; i --) {
2572                         dp->densities[i - 1] = den[p - i];
2573                 }
2574                 if (deflt[0]) {
2575                         dp->default_density = MT_DENSITY4;
2576                 } else if (deflt[1]) {
2577                         dp->default_density = MT_DENSITY3;
2578                 } else if (deflt[2]) {
2579                         dp->default_density = MT_DENSITY2;
2580                 } else {
2581                         dp->default_density = MT_DENSITY1;
2582                 }
2583                 break;
2584         }
2585 
2586         bzero(dp->mediatype, NDENSITIES);
2587 
2588         kmem_free(den_header, buflen);
2589         return (1);
2590 }
2591 
2592 static int
2593 st_get_timeout_values_from_tape_drive(struct scsi_tape *un,
2594     struct st_drivetype *dp)
2595 {
2596         ushort_t timeout;
2597         int rval;
2598 
2599         ST_FUNC(ST_DEVINFO, st_get_timeout_values_from_type_drive);
2600 
2601         rval = st_get_timeouts_value(un, SCMD_ERASE, &timeout, 0);
2602         if (rval) {
2603                 if (rval == EACCES) {
2604                         un->un_dp->type = ST_TYPE_INVALID;
2605                         dp->type = ST_TYPE_INVALID;
2606                         return (1);
2607                 }
2608                 return (0);
2609         }
2610         dp->erase_timeout = timeout;
2611 
2612         rval = st_get_timeouts_value(un, SCMD_READ, &timeout, 0);
2613         if (rval) {
2614                 if (rval == EACCES) {
2615                         un->un_dp->type = ST_TYPE_INVALID;
2616                         dp->type = ST_TYPE_INVALID;
2617                         return (1);
2618                 }
2619                 return (0);
2620         }
2621         dp->io_timeout = timeout;
2622 
2623         rval = st_get_timeouts_value(un, SCMD_WRITE, &timeout, 0);
2624         if (rval) {
2625                 if (rval == EACCES) {
2626                         un->un_dp->type = ST_TYPE_INVALID;
2627                         dp->type = ST_TYPE_INVALID;
2628                         return (1);
2629                 }
2630                 return (0);
2631         }
2632         dp->io_timeout = max(dp->io_timeout, timeout);
2633 
2634         rval = st_get_timeouts_value(un, SCMD_SPACE, &timeout, 0);
2635         if (rval) {
2636                 if (rval == EACCES) {
2637                         un->un_dp->type = ST_TYPE_INVALID;
2638                         dp->type = ST_TYPE_INVALID;
2639                         return (1);
2640                 }
2641                 return (0);
2642         }
2643         dp->space_timeout = timeout;
2644 
2645         rval = st_get_timeouts_value(un, SCMD_LOAD, &timeout, 0);
2646         if (rval) {
2647                 if (rval == EACCES) {
2648                         un->un_dp->type = ST_TYPE_INVALID;
2649                         dp->type = ST_TYPE_INVALID;
2650                         return (1);
2651                 }
2652                 return (0);
2653         }
2654         dp->load_timeout = timeout;
2655         dp->unload_timeout = timeout;
2656 
2657         rval = st_get_timeouts_value(un, SCMD_REWIND, &timeout, 0);
2658         if (rval) {
2659                 if (rval == EACCES) {
2660                         un->un_dp->type = ST_TYPE_INVALID;
2661                         dp->type = ST_TYPE_INVALID;
2662                         return (1);
2663                 }
2664                 return (0);
2665         }
2666         dp->rewind_timeout = timeout;
2667 
2668         rval = st_get_timeouts_value(un, SCMD_INQUIRY, &timeout, 0);
2669         if (rval) {
2670                 if (rval == EACCES) {
2671                         un->un_dp->type = ST_TYPE_INVALID;
2672                         dp->type = ST_TYPE_INVALID;
2673                         return (1);
2674                 }
2675                 return (0);
2676         }
2677         dp->non_motion_timeout = timeout;
2678 
2679         return (1);
2680 }
2681 
2682 static int
2683 st_get_timeouts_value(struct scsi_tape *un, uchar_t option_code,
2684     ushort_t *timeout_value, ushort_t service_action)
2685 {
2686         uchar_t *timeouts;
2687         uchar_t *oper;
2688         uchar_t support;
2689         uchar_t cdbsize;
2690         uchar_t ctdp;
2691         size_t buflen;
2692         int rval;
2693 
2694         ST_FUNC(ST_DEVINFO, st_get_timeouts_value);
2695 
2696         buflen = sizeof (struct one_com_des) +
2697             sizeof (struct com_timeout_des);
2698         oper = kmem_zalloc(buflen, KM_SLEEP);
2699         rval = st_report_supported_operation(un, oper, option_code,
2700             service_action);
2701 
2702         if (rval) {
2703                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2704                     "st_get_timeouts_value(): "
2705                     "fail to timeouts value for command %d.\n", option_code);
2706                 kmem_free(oper, buflen);
2707                 return (rval);
2708         }
2709 
2710         support = ((struct one_com_des *)oper)->support;
2711         if ((support != SUPPORT_VALUES_SUPPORT_SCSI) &&
2712             (support != SUPPORT_VALUES_SUPPORT_VENDOR)) {
2713                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2714                     "st_get_timeouts_value(): "
2715                     "command %d is not supported.\n", option_code);
2716                 kmem_free(oper, buflen);
2717                 return (ENOTSUP);
2718         }
2719 
2720         ctdp = ((struct one_com_des *)oper)->ctdp;
2721         if (!ctdp) {
2722                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2723                     "st_get_timeouts_value(): "
2724                     "command timeout is not included.\n");
2725                 kmem_free(oper, buflen);
2726                 return (ENOTSUP);
2727         }
2728 
2729         cdbsize = BE_16(((struct one_com_des *)oper)->cdb_size);
2730         timeouts = (uchar_t *)(oper + cdbsize + 4);
2731 
2732         /*
2733          * Timeout value in seconds is 4 bytes, but we only support the lower 2
2734          * bytes. If the higher 2 bytes are not zero, the timeout value is set
2735          * to 0xFFFF.
2736          */
2737         if (*(timeouts + 8) != 0 || *(timeouts + 9) != 0) {
2738                 *timeout_value = USHRT_MAX;
2739         } else {
2740                 *timeout_value = ((*(timeouts + 10)) << 8) |
2741                     (*(timeouts + 11));
2742         }
2743 
2744         kmem_free(oper, buflen);
2745         return (0);
2746 }
2747 
2748 static int
2749 st_get_default_conf(struct scsi_tape *un, char *vidpid, struct st_drivetype *dp)
2750 {
2751         int i;
2752 
2753         ST_FUNC(ST_DEVINFO, st_get_default_conf);
2754 
2755         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
2756             "st_get_default_conf(): making drivetype from INQ cmd\n");
2757 
2758         /*
2759          * Make up a name
2760          */
2761         bcopy("Vendor '", dp->name, 8);
2762         bcopy(vidpid, &dp->name[8], VIDLEN);
2763         bcopy("' Product '", &dp->name[16], 11);
2764         bcopy(&vidpid[8], &dp->name[27], PIDLEN);
2765         dp->name[ST_NAMESIZE - 2] = '\'';
2766         dp->name[ST_NAMESIZE - 1] = '\0';
2767         dp->length = min(strlen(ST_INQUIRY->inq_vid), (VIDPIDLEN - 1));
2768         (void) strncpy(dp->vid, ST_INQUIRY->inq_vid, dp->length);
2769         /*
2770          * 'clean' vendor and product strings of non-printing chars
2771          */
2772         for (i = 0; i < ST_NAMESIZE - 2; i++) {
2773                 if (dp->name[i] < ' ' || dp->name[i] > '~') {
2774                         dp->name[i] = '.';
2775                 }
2776         }
2777         dp->type = ST_TYPE_INVALID;
2778         dp->options |= (ST_DYNAMIC | ST_UNLOADABLE | ST_MODE_SEL_COMP);
2779 
2780         return (1); /* Can Not Fail */
2781 }
2782 
2783 /*
2784  * Regular Unix Entry points
2785  */
2786 
2787 
2788 
2789 /* ARGSUSED */
2790 static int
2791 st_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
2792 {
2793         dev_t dev = *dev_p;
2794         int rval = 0;
2795 
2796         GET_SOFT_STATE(dev);
2797 
2798         ST_ENTR(ST_DEVINFO, st_open);
2799 
2800         /*
2801          * validate that we are addressing a sensible unit
2802          */
2803         mutex_enter(ST_MUTEX);
2804 
2805         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2806             "st_open(node = %s dev = 0x%lx, flag = %d, otyp = %d)\n",
2807             st_dev_name(dev), *dev_p, flag, otyp);
2808 
2809         /*
2810          * All device accesss go thru st_strategy() where we check
2811          * suspend status
2812          */
2813 
2814         if (!un->un_attached) {
2815                 st_known_tape_type(un);
2816                 if (!un->un_attached) {
2817                         rval = ENXIO;
2818                         goto exit;
2819                 }
2820 
2821         }
2822 
2823         /*
2824          * Check for the case of the tape in the middle of closing.
2825          * This isn't simply a check of the current state, because
2826          * we could be in state of sensing with the previous state
2827          * that of closing.
2828          *
2829          * And don't allow multiple opens.
2830          */
2831         if (!(flag & (FNDELAY | FNONBLOCK)) && IS_CLOSING(un)) {
2832                 un->un_laststate = un->un_state;
2833                 un->un_state = ST_STATE_CLOSE_PENDING_OPEN;
2834                 while (IS_CLOSING(un) ||
2835                     un->un_state == ST_STATE_CLOSE_PENDING_OPEN) {
2836                         if (cv_wait_sig(&un->un_clscv, ST_MUTEX) == 0) {
2837                                 rval = EINTR;
2838                                 un->un_state = un->un_laststate;
2839                                 goto exit;
2840                         }
2841                 }
2842         } else if (un->un_state != ST_STATE_CLOSED) {
2843                 rval = EBUSY;
2844                 goto busy;
2845         }
2846 
2847         /*
2848          * record current dev
2849          */
2850         un->un_dev = dev;
2851         un->un_oflags = flag;        /* save for use in st_tape_init() */
2852         un->un_errno = 0;    /* no errors yet */
2853         un->un_restore_pos = 0;
2854         un->un_rqs_state = 0;
2855 
2856         /*
2857          * If we are opening O_NDELAY, or O_NONBLOCK, we don't check for
2858          * anything, leave internal states alone, if fileno >= 0
2859          */
2860         if (flag & (FNDELAY | FNONBLOCK)) {
2861                 switch (un->un_pos.pmode) {
2862 
2863                 case invalid:
2864                         un->un_state = ST_STATE_OFFLINE;
2865                         break;
2866 
2867                 case legacy:
2868                         /*
2869                          * If position is anything other than rewound.
2870                          */
2871                         if (un->un_pos.fileno != 0 || un->un_pos.blkno != 0) {
2872                                 /*
2873                                  * set un_read_only/write-protect status.
2874                                  *
2875                                  * If the tape is not bot we can assume
2876                                  * that mspl->wp_status is set properly.
2877                                  * else
2878                                  * we need to do a mode sense/Tur once
2879                                  * again to get the actual tape status.(since
2880                                  * user might have replaced the tape)
2881                                  * Hence make the st state OFFLINE so that
2882                                  * we re-intialize the tape once again.
2883                                  */
2884                                 un->un_read_only =
2885                                     (un->un_oflags & FWRITE) ? RDWR : RDONLY;
2886                                 un->un_state = ST_STATE_OPEN_PENDING_IO;
2887                         } else {
2888                                 un->un_state = ST_STATE_OFFLINE;
2889                         }
2890                         break;
2891                 case logical:
2892                         if (un->un_pos.lgclblkno == 0) {
2893                                 un->un_state = ST_STATE_OFFLINE;
2894                         } else {
2895                                 un->un_read_only =
2896                                     (un->un_oflags & FWRITE) ? RDWR : RDONLY;
2897                                 un->un_state = ST_STATE_OPEN_PENDING_IO;
2898                         }
2899                         break;
2900                 }
2901                 rval = 0;
2902         } else {
2903                 /*
2904                  * Not opening O_NDELAY.
2905                  */
2906                 un->un_state = ST_STATE_OPENING;
2907 
2908                 /*
2909                  * Clear error entry stack
2910                  */
2911                 st_empty_error_stack(un);
2912 
2913                 rval = st_tape_init(un);
2914                 if ((rval == EACCES) && (un->un_read_only & WORM)) {
2915                         un->un_state = ST_STATE_OPEN_PENDING_IO;
2916                         rval = 0; /* so open doesn't fail */
2917                 } else if (rval) {
2918                         /*
2919                          * Release the tape unit, if reserved and not
2920                          * preserve reserve.
2921                          */
2922                         if ((un->un_rsvd_status &
2923                             (ST_RESERVE | ST_PRESERVE_RESERVE)) == ST_RESERVE) {
2924                                 (void) st_reserve_release(un, ST_RELEASE,
2925                                     st_uscsi_cmd);
2926                         }
2927                 } else {
2928                         un->un_state = ST_STATE_OPEN_PENDING_IO;
2929                 }
2930         }
2931 
2932 exit:
2933         /*
2934          * we don't want any uninvited guests scrogging our data when we're
2935          * busy with something, so for successful opens or failed opens
2936          * (except for EBUSY), reset these counters and state appropriately.
2937          */
2938         if (rval != EBUSY) {
2939                 if (rval) {
2940                         un->un_state = ST_STATE_CLOSED;
2941                 }
2942                 un->un_err_resid = 0;
2943                 un->un_retry_ct = 0;
2944         }
2945 busy:
2946         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2947             "st_open: return val = %x, state = %d\n", rval, un->un_state);
2948         mutex_exit(ST_MUTEX);
2949         return (rval);
2950 
2951 }
2952 
2953 static int
2954 st_tape_init(struct scsi_tape *un)
2955 {
2956         int err;
2957         int rval = 0;
2958 
2959         ST_FUNC(ST_DEVINFO, st_tape_init);
2960 
2961         ASSERT(mutex_owned(ST_MUTEX));
2962 
2963         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2964             "st_tape_init(un = 0x%p, oflags = %d)\n", (void*)un, un->un_oflags);
2965 
2966         /*
2967          * Clean up after any errors left by 'last' close.
2968          * This also handles the case of the initial open.
2969          */
2970         if (un->un_state != ST_STATE_INITIALIZING) {
2971                 un->un_laststate = un->un_state;
2972                 un->un_state = ST_STATE_OPENING;
2973         }
2974 
2975         un->un_kbytes_xferred = 0;
2976 
2977         /*
2978          * do a throw away TUR to clear check condition
2979          */
2980         err = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
2981 
2982         /*
2983          * If test unit ready fails because the drive is reserved
2984          * by another host fail the open for no access.
2985          */
2986         if (err) {
2987                 if (un->un_rsvd_status & ST_RESERVATION_CONFLICT) {
2988                         un->un_state = ST_STATE_CLOSED;
2989                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2990                             "st_tape_init: RESERVATION CONFLICT\n");
2991                         rval = EACCES;
2992                         goto exit;
2993                 } else if ((un->un_rsvd_status &
2994                     ST_APPLICATION_RESERVATIONS) != 0) {
2995                         if ((ST_RQSENSE != NULL) &&
2996                             (ST_RQSENSE->es_add_code == 0x2a &&
2997                             ST_RQSENSE->es_qual_code == 0x03)) {
2998                                 un->un_state = ST_STATE_CLOSED;
2999                                 rval = EACCES;
3000                                 goto exit;
3001                         }
3002                 }
3003         }
3004 
3005         /*
3006          * Tape self identification could fail if the tape drive is used by
3007          * another host during attach time. We try to get the tape type
3008          * again. This is also applied to any posponed configuration methods.
3009          */
3010         if (un->un_dp->type == ST_TYPE_INVALID) {
3011                 un->un_comp_page = ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE;
3012                 st_known_tape_type(un);
3013         }
3014 
3015         /*
3016          * If the tape type is still invalid, try to determine the generic
3017          * configuration.
3018          */
3019         if (un->un_dp->type == ST_TYPE_INVALID) {
3020                 rval = st_determine_generic(un);
3021                 if (rval) {
3022                         if (rval != EACCES) {
3023                                 rval = EIO;
3024                         }
3025                         un->un_state = ST_STATE_CLOSED;
3026                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3027                             "st_tape_init: %s invalid type\n",
3028                             rval == EACCES ? "EACCES" : "EIO");
3029                         goto exit;
3030                 }
3031                 /*
3032                  * If this is a Unknown Type drive,
3033                  * Use the READ BLOCK LIMITS to determine if
3034                  * allow large xfer is approprate if not globally
3035                  * disabled with st_allow_large_xfer.
3036                  */
3037                 un->un_allow_large_xfer = (uchar_t)st_allow_large_xfer;
3038         } else {
3039 
3040                 /*
3041                  * If we allow_large_xfer (ie >64k) and have not yet found out
3042                  * the max block size supported by the drive,
3043                  * find it by issueing a READ_BLKLIM command.
3044                  * if READ_BLKLIM cmd fails, assume drive doesn't
3045                  * allow_large_xfer and min/max block sizes as 1 byte and 63k.
3046                  */
3047                 un->un_allow_large_xfer = st_allow_large_xfer &&
3048                     (un->un_dp->options & ST_NO_RECSIZE_LIMIT);
3049         }
3050         /*
3051          * if maxbsize is unknown, set the maximum block size.
3052          */
3053         if (un->un_maxbsize == MAXBSIZE_UNKNOWN) {
3054 
3055                 /*
3056                  * Get the Block limits of the tape drive.
3057                  * if un->un_allow_large_xfer = 0 , then make sure
3058                  * that maxbsize is <= ST_MAXRECSIZE_FIXED.
3059                  */
3060                 un->un_rbl = kmem_zalloc(RBLSIZE, KM_SLEEP);
3061 
3062                 err = st_cmd(un, SCMD_READ_BLKLIM, RBLSIZE, SYNC_CMD);
3063                 if (err) {
3064                         /* Retry */
3065                         err = st_cmd(un, SCMD_READ_BLKLIM, RBLSIZE, SYNC_CMD);
3066                 }
3067                 if (!err) {
3068 
3069                         /*
3070                          * if cmd successful, use limit returned
3071                          */
3072                         un->un_maxbsize = (un->un_rbl->max_hi << 16) +
3073                             (un->un_rbl->max_mid << 8) +
3074                             un->un_rbl->max_lo;
3075                         un->un_minbsize = (un->un_rbl->min_hi << 8) +
3076                             un->un_rbl->min_lo;
3077                         un->un_data_mod = 1 << un->un_rbl->granularity;
3078                         if ((un->un_maxbsize == 0) ||
3079                             (un->un_allow_large_xfer == 0 &&
3080                             un->un_maxbsize > ST_MAXRECSIZE_FIXED)) {
3081                                 un->un_maxbsize = ST_MAXRECSIZE_FIXED;
3082 
3083                         } else if (un->un_dp->type == ST_TYPE_DEFAULT) {
3084                                 /*
3085                                  * Drive is not one that is configured, But the
3086                                  * READ BLOCK LIMITS tells us it can do large
3087                                  * xfers.
3088                                  */
3089                                 if (un->un_maxbsize > ST_MAXRECSIZE_FIXED) {
3090                                         un->un_dp->options |=
3091                                             ST_NO_RECSIZE_LIMIT;
3092                                 }
3093                                 /*
3094                                  * If max and mimimum block limits are the
3095                                  * same this is a fixed block size device.
3096                                  */
3097                                 if (un->un_maxbsize == un->un_minbsize) {
3098                                         un->un_dp->options &= ~ST_VARIABLE;
3099                                 }
3100                         }
3101 
3102                         if (un->un_minbsize == 0) {
3103                                 un->un_minbsize = 1;
3104                         }
3105 
3106                 } else { /* error on read block limits */
3107 
3108                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
3109                             "!st_tape_init: Error on READ BLOCK LIMITS,"
3110                             " errno = %d un_rsvd_status = 0x%X\n",
3111                             err, un->un_rsvd_status);
3112 
3113                         /*
3114                          * since read block limits cmd failed,
3115                          * do not allow large xfers.
3116                          * use old values in st_minphys
3117                          */
3118                         if (un->un_rsvd_status & ST_RESERVATION_CONFLICT) {
3119                                 rval = EACCES;
3120                         } else {
3121                                 un->un_allow_large_xfer = 0;
3122                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
3123                                     "!Disabling large transfers\n");
3124 
3125                                 /*
3126                                  * we guess maxbsize and minbsize
3127                                  */
3128                                 if (un->un_bsize) {
3129                                         un->un_maxbsize = un->un_minbsize =
3130                                             un->un_bsize;
3131                                 } else {
3132                                         un->un_maxbsize = ST_MAXRECSIZE_FIXED;
3133                                         un->un_minbsize = 1;
3134                                 }
3135                                 /*
3136                                  * Data Mod must be set,
3137                                  * Even if read block limits fails.
3138                                  * Prevents Divide By Zero in st_rw().
3139                                  */
3140                                 un->un_data_mod = 1;
3141                         }
3142                 }
3143                 if (un->un_rbl) {
3144                         kmem_free(un->un_rbl, RBLSIZE);
3145                         un->un_rbl = NULL;
3146                 }
3147 
3148                 if (rval) {
3149                         goto exit;
3150                 }
3151         }
3152 
3153         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
3154             "maxdma = %d, maxbsize = %d, minbsize = %d, %s large xfer\n",
3155             un->un_maxdma, un->un_maxbsize, un->un_minbsize,
3156             (un->un_allow_large_xfer ? "ALLOW": "DON'T ALLOW"));
3157 
3158         err = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
3159 
3160         if (err != 0) {
3161                 if (err == EINTR) {
3162                         un->un_laststate = un->un_state;
3163                         un->un_state = ST_STATE_CLOSED;
3164                         rval = EINTR;
3165                         goto exit;
3166                 }
3167                 /*
3168                  * Make sure the tape is ready
3169                  */
3170                 un->un_pos.pmode = invalid;
3171                 if (un->un_status != KEY_UNIT_ATTENTION) {
3172                         /*
3173                          * allow open no media.  Subsequent MTIOCSTATE
3174                          * with media present will complete the open
3175                          * logic.
3176                          */
3177                         un->un_laststate = un->un_state;
3178                         if (un->un_oflags & (FNONBLOCK|FNDELAY)) {
3179                                 un->un_mediastate = MTIO_EJECTED;
3180                                 un->un_state = ST_STATE_OFFLINE;
3181                                 rval = 0;
3182                                 goto exit;
3183                         } else {
3184                                 un->un_state = ST_STATE_CLOSED;
3185                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3186                                     "st_tape_init EIO no media, not opened "
3187                                     "O_NONBLOCK|O_EXCL\n");
3188                                 rval = EIO;
3189                                 goto exit;
3190                         }
3191                 }
3192         }
3193 
3194         /*
3195          * On each open, initialize block size from drivetype struct,
3196          * as it could have been changed by MTSRSZ ioctl.
3197          * Now, ST_VARIABLE simply means drive is capable of variable
3198          * mode. All drives are assumed to support fixed records.
3199          * Hence, un_bsize tells what mode the drive is in.
3200          *      un_bsize        = 0     - variable record length
3201          *                      = x     - fixed record length is x
3202          */
3203         un->un_bsize = un->un_dp->bsize;
3204 
3205         /*
3206          * If saved position is valid go there
3207          */
3208         if (un->un_restore_pos) {
3209                 un->un_restore_pos = 0;
3210                 un->un_pos.fileno = un->un_save_fileno;
3211                 un->un_pos.blkno = un->un_save_blkno;
3212                 rval = st_validate_tapemarks(un, st_uscsi_cmd, &un->un_pos);
3213                 if (rval != 0) {
3214                         if (rval != EACCES) {
3215                                 rval = EIO;
3216                         }
3217                         un->un_laststate = un->un_state;
3218                         un->un_state = ST_STATE_CLOSED;
3219                         goto exit;
3220                 }
3221         }
3222 
3223         if (un->un_pos.pmode == invalid) {
3224                 rval = st_loadtape(un);
3225                 if (rval) {
3226                         if (rval != EACCES) {
3227                                 rval = EIO;
3228                         }
3229                         un->un_laststate = un->un_state;
3230                         un->un_state = ST_STATE_CLOSED;
3231                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3232                             "st_tape_init: %s can't open tape\n",
3233                             rval == EACCES ? "EACCES" : "EIO");
3234                         goto exit;
3235                 }
3236         }
3237 
3238         /*
3239          * do a mode sense to pick up state of current write-protect,
3240          * Could cause reserve and fail due to conflict.
3241          */
3242         if (un->un_unit_attention_flags) {
3243                 rval = st_modesense(un);
3244                 if (rval == EACCES) {
3245                         goto exit;
3246                 }
3247         }
3248 
3249         /*
3250          * If we are opening the tape for writing, check
3251          * to make sure that the tape can be written.
3252          */
3253         if (un->un_oflags & FWRITE) {
3254                 err = 0;
3255                 if (un->un_mspl->wp) {
3256                         un->un_status = KEY_WRITE_PROTECT;
3257                         un->un_laststate = un->un_state;
3258                         un->un_state = ST_STATE_CLOSED;
3259                         rval = EACCES;
3260                         /*
3261                          * STK sets the wp bit if volsafe tape is loaded.
3262                          */
3263                         if ((un->un_dp->type == MT_ISSTK9840) &&
3264                             (un->un_dp->options & ST_WORMABLE)) {
3265                                 un->un_read_only = RDONLY;
3266                         } else {
3267                                 goto exit;
3268                         }
3269                 } else {
3270                         un->un_read_only = RDWR;
3271                 }
3272         } else {
3273                 un->un_read_only = RDONLY;
3274         }
3275 
3276         if (un->un_dp->options & ST_WORMABLE &&
3277             un->un_unit_attention_flags) {
3278                 un->un_read_only |= un->un_wormable(un);
3279 
3280                 if (((un->un_read_only == WORM) ||
3281                     (un->un_read_only == RDWORM)) &&
3282                     ((un->un_oflags & FWRITE) == FWRITE)) {
3283                         un->un_status = KEY_DATA_PROTECT;
3284                         rval = EACCES;
3285                         ST_DEBUG4(ST_DEVINFO, st_label, CE_NOTE,
3286                             "read_only = %d eof = %d oflag = %d\n",
3287                             un->un_read_only, un->un_pos.eof, un->un_oflags);
3288                 }
3289         }
3290 
3291         /*
3292          * If we're opening the tape write-only, we need to
3293          * write 2 filemarks on the HP 1/2 inch drive, to
3294          * create a null file.
3295          */
3296         if ((un->un_read_only == RDWR) ||
3297             (un->un_read_only == WORM) && (un->un_oflags & FWRITE)) {
3298                 if (un->un_dp->options & ST_REEL) {
3299                         un->un_fmneeded = 2;
3300                 } else {
3301                         un->un_fmneeded = 1;
3302                 }
3303         } else {
3304                 un->un_fmneeded = 0;
3305         }
3306 
3307         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
3308             "fmneeded = %x\n", un->un_fmneeded);
3309 
3310         /*
3311          * Make sure the density can be selected correctly.
3312          * If WORM can only write at the append point which in most cases
3313          * isn't BOP. st_determine_density() with a B_WRITE only attempts
3314          * to set and try densities if a BOP.
3315          */
3316         if (st_determine_density(un,
3317             un->un_read_only == RDWR ? B_WRITE : B_READ)) {
3318                 un->un_status = KEY_ILLEGAL_REQUEST;
3319                 un->un_laststate = un->un_state;
3320                 un->un_state = ST_STATE_CLOSED;
3321                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
3322                     "st_tape_init: EIO can't determine density\n");
3323                 rval = EIO;
3324                 goto exit;
3325         }
3326 
3327         /*
3328          * Destroy the knowledge that we have 'determined'
3329          * density so that a later read at BOT comes along
3330          * does the right density determination.
3331          */
3332 
3333         un->un_density_known = 0;
3334 
3335 
3336         /*
3337          * Okay, the tape is loaded and either at BOT or somewhere past.
3338          * Mark the state such that any I/O or tape space operations
3339          * will get/set the right density, etc..
3340          */
3341         un->un_laststate = un->un_state;
3342         un->un_lastop = ST_OP_NIL;
3343         un->un_mediastate = MTIO_INSERTED;
3344         cv_broadcast(&un->un_state_cv);
3345 
3346         /*
3347          *  Set test append flag if writing.
3348          *  First write must check that tape is positioned correctly.
3349          */
3350         un->un_test_append = (un->un_oflags & FWRITE);
3351 
3352         /*
3353          * if there are pending unit attention flags.
3354          * Check that the media has not changed.
3355          */
3356         if (un->un_unit_attention_flags) {
3357                 rval = st_get_media_identification(un, st_uscsi_cmd);
3358                 if (rval != 0 && rval != EACCES) {
3359                         rval = EIO;
3360                 }
3361                 un->un_unit_attention_flags = 0;
3362         }
3363 
3364 exit:
3365         un->un_err_resid = 0;
3366         un->un_last_resid = 0;
3367         un->un_last_count = 0;
3368 
3369         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3370             "st_tape_init: return val = %x\n", rval);
3371         return (rval);
3372 
3373 }
3374 
3375 
3376 
3377 /* ARGSUSED */
3378 static int
3379 st_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
3380 {
3381         int err = 0;
3382         int count, last_state;
3383         minor_t minor = getminor(dev);
3384 #ifdef  __x86
3385         struct contig_mem *cp, *cp_temp;
3386 #endif
3387 
3388         GET_SOFT_STATE(dev);
3389 
3390         ST_ENTR(ST_DEVINFO, st_close);
3391 
3392         /*
3393          * wait till all cmds in the pipeline have been completed
3394          */
3395         mutex_enter(ST_MUTEX);
3396 
3397         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3398             "st_close(dev = 0x%lx, flag = %d, otyp = %d)\n", dev, flag, otyp);
3399 
3400         st_wait_for_io(un);
3401 
3402         /* turn off persistent errors on close, as we want close to succeed */
3403         st_turn_pe_off(un);
3404 
3405         /*
3406          * set state to indicate that we are in process of closing
3407          */
3408         last_state = un->un_laststate = un->un_state;
3409         un->un_state = ST_STATE_CLOSING;
3410 
3411         ST_POS(ST_DEVINFO, "st_close1:", &un->un_pos);
3412 
3413         /*
3414          * BSD behavior:
3415          * a close always causes a silent span to the next file if we've hit
3416          * an EOF (but not yet read across it).
3417          */
3418         if ((minor & MT_BSD) && (un->un_pos.eof == ST_EOF)) {
3419                 if (un->un_pos.pmode != invalid) {
3420                         un->un_pos.fileno++;
3421                         un->un_pos.blkno = 0;
3422                 }
3423                 un->un_pos.eof = ST_NO_EOF;
3424         }
3425 
3426         /*
3427          * SVR4 behavior for skipping to next file:
3428          *
3429          * If we have not seen a filemark, space to the next file
3430          *
3431          * If we have already seen the filemark we are physically in the next
3432          * file and we only increment the filenumber
3433          */
3434         if (((minor & (MT_BSD | MT_NOREWIND)) == MT_NOREWIND) &&
3435             (flag & FREAD) &&               /* reading or at least asked to */
3436             (un->un_mediastate == MTIO_INSERTED) &&  /* tape loaded */
3437             (un->un_pos.pmode != invalid) &&         /* XXX position known */
3438             ((un->un_pos.blkno != 0) &&              /* inside a file */
3439             (un->un_lastop != ST_OP_WRITE) &&                /* Didn't just write */
3440             (un->un_lastop != ST_OP_WEOF))) {                /* or write filemarks */
3441                 switch (un->un_pos.eof) {
3442                 case ST_NO_EOF:
3443                         /*
3444                          * if we were reading and did not read the complete file
3445                          * skip to the next file, leaving the tape correctly
3446                          * positioned to read the first record of the next file
3447                          * Check first for REEL if we are at EOT by trying to
3448                          * read a block
3449                          */
3450                         if ((un->un_dp->options & ST_REEL) &&
3451                             (!(un->un_dp->options & ST_READ_IGNORE_EOFS)) &&
3452                             (un->un_pos.blkno == 0)) {
3453                                 if (st_cmd(un, SCMD_SPACE, Blk(1), SYNC_CMD)) {
3454                                         ST_DEBUG2(ST_DEVINFO, st_label,
3455                                             SCSI_DEBUG,
3456                                             "st_close : EIO can't space\n");
3457                                         err = EIO;
3458                                         goto error_out;
3459                                 }
3460                                 if (un->un_pos.eof >= ST_EOF_PENDING) {
3461                                         un->un_pos.eof = ST_EOT_PENDING;
3462                                         un->un_pos.fileno += 1;
3463                                         un->un_pos.blkno   = 0;
3464                                         break;
3465                                 }
3466                         }
3467                         if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
3468                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3469                                     "st_close: EIO can't space #2\n");
3470                                 err = EIO;
3471                                 goto error_out;
3472                         } else {
3473                                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3474                                     "st_close2: fileno=%x,blkno=%x,eof=%x\n",
3475                                     un->un_pos.fileno, un->un_pos.blkno,
3476                                     un->un_pos.eof);
3477                                 un->un_pos.eof = ST_NO_EOF;
3478                         }
3479                         break;
3480 
3481                 case ST_EOF_PENDING:
3482                 case ST_EOF:
3483                         un->un_pos.fileno += 1;
3484                         un->un_pos.lgclblkno += 1;
3485                         un->un_pos.blkno   = 0;
3486                         un->un_pos.eof = ST_NO_EOF;
3487                         break;
3488 
3489                 case ST_EOT:
3490                 case ST_EOT_PENDING:
3491                 case ST_EOM:
3492                         /* nothing to do */
3493                         break;
3494                 default:
3495                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
3496                             "Undefined state 0x%x", un->un_pos.eof);
3497 
3498                 }
3499         }
3500 
3501 
3502         /*
3503          * For performance reasons (HP 88780), the driver should
3504          * postpone writing the second tape mark until just before a file
3505          * positioning ioctl is issued (e.g., rewind).  This means that
3506          * the user must not manually rewind the tape because the tape will
3507          * be missing the second tape mark which marks EOM.
3508          * However, this small performance improvement is not worth the risk.
3509          */
3510 
3511         /*
3512          * We need to back up over the filemark we inadvertently popped
3513          * over doing a read in between the two filemarks that constitute
3514          * logical eot for 1/2" tapes. Note that ST_EOT_PENDING is only
3515          * set while reading.
3516          *
3517          * If we happen to be at physical eot (ST_EOM) (writing case),
3518          * the writing of filemark(s) will clear the ST_EOM state, which
3519          * we don't want, so we save this state and restore it later.
3520          */
3521 
3522         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3523             "flag=%x, fmneeded=%x, lastop=%x, eof=%x\n",
3524             flag, un->un_fmneeded, un->un_lastop, un->un_pos.eof);
3525 
3526         if (un->un_pos.eof == ST_EOT_PENDING) {
3527                 if (minor & MT_NOREWIND) {
3528                         if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
3529                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3530                                     "st_close: EIO can't space #3\n");
3531                                 err = EIO;
3532                                 goto error_out;
3533                         } else {
3534                                 un->un_pos.blkno = 0;
3535                                 un->un_pos.eof = ST_EOT;
3536                         }
3537                 } else {
3538                         un->un_pos.eof = ST_NO_EOF;
3539                 }
3540 
3541         /*
3542          * Do we need to write a file mark?
3543          *
3544          * only write filemarks if there are fmks to be written and
3545          *   - open for write (possibly read/write)
3546          *   - the last operation was a write
3547          * or:
3548          *   -  opened for wronly
3549          *   -  no data was written
3550          */
3551         } else if ((un->un_pos.pmode != invalid) &&
3552             (un->un_fmneeded > 0) &&
3553             (((flag & FWRITE) &&
3554             ((un->un_lastop == ST_OP_WRITE)||(un->un_lastop == ST_OP_WEOF))) ||
3555             ((flag == FWRITE) && (un->un_lastop == ST_OP_NIL)))) {
3556 
3557                 /* save ST_EOM state */
3558                 int was_at_eom = (un->un_pos.eof == ST_EOM) ? 1 : 0;
3559 
3560                 /*
3561                  * Note that we will write a filemark if we had opened
3562                  * the tape write only and no data was written, thus
3563                  * creating a null file.
3564                  *
3565                  * If the user already wrote one, we only have to write 1 more.
3566                  * If they wrote two, we don't have to write any.
3567                  */
3568 
3569                 count = un->un_fmneeded;
3570                 if (count > 0) {
3571                         if (st_cmd(un, SCMD_WRITE_FILE_MARK, count, SYNC_CMD)) {
3572                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3573                                     "st_close : EIO can't wfm\n");
3574                                 err = EIO;
3575                                 goto error_out;
3576                         }
3577                         if ((un->un_dp->options & ST_REEL) &&
3578                             (minor & MT_NOREWIND)) {
3579                                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
3580                                         ST_DEBUG2(ST_DEVINFO, st_label,
3581                                             SCSI_DEBUG,
3582                                             "st_close : EIO space fmk(-1)\n");
3583                                         err = EIO;
3584                                         goto error_out;
3585                                 }
3586                                 un->un_pos.eof = ST_NO_EOF;
3587                                 /* fix up block number */
3588                                 un->un_pos.blkno = 0;
3589                         }
3590                 }
3591 
3592                 /*
3593                  * If we aren't going to be rewinding, and we were at
3594                  * physical eot, restore the state that indicates we
3595                  * are at physical eot. Once you have reached physical
3596                  * eot, and you close the tape, the only thing you can
3597                  * do on the next open is to rewind. Access to trailer
3598                  * records is only allowed without closing the device.
3599                  */
3600                 if ((minor & MT_NOREWIND) == 0 && was_at_eom) {
3601                         un->un_pos.eof = ST_EOM;
3602                 }
3603         }
3604 
3605         /*
3606          * report soft errors if enabled and available, if we never accessed
3607          * the drive, don't get errors. This will prevent some DAT error
3608          * messages upon LOG SENSE.
3609          */
3610         if (st_report_soft_errors_on_close &&
3611             (un->un_dp->options & ST_SOFT_ERROR_REPORTING) &&
3612             (last_state != ST_STATE_OFFLINE)) {
3613                 if (st_report_soft_errors(dev, flag)) {
3614                         err = EIO;
3615                         goto error_out;
3616                 }
3617         }
3618 
3619 
3620         /*
3621          * Do we need to rewind? Can we rewind?
3622          */
3623         if ((minor & MT_NOREWIND) == 0 &&
3624             un->un_pos.pmode != invalid && err == 0) {
3625                 /*
3626                  * We'd like to rewind with the
3627                  * 'immediate' bit set, but this
3628                  * causes problems on some drives
3629                  * where subsequent opens get a
3630                  * 'NOT READY' error condition
3631                  * back while the tape is rewinding,
3632                  * which is impossible to distinguish
3633                  * from the condition of 'no tape loaded'.
3634                  *
3635                  * Also, for some targets, if you disconnect
3636                  * with the 'immediate' bit set, you don't
3637                  * actually return right away, i.e., the
3638                  * target ignores your request for immediate
3639                  * return.
3640                  *
3641                  * Instead, we'll fire off an async rewind
3642                  * command. We'll mark the device as closed,
3643                  * and any subsequent open will stall on
3644                  * the first TEST_UNIT_READY until the rewind
3645                  * completes.
3646                  */
3647 
3648                 /*
3649                  * Used to be if reserve was not supported we'd send an
3650                  * asynchronious rewind. Comments above may be slightly invalid
3651                  * as the immediate bit was never set. Doing an immedate rewind
3652                  * makes sense, I think fixes to not ready status might handle
3653                  * the problems described above.
3654                  */
3655                 if (un->un_sd->sd_inq->inq_ansi < 2) {
3656                         if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
3657                                 err = EIO;
3658                         }
3659                 } else {
3660                         /* flush data for older drives per scsi spec. */
3661                         if (st_cmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD)) {
3662                                 err = EIO;
3663                         } else {
3664                                 /* release the drive before rewind immediate */
3665                                 if ((un->un_rsvd_status &
3666                                     (ST_RESERVE | ST_PRESERVE_RESERVE)) ==
3667                                     ST_RESERVE) {
3668                                         if (st_reserve_release(un, ST_RELEASE,
3669                                             st_uscsi_cmd)) {
3670                                                 err = EIO;
3671                                         }
3672                                 }
3673 
3674                                 /* send rewind with immediate bit set */
3675                                 if (st_cmd(un, SCMD_REWIND, 1, ASYNC_CMD)) {
3676                                         err = EIO;
3677                                 }
3678                         }
3679                 }
3680                 /*
3681                  * Setting positions invalid in case the rewind doesn't
3682                  * happen. Drives don't like to rewind if resets happen
3683                  * they will tend to move back to where the rewind was
3684                  * issued if a reset or something happens so that if a
3685                  * write happens the data doesn't get clobbered.
3686                  *
3687                  * Not a big deal if the position is invalid when the
3688                  * open occures it will do a read position.
3689                  */
3690                 un->un_pos.pmode = invalid;
3691                 un->un_running.pmode = invalid;
3692 
3693                 if (err == EIO) {
3694                         goto error_out;
3695                 }
3696         }
3697 
3698         /*
3699          * eject tape if necessary
3700          */
3701         if (un->un_eject_tape_on_failure) {
3702                 un->un_eject_tape_on_failure = 0;
3703                 if (st_cmd(un, SCMD_LOAD, LD_UNLOAD, SYNC_CMD)) {
3704                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3705                             "st_close : can't unload tape\n");
3706                         err = EIO;
3707                         goto error_out;
3708                 } else {
3709                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3710                             "st_close : tape unloaded \n");
3711                         un->un_pos.eof = ST_NO_EOF;
3712                         un->un_mediastate = MTIO_EJECTED;
3713                 }
3714         }
3715         /*
3716          * Release the tape unit, if default reserve/release
3717          * behaviour.
3718          */
3719         if ((un->un_rsvd_status &
3720             (ST_RESERVE | ST_PRESERVE_RESERVE |
3721             ST_APPLICATION_RESERVATIONS)) == ST_RESERVE) {
3722                 (void) st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
3723         }
3724 error_out:
3725         /*
3726          * clear up state
3727          */
3728         un->un_laststate = un->un_state;
3729         un->un_state = ST_STATE_CLOSED;
3730         un->un_lastop = ST_OP_NIL;
3731         un->un_throttle = 1; /* assume one request at time, for now */
3732         un->un_retry_ct = 0;
3733         un->un_errno = 0;
3734         un->un_swr_token = (opaque_t)NULL;
3735         un->un_rsvd_status &= ~(ST_INIT_RESERVE);
3736 
3737         /* Restore the options to the init time settings */
3738         if (un->un_init_options & ST_READ_IGNORE_ILI) {
3739                 un->un_dp->options |= ST_READ_IGNORE_ILI;
3740         } else {
3741                 un->un_dp->options &= ~ST_READ_IGNORE_ILI;
3742         }
3743 
3744         if (un->un_init_options & ST_READ_IGNORE_EOFS) {
3745                 un->un_dp->options |= ST_READ_IGNORE_EOFS;
3746         } else {
3747                 un->un_dp->options &= ~ST_READ_IGNORE_EOFS;
3748         }
3749 
3750         if (un->un_init_options & ST_SHORT_FILEMARKS) {
3751                 un->un_dp->options |= ST_SHORT_FILEMARKS;
3752         } else {
3753                 un->un_dp->options &= ~ST_SHORT_FILEMARKS;
3754         }
3755 
3756         ASSERT(mutex_owned(ST_MUTEX));
3757 
3758         /*
3759          * Signal anyone awaiting a close operation to complete.
3760          */
3761         cv_signal(&un->un_clscv);
3762 
3763         /*
3764          * any kind of error on closing causes all state to be tossed
3765          */
3766         if (err && un->un_status != KEY_ILLEGAL_REQUEST) {
3767                 /*
3768                  * note that st_intr has already set
3769                  * un_pos.pmode to invalid.
3770                  */
3771                 un->un_density_known = 0;
3772         }
3773 
3774 #ifdef  __x86
3775         /*
3776          * free any contiguous mem alloc'ed for big block I/O
3777          */
3778         cp = un->un_contig_mem;
3779         while (cp) {
3780                 if (cp->cm_addr) {
3781                         ddi_dma_mem_free(&cp->cm_acc_hdl);
3782                 }
3783                 cp_temp = cp;
3784                 cp = cp->cm_next;
3785                 kmem_free(cp_temp,
3786                     sizeof (struct contig_mem) + biosize());
3787         }
3788         un->un_contig_mem_total_num = 0;
3789         un->un_contig_mem_available_num = 0;
3790         un->un_contig_mem = NULL;
3791         un->un_max_contig_mem_len = 0;
3792 #endif
3793 
3794         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
3795             "st_close3: return val = %x, fileno=%x, blkno=%x, eof=%x\n",
3796             err, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
3797 
3798         mutex_exit(ST_MUTEX);
3799         return (err);
3800 }
3801 
3802 /*
3803  * These routines perform raw i/o operations.
3804  */
3805 
3806 /* ARGSUSED2 */
3807 static int
3808 st_aread(dev_t dev, struct aio_req *aio, cred_t *cred_p)
3809 {
3810 #ifdef STDEBUG
3811         GET_SOFT_STATE(dev);
3812         ST_ENTR(ST_DEVINFO, st_aread);
3813 #endif
3814         return (st_arw(dev, aio, B_READ));
3815 }
3816 
3817 
3818 /* ARGSUSED2 */
3819 static int
3820 st_awrite(dev_t dev, struct aio_req *aio, cred_t *cred_p)
3821 {
3822 #ifdef STDEBUG
3823         GET_SOFT_STATE(dev);
3824         ST_ENTR(ST_DEVINFO, st_awrite);
3825 #endif
3826         return (st_arw(dev, aio, B_WRITE));
3827 }
3828 
3829 
3830 
3831 /* ARGSUSED */
3832 static int
3833 st_read(dev_t dev, struct uio *uiop, cred_t *cred_p)
3834 {
3835 #ifdef STDEBUG
3836         GET_SOFT_STATE(dev);
3837         ST_ENTR(ST_DEVINFO, st_read);
3838 #endif
3839         return (st_rw(dev, uiop, B_READ));
3840 }
3841 
3842 /* ARGSUSED */
3843 static int
3844 st_write(dev_t dev, struct uio *uiop, cred_t *cred_p)
3845 {
3846 #ifdef STDEBUG
3847         GET_SOFT_STATE(dev);
3848         ST_ENTR(ST_DEVINFO, st_write);
3849 #endif
3850         return (st_rw(dev, uiop, B_WRITE));
3851 }
3852 
3853 /*
3854  * Due to historical reasons, old limits are: For variable-length devices:
3855  * if greater than 64KB - 1 (ST_MAXRECSIZE_VARIABLE), block into 64 KB - 2
3856  * ST_MAXRECSIZE_VARIABLE_LIMIT) requests; otherwise,
3857  * (let it through unmodified. For fixed-length record devices:
3858  * 63K (ST_MAXRECSIZE_FIXED) is max (default minphys).
3859  *
3860  * The new limits used are un_maxdma (retrieved using scsi_ifgetcap()
3861  * from the HBA) and un_maxbsize (retrieved by sending SCMD_READ_BLKLIM
3862  * command to the drive).
3863  *
3864  */
3865 static void
3866 st_minphys(struct buf *bp)
3867 {
3868         struct scsi_tape *un;
3869 
3870         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
3871 
3872         ST_FUNC(ST_DEVINFO, st_minphys);
3873 
3874         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3875             "st_minphys(bp = 0x%p): b_bcount = 0x%lx\n", (void *)bp,
3876             bp->b_bcount);
3877 
3878         if (un->un_allow_large_xfer) {
3879 
3880                 /*
3881                  * check un_maxbsize for variable length devices only
3882                  */
3883                 if (un->un_bsize == 0 && bp->b_bcount > un->un_maxbsize) {
3884                         bp->b_bcount = un->un_maxbsize;
3885                 }
3886                 /*
3887                  * can't go more that HBA maxdma limit in either fixed-length
3888                  * or variable-length tape drives.
3889                  */
3890                 if (bp->b_bcount > un->un_maxdma) {
3891                         bp->b_bcount = un->un_maxdma;
3892                 }
3893         } else {
3894 
3895                 /*
3896                  *  use old fixed limits
3897                  */
3898                 if (un->un_bsize == 0) {
3899                         if (bp->b_bcount > ST_MAXRECSIZE_VARIABLE) {
3900                                 bp->b_bcount = ST_MAXRECSIZE_VARIABLE_LIMIT;
3901                         }
3902                 } else {
3903                         if (bp->b_bcount > ST_MAXRECSIZE_FIXED) {
3904                                 bp->b_bcount = ST_MAXRECSIZE_FIXED;
3905                         }
3906                 }
3907         }
3908 
3909         /*
3910          * For regular raw I/O and Fixed Block length devices, make sure
3911          * the adjusted block count is a whole multiple of the device
3912          * block size.
3913          */
3914         if (bp != un->un_sbufp && un->un_bsize) {
3915                 bp->b_bcount -= (bp->b_bcount % un->un_bsize);
3916         }
3917 }
3918 
3919 static int
3920 st_rw(dev_t dev, struct uio *uio, int flag)
3921 {
3922         int rval = 0;
3923         long len;
3924 
3925         GET_SOFT_STATE(dev);
3926 
3927         ST_FUNC(ST_DEVINFO, st_rw);
3928 
3929         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3930             "st_rw(dev = 0x%lx, flag = %s)\n", dev,
3931             (flag == B_READ ? rd_str: wr_str));
3932 
3933         /* get local copy of transfer length */
3934         len = uio->uio_iov->iov_len;
3935 
3936         mutex_enter(ST_MUTEX);
3937 
3938         /*
3939          * Clear error entry stack
3940          */
3941         st_empty_error_stack(un);
3942 
3943         /*
3944          * If in fixed block size mode and requested read or write
3945          * is not an even multiple of that block size.
3946          */
3947         if ((un->un_bsize != 0) && (len % un->un_bsize != 0)) {
3948                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
3949                     "%s: not modulo %d block size\n",
3950                     (flag == B_WRITE) ? wr_str : rd_str, un->un_bsize);
3951                 rval = EINVAL;
3952         }
3953 
3954         /* If device has set granularity in the READ_BLKLIM we honor it. */
3955         if ((un->un_data_mod != 0) && (len % un->un_data_mod != 0)) {
3956                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
3957                     "%s: not modulo %d device granularity\n",
3958                     (flag == B_WRITE) ? wr_str : rd_str, un->un_data_mod);
3959                 rval = EINVAL;
3960         }
3961 
3962         if (st_recov_sz != sizeof (recov_info) && un->un_multipath) {
3963                 scsi_log(ST_DEVINFO, st_label, CE_WARN, mp_misconf);
3964                 rval = EFAULT;
3965         }
3966 
3967         if (rval != 0) {
3968                 un->un_errno = rval;
3969                 mutex_exit(ST_MUTEX);
3970                 return (rval);
3971         }
3972 
3973         /*
3974          * Reset this so it can be set if Berkeley and read over a filemark.
3975          */
3976         un->un_silent_skip = 0;
3977         mutex_exit(ST_MUTEX);
3978 
3979         len = uio->uio_resid;
3980 
3981         rval = physio(st_queued_strategy, (struct buf *)NULL,
3982             dev, flag, st_minphys, uio);
3983         /*
3984          * if we have hit logical EOT during this xfer and there is not a
3985          * full residue, then set eof back  to ST_EOM to make sure that
3986          * the user will see at least one zero write
3987          * after this short write
3988          */
3989         mutex_enter(ST_MUTEX);
3990         if (un->un_pos.eof > ST_NO_EOF) {
3991                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3992                 "eof=%d resid=%lx\n", un->un_pos.eof, uio->uio_resid);
3993         }
3994         if (un->un_pos.eof >= ST_EOM && (flag == B_WRITE)) {
3995                 if ((uio->uio_resid != len) && (uio->uio_resid != 0)) {
3996                         un->un_pos.eof = ST_EOM;
3997                 } else if (uio->uio_resid == len) {
3998                         un->un_pos.eof = ST_NO_EOF;
3999                 }
4000         }
4001 
4002         if (un->un_silent_skip && uio->uio_resid != len) {
4003                 un->un_pos.eof = ST_EOF;
4004                 un->un_pos.blkno = un->un_save_blkno;
4005                 un->un_pos.fileno--;
4006         }
4007 
4008         un->un_errno = rval;
4009 
4010         mutex_exit(ST_MUTEX);
4011 
4012         return (rval);
4013 }
4014 
4015 static int
4016 st_arw(dev_t dev, struct aio_req *aio, int flag)
4017 {
4018         struct uio *uio = aio->aio_uio;
4019         int rval = 0;
4020         long len;
4021 
4022         GET_SOFT_STATE(dev);
4023 
4024         ST_FUNC(ST_DEVINFO, st_arw);
4025 
4026         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4027             "st_arw(dev = 0x%lx, flag = %s)\n", dev,
4028             (flag == B_READ ? rd_str: wr_str));
4029 
4030         /* get local copy of transfer length */
4031         len = uio->uio_iov->iov_len;
4032 
4033         mutex_enter(ST_MUTEX);
4034 
4035         /*
4036          * If in fixed block size mode and requested read or write
4037          * is not an even multiple of that block size.
4038          */
4039         if ((un->un_bsize != 0) && (len % un->un_bsize != 0)) {
4040                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
4041                     "%s: not modulo %d block size\n",
4042                     (flag == B_WRITE) ? wr_str : rd_str, un->un_bsize);
4043                 rval = EINVAL;
4044         }
4045 
4046         /* If device has set granularity in the READ_BLKLIM we honor it. */
4047         if ((un->un_data_mod != 0) && (len % un->un_data_mod != 0)) {
4048                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
4049                     "%s: not modulo %d device granularity\n",
4050                     (flag == B_WRITE) ? wr_str : rd_str, un->un_data_mod);
4051                 rval = EINVAL;
4052         }
4053 
4054         if (st_recov_sz != sizeof (recov_info) && un->un_multipath) {
4055                 scsi_log(ST_DEVINFO, st_label, CE_WARN, mp_misconf);
4056                 rval = EFAULT;
4057         }
4058 
4059         if (rval != 0) {
4060                 un->un_errno = rval;
4061                 mutex_exit(ST_MUTEX);
4062                 return (rval);
4063         }
4064 
4065         mutex_exit(ST_MUTEX);
4066 
4067         len = uio->uio_resid;
4068 
4069         rval =
4070             aphysio(st_queued_strategy, anocancel, dev, flag, st_minphys, aio);
4071 
4072         /*
4073          * if we have hit logical EOT during this xfer and there is not a
4074          * full residue, then set eof back  to ST_EOM to make sure that
4075          * the user will see at least one zero write
4076          * after this short write
4077          *
4078          * we keep this here just in case the application is not using
4079          * persistent errors
4080          */
4081         mutex_enter(ST_MUTEX);
4082         if (un->un_pos.eof > ST_NO_EOF) {
4083                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4084                     "eof=%d resid=%lx\n", un->un_pos.eof, uio->uio_resid);
4085         }
4086         if (un->un_pos.eof >= ST_EOM && (flag == B_WRITE)) {
4087                 if ((uio->uio_resid != len) && (uio->uio_resid != 0)) {
4088                         un->un_pos.eof = ST_EOM;
4089                 } else if (uio->uio_resid == len &&
4090                     !(un->un_persistence && un->un_persist_errors)) {
4091                         un->un_pos.eof = ST_NO_EOF;
4092                 }
4093         }
4094         un->un_errno = rval;
4095         mutex_exit(ST_MUTEX);
4096 
4097         return (rval);
4098 }
4099 
4100 
4101 
4102 static int
4103 st_queued_strategy(buf_t *bp)
4104 {
4105         struct scsi_tape *un;
4106         char reading = bp->b_flags & B_READ;
4107         int wasopening = 0;
4108 
4109         /*
4110          * validate arguments
4111          */
4112         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
4113         if (un == NULL) {
4114                 bp->b_resid = bp->b_bcount;
4115                 bioerror(bp, ENXIO);
4116                 ST_DEBUG6(NULL, st_label, SCSI_DEBUG,
4117                     "st_queued_strategy: ENXIO error exit\n");
4118                 biodone(bp);
4119                 return (0);
4120         }
4121 
4122         ST_ENTR(ST_DEVINFO, st_queued_strategy);
4123 
4124         mutex_enter(ST_MUTEX);
4125 
4126         while (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
4127                 cv_wait(&un->un_suspend_cv, ST_MUTEX);
4128         }
4129 
4130         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4131             "st_queued_strategy(): bcount=0x%lx, fileno=%d, blkno=%x, eof=%d\n",
4132             bp->b_bcount, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
4133 
4134         /*
4135          * If persistent errors have been flagged, just nix this one. We wait
4136          * for any outstanding I/O's below, so we will be in order.
4137          */
4138         if (un->un_persistence && un->un_persist_errors) {
4139                 goto exit;
4140         }
4141 
4142         /*
4143          * If last command was non queued, wait till it finishes.
4144          */
4145         while (un->un_sbuf_busy) {
4146                 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
4147                 /* woke up because of an error */
4148                 if (un->un_persistence && un->un_persist_errors) {
4149                         goto exit;
4150                 }
4151         }
4152 
4153         /*
4154          * s_buf and recovery commands shouldn't come here.
4155          */
4156         ASSERT(bp != un->un_recov_buf);
4157         ASSERT(bp != un->un_sbufp);
4158 
4159         /*
4160          * If we haven't done/checked reservation on the tape unit
4161          * do it now.
4162          */
4163         if ((un->un_rsvd_status &
4164             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
4165                 if ((un->un_dp->options & ST_NO_RESERVE_RELEASE) == 0) {
4166                         if (st_reserve_release(un, ST_RESERVE, st_uscsi_cmd)) {
4167                                 st_bioerror(bp, un->un_errno);
4168                                 goto exit;
4169                         }
4170                 } else if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4171                         /*
4172                          * Enter here to restore position for possible
4173                          * resets when the device was closed and opened
4174                          * in O_NDELAY mode subsequently
4175                          */
4176                         un->un_state = ST_STATE_INITIALIZING;
4177                         (void) st_cmd(un, SCMD_TEST_UNIT_READY,
4178                             0, SYNC_CMD);
4179                         un->un_state = ST_STATE_OPEN_PENDING_IO;
4180                 }
4181                 un->un_rsvd_status |= ST_INIT_RESERVE;
4182         }
4183 
4184         /*
4185          * If we are offline, we have to initialize everything first.
4186          * This is to handle either when opened with O_NDELAY, or
4187          * we just got a new tape in the drive, after an offline.
4188          * We don't observe O_NDELAY past the open,
4189          * as it will not make sense for tapes.
4190          */
4191         if (un->un_state == ST_STATE_OFFLINE || un->un_restore_pos) {
4192                 /*
4193                  * reset state to avoid recursion
4194                  */
4195                 un->un_laststate = un->un_state;
4196                 un->un_state = ST_STATE_INITIALIZING;
4197                 if (st_tape_init(un)) {
4198                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4199                             "stioctl : OFFLINE init failure ");
4200                         un->un_state = ST_STATE_OFFLINE;
4201                         un->un_pos.pmode = invalid;
4202                         goto b_done_err;
4203                 }
4204                 /* un_restore_pos make invalid */
4205                 un->un_state = ST_STATE_OPEN_PENDING_IO;
4206                 un->un_restore_pos = 0;
4207         }
4208         /*
4209          * Check for legal operations
4210          */
4211         if (un->un_pos.pmode == invalid) {
4212                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4213                     "strategy with un->un_pos.pmode invalid\n");
4214                 goto b_done_err;
4215         }
4216 
4217         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4218             "st_queued_strategy(): regular io\n");
4219 
4220         /*
4221          * Process this first. If we were reading, and we're pending
4222          * logical eot, that means we've bumped one file mark too far.
4223          */
4224 
4225         /*
4226          * Recursion warning: st_cmd will route back through here.
4227          * Not anymore st_cmd will go through st_strategy()!
4228          */
4229         if (un->un_pos.eof == ST_EOT_PENDING) {
4230                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
4231                         un->un_pos.pmode = invalid;
4232                         un->un_density_known = 0;
4233                         goto b_done_err;
4234                 }
4235                 un->un_pos.blkno = 0; /* fix up block number.. */
4236                 un->un_pos.eof = ST_EOT;
4237         }
4238 
4239         /*
4240          * If we are in the process of opening, we may have to
4241          * determine/set the correct density. We also may have
4242          * to do a test_append (if QIC) to see whether we are
4243          * in a position to append to the end of the tape.
4244          *
4245          * If we're already at logical eot, we transition
4246          * to ST_NO_EOF. If we're at physical eot, we punt
4247          * to the switch statement below to handle.
4248          */
4249         if ((un->un_state == ST_STATE_OPEN_PENDING_IO) ||
4250             (un->un_test_append && (un->un_dp->options & ST_QIC))) {
4251 
4252                 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4253                         if (st_determine_density(un, (int)reading)) {
4254                                 goto b_done_err;
4255                         }
4256                 }
4257 
4258                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4259                     "pending_io@fileno %d rw %d qic %d eof %d\n",
4260                     un->un_pos.fileno, (int)reading,
4261                     (un->un_dp->options & ST_QIC) ? 1 : 0,
4262                     un->un_pos.eof);
4263 
4264                 if (!reading && un->un_pos.eof != ST_EOM) {
4265                         if (un->un_pos.eof == ST_EOT) {
4266                                 un->un_pos.eof = ST_NO_EOF;
4267                         } else if (un->un_pos.pmode != invalid &&
4268                             (un->un_dp->options & ST_QIC)) {
4269                                 /*
4270                                  * st_test_append() will do it all
4271                                  */
4272                                 st_test_append(bp);
4273                                 mutex_exit(ST_MUTEX);
4274                                 return (0);
4275                         }
4276                 }
4277                 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4278                         wasopening = 1;
4279                 }
4280                 un->un_laststate = un->un_state;
4281                 un->un_state = ST_STATE_OPEN;
4282         }
4283 
4284 
4285         /*
4286          * Process rest of END OF FILE and END OF TAPE conditions
4287          */
4288 
4289         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4290             "eof=%x, wasopening=%x\n",
4291             un->un_pos.eof, wasopening);
4292 
4293         switch (un->un_pos.eof) {
4294         case ST_EOM:
4295                 /*
4296                  * This allows writes to proceed past physical
4297                  * eot. We'll *really* be in trouble if the
4298                  * user continues blindly writing data too
4299                  * much past this point (unwind the tape).
4300                  * Physical eot really means 'early warning
4301                  * eot' in this context.
4302                  *
4303                  * Every other write from now on will succeed
4304                  * (if sufficient  tape left).
4305                  * This write will return with resid == count
4306                  * but the next one should be successful
4307                  *
4308                  * Note that we only transition to logical EOT
4309                  * if the last state wasn't the OPENING state.
4310                  * We explicitly prohibit running up to physical
4311                  * eot, closing the device, and then re-opening
4312                  * to proceed. Trailer records may only be gotten
4313                  * at by keeping the tape open after hitting eot.
4314                  *
4315                  * Also note that ST_EOM cannot be set by reading-
4316                  * this can only be set during writing. Reading
4317                  * up to the end of the tape gets a blank check
4318                  * or a double-filemark indication (ST_EOT_PENDING),
4319                  * and we prohibit reading after that point.
4320                  *
4321                  */
4322                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOM\n");
4323                 if (wasopening == 0) {
4324                         /*
4325                          * this allows st_rw() to reset it back to
4326                          * will see a zero write
4327                          */
4328                         un->un_pos.eof = ST_WRITE_AFTER_EOM;
4329                 }
4330                 un->un_status = SUN_KEY_EOT;
4331                 goto b_done;
4332 
4333         case ST_WRITE_AFTER_EOM:
4334         case ST_EOT:
4335                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOT\n");
4336                 un->un_status = SUN_KEY_EOT;
4337                 if (SVR4_BEHAVIOR && reading) {
4338                         goto b_done_err;
4339                 }
4340 
4341                 if (reading) {
4342                         goto b_done;
4343                 }
4344                 un->un_pos.eof = ST_NO_EOF;
4345                 break;
4346 
4347         case ST_EOF_PENDING:
4348                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4349                     "EOF PENDING\n");
4350                 un->un_status = SUN_KEY_EOF;
4351                 if (SVR4_BEHAVIOR) {
4352                         un->un_pos.eof = ST_EOF;
4353                         goto b_done;
4354                 }
4355                 /* FALLTHROUGH */
4356         case ST_EOF:
4357                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOF\n");
4358                 un->un_status = SUN_KEY_EOF;
4359                 if (SVR4_BEHAVIOR) {
4360                         goto b_done_err;
4361                 }
4362 
4363                 if (BSD_BEHAVIOR) {
4364                         un->un_pos.eof = ST_NO_EOF;
4365                         un->un_pos.fileno += 1;
4366                         un->un_pos.blkno   = 0;
4367                 }
4368 
4369                 if (reading) {
4370                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4371                             "now file %d (read)\n",
4372                             un->un_pos.fileno);
4373                         goto b_done;
4374                 }
4375                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4376                     "now file %d (write)\n", un->un_pos.fileno);
4377                 break;
4378         default:
4379                 un->un_status = 0;
4380                 break;
4381         }
4382 
4383         bp->b_flags &= ~(B_DONE);
4384         st_bioerror(bp, 0);
4385         bp->av_forw = NULL;
4386         bp->b_resid = 0;
4387         SET_BP_PKT(bp, 0);
4388 
4389 
4390         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4391             "st_queued_strategy: cmd=0x%p  count=%ld  resid=%ld flags=0x%x"
4392             " pkt=0x%p\n",
4393             (void *)bp->b_forw, bp->b_bcount,
4394             bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
4395 
4396 #ifdef  __x86
4397         /*
4398          * We will replace bp with a new bp that can do big blk xfer
4399          * if the requested xfer size is bigger than un->un_maxdma_arch
4400          *
4401          * Also, we need to make sure that we're handling real I/O
4402          * by checking group 0/1 SCSI I/O commands, if needed
4403          */
4404         if (bp->b_bcount > un->un_maxdma_arch &&
4405             ((uchar_t)(uintptr_t)bp->b_forw == SCMD_READ ||
4406             (uchar_t)(uintptr_t)bp->b_forw == SCMD_READ_G4 ||
4407             (uchar_t)(uintptr_t)bp->b_forw == SCMD_WRITE ||
4408             (uchar_t)(uintptr_t)bp->b_forw == SCMD_WRITE_G4)) {
4409                 mutex_exit(ST_MUTEX);
4410                 bp = st_get_bigblk_bp(bp);
4411                 mutex_enter(ST_MUTEX);
4412         }
4413 #endif
4414 
4415         /* put on wait queue */
4416         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4417             "st_queued_strategy: un->un_quef = 0x%p, bp = 0x%p\n",
4418             (void *)un->un_quef, (void *)bp);
4419 
4420         st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quel, bp);
4421 
4422         ST_DO_KSTATS(bp, kstat_waitq_enter);
4423 
4424         st_start(un);
4425 
4426         mutex_exit(ST_MUTEX);
4427         return (0);
4428 
4429 b_done_err:
4430         st_bioerror(bp, EIO);
4431         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4432             "st_queued_strategy : EIO b_done_err\n");
4433 
4434 b_done:
4435         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4436             "st_queued_strategy: b_done\n");
4437 
4438 exit:
4439         /*
4440          * make sure no commands are outstanding or waiting before closing,
4441          * so we can guarantee order
4442          */
4443         st_wait_for_io(un);
4444         un->un_err_resid = bp->b_resid = bp->b_bcount;
4445 
4446         /* override errno here, if persistent errors were flagged */
4447         if (un->un_persistence && un->un_persist_errors)
4448                 bioerror(bp, un->un_errno);
4449 
4450         mutex_exit(ST_MUTEX);
4451 
4452         biodone(bp);
4453         ASSERT(mutex_owned(ST_MUTEX) == 0);
4454         return (0);
4455 }
4456 
4457 
4458 static int
4459 st_strategy(struct buf *bp)
4460 {
4461         struct scsi_tape *un;
4462 
4463         /*
4464          * validate arguments
4465          */
4466         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
4467         if (un == NULL) {
4468                 bp->b_resid = bp->b_bcount;
4469                 bioerror(bp, ENXIO);
4470                 ST_DEBUG6(NULL, st_label, SCSI_DEBUG,
4471                     "st_strategy: ENXIO error exit\n");
4472 
4473                 biodone(bp);
4474                 return (0);
4475 
4476         }
4477 
4478         ST_ENTR(ST_DEVINFO, st_strategy);
4479 
4480         mutex_enter(ST_MUTEX);
4481 
4482         while (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
4483                 cv_wait(&un->un_suspend_cv, ST_MUTEX);
4484         }
4485 
4486         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4487             "st_strategy(): bcount=0x%lx, fileno=%d, blkno=%x, eof=%d\n",
4488             bp->b_bcount, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
4489 
4490         ASSERT((bp == un->un_recov_buf) || (bp == un->un_sbufp));
4491 
4492         bp->b_flags &= ~(B_DONE);
4493         st_bioerror(bp, 0);
4494         bp->av_forw = NULL;
4495         bp->b_resid = 0;
4496         SET_BP_PKT(bp, 0);
4497 
4498 
4499         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4500             "st_strategy: cmd=0x%x  count=%ld  resid=%ld flags=0x%x"
4501             " pkt=0x%p\n",
4502             (unsigned char)(uintptr_t)bp->b_forw, bp->b_bcount,
4503             bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
4504         ST_DO_KSTATS(bp, kstat_waitq_enter);
4505 
4506         st_start(un);
4507 
4508         mutex_exit(ST_MUTEX);
4509         return (0);
4510 }
4511 
4512 /*
4513  * this routine spaces forward over filemarks
4514  */
4515 static int
4516 st_space_fmks(struct scsi_tape *un, int64_t count)
4517 {
4518         int rval = 0;
4519 
4520         ST_FUNC(ST_DEVINFO, st_space_fmks);
4521 
4522         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4523             "st_space_fmks(dev = 0x%lx, count = %"PRIx64")\n",
4524             un->un_dev, count);
4525 
4526         ASSERT(mutex_owned(ST_MUTEX));
4527 
4528         /*
4529          * the risk with doing only one space operation is that we
4530          * may accidentily jump in old data
4531          * the exabyte 8500 reading 8200 tapes cannot use KNOWS_EOD
4532          * because the 8200 does not append a marker; in order not to
4533          * sacrifice the fast file skip, we do a slow skip if the low
4534          * density device has been opened
4535          */
4536 
4537         if ((un->un_dp->options & ST_KNOWS_EOD) &&
4538             !((un->un_dp->type == ST_TYPE_EXB8500 &&
4539             MT_DENSITY(un->un_dev) == 0))) {
4540                 if (st_cmd(un, SCMD_SPACE, Fmk(count), SYNC_CMD)) {
4541                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4542                             "space_fmks : EIO can't do space cmd #1\n");
4543                         rval = EIO;
4544                 }
4545         } else {
4546                 while (count > 0) {
4547                         if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
4548                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4549                                     "space_fmks : EIO can't do space cmd #2\n");
4550                                 rval = EIO;
4551                                 break;
4552                         }
4553                         count -= 1;
4554                         /*
4555                          * read a block to see if we have reached
4556                          * end of medium (double filemark for reel or
4557                          * medium error for others)
4558                          */
4559                         if (count > 0) {
4560                                 if (st_cmd(un, SCMD_SPACE, Blk(1), SYNC_CMD)) {
4561                                         ST_DEBUG2(ST_DEVINFO, st_label,
4562                                             SCSI_DEBUG,
4563                                             "space_fmks : EIO can't do "
4564                                             "space cmd #3\n");
4565                                         rval = EIO;
4566                                         break;
4567                                 }
4568                                 if ((un->un_pos.eof >= ST_EOF_PENDING) &&
4569                                     (un->un_dp->options & ST_REEL)) {
4570                                         un->un_status = SUN_KEY_EOT;
4571                                         ST_DEBUG2(ST_DEVINFO, st_label,
4572                                             SCSI_DEBUG,
4573                                             "space_fmks : EIO ST_REEL\n");
4574                                         rval = EIO;
4575                                         break;
4576                                 } else if (IN_EOF(un->un_pos)) {
4577                                         un->un_pos.eof = ST_NO_EOF;
4578                                         un->un_pos.fileno++;
4579                                         un->un_pos.blkno = 0;
4580                                         count--;
4581                                 } else if (un->un_pos.eof > ST_EOF) {
4582                                         ST_DEBUG2(ST_DEVINFO, st_label,
4583                                             SCSI_DEBUG,
4584                                             "space_fmks, EIO > ST_EOF\n");
4585                                         rval = EIO;
4586                                         break;
4587                                 }
4588 
4589                         }
4590                 }
4591                 un->un_err_resid = count;
4592                 COPY_POS(&un->un_pos, &un->un_err_pos);
4593         }
4594         ASSERT(mutex_owned(ST_MUTEX));
4595         return (rval);
4596 }
4597 
4598 /*
4599  * this routine spaces to EOD
4600  *
4601  * it keeps track of the current filenumber and returns the filenumber after
4602  * the last successful space operation, we keep the number high because as
4603  * tapes are getting larger, the possibility of more and more files exist,
4604  * 0x100000 (1 Meg of files) probably will never have to be changed any time
4605  * soon
4606  */
4607 #define MAX_SKIP        0x100000 /* somewhat arbitrary */
4608 
4609 static int
4610 st_find_eod(struct scsi_tape *un)
4611 {
4612         tapepos_t savepos;
4613         int64_t sp_type;
4614         int result;
4615 
4616         if (un == NULL) {
4617                 return (-1);
4618         }
4619 
4620         ST_FUNC(ST_DEVINFO, st_find_eod);
4621 
4622         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4623             "st_find_eod(dev = 0x%lx): fileno = %d\n", un->un_dev,
4624             un->un_pos.fileno);
4625 
4626         ASSERT(mutex_owned(ST_MUTEX));
4627 
4628         COPY_POS(&savepos, &un->un_pos);
4629 
4630         /*
4631          * see if the drive is smart enough to do the skips in
4632          * one operation; 1/2" use two filemarks
4633          * the exabyte 8500 reading 8200 tapes cannot use KNOWS_EOD
4634          * because the 8200 does not append a marker; in order not to
4635          * sacrifice the fast file skip, we do a slow skip if the low
4636          * density device has been opened
4637          */
4638         if ((un->un_dp->options & ST_KNOWS_EOD) != 0) {
4639                 if ((un->un_dp->type == ST_TYPE_EXB8500) &&
4640                     (MT_DENSITY(un->un_dev) == 0)) {
4641                         sp_type = Fmk(1);
4642                 } else if (un->un_pos.pmode == logical) {
4643                         sp_type = SPACE(SP_EOD, 0);
4644                 } else {
4645                         sp_type = Fmk(MAX_SKIP);
4646                 }
4647         } else {
4648                 sp_type = Fmk(1);
4649         }
4650 
4651         for (;;) {
4652                 result = st_cmd(un, SCMD_SPACE, sp_type, SYNC_CMD);
4653 
4654                 if (result == 0) {
4655                         COPY_POS(&savepos, &un->un_pos);
4656                 }
4657 
4658                 if (sp_type == SPACE(SP_EOD, 0)) {
4659                         if (result != 0) {
4660                                 sp_type = Fmk(MAX_SKIP);
4661                                 continue;
4662                         }
4663 
4664                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4665                             "st_find_eod: 0x%"PRIx64"\n",
4666                             savepos.lgclblkno);
4667                         /*
4668                          * What we return will become the current file position.
4669                          * After completing the space command with the position
4670                          * mode that is not invalid a read position command will
4671                          * be automaticly issued. If the drive support the long
4672                          * read position format a valid file position can be
4673                          * returned.
4674                          */
4675                         return (un->un_pos.fileno);
4676                 }
4677 
4678                 if (result != 0) {
4679                         break;
4680                 }
4681 
4682                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4683                     "count=%"PRIx64", eof=%x, status=%x\n",
4684                     SPACE_CNT(sp_type),  un->un_pos.eof, un->un_status);
4685 
4686                 /*
4687                  * If we're not EOM smart,  space a record
4688                  * to see whether we're now in the slot between
4689                  * the two sequential filemarks that logical
4690                  * EOM consists of (REEL) or hit nowhere land
4691                  * (8mm).
4692                  */
4693                 if (sp_type == Fmk(1)) {
4694                         /*
4695                          * no fast skipping, check a record
4696                          */
4697                         if (st_cmd(un, SCMD_SPACE, Blk((1)), SYNC_CMD)) {
4698                                 break;
4699                         }
4700                         if ((un->un_pos.eof >= ST_EOF_PENDING) &&
4701                             (un->un_dp->options & ST_REEL)) {
4702                                 un->un_status = KEY_BLANK_CHECK;
4703                                 un->un_pos.fileno++;
4704                                 un->un_pos.blkno = 0;
4705                                 break;
4706                         }
4707                         if (IN_EOF(un->un_pos)) {
4708                                 un->un_pos.eof = ST_NO_EOF;
4709                                 un->un_pos.fileno++;
4710                                 un->un_pos.blkno = 0;
4711                         }
4712                         if (un->un_pos.eof > ST_EOF) {
4713                                 break;
4714                         }
4715                 } else {
4716                         if (un->un_pos.eof > ST_EOF) {
4717                                 break;
4718                         }
4719                 }
4720         }
4721 
4722         if (un->un_dp->options & ST_KNOWS_EOD) {
4723                 COPY_POS(&savepos, &un->un_pos);
4724         }
4725 
4726         ASSERT(mutex_owned(ST_MUTEX));
4727 
4728         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4729             "st_find_eod: %x\n", savepos.fileno);
4730         return (savepos.fileno);
4731 }
4732 
4733 
4734 /*
4735  * this routine is frequently used in ioctls below;
4736  * it determines whether we know the density and if not will
4737  * determine it
4738  * if we have written the tape before, one or more filemarks are written
4739  *
4740  * depending on the stepflag, the head is repositioned to where it was before
4741  * the filemarks were written in order not to confuse step counts
4742  */
4743 #define STEPBACK    0
4744 #define NO_STEPBACK 1
4745 
4746 static int
4747 st_check_density_or_wfm(dev_t dev, int wfm, int mode, int stepflag)
4748 {
4749 
4750         GET_SOFT_STATE(dev);
4751 
4752         ST_FUNC(ST_DEVINFO, st_check_density_or_wfm);
4753 
4754         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4755             "st_check_density_or_wfm(dev= 0x%lx, wfm= %d, mode= %d, stpflg= %d)"
4756             "\n", dev, wfm, mode, stepflag);
4757 
4758         ASSERT(mutex_owned(ST_MUTEX));
4759 
4760         /*
4761          * If we don't yet know the density of the tape we have inserted,
4762          * we have to either unconditionally set it (if we're 'writing'),
4763          * or we have to determine it. As side effects, check for any
4764          * write-protect errors, and for the need to put out any file-marks
4765          * before positioning a tape.
4766          *
4767          * If we are going to be spacing forward, and we haven't determined
4768          * the tape density yet, we have to do so now...
4769          */
4770         if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4771                 if (st_determine_density(un, mode)) {
4772                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4773                             "check_density_or_wfm : EIO can't determine "
4774                             "density\n");
4775                         un->un_errno = EIO;
4776                         return (EIO);
4777                 }
4778                 /*
4779                  * Presumably we are at BOT. If we attempt to write, it will
4780                  * either work okay, or bomb. We don't do a st_test_append
4781                  * unless we're past BOT.
4782                  */
4783                 un->un_laststate = un->un_state;
4784                 un->un_state = ST_STATE_OPEN;
4785 
4786         } else if (un->un_pos.pmode != invalid && un->un_fmneeded > 0 &&
4787             ((un->un_lastop == ST_OP_WEOF && wfm) ||
4788             (un->un_lastop == ST_OP_WRITE && wfm))) {
4789 
4790                 tapepos_t spos;
4791 
4792                 COPY_POS(&spos, &un->un_pos);
4793 
4794                 /*
4795                  * We need to write one or two filemarks.
4796                  * In the case of the HP, we need to
4797                  * position the head between the two
4798                  * marks.
4799                  */
4800                 if ((un->un_fmneeded > 0) || (un->un_lastop == ST_OP_WEOF)) {
4801                         wfm = un->un_fmneeded;
4802                         un->un_fmneeded = 0;
4803                 }
4804 
4805                 if (st_write_fm(dev, wfm)) {
4806                         un->un_pos.pmode = invalid;
4807                         un->un_density_known = 0;
4808                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4809                             "check_density_or_wfm : EIO can't write fm\n");
4810                         un->un_errno = EIO;
4811                         return (EIO);
4812                 }
4813 
4814                 if (stepflag == STEPBACK) {
4815                         if (st_cmd(un, SCMD_SPACE, Fmk(-wfm), SYNC_CMD)) {
4816                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4817                                     "check_density_or_wfm : EIO can't space "
4818                                     "(-wfm)\n");
4819                                 un->un_errno = EIO;
4820                                 return (EIO);
4821                         }
4822                         COPY_POS(&un->un_pos, &spos);
4823                 }
4824         }
4825 
4826         /*
4827          * Whatever we do at this point clears the state of the eof flag.
4828          */
4829 
4830         un->un_pos.eof = ST_NO_EOF;
4831 
4832         /*
4833          * If writing, let's check that we're positioned correctly
4834          * at the end of tape before issuing the next write.
4835          */
4836         if (un->un_read_only == RDWR) {
4837                 un->un_test_append = 1;
4838         }
4839 
4840         ASSERT(mutex_owned(ST_MUTEX));
4841         return (0);
4842 }
4843 
4844 
4845 /*
4846  * Wait for all outstaning I/O's to complete
4847  *
4848  * we wait on both ncmds and the wait queue for times when we are flushing
4849  * after persistent errors are flagged, which is when ncmds can be 0, and the
4850  * queue can still have I/O's.  This way we preserve order of biodone's.
4851  */
4852 static void
4853 st_wait_for_io(struct scsi_tape *un)
4854 {
4855         ST_FUNC(ST_DEVINFO, st_wait_for_io);
4856         ASSERT(mutex_owned(ST_MUTEX));
4857         while ((un->un_ncmds) || (un->un_quef) || (un->un_runqf)) {
4858                 cv_wait(&un->un_queue_cv, ST_MUTEX);
4859         }
4860 }
4861 
4862 /*
4863  * This routine implements the ioctl calls.  It is called
4864  * from the device switch at normal priority.
4865  */
4866 /*ARGSUSED*/
4867 static int
4868 st_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p,
4869     int *rval_p)
4870 {
4871         int tmp, rval = 0;
4872 
4873         GET_SOFT_STATE(dev);
4874 
4875         ST_ENTR(ST_DEVINFO, st_ioctl);
4876 
4877         mutex_enter(ST_MUTEX);
4878 
4879         ASSERT(un->un_recov_buf_busy == 0);
4880 
4881         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4882             "st_ioctl(): fileno=%x, blkno=%x, eof=%x, state = %d, "
4883             "pe_flag = %d\n",
4884             un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof, un->un_state,
4885             un->un_persistence && un->un_persist_errors);
4886 
4887         /*
4888          * We don't want to block on these, so let them through
4889          * and we don't care about setting driver states here.
4890          */
4891         if ((cmd == MTIOCGETDRIVETYPE) ||
4892             (cmd == MTIOCGUARANTEEDORDER) ||
4893             (cmd == MTIOCPERSISTENTSTATUS)) {
4894                 goto check_commands;
4895         }
4896 
4897         /*
4898          * We clear error entry stack except command
4899          * MTIOCGETERROR and MTIOCGET
4900          */
4901         if ((cmd != MTIOCGETERROR) &&
4902             (cmd != MTIOCGET)) {
4903                 st_empty_error_stack(un);
4904         }
4905 
4906         /*
4907          * wait for all outstanding commands to complete, or be dequeued.
4908          * And because ioctl's are synchronous commands, any return value
4909          * after this,  will be in order
4910          */
4911         st_wait_for_io(un);
4912 
4913         /*
4914          * allow only a through clear errors and persistent status, and
4915          * status
4916          */
4917         if (un->un_persistence && un->un_persist_errors) {
4918                 if ((cmd == MTIOCLRERR) ||
4919                     (cmd == MTIOCPERSISTENT) ||
4920                     (cmd == MTIOCGET)) {
4921                         goto check_commands;
4922                 } else {
4923                         rval = un->un_errno;
4924                         goto exit;
4925                 }
4926         }
4927 
4928         ASSERT(un->un_throttle != 0);
4929         un->un_throttle = 1; /* > 1 will never happen here */
4930         un->un_errno = 0;    /* start clean from here */
4931 
4932         /*
4933          * first and foremost, handle any ST_EOT_PENDING cases.
4934          * That is, if a logical eot is pending notice, notice it.
4935          */
4936         if (un->un_pos.eof == ST_EOT_PENDING) {
4937                 int resid = un->un_err_resid;
4938                 uchar_t status = un->un_status;
4939                 uchar_t lastop = un->un_lastop;
4940 
4941                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
4942                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4943                             "stioctl : EIO can't space fmk(-1)\n");
4944                         rval = EIO;
4945                         goto exit;
4946                 }
4947                 un->un_lastop = lastop; /* restore last operation */
4948                 if (status == SUN_KEY_EOF) {
4949                         un->un_status = SUN_KEY_EOT;
4950                 } else {
4951                         un->un_status = status;
4952                 }
4953                 un->un_err_resid  = resid;
4954                 /* fix up block number */
4955                 un->un_err_pos.blkno = un->un_pos.blkno = 0;
4956                 /* now we're at logical eot */
4957                 un->un_pos.eof = ST_EOT;
4958         }
4959 
4960         /*
4961          * now, handle the rest of the situations
4962          */
4963 check_commands:
4964         switch (cmd) {
4965         case MTIOCGET:
4966         {
4967 #ifdef _MULTI_DATAMODEL
4968                 /*
4969                  * For use when a 32 bit app makes a call into a
4970                  * 64 bit ioctl
4971                  */
4972                 struct mtget32          mtg_local32;
4973                 struct mtget32          *mtget_32 = &mtg_local32;
4974 #endif /* _MULTI_DATAMODEL */
4975 
4976                         /* Get tape status */
4977                 struct mtget mtg_local;
4978                 struct mtget *mtget = &mtg_local;
4979                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
4980                     "st_ioctl: MTIOCGET\n");
4981 
4982                 bzero((caddr_t)mtget, sizeof (struct mtget));
4983                 mtget->mt_erreg = un->un_status;
4984                 mtget->mt_resid = un->un_err_resid;
4985                 mtget->mt_dsreg = un->un_retry_ct;
4986                 if (un->un_err_pos.pmode == legacy) {
4987                         mtget->mt_fileno = un->un_err_pos.fileno;
4988                 } else {
4989                         mtget->mt_fileno = -1;
4990                 }
4991                 /*
4992                  * If the value is positive fine.
4993                  * If its negative we need to return a value based on the
4994                  * old way if counting backwards from INF (1,000,000,000).
4995                  */
4996                 if (un->un_err_pos.blkno >= 0) {
4997                         mtget->mt_blkno = un->un_err_pos.blkno;
4998                 } else {
4999                         mtget->mt_blkno = INF + 1 - (-un->un_err_pos.blkno);
5000                 }
5001                 mtget->mt_type = un->un_dp->type;
5002                 mtget->mt_flags = MTF_SCSI | MTF_ASF;
5003                 if (un->un_read_pos_type != NO_POS) {
5004                         mtget->mt_flags |= MTF_LOGICAL_BLOCK;
5005                 }
5006                 if (un->un_dp->options & ST_REEL) {
5007                         mtget->mt_flags |= MTF_REEL;
5008                         mtget->mt_bf = 20;
5009                 } else {                /* 1/4" cartridges */
5010                         switch (mtget->mt_type) {
5011                         /* Emulex cartridge tape */
5012                         case MT_ISMT02:
5013                                 mtget->mt_bf = 40;
5014                                 break;
5015                         default:
5016                                 mtget->mt_bf = 126;
5017                                 break;
5018                         }
5019                 }
5020 
5021                 /*
5022                  * If large transfers are allowed and drive options
5023                  * has no record size limit set. Calculate blocking
5024                  * factor from the lesser of maxbsize and maxdma.
5025                  */
5026                 if ((un->un_allow_large_xfer) &&
5027                     (un->un_dp->options & ST_NO_RECSIZE_LIMIT)) {
5028                         mtget->mt_bf = min(un->un_maxbsize,
5029                             un->un_maxdma) / SECSIZE;
5030                 }
5031 
5032                 if (un->un_read_only == WORM ||
5033                     un->un_read_only == RDWORM) {
5034                         mtget->mt_flags |= MTF_WORM_MEDIA;
5035                 }
5036 
5037                 /*
5038                  * In persistent error mode sending a non-queued can hang
5039                  * because this ioctl gets to be run without turning off
5040                  * persistense. Fake the answer based on previous info.
5041                  */
5042                 if (un->un_persistence) {
5043                         rval = 0;
5044                 } else {
5045                         rval = st_check_clean_bit(un);
5046                 }
5047                 if (rval == 0) {
5048                         /*
5049                          * If zero is returned or in persistent mode,
5050                          * use the old data.
5051                          */
5052                         if ((un->un_HeadClean & (TAPE_ALERT_SUPPORTED |
5053                             TAPE_SEQUENTIAL_SUPPORTED|TAPE_ALERT_NOT_SUPPORTED))
5054                             != TAPE_ALERT_NOT_SUPPORTED) {
5055                                 mtget->mt_flags |= MTF_TAPE_CLN_SUPPORTED;
5056                         }
5057                         if (un->un_HeadClean & (TAPE_PREVIOUSLY_DIRTY |
5058                             TAPE_ALERT_STILL_DIRTY)) {
5059                                 mtget->mt_flags |= MTF_TAPE_HEAD_DIRTY;
5060                         }
5061                 } else {
5062                         mtget->mt_flags |= (ushort_t)rval;
5063                         rval = 0;
5064                 }
5065 
5066                 un->un_status = 0;           /* Reset status */
5067                 un->un_err_resid = 0;
5068                 tmp = sizeof (struct mtget);
5069 
5070 #ifdef _MULTI_DATAMODEL
5071 
5072                 switch (ddi_model_convert_from(flag & FMODELS)) {
5073                 case DDI_MODEL_ILP32:
5074                         /*
5075                          * Convert 64 bit back to 32 bit before doing
5076                          * copyout. This is what the ILP32 app expects.
5077                          */
5078                         mtget_32->mt_erreg =         mtget->mt_erreg;
5079                         mtget_32->mt_resid =         mtget->mt_resid;
5080                         mtget_32->mt_dsreg =         mtget->mt_dsreg;
5081                         mtget_32->mt_fileno =        (daddr32_t)mtget->mt_fileno;
5082                         mtget_32->mt_blkno =         (daddr32_t)mtget->mt_blkno;
5083                         mtget_32->mt_type =          mtget->mt_type;
5084                         mtget_32->mt_flags =         mtget->mt_flags;
5085                         mtget_32->mt_bf =    mtget->mt_bf;
5086 
5087                         if (ddi_copyout(mtget_32, (void *)arg,
5088                             sizeof (struct mtget32), flag)) {
5089                                 rval = EFAULT;
5090                         }
5091                         break;
5092 
5093                 case DDI_MODEL_NONE:
5094                         if (ddi_copyout(mtget, (void *)arg, tmp, flag)) {
5095                                 rval = EFAULT;
5096                         }
5097                         break;
5098                 }
5099 #else /* ! _MULTI_DATAMODE */
5100                 if (ddi_copyout(mtget, (void *)arg, tmp, flag)) {
5101                         rval = EFAULT;
5102                 }
5103 #endif /* _MULTI_DATAMODE */
5104 
5105                 break;
5106         }
5107         case MTIOCGETERROR:
5108                         /*
5109                          * get error entry from error stack
5110                          */
5111                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5112                             "st_ioctl: MTIOCGETERROR\n");
5113 
5114                         rval = st_get_error_entry(un, arg, flag);
5115 
5116                         break;
5117 
5118         case MTIOCSTATE:
5119                 {
5120                         /*
5121                          * return when media presence matches state
5122                          */
5123                         enum mtio_state state;
5124 
5125                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5126                             "st_ioctl: MTIOCSTATE\n");
5127 
5128                         if (ddi_copyin((void *)arg, &state, sizeof (int), flag))
5129                                 rval = EFAULT;
5130 
5131                         mutex_exit(ST_MUTEX);
5132 
5133                         rval = st_check_media(dev, state);
5134 
5135                         mutex_enter(ST_MUTEX);
5136 
5137                         if (rval != 0) {
5138                                 break;
5139                         }
5140 
5141                         if (ddi_copyout(&un->un_mediastate, (void *)arg,
5142                             sizeof (int), flag))
5143                                 rval = EFAULT;
5144                         break;
5145 
5146                 }
5147 
5148         case MTIOCGETDRIVETYPE:
5149                 {
5150 #ifdef _MULTI_DATAMODEL
5151                 /*
5152                  * For use when a 32 bit app makes a call into a
5153                  * 64 bit ioctl
5154                  */
5155                 struct mtdrivetype_request32    mtdtrq32;
5156 #endif /* _MULTI_DATAMODEL */
5157 
5158                         /*
5159                          * return mtdrivetype
5160                          */
5161                         struct mtdrivetype_request mtdtrq;
5162                         struct mtdrivetype mtdrtyp;
5163                         struct mtdrivetype *mtdt = &mtdrtyp;
5164                         struct st_drivetype *stdt = un->un_dp;
5165 
5166                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5167                             "st_ioctl: MTIOCGETDRIVETYPE\n");
5168 
5169 #ifdef _MULTI_DATAMODEL
5170                 switch (ddi_model_convert_from(flag & FMODELS)) {
5171                 case DDI_MODEL_ILP32:
5172                 {
5173                         if (ddi_copyin((void *)arg, &mtdtrq32,
5174                             sizeof (struct mtdrivetype_request32), flag)) {
5175                                 rval = EFAULT;
5176                                 break;
5177                         }
5178                         mtdtrq.size = mtdtrq32.size;
5179                         mtdtrq.mtdtp =
5180                             (struct  mtdrivetype *)(uintptr_t)mtdtrq32.mtdtp;
5181                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5182                             "st_ioctl: size 0x%x\n", mtdtrq.size);
5183                         break;
5184                 }
5185                 case DDI_MODEL_NONE:
5186                         if (ddi_copyin((void *)arg, &mtdtrq,
5187                             sizeof (struct mtdrivetype_request), flag)) {
5188                                 rval = EFAULT;
5189                                 break;
5190                         }
5191                         break;
5192                 }
5193 
5194 #else /* ! _MULTI_DATAMODEL */
5195                 if (ddi_copyin((void *)arg, &mtdtrq,
5196                     sizeof (struct mtdrivetype_request), flag)) {
5197                         rval = EFAULT;
5198                         break;
5199                 }
5200 #endif /* _MULTI_DATAMODEL */
5201 
5202                         /*
5203                          * if requested size is < 0 then return
5204                          * error.
5205                          */
5206                         if (mtdtrq.size < 0) {
5207                                 rval = EINVAL;
5208                                 break;
5209                         }
5210                         bzero(mtdt, sizeof (struct mtdrivetype));
5211                         (void) strncpy(mtdt->name, stdt->name, ST_NAMESIZE);
5212                         (void) strncpy(mtdt->vid, stdt->vid, VIDPIDLEN - 1);
5213                         mtdt->type = stdt->type;
5214                         mtdt->bsize = stdt->bsize;
5215                         mtdt->options = stdt->options;
5216                         mtdt->max_rretries = stdt->max_rretries;
5217                         mtdt->max_wretries = stdt->max_wretries;
5218                         for (tmp = 0; tmp < NDENSITIES; tmp++) {
5219                                 mtdt->densities[tmp] = stdt->densities[tmp];
5220                         }
5221                         mtdt->default_density = stdt->default_density;
5222                         /*
5223                          * Speed hasn't been used since the hayday of reel tape.
5224                          * For all drives not setting the option ST_KNOWS_MEDIA
5225                          * the speed member renamed to mediatype are zeros.
5226                          * Those drives that have ST_KNOWS_MEDIA set use the
5227                          * new mediatype member which is used to figure the
5228                          * type of media loaded.
5229                          *
5230                          * So as to not break applications speed in the
5231                          * mtdrivetype structure is not renamed.
5232                          */
5233                         for (tmp = 0; tmp < NDENSITIES; tmp++) {
5234                                 mtdt->speeds[tmp] = stdt->mediatype[tmp];
5235                         }
5236                         mtdt->non_motion_timeout = stdt->non_motion_timeout;
5237                         mtdt->io_timeout = stdt->io_timeout;
5238                         mtdt->rewind_timeout = stdt->rewind_timeout;
5239                         mtdt->space_timeout = stdt->space_timeout;
5240                         mtdt->load_timeout = stdt->load_timeout;
5241                         mtdt->unload_timeout = stdt->unload_timeout;
5242                         mtdt->erase_timeout = stdt->erase_timeout;
5243 
5244                         /*
5245                          * Limit the maximum length of the result to
5246                          * sizeof (struct mtdrivetype).
5247                          */
5248                         tmp = sizeof (struct mtdrivetype);
5249                         if (mtdtrq.size < tmp)
5250                                 tmp = mtdtrq.size;
5251                         if (ddi_copyout(mtdt, mtdtrq.mtdtp, tmp, flag)) {
5252                                 rval = EFAULT;
5253                         }
5254                         break;
5255                 }
5256         case MTIOCPERSISTENT:
5257 
5258                 if (ddi_copyin((void *)arg, &tmp, sizeof (tmp), flag)) {
5259                         rval = EFAULT;
5260                         break;
5261                 }
5262 
5263                 if (tmp) {
5264                         st_turn_pe_on(un);
5265                 } else {
5266                         st_turn_pe_off(un);
5267                 }
5268 
5269                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5270                     "st_ioctl: MTIOCPERSISTENT : persistence = %d\n",
5271                     un->un_persistence);
5272 
5273                 break;
5274 
5275         case MTIOCPERSISTENTSTATUS:
5276                 tmp = (int)un->un_persistence;
5277 
5278                 if (ddi_copyout(&tmp, (void *)arg, sizeof (tmp), flag)) {
5279                         rval = EFAULT;
5280                 }
5281                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5282                     "st_ioctl: MTIOCPERSISTENTSTATUS:persistence = %d\n",
5283                     un->un_persistence);
5284 
5285                 break;
5286 
5287         case MTIOCLRERR:
5288                 {
5289                         /* clear persistent errors */
5290 
5291                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5292                             "st_ioctl: MTIOCLRERR\n");
5293 
5294                         st_clear_pe(un);
5295 
5296                         break;
5297                 }
5298 
5299         case MTIOCGUARANTEEDORDER:
5300                 {
5301                         /*
5302                          * this is just a holder to make a valid ioctl and
5303                          * it won't be in any earlier release
5304                          */
5305                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5306                             "st_ioctl: MTIOCGUARANTEEDORDER\n");
5307 
5308                         break;
5309                 }
5310 
5311         case MTIOCRESERVE:
5312                 {
5313                         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5314                             "st_ioctl: MTIOCRESERVE\n");
5315 
5316                         /*
5317                          * Check if Reserve/Release is supported.
5318                          */
5319                         if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5320                                 rval = ENOTTY;
5321                                 break;
5322                         }
5323 
5324                         rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
5325 
5326                         if (rval == 0) {
5327                                 un->un_rsvd_status |= ST_PRESERVE_RESERVE;
5328                         }
5329                         break;
5330                 }
5331 
5332         case MTIOCRELEASE:
5333                 {
5334                         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5335                             "st_ioctl: MTIOCRELEASE\n");
5336 
5337                         /*
5338                          * Check if Reserve/Release is supported.
5339                          */
5340                         if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5341                                 rval = ENOTTY;
5342                                 break;
5343                         }
5344 
5345                         /*
5346                          * Used to just clear ST_PRESERVE_RESERVE which
5347                          * made the reservation release at next close.
5348                          * As the user may have opened and then done a
5349                          * persistant reservation we now need to drop
5350                          * the reservation without closing if the user
5351                          * attempts to do this.
5352                          */
5353                         rval = st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
5354 
5355                         un->un_rsvd_status &= ~ST_PRESERVE_RESERVE;
5356 
5357                         break;
5358                 }
5359 
5360         case MTIOCFORCERESERVE:
5361         {
5362                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5363                     "st_ioctl: MTIOCFORCERESERVE\n");
5364 
5365                 /*
5366                  * Check if Reserve/Release is supported.
5367                  */
5368                 if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5369                         rval = ENOTTY;
5370                         break;
5371                 }
5372                 /*
5373                  * allow only super user to run this.
5374                  */
5375                 if (drv_priv(cred_p) != 0) {
5376                         rval = EPERM;
5377                         break;
5378                 }
5379                 /*
5380                  * Throw away reserve,
5381                  * not using test-unit-ready
5382                  * since reserve can succeed without tape being
5383                  * present in the drive.
5384                  */
5385                 (void) st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
5386 
5387                 rval = st_take_ownership(un, st_uscsi_cmd);
5388 
5389                 break;
5390         }
5391 
5392         case USCSICMD:
5393         {
5394                 cred_t  *cr;
5395 
5396                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5397                     "st_ioctl: USCSICMD\n");
5398 
5399                 cr = ddi_get_cred();
5400                 if ((drv_priv(cred_p) != 0) && (drv_priv(cr) != 0)) {
5401                         rval = EPERM;
5402                 } else {
5403                         rval = st_uscsi_cmd(un, (struct uscsi_cmd *)arg, flag);
5404                 }
5405                 break;
5406         }
5407         case MTIOCTOP:
5408                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5409                     "st_ioctl: MTIOCTOP\n");
5410                 rval = st_mtioctop(un, arg, flag);
5411                 break;
5412 
5413         case MTIOCLTOP:
5414                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5415                     "st_ioctl: MTIOLCTOP\n");
5416                 rval = st_mtiocltop(un, arg, flag);
5417                 break;
5418 
5419         case MTIOCREADIGNOREILI:
5420                 {
5421                         int set_ili;
5422 
5423                         if (ddi_copyin((void *)arg, &set_ili,
5424                             sizeof (set_ili), flag)) {
5425                                 rval = EFAULT;
5426                                 break;
5427                         }
5428 
5429                         if (un->un_bsize) {
5430                                 rval = ENOTTY;
5431                                 break;
5432                         }
5433 
5434                         switch (set_ili) {
5435                         case 0:
5436                                 un->un_dp->options &= ~ST_READ_IGNORE_ILI;
5437                                 break;
5438 
5439                         case 1:
5440                                 un->un_dp->options |= ST_READ_IGNORE_ILI;
5441                                 break;
5442 
5443                         default:
5444                                 rval = EINVAL;
5445                                 break;
5446                         }
5447                         break;
5448                 }
5449 
5450         case MTIOCREADIGNOREEOFS:
5451                 {
5452                         int ignore_eof;
5453 
5454                         if (ddi_copyin((void *)arg, &ignore_eof,
5455                             sizeof (ignore_eof), flag)) {
5456                                 rval = EFAULT;
5457                                 break;
5458                         }
5459 
5460                         if (!(un->un_dp->options & ST_REEL)) {
5461                                 rval = ENOTTY;
5462                                 break;
5463                         }
5464 
5465                         switch (ignore_eof) {
5466                         case 0:
5467                                 un->un_dp->options &= ~ST_READ_IGNORE_EOFS;
5468                                 break;
5469 
5470                         case 1:
5471                                 un->un_dp->options |= ST_READ_IGNORE_EOFS;
5472                                 break;
5473 
5474                         default:
5475                                 rval = EINVAL;
5476                                 break;
5477                         }
5478                         break;
5479                 }
5480 
5481         case MTIOCSHORTFMK:
5482         {
5483                 int short_fmk;
5484 
5485                 if (ddi_copyin((void *)arg, &short_fmk,
5486                     sizeof (short_fmk), flag)) {
5487                         rval = EFAULT;
5488                         break;
5489                 }
5490 
5491                 switch (un->un_dp->type) {
5492                 case ST_TYPE_EXB8500:
5493                 case ST_TYPE_EXABYTE:
5494                         if (!short_fmk) {
5495                                 un->un_dp->options &= ~ST_SHORT_FILEMARKS;
5496                         } else if (short_fmk == 1) {
5497                                 un->un_dp->options |= ST_SHORT_FILEMARKS;
5498                         } else {
5499                                 rval = EINVAL;
5500                         }
5501                         break;
5502 
5503                 default:
5504                         rval = ENOTTY;
5505                         break;
5506                 }
5507                 break;
5508         }
5509 
5510         case MTIOCGETPOS:
5511                 rval = st_update_block_pos(un, st_cmd, 0);
5512                 if (rval == 0) {
5513                         if (ddi_copyout((void *)&un->un_pos, (void *)arg,
5514                             sizeof (tapepos_t), flag)) {
5515                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
5516                                     "MTIOCGETPOS copy out failed\n");
5517                                 rval = EFAULT;
5518                         }
5519                 }
5520                 break;
5521 
5522         case MTIOCRESTPOS:
5523         {
5524                 tapepos_t dest;
5525 
5526                 if (ddi_copyin((void *)arg, &dest, sizeof (tapepos_t),
5527                     flag) != 0) {
5528                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
5529                             "MTIOCRESTPOS copy in failed\n");
5530                         rval = EFAULT;
5531                         break;
5532                 }
5533                 rval = st_validate_tapemarks(un, st_uscsi_cmd, &dest);
5534                 if (rval != 0) {
5535                         rval = EIO;
5536                 }
5537                 break;
5538         }
5539         default:
5540                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5541                     "st_ioctl: unknown ioctl\n");
5542                 rval = ENOTTY;
5543         }
5544 
5545 exit:
5546         if (!(un->un_persistence && un->un_persist_errors)) {
5547                 un->un_errno = rval;
5548         }
5549 
5550         mutex_exit(ST_MUTEX);
5551 
5552         return (rval);
5553 }
5554 
5555 
5556 /*
5557  * do some MTIOCTOP tape operations
5558  */
5559 static int
5560 st_mtioctop(struct scsi_tape *un, intptr_t arg, int flag)
5561 {
5562 #ifdef _MULTI_DATAMODEL
5563         /*
5564          * For use when a 32 bit app makes a call into a
5565          * 64 bit ioctl
5566          */
5567         struct mtop32   mtop_32_for_64;
5568 #endif /* _MULTI_DATAMODEL */
5569         struct mtop passed;
5570         struct mtlop local;
5571         int rval = 0;
5572 
5573         ST_FUNC(ST_DEVINFO, st_mtioctop);
5574 
5575         ASSERT(mutex_owned(ST_MUTEX));
5576 
5577 #ifdef _MULTI_DATAMODEL
5578         switch (ddi_model_convert_from(flag & FMODELS)) {
5579         case DDI_MODEL_ILP32:
5580                 if (ddi_copyin((void *)arg, &mtop_32_for_64,
5581                     sizeof (struct mtop32), flag)) {
5582                         return (EFAULT);
5583                 }
5584                 local.mt_op = mtop_32_for_64.mt_op;
5585                 local.mt_count =  (int64_t)mtop_32_for_64.mt_count;
5586                 break;
5587 
5588         case DDI_MODEL_NONE:
5589                 if (ddi_copyin((void *)arg, &passed, sizeof (passed), flag)) {
5590                         return (EFAULT);
5591                 }
5592                 local.mt_op = passed.mt_op;
5593                 /* prevent sign extention */
5594                 local.mt_count = (UINT32_MAX & passed.mt_count);
5595                 break;
5596         }
5597 
5598 #else /* ! _MULTI_DATAMODEL */
5599         if (ddi_copyin((void *)arg, &passed, sizeof (passed), flag)) {
5600                 return (EFAULT);
5601         }
5602         local.mt_op = passed.mt_op;
5603         /* prevent sign extention */
5604         local.mt_count = (UINT32_MAX & passed.mt_count);
5605 #endif /* _MULTI_DATAMODEL */
5606 
5607         rval = st_do_mtioctop(un, &local);
5608 
5609 #ifdef _MULTI_DATAMODEL
5610         switch (ddi_model_convert_from(flag & FMODELS)) {
5611         case DDI_MODEL_ILP32:
5612                 if (((uint64_t)local.mt_count) > UINT32_MAX) {
5613                         rval = ERANGE;
5614                         break;
5615                 }
5616                 /*
5617                  * Convert 64 bit back to 32 bit before doing
5618                  * copyout. This is what the ILP32 app expects.
5619                  */
5620                 mtop_32_for_64.mt_op = local.mt_op;
5621                 mtop_32_for_64.mt_count = local.mt_count;
5622 
5623                 if (ddi_copyout(&mtop_32_for_64, (void *)arg,
5624                     sizeof (struct mtop32), flag)) {
5625                         rval = EFAULT;
5626                 }
5627                 break;
5628 
5629         case DDI_MODEL_NONE:
5630                 passed.mt_count = local.mt_count;
5631                 passed.mt_op = local.mt_op;
5632                 if (ddi_copyout(&passed, (void *)arg, sizeof (passed), flag)) {
5633                         rval = EFAULT;
5634                 }
5635                 break;
5636         }
5637 #else /* ! _MULTI_DATAMODE */
5638         if (((uint64_t)local.mt_count) > UINT32_MAX) {
5639                 rval = ERANGE;
5640         } else {
5641                 passed.mt_op = local.mt_op;
5642                 passed.mt_count = local.mt_count;
5643                 if (ddi_copyout(&passed, (void *)arg, sizeof (passed), flag)) {
5644                         rval = EFAULT;
5645                 }
5646         }
5647 #endif /* _MULTI_DATAMODE */
5648 
5649 
5650         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
5651             "st_ioctl: fileno=%x, blkno=%x, eof=%x\n", un->un_pos.fileno,
5652             un->un_pos.blkno, un->un_pos.eof);
5653 
5654         if (un->un_pos.pmode == invalid) {
5655                 un->un_density_known = 0;
5656         }
5657 
5658         ASSERT(mutex_owned(ST_MUTEX));
5659         return (rval);
5660 }
5661 
5662 static int
5663 st_mtiocltop(struct scsi_tape *un, intptr_t arg, int flag)
5664 {
5665         struct mtlop local;
5666         int rval;
5667 
5668         ST_FUNC(ST_DEVINFO, st_mtiocltop);
5669         if (ddi_copyin((void *)arg, &local, sizeof (local), flag)) {
5670                 return (EFAULT);
5671         }
5672 
5673         rval = st_do_mtioctop(un, &local);
5674 
5675         if (ddi_copyout(&local, (void *)arg, sizeof (local), flag)) {
5676                 rval = EFAULT;
5677         }
5678         return (rval);
5679 }
5680 
5681 
5682 static int
5683 st_do_mtioctop(struct scsi_tape *un, struct mtlop *mtop)
5684 {
5685         dev_t dev = un->un_dev;
5686         int savefile;
5687         int rval = 0;
5688 
5689         ST_FUNC(ST_DEVINFO, st_do_mtioctop);
5690 
5691         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5692             "st_do_mtioctop(): mt_op=%x\n", mtop->mt_op);
5693         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5694             "fileno=%x, blkno=%x, eof=%x\n",
5695             un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
5696 
5697         un->un_status = 0;
5698 
5699         /*
5700          * if we are going to mess with a tape, we have to make sure we have
5701          * one and are not offline (i.e. no tape is initialized).  We let
5702          * commands pass here that don't actually touch the tape, except for
5703          * loading and initialization (rewinding).
5704          */
5705         if (un->un_state == ST_STATE_OFFLINE) {
5706                 switch (mtop->mt_op) {
5707                 case MTLOAD:
5708                 case MTNOP:
5709                         /*
5710                          * We don't want strategy calling st_tape_init here,
5711                          * so, change state
5712                          */
5713                         un->un_state = ST_STATE_INITIALIZING;
5714                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5715                             "st_do_mtioctop : OFFLINE state = %d\n",
5716                             un->un_state);
5717                         break;
5718                 default:
5719                         /*
5720                          * reinitialize by normal means
5721                          */
5722                         rval = st_tape_init(un);
5723                         if (rval) {
5724                                 un->un_state = ST_STATE_INITIALIZING;
5725                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5726                                     "st_do_mtioctop : OFFLINE init failure ");
5727                                 un->un_state = ST_STATE_OFFLINE;
5728                                 un->un_pos.pmode = invalid;
5729                                 if (rval != EACCES) {
5730                                         rval = EIO;
5731                                 }
5732                                 return (rval);
5733                         }
5734                         un->un_state = ST_STATE_OPEN_PENDING_IO;
5735                         break;
5736                 }
5737         }
5738 
5739         /*
5740          * If the file position is invalid, allow only those
5741          * commands that properly position the tape and fail
5742          * the rest with EIO
5743          */
5744         if (un->un_pos.pmode == invalid) {
5745                 switch (mtop->mt_op) {
5746                 case MTWEOF:
5747                 case MTRETEN:
5748                 case MTERASE:
5749                 case MTEOM:
5750                 case MTFSF:
5751                 case MTFSR:
5752                 case MTBSF:
5753                 case MTNBSF:
5754                 case MTBSR:
5755                 case MTSRSZ:
5756                 case MTGRSZ:
5757                 case MTSEEK:
5758                 case MTBSSF:
5759                 case MTFSSF:
5760                         return (EIO);
5761                         /* NOTREACHED */
5762                 case MTREW:
5763                 case MTLOAD:
5764                 case MTOFFL:
5765                 case MTNOP:
5766                 case MTTELL:
5767                 case MTLOCK:
5768                 case MTUNLOCK:
5769                         break;
5770 
5771                 default:
5772                         return (ENOTTY);
5773                         /* NOTREACHED */
5774                 }
5775         }
5776 
5777         switch (mtop->mt_op) {
5778         case MTERASE:
5779                 /*
5780                  * MTERASE rewinds the tape, erase it completely, and returns
5781                  * to the beginning of the tape
5782                  */
5783                 if (un->un_mspl->wp || un->un_read_only & WORM) {
5784                         un->un_status = KEY_WRITE_PROTECT;
5785                         un->un_err_resid = mtop->mt_count;
5786                         COPY_POS(&un->un_err_pos, &un->un_pos);
5787                         return (EACCES);
5788                 }
5789                 if (un->un_dp->options & ST_REEL) {
5790                         un->un_fmneeded = 2;
5791                 } else {
5792                         un->un_fmneeded = 1;
5793                 }
5794                 mtop->mt_count = mtop->mt_count ? 1 : 0;
5795                 if (st_check_density_or_wfm(dev, 1, B_WRITE, NO_STEPBACK) ||
5796                     st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
5797                     st_cmd(un, SCMD_ERASE, mtop->mt_count, SYNC_CMD)) {
5798                         un->un_pos.pmode = invalid;
5799                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5800                             "st_do_mtioctop : EIO space or erase or "
5801                             "check den)\n");
5802                         rval = EIO;
5803                 } else {
5804                         /* QIC and helical scan rewind after erase */
5805                         if (un->un_dp->options & ST_REEL) {
5806                                 (void) st_cmd(un, SCMD_REWIND, 0, ASYNC_CMD);
5807                         }
5808                 }
5809                 break;
5810 
5811         case MTWEOF:
5812                 /*
5813                  * write an end-of-file record
5814                  */
5815                 if (un->un_mspl->wp || un->un_read_only & RDONLY) {
5816                         un->un_status = KEY_WRITE_PROTECT;
5817                         un->un_err_resid = mtop->mt_count;
5818                         COPY_POS(&un->un_err_pos, &un->un_pos);
5819                         return (EACCES);
5820                 }
5821 
5822                 /*
5823                  * zero count means just flush buffers
5824                  * negative count is not permitted
5825                  */
5826                 if (mtop->mt_count < 0) {
5827                         return (EINVAL);
5828                 }
5829 
5830                 /* Not on worm */
5831                 if (un->un_read_only == RDWR) {
5832                         un->un_test_append = 1;
5833                 }
5834 
5835                 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
5836                         if (st_determine_density(un, B_WRITE)) {
5837                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5838                                     "st_do_mtioctop : EIO : MTWEOF can't "
5839                                     "determine density");
5840                                 return (EIO);
5841                         }
5842                 }
5843 
5844                 rval = st_write_fm(dev, (int)mtop->mt_count);
5845                 if ((rval != 0) && (rval != EACCES)) {
5846                         /*
5847                          * Failure due to something other than illegal
5848                          * request results in loss of state (st_intr).
5849                          */
5850                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5851                             "st_do_mtioctop : EIO : MTWEOF can't write "
5852                             "file mark");
5853                         rval = EIO;
5854                 }
5855                 break;
5856 
5857         case MTRETEN:
5858                 /*
5859                  * retension the tape
5860                  */
5861                 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK) ||
5862                     st_cmd(un, SCMD_LOAD, LD_LOAD | LD_RETEN, SYNC_CMD)) {
5863                         un->un_pos.pmode = invalid;
5864                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5865                             "st_do_mtioctop : EIO : MTRETEN ");
5866                         rval = EIO;
5867                 }
5868                 break;
5869 
5870         case MTREW:
5871                 /*
5872                  * rewind  the tape
5873                  */
5874                 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK)) {
5875                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5876                             "st_do_mtioctop : EIO:MTREW check "
5877                             "density/wfm failed");
5878                         return (EIO);
5879                 }
5880                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
5881                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5882                             "st_do_mtioctop : EIO : MTREW ");
5883                         rval = EIO;
5884                 }
5885                 break;
5886 
5887         case MTOFFL:
5888                 /*
5889                  * rewinds, and, if appropriate, takes the device offline by
5890                  * unloading the tape
5891                  */
5892                 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK)) {
5893                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5894                             "st_do_mtioctop :EIO:MTOFFL check "
5895                             "density/wfm failed");
5896                         return (EIO);
5897                 }
5898                 (void) st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
5899                 if (st_cmd(un, SCMD_LOAD, LD_UNLOAD, SYNC_CMD)) {
5900                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5901                             "st_do_mtioctop : EIO : MTOFFL");
5902                         return (EIO);
5903                 }
5904                 un->un_pos.eof = ST_NO_EOF;
5905                 un->un_laststate = un->un_state;
5906                 un->un_state = ST_STATE_OFFLINE;
5907                 un->un_mediastate = MTIO_EJECTED;
5908                 break;
5909 
5910         case MTLOAD:
5911                 /*
5912                  * This is to load a tape into the drive
5913                  * Note that if the tape is not loaded, the device will have
5914                  * to be opened via O_NDELAY or O_NONBLOCK.
5915                  */
5916                 /*
5917                  * Let's try and clean things up, if we are not
5918                  * initializing, and then send in the load command, no
5919                  * matter what.
5920                  *
5921                  * load after a media change by the user.
5922                  */
5923 
5924                 if (un->un_state > ST_STATE_INITIALIZING) {
5925                         (void) st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK);
5926                 }
5927                 rval = st_cmd(un, SCMD_LOAD, LD_LOAD, SYNC_CMD);
5928                 /* Load command to a drive that doesn't support load */
5929                 if ((rval == EIO) &&
5930                     ((un->un_status == KEY_NOT_READY) &&
5931                         /* Medium not present */
5932                     (un->un_uscsi_rqs_buf->es_add_code == 0x3a) ||
5933                     ((un->un_status == KEY_ILLEGAL_REQUEST) &&
5934                     (un->un_dp->type == MT_ISSTK9840) &&
5935                         /* CSL not present */
5936                     (un->un_uscsi_rqs_buf->es_add_code == 0x80)))) {
5937                         rval = ENOTTY;
5938                         break;
5939                 } else if (rval != EACCES && rval != 0) {
5940                         rval = EIO;
5941                 }
5942                 if (rval) {
5943                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5944                             "st_do_mtioctop : %s : MTLOAD\n",
5945                             rval == EACCES ? "EACCES" : "EIO");
5946                         /*
5947                          * If load tape fails, who knows what happened...
5948                          */
5949                         un->un_pos.pmode = invalid;
5950                         break;
5951                 }
5952 
5953                 /*
5954                  * reset all counters appropriately using rewind, as if LOAD
5955                  * succeeds, we are at BOT
5956                  */
5957                 un->un_state = ST_STATE_INITIALIZING;
5958 
5959                 rval = st_tape_init(un);
5960                 if ((rval == EACCES) && (un->un_read_only & WORM)) {
5961                         rval = 0;
5962                         break;
5963                 }
5964 
5965                 if (rval != 0) {
5966                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5967                             "st_do_mtioctop : EIO : MTLOAD calls "
5968                             "st_tape_init\n");
5969                         rval = EIO;
5970                         un->un_state = ST_STATE_OFFLINE;
5971                 }
5972 
5973                 break;
5974 
5975         case MTNOP:
5976                 un->un_status = 0;           /* Reset status */
5977                 un->un_err_resid = 0;
5978                 mtop->mt_count = MTUNIT(dev);
5979                 break;
5980 
5981         case MTEOM:
5982                 /*
5983                  * positions the tape at a location just after the last file
5984                  * written on the tape. For cartridge and 8 mm, this after
5985                  * the last file mark; for reel, this is inbetween the two
5986                  * last 2 file marks
5987                  */
5988                 if ((un->un_pos.pmode == legacy && un->un_pos.eof >= ST_EOT) ||
5989                     (un->un_lastop == ST_OP_WRITE) ||
5990                     (un->un_lastop == ST_OP_WEOF)) {
5991                         /*
5992                          * If the command wants to move to logical end
5993                          * of media, and we're already there, we're done.
5994                          * If we were at logical eot, we reset the state
5995                          * to be *not* at logical eot.
5996                          *
5997                          * If we're at physical or logical eot, we prohibit
5998                          * forward space operations (unconditionally).
5999                          *
6000                          * Also if the last operation was a write of any
6001                          * kind the tape is at EOD.
6002                          */
6003                         return (0);
6004                 }
6005                 /*
6006                  * physical tape position may not be what we've been
6007                  * telling the user; adjust the request accordingly
6008                  */
6009                 if (IN_EOF(un->un_pos)) {
6010                         un->un_pos.fileno++;
6011                         un->un_pos.blkno = 0;
6012                 }
6013 
6014                 if (st_check_density_or_wfm(dev, 1, B_READ, NO_STEPBACK)) {
6015                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6016                             "st_do_mtioctop : EIO:MTEOM check density/wfm "
6017                             " failed");
6018                         return (EIO);
6019                 }
6020 
6021                 /*
6022                  * st_find_eod() returns the last fileno we knew about;
6023                  */
6024                 savefile = st_find_eod(un);
6025 
6026                 if ((un->un_status != KEY_BLANK_CHECK) &&
6027                     (un->un_status != SUN_KEY_EOT)) {
6028                         un->un_pos.pmode = invalid;
6029                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6030                             "st_do_mtioctop : EIO : MTEOM status check failed");
6031                         rval = EIO;
6032                 } else {
6033                         /*
6034                          * For 1/2" reel tapes assume logical EOT marked
6035                          * by two file marks or we don't care that we may
6036                          * be extending the last file on the tape.
6037                          */
6038                         if (un->un_dp->options & ST_REEL) {
6039                                 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
6040                                         un->un_pos.pmode = invalid;
6041                                         ST_DEBUG2(ST_DEVINFO, st_label,
6042                                             SCSI_DEBUG,
6043                                             "st_do_mtioctop : EIO : MTEOM space"
6044                                             " cmd failed");
6045                                         rval = EIO;
6046                                         break;
6047                                 }
6048                                 /*
6049                                  * Fix up the block number.
6050                                  */
6051                                 un->un_pos.blkno = 0;
6052                                 un->un_err_pos.blkno = 0;
6053                         }
6054                         un->un_err_resid = 0;
6055                         un->un_pos.fileno = savefile;
6056                         un->un_pos.eof = ST_EOT;
6057                 }
6058                 un->un_status = 0;
6059                 break;
6060 
6061         case MTFSF:
6062                 MAX_SPACE_CNT(mtop->mt_count);
6063                 rval = st_mtfsf_ioctl(un, mtop->mt_count);
6064                 break;
6065 
6066         case MTFSR:
6067                 MAX_SPACE_CNT(mtop->mt_count);
6068                 rval = st_mtfsr_ioctl(un, mtop->mt_count);
6069                 break;
6070 
6071         case MTBSF:
6072                 MAX_SPACE_CNT(mtop->mt_count);
6073                 rval = st_mtbsf_ioctl(un, mtop->mt_count);
6074                 break;
6075 
6076         case MTNBSF:
6077                 MAX_SPACE_CNT(mtop->mt_count);
6078                 rval = st_mtnbsf_ioctl(un, mtop->mt_count);
6079                 break;
6080 
6081         case MTBSR:
6082                 MAX_SPACE_CNT(mtop->mt_count);
6083                 rval = st_mtbsr_ioctl(un, mtop->mt_count);
6084                 break;
6085 
6086         case MTBSSF:
6087                 MAX_SPACE_CNT(mtop->mt_count);
6088                 rval = st_mtbsfm_ioctl(un, mtop->mt_count);
6089                 break;
6090 
6091         case MTFSSF:
6092                 MAX_SPACE_CNT(mtop->mt_count);
6093                 rval = st_mtfsfm_ioctl(un, mtop->mt_count);
6094                 break;
6095 
6096         case MTSRSZ:
6097 
6098                 /*
6099                  * Set record-size to that sent by user
6100                  * Check to see if there is reason that the requested
6101                  * block size should not be set.
6102                  */
6103 
6104                 /* If requesting variable block size is it ok? */
6105                 if ((mtop->mt_count == 0) &&
6106                     ((un->un_dp->options & ST_VARIABLE) == 0)) {
6107                         return (ENOTTY);
6108                 }
6109 
6110                 /*
6111                  * If requested block size is not variable "0",
6112                  * is it less then minimum.
6113                  */
6114                 if ((mtop->mt_count != 0) &&
6115                     (mtop->mt_count < un->un_minbsize)) {
6116                         return (EINVAL);
6117                 }
6118 
6119                 /* Is the requested block size more then maximum */
6120                 if ((mtop->mt_count > min(un->un_maxbsize, un->un_maxdma)) &&
6121                     (un->un_maxbsize != 0)) {
6122                         return (EINVAL);
6123                 }
6124 
6125                 /* Is requested block size a modulus the device likes */
6126                 if ((mtop->mt_count % un->un_data_mod) != 0) {
6127                         return (EINVAL);
6128                 }
6129 
6130                 if (st_change_block_size(un, (uint32_t)mtop->mt_count) != 0) {
6131                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6132                             "st_ioctl : MTSRSZ : EIO : cant set block size");
6133                         return (EIO);
6134                 }
6135 
6136                 return (0);
6137 
6138         case MTGRSZ:
6139                 /*
6140                  * Get record-size to the user
6141                  */
6142                 mtop->mt_count = un->un_bsize;
6143                 rval = 0;
6144                 break;
6145 
6146         case MTTELL:
6147                 rval = st_update_block_pos(un, st_cmd, 0);
6148                 mtop->mt_count = un->un_pos.lgclblkno;
6149                 break;
6150 
6151         case MTSEEK:
6152                 rval = st_logical_block_locate(un, st_uscsi_cmd, &un->un_pos,
6153                     (uint64_t)mtop->mt_count, un->un_pos.partition);
6154                 /*
6155                  * This bit of magic make mt print the actual position if
6156                  * the resulting position was not what was asked for.
6157                  */
6158                 if (rval == ESPIPE) {
6159                         rval = EIO;
6160                         if ((uint64_t)mtop->mt_count != un->un_pos.lgclblkno) {
6161                                 mtop->mt_op = MTTELL;
6162                                 mtop->mt_count = un->un_pos.lgclblkno;
6163                         }
6164                 }
6165                 break;
6166 
6167         case MTLOCK:
6168                 if (st_cmd(un, SCMD_DOORLOCK, MR_LOCK, SYNC_CMD)) {
6169                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6170                             "st_do_mtioctop : EIO : MTLOCK");
6171                         rval = EIO;
6172                 }
6173                 break;
6174 
6175         case MTUNLOCK:
6176                 if (st_cmd(un, SCMD_DOORLOCK, MR_UNLOCK, SYNC_CMD)) {
6177                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6178                             "st_do_mtioctop : EIO : MTUNLOCK");
6179                         rval = EIO;
6180                 }
6181                 break;
6182 
6183         default:
6184                 rval = ENOTTY;
6185         }
6186 
6187         return (rval);
6188 }
6189 
6190 
6191 /*
6192  * Run a command for uscsi ioctl.
6193  */
6194 static int
6195 st_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *ucmd, int flag)
6196 {
6197         struct uscsi_cmd        *uscmd;
6198         struct buf      *bp;
6199         enum uio_seg    uioseg;
6200         int     offline_state = 0;
6201         int     err = 0;
6202         dev_t dev = un->un_dev;
6203 
6204         ST_FUNC(ST_DEVINFO, st_uscsi_cmd);
6205 
6206         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6207             "st_uscsi_cmd(dev = 0x%lx)\n", un->un_dev);
6208 
6209         ASSERT(mutex_owned(ST_MUTEX));
6210 
6211         /*
6212          * We really don't know what commands are coming in here and
6213          * we don't want to limit the commands coming in.
6214          *
6215          * If st_tape_init() gets called from st_strategy(), then we
6216          * will hang the process waiting for un->un_sbuf_busy to be cleared,
6217          * which it never will, as we set it below.  To prevent
6218          * st_tape_init() from getting called, we have to set state to other
6219          * than ST_STATE_OFFLINE, so we choose ST_STATE_INITIALIZING, which
6220          * achieves this purpose already.
6221          *
6222          * We use offline_state to preserve the OFFLINE state, if it exists,
6223          * so other entry points to the driver might have the chance to call
6224          * st_tape_init().
6225          */
6226         if (un->un_state == ST_STATE_OFFLINE) {
6227                 un->un_laststate = ST_STATE_OFFLINE;
6228                 un->un_state = ST_STATE_INITIALIZING;
6229                 offline_state = 1;
6230         }
6231 
6232         mutex_exit(ST_MUTEX);
6233         err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag, ROUTE, &uscmd);
6234         mutex_enter(ST_MUTEX);
6235         if (err != 0) {
6236                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6237                     "st_uscsi_cmd: scsi_uscsi_alloc_and_copyin failed\n");
6238                 goto exit;
6239         }
6240 
6241         uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
6242 
6243         /* check to see if this command requires the drive to be reserved */
6244         if (uscmd->uscsi_cdb != NULL) {
6245                 err = st_check_cdb_for_need_to_reserve(un,
6246                     (uchar_t *)uscmd->uscsi_cdb);
6247                 if (err) {
6248                         goto exit_free;
6249                 }
6250                 /*
6251                  * If this is a space command we need to save the starting
6252                  * point so we can retry from there if the command fails.
6253                  */
6254                 if ((uscmd->uscsi_cdb[0] == SCMD_SPACE) ||
6255                     (uscmd->uscsi_cdb[0] == (char)SCMD_SPACE_G4)) {
6256                         (void) st_update_block_pos(un, st_cmd, 0);
6257                 }
6258         }
6259 
6260         /*
6261          * Forground should not be doing anything while recovery is active.
6262          */
6263         ASSERT(un->un_recov_buf_busy == 0);
6264 
6265         /*
6266          * Get buffer resources...
6267          */
6268         while (un->un_sbuf_busy)
6269                 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
6270         un->un_sbuf_busy = 1;
6271 
6272 #ifdef STDEBUG
6273         if ((uscmd->uscsi_cdb != NULL) && (st_debug & 0x7) > 6) {
6274                 int rw = (uscmd->uscsi_flags & USCSI_READ) ? B_READ : B_WRITE;
6275                 st_print_cdb(ST_DEVINFO, st_label, SCSI_DEBUG,
6276                     "uscsi cdb", uscmd->uscsi_cdb);
6277                 if (uscmd->uscsi_buflen) {
6278                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6279                             "uscsi %s of %ld bytes %s %s space\n",
6280                             (rw == B_READ) ? rd_str : wr_str,
6281                             uscmd->uscsi_buflen,
6282                             (rw == B_READ) ? "to" : "from",
6283                             (uioseg == UIO_SYSSPACE) ? "system" : "user");
6284                 }
6285         }
6286 #endif /* STDEBUG */
6287 
6288         /*
6289          * Although st_uscsi_cmd() never makes use of these
6290          * now, we are just being safe and consistent.
6291          */
6292         uscmd->uscsi_flags &= ~(USCSI_NOINTR | USCSI_NOPARITY |
6293             USCSI_OTAG | USCSI_HTAG | USCSI_HEAD);
6294 
6295         un->un_srqbufp = uscmd->uscsi_rqbuf;
6296         bp = un->un_sbufp;
6297         bzero(bp, sizeof (buf_t));
6298         if (uscmd->uscsi_cdb != NULL) {
6299                 bp->b_forw = (struct buf *)(uintptr_t)uscmd->uscsi_cdb[0];
6300         }
6301         bp->b_back = (struct buf *)uscmd;
6302 
6303         mutex_exit(ST_MUTEX);
6304         err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, st_strategy, bp, NULL);
6305         mutex_enter(ST_MUTEX);
6306 
6307         /*
6308          * If scsi reset successful, don't write any filemarks.
6309          */
6310         if ((err == 0) && (uscmd->uscsi_flags &
6311             (USCSI_RESET_LUN | USCSI_RESET_TARGET | USCSI_RESET_ALL))) {
6312                 un->un_fmneeded = 0;
6313         }
6314 
6315 exit_free:
6316         /*
6317          * Free resources
6318          */
6319         un->un_sbuf_busy = 0;
6320         un->un_srqbufp = NULL;
6321 
6322         /*
6323          * If was a space command need to update logical block position.
6324          * If the command failed such that positioning is invalid, Don't
6325          * update the position as the user must do this to validate the
6326          * position for data protection.
6327          */
6328         if ((uscmd->uscsi_cdb != NULL) &&
6329             ((uscmd->uscsi_cdb[0] == SCMD_SPACE) ||
6330             (uscmd->uscsi_cdb[0] == (char)SCMD_SPACE_G4)) &&
6331             (un->un_pos.pmode != invalid)) {
6332                 un->un_running.pmode = invalid;
6333                 (void) st_update_block_pos(un, st_cmd, 1);
6334                 /*
6335                  * Set running position to invalid so it updates on the
6336                  * next command.
6337                  */
6338                 un->un_running.pmode = invalid;
6339         }
6340         cv_signal(&un->un_sbuf_cv);
6341         mutex_exit(ST_MUTEX);
6342         (void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd);
6343         mutex_enter(ST_MUTEX);
6344         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6345             "st_uscsi_cmd returns 0x%x\n", err);
6346 
6347 exit:
6348         /* don't lose offline state */
6349         if (offline_state) {
6350                 un->un_state = ST_STATE_OFFLINE;
6351         }
6352 
6353         ASSERT(mutex_owned(ST_MUTEX));
6354         return (err);
6355 }
6356 
6357 static int
6358 st_write_fm(dev_t dev, int wfm)
6359 {
6360         int i;
6361         int rval;
6362 
6363         GET_SOFT_STATE(dev);
6364 
6365         ST_FUNC(ST_DEVINFO, st_write_fm);
6366 
6367         ASSERT(mutex_owned(ST_MUTEX));
6368 
6369         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6370             "st_write_fm(dev = 0x%lx, wfm = %d)\n", dev, wfm);
6371 
6372         /*
6373          * write one filemark at the time after EOT
6374          */
6375         if (un->un_pos.eof >= ST_EOT) {
6376                 for (i = 0; i < wfm; i++) {
6377                         rval = st_cmd(un, SCMD_WRITE_FILE_MARK, 1, SYNC_CMD);
6378                         if (rval == EACCES) {
6379                                 return (rval);
6380                         }
6381                         if (rval != 0) {
6382                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6383                                     "st_write_fm : EIO : write EOT file mark");
6384                                 return (EIO);
6385                         }
6386                 }
6387         } else {
6388                 rval = st_cmd(un, SCMD_WRITE_FILE_MARK, wfm, SYNC_CMD);
6389                 if (rval == EACCES) {
6390                         return (rval);
6391                 }
6392                 if (rval) {
6393                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6394                             "st_write_fm : EIO : write file mark");
6395                         return (EIO);
6396                 }
6397         }
6398 
6399         ASSERT(mutex_owned(ST_MUTEX));
6400         return (0);
6401 }
6402 
6403 #ifdef STDEBUG
6404 static void
6405 st_start_dump(struct scsi_tape *un, struct buf *bp)
6406 {
6407         struct scsi_pkt *pkt = BP_PKT(bp);
6408         uchar_t *cdbp = (uchar_t *)pkt->pkt_cdbp;
6409 
6410         ST_FUNC(ST_DEVINFO, st_start_dump);
6411 
6412         if ((st_debug & 0x7) < 6)
6413                 return;
6414         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6415             "st_start: cmd=0x%p count=%ld resid=%ld flags=0x%x pkt=0x%p\n",
6416             (void *)bp->b_forw, bp->b_bcount,
6417             bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
6418         st_print_cdb(ST_DEVINFO, st_label, SCSI_DEBUG,
6419             "st_start: cdb",  (caddr_t)cdbp);
6420         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6421             "st_start: fileno=%d, blk=%d\n",
6422             un->un_pos.fileno, un->un_pos.blkno);
6423 }
6424 #endif
6425 
6426 
6427 /*
6428  * Command start && done functions
6429  */
6430 
6431 /*
6432  * st_start()
6433  *
6434  * Called from:
6435  *  st_strategy() to start a command.
6436  *  st_runout() to retry when scsi_pkt allocation fails on previous attempt(s).
6437  *  st_attach() when resuming from power down state.
6438  *  st_start_restart() to retry transport when device was previously busy.
6439  *  st_done_and_mutex_exit() to start the next command when previous is done.
6440  *
6441  * On entry:
6442  *  scsi_pkt may or may not be allocated.
6443  *
6444  */
6445 static void
6446 st_start(struct scsi_tape *un)
6447 {
6448         struct buf *bp;
6449         int status;
6450         int queued;
6451 
6452         ST_FUNC(ST_DEVINFO, st_start);
6453         ASSERT(mutex_owned(ST_MUTEX));
6454 
6455         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6456             "st_start(): dev = 0x%lx\n", un->un_dev);
6457 
6458         if (un->un_recov_buf_busy) {
6459                 /* recovery commands can happen anytime */
6460                 bp = un->un_recov_buf;
6461                 queued = 0;
6462         } else if (un->un_sbuf_busy) {
6463                 /* sbuf commands should only happen with an empty queue. */
6464                 ASSERT(un->un_quef == NULL);
6465                 ASSERT(un->un_runqf == NULL);
6466                 bp = un->un_sbufp;
6467                 queued = 0;
6468         } else if (un->un_quef != NULL) {
6469                 if (un->un_persistence && un->un_persist_errors) {
6470                         return;
6471                 }
6472                 bp = un->un_quef;
6473                 queued = 1;
6474         } else {
6475                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6476                     "st_start() returning no buf found\n");
6477                 return;
6478         }
6479 
6480         ASSERT((bp->b_flags & B_DONE) == 0);
6481 
6482         /*
6483          * Don't send more than un_throttle commands to the HBA
6484          */
6485         if ((un->un_throttle <= 0) || (un->un_ncmds >= un->un_throttle)) {
6486                 /*
6487                  * if doing recovery we know there is outstanding commands.
6488                  */
6489                 if (bp != un->un_recov_buf) {
6490                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6491                             "st_start returning throttle = %d or ncmds = %d\n",
6492                             un->un_throttle, un->un_ncmds);
6493                         if (un->un_ncmds == 0) {
6494                                 typedef void (*func)();
6495                                 func fnc = (func)st_runout;
6496 
6497                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6498                                     "Sending delayed start to st_runout()\n");
6499                                 mutex_exit(ST_MUTEX);
6500                                 (void) timeout(fnc, un, drv_usectohz(1000000));
6501                                 mutex_enter(ST_MUTEX);
6502                         }
6503                         return;
6504                 }
6505         }
6506 
6507         /*
6508          * If the buf has no scsi_pkt call st_make_cmd() to get one and
6509          * build the command.
6510          */
6511         if (BP_PKT(bp) == NULL) {
6512                 ASSERT((bp->b_flags & B_DONE) == 0);
6513                 st_make_cmd(un, bp, st_runout);
6514                 ASSERT((bp->b_flags & B_DONE) == 0);
6515                 status = geterror(bp);
6516 
6517                 /*
6518                  * Some HBA's don't call bioerror() to set an error.
6519                  * And geterror() returns zero if B_ERROR is not set.
6520                  * So if we get zero we must check b_error.
6521                  */
6522                 if (status == 0 && bp->b_error != 0) {
6523                         status = bp->b_error;
6524                         bioerror(bp, status);
6525                 }
6526 
6527                 /*
6528                  * Some HBA's convert DDI_DMA_NORESOURCES into ENOMEM.
6529                  * In tape ENOMEM has special meaning so we'll change it.
6530                  */
6531                 if (status == ENOMEM) {
6532                         status = 0;
6533                         bioerror(bp, status);
6534                 }
6535 
6536                 /*
6537                  * Did it fail and is it retryable?
6538                  * If so return and wait for the callback through st_runout.
6539                  * Also looks like scsi_init_pkt() will setup a callback even
6540                  * if it isn't retryable.
6541                  */
6542                 if (BP_PKT(bp) == NULL) {
6543                         if (status == 0) {
6544                                 /*
6545                                  * If first attempt save state.
6546                                  */
6547                                 if (un->un_state != ST_STATE_RESOURCE_WAIT) {
6548                                         un->un_laststate = un->un_state;
6549                                         un->un_state = ST_STATE_RESOURCE_WAIT;
6550                                 }
6551                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6552                                     "temp no resources for pkt\n");
6553                         } else if (status == EINVAL) {
6554                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6555                                     "scsi_init_pkt rejected pkt as too big\n");
6556                                 if (un->un_persistence) {
6557                                         st_set_pe_flag(un);
6558                                 }
6559                         } else {
6560                                 /*
6561                                  * Unlikely that it would be retryable then not.
6562                                  */
6563                                 if (un->un_state == ST_STATE_RESOURCE_WAIT) {
6564                                         un->un_state = un->un_laststate;
6565                                 }
6566                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6567                                     "perm no resources for pkt errno = 0x%x\n",
6568                                     status);
6569                         }
6570                         return;
6571                 }
6572                 /*
6573                  * Worked this time set the state back.
6574                  */
6575                 if (un->un_state == ST_STATE_RESOURCE_WAIT) {
6576                         un->un_state = un->un_laststate;
6577                 }
6578         }
6579 
6580         if (queued) {
6581                 /*
6582                  * move from waitq to runq
6583                  */
6584                 (void) st_remove_from_queue(&un->un_quef, &un->un_quel, bp);
6585                 st_add_to_queue(&un->un_runqf, &un->un_runql, un->un_runql, bp);
6586         }
6587 
6588 
6589 #ifdef STDEBUG
6590         st_start_dump(un, bp);
6591 #endif
6592 
6593         /* could not get here if throttle was zero */
6594         un->un_last_throttle = un->un_throttle;
6595         un->un_throttle = 0; /* so nothing else will come in here */
6596         un->un_ncmds++;
6597 
6598         ST_DO_KSTATS(bp, kstat_waitq_to_runq);
6599 
6600         status = st_transport(un, BP_PKT(bp));
6601 
6602         if (un->un_last_throttle) {
6603                 un->un_throttle = un->un_last_throttle;
6604         }
6605 
6606         if (status != TRAN_ACCEPT) {
6607                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
6608                 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
6609                     "Unhappy transport packet status 0x%x\n", status);
6610 
6611                 if (status == TRAN_BUSY) {
6612                         pkt_info *pkti = BP_PKT(bp)->pkt_private;
6613 
6614                         /*
6615                          * If command recovery is enabled and this isn't
6616                          * a recovery command try command recovery.
6617                          */
6618                         if (pkti->privatelen == sizeof (recov_info) &&
6619                             bp != un->un_recov_buf) {
6620                                 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
6621                                     "Command Recovery called on busy send\n");
6622                                 if (st_command_recovery(un, BP_PKT(bp),
6623                                     ATTEMPT_RETRY) == JUST_RETURN) {
6624                                         return;
6625                                 }
6626                         } else {
6627                                 mutex_exit(ST_MUTEX);
6628                                 if (st_handle_start_busy(un, bp,
6629                                     ST_TRAN_BUSY_TIMEOUT, queued) == 0) {
6630                                         mutex_enter(ST_MUTEX);
6631                                         return;
6632                                 }
6633                                 /*
6634                                  * if too many retries, fail the transport
6635                                  */
6636                                 mutex_enter(ST_MUTEX);
6637                         }
6638                 }
6639                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
6640                     "transport rejected %d\n", status);
6641                 bp->b_resid = bp->b_bcount;
6642 
6643                 ST_DO_KSTATS(bp, kstat_waitq_exit);
6644                 ST_DO_ERRSTATS(un, st_transerrs);
6645                 if ((bp == un->un_recov_buf) && (status == TRAN_BUSY)) {
6646                         st_bioerror(bp, EBUSY);
6647                 } else {
6648                         st_bioerror(bp, EIO);
6649                         st_set_pe_flag(un);
6650                 }
6651                 st_done_and_mutex_exit(un, bp);
6652                 mutex_enter(ST_MUTEX);
6653         }
6654 
6655         ASSERT(mutex_owned(ST_MUTEX));
6656 }
6657 
6658 /*
6659  * if the transport is busy, then put this bp back on the waitq
6660  */
6661 static int
6662 st_handle_start_busy(struct scsi_tape *un, struct buf *bp,
6663     clock_t timeout_interval, int queued)
6664 {
6665 
6666         pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
6667 
6668         ST_FUNC(ST_DEVINFO, st_handle_start_busy);
6669 
6670         mutex_enter(ST_MUTEX);
6671 
6672         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6673             "st_handle_start_busy()\n");
6674 
6675         /*
6676          * Check to see if we hit the retry timeout and one last check for
6677          * making sure this is the last on the runq, if it is not, we have
6678          * to fail
6679          */
6680         if ((pktinfo->str_retry_cnt++ > st_retry_count) ||
6681             ((queued) && (un->un_runql != bp))) {
6682                 mutex_exit(ST_MUTEX);
6683                 return (-1);
6684         }
6685 
6686         if (queued) {
6687                 /* put the bp back on the waitq */
6688                 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quef, bp);
6689         }
6690 
6691         /*
6692          * Decrement un_ncmds so that this
6693          * gets thru' st_start() again.
6694          */
6695         un->un_ncmds--;
6696 
6697         if (queued) {
6698                 /*
6699                  * since this is an error case, we won't have to do this list
6700                  * walking much. We've already made sure this bp was the
6701                  * last on the runq
6702                  */
6703                 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
6704 
6705                 /*
6706                  * send a marker pkt, if appropriate
6707                  */
6708                 st_hba_unflush(un);
6709 
6710         }
6711         /*
6712          * all queues are aligned, we are just waiting to
6713          * transport, don't alloc any more buf p's, when
6714          * st_start is reentered.
6715          */
6716         (void) timeout(st_start_restart, un, timeout_interval);
6717 
6718         mutex_exit(ST_MUTEX);
6719         return (0);
6720 }
6721 
6722 
6723 /*
6724  * st_runout a callback that is called what a resource allocatation failed
6725  */
6726 static int
6727 st_runout(caddr_t arg)
6728 {
6729         struct scsi_tape *un = (struct scsi_tape *)arg;
6730         struct buf *bp;
6731         int queued;
6732 
6733         ASSERT(un != NULL);
6734 
6735         ST_FUNC(ST_DEVINFO, st_runout);
6736 
6737         mutex_enter(ST_MUTEX);
6738 
6739         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_runout()\n");
6740 
6741         if (un->un_recov_buf_busy != 0) {
6742                 bp = un->un_recov_buf;
6743                 queued = 0;
6744         } else if (un->un_sbuf_busy != 0) {
6745                 /* sbuf commands should only happen with an empty queue. */
6746                 ASSERT(un->un_quef == NULL);
6747                 ASSERT(un->un_runqf == NULL);
6748                 bp = un->un_sbufp;
6749                 queued = 0;
6750         } else if (un->un_quef != NULL) {
6751                 bp = un->un_quef;
6752                 if (un->un_persistence && un->un_persist_errors) {
6753                         mutex_exit(ST_MUTEX);
6754                         bp->b_resid = bp->b_bcount;
6755                         biodone(bp);
6756                         return (1);
6757                 }
6758                 queued = 1;
6759         } else {
6760                 ASSERT(1 == 0);
6761                 mutex_exit(ST_MUTEX);
6762                 return (1);
6763         }
6764 
6765         /*
6766          * failed scsi_init_pkt(). If errno is zero its retryable.
6767          */
6768         if ((bp != NULL) && (geterror(bp) != 0)) {
6769 
6770                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
6771                     "errors after pkt alloc (b_flags=0x%x, b_error=0x%x)\n",
6772                     bp->b_flags, geterror(bp));
6773                 ASSERT((bp->b_flags & B_DONE) == 0);
6774 
6775                 if (queued) {
6776                         (void) st_remove_from_queue(&un->un_quef, &un->un_quel,
6777                             bp);
6778                 }
6779                 mutex_exit(ST_MUTEX);
6780 
6781                 ASSERT((bp->b_flags & B_DONE) == 0);
6782 
6783                 /*
6784                  * Set resid, Error already set, then unblock calling thread.
6785                  */
6786                 bp->b_resid = bp->b_bcount;
6787                 biodone(bp);
6788         } else {
6789                 /*
6790                  * Try Again
6791                  */
6792                 st_start(un);
6793                 mutex_exit(ST_MUTEX);
6794         }
6795 
6796         /*
6797          * Comments courtesy of sd.c
6798          * The scsi_init_pkt routine allows for the callback function to
6799          * return a 0 indicating the callback should be rescheduled or a 1
6800          * indicating not to reschedule. This routine always returns 1
6801          * because the driver always provides a callback function to
6802          * scsi_init_pkt. This results in a callback always being scheduled
6803          * (via the scsi_init_pkt callback implementation) if a resource
6804          * failure occurs.
6805          */
6806 
6807         return (1);
6808 }
6809 
6810 /*
6811  * st_done_and_mutex_exit()
6812  *      - remove bp from runq
6813  *      - start up the next request
6814  *      - if this was an asynch bp, clean up
6815  *      - exit with released mutex
6816  */
6817 static void
6818 st_done_and_mutex_exit(struct scsi_tape *un, struct buf *bp)
6819 {
6820         int pe_flagged = 0;
6821         struct scsi_pkt *pkt = BP_PKT(bp);
6822         pkt_info *pktinfo = pkt->pkt_private;
6823 
6824         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
6825 #if !defined(lint)
6826         _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&un->un_sd->sd_mutex))
6827 #endif
6828 
6829         ST_FUNC(ST_DEVINFO, st_done_and_mutex_exit);
6830 
6831         ASSERT(mutex_owned(ST_MUTEX));
6832 
6833         (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
6834 
6835         un->un_ncmds--;
6836         cv_signal(&un->un_queue_cv);
6837 
6838         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6839             "st_done_and_mutex_exit(): cmd=0x%x count=%ld resid=%ld  flags="
6840             "0x%x\n", pkt->pkt_cdbp[0], bp->b_bcount,
6841             bp->b_resid, bp->b_flags);
6842 
6843 
6844         /*
6845          * update kstats with transfer count info
6846          */
6847         if (un->un_stats && (bp != un->un_sbufp) && IS_RW(bp)) {
6848                 uint32_t n_done =  bp->b_bcount - bp->b_resid;
6849                 if (bp->b_flags & B_READ) {
6850                         IOSP->reads++;
6851                         IOSP->nread += n_done;
6852                 } else {
6853                         IOSP->writes++;
6854                         IOSP->nwritten += n_done;
6855                 }
6856         }
6857 
6858         /*
6859          * Start the next one before releasing resources on this one, if
6860          * there is something on the queue and persistent errors has not been
6861          * flagged
6862          */
6863 
6864         if ((pe_flagged = (un->un_persistence && un->un_persist_errors)) != 0) {
6865                 un->un_last_resid = bp->b_resid;
6866                 un->un_last_count = bp->b_bcount;
6867         }
6868 
6869         if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
6870                 cv_broadcast(&un->un_tape_busy_cv);
6871         } else if (un->un_quef && un->un_throttle && !pe_flagged &&
6872             (bp != un->un_recov_buf)) {
6873                 st_start(un);
6874         }
6875 
6876         un->un_retry_ct = max(pktinfo->pkt_retry_cnt, pktinfo->str_retry_cnt);
6877 
6878         if (bp == un->un_sbufp && (bp->b_flags & B_ASYNC)) {
6879                 /*
6880                  * Since we marked this ourselves as ASYNC,
6881                  * there isn't anybody around waiting for
6882                  * completion any more.
6883                  */
6884                 uchar_t *cmd = pkt->pkt_cdbp;
6885                 if (*cmd == SCMD_READ || *cmd == SCMD_WRITE) {
6886                         bp->b_un.b_addr = (caddr_t)0;
6887                 }
6888                 ST_DEBUG(ST_DEVINFO, st_label, CE_NOTE,
6889                     "st_done_and_mutex_exit(async): freeing pkt\n");
6890                 st_print_cdb(ST_DEVINFO, st_label, CE_NOTE,
6891                     "CDB sent with B_ASYNC",  (caddr_t)cmd);
6892                 if (pkt) {
6893                         scsi_destroy_pkt(pkt);
6894                 }
6895                 un->un_sbuf_busy = 0;
6896                 cv_signal(&un->un_sbuf_cv);
6897                 mutex_exit(ST_MUTEX);
6898                 return;
6899         }
6900 
6901         if (bp == un->un_sbufp && BP_UCMD(bp)) {
6902                 /*
6903                  * Copy status from scsi_pkt to uscsi_cmd
6904                  * since st_uscsi_cmd needs it
6905                  */
6906                 BP_UCMD(bp)->uscsi_status = SCBP_C(BP_PKT(bp));
6907         }
6908 
6909 
6910 #ifdef STDEBUG
6911         if (((st_debug & 0x7) >= 4) &&
6912             (((un->un_pos.blkno % 100) == 0) ||
6913             (un->un_persistence && un->un_persist_errors))) {
6914 
6915                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6916                     "st_d_a_m_exit(): ncmds = %d, thr = %d, "
6917                     "un_errno = %d, un_pe = %d\n",
6918                     un->un_ncmds, un->un_throttle, un->un_errno,
6919                     un->un_persist_errors);
6920         }
6921 
6922 #endif
6923 
6924         mutex_exit(ST_MUTEX);
6925         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6926             "st_done_and_mutex_exit: freeing pkt\n");
6927 
6928         if (pkt) {
6929                 scsi_destroy_pkt(pkt);
6930         }
6931 
6932         biodone(bp);
6933 
6934         /*
6935          * now that we biodoned that command, if persistent errors have been
6936          * flagged, flush the waitq
6937          */
6938         if (pe_flagged)
6939                 st_flush(un);
6940 }
6941 
6942 
6943 /*
6944  * Tape error, flush tape driver queue.
6945  */
6946 static void
6947 st_flush(struct scsi_tape *un)
6948 {
6949         struct buf *bp;
6950 
6951         ST_FUNC(ST_DEVINFO, st_flush);
6952 
6953         mutex_enter(ST_MUTEX);
6954 
6955         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6956             "st_flush(), ncmds = %d, quef = 0x%p\n",
6957             un->un_ncmds, (void *)un->un_quef);
6958 
6959         /*
6960          * if we still have commands outstanding, wait for them to come in
6961          * before flushing the queue, and make sure there is a queue
6962          */
6963         if (un->un_ncmds || !un->un_quef)
6964                 goto exit;
6965 
6966         /*
6967          * we have no more commands outstanding, so let's deal with special
6968          * cases in the queue for EOM and FM. If we are here, and un_errno
6969          * is 0, then we know there was no error and we return a 0 read or
6970          * write before showing errors
6971          */
6972 
6973         /* Flush the wait queue. */
6974         while ((bp = un->un_quef) != NULL) {
6975                 un->un_quef = bp->b_actf;
6976 
6977                 bp->b_resid = bp->b_bcount;
6978 
6979                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6980                     "st_flush() : blkno=%d, err=%d, b_bcount=%ld\n",
6981                     un->un_pos.blkno, un->un_errno, bp->b_bcount);
6982 
6983                 st_set_pe_errno(un);
6984 
6985                 bioerror(bp, un->un_errno);
6986 
6987                 mutex_exit(ST_MUTEX);
6988                 /* it should have one, but check anyway */
6989                 if (BP_PKT(bp)) {
6990                         scsi_destroy_pkt(BP_PKT(bp));
6991                 }
6992                 biodone(bp);
6993                 mutex_enter(ST_MUTEX);
6994         }
6995 
6996         /*
6997          * It's not a bad practice to reset the
6998          * waitq tail pointer to NULL.
6999          */
7000         un->un_quel = NULL;
7001 
7002 exit:
7003         /* we mucked with the queue, so let others know about it */
7004         cv_signal(&un->un_queue_cv);
7005         mutex_exit(ST_MUTEX);
7006 }
7007 
7008 
7009 /*
7010  * Utility functions
7011  */
7012 static int
7013 st_determine_generic(struct scsi_tape *un)
7014 {
7015         int bsize;
7016         static char *cart = "0.25 inch cartridge";
7017         char *sizestr;
7018 
7019         ST_FUNC(ST_DEVINFO, st_determine_generic);
7020 
7021         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7022             "st_determine_generic(un = 0x%p)\n", (void*)un);
7023 
7024         ASSERT(mutex_owned(ST_MUTEX));
7025 
7026         if (st_modesense(un)) {
7027                 return (-1);
7028         }
7029 
7030         bsize = (un->un_mspl->high_bl << 16)        |
7031             (un->un_mspl->mid_bl << 8)      |
7032             (un->un_mspl->low_bl);
7033 
7034         if (bsize == 0) {
7035                 un->un_dp->options |= ST_VARIABLE;
7036                 un->un_dp->bsize = 0;
7037                 un->un_bsize = 0;
7038         } else if (bsize > ST_MAXRECSIZE_FIXED) {
7039                 /*
7040                  * record size of this device too big.
7041                  * try and convert it to variable record length.
7042                  *
7043                  */
7044                 un->un_dp->options |= ST_VARIABLE;
7045                 if (st_change_block_size(un, 0) != 0) {
7046                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
7047                             "Fixed Record Size %d is too large\n", bsize);
7048                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
7049                             "Cannot switch to variable record size\n");
7050                         un->un_dp->options &= ~ST_VARIABLE;
7051                         return (-1);
7052                 }
7053         } else if (st_change_block_size(un, 0) == 0) {
7054                 /*
7055                  * If the drive was set to a non zero block size,
7056                  * See if it can be set to a zero block size.
7057                  * If it works, ST_VARIABLE so user can set it as they want.
7058                  */
7059                 un->un_dp->options |= ST_VARIABLE;
7060                 un->un_dp->bsize = 0;
7061                 un->un_bsize = 0;
7062         } else {
7063                 un->un_dp->bsize = bsize;
7064                 un->un_bsize = bsize;
7065         }
7066 
7067 
7068         switch (un->un_mspl->density) {
7069         default:
7070         case 0x0:
7071                 /*
7072                  * default density, cannot determine any other
7073                  * information.
7074                  */
7075                 sizestr = "Unknown type- assuming 0.25 inch cartridge";
7076                 un->un_dp->type = ST_TYPE_DEFAULT;
7077                 un->un_dp->options |= (ST_AUTODEN_OVERRIDE|ST_QIC);
7078                 break;
7079         case 0x1:
7080         case 0x2:
7081         case 0x3:
7082         case 0x6:
7083                 /*
7084                  * 1/2" reel
7085                  */
7086                 sizestr = "0.50 inch reel";
7087                 un->un_dp->type = ST_TYPE_REEL;
7088                 un->un_dp->options |= ST_REEL;
7089                 un->un_dp->densities[0] = 0x1;
7090                 un->un_dp->densities[1] = 0x2;
7091                 un->un_dp->densities[2] = 0x6;
7092                 un->un_dp->densities[3] = 0x3;
7093                 break;
7094         case 0x4:
7095         case 0x5:
7096         case 0x7:
7097         case 0x0b:
7098 
7099                 /*
7100                  * Quarter inch.
7101                  */
7102                 sizestr = cart;
7103                 un->un_dp->type = ST_TYPE_DEFAULT;
7104                 un->un_dp->options |= ST_QIC;
7105 
7106                 un->un_dp->densities[1] = 0x4;
7107                 un->un_dp->densities[2] = 0x5;
7108                 un->un_dp->densities[3] = 0x7;
7109                 un->un_dp->densities[0] = 0x0b;
7110                 break;
7111 
7112         case 0x0f:
7113         case 0x10:
7114         case 0x11:
7115         case 0x12:
7116                 /*
7117                  * QIC-120, QIC-150, QIC-320, QIC-600
7118                  */
7119                 sizestr = cart;
7120                 un->un_dp->type = ST_TYPE_DEFAULT;
7121                 un->un_dp->options |= ST_QIC;
7122                 un->un_dp->densities[0] = 0x0f;
7123                 un->un_dp->densities[1] = 0x10;
7124                 un->un_dp->densities[2] = 0x11;
7125                 un->un_dp->densities[3] = 0x12;
7126                 break;
7127 
7128         case 0x09:
7129         case 0x0a:
7130         case 0x0c:
7131         case 0x0d:
7132                 /*
7133                  * 1/2" cartridge tapes. Include HI-TC.
7134                  */
7135                 sizestr = cart;
7136                 sizestr[2] = '5';
7137                 sizestr[3] = '0';
7138                 un->un_dp->type = ST_TYPE_HIC;
7139                 un->un_dp->densities[0] = 0x09;
7140                 un->un_dp->densities[1] = 0x0a;
7141                 un->un_dp->densities[2] = 0x0c;
7142                 un->un_dp->densities[3] = 0x0d;
7143                 break;
7144 
7145         case 0x13:
7146                         /* DDS-2/DDS-3 scsi spec densities */
7147         case 0x24:
7148         case 0x25:
7149         case 0x26:
7150                 sizestr = "DAT Data Storage (DDS)";
7151                 un->un_dp->type = ST_TYPE_DAT;
7152                 un->un_dp->options |= ST_AUTODEN_OVERRIDE;
7153                 break;
7154 
7155         case 0x14:
7156                 /*
7157                  * Helical Scan (Exabyte) devices
7158                  */
7159                 sizestr = "8mm helical scan cartridge";
7160                 un->un_dp->type = ST_TYPE_EXABYTE;
7161                 un->un_dp->options |= ST_AUTODEN_OVERRIDE;
7162                 break;
7163         }
7164 
7165         /*
7166          * Assume LONG ERASE, BSF and BSR
7167          */
7168 
7169         un->un_dp->options |=
7170             (ST_LONG_ERASE | ST_UNLOADABLE | ST_BSF | ST_BSR | ST_KNOWS_EOD);
7171 
7172         /*
7173          * Only if mode sense data says no buffered write, set NOBUF
7174          */
7175         if (un->un_mspl->bufm == 0)
7176                 un->un_dp->options |= ST_NOBUF;
7177 
7178         /*
7179          * set up large read and write retry counts
7180          */
7181 
7182         un->un_dp->max_rretries = un->un_dp->max_wretries = 1000;
7183 
7184         /*
7185          * If this is a 0.50 inch reel tape, and
7186          * it is *not* variable mode, try and
7187          * set it to variable record length
7188          * mode.
7189          */
7190         if ((un->un_dp->options & ST_REEL) && un->un_bsize != 0 &&
7191             (un->un_dp->options & ST_VARIABLE)) {
7192                 if (st_change_block_size(un, 0) == 0) {
7193                         un->un_dp->bsize = 0;
7194                         un->un_mspl->high_bl = un->un_mspl->mid_bl =
7195                             un->un_mspl->low_bl = 0;
7196                 }
7197         }
7198 
7199         /*
7200          * Write to console about type of device found
7201          */
7202         ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
7203             "Generic Drive, Vendor=%s\n\t%s", un->un_dp->name,
7204             sizestr);
7205         if (un->un_dp->options & ST_VARIABLE) {
7206                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7207                     "!Variable record length I/O\n");
7208         } else {
7209                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7210                     "!Fixed record length (%d byte blocks) I/O\n",
7211                     un->un_dp->bsize);
7212         }
7213         ASSERT(mutex_owned(ST_MUTEX));
7214         return (0);
7215 }
7216 
7217 static int
7218 st_determine_density(struct scsi_tape *un, int rw)
7219 {
7220         int rval = 0;
7221 
7222         ST_FUNC(ST_DEVINFO, st_determine_density);
7223 
7224         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7225             "st_determine_density(un = 0x%p, rw = %s)\n",
7226             (void*)un, (rw == B_WRITE ? wr_str: rd_str));
7227 
7228         ASSERT(mutex_owned(ST_MUTEX));
7229 
7230         /*
7231          * If we're past BOT, density is determined already.
7232          */
7233         if (un->un_pos.pmode == logical) {
7234                 if (un->un_pos.lgclblkno != 0) {
7235                         goto exit;
7236                 }
7237         } else if (un->un_pos.pmode == legacy) {
7238                 if ((un->un_pos.fileno != 0) || (un->un_pos.blkno != 0)) {
7239                         /*
7240                          * XXX: put in a bitch message about attempting to
7241                          * XXX: change density past BOT.
7242                          */
7243                         goto exit;
7244                 }
7245         } else {
7246                 goto exit;
7247         }
7248         if ((un->un_pos.pmode == logical) &&
7249             (un->un_pos.lgclblkno != 0)) {
7250                 goto exit;
7251         }
7252 
7253 
7254         /*
7255          * If we're going to be writing, we set the density
7256          */
7257         if (rw == 0 || rw == B_WRITE) {
7258                 /* un_curdens is used as an index into densities table */
7259                 un->un_curdens = MT_DENSITY(un->un_dev);
7260                 if (st_set_density(un)) {
7261                         rval = -1;
7262                 }
7263                 goto exit;
7264         }
7265 
7266         /*
7267          * If density is known already,
7268          * we don't have to get it again.(?)
7269          */
7270         if (!un->un_density_known) {
7271                 if (st_get_density(un)) {
7272                         rval = -1;
7273                 }
7274         }
7275 
7276 exit:
7277         ASSERT(mutex_owned(ST_MUTEX));
7278         return (rval);
7279 }
7280 
7281 
7282 /*
7283  * Try to determine density. We do this by attempting to read the
7284  * first record off the tape, cycling through the available density
7285  * codes as we go.
7286  */
7287 
7288 static int
7289 st_get_density(struct scsi_tape *un)
7290 {
7291         int succes = 0, rval = -1, i;
7292         uint_t size;
7293         uchar_t dens, olddens;
7294 
7295         ST_FUNC(ST_DEVINFO, st_get_density);
7296 
7297         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7298             "st_get_density(un = 0x%p)\n", (void*)un);
7299 
7300         ASSERT(mutex_owned(ST_MUTEX));
7301 
7302         /*
7303          * If Auto Density override is enabled The drive has
7304          * only one density and there is no point in attempting
7305          * find the correct one.
7306          *
7307          * Since most modern drives auto detect the density
7308          * and format of the recorded media before they come
7309          * ready. What this function does is a legacy behavior
7310          * and modern drives not only don't need it, The backup
7311          * utilities that do positioning via uscsi find the un-
7312          * expected rewinds problematic.
7313          *
7314          * The drives that need this are old reel to reel devices.
7315          * I took a swag and said they must be scsi-1 or older.
7316          * I don't beleave there will any of the newer devices
7317          * that need this. There will be some scsi-1 devices that
7318          * don't need this but I don't think they will be using the
7319          * BIG aftermarket backup and restore utilitys.
7320          */
7321         if ((un->un_dp->options & ST_AUTODEN_OVERRIDE) ||
7322             (un->un_sd->sd_inq->inq_ansi > 1)) {
7323                 un->un_density_known = 1;
7324                 rval = 0;
7325                 goto exit;
7326         }
7327 
7328         /*
7329          * This will only work on variable record length tapes
7330          * if and only if all variable record length tapes autodensity
7331          * select.
7332          */
7333         size = (unsigned)(un->un_dp->bsize ? un->un_dp->bsize : SECSIZE);
7334         un->un_tmpbuf = kmem_alloc(size, KM_SLEEP);
7335 
7336         /*
7337          * Start at the specified density
7338          */
7339 
7340         dens = olddens = un->un_curdens = MT_DENSITY(un->un_dev);
7341 
7342         for (i = 0; i < NDENSITIES; i++, ((un->un_curdens == NDENSITIES - 1) ?
7343             (un->un_curdens = 0) : (un->un_curdens += 1))) {
7344                 /*
7345                  * If we've done this density before,
7346                  * don't bother to do it again.
7347                  */
7348                 dens = un->un_dp->densities[un->un_curdens];
7349                 if (i > 0 && dens == olddens)
7350                         continue;
7351                 olddens = dens;
7352                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7353                     "trying density 0x%x\n", dens);
7354                 if (st_set_density(un)) {
7355                         continue;
7356                 }
7357 
7358                 /*
7359                  * XXX - the creates lots of headaches and slowdowns - must
7360                  * fix.
7361                  */
7362                 succes = (st_cmd(un, SCMD_READ, (int)size, SYNC_CMD) == 0);
7363                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
7364                         break;
7365                 }
7366                 if (succes) {
7367                         st_init(un);
7368                         rval = 0;
7369                         un->un_density_known = 1;
7370                         break;
7371                 }
7372         }
7373         kmem_free(un->un_tmpbuf, size);
7374         un->un_tmpbuf = 0;
7375 
7376 exit:
7377         ASSERT(mutex_owned(ST_MUTEX));
7378         return (rval);
7379 }
7380 
7381 static int
7382 st_set_density(struct scsi_tape *un)
7383 {
7384         int rval = 0;
7385 
7386         ST_FUNC(ST_DEVINFO, st_set_density);
7387 
7388         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7389             "st_set_density(un = 0x%p): density = 0x%x\n", (void*)un,
7390             un->un_dp->densities[un->un_curdens]);
7391 
7392         ASSERT(mutex_owned(ST_MUTEX));
7393 
7394         un->un_mspl->density = un->un_dp->densities[un->un_curdens];
7395 
7396         if ((un->un_dp->options & ST_AUTODEN_OVERRIDE) == 0) {
7397                 /*
7398                  * If auto density override is not set, Use mode select
7399                  * to set density and compression.
7400                  */
7401                 if (st_modeselect(un)) {
7402                         rval = -1;
7403                 }
7404         } else if ((un->un_dp->options & ST_MODE_SEL_COMP) != 0) {
7405                 /*
7406                  * If auto density and mode select compression are set,
7407                  * This is a drive with one density code but compression
7408                  * can be enabled or disabled.
7409                  * Set compression but no need to set density.
7410                  */
7411                 rval = st_set_compression(un);
7412                 if ((rval != 0) && (rval != EALREADY)) {
7413                         rval = -1;
7414                 } else {
7415                         rval = 0;
7416                 }
7417         }
7418 
7419         /* If sucessful set density and/or compression, mark density known */
7420         if (rval == 0) {
7421                 un->un_density_known = 1;
7422         }
7423 
7424         ASSERT(mutex_owned(ST_MUTEX));
7425         return (rval);
7426 }
7427 
7428 static int
7429 st_loadtape(struct scsi_tape *un)
7430 {
7431         int rval;
7432 
7433         ST_FUNC(ST_DEVINFO, st_loadtape);
7434 
7435         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7436             "st_loadtape(un = 0x%p)\n", (void*) un);
7437 
7438         ASSERT(mutex_owned(ST_MUTEX));
7439 
7440         rval = st_update_block_pos(un, st_cmd, 0);
7441         if (rval == EACCES) {
7442                 return (rval);
7443         }
7444 
7445         /*
7446          * 'LOAD' the tape to BOT by rewinding
7447          */
7448         rval = st_cmd(un, SCMD_REWIND, 1, SYNC_CMD);
7449         if (rval == 0) {
7450                 st_init(un);
7451                 un->un_density_known = 0;
7452         }
7453 
7454         ASSERT(mutex_owned(ST_MUTEX));
7455         return (rval);
7456 }
7457 
7458 
7459 /*
7460  * Note: QIC devices aren't so smart.  If you try to append
7461  * after EOM, the write can fail because the device doesn't know
7462  * it's at EOM.  In that case, issue a read.  The read should fail
7463  * because there's no data, but the device knows it's at EOM,
7464  * so a subsequent write should succeed.  To further confuse matters,
7465  * the target returns the same error if the tape is positioned
7466  * such that a write would overwrite existing data.  That's why
7467  * we have to do the append test.  A read in the middle of
7468  * recorded data would succeed, thus indicating we're attempting
7469  * something illegal.
7470  */
7471 
7472 
7473 static void
7474 st_test_append(struct buf *bp)
7475 {
7476         dev_t dev = bp->b_edev;
7477         struct scsi_tape *un;
7478         uchar_t status;
7479         unsigned bcount;
7480 
7481         un = ddi_get_soft_state(st_state, MTUNIT(dev));
7482 
7483         ST_FUNC(ST_DEVINFO, st_test_append);
7484 
7485         ASSERT(mutex_owned(ST_MUTEX));
7486 
7487         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7488             "st_test_append(): fileno %d\n", un->un_pos.fileno);
7489 
7490         un->un_laststate = un->un_state;
7491         un->un_state = ST_STATE_APPEND_TESTING;
7492         un->un_test_append = 0;
7493 
7494         /*
7495          * first, map in the buffer, because we're doing a double write --
7496          * first into the kernel, then onto the tape.
7497          */
7498         bp_mapin(bp);
7499 
7500         /*
7501          * get a copy of the data....
7502          */
7503         un->un_tmpbuf = kmem_alloc((unsigned)bp->b_bcount, KM_SLEEP);
7504         bcopy(bp->b_un.b_addr, un->un_tmpbuf, (uint_t)bp->b_bcount);
7505 
7506         /*
7507          * attempt the write..
7508          */
7509 
7510         if (st_cmd(un, (int)SCMD_WRITE, (int)bp->b_bcount, SYNC_CMD) == 0) {
7511 success:
7512                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7513                     "append write succeeded\n");
7514                 bp->b_resid = un->un_sbufp->b_resid;
7515                 mutex_exit(ST_MUTEX);
7516                 bcount = (unsigned)bp->b_bcount;
7517                 biodone(bp);
7518                 mutex_enter(ST_MUTEX);
7519                 un->un_laststate = un->un_state;
7520                 un->un_state = ST_STATE_OPEN;
7521                 kmem_free(un->un_tmpbuf, bcount);
7522                 un->un_tmpbuf = NULL;
7523                 return;
7524         }
7525 
7526         /*
7527          * The append failed. Do a short read. If that fails,  we are at EOM
7528          * so we can retry the write command. If that succeeds, than we're
7529          * all screwed up (the controller reported a real error).
7530          *
7531          * XXX: should the dummy read be > SECSIZE? should it be the device's
7532          * XXX: block size?
7533          *
7534          */
7535         status = un->un_status;
7536         un->un_status = 0;
7537         (void) st_cmd(un, SCMD_READ, SECSIZE, SYNC_CMD);
7538         if (un->un_status == KEY_BLANK_CHECK) {
7539                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7540                     "append at EOM\n");
7541                 /*
7542                  * Okay- the read failed. We should actually have confused
7543                  * the controller enough to allow writing. In any case, the
7544                  * i/o is on its own from here on out.
7545                  */
7546                 un->un_laststate = un->un_state;
7547                 un->un_state = ST_STATE_OPEN;
7548                 bcopy(bp->b_un.b_addr, un->un_tmpbuf, (uint_t)bp->b_bcount);
7549                 if (st_cmd(un, (int)SCMD_WRITE, (int)bp->b_bcount,
7550                     SYNC_CMD) == 0) {
7551                         goto success;
7552                 }
7553         }
7554 
7555         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7556             "append write failed- not at EOM\n");
7557         bp->b_resid = bp->b_bcount;
7558         st_bioerror(bp, EIO);
7559 
7560         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
7561             "st_test_append : EIO : append write failed - not at EOM");
7562 
7563         /*
7564          * backspace one record to get back to where we were
7565          */
7566         if (st_cmd(un, SCMD_SPACE, Blk(-1), SYNC_CMD)) {
7567                 un->un_pos.pmode = invalid;
7568         }
7569 
7570         un->un_err_resid = bp->b_resid;
7571         un->un_status = status;
7572 
7573         /*
7574          * Note: biodone will do a bp_mapout()
7575          */
7576         mutex_exit(ST_MUTEX);
7577         bcount = (unsigned)bp->b_bcount;
7578         biodone(bp);
7579         mutex_enter(ST_MUTEX);
7580         un->un_laststate = un->un_state;
7581         un->un_state = ST_STATE_OPEN_PENDING_IO;
7582         kmem_free(un->un_tmpbuf, bcount);
7583         un->un_tmpbuf = NULL;
7584 }
7585 
7586 /*
7587  * Special command handler
7588  */
7589 
7590 /*
7591  * common st_cmd code. The fourth parameter states
7592  * whether the caller wishes to await the results
7593  * Note the release of the mutex during most of the function
7594  */
7595 static int
7596 st_cmd(struct scsi_tape *un, int com, int64_t count, int wait)
7597 {
7598         struct buf *bp;
7599         int err;
7600         uint_t last_err_resid;
7601 
7602         ST_FUNC(ST_DEVINFO, st_cmd);
7603 
7604         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7605             "st_cmd(dev = 0x%lx, com = 0x%x, count = %"PRIx64", wait = %d)\n",
7606             un->un_dev, com, count, wait);
7607 
7608         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
7609         ASSERT(mutex_owned(ST_MUTEX));
7610 
7611 #ifdef STDEBUG
7612         if ((st_debug & 0x7)) {
7613                 st_debug_cmds(un, com, count, wait);
7614         }
7615 #endif
7616 
7617         st_wait_for_io(un);
7618 
7619         /* check to see if this command requires the drive to be reserved */
7620         err = st_check_cmd_for_need_to_reserve(un, com, count);
7621 
7622         if (err) {
7623                 return (err);
7624         }
7625 
7626         /*
7627          * A space command is not recoverable if we don't know were we
7628          * were when it was issued.
7629          */
7630         if ((com == SCMD_SPACE) || (com == SCMD_SPACE_G4)) {
7631                 (void) st_update_block_pos(un, st_cmd, 0);
7632         }
7633 
7634         /*
7635          * Forground should not be doing anything while recovery is active.
7636          */
7637         ASSERT(un->un_recov_buf_busy == 0);
7638 
7639         while (un->un_sbuf_busy)
7640                 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
7641         un->un_sbuf_busy = 1;
7642 
7643         bp = un->un_sbufp;
7644         bzero(bp, sizeof (buf_t));
7645 
7646         bp->b_flags = (wait) ? B_BUSY : B_BUSY|B_ASYNC;
7647 
7648         err = st_setup_cmd(un, bp, com, count);
7649 
7650         un->un_sbuf_busy = 0;
7651 
7652         /*
7653          * If was a space command need to update logical block position.
7654          * Only do this if the command was sucessful or it will mask the fact
7655          * that the space command failed by promoting the pmode to logical.
7656          */
7657         if (((com == SCMD_SPACE) || (com == SCMD_SPACE_G4)) &&
7658             (un->un_pos.pmode != invalid)) {
7659                 un->un_running.pmode = invalid;
7660                 last_err_resid = un->un_err_resid;
7661                 (void) st_update_block_pos(un, st_cmd, 1);
7662                 /*
7663                  * Set running position to invalid so it updates on the
7664                  * next command.
7665                  */
7666                 un->un_running.pmode = invalid;
7667                 un->un_err_resid = last_err_resid;
7668         }
7669 
7670         cv_signal(&un->un_sbuf_cv);
7671 
7672         return (err);
7673 }
7674 
7675 static int
7676 st_setup_cmd(struct scsi_tape *un, buf_t *bp, int com, int64_t count)
7677 {
7678         int err;
7679         dev_t dev = un->un_dev;
7680 
7681         ST_FUNC(ST_DEVINFO, st_setup_cmd);
7682         /*
7683          * Set count to the actual size of the data tranfer.
7684          * For commands with no data transfer, set bp->b_bcount
7685          * to the value to be used when constructing the
7686          * cdb in st_make_cmd().
7687          */
7688         switch (com) {
7689         case SCMD_READ:
7690                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7691                     "special read %"PRId64"\n", count);
7692                 bp->b_flags |= B_READ;
7693                 bp->b_un.b_addr = un->un_tmpbuf;
7694                 break;
7695 
7696         case SCMD_WRITE:
7697                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7698                     "special write %"PRId64"\n", count);
7699                 bp->b_un.b_addr = un->un_tmpbuf;
7700                 break;
7701 
7702         case SCMD_WRITE_FILE_MARK:
7703                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7704                     "write %"PRId64" file marks\n", count);
7705                 bp->b_bcount = count;
7706                 count = 0;
7707                 break;
7708 
7709         case SCMD_REWIND:
7710                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "rewind\n");
7711                 bp->b_bcount = count;
7712                 count = 0;
7713                 break;
7714 
7715         case SCMD_SPACE:
7716                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "space\n");
7717                 /*
7718                  * If the user could have entered a number that will
7719                  * not fit in the 12 bit count field of space(8),
7720                  * use space(16).
7721                  */
7722                 if (((int64_t)SPACE_CNT(count) > 0x7fffff) ||
7723                     ((int64_t)SPACE_CNT(count) < -(0x7fffff))) {
7724                         com = SCMD_SPACE_G4;
7725                 }
7726                 bp->b_bcount = count;
7727                 count = 0;
7728                 break;
7729 
7730         case SCMD_RESERVE:
7731                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "reserve");
7732                 bp->b_bcount = 0;
7733                 count = 0;
7734                 break;
7735 
7736         case SCMD_RELEASE:
7737                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "release");
7738                 bp->b_bcount = 0;
7739                 count = 0;
7740                 break;
7741 
7742         case SCMD_LOAD:
7743                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7744                     "%s tape\n", (count & LD_LOAD) ? "load" : "unload");
7745                 bp->b_bcount = count;
7746                 count = 0;
7747                 break;
7748 
7749         case SCMD_ERASE:
7750                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7751                     "erase tape\n");
7752                 bp->b_bcount = count;
7753                 count = 0;
7754                 break;
7755 
7756         case SCMD_MODE_SENSE:
7757                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7758                     "mode sense\n");
7759                 bp->b_flags |= B_READ;
7760                 bp->b_un.b_addr = (caddr_t)(un->un_mspl);
7761                 break;
7762 
7763         case SCMD_MODE_SELECT:
7764                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7765                     "mode select\n");
7766                 bp->b_un.b_addr = (caddr_t)(un->un_mspl);
7767                 break;
7768 
7769         case SCMD_READ_BLKLIM:
7770                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7771                     "read block limits\n");
7772                 bp->b_bcount = count;
7773                 bp->b_flags |= B_READ;
7774                 bp->b_un.b_addr = (caddr_t)(un->un_rbl);
7775                 break;
7776 
7777         case SCMD_TEST_UNIT_READY:
7778                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7779                     "test unit ready\n");
7780                 bp->b_bcount = 0;
7781                 count = 0;
7782                 break;
7783 
7784         case SCMD_DOORLOCK:
7785                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7786                     "%s tape\n", (count & MR_LOCK) ? "lock" : "unlock");
7787                 bp->b_bcount = count = 0;
7788                 break;
7789 
7790         case SCMD_READ_POSITION:
7791                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7792                     "read position\n");
7793                 switch (un->un_read_pos_type) {
7794                 case LONG_POS:
7795                         count = sizeof (tape_position_long_t);
7796                         break;
7797                 case EXT_POS:
7798                         count = min(count, sizeof (tape_position_ext_t));
7799                         break;
7800                 case SHORT_POS:
7801                         count = sizeof (tape_position_t);
7802                         break;
7803                 default:
7804                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
7805                             "Unknown read position type 0x%x in "
7806                             "st_make_cmd()\n", un->un_read_pos_type);
7807                 }
7808                 bp->b_bcount = count;
7809                 bp->b_flags |= B_READ;
7810                 bp->b_un.b_addr = (caddr_t)un->un_read_pos_data;
7811                 break;
7812 
7813         default:
7814                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
7815                     "Unhandled scsi command 0x%x in st_setup_cmd()\n", com);
7816         }
7817 
7818         mutex_exit(ST_MUTEX);
7819 
7820         if (count > 0) {
7821                 int flg = (bp->b_flags & B_READ) ? B_READ : B_WRITE;
7822                 /*
7823                  * We're going to do actual I/O.
7824                  * Set things up for physio.
7825                  */
7826                 struct iovec aiov;
7827                 struct uio auio;
7828                 struct uio *uio = &auio;
7829 
7830                 bzero(&auio, sizeof (struct uio));
7831                 bzero(&aiov, sizeof (struct iovec));
7832                 aiov.iov_base = bp->b_un.b_addr;
7833                 aiov.iov_len = count;
7834 
7835                 uio->uio_iov = &aiov;
7836                 uio->uio_iovcnt = 1;
7837                 uio->uio_resid = aiov.iov_len;
7838                 uio->uio_segflg = UIO_SYSSPACE;
7839 
7840                 /*
7841                  * Let physio do the rest...
7842                  */
7843                 bp->b_forw = (struct buf *)(uintptr_t)com;
7844                 bp->b_back = NULL;
7845                 err = physio(st_strategy, bp, dev, flg, st_minphys, uio);
7846                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7847                     "st_setup_cmd: physio returns %d\n", err);
7848         } else {
7849                 /*
7850                  * Mimic physio
7851                  */
7852                 bp->b_forw = (struct buf *)(uintptr_t)com;
7853                 bp->b_back = NULL;
7854                 bp->b_edev = dev;
7855                 bp->b_dev = cmpdev(dev);
7856                 bp->b_blkno = 0;
7857                 bp->b_resid = 0;
7858                 (void) st_strategy(bp);
7859                 if (bp->b_flags & B_ASYNC) {
7860                         /*
7861                          * This is an async command- the caller won't wait
7862                          * and doesn't care about errors.
7863                          */
7864                         mutex_enter(ST_MUTEX);
7865                         return (0);
7866                 }
7867 
7868                 /*
7869                  * BugTraq #4260046
7870                  * ----------------
7871                  * Restore Solaris 2.5.1 behavior, namely call biowait
7872                  * unconditionally. The old comment said...
7873                  *
7874                  * "if strategy was flagged with  persistent errors, we would
7875                  *  have an error here, and the bp would never be sent, so we
7876                  *  don't want to wait on a bp that was never sent...or hang"
7877                  *
7878                  * The new rationale, courtesy of Chitrank...
7879                  *
7880                  * "we should unconditionally biowait() here because
7881                  *  st_strategy() will do a biodone() in the persistent error
7882                  *  case and the following biowait() will return immediately.
7883                  *  If not, in the case of "errors after pkt alloc" in
7884                  *  st_start(), we will not biowait here which will cause the
7885                  *  next biowait() to return immediately which will cause
7886                  *  us to send out the next command. In the case where both of
7887                  *  these use the sbuf, when the first command completes we'll
7888                  *  free the packet attached to sbuf and the same pkt will
7889                  *  get freed again when we complete the second command.
7890                  *  see esc 518987.  BTW, it is necessary to do biodone() in
7891                  *  st_start() for the pkt alloc failure case because physio()
7892                  *  does biowait() and will hang if we don't do biodone()"
7893                  */
7894 
7895                 err = biowait(bp);
7896                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7897                     "st_setup_cmd: biowait returns %d\n", err);
7898         }
7899 
7900         mutex_enter(ST_MUTEX);
7901 
7902         return (err);
7903 }
7904 
7905 static int
7906 st_set_compression(struct scsi_tape *un)
7907 {
7908         int rval;
7909         int turn_compression_on;
7910         minor_t minor;
7911 
7912         ST_FUNC(ST_DEVINFO, st_set_compression);
7913 
7914         /*
7915          * Drive either dosn't have compression or it is controlled with
7916          * special density codes. Return ENOTTY so caller
7917          * knows nothing was done.
7918          */
7919         if ((un->un_dp->options & ST_MODE_SEL_COMP) == 0) {
7920                 un->un_comp_page = 0;
7921                 return (ENOTTY);
7922         }
7923 
7924         /* set compression based on minor node opened */
7925         minor = MT_DENSITY(un->un_dev);
7926 
7927         /*
7928          * If this the compression density or
7929          * the drive has two densities and uses mode select for
7930          * control of compression turn on compression for MT_DENSITY2
7931          * as well.
7932          */
7933         if ((minor == ST_COMPRESSION_DENSITY) ||
7934             (minor == MT_DENSITY(MT_DENSITY2)) &&
7935             (un->un_dp->densities[0] == un->un_dp->densities[1]) &&
7936             (un->un_dp->densities[2] == un->un_dp->densities[3]) &&
7937             (un->un_dp->densities[0] != un->un_dp->densities[2])) {
7938 
7939                 turn_compression_on = 1;
7940         } else {
7941                 turn_compression_on = 0;
7942         }
7943 
7944         un->un_mspl->high_bl = (uchar_t)(un->un_bsize >> 16);
7945         un->un_mspl->mid_bl  = (uchar_t)(un->un_bsize >> 8);
7946         un->un_mspl->low_bl  = (uchar_t)(un->un_bsize);
7947 
7948         /*
7949          * Need to determine which page does the device use for compression.
7950          * First try the data compression page. If this fails try the device
7951          * configuration page
7952          */
7953 
7954         if ((un->un_comp_page & ST_DEV_DATACOMP_PAGE) == ST_DEV_DATACOMP_PAGE) {
7955                 rval = st_set_datacomp_page(un, turn_compression_on);
7956                 if (rval == EALREADY) {
7957                         return (rval);
7958                 }
7959                 if (rval != 0) {
7960                         if (un->un_status == KEY_ILLEGAL_REQUEST) {
7961                                 /*
7962                                  * This device does not support data
7963                                  * compression page
7964                                  */
7965                                 un->un_comp_page = ST_DEV_CONFIG_PAGE;
7966                         } else if (un->un_state >= ST_STATE_OPEN) {
7967                                 un->un_pos.pmode = invalid;
7968                                 rval = EIO;
7969                         } else {
7970                                 rval = -1;
7971                         }
7972                 } else {
7973                         un->un_comp_page = ST_DEV_DATACOMP_PAGE;
7974                 }
7975         }
7976 
7977         if ((un->un_comp_page & ST_DEV_CONFIG_PAGE) == ST_DEV_CONFIG_PAGE) {
7978                 rval = st_set_devconfig_page(un, turn_compression_on);
7979                 if (rval == EALREADY) {
7980                         return (rval);
7981                 }
7982                 if (rval != 0) {
7983                         if (un->un_status == KEY_ILLEGAL_REQUEST) {
7984                                 /*
7985                                  * This device does not support
7986                                  * compression at all advice the
7987                                  * user and unset ST_MODE_SEL_COMP
7988                                  */
7989                                 un->un_dp->options &= ~ST_MODE_SEL_COMP;
7990                                 un->un_comp_page = 0;
7991                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7992                                     "Device Does Not Support Compression\n");
7993                         } else if (un->un_state >= ST_STATE_OPEN) {
7994                                 un->un_pos.pmode = invalid;
7995                                 rval = EIO;
7996                         } else {
7997                                 rval = -1;
7998                         }
7999                 }
8000         }
8001 
8002         return (rval);
8003 }
8004 
8005 /*
8006  * set or unset compression thru device configuration page.
8007  */
8008 static int
8009 st_set_devconfig_page(struct scsi_tape *un, int compression_on)
8010 {
8011         unsigned char cflag;
8012         int rval = 0;
8013 
8014 
8015         ST_FUNC(ST_DEVINFO, st_set_devconfig_page);
8016 
8017         ASSERT(mutex_owned(ST_MUTEX));
8018 
8019         /*
8020          * if the mode sense page is not the correct one, load the correct one.
8021          */
8022         if (un->un_mspl->page_code != ST_DEV_CONFIG_PAGE) {
8023                 rval = st_gen_mode_sense(un, st_uscsi_cmd, ST_DEV_CONFIG_PAGE,
8024                     un->un_mspl, sizeof (struct seq_mode));
8025                 if (rval)
8026                         return (rval);
8027         }
8028 
8029         /*
8030          * Figure what to set compression flag to.
8031          */
8032         if (compression_on) {
8033                 /* They have selected a compression node */
8034                 if (un->un_dp->type == ST_TYPE_FUJI) {
8035                         cflag = 0x84;   /* use EDRC */
8036                 } else {
8037                         cflag = ST_DEV_CONFIG_DEF_COMP;
8038                 }
8039         } else {
8040                 cflag = ST_DEV_CONFIG_NO_COMP;
8041         }
8042 
8043         /*
8044          * If compression is already set the way it was requested.
8045          * And if this not the first time we has tried.
8046          */
8047         if ((cflag == un->un_mspl->page.dev.comp_alg) &&
8048             (un->un_comp_page == ST_DEV_CONFIG_PAGE)) {
8049                 return (EALREADY);
8050         }
8051 
8052         un->un_mspl->page.dev.comp_alg = cflag;
8053         /*
8054          * need to send mode select even if correct compression is
8055          * already set since need to set density code
8056          */
8057 
8058 #ifdef STDEBUG
8059         if ((st_debug & 0x7) >= 6) {
8060                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
8061                     "st_set_devconfig_page: sense data for mode select",
8062                     (char *)un->un_mspl, sizeof (struct seq_mode));
8063         }
8064 #endif
8065         rval = st_gen_mode_select(un, st_uscsi_cmd, un->un_mspl,
8066             sizeof (struct seq_mode));
8067 
8068         return (rval);
8069 }
8070 
8071 /*
8072  * set/reset compression bit thru data compression page
8073  */
8074 static int
8075 st_set_datacomp_page(struct scsi_tape *un, int compression_on)
8076 {
8077         int compression_on_already;
8078         int rval = 0;
8079 
8080 
8081         ST_FUNC(ST_DEVINFO, st_set_datacomp_page);
8082 
8083         ASSERT(mutex_owned(ST_MUTEX));
8084 
8085         /*
8086          * if the mode sense page is not the correct one, load the correct one.
8087          */
8088         if (un->un_mspl->page_code != ST_DEV_DATACOMP_PAGE) {
8089                 rval = st_gen_mode_sense(un, st_uscsi_cmd, ST_DEV_DATACOMP_PAGE,
8090                     un->un_mspl, sizeof (struct seq_mode));
8091                 if (rval)
8092                         return (rval);
8093         }
8094 
8095         /*
8096          * If drive is not capable of compression (at this time)
8097          * return EALREADY so caller doesn't think that this page
8098          * is not supported. This check is for drives that can
8099          * disable compression from the front panel or configuration.
8100          * I doubt that a drive that supports this page is not really
8101          * capable of compression.
8102          */
8103         if (un->un_mspl->page.comp.dcc == 0) {
8104                 return (EALREADY);
8105         }
8106 
8107         /* See if compression currently turned on */
8108         if (un->un_mspl->page.comp.dce) {
8109                 compression_on_already = 1;
8110         } else {
8111                 compression_on_already = 0;
8112         }
8113 
8114         /*
8115          * If compression is already set the way it was requested.
8116          * And if this not the first time we has tried.
8117          */
8118         if ((compression_on == compression_on_already) &&
8119             (un->un_comp_page == ST_DEV_DATACOMP_PAGE)) {
8120                 return (EALREADY);
8121         }
8122 
8123         /*
8124          * if we are already set to the appropriate compression
8125          * mode, don't set it again
8126          */
8127         if (compression_on) {
8128                 /* compression selected */
8129                 un->un_mspl->page.comp.dce = 1;
8130         } else {
8131                 un->un_mspl->page.comp.dce = 0;
8132         }
8133 
8134 
8135 #ifdef STDEBUG
8136         if ((st_debug & 0x7) >= 6) {
8137                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
8138                     "st_set_datacomp_page: sense data for mode select",
8139                     (char *)un->un_mspl, sizeof (struct seq_mode));
8140         }
8141 #endif
8142         rval = st_gen_mode_select(un, st_uscsi_cmd, un->un_mspl,
8143             sizeof (struct seq_mode));
8144 
8145         return (rval);
8146 }
8147 
8148 static int
8149 st_modesense(struct scsi_tape *un)
8150 {
8151         int rval;
8152         uchar_t page;
8153 
8154         ST_FUNC(ST_DEVINFO, st_modesense);
8155 
8156         page = un->un_comp_page;
8157 
8158         switch (page) {
8159         case ST_DEV_DATACOMP_PAGE:
8160         case ST_DEV_CONFIG_PAGE: /* FALLTHROUGH */
8161                 rval = st_gen_mode_sense(un, st_uscsi_cmd, page, un->un_mspl,
8162                     sizeof (struct seq_mode));
8163                 break;
8164 
8165         case ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE:
8166                 if (un->un_dp->options & ST_MODE_SEL_COMP) {
8167                         page = ST_DEV_DATACOMP_PAGE;
8168                         rval = st_gen_mode_sense(un, st_uscsi_cmd, page,
8169                             un->un_mspl, sizeof (struct seq_mode));
8170                         if (rval == 0 && un->un_mspl->page_code == page) {
8171                                 un->un_comp_page = page;
8172                                 break;
8173                         }
8174                         page = ST_DEV_CONFIG_PAGE;
8175                         rval = st_gen_mode_sense(un, st_uscsi_cmd, page,
8176                             un->un_mspl, sizeof (struct seq_mode));
8177                         if (rval == 0 && un->un_mspl->page_code == page) {
8178                                 un->un_comp_page = page;
8179                                 break;
8180                         }
8181                         un->un_dp->options &= ~ST_MODE_SEL_COMP;
8182                         un->un_comp_page = 0;
8183                 } else {
8184                         un->un_comp_page = 0;
8185                 }
8186 
8187         default:        /* FALLTHROUGH */
8188                 rval = st_cmd(un, SCMD_MODE_SENSE, MSIZE, SYNC_CMD);
8189         }
8190         return (rval);
8191 }
8192 
8193 static int
8194 st_modeselect(struct scsi_tape *un)
8195 {
8196         int rval = 0;
8197         int ix;
8198 
8199         ST_FUNC(ST_DEVINFO, st_modeselect);
8200 
8201         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8202             "st_modeselect(dev = 0x%lx): density = 0x%x\n",
8203             un->un_dev, un->un_mspl->density);
8204 
8205         ASSERT(mutex_owned(ST_MUTEX));
8206 
8207         /*
8208          * The parameter list should be the same for all of the
8209          * cases that follow so set them here
8210          *
8211          * Try mode select first if if fails set fields manually
8212          */
8213         rval = st_modesense(un);
8214         if (rval != 0) {
8215                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
8216                     "st_modeselect: First mode sense failed\n");
8217                 un->un_mspl->bd_len  = 8;
8218                 un->un_mspl->high_nb = 0;
8219                 un->un_mspl->mid_nb  = 0;
8220                 un->un_mspl->low_nb  = 0;
8221         }
8222         un->un_mspl->high_bl = (uchar_t)(un->un_bsize >> 16);
8223         un->un_mspl->mid_bl  = (uchar_t)(un->un_bsize >> 8);
8224         un->un_mspl->low_bl  = (uchar_t)(un->un_bsize);
8225 
8226 
8227         /*
8228          * If configured to use a specific density code for a media type.
8229          * curdens is previously set by the minor node opened.
8230          * If the media type doesn't match the minor node we change it so it
8231          * looks like the correct one was opened.
8232          */
8233         if (un->un_dp->options & ST_KNOWS_MEDIA) {
8234                 uchar_t best;
8235 
8236                 for (best = 0xff, ix = 0; ix < NDENSITIES; ix++) {
8237                         if (un->un_mspl->media_type ==
8238                             un->un_dp->mediatype[ix]) {
8239                                 best = ix;
8240                                 /*
8241                                  * It matches but it might not be the only one.
8242                                  * Use the highest matching media type but not
8243                                  * to exceed the density selected by the open.
8244                                  */
8245                                 if (ix < un->un_curdens) {
8246                                         continue;
8247                                 }
8248                                 un->un_curdens = ix;
8249                                 break;
8250                         }
8251                 }
8252                 /* If a match was found best will not be 0xff any more */
8253                 if (best < NDENSITIES) {
8254                         ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
8255                             "found media 0x%X using density 0x%X\n",
8256                             un->un_mspl->media_type,
8257                             un->un_dp->densities[best]);
8258                         un->un_mspl->density = un->un_dp->densities[best];
8259                 } else {
8260                         /* Otherwise set density based on minor node opened */
8261                         un->un_mspl->density =
8262                             un->un_dp->densities[un->un_curdens];
8263                 }
8264         } else {
8265                 un->un_mspl->density = un->un_dp->densities[un->un_curdens];
8266         }
8267 
8268         if (un->un_dp->options & ST_NOBUF) {
8269                 un->un_mspl->bufm = 0;
8270         } else {
8271                 un->un_mspl->bufm = 1;
8272         }
8273 
8274         rval = st_set_compression(un);
8275 
8276         /*
8277          * If st_set_compression returned invalid or already it
8278          * found no need to do the mode select.
8279          * So do it here.
8280          */
8281         if ((rval == ENOTTY) || (rval == EALREADY)) {
8282 
8283                 /* Zero non-writeable fields */
8284                 un->un_mspl->data_len = 0;
8285                 un->un_mspl->media_type = 0;
8286                 un->un_mspl->wp = 0;
8287 
8288                 /* need to set the density code */
8289                 rval = st_cmd(un, SCMD_MODE_SELECT, MSIZE, SYNC_CMD);
8290                 if (rval != 0) {
8291                         if (un->un_state >= ST_STATE_OPEN) {
8292                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
8293                                     "unable to set tape mode\n");
8294                                 un->un_pos.pmode = invalid;
8295                                 rval = EIO;
8296                         } else {
8297                                 rval = -1;
8298                         }
8299                 }
8300         }
8301 
8302         /*
8303          * The spec recommends to send a mode sense after a mode select
8304          */
8305         (void) st_modesense(un);
8306 
8307         ASSERT(mutex_owned(ST_MUTEX));
8308 
8309         return (rval);
8310 }
8311 
8312 /*
8313  * st_gen_mode_sense
8314  *
8315  * generic mode sense.. it allows for any page
8316  */
8317 static int
8318 st_gen_mode_sense(struct scsi_tape *un, ubufunc_t ubf, int page,
8319     struct seq_mode *page_data, int page_size)
8320 {
8321 
8322         int r;
8323         char    cdb[CDB_GROUP0];
8324         struct uscsi_cmd *com;
8325         struct scsi_arq_status status;
8326 
8327         ST_FUNC(ST_DEVINFO, st_gen_mode_sense);
8328 
8329         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8330 
8331         bzero(cdb, CDB_GROUP0);
8332         cdb[0] = SCMD_MODE_SENSE;
8333         cdb[2] = (char)page;
8334         cdb[4] = (char)page_size;
8335 
8336         com->uscsi_cdb = cdb;
8337         com->uscsi_cdblen = CDB_GROUP0;
8338         com->uscsi_bufaddr = (caddr_t)page_data;
8339         com->uscsi_buflen = page_size;
8340         com->uscsi_rqlen = sizeof (status);
8341         com->uscsi_rqbuf = (caddr_t)&status;
8342         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8343         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8344 
8345         r = ubf(un, com, FKIOCTL);
8346         kmem_free(com, sizeof (*com));
8347         return (r);
8348 }
8349 
8350 /*
8351  * st_gen_mode_select
8352  *
8353  * generic mode select.. it allows for any page
8354  */
8355 static int
8356 st_gen_mode_select(struct scsi_tape *un, ubufunc_t ubf,
8357     struct seq_mode *page_data, int page_size)
8358 {
8359 
8360         int r;
8361         char cdb[CDB_GROUP0];
8362         struct uscsi_cmd *com;
8363         struct scsi_arq_status status;
8364 
8365         ST_FUNC(ST_DEVINFO, st_gen_mode_select);
8366 
8367         /* Zero non-writeable fields */
8368         page_data->data_len = 0;
8369         page_data->media_type = 0;
8370         page_data->wp = 0;
8371 
8372         /*
8373          * If mode select has any page data, zero the ps (Page Savable) bit.
8374          */
8375         if (page_size > MSIZE) {
8376                 page_data->ps = 0;
8377         }
8378 
8379 
8380         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8381 
8382         /*
8383          * then, do a mode select to set what ever info
8384          */
8385         bzero(cdb, CDB_GROUP0);
8386         cdb[0] = SCMD_MODE_SELECT;
8387         cdb[1] = 0x10;          /* set PF bit for many third party drives */
8388         cdb[4] = (char)page_size;
8389 
8390         com->uscsi_cdb = cdb;
8391         com->uscsi_cdblen = CDB_GROUP0;
8392         com->uscsi_bufaddr = (caddr_t)page_data;
8393         com->uscsi_buflen = page_size;
8394         com->uscsi_rqlen = sizeof (status);
8395         com->uscsi_rqbuf = (caddr_t)&status;
8396         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8397         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_WRITE;
8398 
8399         r = ubf(un, com, FKIOCTL);
8400 
8401         kmem_free(com, sizeof (*com));
8402         return (r);
8403 }
8404 
8405 static int
8406 st_read_block_limits(struct scsi_tape *un, struct read_blklim *read_blk)
8407 {
8408         int rval;
8409         char cdb[CDB_GROUP0];
8410         struct uscsi_cmd *com;
8411         struct scsi_arq_status status;
8412 
8413         ST_FUNC(ST_DEVINFO, st_read_block_limits);
8414 
8415         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8416 
8417         bzero(cdb, CDB_GROUP0);
8418         cdb[0] = SCMD_READ_BLKLIM;
8419 
8420         com->uscsi_cdb = cdb;
8421         com->uscsi_cdblen = CDB_GROUP0;
8422         com->uscsi_bufaddr = (caddr_t)read_blk;
8423         com->uscsi_buflen = sizeof (struct read_blklim);
8424         com->uscsi_rqlen = sizeof (status);
8425         com->uscsi_rqbuf = (caddr_t)&status;
8426         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8427         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8428 
8429         rval = st_uscsi_cmd(un, com, FKIOCTL);
8430         if (com->uscsi_status || com->uscsi_resid) {
8431                 rval = -1;
8432         }
8433 
8434         kmem_free(com, sizeof (*com));
8435         return (rval);
8436 }
8437 
8438 static int
8439 st_report_density_support(struct scsi_tape *un, uchar_t *density_data,
8440     size_t buflen)
8441 {
8442         int rval;
8443         char cdb[CDB_GROUP1];
8444         struct uscsi_cmd *com;
8445         struct scsi_arq_status status;
8446 
8447         ST_FUNC(ST_DEVINFO, st_report_density_support);
8448 
8449         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8450 
8451         bzero(cdb, CDB_GROUP1);
8452         cdb[0] = SCMD_REPORT_DENSITIES;
8453         cdb[7] = (buflen & 0xff00) >> 8;
8454         cdb[8] = buflen & 0xff;
8455 
8456         com->uscsi_cdb = cdb;
8457         com->uscsi_cdblen = CDB_GROUP1;
8458         com->uscsi_bufaddr = (caddr_t)density_data;
8459         com->uscsi_buflen = buflen;
8460         com->uscsi_rqlen = sizeof (status);
8461         com->uscsi_rqbuf = (caddr_t)&status;
8462         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8463         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8464 
8465         rval = st_uscsi_cmd(un, com, FKIOCTL);
8466         if (com->uscsi_status || com->uscsi_resid) {
8467                 rval = -1;
8468         }
8469 
8470         kmem_free(com, sizeof (*com));
8471         return (rval);
8472 }
8473 
8474 static int
8475 st_report_supported_operation(struct scsi_tape *un, uchar_t *oper_data,
8476     uchar_t option_code, ushort_t service_action)
8477 {
8478         int rval;
8479         char cdb[CDB_GROUP5];
8480         struct uscsi_cmd *com;
8481         struct scsi_arq_status status;
8482         uint32_t allo_length;
8483 
8484         ST_FUNC(ST_DEVINFO, st_report_supported_operation);
8485 
8486         allo_length = sizeof (struct one_com_des) +
8487             sizeof (struct com_timeout_des);
8488         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8489 
8490         bzero(cdb, CDB_GROUP5);
8491         cdb[0] = (char)SCMD_MAINTENANCE_IN;
8492         cdb[1] = SSVC_ACTION_GET_SUPPORTED_OPERATIONS;
8493         if (service_action) {
8494                 cdb[2] = (char)(ONE_COMMAND_DATA_FORMAT | 0x80); /* RCTD */
8495                 cdb[4] = (service_action & 0xff00) >> 8;
8496                 cdb[5] = service_action & 0xff;
8497         } else {
8498                 cdb[2] = (char)(ONE_COMMAND_NO_SERVICE_DATA_FORMAT |
8499                     0x80); /* RCTD */
8500         }
8501         cdb[3] = option_code;
8502         cdb[6] = (allo_length & 0xff000000) >> 24;
8503         cdb[7] = (allo_length & 0xff0000) >> 16;
8504         cdb[8] = (allo_length & 0xff00) >> 8;
8505         cdb[9] = allo_length & 0xff;
8506 
8507         com->uscsi_cdb = cdb;
8508         com->uscsi_cdblen = CDB_GROUP5;
8509         com->uscsi_bufaddr = (caddr_t)oper_data;
8510         com->uscsi_buflen = allo_length;
8511         com->uscsi_rqlen = sizeof (status);
8512         com->uscsi_rqbuf = (caddr_t)&status;
8513         com->uscsi_timeout = un->un_dp->non_motion_timeout;
8514         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8515 
8516         rval = st_uscsi_cmd(un, com, FKIOCTL);
8517         if (com->uscsi_status) {
8518                 rval = -1;
8519         }
8520 
8521         kmem_free(com, sizeof (*com));
8522         return (rval);
8523 }
8524 
8525 /*
8526  * Changes devices blocksize and bsize to requested blocksize nblksz.
8527  * Returns returned value from first failed call or zero on success.
8528  */
8529 static int
8530 st_change_block_size(struct scsi_tape *un, uint32_t nblksz)
8531 {
8532         struct seq_mode *current;
8533         int rval;
8534         uint32_t oldblksz;
8535 
8536         ST_FUNC(ST_DEVINFO, st_change_block_size);
8537 
8538         current = kmem_zalloc(MSIZE, KM_SLEEP);
8539 
8540         /*
8541          * If we haven't got the compression page yet, do that first.
8542          */
8543         if (un->un_comp_page == (ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE)) {
8544                 (void) st_modesense(un);
8545         }
8546 
8547         /* Read current settings */
8548         rval = st_gen_mode_sense(un, st_uscsi_cmd, 0, current, MSIZE);
8549         if (rval != 0) {
8550                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8551                     "mode sense for change block size failed: rval = %d", rval);
8552                 goto finish;
8553         }
8554 
8555         /* Figure the current block size */
8556         oldblksz =
8557             (current->high_bl << 16) |
8558             (current->mid_bl << 8) |
8559             (current->low_bl);
8560 
8561         /* If current block size is the same as requested were done */
8562         if (oldblksz == nblksz) {
8563                 un->un_bsize = nblksz;
8564                 rval = 0;
8565                 goto finish;
8566         }
8567 
8568         /* Change to requested block size */
8569         current->high_bl = (uchar_t)(nblksz >> 16);
8570         current->mid_bl  = (uchar_t)(nblksz >> 8);
8571         current->low_bl  = (uchar_t)(nblksz);
8572 
8573         /* Attempt to change block size */
8574         rval = st_gen_mode_select(un, st_uscsi_cmd, current, MSIZE);
8575         if (rval != 0) {
8576                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8577                     "Set new block size failed: rval = %d", rval);
8578                 goto finish;
8579         }
8580 
8581         /* Read back and verify setting */
8582         rval = st_modesense(un);
8583         if (rval == 0) {
8584                 un->un_bsize =
8585                     (un->un_mspl->high_bl << 16) |
8586                     (un->un_mspl->mid_bl << 8) |
8587                     (un->un_mspl->low_bl);
8588 
8589                 if (un->un_bsize != nblksz) {
8590                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8591                             "Blocksize set does not equal requested blocksize"
8592                             "(read: %u requested: %u)\n", nblksz, un->un_bsize);
8593                         rval = EIO;
8594                 }
8595         }
8596 finish:
8597         kmem_free(current, MSIZE);
8598         return (rval);
8599 }
8600 
8601 
8602 static void
8603 st_init(struct scsi_tape *un)
8604 {
8605         ST_FUNC(ST_DEVINFO, st_init);
8606 
8607         ASSERT(mutex_owned(ST_MUTEX));
8608 
8609         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8610             "st_init(): dev = 0x%lx, will reset fileno, blkno, eof\n",
8611             un->un_dev);
8612 
8613         un->un_pos.blkno = 0;
8614         un->un_pos.fileno = 0;
8615         un->un_lastop = ST_OP_NIL;
8616         un->un_pos.eof = ST_NO_EOF;
8617         un->un_pwr_mgmt = ST_PWR_NORMAL;
8618         if (st_error_level != SCSI_ERR_ALL) {
8619                 if (DEBUGGING) {
8620                         st_error_level = SCSI_ERR_ALL;
8621                 } else {
8622                         st_error_level = SCSI_ERR_RETRYABLE;
8623                 }
8624         }
8625 }
8626 
8627 
8628 static void
8629 st_make_cmd(struct scsi_tape *un, struct buf *bp, int (*func)(caddr_t))
8630 {
8631         struct scsi_pkt *pkt;
8632         struct uscsi_cmd *ucmd;
8633         recov_info *ri;
8634         int tval = 0;
8635         int64_t count;
8636         uint32_t additional = 0;
8637         uint32_t address = 0;
8638         union scsi_cdb *ucdb;
8639         int flags = 0;
8640         int cdb_len = CDB_GROUP0; /* default */
8641         uchar_t com;
8642         char fixbit;
8643         char short_fm = 0;
8644         optype prev_op = un->un_lastop;
8645         int stat_size =
8646             (un->un_arq_enabled ? sizeof (struct scsi_arq_status) : 1);
8647 
8648         ST_FUNC(ST_DEVINFO, st_make_cmd);
8649 
8650         ASSERT(mutex_owned(ST_MUTEX));
8651 
8652         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8653             "st_make_cmd(): dev = 0x%lx\n", un->un_dev);
8654 
8655 
8656         /*
8657          * fixbit is for setting the Fixed Mode and Suppress Incorrect
8658          * Length Indicator bits on read/write commands, for setting
8659          * the Long bit on erase commands, and for setting the Code
8660          * Field bits on space commands.
8661          */
8662 
8663         /* regular raw I/O */
8664         if ((bp != un->un_sbufp) && (bp != un->un_recov_buf)) {
8665                 pkt = scsi_init_pkt(ROUTE, NULL, bp,
8666                     CDB_GROUP0, stat_size, st_recov_sz, 0, func,
8667                     (caddr_t)un);
8668                 if (pkt == NULL) {
8669                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
8670                             "Read Write scsi_init_pkt() failure\n");
8671                         goto exit;
8672                 }
8673                 ASSERT(pkt->pkt_resid == 0);
8674 #ifdef STDEBUG
8675                 bzero(pkt->pkt_private, st_recov_sz);
8676                 bzero(pkt->pkt_scbp, stat_size);
8677 #endif
8678                 ri = (recov_info *)pkt->pkt_private;
8679                 ri->privatelen = st_recov_sz;
8680                 if (un->un_bsize == 0) {
8681                         count = bp->b_bcount;
8682                         fixbit = 0;
8683                 } else {
8684                         count = bp->b_bcount / un->un_bsize;
8685                         fixbit = 1;
8686                 }
8687                 if (bp->b_flags & B_READ) {
8688                         com = SCMD_READ;
8689                         un->un_lastop = ST_OP_READ;
8690                         if ((un->un_bsize == 0) && /* Not Fixed Block */
8691                             (un->un_dp->options & ST_READ_IGNORE_ILI)) {
8692                                 fixbit = 2;
8693                         }
8694                 } else {
8695                         com = SCMD_WRITE;
8696                         un->un_lastop = ST_OP_WRITE;
8697                 }
8698                 tval = un->un_dp->io_timeout;
8699 
8700                 /*
8701                  * For really large xfers, increase timeout
8702                  */
8703                 if (bp->b_bcount > (10 * ONE_MEG))
8704                         tval *= bp->b_bcount/(10 * ONE_MEG);
8705 
8706                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8707                     "%s %d amt 0x%lx\n", (com == SCMD_WRITE) ?
8708                     wr_str: rd_str, un->un_pos.blkno, bp->b_bcount);
8709 
8710         } else if ((ucmd = BP_UCMD(bp)) != NULL) {
8711                 /*
8712                  * uscsi - build command, allocate scsi resources
8713                  */
8714                 st_make_uscsi_cmd(un, ucmd, bp, func);
8715                 goto exit;
8716 
8717         } else {                                /* special I/O */
8718                 struct buf *allocbp = NULL;
8719                 com = (uchar_t)(uintptr_t)bp->b_forw;
8720                 count = bp->b_bcount;
8721 
8722                 switch (com) {
8723                 case SCMD_READ:
8724                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8725                             "special read %"PRId64"\n", count);
8726                         if (un->un_bsize == 0) {
8727                                 fixbit = 2;     /* suppress SILI */
8728                         } else {
8729                                 fixbit = 1;     /* Fixed Block Mode */
8730                                 count /= un->un_bsize;
8731                         }
8732                         allocbp = bp;
8733                         un->un_lastop = ST_OP_READ;
8734                         tval = un->un_dp->io_timeout;
8735                         break;
8736 
8737                 case SCMD_WRITE:
8738                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8739                             "special write %"PRId64"\n", count);
8740                         if (un->un_bsize != 0) {
8741                                 fixbit = 1;     /* Fixed Block Mode */
8742                                 count /= un->un_bsize;
8743                         } else {
8744                                 fixbit = 0;
8745                         }
8746                         allocbp = bp;
8747                         un->un_lastop = ST_OP_WRITE;
8748                         tval = un->un_dp->io_timeout;
8749                         break;
8750 
8751                 case SCMD_WRITE_FILE_MARK:
8752                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8753                             "write %"PRId64" file marks\n", count);
8754                         un->un_lastop = ST_OP_WEOF;
8755                         fixbit = 0;
8756                         tval = un->un_dp->io_timeout;
8757                         /*
8758                          * If ST_SHORT_FILEMARKS bit is ON for EXABYTE
8759                          * device, set the Vendor Unique bit to
8760                          * write Short File Mark.
8761                          */
8762                         if ((un->un_dp->options & ST_SHORT_FILEMARKS) &&
8763                             ((un->un_dp->type == ST_TYPE_EXB8500) ||
8764                             (un->un_dp->type == ST_TYPE_EXABYTE))) {
8765                                 /*
8766                                  * Now the Vendor Unique bit 7 in Byte 5 of CDB
8767                                  * is set to to write Short File Mark
8768                                  */
8769                                 short_fm = 1;
8770                         }
8771                         break;
8772 
8773                 case SCMD_REWIND:
8774                         /*
8775                          * In the case of rewind we're gona do the rewind with
8776                          * the immediate bit set so status will be retured when
8777                          * the command is accepted by the device. We clear the
8778                          * B_ASYNC flag so we wait for that acceptance.
8779                          */
8780                         fixbit = 0;
8781                         if (bp->b_flags & B_ASYNC) {
8782                                 allocbp = bp;
8783                                 if (count) {
8784                                         fixbit = 1;
8785                                         bp->b_flags &= ~B_ASYNC;
8786                                 }
8787                         }
8788                         count = 0;
8789                         bp->b_bcount = 0;
8790                         un->un_lastop = ST_OP_CTL;
8791                         tval = un->un_dp->rewind_timeout;
8792                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8793                             "rewind\n");
8794                         break;
8795 
8796                 case SCMD_SPACE_G4:
8797                         cdb_len = CDB_GROUP4;
8798                         fixbit = SPACE_TYPE(bp->b_bcount);
8799                         count = SPACE_CNT(bp->b_bcount);
8800                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
8801                             " %s space %s %"PRId64" from file %d blk %d\n",
8802                             bp->b_bcount & SP_BACKSP ? "backward" : "forward",
8803                             space_strs[fixbit & 7], count,
8804                             un->un_pos.fileno, un->un_pos.blkno);
8805                         address = (count >> 48) & 0x1fff;
8806                         additional = (count >> 16) & 0xffffffff;
8807                         count &= 0xffff;
8808                         count <<= 16;
8809                         un->un_lastop = ST_OP_CTL;
8810                         tval = un->un_dp->space_timeout;
8811                         break;
8812 
8813                 case SCMD_SPACE:
8814                         fixbit = SPACE_TYPE(bp->b_bcount);
8815                         count = SPACE_CNT(bp->b_bcount);
8816                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8817                             " %s space %s %"PRId64" from file %d blk %d\n",
8818                             bp->b_bcount & SP_BACKSP ? "backward" : "forward",
8819                             space_strs[fixbit & 7], count,
8820                             un->un_pos.fileno, un->un_pos.blkno);
8821                         count &= 0xffffffff;
8822                         un->un_lastop = ST_OP_CTL;
8823                         tval = un->un_dp->space_timeout;
8824                         break;
8825 
8826                 case SCMD_LOAD:
8827                         ASSERT(count < 10);
8828                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8829                             "%s tape\n", load_strs[count]);
8830                         fixbit = 0;
8831 
8832                         /* Loading or Unloading */
8833                         if (count & LD_LOAD) {
8834                                 tval = un->un_dp->load_timeout;
8835                         } else {
8836                                 tval = un->un_dp->unload_timeout;
8837                         }
8838                         /* Is Retension requested */
8839                         if (count & LD_RETEN) {
8840                                 tval += un->un_dp->rewind_timeout;
8841                         }
8842                         un->un_lastop = ST_OP_CTL;
8843                         break;
8844 
8845                 case SCMD_ERASE:
8846                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8847                             "erase tape\n");
8848                         ASSERT(count == 1); /* mt sets this */
8849                         if (count == 1) {
8850                                 /*
8851                                  * do long erase
8852                                  */
8853                                 fixbit = 1; /* Long */
8854 
8855                                 /* Drive might not honor immidiate bit */
8856                                 tval = un->un_dp->erase_timeout;
8857                         } else {
8858                                 /* Short Erase */
8859                                 tval = un->un_dp->erase_timeout;
8860                                 fixbit = 0;
8861                         }
8862                         un->un_lastop = ST_OP_CTL;
8863                         count = 0;
8864                         break;
8865 
8866                 case SCMD_MODE_SENSE:
8867                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8868                             "mode sense\n");
8869                         allocbp = bp;
8870                         fixbit = 0;
8871                         tval = un->un_dp->non_motion_timeout;
8872                         un->un_lastop = ST_OP_CTL;
8873                         break;
8874 
8875                 case SCMD_MODE_SELECT:
8876                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8877                             "mode select\n");
8878                         allocbp = bp;
8879                         fixbit = 0;
8880                         tval = un->un_dp->non_motion_timeout;
8881                         un->un_lastop = ST_OP_CTL;
8882                         break;
8883 
8884                 case SCMD_RESERVE:
8885                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8886                             "reserve\n");
8887                         fixbit = 0;
8888                         tval = un->un_dp->non_motion_timeout;
8889                         un->un_lastop = ST_OP_CTL;
8890                         break;
8891 
8892                 case SCMD_RELEASE:
8893                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8894                             "release\n");
8895                         fixbit = 0;
8896                         tval = un->un_dp->non_motion_timeout;
8897                         un->un_lastop = ST_OP_CTL;
8898                         break;
8899 
8900                 case SCMD_READ_BLKLIM:
8901                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8902                             "read block limits\n");
8903                         allocbp = bp;
8904                         fixbit = count = 0;
8905                         tval = un->un_dp->non_motion_timeout;
8906                         un->un_lastop = ST_OP_CTL;
8907                         break;
8908 
8909                 case SCMD_TEST_UNIT_READY:
8910                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8911                             "test unit ready\n");
8912                         fixbit = 0;
8913                         tval = un->un_dp->non_motion_timeout;
8914                         un->un_lastop = ST_OP_CTL;
8915                         break;
8916 
8917                 case SCMD_DOORLOCK:
8918                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8919                             "prevent/allow media removal\n");
8920                         fixbit = 0;
8921                         tval = un->un_dp->non_motion_timeout;
8922                         un->un_lastop = ST_OP_CTL;
8923                         break;
8924 
8925                 case SCMD_READ_POSITION:
8926                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8927                             "read position\n");
8928                         fixbit = un->un_read_pos_type;
8929                         cdb_len = CDB_GROUP1;
8930                         tval = un->un_dp->non_motion_timeout;
8931                         allocbp = bp;
8932                         un->un_lastop = ST_OP_CTL;
8933                         switch (un->un_read_pos_type) {
8934                         case LONG_POS:
8935                                 count = 0;
8936                                 break;
8937                         case EXT_POS:
8938                                 count = sizeof (tape_position_ext_t);
8939                                 break;
8940                         case SHORT_POS:
8941                                 count = 0;
8942                                 break;
8943                         default:
8944                                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
8945                                     "Unknown read position type 0x%x in "
8946                                     " st_make_cmd()\n", un->un_read_pos_type);
8947                         }
8948                         break;
8949 
8950                 default:
8951                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
8952                             "Unhandled scsi command 0x%x in st_make_cmd()\n",
8953                             com);
8954                 }
8955 
8956                 pkt = scsi_init_pkt(ROUTE, NULL, allocbp, cdb_len, stat_size,
8957                     st_recov_sz, 0, func, (caddr_t)un);
8958                 if (pkt == NULL) {
8959                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
8960                             "generic command scsi_init_pkt() failure\n");
8961                         goto exit;
8962                 }
8963 
8964                 ASSERT(pkt->pkt_resid == 0);
8965 #ifdef STDEBUG
8966                 bzero(pkt->pkt_private, st_recov_sz);
8967                 bzero(pkt->pkt_scbp, stat_size);
8968 #endif
8969                 ri = (recov_info *)pkt->pkt_private;
8970                 ri->privatelen = st_recov_sz;
8971                 if (allocbp) {
8972                         ASSERT(geterror(allocbp) == 0);
8973                 }
8974 
8975         }
8976 
8977         ucdb = (union scsi_cdb *)pkt->pkt_cdbp;
8978 
8979         (void) scsi_setup_cdb(ucdb, com, address, (uint_t)count, additional);
8980         FILL_SCSI1_LUN(un->un_sd, pkt);
8981         /*
8982          * Initialize the SILI/Fixed bits of the byte 1 of cdb.
8983          */
8984         ucdb->t_code = fixbit;
8985         ucdb->g0_vu_1 = short_fm;
8986         pkt->pkt_flags = flags;
8987 
8988         ASSERT(tval);
8989         pkt->pkt_time = tval;
8990         if (bp == un->un_recov_buf) {
8991                 pkt->pkt_comp = st_recov_cb;
8992         } else {
8993                 pkt->pkt_comp = st_intr;
8994         }
8995 
8996         st_add_recovery_info_to_pkt(un, bp, pkt);
8997 
8998         /*
8999          * If we just write data to tape and did a command that doesn't
9000          * change position, we still need to write a filemark.
9001          */
9002         if ((prev_op == ST_OP_WRITE) || (prev_op == ST_OP_WEOF)) {
9003                 recov_info *rcvi = pkt->pkt_private;
9004                 cmd_attribute const *atrib;
9005 
9006                 if (rcvi->privatelen == sizeof (recov_info)) {
9007                         atrib = rcvi->cmd_attrib;
9008                 } else {
9009                         atrib = st_lookup_cmd_attribute(com);
9010                 }
9011                 if (atrib->chg_tape_direction == DIR_NONE) {
9012                         un->un_lastop = prev_op;
9013                 }
9014         }
9015 
9016 exit:
9017         ASSERT(mutex_owned(ST_MUTEX));
9018 }
9019 
9020 
9021 /*
9022  * Build a command based on a uscsi command;
9023  */
9024 static void
9025 st_make_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *ucmd,
9026     struct buf *bp, int (*func)(caddr_t))
9027 {
9028         struct scsi_pkt *pkt;
9029         recov_info *ri;
9030         caddr_t cdb;
9031         int     cdblen;
9032         int     stat_size = 1;
9033         int     flags = 0;
9034 
9035         ST_FUNC(ST_DEVINFO, st_make_uscsi_cmd);
9036 
9037         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9038             "st_make_uscsi_cmd(): dev = 0x%lx\n", un->un_dev);
9039 
9040         if (ucmd->uscsi_flags & USCSI_RQENABLE) {
9041                 if (un->un_arq_enabled) {
9042                         if (ucmd->uscsi_rqlen > SENSE_LENGTH) {
9043                                 stat_size = (int)(ucmd->uscsi_rqlen) +
9044                                     sizeof (struct scsi_arq_status) -
9045                                     sizeof (struct scsi_extended_sense);
9046                                 flags = PKT_XARQ;
9047                         } else {
9048                                 stat_size = sizeof (struct scsi_arq_status);
9049                         }
9050                 }
9051         }
9052 
9053         ASSERT(mutex_owned(ST_MUTEX));
9054 
9055         cdb = ucmd->uscsi_cdb;
9056         cdblen = ucmd->uscsi_cdblen;
9057 
9058         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
9059             "st_make_uscsi_cmd: buflen=%ld bcount=%ld\n",
9060             ucmd->uscsi_buflen, bp->b_bcount);
9061         pkt = scsi_init_pkt(ROUTE, NULL,
9062             (bp->b_bcount > 0) ? bp : NULL,
9063             cdblen, stat_size, st_recov_sz, flags, func, (caddr_t)un);
9064         if (pkt == NULL) {
9065                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
9066                     "uscsi command scsi_init_pkt() failure\n");
9067                 goto exit;
9068         }
9069 
9070         ASSERT(pkt->pkt_resid == 0);
9071 #ifdef STDEBUG
9072         bzero(pkt->pkt_private, st_recov_sz);
9073         bzero(pkt->pkt_scbp, stat_size);
9074 #endif
9075         ri = (recov_info *)pkt->pkt_private;
9076         ri->privatelen = st_recov_sz;
9077 
9078         bcopy(cdb, pkt->pkt_cdbp, (uint_t)cdblen);
9079 
9080 #ifdef STDEBUG
9081         if ((st_debug & 0x7) >= 6) {
9082                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
9083                     "pkt_cdbp", (char *)cdb, cdblen);
9084         }
9085 #endif
9086 
9087         if (ucmd->uscsi_flags & USCSI_SILENT) {
9088                 pkt->pkt_flags |= FLAG_SILENT;
9089         }
9090 
9091         (void) scsi_uscsi_pktinit(ucmd, pkt);
9092 
9093         pkt->pkt_time = ucmd->uscsi_timeout;
9094         if (bp == un->un_recov_buf) {
9095                 pkt->pkt_comp = st_recov_cb;
9096         } else {
9097                 pkt->pkt_comp = st_intr;
9098         }
9099 
9100         st_add_recovery_info_to_pkt(un, bp, pkt);
9101 exit:
9102         ASSERT(mutex_owned(ST_MUTEX));
9103 }
9104 
9105 
9106 /*
9107  * restart cmd currently at the head of the runq
9108  *
9109  * If scsi_transport() succeeds or the retries
9110  * count exhausted, restore the throttle that was
9111  * zeroed out in st_handle_intr_busy().
9112  *
9113  */
9114 static void
9115 st_intr_restart(void *arg)
9116 {
9117         struct scsi_tape *un = arg;
9118         struct buf *bp;
9119         int queued;
9120         int status = TRAN_ACCEPT;
9121 
9122         mutex_enter(ST_MUTEX);
9123 
9124         ST_FUNC(ST_DEVINFO, st_intr_restart);
9125 
9126         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9127             "st_intr_restart(), un = 0x%p\n", (void *)un);
9128 
9129         un->un_hib_tid = 0;
9130 
9131         if (un->un_recov_buf_busy != 0) {
9132                 bp = un->un_recov_buf;
9133                 queued = 0;
9134         } else if (un->un_sbuf_busy != 0) {
9135                 bp = un->un_sbufp;
9136                 queued = 0;
9137         } else if (un->un_quef != NULL) {
9138                 bp = un->un_quef;
9139                 queued = 1;
9140         } else {
9141                 mutex_exit(ST_MUTEX);
9142                 return;
9143         }
9144 
9145         /*
9146          * Here we know :
9147          *      throttle = 0, via st_handle_intr_busy
9148          */
9149 
9150         if (queued) {
9151                 /*
9152                  * move from waitq to runq, if there is anything on the waitq
9153                  */
9154                 (void) st_remove_from_queue(&un->un_quef, &un->un_quef, bp);
9155 
9156                 if (un->un_runqf) {
9157                         /*
9158                          * not good, we don't want to requeue something after
9159                          * another.
9160                          */
9161                         goto done_error;
9162                 } else {
9163                         un->un_runqf = bp;
9164                         un->un_runql = bp;
9165                 }
9166         }
9167 
9168         ST_CDB(ST_DEVINFO, "Interrupt restart CDB",
9169             (char *)BP_PKT(bp)->pkt_cdbp);
9170 
9171         ST_DO_KSTATS(bp, kstat_waitq_to_runq);
9172 
9173         status = st_transport(un, BP_PKT(bp));
9174 
9175         if (status != TRAN_ACCEPT) {
9176                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9177 
9178                 if (status == TRAN_BUSY) {
9179                         pkt_info *pkti = BP_PKT(bp)->pkt_private;
9180 
9181                         if (pkti->privatelen == sizeof (recov_info) &&
9182                             un->un_unit_attention_flags &&
9183                             bp != un->un_recov_buf) {
9184                         un->un_unit_attention_flags = 0;
9185                                 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
9186                                     "Command Recovery called on busy resend\n");
9187                                 if (st_command_recovery(un, BP_PKT(bp),
9188                                     ATTEMPT_RETRY) == JUST_RETURN) {
9189                                         mutex_exit(ST_MUTEX);
9190                                         return;
9191                                 }
9192                         }
9193                         mutex_exit(ST_MUTEX);
9194                         if (st_handle_intr_busy(un, bp,
9195                             ST_TRAN_BUSY_TIMEOUT) == 0)
9196                                 return; /* timeout is setup again */
9197                         mutex_enter(ST_MUTEX);
9198                 }
9199 
9200 done_error:
9201                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
9202                     "restart transport rejected\n");
9203                 bp->b_resid = bp->b_bcount;
9204 
9205                 if (un->un_last_throttle) {
9206                         un->un_throttle = un->un_last_throttle;
9207                 }
9208                 if (status != TRAN_ACCEPT) {
9209                         ST_DO_ERRSTATS(un, st_transerrs);
9210                 }
9211                 ST_DO_KSTATS(bp, kstat_waitq_exit);
9212                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
9213                     "busy restart aborted\n");
9214                 st_set_pe_flag(un);
9215                 st_bioerror(bp, EIO);
9216                 st_done_and_mutex_exit(un, bp);
9217         } else {
9218                 if (un->un_last_throttle) {
9219                         un->un_throttle = un->un_last_throttle;
9220                 }
9221                 mutex_exit(ST_MUTEX);
9222         }
9223 }
9224 
9225 /*
9226  * st_check_media():
9227  * Periodically check the media state using scsi_watch service;
9228  * this service calls back after TUR and possibly request sense
9229  * the callback handler (st_media_watch_cb()) decodes the request sense
9230  * data (if any)
9231  */
9232 
9233 static int
9234 st_check_media(dev_t dev, enum mtio_state state)
9235 {
9236         int rval = 0;
9237         enum mtio_state prev_state;
9238         opaque_t token = NULL;
9239 
9240         GET_SOFT_STATE(dev);
9241 
9242         ST_FUNC(ST_DEVINFO, st_check_media);
9243 
9244         mutex_enter(ST_MUTEX);
9245 
9246         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9247             "st_check_media:state=%x, mediastate=%x\n",
9248             state, un->un_mediastate);
9249 
9250         prev_state = un->un_mediastate;
9251 
9252         /*
9253          * is there anything to do?
9254          */
9255 retry:
9256         if (state == un->un_mediastate || un->un_mediastate == MTIO_NONE) {
9257                 /*
9258                  * submit the request to the scsi_watch service;
9259                  * scsi_media_watch_cb() does the real work
9260                  */
9261                 mutex_exit(ST_MUTEX);
9262                 token = scsi_watch_request_submit(ST_SCSI_DEVP,
9263                     st_check_media_time, SENSE_LENGTH,
9264                     st_media_watch_cb, (caddr_t)dev);
9265                 if (token == NULL) {
9266                         rval = EAGAIN;
9267                         goto done;
9268                 }
9269                 mutex_enter(ST_MUTEX);
9270 
9271                 un->un_swr_token = token;
9272                 un->un_specified_mediastate = state;
9273 
9274                 /*
9275                  * now wait for media change
9276                  * we will not be signalled unless mediastate == state but it
9277                  * still better to test for this condition, since there
9278                  * is a 5 sec cv_broadcast delay when
9279                  *  mediastate == MTIO_INSERTED
9280                  */
9281                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9282                     "st_check_media:waiting for media state change\n");
9283                 while (un->un_mediastate == state) {
9284                         if (cv_wait_sig(&un->un_state_cv, ST_MUTEX) == 0) {
9285                                 mutex_exit(ST_MUTEX);
9286                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9287                                     "st_check_media:waiting for media state "
9288                                     "was interrupted\n");
9289                                 rval = EINTR;
9290                                 goto done;
9291                         }
9292                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9293                             "st_check_media:received signal, state=%x\n",
9294                             un->un_mediastate);
9295                 }
9296         }
9297 
9298         /*
9299          * if we transitioned to MTIO_INSERTED, media has really been
9300          * inserted.  If TUR fails, it is probably a exabyte slow spin up.
9301          * Reset and retry the state change.  If everything is ok, replay
9302          * the open() logic.
9303          */
9304         if ((un->un_mediastate == MTIO_INSERTED) &&
9305             (un->un_state == ST_STATE_OFFLINE)) {
9306                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9307                     "st_check_media: calling st_cmd to confirm inserted\n");
9308 
9309                 /*
9310                  * set this early so that TUR will make it through strategy
9311                  * without triggering a st_tape_init().  We needed it set
9312                  * before calling st_tape_init() ourselves anyway.  If TUR
9313                  * fails, set it back
9314                  */
9315                 un->un_state = ST_STATE_INITIALIZING;
9316 
9317                 /*
9318                  * If not reserved fail as getting reservation conflict
9319                  * will make this hang forever.
9320                  */
9321                 if ((un->un_rsvd_status &
9322                     (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
9323                         mutex_exit(ST_MUTEX);
9324                         rval = EACCES;
9325                         goto done;
9326                 }
9327                 rval = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
9328                 if (rval == EACCES) {
9329                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9330                             "st_check_media: TUR got Reservation Conflict\n");
9331                         mutex_exit(ST_MUTEX);
9332                         goto done;
9333                 }
9334                 if (rval) {
9335                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9336                             "st_check_media: TUR failed, going to retry\n");
9337                         un->un_mediastate = prev_state;
9338                         un->un_state = ST_STATE_OFFLINE;
9339                         goto retry;
9340                 }
9341                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9342                     "st_check_media: media inserted\n");
9343 
9344                 /* this also rewinds the tape */
9345                 rval = st_tape_init(un);
9346                 if (rval != 0) {
9347                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9348                             "st_check_media : OFFLINE init failure ");
9349                         un->un_state = ST_STATE_OFFLINE;
9350                         un->un_pos.pmode = invalid;
9351                 } else {
9352                         un->un_state = ST_STATE_OPEN_PENDING_IO;
9353                 }
9354         } else if ((un->un_mediastate == MTIO_EJECTED) &&
9355             (un->un_state != ST_STATE_OFFLINE)) {
9356                 /*
9357                  * supported devices must be rewound before ejection
9358                  * rewind resets fileno & blkno
9359                  */
9360                 un->un_laststate = un->un_state;
9361                 un->un_state = ST_STATE_OFFLINE;
9362         }
9363         mutex_exit(ST_MUTEX);
9364 done:
9365         if (token) {
9366                 (void) scsi_watch_request_terminate(token,
9367                     SCSI_WATCH_TERMINATE_WAIT);
9368                 mutex_enter(ST_MUTEX);
9369                 un->un_swr_token = (opaque_t)NULL;
9370                 mutex_exit(ST_MUTEX);
9371         }
9372 
9373         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG, "st_check_media: done\n");
9374 
9375         return (rval);
9376 }
9377 
9378 /*
9379  * st_media_watch_cb() is called by scsi_watch_thread for
9380  * verifying the request sense data (if any)
9381  */
9382 static int
9383 st_media_watch_cb(caddr_t arg, struct scsi_watch_result *resultp)
9384 {
9385         struct scsi_status *statusp = resultp->statusp;
9386         struct scsi_extended_sense *sensep = resultp->sensep;
9387         uchar_t actual_sense_length = resultp->actual_sense_length;
9388         struct scsi_tape *un;
9389         enum mtio_state state = MTIO_NONE;
9390         int instance;
9391         dev_t dev = (dev_t)arg;
9392 
9393         instance = MTUNIT(dev);
9394         if ((un = ddi_get_soft_state(st_state, instance)) == NULL) {
9395                 return (-1);
9396         }
9397 
9398         mutex_enter(ST_MUTEX);
9399         ST_FUNC(ST_DEVINFO, st_media_watch_cb);
9400         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9401             "st_media_watch_cb: status=%x, sensep=%p, len=%x\n",
9402             *((char *)statusp), (void *)sensep,
9403             actual_sense_length);
9404 
9405 
9406         /*
9407          * if there was a check condition then sensep points to valid
9408          * sense data
9409          * if status was not a check condition but a reservation or busy
9410          * status then the new state is MTIO_NONE
9411          */
9412         if (sensep) {
9413                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9414                     "st_media_watch_cb: KEY=%x, ASC=%x, ASCQ=%x\n",
9415                     sensep->es_key, sensep->es_add_code, sensep->es_qual_code);
9416 
9417                 switch (un->un_dp->type) {
9418                 default:
9419                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9420                             "st_media_watch_cb: unknown drive type %d, "
9421                             "default to ST_TYPE_HP\n", un->un_dp->type);
9422                 /* FALLTHROUGH */
9423 
9424                 case ST_TYPE_STC3490:   /* STK 4220 1/2" cartridge */
9425                 case ST_TYPE_FUJI:      /* 1/2" cartridge */
9426                 case ST_TYPE_HP:        /* HP 88780 1/2" reel */
9427                         if (un->un_dp->type == ST_TYPE_FUJI) {
9428                                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9429                                     "st_media_watch_cb: ST_TYPE_FUJI\n");
9430                         } else {
9431                                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9432                                     "st_media_watch_cb: ST_TYPE_HP\n");
9433                         }
9434                         switch (sensep->es_key) {
9435                         case KEY_UNIT_ATTENTION:
9436                                 /* not ready to ready transition */
9437                                 /* hp/es_qual_code == 80 on>off>on */
9438                                 /* hp/es_qual_code == 0 on>off>unld>ld>on */
9439                                 if (sensep->es_add_code == 0x28) {
9440                                         state = MTIO_INSERTED;
9441                                 }
9442                                 break;
9443                         case KEY_NOT_READY:
9444                                 /* in process, rewinding or loading */
9445                                 if ((sensep->es_add_code == 0x04) &&
9446                                     (sensep->es_qual_code == 0x00)) {
9447                                         state = MTIO_EJECTED;
9448                                 }
9449                                 break;
9450                         }
9451                         break;
9452 
9453                 case ST_TYPE_EXB8500:   /* Exabyte 8500 */
9454                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9455                             "st_media_watch_cb: ST_TYPE_EXB8500\n");
9456                         switch (sensep->es_key) {
9457                         case KEY_UNIT_ATTENTION:
9458                                 /* operator medium removal request */
9459                                 if ((sensep->es_add_code == 0x5a) &&
9460                                     (sensep->es_qual_code == 0x01)) {
9461                                         state = MTIO_EJECTED;
9462                                 /* not ready to ready transition */
9463                                 } else if ((sensep->es_add_code == 0x28) &&
9464                                     (sensep->es_qual_code == 0x00)) {
9465                                         state = MTIO_INSERTED;
9466                                 }
9467                                 break;
9468                         case KEY_NOT_READY:
9469                                 /* medium not present */
9470                                 if (sensep->es_add_code == 0x3a) {
9471                                         state = MTIO_EJECTED;
9472                                 }
9473                                 break;
9474                         }
9475                         break;
9476                 case ST_TYPE_EXABYTE:   /* Exabyte 8200 */
9477                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9478                             "st_media_watch_cb: ST_TYPE_EXABYTE\n");
9479                         switch (sensep->es_key) {
9480                         case KEY_NOT_READY:
9481                                 if ((sensep->es_add_code == 0x04) &&
9482                                     (sensep->es_qual_code == 0x00)) {
9483                                         /* volume not mounted? */
9484                                         state = MTIO_EJECTED;
9485                                 } else if (sensep->es_add_code == 0x3a) {
9486                                         state = MTIO_EJECTED;
9487                                 }
9488                                 break;
9489                         case KEY_UNIT_ATTENTION:
9490                                 state = MTIO_EJECTED;
9491                                 break;
9492                         }
9493                         break;
9494 
9495                 case ST_TYPE_DLT:               /* quantum DLT4xxx */
9496                         switch (sensep->es_key) {
9497                         case KEY_UNIT_ATTENTION:
9498                                 if (sensep->es_add_code == 0x28) {
9499                                         state = MTIO_INSERTED;
9500                                 }
9501                                 break;
9502                         case KEY_NOT_READY:
9503                                 if (sensep->es_add_code == 0x04) {
9504                                         /* in transition but could be either */
9505                                         state = un->un_specified_mediastate;
9506                                 } else if ((sensep->es_add_code == 0x3a) &&
9507                                     (sensep->es_qual_code == 0x00)) {
9508                                         state = MTIO_EJECTED;
9509                                 }
9510                                 break;
9511                         }
9512                         break;
9513                 }
9514         } else if (*((char *)statusp) == STATUS_GOOD) {
9515                 state = MTIO_INSERTED;
9516         }
9517 
9518         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9519             "st_media_watch_cb:state=%x, specified=%x\n",
9520             state, un->un_specified_mediastate);
9521 
9522         /*
9523          * now signal the waiting thread if this is *not* the specified state;
9524          * delay the signal if the state is MTIO_INSERTED
9525          * to allow the target to recover
9526          */
9527         if (state != un->un_specified_mediastate) {
9528                 un->un_mediastate = state;
9529                 if (state == MTIO_INSERTED) {
9530                         /*
9531                          * delay the signal to give the drive a chance
9532                          * to do what it apparently needs to do
9533                          */
9534                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9535                             "st_media_watch_cb:delayed cv_broadcast\n");
9536                         un->un_delay_tid = timeout(st_delayed_cv_broadcast,
9537                             un, drv_usectohz((clock_t)MEDIA_ACCESS_DELAY));
9538                 } else {
9539                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9540                             "st_media_watch_cb:immediate cv_broadcast\n");
9541                         cv_broadcast(&un->un_state_cv);
9542                 }
9543         }
9544         mutex_exit(ST_MUTEX);
9545         return (0);
9546 }
9547 
9548 /*
9549  * delayed cv_broadcast to allow for target to recover
9550  * from media insertion
9551  */
9552 static void
9553 st_delayed_cv_broadcast(void *arg)
9554 {
9555         struct scsi_tape *un = arg;
9556 
9557         ST_FUNC(ST_DEVINFO, st_delayed_cv_broadcast);
9558 
9559         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9560             "st_delayed_cv_broadcast:delayed cv_broadcast\n");
9561 
9562         mutex_enter(ST_MUTEX);
9563         cv_broadcast(&un->un_state_cv);
9564         mutex_exit(ST_MUTEX);
9565 }
9566 
9567 /*
9568  * restart cmd currently at the start of the waitq
9569  */
9570 static void
9571 st_start_restart(void *arg)
9572 {
9573         struct scsi_tape *un = arg;
9574 
9575         ST_FUNC(ST_DEVINFO, st_start_restart);
9576 
9577         ASSERT(un != NULL);
9578 
9579         mutex_enter(ST_MUTEX);
9580 
9581         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_tran_restart()\n");
9582 
9583         st_start(un);
9584 
9585         mutex_exit(ST_MUTEX);
9586 }
9587 
9588 
9589 /*
9590  * Command completion processing
9591  *
9592  */
9593 static void
9594 st_intr(struct scsi_pkt *pkt)
9595 {
9596         recov_info *rcv = pkt->pkt_private;
9597         struct buf *bp = rcv->cmd_bp;
9598         struct scsi_tape *un;
9599         errstate action = COMMAND_DONE;
9600         clock_t timout;
9601         int     status;
9602 
9603         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
9604 
9605         ST_FUNC(ST_DEVINFO, st_intr);
9606 
9607         ASSERT(un != NULL);
9608 
9609         mutex_enter(ST_MUTEX);
9610 
9611         ASSERT(bp != un->un_recov_buf);
9612 
9613         un->un_rqs_state &= ~(ST_RQS_ERROR);
9614 
9615         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_intr()\n");
9616 
9617         if (pkt->pkt_reason != CMD_CMPLT) {
9618                 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
9619                     "Unhappy packet status reason = %s statistics = 0x%x\n",
9620                     scsi_rname(pkt->pkt_reason), pkt->pkt_statistics);
9621 
9622                 /* If device has gone away not much else to do */
9623                 if (pkt->pkt_reason == CMD_DEV_GONE) {
9624                         action = COMMAND_DONE_ERROR;
9625                 } else if ((pkt == un->un_rqs) ||
9626                     (un->un_state == ST_STATE_SENSING)) {
9627                         ASSERT(pkt == un->un_rqs);
9628                         ASSERT(un->un_state == ST_STATE_SENSING);
9629                         un->un_state = un->un_laststate;
9630                         rcv->cmd_bp = un->un_rqs_bp;
9631                         ST_DO_ERRSTATS(un, st_transerrs);
9632                         action = COMMAND_DONE_ERROR;
9633                 } else {
9634                         action = st_handle_incomplete(un, bp);
9635                 }
9636         /*
9637          * At this point we know that the command was successfully
9638          * completed. Now what?
9639          */
9640         } else if ((pkt == un->un_rqs) || (un->un_state == ST_STATE_SENSING)) {
9641                 /*
9642                  * okay. We were running a REQUEST SENSE. Find
9643                  * out what to do next.
9644                  */
9645                 ASSERT(pkt == un->un_rqs);
9646                 ASSERT(un->un_state == ST_STATE_SENSING);
9647                 scsi_sync_pkt(pkt);
9648                 action = st_handle_sense(un, bp, &un->un_pos);
9649                 /*
9650                  * Make rqs isn't going to be retied.
9651                  */
9652                 if (action != QUE_BUSY_COMMAND && action != QUE_COMMAND) {
9653                         /*
9654                          * set pkt back to original packet in case we will have
9655                          * to requeue it
9656                          */
9657                         pkt = BP_PKT(bp);
9658                         rcv->cmd_bp = un->un_rqs_bp;
9659                         /*
9660                          * some actions are based on un_state, hence
9661                          * restore the state st was in before ST_STATE_SENSING.
9662                          */
9663                         un->un_state = un->un_laststate;
9664                 }
9665 
9666         } else if (un->un_arq_enabled && (pkt->pkt_state & STATE_ARQ_DONE)) {
9667                 /*
9668                  * the transport layer successfully completed an autorqsense
9669                  */
9670                 action = st_handle_autosense(un, bp, &un->un_pos);
9671 
9672         } else  if ((SCBP(pkt)->sts_busy) ||
9673             (SCBP(pkt)->sts_chk) ||
9674             (SCBP(pkt)->sts_vu7)) {
9675                 /*
9676                  * Okay, we weren't running a REQUEST SENSE. Call a routine
9677                  * to see if the status bits we're okay. If a request sense
9678                  * is to be run, that will happen.
9679                  */
9680                 action = st_check_error(un, pkt);
9681         }
9682 
9683         if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
9684                 switch (action) {
9685                         case QUE_COMMAND:
9686                                 /*
9687                                  * return cmd to head to the queue
9688                                  * since we are suspending so that
9689                                  * it gets restarted during resume
9690                                  */
9691                                 st_add_to_queue(&un->un_runqf, &un->un_runql,
9692                                     un->un_runqf, bp);
9693 
9694                                 action = JUST_RETURN;
9695                                 break;
9696 
9697                         case QUE_SENSE:
9698                                 action = COMMAND_DONE_ERROR;
9699                                 break;
9700 
9701                         default:
9702                                 break;
9703                 }
9704         }
9705 
9706         /*
9707          * check for undetected path failover.
9708          */
9709         if (un->un_multipath) {
9710 
9711                 struct uscsi_cmd *ucmd = BP_UCMD(bp);
9712                 int pkt_valid = 0;
9713 
9714                 if (ucmd) {
9715                         /*
9716                          * Also copies path instance to the uscsi structure.
9717                          */
9718                         pkt_valid = scsi_uscsi_pktfini(pkt, ucmd);
9719 
9720                         /*
9721                          * scsi_uscsi_pktfini() zeros pkt_path_instance.
9722                          */
9723                         pkt->pkt_path_instance = ucmd->uscsi_path_instance;
9724                 } else {
9725                         pkt_valid = scsi_pkt_allocated_correctly(pkt);
9726                 }
9727 
9728                 /*
9729                  * If the scsi_pkt was not allocated correctly the
9730                  * pkt_path_instance is not even there.
9731                  */
9732                 if ((pkt_valid != 0) &&
9733                     (un->un_last_path_instance != pkt->pkt_path_instance)) {
9734                         /*
9735                          * Don't recover the path change if it was done
9736                          * intentionally or if the device has not completely
9737                          * opened yet.
9738                          */
9739                         if (((pkt->pkt_flags & FLAG_PKT_PATH_INSTANCE) == 0) &&
9740                             (un->un_state > ST_STATE_OPENING)) {
9741                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
9742                                     "Failover detected, action is %s\n",
9743                                     errstatenames[action]);
9744                                 if (action == COMMAND_DONE) {
9745                                         action = PATH_FAILED;
9746                                 }
9747                         }
9748                         un->un_last_path_instance = pkt->pkt_path_instance;
9749                 }
9750         }
9751 
9752         /*
9753          * Restore old state if we were sensing.
9754          */
9755         if (un->un_state == ST_STATE_SENSING && action != QUE_SENSE) {
9756                 un->un_state = un->un_laststate;
9757         }
9758 
9759         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
9760             "st_intr: pkt=%p, bp=%p, action=%s, status=%x\n",
9761             (void *)pkt, (void *)bp, errstatenames[action], SCBP_C(pkt));
9762 
9763 again:
9764         switch (action) {
9765         case COMMAND_DONE_EACCES:
9766                 /* this is to report a reservation conflict */
9767                 st_bioerror(bp, EACCES);
9768                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9769                     "Reservation Conflict \n");
9770                 un->un_pos.pmode = invalid;
9771 
9772                 /*FALLTHROUGH*/
9773         case COMMAND_DONE_ERROR:
9774                 if (un->un_pos.eof < ST_EOT_PENDING &&
9775                     un->un_state >= ST_STATE_OPEN) {
9776                         /*
9777                          * all errors set state of the tape to 'unknown'
9778                          * unless we're at EOT or are doing append testing.
9779                          * If sense key was illegal request, preserve state.
9780                          */
9781                         if (un->un_status != KEY_ILLEGAL_REQUEST) {
9782                                 un->un_pos.pmode = invalid;
9783                         }
9784                 }
9785 
9786                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9787                 /*
9788                  * since we have an error (COMMAND_DONE_ERROR), we want to
9789                  * make sure an error ocurrs, so make sure at least EIO is
9790                  * returned
9791                  */
9792                 if (geterror(bp) == 0)
9793                         st_bioerror(bp, EIO);
9794 
9795                 st_set_pe_flag(un);
9796                 if (!(un->un_rqs_state & ST_RQS_ERROR) &&
9797                     (un->un_errno == EIO)) {
9798                         un->un_rqs_state &= ~(ST_RQS_VALID);
9799                 }
9800                 break;
9801 
9802         case COMMAND_DONE_ERROR_RECOVERED:
9803                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9804                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
9805                     "st_intr(): COMMAND_DONE_ERROR_RECOVERED");
9806                 if (geterror(bp) == 0) {
9807                         st_bioerror(bp, EIO);
9808                 }
9809                 st_set_pe_flag(un);
9810                 if (!(un->un_rqs_state & ST_RQS_ERROR) &&
9811                     (un->un_errno == EIO)) {
9812                         un->un_rqs_state &= ~(ST_RQS_VALID);
9813                 }
9814                 /*FALLTHROUGH*/
9815         case COMMAND_DONE:
9816                 st_set_state(un, bp);
9817                 break;
9818 
9819         case QUE_SENSE:
9820                 if ((un->un_ncmds > 1) && !un->un_flush_on_errors)
9821                         goto sense_error;
9822 
9823                 if (un->un_state != ST_STATE_SENSING) {
9824                         un->un_laststate = un->un_state;
9825                         un->un_state = ST_STATE_SENSING;
9826                 }
9827 
9828                 /*
9829                  * zero the sense data.
9830                  */
9831                 bzero(un->un_rqs->pkt_scbp, SENSE_LENGTH);
9832 
9833                 /*
9834                  * If this is not a retry on QUE_SENSE point to the original
9835                  * bp of the command that got us here.
9836                  */
9837                 if (pkt != un->un_rqs) {
9838                         ((recov_info *)un->un_rqs->pkt_private)->cmd_bp = bp;
9839                 }
9840 
9841                 if (un->un_throttle) {
9842                         un->un_last_throttle = un->un_throttle;
9843                         un->un_throttle = 0;
9844                 }
9845 
9846                 ST_CDB(ST_DEVINFO, "Queue sense CDB",
9847                     (char *)BP_PKT(bp)->pkt_cdbp);
9848 
9849                 /*
9850                  * never retry this, some other command will have nuked the
9851                  * sense, anyway
9852                  */
9853                 status = st_transport(un, un->un_rqs);
9854 
9855                 if (un->un_last_throttle) {
9856                         un->un_throttle = un->un_last_throttle;
9857                 }
9858 
9859                 if (status == TRAN_ACCEPT) {
9860                         mutex_exit(ST_MUTEX);
9861                         return;
9862                 }
9863                 if (status != TRAN_BUSY)
9864                         ST_DO_ERRSTATS(un, st_transerrs);
9865 sense_error:
9866                 un->un_pos.pmode = invalid;
9867                 st_bioerror(bp, EIO);
9868                 st_set_pe_flag(un);
9869                 break;
9870 
9871         case QUE_BUSY_COMMAND:
9872                 /* longish timeout */
9873                 timout = ST_STATUS_BUSY_TIMEOUT;
9874                 goto que_it_up;
9875 
9876         case QUE_COMMAND:
9877                 /* short timeout */
9878                 timout = ST_TRAN_BUSY_TIMEOUT;
9879 que_it_up:
9880                 /*
9881                  * let st_handle_intr_busy put this bp back on waitq and make
9882                  * checks to see if it is ok to requeue the command.
9883                  */
9884                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9885 
9886                 /*
9887                  * Save the throttle before setting up the timeout
9888                  */
9889                 if (un->un_throttle) {
9890                         un->un_last_throttle = un->un_throttle;
9891                 }
9892                 mutex_exit(ST_MUTEX);
9893                 if (st_handle_intr_busy(un, bp, timout) == 0)
9894                         return;         /* timeout is setup again */
9895 
9896                 mutex_enter(ST_MUTEX);
9897                 un->un_pos.pmode = invalid;
9898                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9899                 st_bioerror(bp, EIO);
9900                 st_set_pe_flag(un);
9901                 break;
9902 
9903         case QUE_LAST_COMMAND:
9904 
9905                 if ((un->un_ncmds > 1) && !un->un_flush_on_errors) {
9906                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
9907                             "un_ncmds: %d can't retry cmd \n", un->un_ncmds);
9908                         goto last_command_error;
9909                 }
9910                 mutex_exit(ST_MUTEX);
9911                 if (st_handle_intr_retry_lcmd(un, bp) == 0)
9912                         return;
9913                 mutex_enter(ST_MUTEX);
9914 last_command_error:
9915                 un->un_err_resid = bp->b_resid = bp->b_bcount;
9916                 un->un_pos.pmode = invalid;
9917                 st_bioerror(bp, EIO);
9918                 st_set_pe_flag(un);
9919                 break;
9920 
9921         case COMMAND_TIMEOUT:
9922         case DEVICE_RESET:
9923         case DEVICE_TAMPER:
9924         case ATTEMPT_RETRY:
9925         case PATH_FAILED:
9926                 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
9927                     "Command Recovery called on %s status\n",
9928                     errstatenames[action]);
9929                 action = st_command_recovery(un, pkt, action);
9930                 goto again;
9931 
9932         default:
9933                 ASSERT(0);
9934                 /* FALLTHRU */
9935         case JUST_RETURN:
9936                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9937                 mutex_exit(ST_MUTEX);
9938                 return;
9939         }
9940 
9941         ST_DO_KSTATS(bp, kstat_runq_exit);
9942         st_done_and_mutex_exit(un, bp);
9943 }
9944 
9945 static errstate
9946 st_handle_incomplete(struct scsi_tape *un, struct buf *bp)
9947 {
9948         static char *fail = "SCSI transport failed: reason '%s': %s\n";
9949         recov_info *rinfo;
9950         errstate rval = COMMAND_DONE_ERROR;
9951         struct scsi_pkt *pkt = (un->un_state == ST_STATE_SENSING) ?
9952             un->un_rqs : BP_PKT(bp);
9953         int result;
9954 
9955         ST_FUNC(ST_DEVINFO, st_handle_incomplete);
9956 
9957         rinfo = (recov_info *)pkt->pkt_private;
9958 
9959         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9960             "st_handle_incomplete(): dev = 0x%lx\n", un->un_dev);
9961 
9962         ASSERT(mutex_owned(ST_MUTEX));
9963 
9964         /* prevent infinite number of retries */
9965         if (rinfo->pkt_retry_cnt++ > st_retry_count) {
9966                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
9967                     "Recovery stopped for incomplete %s command, "
9968                     "retries exhausted",
9969                     st_print_scsi_cmd(pkt->pkt_cdbp[0]));
9970                 return (COMMAND_DONE_ERROR);
9971         }
9972 
9973         switch (pkt->pkt_reason) {
9974         case CMD_INCOMPLETE:    /* tran stopped with not normal state */
9975                 /*
9976                  * this occurs when accessing a powered down drive, no
9977                  * need to complain; just fail the open
9978                  */
9979                 ST_CDB(ST_DEVINFO, "Incomplete CDB", (char *)pkt->pkt_cdbp);
9980 
9981                 /*
9982                  * if we have commands outstanding in HBA, and a command
9983                  * comes back incomplete, we're hosed, so reset target
9984                  * If we have the bus, but cmd_incomplete, we probably just
9985                  * have a failed selection, so don't reset the target, just
9986                  * requeue the command and try again
9987                  */
9988                 if ((un->un_ncmds > 1) || (pkt->pkt_state != STATE_GOT_BUS)) {
9989                         goto reset_target;
9990                 }
9991 
9992                 /*
9993                  * Retry selection a couple more times if we're
9994                  * open.  If opening, we only try just once to
9995                  * reduce probe time for nonexistant devices.
9996                  */
9997                 if ((un->un_laststate > ST_STATE_OPENING) &&
9998                     (rinfo->pkt_retry_cnt < st_selection_retry_count)) {
9999                         /* XXX check retriable? */
10000                         rval = QUE_COMMAND;
10001                 }
10002                 ST_DO_ERRSTATS(un, st_transerrs);
10003                 break;
10004 
10005         case CMD_ABORTED:
10006                 /*
10007                  * most likely this is caused by flush-on-error support. If
10008                  * it was not there, the we're in trouble.
10009                  */
10010                 if (!un->un_flush_on_errors) {
10011                         un->un_status = SUN_KEY_FATAL;
10012                         goto reset_target;
10013                 }
10014 
10015                 st_set_pe_errno(un);
10016                 bioerror(bp, un->un_errno);
10017                 if (un->un_errno)
10018                         return (COMMAND_DONE_ERROR);
10019                 else
10020                         return (COMMAND_DONE);
10021 
10022         case CMD_TIMEOUT:       /* Command timed out */
10023                 un->un_status = SUN_KEY_TIMEOUT;
10024                 return (COMMAND_TIMEOUT);
10025 
10026         case CMD_TRAN_ERR:
10027         case CMD_RESET:
10028                 if (pkt->pkt_statistics & (STAT_BUS_RESET | STAT_DEV_RESET)) {
10029                         if ((un->un_rsvd_status &
10030                             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
10031                             ST_RESERVE) {
10032                                 un->un_rsvd_status |= ST_LOST_RESERVE;
10033                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
10034                                     "Lost Reservation\n");
10035                         }
10036                         rval = DEVICE_RESET;
10037                         return (rval);
10038                 }
10039                 if (pkt->pkt_statistics & (STAT_ABORTED | STAT_TERMINATED)) {
10040                         rval = DEVICE_RESET;
10041                         return (rval);
10042                 }
10043                 /*FALLTHROUGH*/
10044         default:
10045                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10046                     "Unhandled packet status reason = %s statistics = 0x%x\n",
10047                     scsi_rname(pkt->pkt_reason), pkt->pkt_statistics);
10048 reset_target:
10049 
10050                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10051                     "transport completed with %s\n",
10052                     scsi_rname(pkt->pkt_reason));
10053                 ST_DO_ERRSTATS(un, st_transerrs);
10054                 if ((pkt->pkt_state & STATE_GOT_TARGET) &&
10055                     ((pkt->pkt_statistics & (STAT_BUS_RESET | STAT_DEV_RESET |
10056                     STAT_ABORTED)) == 0)) {
10057 
10058                         /*
10059                          * If we haven't reserved the drive don't reset it.
10060                          */
10061                         if ((un->un_rsvd_status &
10062                             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
10063                                 return (rval);
10064                         }
10065 
10066                         /*
10067                          * if we aren't lost yet we will be soon.
10068                          */
10069                         un->un_pos.pmode = invalid;
10070 
10071                         result = st_reset(un, RESET_LUN);
10072 
10073                         if ((result == 0) && (un->un_state >= ST_STATE_OPEN)) {
10074                                 /* no hope left to recover */
10075                                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10076                                     "recovery by resets failed\n");
10077                                 return (rval);
10078                         }
10079                 }
10080         }
10081 
10082 
10083         if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
10084                 rval = QUE_COMMAND;
10085         } else if (bp == un->un_sbufp) {
10086                 if (rinfo->privatelen == sizeof (recov_info)) {
10087                         if (rinfo->cmd_attrib->retriable) {
10088                                 /*
10089                                  * These commands can be rerun
10090                                  * with impunity
10091                                  */
10092                                 rval = QUE_COMMAND;
10093                         }
10094                 } else {
10095                         cmd_attribute const *attrib;
10096                         attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
10097                         if (attrib->retriable) {
10098                                 rval = QUE_COMMAND;
10099                         }
10100                 }
10101         }
10102 
10103         if (un->un_state >= ST_STATE_OPEN) {
10104                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10105                     fail, scsi_rname(pkt->pkt_reason),
10106                     (rval == COMMAND_DONE_ERROR)?
10107                     "giving up" : "retrying command");
10108         }
10109         return (rval);
10110 }
10111 
10112 /*
10113  * if the device is busy, then put this bp back on the waitq, on the
10114  * interrupt thread, where we want the head of the queue and not the
10115  * end
10116  *
10117  * The callers of this routine should take measures to save the
10118  * un_throttle in un_last_throttle which will be restored in
10119  * st_intr_restart(). The only exception should be st_intr_restart()
10120  * calling this routine for which the saving is already done.
10121  */
10122 static int
10123 st_handle_intr_busy(struct scsi_tape *un, struct buf *bp,
10124         clock_t timeout_interval)
10125 {
10126 
10127         int queued;
10128         int rval = 0;
10129         pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
10130 
10131         mutex_enter(ST_MUTEX);
10132 
10133         ST_FUNC(ST_DEVINFO, st_handle_intr_busy);
10134 
10135         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10136             "st_handle_intr_busy(), un = 0x%p\n", (void *)un);
10137 
10138         if ((bp != un->un_sbufp) && (bp != un->un_recov_buf)) {
10139                 queued = 1;
10140         } else {
10141                 queued = 0;
10142         }
10143 
10144         /*
10145          * Check to see if we hit the retry timeout. We check to make sure
10146          * this is the first one on the runq and make sure we have not
10147          * queued up any more, so this one has to be the last on the list
10148          * also. If it is not, we have to fail.  If it is not the first, but
10149          * is the last we are in trouble anyway, as we are in the interrupt
10150          * context here.
10151          */
10152         if ((pktinfo->str_retry_cnt++ > st_retry_count) ||
10153             ((un->un_runqf != bp) && (un->un_runql != bp) && (queued))) {
10154                 rval = -1;
10155                 goto exit;
10156         }
10157 
10158         /* put the bp back on the waitq */
10159         if (queued) {
10160                 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
10161                 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quef, bp);
10162         }
10163 
10164         /*
10165          * We don't want any other commands being started in the mean time.
10166          * If start had just released mutex after putting something on the
10167          * runq, we won't even get here.
10168          */
10169         un->un_throttle = 0;
10170 
10171         /*
10172          * send a marker pkt, if appropriate
10173          */
10174         st_hba_unflush(un);
10175 
10176         /*
10177          * all queues are aligned, we are just waiting to
10178          * transport
10179          */
10180         un->un_hib_tid = timeout(st_intr_restart, un, timeout_interval);
10181 
10182 exit:
10183         mutex_exit(ST_MUTEX);
10184         return (rval);
10185 }
10186 
10187 /*
10188  * To get one error entry from error stack
10189  */
10190 static int
10191 st_get_error_entry(struct scsi_tape *un, intptr_t arg, int flag)
10192 {
10193 #ifdef _MULTI_DATAMODEL
10194         /*
10195          * For use when a 32 bit app makes a call into a
10196          * 64 bit ioctl
10197          */
10198         struct mterror_entry32 err_entry32;
10199 #endif /* _MULTI_DATAMODEL */
10200 
10201         int rval = 0;
10202         struct mterror_entry err_entry;
10203         struct mterror_entry_stack *err_link_entry_p;
10204         size_t arq_status_len_in, arq_status_len_kr;
10205 
10206         ST_FUNC(ST_DEVINFO, st_get_error_entry);
10207 
10208         ASSERT(mutex_owned(ST_MUTEX));
10209 
10210         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10211             "st_get_error_entry()\n");
10212 
10213         /*
10214          * if error record stack empty, return ENXIO
10215          */
10216         if (un->un_error_entry_stk == NULL) {
10217                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10218                     "st_get_error_entry: Error Entry Stack Empty!\n");
10219                 rval = ENXIO;
10220                 goto ret;
10221         }
10222 
10223         /*
10224          * get the top entry from stack
10225          */
10226         err_link_entry_p = un->un_error_entry_stk;
10227         arq_status_len_kr =
10228             err_link_entry_p->mtees_entry.mtee_arq_status_len;
10229 
10230 #ifdef _MULTI_DATAMODEL
10231         switch (ddi_model_convert_from(flag & FMODELS)) {
10232         case DDI_MODEL_ILP32:
10233                 if (ddi_copyin((void *)arg, &err_entry32,
10234                     MTERROR_ENTRY_SIZE_32, flag)) {
10235                         rval = EFAULT;
10236                         goto ret;
10237                 }
10238 
10239                 arq_status_len_in =
10240                     (size_t)err_entry32.mtee_arq_status_len;
10241 
10242                 err_entry32.mtee_cdb_len =
10243                     (size32_t)err_link_entry_p->mtees_entry.mtee_cdb_len;
10244 
10245                 if (arq_status_len_in > arq_status_len_kr)
10246                         err_entry32.mtee_arq_status_len =
10247                             (size32_t)arq_status_len_kr;
10248 
10249                 if (ddi_copyout(
10250                     err_link_entry_p->mtees_entry.mtee_cdb_buf,
10251                     (void *)(uintptr_t)err_entry32.mtee_cdb_buf,
10252                     err_entry32.mtee_cdb_len, flag)) {
10253                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10254                             "st_get_error_entry: Copy cdb buffer error!");
10255                         rval = EFAULT;
10256                 }
10257 
10258                 if (ddi_copyout(
10259                     err_link_entry_p->mtees_entry.mtee_arq_status,
10260                     (void *)(uintptr_t)err_entry32.mtee_arq_status,
10261                     err_entry32.mtee_arq_status_len, flag)) {
10262                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10263                             "st_get_error_entry: copy arq status error!");
10264                         rval = EFAULT;
10265                 }
10266 
10267                 if (ddi_copyout(&err_entry32, (void *)arg,
10268                     MTERROR_ENTRY_SIZE_32, flag)) {
10269                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10270                             "st_get_error_entry: copy arq status out error!");
10271                         rval = EFAULT;
10272                 }
10273                 break;
10274 
10275         case DDI_MODEL_NONE:
10276                 if (ddi_copyin((void *)arg, &err_entry,
10277                     MTERROR_ENTRY_SIZE_64, flag)) {
10278                         rval = EFAULT;
10279                         goto ret;
10280                 }
10281                 arq_status_len_in = err_entry.mtee_arq_status_len;
10282 
10283                 err_entry.mtee_cdb_len =
10284                     err_link_entry_p->mtees_entry.mtee_cdb_len;
10285 
10286                 if (arq_status_len_in > arq_status_len_kr)
10287                         err_entry.mtee_arq_status_len =
10288                             arq_status_len_kr;
10289 
10290                 if (ddi_copyout(
10291                     err_link_entry_p->mtees_entry.mtee_cdb_buf,
10292                     err_entry.mtee_cdb_buf,
10293                     err_entry.mtee_cdb_len, flag)) {
10294                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10295                             "st_get_error_entry: Copy cdb buffer error!");
10296                         rval = EFAULT;
10297                 }
10298 
10299                 if (ddi_copyout(
10300                     err_link_entry_p->mtees_entry.mtee_arq_status,
10301                     err_entry.mtee_arq_status,
10302                     err_entry.mtee_arq_status_len, flag)) {
10303                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10304                             "st_get_error_entry: copy arq status error!");
10305                         rval = EFAULT;
10306                 }
10307 
10308                 if (ddi_copyout(&err_entry, (void *)arg,
10309                     MTERROR_ENTRY_SIZE_64, flag)) {
10310                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10311                             "st_get_error_entry: copy arq status out error!");
10312                         rval = EFAULT;
10313                 }
10314                 break;
10315         }
10316 #else /* _MULTI_DATAMODEL */
10317         if (ddi_copyin((void *)arg, &err_entry,
10318             MTERROR_ENTRY_SIZE_64, flag)) {
10319                 rval = EFAULT;
10320                 goto ret;
10321         }
10322         arq_status_len_in = err_entry.mtee_arq_status_len;
10323 
10324         err_entry.mtee_cdb_len =
10325             err_link_entry_p->mtees_entry.mtee_cdb_len;
10326 
10327         if (arq_status_len_in > arq_status_len_kr)
10328                 err_entry.mtee_arq_status_len =
10329                     arq_status_len_kr;
10330 
10331         if (ddi_copyout(
10332             err_link_entry_p->mtees_entry.mtee_cdb_buf,
10333             err_entry.mtee_cdb_buf,
10334             err_entry.mtee_cdb_len, flag)) {
10335                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10336                     "st_get_error_entry: Copy cdb buffer error!");
10337                 rval = EFAULT;
10338         }
10339 
10340         if (ddi_copyout(
10341             err_link_entry_p->mtees_entry.mtee_arq_status,
10342             err_entry.mtee_arq_status,
10343             err_entry.mtee_arq_status_len, flag)) {
10344                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10345                     "st_get_error_entry: copy arq status buffer error!");
10346                 rval = EFAULT;
10347         }
10348 
10349         if (ddi_copyout(&err_entry, (void *)arg,
10350             MTERROR_ENTRY_SIZE_64, flag)) {
10351                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10352                     "st_get_error_entry: copy arq status out error!");
10353                 rval = EFAULT;
10354         }
10355 #endif /* _MULTI_DATAMODEL */
10356 
10357         /*
10358          * update stack
10359          */
10360         un->un_error_entry_stk = err_link_entry_p->mtees_nextp;
10361 
10362         kmem_free(err_link_entry_p->mtees_entry.mtee_cdb_buf,
10363             err_link_entry_p->mtees_entry.mtee_cdb_len);
10364         err_link_entry_p->mtees_entry.mtee_cdb_buf = NULL;
10365 
10366         kmem_free(err_link_entry_p->mtees_entry.mtee_arq_status,
10367             SECMDS_STATUS_SIZE);
10368         err_link_entry_p->mtees_entry.mtee_arq_status = NULL;
10369 
10370         kmem_free(err_link_entry_p, MTERROR_LINK_ENTRY_SIZE);
10371         err_link_entry_p = NULL;
10372 ret:
10373         return (rval);
10374 }
10375 
10376 /*
10377  * MTIOCGETERROR ioctl needs to retrieve the current sense data along with
10378  * the scsi CDB command which causes the error and generates sense data and
10379  * the scsi status.
10380  *
10381  *      error-record stack
10382  *
10383  *
10384  *             TOP                                     BOTTOM
10385  *              ------------------------------------------
10386  *              |   0   |   1   |   2   |   ...  |   n   |
10387  *              ------------------------------------------
10388  *                  ^
10389  *                  |
10390  *       pointer to error entry
10391  *
10392  * when st driver generates one sense data record, it creates a error-entry
10393  * and pushes it onto the stack.
10394  *
10395  */
10396 
10397 static void
10398 st_update_error_stack(struct scsi_tape *un,
10399                         struct scsi_pkt *pkt,
10400                         struct scsi_arq_status *cmd)
10401 {
10402         struct mterror_entry_stack *err_entry_tmp;
10403         uchar_t *cdbp = (uchar_t *)pkt->pkt_cdbp;
10404         size_t cdblen = scsi_cdb_size[CDB_GROUPID(cdbp[0])];
10405 
10406         ST_FUNC(ST_DEVINFO, st_update_error_stack);
10407 
10408         ASSERT(mutex_owned(ST_MUTEX));
10409 
10410         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10411             "st_update_error_stack()\n");
10412 
10413         ASSERT(cmd);
10414         ASSERT(cdbp);
10415         if (cdblen == 0) {
10416                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10417                     "st_update_error_stack: CDB length error!\n");
10418                 return;
10419         }
10420 
10421         err_entry_tmp = kmem_alloc(MTERROR_LINK_ENTRY_SIZE, KM_SLEEP);
10422         ASSERT(err_entry_tmp != NULL);
10423 
10424         err_entry_tmp->mtees_entry.mtee_cdb_buf =
10425             kmem_alloc(cdblen, KM_SLEEP);
10426         ASSERT(err_entry_tmp->mtees_entry.mtee_cdb_buf != NULL);
10427 
10428         err_entry_tmp->mtees_entry.mtee_arq_status =
10429             kmem_alloc(SECMDS_STATUS_SIZE, KM_SLEEP);
10430         ASSERT(err_entry_tmp->mtees_entry.mtee_arq_status != NULL);
10431 
10432         /*
10433          * copy cdb command & length to current error entry
10434          */
10435         err_entry_tmp->mtees_entry.mtee_cdb_len = cdblen;
10436         bcopy(cdbp, err_entry_tmp->mtees_entry.mtee_cdb_buf, cdblen);
10437 
10438         /*
10439          * copy scsi status length to current error entry
10440          */
10441         err_entry_tmp->mtees_entry.mtee_arq_status_len =
10442             SECMDS_STATUS_SIZE;
10443 
10444         /*
10445          * copy sense data and scsi status to current error entry
10446          */
10447         bcopy(cmd, err_entry_tmp->mtees_entry.mtee_arq_status,
10448             SECMDS_STATUS_SIZE);
10449 
10450         err_entry_tmp->mtees_nextp = un->un_error_entry_stk;
10451         un->un_error_entry_stk = err_entry_tmp;
10452 
10453 }
10454 
10455 /*
10456  * Empty all the error entry in stack
10457  */
10458 static void
10459 st_empty_error_stack(struct scsi_tape *un)
10460 {
10461         struct mterror_entry_stack *linkp;
10462 
10463         ST_FUNC(ST_DEVINFO, st_empty_error_stack);
10464 
10465         ASSERT(mutex_owned(ST_MUTEX));
10466 
10467         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10468             "st_empty_entry_stack()\n");
10469 
10470         while (un->un_error_entry_stk != NULL) {
10471                 linkp = un->un_error_entry_stk;
10472                 un->un_error_entry_stk =
10473                     un->un_error_entry_stk->mtees_nextp;
10474 
10475                 if (linkp->mtees_entry.mtee_cdb_buf != NULL)
10476                         kmem_free(linkp->mtees_entry.mtee_cdb_buf,
10477                             linkp->mtees_entry.mtee_cdb_len);
10478 
10479                 if (linkp->mtees_entry.mtee_arq_status != NULL)
10480                         kmem_free(linkp->mtees_entry.mtee_arq_status,
10481                             linkp->mtees_entry.mtee_arq_status_len);
10482 
10483                 kmem_free(linkp, MTERROR_LINK_ENTRY_SIZE);
10484                 linkp = NULL;
10485         }
10486 }
10487 
10488 static errstate
10489 st_handle_sense(struct scsi_tape *un, struct buf *bp, tapepos_t *pos)
10490 {
10491         struct scsi_pkt *pkt = BP_PKT(bp);
10492         struct scsi_pkt *rqpkt = un->un_rqs;
10493         struct scsi_arq_status arqstat;
10494         recov_info *rcif = pkt->pkt_private;
10495 
10496         errstate rval = COMMAND_DONE_ERROR;
10497         int amt;
10498 
10499         ST_FUNC(ST_DEVINFO, st_handle_sense);
10500 
10501         ASSERT(mutex_owned(ST_MUTEX));
10502 
10503         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10504             "st_handle_sense()\n");
10505 
10506         if (SCBP(rqpkt)->sts_busy) {
10507                 if (rcif->privatelen == sizeof (recov_info)) {
10508                         ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
10509                             "Attempt recovery of busy unit on request sense\n");
10510                         rval = ATTEMPT_RETRY;
10511                 } else if (rcif->pkt_retry_cnt++ < st_retry_count) {
10512                         ST_DEBUG4(ST_DEVINFO, st_label, CE_WARN,
10513                             "Retry busy unit on request sense\n");
10514                         rval = QUE_BUSY_COMMAND;
10515                 }
10516                 return (rval);
10517         } else if (SCBP(rqpkt)->sts_chk) {
10518                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10519                     "Check Condition on REQUEST SENSE\n");
10520                 return (rval);
10521         }
10522 
10523         /*
10524          * Make sure there is sense data to look at.
10525          */
10526         if ((rqpkt->pkt_state & (STATE_GOT_BUS | STATE_GOT_TARGET |
10527             STATE_SENT_CMD | STATE_GOT_STATUS)) != (STATE_GOT_BUS |
10528             STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS)) {
10529                 return (rval);
10530         }
10531 
10532         /* was there enough data? */
10533         amt = (int)MAX_SENSE_LENGTH - rqpkt->pkt_resid;
10534         if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 ||
10535             (amt < SUN_MIN_SENSE_LENGTH)) {
10536                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10537                     "REQUEST SENSE couldn't get sense data\n");
10538                 return (rval);
10539         }
10540 
10541         bcopy(SCBP(pkt), &arqstat.sts_status,
10542             sizeof (struct scsi_status));
10543         bcopy(SCBP(rqpkt), &arqstat.sts_rqpkt_status,
10544             sizeof (struct scsi_status));
10545         arqstat.sts_rqpkt_reason = rqpkt->pkt_reason;
10546         arqstat.sts_rqpkt_resid = rqpkt->pkt_resid;
10547         arqstat.sts_rqpkt_state = rqpkt->pkt_state;
10548         arqstat.sts_rqpkt_statistics = rqpkt->pkt_statistics;
10549         bcopy(ST_RQSENSE, &arqstat.sts_sensedata, SENSE_LENGTH);
10550 
10551         /*
10552          * copy one arqstat entry in the sense data buffer
10553          */
10554         st_update_error_stack(un, pkt, &arqstat);
10555         return (st_decode_sense(un, bp, amt, &arqstat, pos));
10556 }
10557 
10558 static errstate
10559 st_handle_autosense(struct scsi_tape *un, struct buf *bp, tapepos_t *pos)
10560 {
10561         struct scsi_pkt *pkt = BP_PKT(bp);
10562         struct scsi_arq_status *arqstat =
10563             (struct scsi_arq_status *)pkt->pkt_scbp;
10564         errstate rval = COMMAND_DONE_ERROR;
10565         int amt;
10566 
10567         ST_FUNC(ST_DEVINFO, st_handle_autosense);
10568 
10569         ASSERT(mutex_owned(ST_MUTEX));
10570 
10571         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10572             "st_handle_autosense()\n");
10573 
10574         if (arqstat->sts_rqpkt_status.sts_busy) {
10575                 ST_DEBUG4(ST_DEVINFO, st_label, CE_WARN,
10576                     "busy unit on request sense\n");
10577                 /*
10578                  * we return QUE_SENSE so st_intr will setup the SENSE cmd.
10579                  * the disadvantage is that we do not have any delay for the
10580                  * second retry of rqsense and we have to keep a packet around
10581                  */
10582                 return (QUE_SENSE);
10583 
10584         } else if (arqstat->sts_rqpkt_reason != CMD_CMPLT) {
10585                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10586                     "transport error on REQUEST SENSE\n");
10587                 if ((arqstat->sts_rqpkt_state & STATE_GOT_TARGET) &&
10588                     ((arqstat->sts_rqpkt_statistics &
10589                     (STAT_BUS_RESET | STAT_DEV_RESET | STAT_ABORTED)) == 0)) {
10590                         if (st_reset(un, RESET_LUN) == 0) {
10591                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10592                                     "recovery by resets failed\n");
10593                         }
10594                 }
10595                 return (rval);
10596 
10597         } else if (arqstat->sts_rqpkt_status.sts_chk) {
10598                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10599                     "Check Condition on REQUEST SENSE\n");
10600                 return (rval);
10601         }
10602 
10603 
10604         /* was there enough data? */
10605         if (pkt->pkt_state & STATE_XARQ_DONE) {
10606                 amt = (int)MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10607         } else {
10608                 if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) {
10609                         amt = (int)MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10610                 } else {
10611                         amt = (int)SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10612                 }
10613         }
10614         if ((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0 ||
10615             (amt < SUN_MIN_SENSE_LENGTH)) {
10616                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10617                     "REQUEST SENSE couldn't get sense data\n");
10618                 return (rval);
10619         }
10620 
10621         if (pkt->pkt_state & STATE_XARQ_DONE) {
10622                 bcopy(&arqstat->sts_sensedata, ST_RQSENSE, MAX_SENSE_LENGTH);
10623         } else {
10624                 bcopy(&arqstat->sts_sensedata, ST_RQSENSE, SENSE_LENGTH);
10625         }
10626 
10627         /*
10628          * copy one arqstat entry in the sense data buffer
10629          */
10630         st_update_error_stack(un, pkt, arqstat);
10631 
10632         return (st_decode_sense(un, bp, amt, arqstat, pos));
10633 }
10634 
10635 static errstate
10636 st_decode_sense(struct scsi_tape *un, struct buf *bp, int amt,
10637     struct scsi_arq_status *statusp, tapepos_t *pos)
10638 {
10639         struct scsi_pkt *pkt = BP_PKT(bp);
10640         recov_info *ri = pkt->pkt_private;
10641         errstate rval = COMMAND_DONE_ERROR;
10642         cmd_attribute const *attrib;
10643         long resid;
10644         struct scsi_extended_sense *sensep = ST_RQSENSE;
10645         int severity;
10646         int get_error;
10647 
10648         ST_FUNC(ST_DEVINFO, st_decode_sense);
10649 
10650         ASSERT(mutex_owned(ST_MUTEX));
10651         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10652             "st_decode_sense()\n");
10653 
10654         /*
10655          * For uscsi commands, squirrel away a copy of the
10656          * results of the Request Sense.
10657          */
10658         if (USCSI_CMD(bp)) {
10659                 struct uscsi_cmd *ucmd = BP_UCMD(bp);
10660                 ucmd->uscsi_rqstatus = *(uchar_t *)statusp;
10661                 if (ucmd->uscsi_rqlen && un->un_srqbufp) {
10662                         uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
10663                         ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
10664                         bcopy(ST_RQSENSE, un->un_srqbufp, rqlen);
10665                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10666                             "st_decode_sense: stat=0x%x resid=0x%x\n",
10667                             ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
10668                 }
10669         }
10670 
10671         if (ri->privatelen == sizeof (recov_info)) {
10672                 attrib = ri->cmd_attrib;
10673         } else {
10674                 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
10675         }
10676 
10677         /*
10678          * If the drive is an MT-02, reposition the
10679          * secondary error code into the proper place.
10680          *
10681          * XXX  MT-02 is non-CCS tape, so secondary error code
10682          * is in byte 8.  However, in SCSI-2, tape has CCS definition
10683          * so it's in byte 12.
10684          */
10685         if (un->un_dp->type == ST_TYPE_EMULEX) {
10686                 sensep->es_code = sensep->es_add_info[0];
10687         }
10688 
10689         ST_CDB(ST_DEVINFO, "st_decode_sense failed CDB",
10690             (caddr_t)&CDBP(pkt)->scc_cmd);
10691 
10692         ST_SENSE(ST_DEVINFO, "st_decode_sense sense data", (caddr_t)statusp,
10693             sizeof (*statusp));
10694 
10695         /* for normal I/O check extract the resid values. */
10696         if (bp != un->un_sbufp && bp != un->un_recov_buf) {
10697                 if (sensep->es_valid) {
10698                         resid =
10699                             (sensep->es_info_1 << 24) |
10700                             (sensep->es_info_2 << 16) |
10701                             (sensep->es_info_3 << 8)  |
10702                             (sensep->es_info_4);
10703                         /* If fixed block */
10704                         if (un->un_bsize) {
10705                                 resid *= un->un_bsize;
10706                         }
10707                 } else if (pkt->pkt_state & STATE_XFERRED_DATA) {
10708                         resid = pkt->pkt_resid;
10709                 } else {
10710                         resid = bp->b_bcount;
10711                 }
10712                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10713                     "st_decode_sense (rw): xferred bit = %d, resid=%ld (%d), "
10714                     "pkt_resid=%ld\n", pkt->pkt_state & STATE_XFERRED_DATA,
10715                     resid,
10716                     (sensep->es_info_1 << 24) |
10717                     (sensep->es_info_2 << 16) |
10718                     (sensep->es_info_3 << 8)  |
10719                     (sensep->es_info_4),
10720                     pkt->pkt_resid);
10721                 /*
10722                  * The problem is, what should we believe?
10723                  */
10724                 if (resid && (pkt->pkt_resid == 0)) {
10725                         pkt->pkt_resid = resid;
10726                 }
10727         } else {
10728                 /*
10729                  * If the command is SCMD_SPACE, we need to get the
10730                  * residual as returned in the sense data, to adjust
10731                  * our idea of current tape position correctly
10732                  */
10733                 if ((sensep->es_valid) &&
10734                     (CDBP(pkt)->scc_cmd == SCMD_LOCATE) ||
10735                     (CDBP(pkt)->scc_cmd == SCMD_LOCATE_G4) ||
10736                     (CDBP(pkt)->scc_cmd == SCMD_SPACE) ||
10737                     (CDBP(pkt)->scc_cmd == SCMD_SPACE_G4) ||
10738                     (CDBP(pkt)->scc_cmd == SCMD_WRITE_FILE_MARK)) {
10739                         resid =
10740                             (sensep->es_info_1 << 24) |
10741                             (sensep->es_info_2 << 16) |
10742                             (sensep->es_info_3 << 8)  |
10743                             (sensep->es_info_4);
10744                         bp->b_resid = resid;
10745                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10746                             "st_decode_sense(other):    resid=%ld\n", resid);
10747                 } else {
10748                         /*
10749                          * If the special command is SCMD_READ,
10750                          * the correct resid will be set later.
10751                          */
10752                         if (attrib->get_cnt != NULL) {
10753                                 resid = attrib->get_cnt(pkt->pkt_cdbp);
10754                         } else {
10755                                 resid = bp->b_bcount;
10756                         }
10757                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10758                             "st_decode_sense(special read):  resid=%ld\n",
10759                             resid);
10760                 }
10761         }
10762 
10763         if ((un->un_state >= ST_STATE_OPEN) &&
10764             (DEBUGGING || st_error_level == SCSI_ERR_ALL)) {
10765                 st_print_cdb(ST_DEVINFO, st_label, CE_NOTE,
10766                     "Failed CDB", (char *)pkt->pkt_cdbp);
10767                 st_clean_print(ST_DEVINFO, st_label, CE_CONT,
10768                     "sense data", (char *)sensep, amt);
10769                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
10770                     "count 0x%lx resid 0x%lx pktresid 0x%lx\n",
10771                     bp->b_bcount, resid, pkt->pkt_resid);
10772         }
10773 
10774         switch (un->un_status = sensep->es_key) {
10775         case KEY_NO_SENSE:
10776                 severity = SCSI_ERR_INFO;
10777 
10778                 /*
10779                  * Erase, locate or rewind operation in progress, retry
10780                  * ASC  ASCQ
10781                  *  00   18    Erase operation in progress
10782                  *  00   19    Locate operation in progress
10783                  *  00   1A    Rewind operation in progress
10784                  */
10785                 if (sensep->es_add_code == 0 &&
10786                     ((sensep->es_qual_code == 0x18) ||
10787                     (sensep->es_qual_code == 0x19) ||
10788                     (sensep->es_qual_code == 0x1a))) {
10789                         rval = QUE_BUSY_COMMAND;
10790                         break;
10791                 }
10792 
10793                 goto common;
10794 
10795         case KEY_RECOVERABLE_ERROR:
10796                 severity = SCSI_ERR_RECOVERED;
10797                 if ((sensep->es_class == CLASS_EXTENDED_SENSE) &&
10798                     (sensep->es_code == ST_DEFERRED_ERROR)) {
10799                         if (un->un_dp->options &
10800                             ST_RETRY_ON_RECOVERED_DEFERRED_ERROR) {
10801                                 rval = QUE_LAST_COMMAND;
10802                                 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label,
10803                                     severity, pos->lgclblkno,
10804                                     un->un_err_pos.lgclblkno, scsi_cmds,
10805                                     sensep);
10806                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
10807                                     "Command will be retried\n");
10808                         } else {
10809                                 severity = SCSI_ERR_FATAL;
10810                                 rval = COMMAND_DONE_ERROR_RECOVERED;
10811                                 ST_DO_ERRSTATS(un, st_softerrs);
10812                                 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label,
10813                                     severity, pos->lgclblkno,
10814                                     un->un_err_pos.lgclblkno, scsi_cmds,
10815                                     sensep);
10816                         }
10817                         break;
10818                 }
10819 common:
10820                 /*
10821                  * XXX only want reads to be stopped by filemarks.
10822                  * Don't want them to be stopped by EOT.  EOT matters
10823                  * only on write.
10824                  */
10825                 if (sensep->es_filmk && !sensep->es_eom) {
10826                         rval = COMMAND_DONE;
10827                 } else if (sensep->es_eom) {
10828                         rval = COMMAND_DONE;
10829                 } else if (sensep->es_ili) {
10830                         /*
10831                          * Fun with variable length record devices:
10832                          * for specifying larger blocks sizes than the
10833                          * actual physical record size.
10834                          */
10835                         if (un->un_bsize == 0 && resid > 0) {
10836                                 /*
10837                                  * XXX! Ugly.
10838                                  * The requested blocksize is > tape blocksize,
10839                                  * so this is ok, so we just return the
10840                                  * actual size xferred.
10841                                  */
10842                                 pkt->pkt_resid = resid;
10843                                 rval = COMMAND_DONE;
10844                         } else if (un->un_bsize == 0 && resid < 0) {
10845                                 /*
10846                                  * The requested blocksize is < tape blocksize,
10847                                  * so this is not ok, so we err with ENOMEM
10848                                  */
10849                                 rval = COMMAND_DONE_ERROR_RECOVERED;
10850                                 st_bioerror(bp, ENOMEM);
10851                         } else {
10852                                 ST_DO_ERRSTATS(un, st_softerrs);
10853                                 severity = SCSI_ERR_FATAL;
10854                                 rval = COMMAND_DONE_ERROR;
10855                                 st_bioerror(bp, EINVAL);
10856                                 un->un_running.pmode = invalid;
10857                         }
10858                 } else {
10859                         /*
10860                          * we hope and pray for this just being
10861                          * something we can ignore (ie. a
10862                          * truly recoverable soft error)
10863                          */
10864                         rval = COMMAND_DONE;
10865                 }
10866                 if (sensep->es_filmk) {
10867                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10868                             "filemark\n");
10869                         un->un_status = SUN_KEY_EOF;
10870                         pos->eof = ST_EOF_PENDING;
10871                         st_set_pe_flag(un);
10872                 }
10873 
10874                 /*
10875                  * ignore eom when reading, a fmk should terminate reading
10876                  */
10877                 if ((sensep->es_eom) &&
10878                     (CDBP(pkt)->scc_cmd != SCMD_READ)) {
10879                         if ((sensep->es_add_code == 0) &&
10880                             (sensep->es_qual_code == 4)) {
10881                                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10882                                     "bot\n");
10883                                 un->un_status = SUN_KEY_BOT;
10884                                 pos->eof = ST_NO_EOF;
10885                                 pos->lgclblkno = 0;
10886                                 pos->fileno = 0;
10887                                 pos->blkno = 0;
10888                                 if (pos->pmode != legacy)
10889                                         pos->pmode = legacy;
10890                         } else {
10891                                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10892                                     "eom\n");
10893                                 un->un_status = SUN_KEY_EOT;
10894                                 pos->eof = ST_EOM;
10895                         }
10896                         st_set_pe_flag(un);
10897                 }
10898 
10899                 break;
10900 
10901         case KEY_ILLEGAL_REQUEST:
10902 
10903                 if (un->un_laststate >= ST_STATE_OPEN) {
10904                         ST_DO_ERRSTATS(un, st_softerrs);
10905                         severity = SCSI_ERR_FATAL;
10906                 } else {
10907                         severity = SCSI_ERR_INFO;
10908                 }
10909                 break;
10910 
10911         case KEY_MEDIUM_ERROR:
10912                 ST_DO_ERRSTATS(un, st_harderrs);
10913                 severity = SCSI_ERR_FATAL;
10914                 un->un_pos.pmode = invalid;
10915                 un->un_running.pmode = invalid;
10916 check_keys:
10917                 /*
10918                  * attempt to process the keys in the presence of
10919                  * other errors
10920                  */
10921                 if (sensep->es_ili && rval != COMMAND_DONE_ERROR) {
10922                         /*
10923                          * Fun with variable length record devices:
10924                          * for specifying larger blocks sizes than the
10925                          * actual physical record size.
10926                          */
10927                         if (un->un_bsize == 0 && resid > 0) {
10928                                 /*
10929                                  * XXX! Ugly
10930                                  */
10931                                 pkt->pkt_resid = resid;
10932                         } else if (un->un_bsize == 0 && resid < 0) {
10933                                 st_bioerror(bp, EINVAL);
10934                         } else {
10935                                 severity = SCSI_ERR_FATAL;
10936                                 rval = COMMAND_DONE_ERROR;
10937                                 st_bioerror(bp, EINVAL);
10938                         }
10939                 }
10940                 if (sensep->es_filmk) {
10941                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10942                             "filemark\n");
10943                         un->un_status = SUN_KEY_EOF;
10944                         pos->eof = ST_EOF_PENDING;
10945                         st_set_pe_flag(un);
10946                 }
10947 
10948                 /*
10949                  * ignore eom when reading, a fmk should terminate reading
10950                  */
10951                 if ((sensep->es_eom) &&
10952                     (CDBP(pkt)->scc_cmd != SCMD_READ)) {
10953                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "eom\n");
10954                         un->un_status = SUN_KEY_EOT;
10955                         pos->eof = ST_EOM;
10956                         st_set_pe_flag(un);
10957                 }
10958 
10959                 break;
10960 
10961         case KEY_VOLUME_OVERFLOW:
10962                 ST_DO_ERRSTATS(un, st_softerrs);
10963                 pos->eof = ST_EOM;
10964                 severity = SCSI_ERR_FATAL;
10965                 rval = COMMAND_DONE_ERROR;
10966                 goto check_keys;
10967 
10968         case KEY_HARDWARE_ERROR:
10969                 ST_DO_ERRSTATS(un, st_harderrs);
10970                 severity = SCSI_ERR_FATAL;
10971                 rval = COMMAND_DONE_ERROR;
10972                 if (un->un_dp->options & ST_EJECT_ON_CHANGER_FAILURE)
10973                         un->un_eject_tape_on_failure = st_check_asc_ascq(un);
10974                 break;
10975 
10976         case KEY_BLANK_CHECK:
10977                 ST_DO_ERRSTATS(un, st_softerrs);
10978                 severity = SCSI_ERR_INFO;
10979 
10980                 /*
10981                  * if not a special request and some data was xferred then it
10982                  * it is not an error yet
10983                  */
10984                 if (bp != un->un_sbufp && (bp->b_flags & B_READ)) {
10985                         /*
10986                          * no error for read with or without data xferred
10987                          */
10988                         un->un_status = SUN_KEY_EOT;
10989                         pos->eof = ST_EOT;
10990                         rval = COMMAND_DONE_ERROR;
10991                         un->un_running.pmode = invalid;
10992                         st_set_pe_flag(un);
10993                         goto check_keys;
10994                 } else if (bp != un->un_sbufp &&
10995                     (pkt->pkt_state & STATE_XFERRED_DATA)) {
10996                         rval = COMMAND_DONE;
10997                 } else {
10998                         rval = COMMAND_DONE_ERROR_RECOVERED;
10999                 }
11000 
11001                 if (un->un_laststate >= ST_STATE_OPEN) {
11002                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11003                             "blank check\n");
11004                         pos->eof = ST_EOM;
11005                 }
11006                 if ((CDBP(pkt)->scc_cmd == SCMD_LOCATE) ||
11007                     (CDBP(pkt)->scc_cmd == SCMD_LOCATE_G4) ||
11008                     (CDBP(pkt)->scc_cmd == SCMD_SPACE) &&
11009                     (un->un_dp->options & ST_KNOWS_EOD)) {
11010                         /*
11011                          * we were doing a fast forward by skipping
11012                          * multiple fmk at the time
11013                          */
11014                         st_bioerror(bp, EIO);
11015                         severity = SCSI_ERR_RECOVERED;
11016                         rval     = COMMAND_DONE;
11017                 }
11018                 st_set_pe_flag(un);
11019                 goto check_keys;
11020 
11021         case KEY_WRITE_PROTECT:
11022                 if (st_wrongtapetype(un)) {
11023                         un->un_status = SUN_KEY_WRONGMEDIA;
11024                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11025                             "wrong tape for writing- use DC6150 tape "
11026                             "(or equivalent)\n");
11027                         severity = SCSI_ERR_UNKNOWN;
11028                 } else {
11029                         severity = SCSI_ERR_FATAL;
11030                 }
11031                 ST_DO_ERRSTATS(un, st_harderrs);
11032                 rval = COMMAND_DONE_ERROR;
11033                 st_bioerror(bp, EACCES);
11034                 break;
11035 
11036         case KEY_UNIT_ATTENTION:
11037                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11038                     "KEY_UNIT_ATTENTION : un_state = %d\n", un->un_state);
11039 
11040                 un->un_unit_attention_flags |= 1;
11041                 /*
11042                  * If we have detected a Bus Reset and the tape
11043                  * drive has been reserved.
11044                  */
11045                 if (ST_RQSENSE->es_add_code == 0x29) {
11046                         rval = DEVICE_RESET;
11047                         if ((un->un_rsvd_status &
11048                             (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
11049                             ST_RESERVE) {
11050                                 un->un_rsvd_status |= ST_LOST_RESERVE;
11051                                 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
11052                                     "st_decode_sense: Lost Reservation\n");
11053                         }
11054                 }
11055 
11056                 /*
11057                  * If this is a recovery command and retrable, retry.
11058                  */
11059                 if (bp == un->un_recov_buf) {
11060                         severity = SCSI_ERR_INFO;
11061                         if (attrib->retriable &&
11062                             ri->pkt_retry_cnt++ < st_retry_count) {
11063                                 rval = QUE_COMMAND;
11064                         } else {
11065                                 rval = COMMAND_DONE_ERROR;
11066                         }
11067                         break; /* Don't set position invalid */
11068                 }
11069 
11070                 /*
11071                  * If ST_APPLICATION_RESERVATIONS is set,
11072                  * If the asc/ascq indicates that the reservation
11073                  * has been cleared just allow the write to continue
11074                  * which would force a scsi 2 reserve.
11075                  * If preempted that persistent reservation
11076                  * the scsi 2 reserve would get a reservation conflict.
11077                  */
11078                 if ((un->un_rsvd_status &
11079                     ST_APPLICATION_RESERVATIONS) != 0) {
11080                         /*
11081                          * RESERVATIONS PREEMPTED
11082                          * With MPxIO this could be a fail over? XXX
11083                          */
11084                         if (ST_RQSENSE->es_add_code == 0x2a &&
11085                             ST_RQSENSE->es_qual_code == 0x03) {
11086                                 severity = SCSI_ERR_INFO;
11087                                 rval = COMMAND_DONE_ERROR;
11088                                 pos->pmode = invalid;
11089                                 break;
11090                         /*
11091                          * RESERVATIONS RELEASED
11092                          */
11093                         } else if (ST_RQSENSE->es_add_code == 0x2a &&
11094                             ST_RQSENSE->es_qual_code == 0x04) {
11095                                 severity = SCSI_ERR_INFO;
11096                                 rval = COMMAND_DONE;
11097                                 break;
11098                         }
11099                 }
11100 
11101                 if (un->un_state <= ST_STATE_OPENING) {
11102                         /*
11103                          * Look, the tape isn't open yet, now determine
11104                          * if the cause is a BUS RESET, Save the file
11105                          * and Block positions for the callers to
11106                          * recover from the loss of position.
11107                          */
11108                         severity = SCSI_ERR_INFO;
11109                         if ((pos->pmode != invalid) &&
11110                             (rval == DEVICE_RESET) &&
11111                             (un->un_restore_pos != 1)) {
11112                                 un->un_save_fileno = pos->fileno;
11113                                 un->un_save_blkno = pos->blkno;
11114                                 un->un_restore_pos = 1;
11115                         }
11116 
11117                         if (attrib->retriable &&
11118                             ri->pkt_retry_cnt++ < st_retry_count) {
11119                                 rval = QUE_COMMAND;
11120                         } else if (rval == DEVICE_RESET) {
11121                                 break;
11122                         } else {
11123                                 rval = COMMAND_DONE_ERROR;
11124                         }
11125                 /*
11126                  * Means it thinks the mode parameters have changed.
11127                  * This is the result of a reset clearing settings or
11128                  * another initiator changing what we set.
11129                  */
11130                 }
11131                 if (ST_RQSENSE->es_add_code == 0x2a) {
11132                         if (ST_RQSENSE->es_qual_code == 0x1) {
11133                                 /* Error recovery will modeselect and retry. */
11134                                 rval = DEVICE_TAMPER;
11135                                 severity = SCSI_ERR_INFO;
11136                                 break; /* don't set position invalid */
11137                         }
11138                         if (ST_RQSENSE->es_qual_code == 0x0 ||
11139                             ST_RQSENSE->es_qual_code == 0x2 ||
11140                             ST_RQSENSE->es_qual_code == 0x3 ||
11141                             ST_RQSENSE->es_qual_code == 0x4 ||
11142                             ST_RQSENSE->es_qual_code == 0x5 ||
11143                             ST_RQSENSE->es_qual_code == 0x6 ||
11144                             ST_RQSENSE->es_qual_code == 0x7) {
11145                                 rval = DEVICE_TAMPER;
11146                                 severity = SCSI_ERR_INFO;
11147                         }
11148                 } else if (ST_RQSENSE->es_add_code == 0x28 &&
11149                     ((ST_RQSENSE->es_qual_code == 0x0) ||
11150                     ST_RQSENSE->es_qual_code == 0x5)) {
11151                         /*
11152                          * Not Ready to Ready change, Media may have changed.
11153                          */
11154                         rval = DEVICE_TAMPER;
11155                         severity = SCSI_ERR_RETRYABLE;
11156                 } else {
11157                         if (rval != DEVICE_RESET) {
11158                                 rval = COMMAND_DONE_ERROR;
11159                         } else {
11160                                 /*
11161                                  * Returning DEVICE_RESET will call
11162                                  * error recovery.
11163                                  */
11164                                 severity = SCSI_ERR_INFO;
11165                                 break; /* don't set position invalid */
11166                         }
11167                         /*
11168                          * Check if it is an Unexpected Unit Attention.
11169                          * If state is >= ST_STATE_OPEN, we have
11170                          * already done the initialization .
11171                          * In this case it is Fatal Error
11172                          * since no further reading/writing
11173                          * can be done with fileno set to < 0.
11174                          */
11175                         if (un->un_state >= ST_STATE_OPEN) {
11176                                 ST_DO_ERRSTATS(un, st_harderrs);
11177                                 severity = SCSI_ERR_FATAL;
11178                         } else {
11179                                 severity = SCSI_ERR_INFO;
11180                         }
11181                 }
11182 
11183                 pos->pmode = invalid;
11184 
11185                 break;
11186 
11187         case KEY_NOT_READY:
11188                 /*
11189                  * If in process of getting ready retry.
11190                  */
11191                 if (sensep->es_add_code == 0x04) {
11192                         switch (sensep->es_qual_code) {
11193                         case 0x07:
11194                                 /*
11195                                  * We get here when the tape is rewinding.
11196                                  * QUE_BUSY_COMMAND retries every 10 seconds.
11197                                  */
11198                                 if (ri->pkt_retry_cnt++ <
11199                                     (un->un_dp->rewind_timeout / 10)) {
11200                                         rval = QUE_BUSY_COMMAND;
11201                                         severity = SCSI_ERR_INFO;
11202                                 } else {
11203                                         /* give up */
11204                                         rval = COMMAND_DONE_ERROR;
11205                                         severity = SCSI_ERR_FATAL;
11206                                 }
11207                                 break;
11208                         case 0x01:
11209                                 if (ri->pkt_retry_cnt++ < st_retry_count) {
11210                                         rval = QUE_COMMAND;
11211                                         severity = SCSI_ERR_INFO;
11212                                         break;
11213                                 }
11214                         default: /* FALLTHRU */
11215                                 /* give up */
11216                                 rval = COMMAND_DONE_ERROR;
11217                                 severity = SCSI_ERR_FATAL;
11218                         }
11219                 } else {
11220                         /* give up */
11221                         rval = COMMAND_DONE_ERROR;
11222                         severity = SCSI_ERR_FATAL;
11223                 }
11224 
11225                 /*
11226                  * If this was an error and after device opened
11227                  * do error stats.
11228                  */
11229                 if (rval == COMMAND_DONE_ERROR &&
11230                     un->un_state > ST_STATE_OPENING) {
11231                         ST_DO_ERRSTATS(un, st_harderrs);
11232                 }
11233 
11234                 if (ST_RQSENSE->es_add_code == 0x3a) {
11235                         if (st_error_level >= SCSI_ERR_FATAL)
11236                                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
11237                                     "Tape not inserted in drive\n");
11238                         un->un_mediastate = MTIO_EJECTED;
11239                         cv_broadcast(&un->un_state_cv);
11240                 }
11241                 if ((un->un_dp->options & ST_EJECT_ON_CHANGER_FAILURE) &&
11242                     (rval != QUE_COMMAND))
11243                         un->un_eject_tape_on_failure = st_check_asc_ascq(un);
11244                 break;
11245 
11246         case KEY_ABORTED_COMMAND:
11247                 /* XXX Do drives return this when they see a lost light? */
11248                 /* Testing would say yes */
11249 
11250                 if (ri->pkt_retry_cnt++ < st_retry_count) {
11251                         rval = ATTEMPT_RETRY;
11252                         severity = SCSI_ERR_RETRYABLE;
11253                         goto check_keys;
11254                 }
11255                 /*
11256                  * Probably a parity error...
11257                  * if we retry here then this may cause data to be
11258                  * written twice or data skipped during reading
11259                  */
11260                 ST_DO_ERRSTATS(un, st_harderrs);
11261                 severity = SCSI_ERR_FATAL;
11262                 rval = COMMAND_DONE_ERROR;
11263                 goto check_keys;
11264 
11265         default:
11266                 /*
11267                  * Undecoded sense key.  Try retries and hope
11268                  * that will fix the problem.  Otherwise, we're
11269                  * dead.
11270                  */
11271                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11272                     "Unhandled Sense Key '%s'\n",
11273                     sense_keys[un->un_status]);
11274                 ST_DO_ERRSTATS(un, st_harderrs);
11275                 severity = SCSI_ERR_FATAL;
11276                 rval = COMMAND_DONE_ERROR;
11277                 goto check_keys;
11278         }
11279 
11280         if ((!(pkt->pkt_flags & FLAG_SILENT) &&
11281             un->un_state >= ST_STATE_OPEN) && (DEBUGGING ||
11282             (un->un_laststate > ST_STATE_OPENING) &&
11283             (severity >= st_error_level))) {
11284 
11285                 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label, severity,
11286                     pos->lgclblkno, un->un_err_pos.lgclblkno,
11287                     scsi_cmds, sensep);
11288                 if (sensep->es_filmk) {
11289                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
11290                             "File Mark Detected\n");
11291                 }
11292                 if (sensep->es_eom) {
11293                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
11294                             "End-of-Media Detected\n");
11295                 }
11296                 if (sensep->es_ili) {
11297                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
11298                             "Incorrect Length Indicator Set\n");
11299                 }
11300         }
11301         get_error = geterror(bp);
11302         if (((rval == COMMAND_DONE_ERROR) ||
11303             (rval == COMMAND_DONE_ERROR_RECOVERED)) &&
11304             ((get_error == EIO) || (get_error == 0))) {
11305                 un->un_rqs_state |= (ST_RQS_ERROR | ST_RQS_VALID);
11306                 bcopy(ST_RQSENSE, un->un_uscsi_rqs_buf, SENSE_LENGTH);
11307                 if (un->un_rqs_state & ST_RQS_READ) {
11308                         un->un_rqs_state &= ~(ST_RQS_READ);
11309                 } else {
11310                         un->un_rqs_state |= ST_RQS_OVR;
11311                 }
11312         }
11313 
11314         return (rval);
11315 }
11316 
11317 
11318 static int
11319 st_handle_intr_retry_lcmd(struct scsi_tape *un, struct buf *bp)
11320 {
11321         int status = TRAN_ACCEPT;
11322         pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
11323 
11324         mutex_enter(ST_MUTEX);
11325 
11326         ST_FUNC(ST_DEVINFO, st_handle_intr_retry_lcmd);
11327 
11328         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
11329             "st_handle_intr_rtr_lcmd(), un = 0x%p\n", (void *)un);
11330 
11331         /*
11332          * Check to see if we hit the retry timeout. We check to make sure
11333          * this is the first one on the runq and make sure we have not
11334          * queued up any more, so this one has to be the last on the list
11335          * also. If it is not, we have to fail.  If it is not the first, but
11336          * is the last we are in trouble anyway, as we are in the interrupt
11337          * context here.
11338          */
11339         if ((pktinfo->pkt_retry_cnt > st_retry_count) ||
11340             ((un->un_runqf != bp) && (un->un_runql != bp))) {
11341                 goto exit;
11342         }
11343 
11344         if (un->un_throttle) {
11345                 un->un_last_throttle = un->un_throttle;
11346                 un->un_throttle = 0;
11347         }
11348 
11349         /*
11350          * Here we know : bp is the first and last one on the runq
11351          * it is not necessary to put it back on the head of the
11352          * waitq and then move from waitq to runq. Save this queuing
11353          * and call scsi_transport.
11354          */
11355         ST_CDB(ST_DEVINFO, "Retry lcmd CDB", (char *)BP_PKT(bp)->pkt_cdbp);
11356 
11357         status = st_transport(un, BP_PKT(bp));
11358 
11359         if (status == TRAN_ACCEPT) {
11360                 if (un->un_last_throttle) {
11361                         un->un_throttle = un->un_last_throttle;
11362                 }
11363                 mutex_exit(ST_MUTEX);
11364 
11365                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11366                     "restart transport \n");
11367                 return (0);
11368         }
11369 
11370         ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
11371         mutex_exit(ST_MUTEX);
11372 
11373         if (status == TRAN_BUSY) {
11374                 if (st_handle_intr_busy(un, bp, ST_TRAN_BUSY_TIMEOUT) == 0) {
11375                         return (0);
11376                 }
11377         }
11378         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11379             "restart transport rejected\n");
11380         mutex_enter(ST_MUTEX);
11381         ST_DO_ERRSTATS(un, st_transerrs);
11382         if (un->un_last_throttle) {
11383                 un->un_throttle = un->un_last_throttle;
11384         }
11385 exit:
11386         mutex_exit(ST_MUTEX);
11387         return (-1);
11388 }
11389 
11390 static int
11391 st_wrongtapetype(struct scsi_tape *un)
11392 {
11393 
11394         ST_FUNC(ST_DEVINFO, st_wrongtapetype);
11395 
11396         ASSERT(mutex_owned(ST_MUTEX));
11397 
11398         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_wrongtapetype()\n");
11399 
11400         /*
11401          * Hack to handle  600A, 600XTD, 6150 && 660 vs. 300XL tapes...
11402          */
11403         if (un->un_dp && (un->un_dp->options & ST_QIC) && un->un_mspl) {
11404                 switch (un->un_dp->type) {
11405                 case ST_TYPE_WANGTEK:
11406                 case ST_TYPE_ARCHIVE:
11407                         /*
11408                          * If this really worked, we could go off of
11409                          * the density codes set in the modesense
11410                          * page. For this drive, 0x10 == QIC-120,
11411                          * 0xf == QIC-150, and 0x5 should be for
11412                          * both QIC-24 and, maybe, QIC-11. However,
11413                          * the h/w doesn't do what the manual says
11414                          * that it should, so we'll key off of
11415                          * getting a WRITE PROTECT error AND wp *not*
11416                          * set in the mode sense information.
11417                          */
11418                         /*
11419                          * XXX but we already know that status is
11420                          * write protect, so don't check it again.
11421                          */
11422 
11423                         if (un->un_status == KEY_WRITE_PROTECT &&
11424                             un->un_mspl->wp == 0) {
11425                                 return (1);
11426                         }
11427                         break;
11428                 default:
11429                         break;
11430                 }
11431         }
11432         return (0);
11433 }
11434 
11435 static errstate
11436 st_check_error(struct scsi_tape *un, struct scsi_pkt *pkt)
11437 {
11438         errstate action;
11439         recov_info *rcvi = pkt->pkt_private;
11440         buf_t *bp = rcvi->cmd_bp;
11441         struct scsi_arq_status *stat = (struct scsi_arq_status *)pkt->pkt_scbp;
11442 
11443         ST_FUNC(ST_DEVINFO, st_check_error);
11444 
11445         ASSERT(mutex_owned(ST_MUTEX));
11446 
11447         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_check_error()\n");
11448 
11449         switch (SCBP_C(pkt)) {
11450         case STATUS_RESERVATION_CONFLICT:
11451                 /*
11452                  * Command recovery is enabled, not just opening,
11453                  * we had the drive reserved and we thing its ours.
11454                  * Call recovery to attempt to take it back.
11455                  */
11456                 if ((rcvi->privatelen == sizeof (recov_info)) &&
11457                     (bp != un->un_recov_buf) &&
11458                     (un->un_state > ST_STATE_OPEN_PENDING_IO) &&
11459                     ((un->un_rsvd_status & (ST_RESERVE |
11460                     ST_APPLICATION_RESERVATIONS)) != 0)) {
11461                         action = ATTEMPT_RETRY;
11462                         un->un_rsvd_status |= ST_LOST_RESERVE;
11463                 } else {
11464                         action = COMMAND_DONE_EACCES;
11465                         un->un_rsvd_status |= ST_RESERVATION_CONFLICT;
11466                 }
11467                 break;
11468 
11469         case STATUS_BUSY:
11470                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG, "unit busy\n");
11471                 if (rcvi->privatelen == sizeof (recov_info) &&
11472                     un->un_multipath && (pkt->pkt_state == (STATE_GOT_BUS |
11473                     STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS))) {
11474                         /*
11475                          * Status returned by scsi_vhci indicating path
11476                          * has failed over.
11477                          */
11478                         action = PATH_FAILED;
11479                         break;
11480                 }
11481                 /* FALLTHRU */
11482         case STATUS_QFULL:
11483                 if (rcvi->privatelen == sizeof (recov_info)) {
11484                         /*
11485                          * If recovery is inabled use it instead of
11486                          * blind reties.
11487                          */
11488                         action = ATTEMPT_RETRY;
11489                 } else if (rcvi->pkt_retry_cnt++ < st_retry_count) {
11490                         action = QUE_BUSY_COMMAND;
11491                 } else if ((un->un_rsvd_status &
11492                     (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
11493                         /*
11494                          * If this is a command done before reserve is done
11495                          * don't reset.
11496                          */
11497                         action = COMMAND_DONE_ERROR;
11498                 } else {
11499                         ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11500                             "unit busy too long\n");
11501                         (void) st_reset(un, RESET_ALL);
11502                         action = COMMAND_DONE_ERROR;
11503                 }
11504                 break;
11505 
11506         case STATUS_CHECK:
11507         case STATUS_TERMINATED:
11508                 /*
11509                  * we should only get here if the auto rqsense failed
11510                  * thru a uscsi cmd without autorequest sense
11511                  * so we just try again
11512                  */
11513                 if (un->un_arq_enabled &&
11514                     stat->sts_rqpkt_reason == CMD_CMPLT &&
11515                     (stat->sts_rqpkt_state & (STATE_GOT_BUS |
11516                     STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS)) ==
11517                     (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
11518                     STATE_GOT_STATUS)) {
11519 
11520                         ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11521                             "Really got sense data\n");
11522                         action = st_decode_sense(un, bp, MAX_SENSE_LENGTH -
11523                             pkt->pkt_resid, stat, &un->un_pos);
11524                 } else {
11525                         ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11526                             "Trying to queue sense command\n");
11527                         action = QUE_SENSE;
11528                 }
11529                 break;
11530 
11531         case STATUS_TASK_ABORT:
11532                 /*
11533                  * This is an aborted task. This can be a reset on the other
11534                  * port of a multiport drive. Lets try and recover it.
11535                  */
11536                 action = DEVICE_RESET;
11537                 break;
11538 
11539         default:
11540                 action = COMMAND_DONE;
11541                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
11542                     "Unexpected scsi status byte 0x%x\n", SCBP_C(pkt));
11543         }
11544         return (action);
11545 }
11546 
11547 static void
11548 st_calc_bnum(struct scsi_tape *un, struct buf *bp, struct scsi_pkt *pkt)
11549 {
11550         int nblks;
11551         int nfiles;
11552         long count;
11553         recov_info *ri = pkt->pkt_private;
11554         cmd_attribute const *attrib;
11555 
11556         ST_FUNC(ST_DEVINFO, st_calc_bnum);
11557 
11558         ASSERT(mutex_owned(ST_MUTEX));
11559 
11560         if (ri->privatelen == sizeof (recov_info)) {
11561                 attrib = ri->cmd_attrib;
11562                 ASSERT(attrib->recov_pos_type == POS_EXPECTED);
11563                 ASSERT(attrib->chg_tape_pos);
11564         } else {
11565                 ri = NULL;
11566                 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
11567         }
11568 
11569         count = bp->b_bcount - bp->b_resid;
11570 
11571         /* Command reads or writes data */
11572         if (attrib->transfers_data != TRAN_NONE) {
11573                 if (count == 0) {
11574                         if (attrib->transfers_data == TRAN_WRTE) {
11575                                 ASSERT(un->un_pos.eof == ST_EOM);
11576                                 nblks = 0;
11577                                 nfiles = 0;
11578                         } else {
11579                                 ASSERT(un->un_pos.eof == ST_EOF_PENDING);
11580                                 nblks = 0;
11581                                 nfiles = 1;
11582                         }
11583                 } else if (un->un_bsize == 0) {
11584                         /*
11585                          * If variable block mode.
11586                          * Fixed bit in CBD should be zero.
11587                          */
11588                         ASSERT((pkt->pkt_cdbp[1] & 1) == 0);
11589                         nblks = 1;
11590                         un->un_kbytes_xferred += (count / ONE_K);
11591                         nfiles = 0;
11592                 } else {
11593                         /*
11594                          * If fixed block mode.
11595                          * Fixed bit in CBD should be one.
11596                          */
11597                         ASSERT((pkt->pkt_cdbp[1] & 1) == 1);
11598                         nblks = (count / un->un_bsize);
11599                         un->un_kbytes_xferred += (nblks * un->un_bsize) / ONE_K;
11600                         nfiles = 0;
11601                 }
11602                 /*
11603                  * So its possable to read some blocks and hit a filemark.
11604                  * Example reading in fixed block mode where more then one
11605                  * block at a time is requested. In this case because the
11606                  * filemark is hit something less then the requesed number
11607                  * of blocks is read.
11608                  */
11609                 if (un->un_pos.eof == ST_EOF_PENDING && bp->b_resid) {
11610                         nfiles = 1;
11611                 }
11612         } else {
11613                 nblks = 0;
11614                 nfiles = count;
11615         }
11616 
11617         /*
11618          * If some command failed after this one started and it seems
11619          * to have finshed without error count the position.
11620          */
11621         if (un->un_persistence && un->un_persist_errors) {
11622                 ASSERT(un->un_pos.pmode != invalid);
11623         }
11624 
11625         if (attrib->chg_tape_direction == DIR_FORW) {
11626                 un->un_pos.blkno += nblks;
11627                 un->un_pos.lgclblkno += nblks;
11628                 un->un_pos.lgclblkno += nfiles;
11629         } else if (attrib->chg_tape_direction == DIR_REVC) {
11630                 un->un_pos.blkno -= nblks;
11631                 un->un_pos.lgclblkno -= nblks;
11632                 un->un_pos.lgclblkno -= nfiles;
11633         } else {
11634                 ASSERT(0);
11635         }
11636 
11637         /* recovery disabled */
11638         if (ri == NULL) {
11639                 un->un_running.pmode = invalid;
11640                 return;
11641         }
11642 
11643         /*
11644          * If we didn't just read a filemark.
11645          */
11646         if (un->un_pos.eof != ST_EOF_PENDING) {
11647                 ASSERT(nblks != 0 && nfiles == 0);
11648                 /*
11649                  * If Previously calulated expected position does not match
11650                  * debug the expected position.
11651                  */
11652                 if ((ri->pos.pmode != invalid) && nblks &&
11653                     ((un->un_pos.blkno != ri->pos.blkno) ||
11654                     (un->un_pos.lgclblkno != ri->pos.lgclblkno))) {
11655 #ifdef STDEBUG
11656                         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
11657                             "Expected", &ri->pos);
11658                         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
11659                             "But Got", &un->un_pos);
11660 #endif
11661                         un->un_running.pmode = invalid;
11662                 }
11663         } else {
11664                 ASSERT(nfiles != 0);
11665                 if (un->un_running.pmode != invalid) {
11666                         /*
11667                          * blkno and lgclblkno already counted in
11668                          * st_add_recovery_info_to_pkt(). Since a block was not
11669                          * read and a filemark was.
11670                          */
11671                         if (attrib->chg_tape_direction == DIR_FORW) {
11672                                 un->un_running.fileno++;
11673                                 un->un_running.blkno = 0;
11674                         } else if (attrib->chg_tape_direction == DIR_REVC) {
11675                                 un->un_running.fileno--;
11676                                 un->un_running.blkno = LASTBLK;
11677                         }
11678                 }
11679         }
11680 }
11681 
11682 static void
11683 st_set_state(struct scsi_tape *un, struct buf *bp)
11684 {
11685         struct scsi_pkt *sp = BP_PKT(bp);
11686         struct uscsi_cmd *ucmd;
11687 
11688         ST_FUNC(ST_DEVINFO, st_set_state);
11689 
11690         ASSERT(mutex_owned(ST_MUTEX));
11691         ASSERT(bp != un->un_recov_buf);
11692 
11693         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
11694             "st_set_state(): eof=%x     fmneeded=%x  pkt_resid=0x%lx (%ld)\n",
11695             un->un_pos.eof, un->un_fmneeded, sp->pkt_resid, sp->pkt_resid);
11696 
11697         if (bp != un->un_sbufp) {
11698 #ifdef STDEBUG
11699                 if (DEBUGGING && sp->pkt_resid) {
11700                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11701                             "pkt_resid %ld bcount %ld\n",
11702                             sp->pkt_resid, bp->b_bcount);
11703                 }
11704 #endif
11705                 bp->b_resid = sp->pkt_resid;
11706                 if (geterror(bp) != EIO) {
11707                         st_calc_bnum(un, bp, sp);
11708                 }
11709                 if (bp->b_flags & B_READ) {
11710                         un->un_lastop = ST_OP_READ;
11711                         un->un_fmneeded = 0;
11712                 } else {
11713                         un->un_lastop = ST_OP_WRITE;
11714                         if (un->un_dp->options & ST_REEL) {
11715                                 un->un_fmneeded = 2;
11716                         } else {
11717                                 un->un_fmneeded = 1;
11718                         }
11719                 }
11720                 /*
11721                  * all is honky dory at this point, so let's
11722                  * readjust the throttle, to increase speed, if we
11723                  * have not throttled down.
11724                  */
11725                 if (un->un_throttle) {
11726                         un->un_throttle = un->un_max_throttle;
11727                 }
11728         } else {
11729                 optype new_lastop = ST_OP_NIL;
11730                 uchar_t cmd = (uchar_t)(intptr_t)bp->b_forw;
11731 
11732                 switch (cmd) {
11733                 case SCMD_WRITE:
11734                 case SCMD_WRITE_G4:
11735                         bp->b_resid = sp->pkt_resid;
11736                         new_lastop = ST_OP_WRITE;
11737                         if (geterror(bp) == EIO) {
11738                                 break;
11739                         }
11740                         st_calc_bnum(un, bp, sp);
11741                         if (un->un_dp->options & ST_REEL) {
11742                                 un->un_fmneeded = 2;
11743                         } else {
11744                                 un->un_fmneeded = 1;
11745                         }
11746                         break;
11747                 case SCMD_READ:
11748                 case SCMD_READ_G4:
11749                         bp->b_resid = sp->pkt_resid;
11750                         new_lastop = ST_OP_READ;
11751                         un->un_lastop = ST_OP_READ;
11752                         if (geterror(bp) == EIO) {
11753                                 break;
11754                         }
11755                         st_calc_bnum(un, bp, sp);
11756                         un->un_fmneeded = 0;
11757                         break;
11758                 case SCMD_WRITE_FILE_MARK_G4:
11759                 case SCMD_WRITE_FILE_MARK:
11760                 {
11761                         int fmdone;
11762 
11763                         if (un->un_pos.eof != ST_EOM) {
11764                                 un->un_pos.eof = ST_NO_EOF;
11765                         }
11766                         fmdone = (bp->b_bcount - bp->b_resid);
11767                         if (fmdone > 0) {
11768                                 un->un_lastop = new_lastop = ST_OP_WEOF;
11769                                 un->un_pos.lgclblkno += fmdone;
11770                                 un->un_pos.fileno += fmdone;
11771                                 un->un_pos.blkno = 0;
11772                         } else {
11773                                 new_lastop = ST_OP_CTL;
11774                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
11775                                     "Flushed buffer\n");
11776                         }
11777                         if (fmdone > un->un_fmneeded) {
11778                                 un->un_fmneeded = 0;
11779                         } else {
11780                                 un->un_fmneeded -= fmdone;
11781                         }
11782                         break;
11783                 }
11784                 case SCMD_REWIND:
11785                         un->un_pos.eof = ST_NO_EOF;
11786                         un->un_pos.fileno = 0;
11787                         un->un_pos.blkno = 0;
11788                         un->un_pos.lgclblkno = 0;
11789                         if (un->un_pos.pmode != legacy)
11790                                 un->un_pos.pmode = legacy;
11791                         new_lastop = ST_OP_CTL;
11792                         un->un_restore_pos = 0;
11793                         break;
11794 
11795                 case SCMD_SPACE:
11796                 case SCMD_SPACE_G4:
11797                 {
11798                         int64_t count;
11799                         int64_t resid;
11800                         int64_t done;
11801                         cmd_attribute const *attrib;
11802                         recov_info *ri = sp->pkt_private;
11803 
11804                         if (ri->privatelen == sizeof (recov_info)) {
11805                                 attrib = ri->cmd_attrib;
11806                         } else {
11807                                 attrib =
11808                                     st_lookup_cmd_attribute(sp->pkt_cdbp[0]);
11809                         }
11810 
11811                         resid = (int64_t)SPACE_CNT(bp->b_resid);
11812                         count = (int64_t)attrib->get_cnt(sp->pkt_cdbp);
11813 
11814                         if (count >= 0) {
11815                                 done = (count - resid);
11816                         } else {
11817                                 done = ((-count) - resid);
11818                         }
11819                         if (done > 0) {
11820                                 un->un_lastop = new_lastop = ST_OP_CTL;
11821                         } else {
11822                                 new_lastop = ST_OP_CTL;
11823                         }
11824 
11825                         ST_SPAC(ST_DEVINFO, st_label, CE_WARN,
11826                             "space cmd: cdb[1] = %s\n"
11827                             "space data:       = 0x%lx\n"
11828                             "space count:      = %"PRId64"\n"
11829                             "space resid:      = %"PRId64"\n"
11830                             "spaces done:      = %"PRId64"\n"
11831                             "fileno before     = %d\n"
11832                             "blkno before      = %d\n",
11833                             space_strs[sp->pkt_cdbp[1] & 7],
11834                             bp->b_bcount,
11835                             count, resid, done,
11836                             un->un_pos.fileno, un->un_pos.blkno);
11837 
11838                         switch (sp->pkt_cdbp[1]) {
11839                         case SPACE_TYPE(SP_FLM):
11840                                 /* Space file forward */
11841                                 if (count >= 0) {
11842                                         if (un->un_pos.eof <= ST_EOF) {
11843                                                 un->un_pos.eof = ST_NO_EOF;
11844                                         }
11845                                         un->un_pos.fileno += done;
11846                                         un->un_pos.blkno = 0;
11847                                         break;
11848                                 }
11849                                 /* Space file backward */
11850                                 if (done > un->un_pos.fileno) {
11851                                         un->un_pos.fileno = 0;
11852                                         un->un_pos.blkno = 0;
11853                                 } else {
11854                                         un->un_pos.fileno -= done;
11855                                         un->un_pos.blkno = LASTBLK;
11856                                         un->un_running.pmode = invalid;
11857                                 }
11858                                 break;
11859                         case SPACE_TYPE(SP_BLK):
11860                                 /* Space block forward */
11861                                 if (count >= 0) {
11862                                         un->un_pos.blkno += done;
11863                                         break;
11864                                 }
11865                                 /* Space block backward */
11866                                 if (un->un_pos.eof >= ST_EOF_PENDING) {
11867                                 /*
11868                                  * we stepped back into
11869                                  * a previous file; we are not
11870                                  * making an effort to pretend that
11871                                  * we are still in the current file
11872                                  * ie. logical == physical position
11873                                  * and leave it to st_ioctl to correct
11874                                  */
11875                                         if (done > un->un_pos.blkno) {
11876                                                 un->un_pos.blkno = 0;
11877                                         } else {
11878                                                 un->un_pos.fileno--;
11879                                                 un->un_pos.blkno = LASTBLK;
11880                                                 un->un_running.pmode = invalid;
11881                                         }
11882                                 } else {
11883                                         un->un_pos.blkno -= done;
11884                                 }
11885                                 break;
11886                         case SPACE_TYPE(SP_SQFLM):
11887                                 un->un_pos.pmode = logical;
11888                                 un->un_pos.blkno = 0;
11889                                 un->un_lastop = new_lastop = ST_OP_CTL;
11890                                 break;
11891                         case SPACE_TYPE(SP_EOD):
11892                                 un->un_pos.pmode = logical;
11893                                 un->un_pos.eof = ST_EOM;
11894                                 un->un_status = KEY_BLANK_CHECK;
11895                                 break;
11896                         default:
11897                                 un->un_pos.pmode = invalid;
11898                                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
11899                                     "Unsupported space cmd: %s\n",
11900                                     space_strs[sp->pkt_cdbp[1] & 7]);
11901 
11902                                 un->un_lastop = new_lastop = ST_OP_CTL;
11903                         }
11904 
11905                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11906                             "after_space rs %"PRId64" fil %d blk %d\n",
11907                             resid, un->un_pos.fileno, un->un_pos.blkno);
11908 
11909                         break;
11910                 }
11911                 case SCMD_LOAD:
11912                         if ((bp->b_bcount & (LD_LOAD | LD_EOT)) == LD_LOAD) {
11913                                 un->un_pos.fileno = 0;
11914                                 if (un->un_pos.pmode != legacy)
11915                                         un->un_pos.pmode = legacy;
11916                         } else {
11917                                 un->un_state = ST_STATE_OFFLINE;
11918                                 un->un_pos.pmode = invalid;
11919 
11920                         }
11921                         /*
11922                          * If we are loading or unloading we expect the media id
11923                          * to change. Lets make it unknown.
11924                          */
11925                         if (un->un_media_id != bogusID && un->un_media_id_len) {
11926                                 kmem_free(un->un_media_id, un->un_media_id_len);
11927                                 un->un_media_id = NULL;
11928                                 un->un_media_id_len = 0;
11929                         }
11930                         un->un_density_known = 0;
11931                         un->un_pos.eof = ST_NO_EOF;
11932                         un->un_pos.blkno = 0;
11933                         un->un_lastop = new_lastop = ST_OP_CTL;
11934                         break;
11935                 case SCMD_ERASE:
11936                         un->un_pos.eof = ST_NO_EOF;
11937                         un->un_pos.blkno = 0;
11938                         un->un_pos.fileno = 0;
11939                         un->un_pos.lgclblkno = 0;
11940                         if (un->un_pos.pmode != legacy)
11941                                 un->un_pos.pmode = legacy;
11942                         new_lastop = ST_OP_CTL;
11943                         break;
11944                 case SCMD_RESERVE:
11945                         un->un_rsvd_status |= ST_RESERVE;
11946                         un->un_rsvd_status &=
11947                             ~(ST_RELEASE | ST_LOST_RESERVE |
11948                             ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
11949                         new_lastop = ST_OP_CTL;
11950                         break;
11951                 case SCMD_RELEASE:
11952                         un->un_rsvd_status |= ST_RELEASE;
11953                         un->un_rsvd_status &=
11954                             ~(ST_RESERVE | ST_LOST_RESERVE |
11955                             ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
11956                         new_lastop = ST_OP_CTL;
11957                         break;
11958                 case SCMD_PERSISTENT_RESERVE_IN:
11959                         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11960                             "PGR_IN command\n");
11961                         new_lastop = ST_OP_CTL;
11962                         break;
11963                 case SCMD_PERSISTENT_RESERVE_OUT:
11964                         switch (sp->pkt_cdbp[1] & ST_SA_MASK) {
11965                         case ST_SA_SCSI3_RESERVE:
11966                         case ST_SA_SCSI3_PREEMPT:
11967                         case ST_SA_SCSI3_PREEMPTANDABORT:
11968                                 un->un_rsvd_status |=
11969                                     (ST_APPLICATION_RESERVATIONS | ST_RESERVE);
11970                                 un->un_rsvd_status &= ~(ST_RELEASE |
11971                                     ST_LOST_RESERVE | ST_RESERVATION_CONFLICT |
11972                                     ST_INITIATED_RESET);
11973                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11974                                     "PGR Reserve and set: entering"
11975                                     " ST_APPLICATION_RESERVATIONS mode");
11976                                 break;
11977                         case ST_SA_SCSI3_REGISTER:
11978                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11979                                     "PGR Reserve register key");
11980                                 un->un_rsvd_status |= ST_INIT_RESERVE;
11981                                 break;
11982                         case ST_SA_SCSI3_CLEAR:
11983                                 un->un_rsvd_status &= ~ST_INIT_RESERVE;
11984                                 /* FALLTHROUGH */
11985                         case ST_SA_SCSI3_RELEASE:
11986                                 un->un_rsvd_status &=
11987                                     ~(ST_APPLICATION_RESERVATIONS | ST_RESERVE |
11988                                     ST_LOST_RESERVE | ST_RESERVATION_CONFLICT |
11989                                     ST_INITIATED_RESET);
11990                                 un->un_rsvd_status |= ST_RELEASE;
11991                                 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11992                                     "PGR Release and reset: exiting"
11993                                     " ST_APPLICATION_RESERVATIONS mode");
11994                                 break;
11995                         }
11996                         new_lastop = ST_OP_CTL;
11997                         break;
11998                 case SCMD_TEST_UNIT_READY:
11999                 case SCMD_READ_BLKLIM:
12000                 case SCMD_REQUEST_SENSE:
12001                 case SCMD_INQUIRY:
12002                 case SCMD_RECOVER_BUF:
12003                 case SCMD_MODE_SELECT:
12004                 case SCMD_MODE_SENSE:
12005                 case SCMD_DOORLOCK:
12006                 case SCMD_READ_BUFFER:
12007                 case SCMD_REPORT_DENSITIES:
12008                 case SCMD_LOG_SELECT_G1:
12009                 case SCMD_LOG_SENSE_G1:
12010                 case SCMD_REPORT_LUNS:
12011                 case SCMD_READ_ATTRIBUTE:
12012                 case SCMD_WRITE_ATTRIBUTE:
12013                 case SCMD_SVC_ACTION_IN_G5:
12014                 case SCMD_SECURITY_PROTO_IN:
12015                 case SCMD_SECURITY_PROTO_OUT:
12016                         new_lastop = ST_OP_CTL;
12017                         break;
12018                 case SCMD_READ_POSITION:
12019                         new_lastop = ST_OP_CTL;
12020                         /*
12021                          * Only if the buf used was un_sbufp.
12022                          * Among other things the prevents read positions used
12023                          * as part of error recovery from messing up our
12024                          * current position as they will use un_recov_buf.
12025                          */
12026                         if (USCSI_CMD(bp)) {
12027                                 (void) st_get_read_pos(un, bp);
12028                         }
12029                         break;
12030                 case SCMD_LOCATE:
12031                 case SCMD_LOCATE_G4:
12032                         /* Locate makes position mode no longer legacy */
12033                         un->un_lastop = new_lastop = ST_OP_CTL;
12034                         break;
12035                 case SCMD_MAINTENANCE_IN:
12036                         switch (sp->pkt_cdbp[1]) {
12037                         case SSVC_ACTION_GET_SUPPORTED_OPERATIONS:
12038                         case SSVC_ACTION_SET_TARGET_PORT_GROUPS:
12039                                 new_lastop = ST_OP_CTL;
12040                                 break;
12041                         }
12042                         if (new_lastop != ST_OP_NIL) {
12043                                 break;
12044                         }
12045                 default:
12046                         /*
12047                          * Unknown command, If was USCSI and USCSI_SILENT
12048                          * flag was not set, set position to unknown.
12049                          */
12050                         if ((((ucmd = BP_UCMD(bp)) != NULL) &&
12051                             (ucmd->uscsi_flags & USCSI_SILENT) == 0)) {
12052                                 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
12053                                     "unknown cmd 0x%X caused loss of state\n",
12054                                     cmd);
12055                         } else {
12056                                 /*
12057                                  * keep the old agreement to allow unknown
12058                                  * commands with the USCSI_SILENT set.
12059                                  * This prevents ASSERT below.
12060                                  */
12061                                 new_lastop = ST_OP_CTL;
12062                                 break;
12063                         }
12064                         /* FALLTHROUGH */
12065                 case SCMD_WRITE_BUFFER: /* Writes new firmware to device */
12066                         un->un_pos.pmode = invalid;
12067                         un->un_lastop = new_lastop = ST_OP_CTL;
12068                         break;
12069                 }
12070 
12071                 /* new_lastop should have been changed */
12072                 ASSERT(new_lastop != ST_OP_NIL);
12073 
12074                 /* If un_lastop should copy new_lastop  */
12075                 if (((un->un_lastop == ST_OP_WRITE) ||
12076                     (un->un_lastop == ST_OP_WEOF)) &&
12077                     new_lastop != ST_OP_CTL) {
12078                         un->un_lastop = new_lastop;
12079                 }
12080         }
12081 
12082         /*
12083          * In the st driver we have a logical and physical file position.
12084          * Under BSD behavior, when you get a zero read, the logical position
12085          * is before the filemark but after the last record of the file.
12086          * The physical position is after the filemark. MTIOCGET should always
12087          * return the logical file position.
12088          *
12089          * The next read gives a silent skip to the next file.
12090          * Under SVR4, the logical file position remains before the filemark
12091          * until the file is closed or a space operation is performed.
12092          * Hence set err_resid and err_file before changing fileno if case
12093          * BSD Behaviour.
12094          */
12095         un->un_err_resid = bp->b_resid;
12096         COPY_POS(&un->un_err_pos, &un->un_pos);
12097 
12098 
12099         /*
12100          * If we've seen a filemark via the last read operation
12101          * advance the file counter, but mark things such that
12102          * the next read operation gets a zero count. We have
12103          * to put this here to handle the case of sitting right
12104          * at the end of a tape file having seen the file mark,
12105          * but the tape is closed and then re-opened without
12106          * any further i/o. That is, the position information
12107          * must be updated before a close.
12108          */
12109 
12110         if (un->un_lastop == ST_OP_READ && un->un_pos.eof == ST_EOF_PENDING) {
12111                 /*
12112                  * If we're a 1/2" tape, and we get a filemark
12113                  * right on block 0, *AND* we were not in the
12114                  * first file on the tape, and we've hit logical EOM.
12115                  * We'll mark the state so that later we do the
12116                  * right thing (in st_close(), st_strategy() or
12117                  * st_ioctl()).
12118                  *
12119                  */
12120                 if ((un->un_dp->options & ST_REEL) &&
12121                     !(un->un_dp->options & ST_READ_IGNORE_EOFS) &&
12122                     un->un_pos.blkno == 0 && un->un_pos.fileno > 0) {
12123                         un->un_pos.eof = ST_EOT_PENDING;
12124                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12125                             "eot pending\n");
12126                         un->un_pos.fileno++;
12127                         un->un_pos.blkno = 0;
12128                 } else if (BP_UCMD(bp)) {
12129                         /*
12130                          * Uscsi reads have no concept of Berkley ver System IV.
12131                          * Counts here must match raw device.
12132                          * A non-full resid implies fix block mode where an
12133                          * attempt to read X blocks resulted in less then X.
12134                          */
12135                         if (bp->b_resid != bp->b_bcount) {
12136                                 un->un_pos.eof = ST_EOF;
12137                         } else {
12138                                 /* Read over a file mark */
12139                                 un->un_pos.fileno++;
12140                                 /* logical block is counted up elsewhere */
12141                                 /* we're before the first block in next file */
12142                                 un->un_pos.blkno = 0;
12143                                 /* EOF is no longer pending */
12144                                 un->un_pos.eof = ST_NO_EOF;
12145                         }
12146                 } else if (BSD_BEHAVIOR) {
12147                         /*
12148                          * If the read of the filemark was a side effect
12149                          * of reading some blocks (i.e., data was actually
12150                          * read), then the EOF mark is pending and the
12151                          * bump into the next file awaits the next read
12152                          * operation (which will return a zero count), or
12153                          * a close or a space operation, else the bump
12154                          * into the next file occurs now.
12155                          */
12156                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12157                             "resid=%lx, bcount=%lx\n",
12158                             bp->b_resid, bp->b_bcount);
12159 
12160                         if (bp->b_resid != bp->b_bcount) {
12161                                 un->un_pos.eof = ST_EOF;
12162                         } else {
12163                                 un->un_silent_skip = 1;
12164                                 un->un_pos.eof = ST_NO_EOF;
12165                                 un->un_pos.fileno++;
12166                                 un->un_pos.lgclblkno++;
12167                                 un->un_save_blkno = un->un_pos.blkno;
12168                                 un->un_pos.blkno = 0;
12169                         }
12170                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12171                             "eof of file %d, eof=%d\n",
12172                             un->un_pos.fileno, un->un_pos.eof);
12173                 } else if (SVR4_BEHAVIOR) {
12174                         /*
12175                          * If the read of the filemark was a side effect
12176                          * of reading some blocks (i.e., data was actually
12177                          * read), then the next read should return 0
12178                          */
12179                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12180                             "resid=%lx, bcount=%lx\n",
12181                             bp->b_resid, bp->b_bcount);
12182                         if (bp->b_resid == bp->b_bcount) {
12183                                 un->un_pos.eof = ST_EOF;
12184                         }
12185                         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12186                             "eof of file=%d, eof=%d\n",
12187                             un->un_pos.fileno, un->un_pos.eof);
12188                 }
12189         }
12190 }
12191 
12192 /*
12193  * set the correct un_errno, to take corner cases into consideration
12194  */
12195 static void
12196 st_set_pe_errno(struct scsi_tape *un)
12197 {
12198         ST_FUNC(ST_DEVINFO, st_set_pe_errno);
12199 
12200         ASSERT(mutex_owned(ST_MUTEX));
12201 
12202         /* if errno is already set, don't reset it */
12203         if (un->un_errno)
12204                 return;
12205 
12206         /* here un_errno == 0 */
12207         /*
12208          * if the last transfer before flushing all the
12209          * waiting I/O's, was 0 (resid = count), then we
12210          * want to give the user an error on all the rest,
12211          * so here.  If there was a transfer, we set the
12212          * resid and counts to 0, and let it drop through,
12213          * giving a zero return.  the next I/O will then
12214          * give an error.
12215          */
12216         if (un->un_last_resid == un->un_last_count) {
12217                 switch (un->un_pos.eof) {
12218                 case ST_EOM:
12219                         un->un_errno = ENOMEM;
12220                         break;
12221                 case ST_EOT:
12222                 case ST_EOF:
12223                         un->un_errno = EIO;
12224                         break;
12225                 }
12226         } else {
12227                 /*
12228                  * we know they did not have a zero, so make
12229                  * sure they get one
12230                  */
12231                 un->un_last_resid = un->un_last_count = 0;
12232         }
12233 }
12234 
12235 
12236 /*
12237  * send in a marker pkt to terminate flushing of commands by BBA (via
12238  * flush-on-errors) property.  The HBA will always return TRAN_ACCEPT
12239  */
12240 static void
12241 st_hba_unflush(struct scsi_tape *un)
12242 {
12243         ST_FUNC(ST_DEVINFO, st_hba_unflush);
12244 
12245         ASSERT(mutex_owned(ST_MUTEX));
12246 
12247         if (!un->un_flush_on_errors)
12248                 return;
12249 
12250 #ifdef FLUSH_ON_ERRORS
12251 
12252         if (!un->un_mkr_pkt) {
12253                 un->un_mkr_pkt = scsi_init_pkt(ROUTE, NULL, (struct buf *)NULL,
12254                     NULL, 0, 0, 0, SLEEP_FUNC, NULL);
12255 
12256                 /* we slept, so it must be there */
12257                 pkt->pkt_flags |= FLAG_FLUSH_MARKER;
12258         }
12259 
12260         st_transport(un, un->un_mkr_pkt);
12261 #endif
12262 }
12263 
12264 static char *
12265 st_print_scsi_cmd(char cmd)
12266 {
12267         char tmp[64];
12268         char *cpnt;
12269 
12270         cpnt = scsi_cmd_name(cmd, scsi_cmds, tmp);
12271         /* tmp goes out of scope on return and caller sees garbage */
12272         if (cpnt == tmp) {
12273                 cpnt = "Unknown Command";
12274         }
12275         return (cpnt);
12276 }
12277 
12278 static void
12279 st_print_cdb(dev_info_t *dip, char *label, uint_t level,
12280     char *title, char *cdb)
12281 {
12282         int len = scsi_cdb_size[CDB_GROUPID(cdb[0])];
12283         char buf[256];
12284         struct scsi_tape *un;
12285         int instance = ddi_get_instance(dip);
12286 
12287         un = ddi_get_soft_state(st_state, instance);
12288 
12289         ST_FUNC(dip, st_print_cdb);
12290 
12291         /* force one line output so repeated commands are printed once */
12292         if ((st_debug & 0x180) == 0x100) {
12293                 scsi_log(dip, label, level, "node %s cmd %s\n",
12294                     st_dev_name(un->un_dev), st_print_scsi_cmd(*cdb));
12295                 return;
12296         }
12297 
12298         /* force one line output so repeated CDB's are printed once */
12299         if ((st_debug & 0x180) == 0x80) {
12300                 st_clean_print(dip, label, level, NULL, cdb, len);
12301         } else {
12302                 (void) sprintf(buf, "%s for cmd(%s)", title,
12303                     st_print_scsi_cmd(*cdb));
12304                 st_clean_print(dip, label, level, buf, cdb, len);
12305         }
12306 }
12307 
12308 static void
12309 st_clean_print(dev_info_t *dev, char *label, uint_t level,
12310     char *title, char *data, int len)
12311 {
12312         int     i;
12313         int     c;
12314         char    *format;
12315         char    buf[256];
12316         uchar_t byte;
12317 
12318         ST_FUNC(dev, st_clean_print);
12319 
12320 
12321         if (title) {
12322                 (void) sprintf(buf, "%s:\n", title);
12323                 scsi_log(dev, label, level, "%s", buf);
12324                 level = CE_CONT;
12325         }
12326 
12327         for (i = 0; i < len; ) {
12328                 buf[0] = 0;
12329                 for (c = 0; c < 8 && i < len; c++, i++) {
12330                         byte = (uchar_t)data[i];
12331                         if (byte < 0x10)
12332                                 format = "0x0%x ";
12333                         else
12334                                 format = "0x%x ";
12335                         (void) sprintf(&buf[(int)strlen(buf)], format, byte);
12336                 }
12337                 (void) sprintf(&buf[(int)strlen(buf)], "\n");
12338 
12339                 scsi_log(dev, label, level, "%s\n", buf);
12340                 level = CE_CONT;
12341         }
12342 }
12343 
12344 /*
12345  * Conditionally enabled debugging
12346  */
12347 #ifdef  STDEBUG
12348 static void
12349 st_debug_cmds(struct scsi_tape *un, int com, int count, int wait)
12350 {
12351         char tmpbuf[64];
12352 
12353         ST_FUNC(ST_DEVINFO, st_debug_cmds);
12354 
12355         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12356             "cmd=%s count=0x%x (%d)      %ssync\n",
12357             scsi_cmd_name(com, scsi_cmds, tmpbuf),
12358             count, count,
12359             wait == ASYNC_CMD ? "a" : "");
12360 }
12361 #endif  /* STDEBUG */
12362 
12363 /*
12364  * Returns pointer to name of minor node name of device 'dev'.
12365  */
12366 static char *
12367 st_dev_name(dev_t dev)
12368 {
12369         struct scsi_tape *un;
12370         const char density[] = { 'l', 'm', 'h', 'c' };
12371         static char name[32];
12372         minor_t minor;
12373         int instance;
12374         int nprt = 0;
12375 
12376         minor = getminor(dev);
12377         instance = ((minor & 0xff80) >> 5) | (minor & 3);
12378         un = ddi_get_soft_state(st_state, instance);
12379         if (un) {
12380                 ST_FUNC(ST_DEVINFO, st_dev_name);
12381         }
12382 
12383         name[nprt] = density[(minor & MT_DENSITY_MASK) >> 3];
12384 
12385         if (minor & MT_BSD) {
12386                 name[++nprt] = 'b';
12387         }
12388 
12389         if (minor & MT_NOREWIND) {
12390                 name[++nprt] = 'n';
12391         }
12392 
12393         /* NULL terminator */
12394         name[++nprt] = 0;
12395 
12396         return (name);
12397 }
12398 
12399 /*
12400  * Soft error reporting, so far unique to each drive
12401  *
12402  * Currently supported: exabyte and DAT soft error reporting
12403  */
12404 static int
12405 st_report_exabyte_soft_errors(dev_t dev, int flag)
12406 {
12407         uchar_t *sensep;
12408         int amt;
12409         int rval = 0;
12410         char cdb[CDB_GROUP0], *c = cdb;
12411         struct uscsi_cmd *com;
12412 
12413         GET_SOFT_STATE(dev);
12414 
12415         ST_FUNC(ST_DEVINFO, st_report_exabyte_soft_errors);
12416 
12417         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12418             "st_report_exabyte_soft_errors(dev = 0x%lx, flag = %d)\n",
12419             dev, flag);
12420 
12421         ASSERT(mutex_owned(ST_MUTEX));
12422 
12423         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
12424         sensep = kmem_zalloc(TAPE_SENSE_LENGTH, KM_SLEEP);
12425 
12426         *c++ = SCMD_REQUEST_SENSE;
12427         *c++ = 0;
12428         *c++ = 0;
12429         *c++ = 0;
12430         *c++ = TAPE_SENSE_LENGTH;
12431         /*
12432          * set CLRCNT (byte 5, bit 7 which clears the error counts)
12433          */
12434         *c   = (char)0x80;
12435 
12436         com->uscsi_cdb = cdb;
12437         com->uscsi_cdblen = CDB_GROUP0;
12438         com->uscsi_bufaddr = (caddr_t)sensep;
12439         com->uscsi_buflen = TAPE_SENSE_LENGTH;
12440         com->uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_READ;
12441         com->uscsi_timeout = un->un_dp->non_motion_timeout;
12442 
12443         rval = st_uscsi_cmd(un, com, FKIOCTL);
12444         if (rval || com->uscsi_status) {
12445                 goto done;
12446         }
12447 
12448         /*
12449          * was there enough data?
12450          */
12451         amt = (int)TAPE_SENSE_LENGTH - com->uscsi_resid;
12452 
12453         if ((amt >= 19) && un->un_kbytes_xferred) {
12454                 uint_t count, error_rate;
12455                 uint_t rate;
12456 
12457                 if (sensep[21] & CLN) {
12458                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
12459                             "Periodic head cleaning required");
12460                 }
12461                 if (un->un_kbytes_xferred < (EXABYTE_MIN_TRANSFER/ONE_K)) {
12462                         goto done;
12463                 }
12464                 /*
12465                  * check if soft error reporting needs to be done.
12466                  */
12467                 count = sensep[16] << 16 | sensep[17] << 8 | sensep[18];
12468                 count &= 0xffffff;
12469                 error_rate = (count * 100)/un->un_kbytes_xferred;
12470 
12471 #ifdef  STDEBUG
12472                 if (st_soft_error_report_debug) {
12473                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
12474                             "Exabyte Soft Error Report:\n");
12475                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12476                             "read/write error counter: %d\n", count);
12477                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12478                             "number of bytes transferred: %dK\n",
12479                             un->un_kbytes_xferred);
12480                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12481                             "error_rate: %d%%\n", error_rate);
12482 
12483                         if (amt >= 22) {
12484                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12485                                     "unit sense: 0x%b 0x%b 0x%b\n",
12486                                     sensep[19], SENSE_19_BITS,
12487                                     sensep[20], SENSE_20_BITS,
12488                                     sensep[21], SENSE_21_BITS);
12489                         }
12490                         if (amt >= 27) {
12491                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12492                                     "tracking retry counter: %d\n",
12493                                     sensep[26]);
12494                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12495                                     "read/write retry counter: %d\n",
12496                                     sensep[27]);
12497                         }
12498                 }
12499 #endif
12500 
12501                 if (flag & FWRITE) {
12502                         rate = EXABYTE_WRITE_ERROR_THRESHOLD;
12503                 } else {
12504                         rate = EXABYTE_READ_ERROR_THRESHOLD;
12505                 }
12506                 if (error_rate >= rate) {
12507                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
12508                             "Soft error rate (%d%%) during %s was too high",
12509                             error_rate,
12510                             ((flag & FWRITE) ? wrg_str : rdg_str));
12511                         scsi_log(ST_DEVINFO, st_label, CE_CONT,
12512                             "Please, replace tape cartridge\n");
12513                 }
12514         }
12515 
12516 done:
12517         kmem_free(com, sizeof (*com));
12518         kmem_free(sensep, TAPE_SENSE_LENGTH);
12519 
12520         if (rval != 0) {
12521                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12522                     "exabyte soft error reporting failed\n");
12523         }
12524         return (rval);
12525 }
12526 
12527 /*
12528  * this is very specific to Archive 4mm dat
12529  */
12530 #define ONE_GIG (ONE_K * ONE_K * ONE_K)
12531 
12532 static int
12533 st_report_dat_soft_errors(dev_t dev, int flag)
12534 {
12535         uchar_t *sensep;
12536         int amt, i;
12537         int rval = 0;
12538         char cdb[CDB_GROUP1], *c = cdb;
12539         struct uscsi_cmd *com;
12540         struct scsi_arq_status status;
12541 
12542         GET_SOFT_STATE(dev);
12543 
12544         ST_FUNC(ST_DEVINFO, st_report_dat_soft_errors);
12545 
12546         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12547             "st_report_dat_soft_errors(dev = 0x%lx, flag = %d)\n", dev, flag);
12548 
12549         ASSERT(mutex_owned(ST_MUTEX));
12550 
12551         com = kmem_zalloc(sizeof (*com), KM_SLEEP);
12552         sensep = kmem_zalloc(LOG_SENSE_LENGTH, KM_SLEEP);
12553 
12554         *c++ = SCMD_LOG_SENSE_G1;
12555         *c++ = 0;
12556         *c++ = (flag & FWRITE) ? 0x42 : 0x43;
12557         *c++ = 0;
12558         *c++ = 0;
12559         *c++ = 0;
12560         *c++ = 2;
12561         *c++ = 0;
12562         *c++ = (char)LOG_SENSE_LENGTH;
12563         *c   = 0;
12564         com->uscsi_cdb    = cdb;
12565         com->uscsi_cdblen  = CDB_GROUP1;
12566         com->uscsi_bufaddr = (caddr_t)sensep;
12567         com->uscsi_buflen  = LOG_SENSE_LENGTH;
12568         com->uscsi_rqlen = sizeof (status);
12569         com->uscsi_rqbuf = (caddr_t)&status;
12570         com->uscsi_flags   = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
12571         com->uscsi_timeout = un->un_dp->non_motion_timeout;
12572         rval = st_uscsi_cmd(un, com, FKIOCTL);
12573         if (rval) {
12574                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12575                     "DAT soft error reporting failed\n");
12576         }
12577         if (rval || com->uscsi_status) {
12578                 goto done;
12579         }
12580 
12581         /*
12582          * was there enough data?
12583          */
12584         amt = (int)LOG_SENSE_LENGTH - com->uscsi_resid;
12585 
12586         if ((amt >= MIN_LOG_SENSE_LENGTH) && un->un_kbytes_xferred) {
12587                 int total, retries, param_code;
12588 
12589                 total = -1;
12590                 retries = -1;
12591                 amt = sensep[3] + 4;
12592 
12593 
12594 #ifdef STDEBUG
12595                 if (st_soft_error_report_debug) {
12596                         (void) printf("logsense:");
12597                         for (i = 0; i < MIN_LOG_SENSE_LENGTH; i++) {
12598                                 if (i % 16 == 0) {
12599                                         (void) printf("\t\n");
12600                                 }
12601                                 (void) printf(" %x", sensep[i]);
12602                         }
12603                         (void) printf("\n");
12604                 }
12605 #endif
12606 
12607                 /*
12608                  * parse the param_codes
12609                  */
12610                 if (sensep[0] == 2 || sensep[0] == 3) {
12611                         for (i = 4; i < amt; i++) {
12612                                 param_code = (sensep[i++] << 8);
12613                                 param_code += sensep[i++];
12614                                 i++; /* skip control byte */
12615                                 if (param_code == 5) {
12616                                         if (sensep[i++] == 4) {
12617                                                 total = (sensep[i++] << 24);
12618                                                 total += (sensep[i++] << 16);
12619                                                 total += (sensep[i++] << 8);
12620                                                 total += sensep[i];
12621                                         }
12622                                 } else if (param_code == 0x8007) {
12623                                         if (sensep[i++] == 2) {
12624                                                 retries = sensep[i++] << 8;
12625                                                 retries += sensep[i];
12626                                         }
12627                                 } else {
12628                                         i += sensep[i];
12629                                 }
12630                         }
12631                 }
12632 
12633                 /*
12634                  * if the log sense returned valid numbers then determine
12635                  * the read and write error thresholds based on the amount of
12636                  * data transferred
12637                  */
12638 
12639                 if (total > 0 && retries > 0) {
12640                         short normal_retries = 0;
12641                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
12642                             "total xferred (%s) =%x, retries=%x\n",
12643                             ((flag & FWRITE) ? wrg_str : rdg_str),
12644                             total, retries);
12645 
12646                         if (flag & FWRITE) {
12647                                 if (total <=
12648                                     WRITE_SOFT_ERROR_WARNING_THRESHOLD) {
12649                                         normal_retries =
12650                                             DAT_SMALL_WRITE_ERROR_THRESHOLD;
12651                                 } else {
12652                                         normal_retries =
12653                                             DAT_LARGE_WRITE_ERROR_THRESHOLD;
12654                                 }
12655                         } else {
12656                                 if (total <=
12657                                     READ_SOFT_ERROR_WARNING_THRESHOLD) {
12658                                         normal_retries =
12659                                             DAT_SMALL_READ_ERROR_THRESHOLD;
12660                                 } else {
12661                                         normal_retries =
12662                                             DAT_LARGE_READ_ERROR_THRESHOLD;
12663                                 }
12664                         }
12665 
12666                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
12667                         "normal retries=%d\n", normal_retries);
12668 
12669                         if (retries >= normal_retries) {
12670                                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12671                                     "Soft error rate (retries = %d) during "
12672                                     "%s was too high",  retries,
12673                                     ((flag & FWRITE) ? wrg_str : rdg_str));
12674                                 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12675                                     "Periodic head cleaning required "
12676                                     "and/or replace tape cartridge\n");
12677                         }
12678 
12679                 } else if (total == -1 || retries == -1) {
12680                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
12681                             "log sense parameter code does not make sense\n");
12682                 }
12683         }
12684 
12685         /*
12686          * reset all values
12687          */
12688         c = cdb;
12689         *c++ = SCMD_LOG_SELECT_G1;
12690         *c++ = 2;       /* this resets all values */
12691         *c++ = (char)0xc0;
12692         *c++ = 0;
12693         *c++ = 0;
12694         *c++ = 0;
12695         *c++ = 0;
12696         *c++ = 0;
12697         *c++ = 0;
12698         *c   = 0;
12699         com->uscsi_bufaddr = NULL;
12700         com->uscsi_buflen  = 0;
12701         com->uscsi_flags   = USCSI_DIAGNOSE | USCSI_SILENT;
12702         rval = st_uscsi_cmd(un, com, FKIOCTL);
12703         if (rval) {
12704                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12705                     "DAT soft error reset failed\n");
12706         }
12707 done:
12708         kmem_free(com, sizeof (*com));
12709         kmem_free(sensep, LOG_SENSE_LENGTH);
12710         return (rval);
12711 }
12712 
12713 static int
12714 st_report_soft_errors(dev_t dev, int flag)
12715 {
12716         GET_SOFT_STATE(dev);
12717 
12718         ST_FUNC(ST_DEVINFO, st_report_soft_errors);
12719 
12720         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12721             "st_report_soft_errors(dev = 0x%lx, flag = %d)\n", dev, flag);
12722 
12723         ASSERT(mutex_owned(ST_MUTEX));
12724 
12725         switch (un->un_dp->type) {
12726         case ST_TYPE_EXB8500:
12727         case ST_TYPE_EXABYTE:
12728                 return (st_report_exabyte_soft_errors(dev, flag));
12729                 /*NOTREACHED*/
12730         case ST_TYPE_PYTHON:
12731                 return (st_report_dat_soft_errors(dev, flag));
12732                 /*NOTREACHED*/
12733         default:
12734                 un->un_dp->options &= ~ST_SOFT_ERROR_REPORTING;
12735                 return (-1);
12736         }
12737 }
12738 
12739 /*
12740  * persistent error routines
12741  */
12742 
12743 /*
12744  * enable persistent errors, and set the throttle appropriately, checking
12745  * for flush-on-errors capability
12746  */
12747 static void
12748 st_turn_pe_on(struct scsi_tape *un)
12749 {
12750         ST_FUNC(ST_DEVINFO, st_turn_pe_on);
12751 
12752         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_on\n");
12753         ASSERT(mutex_owned(ST_MUTEX));
12754 
12755         un->un_persistence = 1;
12756 
12757         /*
12758          * only use flush-on-errors if auto-request-sense and untagged-qing are
12759          * enabled.  This will simplify the error handling for request senses
12760          */
12761 
12762         if (un->un_arq_enabled && un->un_untagged_qing) {
12763                 uchar_t f_o_e;
12764 
12765                 mutex_exit(ST_MUTEX);
12766                 f_o_e = (scsi_ifsetcap(ROUTE, "flush-on-errors", 1, 1) == 1) ?
12767                     1 : 0;
12768                 mutex_enter(ST_MUTEX);
12769 
12770                 un->un_flush_on_errors = f_o_e;
12771         } else {
12772                 un->un_flush_on_errors = 0;
12773         }
12774 
12775         if (un->un_flush_on_errors)
12776                 un->un_max_throttle = (uchar_t)st_max_throttle;
12777         else
12778                 un->un_max_throttle = 1;
12779 
12780         if (un->un_dp->options & ST_RETRY_ON_RECOVERED_DEFERRED_ERROR)
12781                 un->un_max_throttle = 1;
12782 
12783         /* this will send a marker pkt */
12784         st_clear_pe(un);
12785 }
12786 
12787 /*
12788  * This turns persistent errors permanently off
12789  */
12790 static void
12791 st_turn_pe_off(struct scsi_tape *un)
12792 {
12793         ST_FUNC(ST_DEVINFO, st_turn_pe_off);
12794         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_off\n");
12795         ASSERT(mutex_owned(ST_MUTEX));
12796 
12797         /* turn it off for good */
12798         un->un_persistence = 0;
12799 
12800         /* this will send a marker pkt */
12801         st_clear_pe(un);
12802 
12803         /* turn off flush on error capability, if enabled */
12804         if (un->un_flush_on_errors) {
12805                 mutex_exit(ST_MUTEX);
12806                 (void) scsi_ifsetcap(ROUTE, "flush-on-errors", 0, 1);
12807                 mutex_enter(ST_MUTEX);
12808         }
12809 
12810 
12811         un->un_flush_on_errors = 0;
12812 }
12813 
12814 /*
12815  * This clear persistent errors, allowing more commands through, and also
12816  * sending a marker packet.
12817  */
12818 static void
12819 st_clear_pe(struct scsi_tape *un)
12820 {
12821         ST_FUNC(ST_DEVINFO, st_clear_pe);
12822         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_clear\n");
12823         ASSERT(mutex_owned(ST_MUTEX));
12824 
12825         un->un_persist_errors = 0;
12826         un->un_throttle = un->un_last_throttle = 1;
12827         un->un_errno = 0;
12828         st_hba_unflush(un);
12829 }
12830 
12831 /*
12832  * This will flag persistent errors, shutting everything down, if the
12833  * application had enabled persistent errors via MTIOCPERSISTENT
12834  */
12835 static void
12836 st_set_pe_flag(struct scsi_tape *un)
12837 {
12838         ST_FUNC(ST_DEVINFO, st_set_pe_flag);
12839         ASSERT(mutex_owned(ST_MUTEX));
12840 
12841         if (un->un_persistence) {
12842                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_flag\n");
12843                 un->un_persist_errors = 1;
12844                 un->un_throttle = un->un_last_throttle = 0;
12845                 cv_broadcast(&un->un_sbuf_cv);
12846         }
12847 }
12848 
12849 static int
12850 st_do_reserve(struct scsi_tape *un)
12851 {
12852         int rval;
12853         int was_lost = un->un_rsvd_status & ST_LOST_RESERVE;
12854 
12855         ST_FUNC(ST_DEVINFO, st_do_reserve);
12856 
12857         /*
12858          * Issue a Throw-Away reserve command to clear the
12859          * check condition.
12860          * If the current behaviour of reserve/release is to
12861          * hold reservation across opens , and if a Bus reset
12862          * has been issued between opens then this command
12863          * would set the ST_LOST_RESERVE flags in rsvd_status.
12864          * In this case return an EACCES so that user knows that
12865          * reservation has been lost in between opens.
12866          * If this error is not returned and we continue with
12867          * successful open , then user may think position of the
12868          * tape is still the same but inreality we would rewind the
12869          * tape and continue from BOT.
12870          */
12871         rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
12872         if (rval) {
12873                 if ((un->un_rsvd_status & ST_LOST_RESERVE_BETWEEN_OPENS) ==
12874                     ST_LOST_RESERVE_BETWEEN_OPENS) {
12875                         un->un_rsvd_status &= ~(ST_LOST_RESERVE | ST_RESERVE);
12876                         un->un_errno = EACCES;
12877                         return (EACCES);
12878                 }
12879                 rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
12880         }
12881         if (rval == 0) {
12882                 un->un_rsvd_status |= ST_INIT_RESERVE;
12883         }
12884         if (was_lost) {
12885                 un->un_running.pmode = invalid;
12886         }
12887 
12888         return (rval);
12889 }
12890 
12891 static int
12892 st_check_cdb_for_need_to_reserve(struct scsi_tape *un, uchar_t *cdb)
12893 {
12894         int rval;
12895         cmd_attribute const *attrib;
12896 
12897         ST_FUNC(ST_DEVINFO, st_check_cdb_for_need_to_reserve);
12898 
12899         /*
12900          * If already reserved no need to do it again.
12901          * Also if Reserve and Release are disabled Just return.
12902          */
12903         if ((un->un_rsvd_status & (ST_APPLICATION_RESERVATIONS)) ||
12904             ((un->un_rsvd_status & (ST_RESERVE | ST_LOST_RESERVE)) ==
12905             ST_RESERVE) || (un->un_dp->options & ST_NO_RESERVE_RELEASE)) {
12906                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12907                     "st_check_cdb_for_need_to_reserve() reserve unneeded %s",
12908                     st_print_scsi_cmd((uchar_t)cdb[0]));
12909                 return (0);
12910         }
12911 
12912         /* See if command is on the list */
12913         attrib = st_lookup_cmd_attribute(cdb[0]);
12914 
12915         if (attrib == NULL) {
12916                 rval = 1; /* Not found, when in doubt reserve */
12917         } else if ((attrib->requires_reserve) != 0) {
12918                 rval = 1;
12919         } else if ((attrib->reserve_byte) != 0) {
12920                 /*
12921                  * cmd is on list.
12922                  * if byte is zero always allowed.
12923                  */
12924                 rval = 1;
12925         } else if (((cdb[attrib->reserve_byte]) &
12926             (attrib->reserve_mask)) != 0) {
12927                 rval = 1;
12928         } else {
12929                 rval = 0;
12930         }
12931 
12932         if (rval) {
12933                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12934                     "Command %s requires reservation",
12935                     st_print_scsi_cmd(cdb[0]));
12936 
12937                 rval = st_do_reserve(un);
12938         }
12939 
12940         return (rval);
12941 }
12942 
12943 static int
12944 st_check_cmd_for_need_to_reserve(struct scsi_tape *un, uchar_t cmd, int cnt)
12945 {
12946         int rval;
12947         cmd_attribute const *attrib;
12948 
12949         ST_FUNC(ST_DEVINFO, st_check_cmd_for_need_to_reserve);
12950 
12951         /*
12952          * Do not reserve when already reserved, when not supported or when
12953          * auto-rewinding on device closure.
12954          */
12955         if ((un->un_rsvd_status & (ST_APPLICATION_RESERVATIONS)) ||
12956             ((un->un_rsvd_status & (ST_RESERVE | ST_LOST_RESERVE)) ==
12957             ST_RESERVE) || (un->un_dp->options & ST_NO_RESERVE_RELEASE) ||
12958             ((un->un_state == ST_STATE_CLOSING) && (cmd == SCMD_REWIND))) {
12959                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12960                     "st_check_cmd_for_need_to_reserve() reserve unneeded %s",
12961                     st_print_scsi_cmd(cmd));
12962                 return (0);
12963         }
12964 
12965         /* search for this command on the list */
12966         attrib = st_lookup_cmd_attribute(cmd);
12967 
12968         if (attrib == NULL) {
12969                 rval = 1; /* Not found, when in doubt reserve */
12970         } else if ((attrib->requires_reserve) != 0) {
12971                 rval = 1;
12972         } else if ((attrib->reserve_byte) != 0) {
12973                 /*
12974                  * cmd is on list.
12975                  * if byte is zero always allowed.
12976                  */
12977                 rval = 1;
12978         } else if (((attrib->reserve_mask) & cnt) != 0) {
12979                 rval = 1;
12980         } else {
12981                 rval = 0;
12982         }
12983 
12984         if (rval) {
12985                 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12986                     "Cmd %s requires reservation", st_print_scsi_cmd(cmd));
12987 
12988                 rval = st_do_reserve(un);
12989         }
12990 
12991         return (rval);
12992 }
12993 
12994 static int
12995 st_reserve_release(struct scsi_tape *un, int cmd, ubufunc_t ubf)
12996 {
12997         struct uscsi_cmd        uscsi_cmd;
12998         int                     rval;
12999         char                    cdb[CDB_GROUP0];
13000         struct scsi_arq_status  stat;
13001 
13002 
13003 
13004         ST_FUNC(ST_DEVINFO, st_reserve_release);
13005 
13006         ASSERT(mutex_owned(ST_MUTEX));
13007 
13008         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13009             "st_reserve_release: %s \n",
13010             (cmd == ST_RELEASE)?  "Releasing":"Reserving");
13011 
13012         bzero(&cdb, CDB_GROUP0);
13013         if (cmd == ST_RELEASE) {
13014                 cdb[0] = SCMD_RELEASE;
13015         } else {
13016                 cdb[0] = SCMD_RESERVE;
13017         }
13018         bzero(&uscsi_cmd, sizeof (struct uscsi_cmd));
13019         uscsi_cmd.uscsi_flags = USCSI_WRITE | USCSI_RQENABLE;
13020         uscsi_cmd.uscsi_cdb = cdb;
13021         uscsi_cmd.uscsi_cdblen = CDB_GROUP0;
13022         uscsi_cmd.uscsi_timeout = un->un_dp->non_motion_timeout;
13023         uscsi_cmd.uscsi_rqbuf = (caddr_t)&stat;
13024         uscsi_cmd.uscsi_rqlen = sizeof (stat);
13025 
13026         rval = ubf(un, &uscsi_cmd, FKIOCTL);
13027 
13028         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13029             "st_reserve_release: rval(1)=%d\n", rval);
13030 
13031         if (rval) {
13032                 if (uscsi_cmd.uscsi_status == STATUS_RESERVATION_CONFLICT) {
13033                         rval = EACCES;
13034                 }
13035                 /*
13036                  * dynamically turn off reserve/release support
13037                  * in case of drives which do not support
13038                  * reserve/release command(ATAPI drives).
13039                  */
13040                 if (un->un_status == KEY_ILLEGAL_REQUEST) {
13041                         if ((un->un_dp->options & ST_NO_RESERVE_RELEASE) == 0) {
13042                                 un->un_dp->options |= ST_NO_RESERVE_RELEASE;
13043                                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13044                                     "Tape unit does not support "
13045                                     "reserve/release \n");
13046                         }
13047                         rval = 0;
13048                 }
13049         }
13050         return (rval);
13051 }
13052 
13053 static int
13054 st_take_ownership(struct scsi_tape *un, ubufunc_t ubf)
13055 {
13056         int rval;
13057 
13058         ST_FUNC(ST_DEVINFO, st_take_ownership);
13059 
13060         ASSERT(mutex_owned(ST_MUTEX));
13061 
13062         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13063             "st_take_ownership: Entering ...\n");
13064 
13065 
13066         rval = st_reserve_release(un, ST_RESERVE, ubf);
13067         /*
13068          * XXX -> Should reset be done only if we get EACCES.
13069          * .
13070          */
13071         if (rval) {
13072                 if (st_reset(un, RESET_LUN) == 0) {
13073                         return (EIO);
13074                 }
13075                 un->un_rsvd_status &=
13076                     ~(ST_LOST_RESERVE | ST_RESERVATION_CONFLICT);
13077 
13078                 mutex_exit(ST_MUTEX);
13079                 delay(drv_usectohz(ST_RESERVATION_DELAY));
13080                 mutex_enter(ST_MUTEX);
13081                 /*
13082                  * remove the check condition.
13083                  */
13084                 (void) st_reserve_release(un, ST_RESERVE, ubf);
13085                 rval = st_reserve_release(un, ST_RESERVE, ubf);
13086                 if (rval != 0) {
13087                         if ((st_reserve_release(un, ST_RESERVE, ubf))
13088                             != 0) {
13089                                 rval = (un->un_rsvd_status &
13090                                     ST_RESERVATION_CONFLICT) ? EACCES : EIO;
13091                                 return (rval);
13092                         }
13093                 }
13094                 /*
13095                  * Set tape state to ST_STATE_OFFLINE , in case if
13096                  * the user wants to continue and start using
13097                  * the tape.
13098                  */
13099                 un->un_state = ST_STATE_OFFLINE;
13100                 un->un_rsvd_status |= ST_INIT_RESERVE;
13101         }
13102         return (rval);
13103 }
13104 
13105 static int
13106 st_create_errstats(struct scsi_tape *un, int instance)
13107 {
13108         char    kstatname[KSTAT_STRLEN];
13109 
13110         ST_FUNC(ST_DEVINFO, st_create_errstats);
13111 
13112         /*
13113          * Create device error kstats
13114          */
13115 
13116         if (un->un_errstats == (kstat_t *)0) {
13117                 (void) sprintf(kstatname, "st%d,err", instance);
13118                 un->un_errstats = kstat_create("sterr", instance, kstatname,
13119                     "device_error", KSTAT_TYPE_NAMED,
13120                     sizeof (struct st_errstats) / sizeof (kstat_named_t),
13121                     KSTAT_FLAG_PERSISTENT);
13122 
13123                 if (un->un_errstats) {
13124                         struct st_errstats      *stp;
13125 
13126                         stp = (struct st_errstats *)un->un_errstats->ks_data;
13127                         kstat_named_init(&stp->st_softerrs, "Soft Errors",
13128                             KSTAT_DATA_ULONG);
13129                         kstat_named_init(&stp->st_harderrs, "Hard Errors",
13130                             KSTAT_DATA_ULONG);
13131                         kstat_named_init(&stp->st_transerrs, "Transport Errors",
13132                             KSTAT_DATA_ULONG);
13133                         kstat_named_init(&stp->st_vid, "Vendor",
13134                             KSTAT_DATA_CHAR);
13135                         kstat_named_init(&stp->st_pid, "Product",
13136                             KSTAT_DATA_CHAR);
13137                         kstat_named_init(&stp->st_revision, "Revision",
13138                             KSTAT_DATA_CHAR);
13139                         kstat_named_init(&stp->st_serial, "Serial No",
13140                             KSTAT_DATA_CHAR);
13141                         un->un_errstats->ks_private = un;
13142                         un->un_errstats->ks_update = nulldev;
13143                         kstat_install(un->un_errstats);
13144                         /*
13145                          * Fill in the static data
13146                          */
13147                         (void) strncpy(&stp->st_vid.value.c[0],
13148                             ST_INQUIRY->inq_vid, 8);
13149                         /*
13150                          * XXX:  Emulex MT-02 (and emulators) predates
13151                          *       SCSI-1 and has no vid & pid inquiry data.
13152                          */
13153                         if (ST_INQUIRY->inq_len != 0) {
13154                                 (void) strncpy(&stp->st_pid.value.c[0],
13155                                     ST_INQUIRY->inq_pid, 16);
13156                                 (void) strncpy(&stp->st_revision.value.c[0],
13157                                     ST_INQUIRY->inq_revision, 4);
13158                         }
13159                 }
13160         }
13161         return (0);
13162 }
13163 
13164 static int
13165 st_validate_tapemarks(struct scsi_tape *un, ubufunc_t ubf, tapepos_t *pos)
13166 {
13167         int rval;
13168         bufunc_t bf = (ubf == st_uscsi_rcmd) ? st_rcmd : st_cmd;
13169 
13170         ST_FUNC(ST_DEVINFO, st_validate_tapemarks);
13171 
13172         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
13173         ASSERT(mutex_owned(ST_MUTEX));
13174 
13175         /* Can't restore an invalid position */
13176         if (pos->pmode == invalid) {
13177                 return (4);
13178         }
13179 
13180         /*
13181          * Assumtions:
13182          *      If a position was read and is in logical position mode.
13183          *      If a drive supports read position it supports locate.
13184          *      If the read position type is not NO_POS. even though
13185          *         a read position make not have been attemped yet.
13186          *
13187          *      The drive can locate to the position.
13188          */
13189         if (pos->pmode == logical || un->un_read_pos_type != NO_POS) {
13190                 /*
13191                  * If position mode is logical or legacy mode try
13192                  * to locate there as it is faster.
13193                  * If it fails try the old way.
13194                  */
13195                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
13196                     "Restoring tape position to lgclblkbo=0x%"PRIx64"....",
13197                     pos->lgclblkno);
13198 
13199                 if (st_logical_block_locate(un, st_uscsi_cmd, &un->un_pos,
13200                     pos->lgclblkno, pos->partition) == 0) {
13201                         /* Assume we are there copy rest of position back */
13202                         if (un->un_pos.lgclblkno == pos->lgclblkno) {
13203                                 COPY_POS(&un->un_pos, pos);
13204                         }
13205                         return (0);
13206                 }
13207 
13208                 /*
13209                  * If logical block locate failed to restore a logical
13210                  * position, can't recover.
13211                  */
13212                 if (pos->pmode == logical) {
13213                         return (-1);
13214                 }
13215         }
13216 
13217 
13218         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
13219             "Restoring tape position at fileno=%x, blkno=%x....",
13220             pos->fileno, pos->blkno);
13221 
13222         /*
13223          * Rewind ? Oh yeah, Fidelity has got the STK F/W changed
13224          * so as not to rewind tape on RESETS: Gee, Has life ever
13225          * been simple in tape land ?
13226          */
13227         rval = bf(un, SCMD_REWIND, 0, SYNC_CMD);
13228         if (rval) {
13229                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13230                     "Failed to restore the last file and block position: In"
13231                     " this state, Tape will be loaded at BOT during next open");
13232                 un->un_pos.pmode = invalid;
13233                 return (rval);
13234         }
13235 
13236         /* If the position was as the result of back space file */
13237         if (pos->blkno > (INF / 2)) {
13238                 /* Go one extra file forward */
13239                 pos->fileno++;
13240                 /* Figure how many blocks to back into the previous file */
13241                 pos->blkno = -(INF - pos->blkno);
13242         }
13243 
13244         /* Go to requested fileno */
13245         if (pos->fileno) {
13246                 rval = st_cmd(un, SCMD_SPACE, Fmk(pos->fileno), SYNC_CMD);
13247                 if (rval) {
13248                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
13249                             "Failed to restore the last file position: In this "
13250                             " state, Tape will be loaded at BOT during next"
13251                             " open %d", __LINE__);
13252                         un->un_pos.pmode = invalid;
13253                         pos->pmode = invalid;
13254                         return (rval);
13255                 }
13256         }
13257 
13258         /*
13259          * If backing into a file we already did an extra file forward.
13260          * Now we have to back over the filemark to get to the end of
13261          * the previous file. The blkno has been ajusted to a negative
13262          * value so we will get to the expected location.
13263          */
13264         if (pos->blkno) {
13265                 rval = bf(un, SCMD_SPACE, Fmk(-1), SYNC_CMD);
13266                 if (rval) {
13267                         scsi_log(ST_DEVINFO, st_label, CE_WARN,
13268                             "Failed to restore the last file position: In this "
13269                             " state, Tape will be loaded at BOT during next"
13270                             " open %d", __LINE__);
13271                         un->un_pos.pmode = invalid;
13272                         pos->pmode = invalid;
13273                         return (rval);
13274                 }
13275         }
13276 
13277         /*
13278          * The position mode, block and fileno should be correct,
13279          * This updates eof and logical position information.
13280          */
13281         un->un_pos.eof = pos->eof;
13282         un->un_pos.lgclblkno = pos->lgclblkno;
13283 
13284         return (0);
13285 }
13286 
13287 /*
13288  * check sense key, ASC, ASCQ in order to determine if the tape needs
13289  * to be ejected
13290  */
13291 
13292 static int
13293 st_check_asc_ascq(struct scsi_tape *un)
13294 {
13295         struct scsi_extended_sense *sensep = ST_RQSENSE;
13296         struct tape_failure_code   *code;
13297 
13298         ST_FUNC(ST_DEVINFO, st_check_asc_ascq);
13299 
13300         for (code = st_tape_failure_code; code->key != 0xff; code++) {
13301                 if ((code->key  == sensep->es_key) &&
13302                     (code->add_code  == sensep->es_add_code) &&
13303                     (code->qual_code == sensep->es_qual_code))
13304                         return (1);
13305         }
13306         return (0);
13307 }
13308 
13309 /*
13310  * st_logpage_supported() sends a Log Sense command with
13311  * page code = 0 = Supported Log Pages Page to the device,
13312  * to see whether the page 'page' is supported.
13313  * Return values are:
13314  * -1 if the Log Sense command fails
13315  * 0 if page is not supported
13316  * 1 if page is supported
13317  */
13318 
13319 static int
13320 st_logpage_supported(struct scsi_tape *un, uchar_t page)
13321 {
13322         uchar_t *sp, *sensep;
13323         unsigned length;
13324         struct uscsi_cmd *com;
13325         struct scsi_arq_status status;
13326         int rval;
13327         char cdb[CDB_GROUP1] = {
13328                 SCMD_LOG_SENSE_G1,
13329                 0,
13330                 SUPPORTED_LOG_PAGES_PAGE,
13331                 0,
13332                 0,
13333                 0,
13334                 0,
13335                 0,
13336                 (char)LOG_SENSE_LENGTH,
13337                 0
13338         };
13339 
13340         ST_FUNC(ST_DEVINFO, st_logpage_supported);
13341 
13342         ASSERT(mutex_owned(ST_MUTEX));
13343 
13344         com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13345         sensep = kmem_zalloc(LOG_SENSE_LENGTH, KM_SLEEP);
13346 
13347         com->uscsi_cdb = cdb;
13348         com->uscsi_cdblen = CDB_GROUP1;
13349         com->uscsi_bufaddr = (caddr_t)sensep;
13350         com->uscsi_buflen = LOG_SENSE_LENGTH;
13351         com->uscsi_rqlen = sizeof (status);
13352         com->uscsi_rqbuf = (caddr_t)&status;
13353         com->uscsi_flags =
13354             USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13355         com->uscsi_timeout = un->un_dp->non_motion_timeout;
13356         rval = st_uscsi_cmd(un, com, FKIOCTL);
13357         if (rval || com->uscsi_status) {
13358                 /* uscsi-command failed */
13359                 rval = -1;
13360         } else {
13361 
13362                 sp = sensep + 3;
13363 
13364                 for (length = *sp++; length > 0; length--, sp++) {
13365 
13366                         if (*sp == page) {
13367                                 rval = 1;
13368                                 break;
13369                         }
13370                 }
13371         }
13372         kmem_free(com, sizeof (struct uscsi_cmd));
13373         kmem_free(sensep, LOG_SENSE_LENGTH);
13374         return (rval);
13375 }
13376 
13377 
13378 /*
13379  * st_check_clean_bit() gets the status of the tape's cleaning bit.
13380  *
13381  * If the device does support the TapeAlert log page, then the cleaning bit
13382  * information will be read from this page. Otherwise we will see if one of
13383  * ST_CLN_TYPE_1, ST_CLN_TYPE_2 or ST_CLN_TYPE_3 is set in the properties of
13384  * the device, which means, that we can get the cleaning bit information via
13385  * a RequestSense command.
13386  * If both methods of getting cleaning bit information are not supported
13387  * st_check_clean_bit() will return with 0. Otherwise st_check_clean_bit()
13388  * returns with
13389  * - MTF_TAPE_CLN_SUPPORTED if cleaning bit is not set or
13390  * - MTF_TAPE_CLN_SUPPORTED | MTF_TAPE_HEAD_DIRTY if cleaning bit is set.
13391  * If the call to st_uscsi_cmd() to do the Log Sense or the Request Sense
13392  * command fails, or if the amount of Request Sense data is not enough, then
13393  *  st_check_clean_bit() returns with -1.
13394  */
13395 
13396 static int
13397 st_check_clean_bit(struct scsi_tape *un)
13398 {
13399         int rval = 0;
13400 
13401         ST_FUNC(ST_DEVINFO, st_check_clean_bit);
13402 
13403         ASSERT(mutex_owned(ST_MUTEX));
13404 
13405         if (un->un_HeadClean & TAPE_ALERT_NOT_SUPPORTED) {
13406                 return (rval);
13407         }
13408 
13409         if (un->un_HeadClean == TAPE_ALERT_SUPPORT_UNKNOWN) {
13410 
13411                 rval = st_logpage_supported(un, TAPE_SEQUENTIAL_PAGE);
13412                 if (rval == -1) {
13413                         return (0);
13414                 }
13415                 if (rval == 1) {
13416 
13417                         un->un_HeadClean |= TAPE_SEQUENTIAL_SUPPORTED;
13418                 }
13419 
13420                 rval = st_logpage_supported(un, TAPE_ALERT_PAGE);
13421                 if (rval == -1) {
13422                         return (0);
13423                 }
13424                 if (rval == 1) {
13425 
13426                         un->un_HeadClean |= TAPE_ALERT_SUPPORTED;
13427                 }
13428 
13429                 if (un->un_HeadClean == TAPE_ALERT_SUPPORT_UNKNOWN) {
13430 
13431                         un->un_HeadClean = TAPE_ALERT_NOT_SUPPORTED;
13432                 }
13433         }
13434 
13435         rval = 0;
13436 
13437         if (un->un_HeadClean & TAPE_SEQUENTIAL_SUPPORTED) {
13438 
13439                 rval = st_check_sequential_clean_bit(un);
13440                 if (rval == -1) {
13441                         return (0);
13442                 }
13443         }
13444 
13445         if ((rval == 0) && (un->un_HeadClean & TAPE_ALERT_SUPPORTED)) {
13446 
13447                 rval = st_check_alert_flags(un);
13448                 if (rval == -1) {
13449                         return (0);
13450                 }
13451         }
13452 
13453         if ((rval == 0) && (un->un_dp->options & ST_CLN_MASK)) {
13454 
13455                 rval = st_check_sense_clean_bit(un);
13456                 if (rval == -1) {
13457                         return (0);
13458                 }
13459         }
13460 
13461         /*
13462          * If found a supported means to check need to clean.
13463          */
13464         if (rval & MTF_TAPE_CLN_SUPPORTED) {
13465 
13466                 /*
13467                  * head needs to be cleaned.
13468                  */
13469                 if (rval & MTF_TAPE_HEAD_DIRTY) {
13470 
13471                         /*
13472                          * Print log message only first time
13473                          * found needing cleaned.
13474                          */
13475                         if ((un->un_HeadClean & TAPE_PREVIOUSLY_DIRTY) == 0) {
13476 
13477                                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13478                                     "Periodic head cleaning required");
13479 
13480                                 un->un_HeadClean |= TAPE_PREVIOUSLY_DIRTY;
13481                         }
13482 
13483                 } else {
13484 
13485                         un->un_HeadClean &= ~TAPE_PREVIOUSLY_DIRTY;
13486                 }
13487         }
13488 
13489         return (rval);
13490 }
13491 
13492 
13493 static int
13494 st_check_sequential_clean_bit(struct scsi_tape *un)
13495 {
13496         int rval;
13497         int ix;
13498         ushort_t parameter;
13499         struct uscsi_cmd *cmd;
13500         struct log_sequential_page *sp;
13501         struct log_sequential_page_parameter *prm;
13502         struct scsi_arq_status status;
13503         char cdb[CDB_GROUP1] = {
13504                 SCMD_LOG_SENSE_G1,
13505                 0,
13506                 TAPE_SEQUENTIAL_PAGE | CURRENT_CUMULATIVE_VALUES,
13507                 0,
13508                 0,
13509                 0,
13510                 0,
13511                 (char)(sizeof (struct log_sequential_page) >> 8),
13512                 (char)(sizeof (struct log_sequential_page)),
13513                 0
13514         };
13515 
13516         ST_FUNC(ST_DEVINFO, st_check_sequential_clean_bit);
13517 
13518         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13519         sp  = kmem_zalloc(sizeof (struct log_sequential_page), KM_SLEEP);
13520 
13521         cmd->uscsi_flags   =
13522             USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13523         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
13524         cmd->uscsi_cdb          = cdb;
13525         cmd->uscsi_cdblen  = CDB_GROUP1;
13526         cmd->uscsi_bufaddr = (caddr_t)sp;
13527         cmd->uscsi_buflen  = sizeof (struct log_sequential_page);
13528         cmd->uscsi_rqlen   = sizeof (status);
13529         cmd->uscsi_rqbuf   = (caddr_t)&status;
13530 
13531         rval = st_uscsi_cmd(un, cmd, FKIOCTL);
13532 
13533         if (rval || cmd->uscsi_status || cmd->uscsi_resid) {
13534 
13535                 rval = -1;
13536 
13537         } else if (sp->log_page.code != TAPE_SEQUENTIAL_PAGE) {
13538 
13539                 rval = -1;
13540         }
13541 
13542         prm = &sp->param[0];
13543 
13544         for (ix = 0; rval == 0 && ix < TAPE_SEQUENTIAL_PAGE_PARA; ix++) {
13545 
13546                 if (prm->log_param.length == 0) {
13547                         break;
13548                 }
13549 
13550                 parameter = (((prm->log_param.pc_hi << 8) & 0xff00) +
13551                     (prm->log_param.pc_lo & 0xff));
13552 
13553                 if (parameter == SEQUENTIAL_NEED_CLN) {
13554 
13555                         rval = MTF_TAPE_CLN_SUPPORTED;
13556                         if (prm->param_value[prm->log_param.length - 1]) {
13557 
13558                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13559                                     "sequential log says head dirty\n");
13560                                 rval |= MTF_TAPE_HEAD_DIRTY;
13561                         }
13562                 }
13563                 prm = (struct log_sequential_page_parameter *)
13564                     &prm->param_value[prm->log_param.length];
13565         }
13566 
13567         kmem_free(cmd, sizeof (struct uscsi_cmd));
13568         kmem_free(sp,  sizeof (struct log_sequential_page));
13569 
13570         return (rval);
13571 }
13572 
13573 
13574 static int
13575 st_check_alert_flags(struct scsi_tape *un)
13576 {
13577         struct st_tape_alert *ta;
13578         struct uscsi_cmd *com;
13579         struct scsi_arq_status status;
13580         unsigned ix, length;
13581         int rval;
13582         tape_alert_flags flag;
13583         char cdb[CDB_GROUP1] = {
13584                 SCMD_LOG_SENSE_G1,
13585                 0,
13586                 TAPE_ALERT_PAGE | CURRENT_THRESHOLD_VALUES,
13587                 0,
13588                 0,
13589                 0,
13590                 0,
13591                 (char)(sizeof (struct st_tape_alert) >> 8),
13592                 (char)(sizeof (struct st_tape_alert)),
13593                 0
13594         };
13595 
13596         ST_FUNC(ST_DEVINFO, st_check_alert_clean_bit);
13597 
13598         com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13599         ta  = kmem_zalloc(sizeof (struct st_tape_alert), KM_SLEEP);
13600 
13601         com->uscsi_cdb = cdb;
13602         com->uscsi_cdblen = CDB_GROUP1;
13603         com->uscsi_bufaddr = (caddr_t)ta;
13604         com->uscsi_buflen = sizeof (struct st_tape_alert);
13605         com->uscsi_rqlen = sizeof (status);
13606         com->uscsi_rqbuf = (caddr_t)&status;
13607         com->uscsi_flags =
13608             USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13609         com->uscsi_timeout = un->un_dp->non_motion_timeout;
13610 
13611         rval = st_uscsi_cmd(un, com, FKIOCTL);
13612 
13613         if (rval || com->uscsi_status || com->uscsi_resid) {
13614 
13615                 rval = -1; /* uscsi-command failed */
13616 
13617         } else if (ta->log_page.code != TAPE_ALERT_PAGE) {
13618 
13619                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13620                 "Not Alert Log Page returned 0x%X\n", ta->log_page.code);
13621                 rval = -1;
13622         }
13623 
13624         length = (ta->log_page.length_hi << 8) + ta->log_page.length_lo;
13625 
13626 
13627         if (length != TAPE_ALERT_PARAMETER_LENGTH) {
13628 
13629                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13630                     "TapeAlert length %d\n", length);
13631         }
13632 
13633 
13634         for (ix = 0; ix < TAPE_ALERT_MAX_PARA; ix++) {
13635 
13636                 /*
13637                  * if rval is bad before the first pass don't bother
13638                  */
13639                 if (ix == 0 && rval != 0) {
13640 
13641                         break;
13642                 }
13643 
13644                 flag = ((ta->param[ix].log_param.pc_hi << 8) +
13645                     ta->param[ix].log_param.pc_lo);
13646 
13647                 if ((ta->param[ix].param_value & 1) == 0) {
13648                         continue;
13649                 }
13650                 /*
13651                  * check to see if current parameter is of interest.
13652                  * CLEAN_FOR_ERRORS is vendor specific to 9840 9940 stk's.
13653                  */
13654                 if ((flag == TAF_CLEAN_NOW) ||
13655                     (flag == TAF_CLEAN_PERIODIC) ||
13656                     ((flag == CLEAN_FOR_ERRORS) &&
13657                     (un->un_dp->type == ST_TYPE_STK9840))) {
13658 
13659                         rval = MTF_TAPE_CLN_SUPPORTED;
13660 
13661 
13662                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13663                             "alert_page drive needs clean %d\n", flag);
13664                         un->un_HeadClean |= TAPE_ALERT_STILL_DIRTY;
13665                         rval |= MTF_TAPE_HEAD_DIRTY;
13666 
13667                 } else if (flag == TAF_CLEANING_MEDIA) {
13668 
13669                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13670                             "alert_page drive was cleaned\n");
13671                         un->un_HeadClean &= ~TAPE_ALERT_STILL_DIRTY;
13672                 }
13673 
13674         }
13675 
13676         /*
13677          * Report it as dirty till we see it cleaned
13678          */
13679         if (un->un_HeadClean & TAPE_ALERT_STILL_DIRTY) {
13680 
13681                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13682                     "alert_page still dirty\n");
13683                 rval |= MTF_TAPE_HEAD_DIRTY;
13684         }
13685 
13686         kmem_free(com, sizeof (struct uscsi_cmd));
13687         kmem_free(ta,  sizeof (struct st_tape_alert));
13688 
13689         return (rval);
13690 }
13691 
13692 
13693 static int
13694 st_check_sense_clean_bit(struct scsi_tape *un)
13695 {
13696         uchar_t *sensep;
13697         char cdb[CDB_GROUP0];
13698         struct uscsi_cmd *com;
13699         ushort_t byte_pos;
13700         uchar_t bit_mask;
13701         unsigned length;
13702         int index;
13703         int rval;
13704 
13705         ST_FUNC(ST_DEVINFO, st_check_sense_clean_bit);
13706 
13707         /*
13708          * Since this tape does not support Tape Alert,
13709          * we now try to get the cleanbit status via
13710          * Request Sense.
13711          */
13712 
13713         if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_1) {
13714 
13715                 index = 0;
13716 
13717         } else if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_2) {
13718 
13719                 index = 1;
13720 
13721         } else if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_3) {
13722 
13723                 index = 2;
13724 
13725         } else {
13726 
13727                 return (-1);
13728         }
13729 
13730         byte_pos  = st_cln_bit_position[index].cln_bit_byte;
13731         bit_mask  = st_cln_bit_position[index].cln_bit_mask;
13732         length = byte_pos + 1;
13733 
13734         com    = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13735         sensep = kmem_zalloc(length, KM_SLEEP);
13736 
13737         cdb[0] = SCMD_REQUEST_SENSE;
13738         cdb[1] = 0;
13739         cdb[2] = 0;
13740         cdb[3] = 0;
13741         cdb[4] = (char)length;
13742         cdb[5] = 0;
13743 
13744         com->uscsi_cdb = cdb;
13745         com->uscsi_cdblen = CDB_GROUP0;
13746         com->uscsi_bufaddr = (caddr_t)sensep;
13747         com->uscsi_buflen = length;
13748         com->uscsi_flags =
13749             USCSI_DIAGNOSE | USCSI_SILENT | USCSI_READ;
13750         com->uscsi_timeout = un->un_dp->non_motion_timeout;
13751 
13752         rval = st_uscsi_cmd(un, com, FKIOCTL);
13753 
13754         if (rval || com->uscsi_status || com->uscsi_resid) {
13755 
13756                 rval = -1;
13757 
13758         } else {
13759 
13760                 rval = MTF_TAPE_CLN_SUPPORTED;
13761                 if ((sensep[byte_pos] & bit_mask) == bit_mask) {
13762 
13763                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13764                             "sense data says head dirty\n");
13765                         rval |= MTF_TAPE_HEAD_DIRTY;
13766                 }
13767         }
13768 
13769         kmem_free(com, sizeof (struct uscsi_cmd));
13770         kmem_free(sensep, length);
13771         return (rval);
13772 }
13773 
13774 /*
13775  * st_clear_unit_attention
13776  *
13777  *      run test unit ready's to clear out outstanding
13778  *      unit attentions.
13779  *      returns zero for SUCCESS or the errno from st_cmd call
13780  */
13781 static int
13782 st_clear_unit_attentions(dev_t dev_instance, int max_trys)
13783 {
13784         int     i    = 0;
13785         int     rval;
13786 
13787         GET_SOFT_STATE(dev_instance);
13788         ST_FUNC(ST_DEVINFO, st_clear_unit_attentions);
13789 
13790         do {
13791                 rval = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
13792         } while ((rval != 0) && (rval != ENXIO) && (++i < max_trys));
13793         return (rval);
13794 }
13795 
13796 static void
13797 st_calculate_timeouts(struct scsi_tape *un)
13798 {
13799         ST_FUNC(ST_DEVINFO, st_calculate_timeouts);
13800 
13801         if (un->un_dp->non_motion_timeout == 0) {
13802                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13803                         un->un_dp->non_motion_timeout =
13804                             st_io_time * st_long_timeout_x;
13805                 } else {
13806                         un->un_dp->non_motion_timeout = (ushort_t)st_io_time;
13807                 }
13808         }
13809 
13810         if (un->un_dp->io_timeout == 0) {
13811                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13812                         un->un_dp->io_timeout = st_io_time * st_long_timeout_x;
13813                 } else {
13814                         un->un_dp->io_timeout = (ushort_t)st_io_time;
13815                 }
13816         }
13817 
13818         if (un->un_dp->rewind_timeout == 0) {
13819                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13820                         un->un_dp->rewind_timeout =
13821                             st_space_time * st_long_timeout_x;
13822                 } else {
13823                         un->un_dp->rewind_timeout = (ushort_t)st_space_time;
13824                 }
13825         }
13826 
13827         if (un->un_dp->space_timeout == 0) {
13828                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13829                         un->un_dp->space_timeout =
13830                             st_space_time * st_long_timeout_x;
13831                 } else {
13832                         un->un_dp->space_timeout = (ushort_t)st_space_time;
13833                 }
13834         }
13835 
13836         if (un->un_dp->load_timeout == 0) {
13837                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13838                         un->un_dp->load_timeout =
13839                             st_space_time * st_long_timeout_x;
13840                 } else {
13841                         un->un_dp->load_timeout = (ushort_t)st_space_time;
13842                 }
13843         }
13844 
13845         if (un->un_dp->unload_timeout == 0) {
13846                 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13847                         un->un_dp->unload_timeout =
13848                             st_space_time * st_long_timeout_x;
13849                 } else {
13850                         un->un_dp->unload_timeout = (ushort_t)st_space_time;
13851                 }
13852         }
13853 
13854         if (un->un_dp->erase_timeout == 0) {
13855                 if (un->un_dp->options & ST_LONG_ERASE) {
13856                         un->un_dp->erase_timeout =
13857                             st_space_time * st_long_space_time_x;
13858                 } else {
13859                         un->un_dp->erase_timeout = (ushort_t)st_space_time;
13860                 }
13861         }
13862 }
13863 
13864 
13865 static writablity
13866 st_is_not_wormable(struct scsi_tape *un)
13867 {
13868         ST_FUNC(ST_DEVINFO, st_is_not_wormable);
13869         return (RDWR);
13870 }
13871 
13872 static writablity
13873 st_is_hp_dat_tape_worm(struct scsi_tape *un)
13874 {
13875         writablity wrt;
13876 
13877         ST_FUNC(ST_DEVINFO, st_is_hp_dat_tape_worm);
13878 
13879         /* Mode sense should be current */
13880         if (un->un_mspl->media_type == 1) {
13881                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13882                     "Drive has WORM media loaded\n");
13883                 wrt = WORM;
13884         } else {
13885                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13886                     "Drive has non WORM media loaded\n");
13887                 wrt = RDWR;
13888         }
13889         return (wrt);
13890 }
13891 
13892 #define HP_DAT_INQUIRY 0x4A
13893 static writablity
13894 st_is_hp_dat_worm(struct scsi_tape *un)
13895 {
13896         char *buf;
13897         int result;
13898         writablity wrt;
13899 
13900         ST_FUNC(ST_DEVINFO, st_is_hp_dat_worm);
13901 
13902         buf = kmem_zalloc(HP_DAT_INQUIRY, KM_SLEEP);
13903 
13904         result = st_get_special_inquiry(un, HP_DAT_INQUIRY, buf, 0);
13905 
13906         if (result != 0) {
13907                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13908                     "Read Standard Inquiry for WORM support failed");
13909                 wrt = FAILED;
13910         } else if ((buf[40] & 1) == 0) {
13911                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13912                     "Drive is NOT WORMable\n");
13913                 /* This drive doesn't support it so don't check again */
13914                 un->un_dp->options &= ~ST_WORMABLE;
13915                 wrt = RDWR;
13916                 un->un_wormable = st_is_not_wormable;
13917         } else {
13918                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13919                     "Drive supports WORM version %d\n", buf[40] >> 1);
13920                 un->un_wormable = st_is_hp_dat_tape_worm;
13921                 wrt = un->un_wormable(un);
13922         }
13923 
13924         kmem_free(buf, HP_DAT_INQUIRY);
13925 
13926         /*
13927          * If drive doesn't support it no point in checking further.
13928          */
13929         return (wrt);
13930 }
13931 
13932 static writablity
13933 st_is_hp_lto_tape_worm(struct scsi_tape *un)
13934 {
13935         writablity wrt;
13936 
13937         ST_FUNC(ST_DEVINFO, st_is_hp_lto_tape_worm);
13938 
13939         /* Mode sense should be current */
13940         switch (un->un_mspl->media_type) {
13941         case 0x00:
13942                 switch (un->un_mspl->density) {
13943                 case 0x40:
13944                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13945                             "Drive has standard Gen I media loaded\n");
13946                         break;
13947                 case 0x42:
13948                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13949                             "Drive has standard Gen II media loaded\n");
13950                         break;
13951                 case 0x44:
13952                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13953                             "Drive has standard Gen III media loaded\n");
13954                         break;
13955                 case 0x46:
13956                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13957                             "Drive has standard Gen IV media loaded\n");
13958                         break;
13959                 default:
13960                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13961                             "Drive has standard unknown 0x%X media loaded\n",
13962                             un->un_mspl->density);
13963                 }
13964                 wrt = RDWR;
13965                 break;
13966         case 0x01:
13967                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13968                     "Drive has WORM medium loaded\n");
13969                 wrt = WORM;
13970                 break;
13971         case 0x80:
13972                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13973                     "Drive has CD-ROM emulation medium loaded\n");
13974                 wrt = WORM;
13975                 break;
13976         default:
13977                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13978                     "Drive has an unexpected medium type 0x%X loaded\n",
13979                     un->un_mspl->media_type);
13980                 wrt = RDWR;
13981         }
13982 
13983         return (wrt);
13984 }
13985 
13986 #define LTO_REQ_INQUIRY 44
13987 static writablity
13988 st_is_hp_lto_worm(struct scsi_tape *un)
13989 {
13990         char *buf;
13991         int result;
13992         writablity wrt;
13993 
13994         ST_FUNC(ST_DEVINFO, st_is_hp_lto_worm);
13995 
13996         buf = kmem_zalloc(LTO_REQ_INQUIRY, KM_SLEEP);
13997 
13998         result = st_get_special_inquiry(un, LTO_REQ_INQUIRY, buf, 0);
13999 
14000         if (result != 0) {
14001                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14002                     "Read Standard Inquiry for WORM support failed");
14003                 wrt = FAILED;
14004         } else if ((buf[40] & 1) == 0) {
14005                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14006                     "Drive is NOT WORMable\n");
14007                 /* This drive doesn't support it so don't check again */
14008                 un->un_dp->options &= ~ST_WORMABLE;
14009                 wrt = RDWR;
14010                 un->un_wormable = st_is_not_wormable;
14011         } else {
14012                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14013                     "Drive supports WORM version %d\n", buf[40] >> 1);
14014                 un->un_wormable = st_is_hp_lto_tape_worm;
14015                 wrt = un->un_wormable(un);
14016         }
14017 
14018         kmem_free(buf, LTO_REQ_INQUIRY);
14019 
14020         /*
14021          * If drive doesn't support it no point in checking further.
14022          */
14023         return (wrt);
14024 }
14025 
14026 static writablity
14027 st_is_t10_worm_device(struct scsi_tape *un)
14028 {
14029         writablity wrt;
14030 
14031         ST_FUNC(ST_DEVINFO, st_is_t10_worm_device);
14032 
14033         if (un->un_mspl->media_type == 0x3c) {
14034                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14035                     "Drive has WORM media loaded\n");
14036                 wrt = WORM;
14037         } else {
14038                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14039                     "Drive has non WORM media loaded\n");
14040                 wrt = RDWR;
14041         }
14042         return (wrt);
14043 }
14044 
14045 #define SEQ_CAP_PAGE    (char)0xb0
14046 static writablity
14047 st_is_t10_worm(struct scsi_tape *un)
14048 {
14049         char *buf;
14050         int result;
14051         writablity wrt;
14052 
14053         ST_FUNC(ST_DEVINFO, st_is_t10_worm);
14054 
14055         buf = kmem_zalloc(6, KM_SLEEP);
14056 
14057         result = st_get_special_inquiry(un, 6, buf, SEQ_CAP_PAGE);
14058 
14059         if (result != 0) {
14060                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14061                     "Read Vitial Inquiry for Sequental Capability"
14062                     " WORM support failed %x", result);
14063                 wrt = FAILED;
14064         } else if ((buf[4] & 1) == 0) {
14065                 ASSERT(buf[1] == SEQ_CAP_PAGE);
14066                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14067                     "Drive is NOT WORMable\n");
14068                 /* This drive doesn't support it so don't check again */
14069                 un->un_dp->options &= ~ST_WORMABLE;
14070                 wrt = RDWR;
14071                 un->un_wormable = st_is_not_wormable;
14072         } else {
14073                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14074                     "Drive supports WORM\n");
14075                 un->un_wormable = st_is_t10_worm_device;
14076                 wrt = un->un_wormable(un);
14077         }
14078 
14079         kmem_free(buf, 6);
14080 
14081         return (wrt);
14082 }
14083 
14084 
14085 #define STK_REQ_SENSE 26
14086 
14087 static writablity
14088 st_is_stk_worm(struct scsi_tape *un)
14089 {
14090         char cdb[CDB_GROUP0] = {SCMD_REQUEST_SENSE, 0, 0, 0, STK_REQ_SENSE, 0};
14091         struct scsi_extended_sense *sense;
14092         struct uscsi_cmd *cmd;
14093         char *buf;
14094         int result;
14095         writablity wrt;
14096 
14097         ST_FUNC(ST_DEVINFO, st_is_stk_worm);
14098 
14099         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14100         buf = kmem_alloc(STK_REQ_SENSE, KM_SLEEP);
14101         sense = (struct scsi_extended_sense *)buf;
14102 
14103         cmd->uscsi_flags = USCSI_READ;
14104         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14105         cmd->uscsi_cdb = &cdb[0];
14106         cmd->uscsi_bufaddr = buf;
14107         cmd->uscsi_buflen = STK_REQ_SENSE;
14108         cmd->uscsi_cdblen = CDB_GROUP0;
14109         cmd->uscsi_rqlen = 0;
14110         cmd->uscsi_rqbuf = NULL;
14111 
14112         result = st_uscsi_cmd(un, cmd, FKIOCTL);
14113 
14114         if (result != 0 || cmd->uscsi_status != 0) {
14115                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14116                     "Request Sense for WORM failed");
14117                 wrt = RDWR;
14118         } else if (sense->es_add_len + 8 < 24) {
14119                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14120                     "Drive didn't send enough sense data for WORM byte %d\n",
14121                     sense->es_add_len + 8);
14122                 wrt = RDWR;
14123                 un->un_wormable = st_is_not_wormable;
14124         } else if ((buf[24]) & 0x02) {
14125                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14126                     "Drive has WORM tape loaded\n");
14127                 wrt = WORM;
14128                 un->un_wormable = st_is_stk_worm;
14129         } else {
14130                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14131                     "Drive has normal tape loaded\n");
14132                 wrt = RDWR;
14133                 un->un_wormable = st_is_stk_worm;
14134         }
14135 
14136         kmem_free(buf, STK_REQ_SENSE);
14137         kmem_free(cmd, sizeof (struct uscsi_cmd));
14138         return (wrt);
14139 }
14140 
14141 #define DLT_INQ_SZ 44
14142 
14143 static writablity
14144 st_is_dlt_tape_worm(struct scsi_tape *un)
14145 {
14146         caddr_t buf;
14147         int result;
14148         writablity wrt;
14149 
14150         ST_FUNC(ST_DEVINFO, st_is_dlt_tape_worm);
14151 
14152         buf = kmem_alloc(DLT_INQ_SZ, KM_SLEEP);
14153 
14154         /* Read Attribute Media Type */
14155 
14156         result = st_read_attributes(un, 0x0408, buf, 10, st_uscsi_cmd);
14157 
14158         /*
14159          * If this quantum drive is attached via an HBA that cannot
14160          * support thr read attributes command return error in the
14161          * hope that someday they will support the t10 method.
14162          */
14163         if (result == EINVAL && un->un_max_cdb_sz < CDB_GROUP4) {
14164                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14165                     "Read Attribute Command for WORM Media detection is not "
14166                     "supported on the HBA that this drive is attached to.");
14167                 wrt = RDWR;
14168                 un->un_wormable = st_is_not_wormable;
14169                 goto out;
14170         }
14171 
14172         if (result != 0) {
14173                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14174                     "Read Attribute Command for WORM Media returned 0x%x",
14175                     result);
14176                 wrt = RDWR;
14177                 un->un_dp->options &= ~ST_WORMABLE;
14178                 goto out;
14179         }
14180 
14181         if ((uchar_t)buf[9] == 0x80) {
14182                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14183                     "Drive media is WORM\n");
14184                 wrt = WORM;
14185         } else {
14186                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14187                     "Drive media is not WORM Media 0x%x\n", (uchar_t)buf[9]);
14188                 wrt = RDWR;
14189         }
14190 
14191 out:
14192         kmem_free(buf, DLT_INQ_SZ);
14193         return (wrt);
14194 }
14195 
14196 static writablity
14197 st_is_dlt_worm(struct scsi_tape *un)
14198 {
14199         caddr_t buf;
14200         int result;
14201         writablity wrt;
14202 
14203         ST_FUNC(ST_DEVINFO, st_is_dlt_worm);
14204 
14205         buf = kmem_alloc(DLT_INQ_SZ, KM_SLEEP);
14206 
14207         result = st_get_special_inquiry(un, DLT_INQ_SZ, buf, 0xC0);
14208 
14209         if (result != 0) {
14210                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14211                     "Read Vendor Specific Inquiry for WORM support failed");
14212                 wrt = RDWR;
14213                 goto out;
14214         }
14215 
14216         if ((buf[2] & 1) == 0) {
14217                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14218                     "Drive is not WORMable\n");
14219                 wrt = RDWR;
14220                 un->un_dp->options &= ~ST_WORMABLE;
14221                 un->un_wormable = st_is_not_wormable;
14222                 goto out;
14223         } else {
14224                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14225                     "Drive is WORMable\n");
14226                 un->un_wormable = st_is_dlt_tape_worm;
14227                 wrt = un->un_wormable(un);
14228         }
14229 out:
14230         kmem_free(buf, DLT_INQ_SZ);
14231 
14232         return (wrt);
14233 }
14234 
14235 typedef struct {
14236         struct modeheader_seq header;
14237 #if defined(_BIT_FIELDS_LTOH) /* X86 */
14238         uchar_t pagecode        :6,
14239                                 :2;
14240         uchar_t page_len;
14241         uchar_t syslogalive     :2,
14242                 device          :1,
14243                 abs             :1,
14244                 ulpbot          :1,
14245                 prth            :1,
14246                 ponej           :1,
14247                 ait             :1;
14248         uchar_t span;
14249 
14250         uchar_t                 :6,
14251                 worm            :1,
14252                 mic             :1;
14253         uchar_t worm_cap        :1,
14254                                 :7;
14255         uint32_t                :32;
14256 #else /* SPARC */
14257         uchar_t                 :2,
14258                 pagecode        :6;
14259         uchar_t page_len;
14260         uchar_t ait             :1,
14261                 device          :1,
14262                 abs             :1,
14263                 ulpbot          :1,
14264                 prth            :1,
14265                 ponej           :1,
14266                 syslogalive     :2;
14267         uchar_t span;
14268         uchar_t mic             :1,
14269                 worm            :1,
14270                                 :6;
14271         uchar_t                 :7,
14272                 worm_cap        :1;
14273         uint32_t                :32;
14274 #endif
14275 }ait_dev_con;
14276 
14277 #define AIT_DEV_PAGE 0x31
14278 static writablity
14279 st_is_sony_worm(struct scsi_tape *un)
14280 {
14281         int result;
14282         writablity wrt;
14283         ait_dev_con *ait_conf;
14284 
14285         ST_FUNC(ST_DEVINFO, st_is_sony_worm);
14286 
14287         ait_conf = kmem_zalloc(sizeof (ait_dev_con), KM_SLEEP);
14288 
14289         result = st_gen_mode_sense(un, st_uscsi_cmd, AIT_DEV_PAGE,
14290             (struct seq_mode *)ait_conf, sizeof (ait_dev_con));
14291 
14292         if (result == 0) {
14293 
14294                 if (ait_conf->pagecode != AIT_DEV_PAGE) {
14295                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14296                             "returned page 0x%x not 0x%x AIT_DEV_PAGE\n",
14297                             ait_conf->pagecode, AIT_DEV_PAGE);
14298                         wrt = RDWR;
14299                         un->un_wormable = st_is_not_wormable;
14300 
14301                 } else if (ait_conf->worm_cap) {
14302 
14303                         un->un_wormable = st_is_sony_worm;
14304 
14305                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14306                             "Drives is WORMable\n");
14307                         if (ait_conf->worm) {
14308                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14309                                     "Media is WORM\n");
14310                                 wrt = WORM;
14311                         } else {
14312                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14313                                     "Media is not WORM\n");
14314                                 wrt = RDWR;
14315                         }
14316 
14317                 } else {
14318                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14319                             "Drives not is WORMable\n");
14320                         wrt = RDWR;
14321                         /* No further checking required */
14322                         un->un_dp->options &= ~ST_WORMABLE;
14323                 }
14324 
14325         } else {
14326 
14327                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14328                     "AIT device config mode sense page read command failed"
14329                     " result = %d ", result);
14330                 wrt = FAILED;
14331                 un->un_wormable = st_is_not_wormable;
14332         }
14333 
14334         kmem_free(ait_conf, sizeof (ait_dev_con));
14335         return (wrt);
14336 }
14337 
14338 static writablity
14339 st_is_drive_worm(struct scsi_tape *un)
14340 {
14341         writablity wrt;
14342 
14343         ST_FUNC(ST_DEVINFO, st_is_sony_worm);
14344 
14345         switch (un->un_dp->type) {
14346         case MT_ISDLT:
14347                 wrt = st_is_dlt_worm(un);
14348                 break;
14349 
14350         case MT_ISSTK9840:
14351                 wrt = st_is_stk_worm(un);
14352                 break;
14353 
14354         case MT_IS8MM:
14355         case MT_ISAIT:
14356                 wrt = st_is_sony_worm(un);
14357                 break;
14358 
14359         case MT_LTO:
14360                 if (strncmp("HP ", un->un_dp->vid, 3) == 0) {
14361                         wrt = st_is_hp_lto_worm(un);
14362                 } else {
14363                         wrt = st_is_t10_worm(un);
14364                 }
14365                 break;
14366 
14367         case MT_ISDAT:
14368                 if (strncmp("HP ", un->un_dp->vid, 3) == 0) {
14369                         wrt = st_is_hp_dat_worm(un);
14370                 } else {
14371                         wrt = st_is_t10_worm(un);
14372                 }
14373                 break;
14374 
14375         default:
14376                 wrt = FAILED;
14377                 break;
14378         }
14379 
14380         /*
14381          * If any of the above failed try the t10 standard method.
14382          */
14383         if (wrt == FAILED) {
14384                 wrt = st_is_t10_worm(un);
14385         }
14386 
14387         /*
14388          * Unknown method for detecting WORM media.
14389          */
14390         if (wrt == FAILED) {
14391                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14392                     "Unknown method for WORM media detection\n");
14393                 wrt = RDWR;
14394                 un->un_dp->options &= ~ST_WORMABLE;
14395         }
14396 
14397         return (wrt);
14398 }
14399 
14400 static int
14401 st_read_attributes(struct scsi_tape *un, uint16_t attribute, void *pnt,
14402     size_t size, ubufunc_t bufunc)
14403 {
14404         char cdb[CDB_GROUP4];
14405         int result;
14406         struct uscsi_cmd *cmd;
14407         struct scsi_arq_status status;
14408 
14409         caddr_t buf = (caddr_t)pnt;
14410 
14411         ST_FUNC(ST_DEVINFO, st_read_attributes);
14412 
14413         if (un->un_sd->sd_inq->inq_ansi < 3) {
14414                 return (ENOTTY);
14415         }
14416 
14417         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14418 
14419         cdb[0] = (char)SCMD_READ_ATTRIBUTE;
14420         cdb[1] = 0;
14421         cdb[2] = 0;
14422         cdb[3] = 0;
14423         cdb[4] = 0;
14424         cdb[5] = 0;
14425         cdb[6] = 0;
14426         cdb[7] = 0;
14427         cdb[8] = (char)(attribute >> 8);
14428         cdb[9] = (char)(attribute);
14429         cdb[10] = (char)(size >> 24);
14430         cdb[11] = (char)(size >> 16);
14431         cdb[12] = (char)(size >> 8);
14432         cdb[13] = (char)(size);
14433         cdb[14] = 0;
14434         cdb[15] = 0;
14435 
14436 
14437         cmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE | USCSI_DIAGNOSE;
14438         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14439         cmd->uscsi_cdb = &cdb[0];
14440         cmd->uscsi_bufaddr = (caddr_t)buf;
14441         cmd->uscsi_buflen = size;
14442         cmd->uscsi_cdblen = sizeof (cdb);
14443         cmd->uscsi_rqlen = sizeof (status);
14444         cmd->uscsi_rqbuf = (caddr_t)&status;
14445 
14446         result = bufunc(un, cmd, FKIOCTL);
14447 
14448         if (result != 0 || cmd->uscsi_status != 0) {
14449                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
14450                     "st_read_attribute failed: result %d status %d\n",
14451                     result, cmd->uscsi_status);
14452                 /*
14453                  * If this returns invalid operation code don't try again.
14454                  */
14455                 if (un->un_sd->sd_sense->es_key == KEY_ILLEGAL_REQUEST &&
14456                     un->un_sd->sd_sense->es_add_code == 0x20) {
14457                         result = ENOTTY;
14458                 } else if (result == 0) {
14459                         result = EIO;
14460                 }
14461 
14462         } else {
14463 
14464                 /*
14465                  * The attribute retured should match the attribute requested.
14466                  */
14467                 if (buf[4] != cdb[8] || buf[5] != cdb[9]) {
14468                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14469                             "st_read_attribute got wrong data back expected "
14470                             "0x%x got 0x%x\n", attribute, buf[6] << 8 | buf[7]);
14471                         st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
14472                             "bad? data", buf, size);
14473                         result = EIO;
14474                 }
14475         }
14476 
14477         kmem_free(cmd, sizeof (struct uscsi_cmd));
14478 
14479         return (result);
14480 }
14481 
14482 static int
14483 st_get_special_inquiry(struct scsi_tape *un, uchar_t size, caddr_t dest,
14484     uchar_t page)
14485 {
14486         char cdb[CDB_GROUP0];
14487         struct scsi_extended_sense *sense;
14488         struct uscsi_cmd *cmd;
14489         int result;
14490 
14491         ST_FUNC(ST_DEVINFO, st_get_special_inquiry);
14492 
14493         cdb[0] = SCMD_INQUIRY;
14494         cdb[1] = page ? 1 : 0;
14495         cdb[2] = page;
14496         cdb[3] = 0;
14497         cdb[4] = size;
14498         cdb[5] = 0;
14499 
14500         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14501         sense = kmem_alloc(sizeof (struct scsi_extended_sense), KM_SLEEP);
14502 
14503         cmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE;
14504         cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14505         cmd->uscsi_cdb = &cdb[0];
14506         cmd->uscsi_bufaddr = dest;
14507         cmd->uscsi_buflen = size;
14508         cmd->uscsi_cdblen = CDB_GROUP0;
14509         cmd->uscsi_rqlen = sizeof (struct scsi_extended_sense);
14510         cmd->uscsi_rqbuf = (caddr_t)sense;
14511 
14512         result = st_uscsi_cmd(un, cmd, FKIOCTL);
14513 
14514         if (result != 0 || cmd->uscsi_status != 0) {
14515                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14516                     "st_get_special_inquiry() failed for page %x", page);
14517                 if (result == 0) {
14518                         result = EIO;
14519                 }
14520         }
14521 
14522         kmem_free(sense, sizeof (struct scsi_extended_sense));
14523         kmem_free(cmd, sizeof (struct uscsi_cmd));
14524 
14525         return (result);
14526 }
14527 
14528 
14529 static int
14530 st_update_block_pos(struct scsi_tape *un, bufunc_t bf, int post_space)
14531 {
14532         int rval = ENOTTY;
14533         uchar_t status = un->un_status;
14534         posmode previous_pmode = un->un_running.pmode;
14535 
14536         ST_FUNC(ST_DEVINFO, st_update_block_pos);
14537 
14538         while (un->un_read_pos_type != NO_POS) {
14539                 rval = bf(un, SCMD_READ_POSITION, 32, SYNC_CMD);
14540 
14541                 /*
14542                  * If read position command returned good status
14543                  * Parse the data to see if the position can be interpreted.
14544                  */
14545                 if ((rval == 0) &&
14546                     ((rval = st_interpret_read_pos(un, &un->un_pos,
14547                     un->un_read_pos_type, 32, (caddr_t)un->un_read_pos_data,
14548                     post_space)) == 0)) {
14549                         /*
14550                          * Update the running position as well if un_pos was
14551                          * ok. But only if recovery is enabled.
14552                          */
14553                         if (st_recov_sz != sizeof (recov_info)) {
14554                                 break;
14555                         }
14556                         rval = st_interpret_read_pos(un, &un->un_running,
14557                             un->un_read_pos_type, 32,
14558                             (caddr_t)un->un_read_pos_data, post_space);
14559                         un->un_status = status;
14560                         break;
14561                 } else if (un->un_status == KEY_UNIT_ATTENTION) {
14562                         un->un_running.pmode = previous_pmode;
14563                         continue;
14564                 } else if (un->un_status != KEY_ILLEGAL_REQUEST) {
14565                         scsi_log(ST_DEVINFO, st_label, CE_NOTE,
14566                             "st_update_block_pos() read position cmd 0x%x"
14567                             " returned 0x%x un_status = %d",
14568                             un->un_read_pos_type, rval, un->un_status);
14569                         /* ENOTTY means it read garbage. try something else. */
14570                         if (rval == ENOTTY) {
14571                                 rval = EIO; /* so ENOTTY is not final rval */
14572                         } else {
14573                                 break;
14574                         }
14575                 } else {
14576                         ST_DEBUG4(ST_DEVINFO, st_label, CE_NOTE,
14577                             "st_update_block_pos() read position cmd %x"
14578                             " returned %x", un->un_read_pos_type, rval);
14579                         un->un_running.pmode = previous_pmode;
14580                 }
14581 
14582                 switch (un->un_read_pos_type) {
14583                 case SHORT_POS:
14584                         un->un_read_pos_type = NO_POS;
14585                         break;
14586 
14587                 case LONG_POS:
14588                         un->un_read_pos_type = EXT_POS;
14589                         break;
14590 
14591                 case EXT_POS:
14592                         un->un_read_pos_type = SHORT_POS;
14593                         break;
14594 
14595                 default:
14596                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
14597                             "Unexpected read position type 0x%x",
14598                             un->un_read_pos_type);
14599                 }
14600                 un->un_status = KEY_NO_SENSE;
14601         }
14602 
14603         return (rval);
14604 }
14605 
14606 static int
14607 st_get_read_pos(struct scsi_tape *un, buf_t *bp)
14608 {
14609         int result;
14610         size_t d_sz;
14611         caddr_t pos_info;
14612         struct uscsi_cmd *cmd = (struct uscsi_cmd *)bp->b_back;
14613 
14614         ST_FUNC(ST_DEVINFO, st_get_read_pos);
14615 
14616         if (cmd->uscsi_bufaddr == NULL || cmd->uscsi_buflen <= 0) {
14617                 return (0);
14618         }
14619 
14620         if (bp_mapin_common(bp, VM_NOSLEEP) == NULL) {
14621 
14622                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14623                     "bp_mapin_common() failed");
14624 
14625                 return (EIO);
14626         }
14627 
14628         d_sz = bp->b_bcount - bp->b_resid;
14629         if (d_sz == 0) {
14630                 bp_mapout(bp);
14631                 return (EIO);
14632         }
14633 
14634         /*
14635          * Copy the buf to a double-word aligned memory that can hold the
14636          * tape_position_t data structure.
14637          */
14638         if ((pos_info = kmem_alloc(d_sz, KM_NOSLEEP)) == NULL) {
14639                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14640                     "kmem_alloc() failed");
14641                 bp_mapout(bp);
14642                 return (EIO);
14643         }
14644         bcopy(bp->b_un.b_addr, pos_info, d_sz);
14645 
14646 #ifdef STDEBUG
14647         if ((st_debug & 0x7) > 2) {
14648                 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
14649                     "st_get_read_pos() position info",
14650                     pos_info, bp->b_bcount);
14651         }
14652 #endif
14653 
14654         result = st_interpret_read_pos(un, &un->un_pos, cmd->uscsi_cdb[1],
14655             d_sz, pos_info, 0);
14656 
14657         COPY_POS(&un->un_running, &un->un_pos);
14658 
14659         kmem_free(pos_info, d_sz);
14660         bp_mapout(bp);
14661 
14662         return (result);
14663 }
14664 
14665 #if defined(_BIG_ENDIAN)
14666 
14667 #define FIX_ENDIAN16(x)
14668 #define FIX_ENDIAN32(x)
14669 #define FIX_ENDIAN64(x)
14670 
14671 #elif defined(_LITTLE_ENDIAN)
14672 
14673 static void
14674 st_swap16(uint16_t *val)
14675 {
14676         uint16_t tmp;
14677 
14678         tmp = (*val >>  8) & 0xff;
14679         tmp |= (*val <<  8) & 0xff00;
14680 
14681         *val = tmp;
14682 }
14683 
14684 static void
14685 st_swap32(uint32_t *val)
14686 {
14687         uint32_t tmp;
14688 
14689         tmp =  (*val >> 24) & 0xff;
14690         tmp |= (*val >>  8) & 0xff00;
14691         tmp |= (*val <<  8) & 0xff0000;
14692         tmp |= (*val << 24) & 0xff000000;
14693 
14694         *val = tmp;
14695 }
14696 
14697 static void
14698 st_swap64(uint64_t *val)
14699 {
14700         uint32_t low;
14701         uint32_t high;
14702 
14703         low =  (uint32_t)(*val);
14704         high = (uint32_t)(*val >> 32);
14705 
14706         st_swap32(&low);
14707         st_swap32(&high);
14708 
14709         *val =  high;
14710         *val |= ((uint64_t)low << 32);
14711 }
14712 
14713 #define FIX_ENDIAN16(x) st_swap16(x)
14714 #define FIX_ENDIAN32(x) st_swap32(x)
14715 #define FIX_ENDIAN64(x) st_swap64(x)
14716 #endif
14717 
14718 /*
14719  * st_interpret_read_pos()
14720  *
14721  * Returns:
14722  *      0       If secsessful.
14723  *      EIO     If read postion responce data was unuseable or invalid.
14724  *      ERANGE  If the position of the drive is too large for the read_p_type.
14725  *      ENOTTY  If the responce data looks invalid for the read position type.
14726  */
14727 
14728 static int
14729 st_interpret_read_pos(struct scsi_tape const *un, tapepos_t *dest,
14730     read_p_types type, size_t data_sz, const caddr_t responce, int post_space)
14731 {
14732         int rval = 0;
14733         int flag = 0;
14734         tapepos_t org;
14735 
14736         ST_FUNC(ST_DEVINFO, st_interpret_read_pos);
14737 
14738         /*
14739          * We expect the position value to change after a space command.
14740          * So if post_space is set we don't print out what has changed.
14741          */
14742         if ((dest != &un->un_pos) && (post_space == 0) &&
14743             (st_recov_sz == sizeof (recov_info))) {
14744                 COPY_POS(&org, dest);
14745                 flag = 1;
14746         }
14747 
14748         /*
14749          * See what kind of read position was requested.
14750          */
14751         switch (type) {
14752 
14753         case SHORT_POS: /* Short data format */
14754         {
14755                 tape_position_t *pos_info = (tape_position_t *)responce;
14756                 uint32_t value;
14757 
14758                 /* If reserved fields are non zero don't use the data */
14759                 if (pos_info->reserved0 || pos_info->reserved1 ||
14760                     pos_info->reserved2[0] || pos_info->reserved2[1] ||
14761                     pos_info->reserved3) {
14762                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14763                             "Invalid Read Short Position Data returned\n");
14764                         rval = EIO;
14765                         break;
14766                 }
14767                 /*
14768                  * Position is to large to use this type of read position.
14769                  */
14770                 if (pos_info->posi_err == 1) {
14771                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14772                             "Drive reported position error\n");
14773                         rval = ERANGE;
14774                         break;
14775                 }
14776                 /*
14777                  * If your at the begining of partition and end at the same
14778                  * time it's very small partition or bad data.
14779                  */
14780                 if (pos_info->begin_of_part && pos_info->end_of_part) {
14781                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14782                             "SHORT_POS returned begin and end of"
14783                             " partition\n");
14784                         rval = EIO;
14785                         break;
14786                 }
14787 
14788                 if (pos_info->blk_posi_unkwn == 0) {
14789 
14790                         value = pos_info->host_block;
14791                         FIX_ENDIAN32(&value);
14792 
14793                         /*
14794                          * If the tape is rewound the host blcok should be 0.
14795                          */
14796                         if ((pos_info->begin_of_part == 1) &&
14797                             (value != 0)) {
14798                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14799                                     "SHORT_POS returned begin of partition"
14800                                     " but host block was 0x%x\n", value);
14801                                 rval = EIO;
14802                                 break;
14803                         }
14804 
14805                         if (dest->lgclblkno != value) {
14806                                 if (flag)
14807                                         flag++;
14808                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14809                                     "SHORT_POS current logical 0x%"PRIx64" read"
14810                                     " 0x%x\n", dest->lgclblkno, value);
14811                         }
14812 
14813                         dest->lgclblkno = (uint64_t)value;
14814 
14815                         /*
14816                          * If the begining of partition is true and the
14817                          * block number is zero we will beleive that it is
14818                          * rewound. Promote the pmode to legacy.
14819                          */
14820                         if ((pos_info->begin_of_part == 1) &&
14821                             (value == 0)) {
14822                                 dest->blkno = 0;
14823                                 dest->fileno = 0;
14824                                 if (dest->pmode != legacy)
14825                                         dest->pmode = legacy;
14826                         /*
14827                          * otherwise if the pmode was invalid,
14828                          * promote it to logical.
14829                          */
14830                         } else if (dest->pmode == invalid) {
14831                                 dest->pmode = logical;
14832                         }
14833 
14834                         if (dest->partition != pos_info->partition_number) {
14835                                 if (flag)
14836                                         flag++;
14837                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14838                                     "SHORT_POS current partition %d read %d\n",
14839                                     dest->partition,
14840                                     pos_info->partition_number);
14841                         }
14842 
14843                         dest->partition = pos_info->partition_number;
14844 
14845                 } else {
14846                         dest->pmode = invalid;
14847                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14848                             "Tape drive reported block position as unknown\n");
14849                 }
14850                 break;
14851         }
14852 
14853         case LONG_POS: /* Long data format */
14854         {
14855                 uint64_t value;
14856                 tape_position_long_t *long_pos_info =
14857                     (tape_position_long_t *)responce;
14858 
14859                 /* If reserved fields are non zero don't use the data */
14860                 if ((long_pos_info->reserved0) ||
14861                     (long_pos_info->reserved1) ||
14862                     (long_pos_info->reserved2)) {
14863                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14864                             "Invalid Read Long Position Data returned\n");
14865                         rval = ENOTTY;
14866                         break;
14867                 }
14868 
14869                 /* Is position Valid */
14870                 if (long_pos_info->blk_posi_unkwn == 0) {
14871                         uint32_t part;
14872 
14873                         value = long_pos_info->block_number;
14874                         FIX_ENDIAN64(&value);
14875 
14876                         /*
14877                          * If it says we are at the begining of partition
14878                          * the block value better be 0.
14879                          */
14880                         if ((long_pos_info->begin_of_part == 1) &&
14881                             (value != 0)) {
14882                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14883                                     "LONG_POS returned begin of partition but"
14884                                     " block number was 0x%"PRIx64"\n", value);
14885                                 rval = ENOTTY;
14886                                 break;
14887                         }
14888                         /*
14889                          * Can't be at the start and the end of the partition
14890                          * at the same time if the partition is larger the 0.
14891                          */
14892                         if (long_pos_info->begin_of_part &&
14893                             long_pos_info->end_of_part) {
14894                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14895                                     "LONG_POS returned begin and end of"
14896                                     " partition\n");
14897                                 rval = ENOTTY;
14898                                 break;
14899                         }
14900 
14901                         /*
14902                          * If the logical block number is not what we expected.
14903                          */
14904                         if (dest->lgclblkno != value) {
14905                                 if (flag)
14906                                         flag++;
14907                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14908                                     "LONG_POS current logical 0x%"PRIx64
14909                                     " read 0x%"PRIx64"\n",
14910                                     dest->lgclblkno, value);
14911                         }
14912                         dest->lgclblkno = value;
14913 
14914                         /*
14915                          * If the begining of partition is true and the
14916                          * block number is zero we will beleive that it is
14917                          * rewound. Promote the pmode to legacy.
14918                          */
14919                         if ((long_pos_info->begin_of_part == 1) &&
14920                             (long_pos_info->block_number == 0)) {
14921                                 dest->blkno = 0;
14922                                 dest->fileno = 0;
14923                                 if (dest->pmode != legacy)
14924                                         dest->pmode = legacy;
14925                         /*
14926                          * otherwise if the pmode was invalid,
14927                          * promote it to logical.
14928                          */
14929                         } else if (dest->pmode == invalid) {
14930                                 dest->pmode = logical;
14931                         }
14932 
14933                         part = long_pos_info->partition;
14934                         FIX_ENDIAN32(&part);
14935                         if (dest->partition != part) {
14936                                 if (flag)
14937                                         flag++;
14938                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14939                                     "LONG_POS current partition %d"
14940                                     " read %d\n", dest->partition, part);
14941                         }
14942                         dest->partition = part;
14943                 } else {
14944                         /*
14945                          * If the drive doesn't know location,
14946                          * we don't either.
14947                          */
14948                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14949                             "Tape drive reported block position as unknown\n");
14950                         dest->pmode = invalid;
14951                 }
14952 
14953                 /* Is file position valid */
14954                 if (long_pos_info->mrk_posi_unkwn == 0) {
14955                         value = long_pos_info->file_number;
14956                         FIX_ENDIAN64(&value);
14957                         /*
14958                          * If it says we are at the begining of partition
14959                          * the block value better be 0.
14960                          */
14961                         if ((long_pos_info->begin_of_part == 1) &&
14962                             (value != 0)) {
14963                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14964                                     "LONG_POS returned begin of partition but"
14965                                     " block number was 0x%"PRIx64"\n", value);
14966                                 rval = ENOTTY;
14967                                 break;
14968                         }
14969                         if (((dest->pmode == legacy) ||
14970                             (dest->pmode == logical)) &&
14971                             (dest->fileno != value)) {
14972                                 if (flag)
14973                                         flag++;
14974                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14975                                     "LONG_POS fileno 0x%"PRIx64
14976                                     " not un_pos %x\n", value,
14977                                     dest->fileno);
14978                         } else if (dest->pmode == invalid) {
14979                                 dest->pmode = logical;
14980                         }
14981                         dest->fileno = (int32_t)value;
14982                 }
14983 
14984                 if (dest->pmode != invalid && long_pos_info->end_of_part) {
14985                         dest->eof = ST_EOT;
14986                 }
14987 
14988                 break;
14989         }
14990 
14991         case EXT_POS: /* Extended data format */
14992         {
14993                 uint64_t value;
14994                 uint16_t len;
14995                 tape_position_ext_t *ext_pos_info =
14996                     (tape_position_ext_t *)responce;
14997 
14998                 /* Make sure that there is enough data there */
14999                 if (data_sz < 16) {
15000                         break;
15001                 }
15002 
15003                 /* If reserved fields are non zero don't use the data */
15004                 if (ext_pos_info->reserved0 || ext_pos_info->reserved1) {
15005                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15006                             "EXT_POS reserved fields not zero\n");
15007                         rval = ENOTTY;
15008                         break;
15009                 }
15010 
15011                 /*
15012                  * In the unlikely event of overflowing 64 bits of position.
15013                  */
15014                 if (ext_pos_info->posi_err != 0) {
15015                         rval = ERANGE;
15016                         break;
15017                 }
15018 
15019                 len = ext_pos_info->parameter_len;
15020                 FIX_ENDIAN16(&len);
15021 
15022                 if (len != 0x1c) {
15023                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15024                             "EXT_POS parameter_len should be 0x1c was 0x%x\n",
15025                             len);
15026                         rval = ENOTTY;
15027                         break;
15028                 }
15029 
15030                 /* Is block position information valid */
15031                 if (ext_pos_info->blk_posi_unkwn == 0) {
15032 
15033                         value = ext_pos_info->host_block;
15034                         FIX_ENDIAN64(&value);
15035                         if ((ext_pos_info->begin_of_part == 1) &&
15036                             (value != 0)) {
15037                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15038                                     "EXT_POS returned begining of partition but"
15039                                     " the host block was 0x%"PRIx64"\n", value);
15040                                 rval = ENOTTY;
15041                                 break;
15042                         }
15043 
15044                         if (dest->lgclblkno != value) {
15045                                 if (flag)
15046                                         flag++;
15047                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15048                                     "EXT_POS current logical 0x%"PRIx64
15049                                     " read 0x%"PRIx64"\n",
15050                                     dest->lgclblkno, value);
15051                         }
15052                         dest->lgclblkno = value;
15053 
15054                         /*
15055                          * If the begining of partition is true and the
15056                          * block number is zero we will beleive that it is
15057                          * rewound. Promote the pmode to legacy.
15058                          */
15059                         if ((ext_pos_info->begin_of_part == 1) &&
15060                             (ext_pos_info->host_block == 0)) {
15061                                 dest->blkno = 0;
15062                                 dest->fileno = 0;
15063                                 if (dest->pmode != legacy) {
15064                                         dest->pmode = legacy;
15065                                 }
15066                         /*
15067                          * otherwise if the pmode was invalid,
15068                          * promote it to logical.
15069                          */
15070                         } else if (dest->pmode == invalid) {
15071                                 dest->pmode = logical;
15072                         }
15073 
15074                         if (dest->partition != ext_pos_info->partition) {
15075                                 if (flag)
15076                                         flag++;
15077                                 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15078                                     "EXT_POS current partition %d read %d\n",
15079                                     dest->partition,
15080                                     ext_pos_info->partition);
15081                         }
15082                         dest->partition = ext_pos_info->partition;
15083 
15084                 } else {
15085                         dest->pmode = invalid;
15086                 }
15087                 break;
15088         }
15089 
15090         default:
15091                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
15092                     "Got unexpected SCMD_READ_POSITION type %d\n", type);
15093                 rval = EIO;
15094         }
15095 
15096         if ((flag > 1) && (rval == 0) && (org.pmode != invalid)) {
15097                 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
15098                     "position read in", &org);
15099                 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
15100                     "position read out", dest);
15101         }
15102 
15103         return (rval);
15104 }
15105 
15106 static int
15107 st_logical_block_locate(struct scsi_tape *un, ubufunc_t ubf, tapepos_t *pos,
15108     uint64_t lblk, uchar_t partition)
15109 {
15110         int rval;
15111         char cdb[CDB_GROUP4];
15112         struct uscsi_cmd *cmd;
15113         struct scsi_extended_sense sense;
15114         bufunc_t bf = (ubf == st_uscsi_cmd) ? st_cmd : st_rcmd;
15115 
15116         ST_FUNC(ST_DEVINFO, st_logical_block_locate);
15117         /*
15118          * Not sure what to do when doing recovery and not wanting
15119          * to update un_pos
15120          */
15121 
15122         cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
15123 
15124         if (lblk <= INT32_MAX) {
15125                 cmd->uscsi_cdblen = CDB_GROUP1;
15126                 cdb[0] = SCMD_LOCATE;
15127                 cdb[1] = pos->partition == partition ? 0 : 2;
15128                 cdb[2] = 0;
15129                 cdb[3] = (char)(lblk >> 24);
15130                 cdb[4] = (char)(lblk >> 16);
15131                 cdb[5] = (char)(lblk >> 8);
15132                 cdb[6] = (char)(lblk);
15133                 cdb[7] = 0;
15134                 cdb[8] = partition;
15135                 cdb[9] = 0;
15136         } else {
15137                 /*
15138                  * If the drive doesn't give a 64 bit read position data
15139                  * it is unlikely it will accept 64 bit locates.
15140                  */
15141                 if (un->un_read_pos_type != LONG_POS) {
15142                         kmem_free(cmd, sizeof (struct uscsi_cmd));
15143                         return (ERANGE);
15144                 }
15145                 cmd->uscsi_cdblen = CDB_GROUP4;
15146                 cdb[0] = (char)SCMD_LOCATE_G4;
15147                 cdb[1] = pos->partition == partition ? 0 : 2;
15148                 cdb[2] = 0;
15149                 cdb[3] = partition;
15150                 cdb[4] = (char)(lblk >> 56);
15151                 cdb[5] = (char)(lblk >> 48);
15152                 cdb[6] = (char)(lblk >> 40);
15153                 cdb[7] = (char)(lblk >> 32);
15154                 cdb[8] = (char)(lblk >> 24);
15155                 cdb[9] = (char)(lblk >> 16);
15156                 cdb[10] = (char)(lblk >> 8);
15157                 cdb[11] = (char)(lblk);
15158                 cdb[12] = 0;
15159                 cdb[13] = 0;
15160                 cdb[14] = 0;
15161                 cdb[15] = 0;
15162         }
15163 
15164 
15165         cmd->uscsi_flags = USCSI_WRITE | USCSI_DIAGNOSE | USCSI_RQENABLE;
15166         cmd->uscsi_rqbuf = (caddr_t)&sense;
15167         cmd->uscsi_rqlen = sizeof (sense);
15168         cmd->uscsi_timeout = un->un_dp->space_timeout;
15169         cmd->uscsi_cdb = cdb;
15170 
15171         rval = ubf(un, cmd, FKIOCTL);
15172 
15173         pos->pmode = logical;
15174         pos->eof = ST_NO_EOF;
15175 
15176         if (lblk > INT32_MAX) {
15177                 /*
15178                  * XXX This is a work around till we handle Descriptor format
15179                  * sense data. Since we are sending a command where the standard
15180                  * sense data can not correctly represent a correct residual in
15181                  * 4 bytes.
15182                  */
15183                 if (un->un_status == KEY_ILLEGAL_REQUEST) {
15184                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15185                             "Big LOCATE ILLEGAL_REQUEST: rval = %d\n", rval);
15186                         /* Doesn't like big locate command */
15187                         un->un_status = 0;
15188                         rval = ERANGE;
15189                 } else if ((un->un_pos.pmode == invalid) || (rval != 0)) {
15190                         /* Aborted big locate command */
15191                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15192                             "Big LOCATE resulted in invalid pos: rval = %d\n",
15193                             rval);
15194                         un->un_status = 0;
15195                         rval = EIO;
15196                 } else if (st_update_block_pos(un, bf, 1)) {
15197                         /* read position failed */
15198                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15199                             "Big LOCATE and read pos: rval = %d\n", rval);
15200                         rval = EIO;
15201                 } else if (lblk > un->un_pos.lgclblkno) {
15202                         /* read position worked but position was not expected */
15203                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15204                             "Big LOCATE and recover read less then desired 0x%"
15205                             PRIx64"\n", un->un_pos.lgclblkno);
15206                         un->un_err_resid = lblk - un->un_pos.lgclblkno;
15207                         un->un_status = KEY_BLANK_CHECK;
15208                         rval = ESPIPE;
15209                 } else if (lblk == un->un_pos.lgclblkno) {
15210                         /* read position was what was expected */
15211                         scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15212                             "Big LOCATE and recover seems to have worked\n");
15213                         un->un_err_resid = 0;
15214                         rval = 0;
15215                 } else {
15216                         ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
15217                             "BIGLOCATE end up going backwards");
15218                         un->un_err_resid = lblk;
15219                         rval = EIO;
15220                 }
15221 
15222         } else if (rval == 0) {
15223                 /* Worked as requested */
15224                 pos->lgclblkno = lblk;
15225 
15226         } else if (((cmd->uscsi_status & ST_STATUS_MASK) == STATUS_CHECK) &&
15227             (cmd->uscsi_resid != 0)) {
15228                 /* Got part way there but wasn't enough blocks on tape */
15229                 pos->lgclblkno = lblk - cmd->uscsi_resid;
15230                 un->un_err_resid = cmd->uscsi_resid;
15231                 un->un_status = KEY_BLANK_CHECK;
15232                 rval = ESPIPE;
15233 
15234         } else if (st_update_block_pos(un, bf, 1) == 0) {
15235                 /* Got part way there but drive didn't tell what we missed by */
15236                 un->un_err_resid = lblk - pos->lgclblkno;
15237                 un->un_status = KEY_BLANK_CHECK;
15238                 rval = ESPIPE;
15239 
15240         } else {
15241                 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15242                     "Failed LOCATE and recover pos: rval = %d status = %d\n",
15243                     rval, cmd->uscsi_status);
15244                 un->un_err_resid = lblk;
15245                 un->un_status = KEY_ILLEGAL_REQUEST;
15246                 pos->pmode = invalid;
15247                 rval = EIO;
15248         }
15249 
15250         kmem_free(cmd, sizeof (struct uscsi_cmd));
15251 
15252         return (rval);
15253 }
15254 
15255 static int
15256 st_mtfsf_ioctl(struct scsi_tape *un, int64_t files)
15257 {
15258         int rval;
15259 
15260         ST_FUNC(ST_DEVINFO, st_mtfsf_ioctl);
15261 
15262 
15263         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15264             "st_mtfsf_ioctl: count=%"PRIx64", eof=%x\n", files, un->un_pos.eof);
15265 #if 0
15266         if ((IN_EOF(un->un_pos)) && (files == 1)) {
15267                 un->un_pos.fileno++;
15268                 un->un_pos.blkno = 0;
15269                 return (0);
15270         }
15271 #endif
15272         /* pmode == invalid already handled */
15273         if (un->un_pos.pmode == legacy) {
15274                 /*
15275                  * forward space over filemark
15276                  *
15277                  * For ASF we allow a count of 0 on fsf which means
15278                  * we just want to go to beginning of current file.
15279                  * Equivalent to "nbsf(0)" or "bsf(1) + fsf".
15280                  * Allow stepping over double fmk with reel
15281                  */
15282                 if ((un->un_pos.eof >= ST_EOT) &&
15283                     (files > 0) &&
15284                     ((un->un_dp->options & ST_REEL) == 0)) {
15285                         /* we're at EOM */
15286                         un->un_err_resid = files;
15287                         un->un_status = KEY_BLANK_CHECK;
15288                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15289                             "st_mtfsf_ioctl: EIO : MTFSF at EOM");
15290                         return (EIO);
15291                 }
15292 
15293                 /*
15294                  * physical tape position may not be what we've been
15295                  * telling the user; adjust the request accordingly
15296                  */
15297                 if (IN_EOF(un->un_pos)) {
15298                         un->un_pos.fileno++;
15299                         un->un_pos.blkno = 0;
15300                         /*
15301                          * For positive direction case, we're now covered.
15302                          * For zero or negative direction, we're covered
15303                          * (almost)
15304                          */
15305                         files--;
15306                 }
15307 
15308         }
15309 
15310         if (st_check_density_or_wfm(un->un_dev, 1, B_READ, STEPBACK)) {
15311                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15312                     "st_mtfsf_ioctl: EIO : MTFSF density/wfm failed");
15313                 return (EIO);
15314         }
15315 
15316 
15317         /*
15318          * Forward space file marks.
15319          * We leave ourselves at block zero
15320          * of the target file number.
15321          */
15322         if (files < 0) {
15323                 rval = st_backward_space_files(un, -files, 0);
15324         } else {
15325                 rval = st_forward_space_files(un, files);
15326         }
15327 
15328         return (rval);
15329 }
15330 
15331 static int
15332 st_forward_space_files(struct scsi_tape *un, int64_t count)
15333 {
15334         int rval;
15335 
15336         ST_FUNC(ST_DEVINFO, st_forward_space_files);
15337 
15338         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15339             "fspace: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15340 
15341         ASSERT(count >= 0);
15342         ASSERT(un->un_pos.pmode != invalid);
15343 
15344         /*
15345          * A space with a count of zero means take me to the start of file.
15346          */
15347         if (count == 0) {
15348 
15349                 /* Hay look were already there */
15350                 if (un->un_pos.pmode == legacy && un->un_pos.blkno == 0) {
15351                         un->un_err_resid = 0;
15352                         COPY_POS(&un->un_err_pos, &un->un_pos);
15353                         return (0);
15354                 }
15355 
15356                 /*
15357                  * Well we are in the first file.
15358                  * A rewind will get to the start.
15359                  */
15360                 if (un->un_pos.pmode == legacy && un->un_pos.fileno == 0) {
15361                         rval = st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
15362 
15363                 /*
15364                  * Can we backspace to get there?
15365                  * This should work in logical mode.
15366                  */
15367                 } else if (un->un_dp->options & ST_BSF) {
15368                         rval = st_space_to_begining_of_file(un);
15369 
15370                 /*
15371                  * Can't back space but current file number is known,
15372                  * So rewind and space from the begining of the partition.
15373                  */
15374                 } else if (un->un_pos.pmode == legacy) {
15375                         rval = st_scenic_route_to_begining_of_file(un,
15376                             un->un_pos.fileno);
15377 
15378                 /*
15379                  * pmode is logical and ST_BSF is not set.
15380                  * The LONG_POS read position contains the fileno.
15381                  * If the read position works, rewind and space.
15382                  */
15383                 } else if (un->un_read_pos_type == LONG_POS) {
15384                         rval = st_cmd(un, SCMD_READ_POSITION, 0, SYNC_CMD);
15385                         if (rval) {
15386                                 /*
15387                                  * We didn't get the file position from the
15388                                  * read position command.
15389                                  * We are going to trust the drive to backspace
15390                                  * and then position after the filemark.
15391                                  */
15392                                 rval = st_space_to_begining_of_file(un);
15393                         }
15394                         rval = st_interpret_read_pos(un, &un->un_pos, LONG_POS,
15395                             32, (caddr_t)un->un_read_pos_data, 0);
15396                         if ((rval) && (un->un_pos.pmode == invalid)) {
15397                                 rval = st_space_to_begining_of_file(un);
15398                         } else {
15399                                 rval = st_scenic_route_to_begining_of_file(un,
15400                                     un->un_pos.fileno);
15401                         }
15402                 } else {
15403                         rval = EIO;
15404                 }
15405                 /*
15406                  * If something didn't work we are lost
15407                  */
15408                 if (rval != 0) {
15409                         un->un_pos.pmode = invalid;
15410                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15411                             "st_mtioctop : EIO : fspace pmode invalid");
15412 
15413                         rval = EIO;
15414                 }
15415 
15416         } else {
15417                 rval = st_space_fmks(un, count);
15418         }
15419 
15420         if (rval != EIO && count < 0) {
15421                 /*
15422                  * we came here with a count < 0; we now need
15423                  * to skip back to end up before the filemark
15424                  */
15425                 rval = st_backward_space_files(un, 1, 1);
15426         }
15427 
15428         return (rval);
15429 }
15430 
15431 static int
15432 st_scenic_route_to_begining_of_file(struct scsi_tape *un, int32_t fileno)
15433 {
15434         int rval;
15435 
15436         ST_FUNC(ST_DEVINFO, st_scenic_route_to_begining_of_file);
15437 
15438         if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15439                 rval = EIO;
15440         } else if (st_cmd(un, SCMD_SPACE, Fmk(fileno), SYNC_CMD)) {
15441                 rval = EIO;
15442         }
15443 
15444         return (rval);
15445 }
15446 
15447 static int
15448 st_space_to_begining_of_file(struct scsi_tape *un)
15449 {
15450         int rval;
15451 
15452         ST_FUNC(ST_DEVINFO, st_space_to_begining_of_file);
15453 
15454         /*
15455          * Back space of the file at the begining of the file.
15456          */
15457         rval = st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD);
15458         if (rval) {
15459                 rval = EIO;
15460                 return (rval);
15461         }
15462 
15463         /*
15464          * Other interesting answers might be crashed BOT which isn't bad.
15465          */
15466         if (un->un_status == SUN_KEY_BOT) {
15467                 return (rval);
15468         }
15469 
15470         un->un_running.pmode = invalid;
15471 
15472         /*
15473          * Now we are on the BOP side of the filemark. Forward space to
15474          * the EOM side and we are at the begining of the file.
15475          */
15476         rval = st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD);
15477         if (rval) {
15478                 rval = EIO;
15479         }
15480 
15481         return (rval);
15482 }
15483 
15484 static int
15485 st_mtfsr_ioctl(struct scsi_tape *un, int64_t count)
15486 {
15487 
15488         ST_FUNC(ST_DEVINFO, st_mtfsr_ioctl);
15489 
15490         /*
15491          * forward space to inter-record gap
15492          *
15493          */
15494 
15495         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15496             "st_ioctl_fsr: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15497 
15498         if (un->un_pos.pmode == legacy) {
15499                 /*
15500                  * If were are at end of tape and count is forward.
15501                  * Return blank check.
15502                  */
15503                 if ((un->un_pos.eof >= ST_EOT) && (count > 0)) {
15504                         /* we're at EOM */
15505                         un->un_err_resid = count;
15506                         un->un_status = KEY_BLANK_CHECK;
15507                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15508                             "st_mtfsr_ioctl: EIO : MTFSR eof > ST_EOT");
15509                         return (EIO);
15510                 }
15511 
15512                 /*
15513                  * If count is zero there is nothing to do.
15514                  */
15515                 if (count == 0) {
15516                         un->un_err_pos.fileno = un->un_pos.fileno;
15517                         un->un_err_pos.blkno = un->un_pos.blkno;
15518                         un->un_err_resid = 0;
15519                         if (IN_EOF(un->un_pos) && SVR4_BEHAVIOR) {
15520                                 un->un_status = SUN_KEY_EOF;
15521                         }
15522                         return (0);
15523                 }
15524 
15525                 /*
15526                  * physical tape position may not be what we've been
15527                  * telling the user; adjust the position accordingly
15528                  */
15529                 if (IN_EOF(un->un_pos)) {
15530                         daddr_t blkno = un->un_pos.blkno;
15531                         int fileno = un->un_pos.fileno;
15532 
15533                         optype lastop = un->un_lastop;
15534                         if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)
15535                             == -1) {
15536                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15537                                     "st_mtfsr_ioctl:EIO:MTFSR count && IN_EOF");
15538                                 return (EIO);
15539                         }
15540 
15541                         un->un_pos.blkno = blkno;
15542                         un->un_pos.fileno = fileno;
15543                         un->un_lastop = lastop;
15544                 }
15545         }
15546 
15547         if (st_check_density_or_wfm(un->un_dev, 1, B_READ, STEPBACK)) {
15548                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15549                     "st_mtfsr_ioctl: EIO : MTFSR st_check_den");
15550                 return (EIO);
15551         }
15552 
15553         return (st_space_records(un, count));
15554 }
15555 
15556 static int
15557 st_space_records(struct scsi_tape *un, int64_t count)
15558 {
15559         int64_t dblk;
15560         int rval = 0;
15561 
15562         ST_FUNC(ST_DEVINFO, st_space_records);
15563 
15564         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15565             "st_space_records: count=%"PRIx64", eof=%x\n",
15566             count, un->un_pos.eof);
15567 
15568         if (un->un_pos.pmode == logical) {
15569                 rval = st_cmd(un, SCMD_SPACE, Blk(count), SYNC_CMD);
15570                 if (rval != 0) {
15571                         rval = EIO;
15572                 }
15573                 return (rval);
15574         }
15575 
15576         dblk = count + un->un_pos.blkno;
15577 
15578         /* Already there */
15579         if (dblk == un->un_pos.blkno) {
15580                 un->un_err_resid = 0;
15581                 COPY_POS(&un->un_err_pos, &un->un_pos);
15582                 return (0);
15583         }
15584 
15585         /*
15586          * If the destination block is forward
15587          * or the drive will backspace records.
15588          */
15589         if (un->un_pos.blkno < dblk || (un->un_dp->options & ST_BSR)) {
15590                 /*
15591                  * If we're spacing forward, or the device can
15592                  * backspace records, we can just use the SPACE
15593                  * command.
15594                  */
15595                 dblk -= un->un_pos.blkno;
15596                 if (st_cmd(un, SCMD_SPACE, Blk(dblk), SYNC_CMD)) {
15597                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15598                             "st_space_records:EIO:space_records can't spc");
15599                         rval = EIO;
15600                 } else if (un->un_pos.eof >= ST_EOF_PENDING) {
15601                         /*
15602                          * check if we hit BOT/EOT
15603                          */
15604                         if (dblk < 0 && un->un_pos.eof == ST_EOM) {
15605                                 un->un_status = SUN_KEY_BOT;
15606                                 un->un_pos.eof = ST_NO_EOF;
15607                         } else if (dblk < 0 &&
15608                             un->un_pos.eof == ST_EOF_PENDING) {
15609                                 int residue = un->un_err_resid;
15610                                 /*
15611                                  * we skipped over a filemark
15612                                  * and need to go forward again
15613                                  */
15614                                 if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
15615                                         ST_DEBUG2(ST_DEVINFO, st_label,
15616                                             SCSI_DEBUG, "st_space_records: EIO"
15617                                             " : can't space #2");
15618                                         rval = EIO;
15619                                 }
15620                                 un->un_err_resid = residue;
15621                         }
15622                         if (rval == 0) {
15623                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15624                                     "st_space_records: EIO : space_rec rval"
15625                                     " == 0");
15626                                 rval = EIO;
15627                         }
15628                 }
15629         } else {
15630                 /*
15631                  * else we rewind, space forward across filemarks to
15632                  * the desired file, and then space records to the
15633                  * desired block.
15634                  */
15635 
15636                 int dfile = un->un_pos.fileno;       /* save current file */
15637 
15638                 if (dblk < 0) {
15639                         /*
15640                          * Wups - we're backing up over a filemark
15641                          */
15642                         if (un->un_pos.blkno != 0 &&
15643                             (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
15644                             st_cmd(un, SCMD_SPACE, Fmk(dfile), SYNC_CMD))) {
15645                                 un->un_pos.pmode = invalid;
15646                         }
15647                         un->un_err_resid = -dblk;
15648                         if (un->un_pos.fileno == 0 && un->un_pos.blkno == 0) {
15649                                 un->un_status = SUN_KEY_BOT;
15650                                 un->un_pos.eof = ST_NO_EOF;
15651                         } else if (un->un_pos.fileno > 0) {
15652                                 un->un_status = SUN_KEY_EOF;
15653                                 un->un_pos.eof = ST_NO_EOF;
15654                         }
15655                         COPY_POS(&un->un_err_pos, &un->un_pos);
15656                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15657                             "st_space_records:EIO:space_records : dblk < 0");
15658                         rval = EIO;
15659                 } else if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
15660                     st_cmd(un, SCMD_SPACE, Fmk(dfile), SYNC_CMD) ||
15661                     st_cmd(un, SCMD_SPACE, Blk(dblk), SYNC_CMD)) {
15662                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15663                             "st_space_records: EIO :space_records : rewind "
15664                             "and space failed");
15665                         un->un_pos.pmode = invalid;
15666                         rval = EIO;
15667                 }
15668         }
15669 
15670         return (rval);
15671 }
15672 
15673 static int
15674 st_mtbsf_ioctl(struct scsi_tape *un, int64_t files)
15675 {
15676         ST_FUNC(ST_DEVINFO, st_mtbsf_ioctl);
15677 
15678         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15679             "st_mtbsf_ioctl: count=%"PRIx64", eof=%x\n", files, un->un_pos.eof);
15680         /*
15681          * backward space of file filemark (1/2" and 8mm)
15682          * tape position will end on the beginning of tape side
15683          * of the desired file mark
15684          */
15685         if ((un->un_dp->options & ST_BSF) == 0) {
15686                 return (ENOTTY);
15687         }
15688 
15689         if (un->un_pos.pmode == legacy) {
15690 
15691                 /*
15692                  * If a negative count (which implies a forward space op)
15693                  * is specified, and we're at logical or physical eot,
15694                  * bounce the request.
15695                  */
15696 
15697                 if (un->un_pos.eof >= ST_EOT && files < 0) {
15698                         un->un_err_resid = files;
15699                         un->un_status = SUN_KEY_EOT;
15700                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15701                             "st_ioctl_mt_bsf : EIO : MTBSF : eof > ST_EOF");
15702                         return (EIO);
15703                 }
15704                 /*
15705                  * physical tape position may not be what we've been
15706                  * telling the user; adjust the request accordingly
15707                  */
15708                 if (IN_EOF(un->un_pos)) {
15709                         un->un_pos.fileno++;
15710                         un->un_pos.blkno = 0;
15711                         files++;
15712                         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15713                             "st_mtbsf_ioctl in eof: count=%"PRIx64", op=%x\n",
15714                             files, MTBSF);
15715 
15716                 }
15717         }
15718 
15719         if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
15720                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15721                     "st_ioctl : EIO : MTBSF : check den wfm");
15722                 return (EIO);
15723         }
15724 
15725         if (files <= 0) {
15726                 /*
15727                  * for a negative count, we need to step forward
15728                  * first and then step back again
15729                  */
15730                 files = -files + 1;
15731                 return (st_forward_space_files(un, files));
15732         }
15733         return (st_backward_space_files(un, files, 1));
15734 }
15735 
15736 static int
15737 st_backward_space_files(struct scsi_tape *un, int64_t count, int infront)
15738 {
15739         int64_t end_fileno;
15740         int64_t skip_cnt;
15741         int rval = 0;
15742 
15743         ST_FUNC(ST_DEVINFO, st_backward_space_files);
15744 
15745         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15746             "st_backward_space_files: count=%"PRIx64" eof=%x\n",
15747             count, un->un_pos.eof);
15748         /*
15749          * Backspace files (MTNBSF): infront == 0
15750          *
15751          *      For tapes that can backspace, backspace
15752          *      count+1 filemarks and then run forward over
15753          *      a filemark
15754          *
15755          *      For tapes that can't backspace,
15756          *              calculate desired filenumber
15757          *              (un->un_pos.fileno - count), rewind,
15758          *              and then space forward this amount
15759          *
15760          * Backspace filemarks (MTBSF) infront == 1
15761          *
15762          *      For tapes that can backspace, backspace count
15763          *      filemarks
15764          *
15765          *      For tapes that can't backspace, calculate
15766          *      desired filenumber (un->un_pos.fileno - count),
15767          *      add 1, rewind, space forward this amount,
15768          *      and mark state as ST_EOF_PENDING appropriately.
15769          */
15770 
15771         if (un->un_pos.pmode == logical) {
15772 
15773                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15774                     "st_backward_space_files: mt_op=%x count=%"PRIx64
15775                     "lgclblkno=%"PRIx64"\n", infront?MTBSF:MTNBSF, count,
15776                     un->un_pos.lgclblkno);
15777 
15778 
15779                 /* In case a drive that won't back space gets in logical mode */
15780                 if ((un->un_dp->options & ST_BSF) == 0) {
15781                         rval = EIO;
15782                         return (rval);
15783                 }
15784                 if ((infront == 1) &&
15785                     (st_cmd(un, SCMD_SPACE, Fmk(-count), SYNC_CMD))) {
15786                         rval = EIO;
15787                         return (rval);
15788                 } else if ((infront == 0) &&
15789                     (st_cmd(un, SCMD_SPACE, Fmk((-count)-1), SYNC_CMD)) &&
15790                     (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD))) {
15791                         rval = EIO;
15792                         return (rval);
15793                 }
15794                 return (rval);
15795         }
15796 
15797         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15798             "st_backward_space_files: mt_op=%x count=%"PRIx64
15799             "fileno=%x blkno=%x\n",
15800             infront?MTBSF:MTNBSF, count, un->un_pos.fileno, un->un_pos.blkno);
15801 
15802 
15803 
15804         /*
15805          * Handle the simple case of BOT
15806          * playing a role in these cmds.
15807          * We do this by calculating the
15808          * ending file number. If the ending
15809          * file is < BOT, rewind and set an
15810          * error and mark resid appropriately.
15811          * If we're backspacing a file (not a
15812          * filemark) and the target file is
15813          * the first file on the tape, just
15814          * rewind.
15815          */
15816 
15817         /* figure expected destination of this SPACE command */
15818         end_fileno = un->un_pos.fileno - count;
15819 
15820         /*
15821          * Would the end effect of this SPACE be the same as rewinding?
15822          * If so just rewind instead.
15823          */
15824         if ((infront != 0) && (end_fileno < 0) ||
15825             (infront == 0) && (end_fileno <= 0)) {
15826                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15827                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15828                             "st_backward_space_files: EIO : "
15829                             "rewind in lou of BSF failed\n");
15830                         rval = EIO;
15831                 }
15832                 if (end_fileno < 0) {
15833                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15834                             "st_backward_space_files: EIO : "
15835                             "back space file greater then fileno\n");
15836                         rval = EIO;
15837                         un->un_err_resid = -end_fileno;
15838                         un->un_status = SUN_KEY_BOT;
15839                 }
15840                 return (rval);
15841         }
15842 
15843         if (un->un_dp->options & ST_BSF) {
15844                 skip_cnt = 1 - infront;
15845                 /*
15846                  * If we are going to end up at the beginning
15847                  * of the file, we have to space one extra file
15848                  * first, and then space forward later.
15849                  */
15850                 end_fileno = -(count + skip_cnt);
15851                 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
15852                     "skip_cnt=%"PRIx64", tmp=%"PRIx64"\n",
15853                     skip_cnt, end_fileno);
15854                 if (st_cmd(un, SCMD_SPACE, Fmk(end_fileno), SYNC_CMD)) {
15855                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15856                             "st_backward_space_files:EIO:back space fm failed");
15857                         rval = EIO;
15858                 }
15859         } else {
15860                 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15861                         rval = EIO;
15862                 } else {
15863                         skip_cnt = end_fileno + infront;
15864                 }
15865         }
15866 
15867         /*
15868          * If we have to space forward, do so...
15869          */
15870         ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
15871             "space forward skip_cnt=%"PRIx64", rval=%x\n", skip_cnt, rval);
15872 
15873         if (rval == 0 && skip_cnt) {
15874                 if (st_cmd(un, SCMD_SPACE, Fmk(skip_cnt), SYNC_CMD)) {
15875                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15876                             "st_backward_space_files:EIO:space fm skip count");
15877                         rval = EIO;
15878                 } else if (infront) {
15879                         /*
15880                          * If we had to space forward, and we're
15881                          * not a tape that can backspace, mark state
15882                          * as if we'd just seen a filemark during a
15883                          * a read.
15884                          */
15885                         if ((un->un_dp->options & ST_BSF) == 0) {
15886                                 un->un_pos.eof = ST_EOF_PENDING;
15887                                 un->un_pos.fileno -= 1;
15888                                 un->un_pos.blkno = LASTBLK;
15889                                 un->un_running.pmode = invalid;
15890                         }
15891                 }
15892         }
15893 
15894         if (rval != 0) {
15895                 un->un_pos.pmode = invalid;
15896         }
15897 
15898         return (rval);
15899 }
15900 
15901 static int
15902 st_mtnbsf_ioctl(struct scsi_tape *un, int64_t count)
15903 {
15904         int rval;
15905 
15906         ST_FUNC(ST_DEVINFO, st_mtnbsf_ioctl);
15907 
15908         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15909             "nbsf: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15910 
15911         if (un->un_pos.pmode == legacy) {
15912                 /*
15913                  * backward space file to beginning of file
15914                  *
15915                  * If a negative count (which implies a forward space op)
15916                  * is specified, and we're at logical or physical eot,
15917                  * bounce the request.
15918                  */
15919 
15920                 if (un->un_pos.eof >= ST_EOT && count < 0) {
15921                         un->un_err_resid = count;
15922                         un->un_status = SUN_KEY_EOT;
15923                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15924                             "st_ioctl : EIO : > EOT and count < 0");
15925                         return (EIO);
15926                 }
15927                 /*
15928                  * physical tape position may not be what we've been
15929                  * telling the user; adjust the request accordingly
15930                  */
15931                 if (IN_EOF(un->un_pos)) {
15932                         un->un_pos.fileno++;
15933                         un->un_pos.blkno = 0;
15934                         count++;
15935                 }
15936         }
15937 
15938         if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
15939                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15940                     "st_ioctl : EIO : MTNBSF check den and wfm");
15941                 return (EIO);
15942         }
15943 
15944         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15945             "mtnbsf: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15946 
15947         if (count <= 0) {
15948                 rval = st_forward_space_files(un, -count);
15949         } else {
15950                 rval = st_backward_space_files(un, count, 0);
15951         }
15952         return (rval);
15953 }
15954 
15955 static int
15956 st_mtbsr_ioctl(struct scsi_tape *un, int64_t num)
15957 {
15958         ST_FUNC(ST_DEVINFO, st_mtbsr_ioctl);
15959 
15960         ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15961             "bsr: count=%"PRIx64", eof=%x\n", num, un->un_pos.eof);
15962 
15963         if (un->un_pos.pmode == legacy) {
15964                 /*
15965                  * backward space into inter-record gap
15966                  *
15967                  * If a negative count (which implies a forward space op)
15968                  * is specified, and we're at logical or physical eot,
15969                  * bounce the request.
15970                  */
15971                 if (un->un_pos.eof >= ST_EOT && num < 0) {
15972                         un->un_err_resid = num;
15973                         un->un_status = SUN_KEY_EOT;
15974                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15975                             "st_ioctl : EIO : MTBSR > EOT");
15976                         return (EIO);
15977                 }
15978 
15979                 if (num == 0) {
15980                         COPY_POS(&un->un_err_pos, &un->un_pos);
15981                         un->un_err_resid = 0;
15982                         if (IN_EOF(un->un_pos) && SVR4_BEHAVIOR) {
15983                                 un->un_status = SUN_KEY_EOF;
15984                         }
15985                         return (0);
15986                 }
15987 
15988                 /*
15989                  * physical tape position may not be what we've been
15990                  * telling the user; adjust the position accordingly.
15991                  * bsr can not skip filemarks and continue to skip records
15992                  * therefore if we are logically before the filemark but
15993                  * physically at the EOT side of the filemark, we need to step
15994                  * back; this allows fsr N where N > number of blocks in file
15995                  * followed by bsr 1 to position at the beginning of last block
15996                  */
15997                 if (IN_EOF(un->un_pos)) {
15998                         tapepos_t save;
15999                         optype lastop = un->un_lastop;
16000 
16001                         COPY_POS(&save, &un->un_pos);
16002                         if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD) == -1) {
16003                                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16004                                     "st_mtbsr_ioctl: EIO : MTBSR can't space");
16005                                 return (EIO);
16006                         }
16007 
16008                         COPY_POS(&un->un_pos, &save);
16009                         un->un_lastop = lastop;
16010                 }
16011         }
16012 
16013         un->un_pos.eof = ST_NO_EOF;
16014 
16015         if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
16016                 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16017                     "st_ioctl : EIO : MTBSR : can't set density or wfm");
16018                 return (EIO);
16019         }
16020 
16021         num = -num;
16022         return (st_space_records(un, num));
16023 }
16024 
16025 static int
16026 st_mtfsfm_ioctl(struct scsi_tape *un, int64_t cnt)
16027 {
16028         int rval;
16029 
16030         ST_FUNC(ST_DEVINFO, st_mtfsfm_ioctl);
16031 
16032         rval = st_cmd(un, SCMD_SPACE, SPACE(SP_SQFLM, cnt), SYNC_CMD);
16033         if (rval == 0) {
16034                 un->un_pos.pmode = logical;
16035         } else if ((un->un_status == KEY_ILLEGAL_REQUEST) &&
16036             (un->un_sd->sd_sense->es_add_code == 0x24)) {
16037                 /*
16038                  * Drive says invalid field in cdb.
16039                  * Doesn't like space multiple. Position isn't lost.
16040                  */
16041                 un->un_err_resid = cnt;
16042                 un->un_status = 0;
16043                 rval = ENOTTY;
16044         } else {
16045                 un->un_err_resid = cnt;
16046                 un->un_pos.pmode = invalid;
16047         }
16048         return (rval);
16049 }
16050 
16051 static int
16052 st_mtbsfm_ioctl(struct scsi_tape *un, int64_t cnt)
16053 {
16054         int rval;
16055 
16056         ST_FUNC(ST_DEVINFO, st_mtbsfm_ioctl);
16057 
16058         rval = st_cmd(un, SCMD_SPACE, SPACE(SP_SQFLM, -cnt), SYNC_CMD);
16059         if (rval == 0) {
16060                 un->un_pos.pmode = logical;
16061         } else if ((un->un_status == KEY_ILLEGAL_REQUEST) &&
16062             (un->un_sd->sd_sense->es_add_code == 0x24)) {
16063                 /*
16064                  * Drive says invalid field in cdb.
16065                  * Doesn't like space multiple. Position isn't lost.
16066                  */
16067                 un->un_err_resid = cnt;
16068                 un->un_status = 0;
16069                 rval = ENOTTY;
16070         } else {
16071                 un->un_err_resid = cnt;
16072                 un->un_pos.pmode = invalid;
16073         }
16074         return (rval);
16075 }
16076 
16077 #ifdef  __x86
16078 
16079 /*
16080  * release contig_mem and wake up waiting thread, if any
16081  */
16082 static void
16083 st_release_contig_mem(struct scsi_tape *un, struct contig_mem *cp)
16084 {
16085         mutex_enter(ST_MUTEX);
16086 
16087         ST_FUNC(ST_DEVINFO, st_release_contig_mem);
16088 
16089         cp->cm_next = un->un_contig_mem;
16090         un->un_contig_mem = cp;
16091         un->un_contig_mem_available_num++;
16092         cv_broadcast(&un->un_contig_mem_cv);
16093 
16094         mutex_exit(ST_MUTEX);
16095 }
16096 
16097 /*
16098  * St_get_contig_mem will return a contig_mem if there is one available
16099  * in current system. Otherwise, it will try to alloc one, if the total
16100  * number of contig_mem is within st_max_contig_mem_num.
16101  * It will sleep, if allowed by caller or return NULL, if no contig_mem
16102  * is available for now.
16103  */
16104 static struct contig_mem *
16105 st_get_contig_mem(struct scsi_tape *un, size_t len, int alloc_flags)
16106 {
16107         size_t rlen;
16108         struct contig_mem *cp = NULL;
16109         ddi_acc_handle_t acc_hdl;
16110         caddr_t addr;
16111         int big_enough = 0;
16112         int (*dma_alloc_cb)() = (alloc_flags == KM_SLEEP) ?
16113             DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
16114 
16115         /* Try to get one available contig_mem */
16116         mutex_enter(ST_MUTEX);
16117 
16118         ST_FUNC(ST_DEVINFO, st_get_contig_mem);
16119 
16120         if (un->un_contig_mem_available_num > 0) {
16121                 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16122         } else if (un->un_contig_mem_total_num < st_max_contig_mem_num) {
16123                 /*
16124                  * we failed to get one. we're going to
16125                  * alloc one more contig_mem for this I/O
16126                  */
16127                 mutex_exit(ST_MUTEX);
16128                 cp = (struct contig_mem *)kmem_zalloc(
16129                     sizeof (struct contig_mem) + biosize(),
16130                     alloc_flags);
16131                 if (cp == NULL) {
16132                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16133                             "alloc contig_mem failure\n");
16134                         return (NULL); /* cannot get one */
16135                 }
16136                 cp->cm_bp = (struct buf *)
16137                     (((caddr_t)cp) + sizeof (struct contig_mem));
16138                 bioinit(cp->cm_bp);
16139                 mutex_enter(ST_MUTEX);
16140                 un->un_contig_mem_total_num++; /* one more available */
16141         } else {
16142                 /*
16143                  * we failed to get one and we're NOT allowed to
16144                  * alloc more contig_mem
16145                  */
16146                 if (alloc_flags == KM_SLEEP) {
16147                         while (un->un_contig_mem_available_num <= 0) {
16148                                 cv_wait(&un->un_contig_mem_cv, ST_MUTEX);
16149                         }
16150                         ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16151                 } else {
16152                         mutex_exit(ST_MUTEX);
16153                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16154                             "alloc contig_mem failure\n");
16155                         return (NULL); /* cannot get one */
16156                 }
16157         }
16158         mutex_exit(ST_MUTEX);
16159 
16160         /* We need to check if this block of mem is big enough for this I/O */
16161         if (cp->cm_len < len) {
16162                 /* not big enough, need to alloc a new one */
16163                 if (ddi_dma_mem_alloc(un->un_contig_mem_hdl, len, &st_acc_attr,
16164                     DDI_DMA_STREAMING, dma_alloc_cb, NULL,
16165                     &addr, &rlen, &acc_hdl) != DDI_SUCCESS) {
16166                         ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16167                             "alloc contig_mem failure: not enough mem\n");
16168                         st_release_contig_mem(un, cp);
16169                         cp = NULL;
16170                 } else {
16171                         if (cp->cm_addr) {
16172                                 /* release previous one before attach new one */
16173                                 ddi_dma_mem_free(&cp->cm_acc_hdl);
16174                         }
16175                         mutex_enter(ST_MUTEX);
16176                         un->un_max_contig_mem_len =
16177                             un->un_max_contig_mem_len >= len ?
16178                             un->un_max_contig_mem_len : len;
16179                         mutex_exit(ST_MUTEX);
16180 
16181                         /* attach new mem to this cp */
16182                         cp->cm_addr = addr;
16183                         cp->cm_acc_hdl = acc_hdl;
16184                         cp->cm_len = len;
16185 
16186                         goto alloc_ok; /* get one usable cp */
16187                 }
16188         } else {
16189                 goto alloc_ok; /* get one usable cp */
16190         }
16191 
16192         /* cannot find/alloc a usable cp, when we get here */
16193 
16194         mutex_enter(ST_MUTEX);
16195         if ((un->un_max_contig_mem_len < len) ||
16196             (alloc_flags != KM_SLEEP)) {
16197                 mutex_exit(ST_MUTEX);
16198                 return (NULL);
16199         }
16200 
16201         /*
16202          * we're allowed to sleep, and there is one big enough
16203          * contig mem in the system, which is currently in use,
16204          * wait for it...
16205          */
16206         big_enough = 1;
16207         do {
16208                 cv_wait(&un->un_contig_mem_cv, ST_MUTEX);
16209                 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16210         } while (cp == NULL);
16211         mutex_exit(ST_MUTEX);
16212 
16213         /* we get the big enough contig mem, finally */
16214 
16215 alloc_ok:
16216         /* init bp attached to this cp */
16217         bioreset(cp->cm_bp);
16218         cp->cm_bp->b_un.b_addr = cp->cm_addr;
16219         cp->cm_bp->b_private = (void *)cp;
16220 
16221         return (cp);
16222 }
16223 
16224 /*
16225  * this is the biodone func for the bp used in big block I/O
16226  */
16227 static int
16228 st_bigblk_xfer_done(struct buf *bp)
16229 {
16230         struct contig_mem *cp;
16231         struct buf *orig_bp;
16232         int ioerr;
16233         struct scsi_tape *un;
16234 
16235         /* sanity check */
16236         if (bp == NULL) {
16237                 return (DDI_FAILURE);
16238         }
16239 
16240         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16241         if (un == NULL) {
16242                 return (DDI_FAILURE);
16243         }
16244 
16245         ST_FUNC(ST_DEVINFO, st_bigblk_xfer_done);
16246 
16247         cp = (struct contig_mem *)bp->b_private;
16248         orig_bp = cp->cm_bp; /* get back the bp we have replaced */
16249         cp->cm_bp = bp;
16250 
16251         /* special handling for special I/O */
16252         if (cp->cm_use_sbuf) {
16253 #ifndef __lock_lint
16254                 ASSERT(un->un_sbuf_busy);
16255 #endif
16256                 un->un_sbufp = orig_bp;
16257                 cp->cm_use_sbuf = 0;
16258         }
16259 
16260         orig_bp->b_resid = bp->b_resid;
16261         ioerr = geterror(bp);
16262         if (ioerr != 0) {
16263                 bioerror(orig_bp, ioerr);
16264         } else if (orig_bp->b_flags & B_READ) {
16265                 /* copy data back to original bp */
16266                 (void) bp_copyout(bp->b_un.b_addr, orig_bp, 0,
16267                     bp->b_bcount - bp->b_resid);
16268         }
16269 
16270         st_release_contig_mem(un, cp);
16271 
16272         biodone(orig_bp);
16273 
16274         return (DDI_SUCCESS);
16275 }
16276 
16277 /*
16278  * We use this func to replace original bp that may not be able to do I/O
16279  * in big block size with one that can
16280  */
16281 static struct buf *
16282 st_get_bigblk_bp(struct buf *bp)
16283 {
16284         struct contig_mem *cp;
16285         struct scsi_tape *un;
16286         struct buf *cont_bp;
16287 
16288         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16289         if (un == NULL) {
16290                 return (bp);
16291         }
16292 
16293         ST_FUNC(ST_DEVINFO, st_get_bigblk_bp);
16294 
16295         /* try to get one contig_mem */
16296         cp = st_get_contig_mem(un, bp->b_bcount, KM_SLEEP);
16297         if (!cp) {
16298                 scsi_log(ST_DEVINFO, st_label, CE_WARN,
16299                     "Cannot alloc contig buf for I/O for %lu blk size",
16300                     bp->b_bcount);
16301                 return (bp);
16302         }
16303         cont_bp = cp->cm_bp;
16304         cp->cm_bp = bp;
16305 
16306         /* make sure that we "are" using un_sbufp for special I/O */
16307         if (bp == un->un_sbufp) {
16308 #ifndef __lock_lint
16309                 ASSERT(un->un_sbuf_busy);
16310 #endif
16311                 un->un_sbufp = cont_bp;
16312                 cp->cm_use_sbuf = 1;
16313         }
16314 
16315         /* clone bp */
16316         cont_bp->b_bcount = bp->b_bcount;
16317         cont_bp->b_resid = bp->b_resid;
16318         cont_bp->b_iodone = st_bigblk_xfer_done;
16319         cont_bp->b_file = bp->b_file;
16320         cont_bp->b_offset = bp->b_offset;
16321         cont_bp->b_dip = bp->b_dip;
16322         cont_bp->b_error = 0;
16323         cont_bp->b_proc = NULL;
16324         cont_bp->b_flags = bp->b_flags & ~(B_PAGEIO | B_PHYS | B_SHADOW);
16325         cont_bp->b_shadow = NULL;
16326         cont_bp->b_pages = NULL;
16327         cont_bp->b_edev = bp->b_edev;
16328         cont_bp->b_dev = bp->b_dev;
16329         cont_bp->b_lblkno = bp->b_lblkno;
16330         cont_bp->b_forw = bp->b_forw;
16331         cont_bp->b_back = bp->b_back;
16332         cont_bp->av_forw = bp->av_forw;
16333         cont_bp->av_back = bp->av_back;
16334         cont_bp->b_bufsize = bp->b_bufsize;
16335 
16336         /* get data in original bp */
16337         if (bp->b_flags & B_WRITE) {
16338                 (void) bp_copyin(bp, cont_bp->b_un.b_addr, 0, bp->b_bcount);
16339         }
16340 
16341         return (cont_bp);
16342 }
16343 #else
16344 #ifdef __lock_lint
16345 static int
16346 st_bigblk_xfer_done(struct buf *bp)
16347 {
16348         return (0);
16349 }
16350 #endif
16351 #endif
16352 
16353 static const char *eof_status[] =
16354 {
16355         "NO_EOF",
16356         "EOF_PENDING",
16357         "EOF",
16358         "EOT_PENDING",
16359         "EOT",
16360         "EOM",
16361         "AFTER_EOM"
16362 };
16363 static const char *mode[] = {
16364         "invalid",
16365         "legacy",
16366         "logical"
16367 };
16368 
16369 static void
16370 st_print_position(dev_info_t *dev, char *label, uint_t level,
16371 const char *comment, tapepos_t *pos)
16372 {
16373         ST_FUNC(dev, st_print_position);
16374 
16375         scsi_log(dev, label, level,
16376             "%s Position data:\n", comment);
16377         scsi_log(dev, label, CE_CONT,
16378             "Positioning mode = %s", mode[pos->pmode]);
16379         scsi_log(dev, label, CE_CONT,
16380             "End Of File/Tape = %s", eof_status[pos->eof]);
16381         scsi_log(dev, label, CE_CONT,
16382             "File Number      = 0x%x", pos->fileno);
16383         scsi_log(dev, label, CE_CONT,
16384             "Block Number     = 0x%x", pos->blkno);
16385         scsi_log(dev, label, CE_CONT,
16386             "Logical Block    = 0x%"PRIx64, pos->lgclblkno);
16387         scsi_log(dev, label, CE_CONT,
16388             "Partition Number = 0x%x", pos->partition);
16389 }
16390 static int
16391 st_check_if_media_changed(struct scsi_tape *un, caddr_t data, int size)
16392 {
16393 
16394         int result = 0;
16395         int i;
16396         ST_FUNC(ST_DEVINFO, st_check_if_media_changed);
16397 
16398         /*
16399          * find non alpha numeric working from the end.
16400          */
16401         for (i = size - 1; i >= 0; i--) {
16402                 if (ISALNUM(data[i]) == 0 || data[i] == ' ') {
16403                         data[i] = 0;
16404                         size = i;
16405                 }
16406         }
16407 
16408         if (size == 1) {
16409                 /*
16410                  * Drive seems to think its returning useful data
16411                  * but it looks like all junk
16412                  */
16413                 return (result);
16414         }
16415 
16416         size++;
16417 
16418         /*
16419          * Actually got a valid serial number.
16420          * If never stored one before alloc space for it.
16421          */
16422         if (un->un_media_id_len == 0) {
16423                 un->un_media_id = kmem_zalloc(size, KM_SLEEP);
16424                 un->un_media_id_len = size;
16425                 (void) strncpy(un->un_media_id, data, min(size, strlen(data)));
16426                 un->un_media_id[min(size, strlen(data))] = 0;
16427                 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16428                     "Found Media Id %s length = %d\n", un->un_media_id, size);
16429         } else if (size > un->un_media_id_len) {
16430                 if (strncmp(un->un_media_id, data, size) != 0) {
16431                         result = ESPIPE;
16432                 }
16433                 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16434                     "Longer Media Id old ID:%s new ID:%s\n",
16435                     un->un_media_id, data);
16436                 kmem_free(un->un_media_id, un->un_media_id_len);
16437                 un->un_media_id = kmem_zalloc(size, KM_SLEEP);
16438                 un->un_media_id_len = size;
16439                 (void) strncpy(un->un_media_id, data, size);
16440                 un->un_media_id[size] = 0;
16441         } else if (strncmp(data, un->un_media_id,
16442             min(size, un->un_media_id_len)) != 0) {
16443                 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16444                     "Old Media Id %s length = %d New %s length = %d\n",
16445                     un->un_media_id, un->un_media_id_len, data, size);
16446                 bzero(un->un_media_id, un->un_media_id_len);
16447                 (void) strncpy(un->un_media_id, data, min(size, strlen(data)));
16448                 un->un_media_id[min(size, strlen(data))] = 0;
16449                 result = ESPIPE;
16450         } else {
16451                 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
16452                     "Media Id still %s\n", un->un_media_id);
16453         }
16454 
16455         ASSERT(strlen(un->un_media_id) <= size);
16456 
16457         return (result);
16458 }
16459 #define ID_SIZE 32
16460 typedef struct
16461 {
16462         uchar_t avilable_data0;
16463         uchar_t avilable_data1;
16464         uchar_t avilable_data2;
16465         uchar_t avilable_data3;
16466         uchar_t attribute_msb;
16467         uchar_t attribute_lsb;
16468 #ifdef _BIT_FIELDS_LTOH
16469         uchar_t format          : 2,
16470                                 : 5,
16471                 read_only       : 1;
16472 #else
16473         uchar_t read_only       : 1,
16474                                 : 5,
16475                 format          : 2;
16476 #endif
16477         uchar_t attribute_len_msb;
16478         uchar_t attribute_len_lsb;
16479 }attribute_header;
16480 
16481 typedef struct {
16482         attribute_header header;
16483         char data[1];
16484 }mam_attribute;
16485 
16486 static int
16487 st_handle_hex_media_id(struct scsi_tape *un, void *pnt, int size)
16488 {
16489         int result;
16490         int newsize = (size << 1) + 3; /* extra for leading 0x and null term */
16491         int i;
16492         uchar_t byte;
16493         char *format;
16494         uchar_t *data = (uchar_t *)pnt;
16495         char *buf = kmem_alloc(newsize, KM_SLEEP);
16496 
16497         ST_FUNC(ST_DEVINFO, st_handle_hex_media_id);
16498 
16499         (void) sprintf(buf, "0x");
16500         for (i = 0; i < size; i++) {
16501                 byte = data[i];
16502                 if (byte < 0x10)
16503                         format = "0%x";
16504                 else
16505                         format = "%x";
16506                 (void) sprintf(&buf[(int)strlen(buf)], format, byte);
16507         }
16508         result = st_check_if_media_changed(un, buf, newsize);
16509 
16510         kmem_free(buf, newsize);
16511 
16512         return (result);
16513 }
16514 
16515 
16516 static int
16517 st_get_media_id_via_read_attribute(struct scsi_tape *un, ubufunc_t bufunc)
16518 {
16519         int result;
16520         mam_attribute *buffer;
16521         int size;
16522         int newsize;
16523 
16524         ST_FUNC(ST_DEVINFO, st_get_media_id_via_read_attribute);
16525         size = sizeof (attribute_header) + max(un->un_media_id_len, ID_SIZE);
16526 again:
16527         buffer = kmem_zalloc(size, KM_SLEEP);
16528         result = st_read_attributes(un, 0x0401, buffer, size, bufunc);
16529         if (result == 0) {
16530 
16531                 newsize = (buffer->header.attribute_len_msb << 8) |
16532                     buffer->header.attribute_len_lsb;
16533 
16534                 if (newsize + sizeof (attribute_header) > size) {
16535                         ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
16536                             "resizing read attribute data from %d to %d format"
16537                             " %d\n", size, (int)sizeof (attribute_header) +
16538                             newsize, buffer->header.format);
16539                         kmem_free(buffer, size);
16540                         size = newsize + sizeof (attribute_header);
16541                         goto again;
16542                 }
16543 
16544                 un->un_media_id_method = st_get_media_id_via_read_attribute;
16545                 if (buffer->header.format == 0) {
16546                         result =
16547                             st_handle_hex_media_id(un, buffer->data, newsize);
16548                 } else {
16549                         result = st_check_if_media_changed(un, buffer->data,
16550                             newsize);
16551                 }
16552         } else if (result == EINVAL && un->un_max_cdb_sz < CDB_GROUP4) {
16553                 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
16554                     "Read Attribute Command for Media Identification is not "
16555                     "supported on the HBA that this drive is attached to.");
16556                 result = ENOTTY;
16557         }
16558 
16559         kmem_free(buffer, size);
16560         un->un_status = 0;
16561 
16562         return (result);
16563 }
16564 
16565 
16566 static int
16567 st_get_media_id_via_media_serial_cmd(struct scsi_tape *un, ubufunc_t bufunc)
16568 {
16569         char cdb[CDB_GROUP5];
16570         struct uscsi_cmd *ucmd;
16571         struct scsi_extended_sense sense;
16572         int rval;
16573         int size = max(un->un_media_id_len, ID_SIZE);
16574         caddr_t buf;
16575 
16576         ST_FUNC(ST_DEVINFO, st_get_media_id_via_media_serial_cmd);
16577 
16578         if (un->un_sd->sd_inq->inq_ansi < 3) {
16579                 return (ENOTTY);
16580         }
16581 
16582         ucmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
16583 upsize:
16584         buf = kmem_alloc(size, KM_SLEEP);
16585 
16586         cdb[0] = (char)SCMD_SVC_ACTION_IN_G5;
16587         cdb[1] = SSVC_ACTION_READ_MEDIA_SERIAL;
16588         cdb[2] = 0;
16589         cdb[3] = 0;
16590         cdb[4] = 0;
16591         cdb[5] = 0;
16592         cdb[6] = (char)(size >> 24);
16593         cdb[7] = (char)(size >> 16);
16594         cdb[8] = (char)(size >> 8);
16595         cdb[9] = (char)(size);
16596         cdb[10] = 0;
16597         cdb[11] = 0;
16598 
16599         ucmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE;
16600         ucmd->uscsi_timeout = un->un_dp->non_motion_timeout;
16601         ucmd->uscsi_cdb = &cdb[0];
16602         ucmd->uscsi_cdblen = sizeof (cdb);
16603         ucmd->uscsi_bufaddr = buf;
16604         ucmd->uscsi_buflen = size;
16605         ucmd->uscsi_rqbuf = (caddr_t)&sense;
16606         ucmd->uscsi_rqlen = sizeof (sense);
16607 
16608         rval = bufunc(un, ucmd, FKIOCTL);
16609 
16610         if (rval || ucmd->uscsi_status != 0) {
16611                 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
16612                     "media serial command returned %d scsi_status %d"
16613                     " rqstatus %d", rval, ucmd->uscsi_status,
16614                     ucmd->uscsi_rqstatus);
16615                 /*
16616                  * If this returns invalid operation code don't try again.
16617                  */
16618                 if (sense.es_key == KEY_ILLEGAL_REQUEST &&
16619                     sense.es_add_code == 0x20) {
16620                         rval = ENOTTY;
16621                 } else if (rval == 0) {
16622                         rval = EIO;
16623                 }
16624                 un->un_status = 0;
16625         } else {
16626                 int act_size;
16627 
16628                 /*
16629                  * get reported size.
16630                  */
16631                 act_size = (int)buf[3] | (int)(buf[2] << 8) |
16632                     (int)(buf[1] << 16) | (int)(buf[0] << 24);
16633 
16634                 /* documentation says mod 4. */
16635                 while (act_size & 3) {
16636                         act_size++;
16637                 }
16638 
16639                 /*
16640                  * If reported size is larger that we our buffer.
16641                  * Free the old one and allocate one that is larger
16642                  * enough and re-issuse the command.
16643                  */
16644                 if (act_size + 4 > size) {
16645                         kmem_free(buf, size);
16646                         size = act_size + 4;
16647                         goto upsize;
16648                 }
16649 
16650                 if (act_size == 0) {
16651                         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
16652                             "media serial number is not available");
16653                         un->un_status = 0;
16654                         rval = 0;
16655                 } else {
16656                         /*
16657                          * set data pointer to point to the start
16658                          * of that serial number.
16659                          */
16660                         un->un_media_id_method =
16661                             st_get_media_id_via_media_serial_cmd;
16662                         rval =
16663                             st_check_if_media_changed(un, &buf[4], act_size);
16664                 }
16665         }
16666 
16667         kmem_free(ucmd, sizeof (struct uscsi_cmd));
16668         kmem_free(buf, size);
16669 
16670         return (rval);
16671 }
16672 
16673 
16674 /* ARGSUSED */
16675 static int
16676 st_bogus_media_id(struct scsi_tape *un, ubufunc_t bufunc)
16677 {
16678         ST_FUNC(ST_DEVINFO, st_bogus_media_id);
16679 
16680         ASSERT(un->un_media_id == NULL || un->un_media_id == bogusID);
16681         ASSERT(un->un_media_id_len == 0);
16682         un->un_media_id = (char *)bogusID;
16683         un->un_media_id_len = 0;
16684         return (0);
16685 }
16686 
16687 typedef int (*media_chk_function)(struct scsi_tape *, ubufunc_t bufunc);
16688 
16689 media_chk_function media_chk_functions[] = {
16690         st_get_media_id_via_media_serial_cmd,
16691         st_get_media_id_via_read_attribute,
16692         st_bogus_media_id
16693 };
16694 
16695 static int
16696 st_get_media_identification(struct scsi_tape *un, ubufunc_t bufunc)
16697 {
16698         int result = 0;
16699         int i;
16700 
16701         ST_FUNC(ST_DEVINFO, st_get_media_identification);
16702 
16703         for (i = 0; i < ST_NUM_MEMBERS(media_chk_functions); i++) {
16704                 if (result == ENOTTY) {
16705                         /*
16706                          * Last operation type not supported by this device.
16707                          * Make so next time it doesn`t do that again.
16708                          */
16709                         un->un_media_id_method = media_chk_functions[i];
16710                 } else if (un->un_media_id_method != media_chk_functions[i] &&
16711                     un->un_media_id_method != st_get_media_identification) {
16712                         continue;
16713                 }
16714                 result = media_chk_functions[i](un, bufunc);
16715                 /*
16716                  * If result indicates the function was successful or
16717                  * that the media is not the same as last known, break.
16718                  */
16719                 if (result == 0 || result == ESPIPE) {
16720                         break;
16721                 }
16722         }
16723 
16724         return (result);
16725 }
16726 
16727 static errstate
16728 st_command_recovery(struct scsi_tape *un, struct scsi_pkt *pkt,
16729     errstate onentry)
16730 {
16731 
16732         int ret;
16733         st_err_info *errinfo;
16734         recov_info *ri = (recov_info *)pkt->pkt_private;
16735 
16736         ST_FUNC(ST_DEVINFO, st_command_recovery);
16737 
16738         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
16739 
16740         ASSERT(un->un_recov_buf_busy == 0);
16741 
16742         /*
16743          * Don't try and recover a reset that this device sent.
16744          */
16745         if (un->un_rsvd_status & ST_INITIATED_RESET &&
16746             onentry == DEVICE_RESET) {
16747                 return (COMMAND_DONE_ERROR);
16748         }
16749 
16750         /*
16751          * See if expected position was passed with scsi_pkt.
16752          */
16753         if (ri->privatelen == sizeof (recov_info)) {
16754 
16755                 /*
16756                  * Not for this command.
16757                  */
16758                 if (ri->cmd_attrib->do_not_recover) {
16759                         return (COMMAND_DONE_ERROR);
16760                 }
16761 
16762                 /*
16763                  * Create structure to hold all error state info.
16764                  */
16765                 errinfo = kmem_zalloc(ST_ERR_INFO_SIZE, KM_SLEEP);
16766                 errinfo->ei_error_type = onentry;
16767                 errinfo->ei_failing_bp = ri->cmd_bp;
16768                 COPY_POS(&errinfo->ei_expected_pos, &ri->pos);
16769         } else {
16770                 /* disabled */
16771                 return (COMMAND_DONE_ERROR);
16772         }
16773 
16774         bcopy(pkt, &errinfo->ei_failed_pkt, scsi_pkt_size());
16775         bcopy(pkt->pkt_scbp, &errinfo->ei_failing_status, SECMDS_STATUS_SIZE);
16776         ret = ddi_taskq_dispatch(un->un_recov_taskq, st_recover, errinfo,
16777             DDI_NOSLEEP);
16778         ASSERT(ret == DDI_SUCCESS);
16779         if (ret != DDI_SUCCESS) {
16780                 kmem_free(errinfo, ST_ERR_INFO_SIZE);
16781                 return (COMMAND_DONE_ERROR);
16782         }
16783         return (JUST_RETURN); /* release calling thread */
16784 }
16785 
16786 
16787 static void
16788 st_recov_ret(struct scsi_tape *un, st_err_info *errinfo, errstate err)
16789 {
16790         int error_number;
16791         buf_t *bp;
16792 
16793 
16794         ST_FUNC(ST_DEVINFO, st_recov_ret);
16795 
16796         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
16797 #if !defined(lint)
16798         _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&un->un_sd->sd_mutex))
16799 #endif
16800 
16801         bp = errinfo->ei_failing_bp;
16802         kmem_free(errinfo, ST_ERR_INFO_SIZE);
16803 
16804         switch (err) {
16805         case JUST_RETURN:
16806                 mutex_exit(&un->un_sd->sd_mutex);
16807                 return;
16808 
16809         case COMMAND_DONE:
16810         case COMMAND_DONE_ERROR_RECOVERED:
16811                 ST_DO_KSTATS(bp, kstat_runq_exit);
16812                 error_number = 0;
16813                 break;
16814 
16815         default:
16816                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
16817                     "st_recov_ret with unhandled errstat %d\n", err);
16818                 /* FALLTHROUGH */
16819         case COMMAND_DONE_ERROR:
16820                 un->un_pos.pmode = invalid;
16821                 un->un_running.pmode = invalid;
16822                 /* FALLTHROUGH */
16823         case COMMAND_DONE_EACCES:
16824                 ST_DO_KSTATS(bp, kstat_waitq_exit);
16825                 ST_DO_ERRSTATS(un, st_transerrs);
16826                 error_number = EIO;
16827                 st_set_pe_flag(un);
16828                 break;
16829 
16830         }
16831 
16832         st_bioerror(bp, error_number);
16833         st_done_and_mutex_exit(un, bp);
16834 }
16835 
16836 
16837 static void
16838 st_recover(void *arg)
16839 {
16840         st_err_info *const errinfo = (st_err_info *)arg;
16841         uchar_t com = errinfo->ei_failed_pkt.pkt_cdbp[0];
16842         struct scsi_tape *un;
16843         tapepos_t cur_pos;
16844         int rval;
16845         errstate status = COMMAND_DONE_ERROR;
16846         recov_info *rcv;
16847         buf_t *bp;
16848 
16849 
16850         rcv = errinfo->ei_failed_pkt.pkt_private;
16851         ASSERT(rcv->privatelen == sizeof (recov_info));
16852         bp = rcv->cmd_bp;
16853 
16854         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16855 
16856         ASSERT(un != NULL);
16857 
16858         mutex_enter(ST_MUTEX);
16859 
16860         ST_FUNC(ST_DEVINFO, st_recover);
16861 
16862         ST_CDB(ST_DEVINFO, "Recovering command",
16863             (caddr_t)errinfo->ei_failed_pkt.pkt_cdbp);
16864         ST_SENSE(ST_DEVINFO, "sense status for failed command",
16865             (caddr_t)&errinfo->ei_failing_status,
16866             sizeof (struct scsi_arq_status));
16867         ST_POS(ST_DEVINFO, rcv->cmd_attrib->recov_pos_type == POS_STARTING ?
16868             "starting position for recovery command" :
16869             "expected position for recovery command",
16870             &errinfo->ei_expected_pos);
16871 
16872         rval = st_test_path_to_device(un);
16873 
16874         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
16875             "st_recover called with %s, TUR returned %d\n",
16876             errstatenames[errinfo->ei_error_type], rval);
16877         /*
16878          * If the drive responed to the TUR lets try and get it to sync
16879          * any data it might have in the buffer.
16880          */
16881         if (rval == 0 && rcv->cmd_attrib->chg_tape_data) {
16882                 rval = st_rcmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD);
16883                 if (rval) {
16884                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
16885                             "st_recover failed to flush, returned %d\n", rval);
16886                         st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16887                         return;
16888                 }
16889         }
16890         switch (errinfo->ei_error_type) {
16891         case ATTEMPT_RETRY:
16892         case COMMAND_TIMEOUT:
16893         case DEVICE_RESET:
16894         case PATH_FAILED:
16895                 /*
16896                  * For now if we can't talk to the device we are done.
16897                  * If the drive is reserved we can try to get it back.
16898                  */
16899                 if (rval != 0 && rval != EACCES) {
16900                         st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16901                         return;
16902                 }
16903 
16904                 /*
16905                  * If reservation conflict and do a preempt, fail it.
16906                  */
16907                 if ((un->un_rsvd_status &
16908                     (ST_APPLICATION_RESERVATIONS | ST_RESERVE)) != 0) {
16909                         if ((errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16910                             SCMD_PERSISTENT_RESERVE_OUT) &&
16911                             (errinfo->ei_failed_pkt.pkt_cdbp[1] ==
16912                             ST_SA_SCSI3_PREEMPT) &&
16913                             (SCBP_C(&errinfo->ei_failed_pkt) ==
16914                             STATUS_RESERVATION_CONFLICT)) {
16915                                 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16916                                 return;
16917                         }
16918                 }
16919 
16920                 /*
16921                  * If we have already set a scsi II reserve and get a
16922                  * conflict on a scsi III type reserve fail without
16923                  * any attempt to recover.
16924                  */
16925                 if ((un->un_rsvd_status & ST_RESERVE | ST_PRESERVE_RESERVE) &&
16926                     (errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16927                     SCMD_PERSISTENT_RESERVE_OUT) ||
16928                     (errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16929                     SCMD_PERSISTENT_RESERVE_IN)) {
16930                         st_recov_ret(un, errinfo, COMMAND_DONE_EACCES);
16931                         return;
16932                 }
16933 
16934                 /*
16935                  * If scsi II lost reserve try and get it back.
16936                  */
16937                 if ((((un->un_rsvd_status &
16938                     (ST_LOST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
16939                     ST_LOST_RESERVE)) &&
16940                     (errinfo->ei_failed_pkt.pkt_cdbp[0] != SCMD_RELEASE)) {
16941                         rval = st_reserve_release(un, ST_RESERVE,
16942                             st_uscsi_rcmd);
16943                         if (rval != 0) {
16944                                 if (st_take_ownership(un, st_uscsi_rcmd) != 0) {
16945                                         st_recov_ret(un, errinfo,
16946                                             COMMAND_DONE_EACCES);
16947                                         return;
16948                                 }
16949                         }
16950                         un->un_rsvd_status |= ST_RESERVE;
16951                         un->un_rsvd_status &= ~(ST_RELEASE | ST_LOST_RESERVE |
16952                             ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
16953                 }
16954                 rval = st_make_sure_mode_data_is_correct(un, st_uscsi_rcmd);
16955                 if (rval) {
16956                         st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16957                         return;
16958                 }
16959                 break;
16960         case DEVICE_TAMPER:
16961                 /*
16962                  * Check if the ASC/ASCQ says mode data has changed.
16963                  */
16964                 if ((errinfo->ei_failing_status.sts_sensedata.es_add_code ==
16965                     0x2a) &&
16966                     (errinfo->ei_failing_status.sts_sensedata.es_qual_code ==
16967                     0x01)) {
16968                         /*
16969                          * See if mode sense changed.
16970                          */
16971                         rval = st_make_sure_mode_data_is_correct(un,
16972                             st_uscsi_rcmd);
16973                         if (rval) {
16974                                 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16975                                 return;
16976                         }
16977                 }
16978                 /*
16979                  * if we have a media id and its not bogus.
16980                  * Check to see if it the same.
16981                  */
16982                 if (un->un_media_id != NULL && un->un_media_id != bogusID) {
16983                         rval = st_get_media_identification(un, st_uscsi_rcmd);
16984                         if (rval == ESPIPE) {
16985                                 st_recov_ret(un, errinfo, COMMAND_DONE_EACCES);
16986                                 return;
16987                         }
16988                 }
16989                 break;
16990         default:
16991                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
16992                     "Unhandled error type %s in st_recover() 0x%x\n",
16993                     errstatenames[errinfo->ei_error_type], com);
16994         }
16995 
16996         /*
16997          * if command is retriable retry it.
16998          * Special case here. The command attribute for SCMD_REQUEST_SENSE
16999          * does not say that it is retriable. That because if you reissue a
17000          * request sense and the target responds the sense data will have
17001          * been consumed and no long be valid. If we get a busy status on
17002          * request sense while the state is ST_STATE_SENSING this will
17003          * reissue that pkt.
17004          *
17005          * XXX If this request sense gets sent to a different port then
17006          * the original command that failed was sent on it will not get
17007          * valid sense data for that command.
17008          */
17009         if (rcv->cmd_attrib->retriable || un->un_rqs_bp == bp) {
17010                 status = st_recover_reissue_pkt(un, &errinfo->ei_failed_pkt);
17011 
17012         /*
17013          * if drive doesn't support read position we are done
17014          */
17015         } else if (un->un_read_pos_type == NO_POS) {
17016                 status = COMMAND_DONE_ERROR;
17017         /*
17018          * If this command results in a changed tape position,
17019          * lets see where we are.
17020          */
17021         } else if (rcv->cmd_attrib->chg_tape_pos) {
17022                 /*
17023                  * XXX May be a reason to choose a different type here.
17024                  * Long format has file position information.
17025                  * Short and Extended have information about whats
17026                  * in the buffer. St's positioning assumes in the buffer
17027                  * to be the same as on tape.
17028                  */
17029                 rval = st_compare_expected_position(un, errinfo,
17030                     rcv->cmd_attrib, &cur_pos);
17031                 if (rval == 0) {
17032                         status = COMMAND_DONE;
17033                 } else if (rval == EAGAIN) {
17034                         status = st_recover_reissue_pkt(un,
17035                             &errinfo->ei_failed_pkt);
17036                 } else {
17037                         status = COMMAND_DONE_ERROR;
17038                 }
17039         } else {
17040                 ASSERT(0);
17041         }
17042 
17043         st_recov_ret(un, errinfo, status);
17044 }
17045 
17046 static void
17047 st_recov_cb(struct scsi_pkt *pkt)
17048 {
17049         struct scsi_tape *un;
17050         struct buf *bp;
17051         recov_info *rcv;
17052         errstate action = COMMAND_DONE_ERROR;
17053         int timout = ST_TRAN_BUSY_TIMEOUT; /* short (default) timeout */
17054 
17055         /*
17056          * Get the buf from the packet.
17057          */
17058         rcv = pkt->pkt_private;
17059         ASSERT(rcv->privatelen == sizeof (recov_info));
17060         bp = rcv->cmd_bp;
17061 
17062         /*
17063          * get the unit from the buf.
17064          */
17065         un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
17066         ASSERT(un != NULL);
17067 
17068         ST_FUNC(ST_DEVINFO, st_recov_cb);
17069 
17070         mutex_enter(ST_MUTEX);
17071 
17072         ASSERT(bp == un->un_recov_buf);
17073 
17074 
17075         switch (pkt->pkt_reason) {
17076         case CMD_CMPLT:
17077                 if (un->un_arq_enabled && pkt->pkt_state & STATE_ARQ_DONE) {
17078                         action = st_handle_autosense(un, bp, &rcv->pos);
17079                 } else  if ((SCBP(pkt)->sts_busy) ||
17080                     (SCBP(pkt)->sts_chk) ||
17081                     (SCBP(pkt)->sts_vu7)) {
17082                         action = st_check_error(un, pkt);
17083                 } else {
17084                         action = COMMAND_DONE;
17085                 }
17086                 break;
17087         case CMD_TIMEOUT:
17088                 action = COMMAND_TIMEOUT;
17089                 break;
17090         case CMD_TRAN_ERR:
17091                 action = QUE_COMMAND;
17092                 break;
17093         case CMD_DEV_GONE:
17094                 if (un->un_multipath)
17095                         action = PATH_FAILED;
17096                 else
17097                         action = COMMAND_DONE_ERROR;
17098                 break;
17099         default:
17100                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
17101                     "pkt_reason not handled yet %s",
17102                     scsi_rname(pkt->pkt_reason));
17103                 action = COMMAND_DONE_ERROR;
17104         }
17105 
17106         /*
17107          * check for undetected path failover.
17108          */
17109         if (un->un_multipath) {
17110                 if (scsi_pkt_allocated_correctly(pkt) &&
17111                     (un->un_last_path_instance != pkt->pkt_path_instance)) {
17112                         if (un->un_state > ST_STATE_OPENING) {
17113                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17114                                     "Failover detected in recovery, action is "
17115                                     "%s\n", errstatenames[action]);
17116                         }
17117                         un->un_last_path_instance = pkt->pkt_path_instance;
17118                 }
17119         }
17120 
17121         ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
17122             "Recovery call back got %s status on %s\n",
17123             errstatenames[action], st_print_scsi_cmd(pkt->pkt_cdbp[0]));
17124 
17125         switch (action) {
17126         case COMMAND_DONE:
17127                 break;
17128 
17129         case COMMAND_DONE_EACCES:
17130                 bioerror(bp, EACCES);
17131                 break;
17132 
17133         case COMMAND_DONE_ERROR_RECOVERED: /* XXX maybe wrong */
17134                 ASSERT(0);
17135                 break;
17136 
17137         case COMMAND_TIMEOUT:
17138         case COMMAND_DONE_ERROR:
17139                 bioerror(bp, EIO);
17140                 break;
17141 
17142         case DEVICE_RESET:
17143         case QUE_BUSY_COMMAND:
17144         case PATH_FAILED:
17145                 /* longish timeout */
17146                 timout = ST_STATUS_BUSY_TIMEOUT;
17147                 /* FALLTHRU */
17148         case QUE_COMMAND:
17149         case DEVICE_TAMPER:
17150         case ATTEMPT_RETRY:
17151                 /*
17152                  * let st_handle_intr_busy put this bp back on waitq and make
17153                  * checks to see if it is ok to requeue the command.
17154                  */
17155                 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
17156 
17157                 /*
17158                  * Save the throttle before setting up the timeout
17159                  */
17160                 if (un->un_throttle) {
17161                         un->un_last_throttle = un->un_throttle;
17162                 }
17163                 mutex_exit(ST_MUTEX);
17164                 if (st_handle_intr_busy(un, bp, timout) == 0) {
17165                         return;         /* timeout is setup again */
17166                 }
17167                 mutex_enter(ST_MUTEX);
17168                 un->un_pos.pmode = invalid;
17169                 un->un_err_resid = bp->b_resid = bp->b_bcount;
17170                 st_bioerror(bp, EIO);
17171                 st_set_pe_flag(un);
17172                 break;
17173 
17174         default:
17175                 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
17176                     "Unhandled recovery state 0x%x\n", action);
17177                 un->un_pos.pmode = invalid;
17178                 un->un_err_resid = bp->b_resid = bp->b_bcount;
17179                 st_bioerror(bp, EIO);
17180                 st_set_pe_flag(un);
17181                 break;
17182         }
17183 
17184         st_done_and_mutex_exit(un, bp);
17185 }
17186 
17187 static int
17188 st_rcmd(struct scsi_tape *un, int com, int64_t count, int wait)
17189 {
17190         struct buf *bp;
17191         int err;
17192 
17193         ST_FUNC(ST_DEVINFO, st_rcmd);
17194 
17195         ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
17196             "st_rcmd(un = 0x%p, com = 0x%x, count = %"PRIx64", wait = %d)\n",
17197             (void *)un, com, count, wait);
17198 
17199         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
17200         ASSERT(mutex_owned(ST_MUTEX));
17201 
17202 #ifdef STDEBUG
17203         if ((st_debug & 0x7)) {
17204                 st_debug_cmds(un, com, count, wait);
17205         }
17206 #endif
17207 
17208         while (un->un_recov_buf_busy)
17209                 cv_wait(&un->un_recov_buf_cv, ST_MUTEX);
17210         un->un_recov_buf_busy = 1;
17211 
17212         bp = un->un_recov_buf;
17213         bzero(bp, sizeof (buf_t));
17214 
17215         bp->b_flags = (wait) ? B_BUSY : B_BUSY|B_ASYNC;
17216 
17217         err = st_setup_cmd(un, bp, com, count);
17218 
17219         un->un_recov_buf_busy = 0;
17220 
17221         cv_signal(&un->un_recov_buf_cv);
17222 
17223         return (err);
17224 }
17225 
17226 /* args used */
17227 static int
17228 st_uscsi_rcmd(struct scsi_tape *un, struct uscsi_cmd *ucmd, int flag)
17229 {
17230         int rval;
17231         buf_t *bp;
17232 
17233         ST_FUNC(ST_DEVINFO, st_uscsi_rcmd);
17234         ASSERT(flag == FKIOCTL);
17235 
17236         /*
17237          * Get buffer resources...
17238          */
17239         while (un->un_recov_buf_busy)
17240                 cv_wait(&un->un_recov_buf_cv, ST_MUTEX);
17241         un->un_recov_buf_busy = 1;
17242 
17243         bp = un->un_recov_buf;
17244         bzero(bp, sizeof (buf_t));
17245 
17246         bp->b_forw = (struct buf *)(uintptr_t)ucmd->uscsi_cdb[0];
17247         bp->b_back = (struct buf *)ucmd;
17248 
17249         mutex_exit(ST_MUTEX);
17250         rval = scsi_uscsi_handle_cmd(un->un_dev, UIO_SYSSPACE, ucmd,
17251             st_strategy, bp, NULL);
17252         mutex_enter(ST_MUTEX);
17253 
17254         ucmd->uscsi_resid = bp->b_resid;
17255 
17256         /*
17257          * Free resources
17258          */
17259         un->un_recov_buf_busy = 0;
17260         cv_signal(&un->un_recov_buf_cv);
17261 
17262         return (rval);
17263 }
17264 
17265 /*
17266  * Add data to scsi_pkt to help know what to do if the command fails.
17267  */
17268 static void
17269 st_add_recovery_info_to_pkt(struct scsi_tape *un, buf_t *bp,
17270     struct scsi_pkt *pkt)
17271 {
17272         uint64_t count;
17273         recov_info *rinfo = (recov_info *)pkt->pkt_private;
17274 
17275         ST_FUNC(ST_DEVINFO, st_add_recovery_info_to_pkt);
17276 
17277         ASSERT(rinfo->privatelen == sizeof (pkt_info) ||
17278             rinfo->privatelen == sizeof (recov_info));
17279 
17280         SET_BP_PKT(bp, pkt);
17281         rinfo->cmd_bp = bp;
17282 
17283         if (rinfo->privatelen != sizeof (recov_info)) {
17284                 return;
17285         }
17286 
17287         rinfo->cmd_bp = bp;
17288 
17289         rinfo->cmd_attrib = NULL;
17290 
17291         /*
17292          * lookup the command attributes and add them to the recovery info.
17293          */
17294         rinfo->cmd_attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
17295 
17296         ASSERT(rinfo->cmd_attrib);
17297 
17298         /*
17299          * For commands that there is no way to figure the expected position
17300          * once completed, we save the position the command was started from
17301          * so that if they fail we can position back and try again.
17302          * This has already been done in st_cmd() or st_iscsi_cmd().
17303          */
17304         if (rinfo->cmd_attrib->recov_pos_type == POS_STARTING) {
17305                 /* save current position as the starting position. */
17306                 COPY_POS(&rinfo->pos, &un->un_pos);
17307                 un->un_running.pmode = invalid;
17308                 return;
17309         }
17310 
17311         /*
17312          * Don't want to update the running position for recovery.
17313          */
17314         if (bp == un->un_recov_buf) {
17315                 rinfo->pos.pmode = un->un_running.pmode;
17316                 return;
17317         }
17318         /*
17319          * If running position is invalid copy the current position.
17320          * Running being set invalid means we are not in a read, write
17321          * or write filemark sequence.
17322          * We'll copy the current position and start from there.
17323          */
17324         if (un->un_running.pmode == invalid) {
17325                 COPY_POS(&un->un_running, &un->un_pos);
17326                 COPY_POS(&rinfo->pos, &un->un_running);
17327         } else {
17328                 COPY_POS(&rinfo->pos, &un->un_running);
17329                 if (rinfo->pos.pmode == legacy) {
17330                         /*
17331                          * Always should be more logical blocks then
17332                          * data blocks and files marks.
17333                          */
17334                         ASSERT((rinfo->pos.blkno >= 0) ?
17335                             rinfo->pos.lgclblkno >=
17336                             (rinfo->pos.blkno + rinfo->pos.fileno) : 1);
17337                 }
17338         }
17339 
17340         /*
17341          * If the command is not expected to change the drive position
17342          * then the running position should be the expected position.
17343          */
17344         if (rinfo->cmd_attrib->chg_tape_pos == 0) {
17345                 ASSERT(rinfo->cmd_attrib->chg_tape_direction == DIR_NONE);
17346                 return;
17347         }
17348 
17349         if (rinfo->cmd_attrib->explicit_cmd_set) {
17350                 ASSERT(rinfo->pos.pmode != invalid);
17351                 ASSERT(rinfo->cmd_attrib->get_cnt);
17352                 count = rinfo->cmd_attrib->get_cnt(pkt->pkt_cdbp);
17353                 /*
17354                  * This is a user generated CDB.
17355                  */
17356                 if (bp == un->un_sbufp) {
17357                         uint64_t lbn;
17358 
17359                         lbn = rinfo->cmd_attrib->get_lba(pkt->pkt_cdbp);
17360 
17361                         /*
17362                          * See if this CDB will generate a locate or change
17363                          * partition.
17364                          */
17365                         if ((lbn != un->un_running.lgclblkno) ||
17366                             (pkt->pkt_cdbp[3] != un->un_running.partition)) {
17367                                 rinfo->pos.partition = pkt->pkt_cdbp[3];
17368                                 rinfo->pos.pmode = logical;
17369                                 rinfo->pos.lgclblkno = lbn;
17370                                 un->un_running.partition = pkt->pkt_cdbp[3];
17371                                 un->un_running.pmode = logical;
17372                                 un->un_running.lgclblkno = lbn;
17373                         }
17374                 } else {
17375                         uint64_t lbn = un->un_running.lgclblkno;
17376 
17377                         pkt->pkt_cdbp[3]  = (uchar_t)un->un_running.partition;
17378 
17379                         pkt->pkt_cdbp[4]  = (uchar_t)(lbn >> 56);
17380                         pkt->pkt_cdbp[5]  = (uchar_t)(lbn >> 48);
17381                         pkt->pkt_cdbp[6]  = (uchar_t)(lbn >> 40);
17382                         pkt->pkt_cdbp[7]  = (uchar_t)(lbn >> 32);
17383                         pkt->pkt_cdbp[8]  = (uchar_t)(lbn >> 24);
17384                         pkt->pkt_cdbp[9]  = (uchar_t)(lbn >> 16);
17385                         pkt->pkt_cdbp[10] = (uchar_t)(lbn >> 8);
17386                         pkt->pkt_cdbp[11] = (uchar_t)(lbn);
17387                 }
17388                 rinfo->pos.lgclblkno += count;
17389                 rinfo->pos.blkno += count;
17390                 un->un_running.lgclblkno += count;
17391                 return;
17392         }
17393 
17394         if (rinfo->cmd_attrib->chg_tape_pos) {
17395 
17396                 /* should not have got an invalid position from running. */
17397                 if (un->un_mediastate == MTIO_INSERTED) {
17398                         ASSERT(rinfo->pos.pmode != invalid);
17399                 }
17400 
17401                 /* should have either a get count or or get lba function */
17402                 ASSERT(rinfo->cmd_attrib->get_cnt != NULL ||
17403                     rinfo->cmd_attrib->get_lba != NULL);
17404 
17405                 /* only explicit commands have both and they're handled above */
17406                 ASSERT(!(rinfo->cmd_attrib->get_cnt != NULL &&
17407                     rinfo->cmd_attrib->get_lba != NULL));
17408 
17409                 /* if it has a get count function */
17410                 if (rinfo->cmd_attrib->get_cnt != NULL) {
17411                         count = rinfo->cmd_attrib->get_cnt(pkt->pkt_cdbp);
17412                         if (count == 0) {
17413                                 return;
17414                         }
17415                         /*
17416                          * Changes position but doesn't transfer data.
17417                          * i.e. rewind, write_file_mark and load.
17418                          */
17419                         if (rinfo->cmd_attrib->transfers_data == TRAN_NONE) {
17420                                 switch (rinfo->cmd_attrib->chg_tape_direction) {
17421                                 case DIR_NONE: /* Erase */
17422                                         ASSERT(rinfo->cmd_attrib->cmd ==
17423                                             SCMD_ERASE);
17424                                         break;
17425                                 case DIR_FORW: /* write_file_mark */
17426                                         rinfo->pos.fileno += count;
17427                                         rinfo->pos.lgclblkno += count;
17428                                         rinfo->pos.blkno = 0;
17429                                         un->un_running.fileno += count;
17430                                         un->un_running.lgclblkno += count;
17431                                         un->un_running.blkno = 0;
17432                                         break;
17433                                 case DIR_REVC: /* rewind */
17434                                         rinfo->pos.fileno = 0;
17435                                         rinfo->pos.lgclblkno = 0;
17436                                         rinfo->pos.blkno = 0;
17437                                         rinfo->pos.eof = ST_NO_EOF;
17438                                         rinfo->pos.pmode = legacy;
17439                                         un->un_running.fileno = 0;
17440                                         un->un_running.lgclblkno = 0;
17441                                         un->un_running.blkno = 0;
17442                                         un->un_running.eof = ST_NO_EOF;
17443                                         if (un->un_running.pmode != legacy)
17444                                                 un->un_running.pmode = legacy;
17445                                         break;
17446                                 case DIR_EITH: /* Load unload */
17447                                         ASSERT(rinfo->cmd_attrib->cmd ==
17448                                             SCMD_LOAD);
17449                                         switch (count & (LD_LOAD | LD_RETEN |
17450                                             LD_RETEN | LD_HOLD)) {
17451                                         case LD_UNLOAD:
17452                                         case LD_RETEN:
17453                                         case LD_HOLD:
17454                                         case LD_LOAD | LD_HOLD:
17455                                         case LD_EOT | LD_HOLD:
17456                                         case LD_RETEN | LD_HOLD:
17457                                                 rinfo->pos.pmode = invalid;
17458                                                 un->un_running.pmode = invalid;
17459                                                 break;
17460                                         case LD_EOT:
17461                                         case LD_LOAD | LD_EOT:
17462                                                 rinfo->pos.eof = ST_EOT;
17463                                                 rinfo->pos.pmode = invalid;
17464                                                 un->un_running.eof = ST_EOT;
17465                                                 un->un_running.pmode = invalid;
17466                                                 break;
17467                                         case LD_LOAD:
17468                                         case LD_RETEN | LD_LOAD:
17469                                                 rinfo->pos.fileno = 0;
17470                                                 rinfo->pos.lgclblkno = 0;
17471                                                 rinfo->pos.blkno = 0;
17472                                                 rinfo->pos.eof = ST_NO_EOF;
17473                                                 rinfo->pos.pmode = legacy;
17474                                                 un->un_running.fileno = 0;
17475                                                 un->un_running.lgclblkno = 0;
17476                                                 un->un_running.blkno = 0;
17477                                                 un->un_running.eof = ST_NO_EOF;
17478                                                 break;
17479                                         default:
17480                                                 ASSERT(0);
17481                                         }
17482                                         break;
17483                                 default:
17484                                         ASSERT(0);
17485                                         break;
17486                                 }
17487                         } else {
17488                                 /*
17489                                  * Changes position and does transfer data.
17490                                  * i.e. read or write.
17491                                  */
17492                                 switch (rinfo->cmd_attrib->chg_tape_direction) {
17493                                 case DIR_FORW:
17494                                         rinfo->pos.lgclblkno += count;
17495                                         rinfo->pos.blkno += count;
17496                                         un->un_running.lgclblkno += count;
17497                                         un->un_running.blkno += count;
17498                                         break;
17499                                 case DIR_REVC:
17500                                         rinfo->pos.lgclblkno -= count;
17501                                         rinfo->pos.blkno -= count;
17502                                         un->un_running.lgclblkno -= count;
17503                                         un->un_running.blkno -= count;
17504                                         break;
17505                                 default:
17506                                         ASSERT(0);
17507                                         break;
17508                                 }
17509                         }
17510                 } else if (rinfo->cmd_attrib->get_lba != NULL) {
17511                         /* Have a get LBA fuction. i.e. Locate */
17512                         ASSERT(rinfo->cmd_attrib->chg_tape_direction ==
17513                             DIR_EITH);
17514                         count = rinfo->cmd_attrib->get_lba(pkt->pkt_cdbp);
17515                         un->un_running.lgclblkno = count;
17516                         un->un_running.blkno = 0;
17517                         un->un_running.fileno = 0;
17518                         un->un_running.pmode = logical;
17519                         rinfo->pos.lgclblkno = count;
17520                         rinfo->pos.pmode = invalid;
17521                 } else {
17522                         ASSERT(0);
17523                 }
17524                 return;
17525         }
17526 
17527         ST_CDB(ST_DEVINFO, "Unhanded CDB for position prediction",
17528             (char *)pkt->pkt_cdbp);
17529 
17530 }
17531 
17532 static int
17533 st_make_sure_mode_data_is_correct(struct scsi_tape *un, ubufunc_t ubf)
17534 {
17535         int rval;
17536 
17537         ST_FUNC(ST_DEVINFO, st_make_sure_mode_data_is_correct);
17538 
17539         /*
17540          * check to see if mode data has changed.
17541          */
17542         rval = st_check_mode_for_change(un, ubf);
17543         if (rval) {
17544                 rval = st_gen_mode_select(un, ubf, un->un_mspl,
17545                     sizeof (struct seq_mode));
17546         }
17547         if (un->un_tlr_flag != TLR_NOT_SUPPORTED) {
17548                 rval |= st_set_target_TLR_mode(un, ubf);
17549         }
17550         return (rval);
17551 }
17552 
17553 static int
17554 st_check_mode_for_change(struct scsi_tape *un, ubufunc_t ubf)
17555 {
17556         struct seq_mode *current;
17557         int rval;
17558         int i;
17559         caddr_t this;
17560         caddr_t that;
17561 
17562         ST_FUNC(ST_DEVINFO, st_check_mode_for_change);
17563 
17564         /* recovery called with mode tamper before mode selection */
17565         if (un->un_comp_page == (ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE)) {
17566                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17567                     "Mode Select not done yet");
17568                 return (0);
17569         }
17570 
17571         current = kmem_zalloc(sizeof (struct seq_mode), KM_SLEEP);
17572 
17573         rval = st_gen_mode_sense(un, ubf, un->un_comp_page, current,
17574             sizeof (struct seq_mode));
17575         if (rval != 0) {
17576                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17577                     "Mode Sense for mode verification failed");
17578                 kmem_free(current, sizeof (struct seq_mode));
17579                 return (rval);
17580         }
17581 
17582         this = (caddr_t)current;
17583         that = (caddr_t)un->un_mspl;
17584 
17585         rval = bcmp(this, that, sizeof (struct seq_mode));
17586         if (rval == 0) {
17587                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17588                     "Found no changes in mode data");
17589         }
17590 #ifdef STDEBUG
17591         else {
17592                 for (i = 1; i < sizeof (struct seq_mode); i++) {
17593                         if (this[i] != that[i]) {
17594                                 ST_RECOV(ST_DEVINFO, st_label, CE_CONT,
17595                                     "sense data changed at byte %d was "
17596                                     "0x%x now 0x%x", i,
17597                                     (uchar_t)that[i], (uchar_t)this[i]);
17598                         }
17599                 }
17600         }
17601 #endif
17602         kmem_free(current, sizeof (struct seq_mode));
17603 
17604         return (rval);
17605 }
17606 
17607 static int
17608 st_test_path_to_device(struct scsi_tape *un)
17609 {
17610         int rval = 0;
17611         int limit = st_retry_count;
17612 
17613         ST_FUNC(ST_DEVINFO, st_test_path_to_device);
17614 
17615         /*
17616          * XXX Newer drives may not RESEVATION CONFLICT a TUR.
17617          */
17618         do {
17619                 if (rval != 0) {
17620                         mutex_exit(ST_MUTEX);
17621                         delay(drv_usectohz(1000000));
17622                         mutex_enter(ST_MUTEX);
17623                 }
17624                 rval = st_rcmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
17625                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17626                     "ping TUR returned 0x%x", rval);
17627                 limit--;
17628         } while (((rval == EACCES) || (rval == EBUSY)) && limit);
17629 
17630         if (un->un_status == KEY_NOT_READY || un->un_mediastate == MTIO_EJECTED)
17631                 rval = 0;
17632 
17633         return (rval);
17634 }
17635 
17636 /*
17637  * Does read position using recov_buf and doesn't update un_pos.
17638  * Does what ever kind of read position you want.
17639  */
17640 static int
17641 st_recovery_read_pos(struct scsi_tape *un, read_p_types type,
17642     read_pos_data_t *raw)
17643 {
17644         int rval;
17645         struct uscsi_cmd cmd;
17646         struct scsi_arq_status status;
17647         char cdb[CDB_GROUP1];
17648 
17649         ST_FUNC(ST_DEVINFO, st_recovery_read_pos);
17650         bzero(&cmd, sizeof (cmd));
17651 
17652         cdb[0] = SCMD_READ_POSITION;
17653         cdb[1] = type;
17654         cdb[2] = 0;
17655         cdb[3] = 0;
17656         cdb[4] = 0;
17657         cdb[5] = 0;
17658         cdb[6] = 0;
17659         cdb[7] = 0;
17660         cdb[8] = (type == EXT_POS) ? 28 : 0;
17661         cdb[9] = 0;
17662 
17663         cmd.uscsi_flags = USCSI_READ | USCSI_RQENABLE;
17664         cmd.uscsi_timeout = un->un_dp->non_motion_timeout;
17665         cmd.uscsi_cdb = cdb;
17666         cmd.uscsi_cdblen = sizeof (cdb);
17667         cmd.uscsi_rqlen = sizeof (status);
17668         cmd.uscsi_rqbuf = (caddr_t)&status;
17669         cmd.uscsi_bufaddr = (caddr_t)raw;
17670         switch (type) {
17671         case SHORT_POS:
17672                 cmd.uscsi_buflen = sizeof (tape_position_t);
17673                 break;
17674         case LONG_POS:
17675                 cmd.uscsi_buflen = sizeof (tape_position_long_t);
17676                 break;
17677         case EXT_POS:
17678                 cmd.uscsi_buflen = sizeof (tape_position_ext_t);
17679                 break;
17680         default:
17681                 ASSERT(0);
17682         }
17683 
17684         rval = st_uscsi_rcmd(un, &cmd, FKIOCTL);
17685         if (cmd.uscsi_status) {
17686                 rval = EIO;
17687         }
17688         return (rval);
17689 }
17690 
17691 static int
17692 st_recovery_get_position(struct scsi_tape *un, tapepos_t *read,
17693     read_pos_data_t *raw)
17694 {
17695         int rval;
17696         read_p_types type = un->un_read_pos_type;
17697 
17698         ST_FUNC(ST_DEVINFO, st_recovery_get_position);
17699 
17700         do {
17701                 rval = st_recovery_read_pos(un, type, raw);
17702                 if (rval != 0) {
17703                         switch (type) {
17704                         case SHORT_POS:
17705                                 type = NO_POS;
17706                                 break;
17707 
17708                         case LONG_POS:
17709                                 type = EXT_POS;
17710                                 break;
17711 
17712                         case EXT_POS:
17713                                 type = SHORT_POS;
17714                                 break;
17715 
17716                         default:
17717                                 type = LONG_POS;
17718                                 break;
17719 
17720                         }
17721                 } else {
17722                         if (type != un->un_read_pos_type) {
17723                                 un->un_read_pos_type = type;
17724                         }
17725                         break;
17726                 }
17727         } while (type != NO_POS);
17728 
17729         if (rval == 0) {
17730                 rval = st_interpret_read_pos(un, read, type,
17731                     sizeof (read_pos_data_t), (caddr_t)raw, 1);
17732         }
17733         return (rval);
17734 }
17735 
17736 /*
17737  * based on the command do we retry, continue or give up?
17738  * possable return values?
17739  *      zero do nothing looks fine.
17740  *      EAGAIN retry.
17741  *      EIO failed makes no sense.
17742  */
17743 static int
17744 st_compare_expected_position(struct scsi_tape *un, st_err_info *ei,
17745     cmd_attribute const * cmd_att, tapepos_t *read)
17746 {
17747         int rval;
17748         read_pos_data_t *readp_datap;
17749 
17750         ST_FUNC(ST_DEVINFO, st_compare_expected_position);
17751 
17752         ASSERT(un != NULL);
17753         ASSERT(ei != NULL);
17754         ASSERT(read != NULL);
17755         ASSERT(cmd_att->chg_tape_pos);
17756 
17757         COPY_POS(read, &ei->ei_expected_pos);
17758 
17759         readp_datap = kmem_zalloc(sizeof (read_pos_data_t), KM_SLEEP);
17760 
17761         rval = st_recovery_get_position(un, read, readp_datap);
17762 
17763         kmem_free(readp_datap, sizeof (read_pos_data_t));
17764 
17765         if (rval != 0) {
17766                 return (EIO);
17767         }
17768 
17769         ST_POS(ST_DEVINFO, "st_compare_expected_position", read);
17770 
17771         if ((read->pmode == invalid) ||
17772             (ei->ei_expected_pos.pmode == invalid)) {
17773                 return (EIO);
17774         }
17775 
17776         /*
17777          * Command that changes tape position and have an expected position
17778          * if it were to chave completed sucessfully.
17779          */
17780         if (cmd_att->recov_pos_type == POS_EXPECTED) {
17781                 uint32_t count;
17782                 int64_t difference;
17783                 uchar_t reposition = 0;
17784 
17785                 ASSERT(cmd_att->get_cnt);
17786                 count = cmd_att->get_cnt(ei->ei_failed_pkt.pkt_cdbp);
17787 
17788                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17789                     "Got count from CDB and it was %d\n", count);
17790 
17791                 /*
17792                  * At expected?
17793                  */
17794                 if (read->lgclblkno == ei->ei_expected_pos.lgclblkno) {
17795                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17796                             "Found drive to be at expected position\n");
17797 
17798                         /*
17799                          * If the command should move tape and it got a busy
17800                          * it shouldn't be in the expected position.
17801                          */
17802                         if (ei->ei_failing_status.sts_status.sts_busy != 0) {
17803                                 reposition = 1;
17804 
17805                         /*
17806                          * If the command doesn't transfer data should be good.
17807                          */
17808                         } else if (cmd_att->transfers_data == TRAN_NONE) {
17809                                 return (0); /* Good */
17810 
17811                         /*
17812                          * Command transfers data, should have done so.
17813                          */
17814                         } else if (ei->ei_failed_pkt.pkt_state &
17815                             STATE_XFERRED_DATA) {
17816                                 return (0); /* Good */
17817                         } else {
17818                                 reposition = 1;
17819                         }
17820                 }
17821 
17822                 if (cmd_att->chg_tape_direction == DIR_FORW) {
17823                         difference =
17824                             ei->ei_expected_pos.lgclblkno - read->lgclblkno;
17825 
17826                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17827                             "difference between expected and actual is %"
17828                             PRId64"\n", difference);
17829                         if (count == difference && reposition == 0) {
17830                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17831                                     "Found failed FORW command, retrying\n");
17832                                 return (EAGAIN);
17833                         }
17834 
17835                         /*
17836                          * If rewound or somewhere between the starting position
17837                          * and the expected position (partial read or write).
17838                          * Locate to the starting position and try the whole
17839                          * thing over again.
17840                          */
17841                         if ((read->lgclblkno == 0) ||
17842                             ((difference > 0) && (difference < count))) {
17843                                 rval = st_logical_block_locate(un,
17844                                     st_uscsi_rcmd, read,
17845                                     ei->ei_expected_pos.lgclblkno - count,
17846                                     ei->ei_expected_pos.partition);
17847                                 if (rval == 0) {
17848                                         ST_RECOV(ST_DEVINFO, st_label,
17849                                             CE_NOTE, "reestablished FORW"
17850                                             " command retrying\n");
17851                                         return (EAGAIN);
17852                                 }
17853                         /*
17854                          * This handles flushed read ahead on the drive or
17855                          * an aborted read that presents as a busy and advanced
17856                          * the tape position.
17857                          */
17858                         } else if ((cmd_att->transfers_data == TRAN_READ) &&
17859                             ((difference < 0) || (reposition == 1))) {
17860                                 rval = st_logical_block_locate(un,
17861                                     st_uscsi_rcmd, read,
17862                                     ei->ei_expected_pos.lgclblkno - count,
17863                                     ei->ei_expected_pos.partition);
17864                                 if (rval == 0) {
17865                                         ST_RECOV(ST_DEVINFO, st_label,
17866                                             CE_NOTE, "reestablished FORW"
17867                                             " read command retrying\n");
17868                                         return (EAGAIN);
17869                                 }
17870                         /*
17871                          * XXX swag seeing difference of 2 on write filemark.
17872                          * If the space to the starting position works on a
17873                          * write that means the previous write made it to tape.
17874                          * If not we lost data and have to give up.
17875                          *
17876                          * The plot thickens. Now I am attempting to cover a
17877                          * count of 1 and a differance of 2 on a write.
17878                          */
17879                         } else if ((difference > count) || (reposition == 1)) {
17880                                 rval = st_logical_block_locate(un,
17881                                     st_uscsi_rcmd, read,
17882                                     ei->ei_expected_pos.lgclblkno - count,
17883                                     ei->ei_expected_pos.partition);
17884                                 if (rval == 0) {
17885                                         ST_RECOV(ST_DEVINFO, st_label,
17886                                             CE_NOTE, "reestablished FORW"
17887                                             " write command retrying\n");
17888                                         return (EAGAIN);
17889                                 }
17890                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17891                                     "Seek to block %"PRId64" returned %d\n",
17892                                     ei->ei_expected_pos.lgclblkno - count,
17893                                     rval);
17894                         } else {
17895                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17896                                     "Not expected transfers_data = %d "
17897                                     "difference = %"PRId64,
17898                                     cmd_att->transfers_data, difference);
17899                         }
17900 
17901                         return (EIO);
17902 
17903                 } else if (cmd_att->chg_tape_direction == DIR_REVC) {
17904                         /* Don't think we can write backwards */
17905                         ASSERT(cmd_att->transfers_data != TRAN_WRTE);
17906                         difference =
17907                             read->lgclblkno - ei->ei_expected_pos.lgclblkno;
17908                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17909                             "difference between expected and actual is %"
17910                             PRId64"\n", difference);
17911                         if (count == difference && reposition == 0) {
17912                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17913                                     "Found failed REVC command, retrying\n");
17914                                 return (EAGAIN);
17915                         }
17916                         if ((read->lgclblkno == 0) ||
17917                             ((difference > 0) && (difference < count))) {
17918                                 rval = st_logical_block_locate(un,
17919                                     st_uscsi_rcmd, read,
17920                                     ei->ei_expected_pos.lgclblkno + count,
17921                                     ei->ei_expected_pos.partition);
17922                                 if (rval == 0) {
17923                                         ST_RECOV(ST_DEVINFO, st_label,
17924                                             CE_NOTE, "reestablished REVC"
17925                                             " command retrying\n");
17926                                         return (EAGAIN);
17927                                 }
17928                         /* This handles read ahead in reverse direction */
17929                         } else if ((cmd_att->transfers_data == TRAN_READ) &&
17930                             (difference < 0) || (reposition == 1)) {
17931                                 rval = st_logical_block_locate(un,
17932                                     st_uscsi_rcmd, read,
17933                                     ei->ei_expected_pos.lgclblkno - count,
17934                                     ei->ei_expected_pos.partition);
17935                                 if (rval == 0) {
17936                                         ST_RECOV(ST_DEVINFO, st_label,
17937                                             CE_NOTE, "reestablished REVC"
17938                                             " read command retrying\n");
17939                                         return (EAGAIN);
17940                                 }
17941                         } else {
17942                                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17943                                     "Not expected transfers_data = %d "
17944                                     "difference = %"PRId64,
17945                                     cmd_att->transfers_data, difference);
17946                         }
17947                         return (EIO);
17948 
17949                 } else {
17950                         /*
17951                          * Commands that change tape position either
17952                          * direction or don't change position should not
17953                          * get here.
17954                          */
17955                         ASSERT(0);
17956                 }
17957                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17958                     "Didn't find a recoverable position, Failing\n");
17959 
17960         /*
17961          * Command that changes tape position and can only be recovered
17962          * by going back to the point of origin and retrying.
17963          *
17964          * Example SCMD_SPACE.
17965          */
17966         } else if (cmd_att->recov_pos_type == POS_STARTING) {
17967                 /*
17968                  * This type of command stores the starting position.
17969                  * If the read position is the starting position,
17970                  * reissue the command.
17971                  */
17972                 if (ei->ei_expected_pos.lgclblkno == read->lgclblkno) {
17973                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17974                             "Found Space command at starting position, "
17975                             "Reissuing\n");
17976                         return (EAGAIN);
17977                 }
17978                 /*
17979                  * Not in the position that the command was originally issued,
17980                  * Attempt to locate to that position.
17981                  */
17982                 rval = st_logical_block_locate(un, st_uscsi_rcmd, read,
17983                     ei->ei_expected_pos.lgclblkno,
17984                     ei->ei_expected_pos.partition);
17985                 if (rval) {
17986                         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17987                             "Found Space at an unexpected position and locate "
17988                             "back to starting position failed\n");
17989                         return (EIO);
17990                 }
17991                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17992                     "Found Space at an unexpected position and locate "
17993                     "back to starting position worked, Reissuing\n");
17994                 return (EAGAIN);
17995         }
17996         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
17997             "Unhandled attribute/expected position", &ei->ei_expected_pos);
17998         st_print_position(ST_DEVINFO, st_label, CE_NOTE,
17999             "Read position above did not make sense", read);
18000         ASSERT(0);
18001         return (EIO);
18002 }
18003 
18004 static errstate
18005 st_recover_reissue_pkt(struct scsi_tape *un, struct scsi_pkt *oldpkt)
18006 {
18007         buf_t *bp;
18008         buf_t *pkt_bp;
18009         struct scsi_pkt *newpkt;
18010         cmd_attribute const *attrib;
18011         recov_info *rcv = oldpkt->pkt_private;
18012         uint_t cdblen;
18013         int queued = 0;
18014         int rval;
18015         int flags = 0;
18016         int stat_size =
18017             (un->un_arq_enabled ? sizeof (struct scsi_arq_status) : 1);
18018 
18019         ST_FUNC(ST_DEVINFO, st_recover_reissue_pkt);
18020 
18021         bp = rcv->cmd_bp;
18022 
18023         if (rcv->privatelen == sizeof (recov_info)) {
18024                 attrib = rcv->cmd_attrib;
18025         } else {
18026                 attrib = st_lookup_cmd_attribute(oldpkt->pkt_cdbp[0]);
18027         }
18028 
18029         /*
18030          * Some non-uscsi commands use the b_bcount for values that
18031          * have nothing to do with how much data is transfered.
18032          * In those cases we need to hide the buf_t from scsi_init_pkt().
18033          */
18034         if ((BP_UCMD(bp)) && (bp->b_bcount)) {
18035                 pkt_bp = bp;
18036         } else if (attrib->transfers_data == TRAN_NONE) {
18037                 pkt_bp = NULL;
18038         } else {
18039                 pkt_bp = bp;
18040         }
18041 
18042         /*
18043          * if this is a queued command make sure it the only one in the
18044          * run queue.
18045          */
18046         if (bp != un->un_sbufp && bp != un->un_recov_buf) {
18047                 ASSERT(un->un_runqf == un->un_runql);
18048                 ASSERT(un->un_runqf == bp);
18049                 queued = 1;
18050         }
18051 
18052         cdblen = scsi_cdb_size[CDB_GROUPID(oldpkt->pkt_cdbp[0])];
18053 
18054         if (pkt_bp == un->un_rqs_bp) {
18055                 flags |= PKT_CONSISTENT;
18056                 stat_size = 1;
18057         }
18058 
18059         newpkt = scsi_init_pkt(ROUTE, NULL, pkt_bp, cdblen,
18060             stat_size, rcv->privatelen, flags, NULL_FUNC, NULL);
18061         if (newpkt == NULL) {
18062                 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
18063                     "Reissue pkt scsi_init_pkt() failure\n");
18064                 return (COMMAND_DONE_ERROR);
18065         }
18066 
18067         ASSERT(newpkt->pkt_resid == 0);
18068         bp->b_flags &= ~(B_DONE);
18069         bp->b_resid = 0;
18070         st_bioerror(bp, 0);
18071 
18072         bcopy(oldpkt->pkt_private, newpkt->pkt_private, rcv->privatelen);
18073 
18074         newpkt->pkt_comp = oldpkt->pkt_comp;
18075         newpkt->pkt_time = oldpkt->pkt_time;
18076 
18077         bzero(newpkt->pkt_scbp, stat_size);
18078         bcopy(oldpkt->pkt_cdbp, newpkt->pkt_cdbp, cdblen);
18079 
18080         newpkt->pkt_state = 0;
18081         newpkt->pkt_statistics = 0;
18082 
18083         /*
18084          * oldpkt passed in was a copy of the original.
18085          * to distroy we need the address of the original.
18086          */
18087         oldpkt = BP_PKT(bp);
18088 
18089         if (oldpkt == un->un_rqs) {
18090                 ASSERT(bp == un->un_rqs_bp);
18091                 un->un_rqs = newpkt;
18092         }
18093 
18094         SET_BP_PKT(bp, newpkt);
18095 
18096         scsi_destroy_pkt(oldpkt);
18097 
18098         rval = st_transport(un, newpkt);
18099         if (rval == TRAN_ACCEPT) {
18100                 return (JUST_RETURN);
18101         }
18102         ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
18103             "Reissue pkt st_transport(0x%x) failure\n", rval);
18104         if (rval != TRAN_BUSY) {
18105                 return (COMMAND_DONE_ERROR);
18106         }
18107         mutex_exit(ST_MUTEX);
18108         rval = st_handle_start_busy(un, bp, ST_TRAN_BUSY_TIMEOUT, queued);
18109         mutex_enter(ST_MUTEX);
18110         if (rval) {
18111                 return (COMMAND_DONE_ERROR);
18112         }
18113 
18114         return (JUST_RETURN);
18115 }
18116 
18117 static int
18118 st_transport(struct scsi_tape *un, struct scsi_pkt *pkt)
18119 {
18120         int status;
18121 
18122         ST_FUNC(ST_DEVINFO, st_transport);
18123 
18124         ST_CDB(ST_DEVINFO, "transport CDB", (caddr_t)pkt->pkt_cdbp);
18125 
18126         mutex_exit(ST_MUTEX);
18127 
18128         status = scsi_transport(pkt);
18129 
18130         mutex_enter(ST_MUTEX);
18131 
18132         return (status);
18133 }
18134 
18135 /*
18136  * Removed the buf_t bp from the queue referenced to by head and tail.
18137  * Returns the buf_t pointer if it is found in the queue.
18138  * Returns NULL if it is not found.
18139  */
18140 static buf_t *
18141 st_remove_from_queue(buf_t **head, buf_t **tail, buf_t *bp)
18142 {
18143         buf_t *runqbp;
18144         buf_t *prevbp = NULL;
18145 
18146         for (runqbp = *head; runqbp != 0; runqbp = runqbp->av_forw) {
18147                 if (runqbp == bp) {
18148                         /* found it, is it at the head? */
18149                         if (runqbp == *head) {
18150                                 *head = bp->av_forw;
18151                         } else {
18152                                 prevbp->av_forw = bp->av_forw;
18153                         }
18154                         if (*tail == bp) {
18155                                 *tail = prevbp;
18156                         }
18157                         bp->av_forw = NULL;
18158                         return (bp); /* found and removed */
18159                 }
18160                 prevbp = runqbp;
18161         }
18162         return (NULL);
18163 }
18164 
18165 /*
18166  * Adds a buf_t to the queue pointed to by head and tail.
18167  * Adds it either to the head end or the tail end based on which
18168  * the passed variable end (head or tail) points at.
18169  */
18170 static void
18171 st_add_to_queue(buf_t **head, buf_t **tail, buf_t *end, buf_t *bp)
18172 {
18173 
18174         bp->av_forw = NULL;
18175         if (*head) {
18176                 /* Queue is not empty */
18177                 if (end == *head) {
18178                         /* Add at front of queue */
18179                         bp->av_forw = *head;
18180                         *head = bp;
18181                 } else if (end == *tail) {
18182                         /* Add at end of queue */
18183                         (*tail)->av_forw = bp;
18184                         *tail = bp;
18185                 } else {
18186                         ASSERT(0);
18187                 }
18188         } else {
18189                 /* Queue is empty */
18190                 *head = bp;
18191                 *tail = bp;
18192         }
18193 }
18194 
18195 
18196 static uint64_t
18197 st_get_cdb_g0_rw_count(uchar_t *cdb)
18198 {
18199         uint64_t count;
18200 
18201         if ((cdb[1]) & 1) {
18202                 /* fixed block mode, the count is the number of blocks */
18203                 count =
18204                     cdb[2] << 16 |
18205                     cdb[3] << 8 |
18206                     cdb[4];
18207         } else {
18208                 /* variable block mode, the count is the block size */
18209                 count = 1;
18210         }
18211         return (count);
18212 }
18213 
18214 static uint64_t
18215 st_get_cdb_g0_sign_count(uchar_t *cdb)
18216 {
18217         uint64_t count;
18218 
18219         count =
18220             cdb[2] << 16 |
18221             cdb[3] << 8 |
18222             cdb[4];
18223         /*
18224          * If the sign bit of the 3 byte value is set, extended it.
18225          */
18226         if (count & 0x800000) {
18227                 count |= 0xffffffffff000000;
18228         }
18229         return (count);
18230 }
18231 
18232 static uint64_t
18233 st_get_cdb_g0_count(uchar_t *cdb)
18234 {
18235         uint64_t count;
18236 
18237         count =
18238             cdb[2] << 16 |
18239             cdb[3] << 8 |
18240             cdb[4];
18241         return (count);
18242 }
18243 
18244 static uint64_t
18245 st_get_cdb_g5_rw_cnt(uchar_t *cdb)
18246 {
18247         uint64_t count;
18248 
18249         if ((cdb[1]) & 1) {
18250                 /* fixed block mode */
18251                 count =
18252                     cdb[12] << 16 |
18253                     cdb[13] << 8 |
18254                     cdb[14];
18255         } else {
18256                 /* variable block mode */
18257                 count = 1;
18258         }
18259         return (count);
18260 }
18261 
18262 static uint64_t
18263 st_get_no_count(uchar_t *cdb)
18264 {
18265         ASSERT(cdb[0] == SCMD_REWIND);
18266         return ((uint64_t)cdb[0]);
18267 }
18268 
18269 static uint64_t
18270 st_get_load_options(uchar_t *cdb)
18271 {
18272         return ((uint64_t)(cdb[4] | (LD_HOLD << 1)));
18273 }
18274 
18275 static uint64_t
18276 st_get_erase_options(uchar_t *cdb)
18277 {
18278         return (cdb[1] | (cdb[0] << 8));
18279 }
18280 
18281 static uint64_t
18282 st_get_cdb_g1_lba(uchar_t *cdb)
18283 {
18284         uint64_t lba;
18285 
18286         lba =
18287             cdb[3] << 24 |
18288             cdb[4] << 16 |
18289             cdb[5] << 8 |
18290             cdb[6];
18291         return (lba);
18292 }
18293 
18294 static uint64_t
18295 st_get_cdb_g5_count(uchar_t *cdb)
18296 {
18297         uint64_t count =
18298             cdb[12] << 16 |
18299             cdb[13] << 8 |
18300             cdb[14];
18301 
18302         return (count);
18303 }
18304 
18305 static uint64_t
18306 st_get_cdb_g4g5_cnt(uchar_t *cdb)
18307 {
18308         uint64_t lba;
18309 
18310         lba =
18311             (uint64_t)cdb[4] << 56 |
18312             (uint64_t)cdb[5] << 48 |
18313             (uint64_t)cdb[6] << 40 |
18314             (uint64_t)cdb[7] << 32 |
18315             (uint64_t)cdb[8] << 24 |
18316             (uint64_t)cdb[9] << 16 |
18317             (uint64_t)cdb[10] << 8 |
18318             (uint64_t)cdb[11];
18319         return (lba);
18320 }
18321 
18322 static const cmd_attribute cmd_attributes[] = {
18323         { SCMD_READ,
18324             1, 0, 1, 0, 0, DIR_FORW, TRAN_READ, POS_EXPECTED,
18325             0, 0, 0, st_get_cdb_g0_rw_count },
18326         { SCMD_WRITE,
18327             1, 0, 1, 1, 0, DIR_FORW, TRAN_WRTE, POS_EXPECTED,
18328             0, 0, 0, st_get_cdb_g0_rw_count },
18329         { SCMD_TEST_UNIT_READY,
18330             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18331             0, 0, 0 },
18332         { SCMD_REWIND,
18333             1, 1, 1, 0, 0, DIR_REVC, TRAN_NONE, POS_EXPECTED,
18334             0, 0, 0, st_get_no_count },
18335         { SCMD_REQUEST_SENSE,
18336             0, 0, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18337             0, 0, 0 },
18338         { SCMD_READ_BLKLIM,
18339             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18340             0, 0, 0 },
18341         { SCMD_READ_G4,
18342             1, 0, 1, 0, 1, DIR_FORW, TRAN_READ, POS_EXPECTED,
18343             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18344         { SCMD_WRITE_G4,
18345             1, 0, 1, 1, 1, DIR_FORW, TRAN_WRTE, POS_EXPECTED,
18346             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18347         { SCMD_READ_REVERSE,
18348             1, 0, 1, 1, 0, DIR_REVC, TRAN_READ, POS_EXPECTED,
18349             0, 0, 0, st_get_cdb_g0_rw_count },
18350         { SCMD_READ_REVERSE_G4,
18351             1, 0, 1, 1, 1, DIR_REVC, TRAN_READ, POS_EXPECTED,
18352             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18353         { SCMD_WRITE_FILE_MARK,
18354             1, 0, 1, 1, 0, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18355             0, 0, 0, st_get_cdb_g0_count },
18356         { SCMD_WRITE_FILE_MARK_G4,
18357             1, 0, 1, 1, 1, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18358             0, 0, 0, st_get_cdb_g5_count, st_get_cdb_g4g5_cnt },
18359         { SCMD_SPACE,
18360             1, 0, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_STARTING,
18361             0, 0, 0, st_get_cdb_g0_sign_count },
18362         { SCMD_SPACE_G4,
18363             1, 0, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_STARTING,
18364             0, 0, 0, st_get_cdb_g4g5_cnt },
18365         { SCMD_INQUIRY,
18366             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18367             0, 0, 0 },
18368         { SCMD_VERIFY_G0,
18369             1, 0, 1, 0, 0, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18370             0, 0, 0, st_get_cdb_g0_rw_count },
18371         { SCMD_VERIFY_G4,
18372             1, 0, 1, 0, 1, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18373             0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18374         { SCMD_RECOVER_BUF,
18375             1, 0, 1, 1, 0, DIR_REVC, TRAN_READ, POS_EXPECTED,
18376             0, 0, 0 },
18377         { SCMD_MODE_SELECT,
18378             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18379             0, 0, 0 },
18380         { SCMD_RESERVE,
18381             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18382             0, 0, 0 },
18383         { SCMD_RELEASE,
18384             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18385             0, 0, 0 },
18386         { SCMD_ERASE,
18387             1, 0, 1, 1, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18388             0, 0, 0, st_get_erase_options },
18389         { SCMD_MODE_SENSE,
18390             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18391             0, 0, 0 },
18392         { SCMD_LOAD,
18393             1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18394             0, 0, 0, st_get_load_options },
18395         { SCMD_GDIAG,
18396             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18397             1, 0, 0 },
18398         { SCMD_SDIAG,
18399             1, 0, 1, 1, 0, DIR_EITH, TRAN_WRTE, POS_EXPECTED,
18400             1, 0, 0 },
18401         { SCMD_DOORLOCK,
18402             0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18403             0, 4, 3 },
18404         { SCMD_LOCATE,
18405             1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18406             0, 0, 0, NULL, st_get_cdb_g1_lba },
18407         { SCMD_READ_POSITION,
18408             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18409             0, 0, 0 },
18410         { SCMD_WRITE_BUFFER,
18411             1, 0, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18412             1, 0, 0 },
18413         { SCMD_READ_BUFFER,
18414             1, 0, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18415             1, 0, 0 },
18416         { SCMD_REPORT_DENSITIES,
18417             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18418             0, 0, 0 },
18419         { SCMD_LOG_SELECT_G1,
18420             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18421             0, 0, 0 },
18422         { SCMD_LOG_SENSE_G1,
18423             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18424             0, 0, 0 },
18425         { SCMD_PRIN,
18426             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18427             0, 0, 0 },
18428         { SCMD_PROUT,
18429             0, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18430             0, 0, 0 },
18431         { SCMD_READ_ATTRIBUTE,
18432             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18433             0, 0, 0 },
18434         { SCMD_WRITE_ATTRIBUTE,
18435             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18436             0, 0, 0 },
18437         { SCMD_LOCATE_G4,
18438             1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18439             0, 0, 0, NULL, st_get_cdb_g4g5_cnt },
18440         { SCMD_REPORT_LUNS,
18441             0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18442             0, 0, 0 },
18443         { SCMD_SVC_ACTION_IN_G5,
18444             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18445             0, 0, 0 },
18446         { SCMD_MAINTENANCE_IN,
18447             1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18448             0, 0, 0 },
18449         { SCMD_MAINTENANCE_OUT,
18450             1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18451             0, 0, 0 },
18452         { 0xff, /* Default attribute for unsupported commands */
18453             1, 0, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_STARTING,
18454             1, 0, 0, NULL, NULL }
18455 };
18456 
18457 static const cmd_attribute *
18458 st_lookup_cmd_attribute(unsigned char cmd)
18459 {
18460         int i;
18461         cmd_attribute const *attribute;
18462 
18463         for (i = 0; i < ST_NUM_MEMBERS(cmd_attributes); i++) {
18464                 attribute = &cmd_attributes[i];
18465                 if (attribute->cmd == cmd) {
18466                         return (attribute);
18467                 }
18468         }
18469         ASSERT(attribute);
18470         return (attribute);
18471 }
18472 
18473 static int
18474 st_reset(struct scsi_tape *un, int reset_type)
18475 {
18476         int rval;
18477 
18478         ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
18479 
18480         ST_FUNC(ST_DEVINFO, st_reset);
18481         un->un_rsvd_status |= ST_INITIATED_RESET;
18482         mutex_exit(ST_MUTEX);
18483         do {
18484                 rval = scsi_reset(&un->un_sd->sd_address, reset_type);
18485                 if (rval == 0) {
18486                         switch (reset_type) {
18487                         case RESET_LUN:
18488                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18489                                     "LUN reset failed trying target reset");
18490                                 reset_type = RESET_TARGET;
18491                                 break;
18492                         case RESET_TARGET:
18493                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18494                                     "target reset failed trying bus reset");
18495                                 reset_type = RESET_BUS;
18496                                 break;
18497                         case RESET_BUS:
18498                                 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18499                                     "bus reset failed trying all reset");
18500                                 reset_type = RESET_ALL;
18501                         default:
18502                                 mutex_enter(ST_MUTEX);
18503                                 return (rval);
18504                         }
18505                 }
18506         } while (rval == 0);
18507         mutex_enter(ST_MUTEX);
18508         return (rval);
18509 }
18510 
18511 #define SAS_TLR_MOD_LEN sizeof (struct seq_mode)
18512 static int
18513 st_set_target_TLR_mode(struct scsi_tape *un, ubufunc_t ubf)
18514 {
18515         int ret;
18516         int amount = SAS_TLR_MOD_LEN;
18517         struct seq_mode *mode_data;
18518 
18519         ST_FUNC(ST_DEVINFO, st_set_target_TLR_mode);
18520 
18521         mode_data = kmem_zalloc(SAS_TLR_MOD_LEN, KM_SLEEP);
18522         ret = st_gen_mode_sense(un, ubf, 0x18, mode_data, amount);
18523         if (ret != DDI_SUCCESS) {
18524                 if (ret != EACCES)
18525                         un->un_tlr_flag = TLR_NOT_SUPPORTED;
18526                 goto out;
18527         }
18528         if (mode_data->data_len != amount + 1) {
18529                 amount = mode_data->data_len + 1;
18530         }
18531         /* Must be SAS protocol */
18532         if (mode_data->page.saslun.protocol_id != 6) {
18533                 un->un_tlr_flag = TLR_NOT_SUPPORTED;
18534                 ret = ENOTSUP;
18535                 goto out;
18536         }
18537         if (un->un_tlr_flag == TLR_SAS_ONE_DEVICE) {
18538                 if (mode_data->page.saslun.tran_layer_ret == 1)
18539                         goto out;
18540                 mode_data->page.saslun.tran_layer_ret = 1;
18541         } else {
18542                 if (mode_data->page.saslun.tran_layer_ret == 0)
18543                         goto out;
18544                 mode_data->page.saslun.tran_layer_ret = 0;
18545         }
18546         ret = st_gen_mode_select(un, ubf, mode_data, amount);
18547         if (ret != DDI_SUCCESS) {
18548                 if (ret != EACCES)
18549                         un->un_tlr_flag = TLR_NOT_SUPPORTED;
18550         } else {
18551                 if (mode_data->page.saslun.tran_layer_ret == 0)
18552                         un->un_tlr_flag = TLR_NOT_KNOWN;
18553                 else
18554                         un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
18555         }
18556 #ifdef STDEBUG
18557         st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG, "TLR data sent",
18558             (char *)mode_data, amount);
18559 #endif
18560 out:
18561         kmem_free(mode_data, SAS_TLR_MOD_LEN);
18562         return (ret);
18563 }
18564 
18565 
18566 static void
18567 st_reset_notification(caddr_t arg)
18568 {
18569         struct scsi_tape *un = (struct scsi_tape *)arg;
18570 
18571         ST_FUNC(ST_DEVINFO, st_reset_notification);
18572         mutex_enter(ST_MUTEX);
18573 
18574         un->un_unit_attention_flags |= 2;
18575         if ((un->un_rsvd_status & (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
18576             ST_RESERVE) {
18577                 un->un_rsvd_status |= ST_LOST_RESERVE;
18578                 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
18579                     "Lost Reservation notification");
18580         } else {
18581                 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
18582                     "reset notification");
18583         }
18584 
18585         if ((un->un_restore_pos == 0) &&
18586             (un->un_state == ST_STATE_CLOSED) ||
18587             (un->un_state == ST_STATE_OPEN_PENDING_IO) ||
18588             (un->un_state == ST_STATE_CLOSING)) {
18589                 un->un_restore_pos = 1;
18590         }
18591         ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
18592             "reset and state was %d\n", un->un_state);
18593         mutex_exit(ST_MUTEX);
18594 }