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