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 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright Siemens 1999
  29  * All rights reserved.
  30  */
  31 
  32 
  33 /*
  34  * sgen - SCSI generic device driver
  35  *
  36  * The sgen driver provides user programs access to SCSI devices that
  37  * are not supported by other drivers by providing the USCSI(7I) interface.
  38  */
  39 
  40 #include <sys/modctl.h>
  41 #include <sys/file.h>
  42 #include <sys/scsi/scsi.h>
  43 #include <sys/scsi/targets/sgendef.h>
  44 
  45 /* The name of the driver, established from the module name in _init. */
  46 static  char *sgen_label        = NULL;
  47 
  48 #define DDI_NT_SGEN             "ddi_generic:scsi"
  49 
  50 static char *sgen_devtypes[] = {
  51         "direct",               /* 0x00 -- disks */
  52         "sequential",           /* 0x01 */
  53         "printer",              /* 0x02 */
  54         "processor",            /* 0x03 */
  55         "worm",                 /* 0x04 */
  56         "rodirect",             /* 0x05 */
  57         "scanner",              /* 0x06 */
  58         "optical",              /* 0x07 */
  59         "changer",              /* 0x08 */
  60         "comm",                 /* 0x09 */
  61         "prepress1",            /* 0x0a -- reserved for prepress (ASC IT8) */
  62         "prepress2",            /* 0x0b -- reserved for prepress (ASC IT8) */
  63         "array_ctrl",           /* 0x0c -- storage array */
  64         "ses",                  /* 0x0d -- enclosure services */
  65         "rbc",                  /* 0x0e -- simplified block */
  66         "ocrw",                 /* 0x0f -- optical card read/write */
  67         "bridge",               /* 0x10 -- reserved for bridging expanders */
  68         "type_0x11",            /* 0x11 */
  69         "type_0x12",            /* 0x12 */
  70         "type_0x13",            /* 0x13 */
  71         "type_0x14",            /* 0x14 */
  72         "type_0x15",            /* 0x15 */
  73         "type_0x16",            /* 0x16 */
  74         "type_0x17",            /* 0x17 */
  75         "type_0x18",            /* 0x18 */
  76         "type_0x19",            /* 0x19 */
  77         "type_0x1a",            /* 0x1a */
  78         "type_0x1b",            /* 0x1b */
  79         "type_0x1c",            /* 0x1c */
  80         "type_0x1d",            /* 0x1d */
  81         "type_0x1e",            /* 0x1e */
  82         "type_unknown"          /* 0x1f is "no device type" or "unknown" */
  83 };
  84 
  85 #define SGEN_NDEVTYPES ((sizeof (sgen_devtypes) / sizeof (char *)))
  86 
  87 #define SGEN_INQSTRLEN 24
  88 #define SGEN_VENDID_MAX 8
  89 #define SGEN_PRODID_MAX 16
  90 
  91 #define FILL_SCSI1_LUN(devp, pkt)                                       \
  92         if ((devp)->sd_inq->inq_ansi == 0x1) {                            \
  93                 int _lun;                                               \
  94                 _lun = ddi_prop_get_int(DDI_DEV_T_ANY, (devp)->sd_dev,       \
  95                     DDI_PROP_DONTPASS, SCSI_ADDR_PROP_LUN, 0);          \
  96                 if (_lun > 0) {                                              \
  97                         ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun =    \
  98                             _lun;                                       \
  99                 }                                                       \
 100         }
 101 
 102 #define SGEN_DO_ERRSTATS(sg_state, x)  \
 103         if (sg_state->sgen_kstats) { \
 104                 struct sgen_errstats *sp; \
 105                 sp = (struct sgen_errstats *)sg_state->sgen_kstats->ks_data; \
 106                 sp->x.value.ui32++; \
 107         }
 108 
 109 #define SCBP_C(pkt)     ((*(pkt)->pkt_scbp) & STATUS_MASK)
 110 
 111 /*
 112  * Standard entrypoints
 113  */
 114 static int sgen_attach(dev_info_t *, ddi_attach_cmd_t);
 115 static int sgen_detach(dev_info_t *, ddi_detach_cmd_t);
 116 static int sgen_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
 117 static int sgen_probe(dev_info_t *);
 118 static int sgen_open(dev_t *, int, int, cred_t *);
 119 static int sgen_close(dev_t, int, int, cred_t *);
 120 static int sgen_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
 121 
 122 /*
 123  * Configuration routines
 124  */
 125 static int sgen_do_attach(dev_info_t *);
 126 static int sgen_setup_sense(sgen_state_t *);
 127 static void sgen_create_errstats(sgen_state_t *, int);
 128 static int sgen_do_suspend(dev_info_t *);
 129 static int sgen_do_detach(dev_info_t *);
 130 static void sgen_setup_binddb(dev_info_t *);
 131 static void sgen_cleanup_binddb();
 132 
 133 /*
 134  * Packet transport routines
 135  */
 136 static int  sgen_uscsi_cmd(dev_t, struct uscsi_cmd *, int);
 137 static int sgen_start(struct buf *);
 138 static int sgen_hold_cmdbuf(sgen_state_t *);
 139 static void sgen_rele_cmdbuf(sgen_state_t *);
 140 static int sgen_make_uscsi_cmd(sgen_state_t *, struct buf *);
 141 static void sgen_restart(void *);
 142 static void sgen_callback(struct scsi_pkt *);
 143 static int sgen_handle_autosense(sgen_state_t *, struct scsi_pkt *);
 144 static int sgen_handle_sense(sgen_state_t *);
 145 static int sgen_handle_incomplete(sgen_state_t *, struct scsi_pkt *);
 146 static int sgen_check_error(sgen_state_t *, struct buf *);
 147 static int sgen_initiate_sense(sgen_state_t *, int);
 148 static int sgen_scsi_transport(struct scsi_pkt *);
 149 static int sgen_tur(dev_t);
 150 
 151 /*
 152  * Logging/debugging routines
 153  */
 154 static void sgen_log(sgen_state_t  *, int,  const char *, ...);
 155 static int sgen_diag_ok(sgen_state_t *, int);
 156 static void sgen_dump_cdb(sgen_state_t *, const char *, union scsi_cdb *, int);
 157 static void sgen_dump_sense(sgen_state_t *, size_t, uchar_t *);
 158 
 159 int sgen_diag = 0;
 160 int sgen_sporadic_failures = 0;
 161 int sgen_force_manual_sense = 0;
 162 struct sgen_binddb sgen_binddb;
 163 
 164 static struct cb_ops sgen_cb_ops = {
 165         sgen_open,                      /* open */
 166         sgen_close,                     /* close */
 167         nodev,                          /* strategy */
 168         nodev,                          /* print */
 169         nodev,                          /* dump */
 170         nodev,                          /* read */
 171         nodev,                          /* write */
 172         sgen_ioctl,                     /* ioctl */
 173         nodev,                          /* devmap */
 174         nodev,                          /* mmap */
 175         nodev,                          /* segmap */
 176         nochpoll,                       /* poll */
 177         ddi_prop_op,                    /* cb_prop_op */
 178         0,                              /* streamtab  */
 179         D_MP | D_NEW | D_HOTPLUG        /* Driver compatibility flag */
 180 };
 181 
 182 static struct dev_ops sgen_dev_ops = {
 183         DEVO_REV,               /* devo_rev, */
 184         0,                      /* refcnt  */
 185         sgen_getinfo,           /* info */
 186         nodev,                  /* identify */
 187         sgen_probe,             /* probe */
 188         sgen_attach,            /* attach */
 189         sgen_detach,            /* detach */
 190         nodev,                  /* reset */
 191         &sgen_cb_ops,               /* driver operations */
 192         (struct bus_ops *)0,    /* bus operations */
 193         NULL,                   /* power */
 194         ddi_quiesce_not_supported,      /* devo_quiesce */
 195 };
 196 
 197 static void *sgen_soft_state = NULL;
 198 
 199 static struct modldrv modldrv = {
 200         &mod_driverops, "SCSI generic driver", &sgen_dev_ops
 201 };
 202 
 203 static struct modlinkage modlinkage = {
 204         MODREV_1, &modldrv, NULL
 205 };
 206 
 207 int
 208 _init(void)
 209 {
 210         int err;
 211 
 212         /* establish driver name from module name */
 213         sgen_label = (char *)mod_modname(&modlinkage);
 214 
 215         sgen_log(NULL, SGEN_DIAG2, "in sgen_init()");
 216         if ((err = ddi_soft_state_init(&sgen_soft_state,
 217             sizeof (sgen_state_t), SGEN_ESTIMATED_NUM_DEVS)) != 0) {
 218                 goto done;
 219         }
 220 
 221         if ((err = mod_install(&modlinkage)) != 0) {
 222                 ddi_soft_state_fini(&sgen_soft_state);
 223                 goto done;
 224         }
 225 
 226 done:
 227         sgen_log(NULL, SGEN_DIAG2, "%s sgen_init()", err ? "failed" : "done");
 228         return (err);
 229 }
 230 
 231 int
 232 _fini(void)
 233 {
 234         int err;
 235         sgen_log(NULL, SGEN_DIAG2, "in sgen_fini()");
 236 
 237         if ((err = mod_remove(&modlinkage)) != 0) {
 238                 goto done;
 239         }
 240 
 241         ddi_soft_state_fini(&sgen_soft_state);
 242         sgen_cleanup_binddb();
 243 
 244 done:
 245         sgen_log(NULL, SGEN_DIAG2, "%s sgen_fini()", err ? "failed" : "done");
 246         return (err);
 247 }
 248 
 249 int
 250 _info(struct modinfo *modinfop)
 251 {
 252         return (mod_info(&modlinkage, modinfop));
 253 }
 254 
 255 /*
 256  * sgen_typename()
 257  *      return a device type's name by looking it up in the sgen_devtypes table.
 258  */
 259 static char *
 260 sgen_typename(uchar_t typeno)
 261 {
 262         if (typeno >= SGEN_NDEVTYPES)
 263                 return ("type_unknown");
 264         return (sgen_devtypes[typeno]);
 265 }
 266 
 267 /*
 268  * sgen_typenum()
 269  *      return a device type's number by looking it up in the sgen_devtypes
 270  *      table.
 271  */
 272 static int
 273 sgen_typenum(const char *typename, uchar_t *typenum)
 274 {
 275         int i;
 276         for (i = 0; i < SGEN_NDEVTYPES; i++) {
 277                 if (strcasecmp(sgen_devtypes[i], typename) == 0) {
 278                         *typenum = (uchar_t)i;
 279                         return (0);
 280                 }
 281         }
 282         return (-1);
 283 }
 284 
 285 /*
 286  * sgen_setup_binddb()
 287  *      initialize a data structure which stores all of the information about
 288  *      which devices and device types the driver should bind to.
 289  */
 290 static void
 291 sgen_setup_binddb(dev_info_t *dip)
 292 {
 293         char **strs = NULL, *cp, *pcp, *vcp;
 294         uint_t nelems, pcplen, vcplen, idx;
 295 
 296         ASSERT(sgen_binddb.sdb_init == 0);
 297         ASSERT(MUTEX_HELD(&sgen_binddb.sdb_lock));
 298 
 299         if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 300             "device-type-config-list", &strs, &nelems) == DDI_PROP_SUCCESS) {
 301                 /*
 302                  * for each device type specifier make a copy and put it into a
 303                  * node in the binddb.
 304                  */
 305                 for (idx = 0; idx < nelems; idx++) {
 306                         sgen_type_node_t *nodep;
 307                         uchar_t devtype;
 308                         cp = strs[idx];
 309                         if (sgen_typenum(cp, &devtype) != 0) {
 310                                 sgen_log(NULL, CE_WARN,
 311                                     "unknown device type '%s', "
 312                                     "device unit-address @%s",
 313                                     cp, ddi_get_name_addr(dip));
 314                                 continue;
 315                         }
 316                         nodep = kmem_zalloc(sizeof (sgen_type_node_t),
 317                             KM_SLEEP);
 318                         nodep->node_type = devtype;
 319                         nodep->node_next = sgen_binddb.sdb_type_nodes;
 320                         sgen_binddb.sdb_type_nodes = nodep;
 321 
 322                         sgen_log(NULL, SGEN_DIAG2, "found device type "
 323                             "'%s' in device-type-config-list, "
 324                             "device unit-address @%s",
 325                             cp, ddi_get_name_addr(dip));
 326                 }
 327                 ddi_prop_free(strs);
 328         }
 329 
 330         /*
 331          * for each Vendor/Product inquiry pair, build a node and put it
 332          * into the the binddb.
 333          */
 334         if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 335             "inquiry-config-list", &strs, &nelems) == DDI_PROP_SUCCESS) {
 336 
 337                 if (nelems % 2 == 1) {
 338                         sgen_log(NULL, CE_WARN, "inquiry-config-list must "
 339                             "contain Vendor/Product pairs, "
 340                             "device unit-address @%s",
 341                             ddi_get_name_addr(dip));
 342                         nelems--;
 343                 }
 344                 for (idx = 0; idx < nelems; idx += 2) {
 345                         sgen_inq_node_t *nodep;
 346                         /*
 347                          * Grab vendor and product ID.
 348                          */
 349                         vcp = strs[idx];
 350                         vcplen = strlen(vcp);
 351                         if (vcplen == 0 || vcplen > SGEN_VENDID_MAX) {
 352                                 sgen_log(NULL, CE_WARN,
 353                                     "Invalid vendor ID '%s', "
 354                                     "device unit-address @%s",
 355                                     vcp, ddi_get_name_addr(dip));
 356                                 continue;
 357                         }
 358 
 359                         pcp = strs[idx + 1];
 360                         pcplen = strlen(pcp);
 361                         if (pcplen == 0 || pcplen > SGEN_PRODID_MAX) {
 362                                 sgen_log(NULL, CE_WARN,
 363                                     "Invalid product ID '%s', "
 364                                     "device unit-address @%s",
 365                                     pcp, ddi_get_name_addr(dip));
 366                                 continue;
 367                         }
 368 
 369                         nodep = kmem_zalloc(sizeof (sgen_inq_node_t),
 370                             KM_SLEEP);
 371                         nodep->node_vendor = kmem_alloc(vcplen + 1, KM_SLEEP);
 372                         (void) strcpy(nodep->node_vendor, vcp);
 373                         nodep->node_product = kmem_alloc(pcplen + 1, KM_SLEEP);
 374                         (void) strcpy(nodep->node_product, pcp);
 375 
 376                         nodep->node_next = sgen_binddb.sdb_inq_nodes;
 377                         sgen_binddb.sdb_inq_nodes = nodep;
 378 
 379                         sgen_log(NULL, SGEN_DIAG2, "found inquiry string "
 380                             "'%s' '%s' in device-type-config-list, "
 381                             "device unit-address @%s",
 382                             nodep->node_vendor, nodep->node_product,
 383                             ddi_get_name_addr(dip));
 384                 }
 385                 ddi_prop_free(strs);
 386         }
 387 
 388         sgen_binddb.sdb_init = 1;
 389 }
 390 
 391 /*
 392  * sgen_cleanup_binddb()
 393  *      deallocate data structures for binding database.
 394  */
 395 static void
 396 sgen_cleanup_binddb()
 397 {
 398         sgen_inq_node_t *inqp, *inqnextp;
 399         sgen_type_node_t *typep, *typenextp;
 400 
 401         mutex_enter(&sgen_binddb.sdb_lock);
 402         if (sgen_binddb.sdb_init == 0) {
 403                 mutex_exit(&sgen_binddb.sdb_lock);
 404                 return;
 405         }
 406 
 407         for (inqp = sgen_binddb.sdb_inq_nodes; inqp != NULL; inqp = inqnextp) {
 408                 inqnextp = inqp->node_next;
 409                 ASSERT(inqp->node_vendor && inqp->node_product);
 410                 kmem_free(inqp->node_vendor,
 411                     strlen(inqp->node_vendor) + 1);
 412                 kmem_free(inqp->node_product,
 413                     strlen(inqp->node_product) + 1);
 414                 kmem_free(inqp, sizeof (sgen_inq_node_t));
 415         }
 416 
 417         for (typep = sgen_binddb.sdb_type_nodes; typep != NULL;
 418             typep = typenextp) {
 419                 typenextp = typep->node_next;
 420                 kmem_free(typep, sizeof (sgen_type_node_t));
 421         }
 422         mutex_exit(&sgen_binddb.sdb_lock);
 423 }
 424 
 425 /*
 426  * sgen_bind_byinq()
 427  *      lookup a device in the binding database by its inquiry data.
 428  */
 429 static int
 430 sgen_bind_byinq(dev_info_t *dip)
 431 {
 432         sgen_inq_node_t *nodep;
 433         char vend_str[SGEN_VENDID_MAX+1];
 434         char prod_str[SGEN_PRODID_MAX+1];
 435         struct scsi_device *scsidevp;
 436 
 437         scsidevp = ddi_get_driver_private(dip);
 438 
 439         /*
 440          * inq_vid and inq_pid are laid out by the protocol in order in the
 441          * inquiry structure, and are not delimited by \0.
 442          */
 443         bcopy(scsidevp->sd_inq->inq_vid, vend_str, SGEN_VENDID_MAX);
 444         vend_str[SGEN_VENDID_MAX] = '\0';
 445         bcopy(scsidevp->sd_inq->inq_pid, prod_str, SGEN_PRODID_MAX);
 446         prod_str[SGEN_PRODID_MAX] = '\0';
 447 
 448         for (nodep = sgen_binddb.sdb_inq_nodes; nodep != NULL;
 449             nodep = nodep->node_next) {
 450                 /*
 451                  * Allow the "*" wildcard to match all vendor IDs.
 452                  */
 453                 if (strcmp(nodep->node_vendor, "*") != 0) {
 454                         if (strncasecmp(nodep->node_vendor, vend_str,
 455                             strlen(nodep->node_vendor)) != 0) {
 456                                 continue;
 457                         }
 458                 }
 459 
 460                 /*
 461                  * Using strncasecmp() with the key length allows substring
 462                  * matching for product data.
 463                  */
 464                 if (strncasecmp(nodep->node_product, prod_str,
 465                     strlen(nodep->node_product)) == 0) {
 466                         return (0);
 467                 }
 468         }
 469         return (-1);
 470 }
 471 
 472 /*
 473  * sgen_bind_bytype()
 474  *      lookup a device type in the binding database; if found, return a
 475  *      format string corresponding to the string in the .conf file.
 476  */
 477 static int
 478 sgen_bind_bytype(dev_info_t *dip)
 479 {
 480         sgen_type_node_t *nodep;
 481         struct scsi_device *scsidevp;
 482 
 483         scsidevp = ddi_get_driver_private(dip);
 484 
 485         for (nodep = sgen_binddb.sdb_type_nodes; nodep != NULL;
 486             nodep = nodep->node_next) {
 487                 if (nodep->node_type == scsidevp->sd_inq->inq_dtype) {
 488                         return (0);
 489                 }
 490         }
 491         return (-1);
 492 }
 493 
 494 /*
 495  * sgen_get_binding()
 496  *      Check to see if the device in question matches the criteria for
 497  *      sgen to bind.
 498  *
 499  *      Either the .conf file must specify a device_type entry which
 500  *      matches the SCSI device type of this device, or the inquiry
 501  *      string provided by the device must match an inquiry string specified
 502  *      in the .conf file.  Inquiry data is matched first.
 503  */
 504 static int
 505 sgen_get_binding(dev_info_t *dip)
 506 {
 507         int retval = 0;
 508 
 509         mutex_enter(&sgen_binddb.sdb_lock);
 510         if (sgen_binddb.sdb_init == 0)
 511                 sgen_setup_binddb(dip);
 512         mutex_exit(&sgen_binddb.sdb_lock);
 513 
 514 
 515         /*
 516          * Check device-type-config-list for a match by device type.
 517          */
 518         if (sgen_bind_bytype(dip) == 0)
 519                 goto done;
 520 
 521         /*
 522          * Check inquiry-config-list for a match by Vendor/Product ID.
 523          */
 524         if (sgen_bind_byinq(dip) == 0)
 525                 goto done;
 526 
 527         retval = -1;
 528 done:
 529         return (retval);
 530 }
 531 
 532 /*
 533  * sgen_attach()
 534  *      attach(9e) entrypoint.
 535  */
 536 static int
 537 sgen_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 538 {
 539         int err;
 540 
 541         sgen_log(NULL, SGEN_DIAG2, "in sgen_attach(), device unit-address @%s",
 542             ddi_get_name_addr(dip));
 543 
 544         switch (cmd) {
 545         case DDI_ATTACH:
 546                 err = sgen_do_attach(dip);
 547                 break;
 548         case DDI_RESUME:
 549                 err = DDI_SUCCESS;
 550                 break;
 551         case DDI_PM_RESUME:
 552         default:
 553                 err = DDI_FAILURE;
 554                 break;
 555         }
 556 
 557 done:
 558         sgen_log(NULL, SGEN_DIAG2, "%s sgen_attach(), device unit-address @%s",
 559             err == DDI_SUCCESS ? "done" : "failed", ddi_get_name_addr(dip));
 560         return (err);
 561 }
 562 
 563 /*
 564  * sgen_do_attach()
 565  *      handle the nitty details of attach.
 566  */
 567 static int
 568 sgen_do_attach(dev_info_t *dip)
 569 {
 570         int instance;
 571         struct scsi_device *scsidevp;
 572         sgen_state_t *sg_state;
 573         uchar_t devtype;
 574         struct scsi_inquiry *inq;
 575 
 576         instance = ddi_get_instance(dip);
 577 
 578         scsidevp = ddi_get_driver_private(dip);
 579         ASSERT(scsidevp);
 580 
 581         sgen_log(NULL, SGEN_DIAG2, "sgen_do_attach: instance = %d, "
 582             "device unit-address @%s", instance, ddi_get_name_addr(dip));
 583 
 584         /*
 585          * Probe the device in order to get its device type to name the minor
 586          * node.
 587          */
 588         if (scsi_probe(scsidevp, NULL_FUNC) != SCSIPROBE_EXISTS) {
 589                 scsi_unprobe(scsidevp);
 590                 return (DDI_FAILURE);
 591         }
 592 
 593         if (ddi_soft_state_zalloc(sgen_soft_state, instance) != DDI_SUCCESS) {
 594                 sgen_log(NULL, SGEN_DIAG1,
 595                     "sgen_do_attach: failed to allocate softstate, "
 596                     "device unit-address @%s", ddi_get_name_addr(dip));
 597                 scsi_unprobe(scsidevp);
 598                 return (DDI_FAILURE);
 599         }
 600 
 601         inq = scsidevp->sd_inq;              /* valid while device is probed... */
 602         devtype = inq->inq_dtype;
 603 
 604         sg_state = ddi_get_soft_state(sgen_soft_state, instance);
 605         sg_state->sgen_scsidev = scsidevp;
 606         scsidevp->sd_dev = dip;
 607 
 608         /*
 609          * Now that sg_state->sgen_scsidev is initialized, it's ok to
 610          * call sgen_log with sg_state instead of NULL.
 611          */
 612 
 613         /*
 614          * If the user specified the sgen_diag property, override the global
 615          * sgen_diag setting by setting sg_state's sgen_diag value.  If the
 616          * user gave a value out of range, default to '0'.
 617          */
 618         sg_state->sgen_diag = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 619             "sgen-diag", -1);
 620 
 621         if (sg_state->sgen_diag != -1) {
 622                 if (sg_state->sgen_diag < 0 || sg_state->sgen_diag > 3)
 623                         sg_state->sgen_diag = 0;
 624         }
 625 
 626         sgen_log(sg_state, SGEN_DIAG2,
 627             "sgen_do_attach: sgen_soft_state=0x%p, instance=%d, "
 628             "device unit-address @%s",
 629             sgen_soft_state, instance, ddi_get_name_addr(dip));
 630 
 631         /*
 632          * For simplicity, the minor number == the instance number
 633          */
 634         if (ddi_create_minor_node(dip, sgen_typename(devtype), S_IFCHR,
 635             instance, DDI_NT_SGEN, NULL) == DDI_FAILURE) {
 636                 scsi_unprobe(scsidevp);
 637                 ddi_prop_remove_all(dip);
 638                 sgen_log(sg_state, SGEN_DIAG1,
 639                     "sgen_do_attach: minor node creation failed, "
 640                     "device unit-address @%s", ddi_get_name_addr(dip));
 641                 ddi_soft_state_free(sgen_soft_state, instance);
 642                 return (DDI_FAILURE);
 643         }
 644 
 645         /*
 646          * Allocate the command buffer, then create a condition variable for
 647          * managing it; mark the command buffer as free.
 648          */
 649         sg_state->sgen_cmdbuf = getrbuf(KM_SLEEP);
 650         cv_init(&sg_state->sgen_cmdbuf_cv, NULL, CV_DRIVER, NULL);
 651 
 652         SGEN_CLR_BUSY(sg_state);
 653         SGEN_CLR_OPEN(sg_state);
 654         SGEN_CLR_SUSP(sg_state);
 655 
 656         /*
 657          * If the hba and the target both support wide xfers, enable them.
 658          */
 659         if (scsi_ifgetcap(&sg_state->sgen_scsiaddr, "wide-xfer", 1) != -1) {
 660                 int wide = 0;
 661                 if ((inq->inq_rdf == RDF_SCSI2) &&
 662                     (inq->inq_wbus16 || inq->inq_wbus32))
 663                         wide = 1;
 664                 if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, "wide-xfer",
 665                     wide, 1) == 1) {
 666                         sgen_log(sg_state, SGEN_DIAG1,
 667                             "sgen_attach: wide xfer %s, "
 668                             "device unit-address @%s",
 669                             wide ? "enabled" : "disabled",
 670                             ddi_get_name_addr(dip));
 671                 }
 672         }
 673 
 674         /*
 675          * This is a little debugging code-- since the codepath for auto-sense
 676          * and 'manual' sense is split, toggling this variable will make
 677          * sgen act as though the adapter in question can't do auto-sense.
 678          */
 679         if (sgen_force_manual_sense) {
 680                 if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, "auto-rqsense",
 681                     0, 1) == 1) {
 682                         sg_state->sgen_arq_enabled = 0;
 683                 } else {
 684                         sg_state->sgen_arq_enabled = 1;
 685                 }
 686         } else {
 687                 /*
 688                  * Enable autorequest sense, if supported
 689                  */
 690                 if (scsi_ifgetcap(&sg_state->sgen_scsiaddr,
 691                     "auto-rqsense", 1) != 1) {
 692                         if (scsi_ifsetcap(&sg_state->sgen_scsiaddr,
 693                             "auto-rqsense", 1, 1) == 1) {
 694                                 sg_state->sgen_arq_enabled = 1;
 695                                 sgen_log(sg_state, SGEN_DIAG1,
 696                                     "sgen_attach: auto-request-sense enabled, "
 697                                     "device unit-address @%s",
 698                                     ddi_get_name_addr(dip));
 699                         } else {
 700                                 sg_state->sgen_arq_enabled = 0;
 701                                 sgen_log(sg_state, SGEN_DIAG1,
 702                                     "sgen_attach: auto-request-sense disabled, "
 703                                     "device unit-address @%s",
 704                                     ddi_get_name_addr(dip));
 705                         }
 706                 } else {
 707                         sg_state->sgen_arq_enabled = 1;      /* already enabled */
 708                         sgen_log(sg_state, SGEN_DIAG1,
 709                             "sgen_attach: auto-request-sense enabled, "
 710                             "device unit-address @%s", ddi_get_name_addr(dip));
 711                 }
 712         }
 713 
 714         /*
 715          * Allocate plumbing for manually fetching sense.
 716          */
 717         if (sgen_setup_sense(sg_state) != 0) {
 718                 freerbuf(sg_state->sgen_cmdbuf);
 719                 ddi_prop_remove_all(dip);
 720                 ddi_remove_minor_node(dip, NULL);
 721                 scsi_unprobe(scsidevp);
 722                 sgen_log(sg_state, SGEN_DIAG1,
 723                     "sgen_do_attach: failed to setup request-sense, "
 724                     "device unit-address @%s", ddi_get_name_addr(dip));
 725                 ddi_soft_state_free(sgen_soft_state, instance);
 726                 return (DDI_FAILURE);
 727         }
 728 
 729         sgen_create_errstats(sg_state, instance);
 730 
 731         ddi_report_dev(dip);
 732 
 733         return (DDI_SUCCESS);
 734 }
 735 
 736 /*
 737  * sgen_setup_sense()
 738  *      Allocate a request sense packet so that if sgen needs to fetch sense
 739  *      data for the user, it will have a pkt ready to send.
 740  */
 741 static int
 742 sgen_setup_sense(sgen_state_t *sg_state)
 743 {
 744         struct buf *bp;
 745         struct scsi_pkt *rqpkt;
 746 
 747         if ((bp = scsi_alloc_consistent_buf(&sg_state->sgen_scsiaddr, NULL,
 748             MAX_SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
 749                 return (-1);
 750         }
 751 
 752         if ((rqpkt = scsi_init_pkt(&sg_state->sgen_scsiaddr, NULL, bp,
 753             CDB_GROUP0, 1, 0, PKT_CONSISTENT, SLEEP_FUNC, NULL)) == NULL) {
 754                 scsi_free_consistent_buf(bp);
 755                 return (-1);
 756         }
 757 
 758         /*
 759          * Make the results of running a SENSE available by filling out the
 760          * sd_sense field of the scsi device (sgen_sense is just an alias).
 761          */
 762         sg_state->sgen_sense = (struct scsi_extended_sense *)bp->b_un.b_addr;
 763 
 764         (void) scsi_setup_cdb((union scsi_cdb *)rqpkt->pkt_cdbp,
 765             SCMD_REQUEST_SENSE, 0, MAX_SENSE_LENGTH, 0);
 766         FILL_SCSI1_LUN(sg_state->sgen_scsidev, rqpkt);
 767 
 768         rqpkt->pkt_comp = sgen_callback;
 769         rqpkt->pkt_time = SGEN_IO_TIME;
 770         rqpkt->pkt_flags |= FLAG_SENSING;
 771         rqpkt->pkt_private = sg_state;
 772 
 773         sg_state->sgen_rqspkt = rqpkt;
 774         sg_state->sgen_rqsbuf = bp;
 775 
 776         return (0);
 777 }
 778 
 779 /*
 780  * sgen_create_errstats()
 781  *      create named kstats for tracking occurrence of errors.
 782  */
 783 static void
 784 sgen_create_errstats(sgen_state_t *sg_state, int instance)
 785 {
 786         char kstatname[KSTAT_STRLEN];
 787         struct sgen_errstats *stp;
 788 
 789         (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,err",
 790             sgen_label, instance);
 791         sg_state->sgen_kstats = kstat_create("sgenerr", instance,
 792             kstatname, "device_error", KSTAT_TYPE_NAMED,
 793             sizeof (struct sgen_errstats) / sizeof (kstat_named_t),
 794             KSTAT_FLAG_PERSISTENT);
 795 
 796         if (sg_state->sgen_kstats == NULL)
 797                 return;
 798 
 799         stp = (struct sgen_errstats *)sg_state->sgen_kstats->ks_data;
 800         kstat_named_init(&stp->sgen_trans_err, "transport_errors",
 801             KSTAT_DATA_UINT32);
 802         kstat_named_init(&stp->sgen_restart, "command_restarts",
 803             KSTAT_DATA_UINT32);
 804         kstat_named_init(&stp->sgen_incmp_err, "incomplete_commands",
 805             KSTAT_DATA_UINT32);
 806         kstat_named_init(&stp->sgen_autosen_rcv, "autosense_occurred",
 807             KSTAT_DATA_UINT32);
 808         kstat_named_init(&stp->sgen_autosen_bad, "autosense_undecipherable",
 809             KSTAT_DATA_UINT32);
 810         kstat_named_init(&stp->sgen_sense_rcv, "sense_fetches",
 811             KSTAT_DATA_UINT32);
 812         kstat_named_init(&stp->sgen_sense_bad, "sense_data_undecipherable",
 813             KSTAT_DATA_UINT32);
 814         kstat_named_init(&stp->sgen_recov_err, "recoverable_error",
 815             KSTAT_DATA_UINT32);
 816         kstat_named_init(&stp->sgen_nosen_err, "NO_SENSE_sense_key",
 817             KSTAT_DATA_UINT32);
 818         kstat_named_init(&stp->sgen_unrecov_err, "unrecoverable_sense_error",
 819             KSTAT_DATA_UINT32);
 820         sg_state->sgen_kstats->ks_private = sg_state;
 821         sg_state->sgen_kstats->ks_update = nulldev;
 822         kstat_install(sg_state->sgen_kstats);
 823 }
 824 
 825 /*
 826  * sgen_detach()
 827  *      detach(9E) entrypoint
 828  */
 829 static int
 830 sgen_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 831 {
 832         int instance;
 833         sgen_state_t *sg_state;
 834 
 835         instance = ddi_get_instance(dip);
 836         sg_state = ddi_get_soft_state(sgen_soft_state, instance);
 837 
 838         sgen_log(sg_state, SGEN_DIAG2, "in sgen_detach(), "
 839             "device unit-address @%s", ddi_get_name_addr(dip));
 840 
 841         if (sg_state == NULL) {
 842                 sgen_log(NULL, SGEN_DIAG1,
 843                     "sgen_detach: failed, no softstate found (%d), "
 844                     "device unit-address @%s",
 845                     instance, ddi_get_name_addr(dip));
 846                 return (DDI_FAILURE);
 847         }
 848 
 849         switch (cmd) {
 850         case DDI_DETACH:
 851                 return (sgen_do_detach(dip));
 852         case DDI_SUSPEND:
 853                 return (sgen_do_suspend(dip));
 854         case DDI_PM_SUSPEND:
 855         default:
 856                 return (DDI_FAILURE);
 857         }
 858 }
 859 
 860 /*
 861  * sgen_do_detach()
 862  *      detach the driver, tearing down resources.
 863  */
 864 static int
 865 sgen_do_detach(dev_info_t *dip)
 866 {
 867         int instance;
 868         sgen_state_t *sg_state;
 869         struct scsi_device *devp;
 870 
 871         instance = ddi_get_instance(dip);
 872         sg_state = ddi_get_soft_state(sgen_soft_state, instance);
 873         ASSERT(sg_state);
 874 
 875         sgen_log(sg_state, SGEN_DIAG2, "in sgen_do_detach(), "
 876             "device unit-address @%s", ddi_get_name_addr(dip));
 877         devp = ddi_get_driver_private(dip);
 878 
 879         mutex_enter(&sg_state->sgen_mutex);
 880         if (SGEN_IS_BUSY(sg_state)) {
 881                 mutex_exit(&sg_state->sgen_mutex);
 882                 sgen_log(sg_state, SGEN_DIAG1, "sgen_do_detach: failed because "
 883                     "device is busy, device unit-address @%s",
 884                     ddi_get_name_addr(dip));
 885                 return (DDI_FAILURE);
 886         }
 887         mutex_exit(&sg_state->sgen_mutex);
 888 
 889         /*
 890          * Final approach for detach.  Free data allocated by scsi_probe()
 891          * in attach.
 892          */
 893         if (sg_state->sgen_restart_timeid)
 894                 (void) untimeout(sg_state->sgen_restart_timeid);
 895         sg_state->sgen_restart_timeid = 0;
 896         scsi_unprobe(devp);
 897 
 898         /*
 899          * Free auto-request plumbing.
 900          */
 901         scsi_free_consistent_buf(sg_state->sgen_rqsbuf);
 902         scsi_destroy_pkt(sg_state->sgen_rqspkt);
 903 
 904         if (sg_state->sgen_kstats) {
 905                 kstat_delete(sg_state->sgen_kstats);
 906                 sg_state->sgen_kstats = NULL;
 907         }
 908 
 909         /*
 910          * Free command buffer and clean up
 911          */
 912         freerbuf(sg_state->sgen_cmdbuf);
 913         cv_destroy(&sg_state->sgen_cmdbuf_cv);
 914 
 915         sgen_log(sg_state, SGEN_DIAG2, "done sgen_do_detach(), "
 916             "device unit-address @%s", ddi_get_name_addr(dip));
 917 
 918         ddi_soft_state_free(sgen_soft_state, instance);
 919         ddi_prop_remove_all(dip);
 920         ddi_remove_minor_node(dip, NULL);
 921         return (DDI_SUCCESS);
 922 }
 923 
 924 /*
 925  * sgen_do_suspend()
 926  *      suspend the driver.  This sets the "suspend" bit for this target if it
 927  *      is currently open; once resumed, the suspend bit will cause
 928  *      subsequent I/Os to fail.  We want user programs to close and
 929  *      reopen the device to acknowledge that they need to reexamine its
 930  *      state and do the right thing.
 931  */
 932 static int
 933 sgen_do_suspend(dev_info_t *dip)
 934 {
 935         int instance;
 936         sgen_state_t *sg_state;
 937 
 938         instance = ddi_get_instance(dip);
 939         sg_state = ddi_get_soft_state(sgen_soft_state, instance);
 940         ASSERT(sg_state);
 941 
 942         sgen_log(sg_state, SGEN_DIAG2, "in sgen_do_suspend(), "
 943             "device unit-address @%s", ddi_get_name_addr(dip));
 944 
 945         if (sg_state->sgen_restart_timeid) {
 946                 (void) untimeout(sg_state->sgen_restart_timeid);
 947         }
 948         sg_state->sgen_restart_timeid = 0;
 949 
 950         mutex_enter(&sg_state->sgen_mutex);
 951         if (SGEN_IS_OPEN(sg_state))
 952                 SGEN_SET_SUSP(sg_state);
 953         mutex_exit(&sg_state->sgen_mutex);
 954 
 955         sgen_log(sg_state, SGEN_DIAG2, "done sgen_do_suspend(), "
 956             "device unit-address @%s", ddi_get_name_addr(dip));
 957         return (DDI_SUCCESS);
 958 }
 959 
 960 /*
 961  * sgen_getinfo()
 962  *      getinfo(9e) entrypoint.
 963  */
 964 /*ARGSUSED*/
 965 static int
 966 sgen_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
 967 {
 968         dev_t dev;
 969         sgen_state_t *sg_state;
 970         int instance, error;
 971         switch (infocmd) {
 972         case DDI_INFO_DEVT2DEVINFO:
 973                 dev = (dev_t)arg;
 974                 instance = getminor(dev);
 975                 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance))
 976                     == NULL)
 977                         return (DDI_FAILURE);
 978                 *result = (void *) sg_state->sgen_scsidev->sd_dev;
 979                 error = DDI_SUCCESS;
 980                 break;
 981         case DDI_INFO_DEVT2INSTANCE:
 982                 dev = (dev_t)arg;
 983                 instance = getminor(dev);
 984                 *result = (void *)(uintptr_t)instance;
 985                 error = DDI_SUCCESS;
 986                 break;
 987         default:
 988                 error = DDI_FAILURE;
 989         }
 990         return (error);
 991 }
 992 
 993 /*
 994  * sgen_probe()
 995  *      probe(9e) entrypoint.  sgen *never* returns DDI_PROBE_PARTIAL, in
 996  *      order to avoid leaving around extra devinfos.  If sgen's binding
 997  *      rules indicate that it should bind, it returns DDI_PROBE_SUCCESS.
 998  */
 999 static int
