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