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