1000 sgen_probe(dev_info_t *dip)
1001 {
1002         struct scsi_device *scsidevp;
1003         int instance;
1004         int rval;
1005 
1006         scsidevp = ddi_get_driver_private(dip);
1007         instance = ddi_get_instance(dip);
1008         sgen_log(NULL, SGEN_DIAG2, "in sgen_probe(): instance = %d, "
1009             "device unit-address @%s", instance, ddi_get_name_addr(dip));
1010 
1011         if (ddi_dev_is_sid(dip) == DDI_SUCCESS)
1012                 return (DDI_PROBE_DONTCARE);
1013 
1014         if (ddi_get_soft_state(sgen_soft_state, instance) != NULL)
1015                 return (DDI_PROBE_FAILURE);
1016 
1017         mutex_enter(&sgen_binddb.sdb_lock);
1018         if (sgen_binddb.sdb_init == 0) {
1019                 sgen_setup_binddb(dip);
1020         }
1021         mutex_exit(&sgen_binddb.sdb_lock);
1022 
1023         /*
1024          * A small optimization: if it's impossible for sgen to bind to
1025          * any devices, don't bother probing, just fail.
1026          */
1027         if ((sgen_binddb.sdb_inq_nodes == NULL) &&
1028             (sgen_binddb.sdb_type_nodes == NULL)) {
1029                 return (DDI_PROBE_FAILURE);
1030         }
1031 
1032         if (scsi_probe(scsidevp, NULL_FUNC) == SCSIPROBE_EXISTS) {
1033                 if (sgen_get_binding(dip) == 0) {
1034                         rval = DDI_PROBE_SUCCESS;
1035                 }
1036         } else {
1037                 rval = DDI_PROBE_FAILURE;
1038         }
1039         scsi_unprobe(scsidevp);
1040 
1041         sgen_log(NULL, SGEN_DIAG2, "sgen_probe() %s, device unit-address @%s",
1042             rval == DDI_PROBE_SUCCESS ? "succeeded" : "failed",
1043             ddi_get_name_addr(dip));
1044         return (rval);
1045 }
1046 
1047 /*
1048  * sgen_open()
1049  *      open(9e) entrypoint.  sgen enforces a strict exclusive open policy per
1050  *      target.
1051  */
1052 /*ARGSUSED1*/
1053 static int
1054 sgen_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
1055 {
1056         dev_t dev = *dev_p;
1057         sgen_state_t *sg_state;
1058         int instance;
1059 
1060         instance = getminor(dev);
1061 
1062         if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL)
1063                 return (ENXIO);
1064 
1065         sgen_log(sg_state, SGEN_DIAG2, "in sgen_open(): instance = %d",
1066             instance);
1067 
1068         mutex_enter(&sg_state->sgen_mutex);
1069 
1070         /*
1071          * Don't allow new opens of a suspended device until the last close has
1072          * happened.  This is rather simplistic, but keeps the implementation
1073          * straightforward.
1074          */
1075         if (SGEN_IS_SUSP(sg_state)) {
1076                 mutex_exit(&sg_state->sgen_mutex);
1077                 return (EIO);
1078         }
1079 
1080         /*
1081          * Enforce exclusive access.
1082          */
1083         if (SGEN_IS_EXCL(sg_state) ||
1084             (SGEN_IS_OPEN(sg_state) && (flag & FEXCL))) {
1085                 mutex_exit(&sg_state->sgen_mutex);
1086                 return (EBUSY);
1087         }
1088 
1089         if (flag & FEXCL)
1090                 SGEN_SET_EXCL(sg_state);
1091 
1092         SGEN_SET_OPEN(sg_state);
1093 
1094         mutex_exit(&sg_state->sgen_mutex);
1095 
1096         return (0);
1097 }
1098 
1099 /*
1100  * sgen_close()
1101  *      close(9e) entrypoint.
1102  */
1103 /*ARGSUSED1*/
1104 static int
1105 sgen_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
1106 {
1107         sgen_state_t *sg_state;
1108         int instance;
1109 
1110         instance = getminor(dev);
1111 
1112         if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL)
1113                 return (ENXIO);
1114 
1115         sgen_log(sg_state, SGEN_DIAG2, "in sgen_close(): instance = %d",
1116             instance);
1117 
1118         mutex_enter(&sg_state->sgen_mutex);
1119         SGEN_CLR_OPEN(sg_state);
1120         SGEN_CLR_EXCL(sg_state);
1121         SGEN_CLR_SUSP(sg_state); /* closing clears the 'I was suspended' bit */
1122         mutex_exit(&sg_state->sgen_mutex);
1123 
1124         sgen_log(sg_state, SGEN_DIAG2, "done sgen_close()");
1125 
1126         return (0);
1127 }
1128 
1129 /*
1130  * sgen_ioctl()
1131  *      sgen supports the USCSI(7I) ioctl interface.
1132  */
1133 /*ARGSUSED4*/
1134 static int
1135 sgen_ioctl(dev_t dev,
1136     int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p)
1137 {
1138         int retval = 0;
1139         sgen_state_t *sg_state;
1140         int instance;
1141 
1142         instance = getminor(dev);
1143 
1144         if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL)
1145                 return (ENXIO);
1146 
1147         sgen_log(sg_state, SGEN_DIAG2, "in sgen_ioctl(): instance = %d",
1148             instance);
1149 
1150         /*
1151          * If the driver has been suspended since the last open, fail all
1152          * subsequent IO's so that the userland consumer reinitializes state.
1153          */
1154         mutex_enter(&sg_state->sgen_mutex);
1155         if (SGEN_IS_SUSP(sg_state)) {
1156                 mutex_exit(&sg_state->sgen_mutex);
1157                 sgen_log(sg_state, SGEN_DIAG1, "sgen_ioctl: returning EIO: "
1158                     "driver instance %d was previously suspended", instance);
1159                 return (EIO);
1160         }
1161         mutex_exit(&sg_state->sgen_mutex);
1162 
1163         switch (cmd) {
1164         case SGEN_IOC_DIAG: {
1165                 if (arg > 3) {
1166                         arg = 0;
1167                 }
1168                 sg_state->sgen_diag = (int)arg;
1169                 retval = 0;
1170                 break;
1171         }
1172 
1173         case SGEN_IOC_READY: {
1174                 if (sgen_tur(dev) != 0) {
1175                         retval = EIO;
1176                 } else {
1177                         retval = 0;
1178                 }
1179                 break;
1180         }
1181 
1182         case USCSICMD:
1183                 retval = sgen_uscsi_cmd(dev, (struct uscsi_cmd *)arg, flag);
1184                 break;
1185 
1186         default:
1187                 retval = ENOTTY;
1188         }
1189 
1190         sgen_log(sg_state, SGEN_DIAG2, "done sgen_ioctl(), returning %d",
1191             retval);
1192 
1193         return (retval);
1194 }
1195 
1196 /*
1197  * sgen_uscsi_cmd()
1198  *      Setup, configuration and teardown for a uscsi(7I) command
1199  */
1200 /*ARGSUSED*/
1201 static int
1202 sgen_uscsi_cmd(dev_t dev, struct uscsi_cmd *ucmd, int flag)
1203 {
1204         struct uscsi_cmd        *uscmd;
1205         struct buf      *bp;
1206         sgen_state_t    *sg_state;
1207         enum uio_seg    uioseg;
1208         int     instance;
1209         int     flags;
1210         int     err;
1211 
1212         instance = getminor(dev);
1213 
1214         sg_state = ddi_get_soft_state(sgen_soft_state, instance);
1215         ASSERT(sg_state);
1216 
1217         sgen_log(sg_state, SGEN_DIAG2, "in sgen_uscsi_cmd(): instance = %d",
1218             instance);
1219 
1220         /*
1221          * At this point, we start affecting state relevant to the target,
1222          * so access needs to be serialized.
1223          */
1224         if (sgen_hold_cmdbuf(sg_state) != 0) {
1225                 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: interrupted");
1226                 return (EINTR);
1227         }
1228 
1229         err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag,
1230             &sg_state->sgen_scsiaddr, &uscmd);
1231         if (err != 0) {
1232                 sgen_rele_cmdbuf(sg_state);
1233                 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: "
1234                     "scsi_uscsi_alloc_and_copyin failed\n");
1235                 return (err);
1236         }
1237 
1238         /*
1239          * Clear out undesirable command flags
1240          */
1241         flags = (uscmd->uscsi_flags & ~(USCSI_NOINTR | USCSI_NOPARITY |
1242             USCSI_OTAG | USCSI_HTAG | USCSI_HEAD));
1243         if (flags != uscmd->uscsi_flags) {
1244                 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: cleared "
1245                     "unsafe uscsi_flags 0x%x", uscmd->uscsi_flags & ~flags);
1246                 uscmd->uscsi_flags = flags;
1247         }
1248 
1249         if (uscmd->uscsi_cdb != NULL) {
1250                 sgen_dump_cdb(sg_state, "sgen_uscsi_cmd: ",
1251                     (union scsi_cdb *)uscmd->uscsi_cdb, uscmd->uscsi_cdblen);
1252         }
1253 
1254         /*
1255          * Stash the sense buffer into sgen_rqs_sen for convenience.
1256          */
1257         sg_state->sgen_rqs_sen = uscmd->uscsi_rqbuf;
1258 
1259         bp = sg_state->sgen_cmdbuf;
1260         bp->av_back = NULL;
1261         bp->av_forw = NULL;
1262         bp->b_private = (struct buf *)uscmd;
1263         uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
1264 
1265         err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, sgen_start, bp, NULL);
1266 
1267         if (sg_state->sgen_cmdpkt != NULL) {
1268                 uscmd->uscsi_status = SCBP_C(sg_state->sgen_cmdpkt);
1269         } else {
1270                 uscmd->uscsi_status = 0;
1271         }
1272 
1273         sgen_log(sg_state, SGEN_DIAG3, "sgen_uscsi_cmd: awake from waiting "
1274             "for command.  Status is 0x%x", uscmd->uscsi_status);
1275 
1276         if (uscmd->uscsi_rqbuf != NULL) {
1277                 int rqlen = uscmd->uscsi_rqlen - uscmd->uscsi_rqresid;
1278                 sgen_dump_sense(sg_state, rqlen,
1279                     (uchar_t *)uscmd->uscsi_rqbuf);
1280         }
1281 
1282         (void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd);
1283 
1284         if (sg_state->sgen_cmdpkt != NULL) {
1285                 scsi_destroy_pkt(sg_state->sgen_cmdpkt);
1286                 sg_state->sgen_cmdpkt = NULL;
1287         }
1288 
1289         /*
1290          * After this point, we can't touch per-target state.
1291          */
1292         sgen_rele_cmdbuf(sg_state);
1293 
1294         sgen_log(sg_state, SGEN_DIAG2, "done sgen_uscsi_cmd()");
1295 
1296         return (err);
1297 }
1298 
1299 /*
1300  * sgen_hold_cmdbuf()
1301  *      Acquire a lock on the command buffer for the given target.  Returns
1302  *      non-zero if interrupted.
1303  */
1304 static int
1305 sgen_hold_cmdbuf(sgen_state_t *sg_state)
1306 {
1307         mutex_enter(&sg_state->sgen_mutex);
1308         while (SGEN_IS_BUSY(sg_state)) {
1309                 if (!cv_wait_sig(&sg_state->sgen_cmdbuf_cv,
1310                     &sg_state->sgen_mutex)) {
1311                         mutex_exit(&sg_state->sgen_mutex);
1312                         return (-1);
1313                 }
1314         }
1315         SGEN_SET_BUSY(sg_state);
1316         mutex_exit(&sg_state->sgen_mutex);
1317         return (0);
1318 }
1319 
1320 /*
1321  * sgen_rele_cmdbuf()
1322  *      release the command buffer for a particular target.
1323  */
1324 static void
1325 sgen_rele_cmdbuf(sgen_state_t *sg_state)
1326 {
1327         mutex_enter(&sg_state->sgen_mutex);
1328         SGEN_CLR_BUSY(sg_state);
1329         cv_signal(&sg_state->sgen_cmdbuf_cv);
1330         mutex_exit(&sg_state->sgen_mutex);
1331 }
1332 
1333 /*
1334  * sgen_start()
1335  *      Transport a uscsi command; this is invoked by physio() or directly
1336  *      by sgen_uscsi_cmd().
1337  */
1338 static int
1339 sgen_start(struct buf *bp)
1340 {
1341         sgen_state_t *sg_state;
1342         dev_t dev = bp->b_edev;
1343         int trans_err;
1344 
1345         if ((sg_state = ddi_get_soft_state(sgen_soft_state,
1346             getminor(dev))) == NULL) {
1347                 bp->b_resid = bp->b_bcount;
1348                 bioerror(bp, ENXIO);
1349                 biodone(bp);
1350                 return (ENXIO);
1351         }
1352 
1353         /*
1354          * Sanity checks - command should not be complete, no packet should
1355          * be allocated, and there ought to be a uscsi cmd in b_private
1356          */
1357         ASSERT(bp == sg_state->sgen_cmdbuf && sg_state->sgen_cmdpkt == NULL);
1358         ASSERT((bp->b_flags & B_DONE) == 0);
1359         ASSERT(bp->b_private);
1360         if (sgen_make_uscsi_cmd(sg_state, bp) != 0) {
1361                 bp->b_resid = bp->b_bcount;
1362                 bioerror(bp, EFAULT);
1363                 biodone(bp);
1364                 return (EFAULT);
1365         }
1366 
1367         ASSERT(sg_state->sgen_cmdpkt != NULL);
1368 
1369         /*
1370          * Clear out the residual and error fields
1371          */
1372         bp->b_resid = 0;
1373         bp->b_error = 0;
1374 
1375         trans_err = sgen_scsi_transport(sg_state->sgen_cmdpkt);
1376         switch (trans_err) {
1377         case TRAN_ACCEPT:
1378                 break;
1379         case TRAN_BUSY:
1380                 sgen_log(sg_state, SGEN_DIAG2,
1381                     "sgen_start: scsi_transport() returned TRAN_BUSY");
1382                 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state,
1383                     SGEN_BSY_TIMEOUT);
1384                 break;
1385         default:
1386                 /*
1387                  * Indicate there has been an I/O transfer error.
1388                  * Be done with the command.
1389                  */
1390                 mutex_enter(&sg_state->sgen_mutex);
1391                 SGEN_DO_ERRSTATS(sg_state, sgen_trans_err);
1392                 mutex_exit(&sg_state->sgen_mutex);
1393                 sgen_log(sg_state, SGEN_DIAG2, "sgen_start: scsi_transport() "
1394                     "returned %d", trans_err);
1395                 bioerror(bp, EIO);
1396                 biodone(bp);
1397                 return (EIO);
1398         }
1399         sgen_log(sg_state, SGEN_DIAG2, "sgen_start: b_flags 0x%x", bp->b_flags);
1400         return (0);
1401 }
1402 
1403 /*
1404  * sgen_scsi_transport()
1405  *      a simple scsi_transport() wrapper which can be configured to inject
1406  *      sporadic errors for testing.
1407  */
1408 static int
1409 sgen_scsi_transport(struct scsi_pkt *pkt)
1410 {
1411         int trans_err;
1412         static int cnt = 0;
1413         sgen_state_t *sg_state = pkt->pkt_private;
1414 
1415         if (sgen_sporadic_failures == 0) {
1416                 return (scsi_transport(pkt));
1417         }
1418 
1419         cnt = (cnt * 2416 + 374441) % 1771875;  /* borrowed from kmem.c */
1420         if (cnt % 40 == 1) {
1421                 sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: "
1422                     "injecting sporadic BUSY");
1423                 trans_err = TRAN_BUSY;
1424         } else if (cnt % 40 == 2) {
1425                 sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: "
1426                     "injecting sporadic BADPKT");
1427                 trans_err = TRAN_BADPKT;
1428         } else {
1429                 /*
1430                  * Most of the time we take the normal path
1431                  */
1432                 trans_err = scsi_transport(pkt);
1433         }
1434         return (trans_err);
1435 }
1436 
1437 /*
1438  * sgen_make_uscsi_cmd()
1439  *      Initialize a SCSI packet usable for USCSI.
1440  */
1441 static int
1442 sgen_make_uscsi_cmd(sgen_state_t *sg_state, struct buf *bp)
1443 {
1444         struct scsi_pkt *pkt;
1445         struct uscsi_cmd *ucmd;
1446         int stat_size = 1;
1447         int flags = 0;
1448 
1449         ASSERT(bp);
1450 
1451         sgen_log(sg_state, SGEN_DIAG2, "in sgen_make_uscsi_cmd()");
1452 
1453         ucmd = (struct uscsi_cmd *)bp->b_private;
1454 
1455         if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1456                 if (ucmd->uscsi_rqlen > SENSE_LENGTH) {
1457                         stat_size = (int)(ucmd->uscsi_rqlen) +
1458                             sizeof (struct scsi_arq_status) -
1459                             sizeof (struct scsi_extended_sense);
1460                         flags = PKT_XARQ;
1461                 } else {
1462                         stat_size = sizeof (struct scsi_arq_status);
1463                 }
1464         }
1465 
1466         sgen_log(sg_state, SGEN_DIAG3, "sgen_make_uscsi_cmd: b_bcount = %ld",
1467             bp->b_bcount);
1468         pkt = scsi_init_pkt(&sg_state->sgen_scsiaddr,
1469             NULL,                       /* in_pkt - null so it'll be alloc'd */
1470             bp->b_bcount ? bp : NULL,        /* buf structure for data xfer */
1471             ucmd->uscsi_cdblen,              /* cmdlen */
1472             stat_size,                  /* statuslen */
1473             0,                          /* privatelen */
1474             flags,                      /* flags */
1475             SLEEP_FUNC,                 /* callback */
1476             (caddr_t)sg_state);         /* callback_arg */
1477 
1478         if (pkt == NULL) {
1479                 sgen_log(sg_state, SGEN_DIAG2, "failed sgen_make_uscsi_cmd()");
1480                 return (-1);
1481         }
1482 
1483         pkt->pkt_comp = sgen_callback;
1484         pkt->pkt_private = sg_state;
1485         sg_state->sgen_cmdpkt = pkt;
1486 
1487         /*
1488          * We *don't* call scsi_setup_cdb here, as is customary, since the
1489          * user could specify a command from one group, but pass cdblen
1490          * as something totally different.  If cdblen is smaller than expected,
1491          * this results in scsi_setup_cdb writing past the end of the cdb.
1492          */
1493         bcopy(ucmd->uscsi_cdb, pkt->pkt_cdbp, ucmd->uscsi_cdblen);
1494         if (ucmd->uscsi_cdblen >= CDB_GROUP0) {
1495                 FILL_SCSI1_LUN(sg_state->sgen_scsidev, pkt);
1496         }
1497 
1498         if (ucmd->uscsi_timeout > 0)
1499                 pkt->pkt_time = ucmd->uscsi_timeout;
1500         else
1501                 pkt->pkt_time = SGEN_IO_TIME;
1502 
1503         /*
1504          * Set packet options
1505          */
1506         if (ucmd->uscsi_flags & USCSI_SILENT)
1507                 pkt->pkt_flags |= FLAG_SILENT;
1508         if (ucmd->uscsi_flags & USCSI_ISOLATE)
1509                 pkt->pkt_flags |= FLAG_ISOLATE;
1510         if (ucmd->uscsi_flags & USCSI_DIAGNOSE)
1511                 pkt->pkt_flags |= FLAG_DIAGNOSE;
1512         if (ucmd->uscsi_flags & USCSI_RENEGOT) {
1513                 pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC;
1514         }
1515 
1516         /* Transfer uscsi information to scsi_pkt */
1517         (void) scsi_uscsi_pktinit(ucmd, pkt);
1518 
1519         sgen_log(sg_state, SGEN_DIAG2, "done sgen_make_uscsi_cmd()");
1520         return (0);
1521 }
1522 
1523 
1524 /*
1525  * sgen_restart()
1526  *      sgen_restart() is called after a timeout, when a command has been
1527  *      postponed due to a TRAN_BUSY response from the HBA.
1528  */
1529 static void
1530 sgen_restart(void *arg)
1531 {
1532         sgen_state_t *sg_state = (sgen_state_t *)arg;
1533         struct scsi_pkt *pkt;
1534         struct buf *bp;
1535 
1536         sgen_log(sg_state, SGEN_DIAG2, "in sgen_restart()");
1537 
1538         bp = sg_state->sgen_cmdbuf;
1539         pkt = sg_state->sgen_cmdpkt;
1540         ASSERT(bp && pkt);
1541 
1542         SGEN_DO_ERRSTATS(sg_state, sgen_restart);
1543 
1544         /*
1545          * If the packet is marked with the sensing flag, sgen is off running
1546          * a request sense, and *that packet* is what needs to be restarted.
1547          */
1548         if (pkt->pkt_flags & FLAG_SENSING) {
1549                 sgen_log(sg_state, SGEN_DIAG3,
1550                     "sgen_restart: restarting REQUEST SENSE");
1551                 pkt = sg_state->sgen_rqspkt;
1552         }
1553 
1554         if (sgen_scsi_transport(pkt) != TRAN_ACCEPT) {
1555                 bp->b_resid = bp->b_bcount;
1556                 bioerror(bp, EIO);
1557                 biodone(bp);
1558         }
1559 }
1560 
1561 /*
1562  * sgen_callback()
1563  *      Command completion processing
1564  *
1565  *      sgen's completion processing is very pessimistic-- it does not retry
1566  *      failed commands; instead, it allows the user application to make
1567  *      decisions about what has gone wrong.
1568  */
1569 static void
1570 sgen_callback(struct scsi_pkt *pkt)
1571 {
1572         sgen_state_t *sg_state;
1573         struct uscsi_cmd *ucmd;
1574         struct buf *bp;
1575         int action;
1576 
1577         sg_state = pkt->pkt_private;
1578         /*
1579          * bp should always be the command buffer regardless of whether
1580          * this is a command completion or a request-sense completion.
1581          * This is because there is no need to biodone() the sense buf
1582          * when it completes-- we want to biodone() the actual command buffer!
1583          */
1584         bp = sg_state->sgen_cmdbuf;
1585         if (pkt->pkt_flags & FLAG_SENSING) {
1586                 ASSERT(pkt == sg_state->sgen_rqspkt);
1587                 sgen_log(sg_state, SGEN_DIAG2,
1588                     "in sgen_callback() (SENSE completion callback)");
1589         } else {
1590                 ASSERT(pkt == sg_state->sgen_cmdpkt);
1591                 sgen_log(sg_state, SGEN_DIAG2,
1592                     "in sgen_callback() (command completion callback)");
1593         }
1594         ucmd = (struct uscsi_cmd *)bp->b_private;
1595 
1596         sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: reason=0x%x resid=%ld "
1597             "state=0x%x", pkt->pkt_reason, pkt->pkt_resid, pkt->pkt_state);
1598 
1599         /* Transfer scsi_pkt information to uscsi */
1600         (void) scsi_uscsi_pktfini(pkt, ucmd);
1601 
1602         if (pkt->pkt_reason != CMD_CMPLT) {
1603                 /*
1604                  * The command did not complete.
1605                  */
1606                 sgen_log(sg_state, SGEN_DIAG3,
1607                     "sgen_callback: command did not complete");
1608                 action = sgen_handle_incomplete(sg_state, pkt);
1609         } else if (sg_state->sgen_arq_enabled &&
1610             (pkt->pkt_state & STATE_ARQ_DONE)) {
1611                 /*
1612                  * The auto-rqsense happened, and the packet has a filled-in
1613                  * scsi_arq_status structure, pointed to by pkt_scbp.
1614                  */
1615                 sgen_log(sg_state, SGEN_DIAG3,
1616                     "sgen_callback: received auto-requested sense");
1617                 action = sgen_handle_autosense(sg_state, pkt);
1618                 ASSERT(action != FETCH_SENSE);
1619         } else if (pkt->pkt_flags & FLAG_SENSING) {
1620                 /*
1621                  * sgen was running a REQUEST SENSE. Decode the sense data and
1622                  * decide what to do next.
1623                  *
1624                  * Clear FLAG_SENSING on the original packet for completeness.
1625                  */
1626                 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: received sense");
1627                 sg_state->sgen_cmdpkt->pkt_flags &= ~FLAG_SENSING;
1628                 action = sgen_handle_sense(sg_state);
1629                 ASSERT(action != FETCH_SENSE);
1630         } else {
1631                 /*
1632                  * Command completed and we're not getting sense. Check for
1633                  * errors and decide what to do next.
1634                  */
1635                 sgen_log(sg_state, SGEN_DIAG3,
1636                     "sgen_callback: command appears complete");
1637                 action = sgen_check_error(sg_state, bp);
1638         }
1639 
1640         switch (action) {
1641         case FETCH_SENSE:
1642                 /*
1643                  * If there is sense to fetch, break out to prevent biodone'ing
1644                  * until the sense fetch is complete.
1645                  */
1646                 if (sgen_initiate_sense(sg_state,
1647                     scsi_pkt_allocated_correctly(pkt) ?
1648                     pkt->pkt_path_instance : 0) == 0)
1649                         break;
1650                 /*FALLTHROUGH*/
1651         case COMMAND_DONE_ERROR:
1652                 bp->b_resid = bp->b_bcount;
1653                 bioerror(bp, EIO);
1654                 /*FALLTHROUGH*/
1655         case COMMAND_DONE:
1656                 biodone(bp);
1657                 break;
1658         default:
1659                 ASSERT(0);
1660                 break;
1661         }
1662 
1663         sgen_log(sg_state, SGEN_DIAG2, "done sgen_callback()");
1664 }
1665 
1666 /*
1667  * sgen_initiate_sense()
1668  *      Send the sgen_rqspkt to the target, thereby requesting sense data.
1669  */
1670 static int
1671 sgen_initiate_sense(sgen_state_t *sg_state, int path_instance)
1672 {
1673         /* use same path_instance as command */
1674         if (scsi_pkt_allocated_correctly(sg_state->sgen_rqspkt))
1675                 sg_state->sgen_rqspkt->pkt_path_instance = path_instance;
1676 
1677         switch (sgen_scsi_transport(sg_state->sgen_rqspkt)) {
1678         case TRAN_ACCEPT:
1679                 sgen_log(sg_state, SGEN_DIAG3, "sgen_initiate_sense: "
1680                     "sense fetch transport accepted.");
1681                 return (0);
1682         case TRAN_BUSY:
1683                 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: "
1684                     "sense fetch transport busy, setting timeout.");
1685                 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state,
1686                     SGEN_BSY_TIMEOUT);
1687                 return (0);
1688         default:
1689                 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: "
1690                     "sense fetch transport failed or busy.");
1691                 return (-1);
1692         }
1693 }
1694 
1695 /*
1696  * sgen_handle_incomplete()
1697  *      sgen is pessimistic, but also careful-- it doesn't try to retry
1698  *      incomplete commands, but it also doesn't go resetting devices;
1699  *      it is hard to tell if the device will be tolerant of that sort
1700  *      of prodding.
1701  *
1702  *      This routine has been left as a guide for the future--- the
1703  *      current administration's hands-off policy may need modification.
1704  */
1705 /*ARGSUSED*/
1706 static int
1707 sgen_handle_incomplete(sgen_state_t *sg_state, struct scsi_pkt *pkt)
1708 {
1709         SGEN_DO_ERRSTATS(sg_state, sgen_incmp_err);
1710         return (COMMAND_DONE_ERROR);
1711 }
1712 
1713 /*
1714  * sgen_handle_autosense()
1715  *      Deal with SENSE data acquired automatically via the auto-request-sense
1716  *      facility.
1717  *
1718  *      Sgen takes a pessimistic view of things-- it doesn't retry commands,
1719  *      and unless the device recovered from the problem, this routine returns
1720  *      COMMAND_DONE_ERROR.
1721  */
1722 static int
1723 sgen_handle_autosense(sgen_state_t *sg_state, struct scsi_pkt *pkt)
1724 {
1725         struct scsi_arq_status *arqstat;
1726         struct uscsi_cmd *ucmd =
1727             (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private;
1728         int amt;
1729 
1730         arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp);
1731 
1732         SGEN_DO_ERRSTATS(sg_state, sgen_autosen_rcv);
1733 
1734         if (arqstat->sts_rqpkt_reason != CMD_CMPLT) {
1735                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: ARQ"
1736                     "failed to complete.");
1737                 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad);
1738                 return (COMMAND_DONE_ERROR);
1739         }
1740 
1741         if (pkt->pkt_state & STATE_XARQ_DONE) {
1742                 amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
1743         } else {
1744                 if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) {
1745                         amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
1746                 } else {
1747                         amt = SENSE_LENGTH - arqstat->sts_rqpkt_resid;
1748                 }
1749         }
1750 
1751         if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1752                 ucmd->uscsi_rqstatus = *((char *)&arqstat->sts_rqpkt_status);
1753                 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
1754                 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
1755                 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen);
1756                 bcopy(&(arqstat->sts_sensedata), sg_state->sgen_rqs_sen, rqlen);
1757                 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_autosense: "
1758                     "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n",
1759                     ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
1760         }
1761 
1762         if (arqstat->sts_rqpkt_status.sts_chk) {
1763                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got "
1764                     "check condition on auto request sense!");
1765                 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad);
1766                 return (COMMAND_DONE_ERROR);
1767         }
1768 
1769         if (((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0) ||
1770             (amt == 0)) {
1771                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got "
1772                     "auto-sense, but it contains no data!");
1773                 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad);
1774                 return (COMMAND_DONE_ERROR);
1775         }
1776 
1777         /*
1778          * Stuff the sense data pointer into sgen_sense for later retrieval
1779          */
1780         sg_state->sgen_sense = &arqstat->sts_sensedata;
1781 
1782         /*
1783          * Now, check to see whether we got enough sense data to make any
1784          * sense out if it (heh-heh).
1785          */
1786         if (amt < SUN_MIN_SENSE_LENGTH) {
1787                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: not "
1788                     "enough auto sense data");
1789                 return (COMMAND_DONE_ERROR);
1790         }
1791 
1792         switch (arqstat->sts_sensedata.es_key) {
1793         case KEY_RECOVERABLE_ERROR:
1794                 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err);
1795                 break;
1796         case KEY_NO_SENSE:
1797                 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err);
1798                 break;
1799         default:
1800                 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err);
1801                 break;
1802         }
1803 
1804         return (COMMAND_DONE);
1805 }
1806 
1807 /*
1808  * sgen_handle_sense()
1809  *      Examine sense data that was manually fetched from the target.
1810  */
1811 static int
1812 sgen_handle_sense(sgen_state_t *sg_state)
1813 {
1814         struct scsi_pkt *rqpkt = sg_state->sgen_rqspkt;
1815         struct scsi_status *rqstatus = (struct scsi_status *)rqpkt->pkt_scbp;
1816         struct uscsi_cmd *ucmd =
1817             (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private;
1818         int amt;
1819 
1820         SGEN_DO_ERRSTATS(sg_state, sgen_sense_rcv);
1821 
1822         amt = MAX_SENSE_LENGTH - rqpkt->pkt_resid;
1823 
1824         if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1825                 ucmd->uscsi_rqstatus = *((char *)rqstatus);
1826                 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
1827                 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
1828                 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen);
1829                 bcopy(sg_state->sgen_sense, sg_state->sgen_rqs_sen, rqlen);
1830                 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_sense: "
1831                     "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n",
1832                     ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
1833         }
1834 
1835         if (rqstatus->sts_busy) {
1836                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got busy "
1837                     "on request sense");
1838                 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1839                 return (COMMAND_DONE_ERROR);
1840         }
1841 
1842         if (rqstatus->sts_chk) {
1843                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got check "
1844                     "condition on request sense!");
1845                 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1846                 return (COMMAND_DONE_ERROR);
1847         }
1848 
1849         if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) {
1850                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got "
1851                     "sense, but it contains no data");
1852                 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1853                 return (COMMAND_DONE_ERROR);
1854         }
1855 
1856         /*
1857          * Now, check to see whether we got enough sense data to make any
1858          * sense out if it (heh-heh).
1859          */
1860         if (amt < SUN_MIN_SENSE_LENGTH) {
1861                 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: not "
1862                     "enough sense data");
1863                 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1864                 return (COMMAND_DONE_ERROR);
1865         }
1866 
1867         /*
1868          * Decode the sense data-- this was deposited here for us by the
1869          * setup in sgen_do_attach(). (note that sgen_sense is an alias for
1870          * the sd_sense field in the scsi_device).
1871          */
1872         sgen_log(sg_state, SGEN_DIAG1, "Sense key is %s [0x%x]",
1873             scsi_sname(sg_state->sgen_sense->es_key),
1874             sg_state->sgen_sense->es_key);
1875         switch (sg_state->sgen_sense->es_key) {
1876         case KEY_RECOVERABLE_ERROR:
1877                 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err);
1878                 break;
1879         case KEY_NO_SENSE:
1880                 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err);
1881                 break;
1882         default:
1883                 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err);
1884                 break;
1885         }
1886 
1887         return (COMMAND_DONE);
1888 }
1889 
1890 /*
1891  * sgen_check_error()
1892  *      examine the command packet for abnormal completion.
1893  *
1894  *      sgen_check_error should only be called at the completion of the
1895  *      command packet.
1896  */
1897 static int
1898 sgen_check_error(sgen_state_t *sg_state, struct buf *bp)
1899 {
1900         struct scsi_pkt *pkt = sg_state->sgen_cmdpkt;
1901         struct scsi_status *status = (struct scsi_status *)pkt->pkt_scbp;
1902         struct uscsi_cmd *ucmd =
1903             (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private;
1904 
1905         if (status->sts_busy) {
1906                 sgen_log(sg_state, SGEN_DIAG1,
1907                     "sgen_check_error: target is busy");
1908                 return (COMMAND_DONE_ERROR);
1909         }
1910 
1911         /*
1912          * pkt_resid will reflect, at this point, a residual of how many bytes
1913          * were not transferred; a non-zero pkt_resid is an error.
1914          */
1915         if (pkt->pkt_resid) {
1916                 bp->b_resid += pkt->pkt_resid;
1917         }
1918 
1919         if (status->sts_chk) {
1920                 if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1921                         if (sg_state->sgen_arq_enabled) {
1922                                 sgen_log(sg_state, SGEN_DIAG1,
1923                                     "sgen_check_error: strange: target "
1924                                     "indicates CHECK CONDITION with auto-sense "
1925                                     "enabled.");
1926                         }
1927                         sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: "
1928                             "target ready for sense fetch");
1929                         return (FETCH_SENSE);
1930                 } else {
1931                         sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: "
1932                             "target indicates CHECK CONDITION");
1933                 }
1934         }
1935 
1936         return (COMMAND_DONE);
1937 }
1938 
1939 /*
1940  * sgen_tur()
1941  *      test if a target is ready to operate by sending it a TUR command.
1942  */
1943 static int
1944 sgen_tur(dev_t dev)
1945 {
1946         char cmdblk[CDB_GROUP0];
1947         struct uscsi_cmd scmd;
1948 
1949         bzero(&scmd, sizeof (scmd));
1950         scmd.uscsi_bufaddr = 0;
1951         scmd.uscsi_buflen = 0;
1952         bzero(cmdblk, CDB_GROUP0);
1953         cmdblk[0] = (char)SCMD_TEST_UNIT_READY;
1954         scmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_WRITE;
1955         scmd.uscsi_cdb = cmdblk;
1956         scmd.uscsi_cdblen = CDB_GROUP0;
1957 
1958         return (sgen_uscsi_cmd(dev, &scmd, FKIOCTL));
1959 }
1960 
1961 /*
1962  * sgen_diag_ok()
1963  *      given an sg_state and a desired diagnostic level, return true if
1964  *      it is acceptable to output a message.
1965  */
1966 /*ARGSUSED*/
1967 static int
1968 sgen_diag_ok(sgen_state_t *sg_state, int level)
1969 {
1970         int diag_lvl;
1971 
1972         switch (level) {
1973         case CE_WARN:
1974         case CE_NOTE:
1975         case CE_CONT:
1976         case CE_PANIC:
1977                 return (1);
1978         case SGEN_DIAG1:
1979         case SGEN_DIAG2:
1980         case SGEN_DIAG3:
1981                 if (sg_state) {
1982                         /*
1983                          * Check to see if user overrode the diagnostics level
1984                          * for this instance (either via SGEN_IOC_DIAG or via
1985                          * .conf file).  If not, fall back to the global diag
1986                          * level.
1987                          */
1988                         if (sg_state->sgen_diag != -1)
1989                                 diag_lvl = sg_state->sgen_diag;
1990                         else
1991                                 diag_lvl = sgen_diag;
1992                 } else {
1993                         diag_lvl = sgen_diag;
1994                 }
1995                 if (((diag_lvl << 8) | CE_CONT) >= level) {
1996                         return (1);
1997                 } else {
1998                         return (0);
1999                 }
2000         default:
2001                 return (1);
2002         }
2003 }
2004 
2005 /*PRINTFLIKE3*/
2006 static void
2007 sgen_log(sgen_state_t *sg_state, int level, const char *fmt, ...)
2008 {
2009         va_list ap;
2010         char buf[256];
2011 
2012         if (!sgen_diag_ok(sg_state, level))
2013                 return;
2014 
2015         va_start(ap, fmt);
2016         (void) vsnprintf(buf, sizeof (buf), fmt, ap);
2017         va_end(ap);
2018 
2019         switch (level) {
2020         case CE_NOTE:
2021         case CE_CONT:
2022         case CE_WARN:
2023         case CE_PANIC:
2024                 if (sg_state == (sgen_state_t *)NULL) {
2025                         cmn_err(level, "%s", buf);
2026                 } else {
2027                         scsi_log(sg_state->sgen_devinfo, sgen_label, level,
2028                             "%s", buf);
2029                 }
2030                 break;
2031         case SGEN_DIAG1:
2032         case SGEN_DIAG2:
2033         case SGEN_DIAG3:
2034         default:
2035                 if (sg_state == (sgen_state_t *)NULL) {
2036                         scsi_log(NULL, sgen_label, CE_CONT, "%s", buf);
2037                 } else {
2038                         scsi_log(sg_state->sgen_devinfo, sgen_label, CE_CONT,
2039                             "%s", buf);
2040                 }
2041         }
2042 }
2043 
2044 /*
2045  * sgen_dump_cdb()
2046  *      dump out the contents of a cdb.  Take care that 'label' is not too
2047  *      large, or 'buf' could overflow.
2048  */
2049 static void
2050 sgen_dump_cdb(sgen_state_t *sg_state, const char *label,
2051     union scsi_cdb *cdb, int cdblen)
2052 {
2053         static char hex[] = "0123456789abcdef";
2054         char *buf, *p;
2055         size_t nbytes;
2056         int i;
2057         uchar_t *cdbp = (uchar_t *)cdb;
2058 
2059         /*
2060          * fastpath-- if we're not able to print out, don't do all of this
2061          * extra work.
2062          */
2063         if (!sgen_diag_ok(sg_state, SGEN_DIAG3))
2064                 return;
2065 
2066         /*
2067          * 3 characters for each byte (because of the ' '), plus the size of
2068          * the label, plus the trailing ']' and the null character.
2069          */
2070         nbytes = 3 * cdblen + strlen(label) + strlen(" CDB = [") + 2;
2071         buf = kmem_alloc(nbytes, KM_SLEEP);
2072         (void) sprintf(buf, "%s CDB = [", label);
2073         p = &buf[strlen(buf)];
2074         for (i = 0; i < cdblen; i++, cdbp++) {
2075                 if (i > 0)
2076                         *p++ = ' ';
2077                 *p++ = hex[(*cdbp >> 4) & 0x0f];
2078                 *p++ = hex[*cdbp & 0x0f];
2079         }
2080         *p++ = ']';
2081         *p = 0;
2082         sgen_log(sg_state, SGEN_DIAG3, buf);
2083         kmem_free(buf, nbytes);
2084 }
2085 
2086 static void
2087 sgen_dump_sense(sgen_state_t *sg_state, size_t rqlen, uchar_t *rqbuf)
2088 {
2089         static char hex[] = "0123456789abcdef";
2090         char *buf, *p;
2091         size_t nbytes;
2092         int i;
2093 
2094         /*
2095          * fastpath-- if we're not able to print out, don't do all of this
2096          * extra work.
2097          */
2098         if (!sgen_diag_ok(sg_state, SGEN_DIAG3))
2099                 return;
2100 
2101         /*
2102          * 3 characters for each byte (because of the ' '), plus the size of
2103          * the label, plus the trailing ']' and the null character.
2104          */
2105         nbytes = 3 * rqlen + strlen(" SENSE = [") + 2;
2106         buf = kmem_alloc(nbytes, KM_SLEEP);
2107         (void) sprintf(buf, "SENSE = [");
2108         p = &buf[strlen(buf)];
2109         for (i = 0; i < rqlen; i++, rqbuf++) {
2110                 if (i > 0)
2111                         *p++ = ' ';
2112                 *p++ = hex[(*rqbuf >> 4) & 0x0f];
2113                 *p++ = hex[*rqbuf & 0x0f];
2114         }
2115         *p++ = ']';
2116         *p = 0;
2117         sgen_log(sg_state, SGEN_DIAG3, buf);
2118         kmem_free(buf, nbytes);
2119 }