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