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(7I) 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. */
46static	char *sgen_label	= NULL;
47
48#define	DDI_NT_SGEN		"ddi_generic:scsi"
49
50static 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 */
114static int sgen_attach(dev_info_t *, ddi_attach_cmd_t);
115static int sgen_detach(dev_info_t *, ddi_detach_cmd_t);
116static int sgen_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
117static int sgen_probe(dev_info_t *);
118static int sgen_open(dev_t *, int, int, cred_t *);
119static int sgen_close(dev_t, int, int, cred_t *);
120static int sgen_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
121
122/*
123 * Configuration routines
124 */
125static int sgen_do_attach(dev_info_t *);
126static int sgen_setup_sense(sgen_state_t *);
127static void sgen_create_errstats(sgen_state_t *, int);
128static int sgen_do_suspend(dev_info_t *);
129static int sgen_do_detach(dev_info_t *);
130static void sgen_setup_binddb(dev_info_t *);
131static void sgen_cleanup_binddb();
132
133/*
134 * Packet transport routines
135 */
136static int  sgen_uscsi_cmd(dev_t, struct uscsi_cmd *, int);
137static int sgen_start(struct buf *);
138static int sgen_hold_cmdbuf(sgen_state_t *);
139static void sgen_rele_cmdbuf(sgen_state_t *);
140static int sgen_make_uscsi_cmd(sgen_state_t *, struct buf *);
141static void sgen_restart(void *);
142static void sgen_callback(struct scsi_pkt *);
143static int sgen_handle_autosense(sgen_state_t *, struct scsi_pkt *);
144static int sgen_handle_sense(sgen_state_t *);
145static int sgen_handle_incomplete(sgen_state_t *, struct scsi_pkt *);
146static int sgen_check_error(sgen_state_t *, struct buf *);
147static int sgen_initiate_sense(sgen_state_t *, int);
148static int sgen_scsi_transport(struct scsi_pkt *);
149static int sgen_tur(dev_t);
150
151/*
152 * Logging/debugging routines
153 */
154static void sgen_log(sgen_state_t  *, int,  const char *, ...);
155static int sgen_diag_ok(sgen_state_t *, int);
156static void sgen_dump_cdb(sgen_state_t *, const char *, union scsi_cdb *, int);
157static void sgen_dump_sense(sgen_state_t *, size_t, uchar_t *);
158
159int sgen_diag = 0;
160int sgen_sporadic_failures = 0;
161int sgen_force_manual_sense = 0;
162struct sgen_binddb sgen_binddb;
163
164static 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
182static 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
197static void *sgen_soft_state = NULL;
198
199static struct modldrv modldrv = {
200	&mod_driverops, "SCSI generic driver", &sgen_dev_ops
201};
202
203static struct modlinkage modlinkage = {
204	MODREV_1, &modldrv, NULL
205};
206
207int
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
226done:
227	sgen_log(NULL, SGEN_DIAG2, "%s sgen_init()", err ? "failed" : "done");
228	return (err);
229}
230
231int
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
244done:
245	sgen_log(NULL, SGEN_DIAG2, "%s sgen_fini()", err ? "failed" : "done");
246	return (err);
247}
248
249int
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 */
259static char *
260sgen_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 */
272static int
273sgen_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 */
290static void
291sgen_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 */
395static void
396sgen_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 */
429static int
430sgen_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 */
477static int
478sgen_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 */
504static int
505sgen_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;
528done:
529	return (retval);
530}
531
532/*
533 * sgen_attach()
534 * 	attach(9e) entrypoint.
535 */
536static int
537sgen_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
557done:
558	sgen_log(NULL, SGEN_DIAG2, "%s sgen_attach(), device unit-address @%s",
559	    err == DDI_SUCCESS ? "done" : "failed", ddi_get_name_addr(dip));
560	return (err);
561}
562
563/*
564 * sgen_do_attach()
565 *	handle the nitty details of attach.
566 */
567static int
568sgen_do_attach(dev_info_t *dip)
569{
570	int instance;
571	struct scsi_device *scsidevp;
572	sgen_state_t *sg_state;
573	uchar_t devtype;
574	struct scsi_inquiry *inq;
575
576	instance = ddi_get_instance(dip);
577
578	scsidevp = ddi_get_driver_private(dip);
579	ASSERT(scsidevp);
580
581	sgen_log(NULL, SGEN_DIAG2, "sgen_do_attach: instance = %d, "
582	    "device unit-address @%s", instance, ddi_get_name_addr(dip));
583
584	/*
585	 * Probe the device in order to get its device type to name the minor
586	 * node.
587	 */
588	if (scsi_probe(scsidevp, NULL_FUNC) != SCSIPROBE_EXISTS) {
589		scsi_unprobe(scsidevp);
590		return (DDI_FAILURE);
591	}
592
593	if (ddi_soft_state_zalloc(sgen_soft_state, instance) != DDI_SUCCESS) {
594		sgen_log(NULL, SGEN_DIAG1,
595		    "sgen_do_attach: failed to allocate softstate, "
596		    "device unit-address @%s", ddi_get_name_addr(dip));
597		scsi_unprobe(scsidevp);
598		return (DDI_FAILURE);
599	}
600
601	inq = scsidevp->sd_inq;		/* valid while device is probed... */
602	devtype = inq->inq_dtype;
603
604	sg_state = ddi_get_soft_state(sgen_soft_state, instance);
605	sg_state->sgen_scsidev = scsidevp;
606	scsidevp->sd_dev = dip;
607
608	/*
609	 * Now that sg_state->sgen_scsidev is initialized, it's ok to
610	 * call sgen_log with sg_state instead of NULL.
611	 */
612
613	/*
614	 * If the user specified the sgen_diag property, override the global
615	 * sgen_diag setting by setting sg_state's sgen_diag value.  If the
616	 * user gave a value out of range, default to '0'.
617	 */
618	sg_state->sgen_diag = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
619	    "sgen-diag", -1);
620
621	if (sg_state->sgen_diag != -1) {
622		if (sg_state->sgen_diag < 0 || sg_state->sgen_diag > 3)
623			sg_state->sgen_diag = 0;
624	}
625
626	sgen_log(sg_state, SGEN_DIAG2,
627	    "sgen_do_attach: sgen_soft_state=0x%p, instance=%d, "
628	    "device unit-address @%s",
629	    sgen_soft_state, instance, ddi_get_name_addr(dip));
630
631	/*
632	 * For simplicity, the minor number == the instance number
633	 */
634	if (ddi_create_minor_node(dip, sgen_typename(devtype), S_IFCHR,
635	    instance, DDI_NT_SGEN, NULL) == DDI_FAILURE) {
636		scsi_unprobe(scsidevp);
637		ddi_prop_remove_all(dip);
638		sgen_log(sg_state, SGEN_DIAG1,
639		    "sgen_do_attach: minor node creation failed, "
640		    "device unit-address @%s", ddi_get_name_addr(dip));
641		ddi_soft_state_free(sgen_soft_state, instance);
642		return (DDI_FAILURE);
643	}
644
645	/*
646	 * Allocate the command buffer, then create a condition variable for
647	 * managing it; mark the command buffer as free.
648	 */
649	sg_state->sgen_cmdbuf = getrbuf(KM_SLEEP);
650	cv_init(&sg_state->sgen_cmdbuf_cv, NULL, CV_DRIVER, NULL);
651
652	SGEN_CLR_BUSY(sg_state);
653	SGEN_CLR_OPEN(sg_state);
654	SGEN_CLR_SUSP(sg_state);
655
656	/*
657	 * If the hba and the target both support wide xfers, enable them.
658	 */
659	if (scsi_ifgetcap(&sg_state->sgen_scsiaddr, "wide-xfer", 1) != -1) {
660		int wide = 0;
661		if ((inq->inq_rdf == RDF_SCSI2) &&
662		    (inq->inq_wbus16 || inq->inq_wbus32))
663			wide = 1;
664		if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, "wide-xfer",
665		    wide, 1) == 1) {
666			sgen_log(sg_state, SGEN_DIAG1,
667			    "sgen_attach: wide xfer %s, "
668			    "device unit-address @%s",
669			    wide ? "enabled" : "disabled",
670			    ddi_get_name_addr(dip));
671		}
672	}
673
674	/*
675	 * This is a little debugging code-- since the codepath for auto-sense
676	 * and 'manual' sense is split, toggling this variable will make
677	 * sgen act as though the adapter in question can't do auto-sense.
678	 */
679	if (sgen_force_manual_sense) {
680		if (scsi_ifsetcap(&sg_state->sgen_scsiaddr, "auto-rqsense",
681		    0, 1) == 1) {
682			sg_state->sgen_arq_enabled = 0;
683		} else {
684			sg_state->sgen_arq_enabled = 1;
685		}
686	} else {
687		/*
688		 * Enable autorequest sense, if supported
689		 */
690		if (scsi_ifgetcap(&sg_state->sgen_scsiaddr,
691		    "auto-rqsense", 1) != 1) {
692			if (scsi_ifsetcap(&sg_state->sgen_scsiaddr,
693			    "auto-rqsense", 1, 1) == 1) {
694				sg_state->sgen_arq_enabled = 1;
695				sgen_log(sg_state, SGEN_DIAG1,
696				    "sgen_attach: auto-request-sense enabled, "
697				    "device unit-address @%s",
698				    ddi_get_name_addr(dip));
699			} else {
700				sg_state->sgen_arq_enabled = 0;
701				sgen_log(sg_state, SGEN_DIAG1,
702				    "sgen_attach: auto-request-sense disabled, "
703				    "device unit-address @%s",
704				    ddi_get_name_addr(dip));
705			}
706		} else {
707			sg_state->sgen_arq_enabled = 1;	/* already enabled */
708			sgen_log(sg_state, SGEN_DIAG1,
709			    "sgen_attach: auto-request-sense enabled, "
710			    "device unit-address @%s", ddi_get_name_addr(dip));
711		}
712	}
713
714	/*
715	 * Allocate plumbing for manually fetching sense.
716	 */
717	if (sgen_setup_sense(sg_state) != 0) {
718		freerbuf(sg_state->sgen_cmdbuf);
719		ddi_prop_remove_all(dip);
720		ddi_remove_minor_node(dip, NULL);
721		scsi_unprobe(scsidevp);
722		sgen_log(sg_state, SGEN_DIAG1,
723		    "sgen_do_attach: failed to setup request-sense, "
724		    "device unit-address @%s", ddi_get_name_addr(dip));
725		ddi_soft_state_free(sgen_soft_state, instance);
726		return (DDI_FAILURE);
727	}
728
729	sgen_create_errstats(sg_state, instance);
730
731	ddi_report_dev(dip);
732
733	return (DDI_SUCCESS);
734}
735
736/*
737 * sgen_setup_sense()
738 * 	Allocate a request sense packet so that if sgen needs to fetch sense
739 * 	data for the user, it will have a pkt ready to send.
740 */
741static int
742sgen_setup_sense(sgen_state_t *sg_state)
743{
744	struct buf *bp;
745	struct scsi_pkt *rqpkt;
746
747	if ((bp = scsi_alloc_consistent_buf(&sg_state->sgen_scsiaddr, NULL,
748	    MAX_SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
749		return (-1);
750	}
751
752	if ((rqpkt = scsi_init_pkt(&sg_state->sgen_scsiaddr, NULL, bp,
753	    CDB_GROUP0, 1, 0, PKT_CONSISTENT, SLEEP_FUNC, NULL)) == NULL) {
754		scsi_free_consistent_buf(bp);
755		return (-1);
756	}
757
758	/*
759	 * Make the results of running a SENSE available by filling out the
760	 * sd_sense field of the scsi device (sgen_sense is just an alias).
761	 */
762	sg_state->sgen_sense = (struct scsi_extended_sense *)bp->b_un.b_addr;
763
764	(void) scsi_setup_cdb((union scsi_cdb *)rqpkt->pkt_cdbp,
765	    SCMD_REQUEST_SENSE, 0, MAX_SENSE_LENGTH, 0);
766	FILL_SCSI1_LUN(sg_state->sgen_scsidev, rqpkt);
767
768	rqpkt->pkt_comp = sgen_callback;
769	rqpkt->pkt_time = SGEN_IO_TIME;
770	rqpkt->pkt_flags |= FLAG_SENSING;
771	rqpkt->pkt_private = sg_state;
772
773	sg_state->sgen_rqspkt = rqpkt;
774	sg_state->sgen_rqsbuf = bp;
775
776	return (0);
777}
778
779/*
780 * sgen_create_errstats()
781 * 	create named kstats for tracking occurrence of errors.
782 */
783static void
784sgen_create_errstats(sgen_state_t *sg_state, int instance)
785{
786	char kstatname[KSTAT_STRLEN];
787	struct sgen_errstats *stp;
788
789	(void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,err",
790	    sgen_label, instance);
791	sg_state->sgen_kstats = kstat_create("sgenerr", instance,
792	    kstatname, "device_error", KSTAT_TYPE_NAMED,
793	    sizeof (struct sgen_errstats) / sizeof (kstat_named_t),
794	    KSTAT_FLAG_PERSISTENT);
795
796	if (sg_state->sgen_kstats == NULL)
797		return;
798
799	stp = (struct sgen_errstats *)sg_state->sgen_kstats->ks_data;
800	kstat_named_init(&stp->sgen_trans_err, "transport_errors",
801	    KSTAT_DATA_UINT32);
802	kstat_named_init(&stp->sgen_restart, "command_restarts",
803	    KSTAT_DATA_UINT32);
804	kstat_named_init(&stp->sgen_incmp_err, "incomplete_commands",
805	    KSTAT_DATA_UINT32);
806	kstat_named_init(&stp->sgen_autosen_rcv, "autosense_occurred",
807	    KSTAT_DATA_UINT32);
808	kstat_named_init(&stp->sgen_autosen_bad, "autosense_undecipherable",
809	    KSTAT_DATA_UINT32);
810	kstat_named_init(&stp->sgen_sense_rcv, "sense_fetches",
811	    KSTAT_DATA_UINT32);
812	kstat_named_init(&stp->sgen_sense_bad, "sense_data_undecipherable",
813	    KSTAT_DATA_UINT32);
814	kstat_named_init(&stp->sgen_recov_err, "recoverable_error",
815	    KSTAT_DATA_UINT32);
816	kstat_named_init(&stp->sgen_nosen_err, "NO_SENSE_sense_key",
817	    KSTAT_DATA_UINT32);
818	kstat_named_init(&stp->sgen_unrecov_err, "unrecoverable_sense_error",
819	    KSTAT_DATA_UINT32);
820	sg_state->sgen_kstats->ks_private = sg_state;
821	sg_state->sgen_kstats->ks_update = nulldev;
822	kstat_install(sg_state->sgen_kstats);
823}
824
825/*
826 * sgen_detach()
827 * 	detach(9E) entrypoint
828 */
829static int
830sgen_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
831{
832	int instance;
833	sgen_state_t *sg_state;
834
835	instance = ddi_get_instance(dip);
836	sg_state = ddi_get_soft_state(sgen_soft_state, instance);
837
838	sgen_log(sg_state, SGEN_DIAG2, "in sgen_detach(), "
839	    "device unit-address @%s", ddi_get_name_addr(dip));
840
841	if (sg_state == NULL) {
842		sgen_log(NULL, SGEN_DIAG1,
843		    "sgen_detach: failed, no softstate found (%d), "
844		    "device unit-address @%s",
845		    instance, ddi_get_name_addr(dip));
846		return (DDI_FAILURE);
847	}
848
849	switch (cmd) {
850	case DDI_DETACH:
851		return (sgen_do_detach(dip));
852	case DDI_SUSPEND:
853		return (sgen_do_suspend(dip));
854	case DDI_PM_SUSPEND:
855	default:
856		return (DDI_FAILURE);
857	}
858}
859
860/*
861 * sgen_do_detach()
862 * 	detach the driver, tearing down resources.
863 */
864static int
865sgen_do_detach(dev_info_t *dip)
866{
867	int instance;
868	sgen_state_t *sg_state;
869	struct scsi_device *devp;
870
871	instance = ddi_get_instance(dip);
872	sg_state = ddi_get_soft_state(sgen_soft_state, instance);
873	ASSERT(sg_state);
874
875	sgen_log(sg_state, SGEN_DIAG2, "in sgen_do_detach(), "
876	    "device unit-address @%s", ddi_get_name_addr(dip));
877	devp = ddi_get_driver_private(dip);
878
879	mutex_enter(&sg_state->sgen_mutex);
880	if (SGEN_IS_BUSY(sg_state)) {
881		mutex_exit(&sg_state->sgen_mutex);
882		sgen_log(sg_state, SGEN_DIAG1, "sgen_do_detach: failed because "
883		    "device is busy, device unit-address @%s",
884		    ddi_get_name_addr(dip));
885		return (DDI_FAILURE);
886	}
887	mutex_exit(&sg_state->sgen_mutex);
888
889	/*
890	 * Final approach for detach.  Free data allocated by scsi_probe()
891	 * in attach.
892	 */
893	if (sg_state->sgen_restart_timeid)
894		(void) untimeout(sg_state->sgen_restart_timeid);
895	sg_state->sgen_restart_timeid = 0;
896	scsi_unprobe(devp);
897
898	/*
899	 * Free auto-request plumbing.
900	 */
901	scsi_free_consistent_buf(sg_state->sgen_rqsbuf);
902	scsi_destroy_pkt(sg_state->sgen_rqspkt);
903
904	if (sg_state->sgen_kstats) {
905		kstat_delete(sg_state->sgen_kstats);
906		sg_state->sgen_kstats = NULL;
907	}
908
909	/*
910	 * Free command buffer and clean up
911	 */
912	freerbuf(sg_state->sgen_cmdbuf);
913	cv_destroy(&sg_state->sgen_cmdbuf_cv);
914
915	sgen_log(sg_state, SGEN_DIAG2, "done sgen_do_detach(), "
916	    "device unit-address @%s", ddi_get_name_addr(dip));
917
918	ddi_soft_state_free(sgen_soft_state, instance);
919	ddi_prop_remove_all(dip);
920	ddi_remove_minor_node(dip, NULL);
921	return (DDI_SUCCESS);
922}
923
924/*
925 * sgen_do_suspend()
926 * 	suspend the driver.  This sets the "suspend" bit for this target if it
927 * 	is currently open; once resumed, the suspend bit will cause
928 * 	subsequent I/Os to fail.  We want user programs to close and
929 * 	reopen the device to acknowledge that they need to reexamine its
930 * 	state and do the right thing.
931 */
932static int
933sgen_do_suspend(dev_info_t *dip)
934{
935	int instance;
936	sgen_state_t *sg_state;
937
938	instance = ddi_get_instance(dip);
939	sg_state = ddi_get_soft_state(sgen_soft_state, instance);
940	ASSERT(sg_state);
941
942	sgen_log(sg_state, SGEN_DIAG2, "in sgen_do_suspend(), "
943	    "device unit-address @%s", ddi_get_name_addr(dip));
944
945	if (sg_state->sgen_restart_timeid) {
946		(void) untimeout(sg_state->sgen_restart_timeid);
947	}
948	sg_state->sgen_restart_timeid = 0;
949
950	mutex_enter(&sg_state->sgen_mutex);
951	if (SGEN_IS_OPEN(sg_state))
952		SGEN_SET_SUSP(sg_state);
953	mutex_exit(&sg_state->sgen_mutex);
954
955	sgen_log(sg_state, SGEN_DIAG2, "done sgen_do_suspend(), "
956	    "device unit-address @%s", ddi_get_name_addr(dip));
957	return (DDI_SUCCESS);
958}
959
960/*
961 * sgen_getinfo()
962 *	getinfo(9e) entrypoint.
963 */
964/*ARGSUSED*/
965static int
966sgen_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
967{
968	dev_t dev;
969	sgen_state_t *sg_state;
970	int instance, error;
971	switch (infocmd) {
972	case DDI_INFO_DEVT2DEVINFO:
973		dev = (dev_t)arg;
974		instance = getminor(dev);
975		if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance))
976		    == NULL)
977			return (DDI_FAILURE);
978		*result = (void *) sg_state->sgen_scsidev->sd_dev;
979		error = DDI_SUCCESS;
980		break;
981	case DDI_INFO_DEVT2INSTANCE:
982		dev = (dev_t)arg;
983		instance = getminor(dev);
984		*result = (void *)(uintptr_t)instance;
985		error = DDI_SUCCESS;
986		break;
987	default:
988		error = DDI_FAILURE;
989	}
990	return (error);
991}
992
993/*
994 * sgen_probe()
995 * 	probe(9e) entrypoint.  sgen *never* returns DDI_PROBE_PARTIAL, in
996 * 	order to avoid leaving around extra devinfos.  If sgen's binding
997 * 	rules indicate that it should bind, it returns DDI_PROBE_SUCCESS.
998 */
999static int
1000sgen_probe(dev_info_t *dip)
1001{
1002	struct scsi_device *scsidevp;
1003	int instance;
1004	int rval;
1005
1006	scsidevp = ddi_get_driver_private(dip);
1007	instance = ddi_get_instance(dip);
1008	sgen_log(NULL, SGEN_DIAG2, "in sgen_probe(): instance = %d, "
1009	    "device unit-address @%s", instance, ddi_get_name_addr(dip));
1010
1011	if (ddi_dev_is_sid(dip) == DDI_SUCCESS)
1012		return (DDI_PROBE_DONTCARE);
1013
1014	if (ddi_get_soft_state(sgen_soft_state, instance) != NULL)
1015		return (DDI_PROBE_FAILURE);
1016
1017	mutex_enter(&sgen_binddb.sdb_lock);
1018	if (sgen_binddb.sdb_init == 0) {
1019		sgen_setup_binddb(dip);
1020	}
1021	mutex_exit(&sgen_binddb.sdb_lock);
1022
1023	/*
1024	 * A small optimization: if it's impossible for sgen to bind to
1025	 * any devices, don't bother probing, just fail.
1026	 */
1027	if ((sgen_binddb.sdb_inq_nodes == NULL) &&
1028	    (sgen_binddb.sdb_type_nodes == NULL)) {
1029		return (DDI_PROBE_FAILURE);
1030	}
1031
1032	if (scsi_probe(scsidevp, NULL_FUNC) == SCSIPROBE_EXISTS) {
1033		if (sgen_get_binding(dip) == 0) {
1034			rval = DDI_PROBE_SUCCESS;
1035		}
1036	} else {
1037		rval = DDI_PROBE_FAILURE;
1038	}
1039	scsi_unprobe(scsidevp);
1040
1041	sgen_log(NULL, SGEN_DIAG2, "sgen_probe() %s, device unit-address @%s",
1042	    rval == DDI_PROBE_SUCCESS ? "succeeded" : "failed",
1043	    ddi_get_name_addr(dip));
1044	return (rval);
1045}
1046
1047/*
1048 * sgen_open()
1049 * 	open(9e) entrypoint.  sgen enforces a strict exclusive open policy per
1050 * 	target.
1051 */
1052/*ARGSUSED1*/
1053static int
1054sgen_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
1055{
1056	dev_t dev = *dev_p;
1057	sgen_state_t *sg_state;
1058	int instance;
1059
1060	instance = getminor(dev);
1061
1062	if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL)
1063		return (ENXIO);
1064
1065	sgen_log(sg_state, SGEN_DIAG2, "in sgen_open(): instance = %d",
1066	    instance);
1067
1068	mutex_enter(&sg_state->sgen_mutex);
1069
1070	/*
1071	 * Don't allow new opens of a suspended device until the last close has
1072	 * happened.  This is rather simplistic, but keeps the implementation
1073	 * straightforward.
1074	 */
1075	if (SGEN_IS_SUSP(sg_state)) {
1076		mutex_exit(&sg_state->sgen_mutex);
1077		return (EIO);
1078	}
1079
1080	/*
1081	 * Enforce exclusive access.
1082	 */
1083	if (SGEN_IS_EXCL(sg_state) ||
1084	    (SGEN_IS_OPEN(sg_state) && (flag & FEXCL))) {
1085		mutex_exit(&sg_state->sgen_mutex);
1086		return (EBUSY);
1087	}
1088
1089	if (flag & FEXCL)
1090		SGEN_SET_EXCL(sg_state);
1091
1092	SGEN_SET_OPEN(sg_state);
1093
1094	mutex_exit(&sg_state->sgen_mutex);
1095
1096	return (0);
1097}
1098
1099/*
1100 * sgen_close()
1101 * 	close(9e) entrypoint.
1102 */
1103/*ARGSUSED1*/
1104static int
1105sgen_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
1106{
1107	sgen_state_t *sg_state;
1108	int instance;
1109
1110	instance = getminor(dev);
1111
1112	if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL)
1113		return (ENXIO);
1114
1115	sgen_log(sg_state, SGEN_DIAG2, "in sgen_close(): instance = %d",
1116	    instance);
1117
1118	mutex_enter(&sg_state->sgen_mutex);
1119	SGEN_CLR_OPEN(sg_state);
1120	SGEN_CLR_EXCL(sg_state);
1121	SGEN_CLR_SUSP(sg_state); /* closing clears the 'I was suspended' bit */
1122	mutex_exit(&sg_state->sgen_mutex);
1123
1124	sgen_log(sg_state, SGEN_DIAG2, "done sgen_close()");
1125
1126	return (0);
1127}
1128
1129/*
1130 * sgen_ioctl()
1131 * 	sgen supports the USCSI(7I) ioctl interface.
1132 */
1133/*ARGSUSED4*/
1134static int
1135sgen_ioctl(dev_t dev,
1136    int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p)
1137{
1138	int retval = 0;
1139	sgen_state_t *sg_state;
1140	int instance;
1141
1142	instance = getminor(dev);
1143
1144	if ((sg_state = ddi_get_soft_state(sgen_soft_state, instance)) == NULL)
1145		return (ENXIO);
1146
1147	sgen_log(sg_state, SGEN_DIAG2, "in sgen_ioctl(): instance = %d",
1148	    instance);
1149
1150	/*
1151	 * If the driver has been suspended since the last open, fail all
1152	 * subsequent IO's so that the userland consumer reinitializes state.
1153	 */
1154	mutex_enter(&sg_state->sgen_mutex);
1155	if (SGEN_IS_SUSP(sg_state)) {
1156		mutex_exit(&sg_state->sgen_mutex);
1157		sgen_log(sg_state, SGEN_DIAG1, "sgen_ioctl: returning EIO: "
1158		    "driver instance %d was previously suspended", instance);
1159		return (EIO);
1160	}
1161	mutex_exit(&sg_state->sgen_mutex);
1162
1163	switch (cmd) {
1164	case SGEN_IOC_DIAG: {
1165		if (arg > 3) {
1166			arg = 0;
1167		}
1168		sg_state->sgen_diag = (int)arg;
1169		retval = 0;
1170		break;
1171	}
1172
1173	case SGEN_IOC_READY: {
1174		if (sgen_tur(dev) != 0) {
1175			retval = EIO;
1176		} else {
1177			retval = 0;
1178		}
1179		break;
1180	}
1181
1182	case USCSICMD:
1183		retval = sgen_uscsi_cmd(dev, (struct uscsi_cmd *)arg, flag);
1184		break;
1185
1186	default:
1187		retval = ENOTTY;
1188	}
1189
1190	sgen_log(sg_state, SGEN_DIAG2, "done sgen_ioctl(), returning %d",
1191	    retval);
1192
1193	return (retval);
1194}
1195
1196/*
1197 * sgen_uscsi_cmd()
1198 * 	Setup, configuration and teardown for a uscsi(7I) command
1199 */
1200/*ARGSUSED*/
1201static int
1202sgen_uscsi_cmd(dev_t dev, struct uscsi_cmd *ucmd, int flag)
1203{
1204	struct uscsi_cmd	*uscmd;
1205	struct buf	*bp;
1206	sgen_state_t	*sg_state;
1207	enum uio_seg	uioseg;
1208	int	instance;
1209	int	flags;
1210	int	err;
1211
1212	instance = getminor(dev);
1213
1214	sg_state = ddi_get_soft_state(sgen_soft_state, instance);
1215	ASSERT(sg_state);
1216
1217	sgen_log(sg_state, SGEN_DIAG2, "in sgen_uscsi_cmd(): instance = %d",
1218	    instance);
1219
1220	/*
1221	 * At this point, we start affecting state relevant to the target,
1222	 * so access needs to be serialized.
1223	 */
1224	if (sgen_hold_cmdbuf(sg_state) != 0) {
1225		sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: interrupted");
1226		return (EINTR);
1227	}
1228
1229	err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag,
1230	    &sg_state->sgen_scsiaddr, &uscmd);
1231	if (err != 0) {
1232		sgen_rele_cmdbuf(sg_state);
1233		sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: "
1234		    "scsi_uscsi_alloc_and_copyin failed\n");
1235		return (err);
1236	}
1237
1238	/*
1239	 * Clear out undesirable command flags
1240	 */
1241	flags = (uscmd->uscsi_flags & ~(USCSI_NOINTR | USCSI_NOPARITY |
1242	    USCSI_OTAG | USCSI_HTAG | USCSI_HEAD));
1243	if (flags != uscmd->uscsi_flags) {
1244		sgen_log(sg_state, SGEN_DIAG1, "sgen_uscsi_cmd: cleared "
1245		    "unsafe uscsi_flags 0x%x", uscmd->uscsi_flags & ~flags);
1246		uscmd->uscsi_flags = flags;
1247	}
1248
1249	if (uscmd->uscsi_cdb != NULL) {
1250		sgen_dump_cdb(sg_state, "sgen_uscsi_cmd: ",
1251		    (union scsi_cdb *)uscmd->uscsi_cdb, uscmd->uscsi_cdblen);
1252	}
1253
1254	/*
1255	 * Stash the sense buffer into sgen_rqs_sen for convenience.
1256	 */
1257	sg_state->sgen_rqs_sen = uscmd->uscsi_rqbuf;
1258
1259	bp = sg_state->sgen_cmdbuf;
1260	bp->av_back = NULL;
1261	bp->av_forw = NULL;
1262	bp->b_private = (struct buf *)uscmd;
1263	uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
1264
1265	err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, sgen_start, bp, NULL);
1266
1267	if (sg_state->sgen_cmdpkt != NULL) {
1268		uscmd->uscsi_status = SCBP_C(sg_state->sgen_cmdpkt);
1269	} else {
1270		uscmd->uscsi_status = 0;
1271	}
1272
1273	sgen_log(sg_state, SGEN_DIAG3, "sgen_uscsi_cmd: awake from waiting "
1274	    "for command.  Status is 0x%x", uscmd->uscsi_status);
1275
1276	if (uscmd->uscsi_rqbuf != NULL) {
1277		int rqlen = uscmd->uscsi_rqlen - uscmd->uscsi_rqresid;
1278		sgen_dump_sense(sg_state, rqlen,
1279		    (uchar_t *)uscmd->uscsi_rqbuf);
1280	}
1281
1282	(void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd);
1283
1284	if (sg_state->sgen_cmdpkt != NULL) {
1285		scsi_destroy_pkt(sg_state->sgen_cmdpkt);
1286		sg_state->sgen_cmdpkt = NULL;
1287	}
1288
1289	/*
1290	 * After this point, we can't touch per-target state.
1291	 */
1292	sgen_rele_cmdbuf(sg_state);
1293
1294	sgen_log(sg_state, SGEN_DIAG2, "done sgen_uscsi_cmd()");
1295
1296	return (err);
1297}
1298
1299/*
1300 * sgen_hold_cmdbuf()
1301 * 	Acquire a lock on the command buffer for the given target.  Returns
1302 * 	non-zero if interrupted.
1303 */
1304static int
1305sgen_hold_cmdbuf(sgen_state_t *sg_state)
1306{
1307	mutex_enter(&sg_state->sgen_mutex);
1308	while (SGEN_IS_BUSY(sg_state)) {
1309		if (!cv_wait_sig(&sg_state->sgen_cmdbuf_cv,
1310		    &sg_state->sgen_mutex)) {
1311			mutex_exit(&sg_state->sgen_mutex);
1312			return (-1);
1313		}
1314	}
1315	SGEN_SET_BUSY(sg_state);
1316	mutex_exit(&sg_state->sgen_mutex);
1317	return (0);
1318}
1319
1320/*
1321 * sgen_rele_cmdbuf()
1322 * 	release the command buffer for a particular target.
1323 */
1324static void
1325sgen_rele_cmdbuf(sgen_state_t *sg_state)
1326{
1327	mutex_enter(&sg_state->sgen_mutex);
1328	SGEN_CLR_BUSY(sg_state);
1329	cv_signal(&sg_state->sgen_cmdbuf_cv);
1330	mutex_exit(&sg_state->sgen_mutex);
1331}
1332
1333/*
1334 * sgen_start()
1335 * 	Transport a uscsi command; this is invoked by physio() or directly
1336 * 	by sgen_uscsi_cmd().
1337 */
1338static int
1339sgen_start(struct buf *bp)
1340{
1341	sgen_state_t *sg_state;
1342	dev_t dev = bp->b_edev;
1343	int trans_err;
1344
1345	if ((sg_state = ddi_get_soft_state(sgen_soft_state,
1346	    getminor(dev))) == NULL) {
1347		bp->b_resid = bp->b_bcount;
1348		bioerror(bp, ENXIO);
1349		biodone(bp);
1350		return (ENXIO);
1351	}
1352
1353	/*
1354	 * Sanity checks - command should not be complete, no packet should
1355	 * be allocated, and there ought to be a uscsi cmd in b_private
1356	 */
1357	ASSERT(bp == sg_state->sgen_cmdbuf && sg_state->sgen_cmdpkt == NULL);
1358	ASSERT((bp->b_flags & B_DONE) == 0);
1359	ASSERT(bp->b_private);
1360	if (sgen_make_uscsi_cmd(sg_state, bp) != 0) {
1361		bp->b_resid = bp->b_bcount;
1362		bioerror(bp, EFAULT);
1363		biodone(bp);
1364		return (EFAULT);
1365	}
1366
1367	ASSERT(sg_state->sgen_cmdpkt != NULL);
1368
1369	/*
1370	 * Clear out the residual and error fields
1371	 */
1372	bp->b_resid = 0;
1373	bp->b_error = 0;
1374
1375	trans_err = sgen_scsi_transport(sg_state->sgen_cmdpkt);
1376	switch (trans_err) {
1377	case TRAN_ACCEPT:
1378		break;
1379	case TRAN_BUSY:
1380		sgen_log(sg_state, SGEN_DIAG2,
1381		    "sgen_start: scsi_transport() returned TRAN_BUSY");
1382		sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state,
1383		    SGEN_BSY_TIMEOUT);
1384		break;
1385	default:
1386		/*
1387		 * Indicate there has been an I/O transfer error.
1388		 * Be done with the command.
1389		 */
1390		mutex_enter(&sg_state->sgen_mutex);
1391		SGEN_DO_ERRSTATS(sg_state, sgen_trans_err);
1392		mutex_exit(&sg_state->sgen_mutex);
1393		sgen_log(sg_state, SGEN_DIAG2, "sgen_start: scsi_transport() "
1394		    "returned %d", trans_err);
1395		bioerror(bp, EIO);
1396		biodone(bp);
1397		return (EIO);
1398	}
1399	sgen_log(sg_state, SGEN_DIAG2, "sgen_start: b_flags 0x%x", bp->b_flags);
1400	return (0);
1401}
1402
1403/*
1404 * sgen_scsi_transport()
1405 * 	a simple scsi_transport() wrapper which can be configured to inject
1406 * 	sporadic errors for testing.
1407 */
1408static int
1409sgen_scsi_transport(struct scsi_pkt *pkt)
1410{
1411	int trans_err;
1412	static int cnt = 0;
1413	sgen_state_t *sg_state = pkt->pkt_private;
1414
1415	if (sgen_sporadic_failures == 0) {
1416		return (scsi_transport(pkt));
1417	}
1418
1419	cnt = (cnt * 2416 + 374441) % 1771875;	/* borrowed from kmem.c */
1420	if (cnt % 40 == 1) {
1421		sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: "
1422		    "injecting sporadic BUSY");
1423		trans_err = TRAN_BUSY;
1424	} else if (cnt % 40 == 2) {
1425		sgen_log(sg_state, SGEN_DIAG1, "sgen_scsi_transport: "
1426		    "injecting sporadic BADPKT");
1427		trans_err = TRAN_BADPKT;
1428	} else {
1429		/*
1430		 * Most of the time we take the normal path
1431		 */
1432		trans_err = scsi_transport(pkt);
1433	}
1434	return (trans_err);
1435}
1436
1437/*
1438 * sgen_make_uscsi_cmd()
1439 * 	Initialize a SCSI packet usable for USCSI.
1440 */
1441static int
1442sgen_make_uscsi_cmd(sgen_state_t *sg_state, struct buf *bp)
1443{
1444	struct scsi_pkt	*pkt;
1445	struct uscsi_cmd *ucmd;
1446	int stat_size = 1;
1447	int flags = 0;
1448
1449	ASSERT(bp);
1450
1451	sgen_log(sg_state, SGEN_DIAG2, "in sgen_make_uscsi_cmd()");
1452
1453	ucmd = (struct uscsi_cmd *)bp->b_private;
1454
1455	if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1456		if (ucmd->uscsi_rqlen > SENSE_LENGTH) {
1457			stat_size = (int)(ucmd->uscsi_rqlen) +
1458			    sizeof (struct scsi_arq_status) -
1459			    sizeof (struct scsi_extended_sense);
1460			flags = PKT_XARQ;
1461		} else {
1462			stat_size = sizeof (struct scsi_arq_status);
1463		}
1464	}
1465
1466	sgen_log(sg_state, SGEN_DIAG3, "sgen_make_uscsi_cmd: b_bcount = %ld",
1467	    bp->b_bcount);
1468	pkt = scsi_init_pkt(&sg_state->sgen_scsiaddr,
1469	    NULL,			/* in_pkt - null so it'll be alloc'd */
1470	    bp->b_bcount ? bp : NULL,	/* buf structure for data xfer */
1471	    ucmd->uscsi_cdblen,		/* cmdlen */
1472	    stat_size,			/* statuslen */
1473	    0,				/* privatelen */
1474	    flags,			/* flags */
1475	    SLEEP_FUNC,			/* callback */
1476	    (caddr_t)sg_state);		/* callback_arg */
1477
1478	if (pkt == NULL) {
1479		sgen_log(sg_state, SGEN_DIAG2, "failed sgen_make_uscsi_cmd()");
1480		return (-1);
1481	}
1482
1483	pkt->pkt_comp = sgen_callback;
1484	pkt->pkt_private = sg_state;
1485	sg_state->sgen_cmdpkt = pkt;
1486
1487	/*
1488	 * We *don't* call scsi_setup_cdb here, as is customary, since the
1489	 * user could specify a command from one group, but pass cdblen
1490	 * as something totally different.  If cdblen is smaller than expected,
1491	 * this results in scsi_setup_cdb writing past the end of the cdb.
1492	 */
1493	bcopy(ucmd->uscsi_cdb, pkt->pkt_cdbp, ucmd->uscsi_cdblen);
1494	if (ucmd->uscsi_cdblen >= CDB_GROUP0) {
1495		FILL_SCSI1_LUN(sg_state->sgen_scsidev, pkt);
1496	}
1497
1498	if (ucmd->uscsi_timeout > 0)
1499		pkt->pkt_time = ucmd->uscsi_timeout;
1500	else
1501		pkt->pkt_time = SGEN_IO_TIME;
1502
1503	/*
1504	 * Set packet options
1505	 */
1506	if (ucmd->uscsi_flags & USCSI_SILENT)
1507		pkt->pkt_flags |= FLAG_SILENT;
1508	if (ucmd->uscsi_flags & USCSI_ISOLATE)
1509		pkt->pkt_flags |= FLAG_ISOLATE;
1510	if (ucmd->uscsi_flags & USCSI_DIAGNOSE)
1511		pkt->pkt_flags |= FLAG_DIAGNOSE;
1512	if (ucmd->uscsi_flags & USCSI_RENEGOT) {
1513		pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC;
1514	}
1515
1516	/* Transfer uscsi information to scsi_pkt */
1517	(void) scsi_uscsi_pktinit(ucmd, pkt);
1518
1519	sgen_log(sg_state, SGEN_DIAG2, "done sgen_make_uscsi_cmd()");
1520	return (0);
1521}
1522
1523
1524/*
1525 * sgen_restart()
1526 * 	sgen_restart() is called after a timeout, when a command has been
1527 * 	postponed due to a TRAN_BUSY response from the HBA.
1528 */
1529static void
1530sgen_restart(void *arg)
1531{
1532	sgen_state_t *sg_state = (sgen_state_t *)arg;
1533	struct scsi_pkt *pkt;
1534	struct buf *bp;
1535
1536	sgen_log(sg_state, SGEN_DIAG2, "in sgen_restart()");
1537
1538	bp = sg_state->sgen_cmdbuf;
1539	pkt = sg_state->sgen_cmdpkt;
1540	ASSERT(bp && pkt);
1541
1542	SGEN_DO_ERRSTATS(sg_state, sgen_restart);
1543
1544	/*
1545	 * If the packet is marked with the sensing flag, sgen is off running
1546	 * a request sense, and *that packet* is what needs to be restarted.
1547	 */
1548	if (pkt->pkt_flags & FLAG_SENSING) {
1549		sgen_log(sg_state, SGEN_DIAG3,
1550		    "sgen_restart: restarting REQUEST SENSE");
1551		pkt = sg_state->sgen_rqspkt;
1552	}
1553
1554	if (sgen_scsi_transport(pkt) != TRAN_ACCEPT) {
1555		bp->b_resid = bp->b_bcount;
1556		bioerror(bp, EIO);
1557		biodone(bp);
1558	}
1559}
1560
1561/*
1562 * sgen_callback()
1563 * 	Command completion processing
1564 *
1565 * 	sgen's completion processing is very pessimistic-- it does not retry
1566 * 	failed commands; instead, it allows the user application to make
1567 * 	decisions about what has gone wrong.
1568 */
1569static void
1570sgen_callback(struct scsi_pkt *pkt)
1571{
1572	sgen_state_t *sg_state;
1573	struct uscsi_cmd *ucmd;
1574	struct buf *bp;
1575	int action;
1576
1577	sg_state = pkt->pkt_private;
1578	/*
1579	 * bp should always be the command buffer regardless of whether
1580	 * this is a command completion or a request-sense completion.
1581	 * This is because there is no need to biodone() the sense buf
1582	 * when it completes-- we want to biodone() the actual command buffer!
1583	 */
1584	bp = sg_state->sgen_cmdbuf;
1585	if (pkt->pkt_flags & FLAG_SENSING) {
1586		ASSERT(pkt == sg_state->sgen_rqspkt);
1587		sgen_log(sg_state, SGEN_DIAG2,
1588		    "in sgen_callback() (SENSE completion callback)");
1589	} else {
1590		ASSERT(pkt == sg_state->sgen_cmdpkt);
1591		sgen_log(sg_state, SGEN_DIAG2,
1592		    "in sgen_callback() (command completion callback)");
1593	}
1594	ucmd = (struct uscsi_cmd *)bp->b_private;
1595
1596	sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: reason=0x%x resid=%ld "
1597	    "state=0x%x", pkt->pkt_reason, pkt->pkt_resid, pkt->pkt_state);
1598
1599	/* Transfer scsi_pkt information to uscsi */
1600	(void) scsi_uscsi_pktfini(pkt, ucmd);
1601
1602	if (pkt->pkt_reason != CMD_CMPLT) {
1603		/*
1604		 * The command did not complete.
1605		 */
1606		sgen_log(sg_state, SGEN_DIAG3,
1607		    "sgen_callback: command did not complete");
1608		action = sgen_handle_incomplete(sg_state, pkt);
1609	} else if (sg_state->sgen_arq_enabled &&
1610	    (pkt->pkt_state & STATE_ARQ_DONE)) {
1611		/*
1612		 * The auto-rqsense happened, and the packet has a filled-in
1613		 * scsi_arq_status structure, pointed to by pkt_scbp.
1614		 */
1615		sgen_log(sg_state, SGEN_DIAG3,
1616		    "sgen_callback: received auto-requested sense");
1617		action = sgen_handle_autosense(sg_state, pkt);
1618		ASSERT(action != FETCH_SENSE);
1619	} else if (pkt->pkt_flags & FLAG_SENSING) {
1620		/*
1621		 * sgen was running a REQUEST SENSE. Decode the sense data and
1622		 * decide what to do next.
1623		 *
1624		 * Clear FLAG_SENSING on the original packet for completeness.
1625		 */
1626		sgen_log(sg_state, SGEN_DIAG3, "sgen_callback: received sense");
1627		sg_state->sgen_cmdpkt->pkt_flags &= ~FLAG_SENSING;
1628		action = sgen_handle_sense(sg_state);
1629		ASSERT(action != FETCH_SENSE);
1630	} else {
1631		/*
1632		 * Command completed and we're not getting sense. Check for
1633		 * errors and decide what to do next.
1634		 */
1635		sgen_log(sg_state, SGEN_DIAG3,
1636		    "sgen_callback: command appears complete");
1637		action = sgen_check_error(sg_state, bp);
1638	}
1639
1640	switch (action) {
1641	case FETCH_SENSE:
1642		/*
1643		 * If there is sense to fetch, break out to prevent biodone'ing
1644		 * until the sense fetch is complete.
1645		 */
1646		if (sgen_initiate_sense(sg_state,
1647		    scsi_pkt_allocated_correctly(pkt) ?
1648		    pkt->pkt_path_instance : 0) == 0)
1649			break;
1650		/*FALLTHROUGH*/
1651	case COMMAND_DONE_ERROR:
1652		bp->b_resid = bp->b_bcount;
1653		bioerror(bp, EIO);
1654		/*FALLTHROUGH*/
1655	case COMMAND_DONE:
1656		biodone(bp);
1657		break;
1658	default:
1659		ASSERT(0);
1660		break;
1661	}
1662
1663	sgen_log(sg_state, SGEN_DIAG2, "done sgen_callback()");
1664}
1665
1666/*
1667 * sgen_initiate_sense()
1668 *	Send the sgen_rqspkt to the target, thereby requesting sense data.
1669 */
1670static int
1671sgen_initiate_sense(sgen_state_t *sg_state, int path_instance)
1672{
1673	/* use same path_instance as command */
1674	if (scsi_pkt_allocated_correctly(sg_state->sgen_rqspkt))
1675		sg_state->sgen_rqspkt->pkt_path_instance = path_instance;
1676
1677	switch (sgen_scsi_transport(sg_state->sgen_rqspkt)) {
1678	case TRAN_ACCEPT:
1679		sgen_log(sg_state, SGEN_DIAG3, "sgen_initiate_sense: "
1680		    "sense fetch transport accepted.");
1681		return (0);
1682	case TRAN_BUSY:
1683		sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: "
1684		    "sense fetch transport busy, setting timeout.");
1685		sg_state->sgen_restart_timeid = timeout(sgen_restart, sg_state,
1686		    SGEN_BSY_TIMEOUT);
1687		return (0);
1688	default:
1689		sgen_log(sg_state, SGEN_DIAG2, "sgen_initiate_sense: "
1690		    "sense fetch transport failed or busy.");
1691		return (-1);
1692	}
1693}
1694
1695/*
1696 * sgen_handle_incomplete()
1697 * 	sgen is pessimistic, but also careful-- it doesn't try to retry
1698 * 	incomplete commands, but it also doesn't go resetting devices;
1699 * 	it is hard to tell if the device will be tolerant of that sort
1700 * 	of prodding.
1701 *
1702 * 	This routine has been left as a guide for the future--- the
1703 * 	current administration's hands-off policy may need modification.
1704 */
1705/*ARGSUSED*/
1706static int
1707sgen_handle_incomplete(sgen_state_t *sg_state, struct scsi_pkt *pkt)
1708{
1709	SGEN_DO_ERRSTATS(sg_state, sgen_incmp_err);
1710	return (COMMAND_DONE_ERROR);
1711}
1712
1713/*
1714 * sgen_handle_autosense()
1715 * 	Deal with SENSE data acquired automatically via the auto-request-sense
1716 * 	facility.
1717 *
1718 * 	Sgen takes a pessimistic view of things-- it doesn't retry commands,
1719 * 	and unless the device recovered from the problem, this routine returns
1720 * 	COMMAND_DONE_ERROR.
1721 */
1722static int
1723sgen_handle_autosense(sgen_state_t *sg_state, struct scsi_pkt *pkt)
1724{
1725	struct scsi_arq_status *arqstat;
1726	struct uscsi_cmd *ucmd =
1727	    (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private;
1728	int amt;
1729
1730	arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp);
1731
1732	SGEN_DO_ERRSTATS(sg_state, sgen_autosen_rcv);
1733
1734	if (arqstat->sts_rqpkt_reason != CMD_CMPLT) {
1735		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: ARQ"
1736		    "failed to complete.");
1737		SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad);
1738		return (COMMAND_DONE_ERROR);
1739	}
1740
1741	if (pkt->pkt_state & STATE_XARQ_DONE) {
1742		amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
1743	} else {
1744		if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) {
1745			amt = MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
1746		} else {
1747			amt = SENSE_LENGTH - arqstat->sts_rqpkt_resid;
1748		}
1749	}
1750
1751	if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1752		ucmd->uscsi_rqstatus = *((char *)&arqstat->sts_rqpkt_status);
1753		uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
1754		ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
1755		ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen);
1756		bcopy(&(arqstat->sts_sensedata), sg_state->sgen_rqs_sen, rqlen);
1757		sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_autosense: "
1758		    "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n",
1759		    ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
1760	}
1761
1762	if (arqstat->sts_rqpkt_status.sts_chk) {
1763		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got "
1764		    "check condition on auto request sense!");
1765		SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad);
1766		return (COMMAND_DONE_ERROR);
1767	}
1768
1769	if (((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0) ||
1770	    (amt == 0)) {
1771		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: got "
1772		    "auto-sense, but it contains no data!");
1773		SGEN_DO_ERRSTATS(sg_state, sgen_autosen_bad);
1774		return (COMMAND_DONE_ERROR);
1775	}
1776
1777	/*
1778	 * Stuff the sense data pointer into sgen_sense for later retrieval
1779	 */
1780	sg_state->sgen_sense = &arqstat->sts_sensedata;
1781
1782	/*
1783	 * Now, check to see whether we got enough sense data to make any
1784	 * sense out if it (heh-heh).
1785	 */
1786	if (amt < SUN_MIN_SENSE_LENGTH) {
1787		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_autosense: not "
1788		    "enough auto sense data");
1789		return (COMMAND_DONE_ERROR);
1790	}
1791
1792	switch (arqstat->sts_sensedata.es_key) {
1793	case KEY_RECOVERABLE_ERROR:
1794		SGEN_DO_ERRSTATS(sg_state, sgen_recov_err);
1795		break;
1796	case KEY_NO_SENSE:
1797		SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err);
1798		break;
1799	default:
1800		SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err);
1801		break;
1802	}
1803
1804	return (COMMAND_DONE);
1805}
1806
1807/*
1808 * sgen_handle_sense()
1809 * 	Examine sense data that was manually fetched from the target.
1810 */
1811static int
1812sgen_handle_sense(sgen_state_t *sg_state)
1813{
1814	struct scsi_pkt *rqpkt = sg_state->sgen_rqspkt;
1815	struct scsi_status *rqstatus = (struct scsi_status *)rqpkt->pkt_scbp;
1816	struct uscsi_cmd *ucmd =
1817	    (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private;
1818	int amt;
1819
1820	SGEN_DO_ERRSTATS(sg_state, sgen_sense_rcv);
1821
1822	amt = MAX_SENSE_LENGTH - rqpkt->pkt_resid;
1823
1824	if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1825		ucmd->uscsi_rqstatus = *((char *)rqstatus);
1826		uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
1827		ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
1828		ASSERT(ucmd->uscsi_rqlen && sg_state->sgen_rqs_sen);
1829		bcopy(sg_state->sgen_sense, sg_state->sgen_rqs_sen, rqlen);
1830		sgen_log(sg_state, SGEN_DIAG2, "sgen_handle_sense: "
1831		    "uscsi_rqstatus=0x%x uscsi_rqresid=%d\n",
1832		    ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
1833	}
1834
1835	if (rqstatus->sts_busy) {
1836		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got busy "
1837		    "on request sense");
1838		SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1839		return (COMMAND_DONE_ERROR);
1840	}
1841
1842	if (rqstatus->sts_chk) {
1843		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got check "
1844		    "condition on request sense!");
1845		SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1846		return (COMMAND_DONE_ERROR);
1847	}
1848
1849	if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) {
1850		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: got "
1851		    "sense, but it contains no data");
1852		SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1853		return (COMMAND_DONE_ERROR);
1854	}
1855
1856	/*
1857	 * Now, check to see whether we got enough sense data to make any
1858	 * sense out if it (heh-heh).
1859	 */
1860	if (amt < SUN_MIN_SENSE_LENGTH) {
1861		sgen_log(sg_state, SGEN_DIAG1, "sgen_handle_sense: not "
1862		    "enough sense data");
1863		SGEN_DO_ERRSTATS(sg_state, sgen_sense_bad);
1864		return (COMMAND_DONE_ERROR);
1865	}
1866
1867	/*
1868	 * Decode the sense data-- this was deposited here for us by the
1869	 * setup in sgen_do_attach(). (note that sgen_sense is an alias for
1870	 * the sd_sense field in the scsi_device).
1871	 */
1872	sgen_log(sg_state, SGEN_DIAG1, "Sense key is %s [0x%x]",
1873	    scsi_sname(sg_state->sgen_sense->es_key),
1874	    sg_state->sgen_sense->es_key);
1875	switch (sg_state->sgen_sense->es_key) {
1876	case KEY_RECOVERABLE_ERROR:
1877		SGEN_DO_ERRSTATS(sg_state, sgen_recov_err);
1878		break;
1879	case KEY_NO_SENSE:
1880		SGEN_DO_ERRSTATS(sg_state, sgen_nosen_err);
1881		break;
1882	default:
1883		SGEN_DO_ERRSTATS(sg_state, sgen_unrecov_err);
1884		break;
1885	}
1886
1887	return (COMMAND_DONE);
1888}
1889
1890/*
1891 * sgen_check_error()
1892 * 	examine the command packet for abnormal completion.
1893 *
1894 *	sgen_check_error should only be called at the completion of the
1895 *	command packet.
1896 */
1897static int
1898sgen_check_error(sgen_state_t *sg_state, struct buf *bp)
1899{
1900	struct scsi_pkt *pkt = sg_state->sgen_cmdpkt;
1901	struct scsi_status *status = (struct scsi_status *)pkt->pkt_scbp;
1902	struct uscsi_cmd *ucmd =
1903	    (struct uscsi_cmd *)sg_state->sgen_cmdbuf->b_private;
1904
1905	if (status->sts_busy) {
1906		sgen_log(sg_state, SGEN_DIAG1,
1907		    "sgen_check_error: target is busy");
1908		return (COMMAND_DONE_ERROR);
1909	}
1910
1911	/*
1912	 * pkt_resid will reflect, at this point, a residual of how many bytes
1913	 * were not transferred; a non-zero pkt_resid is an error.
1914	 */
1915	if (pkt->pkt_resid) {
1916		bp->b_resid += pkt->pkt_resid;
1917	}
1918
1919	if (status->sts_chk) {
1920		if (ucmd->uscsi_flags & USCSI_RQENABLE) {
1921			if (sg_state->sgen_arq_enabled) {
1922				sgen_log(sg_state, SGEN_DIAG1,
1923				    "sgen_check_error: strange: target "
1924				    "indicates CHECK CONDITION with auto-sense "
1925				    "enabled.");
1926			}
1927			sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: "
1928			    "target ready for sense fetch");
1929			return (FETCH_SENSE);
1930		} else {
1931			sgen_log(sg_state, SGEN_DIAG2, "sgen_check_error: "
1932			    "target indicates CHECK CONDITION");
1933		}
1934	}
1935
1936	return (COMMAND_DONE);
1937}
1938
1939/*
1940 * sgen_tur()
1941 * 	test if a target is ready to operate by sending it a TUR command.
1942 */
1943static int
1944sgen_tur(dev_t dev)
1945{
1946	char cmdblk[CDB_GROUP0];
1947	struct uscsi_cmd scmd;
1948
1949	bzero(&scmd, sizeof (scmd));
1950	scmd.uscsi_bufaddr = 0;
1951	scmd.uscsi_buflen = 0;
1952	bzero(cmdblk, CDB_GROUP0);
1953	cmdblk[0] = (char)SCMD_TEST_UNIT_READY;
1954	scmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_WRITE;
1955	scmd.uscsi_cdb = cmdblk;
1956	scmd.uscsi_cdblen = CDB_GROUP0;
1957
1958	return (sgen_uscsi_cmd(dev, &scmd, FKIOCTL));
1959}
1960
1961/*
1962 * sgen_diag_ok()
1963 * 	given an sg_state and a desired diagnostic level, return true if
1964 * 	it is acceptable to output a message.
1965 */
1966/*ARGSUSED*/
1967static int
1968sgen_diag_ok(sgen_state_t *sg_state, int level)
1969{
1970	int diag_lvl;
1971
1972	switch (level) {
1973	case CE_WARN:
1974	case CE_NOTE:
1975	case CE_CONT:
1976	case CE_PANIC:
1977		return (1);
1978	case SGEN_DIAG1:
1979	case SGEN_DIAG2:
1980	case SGEN_DIAG3:
1981		if (sg_state) {
1982			/*
1983			 * Check to see if user overrode the diagnostics level
1984			 * for this instance (either via SGEN_IOC_DIAG or via
1985			 * .conf file).  If not, fall back to the global diag
1986			 * level.
1987			 */
1988			if (sg_state->sgen_diag != -1)
1989				diag_lvl = sg_state->sgen_diag;
1990			else
1991				diag_lvl = sgen_diag;
1992		} else {
1993			diag_lvl = sgen_diag;
1994		}
1995		if (((diag_lvl << 8) | CE_CONT) >= level) {
1996			return (1);
1997		} else {
1998			return (0);
1999		}
2000	default:
2001		return (1);
2002	}
2003}
2004
2005/*PRINTFLIKE3*/
2006static void
2007sgen_log(sgen_state_t *sg_state, int level, const char *fmt, ...)
2008{
2009	va_list	ap;
2010	char buf[256];
2011
2012	if (!sgen_diag_ok(sg_state, level))
2013		return;
2014
2015	va_start(ap, fmt);
2016	(void) vsnprintf(buf, sizeof (buf), fmt, ap);
2017	va_end(ap);
2018
2019	switch (level) {
2020	case CE_NOTE:
2021	case CE_CONT:
2022	case CE_WARN:
2023	case CE_PANIC:
2024		if (sg_state == (sgen_state_t *)NULL) {
2025			cmn_err(level, "%s", buf);
2026		} else {
2027			scsi_log(sg_state->sgen_devinfo, sgen_label, level,
2028			    "%s", buf);
2029		}
2030		break;
2031	case SGEN_DIAG1:
2032	case SGEN_DIAG2:
2033	case SGEN_DIAG3:
2034	default:
2035		if (sg_state == (sgen_state_t *)NULL) {
2036			scsi_log(NULL, sgen_label, CE_CONT, "%s", buf);
2037		} else {
2038			scsi_log(sg_state->sgen_devinfo, sgen_label, CE_CONT,
2039			    "%s", buf);
2040		}
2041	}
2042}
2043
2044/*
2045 * sgen_dump_cdb()
2046 * 	dump out the contents of a cdb.  Take care that 'label' is not too
2047 * 	large, or 'buf' could overflow.
2048 */
2049static void
2050sgen_dump_cdb(sgen_state_t *sg_state, const char *label,
2051    union scsi_cdb *cdb, int cdblen)
2052{
2053	static char hex[] = "0123456789abcdef";
2054	char *buf, *p;
2055	size_t nbytes;
2056	int i;
2057	uchar_t	*cdbp = (uchar_t *)cdb;
2058
2059	/*
2060	 * fastpath-- if we're not able to print out, don't do all of this
2061	 * extra work.
2062	 */
2063	if (!sgen_diag_ok(sg_state, SGEN_DIAG3))
2064		return;
2065
2066	/*
2067	 * 3 characters for each byte (because of the ' '), plus the size of
2068	 * the label, plus the trailing ']' and the null character.
2069	 */
2070	nbytes = 3 * cdblen + strlen(label) + strlen(" CDB = [") + 2;
2071	buf = kmem_alloc(nbytes, KM_SLEEP);
2072	(void) sprintf(buf, "%s CDB = [", label);
2073	p = &buf[strlen(buf)];
2074	for (i = 0; i < cdblen; i++, cdbp++) {
2075		if (i > 0)
2076			*p++ = ' ';
2077		*p++ = hex[(*cdbp >> 4) & 0x0f];
2078		*p++ = hex[*cdbp & 0x0f];
2079	}
2080	*p++ = ']';
2081	*p = 0;
2082	sgen_log(sg_state, SGEN_DIAG3, buf);
2083	kmem_free(buf, nbytes);
2084}
2085
2086static void
2087sgen_dump_sense(sgen_state_t *sg_state, size_t rqlen, uchar_t *rqbuf)
2088{
2089	static char hex[] = "0123456789abcdef";
2090	char *buf, *p;
2091	size_t nbytes;
2092	int i;
2093
2094	/*
2095	 * fastpath-- if we're not able to print out, don't do all of this
2096	 * extra work.
2097	 */
2098	if (!sgen_diag_ok(sg_state, SGEN_DIAG3))
2099		return;
2100
2101	/*
2102	 * 3 characters for each byte (because of the ' '), plus the size of
2103	 * the label, plus the trailing ']' and the null character.
2104	 */
2105	nbytes = 3 * rqlen + strlen(" SENSE = [") + 2;
2106	buf = kmem_alloc(nbytes, KM_SLEEP);
2107	(void) sprintf(buf, "SENSE = [");
2108	p = &buf[strlen(buf)];
2109	for (i = 0; i < rqlen; i++, rqbuf++) {
2110		if (i > 0)
2111			*p++ = ' ';
2112		*p++ = hex[(*rqbuf >> 4) & 0x0f];
2113		*p++ = hex[*rqbuf & 0x0f];
2114	}
2115	*p++ = ']';
2116	*p = 0;
2117	sgen_log(sg_state, SGEN_DIAG3, buf);
2118	kmem_free(buf, nbytes);
2119}
2120