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, 0) == 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 } 2120