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