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. */
46 static char *sgen_label = NULL;
47
48 #define DDI_NT_SGEN "ddi_generic:scsi"
49
50 static char *sgen_devtypes[] = {
51 "direct", /* 0x00 -- disks */
52 "sequential", /* 0x01 */
53 "printer", /* 0x02 */
54 "processor", /* 0x03 */
55 "worm", /* 0x04 */
56 "rodirect", /* 0x05 */
57 "scanner", /* 0x06 */
58 "optical", /* 0x07 */
59 "changer", /* 0x08 */
60 "comm", /* 0x09 */
61 "prepress1", /* 0x0a -- reserved for prepress (ASC IT8) */
62 "prepress2", /* 0x0b -- reserved for prepress (ASC IT8) */
63 "array_ctrl", /* 0x0c -- storage array */
64 "ses", /* 0x0d -- enclosure services */
65 "rbc", /* 0x0e -- simplified block */
66 "ocrw", /* 0x0f -- optical card read/write */
67 "bridge", /* 0x10 -- reserved for bridging expanders */
68 "type_0x11", /* 0x11 */
69 "type_0x12", /* 0x12 */
70 "type_0x13", /* 0x13 */
71 "type_0x14", /* 0x14 */
72 "type_0x15", /* 0x15 */
73 "type_0x16", /* 0x16 */
74 "type_0x17", /* 0x17 */
75 "type_0x18", /* 0x18 */
76 "type_0x19", /* 0x19 */
77 "type_0x1a", /* 0x1a */
78 "type_0x1b", /* 0x1b */
79 "type_0x1c", /* 0x1c */
80 "type_0x1d", /* 0x1d */
81 "type_0x1e", /* 0x1e */
82 "type_unknown" /* 0x1f is "no device type" or "unknown" */
83 };
84
85 #define SGEN_NDEVTYPES ((sizeof (sgen_devtypes) / sizeof (char *)))
86
87 #define SGEN_INQSTRLEN 24
88 #define SGEN_VENDID_MAX 8
89 #define SGEN_PRODID_MAX 16
90
91 #define FILL_SCSI1_LUN(devp, pkt) \
92 if ((devp)->sd_inq->inq_ansi == 0x1) { \
93 int _lun; \
94 _lun = ddi_prop_get_int(DDI_DEV_T_ANY, (devp)->sd_dev, \
95 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_LUN, 0); \
96 if (_lun > 0) { \
97 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
98 _lun; \
99 } \
100 }
101
102 #define SGEN_DO_ERRSTATS(sg_state, x) \
103 if (sg_state->sgen_kstats) { \
104 struct sgen_errstats *sp; \
105 sp = (struct sgen_errstats *)sg_state->sgen_kstats->ks_data; \
106 sp->x.value.ui32++; \
107 }
108
109 #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK)
110
111 /*
112 * Standard entrypoints
113 */
114 static int sgen_attach(dev_info_t *, ddi_attach_cmd_t);
115 static int sgen_detach(dev_info_t *, ddi_detach_cmd_t);
116 static int sgen_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
117 static int sgen_probe(dev_info_t *);
118 static int sgen_open(dev_t *, int, int, cred_t *);
119 static int sgen_close(dev_t, int, int, cred_t *);
120 static int sgen_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
121
122 /*
123 * Configuration routines
124 */
125 static int sgen_do_attach(dev_info_t *);
126 static int sgen_setup_sense(sgen_state_t *);
127 static void sgen_create_errstats(sgen_state_t *, int);
128 static int sgen_do_suspend(dev_info_t *);
129 static int sgen_do_detach(dev_info_t *);
130 static void sgen_setup_binddb(dev_info_t *);
131 static void sgen_cleanup_binddb();
132
133 /*
134 * Packet transport routines
135 */
136 static int sgen_uscsi_cmd(dev_t, struct uscsi_cmd *, int);
137 static int sgen_start(struct buf *);
138 static int sgen_hold_cmdbuf(sgen_state_t *);
139 static void sgen_rele_cmdbuf(sgen_state_t *);
140 static int sgen_make_uscsi_cmd(sgen_state_t *, struct buf *);
141 static void sgen_restart(void *);
142 static void sgen_callback(struct scsi_pkt *);
143 static int sgen_handle_autosense(sgen_state_t *, struct scsi_pkt *);
144 static int sgen_handle_sense(sgen_state_t *);
145 static int sgen_handle_incomplete(sgen_state_t *, struct scsi_pkt *);
146 static int sgen_check_error(sgen_state_t *, struct buf *);
147 static int sgen_initiate_sense(sgen_state_t *, int);
148 static int sgen_scsi_transport(struct scsi_pkt *);
149 static int sgen_tur(dev_t);
150
151 /*
152 * Logging/debugging routines
153 */
154 static void sgen_log(sgen_state_t *, int, const char *, ...);
155 static int sgen_diag_ok(sgen_state_t *, int);
156 static void sgen_dump_cdb(sgen_state_t *, const char *, union scsi_cdb *, int);
157 static void sgen_dump_sense(sgen_state_t *, size_t, uchar_t *);
158
159 int sgen_diag = 0;
160 int sgen_sporadic_failures = 0;
161 int sgen_force_manual_sense = 0;
162 struct sgen_binddb sgen_binddb;
163
164 static struct cb_ops sgen_cb_ops = {
165 sgen_open, /* open */
166 sgen_close, /* close */
167 nodev, /* strategy */
168 nodev, /* print */
169 nodev, /* dump */
170 nodev, /* read */
171 nodev, /* write */
172 sgen_ioctl, /* ioctl */
173 nodev, /* devmap */
174 nodev, /* mmap */
175 nodev, /* segmap */
176 nochpoll, /* poll */
177 ddi_prop_op, /* cb_prop_op */
178 0, /* streamtab */
179 D_MP | D_NEW | D_HOTPLUG /* Driver compatibility flag */
180 };
181
182 static struct dev_ops sgen_dev_ops = {
183 DEVO_REV, /* devo_rev, */
184 0, /* refcnt */
185 sgen_getinfo, /* info */
186 nodev, /* identify */
187 sgen_probe, /* probe */
188 sgen_attach, /* attach */
189 sgen_detach, /* detach */
190 nodev, /* reset */
191 &sgen_cb_ops, /* driver operations */
192 (struct bus_ops *)0, /* bus operations */
193 NULL, /* power */
194 ddi_quiesce_not_supported, /* devo_quiesce */
195 };
196
197 static void *sgen_soft_state = NULL;
198
199 static struct modldrv modldrv = {
200 &mod_driverops, "SCSI generic driver", &sgen_dev_ops
201 };
202
203 static struct modlinkage modlinkage = {
204 MODREV_1, &modldrv, NULL
205 };
206
207 int
_init(void)208 _init(void)
209 {
210 int err;
211
212 /* establish driver name from module name */
213 sgen_label = (char *)mod_modname(&modlinkage);
214
215 sgen_log(NULL, SGEN_DIAG2, "in sgen_init()");
216 if ((err = ddi_soft_state_init(&sgen_soft_state,
217 sizeof (sgen_state_t), SGEN_ESTIMATED_NUM_DEVS)) != 0) {
218 goto done;
219 }
220
221 if ((err = mod_install(&modlinkage)) != 0) {
222 ddi_soft_state_fini(&sgen_soft_state);
223 goto done;
224 }
225
226 done:
227 sgen_log(NULL, SGEN_DIAG2, "%s sgen_init()", err ? "failed" : "done");
228 return (err);
229 }
230
231 int
_fini(void)232 _fini(void)
233 {
234 int err;
235 sgen_log(NULL, SGEN_DIAG2, "in sgen_fini()");
236
237 if ((err = mod_remove(&modlinkage)) != 0) {
238 goto done;
239 }
240
241 ddi_soft_state_fini(&sgen_soft_state);
242 sgen_cleanup_binddb();
243
244 done:
245 sgen_log(NULL, SGEN_DIAG2, "%s sgen_fini()", err ? "failed" : "done");
246 return (err);
247 }
248
249 int
_info(struct modinfo * modinfop)250 _info(struct modinfo *modinfop)
251 {
252 return (mod_info(&modlinkage, modinfop));
253 }
254
255 /*
256 * sgen_typename()
257 * return a device type's name by looking it up in the sgen_devtypes table.
258 */
259 static char *
sgen_typename(uchar_t typeno)260 sgen_typename(uchar_t typeno)
261 {
262 if (typeno >= SGEN_NDEVTYPES)
263 return ("type_unknown");
264 return (sgen_devtypes[typeno]);
265 }
266
267 /*
268 * sgen_typenum()
269 * return a device type's number by looking it up in the sgen_devtypes
270 * table.
271 */
272 static int
sgen_typenum(const char * typename,uchar_t * typenum)273 sgen_typenum(const char *typename, uchar_t *typenum)
274 {
275 int i;
276 for (i = 0; i < SGEN_NDEVTYPES; i++) {
277 if (strcasecmp(sgen_devtypes[i], typename) == 0) {
278 *typenum = (uchar_t)i;
279 return (0);
280 }
281 }
282 return (-1);
283 }
284
285 /*
286 * sgen_setup_binddb()
287 * initialize a data structure which stores all of the information about
288 * which devices and device types the driver should bind to.
289 */
290 static void
sgen_setup_binddb(dev_info_t * dip)291 sgen_setup_binddb(dev_info_t *dip)
292 {
293 char **strs = NULL, *cp, *pcp, *vcp;
294 uint_t nelems, pcplen, vcplen, idx;
295
296 ASSERT(sgen_binddb.sdb_init == 0);
297 ASSERT(MUTEX_HELD(&sgen_binddb.sdb_lock));
298
299 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
300 "device-type-config-list", &strs, &nelems) == DDI_PROP_SUCCESS) {
301 /*
302 * for each device type specifier make a copy and put it into a
303 * node in the binddb.
304 */
305 for (idx = 0; idx < nelems; idx++) {
306 sgen_type_node_t *nodep;
307 uchar_t devtype;
308 cp = strs[idx];
309 if (sgen_typenum(cp, &devtype) != 0) {
310 sgen_log(NULL, CE_WARN,
311 "unknown device type '%s', "
312 "device unit-address @%s",
313 cp, ddi_get_name_addr(dip));
314 continue;
315 }
316 nodep = kmem_zalloc(sizeof (sgen_type_node_t),
317 KM_SLEEP);
318 nodep->node_type = devtype;
319 nodep->node_next = sgen_binddb.sdb_type_nodes;
320 sgen_binddb.sdb_type_nodes = nodep;
321
322 sgen_log(NULL, SGEN_DIAG2, "found device type "
323 "'%s' in device-type-config-list, "
324 "device unit-address @%s",
325 cp, ddi_get_name_addr(dip));
326 }
327 ddi_prop_free(strs);
328 }
329
330 /*
331 * for each Vendor/Product inquiry pair, build a node and put it
332 * into the the binddb.
333 */
334 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
335 "inquiry-config-list", &strs, &nelems) == DDI_PROP_SUCCESS) {
336
337 if (nelems % 2 == 1) {
338 sgen_log(NULL, CE_WARN, "inquiry-config-list must "
339 "contain Vendor/Product pairs, "
340 "device unit-address @%s",
341 ddi_get_name_addr(dip));
342 nelems--;
343 }
344 for (idx = 0; idx < nelems; idx += 2) {
345 sgen_inq_node_t *nodep;
346 /*
347 * Grab vendor and product ID.
348 */
349 vcp = strs[idx];
350 vcplen = strlen(vcp);
351 if (vcplen == 0 || vcplen > SGEN_VENDID_MAX) {
352 sgen_log(NULL, CE_WARN,
353 "Invalid vendor ID '%s', "
354 "device unit-address @%s",
355 vcp, ddi_get_name_addr(dip));
356 continue;
357 }
358
359 pcp = strs[idx + 1];
360 pcplen = strlen(pcp);
361 if (pcplen == 0 || pcplen > SGEN_PRODID_MAX) {
362 sgen_log(NULL, CE_WARN,
363 "Invalid product ID '%s', "
364 "device unit-address @%s",
365 pcp, ddi_get_name_addr(dip));
366 continue;
367 }
368
369 nodep = kmem_zalloc(sizeof (sgen_inq_node_t),
370 KM_SLEEP);
371 nodep->node_vendor = kmem_alloc(vcplen + 1, KM_SLEEP);
372 (void) strcpy(nodep->node_vendor, vcp);
373 nodep->node_product = kmem_alloc(pcplen + 1, KM_SLEEP);
374 (void) strcpy(nodep->node_product, pcp);
375
376 nodep->node_next = sgen_binddb.sdb_inq_nodes;
377 sgen_binddb.sdb_inq_nodes = nodep;
378
379 sgen_log(NULL, SGEN_DIAG2, "found inquiry string "
380 "'%s' '%s' in device-type-config-list, "
381 "device unit-address @%s",
382 nodep->node_vendor, nodep->node_product,
383 ddi_get_name_addr(dip));
384 }
385 ddi_prop_free(strs);
386 }
387
388 sgen_binddb.sdb_init = 1;
389 }
390
391 /*
392 * sgen_cleanup_binddb()
393 * deallocate data structures for binding database.
394 */
395 static void
sgen_cleanup_binddb()396 sgen_cleanup_binddb()
397 {
398 sgen_inq_node_t *inqp, *inqnextp;
399 sgen_type_node_t *typep, *typenextp;
400
401 mutex_enter(&sgen_binddb.sdb_lock);
402 if (sgen_binddb.sdb_init == 0) {
403 mutex_exit(&sgen_binddb.sdb_lock);
404 return;
405 }
406
407 for (inqp = sgen_binddb.sdb_inq_nodes; inqp != NULL; inqp = inqnextp) {
408 inqnextp = inqp->node_next;
409 ASSERT(inqp->node_vendor && inqp->node_product);
410 kmem_free(inqp->node_vendor,
411 strlen(inqp->node_vendor) + 1);
412 kmem_free(inqp->node_product,
413 strlen(inqp->node_product) + 1);
414 kmem_free(inqp, sizeof (sgen_inq_node_t));
415 }
416
417 for (typep = sgen_binddb.sdb_type_nodes; typep != NULL;
418 typep = typenextp) {
419 typenextp = typep->node_next;
420 kmem_free(typep, sizeof (sgen_type_node_t));
421 }
422 mutex_exit(&sgen_binddb.sdb_lock);
423 }
424
425 /*
426 * sgen_bind_byinq()
427 * lookup a device in the binding database by its inquiry data.
428 */
429 static int
sgen_bind_byinq(dev_info_t * dip)430 sgen_bind_byinq(dev_info_t *dip)
431 {
432 sgen_inq_node_t *nodep;
433 char vend_str[SGEN_VENDID_MAX+1];
434 char prod_str[SGEN_PRODID_MAX+1];
435 struct scsi_device *scsidevp;
436
437 scsidevp = ddi_get_driver_private(dip);
438
439 /*
440 * inq_vid and inq_pid are laid out by the protocol in order in the
441 * inquiry structure, and are not delimited by \0.
442 */
443 bcopy(scsidevp->sd_inq->inq_vid, vend_str, SGEN_VENDID_MAX);
444 vend_str[SGEN_VENDID_MAX] = '\0';
445 bcopy(scsidevp->sd_inq->inq_pid, prod_str, SGEN_PRODID_MAX);
446 prod_str[SGEN_PRODID_MAX] = '\0';
447
448 for (nodep = sgen_binddb.sdb_inq_nodes; nodep != NULL;
449 nodep = nodep->node_next) {
450 /*
451 * Allow the "*" wildcard to match all vendor IDs.
452 */
453 if (strcmp(nodep->node_vendor, "*") != 0) {
454 if (strncasecmp(nodep->node_vendor, vend_str,
455 strlen(nodep->node_vendor)) != 0) {
456 continue;
457 }
458 }
459
460 /*
461 * Using strncasecmp() with the key length allows substring
462 * matching for product data.
463 */
464 if (strncasecmp(nodep->node_product, prod_str,
465 strlen(nodep->node_product)) == 0) {
466 return (0);
467 }
468 }
469 return (-1);
470 }
471
472 /*
473 * sgen_bind_bytype()
474 * lookup a device type in the binding database; if found, return a
475 * format string corresponding to the string in the .conf file.
476 */
477 static int
sgen_bind_bytype(dev_info_t * dip)478 sgen_bind_bytype(dev_info_t *dip)
479 {
480 sgen_type_node_t *nodep;
481 struct scsi_device *scsidevp;
482
483 scsidevp = ddi_get_driver_private(dip);
484
485 for (nodep = sgen_binddb.sdb_type_nodes; nodep != NULL;
486 nodep = nodep->node_next) {
487 if (nodep->node_type == scsidevp->sd_inq->inq_dtype) {
488 return (0);
489 }
490 }
491 return (-1);
492 }
493
494 /*
495 * sgen_get_binding()
496 * Check to see if the device in question matches the criteria for
497 * sgen to bind.
498 *
499 * Either the .conf file must specify a device_type entry which
500 * matches the SCSI device type of this device, or the inquiry
501 * string provided by the device must match an inquiry string specified
502 * in the .conf file. Inquiry data is matched first.
503 */
504 static int
sgen_get_binding(dev_info_t * dip)505 sgen_get_binding(dev_info_t *dip)
506 {
507 int retval = 0;
508
509 mutex_enter(&sgen_binddb.sdb_lock);
510 if (sgen_binddb.sdb_init == 0)
511 sgen_setup_binddb(dip);
512 mutex_exit(&sgen_binddb.sdb_lock);
513
514
515 /*
516 * Check device-type-config-list for a match by device type.
517 */
518 if (sgen_bind_bytype(dip) == 0)
519 goto done;
520
521 /*
522 * Check inquiry-config-list for a match by Vendor/Product ID.
523 */
524 if (sgen_bind_byinq(dip) == 0)
525 goto done;
526
527 retval = -1;
528 done:
529 return (retval);
530 }
531
532 /*
533 * sgen_attach()
534 * attach(9e) entrypoint.
535 */
536 static int
sgen_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)537 sgen_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
538 {
539 int err;
540
541 sgen_log(NULL, SGEN_DIAG2, "in sgen_attach(), device unit-address @%s",
542 ddi_get_name_addr(dip));
543
544 switch (cmd) {
545 case DDI_ATTACH:
546 err = sgen_do_attach(dip);
547 break;
548 case DDI_RESUME:
549 err = DDI_SUCCESS;
550 break;
551 case DDI_PM_RESUME:
552 default:
553 err = DDI_FAILURE;
554 break;
555 }
556
557 done:
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 */
567 static int
sgen_do_attach(dev_info_t * dip)568 sgen_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 */
741 static int
sgen_setup_sense(sgen_state_t * sg_state)742 sgen_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 */
783 static void
sgen_create_errstats(sgen_state_t * sg_state,int instance)784 sgen_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 */
829 static int
sgen_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)830 sgen_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 */
864 static int
sgen_do_detach(dev_info_t * dip)865 sgen_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 */
932 static int
sgen_do_suspend(dev_info_t * dip)933 sgen_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*/
965 static int
sgen_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)966 sgen_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 */
999 static int
sgen_probe(dev_info_t * dip)1000 sgen_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*/
1053 static int
sgen_open(dev_t * dev_p,int flag,int otyp,cred_t * cred_p)1054 sgen_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*/
1104 static int
sgen_close(dev_t dev,int flag,int otyp,cred_t * cred_p)1105 sgen_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*/
1134 static int
sgen_ioctl(dev_t dev,int cmd,intptr_t arg,int flag,cred_t * cred_p,int * rval_p)1135 sgen_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*/
1201 static int
sgen_uscsi_cmd(dev_t dev,struct uscsi_cmd * ucmd,int flag)1202 sgen_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 */
1304 static int
sgen_hold_cmdbuf(sgen_state_t * sg_state)1305 sgen_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 */
1324 static void
sgen_rele_cmdbuf(sgen_state_t * sg_state)1325 sgen_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 */
1338 static int
sgen_start(struct buf * bp)1339 sgen_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 */
1408 static int
sgen_scsi_transport(struct scsi_pkt * pkt)1409 sgen_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 */
1441 static int
sgen_make_uscsi_cmd(sgen_state_t * sg_state,struct buf * bp)1442 sgen_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 */
1529 static void
sgen_restart(void * arg)1530 sgen_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 */
1569 static void
sgen_callback(struct scsi_pkt * pkt)1570 sgen_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 */
1670 static int
sgen_initiate_sense(sgen_state_t * sg_state,int path_instance)1671 sgen_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*/
1706 static int
sgen_handle_incomplete(sgen_state_t * sg_state,struct scsi_pkt * pkt)1707 sgen_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 */
1722 static int
sgen_handle_autosense(sgen_state_t * sg_state,struct scsi_pkt * pkt)1723 sgen_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 */
1811 static int
sgen_handle_sense(sgen_state_t * sg_state)1812 sgen_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 */
1897 static int
sgen_check_error(sgen_state_t * sg_state,struct buf * bp)1898 sgen_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 */
1943 static int
sgen_tur(dev_t dev)1944 sgen_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*/
1967 static int
sgen_diag_ok(sgen_state_t * sg_state,int level)1968 sgen_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*/
2006 static void
sgen_log(sgen_state_t * sg_state,int level,const char * fmt,...)2007 sgen_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 */
2049 static void
sgen_dump_cdb(sgen_state_t * sg_state,const char * label,union scsi_cdb * cdb,int cdblen)2050 sgen_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
2086 static void
sgen_dump_sense(sgen_state_t * sg_state,size_t rqlen,uchar_t * rqbuf)2087 sgen_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