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(4I) 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 sgen_log(NULL, SGEN_DIAG2, "%s sgen_attach(), device unit-address @%s", 558 err == DDI_SUCCESS ? "done" : "failed", ddi_get_name_addr(dip)); 559 return (err); 560 } 561 562 /* 563 * sgen_do_attach() 564 * handle the nitty details of attach. 565 */ 566 static int 567 sgen_do_attach(dev_info_t *dip) 568 { 569 int instance; 570 struct scsi_device *scsidevp; 571 sgen_state_t *sg_state; 572 uchar_t devtype; 573 struct scsi_inquiry *inq; 574 575 instance = ddi_get_instance(dip); 576 577 scsidevp = ddi_get_driver_private(dip); 578 ASSERT(scsidevp); 579 580 sgen_log(NULL, SGEN_DIAG2, "sgen_do_attach: instance = %d, " 581 "device unit-address @%s", instance, ddi_get_name_addr(dip)); 582 583 /* 584 * Probe the device in order to get its device type to name the minor 585 * node. 586 */ 587 if (scsi_probe(scsidevp, NULL_FUNC) != SCSIPROBE_EXISTS) { 588 scsi_unprobe(scsidevp); 589 return (DDI_FAILURE); 590 } 591 592 if (ddi_soft_state_zalloc(sgen_soft_state, instance) != DDI_SUCCESS) { 593 sgen_log(NULL, SGEN_DIAG1, 594 "sgen_do_attach: failed to allocate softstate, " 595 "device unit-address @%s", ddi_get_name_addr(dip)); 596 scsi_unprobe(scsidevp); 597 return (DDI_FAILURE); 598 } 599 600 inq = scsidevp->sd_inq; /* valid while device is probed... */ 601 devtype = inq->inq_dtype; 602 603 sg_state = ddi_get_soft_state(sgen_soft_state, instance); 604 sg_state->sgen_scsidev = scsidevp; 605 scsidevp->sd_dev = dip; 606 607 /* 608 * Now that sg_state->sgen_scsidev is initialized, it's ok to 609 * call sgen_log with sg_state instead of NULL. 610 */ 611 612 /* 613 * If the user specified the sgen_diag property, override the global 614 * sgen_diag setting by setting sg_state's sgen_diag value. If the 615 * user gave a value out of range, default to '0'. 616 */ 617 sg_state->sgen_diag = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 618 "sgen-diag", -1); 619 620 if (sg_state->sgen_diag != -1) { 621 if (sg_state->sgen_diag < 0 || sg_state->sgen_diag > 3) 622 sg_state->sgen_diag = 0; 623 } 624 625 sgen_log(sg_state, SGEN_DIAG2, 626 "sgen_do_attach: sgen_soft_state=0x%p, instance=%d, " 627 "device unit-address @%s", 628 sgen_soft_state, instance, ddi_get_name_addr(dip)); 629 630 /* 631 * For simplicity, the minor number == the instance number 632 */ 633 if (ddi_create_minor_node(dip, sgen_typename(devtype), S_IFCHR, 634 instance, DDI_NT_SGEN, 0) == DDI_FAILURE) { 635 scsi_unprobe(scsidevp); 636 ddi_prop_remove_all(dip); 637 sgen_log(sg_state, SGEN_DIAG1, 638 "sgen_do_attach: minor node creation failed, " 639 "device unit-address @%s", ddi_get_name_addr(dip)); 640 ddi_soft_state_free(sgen_soft_state, instance); 641 return (DDI_FAILURE); 642 } 643 644 /* 645 * Allocate the command buffer, then create a condition variable for 646 * managing it; mark the command buffer as free. 647 */ 648 sg_state->sgen_cmdbuf = getrbuf(KM_SLEEP); 649 cv_init(&sg_state->sgen_cmdbuf_cv, NULL, CV_DRIVER, NULL); 650 651 SGEN_CLR_BUSY(sg_state); 652 SGEN_CLR_OPEN(sg_state); 653 SGEN_CLR_SUSP(sg_state); 654 655 /* 656 * If the hba and the target both support wide xfers, enable them. 657 */ 658 if (scsi_ifgetcap(&sg_state->sgen_scsiaddr, "wide-xfer", 1) != -1) { 659 int wide = 0; 660 if ((inq->inq_rdf == RDF_SCSI2) && 661 (inq->inq_wbus16 || inq->inq_wbus32)) 662 wide = 1; 663 if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, "wide-xfer", 664 wide, 1) == 1) { 665 sgen_log(sg_state, SGEN_DIAG1, 666 "sgen_attach: wide xfer %s, " 667 "device unit-address @%s", 668 wide ? "enabled" : "disabled", 669 ddi_get_name_addr(dip)); 670 } 671 } 672 673 /* 674 * This is a little debugging code-- since the codepath for auto-sense 675 * and 'manual' sense is split, toggling this variable will make 676 * sgen act as though the adapter in question can't do auto-sense. 677 */ 678 if (sgen_force_manual_sense) { 679 if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, "auto-rqsense", 680 0, 1) == 1) { 681 sg_state->sgen_arq_enabled = 0; 682 } else { 683 sg_state->sgen_arq_enabled = 1; 684 } 685 } else { 686 /* 687 * Enable autorequest sense, if supported 688 */ 689 if (scsi_ifgetcap(&sg_state->sgen_scsiaddr, 690 "auto-rqsense", 1) != 1) { 691 if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, 692 "auto-rqsense", 1, 1) == 1) { 693 sg_state->sgen_arq_enabled = 1; 694 sgen_log(sg_state, SGEN_DIAG1, 695 "sgen_attach: auto-request-sense enabled, " 696 "device unit-address @%s", 697 ddi_get_name_addr(dip)); 698 } else { 699 sg_state->sgen_arq_enabled = 0; 700 sgen_log(sg_state, SGEN_DIAG1, 701 "sgen_attach: auto-request-sense disabled, " 702 "device unit-address @%s", 703 ddi_get_name_addr(dip)); 704 } 705 } else { 706 sg_state->sgen_arq_enabled = 1; /* already enabled */ 707 sgen_log(sg_state, SGEN_DIAG1, 708 "sgen_attach: auto-request-sense enabled, " 709 "device unit-address @%s", ddi_get_name_addr(dip)); 710 } 711 } 712 713 /* 714 * Allocate plumbing for manually fetching sense. 715 */ 716 if (sgen_setup_sense(sg_state) != 0) { 717 freerbuf(sg_state->sgen_cmdbuf); 718 ddi_prop_remove_all(dip); 719 ddi_remove_minor_node(dip, NULL); 720 scsi_unprobe(scsidevp); 721 sgen_log(sg_state, SGEN_DIAG1, 722 "sgen_do_attach: failed to setup request-sense, " 723 "device unit-address @%s", ddi_get_name_addr(dip)); 724 ddi_soft_state_free(sgen_soft_state, instance); 725 return (DDI_FAILURE); 726 } 727 728 sgen_create_errstats(sg_state, instance); 729 730 ddi_report_dev(dip); 731 732 return (DDI_SUCCESS); 733 } 734 735 /* 736 * sgen_setup_sense() 737 * Allocate a request sense packet so that if sgen needs to fetch sense 738 * data for the user, it will have a pkt ready to send. 739 */ 740 static int 741 sgen_setup_sense(sgen_state_t *sg_state) 742 { 743 struct buf *bp; 744 struct scsi_pkt *rqpkt; 745 746 if ((bp = scsi_alloc_consistent_buf(&sg_state->sgen_scsiaddr, NULL, 747 MAX_SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) { 748 return (-1); 749 } 750 751 if ((rqpkt = scsi_init_pkt(&sg_state->sgen_scsiaddr, NULL, bp, 752 CDB_GROUP0, 1, 0, PKT_CONSISTENT, SLEEP_FUNC, NULL)) == NULL) { 753 scsi_free_consistent_buf(bp); 754 return (-1); 755 } 756 757 /* 758 * Make the results of running a SENSE available by filling out the 759 * sd_sense field of the scsi device (sgen_sense is just an alias). 760 */ 761 sg_state->sgen_sense = (struct scsi_extended_sense *)bp->b_un.b_addr; 762 763 (void) scsi_setup_cdb((union scsi_cdb *)rqpkt->pkt_cdbp, 764 SCMD_REQUEST_SENSE, 0, MAX_SENSE_LENGTH, 0); 765 FILL_SCSI1_LUN(sg_state->sgen_scsidev, rqpkt); 766 767 rqpkt->pkt_comp = sgen_callback; 768 rqpkt->pkt_time = SGEN_IO_TIME; 769 rqpkt->pkt_flags |= FLAG_SENSING; 770 rqpkt->pkt_private = sg_state; 771 772 sg_state->sgen_rqspkt = rqpkt; 773 sg_state->sgen_rqsbuf = bp; 774 775 return (0); 776 } 777 778 /* 779 * sgen_create_errstats() 780 * create named kstats for tracking occurrence of errors. 781 */ 782 static void 783 sgen_create_errstats(sgen_state_t *sg_state, int instance) 784 { 785 char kstatname[KSTAT_STRLEN]; 786 struct sgen_errstats *stp; 787 788 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,err", 789 sgen_label, instance); 790 sg_state->sgen_kstats = kstat_create("sgenerr", instance, 791 kstatname, "device_error", KSTAT_TYPE_NAMED, 792 sizeof (struct sgen_errstats) / sizeof (kstat_named_t), 793 KSTAT_FLAG_PERSISTENT); 794 795 if (sg_state->sgen_kstats == NULL) 796 return; 797 798 stp = (struct sgen_errstats *)sg_state->sgen_kstats->ks_data; 799 kstat_named_init(&stp->sgen_trans_err, "transport_errors", 800 KSTAT_DATA_UINT32); 801 kstat_named_init(&stp->sgen_restart, "command_restarts", 802 KSTAT_DATA_UINT32); 803 kstat_named_init(&stp->sgen_incmp_err, "incomplete_commands", 804 KSTAT_DATA_UINT32); 805 kstat_named_init(&stp->sgen_autosen_rcv, "autosense_occurred", 806 KSTAT_DATA_UINT32); 807 kstat_named_init(&stp->sgen_autosen_bad, "autosense_undecipherable", 808 KSTAT_DATA_UINT32); 809 kstat_named_init(&stp->sgen_sense_rcv, "sense_fetches", 810 KSTAT_DATA_UINT32); 811 kstat_named_init(&stp->sgen_sense_bad, "sense_data_undecipherable", 812 KSTAT_DATA_UINT32); 813 kstat_named_init(&stp->sgen_recov_err, "recoverable_error", 814 KSTAT_DATA_UINT32); 815 kstat_named_init(&stp->sgen_nosen_err, "NO_SENSE_sense_key", 816 KSTAT_DATA_UINT32); 817 kstat_named_init(&stp->sgen_unrecov_err, "unrecoverable_sense_error", 818 KSTAT_DATA_UINT32); 819 sg_state->sgen_kstats->ks_private = sg_state; 820 sg_state->sgen_kstats->ks_update = nulldev; 821 kstat_install(sg_state->sgen_kstats); 822 } 823 824 /* 825 * sgen_detach() 826 * detach(9E) entrypoint 827 */ 828 static int 829 sgen_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 830 { 831 int instance; 832 sgen_state_t *sg_state; 833 834 instance = ddi_get_instance(dip); 835 sg_state = ddi_get_soft_state(sgen_soft_state, instance); 836 837 sgen_log(sg_state, SGEN_DIAG2, "in sgen_detach(), " 838 "device unit-address @%s", ddi_get_name_addr(dip)); 839 840 if (sg_state == NULL) { 841 sgen_log(NULL, SGEN_DIAG1, 842 "sgen_detach: failed, no softstate found (%d), " 843 "device unit-address @%s", 844 instance, ddi_get_name_addr(dip)); 845 return (DDI_FAILURE); 846 } 847 848 switch (cmd) { 849 case DDI_DETACH: 850 return (sgen_do_detach(dip)); 851 case DDI_SUSPEND: 852 return (sgen_do_suspend(dip)); 853 case DDI_PM_SUSPEND: 854 default: 855 return (DDI_FAILURE); 856 } 857 } 858 859 /* 860 * sgen_do_detach() 861 * detach the driver, tearing down resources. 862 */ 863 static int 864 sgen_do_detach(dev_info_t *dip) 865 { 866 int instance; 867 sgen_state_t *sg_state; 868 struct scsi_device *devp; 869 870 instance = ddi_get_instance(dip); 871 sg_state = ddi_get_soft_state(sgen_soft_state, instance); 872 ASSERT(sg_state); 873 874 sgen_log(sg_state, SGEN_DIAG2, "in sgen_do_detach(), " 875 "device unit-address @%s", ddi_get_name_addr(dip)); 876 devp = ddi_get_driver_private(dip); 877 878 mutex_enter(&sg_state->sgen_mutex); 879 if (SGEN_IS_BUSY(sg_state)) { 880 mutex_exit(&sg_state->sgen_mutex); 881 sgen_log(sg_state, SGEN_DIAG1, "sgen_do_detach: failed because " 882 "device is busy, device unit-address @%s", 883 ddi_get_name_addr(dip)); 884 return (DDI_FAILURE); 885 } 886 mutex_exit(&sg_state->sgen_mutex); 887 888 /* 889 * Final approach for detach. Free data allocated by scsi_probe() 890 * in attach. 891 */ 892 if (sg_state->sgen_restart_timeid) 893 (void) untimeout(sg_state->sgen_restart_timeid); 894 sg_state->sgen_restart_timeid = 0; 895 scsi_unprobe(devp); 896 897 /* 898 * Free auto-request plumbing. 899 */ 900 scsi_free_consistent_buf(sg_state->sgen_rqsbuf); 901 scsi_destroy_pkt(sg_state->sgen_rqspkt); 902 903 if (sg_state->sgen_kstats) { 904 kstat_delete(sg_state->sgen_kstats); 905 sg_state->sgen_kstats = NULL; 906 } 907 908 /* 909 * Free command buffer and clean up 910 */ 911 freerbuf(sg_state->sgen_cmdbuf); 912 cv_destroy(&sg_state->sgen_cmdbuf_cv); 913 914 sgen_log(sg_state, SGEN_DIAG2, "done sgen_do_detach(), " 915 "device unit-address @%s", ddi_get_name_addr(dip)); 916 917 ddi_soft_state_free(sgen_soft_state, instance); 918 ddi_prop_remove_all(dip); 919 ddi_remove_minor_node(dip, NULL); 920 return (DDI_SUCCESS); 921 } 922 923 /* 924 * sgen_do_suspend() 925 * suspend the driver. This sets the "suspend" bit for this target if it 926 * is currently open; once resumed, the suspend bit will cause 927 * subsequent I/Os to fail. We want user programs to close and 928 * reopen the device to acknowledge that they need to reexamine its 929 * state and do the right thing. 930 */ 931 static int 932 sgen_do_suspend(dev_info_t *dip) 933 { 934 int instance; 935 sgen_state_t *sg_state; 936 937 instance = ddi_get_instance(dip); 938 sg_state = ddi_get_soft_state(sgen_soft_state, instance); 939 ASSERT(sg_state); 940 941 sgen_log(sg_state, SGEN_DIAG2, "in sgen_do_suspend(), " 942 "device unit-address @%s", ddi_get_name_addr(dip)); 943 944 if (sg_state->sgen_restart_timeid) { 945 (void) untimeout(sg_state->sgen_restart_timeid); 946 } 947 sg_state->sgen_restart_timeid = 0; 948 949 mutex_enter(&sg_state->sgen_mutex); 950 if (SGEN_IS_OPEN(sg_state)) 951 SGEN_SET_SUSP(sg_state); 952 mutex_exit(&sg_state->sgen_mutex); 953 954 sgen_log(sg_state, SGEN_DIAG2, "done sgen_do_suspend(), " 955 "device unit-address @%s", ddi_get_name_addr(dip)); 956 return (DDI_SUCCESS); 957 } 958 959 /* 960 * sgen_getinfo() 961 * getinfo(9e) entrypoint. 962 */ 963 /*ARGSUSED*/ 964 static int 965 sgen_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 966 { 967 dev_t dev; 968 sgen_state_t *sg_state; 969 int instance, error; 970 switch (infocmd) { 971 case DDI_INFO_DEVT2DEVINFO: 972 dev = (dev_t)arg; 973 instance = getminor(dev); 974 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) 975 == NULL) 976 return (DDI_FAILURE); 977 *result = (void *) sg_state->sgen_scsidev->sd_dev; 978 error = DDI_SUCCESS; 979 break; 980 case DDI_INFO_DEVT2INSTANCE: 981 dev = (dev_t)arg; 982 instance = getminor(dev); 983 *result = (void *)(uintptr_t)instance; 984 error = DDI_SUCCESS; 985 break; 986 default: 987 error = DDI_FAILURE; 988 } 989 return (error); 990 } 991 992 /* 993 * sgen_probe() 994 * probe(9e) entrypoint. sgen *never* returns DDI_PROBE_PARTIAL, in 995 * order to avoid leaving around extra devinfos. If sgen's binding 996 * rules indicate that it should bind, it returns DDI_PROBE_SUCCESS. 997 */ 998 static int 999 sgen_probe(dev_info_t *dip) 1000 { 1001 struct scsi_device *scsidevp; 1002 int instance; 1003 int rval; 1004 1005 scsidevp = ddi_get_driver_private(dip); 1006 instance = ddi_get_instance(dip); 1007 sgen_log(NULL, SGEN_DIAG2, "in sgen_probe(): instance = %d, " 1008 "device unit-address @%s", instance, ddi_get_name_addr(dip)); 1009 1010 if (ddi_dev_is_sid(dip) == DDI_SUCCESS) 1011 return (DDI_PROBE_DONTCARE); 1012 1013 if (ddi_get_soft_state(sgen_soft_state, instance) != NULL) 1014 return (DDI_PROBE_FAILURE); 1015 1016 mutex_enter(&sgen_binddb.sdb_lock); 1017 if (sgen_binddb.sdb_init == 0) { 1018 sgen_setup_binddb(dip); 1019 } 1020 mutex_exit(&sgen_binddb.sdb_lock); 1021 1022 /* 1023 * A small optimization: if it's impossible for sgen to bind to 1024 * any devices, don't bother probing, just fail. 1025 */ 1026 if ((sgen_binddb.sdb_inq_nodes == NULL) && 1027 (sgen_binddb.sdb_type_nodes == NULL)) { 1028 return (DDI_PROBE_FAILURE); 1029 } 1030 1031 if (scsi_probe(scsidevp, NULL_FUNC) == SCSIPROBE_EXISTS) { 1032 if (sgen_get_binding(dip) == 0) { 1033 rval = DDI_PROBE_SUCCESS; 1034 } 1035 } else { 1036 rval = DDI_PROBE_FAILURE; 1037 } 1038 scsi_unprobe(scsidevp); 1039 1040 sgen_log(NULL, SGEN_DIAG2, "sgen_probe() %s, device unit-address @%s", 1041 rval == DDI_PROBE_SUCCESS ? "succeeded" : "failed", 1042 ddi_get_name_addr(dip)); 1043 return (rval); 1044 } 1045 1046 /* 1047 * sgen_open() 1048 * open(9e) entrypoint. sgen enforces a strict exclusive open policy per 1049 * target. 1050 */ 1051 /*ARGSUSED1*/ 1052 static int 1053 sgen_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) 1054 { 1055 dev_t dev = *dev_p; 1056 sgen_state_t *sg_state; 1057 int instance; 1058 1059 instance = getminor(dev); 1060 1061 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL) 1062 return (ENXIO); 1063 1064 sgen_log(sg_state, SGEN_DIAG2, "in sgen_open(): instance = %d", 1065 instance); 1066 1067 mutex_enter(&sg_state->sgen_mutex); 1068 1069 /* 1070 * Don't allow new opens of a suspended device until the last close has 1071 * happened. This is rather simplistic, but keeps the implementation 1072 * straightforward. 1073 */ 1074 if (SGEN_IS_SUSP(sg_state)) { 1075 mutex_exit(&sg_state->sgen_mutex); 1076 return (EIO); 1077 } 1078 1079 /* 1080 * Enforce exclusive access. 1081 */ 1082 if (SGEN_IS_EXCL(sg_state) || 1083 (SGEN_IS_OPEN(sg_state) && (flag & FEXCL))) { 1084 mutex_exit(&sg_state->sgen_mutex); 1085 return (EBUSY); 1086 } 1087 1088 if (flag & FEXCL) 1089 SGEN_SET_EXCL(sg_state); 1090 1091 SGEN_SET_OPEN(sg_state); 1092 1093 mutex_exit(&sg_state->sgen_mutex); 1094 1095 return (0); 1096 } 1097 1098 /* 1099 * sgen_close() 1100 * close(9e) entrypoint. 1101 */ 1102 /*ARGSUSED1*/ 1103 static int 1104 sgen_close(dev_t dev, int flag, int otyp, cred_t *cred_p) 1105 { 1106 sgen_state_t *sg_state; 1107 int instance; 1108 1109 instance = getminor(dev); 1110 1111 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL) 1112 return (ENXIO); 1113 1114 sgen_log(sg_state, SGEN_DIAG2, "in sgen_close(): instance = %d", 1115 instance); 1116 1117 mutex_enter(&sg_state->sgen_mutex); 1118 SGEN_CLR_OPEN(sg_state); 1119 SGEN_CLR_EXCL(sg_state); 1120 SGEN_CLR_SUSP(sg_state); /* closing clears the 'I was suspended' bit */ 1121 mutex_exit(&sg_state->sgen_mutex); 1122 1123 sgen_log(sg_state, SGEN_DIAG2, "done sgen_close()"); 1124 1125 return (0); 1126 } 1127 1128 /* 1129 * sgen_ioctl() 1130 * sgen supports the uscsi(4I) ioctl interface. 1131 */ 1132 /*ARGSUSED4*/ 1133 static int 1134 sgen_ioctl(dev_t dev, 1135 int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p) 1136 { 1137 int retval = 0; 1138 sgen_state_t *sg_state; 1139 int instance; 1140 1141 instance = getminor(dev); 1142 1143 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL) 1144 return (ENXIO); 1145 1146 sgen_log(sg_state, SGEN_DIAG2, "in sgen_ioctl(): instance = %d", 1147 instance); 1148 1149 /* 1150 * If the driver has been suspended since the last open, fail all 1151 * subsequent IO's so that the userland consumer reinitializes state. 1152 */ 1153 mutex_enter(&sg_state->sgen_mutex); 1154 if (SGEN_IS_SUSP(sg_state)) { 1155 mutex_exit(&sg_state->sgen_mutex); 1156 sgen_log(sg_state, SGEN_DIAG1, "sgen_ioctl: returning EIO: " 1157 "driver instance %d was previously suspended", instance); 1158 return (EIO); 1159 } 1160 mutex_exit(&sg_state->sgen_mutex); 1161 1162 switch (cmd) { 1163 case SGEN_IOC_DIAG: { 1164 if (arg > 3) { 1165 arg = 0; 1166 } 1167 sg_state->sgen_diag = (int)arg; 1168 retval = 0; 1169 break; 1170 } 1171 1172 case SGEN_IOC_READY: { 1173 if (sgen_tur(dev) != 0) { 1174 retval = EIO; 1175 } else { 1176 retval = 0; 1177 } 1178 break; 1179 } 1180 1181 case USCSICMD: 1182 retval = sgen_uscsi_cmd(dev, (struct uscsi_cmd *)arg, flag); 1183 break; 1184 1185 default: 1186 retval = ENOTTY; 1187 } 1188 1189 sgen_log(sg_state, SGEN_DIAG2, "done sgen_ioctl(), returning %d", 1190 retval); 1191 1192 return (retval); 1193 } 1194 1195 /* 1196 * sgen_uscsi_cmd() 1197 * Setup, configuration and teardown for a uscsi(4I) command 1198 */ 1199 /*ARGSUSED*/ 1200 static int 1201 sgen_uscsi_cmd(dev_t dev, struct uscsi_cmd *ucmd, int flag) 1202 { 1203 struct uscsi_cmd *uscmd; 1204 struct buf *bp; 1205 sgen_state_t *sg_state; 1206 enum uio_seg uioseg; 1207 int instance; 1208 int flags; 1209 int err; 1210 1211 instance = getminor(dev); 1212 1213 sg_state = ddi_get_soft_state(sgen_soft_state, instance); 1214 ASSERT(sg_state); 1215 1216 sgen_log(sg_state, SGEN_DIAG2, "in sgen_uscsi_cmd(): instance = %d", 1217 instance); 1218 1219 /* 1220 * At this point, we start affecting state relevant to the target, 1221 * so access needs to be serialized. 1222 */ 1223 if (sgen_hold_cmdbuf(sg_state) != 0) { 1224 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: interrupted"); 1225 return (EINTR); 1226 } 1227 1228 err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag, 1229 &sg_state->sgen_scsiaddr, &uscmd); 1230 if (err != 0) { 1231 sgen_rele_cmdbuf(sg_state); 1232 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: " 1233 "scsi_uscsi_alloc_and_copyin failed\n"); 1234 return (err); 1235 } 1236 1237 /* 1238 * Clear out undesirable command flags 1239 */ 1240 flags = (uscmd->uscsi_flags & ~(USCSI_NOINTR | USCSI_NOPARITY | 1241 USCSI_OTAG | USCSI_HTAG | USCSI_HEAD)); 1242 if (flags != uscmd->uscsi_flags) { 1243 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: cleared " 1244 "unsafe uscsi_flags 0x%x", uscmd->uscsi_flags & ~flags); 1245 uscmd->uscsi_flags = flags; 1246 } 1247 1248 if (uscmd->uscsi_cdb != NULL) { 1249 sgen_dump_cdb(sg_state, "sgen_uscsi_cmd: ", 1250 (union scsi_cdb *)uscmd->uscsi_cdb, uscmd->uscsi_cdblen); 1251 } 1252 1253 /* 1254 * Stash the sense buffer into sgen_rqs_sen for convenience. 1255 */ 1256 sg_state->sgen_rqs_sen = uscmd->uscsi_rqbuf; 1257 1258 bp = sg_state->sgen_cmdbuf; 1259 bp->av_back = NULL; 1260 bp->av_forw = NULL; 1261 bp->b_private = (struct buf *)uscmd; 1262 uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE; 1263 1264 err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, sgen_start, bp, NULL); 1265 1266 if (sg_state->sgen_cmdpkt != NULL) { 1267 uscmd->uscsi_status = SCBP_C(sg_state->sgen_cmdpkt); 1268 } else { 1269 uscmd->uscsi_status = 0; 1270 } 1271 1272 sgen_log(sg_state, SGEN_DIAG3, "sgen_uscsi_cmd: awake from waiting " 1273 "for command. Status is 0x%x", uscmd->uscsi_status); 1274 1275 if (uscmd->uscsi_rqbuf != NULL) { 1276 int rqlen = uscmd->uscsi_rqlen - uscmd->uscsi_rqresid; 1277 sgen_dump_sense(sg_state, rqlen, 1278 (uchar_t *)uscmd->uscsi_rqbuf); 1279 } 1280 1281 (void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd); 1282 1283 if (sg_state->sgen_cmdpkt != NULL) { 1284 scsi_destroy_pkt(sg_state->sgen_cmdpkt); 1285 sg_state->sgen_cmdpkt = NULL; 1286 } 1287 1288 /* 1289 * After this point, we can't touch per-target state. 1290 */ 1291 sgen_rele_cmdbuf(sg_state); 1292 1293 sgen_log(sg_state, SGEN_DIAG2, "done sgen_uscsi_cmd()"); 1294 1295 return (err); 1296 } 1297 1298 /* 1299 * sgen_hold_cmdbuf() 1300 * Acquire a lock on the command buffer for the given target. Returns 1301 * non-zero if interrupted. 1302 */ 1303 static int 1304 sgen_hold_cmdbuf(sgen_state_t *sg_state) 1305 { 1306 mutex_enter(&sg_state->sgen_mutex); 1307 while (SGEN_IS_BUSY(sg_state)) { 1308 if (!cv_wait_sig(&sg_state->sgen_cmdbuf_cv, 1309 &sg_state->sgen_mutex)) { 1310 mutex_exit(&sg_state->sgen_mutex); 1311 return (-1); 1312 } 1313 } 1314 SGEN_SET_BUSY(sg_state); 1315 mutex_exit(&sg_state->sgen_mutex); 1316 return (0); 1317 } 1318 1319 /* 1320 * sgen_rele_cmdbuf() 1321 * release the command buffer for a particular target. 1322 */ 1323 static void 1324 sgen_rele_cmdbuf(sgen_state_t *sg_state) 1325 { 1326 mutex_enter(&sg_state->sgen_mutex); 1327 SGEN_CLR_BUSY(sg_state); 1328 cv_signal(&sg_state->sgen_cmdbuf_cv); 1329 mutex_exit(&sg_state->sgen_mutex); 1330 } 1331 1332 /* 1333 * sgen_start() 1334 * Transport a uscsi command; this is invoked by physio() or directly 1335 * by sgen_uscsi_cmd(). 1336 */ 1337 static int 1338 sgen_start(struct buf *bp) 1339 { 1340 sgen_state_t *sg_state; 1341 dev_t dev = bp->b_edev; 1342 int trans_err; 1343 1344 if ((sg_state = ddi_get_soft_state(sgen_soft_state, 1345 getminor(dev))) == NULL) { 1346 bp->b_resid = bp->b_bcount; 1347 bioerror(bp, ENXIO); 1348 biodone(bp); 1349 return (ENXIO); 1350 } 1351 1352 /* 1353 * Sanity checks - command should not be complete, no packet should 1354 * be allocated, and there ought to be a uscsi cmd in b_private 1355 */ 1356 ASSERT(bp == sg_state->sgen_cmdbuf && sg_state->sgen_cmdpkt == NULL); 1357 ASSERT((bp->b_flags & B_DONE) == 0); 1358 ASSERT(bp->b_private); 1359 if (sgen_make_uscsi_cmd(sg_state, bp) != 0) { 1360 bp->b_resid = bp->b_bcount; 1361 bioerror(bp, EFAULT); 1362 biodone(bp); 1363 return (EFAULT); 1364 } 1365 1366 ASSERT(sg_state->sgen_cmdpkt != NULL); 1367 1368 /* 1369 * Clear out the residual and error fields 1370 */ 1371 bp->b_resid = 0; 1372 bp->b_error = 0; 1373 1374 trans_err = sgen_scsi_transport(sg_state->sgen_cmdpkt); 1375 switch (trans_err) { 1376 case TRAN_ACCEPT: 1377 break; 1378 case TRAN_BUSY: 1379 sgen_log(sg_state, SGEN_DIAG2, 1380 "sgen_start: scsi_transport() returned TRAN_BUSY"); 1381 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state, 1382 SGEN_BSY_TIMEOUT); 1383 break; 1384 default: 1385 /* 1386 * Indicate there has been an I/O transfer error. 1387 * Be done with the command. 1388 */ 1389 mutex_enter(&sg_state->sgen_mutex); 1390 SGEN_DO_ERRSTATS(sg_state, sgen_trans_err); 1391 mutex_exit(&sg_state->sgen_mutex); 1392 sgen_log(sg_state, SGEN_DIAG2, "sgen_start: scsi_transport() " 1393 "returned %d", trans_err); 1394 bioerror(bp, EIO); 1395 biodone(bp); 1396 return (EIO); 1397 } 1398 sgen_log(sg_state, SGEN_DIAG2, "sgen_start: b_flags 0x%x", bp->b_flags); 1399 return (0); 1400 } 1401 1402 /* 1403 * sgen_scsi_transport() 1404 * a simple scsi_transport() wrapper which can be configured to inject 1405 * sporadic errors for testing. 1406 */ 1407 static int 1408 sgen_scsi_transport(struct scsi_pkt *pkt) 1409 { 1410 int trans_err; 1411 static int cnt = 0; 1412 sgen_state_t *sg_state = pkt->pkt_private; 1413 1414 if (sgen_sporadic_failures == 0) { 1415 return (scsi_transport(pkt)); 1416 } 1417 1418 cnt = (cnt * 2416 + 374441) % 1771875; /* borrowed from kmem.c */ 1419 if (cnt % 40 == 1) { 1420 sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: " 1421 "injecting sporadic BUSY"); 1422 trans_err = TRAN_BUSY; 1423 } else if (cnt % 40 == 2) { 1424 sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: " 1425 "injecting sporadic BADPKT"); 1426 trans_err = TRAN_BADPKT; 1427 } else { 1428 /* 1429 * Most of the time we take the normal path 1430 */ 1431 trans_err = scsi_transport(pkt); 1432 } 1433 return (trans_err); 1434 } 1435 1436 /* 1437 * sgen_make_uscsi_cmd() 1438 * Initialize a SCSI packet usable for USCSI. 1439 */ 1440 static int 1441 sgen_make_uscsi_cmd(sgen_state_t *sg_state, struct buf *bp) 1442 { 1443 struct scsi_pkt *pkt; 1444 struct uscsi_cmd *ucmd; 1445 int stat_size = 1; 1446 int flags = 0; 1447 1448 ASSERT(bp); 1449 1450 sgen_log(sg_state, SGEN_DIAG2, "in sgen_make_uscsi_cmd()"); 1451 1452 ucmd = (struct uscsi_cmd *)bp->b_private; 1453 1454 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1455 if (ucmd->uscsi_rqlen > SENSE_LENGTH) { 1456 stat_size = (int)(ucmd->uscsi_rqlen) + 1457 sizeof (struct scsi_arq_status) - 1458 sizeof (struct scsi_extended_sense); 1459 flags = PKT_XARQ; 1460 } else { 1461 stat_size = sizeof (struct scsi_arq_status); 1462 } 1463 } 1464 1465 sgen_log(sg_state, SGEN_DIAG3, "sgen_make_uscsi_cmd: b_bcount = %ld", 1466 bp->b_bcount); 1467 pkt = scsi_init_pkt(&sg_state->sgen_scsiaddr, 1468 NULL, /* in_pkt - null so it'll be alloc'd */ 1469 bp->b_bcount ? bp : NULL, /* buf structure for data xfer */ 1470 ucmd->uscsi_cdblen, /* cmdlen */ 1471 stat_size, /* statuslen */ 1472 0, /* privatelen */ 1473 flags, /* flags */ 1474 SLEEP_FUNC, /* callback */ 1475 (caddr_t)sg_state); /* callback_arg */ 1476 1477 if (pkt == NULL) { 1478 sgen_log(sg_state, SGEN_DIAG2, "failed sgen_make_uscsi_cmd()"); 1479 return (-1); 1480 } 1481 1482 pkt->pkt_comp = sgen_callback; 1483 pkt->pkt_private = sg_state; 1484 sg_state->sgen_cmdpkt = pkt; 1485 1486 /* 1487 * We *don't* call scsi_setup_cdb here, as is customary, since the 1488 * user could specify a command from one group, but pass cdblen 1489 * as something totally different. If cdblen is smaller than expected, 1490 * this results in scsi_setup_cdb writing past the end of the cdb. 1491 */ 1492 bcopy(ucmd->uscsi_cdb, pkt->pkt_cdbp, ucmd->uscsi_cdblen); 1493 if (ucmd->uscsi_cdblen >= CDB_GROUP0) { 1494 FILL_SCSI1_LUN(sg_state->sgen_scsidev, pkt); 1495 } 1496 1497 if (ucmd->uscsi_timeout > 0) 1498 pkt->pkt_time = ucmd->uscsi_timeout; 1499 else 1500 pkt->pkt_time = SGEN_IO_TIME; 1501 1502 /* 1503 * Set packet options 1504 */ 1505 if (ucmd->uscsi_flags & USCSI_SILENT) 1506 pkt->pkt_flags |= FLAG_SILENT; 1507 if (ucmd->uscsi_flags & USCSI_ISOLATE) 1508 pkt->pkt_flags |= FLAG_ISOLATE; 1509 if (ucmd->uscsi_flags & USCSI_DIAGNOSE) 1510 pkt->pkt_flags |= FLAG_DIAGNOSE; 1511 if (ucmd->uscsi_flags & USCSI_RENEGOT) { 1512 pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC; 1513 } 1514 1515 /* Transfer uscsi information to scsi_pkt */ 1516 (void) scsi_uscsi_pktinit(ucmd, pkt); 1517 1518 sgen_log(sg_state, SGEN_DIAG2, "done sgen_make_uscsi_cmd()"); 1519 return (0); 1520 } 1521 1522 1523 /* 1524 * sgen_restart() 1525 * sgen_restart() is called after a timeout, when a command has been 1526 * postponed due to a TRAN_BUSY response from the HBA. 1527 */ 1528 static void 1529 sgen_restart(void *arg) 1530 { 1531 sgen_state_t *sg_state = (sgen_state_t *)arg; 1532 struct scsi_pkt *pkt; 1533 struct buf *bp; 1534 1535 sgen_log(sg_state, SGEN_DIAG2, "in sgen_restart()"); 1536 1537 bp = sg_state->sgen_cmdbuf; 1538 pkt = sg_state->sgen_cmdpkt; 1539 ASSERT(bp && pkt); 1540 1541 SGEN_DO_ERRSTATS(sg_state, sgen_restart); 1542 1543 /* 1544 * If the packet is marked with the sensing flag, sgen is off running 1545 * a request sense, and *that packet* is what needs to be restarted. 1546 */ 1547 if (pkt->pkt_flags & FLAG_SENSING) { 1548 sgen_log(sg_state, SGEN_DIAG3, 1549 "sgen_restart: restarting REQUEST SENSE"); 1550 pkt = sg_state->sgen_rqspkt; 1551 } 1552 1553 if (sgen_scsi_transport(pkt) != TRAN_ACCEPT) { 1554 bp->b_resid = bp->b_bcount; 1555 bioerror(bp, EIO); 1556 biodone(bp); 1557 } 1558 } 1559 1560 /* 1561 * sgen_callback() 1562 * Command completion processing 1563 * 1564 * sgen's completion processing is very pessimistic-- it does not retry 1565 * failed commands; instead, it allows the user application to make 1566 * decisions about what has gone wrong. 1567 */ 1568 static void 1569 sgen_callback(struct scsi_pkt *pkt) 1570 { 1571 sgen_state_t *sg_state; 1572 struct uscsi_cmd *ucmd; 1573 struct buf *bp; 1574 int action; 1575 1576 sg_state = pkt->pkt_private; 1577 /* 1578 * bp should always be the command buffer regardless of whether 1579 * this is a command completion or a request-sense completion. 1580 * This is because there is no need to biodone() the sense buf 1581 * when it completes-- we want to biodone() the actual command buffer! 1582 */ 1583 bp = sg_state->sgen_cmdbuf; 1584 if (pkt->pkt_flags & FLAG_SENSING) { 1585 ASSERT(pkt == sg_state->sgen_rqspkt); 1586 sgen_log(sg_state, SGEN_DIAG2, 1587 "in sgen_callback() (SENSE completion callback)"); 1588 } else { 1589 ASSERT(pkt == sg_state->sgen_cmdpkt); 1590 sgen_log(sg_state, SGEN_DIAG2, 1591 "in sgen_callback() (command completion callback)"); 1592 } 1593 ucmd = (struct uscsi_cmd *)bp->b_private; 1594 1595 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: reason=0x%x resid=%ld " 1596 "state=0x%x", pkt->pkt_reason, pkt->pkt_resid, pkt->pkt_state); 1597 1598 /* Transfer scsi_pkt information to uscsi */ 1599 (void) scsi_uscsi_pktfini(pkt, ucmd); 1600 1601 if (pkt->pkt_reason != CMD_CMPLT) { 1602 /* 1603 * The command did not complete. 1604 */ 1605 sgen_log(sg_state, SGEN_DIAG3, 1606 "sgen_callback: command did not complete"); 1607 action = sgen_handle_incomplete(sg_state, pkt); 1608 } else if (sg_state->sgen_arq_enabled && 1609 (pkt->pkt_state & STATE_ARQ_DONE)) { 1610 /* 1611 * The auto-rqsense happened, and the packet has a filled-in 1612 * scsi_arq_status structure, pointed to by pkt_scbp. 1613 */ 1614 sgen_log(sg_state, SGEN_DIAG3, 1615 "sgen_callback: received auto-requested sense"); 1616 action = sgen_handle_autosense(sg_state, pkt); 1617 ASSERT(action != FETCH_SENSE); 1618 } else if (pkt->pkt_flags & FLAG_SENSING) { 1619 /* 1620 * sgen was running a REQUEST SENSE. Decode the sense data and 1621 * decide what to do next. 1622 * 1623 * Clear FLAG_SENSING on the original packet for completeness. 1624 */ 1625 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: received sense"); 1626 sg_state->sgen_cmdpkt->pkt_flags &= ~FLAG_SENSING; 1627 action = sgen_handle_sense(sg_state); 1628 ASSERT(action != FETCH_SENSE); 1629 } else { 1630 /* 1631 * Command completed and we're not getting sense. Check for 1632 * errors and decide what to do next. 1633 */ 1634 sgen_log(sg_state, SGEN_DIAG3, 1635 "sgen_callback: command appears complete"); 1636 action = sgen_check_error(sg_state, bp); 1637 } 1638 1639 switch (action) { 1640 case FETCH_SENSE: 1641 /* 1642 * If there is sense to fetch, break out to prevent biodone'ing 1643 * until the sense fetch is complete. 1644 */ 1645 if (sgen_initiate_sense(sg_state, 1646 scsi_pkt_allocated_correctly(pkt) ? 1647 pkt->pkt_path_instance : 0) == 0) 1648 break; 1649 /*FALLTHROUGH*/ 1650 case COMMAND_DONE_ERROR: 1651 bp->b_resid = bp->b_bcount; 1652 bioerror(bp, EIO); 1653 /*FALLTHROUGH*/ 1654 case COMMAND_DONE: 1655 biodone(bp); 1656 break; 1657 default: 1658 ASSERT(0); 1659 break; 1660 } 1661 1662 sgen_log(sg_state, SGEN_DIAG2, "done sgen_callback()"); 1663 } 1664 1665 /* 1666 * sgen_initiate_sense() 1667 * Send the sgen_rqspkt to the target, thereby requesting sense data. 1668 */ 1669 static int 1670 sgen_initiate_sense(sgen_state_t *sg_state, int path_instance) 1671 { 1672 /* use same path_instance as command */ 1673 if (scsi_pkt_allocated_correctly(sg_state->sgen_rqspkt)) 1674 sg_state->sgen_rqspkt->pkt_path_instance = path_instance; 1675 1676 switch (sgen_scsi_transport(sg_state->sgen_rqspkt)) { 1677 case TRAN_ACCEPT: 1678 sgen_log(sg_state, SGEN_DIAG3, "sgen_initiate_sense: " 1679 "sense fetch transport accepted."); 1680 return (0); 1681 case TRAN_BUSY: 1682 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: " 1683 "sense fetch transport busy, setting timeout."); 1684 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state, 1685 SGEN_BSY_TIMEOUT); 1686 return (0); 1687 default: 1688 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: " 1689 "sense fetch transport failed or busy."); 1690 return (-1); 1691 } 1692 } 1693 1694 /* 1695 * sgen_handle_incomplete() 1696 * sgen is pessimistic, but also careful-- it doesn't try to retry 1697 * incomplete commands, but it also doesn't go resetting devices; 1698 * it is hard to tell if the device will be tolerant of that sort 1699 * of prodding. 1700 * 1701 * This routine has been left as a guide for the future--- the 1702 * current administration's hands-off policy may need modification. 1703 */ 1704 /*ARGSUSED*/ 1705 static int 1706 sgen_handle_incomplete(sgen_state_t *sg_state, struct scsi_pkt *pkt) 1707 { 1708 SGEN_DO_ERRSTATS(sg_state, sgen_incmp_err); 1709 return (COMMAND_DONE_ERROR); 1710 } 1711 1712 /* 1713 * sgen_handle_autosense() 1714 * Deal with SENSE data acquired automatically via the auto-request-sense 1715 * facility. 1716 * 1717 * Sgen takes a pessimistic view of things-- it doesn't retry commands, 1718 * and unless the device recovered from the problem, this routine returns 1719 * COMMAND_DONE_ERROR. 1720 */ 1721 static int 1722 sgen_handle_autosense(sgen_state_t *sg_state, struct scsi_pkt *pkt) 1723 { 1724 struct scsi_arq_status *arqstat; 1725 struct uscsi_cmd *ucmd = 1726 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1727 int amt; 1728 1729 arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp); 1730 1731 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_rcv); 1732 1733 if (arqstat->sts_rqpkt_reason != CMD_CMPLT) { 1734 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: ARQ" 1735 "failed to complete."); 1736 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1737 return (COMMAND_DONE_ERROR); 1738 } 1739 1740 if (pkt->pkt_state & STATE_XARQ_DONE) { 1741 amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1742 } else { 1743 if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) { 1744 amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1745 } else { 1746 amt = SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1747 } 1748 } 1749 1750 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1751 ucmd->uscsi_rqstatus = *((char *)&arqstat->sts_rqpkt_status); 1752 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen); 1753 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen; 1754 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen); 1755 bcopy(&(arqstat->sts_sensedata), sg_state->sgen_rqs_sen, rqlen); 1756 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_autosense: " 1757 "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n", 1758 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid); 1759 } 1760 1761 if (arqstat->sts_rqpkt_status.sts_chk) { 1762 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got " 1763 "check condition on auto request sense!"); 1764 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1765 return (COMMAND_DONE_ERROR); 1766 } 1767 1768 if (((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0) || 1769 (amt == 0)) { 1770 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got " 1771 "auto-sense, but it contains no data!"); 1772 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1773 return (COMMAND_DONE_ERROR); 1774 } 1775 1776 /* 1777 * Stuff the sense data pointer into sgen_sense for later retrieval 1778 */ 1779 sg_state->sgen_sense = &arqstat->sts_sensedata; 1780 1781 /* 1782 * Now, check to see whether we got enough sense data to make any 1783 * sense out if it (heh-heh). 1784 */ 1785 if (amt < SUN_MIN_SENSE_LENGTH) { 1786 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: not " 1787 "enough auto sense data"); 1788 return (COMMAND_DONE_ERROR); 1789 } 1790 1791 switch (arqstat->sts_sensedata.es_key) { 1792 case KEY_RECOVERABLE_ERROR: 1793 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err); 1794 break; 1795 case KEY_NO_SENSE: 1796 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err); 1797 break; 1798 default: 1799 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err); 1800 break; 1801 } 1802 1803 return (COMMAND_DONE); 1804 } 1805 1806 /* 1807 * sgen_handle_sense() 1808 * Examine sense data that was manually fetched from the target. 1809 */ 1810 static int 1811 sgen_handle_sense(sgen_state_t *sg_state) 1812 { 1813 struct scsi_pkt *rqpkt = sg_state->sgen_rqspkt; 1814 struct scsi_status *rqstatus = (struct scsi_status *)rqpkt->pkt_scbp; 1815 struct uscsi_cmd *ucmd = 1816 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1817 int amt; 1818 1819 SGEN_DO_ERRSTATS(sg_state, sgen_sense_rcv); 1820 1821 amt = MAX_SENSE_LENGTH - rqpkt->pkt_resid; 1822 1823 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1824 ucmd->uscsi_rqstatus = *((char *)rqstatus); 1825 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen); 1826 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen; 1827 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen); 1828 bcopy(sg_state->sgen_sense, sg_state->sgen_rqs_sen, rqlen); 1829 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_sense: " 1830 "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n", 1831 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid); 1832 } 1833 1834 if (rqstatus->sts_busy) { 1835 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got busy " 1836 "on request sense"); 1837 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1838 return (COMMAND_DONE_ERROR); 1839 } 1840 1841 if (rqstatus->sts_chk) { 1842 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got check " 1843 "condition on request sense!"); 1844 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1845 return (COMMAND_DONE_ERROR); 1846 } 1847 1848 if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) { 1849 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got " 1850 "sense, but it contains no data"); 1851 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1852 return (COMMAND_DONE_ERROR); 1853 } 1854 1855 /* 1856 * Now, check to see whether we got enough sense data to make any 1857 * sense out if it (heh-heh). 1858 */ 1859 if (amt < SUN_MIN_SENSE_LENGTH) { 1860 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: not " 1861 "enough sense data"); 1862 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1863 return (COMMAND_DONE_ERROR); 1864 } 1865 1866 /* 1867 * Decode the sense data-- this was deposited here for us by the 1868 * setup in sgen_do_attach(). (note that sgen_sense is an alias for 1869 * the sd_sense field in the scsi_device). 1870 */ 1871 sgen_log(sg_state, SGEN_DIAG1, "Sense key is %s [0x%x]", 1872 scsi_sname(sg_state->sgen_sense->es_key), 1873 sg_state->sgen_sense->es_key); 1874 switch (sg_state->sgen_sense->es_key) { 1875 case KEY_RECOVERABLE_ERROR: 1876 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err); 1877 break; 1878 case KEY_NO_SENSE: 1879 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err); 1880 break; 1881 default: 1882 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err); 1883 break; 1884 } 1885 1886 return (COMMAND_DONE); 1887 } 1888 1889 /* 1890 * sgen_check_error() 1891 * examine the command packet for abnormal completion. 1892 * 1893 * sgen_check_error should only be called at the completion of the 1894 * command packet. 1895 */ 1896 static int 1897 sgen_check_error(sgen_state_t *sg_state, struct buf *bp) 1898 { 1899 struct scsi_pkt *pkt = sg_state->sgen_cmdpkt; 1900 struct scsi_status *status = (struct scsi_status *)pkt->pkt_scbp; 1901 struct uscsi_cmd *ucmd = 1902 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1903 1904 if (status->sts_busy) { 1905 sgen_log(sg_state, SGEN_DIAG1, 1906 "sgen_check_error: target is busy"); 1907 return (COMMAND_DONE_ERROR); 1908 } 1909 1910 /* 1911 * pkt_resid will reflect, at this point, a residual of how many bytes 1912 * were not transferred; a non-zero pkt_resid is an error. 1913 */ 1914 if (pkt->pkt_resid) { 1915 bp->b_resid += pkt->pkt_resid; 1916 } 1917 1918 if (status->sts_chk) { 1919 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1920 if (sg_state->sgen_arq_enabled) { 1921 sgen_log(sg_state, SGEN_DIAG1, 1922 "sgen_check_error: strange: target " 1923 "indicates CHECK CONDITION with auto-sense " 1924 "enabled."); 1925 } 1926 sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: " 1927 "target ready for sense fetch"); 1928 return (FETCH_SENSE); 1929 } else { 1930 sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: " 1931 "target indicates CHECK CONDITION"); 1932 } 1933 } 1934 1935 return (COMMAND_DONE); 1936 } 1937 1938 /* 1939 * sgen_tur() 1940 * test if a target is ready to operate by sending it a TUR command. 1941 */ 1942 static int 1943 sgen_tur(dev_t dev) 1944 { 1945 char cmdblk[CDB_GROUP0]; 1946 struct uscsi_cmd scmd; 1947 1948 bzero(&scmd, sizeof (scmd)); 1949 scmd.uscsi_bufaddr = 0; 1950 scmd.uscsi_buflen = 0; 1951 bzero(cmdblk, CDB_GROUP0); 1952 cmdblk[0] = (char)SCMD_TEST_UNIT_READY; 1953 scmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_WRITE; 1954 scmd.uscsi_cdb = cmdblk; 1955 scmd.uscsi_cdblen = CDB_GROUP0; 1956 1957 return (sgen_uscsi_cmd(dev, &scmd, FKIOCTL)); 1958 } 1959 1960 /* 1961 * sgen_diag_ok() 1962 * given an sg_state and a desired diagnostic level, return true if 1963 * it is acceptable to output a message. 1964 */ 1965 /*ARGSUSED*/ 1966 static int 1967 sgen_diag_ok(sgen_state_t *sg_state, int level) 1968 { 1969 int diag_lvl; 1970 1971 switch (level) { 1972 case CE_WARN: 1973 case CE_NOTE: 1974 case CE_CONT: 1975 case CE_PANIC: 1976 return (1); 1977 case SGEN_DIAG1: 1978 case SGEN_DIAG2: 1979 case SGEN_DIAG3: 1980 if (sg_state) { 1981 /* 1982 * Check to see if user overrode the diagnostics level 1983 * for this instance (either via SGEN_IOC_DIAG or via 1984 * .conf file). If not, fall back to the global diag 1985 * level. 1986 */ 1987 if (sg_state->sgen_diag != -1) 1988 diag_lvl = sg_state->sgen_diag; 1989 else 1990 diag_lvl = sgen_diag; 1991 } else { 1992 diag_lvl = sgen_diag; 1993 } 1994 if (((diag_lvl << 8) | CE_CONT) >= level) { 1995 return (1); 1996 } else { 1997 return (0); 1998 } 1999 default: 2000 return (1); 2001 } 2002 } 2003 2004 /*PRINTFLIKE3*/ 2005 static void 2006 sgen_log(sgen_state_t *sg_state, int level, const char *fmt, ...) 2007 { 2008 va_list ap; 2009 char buf[256]; 2010 2011 if (!sgen_diag_ok(sg_state, level)) 2012 return; 2013 2014 va_start(ap, fmt); 2015 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 2016 va_end(ap); 2017 2018 switch (level) { 2019 case CE_NOTE: 2020 case CE_CONT: 2021 case CE_WARN: 2022 case CE_PANIC: 2023 if (sg_state == (sgen_state_t *)NULL) { 2024 cmn_err(level, "%s", buf); 2025 } else { 2026 scsi_log(sg_state->sgen_devinfo, sgen_label, level, 2027 "%s", buf); 2028 } 2029 break; 2030 case SGEN_DIAG1: 2031 case SGEN_DIAG2: 2032 case SGEN_DIAG3: 2033 default: 2034 if (sg_state == (sgen_state_t *)NULL) { 2035 scsi_log(NULL, sgen_label, CE_CONT, "%s", buf); 2036 } else { 2037 scsi_log(sg_state->sgen_devinfo, sgen_label, CE_CONT, 2038 "%s", buf); 2039 } 2040 } 2041 } 2042 2043 /* 2044 * sgen_dump_cdb() 2045 * dump out the contents of a cdb. Take care that 'label' is not too 2046 * large, or 'buf' could overflow. 2047 */ 2048 static void 2049 sgen_dump_cdb(sgen_state_t *sg_state, const char *label, 2050 union scsi_cdb *cdb, int cdblen) 2051 { 2052 static char hex[] = "0123456789abcdef"; 2053 char *buf, *p; 2054 size_t nbytes; 2055 int i; 2056 uchar_t *cdbp = (uchar_t *)cdb; 2057 2058 /* 2059 * fastpath-- if we're not able to print out, don't do all of this 2060 * extra work. 2061 */ 2062 if (!sgen_diag_ok(sg_state, SGEN_DIAG3)) 2063 return; 2064 2065 /* 2066 * 3 characters for each byte (because of the ' '), plus the size of 2067 * the label, plus the trailing ']' and the null character. 2068 */ 2069 nbytes = 3 * cdblen + strlen(label) + strlen(" CDB = [") + 2; 2070 buf = kmem_alloc(nbytes, KM_SLEEP); 2071 (void) sprintf(buf, "%s CDB = [", label); 2072 p = &buf[strlen(buf)]; 2073 for (i = 0; i < cdblen; i++, cdbp++) { 2074 if (i > 0) 2075 *p++ = ' '; 2076 *p++ = hex[(*cdbp >> 4) & 0x0f]; 2077 *p++ = hex[*cdbp & 0x0f]; 2078 } 2079 *p++ = ']'; 2080 *p = 0; 2081 sgen_log(sg_state, SGEN_DIAG3, buf); 2082 kmem_free(buf, nbytes); 2083 } 2084 2085 static void 2086 sgen_dump_sense(sgen_state_t *sg_state, size_t rqlen, uchar_t *rqbuf) 2087 { 2088 static char hex[] = "0123456789abcdef"; 2089 char *buf, *p; 2090 size_t nbytes; 2091 int i; 2092 2093 /* 2094 * fastpath-- if we're not able to print out, don't do all of this 2095 * extra work. 2096 */ 2097 if (!sgen_diag_ok(sg_state, SGEN_DIAG3)) 2098 return; 2099 2100 /* 2101 * 3 characters for each byte (because of the ' '), plus the size of 2102 * the label, plus the trailing ']' and the null character. 2103 */ 2104 nbytes = 3 * rqlen + strlen(" SENSE = [") + 2; 2105 buf = kmem_alloc(nbytes, KM_SLEEP); 2106 (void) sprintf(buf, "SENSE = ["); 2107 p = &buf[strlen(buf)]; 2108 for (i = 0; i < rqlen; i++, rqbuf++) { 2109 if (i > 0) 2110 *p++ = ' '; 2111 *p++ = hex[(*rqbuf >> 4) & 0x0f]; 2112 *p++ = hex[*rqbuf & 0x0f]; 2113 } 2114 *p++ = ']'; 2115 *p = 0; 2116 sgen_log(sg_state, SGEN_DIAG3, buf); 2117 kmem_free(buf, nbytes); 2118 } 2119