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 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, 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", ucmd->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; 1421 1422 ASSERT(bp); 1423 1424 sgen_log(sg_state, SGEN_DIAG2, "in sgen_make_uscsi_cmd()"); 1425 1426 ucmd = (struct uscsi_cmd *)bp->b_private; 1427 1428 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1429 stat_size = sizeof (struct scsi_arq_status); 1430 } else { 1431 stat_size = 1; 1432 } 1433 1434 sgen_log(sg_state, SGEN_DIAG3, "sgen_make_uscsi_cmd: b_bcount = %ld", 1435 bp->b_bcount); 1436 pkt = scsi_init_pkt(&sg_state->sgen_scsiaddr, 1437 NULL, /* in_pkt - null so it'll be alloc'd */ 1438 bp->b_bcount ? bp : NULL, /* buf structure for data xfer */ 1439 ucmd->uscsi_cdblen, /* cmdlen */ 1440 stat_size, /* statuslen */ 1441 0, /* privatelen */ 1442 0, /* flags */ 1443 SLEEP_FUNC, /* callback */ 1444 (caddr_t)sg_state); /* callback_arg */ 1445 1446 if (pkt == NULL) { 1447 sgen_log(sg_state, SGEN_DIAG2, "failed sgen_make_uscsi_cmd()"); 1448 return (-1); 1449 } 1450 1451 pkt->pkt_comp = sgen_callback; 1452 pkt->pkt_private = sg_state; 1453 sg_state->sgen_cmdpkt = pkt; 1454 1455 /* 1456 * We *don't* call scsi_setup_cdb here, as is customary, since the 1457 * user could specify a command from one group, but pass cdblen 1458 * as something totally different. If cdblen is smaller than expected, 1459 * this results in scsi_setup_cdb writing past the end of the cdb. 1460 */ 1461 bcopy(ucmd->uscsi_cdb, pkt->pkt_cdbp, ucmd->uscsi_cdblen); 1462 if (ucmd->uscsi_cdblen >= CDB_GROUP0) { 1463 FILL_SCSI1_LUN(sg_state->sgen_scsidev, pkt); 1464 } 1465 1466 if (ucmd->uscsi_timeout > 0) 1467 pkt->pkt_time = ucmd->uscsi_timeout; 1468 else 1469 pkt->pkt_time = SGEN_IO_TIME; 1470 1471 /* 1472 * Set packet options 1473 */ 1474 if (ucmd->uscsi_flags & USCSI_SILENT) 1475 pkt->pkt_flags |= FLAG_SILENT; 1476 if (ucmd->uscsi_flags & USCSI_ISOLATE) 1477 pkt->pkt_flags |= FLAG_ISOLATE; 1478 if (ucmd->uscsi_flags & USCSI_DIAGNOSE) 1479 pkt->pkt_flags |= FLAG_DIAGNOSE; 1480 if (ucmd->uscsi_flags & USCSI_RENEGOT) { 1481 pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC; 1482 } 1483 1484 sgen_log(sg_state, SGEN_DIAG2, "done sgen_make_uscsi_cmd()"); 1485 return (0); 1486 } 1487 1488 1489 /* 1490 * sgen_restart() 1491 * sgen_restart() is called after a timeout, when a command has been 1492 * postponed due to a TRAN_BUSY response from the HBA. 1493 */ 1494 static void 1495 sgen_restart(void *arg) 1496 { 1497 sgen_state_t *sg_state = (sgen_state_t *)arg; 1498 struct scsi_pkt *pkt; 1499 struct buf *bp; 1500 1501 sgen_log(sg_state, SGEN_DIAG2, "in sgen_restart()"); 1502 1503 bp = sg_state->sgen_cmdbuf; 1504 pkt = sg_state->sgen_cmdpkt; 1505 ASSERT(bp && pkt); 1506 1507 SGEN_DO_ERRSTATS(sg_state, sgen_restart); 1508 1509 /* 1510 * If the packet is marked with the sensing flag, sgen is off running 1511 * a request sense, and *that packet* is what needs to be restarted. 1512 */ 1513 if (pkt->pkt_flags & FLAG_SENSING) { 1514 sgen_log(sg_state, SGEN_DIAG3, 1515 "sgen_restart: restarting REQUEST SENSE"); 1516 pkt = sg_state->sgen_rqspkt; 1517 } 1518 1519 if (sgen_scsi_transport(pkt) != TRAN_ACCEPT) { 1520 bp->b_resid = bp->b_bcount; 1521 bioerror(bp, EIO); 1522 biodone(bp); 1523 } 1524 } 1525 1526 /* 1527 * sgen_callback() 1528 * Command completion processing 1529 * 1530 * sgen's completion processing is very pessimistic-- it does not retry 1531 * failed commands; instead, it allows the user application to make 1532 * decisions about what has gone wrong. 1533 */ 1534 static void 1535 sgen_callback(struct scsi_pkt *pkt) 1536 { 1537 sgen_state_t *sg_state; 1538 struct buf *bp; 1539 int action; 1540 1541 sg_state = pkt->pkt_private; 1542 /* 1543 * bp should always be the command buffer regardless of whether 1544 * this is a command completion or a request-sense completion. 1545 * This is because there is no need to biodone() the sense buf 1546 * when it completes-- we want to biodone() the actual command buffer! 1547 */ 1548 bp = sg_state->sgen_cmdbuf; 1549 if (pkt->pkt_flags & FLAG_SENSING) { 1550 ASSERT(pkt == sg_state->sgen_rqspkt); 1551 sgen_log(sg_state, SGEN_DIAG2, 1552 "in sgen_callback() (SENSE completion callback)"); 1553 } else { 1554 ASSERT(pkt == sg_state->sgen_cmdpkt); 1555 sgen_log(sg_state, SGEN_DIAG2, 1556 "in sgen_callback() (command completion callback)"); 1557 } 1558 1559 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: reason=0x%x resid=%ld " 1560 "state=0x%x", pkt->pkt_reason, pkt->pkt_resid, pkt->pkt_state); 1561 1562 if (pkt->pkt_reason != CMD_CMPLT) { 1563 /* 1564 * The command did not complete. 1565 */ 1566 sgen_log(sg_state, SGEN_DIAG3, 1567 "sgen_callback: command did not complete"); 1568 action = sgen_handle_incomplete(sg_state, pkt); 1569 } else if (sg_state->sgen_arq_enabled && 1570 (pkt->pkt_state & STATE_ARQ_DONE)) { 1571 /* 1572 * The auto-rqsense happened, and the packet has a filled-in 1573 * scsi_arq_status structure, pointed to by pkt_scbp. 1574 */ 1575 sgen_log(sg_state, SGEN_DIAG3, 1576 "sgen_callback: received auto-requested sense"); 1577 action = sgen_handle_autosense(sg_state, pkt); 1578 ASSERT(action != FETCH_SENSE); 1579 } else if (pkt->pkt_flags & FLAG_SENSING) { 1580 /* 1581 * sgen was running a REQUEST SENSE. Decode the sense data and 1582 * decide what to do next. 1583 * 1584 * Clear FLAG_SENSING on the original packet for completeness. 1585 */ 1586 sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: received sense"); 1587 sg_state->sgen_cmdpkt->pkt_flags &= ~FLAG_SENSING; 1588 action = sgen_handle_sense(sg_state); 1589 ASSERT(action != FETCH_SENSE); 1590 } else { 1591 /* 1592 * Command completed and we're not getting sense. Check for 1593 * errors and decide what to do next. 1594 */ 1595 sgen_log(sg_state, SGEN_DIAG3, 1596 "sgen_callback: command appears complete"); 1597 action = sgen_check_error(sg_state, bp); 1598 } 1599 1600 switch (action) { 1601 case FETCH_SENSE: 1602 /* 1603 * If there is sense to fetch, break out to prevent biodone'ing 1604 * until the sense fetch is complete. 1605 */ 1606 if (sgen_initiate_sense(sg_state) == 0) 1607 break; 1608 /*FALLTHROUGH*/ 1609 case COMMAND_DONE_ERROR: 1610 bp->b_resid = bp->b_bcount; 1611 bioerror(bp, EIO); 1612 /*FALLTHROUGH*/ 1613 case COMMAND_DONE: 1614 biodone(bp); 1615 break; 1616 default: 1617 ASSERT(0); 1618 break; 1619 } 1620 1621 sgen_log(sg_state, SGEN_DIAG2, "done sgen_callback()"); 1622 } 1623 1624 /* 1625 * sgen_initiate_sense() 1626 * Send the sgen_rqspkt to the target, thereby requesting sense data. 1627 */ 1628 static int 1629 sgen_initiate_sense(sgen_state_t *sg_state) 1630 { 1631 switch (sgen_scsi_transport(sg_state->sgen_rqspkt)) { 1632 case TRAN_ACCEPT: 1633 sgen_log(sg_state, SGEN_DIAG3, "sgen_initiate_sense: " 1634 "sense fetch transport accepted."); 1635 return (0); 1636 case TRAN_BUSY: 1637 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: " 1638 "sense fetch transport busy, setting timeout."); 1639 sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state, 1640 SGEN_BSY_TIMEOUT); 1641 return (0); 1642 default: 1643 sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: " 1644 "sense fetch transport failed or busy."); 1645 return (-1); 1646 } 1647 } 1648 1649 /* 1650 * sgen_handle_incomplete() 1651 * sgen is pessimistic, but also careful-- it doesn't try to retry 1652 * incomplete commands, but it also doesn't go resetting devices; 1653 * it is hard to tell if the device will be tolerant of that sort 1654 * of prodding. 1655 * 1656 * This routine has been left as a guide for the future--- the 1657 * current administration's hands-off policy may need modification. 1658 */ 1659 /*ARGSUSED*/ 1660 static int 1661 sgen_handle_incomplete(sgen_state_t *sg_state, struct scsi_pkt *pkt) 1662 { 1663 SGEN_DO_ERRSTATS(sg_state, sgen_incmp_err); 1664 return (COMMAND_DONE_ERROR); 1665 } 1666 1667 /* 1668 * sgen_handle_autosense() 1669 * Deal with SENSE data acquired automatically via the auto-request-sense 1670 * facility. 1671 * 1672 * Sgen takes a pessimistic view of things-- it doesn't retry commands, 1673 * and unless the device recovered from the problem, this routine returns 1674 * COMMAND_DONE_ERROR. 1675 */ 1676 static int 1677 sgen_handle_autosense(sgen_state_t *sg_state, struct scsi_pkt *pkt) 1678 { 1679 struct scsi_arq_status *arqstat; 1680 struct uscsi_cmd *ucmd = 1681 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1682 int amt; 1683 1684 arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp); 1685 1686 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_rcv); 1687 1688 if (arqstat->sts_rqpkt_reason != CMD_CMPLT) { 1689 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: ARQ" 1690 "failed to complete."); 1691 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1692 return (COMMAND_DONE_ERROR); 1693 } 1694 1695 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1696 ucmd->uscsi_rqstatus = *((char *)&arqstat->sts_rqpkt_status); 1697 ucmd->uscsi_rqresid = arqstat->sts_rqpkt_resid; 1698 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen); 1699 bcopy(&(arqstat->sts_sensedata), sg_state->sgen_rqs_sen, 1700 ucmd->uscsi_rqlen); 1701 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_autosense: " 1702 "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n", 1703 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid); 1704 } 1705 1706 if (arqstat->sts_rqpkt_status.sts_chk) { 1707 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got " 1708 "check condition on auto request sense!"); 1709 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1710 return (COMMAND_DONE_ERROR); 1711 } 1712 1713 amt = SENSE_LENGTH - arqstat->sts_rqpkt_resid; 1714 if (((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0) || 1715 (amt == 0)) { 1716 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got " 1717 "auto-sense, but it contains no data!"); 1718 SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad); 1719 return (COMMAND_DONE_ERROR); 1720 } 1721 1722 /* 1723 * Stuff the sense data pointer into sgen_sense for later retrieval 1724 */ 1725 sg_state->sgen_sense = &arqstat->sts_sensedata; 1726 1727 /* 1728 * Now, check to see whether we got enough sense data to make any 1729 * sense out if it (heh-heh). 1730 */ 1731 if (amt < SUN_MIN_SENSE_LENGTH) { 1732 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: not " 1733 "enough auto sense data"); 1734 return (COMMAND_DONE_ERROR); 1735 } 1736 1737 switch (arqstat->sts_sensedata.es_key) { 1738 case KEY_RECOVERABLE_ERROR: 1739 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err); 1740 break; 1741 case KEY_NO_SENSE: 1742 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err); 1743 break; 1744 default: 1745 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err); 1746 break; 1747 } 1748 1749 return (COMMAND_DONE); 1750 } 1751 1752 /* 1753 * sgen_handle_sense() 1754 * Examine sense data that was manually fetched from the target. 1755 */ 1756 static int 1757 sgen_handle_sense(sgen_state_t *sg_state) 1758 { 1759 struct scsi_pkt *rqpkt = sg_state->sgen_rqspkt; 1760 struct scsi_status *rqstatus = (struct scsi_status *)rqpkt->pkt_scbp; 1761 struct uscsi_cmd *ucmd = 1762 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1763 int amt; 1764 1765 SGEN_DO_ERRSTATS(sg_state, sgen_sense_rcv); 1766 1767 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1768 ucmd->uscsi_rqstatus = *((char *)rqstatus); 1769 ucmd->uscsi_rqresid = rqpkt->pkt_resid; 1770 ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen); 1771 bcopy(sg_state->sgen_sense, sg_state->sgen_rqs_sen, 1772 ucmd->uscsi_rqlen); 1773 sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_sense: " 1774 "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n", 1775 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid); 1776 } 1777 1778 if (rqstatus->sts_busy) { 1779 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got busy " 1780 "on request sense"); 1781 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1782 return (COMMAND_DONE_ERROR); 1783 } 1784 1785 if (rqstatus->sts_chk) { 1786 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got check " 1787 "condition on request sense!"); 1788 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1789 return (COMMAND_DONE_ERROR); 1790 } 1791 1792 amt = SENSE_LENGTH - rqpkt->pkt_resid; 1793 if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) { 1794 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got " 1795 "sense, but it contains no data"); 1796 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1797 return (COMMAND_DONE_ERROR); 1798 } 1799 1800 /* 1801 * Now, check to see whether we got enough sense data to make any 1802 * sense out if it (heh-heh). 1803 */ 1804 if (amt < SUN_MIN_SENSE_LENGTH) { 1805 sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: not " 1806 "enough sense data"); 1807 SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad); 1808 return (COMMAND_DONE_ERROR); 1809 } 1810 1811 /* 1812 * Decode the sense data-- this was deposited here for us by the 1813 * setup in sgen_do_attach(). (note that sgen_sense is an alias for 1814 * the sd_sense field in the scsi_device). 1815 */ 1816 sgen_log(sg_state, SGEN_DIAG1, "Sense key is %s [0x%x]", 1817 scsi_sname(sg_state->sgen_sense->es_key), 1818 sg_state->sgen_sense->es_key); 1819 switch (sg_state->sgen_sense->es_key) { 1820 case KEY_RECOVERABLE_ERROR: 1821 SGEN_DO_ERRSTATS(sg_state, sgen_recov_err); 1822 break; 1823 case KEY_NO_SENSE: 1824 SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err); 1825 break; 1826 default: 1827 SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err); 1828 break; 1829 } 1830 1831 return (COMMAND_DONE); 1832 } 1833 1834 /* 1835 * sgen_check_error() 1836 * examine the command packet for abnormal completion. 1837 * 1838 * sgen_check_error should only be called at the completion of the 1839 * command packet. 1840 */ 1841 static int 1842 sgen_check_error(sgen_state_t *sg_state, struct buf *bp) 1843 { 1844 struct scsi_pkt *pkt = sg_state->sgen_cmdpkt; 1845 struct scsi_status *status = (struct scsi_status *)pkt->pkt_scbp; 1846 struct uscsi_cmd *ucmd = 1847 (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private; 1848 1849 if (status->sts_busy) { 1850 sgen_log(sg_state, SGEN_DIAG1, 1851 "sgen_check_error: target is busy"); 1852 return (COMMAND_DONE_ERROR); 1853 } 1854 1855 /* 1856 * pkt_resid will reflect, at this point, a residual of how many bytes 1857 * were not transferred; a non-zero pkt_resid is an error. 1858 */ 1859 if (pkt->pkt_resid) { 1860 bp->b_resid += pkt->pkt_resid; 1861 } 1862 1863 if (status->sts_chk) { 1864 if (ucmd->uscsi_flags & USCSI_RQENABLE) { 1865 if (sg_state->sgen_arq_enabled) { 1866 sgen_log(sg_state, SGEN_DIAG1, 1867 "sgen_check_error: strange: target " 1868 "indicates CHECK CONDITION with auto-sense " 1869 "enabled."); 1870 } 1871 sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: " 1872 "target ready for sense fetch"); 1873 return (FETCH_SENSE); 1874 } else { 1875 sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: " 1876 "target indicates CHECK CONDITION"); 1877 } 1878 } 1879 1880 return (COMMAND_DONE); 1881 } 1882 1883 /* 1884 * sgen_tur() 1885 * test if a target is ready to operate by sending it a TUR command. 1886 */ 1887 static int 1888 sgen_tur(dev_t dev) 1889 { 1890 char cmdblk[CDB_GROUP0]; 1891 struct uscsi_cmd scmd; 1892 1893 bzero(&scmd, sizeof (scmd)); 1894 scmd.uscsi_bufaddr = 0; 1895 scmd.uscsi_buflen = 0; 1896 bzero(cmdblk, CDB_GROUP0); 1897 cmdblk[0] = (char)SCMD_TEST_UNIT_READY; 1898 scmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_WRITE; 1899 scmd.uscsi_cdb = cmdblk; 1900 scmd.uscsi_cdblen = CDB_GROUP0; 1901 1902 return (sgen_uscsi_cmd(dev, &scmd, FKIOCTL)); 1903 } 1904 1905 /* 1906 * sgen_diag_ok() 1907 * given an sg_state and a desired diagnostic level, return true if 1908 * it is acceptable to output a message. 1909 */ 1910 /*ARGSUSED*/ 1911 static int 1912 sgen_diag_ok(sgen_state_t *sg_state, int level) 1913 { 1914 int diag_lvl; 1915 1916 switch (level) { 1917 case CE_WARN: 1918 case CE_NOTE: 1919 case CE_CONT: 1920 case CE_PANIC: 1921 return (1); 1922 case SGEN_DIAG1: 1923 case SGEN_DIAG2: 1924 case SGEN_DIAG3: 1925 if (sg_state) { 1926 /* 1927 * Check to see if user overrode the diagnostics level 1928 * for this instance (either via SGEN_IOC_DIAG or via 1929 * .conf file). If not, fall back to the global diag 1930 * level. 1931 */ 1932 if (sg_state->sgen_diag != -1) 1933 diag_lvl = sg_state->sgen_diag; 1934 else 1935 diag_lvl = sgen_diag; 1936 } else { 1937 diag_lvl = sgen_diag; 1938 } 1939 if (((diag_lvl << 8) | CE_CONT) >= level) { 1940 return (1); 1941 } else { 1942 return (0); 1943 } 1944 default: 1945 return (1); 1946 } 1947 } 1948 1949 /*PRINTFLIKE3*/ 1950 static void 1951 sgen_log(sgen_state_t *sg_state, int level, const char *fmt, ...) 1952 { 1953 va_list ap; 1954 char buf[256]; 1955 1956 if (!sgen_diag_ok(sg_state, level)) 1957 return; 1958 1959 va_start(ap, fmt); 1960 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 1961 va_end(ap); 1962 1963 switch (level) { 1964 case CE_NOTE: 1965 case CE_CONT: 1966 case CE_WARN: 1967 case CE_PANIC: 1968 if (sg_state == (sgen_state_t *)NULL) { 1969 cmn_err(level, "%s", buf); 1970 } else { 1971 scsi_log(sg_state->sgen_devinfo, "sgen", level, 1972 "%s", buf); 1973 } 1974 break; 1975 case SGEN_DIAG1: 1976 case SGEN_DIAG2: 1977 case SGEN_DIAG3: 1978 default: 1979 if (sg_state == (sgen_state_t *)NULL) { 1980 scsi_log(NULL, "sgen", CE_CONT, "%s", buf); 1981 } else { 1982 scsi_log(sg_state->sgen_devinfo, "sgen", CE_CONT, 1983 "%s", buf); 1984 } 1985 } 1986 } 1987 1988 /* 1989 * sgen_dump_cdb() 1990 * dump out the contents of a cdb. Take care that 'label' is not too 1991 * large, or 'buf' could overflow. 1992 */ 1993 static void 1994 sgen_dump_cdb(sgen_state_t *sg_state, const char *label, 1995 union scsi_cdb *cdb, int cdblen) 1996 { 1997 static char hex[] = "0123456789abcdef"; 1998 char *buf, *p; 1999 size_t nbytes; 2000 int i; 2001 uchar_t *cdbp = (uchar_t *)cdb; 2002 2003 /* 2004 * fastpath-- if we're not able to print out, don't do all of this 2005 * extra work. 2006 */ 2007 if (!sgen_diag_ok(sg_state, SGEN_DIAG3)) 2008 return; 2009 2010 /* 2011 * 3 characters for each byte (because of the ' '), plus the size of 2012 * the label, plus the trailing ']' and the null character. 2013 */ 2014 nbytes = 3 * cdblen + strlen(label) + strlen(" CDB = [") + 2; 2015 buf = kmem_alloc(nbytes, KM_SLEEP); 2016 (void) sprintf(buf, "%s CDB = [", label); 2017 p = &buf[strlen(buf)]; 2018 for (i = 0; i < cdblen; i++, cdbp++) { 2019 if (i > 0) 2020 *p++ = ' '; 2021 *p++ = hex[(*cdbp >> 4) & 0x0f]; 2022 *p++ = hex[*cdbp & 0x0f]; 2023 } 2024 *p++ = ']'; 2025 *p = 0; 2026 sgen_log(sg_state, SGEN_DIAG3, buf); 2027 kmem_free(buf, nbytes); 2028 } 2029 2030 static void 2031 sgen_dump_sense(sgen_state_t *sg_state, size_t rqlen, uchar_t *rqbuf) 2032 { 2033 static char hex[] = "0123456789abcdef"; 2034 char *buf, *p; 2035 size_t nbytes; 2036 int i; 2037 2038 /* 2039 * fastpath-- if we're not able to print out, don't do all of this 2040 * extra work. 2041 */ 2042 if (!sgen_diag_ok(sg_state, SGEN_DIAG3)) 2043 return; 2044 2045 /* 2046 * 3 characters for each byte (because of the ' '), plus the size of 2047 * the label, plus the trailing ']' and the null character. 2048 */ 2049 nbytes = 3 * rqlen + strlen(" SENSE = [") + 2; 2050 buf = kmem_alloc(nbytes, KM_SLEEP); 2051 (void) sprintf(buf, "SENSE = ["); 2052 p = &buf[strlen(buf)]; 2053 for (i = 0; i < rqlen; i++, rqbuf++) { 2054 if (i > 0) 2055 *p++ = ' '; 2056 *p++ = hex[(*rqbuf >> 4) & 0x0f]; 2057 *p++ = hex[*rqbuf & 0x0f]; 2058 } 2059 *p++ = ']'; 2060 *p = 0; 2061 sgen_log(sg_state, SGEN_DIAG3, buf); 2062 kmem_free(buf, nbytes); 2063 } 2064