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 2007 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 void 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 *); 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 occurence 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 if (SGEN_IS_OPEN(sg_state)) { 1064 mutex_exit(&sg_state->sgen_mutex); 1065 return (EBUSY); 1066 } 1067 1068 SGEN_SET_OPEN(sg_state); 1069 1070 /* 1071 * At this point, sgen cannot have the suspended bit set, 1072 * since each target is exclusive-access; when the previous 1073 * close occurred, it cleared the flag. 1074 */ 1075 ASSERT(!SGEN_IS_SUSP(sg_state)); 1076 mutex_exit(&sg_state->sgen_mutex); 1077 1078 return (0); 1079 } 1080 1081 /* 1082 * sgen_close() 1083 * close(9e) entrypoint. 1084 */ 1085 /*ARGSUSED1*/ 1086 static int 1087 sgen_close(dev_t dev, int flag, int otyp, cred_t *cred_p) 1088 { 1089 sgen_state_t *sg_state; 1090 int instance; 1091 1092 instance = getminor(dev); 1093 1094 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL) 1095 return (ENXIO); 1096 1097 sgen_log(sg_state, SGEN_DIAG2, "in sgen_close(): instance = %d", 1098 instance); 1099 1100 mutex_enter(&sg_state->sgen_mutex); 1101 SGEN_CLR_OPEN(sg_state); 1102 SGEN_CLR_SUSP(sg_state); /* closing clears the 'I was suspended' bit */ 1103 mutex_exit(&sg_state->sgen_mutex); 1104 1105 sgen_log(sg_state, SGEN_DIAG2, "done sgen_close()"); 1106 1107 return (0); 1108 } 1109 1110 /* 1111 * sgen_ioctl() 1112 * sgen supports the USCSI(7I) ioctl interface. 1113 */ 1114 /*ARGSUSED4*/ 1115 static int 1116 sgen_ioctl(dev_t dev, 1117 int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p) 1118 { 1119 int retval = 0; 1120 sgen_state_t *sg_state; 1121 int instance; 1122 1123 instance = getminor(dev); 1124 1125 if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL) 1126 return (ENXIO); 1127 1128 sgen_log(sg_state, SGEN_DIAG2, "in sgen_ioctl(): instance = %d", 1129 instance); 1130 1131 /* 1132 * If the driver has been suspended since the last open, fail all 1133 * subsequent IO's so that the userland consumer reinitializes state. 1134 */ 1135 mutex_enter(&sg_state->sgen_mutex); 1136 if (SGEN_IS_SUSP(sg_state)) { 1137 mutex_exit(&sg_state->sgen_mutex); 1138 sgen_log(sg_state, SGEN_DIAG1, "sgen_ioctl: returning EIO: " 1139 "driver instance %d was previously suspended", instance); 1140 return (EIO); 1141 } 1142 mutex_exit(&sg_state->sgen_mutex); 1143 1144 switch (cmd) { 1145 case SGEN_IOC_DIAG: { 1146 if (arg > 3) { 1147 arg = 0; 1148 } 1149 sg_state->sgen_diag = (int)arg; 1150 retval = 0; 1151 break; 1152 } 1153 1154 case SGEN_IOC_READY: { 1155 if (sgen_tur(dev) != 0) { 1156 retval = EIO; 1157 } else { 1158 retval = 0; 1159 } 1160 break; 1161 } 1162 1163 case USCSICMD: 1164 retval = sgen_uscsi_cmd(dev, (struct uscsi_cmd *)arg, flag); 1165 break; 1166 1167 default: 1168 retval = ENOTTY; 1169 } 1170 1171 sgen_log(sg_state, SGEN_DIAG2, "done sgen_ioctl(), returning %d", 1172 retval); 1173 1174 return (retval); 1175 } 1176 1177 /* 1178 * sgen_uscsi_cmd() 1179 * Setup, configuration and teardown for a uscsi(7I) command 1180 */ 1181 /*ARGSUSED*/ 1182 static int 1183 sgen_uscsi_cmd(dev_t dev, struct uscsi_cmd *ucmd, int flag) 1184 { 1185 struct uscsi_cmd *uscmd; 1186 struct buf *bp; 1187 sgen_state_t *sg_state; 1188 enum uio_seg uioseg; 1189 int cmdbufhold = 0; 1190 int instance; 1191 int flags; 1192 int err; 1193 1194 instance = getminor(dev); 1195 1196 sg_state = ddi_get_soft_state(sgen_soft_state, instance); 1197 ASSERT(sg_state); 1198 1199 sgen_log(sg_state, SGEN_DIAG2, "in sgen_uscsi_cmd(): instance = %d", 1200 instance); 1201 1202 err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag, 1203 &sg_state->sgen_scsiaddr, &uscmd); 1204 if (err != 0) { 1205 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: " 1206 "scsi_uscsi_alloc_and_copyin failed\n"); 1207 return (err); 1208 } 1209 1210 /* 1211 * Clear out undesirable command flags 1212 */ 1213 flags = (uscmd->uscsi_flags & ~(USCSI_NOINTR | USCSI_NOPARITY | 1214 USCSI_OTAG | USCSI_HTAG | USCSI_HEAD)); 1215 if (flags != uscmd->uscsi_flags) { 1216 sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: cleared " 1217 "unsafe uscsi_flags 0x%x", uscmd->uscsi_flags & ~flags); 1218 uscmd->uscsi_flags = flags; 1219 } 1220 1221 /* 1222 * At this point, we start affecting state relevant to the target, 1223 * so access needs to be serialized. 1224 */ 1225 sgen_hold_cmdbuf(sg_state); /* lock command buf for this target */ 1226 cmdbufhold = 1; 1227 1228 if (uscmd->uscsi_cdb != NULL) { 1229 sgen_dump_cdb(sg_state, "sgen_uscsi_cmd: ", 1230 (union scsi_cdb *)uscmd->uscsi_cdb, uscmd->uscsi_cdblen); 1231 } 1232 1233 /* 1234 * Stash the sense buffer into sgen_rqs_sen for convenience. 1235 */ 1236 sg_state->sgen_rqs_sen = uscmd->uscsi_rqbuf; 1237 1238 bp = sg_state->sgen_cmdbuf; 1239 bp->av_back = NULL; 1240 bp->av_forw = NULL; 1241 bp->b_private = (struct buf *)uscmd; 1242 uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE; 1243 1244 err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, sgen_start, bp, NULL); 1245 1246 if (sg_state->sgen_cmdpkt != NULL) { 1247 uscmd->uscsi_status = SCBP_C(sg_state->sgen_cmdpkt); 1248 } else { 1249 uscmd->uscsi_status = 0; 1250 } 1251 1252 sgen_log(sg_state, SGEN_DIAG3, "sgen_uscsi_cmd: awake from waiting " 1253 "for command. Status is 0x%x", uscmd->uscsi_status); 1254 1255 if (uscmd->uscsi_rqbuf != NULL) { 1256 int rqlen = uscmd->uscsi_rqlen - uscmd->uscsi_rqresid; 1257 sgen_dump_sense(sg_state, rqlen, 1258 (uchar_t *)uscmd->uscsi_rqbuf); 1259 } 1260 1261 (void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd); 1262 1263 if (sg_state->sgen_cmdpkt != NULL) { 1264 scsi_destroy_pkt(sg_state->sgen_cmdpkt); 1265 sg_state->sgen_cmdpkt = NULL; 1266 } 1267 1268 /* 1269 * After this point, we can't touch per-target state. 1270 */ 1271 if (cmdbufhold) { 1272 sgen_rele_cmdbuf(sg_state); 1273 } 1274 1275 sgen_log(sg_state, SGEN_DIAG2, "done sgen_uscsi_cmd()"); 1276 1277 return (err); 1278 } 1279 1280 /* 1281 * sgen_hold_cmdbuf() 1282 * Aquire a lock on the command buffer for the given target. 1283 */ 1284 static void 1285 sgen_hold_cmdbuf(sgen_state_t *sg_state) 1286 { 1287 mutex_enter(&sg_state->sgen_mutex); 1288 while (SGEN_IS_BUSY(sg_state)) 1289 cv_wait(&sg_state->sgen_cmdbuf_cv, &sg_state->sgen_mutex); 1290 SGEN_SET_BUSY(sg_state); 1291 mutex_exit(&sg_state->sgen_mutex); 1292 } 1293 1294 /* 1295 * sgen_rele_cmdbuf() 1296 * release the command buffer for a particular target. 1297 */ 1298 static void 1299 sgen_rele_cmdbuf(sgen_state_t *sg_state) 1300 { 1301 mutex_enter(&sg_state->sgen_mutex); 1302 SGEN_CLR_BUSY(sg_state); 1303 cv_signal(&sg_state->sgen_cmdbuf_cv); 1304 mutex_exit(&sg_state->sgen_mutex); 1305 } 1306 1307 /* 1308 * sgen_start() 1309 * Transport a uscsi command; this is invoked by physio() or directly 1310 * by sgen_uscsi_cmd(). 1311 */ 1312 static int 1313 sgen_start(struct buf *bp) 1314 { 1315 sgen_state_t *sg_state; 1316 dev_t dev = bp->b_edev; 1317 int trans_err; 1318 1319 if ((sg_state = ddi_get_soft_state(sgen_soft_state, 1320 getminor(dev))) == NULL) { 1321 bp->b_resid = bp->b_bcount; 1322 bioerror(bp, ENXIO); 1323 biodone(bp); 1324 return (ENXIO); 1325 } 1326 1327 /* 1328 * Sanity checks - command should not be complete, no packet should 1329 * be allocated, and there ought to be a uscsi cmd in b_private 1330 */ 1331 ASSERT(bp == sg_state->sgen_cmdbuf && sg_state->sgen_cmdpkt == NULL); 1332 ASSERT((bp->b_flags & B_DONE) == 0); 1333 ASSERT(bp->b_private); 1334 if (sgen_make_uscsi_cmd(sg_state, bp) != 0) { 1335 bp->b_resid = bp->b_bcount; 1336 bioerror(bp, EFAULT); 1337 biodone(bp); 1338 return (EFAULT); 1339 } 1340 1341 ASSERT(sg_state->sgen_cmdpkt != NULL); 1342 1343 /* 1344 * Clear out the residual and error fields 1345 */ 1346 bp->b_resid = 0; 1347 bp->b_error = 0; 1348 1349 trans_err = sgen_scsi_transport(sg_state->sgen_cmdpkt); 1350 switch (trans_err) { 1351 case TRAN_ACCEPT: 1352 break; 1353 case TRAN_BUSY: 1354 sgen_log(sg_state, SGEN_DIAG2, 1355 "sgen_start: scsi_transport() returned TRAN_BUSY"); 1356 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state, 1357 SGEN_BSY_TIMEOUT); 1358 break; 1359 default: 1360 /* 1361 * Indicate there has been an I/O transfer error. 1362 * Be done with the command. 1363 */ 1364 mutex_enter(&sg_state->sgen_mutex); 1365 SGEN_DO_ERRSTATS(sg_state, sgen_trans_err); 1366 mutex_exit(&sg_state->sgen_mutex); 1367 sgen_log(sg_state, SGEN_DIAG2, "sgen_start: scsi_transport() " 1368 "returned %d", trans_err); 1369 bioerror(bp, EIO); 1370 biodone(bp); 1371 return (EIO); 1372 } 1373 sgen_log(sg_state, SGEN_DIAG2, "sgen_start: b_flags 0x%x", bp->b_flags); 1374 return (0); 1375 } 1376 1377 /* 1378 * sgen_scsi_transport() 1379 * a simple scsi_transport() wrapper which can be configured to inject 1380 * sporadic errors for testing. 1381 */ 1382 static int 1383 sgen_scsi_transport(struct scsi_pkt *pkt) 1384 { 1385 int trans_err; 1386 static int cnt = 0; 1387 sgen_state_t *sg_state = pkt->pkt_private; 1388 1389 if (sgen_sporadic_failures == 0) { 1390 return (scsi_transport(pkt)); 1391 } 1392 1393 cnt = (cnt * 2416 + 374441) % 1771875; /* borrowed from kmem.c */ 1394 if (cnt % 40 == 1) { 1395 sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: " 1396 "injecting sporadic BUSY"); 1397 trans_err = TRAN_BUSY; 1398 } else if (cnt % 40 == 2) { 1399 sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: " 1400 "injecting sporadic BADPKT"); 1401 trans_err = TRAN_BADPKT; 1402 } else { 1403 /* 1404 * Most of the time we take the normal path 1405 */ 1406 trans_err = scsi_transport(pkt); 1407 } 1408 return (trans_err); 1409 } 1410 1411 /* 1412 * sgen_make_uscsi_cmd() 1413 * Initialize a SCSI packet usable for USCSI. 1414 */ 1415 static int 1416 sgen_make_uscsi_cmd(sgen_state_t *sg_state, struct buf *bp) 1417 { 1418 struct scsi_pkt *pkt; 1419 struct uscsi_cmd *ucmd; 1420 int stat_size = 1; 1421 int flags = 0; 1422 1423 ASSERT(bp); 1424 1425 sgen_log(sg_state, SGEN_DIAG2, "in sgen_make_uscsi_cmd()"); 1426 1427 ucmd = (struct uscsi_cmd *)bp->b_private; 1428 1429 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1430 if (ucmd->uscsi_rqlen > SENSE_LENGTH) { 1431 stat_size = (int)(ucmd->uscsi_rqlen) + 1432 sizeof (struct scsi_arq_status) - 1433 sizeof (struct scsi_extended_sense); 1434 flags = PKT_XARQ; 1435 } else { 1436 stat_size = sizeof (struct scsi_arq_status); 1437 } 1438 } 1439 1440 sgen_log(sg_state, SGEN_DIAG3, "sgen_make_uscsi_cmd: b_bcount = %ld", 1441 bp->b_bcount); 1442 pkt = scsi_init_pkt(&sg_state->sgen_scsiaddr, 1443 NULL, /* in_pkt - null so it'll be alloc'd */ 1444 bp->b_bcount ? bp : NULL, /* buf structure for data xfer */ 1445 ucmd->uscsi_cdblen, /* cmdlen */ 1446 stat_size, /* statuslen */ 1447 0, /* privatelen */ 1448 flags, /* flags */ 1449 SLEEP_FUNC, /* callback */ 1450 (caddr_t)sg_state); /* callback_arg */ 1451 1452 if (pkt == NULL) { 1453 sgen_log(sg_state, SGEN_DIAG2, "failed sgen_make_uscsi_cmd()"); 1454 return (-1); 1455 } 1456 1457 pkt->pkt_comp = sgen_callback; 1458 pkt->pkt_private = sg_state; 1459 sg_state->sgen_cmdpkt = pkt; 1460 1461 /* 1462 * We *don't* call scsi_setup_cdb here, as is customary, since the 1463 * user could specify a command from one group, but pass cdblen 1464 * as something totally different. If cdblen is smaller than expected, 1465 * this results in scsi_setup_cdb writing past the end of the cdb. 1466 */ 1467 bcopy(ucmd->uscsi_cdb, pkt->pkt_cdbp, ucmd->uscsi_cdblen); 1468 if (ucmd->uscsi_cdblen >= CDB_GROUP0) { 1469 FILL_SCSI1_LUN(sg_state->sgen_scsidev, pkt); 1470 } 1471 1472 if (ucmd->uscsi_timeout > 0) 1473 pkt->pkt_time = ucmd->uscsi_timeout; 1474 else 1475 pkt->pkt_time = SGEN_IO_TIME; 1476 1477 /* 1478 * Set packet options 1479 */ 1480 if (ucmd->uscsi_flags & USCSI_SILENT) 1481 pkt->pkt_flags |= FLAG_SILENT; 1482 if (ucmd->uscsi_flags & USCSI_ISOLATE) 1483 pkt->pkt_flags |= FLAG_ISOLATE; 1484 if (ucmd->uscsi_flags & USCSI_DIAGNOSE) 1485 pkt->pkt_flags |= FLAG_DIAGNOSE; 1486 if (ucmd->uscsi_flags & USCSI_RENEGOT) { 1487 pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC; 1488 } 1489 1490 sgen_log(sg_state, SGEN_DIAG2, "done sgen_make_uscsi_cmd()"); 1491 return (0); 1492 } 1493 1494 1495 /* 1496 * sgen_restart() 1497 * sgen_restart() is called after a timeout, when a command has been 1498 * postponed due to a TRAN_BUSY response from the HBA. 1499 */ 1500 static void 1501 sgen_restart(void *arg) 1502 { 1503 sgen_state_t *sg_state = (sgen_state_t *)arg; 1504 struct scsi_pkt *pkt; 1505 struct buf *bp; 1506 1507 sgen_log(sg_state, SGEN_DIAG2, "in sgen_restart()"); 1508 1509 bp = sg_state->sgen_cmdbuf; 1510 pkt = sg_state->sgen_cmdpkt; 1511 ASSERT(bp && pkt); 1512 1513 SGEN_DO_ERRSTATS(sg_state, sgen_restart); 1514 1515 /* 1516 * If the packet is marked with the sensing flag, sgen is off running 1517 * a request sense, and *that packet* is what needs to be restarted. 1518 */ 1519 if (pkt->pkt_flags & FLAG_SENSING) { 1520 sgen_log(sg_state, SGEN_DIAG3, 1521 "sgen_restart: restarting REQUEST SENSE"); 1522 pkt = sg_state->sgen_rqspkt; 1523 } 1524 1525 if (sgen_scsi_transport(pkt) != TRAN_ACCEPT) { 1526 bp->b_resid = bp->b_bcount; 1527 bioerror(bp, EIO); 1528 biodone(bp); 1529 } 1530 } 1531 1532 /* 1533 * sgen_callback() 1534 * Command completion processing 1535 * 1536 * sgen's completion processing is very pessimistic-- it does not retry 1537 * failed commands; instead, it allows the user application to make 1538 * decisions about what has gone wrong. 1539 */ 1540 static void 1541 sgen_callback(struct scsi_pkt *pkt) 1542 { 1543 sgen_state_t *sg_state; 1544 struct buf *bp; 1545 int action; 1546 1547 sg_state = pkt->pkt_private; 1548 /* 1549 * bp should always be the command buffer regardless of whether 1550 * this is a command completion or a request-sense completion. 1551 * This is because there is no need to biodone() the sense buf 1552 * when it completes-- we want to biodone() the actual command buffer! 1553 */ 1554 bp = sg_state->sgen_cmdbuf; 1555 if (pkt->pkt_flags & FLAG_SENSING) { 1556 ASSERT(pkt == sg_state->sgen_rqspkt); 1557 sgen_log(sg_state, SGEN_DIAG2, 1558 "in sgen_callback() (SENSE completion callback)"); 1559 } else { 1560 ASSERT(pkt == sg_state->sgen_cmdpkt); 1561 sgen_log(sg_state, SGEN_DIAG2, 1562 "in sgen_callback() (command completion callback)"); 1563 } 1564 1565 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: reason=0x%x resid=%ld " 1566 "state=0x%x", pkt->pkt_reason, pkt->pkt_resid, pkt->pkt_state); 1567 1568 if (pkt->pkt_reason != CMD_CMPLT) { 1569 /* 1570 * The command did not complete. 1571 */ 1572 sgen_log(sg_state, SGEN_DIAG3, 1573 "sgen_callback: command did not complete"); 1574 action = sgen_handle_incomplete(sg_state, pkt); 1575 } else if (sg_state->sgen_arq_enabled && 1576 (pkt->pkt_state & STATE_ARQ_DONE)) { 1577 /* 1578 * The auto-rqsense happened, and the packet has a filled-in 1579 * scsi_arq_status structure, pointed to by pkt_scbp. 1580 */ 1581 sgen_log(sg_state, SGEN_DIAG3, 1582 "sgen_callback: received auto-requested sense"); 1583 action = sgen_handle_autosense(sg_state, pkt); 1584 ASSERT(action != FETCH_SENSE); 1585 } else if (pkt->pkt_flags & FLAG_SENSING) { 1586 /* 1587 * sgen was running a REQUEST SENSE. Decode the sense data and 1588 * decide what to do next. 1589 * 1590 * Clear FLAG_SENSING on the original packet for completeness. 1591 */ 1592 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: received sense"); 1593 sg_state->sgen_cmdpkt->pkt_flags &= ~FLAG_SENSING; 1594 action = sgen_handle_sense(sg_state); 1595 ASSERT(action != FETCH_SENSE); 1596 } else { 1597 /* 1598 * Command completed and we're not getting sense. Check for 1599 * errors and decide what to do next. 1600 */ 1601 sgen_log(sg_state, SGEN_DIAG3, 1602 "sgen_callback: command appears complete"); 1603 action = sgen_check_error(sg_state, bp); 1604 } 1605 1606 switch (action) { 1607 case FETCH_SENSE: 1608 /* 1609 * If there is sense to fetch, break out to prevent biodone'ing 1610 * until the sense fetch is complete. 1611 */ 1612 if (sgen_initiate_sense(sg_state) == 0) 1613 break; 1614 /*FALLTHROUGH*/ 1615 case COMMAND_DONE_ERROR: 1616 bp->b_resid = bp->b_bcount; 1617 bioerror(bp, EIO); 1618 /*FALLTHROUGH*/ 1619 case COMMAND_DONE: 1620 biodone(bp); 1621 break; 1622 default: 1623 ASSERT(0); 1624 break; 1625 } 1626 1627 sgen_log(sg_state, SGEN_DIAG2, "done sgen_callback()"); 1628 } 1629 1630 /* 1631 * sgen_initiate_sense() 1632 * Send the sgen_rqspkt to the target, thereby requesting sense data. 1633 */ 1634 static int 1635 sgen_initiate_sense(sgen_state_t *sg_state) 1636 { 1637 switch (sgen_scsi_transport(sg_state->sgen_rqspkt)) { 1638 case TRAN_ACCEPT: 1639 sgen_log(sg_state, SGEN_DIAG3, "sgen_initiate_sense: " 1640 "sense fetch transport accepted."); 1641 return (0); 1642 case TRAN_BUSY: 1643 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: " 1644 "sense fetch transport busy, setting timeout."); 1645 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state, 1646 SGEN_BSY_TIMEOUT); 1647 return (0); 1648 default: 1649 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: " 1650 "sense fetch transport failed or busy."); 1651 return (-1); 1652 } 1653 } 1654 1655 /* 1656 * sgen_handle_incomplete() 1657 * sgen is pessimistic, but also careful-- it doesn't try to retry 1658 * incomplete commands, but it also doesn't go resetting devices; 1659 * it is hard to tell if the device will be tolerant of that sort 1660 * of prodding. 1661 * 1662 * This routine has been left as a guide for the future--- the 1663 * current administration's hands-off policy may need modification. 1664 */ 1665 /*ARGSUSED*/ 1666 static int 1667 sgen_handle_incomplete(sgen_state_t *sg_state, struct scsi_pkt *pkt) 1668 { 1669 SGEN_DO_ERRSTATS(sg_state, sgen_incmp_err); 1670 return (COMMAND_DONE_ERROR); 1671 } 1672 1673 /* 1674 * sgen_handle_autosense() 1675 * Deal with SENSE data acquired automatically via the auto-request-sense 1676 * facility. 1677 * 1678 * Sgen takes a pessimistic view of things-- it doesn't retry commands, 1679 * and unless the device recovered from the problem, this routine returns 1680 * COMMAND_DONE_ERROR. 1681 */ 1682 static int 1683 sgen_handle_autosense(sgen_state_t *sg_state, struct scsi_pkt *pkt) 1684 { 1685 struct scsi_arq_status *arqstat; 1686 struct uscsi_cmd *ucmd = 1687 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1688 int amt; 1689 1690 arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp); 1691 1692 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_rcv); 1693 1694 if (arqstat->sts_rqpkt_reason != CMD_CMPLT) { 1695 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: ARQ" 1696 "failed to complete."); 1697 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1698 return (COMMAND_DONE_ERROR); 1699 } 1700 1701 if (pkt->pkt_state & STATE_XARQ_DONE) { 1702 amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1703 } else { 1704 if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) { 1705 amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1706 } else { 1707 amt = SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1708 } 1709 } 1710 1711 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1712 ucmd->uscsi_rqstatus = *((char *)&arqstat->sts_rqpkt_status); 1713 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen); 1714 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen; 1715 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen); 1716 bcopy(&(arqstat->sts_sensedata), sg_state->sgen_rqs_sen, rqlen); 1717 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_autosense: " 1718 "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n", 1719 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid); 1720 } 1721 1722 if (arqstat->sts_rqpkt_status.sts_chk) { 1723 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got " 1724 "check condition on auto request sense!"); 1725 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1726 return (COMMAND_DONE_ERROR); 1727 } 1728 1729 if (((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0) || 1730 (amt == 0)) { 1731 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got " 1732 "auto-sense, but it contains no data!"); 1733 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1734 return (COMMAND_DONE_ERROR); 1735 } 1736 1737 /* 1738 * Stuff the sense data pointer into sgen_sense for later retrieval 1739 */ 1740 sg_state->sgen_sense = &arqstat->sts_sensedata; 1741 1742 /* 1743 * Now, check to see whether we got enough sense data to make any 1744 * sense out if it (heh-heh). 1745 */ 1746 if (amt < SUN_MIN_SENSE_LENGTH) { 1747 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: not " 1748 "enough auto sense data"); 1749 return (COMMAND_DONE_ERROR); 1750 } 1751 1752 switch (arqstat->sts_sensedata.es_key) { 1753 case KEY_RECOVERABLE_ERROR: 1754 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err); 1755 break; 1756 case KEY_NO_SENSE: 1757 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err); 1758 break; 1759 default: 1760 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err); 1761 break; 1762 } 1763 1764 return (COMMAND_DONE); 1765 } 1766 1767 /* 1768 * sgen_handle_sense() 1769 * Examine sense data that was manually fetched from the target. 1770 */ 1771 static int 1772 sgen_handle_sense(sgen_state_t *sg_state) 1773 { 1774 struct scsi_pkt *rqpkt = sg_state->sgen_rqspkt; 1775 struct scsi_status *rqstatus = (struct scsi_status *)rqpkt->pkt_scbp; 1776 struct uscsi_cmd *ucmd = 1777 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1778 int amt; 1779 1780 SGEN_DO_ERRSTATS(sg_state, sgen_sense_rcv); 1781 1782 amt = MAX_SENSE_LENGTH - rqpkt->pkt_resid; 1783 1784 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1785 ucmd->uscsi_rqstatus = *((char *)rqstatus); 1786 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen); 1787 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen; 1788 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen); 1789 bcopy(sg_state->sgen_sense, sg_state->sgen_rqs_sen, rqlen); 1790 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_sense: " 1791 "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n", 1792 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid); 1793 } 1794 1795 if (rqstatus->sts_busy) { 1796 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got busy " 1797 "on request sense"); 1798 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1799 return (COMMAND_DONE_ERROR); 1800 } 1801 1802 if (rqstatus->sts_chk) { 1803 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got check " 1804 "condition on request sense!"); 1805 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1806 return (COMMAND_DONE_ERROR); 1807 } 1808 1809 if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) { 1810 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got " 1811 "sense, but it contains no data"); 1812 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1813 return (COMMAND_DONE_ERROR); 1814 } 1815 1816 /* 1817 * Now, check to see whether we got enough sense data to make any 1818 * sense out if it (heh-heh). 1819 */ 1820 if (amt < SUN_MIN_SENSE_LENGTH) { 1821 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: not " 1822 "enough sense data"); 1823 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1824 return (COMMAND_DONE_ERROR); 1825 } 1826 1827 /* 1828 * Decode the sense data-- this was deposited here for us by the 1829 * setup in sgen_do_attach(). (note that sgen_sense is an alias for 1830 * the sd_sense field in the scsi_device). 1831 */ 1832 sgen_log(sg_state, SGEN_DIAG1, "Sense key is %s [0x%x]", 1833 scsi_sname(sg_state->sgen_sense->es_key), 1834 sg_state->sgen_sense->es_key); 1835 switch (sg_state->sgen_sense->es_key) { 1836 case KEY_RECOVERABLE_ERROR: 1837 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err); 1838 break; 1839 case KEY_NO_SENSE: 1840 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err); 1841 break; 1842 default: 1843 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err); 1844 break; 1845 } 1846 1847 return (COMMAND_DONE); 1848 } 1849 1850 /* 1851 * sgen_check_error() 1852 * examine the command packet for abnormal completion. 1853 * 1854 * sgen_check_error should only be called at the completion of the 1855 * command packet. 1856 */ 1857 static int 1858 sgen_check_error(sgen_state_t *sg_state, struct buf *bp) 1859 { 1860 struct scsi_pkt *pkt = sg_state->sgen_cmdpkt; 1861 struct scsi_status *status = (struct scsi_status *)pkt->pkt_scbp; 1862 struct uscsi_cmd *ucmd = 1863 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1864 1865 if (status->sts_busy) { 1866 sgen_log(sg_state, SGEN_DIAG1, 1867 "sgen_check_error: target is busy"); 1868 return (COMMAND_DONE_ERROR); 1869 } 1870 1871 /* 1872 * pkt_resid will reflect, at this point, a residual of how many bytes 1873 * were not transferred; a non-zero pkt_resid is an error. 1874 */ 1875 if (pkt->pkt_resid) { 1876 bp->b_resid += pkt->pkt_resid; 1877 } 1878 1879 if (status->sts_chk) { 1880 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1881 if (sg_state->sgen_arq_enabled) { 1882 sgen_log(sg_state, SGEN_DIAG1, 1883 "sgen_check_error: strange: target " 1884 "indicates CHECK CONDITION with auto-sense " 1885 "enabled."); 1886 } 1887 sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: " 1888 "target ready for sense fetch"); 1889 return (FETCH_SENSE); 1890 } else { 1891 sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: " 1892 "target indicates CHECK CONDITION"); 1893 } 1894 } 1895 1896 return (COMMAND_DONE); 1897 } 1898 1899 /* 1900 * sgen_tur() 1901 * test if a target is ready to operate by sending it a TUR command. 1902 */ 1903 static int 1904 sgen_tur(dev_t dev) 1905 { 1906 char cmdblk[CDB_GROUP0]; 1907 struct uscsi_cmd scmd; 1908 1909 bzero(&scmd, sizeof (scmd)); 1910 scmd.uscsi_bufaddr = 0; 1911 scmd.uscsi_buflen = 0; 1912 bzero(cmdblk, CDB_GROUP0); 1913 cmdblk[0] = (char)SCMD_TEST_UNIT_READY; 1914 scmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_WRITE; 1915 scmd.uscsi_cdb = cmdblk; 1916 scmd.uscsi_cdblen = CDB_GROUP0; 1917 1918 return (sgen_uscsi_cmd(dev, &scmd, FKIOCTL)); 1919 } 1920 1921 /* 1922 * sgen_diag_ok() 1923 * given an sg_state and a desired diagnostic level, return true if 1924 * it is acceptable to output a message. 1925 */ 1926 /*ARGSUSED*/ 1927 static int 1928 sgen_diag_ok(sgen_state_t *sg_state, int level) 1929 { 1930 int diag_lvl; 1931 1932 switch (level) { 1933 case CE_WARN: 1934 case CE_NOTE: 1935 case CE_CONT: 1936 case CE_PANIC: 1937 return (1); 1938 case SGEN_DIAG1: 1939 case SGEN_DIAG2: 1940 case SGEN_DIAG3: 1941 if (sg_state) { 1942 /* 1943 * Check to see if user overrode the diagnostics level 1944 * for this instance (either via SGEN_IOC_DIAG or via 1945 * .conf file). If not, fall back to the global diag 1946 * level. 1947 */ 1948 if (sg_state->sgen_diag != -1) 1949 diag_lvl = sg_state->sgen_diag; 1950 else 1951 diag_lvl = sgen_diag; 1952 } else { 1953 diag_lvl = sgen_diag; 1954 } 1955 if (((diag_lvl << 8) | CE_CONT) >= level) { 1956 return (1); 1957 } else { 1958 return (0); 1959 } 1960 default: 1961 return (1); 1962 } 1963 } 1964 1965 /*PRINTFLIKE3*/ 1966 static void 1967 sgen_log(sgen_state_t *sg_state, int level, const char *fmt, ...) 1968 { 1969 va_list ap; 1970 char buf[256]; 1971 1972 if (!sgen_diag_ok(sg_state, level)) 1973 return; 1974 1975 va_start(ap, fmt); 1976 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 1977 va_end(ap); 1978 1979 switch (level) { 1980 case CE_NOTE: 1981 case CE_CONT: 1982 case CE_WARN: 1983 case CE_PANIC: 1984 if (sg_state == (sgen_state_t *)NULL) { 1985 cmn_err(level, "%s", buf); 1986 } else { 1987 scsi_log(sg_state->sgen_devinfo, "sgen", level, 1988 "%s", buf); 1989 } 1990 break; 1991 case SGEN_DIAG1: 1992 case SGEN_DIAG2: 1993 case SGEN_DIAG3: 1994 default: 1995 if (sg_state == (sgen_state_t *)NULL) { 1996 scsi_log(NULL, "sgen", CE_CONT, "%s", buf); 1997 } else { 1998 scsi_log(sg_state->sgen_devinfo, "sgen", CE_CONT, 1999 "%s", buf); 2000 } 2001 } 2002 } 2003 2004 /* 2005 * sgen_dump_cdb() 2006 * dump out the contents of a cdb. Take care that 'label' is not too 2007 * large, or 'buf' could overflow. 2008 */ 2009 static void 2010 sgen_dump_cdb(sgen_state_t *sg_state, const char *label, 2011 union scsi_cdb *cdb, int cdblen) 2012 { 2013 static char hex[] = "0123456789abcdef"; 2014 char *buf, *p; 2015 size_t nbytes; 2016 int i; 2017 uchar_t *cdbp = (uchar_t *)cdb; 2018 2019 /* 2020 * fastpath-- if we're not able to print out, don't do all of this 2021 * extra work. 2022 */ 2023 if (!sgen_diag_ok(sg_state, SGEN_DIAG3)) 2024 return; 2025 2026 /* 2027 * 3 characters for each byte (because of the ' '), plus the size of 2028 * the label, plus the trailing ']' and the null character. 2029 */ 2030 nbytes = 3 * cdblen + strlen(label) + strlen(" CDB = [") + 2; 2031 buf = kmem_alloc(nbytes, KM_SLEEP); 2032 (void) sprintf(buf, "%s CDB = [", label); 2033 p = &buf[strlen(buf)]; 2034 for (i = 0; i < cdblen; i++, cdbp++) { 2035 if (i > 0) 2036 *p++ = ' '; 2037 *p++ = hex[(*cdbp >> 4) & 0x0f]; 2038 *p++ = hex[*cdbp & 0x0f]; 2039 } 2040 *p++ = ']'; 2041 *p = 0; 2042 sgen_log(sg_state, SGEN_DIAG3, buf); 2043 kmem_free(buf, nbytes); 2044 } 2045 2046 static void 2047 sgen_dump_sense(sgen_state_t *sg_state, size_t rqlen, uchar_t *rqbuf) 2048 { 2049 static char hex[] = "0123456789abcdef"; 2050 char *buf, *p; 2051 size_t nbytes; 2052 int i; 2053 2054 /* 2055 * fastpath-- if we're not able to print out, don't do all of this 2056 * extra work. 2057 */ 2058 if (!sgen_diag_ok(sg_state, SGEN_DIAG3)) 2059 return; 2060 2061 /* 2062 * 3 characters for each byte (because of the ' '), plus the size of 2063 * the label, plus the trailing ']' and the null character. 2064 */ 2065 nbytes = 3 * rqlen + strlen(" SENSE = [") + 2; 2066 buf = kmem_alloc(nbytes, KM_SLEEP); 2067 (void) sprintf(buf, "SENSE = ["); 2068 p = &buf[strlen(buf)]; 2069 for (i = 0; i < rqlen; i++, rqbuf++) { 2070 if (i > 0) 2071 *p++ = ' '; 2072 *p++ = hex[(*rqbuf >> 4) & 0x0f]; 2073 *p++ = hex[*rqbuf & 0x0f]; 2074 } 2075 *p++ = ']'; 2076 *p = 0; 2077 sgen_log(sg_state, SGEN_DIAG3, buf); 2078 kmem_free(buf, nbytes); 2079 } 2080