xref: /illumos-gate/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c (revision 43d18f1c320355e93c47399bea0b2e022fe06364)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * scsa2usb bridge nexus driver:
31  *
32  * This driver supports the following wire transports:
33  * a. Bulk Only transport (see usb_ms_bulkonly.c)
34  * b. CB transport (see usb_ms_cbi.c)
35  * c. CBI transport with interrupt status completion (see usb_ms_cbi.c)
36  *
37  * It handles the following command sets:
38  * a. SCSI
39  * b. ATAPI command set (subset of SCSI command set)
40  * c. UFI command set (
41  *	http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf)
42  *
43  * For details on USB Mass Storage Class overview:
44  *	http://www.usb.org/developers/devclass_docs/usbmassover_11.pdf
45  */
46 #if defined(lint) && !defined(DEBUG)
47 #define	DEBUG	1
48 #endif
49 
50 #include <sys/usb/usba/usbai_version.h>
51 #include <sys/scsi/scsi.h>
52 #include <sys/cdio.h>
53 #include <sys/sunndi.h>
54 #include <sys/esunddi.h>
55 #include <sys/callb.h>
56 #include <sys/kobj.h>
57 #include <sys/kobj_lex.h>
58 #include <sys/strsubr.h>
59 #include <sys/sysmacros.h>
60 
61 #include <sys/usb/usba.h>
62 #include <sys/usb/usba/usba_ugen.h>
63 
64 #include <sys/usb/usba/usba_private.h>
65 #include <sys/usb/clients/mass_storage/usb_bulkonly.h>
66 #include <sys/usb/scsa2usb/scsa2usb.h>
67 
68 /*
69  * Function Prototypes
70  */
71 static int	scsa2usb_attach(dev_info_t *, ddi_attach_cmd_t);
72 static int	scsa2usb_info(dev_info_t *, ddi_info_cmd_t, void *,
73 						void **);
74 static int	scsa2usb_detach(dev_info_t *, ddi_detach_cmd_t);
75 static int	scsa2usb_cleanup(dev_info_t *, scsa2usb_state_t *);
76 static void	scsa2usb_validate_attrs(scsa2usb_state_t *);
77 static void	scsa2usb_create_luns(scsa2usb_state_t *);
78 static int	scsa2usb_is_usb(dev_info_t *);
79 static int	scsa2usb_fake_inquiry(scsa2usb_state_t *,
80 					scsa2usb_cmd_t *, uint_t);
81 static void	scsa2usb_do_inquiry(scsa2usb_state_t *,
82 						uint_t, uint_t);
83 
84 /* override property handling */
85 static void	scsa2usb_override(scsa2usb_state_t *);
86 static int	scsa2usb_parse_input_str(char *, scsa2usb_ov_t *,
87 		    scsa2usb_state_t *);
88 static void	scsa2usb_override_error(char *, scsa2usb_state_t *);
89 static char	*scsa2usb_strtok_r(char *, char *, char **);
90 
91 
92 /* PANIC callback handling */
93 static void	scsa2usb_panic_callb_init(scsa2usb_state_t *);
94 static void	scsa2usb_panic_callb_fini(scsa2usb_state_t *);
95 static boolean_t scsa2usb_panic_callb(void *, int);
96 
97 /* SCSA support */
98 static int	scsa2usb_scsi_tgt_probe(struct scsi_device *, int (*)(void));
99 static int	scsa2usb_scsi_tgt_init(dev_info_t *, dev_info_t *,
100 		    scsi_hba_tran_t *, struct scsi_device *);
101 static void	scsa2usb_scsi_tgt_free(dev_info_t *, dev_info_t *,
102 		    scsi_hba_tran_t *, struct scsi_device *);
103 static struct	scsi_pkt *scsa2usb_scsi_init_pkt(struct scsi_address *,
104 		    struct scsi_pkt *, struct buf *, int, int,
105 		    int, int, int (*)(), caddr_t);
106 static void	scsa2usb_scsi_destroy_pkt(struct scsi_address *,
107 		    struct scsi_pkt *);
108 static int	scsa2usb_scsi_start(struct scsi_address *, struct scsi_pkt *);
109 static int	scsa2usb_scsi_abort(struct scsi_address *, struct scsi_pkt *);
110 static int	scsa2usb_scsi_reset(struct scsi_address *, int);
111 static int	scsa2usb_scsi_getcap(struct scsi_address *, char *, int);
112 static int	scsa2usb_scsi_setcap(struct scsi_address *, char *, int, int);
113 static int	scsa2usb_scsi_bus_config(dev_info_t *, uint_t,
114 		    ddi_bus_config_op_t, void *, dev_info_t **);
115 static int	scsa2usb_scsi_bus_unconfig(dev_info_t *, uint_t,
116 		    ddi_bus_config_op_t, void *);
117 
118 /* functions for command and transport support */
119 static void	scsa2usb_prepare_pkt(scsa2usb_state_t *, struct scsi_pkt *);
120 static int	scsa2usb_cmd_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
121 static int	scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t *,
122 		    scsa2usb_cmd_t *, uchar_t);
123 static int	scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *, uchar_t,
124 		    scsa2usb_cmd_t *);
125 static int	scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *,
126 		    scsa2usb_cmd_t *, struct scsi_pkt *);
127 static int	scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *,
128 		    scsa2usb_cmd_t *, struct scsi_pkt *);
129 
130 /* waitQ handling */
131 static void	scsa2usb_work_thread(void *);
132 static void	scsa2usb_transport_request(scsa2usb_state_t *, uint_t);
133 static void	scsa2usb_flush_waitQ(scsa2usb_state_t *, uint_t, uchar_t);
134 static int	scsa2usb_all_waitQs_empty(scsa2usb_state_t *);
135 
136 /* auto request sense handling */
137 static int	scsa2usb_create_arq_pkt(scsa2usb_state_t *,
138 		    struct scsi_address *);
139 static void	scsa2usb_delete_arq_pkt(scsa2usb_state_t *);
140 static void	scsa2usb_complete_arq_pkt(scsa2usb_state_t *, struct scsi_pkt *,
141 		    scsa2usb_cmd_t *, struct buf *);
142 
143 /* utility functions for any transport */
144 static int	scsa2usb_open_usb_pipes(scsa2usb_state_t *);
145 void		scsa2usb_close_usb_pipes(scsa2usb_state_t *);
146 
147 static void	scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *, int);
148 static void	scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *, int);
149 static void	scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *, int, int);
150 static void	scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *, int, int);
151 static int	scsa2usb_read_cd_blk_size(uchar_t);
152 int		scsa2usb_rw_transport(scsa2usb_state_t *, struct scsi_pkt *);
153 void		scsa2usb_setup_next_xfer(scsa2usb_state_t *, scsa2usb_cmd_t *);
154 
155 static mblk_t	*scsa2usb_bp_to_mblk(scsa2usb_state_t *);
156 int		scsa2usb_handle_data_start(scsa2usb_state_t *,
157 		    scsa2usb_cmd_t *, usb_bulk_req_t *);
158 void		scsa2usb_handle_data_done(scsa2usb_state_t *,
159 		    scsa2usb_cmd_t *cmd, usb_bulk_req_t *);
160 
161 usb_bulk_req_t *scsa2usb_init_bulk_req(scsa2usb_state_t *,
162 			    size_t, uint_t, usb_req_attrs_t, usb_flags_t);
163 int		scsa2usb_bulk_timeout(int);
164 int		scsa2usb_clear_ept_stall(scsa2usb_state_t *, uint_t,
165 		    usb_pipe_handle_t, char *);
166 static void	scsa2usb_pkt_completion(scsa2usb_state_t *, struct scsi_pkt *);
167 
168 /* event handling */
169 static int	scsa2usb_reconnect_event_cb(dev_info_t *);
170 static int	scsa2usb_disconnect_event_cb(dev_info_t *);
171 static int	scsa2usb_cpr_suspend(dev_info_t *);
172 static void	scsa2usb_cpr_resume(dev_info_t *);
173 static void	scsa2usb_restore_device_state(dev_info_t *, scsa2usb_state_t *);
174 
175 /* PM handling */
176 static void	scsa2usb_create_pm_components(dev_info_t *, scsa2usb_state_t *);
177 static void	scsa2usb_raise_power(scsa2usb_state_t *);
178 static int	scsa2usb_pwrlvl0(scsa2usb_state_t *);
179 static int	scsa2usb_pwrlvl1(scsa2usb_state_t *);
180 static int	scsa2usb_pwrlvl2(scsa2usb_state_t *);
181 static int	scsa2usb_pwrlvl3(scsa2usb_state_t *);
182 static int	scsa2usb_power(dev_info_t *, int comp, int level);
183 static void	scsa2usb_pm_busy_component(scsa2usb_state_t *);
184 static void	scsa2usb_pm_idle_component(scsa2usb_state_t *);
185 
186 /* external functions for Bulk only (BO) support */
187 extern int	scsa2usb_bulk_only_transport(scsa2usb_state_t *,
188 		    scsa2usb_cmd_t *);
189 extern int	scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *);
190 
191 /* external functions for CB/CBI support */
192 extern int	scsa2usb_cbi_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
193 extern void	scsa2usb_cbi_stop_intr_polling(scsa2usb_state_t *);
194 
195 
196 /* cmd decoding */
197 static char *scsa2usb_cmds[] = {
198 	"\000tur",
199 	"\001rezero",
200 	"\003rqsense",
201 	"\004format",
202 	"\014cartprot",
203 	"\022inquiry",
204 	"\026tranlba",
205 	"\030fmtverify",
206 	"\032modesense",
207 	"\033start",
208 	"\035snddiag",
209 	"\036doorlock",
210 	"\043formatcap",
211 	"\045readcap",
212 	"\050read10",
213 	"\052write10",
214 	"\053seek10",
215 	"\056writeverify",
216 	"\057verify",
217 	"\065synchcache",
218 	"\076readlong",
219 	"\077writelong",
220 	"\102readsubchan",
221 	"\103readtoc",
222 	"\104readhdr",
223 	"\105playaudio10",
224 	"\107playaudio_msf",
225 	"\110playaudio_ti",
226 	"\111playtrk_r10",
227 	"\112geteventnotify",
228 	"\113pause_resume",
229 	"\116stop/play_scan",
230 	"\121readdiscinfo",
231 	"\122readtrkinfo",
232 	"\123reservedtrk",
233 	"\124sendopcinfo",
234 	"\125modeselect",
235 	"\132modesense",
236 	"\133closetrksession",
237 	"\135sendcuesheet",
238 	"\136prin",
239 	"\137prout",
240 	"\241blankcd",
241 	"\245playaudio12",
242 	"\250read12",
243 	"\251playtrk12",
244 	"\252write12",
245 	"\254getperf",
246 	"\271readcdmsf",
247 	"\273setcdspeed",
248 	"\275mechanism_sts",
249 	"\276readcd",
250 	NULL
251 };
252 
253 
254 /*
255  * Mass-Storage devices masquerade as "sd" disks.
256  *
257  * These devices may not support all SCSI CDBs in their
258  * entirety due to their hardware implementation limitations.
259  *
260  * As such, following is a list of some of the black-listed
261  * devices w/ the attributes that they do not support.
262  * (See scsa2usb.h for description on each attribute)
263  */
264 #define	X	((uint16_t)(-1))
265 
266 static struct blacklist {
267 	uint16_t	idVendor;	/* vendor ID			*/
268 	uint16_t	idProduct;	/* product ID			*/
269 	uint16_t	bcdDevice;	/* device release number in bcd */
270 	uint16_t	attributes;	/* attributes to blacklist	*/
271 } scsa2usb_blacklist[] = {
272 	/* Iomega Zip100 drive (prototype) with flaky bridge */
273 	{MS_IOMEGA_VID, MS_IOMEGA_PID1_ZIP100, 0,
274 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
275 
276 	/* Iomega Zip100 drive (newer model) with flaky bridge */
277 	{MS_IOMEGA_VID, MS_IOMEGA_PID2_ZIP100, 0,
278 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
279 
280 	/* Iomega Zip100 drive (newer model) with flaky bridge */
281 	{MS_IOMEGA_VID, MS_IOMEGA_PID3_ZIP100, 0,
282 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
283 
284 	/* Iomega Zip250 drive */
285 	{MS_IOMEGA_VID, MS_IOMEGA_PID_ZIP250, 0, SCSA2USB_ATTRS_GET_LUN},
286 
287 	/* Iomega Clik! drive */
288 	{MS_IOMEGA_VID, MS_IOMEGA_PID_CLIK, 0,
289 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
290 
291 	/* SMSC floppy Device - and its clones */
292 	{MS_SMSC_VID, X, 0, SCSA2USB_ATTRS_START_STOP},
293 
294 	/* Hagiwara SmartMedia Device */
295 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID1, 0,
296 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
297 
298 	/* Hagiwara CompactFlash Device */
299 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID2, 0,
300 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
301 
302 	/* Hagiwara SmartMedia/CompactFlash Combo Device */
303 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID3, 0,
304 	    SCSA2USB_ATTRS_START_STOP},
305 
306 	/* Hagiwara new SM Device */
307 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID4, 0,
308 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
309 
310 	/* Hagiwara new CF Device */
311 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID5, 0,
312 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
313 
314 	/* Mitsumi CD-RW Device(s) */
315 	{MS_MITSUMI_VID, X, X, SCSA2USB_ATTRS_BIG_TIMEOUT |
316 	    SCSA2USB_ATTRS_GET_CONF | SCSA2USB_ATTRS_GET_PERF},
317 
318 	/* Neodio Technologies Corporation SM/CF/MS/SD Combo Device */
319 	{MS_NEODIO_VID, MS_NEODIO_DEVICE_3050, 0,
320 	    SCSA2USB_ATTRS_MODE_SENSE },
321 
322 	/* dumb flash devices */
323 	{MS_SONY_FLASH_VID, MS_SONY_FLASH_PID, 0,
324 	    SCSA2USB_ATTRS_REDUCED_CMD},
325 
326 	{MS_TREK_FLASH_VID, MS_TREK_FLASH_PID, 0,
327 	    SCSA2USB_ATTRS_REDUCED_CMD},
328 
329 	{MS_PENN_FLASH_VID, MS_PENN_FLASH_PID, 0,
330 	    SCSA2USB_ATTRS_REDUCED_CMD},
331 
332 	/* SimpleTech UCF-100 CF Device */
333 	{MS_SIMPLETECH_VID, MS_SIMPLETECH_PID1, 0,
334 	    SCSA2USB_ATTRS_REDUCED_CMD},
335 
336 	{MS_ADDONICS_CARD_READER_VID, MS_ADDONICS_CARD_READER_PID,
337 	    0, SCSA2USB_ATTRS_REDUCED_CMD},
338 };
339 
340 
341 #define	N_SCSA2USB_BLACKLIST (sizeof (scsa2usb_blacklist))/ \
342 				sizeof (struct blacklist)
343 
344 /*
345  * Attribute values can be overridden by values
346  * contained in the scsa2usb.conf file.
347  * These arrays define possible user input values.
348  */
349 
350 struct scsa2usb_subclass_protocol_override {
351 	char	*name;
352 	int	value;
353 };
354 
355 static struct scsa2usb_subclass_protocol_override scsa2usb_protocol[] =  {
356 	{"CB", SCSA2USB_CB_PROTOCOL},
357 	{"CBI", SCSA2USB_CBI_PROTOCOL},
358 	{"BO", SCSA2USB_BULK_ONLY_PROTOCOL}
359 };
360 
361 static struct scsa2usb_subclass_protocol_override scsa2usb_subclass[] = {
362 	{"SCSI", SCSA2USB_SCSI_CMDSET},
363 	{"ATAPI", SCSA2USB_ATAPI_CMDSET},
364 	{"UFI", SCSA2USB_UFI_CMDSET}
365 };
366 
367 
368 #define	N_SCSA2USB_SUBC_OVERRIDE (sizeof (scsa2usb_subclass))/ \
369 			sizeof (struct scsa2usb_subclass_protocol_override)
370 
371 #define	N_SCSA2USB_PROT_OVERRIDE (sizeof (scsa2usb_protocol))/ \
372 			sizeof (struct scsa2usb_subclass_protocol_override)
373 
374 /* global variables */
375 static void *scsa2usb_statep;				/* for soft state */
376 static boolean_t scsa2usb_sync_message = B_TRUE;	/* for syncing */
377 
378 /* for debug messages */
379 uint_t	scsa2usb_errmask	= (uint_t)DPRINT_MASK_ALL;
380 uint_t	scsa2usb_errlevel	= USB_LOG_L4;
381 uint_t	scsa2usb_instance_debug = (uint_t)-1;
382 uint_t	scsa2usb_scsi_bus_config_debug = 0;
383 uint_t	scsa2usb_long_timeout	= 50 * SCSA2USB_BULK_PIPE_TIMEOUT;
384 
385 
386 /*
387  * Some devices have problems with big bulk transfers,
388  * transfers >= 128kbytes hang the device.  This tunable allows to
389  * limit the maximum bulk transfers rate.
390  */
391 uint_t	scsa2usb_max_bulk_xfer_size = SCSA2USB_MAX_BULK_XFER_SIZE;
392 
393 
394 #ifdef	SCSA2USB_BULK_ONLY_TEST
395 /*
396  * Test BO 13 cases. (See USB Mass Storage Class - Bulk Only Transport).
397  * We are not covering test cases 1, 6, and 12 as these are the "good"
398  * test cases and are tested as part of the normal drive access operations.
399  *
400  * NOTE: This is for testing only. It will be replaced by a uscsi test.
401  * Some are listed here while; other test cases are moved to usb_bulkonly.c
402  */
403 static int scsa2usb_test_case_5 = 0;
404 int scsa2usb_test_case_8 = 0;
405 int scsa2usb_test_case_10 = 0;
406 static int scsa2usb_test_case_11 = 0;
407 
408 static void	scsa2usb_test_mblk(scsa2usb_state_t *, boolean_t);
409 #endif	/* SCSA2USB_BULK_ONLY_TEST */
410 
411 static int	scsa2usb_ugen_open(dev_t *, int, int, cred_t *);
412 static int	scsa2usb_ugen_close(dev_t, int, int, cred_t *);
413 static int	scsa2usb_ugen_strategy(struct buf *);
414 static int	scsa2usb_ugen_read(dev_t, struct uio *, cred_t *);
415 static int	scsa2usb_ugen_write(dev_t, struct uio *, cred_t *);
416 static int	scsa2usb_ugen_poll(dev_t, short, int,  short *,
417 						struct pollhead **);
418 
419 /* scsa2usb cb_ops */
420 static struct cb_ops scsa2usb_cbops = {
421 	scsa2usb_ugen_open,	/* open  */
422 	scsa2usb_ugen_close,	/* close */
423 	nodev,			/* strategy */
424 	nodev,			/* print */
425 	nodev,			/* dump */
426 	scsa2usb_ugen_read,	/* read */
427 	scsa2usb_ugen_write,	/* write */
428 	NULL,			/* ioctl */
429 	nodev,			/* devmap */
430 	nodev,			/* mmap */
431 	nodev,			/* segmap */
432 	scsa2usb_ugen_poll,	/* poll */
433 	ddi_prop_op,		/* prop_op */
434 	NULL,			/* stream */
435 	D_MP,			/* cb_flag */
436 	CB_REV, 		/* rev */
437 	nodev,			/* int (*cb_aread)() */
438 	nodev			/* int (*cb_awrite)() */
439 };
440 
441 /* modloading support */
442 static struct dev_ops scsa2usb_ops = {
443 	DEVO_REV,		/* devo_rev, */
444 	0,			/* refcnt  */
445 	scsa2usb_info,		/* info */
446 	nulldev,		/* identify */
447 	nulldev,		/* probe */
448 	scsa2usb_attach,	/* attach */
449 	scsa2usb_detach,	/* detach */
450 	nodev,			/* reset */
451 	&scsa2usb_cbops,	/* driver operations */
452 	NULL,			/* bus operations */
453 	scsa2usb_power		/* power */
454 };
455 
456 static struct modldrv modldrv = {
457 	&mod_driverops,			/* Module type. This one is a driver */
458 	"SCSA to USB Driver %I%",	/* Name of the module. */
459 	&scsa2usb_ops,			/* driver ops */
460 };
461 
462 static struct modlinkage modlinkage = {
463 	MODREV_1, (void *)&modldrv, NULL
464 };
465 
466 /* event support */
467 static usb_event_t scsa2usb_events = {
468 	scsa2usb_disconnect_event_cb,
469 	scsa2usb_reconnect_event_cb,
470 	NULL, NULL
471 };
472 
473 int
474 _init(void)
475 {
476 	int rval;
477 
478 	if (((rval = ddi_soft_state_init(&scsa2usb_statep,
479 	    sizeof (scsa2usb_state_t), SCSA2USB_INITIAL_ALLOC)) != 0)) {
480 
481 		return (rval);
482 	}
483 
484 	if ((rval = scsi_hba_init(&modlinkage)) != 0) {
485 		ddi_soft_state_fini(&scsa2usb_statep);
486 
487 		return (rval);
488 	}
489 
490 	if ((rval = mod_install(&modlinkage)) != 0) {
491 		scsi_hba_fini(&modlinkage);
492 		ddi_soft_state_fini(&scsa2usb_statep);
493 
494 		return (rval);
495 	}
496 
497 	return (rval);
498 }
499 
500 
501 int
502 _fini(void)
503 {
504 	int	rval;
505 
506 	if ((rval = mod_remove(&modlinkage)) == 0) {
507 		scsi_hba_fini(&modlinkage);
508 		ddi_soft_state_fini(&scsa2usb_statep);
509 	}
510 
511 	return (rval);
512 }
513 
514 
515 int
516 _info(struct modinfo *modinfop)
517 {
518 	return (mod_info(&modlinkage, modinfop));
519 }
520 
521 
522 /*
523  * scsa2usb_info :
524  *	Get minor number, soft state structure etc.
525  */
526 /*ARGSUSED*/
527 static int
528 scsa2usb_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
529     void *arg, void **result)
530 {
531 	scsa2usb_state_t *scsa2usbp = NULL;
532 	int error = DDI_FAILURE;
533 	int instance = SCSA2USB_MINOR_TO_INSTANCE(getminor((dev_t)arg));
534 
535 	switch (infocmd) {
536 	case DDI_INFO_DEVT2DEVINFO:
537 		if (((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
538 		    instance)) != NULL) &&
539 		    scsa2usbp->scsa2usb_dip) {
540 			*result = scsa2usbp->scsa2usb_dip;
541 			error = DDI_SUCCESS;
542 		} else {
543 			*result = NULL;
544 		}
545 		break;
546 	case DDI_INFO_DEVT2INSTANCE:
547 		*result = (void *)(uintptr_t)instance;
548 		error = DDI_SUCCESS;
549 		break;
550 	default:
551 		break;
552 	}
553 
554 	return (error);
555 }
556 
557 
558 /*
559  * scsa2usb_attach:
560  *	Attach driver
561  *	Allocate a "scsi_hba_tran" - call scsi_hba_tran_alloc()
562  *	Invoke scsi_hba_attach_setup
563  *	Get the serialno of the device
564  *	Open bulk pipes
565  *	Create disk child(ren)
566  *	Register events
567  *	Create and register panic callback
568  *
569  * NOTE: Replaced CBW_DIR_OUT with USB_EP_DIR_OUT and CBW_DIR_IN with
570  * USB_EP_DIR_IN as they are the same #defines.
571  */
572 static int
573 scsa2usb_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
574 {
575 	int			instance = ddi_get_instance(dip);
576 	int			interface;
577 	uint_t			lun;
578 	boolean_t		ept_check = B_TRUE;
579 	scsi_hba_tran_t		*tran;		/* scsi transport */
580 	scsa2usb_state_t	*scsa2usbp;
581 	usb_log_handle_t	log_handle;
582 	usb_ep_data_t		*ep_data;
583 	usb_client_dev_data_t	*dev_data;
584 	usb_alt_if_data_t	*altif_data;
585 	usb_ugen_info_t 	usb_ugen_info;
586 
587 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL,
588 	    "scsa2usb_attach: dip = 0x%p", dip);
589 
590 	switch (cmd) {
591 	case DDI_ATTACH:
592 		break;
593 	case DDI_RESUME:
594 		scsa2usb_cpr_resume(dip);
595 
596 		return (DDI_SUCCESS);
597 	default:
598 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, NULL,
599 		    "scsa2usb_attach: failed");
600 
601 		return (DDI_FAILURE);
602 	}
603 
604 	/* Allocate softc information */
605 	if (ddi_soft_state_zalloc(scsa2usb_statep, instance) != DDI_SUCCESS) {
606 		ddi_prop_remove_all(dip);
607 
608 		return (DDI_FAILURE);
609 	}
610 
611 	/* get soft state space and initialize */
612 	if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
613 	    instance)) == NULL) {
614 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, NULL,
615 		    "scsa2usb%d: bad soft state", instance);
616 		ddi_prop_remove_all(dip);
617 
618 		return (DDI_FAILURE);
619 	}
620 
621 	scsa2usbp->scsa2usb_dip 	= dip;
622 	scsa2usbp->scsa2usb_instance	= instance;
623 
624 	/* allocate a log handle for debug/error messages */
625 	scsa2usbp->scsa2usb_log_handle = log_handle =
626 	    usb_alloc_log_hdl(dip, "s2u",
627 				&scsa2usb_errlevel,
628 				&scsa2usb_errmask, &scsa2usb_instance_debug,
629 				0);
630 
631 	/* attach to USBA */
632 	if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) {
633 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
634 		    "usb_client_attach failed");
635 
636 		goto fail;
637 	}
638 	if (usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0) !=
639 	    USB_SUCCESS) {
640 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
641 		    "usb_get_dev_data failed");
642 
643 		goto fail;
644 	}
645 
646 	/* initialize the mutex with the right cookie */
647 	mutex_init(&scsa2usbp->scsa2usb_mutex, NULL, MUTEX_DRIVER,
648 					dev_data->dev_iblock_cookie);
649 	cv_init(&scsa2usbp->scsa2usb_transport_busy_cv, NULL, CV_DRIVER, NULL);
650 
651 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
652 		usba_init_list(&scsa2usbp->scsa2usb_waitQ[lun], NULL,
653 					dev_data->dev_iblock_cookie);
654 	}
655 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
656 	scsa2usbp->scsa2usb_dip 	= dip;
657 	scsa2usbp->scsa2usb_instance	= instance;
658 	scsa2usbp->scsa2usb_attrs	= SCSA2USB_ALL_ATTRS;
659 	scsa2usbp->scsa2usb_dev_data	= dev_data;
660 
661 
662 	/* save the default pipe handle */
663 	scsa2usbp->scsa2usb_default_pipe = dev_data->dev_default_ph;
664 
665 	/* basic inits are done */
666 	scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_LOCKS_INIT;
667 
668 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, log_handle,
669 	    "curr_cfg=%d, curr_if=%d",
670 	    dev_data->dev_curr_cfg - &dev_data->dev_cfg[0],
671 	    dev_data->dev_curr_if);
672 
673 	interface = dev_data->dev_curr_if;
674 	scsa2usbp->scsa2usb_intfc_num = dev_data->dev_curr_if;
675 
676 	/* now find out relevant descriptors for alternate 0 */
677 	altif_data = &dev_data->dev_curr_cfg->cfg_if[interface].if_alt[0];
678 
679 	if (altif_data->altif_n_ep == 0) {
680 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
681 		    "invalid alt 0 for interface %d", interface);
682 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
683 
684 		goto fail;
685 	}
686 
687 	/* All CB/CBI, BO devices should have this value set */
688 	if (altif_data->altif_descr.bInterfaceClass !=
689 	    USB_CLASS_MASS_STORAGE) {
690 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
691 		    "invalid interface class (0x%x)",
692 		    altif_data->altif_descr.bInterfaceClass);
693 	}
694 	scsa2usbp->scsa2usb_intfc_descr = altif_data->altif_descr;
695 
696 	/* figure out the endpoints and copy the descr */
697 	if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
698 	    USB_EP_ATTR_BULK, USB_EP_DIR_OUT)) != NULL) {
699 		scsa2usbp->scsa2usb_bulkout_ept = ep_data->ep_descr;
700 	}
701 	if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
702 	    USB_EP_ATTR_BULK, USB_EP_DIR_IN)) != NULL) {
703 		scsa2usbp->scsa2usb_bulkin_ept = ep_data->ep_descr;
704 	}
705 	if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
706 	    USB_EP_ATTR_INTR, USB_EP_DIR_IN)) != NULL) {
707 		scsa2usbp->scsa2usb_intr_ept = ep_data->ep_descr;
708 	}
709 
710 	/*
711 	 * check here for protocol and subclass supported by this driver
712 	 *
713 	 * first check if conf file has override values
714 	 * Note: override values are not used if supplied values are legal
715 	 */
716 	scsa2usb_override(scsa2usbp);
717 
718 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, log_handle,
719 	    "protocol=0x%x override=0x%x subclass=0x%x override=0x%x",
720 	    scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol,
721 	    scsa2usbp->scsa2usb_protocol_override,
722 	    scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass,
723 	    scsa2usbp->scsa2usb_subclass_override);
724 
725 	switch (scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol) {
726 	case USB_PROTO_MS_CBI:
727 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_CB_PROTOCOL;
728 		break;
729 	case USB_PROTO_MS_CBI_WC:
730 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_CBI_PROTOCOL;
731 		break;
732 	case USB_PROTO_MS_ISD_1999_SILICN:
733 	case USB_PROTO_MS_BULK_ONLY:
734 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_BULK_ONLY_PROTOCOL;
735 		break;
736 	default:
737 		if (scsa2usbp->scsa2usb_protocol_override) {
738 			scsa2usbp->scsa2usb_cmd_protocol |=
739 			    scsa2usbp->scsa2usb_protocol_override;
740 			USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
741 			    "overriding protocol %x",
742 			    scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol);
743 			break;
744 		}
745 
746 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
747 		    "unsupported protocol = %x",
748 		    scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol);
749 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
750 
751 		goto fail;
752 	}
753 
754 	switch (scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass) {
755 	case USB_SUBCLS_MS_SCSI:		/* transparent SCSI */
756 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_SCSI_CMDSET;
757 		break;
758 	case USB_SUBCLS_MS_SFF8020I:
759 	case USB_SUBCLS_MS_SFF8070I:
760 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_ATAPI_CMDSET;
761 		break;
762 	case USB_SUBCLS_MS_UFI:		/* UFI */
763 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
764 		break;
765 	default:
766 		if (scsa2usbp->scsa2usb_subclass_override) {
767 			scsa2usbp->scsa2usb_cmd_protocol |=
768 			    scsa2usbp->scsa2usb_subclass_override;
769 			USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
770 			    "overriding subclass %x",
771 			    scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass);
772 			break;
773 		}
774 
775 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
776 		    "unsupported subclass = %x",
777 		    scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass);
778 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
779 
780 		goto fail;
781 	}
782 
783 	/* check that we have the right set of endpoint descriptors */
784 	if (SCSA2USB_IS_BULK_ONLY(scsa2usbp) || SCSA2USB_IS_CB(scsa2usbp)) {
785 		if ((scsa2usbp->scsa2usb_bulkout_ept.bLength == 0) ||
786 		    (scsa2usbp->scsa2usb_bulkin_ept.bLength == 0)) {
787 			ept_check = B_FALSE;
788 		}
789 	} else if (SCSA2USB_IS_CBI(scsa2usbp)) {
790 		if ((scsa2usbp->scsa2usb_bulkout_ept.bLength == 0) ||
791 		    (scsa2usbp->scsa2usb_bulkin_ept.bLength == 0) ||
792 		    (scsa2usbp->scsa2usb_intr_ept.bLength == 0)) {
793 			ept_check = B_FALSE;
794 		}
795 	}
796 
797 	if (ept_check == B_FALSE) {
798 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
799 		    "scsa2usb%d doesn't support minimum required endpoints",
800 		    instance);
801 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
802 
803 		goto fail;
804 	}
805 
806 	/*
807 	 * Validate the black-listed attributes
808 	 */
809 	scsa2usb_validate_attrs(scsa2usbp);
810 
811 	/* Print the serial number from the registration data */
812 	if (scsa2usbp->scsa2usb_dev_data->dev_serial) {
813 		USB_DPRINTF_L4(DPRINT_MASK_SCSA,
814 		    scsa2usbp->scsa2usb_log_handle, "Serial Number = %s",
815 		    scsa2usbp->scsa2usb_dev_data->dev_serial);
816 	}
817 
818 	/*
819 	 * Allocate a SCSA transport structure
820 	 */
821 	tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
822 	scsa2usbp->scsa2usb_tran = tran;
823 
824 	/*
825 	 * initialize transport structure
826 	 */
827 	tran->tran_hba_private		= scsa2usbp;
828 	tran->tran_tgt_private		= NULL;
829 	tran->tran_tgt_init		= scsa2usb_scsi_tgt_init;
830 	tran->tran_tgt_probe		= scsa2usb_scsi_tgt_probe;
831 	tran->tran_tgt_free		= scsa2usb_scsi_tgt_free;
832 	tran->tran_start		= scsa2usb_scsi_start;
833 	tran->tran_abort		= scsa2usb_scsi_abort;
834 	tran->tran_reset		= scsa2usb_scsi_reset;
835 	tran->tran_getcap		= scsa2usb_scsi_getcap;
836 	tran->tran_setcap		= scsa2usb_scsi_setcap;
837 	tran->tran_init_pkt		= scsa2usb_scsi_init_pkt;
838 	tran->tran_destroy_pkt		= scsa2usb_scsi_destroy_pkt;
839 	tran->tran_dmafree		= NULL;
840 	tran->tran_sync_pkt		= NULL;
841 	tran->tran_reset_notify		= NULL;
842 	tran->tran_get_bus_addr		= NULL;
843 	tran->tran_get_name		= NULL;
844 	tran->tran_quiesce		= NULL;
845 	tran->tran_unquiesce		= NULL;
846 	tran->tran_bus_reset		= NULL;
847 	tran->tran_add_eventcall	= NULL;
848 	tran->tran_get_eventcookie	= NULL;
849 	tran->tran_post_event		= NULL;
850 	tran->tran_remove_eventcall	= NULL;
851 	tran->tran_bus_config		= scsa2usb_scsi_bus_config;
852 	tran->tran_bus_unconfig		= scsa2usb_scsi_bus_unconfig;
853 
854 	/*
855 	 * register with SCSA as an HBA
856 	 * Note that the dma attributes are from parent nexus
857 	 */
858 	if (scsi_hba_attach_setup(dip, usba_get_hc_dma_attr(dip), tran, 0)) {
859 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
860 		    "scsi_hba_attach_setup failed");
861 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
862 
863 		goto fail;
864 	}
865 
866 	scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_HBA_ATTACH_SETUP;
867 
868 	/* create minor node */
869 	if (ddi_create_minor_node(dip, "scsa2usb", S_IFCHR,
870 	    instance << SCSA2USB_MINOR_INSTANCE_SHIFT,
871 	    DDI_NT_SCSI_NEXUS, 0) != DDI_SUCCESS) {
872 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
873 		    "scsi_attach: ddi_create_minor_node failed");
874 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
875 
876 		goto fail;
877 	}
878 
879 	/* open pipes and set scsa2usb_flags */
880 	if (scsa2usb_open_usb_pipes(scsa2usbp) == USB_FAILURE) {
881 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
882 		    "error opening pipes");
883 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
884 
885 		goto fail;
886 	}
887 
888 	/* set default block size. updated after read cap cmd */
889 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
890 		scsa2usbp->scsa2usb_lbasize[lun] = DEV_BSIZE;
891 	}
892 
893 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
894 
895 	/* initialize PANIC callback */
896 	scsa2usb_panic_callb_init(scsa2usbp);
897 
898 	/* finally we are all done 'initializing' the device */
899 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
900 	scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
901 
902 	/* enable PM, mutex needs to be held across this */
903 	scsa2usb_create_pm_components(dip, scsa2usbp);
904 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
905 
906 	/* register for connect/disconnect events */
907 	if (usb_register_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events,
908 	    0) != USB_SUCCESS) {
909 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
910 		    "error cb registering");
911 		goto fail;
912 	}
913 
914 	/* free the dev_data tree, we no longer need it */
915 	usb_free_descr_tree(dip, dev_data);
916 
917 	scsa2usb_pm_idle_component(scsa2usbp);
918 
919 	/* log the conf file override string if there is one */
920 	if (scsa2usbp->scsa2usb_override_str) {
921 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
922 		    "scsa2usb.conf override: %s",
923 		    scsa2usbp->scsa2usb_override_str);
924 	}
925 
926 	if (usb_owns_device(dip)) {
927 		/* get a ugen handle */
928 		bzero(&usb_ugen_info, sizeof (usb_ugen_info));
929 		usb_ugen_info.usb_ugen_flags = 0;
930 		usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask =
931 				(dev_t)SCSA2USB_MINOR_UGEN_BITS_MASK;
932 		usb_ugen_info.usb_ugen_minor_node_instance_mask =
933 				(dev_t)~SCSA2USB_MINOR_UGEN_BITS_MASK;
934 		scsa2usbp->scsa2usb_ugen_hdl =
935 					usb_ugen_get_hdl(dip, &usb_ugen_info);
936 
937 		if (usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl, cmd) !=
938 		    USB_SUCCESS) {
939 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
940 			    scsa2usbp->scsa2usb_log_handle,
941 			    "usb_ugen_attach failed");
942 
943 			usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
944 			scsa2usbp->scsa2usb_ugen_hdl = NULL;
945 		}
946 	}
947 
948 	/* report device */
949 	ddi_report_dev(dip);
950 
951 	return (DDI_SUCCESS);
952 
953 fail:
954 	if (scsa2usbp) {
955 		(void) scsa2usb_cleanup(dip, scsa2usbp);
956 	}
957 
958 	return (DDI_FAILURE);
959 }
960 
961 
962 /*
963  * scsa2usb_detach:
964  *	detach or suspend driver instance
965  */
966 static int
967 scsa2usb_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
968 {
969 	scsi_hba_tran_t	*tran;
970 	scsa2usb_state_t *scsa2usbp;
971 	int rval;
972 
973 	tran = ddi_get_driver_private(dip);
974 	ASSERT(tran != NULL);
975 
976 	scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
977 	ASSERT(scsa2usbp);
978 
979 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
980 	    "scsa2usb_detach: dip = 0x%p, cmd = %d", dip, cmd);
981 
982 	switch (cmd) {
983 	case DDI_DETACH:
984 
985 		if (scsa2usb_cleanup(dip, scsa2usbp) != USB_SUCCESS) {
986 
987 			return (DDI_FAILURE);
988 		}
989 
990 		return (DDI_SUCCESS);
991 	case DDI_SUSPEND:
992 		rval = scsa2usb_cpr_suspend(dip);
993 
994 		return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
995 	default:
996 
997 		return (DDI_FAILURE);
998 	}
999 }
1000 
1001 
1002 /*
1003  * ugen support
1004  */
1005 /*
1006  * scsa2usb_ugen_open()
1007  * (all ugen opens and pipe opens are by definition exclusive so it is OK
1008  * to count opens)
1009  */
1010 static int
1011 scsa2usb_ugen_open(dev_t *devp, int flag, int sflag, cred_t *cr)
1012 {
1013 	scsa2usb_state_t *scsa2usbp;
1014 	int		rval;
1015 
1016 	if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1017 	    SCSA2USB_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) {
1018 		/* deferred detach */
1019 
1020 		return (ENXIO);
1021 	}
1022 
1023 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1024 	    "scsa2usb_ugen_open: dev_t=0x%lx", *devp);
1025 
1026 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1027 
1028 	/* if this is the first ugen open, check on transport busy */
1029 	if (scsa2usbp->scsa2usb_ugen_open_count == 0) {
1030 		while (scsa2usbp->scsa2usb_transport_busy ||
1031 		    (scsa2usb_all_waitQs_empty(scsa2usbp) !=
1032 		    USB_SUCCESS)) {
1033 			rval = cv_wait_sig(
1034 				&scsa2usbp->scsa2usb_transport_busy_cv,
1035 				&scsa2usbp->scsa2usb_mutex);
1036 			if (rval == 0) {
1037 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
1038 
1039 				return (EINTR);
1040 			}
1041 		}
1042 		scsa2usbp->scsa2usb_transport_busy++;
1043 		scsa2usbp->scsa2usb_busy_thread = curthread;
1044 	}
1045 	scsa2usbp->scsa2usb_ugen_open_count++;
1046 
1047 	scsa2usb_raise_power(scsa2usbp);
1048 
1049 	scsa2usb_close_usb_pipes(scsa2usbp);
1050 
1051 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1052 
1053 	rval = usb_ugen_open(scsa2usbp->scsa2usb_ugen_hdl, devp, flag,
1054 		sflag, cr);
1055 
1056 	if (rval) {
1057 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1058 
1059 		/* reopen the pipes */
1060 		if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1061 			scsa2usbp->scsa2usb_transport_busy--;
1062 			scsa2usbp->scsa2usb_busy_thread = NULL;
1063 			cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1064 		}
1065 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1066 
1067 		scsa2usb_pm_idle_component(scsa2usbp);
1068 	}
1069 
1070 	return (rval);
1071 }
1072 
1073 
1074 /*
1075  * scsa2usb_ugen_close()
1076  */
1077 static int
1078 scsa2usb_ugen_close(dev_t dev, int flag, int otype, cred_t *cr)
1079 {
1080 	int rval;
1081 
1082 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1083 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1084 
1085 	if (scsa2usbp == NULL) {
1086 
1087 		return (ENXIO);
1088 	}
1089 
1090 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1091 	    "scsa2usb_ugen_close: dev_t=0x%lx", dev);
1092 
1093 	rval = usb_ugen_close(scsa2usbp->scsa2usb_ugen_hdl, dev, flag,
1094 		otype, cr);
1095 
1096 	if (rval == 0) {
1097 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1098 
1099 		/* reopen the pipes */
1100 		if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1101 			scsa2usbp->scsa2usb_transport_busy--;
1102 			scsa2usbp->scsa2usb_busy_thread = NULL;
1103 			cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1104 		}
1105 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1106 
1107 		scsa2usb_pm_idle_component(scsa2usbp);
1108 	}
1109 
1110 	return (rval);
1111 }
1112 
1113 
1114 /*
1115  * scsa2usb_ugen_read/write()
1116  */
1117 /*ARGSUSED*/
1118 static int
1119 scsa2usb_ugen_read(dev_t dev, struct uio *uiop, cred_t *credp)
1120 {
1121 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1122 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1123 
1124 	if (scsa2usbp == NULL) {
1125 
1126 		return (ENXIO);
1127 	}
1128 
1129 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1130 	    "scsa2usb_ugen_read: dev_t=0x%lx", dev);
1131 
1132 
1133 	return (usb_ugen_read(scsa2usbp->scsa2usb_ugen_hdl, dev,
1134 					uiop, credp));
1135 }
1136 
1137 
1138 /*ARGSUSED*/
1139 static int
1140 scsa2usb_ugen_write(dev_t dev, struct uio *uiop, cred_t *credp)
1141 {
1142 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1143 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1144 
1145 	if (scsa2usbp == NULL) {
1146 
1147 		return (ENXIO);
1148 	}
1149 
1150 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1151 	    "scsa2usb_ugen_write: dev_t=0x%lx", dev);
1152 
1153 	return (usb_ugen_write(scsa2usbp->scsa2usb_ugen_hdl,
1154 					dev, uiop, credp));
1155 }
1156 
1157 
1158 /*
1159  * scsa2usb_ugen_poll
1160  */
1161 static int
1162 scsa2usb_ugen_poll(dev_t dev, short events,
1163     int anyyet,  short *reventsp, struct pollhead **phpp)
1164 {
1165 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1166 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1167 
1168 	if (scsa2usbp == NULL) {
1169 
1170 		return (ENXIO);
1171 	}
1172 
1173 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1174 	    "scsa2usb_ugen_poll: dev_t=0x%lx", dev);
1175 
1176 	return (usb_ugen_poll(scsa2usbp->scsa2usb_ugen_hdl, dev, events,
1177 					anyyet, reventsp, phpp));
1178 }
1179 
1180 
1181 /*
1182  * scsa2usb_cleanup:
1183  *	cleanup whatever attach has setup
1184  */
1185 static int
1186 scsa2usb_cleanup(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
1187 {
1188 	int		rval, i;
1189 	scsa2usb_power_t *pm;
1190 	uint_t		lun;
1191 
1192 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1193 	    "scsa2usb_cleanup:");
1194 
1195 	/* wait till the work thread is done */
1196 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1197 	for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
1198 		if (scsa2usbp->scsa2usb_work_thread_id == NULL) {
1199 
1200 			break;
1201 		}
1202 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1203 		delay(drv_usectohz(1000000));
1204 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1205 	}
1206 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1207 
1208 	if (i >= SCSA2USB_DRAIN_TIMEOUT) {
1209 
1210 		return (USB_FAILURE);
1211 	}
1212 
1213 	/*
1214 	 * Disable the event callbacks first, after this point, event
1215 	 * callbacks will never get called. Note we shouldn't hold
1216 	 * mutex while unregistering events because there may be a
1217 	 * competing event callback thread. Event callbacks are done
1218 	 * with ndi mutex held and this can cause a potential deadlock.
1219 	 */
1220 	usb_unregister_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events);
1221 
1222 	if (scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_LOCKS_INIT) {
1223 		/*
1224 		 * if a waitQ exists, get rid of it before destroying it
1225 		 */
1226 		for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
1227 			scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_TRAN_ERR);
1228 			usba_destroy_list(&scsa2usbp->scsa2usb_waitQ[lun]);
1229 		}
1230 
1231 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1232 		if (scsa2usbp->scsa2usb_flags &
1233 		    SCSA2USB_FLAGS_HBA_ATTACH_SETUP) {
1234 			(void) scsi_hba_detach(dip);
1235 			scsi_hba_tran_free(scsa2usbp->scsa2usb_tran);
1236 		}
1237 
1238 		if (scsa2usbp->scsa2usb_flags &
1239 		    SCSA2USB_FLAGS_PIPES_OPENED) {
1240 			scsa2usb_close_usb_pipes(scsa2usbp);
1241 		}
1242 
1243 		/* Lower the power */
1244 		pm = scsa2usbp->scsa2usb_pm;
1245 
1246 		if (pm && (scsa2usbp->scsa2usb_dev_state !=
1247 		    USB_DEV_DISCONNECTED)) {
1248 			if (pm->scsa2usb_wakeup_enabled) {
1249 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
1250 				(void) pm_raise_power(dip, 0,
1251 						USB_DEV_OS_FULL_PWR);
1252 
1253 				if ((rval = usb_handle_remote_wakeup(dip,
1254 				    USB_REMOTE_WAKEUP_DISABLE)) !=
1255 				    USB_SUCCESS) {
1256 					USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1257 					    scsa2usbp->scsa2usb_log_handle,
1258 					    "disable remote wakeup failed "
1259 					    "(%d)", rval);
1260 				}
1261 			} else {
1262 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
1263 			}
1264 
1265 			(void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
1266 
1267 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
1268 		}
1269 
1270 		if (pm) {
1271 			kmem_free(pm, sizeof (scsa2usb_power_t));
1272 		}
1273 
1274 		if (scsa2usbp->scsa2usb_override_str) {
1275 			kmem_free(scsa2usbp->scsa2usb_override_str,
1276 			    strlen(scsa2usbp->scsa2usb_override_str) + 1);
1277 			scsa2usbp->scsa2usb_override_str = NULL;
1278 		}
1279 
1280 		/* remove the minor nodes */
1281 		ddi_remove_minor_node(dip, NULL);
1282 
1283 		/* Cancel the registered panic callback */
1284 		scsa2usb_panic_callb_fini(scsa2usbp);
1285 
1286 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1287 
1288 		mutex_destroy(&scsa2usbp->scsa2usb_mutex);
1289 		cv_destroy(&scsa2usbp->scsa2usb_transport_busy_cv);
1290 	}
1291 
1292 	usb_client_detach(scsa2usbp->scsa2usb_dip,
1293 				scsa2usbp->scsa2usb_dev_data);
1294 
1295 	if (scsa2usbp->scsa2usb_ugen_hdl) {
1296 		(void) usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
1297 							DDI_DETACH);
1298 		usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
1299 	}
1300 
1301 	usb_free_log_hdl(scsa2usbp->scsa2usb_log_handle);
1302 
1303 	ddi_prop_remove_all(dip);
1304 
1305 	ddi_soft_state_free(scsa2usb_statep, ddi_get_instance(dip));
1306 
1307 	return (USB_SUCCESS);
1308 }
1309 
1310 
1311 /*
1312  * scsa2usb_override:
1313  *	some devices may be attached even though their subclass or
1314  *	protocol info is not according to spec.
1315  *	these can be determined by the 'subclass-protocol-override'
1316  *	property set in the conf file.
1317  */
1318 static void
1319 scsa2usb_override(scsa2usb_state_t *scsa2usbp)
1320 {
1321 	scsa2usb_ov_t ov;
1322 	char	**override_str = NULL;
1323 	char	*override_str_cpy;
1324 	uint_t	override_str_len, override_str_cpy_len;
1325 	uint_t	i;
1326 	usb_dev_descr_t *descr = scsa2usbp->scsa2usb_dev_data->dev_descr;
1327 
1328 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
1329 
1330 	scsa2usbp->scsa2usb_subclass_override =
1331 	    scsa2usbp->scsa2usb_protocol_override = 0;
1332 
1333 	if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, scsa2usbp->scsa2usb_dip,
1334 	    DDI_PROP_DONTPASS, "attribute-override-list",
1335 	    &override_str, &override_str_len) != DDI_PROP_SUCCESS) {
1336 
1337 		return;
1338 	}
1339 
1340 	/* parse each string in the subclass-protocol-override property */
1341 	for (i = 0; i < override_str_len; i++) {
1342 
1343 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1344 		    "override_str[%d] = %s", i, override_str[i]);
1345 
1346 		/*
1347 		 * save a copy of the override string for possible
1348 		 * inclusion in soft state later
1349 		 */
1350 		override_str_cpy_len = strlen(override_str[i]) + 1;
1351 		override_str_cpy = kmem_zalloc(override_str_cpy_len, KM_SLEEP);
1352 		(void) strcpy(override_str_cpy, override_str[i]);
1353 
1354 		bzero(&ov, sizeof (scsa2usb_ov_t));
1355 
1356 		if (scsa2usb_parse_input_str(override_str[i], &ov,
1357 		    scsa2usbp) == USB_FAILURE) {
1358 			kmem_free(override_str_cpy, override_str_cpy_len);
1359 			continue;
1360 		}
1361 
1362 		/*
1363 		 * see if subclass/protocol needs to be overridden for device
1364 		 * or if device should not be power managed
1365 		 * if there'a a match, save the override string in soft state
1366 		 */
1367 		if (((descr->idVendor == (uint16_t)ov.vid) || (ov.vid == 0)) &&
1368 		    ((descr->idProduct == (uint16_t)ov.pid) || (ov.pid == 0)) &&
1369 		    ((descr->bcdDevice == (uint16_t)ov.rev) || (ov.rev == 0))) {
1370 			scsa2usbp->scsa2usb_subclass_override = ov.subclass;
1371 			scsa2usbp->scsa2usb_protocol_override = ov.protocol;
1372 
1373 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1374 			    scsa2usbp->scsa2usb_log_handle,
1375 			    "vid=0x%x pid=0x%x rev=0x%x subclass=0x%x "
1376 			    "protocol=0x%x "
1377 			    "pmoff=%d not_removable=%d modesense=%d "
1378 			    "reduced-cmd-support=%d",
1379 			    ov.vid, ov.pid, ov.rev, ov.subclass, ov.protocol,
1380 			    ov.pmoff, ov.not_removable, ov.no_modesense,
1381 			    ov.reduced_cmd_support);
1382 
1383 			if (ov.pmoff) {
1384 				scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_PM;
1385 			}
1386 			if (ov.not_removable) {
1387 				scsa2usbp->scsa2usb_attrs &=
1388 				    ~SCSA2USB_ATTRS_RMB;
1389 			}
1390 			if (ov.no_modesense) {
1391 				scsa2usbp->scsa2usb_attrs &=
1392 				    ~SCSA2USB_ATTRS_MODE_SENSE;
1393 			}
1394 			if (ov.reduced_cmd_support) {
1395 				scsa2usbp->scsa2usb_attrs &=
1396 				    ~SCSA2USB_ATTRS_REDUCED_CMD;
1397 			}
1398 			scsa2usbp->scsa2usb_override_str = override_str_cpy;
1399 			break;
1400 		} else {
1401 			kmem_free(override_str_cpy, override_str_cpy_len);
1402 		}
1403 	}
1404 
1405 	ddi_prop_free(override_str);
1406 }
1407 
1408 
1409 /*
1410  * scsa2usb_parse_input_str:
1411  *	parse one conf file subclass-protocol-override string
1412  *	return vendor id, product id, revision, subclass, protocol
1413  *	function return is success or failure
1414  */
1415 static int
1416 scsa2usb_parse_input_str(char *str, scsa2usb_ov_t *ovp,
1417     scsa2usb_state_t *scsa2usbp)
1418 {
1419 	char		*input_field, *input_value;
1420 	char		*lasts;
1421 	uint_t		i;
1422 	u_longlong_t	value;
1423 
1424 	/* parse all the input pairs in the string */
1425 	for (input_field = scsa2usb_strtok_r(str, "=", &lasts);
1426 	    input_field != NULL;
1427 	    input_field = scsa2usb_strtok_r(lasts, "=", &lasts)) {
1428 
1429 		if ((input_value = scsa2usb_strtok_r(lasts, " ", &lasts)) ==
1430 		    NULL) {
1431 			scsa2usb_override_error("format", scsa2usbp);
1432 
1433 			return (USB_FAILURE);
1434 		}
1435 		/* if input value is a 'don't care', skip to the next pair */
1436 		if (strcmp(input_value, "*") == 0) {
1437 			continue;
1438 		}
1439 		if (strcasecmp(input_field, "vid") == 0) {
1440 			if (kobj_getvalue(input_value, &value) == -1) {
1441 				scsa2usb_override_error("vendor id", scsa2usbp);
1442 
1443 				return (USB_FAILURE);
1444 			}
1445 			ovp->vid = (int)value;
1446 		} else if (strcasecmp(input_field, "pid") == 0) {
1447 			if (kobj_getvalue(input_value, &value) == -1) {
1448 				scsa2usb_override_error("product id",
1449 				    scsa2usbp);
1450 
1451 				return (USB_FAILURE);
1452 			}
1453 			ovp->pid = (int)value;
1454 		} else if (strcasecmp(input_field, "rev") == 0) {
1455 			if (kobj_getvalue(input_value, &value) == -1) {
1456 				scsa2usb_override_error("revision id",
1457 				    scsa2usbp);
1458 
1459 				return (USB_FAILURE);
1460 			}
1461 			ovp->rev = (int)value;
1462 		} else if (strcasecmp(input_field, "subclass") == 0) {
1463 			for (i = 0; i < N_SCSA2USB_SUBC_OVERRIDE; i++) {
1464 				if (strcasecmp(input_value,
1465 				    scsa2usb_subclass[i].name) == 0) {
1466 					ovp->subclass =
1467 					    scsa2usb_subclass[i].value;
1468 					break;
1469 				}
1470 			}
1471 			if (ovp->subclass == 0) {
1472 				scsa2usb_override_error("subclass", scsa2usbp);
1473 
1474 				return (USB_FAILURE);
1475 			}
1476 		} else if (strcasecmp(input_field, "protocol") == 0) {
1477 			for (i = 0; i < N_SCSA2USB_PROT_OVERRIDE; i++) {
1478 				if (strcasecmp(input_value,
1479 				    scsa2usb_protocol[i].name) == 0) {
1480 					ovp->protocol =
1481 					    scsa2usb_protocol[i].value;
1482 					break;
1483 				}
1484 			}
1485 			if (ovp->protocol == 0) {
1486 				scsa2usb_override_error("protocol", scsa2usbp);
1487 
1488 				return (USB_FAILURE);
1489 			}
1490 		} else if (strcasecmp(input_field, "pm") == 0) {
1491 			if (strcasecmp(input_value, "off") == 0) {
1492 				ovp->pmoff = 1;
1493 				break;
1494 			} else {
1495 				scsa2usb_override_error("pm", scsa2usbp);
1496 
1497 				return (USB_FAILURE);
1498 			}
1499 		} else if (strcasecmp(input_field, "removable") == 0) {
1500 			if (strcasecmp(input_value, "false") == 0) {
1501 				ovp->not_removable = 1;
1502 				break;
1503 			} else {
1504 				scsa2usb_override_error("removable", scsa2usbp);
1505 
1506 				return (USB_FAILURE);
1507 			}
1508 		} else if (strcasecmp(input_field, "modesense") == 0) {
1509 			if (strcasecmp(input_value, "false") == 0) {
1510 				ovp->no_modesense = 1;
1511 				break;
1512 			} else {
1513 				scsa2usb_override_error("modesense",
1514 								scsa2usbp);
1515 
1516 				return (USB_FAILURE);
1517 			}
1518 		} else if (strcasecmp(input_field,
1519 		    "reduced-cmd-support") == 0) {
1520 			if (strcasecmp(input_value, "true") == 0) {
1521 				ovp->reduced_cmd_support = 1;
1522 				break;
1523 			} else {
1524 				scsa2usb_override_error(
1525 				    "reduced-cmd-support", scsa2usbp);
1526 
1527 				return (USB_FAILURE);
1528 			}
1529 		} else {
1530 			scsa2usb_override_error(input_field, scsa2usbp);
1531 
1532 			return (USB_FAILURE);
1533 		}
1534 	}
1535 
1536 	return (USB_SUCCESS);
1537 }
1538 
1539 
1540 /*
1541  * scsa2usb_override_error:
1542  *	print an error message if conf file string is bad format
1543  */
1544 static void
1545 scsa2usb_override_error(char *input_field, scsa2usb_state_t *scsa2usbp)
1546 {
1547 	USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1548 	    "invalid %s in scsa2usb.conf file entry", input_field);
1549 }
1550 
1551 /*
1552  * scsa2usb_strtok_r:
1553  *	parse a list of tokens
1554  */
1555 static char *
1556 scsa2usb_strtok_r(char *p, char *sep, char **lasts)
1557 {
1558 	char	*e;
1559 	char	*tok = NULL;
1560 
1561 	if (p == 0 || *p == 0) {
1562 
1563 		return (NULL);
1564 	}
1565 
1566 	e = p+strlen(p);
1567 
1568 	do {
1569 		if (strchr(sep, *p) != NULL) {
1570 			if (tok != NULL) {
1571 				*p = 0;
1572 				*lasts = p+1;
1573 
1574 				return (tok);
1575 			}
1576 		} else if (tok == NULL) {
1577 			tok = p;
1578 		}
1579 	} while (++p < e);
1580 
1581 	*lasts = NULL;
1582 
1583 	return (tok);
1584 }
1585 
1586 
1587 /*
1588  * scsa2usb_validate_attrs:
1589  *	many devices have BO/CB/CBI protocol support issues.
1590  *	use vendor/product info to reset the
1591  *	individual erroneous attributes
1592  *
1593  * NOTE: we look at only device at a time (at attach time)
1594  */
1595 static void
1596 scsa2usb_validate_attrs(scsa2usb_state_t *scsa2usbp)
1597 {
1598 	int i, mask;
1599 	usb_dev_descr_t *desc = scsa2usbp->scsa2usb_dev_data->dev_descr;
1600 
1601 	if (!SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1602 		scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_GET_LUN;
1603 	}
1604 
1605 	/* determine if this device is on the blacklist */
1606 	for (i = 0; i < N_SCSA2USB_BLACKLIST; i++) {
1607 		if ((scsa2usb_blacklist[i].idVendor == desc->idVendor) &&
1608 		    ((scsa2usb_blacklist[i].idProduct == desc->idProduct) ||
1609 		    (scsa2usb_blacklist[i].idProduct == X))) {
1610 			scsa2usbp->scsa2usb_attrs &=
1611 				~(scsa2usb_blacklist[i].attributes);
1612 			break;
1613 		}
1614 	}
1615 
1616 	/*
1617 	 * Mitsumi's CD-RW drives subclass isn't UFI.
1618 	 * But they support UFI command-set (this code ensures that)
1619 	 * NOTE: This is a special case, and is being called out so.
1620 	 */
1621 	if (desc->idVendor == MS_MITSUMI_VID) {
1622 		mask = scsa2usbp->scsa2usb_cmd_protocol & SCSA2USB_CMDSET_MASK;
1623 		if (mask) {
1624 			scsa2usbp->scsa2usb_cmd_protocol &= ~mask;
1625 		}
1626 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
1627 	}
1628 
1629 	if (scsa2usbp->scsa2usb_attrs != SCSA2USB_ALL_ATTRS) {
1630 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1631 		    scsa2usbp->scsa2usb_log_handle,
1632 		    "scsa2usb attributes modified: 0x%x",
1633 		    scsa2usbp->scsa2usb_attrs);
1634 	}
1635 }
1636 
1637 
1638 /*
1639  * scsa2usb_create_luns:
1640  *	check the number of luns but continue if the check fails,
1641  *	create child nodes for each lun
1642  */
1643 static void
1644 scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp)
1645 {
1646 	int		lun, rval;
1647 	char		*compatible[MAX_COMPAT_NAMES];	/* compatible names */
1648 	dev_info_t	*cdip;
1649 	uchar_t		dtype;
1650 	char		*node_name;
1651 	char		*driver_name = NULL;
1652 
1653 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1654 	    "scsa2usb_create_luns:");
1655 
1656 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1657 
1658 	/* Set n_luns to 1 by default (for floppies and other devices) */
1659 	scsa2usbp->scsa2usb_n_luns = 1;
1660 
1661 	/*
1662 	 * Check if there are any device out there which don't
1663 	 * support the GET_MAX_LUN command. If so, don't issue
1664 	 * control request to them.
1665 	 */
1666 	if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_LUN) == 0) {
1667 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1668 		    "get_max_lun cmd not supported");
1669 	} else {
1670 		if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1671 			scsa2usbp->scsa2usb_n_luns =
1672 				scsa2usb_bulk_only_get_max_lun(scsa2usbp);
1673 		}
1674 	}
1675 
1676 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1677 	    "scsa2usb_create_luns: %d luns found", scsa2usbp->scsa2usb_n_luns);
1678 
1679 	/*
1680 	 * create disk child for each lun
1681 	 */
1682 	for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
1683 		ASSERT(scsa2usbp->scsa2usb_lun_dip[lun] == NULL);
1684 
1685 		/* do an inquiry to get the dtype of this lun */
1686 		scsa2usb_do_inquiry(scsa2usbp, 0, lun);
1687 
1688 		dtype = scsa2usbp->scsa2usb_lun_inquiry[lun].
1689 						inq_dtype & DTYPE_MASK;
1690 
1691 		USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1692 		    "dtype[%d]=0x%x", lun, dtype);
1693 
1694 		driver_name = NULL;
1695 
1696 		switch (dtype) {
1697 		case DTYPE_DIRECT:
1698 		case DTYPE_RODIRECT:
1699 		case DTYPE_OPTICAL:
1700 			node_name = "disk";
1701 			driver_name = "sd";
1702 
1703 			break;
1704 		case DTYPE_SEQUENTIAL:
1705 			node_name = "tape";
1706 			driver_name = "st";
1707 
1708 			break;
1709 		case DTYPE_PRINTER:
1710 			node_name = "printer";
1711 
1712 			break;
1713 		case DTYPE_PROCESSOR:
1714 			node_name = "processor";
1715 
1716 			break;
1717 		case DTYPE_WORM:
1718 			node_name = "worm";
1719 
1720 			break;
1721 		case DTYPE_SCANNER:
1722 			node_name = "scanner";
1723 
1724 			break;
1725 		case DTYPE_CHANGER:
1726 			node_name = "changer";
1727 
1728 			break;
1729 		case DTYPE_COMM:
1730 			node_name = "comm";
1731 
1732 			break;
1733 		case DTYPE_ARRAY_CTRL:
1734 			node_name = "array_ctrl";
1735 
1736 			break;
1737 		case DTYPE_ESI:
1738 			node_name = "esi";
1739 			driver_name = "ses";
1740 
1741 			break;
1742 		default:
1743 			node_name = "generic";
1744 
1745 			break;
1746 		}
1747 
1748 		if (driver_name) {
1749 			compatible[0] = driver_name;
1750 		}
1751 
1752 		ndi_devi_alloc_sleep(scsa2usbp->scsa2usb_dip, node_name,
1753 		    (pnode_t)DEVI_SID_NODEID, &cdip);
1754 
1755 		/* attach target & lun properties */
1756 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0);
1757 		if (rval != DDI_PROP_SUCCESS) {
1758 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1759 			    scsa2usbp->scsa2usb_log_handle,
1760 			    "ndi_prop_update_int target failed %d", rval);
1761 			(void) ndi_devi_free(cdip);
1762 			continue;
1763 		}
1764 
1765 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", lun);
1766 		if (rval != DDI_PROP_SUCCESS) {
1767 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1768 			    scsa2usbp->scsa2usb_log_handle,
1769 			    "ndi_prop_update_int lun failed %d", rval);
1770 			ddi_prop_remove_all(cdip);
1771 			(void) ndi_devi_free(cdip);
1772 			continue;
1773 		}
1774 
1775 		if (driver_name) {
1776 			rval = ndi_prop_update_string_array(DDI_DEV_T_NONE,
1777 			    cdip, "compatible", (char **)compatible,
1778 			    MAX_COMPAT_NAMES);
1779 			if (rval != DDI_PROP_SUCCESS) {
1780 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1781 				    scsa2usbp->scsa2usb_log_handle,
1782 				    "ndi_prop_update_string_array failed %d",
1783 				    rval);
1784 				ddi_prop_remove_all(cdip);
1785 				(void) ndi_devi_free(cdip);
1786 				continue;
1787 			}
1788 		}
1789 
1790 		/*
1791 		 * add property "usb" so we always verify that it is our child
1792 		 */
1793 		rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb");
1794 		if (rval != DDI_PROP_SUCCESS) {
1795 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1796 			    scsa2usbp->scsa2usb_log_handle,
1797 			    "ndi_prop_create_boolean failed %d", rval);
1798 			ddi_prop_remove_all(cdip);
1799 			(void) ndi_devi_free(cdip);
1800 			continue;
1801 		}
1802 
1803 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1804 		(void) ddi_initchild(scsa2usbp->scsa2usb_dip, cdip);
1805 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1806 
1807 		usba_set_usba_device(cdip,
1808 			usba_get_usba_device(scsa2usbp->scsa2usb_dip));
1809 	}
1810 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1811 }
1812 
1813 
1814 /*
1815  * scsa2usb_is_usb:
1816  *	scsa2usb gets called for all possible sd children.
1817  *	we can only accept usb children
1818  */
1819 static int
1820 scsa2usb_is_usb(dev_info_t *dip)
1821 {
1822 	if (dip) {
1823 		return (ddi_prop_exists(DDI_DEV_T_ANY, dip,
1824 		    DDI_PROP_DONTPASS, "usb"));
1825 	}
1826 	return (0);
1827 }
1828 
1829 
1830 /*
1831  * Panic Stuff
1832  * scsa2usb_panic_callb_init:
1833  *	initialize PANIC callb and free allocated resources
1834  */
1835 static void
1836 scsa2usb_panic_callb_init(scsa2usb_state_t *scsa2usbp)
1837 {
1838 	/*
1839 	 * In case the system panics, the sync command flushes
1840 	 * dirty FS pages or buffers. This would cause a hang
1841 	 * in USB.
1842 	 * The reason for the failure is that we enter
1843 	 * polled mode (interrupts disabled) and HCD gets stuck
1844 	 * trying to execute bulk requests
1845 	 * The panic_callback registered below provides a warning
1846 	 * that a panic has occurred and from that point onwards, we
1847 	 * complete each request successfully and immediately. This
1848 	 * will fake successful syncing so at least the rest of the
1849 	 * filesystems complete syncing.
1850 	 */
1851 	scsa2usbp->scsa2usb_panic_info =
1852 		kmem_zalloc(sizeof (scsa2usb_cpr_t), KM_SLEEP);
1853 	mutex_init(&scsa2usbp->scsa2usb_panic_info->lockp,
1854 		NULL, MUTEX_DRIVER,
1855 		scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
1856 	scsa2usbp->scsa2usb_panic_info->statep = scsa2usbp;
1857 	scsa2usbp->scsa2usb_panic_info->cpr.cc_lockp =
1858 				&scsa2usbp->scsa2usb_panic_info->lockp;
1859 	scsa2usbp->scsa2usb_panic_info->cpr.cc_id =
1860 			callb_add(scsa2usb_panic_callb,
1861 			    (void *)scsa2usbp->scsa2usb_panic_info,
1862 			    CB_CL_PANIC, "scsa2usb");
1863 }
1864 
1865 
1866 /*
1867  * scsa2usb_panic_callb_fini:
1868  *	cancel out PANIC callb and free allocated resources
1869  */
1870 static void
1871 scsa2usb_panic_callb_fini(scsa2usb_state_t *scsa2usbp)
1872 {
1873 	if (scsa2usbp->scsa2usb_panic_info) {
1874 		SCSA2USB_CANCEL_CB(scsa2usbp->scsa2usb_panic_info->cpr.cc_id);
1875 		mutex_destroy(&scsa2usbp->scsa2usb_panic_info->lockp);
1876 		scsa2usbp->scsa2usb_panic_info->statep = NULL;
1877 		kmem_free(scsa2usbp->scsa2usb_panic_info,
1878 		    sizeof (scsa2usb_cpr_t));
1879 		scsa2usbp->scsa2usb_panic_info = NULL;
1880 	}
1881 }
1882 
1883 
1884 /*
1885  * scsa2usb_panic_callb:
1886  *	This routine is called when there is a system panic.
1887  */
1888 /* ARGSUSED */
1889 static boolean_t
1890 scsa2usb_panic_callb(void *arg, int code)
1891 {
1892 	scsa2usb_cpr_t *cpr_infop;
1893 	scsa2usb_state_t *scsa2usbp;
1894 	uint_t		lun;
1895 
1896 	_NOTE(NO_COMPETING_THREADS_NOW);
1897 	cpr_infop = (scsa2usb_cpr_t *)arg;
1898 	scsa2usbp = (scsa2usb_state_t *)cpr_infop->statep;
1899 
1900 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1901 	    "scsa2usb_panic_callb: code=%d", code);
1902 
1903 	/*
1904 	 * If we return error here, "sd" prints lots of error
1905 	 * messages and could retry the same pkt over and over again.
1906 	 * The sync recovery isn't "smooth" in that case. By faking
1907 	 * a success return, instead,  we force sync to complete.
1908 	 */
1909 	if (scsa2usbp->scsa2usb_cur_pkt) {
1910 		/*
1911 		 * Do not print the "no sync" warning here. it will then be
1912 		 * displayed before we actually start syncing. Also we don't
1913 		 * replace this code with a call to scsa2usb_pkt_completion().
1914 		 * NOTE: mutexes are disabled during panic.
1915 		 */
1916 		scsa2usbp->scsa2usb_cur_pkt->pkt_reason = CMD_CMPLT;
1917 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1918 		scsa2usb_pkt_completion(scsa2usbp, scsa2usbp->scsa2usb_cur_pkt);
1919 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1920 	}
1921 
1922 	/* get rid of waitQ */
1923 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
1924 		scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_CMPLT);
1925 	}
1926 
1927 	_NOTE(COMPETING_THREADS_NOW);
1928 
1929 	return (B_TRUE);
1930 }
1931 
1932 /*
1933  * scsa2usb_cpr_suspend
1934  *	determine if the device's state can be changed to SUSPENDED
1935  *	close pipes if there is no activity
1936  */
1937 /* ARGSUSED */
1938 static int
1939 scsa2usb_cpr_suspend(dev_info_t *dip)
1940 {
1941 	scsa2usb_state_t *scsa2usbp;
1942 	int	prev_state;
1943 	int	rval = USB_FAILURE;
1944 
1945 	scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
1946 
1947 	ASSERT(scsa2usbp != NULL);
1948 
1949 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1950 	    "scsa2usb_cpr_suspend:");
1951 
1952 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1953 	switch (scsa2usbp->scsa2usb_dev_state) {
1954 	case USB_DEV_ONLINE:
1955 	case USB_DEV_PWRED_DOWN:
1956 	case USB_DEV_DISCONNECTED:
1957 		prev_state = scsa2usbp->scsa2usb_dev_state;
1958 		scsa2usbp->scsa2usb_dev_state = USB_DEV_SUSPENDED;
1959 
1960 		/*
1961 		 * If the device is busy, we cannot suspend
1962 		 */
1963 		if (SCSA2USB_BUSY(scsa2usbp)) {
1964 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
1965 			    scsa2usbp->scsa2usb_log_handle,
1966 			    "scsa2usb_cpr_suspend: I/O active");
1967 
1968 			/* fall back to previous state */
1969 			scsa2usbp->scsa2usb_dev_state = prev_state;
1970 		} else {
1971 			rval = USB_SUCCESS;
1972 		}
1973 
1974 		break;
1975 	case USB_DEV_SUSPENDED:
1976 	default:
1977 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1978 		    "scsa2usb_cpr_suspend: Illegal dev state: %d",
1979 		    scsa2usbp->scsa2usb_dev_state);
1980 
1981 		break;
1982 	}
1983 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1984 
1985 	if ((rval == USB_SUCCESS) && scsa2usbp->scsa2usb_ugen_hdl) {
1986 		rval = usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
1987 							DDI_SUSPEND);
1988 	}
1989 
1990 	return (rval);
1991 }
1992 
1993 
1994 /*
1995  * scsa2usb_cpr_resume:
1996  *	restore device's state
1997  */
1998 static void
1999 scsa2usb_cpr_resume(dev_info_t *dip)
2000 {
2001 	scsa2usb_state_t *scsa2usbp =
2002 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2003 
2004 	ASSERT(scsa2usbp != NULL);
2005 
2006 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2007 	    "scsa2usb_cpr_resume: dip = 0x%p", dip);
2008 
2009 	scsa2usb_restore_device_state(dip, scsa2usbp);
2010 
2011 	if (scsa2usbp->scsa2usb_ugen_hdl) {
2012 		(void) usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl,
2013 							DDI_RESUME);
2014 	}
2015 }
2016 
2017 
2018 /*
2019  * scsa2usb_restore_device_state:
2020  *	- raise the device's power
2021  *	- reopen all the pipes
2022  */
2023 static void
2024 scsa2usb_restore_device_state(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
2025 {
2026 	uint_t	prev_state;
2027 
2028 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2029 	    "scsa2usb_restore_device_state:");
2030 
2031 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2032 	prev_state = scsa2usbp->scsa2usb_dev_state;
2033 
2034 	scsa2usb_raise_power(scsa2usbp);
2035 
2036 	ASSERT((prev_state == USB_DEV_DISCONNECTED) ||
2037 	    (prev_state == USB_DEV_SUSPENDED));
2038 
2039 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2040 
2041 	/* Check for the same device */
2042 	if (usb_check_same_device(dip, scsa2usbp->scsa2usb_log_handle,
2043 	    USB_LOG_L0, DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) {
2044 
2045 		/* change the flags to active */
2046 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2047 		scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
2048 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2049 
2050 		scsa2usb_pm_idle_component(scsa2usbp);
2051 
2052 		return;
2053 	}
2054 
2055 	/*
2056 	 * if the device had remote wakeup earlier,
2057 	 * enable it again
2058 	 */
2059 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2060 	if (scsa2usbp->scsa2usb_pm &&
2061 	    scsa2usbp->scsa2usb_pm->scsa2usb_wakeup_enabled) {
2062 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2063 		(void) usb_handle_remote_wakeup(scsa2usbp->scsa2usb_dip,
2064 		    USB_REMOTE_WAKEUP_ENABLE);
2065 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2066 	}
2067 
2068 	scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
2069 	scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
2070 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2071 
2072 	scsa2usb_pm_idle_component(scsa2usbp);
2073 }
2074 
2075 
2076 /*
2077  * SCSA entry points:
2078  *
2079  * scsa2usb_scsi_tgt_probe:
2080  * scsa functions are exported by means of the transport table
2081  * Issue a probe to get the inquiry data.
2082  */
2083 /* ARGSUSED */
2084 static int
2085 scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void))
2086 {
2087 	scsi_hba_tran_t *tran;
2088 	scsa2usb_state_t *scsa2usbp;
2089 	dev_info_t *dip = ddi_get_parent(sd->sd_dev);
2090 	int rval;
2091 
2092 	ASSERT(dip);
2093 
2094 	tran = ddi_get_driver_private(dip);
2095 	ASSERT(tran != NULL);
2096 	scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
2097 	ASSERT(scsa2usbp);
2098 
2099 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2100 	    "scsa2usb_scsi_tgt_probe:");
2101 
2102 	/* if device is disconnected (ie. pipes closed), fail immediately */
2103 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2104 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2105 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2106 
2107 		return (SCSIPROBE_FAILURE);
2108 	}
2109 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2110 
2111 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2112 	    "scsa2usb_scsi_tgt_probe: scsi_device = 0x%p", sd);
2113 
2114 	if ((rval = scsi_hba_probe(sd, waitfunc)) == SCSIPROBE_EXISTS) {
2115 		/*
2116 		 * fake the removable bit on all USB storage devices
2117 		 * unless overridden by a scsa2usb.conf entry
2118 		 */
2119 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2120 		if (scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB) {
2121 			_NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry))
2122 			sd->sd_inq->inq_rmb = 1;
2123 		}
2124 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2125 	}
2126 
2127 	return (rval);
2128 }
2129 
2130 
2131 /*
2132  * scsa2usb_scsi_tgt_init:
2133  *	check whether we created this child ourselves
2134  */
2135 /* ARGSUSED */
2136 static int
2137 scsa2usb_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip,
2138     scsi_hba_tran_t *tran, struct scsi_device *sd)
2139 {
2140 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2141 					tran->tran_hba_private;
2142 	int lun;
2143 	int t_len = sizeof (lun);
2144 
2145 	if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2146 	    DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2147 	    &t_len) != DDI_PROP_SUCCESS) {
2148 
2149 		return (DDI_FAILURE);
2150 	}
2151 
2152 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2153 	    "scsa2usb_scsi_tgt_init: %s, lun%d", ddi_driver_name(cdip), lun);
2154 
2155 	/* is this a child we created? */
2156 	if (scsa2usb_is_usb(cdip) == 0) {
2157 
2158 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2159 		    "scsa2usb_scsi_tgt_init: new child %s%d",
2160 		    ddi_driver_name(cdip), ddi_get_instance(cdip));
2161 
2162 		/*
2163 		 * add property "usb" so we can always verify that it
2164 		 * is our child
2165 		 */
2166 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb") !=
2167 		    DDI_PROP_SUCCESS) {
2168 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2169 			    scsa2usbp->scsa2usb_log_handle,
2170 			    "ndi_prop_create_boolean failed");
2171 
2172 			return (DDI_FAILURE);
2173 		}
2174 
2175 		usba_set_usba_device(cdip,
2176 			usba_get_usba_device(scsa2usbp->scsa2usb_dip));
2177 
2178 		/*
2179 		 * we don't store this dip in scsa2usb_lun_dip, there
2180 		 * might be multiple dips for the same device
2181 		 */
2182 
2183 		return (DDI_SUCCESS);
2184 	}
2185 
2186 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2187 	if ((lun >= scsa2usbp->scsa2usb_n_luns) ||
2188 	    (scsa2usbp->scsa2usb_lun_dip[lun] != NULL)) {
2189 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2190 
2191 		return (DDI_FAILURE);
2192 	}
2193 
2194 	scsa2usbp->scsa2usb_lun_dip[lun] = cdip;
2195 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2196 
2197 	return (DDI_SUCCESS);
2198 }
2199 
2200 
2201 /*
2202  * scsa2usb_scsi_tgt_free:
2203  */
2204 /* ARGSUSED */
2205 static void
2206 scsa2usb_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *cdip,
2207 	scsi_hba_tran_t *tran, struct scsi_device *sd)
2208 {
2209 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2210 					tran->tran_hba_private;
2211 	int lun;
2212 	int t_len = sizeof (lun);
2213 
2214 	/* is this our child? */
2215 	if (scsa2usb_is_usb(cdip) == 0) {
2216 
2217 		return;
2218 	}
2219 
2220 	if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2221 	    DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2222 	    &t_len) != DDI_PROP_SUCCESS) {
2223 
2224 		return;
2225 	}
2226 
2227 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2228 	    "scsa2usb_scsi_tgt_free: %s lun%d", ddi_driver_name(cdip), lun);
2229 
2230 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2231 	if (lun < scsa2usbp->scsa2usb_n_luns) {
2232 		if (scsa2usbp->scsa2usb_lun_dip[lun] == cdip) {
2233 			scsa2usbp->scsa2usb_lun_dip[lun] = NULL;
2234 		}
2235 	}
2236 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2237 }
2238 
2239 
2240 /*
2241  * bus enumeration entry points
2242  */
2243 static int
2244 scsa2usb_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2245     void *arg, dev_info_t **child)
2246 {
2247 	int	circ;
2248 	int	rval;
2249 
2250 	scsa2usb_state_t *scsa2usbp =
2251 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2252 
2253 	ASSERT(scsa2usbp != NULL);
2254 
2255 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2256 	    "scsa2usb_scsi_bus_config: op=%d", op);
2257 
2258 	if (scsa2usb_scsi_bus_config_debug) {
2259 		flag |= NDI_DEVI_DEBUG;
2260 	}
2261 
2262 	ndi_devi_enter(dip, &circ);
2263 	/* create children if necessary */
2264 	if (DEVI(dip)->devi_child == NULL) {
2265 		scsa2usb_create_luns(scsa2usbp);
2266 	}
2267 
2268 	rval = ndi_busop_bus_config(dip, flag, op, arg, child, 0);
2269 
2270 	ndi_devi_exit(dip, circ);
2271 
2272 	return (rval);
2273 }
2274 
2275 
2276 static int
2277 scsa2usb_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2278     void *arg)
2279 {
2280 	scsa2usb_state_t *scsa2usbp =
2281 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2282 
2283 	int		circular_count;
2284 	int		rval = NDI_SUCCESS;
2285 	uint_t		save_flag = flag;
2286 
2287 	ASSERT(scsa2usbp != NULL);
2288 
2289 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2290 	    "scsa2usb_scsi_bus_unconfig: op=%d", op);
2291 
2292 	if (scsa2usb_scsi_bus_config_debug) {
2293 		flag |= NDI_DEVI_DEBUG;
2294 	}
2295 
2296 	/*
2297 	 * first offline and if offlining successful, then
2298 	 * remove children
2299 	 */
2300 	if (op == BUS_UNCONFIG_ALL) {
2301 		flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG);
2302 	}
2303 
2304 	ndi_devi_enter(dip, &circular_count);
2305 	rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2306 
2307 	/*
2308 	 * If unconfig is successful and not part of modunload
2309 	 * daemon, attempt to remove children.
2310 	 */
2311 	if (op == BUS_UNCONFIG_ALL && rval == NDI_SUCCESS &&
2312 	    (flag & NDI_AUTODETACH) == 0) {
2313 		flag |= NDI_DEVI_REMOVE;
2314 		rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2315 	}
2316 	ndi_devi_exit(dip, circular_count);
2317 
2318 	if ((rval != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) &&
2319 	    (save_flag & NDI_DEVI_REMOVE)) {
2320 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2321 		if (scsa2usbp->scsa2usb_warning_given != B_TRUE) {
2322 			USB_DPRINTF_L0(DPRINT_MASK_SCSA,
2323 			    scsa2usbp->scsa2usb_log_handle,
2324 			    "Disconnected device was busy, "
2325 			    "please reconnect.");
2326 			scsa2usbp->scsa2usb_warning_given = B_TRUE;
2327 		}
2328 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2329 	}
2330 
2331 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2332 	    "scsa2usb_scsi_bus_unconfig: rval=%d", rval);
2333 
2334 	return (rval);
2335 }
2336 
2337 
2338 /*
2339  * scsa2usb_scsi_init_pkt:
2340  *	Set up the scsi_pkt for transport. Also initialize
2341  *	scsa2usb_cmd struct for the transport.
2342  *	NOTE: We do not do any DMA setup here as USBA framework
2343  *	does that for us.
2344  */
2345 static struct scsi_pkt *
2346 scsa2usb_scsi_init_pkt(struct scsi_address *ap,
2347     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
2348     int tgtlen, int flags, int (*callback)(), caddr_t arg)
2349 {
2350 	scsa2usb_cmd_t	 *cmd;
2351 	scsa2usb_state_t *scsa2usbp;
2352 	struct scsi_pkt	 *in_pkt = pkt;
2353 
2354 	ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
2355 
2356 	scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2357 
2358 	/* Print sync message */
2359 	if (ddi_in_panic()) {
2360 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2361 		SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2362 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2363 		/* continue so caller will not hang or complain */
2364 	}
2365 
2366 	/* allocate a pkt, if none already allocated */
2367 	if (pkt == NULL) {
2368 		if (statuslen < sizeof (struct scsi_arq_status)) {
2369 			statuslen = sizeof (struct scsi_arq_status);
2370 		}
2371 
2372 		pkt = scsi_hba_pkt_alloc(scsa2usbp->scsa2usb_dip, ap, cmdlen,
2373 			statuslen, tgtlen, sizeof (scsa2usb_cmd_t),
2374 			callback, arg);
2375 		if (pkt == NULL) {
2376 
2377 			return (NULL);
2378 		}
2379 
2380 		cmd = PKT2CMD(pkt);
2381 		cmd->cmd_pkt	= pkt; /* back link to pkt */
2382 		cmd->cmd_scblen	= statuslen;
2383 		cmd->cmd_cdblen	= (uchar_t)cmdlen;
2384 
2385 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2386 		cmd->cmd_tag	= scsa2usbp->scsa2usb_tag++;
2387 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2388 
2389 		cmd->cmd_bp	= bp;
2390 		pkt->pkt_scbp	= (opaque_t)&cmd->cmd_scb;
2391 
2392 		usba_init_list(&cmd->cmd_waitQ, (usb_opaque_t)cmd,
2393 			scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2394 	} else {
2395 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2396 		    "scsa2usb: pkt != NULL");
2397 
2398 		/* nothing to do */
2399 	}
2400 
2401 	if (bp) {
2402 		if ((bp_mapin_common(bp, (callback == SLEEP_FUNC) ?
2403 		    VM_SLEEP : VM_NOSLEEP)) == NULL) {
2404 			if (pkt != in_pkt) {
2405 				scsi_hba_pkt_free(ap, pkt);
2406 			}
2407 
2408 			return (NULL);
2409 		}
2410 
2411 		USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2412 		    scsa2usbp->scsa2usb_log_handle,
2413 		    "scsa2usb_scsi_init_pkt: mapped in 0x%p, addr=0x%p",
2414 		    bp, bp->b_un.b_addr);
2415 	}
2416 
2417 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2418 	    "scsa2usb_scsi_init_pkt: ap = 0x%p pkt: 0x%p\n\t"
2419 	    "bp = 0x%p cmdlen = %x stlen = 0x%x tlen = 0x%x flags = 0x%x",
2420 	    ap, pkt, bp, cmdlen, statuslen, tgtlen, flags);
2421 
2422 	return (pkt);
2423 }
2424 
2425 
2426 /*
2427  * scsa2usb_scsi_destroy_pkt:
2428  *	We are done with the packet. Get rid of it.
2429  */
2430 static void
2431 scsa2usb_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2432 {
2433 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
2434 	scsa2usb_state_t *scsa2usbp = ADDR2SCSA2USB(ap);
2435 
2436 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2437 	    "scsa2usb_scsi_destroy_pkt: pkt=0x%p", pkt);
2438 
2439 	usba_destroy_list(&cmd->cmd_waitQ);
2440 	scsi_hba_pkt_free(ap, pkt);
2441 }
2442 
2443 
2444 /*
2445  * scsa2usb_scsi_start:
2446  *	For each command being issued, build up the CDB
2447  *	and call scsi_transport to issue the command. This
2448  *	function is based on the assumption that USB allows
2449  *	a subset of SCSI commands. Other SCSI commands we fail.
2450  */
2451 static int
2452 scsa2usb_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2453 {
2454 	scsa2usb_cmd_t		*cmd;
2455 	scsa2usb_state_t	*scsa2usbp = ADDR2SCSA2USB(ap);
2456 	uint_t			lun = ap->a_lun;
2457 
2458 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2459 
2460 	cmd = PKT2CMD(pkt);
2461 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2462 	    "scsa2usb_scsi_start:\n\t"
2463 	    "bp: 0x%p ap: 0x%p pkt: 0x%p flag: 0x%x time: 0x%x\n\tcdb0: 0x%x "
2464 	    "dev_state: 0x%x pkt_state: 0x%x flags: 0x%x pipe_state: 0x%x",
2465 	    cmd->cmd_bp, ap, pkt, pkt->pkt_flags, pkt->pkt_time,
2466 	    pkt->pkt_cdbp[0], scsa2usbp->scsa2usb_dev_state,
2467 	    scsa2usbp->scsa2usb_pkt_state, scsa2usbp->scsa2usb_flags,
2468 	    scsa2usbp->scsa2usb_pipe_state);
2469 
2470 	if (pkt->pkt_time == 0) {
2471 		USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2472 		    "pkt submitted with 0 timeout which may cause indefinite "
2473 		    "hangs");
2474 	}
2475 
2476 	/*
2477 	 * if we are in panic, we are in polled mode, so we can just
2478 	 * accept the request, drop it and return
2479 	 * if we fail this request, the rest of the file systems do not
2480 	 * get synced
2481 	 */
2482 	if (ddi_in_panic()) {
2483 		extern int do_polled_io;
2484 
2485 		ASSERT(do_polled_io);
2486 		scsa2usb_prepare_pkt(scsa2usbp, pkt);
2487 		SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2488 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2489 
2490 		return (TRAN_ACCEPT);
2491 	}
2492 
2493 	/* we cannot do polling, this should not happen */
2494 	if (pkt->pkt_flags & FLAG_NOINTR) {
2495 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2496 		    "NOINTR packet: opcode = 0%x", pkt->pkt_cdbp[0]);
2497 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2498 
2499 		return (TRAN_BADPKT);
2500 	}
2501 
2502 	/* is there a ugen open? */
2503 	if (scsa2usbp->scsa2usb_ugen_open_count) {
2504 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2505 		    "ugen access in progress (count=%d)",
2506 		    scsa2usbp->scsa2usb_ugen_open_count);
2507 
2508 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2509 
2510 		return (TRAN_BUSY);
2511 	}
2512 
2513 	/* prepare packet */
2514 	scsa2usb_prepare_pkt(scsa2usbp, pkt);
2515 
2516 	/* just queue up the requests in the waitQ if below max */
2517 	if (usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]) >
2518 	    SCSA2USB_MAX_REQ_PER_LUN) {
2519 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2520 		    scsa2usbp->scsa2usb_log_handle,
2521 		    "scsa2usb_scsi_start: limit (%d) exceeded",
2522 		    SCSA2USB_MAX_REQ_PER_LUN);
2523 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2524 
2525 		return (TRAN_BUSY);
2526 	}
2527 
2528 	usba_add_to_list(&scsa2usbp->scsa2usb_waitQ[lun], &cmd->cmd_waitQ);
2529 
2530 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2531 	    "scsa2usb_work_thread_id=0x%x, count=%d, lun=%d",
2532 	    scsa2usbp->scsa2usb_work_thread_id,
2533 	    usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]), lun);
2534 
2535 	/* fire up a thread to start executing the protocol */
2536 	if (scsa2usbp->scsa2usb_work_thread_id == 0) {
2537 		if ((usb_async_req(scsa2usbp->scsa2usb_dip,
2538 		    scsa2usb_work_thread,
2539 		    (void *)scsa2usbp, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
2540 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2541 			    scsa2usbp->scsa2usb_log_handle,
2542 			    "no work thread started");
2543 
2544 			if (usba_rm_from_list(
2545 			    &scsa2usbp->scsa2usb_waitQ[lun],
2546 			    &cmd->cmd_waitQ) == USB_SUCCESS) {
2547 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
2548 
2549 				return (TRAN_BUSY);
2550 			} else {
2551 
2552 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
2553 
2554 				return (TRAN_ACCEPT);
2555 			}
2556 		}
2557 		scsa2usbp->scsa2usb_work_thread_id = (kthread_t *)1;
2558 	}
2559 
2560 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2561 
2562 	return (TRAN_ACCEPT);
2563 }
2564 
2565 
2566 /*
2567  * scsa2usb_scsi_abort:
2568  *	Issue SCSI abort command. This function is a NOP.
2569  */
2570 /* ARGSUSED */
2571 static int
2572 scsa2usb_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
2573 {
2574 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2575 
2576 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2577 	    "scsa2usb_scsi_abort: pkt = %p", pkt);
2578 
2579 	/* if device is disconnected (ie. pipes closed), fail immediately */
2580 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2581 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2582 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2583 
2584 		return (0);
2585 	}
2586 
2587 	/* flush waitQ if target and lun match */
2588 	if ((ap->a_target == pkt->pkt_address.a_target) &&
2589 	    (ap->a_lun == pkt->pkt_address.a_lun)) {
2590 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2591 		scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_ABORTED);
2592 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2593 	}
2594 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2595 
2596 	return (0);
2597 }
2598 
2599 
2600 /*
2601  * scsa2usb_scsi_reset:
2602  *	device reset may turn the device into a brick and bus reset
2603  *	is not applicable.
2604  *	just flush the waitQ
2605  *	We return success, always.
2606  */
2607 /* ARGSUSED */
2608 static int
2609 scsa2usb_scsi_reset(struct scsi_address *ap, int level)
2610 {
2611 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2612 
2613 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2614 	    "scsa2usb_scsi_reset: ap = 0x%p, level = %d", ap, level);
2615 
2616 	/* flush waitQ */
2617 	scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_RESET);
2618 
2619 	return (1);
2620 }
2621 
2622 
2623 /*
2624  * scsa2usb_scsi_getcap:
2625  *	Get SCSI capabilities.
2626  */
2627 /* ARGSUSED */
2628 static int
2629 scsa2usb_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
2630 {
2631 	int rval = -1;
2632 	uint_t cidx;
2633 	size_t dev_bsize_cap;
2634 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2635 	ASSERT(scsa2usbp);
2636 
2637 	if (cap == NULL) {
2638 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2639 		    "scsa2usb_scsi_getcap: invalid arg, "
2640 		    "cap = 0x%p whom = %d", cap, whom);
2641 
2642 		return (rval);
2643 	}
2644 
2645 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2646 	    "scsa2usb_scsi_getcap: cap = %s", cap);
2647 
2648 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2649 
2650 	/* if device is disconnected (ie. pipes closed), fail immediately */
2651 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2652 
2653 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2654 
2655 		return (rval);
2656 	}
2657 
2658 	cidx =	scsi_hba_lookup_capstr(cap);
2659 	switch (cidx) {
2660 	case SCSI_CAP_GEOMETRY:
2661 		dev_bsize_cap = scsa2usbp->scsa2usb_totalsec[ap->a_lun];
2662 
2663 		if (scsa2usbp->scsa2usb_secsz[ap->a_lun] > DEV_BSIZE) {
2664 			dev_bsize_cap *=
2665 			    scsa2usbp->scsa2usb_secsz[ap->a_lun] / DEV_BSIZE;
2666 		} else if (scsa2usbp->scsa2usb_secsz[ap->a_lun] <
2667 		    DEV_BSIZE) {
2668 			dev_bsize_cap /=
2669 			    DEV_BSIZE / scsa2usbp->scsa2usb_secsz[ap->a_lun];
2670 		}
2671 
2672 		if (dev_bsize_cap < 65536 * 2 * 18) {		/* < ~1GB */
2673 			/* unlabeled floppy, 18k per cylinder */
2674 			rval = ((2 << 16) | 18);
2675 		} else if (dev_bsize_cap < 65536 * 64 * 32) {	/* < 64GB */
2676 			/* 1024k per cylinder */
2677 			rval = ((64 << 16) | 32);
2678 		} else if (dev_bsize_cap < 65536 * 255 * 63) {	/* < ~500GB */
2679 			/* ~8m per cylinder */
2680 			rval = ((255 << 16) | 63);
2681 		} else {					/* .. 8TB */
2682 			/* 64m per cylinder */
2683 			rval = ((512 << 16) | 256);
2684 		}
2685 		break;
2686 
2687 	case SCSI_CAP_DMA_MAX:
2688 		rval = scsa2usbp->scsa2usb_max_bulk_xfer_size;
2689 		break;
2690 	case SCSI_CAP_SCSI_VERSION:
2691 		rval = SCSI_VERSION_2;
2692 		break;
2693 	case SCSI_CAP_INTERCONNECT_TYPE:
2694 		rval = INTERCONNECT_USB;
2695 		break;
2696 	case SCSI_CAP_ARQ:
2697 		/* FALLTHRU */
2698 	case SCSI_CAP_UNTAGGED_QING:
2699 		rval = 1;
2700 		break;
2701 	default:
2702 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2703 		    "scsa2usb_scsi_getcap: unsupported cap = %s", cap);
2704 		break;
2705 	}
2706 
2707 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2708 	    "scsa2usb_scsi_getcap: cap = %s, returned = %d", cap, rval);
2709 
2710 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2711 
2712 	return (rval);
2713 }
2714 
2715 
2716 /*
2717  * scsa2usb_scsi_setcap:
2718  *	Set SCSI capabilities.
2719  */
2720 /* ARGSUSED */
2721 static int
2722 scsa2usb_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
2723 {
2724 	int rval = -1; /* default is cap undefined */
2725 	uint_t cidx;
2726 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2727 	ASSERT(scsa2usbp);
2728 
2729 	if (cap == NULL || whom == 0) {
2730 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2731 		    "scsa2usb_scsi_setcap: invalid arg");
2732 
2733 		return (rval);
2734 	}
2735 
2736 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2737 	/* if device is disconnected (ie. pipes closed), fail immediately */
2738 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2739 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2740 
2741 		return (rval);
2742 	}
2743 
2744 	cidx =	scsi_hba_lookup_capstr(cap);
2745 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2746 	    "scsa2usb_scsi_setcap: ap = 0x%p value = 0x%x whom = 0x%x "
2747 	    "cidx = 0x%x", ap, value, whom, cidx);
2748 
2749 	switch (cidx) {
2750 	case SCSI_CAP_SECTOR_SIZE:
2751 		if (value) {
2752 			scsa2usbp->scsa2usb_secsz[ap->a_lun] = value;
2753 		}
2754 		break;
2755 	case SCSI_CAP_TOTAL_SECTORS:
2756 		if (value) {
2757 			scsa2usbp->scsa2usb_totalsec[ap->a_lun] = value;
2758 		}
2759 		break;
2760 	case SCSI_CAP_ARQ:
2761 		rval = 1;
2762 		break;
2763 	case SCSI_CAP_DMA_MAX:
2764 	case SCSI_CAP_SCSI_VERSION:
2765 	case SCSI_CAP_INTERCONNECT_TYPE:
2766 	case SCSI_CAP_UNTAGGED_QING:
2767 		/* supported but not settable */
2768 		rval = 0;
2769 		break;
2770 	default:
2771 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2772 		    "scsa2usb_scsi_setcap: unsupported cap = %s", cap);
2773 		break;
2774 	}
2775 
2776 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2777 
2778 	return (rval);
2779 }
2780 
2781 
2782 /*
2783  * scsa2usb - cmd and transport stuff
2784  */
2785 /*
2786  * scsa2usb_prepare_pkt:
2787  *	initialize some fields of the pkt and cmd
2788  *	(the pkt may have been resubmitted/retried)
2789  */
2790 static void
2791 scsa2usb_prepare_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
2792 {
2793 	scsa2usb_cmd_t	*cmd = PKT2CMD(pkt);
2794 
2795 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2796 	    "scsa2usb_prepare_pkt: pkt=0x%p cdb: 0x%x (%s)",
2797 	    pkt, pkt->pkt_cdbp[0],
2798 	    scsi_cname(pkt->pkt_cdbp[0], scsa2usb_cmds));
2799 
2800 	pkt->pkt_reason = CMD_CMPLT;	/* Set reason to pkt_complete */
2801 	pkt->pkt_state = 0;		/* Reset next three fields */
2802 	pkt->pkt_statistics = 0;
2803 	pkt->pkt_resid = 0;
2804 	bzero(pkt->pkt_scbp, cmd->cmd_scblen); /* Set status to good */
2805 
2806 	if (cmd) {
2807 		cmd->cmd_timeout = pkt->pkt_time;
2808 		cmd->cmd_xfercount = 0;		/* Reset the fields */
2809 		cmd->cmd_total_xfercount = 0;
2810 		cmd->cmd_lba = 0;
2811 		cmd->cmd_done = 0;
2812 		cmd->cmd_dir = 0;
2813 		cmd->cmd_offset = 0;
2814 		cmd->cmd_actual_len = cmd->cmd_cdblen;
2815 	}
2816 }
2817 
2818 
2819 /*
2820  * scsa2usb_force_invalid_request
2821  */
2822 static void
2823 scsa2usb_force_invalid_request(scsa2usb_state_t *scsa2usbp,
2824     scsa2usb_cmd_t *cmd)
2825 {
2826 	struct scsi_arq_status	*arqp;
2827 
2828 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2829 	    "scsa2usb_force_invalid_request: pkt = 0x%p", cmd->cmd_pkt);
2830 
2831 	if (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) {
2832 		arqp = (struct scsi_arq_status *)cmd->cmd_pkt->pkt_scbp;
2833 		bzero(arqp, cmd->cmd_scblen);
2834 
2835 		arqp->sts_status.sts_chk = 1;
2836 		arqp->sts_rqpkt_reason = CMD_CMPLT;
2837 		arqp->sts_rqpkt_state = STATE_XFERRED_DATA |
2838 		    STATE_GOT_BUS | STATE_GOT_STATUS;
2839 		arqp->sts_sensedata.es_valid = 1;
2840 		arqp->sts_sensedata.es_class = 7;
2841 		arqp->sts_sensedata.es_key = KEY_ILLEGAL_REQUEST;
2842 
2843 		cmd->cmd_pkt->pkt_state = STATE_ARQ_DONE |
2844 		    STATE_GOT_BUS | STATE_GOT_BUS | STATE_GOT_BUS |
2845 		    STATE_GOT_STATUS;
2846 #ifdef DEBUG
2847 		{
2848 			uchar_t *p = (uchar_t *)(&arqp->sts_sensedata);
2849 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2850 			    scsa2usbp->scsa2usb_log_handle,
2851 			    "cdb: %x rqsense: "
2852 			    "%x %x %x %x %x %x %x %x %x %x "
2853 			    "%x %x %x %x %x %x %x %x %x %x",
2854 			    cmd->cmd_pkt->pkt_cdbp[0],
2855 			    p[0], p[1], p[2], p[3], p[4],
2856 			    p[5], p[6], p[7], p[8], p[9],
2857 			    p[10], p[11], p[12], p[13], p[14],
2858 			    p[15], p[16], p[17], p[18], p[19]);
2859 		}
2860 #endif
2861 
2862 	}
2863 }
2864 
2865 
2866 /*
2867  * scsa2usb_cmd_transport:
2868  */
2869 static int
2870 scsa2usb_cmd_transport(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
2871 {
2872 	int rval, transport;
2873 	struct scsi_pkt *pkt;
2874 
2875 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2876 	    "scsa2usb_cmd_transport: pkt: 0x%p, cur_pkt = 0x%p",
2877 	    cmd->cmd_pkt, scsa2usbp->scsa2usb_cur_pkt);
2878 
2879 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
2880 	ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
2881 
2882 	pkt = scsa2usbp->scsa2usb_cur_pkt = cmd->cmd_pkt;
2883 
2884 	/* check black-listed attrs first */
2885 	if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
2886 		transport = scsa2usb_check_bulkonly_blacklist_attrs(scsa2usbp,
2887 					cmd, pkt->pkt_cdbp[0]);
2888 	} else if (SCSA2USB_IS_CB(scsa2usbp) || SCSA2USB_IS_CBI(scsa2usbp)) {
2889 		transport =  scsa2usb_check_ufi_blacklist_attrs(scsa2usbp,
2890 					pkt->pkt_cdbp[0], cmd);
2891 	}
2892 
2893 	/* just accept the command */
2894 	if (transport == SCSA2USB_JUST_ACCEPT) {
2895 		SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
2896 
2897 		return (TRAN_ACCEPT);
2898 	}
2899 
2900 	/* check command set next */
2901 	if (SCSA2USB_IS_SCSI_CMDSET(scsa2usbp) ||
2902 	    SCSA2USB_IS_ATAPI_CMDSET(scsa2usbp)) {
2903 		transport =
2904 		    scsa2usb_handle_scsi_cmd_sub_class(scsa2usbp, cmd, pkt);
2905 	} else if (SCSA2USB_IS_UFI_CMDSET(scsa2usbp)) {
2906 		transport =
2907 		    scsa2usb_handle_ufi_subclass_cmd(scsa2usbp, cmd, pkt);
2908 	} else {
2909 		transport = SCSA2USB_REJECT;
2910 	}
2911 
2912 	if (transport == SCSA2USB_TRANSPORT) {
2913 		if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
2914 			rval = scsa2usb_bulk_only_transport(scsa2usbp, cmd);
2915 		} else if (SCSA2USB_IS_CB(scsa2usbp) ||
2916 		    SCSA2USB_IS_CBI(scsa2usbp)) {
2917 			rval = scsa2usb_cbi_transport(scsa2usbp, cmd);
2918 		} else {
2919 			rval = TRAN_FATAL_ERROR;
2920 		}
2921 	} else {
2922 		rval = TRAN_FATAL_ERROR;
2923 	}
2924 
2925 
2926 	return (rval);
2927 }
2928 
2929 
2930 /*
2931  * scsa2usb_check_bulkonly_blacklist_attrs:
2932  *	validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
2933  *	if blacklisted attrs match accept the request
2934  *	attributes checked are:-
2935  *		SCSA2USB_ATTRS_START_STOP
2936  */
2937 int
2938 scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t *scsa2usbp,
2939     scsa2usb_cmd_t *cmd, uchar_t opcode)
2940 {
2941 	struct scsi_inquiry *inq =
2942 	    &scsa2usbp->scsa2usb_lun_inquiry[cmd->cmd_pkt->pkt_address.a_lun];
2943 
2944 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2945 	    "scsa2usb_check_bulkonly_blacklist_attrs: opcode = %s",
2946 	    scsi_cname(opcode, scsa2usb_cmds));
2947 
2948 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
2949 
2950 	/*
2951 	 * decode and convert the packet
2952 	 * for most cmds, we can bcopy the cdb
2953 	 */
2954 	switch (opcode) {
2955 	case SCMD_DOORLOCK:
2956 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_DOORLOCK)) {
2957 
2958 			return (SCSA2USB_JUST_ACCEPT);
2959 
2960 		/*
2961 		 * only lock the door for CD and DVD drives
2962 		 */
2963 		} else if ((inq->inq_dtype == DTYPE_RODIRECT) ||
2964 		    (inq->inq_dtype == DTYPE_OPTICAL)) {
2965 
2966 			if (inq->inq_rmb) {
2967 
2968 				break;
2969 			}
2970 		}
2971 
2972 		return (SCSA2USB_JUST_ACCEPT);
2973 
2974 	case SCMD_START_STOP:
2975 		/*
2976 		 * these devices don't have mechanics that spin the
2977 		 * media up and down. So, it doesn't make much sense
2978 		 * to issue this cmd.
2979 		 *
2980 		 * Furthermore, Hagiwara devices do not handle these
2981 		 * cmds well. just accept this command as success.
2982 		 */
2983 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
2984 
2985 			return (SCSA2USB_JUST_ACCEPT);
2986 
2987 		} else if (cmd->cmd_pkt->pkt_cdbp[4] & LOEJECT) {
2988 			/*
2989 			 * if the device is really a removable then
2990 			 * pass it on to the device, else just accept
2991 			 */
2992 			if (inq->inq_rmb) {
2993 
2994 				break;
2995 			}
2996 
2997 			return (SCSA2USB_JUST_ACCEPT);
2998 
2999 		} else if (!scsa2usbp->scsa2usb_rcvd_not_ready) {
3000 			/*
3001 			 * if we have not received a NOT READY condition,
3002 			 * just accept since some device choke on this too.
3003 			 * we do have to let EJECT get through though
3004 			 */
3005 			return (SCSA2USB_JUST_ACCEPT);
3006 		}
3007 
3008 		break;
3009 	case SCMD_INQUIRY:
3010 		/*
3011 		 * Some devices do not handle the inquiry cmd well
3012 		 * so build an inquiry and accept this command as
3013 		 * success.
3014 		 */
3015 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3016 			uchar_t evpd = 0x01;
3017 
3018 			if (cmd->cmd_cdb[1] & evpd) {
3019 
3020 				return (SCSA2USB_REJECT);
3021 			}
3022 			cmd->cmd_pkt->pkt_resid -=
3023 					scsa2usb_fake_inquiry(scsa2usbp, cmd,
3024 					cmd->cmd_pkt->pkt_address.a_lun);
3025 			cmd->cmd_pkt->pkt_state |= STATE_XFERRED_DATA;
3026 
3027 			return (SCSA2USB_JUST_ACCEPT);
3028 		}
3029 		break;
3030 
3031 	/*
3032 	 * Fake accepting the following  Opcodes
3033 	 * (as most drives don't support these)
3034 	 * These are needed by format command.
3035 	 */
3036 	case SCMD_RESERVE:
3037 	case SCMD_RELEASE:
3038 	case SCMD_PERSISTENT_RESERVE_IN:
3039 	case SCMD_PERSISTENT_RESERVE_OUT:
3040 
3041 		return (SCSA2USB_JUST_ACCEPT);
3042 
3043 	case SCMD_MODE_SENSE:
3044 	case SCMD_MODE_SELECT:
3045 	case SCMD_MODE_SENSE_G1:
3046 	case SCMD_MODE_SELECT_G1:
3047 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_MODE_SENSE)) {
3048 			if (cmd->cmd_bp) {
3049 				cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3050 								b_bcount;
3051 			}
3052 			scsa2usb_force_invalid_request(scsa2usbp, cmd);
3053 
3054 			return (SCSA2USB_JUST_ACCEPT);
3055 		}
3056 
3057 		break;
3058 	default:
3059 
3060 		break;
3061 	}
3062 
3063 	return (SCSA2USB_TRANSPORT);
3064 }
3065 
3066 
3067 /*
3068  * scsa2usb_handle_scsi_cmd_sub_class:
3069  *	prepare a scsi cmd
3070  *	returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT, SCSA2USB_JUST_ACCEPT
3071  */
3072 int
3073 scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *scsa2usbp,
3074     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3075 {
3076 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3077 	    "scsa2usb_handle_scsi_cmd_sub_class: cmd = 0x%p pkt = 0x%p",
3078 	    cmd, pkt);
3079 
3080 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3081 
3082 	bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3083 	cmd->cmd_cdb[SCSA2USB_OPCODE] = pkt->pkt_cdbp[0];   /* Set the opcode */
3084 	cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3085 
3086 	/*
3087 	 * decode and convert the packet
3088 	 * for most cmds, we can bcopy the cdb
3089 	 */
3090 	switch (pkt->pkt_cdbp[0]) {
3091 	case SCMD_FORMAT:
3092 		/*
3093 		 * SCMD_FORMAT used to limit cmd->cmd_xfercount
3094 		 * to 4 bytes, but this hangs
3095 		 * formatting dvd media using cdrecord (that is,
3096 		 * a SCSI FORMAT UNIT command with a parameter list > 4 bytes)
3097 		 * (bit 4 in cdb1 is the Fmtdata bit)
3098 		 */
3099 		if ((pkt->pkt_cdbp[1] & 0x10) && cmd->cmd_bp) {
3100 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3101 		} else {
3102 			cmd->cmd_xfercount = 4;
3103 		}
3104 		cmd->cmd_dir = CBW_DIR_OUT;
3105 		cmd->cmd_actual_len = CDB_GROUP0;
3106 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3107 		break;
3108 
3109 	case SCMD_INQUIRY:
3110 		cmd->cmd_dir = CBW_DIR_IN;
3111 		cmd->cmd_actual_len = CDB_GROUP0;
3112 		cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3113 		cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3114 		    min(SCSA2USB_MAX_INQ_LEN,
3115 		    cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3116 		break;
3117 
3118 	case SCMD_READ_CAPACITY:
3119 		cmd->cmd_dir = CBW_DIR_IN;
3120 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3121 		cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3122 		break;
3123 
3124 	/*
3125 	 * SCMD_READ/SCMD_WRITE are converted to G1 cmds
3126 	 * (as ATAPI devices don't recognize G0 commands)
3127 	 *
3128 	 * SCMD_READ_LONG/SCMD_WRITE_LONG are handled in
3129 	 * scsa2usb_rw_transport() along with other commands.
3130 	 *
3131 	 * USB Host Controllers cannot handle large (read/write)
3132 	 * xfers. We split the large request to chunks of
3133 	 * smaller ones to meet the HCD limitations.
3134 	 */
3135 	case SCMD_READ:
3136 	case SCMD_WRITE:
3137 	case SCMD_READ_G1:
3138 	case SCMD_WRITE_G1:
3139 	case SCMD_READ_G5:
3140 	case SCMD_WRITE_G5:
3141 	case SCMD_READ_LONG:
3142 	case SCMD_WRITE_LONG:
3143 	case SCMD_READ_CD:
3144 		switch (scsa2usbp->
3145 		    scsa2usb_lun_inquiry[pkt->pkt_address.a_lun].
3146 		    inq_dtype & DTYPE_MASK) {
3147 		case DTYPE_DIRECT:
3148 		case DTYPE_RODIRECT:
3149 		case DTYPE_OPTICAL:
3150 			return (scsa2usb_rw_transport(
3151 					scsa2usbp, pkt));
3152 		default:
3153 			bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3154 			if (cmd->cmd_bp) {
3155 				cmd->cmd_dir =
3156 				    (cmd->cmd_bp->b_flags & B_READ) ?
3157 				    CBW_DIR_IN : CBW_DIR_OUT;
3158 				cmd->cmd_xfercount =
3159 				    cmd->cmd_bp->b_bcount;
3160 			}
3161 			break;
3162 		}
3163 		break;
3164 
3165 	case SCMD_REQUEST_SENSE:
3166 		cmd->cmd_dir = CBW_DIR_IN;
3167 		cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3168 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3169 		cmd->cmd_actual_len = CDB_GROUP0;
3170 		break;
3171 
3172 	/*
3173 	 * do not convert SCMD_MODE_SENSE/SELECT to G1 cmds because
3174 	 * the mode header is different as well
3175 	 */
3176 
3177 	case SCMD_DOORLOCK:
3178 	case SCMD_START_STOP:
3179 	case SCMD_TEST_UNIT_READY:
3180 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3181 		break;
3182 
3183 	/*
3184 	 * Needed by zip protocol to reset the device
3185 	 */
3186 	case SCMD_SDIAG:
3187 	case SCMD_REZERO_UNIT:
3188 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3189 		cmd->cmd_actual_len = CDB_GROUP1;
3190 		break;
3191 
3192 	case SCMD_WRITE_VERIFY:
3193 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3194 		cmd->cmd_dir = CBW_DIR_OUT;
3195 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3196 		cmd->cmd_actual_len = CDB_GROUP1;
3197 		break;
3198 
3199 	/*
3200 	 * Next command does not have a SCSI equivalent as
3201 	 * it is vendor specific.
3202 	 * It was listed in the vendor's ATAPI Zip specs.
3203 	 */
3204 	case SCMD_READ_FORMAT_CAP:
3205 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3206 		cmd->cmd_dir = CBW_DIR_IN;
3207 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3208 		cmd->cmd_actual_len = CDB_GROUP1;
3209 		break;
3210 	case IOMEGA_CMD_CARTRIDGE_PROTECT:
3211 		cmd->cmd_dir = CBW_DIR_OUT;
3212 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3213 		cmd->cmd_cdb[SCSA2USB_LBA_2] &= ~1;	/* Make it even */
3214 		cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3215 		cmd->cmd_actual_len = CDB_GROUP0;
3216 		cmd->cmd_xfercount = pkt->pkt_cdbp[4]; /* Length of password */
3217 		break;
3218 
3219 	default:
3220 		/*
3221 		 * an unknown command may be a uscsi cmd which we
3222 		 * should let go thru without mapping
3223 		 */
3224 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3225 		if (cmd->cmd_bp) {
3226 			cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3227 						CBW_DIR_IN : CBW_DIR_OUT;
3228 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3229 		}
3230 
3231 		break;
3232 	} /* end of switch */
3233 
3234 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3235 	    "scsa2usb_handle_scsi_cmd_sub_class: opcode = 0x%x count = 0x%lx",
3236 	    pkt->pkt_cdbp[SCSA2USB_OPCODE], cmd->cmd_xfercount);
3237 
3238 	cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3239 
3240 	return (SCSA2USB_TRANSPORT);
3241 }
3242 
3243 
3244 /*
3245  * scsa2usb_check_ufi_blacklist_attrs:
3246  *	validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3247  *	if blacklisted attrs match accept the request
3248  *	attributes checked are:-
3249  *		SCSA2USB_ATTRS_GET_CONF
3250  *		SCSA2USB_ATTRS_GET_PERF
3251  *		SCSA2USB_ATTRS_GET_START_STOP
3252  */
3253 static int
3254 scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *scsa2usbp, uchar_t opcode,
3255     scsa2usb_cmd_t *cmd)
3256 {
3257 	int	rval = SCSA2USB_TRANSPORT;
3258 
3259 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3260 
3261 	switch (opcode) {
3262 	case SCMD_PRIN:
3263 	case SCMD_PROUT:
3264 		rval = SCSA2USB_JUST_ACCEPT;
3265 		break;
3266 	case SCMD_MODE_SENSE:
3267 	case SCMD_MODE_SELECT:
3268 		if (cmd->cmd_bp) {
3269 			cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3270 		}
3271 		scsa2usb_force_invalid_request(scsa2usbp, cmd);
3272 		rval = SCSA2USB_JUST_ACCEPT;
3273 		break;
3274 	case SCMD_GET_CONFIGURATION:
3275 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_CONF)) {
3276 			rval = SCSA2USB_JUST_ACCEPT;
3277 		}
3278 		break;
3279 	case SCMD_GET_PERFORMANCE:
3280 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_PERF)) {
3281 			rval = SCSA2USB_JUST_ACCEPT;
3282 		}
3283 		break;
3284 	case SCMD_START_STOP:
3285 		/*
3286 		 * some CB/CBI devices don't have mechanics that spin the
3287 		 * media up and down. So, it doesn't make much sense
3288 		 * to issue this cmd to those devices.
3289 		 */
3290 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3291 			rval = SCSA2USB_JUST_ACCEPT;
3292 		}
3293 		break;
3294 	default:
3295 		break;
3296 	}
3297 
3298 	return (rval);
3299 }
3300 
3301 
3302 /*
3303  * scsa2usb_handle_ufi_subclass_cmd:
3304  *	prepare a UFI cmd
3305  *	returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT
3306  */
3307 int
3308 scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *scsa2usbp,
3309     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3310 {
3311 	uchar_t opcode =  pkt->pkt_cdbp[0];
3312 
3313 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3314 	    "scsa2usb_handle_ufi_subclass_cmd: cmd = 0x%p pkt = 0x%p",
3315 	    cmd, pkt);
3316 
3317 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3318 
3319 	bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3320 	cmd->cmd_cdb[SCSA2USB_OPCODE] = opcode;   /* Set the opcode */
3321 	cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3322 
3323 	/*
3324 	 * decode and convert the packet if necessary
3325 	 * for most cmds, we can bcopy the cdb
3326 	 */
3327 	switch (opcode) {
3328 	case SCMD_FORMAT:
3329 		/* if parameter list is specified */
3330 		if (pkt->pkt_cdbp[1] & 0x10) {
3331 			cmd->cmd_xfercount =
3332 				(pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3333 			cmd->cmd_dir = USB_EP_DIR_OUT;
3334 			cmd->cmd_actual_len = CDB_GROUP5;
3335 		}
3336 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3337 		break;
3338 	case SCMD_INQUIRY:
3339 		cmd->cmd_dir = USB_EP_DIR_IN;
3340 		cmd->cmd_actual_len = CDB_GROUP0;
3341 		cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3342 		cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3343 		    min(SCSA2USB_MAX_INQ_LEN,
3344 		    cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3345 		break;
3346 	case SCMD_READ_CAPACITY:
3347 		cmd->cmd_dir = USB_EP_DIR_IN;
3348 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3349 		cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3350 		break;
3351 	case SCMD_REQUEST_SENSE:
3352 		cmd->cmd_dir = USB_EP_DIR_IN;
3353 		cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3354 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3355 		cmd->cmd_actual_len = CDB_GROUP0;
3356 		break;
3357 
3358 	/*
3359 	 * do not convert SCMD_MODE_SENSE/SELECT because the
3360 	 * mode header is different as well
3361 	 */
3362 
3363 	/*
3364 	 * see usb_bulkonly.c for comments on the next set of commands
3365 	 */
3366 	case SCMD_READ:
3367 	case SCMD_WRITE:
3368 	case SCMD_READ_G1:
3369 	case SCMD_WRITE_G1:
3370 	case SCMD_READ_G5:
3371 	case SCMD_WRITE_G5:
3372 	case SCMD_READ_LONG:
3373 	case SCMD_WRITE_LONG:
3374 	case SCMD_READ_CD:
3375 
3376 		return (scsa2usb_rw_transport(scsa2usbp, pkt));
3377 
3378 	case SCMD_TEST_UNIT_READY:
3379 		/*
3380 		 * Some CB/CBI devices may not support TUR.
3381 		 */
3382 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3383 		break;
3384 	case SCMD_READ_FORMAT_CAP:
3385 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3386 		cmd->cmd_dir = USB_EP_DIR_IN;
3387 		cmd->cmd_actual_len = CDB_GROUP1;
3388 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3389 		break;
3390 	case SCMD_WRITE_VERIFY:
3391 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3392 		cmd->cmd_dir = USB_EP_DIR_OUT;
3393 		cmd->cmd_actual_len = CDB_GROUP1;
3394 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3395 		break;
3396 	case SCMD_START_STOP:
3397 		/* A larger timeout is needed for 'flaky' CD-RW devices */
3398 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_BIG_TIMEOUT)) {
3399 			cmd->cmd_timeout = max(cmd->cmd_timeout,
3400 					20 * SCSA2USB_BULK_PIPE_TIMEOUT);
3401 		}
3402 		/* FALLTHRU */
3403 	default:
3404 		/*
3405 		 * all other commands don't need special mapping
3406 		 */
3407 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3408 		if (cmd->cmd_bp) {
3409 			cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3410 						CBW_DIR_IN : CBW_DIR_OUT;
3411 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3412 		}
3413 		break;
3414 
3415 	} /* end of switch */
3416 
3417 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3418 	    "scsa2usb_handle_ufi_subclass_cmd: opcode = 0x%x count = 0x%lx",
3419 	    opcode, cmd->cmd_xfercount);
3420 
3421 	cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3422 
3423 	return (SCSA2USB_TRANSPORT);
3424 }
3425 
3426 
3427 /*
3428  * scsa2usb_rw_transport:
3429  *	Handle splitting READ and WRITE requests to the
3430  *	device to a size that the host controller allows.
3431  *
3432  *	returns TRAN_* values and not USB_SUCCESS/FAILURE
3433  *
3434  * To support CD-R/CD-RW/DVD media, we need to support a
3435  * variety of block sizes for the different types of CD
3436  * data (audio, data, video, CD-XA, yellowbook, redbook etc.)
3437  *
3438  * Some of the block sizes used are:- 512, 1k, 2k, 2056, 2336
3439  * 2340, 2352, 2368, 2448, 2646, 2647 etc.
3440  *
3441  * NOTE: the driver could be entertaining a SCSI CDB that uses
3442  * any of the above listed block sizes at a given time, and a
3443  * totally different block size at any other given time for a
3444  * different CDB.
3445  *
3446  * We need to compute block size every time and figure out
3447  * matching LBA and LEN accordingly.
3448  *
3449  * Also UHCI has a limitation that it can only xfer 32k at a
3450  * given time. So, with "odd" sized blocks and a limitation of
3451  * how much we can xfer per shot, we need to compute xfer_count
3452  * as well each time.
3453  *
3454  * The same computation is also done in the function
3455  * scsa2usb_setup_next_xfer().	To save computing block_size in
3456  * this function, I am saving block_size in "cmd" now.
3457  */
3458 int
3459 scsa2usb_rw_transport(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
3460 {
3461 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
3462 	int lba, dir, opcode;
3463 	struct buf *bp = cmd->cmd_bp;
3464 	size_t len, xfer_count;
3465 	size_t blk_size;	/* calculate the block size to be used */
3466 	int sz;
3467 
3468 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3469 	    "scsa2usb_rw_transport:");
3470 
3471 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3472 
3473 	opcode = pkt->pkt_cdbp[0];
3474 	blk_size  = scsa2usbp->scsa2usb_lbasize[pkt->pkt_address.a_lun];
3475 						/* set to default */
3476 
3477 	switch (opcode) {
3478 	case SCMD_READ:
3479 		/*
3480 		 * Note that READ/WRITE(6) are not supported by the drive.
3481 		 * convert it into a 10 byte read/write.
3482 		 */
3483 		lba = SCSA2USB_LBA_6BYTE(pkt);
3484 		len = SCSA2USB_LEN_6BYTE(pkt);
3485 		opcode = SCMD_READ_G1;	/* Overwrite it w/ byte 10 cmd val */
3486 		dir = USB_EP_DIR_IN;
3487 		break;
3488 	case SCMD_WRITE:
3489 		lba = SCSA2USB_LBA_6BYTE(pkt);
3490 		len = SCSA2USB_LEN_6BYTE(pkt);
3491 		opcode = SCMD_WRITE_G1;	/* Overwrite it w/ byte 10 cmd val */
3492 		dir = USB_EP_DIR_OUT;
3493 		break;
3494 	case SCMD_READ_G1:
3495 	case SCMD_READ_LONG:
3496 		lba = SCSA2USB_LBA_10BYTE(pkt);
3497 		len = SCSA2USB_LEN_10BYTE(pkt);
3498 		dir = USB_EP_DIR_IN;
3499 		break;
3500 	case SCMD_WRITE_G1:
3501 	case SCMD_WRITE_LONG:
3502 		lba = SCSA2USB_LBA_10BYTE(pkt);
3503 		len = SCSA2USB_LEN_10BYTE(pkt);
3504 		dir = USB_EP_DIR_OUT;
3505 		if (len) {
3506 			sz = SCSA2USB_CDRW_BLKSZ(bp ? bp->b_bcount : 0, len);
3507 			if (SCSA2USB_VALID_CDRW_BLKSZ(sz)) {
3508 				blk_size = sz;	/* change it accordingly */
3509 			}
3510 		}
3511 		break;
3512 	case SCMD_READ_CD:
3513 		lba = SCSA2USB_LBA_10BYTE(pkt);
3514 		len = SCSA2USB_LEN_READ_CD(pkt);
3515 		dir = USB_EP_DIR_IN;
3516 
3517 		/* Figure out the block size */
3518 		blk_size = scsa2usb_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2);
3519 		break;
3520 	case SCMD_READ_G5:
3521 		lba = SCSA2USB_LBA_12BYTE(pkt);
3522 		len = SCSA2USB_LEN_12BYTE(pkt);
3523 		dir = USB_EP_DIR_IN;
3524 		break;
3525 	case SCMD_WRITE_G5:
3526 		lba = SCSA2USB_LBA_12BYTE(pkt);
3527 		len = SCSA2USB_LEN_12BYTE(pkt);
3528 		dir = USB_EP_DIR_OUT;
3529 		break;
3530 	}
3531 
3532 	cmd->cmd_total_xfercount = xfer_count = len * blk_size;
3533 
3534 	/* reduce xfer count if necessary */
3535 	if (blk_size &&
3536 	    (xfer_count > scsa2usbp->scsa2usb_max_bulk_xfer_size)) {
3537 		/*
3538 		 * For CD-RW devices reduce the xfer count based
3539 		 * on the block size used by these devices. The
3540 		 * block size could change for READ_CD and WRITE
3541 		 * opcodes.
3542 		 *
3543 		 * Also as UHCI allows a max xfer of 32k at a time;
3544 		 * compute the xfer_count based on the new block_size.
3545 		 *
3546 		 * The len part of the cdb changes as a result of that.
3547 		 */
3548 		if (SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3549 			xfer_count = ((scsa2usbp->scsa2usb_max_bulk_xfer_size/
3550 					blk_size) * blk_size);
3551 			len = xfer_count/blk_size;
3552 			xfer_count = blk_size * len;
3553 		} else {
3554 			xfer_count = scsa2usbp->scsa2usb_max_bulk_xfer_size;
3555 			len = xfer_count/blk_size;
3556 		}
3557 	}
3558 
3559 	cmd->cmd_xfercount = xfer_count;
3560 	cmd->cmd_dir = (uchar_t)dir;
3561 	cmd->cmd_blksize = blk_size;
3562 
3563 	/*
3564 	 * Having figure out the 'partial' xfer len based on he
3565 	 * block size; fill it in to the cmd->cmd_cdb
3566 	 */
3567 	cmd->cmd_cdb[SCSA2USB_OPCODE] = (uchar_t)opcode;
3568 	switch (opcode) {
3569 	case SCMD_READ_CD:
3570 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3571 		scsa2usb_fill_up_ReadCD_cdb_len(cmd, len, CDB_GROUP5);
3572 		break;
3573 	case SCMD_WRITE_G5:
3574 	case SCMD_READ_G5:
3575 		scsa2usb_fill_up_12byte_cdb_len(cmd, len, CDB_GROUP5);
3576 		break;
3577 	default:
3578 		scsa2usb_fill_up_cdb_len(cmd, len);
3579 		cmd->cmd_actual_len = CDB_GROUP1;
3580 		break;
3581 	}
3582 
3583 	scsa2usb_fill_up_cdb_lba(cmd, lba);
3584 
3585 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3586 	    "bcount=0x%lx lba=0x%x len=0x%lx xfercount=0x%lx total=0x%lx",
3587 	    bp ? bp->b_bcount : 0, lba, len, cmd->cmd_xfercount,
3588 	    cmd->cmd_total_xfercount);
3589 
3590 	/* Set the timeout value as per command request */
3591 	if ((opcode == SCMD_WRITE_G1) && SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3592 		/*
3593 		 * We increase the time as CD-RW writes have two things
3594 		 * to do. After writing out the data to the media, a
3595 		 * TOC needs to be filled up at the beginning of the media
3596 		 * This is when the write gets "finalized".
3597 		 * Hence the actual write could take longer than the
3598 		 * value specified in cmd->cmd_timeout.
3599 		 */
3600 		cmd->cmd_timeout *= 4;
3601 
3602 		USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3603 		    scsa2usbp->scsa2usb_log_handle,
3604 		    "new timeout value = 0x%x", cmd->cmd_timeout);
3605 	}
3606 
3607 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3608 	    "lba 0x%x len 0x%lx xfercount 0x%lx total 0x%lx",
3609 	    lba, len, cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3610 
3611 	return (SCSA2USB_TRANSPORT);
3612 }
3613 
3614 
3615 /*
3616  * scsa2usb_setup_next_xfer:
3617  *	For READs and WRITEs we split up the transfer in terms of
3618  *	HCD understood units. This function handles the split transfers.
3619  *
3620  * See comments in the previous function scsa2usb_rw_transport
3621  *
3622  * The lba computation was being done based on scsa2usb_max_bulk_xfer_size
3623  * earlier. With CD-RW devices, the xfer_count and the block_size may
3624  * no longer be a multiple of scsa2usb_max_bulk_xfer_size. So compute
3625  * xfer_count all over again. Adjust lba, based on the previous requests'
3626  * len. Find out the len and add it to cmd->cmd_lba to get the new lba
3627  */
3628 void
3629 scsa2usb_setup_next_xfer(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3630 {
3631 	int xfer_len = min(scsa2usbp->scsa2usb_max_bulk_xfer_size,
3632 			cmd->cmd_total_xfercount);
3633 	int cdb_len;
3634 	size_t blk_size;
3635 
3636 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3637 
3638 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3639 	    "scsa2usb_setup_next_xfer: opcode = 0x%x lba = 0x%x "
3640 	    "total count = 0x%lx", cmd->cmd_cdb[SCSA2USB_OPCODE],
3641 	    cmd->cmd_lba, cmd->cmd_total_xfercount);
3642 
3643 	ASSERT(cmd->cmd_total_xfercount > 0);
3644 	cmd->cmd_xfercount = xfer_len;
3645 	blk_size = scsa2usbp->scsa2usb_lbasize[
3646 				cmd->cmd_pkt->pkt_address.a_lun];
3647 
3648 	/*
3649 	 * For CD-RW devices reduce the xfer count based on the
3650 	 * block_size used by these devices. See changes below
3651 	 * where xfer_count is being adjusted.
3652 	 *
3653 	 * Also adjust len/lba based on the block_size and xfer_count.
3654 	 * NOTE: Always calculate lba first, as it based on previous
3655 	 * commands' values.
3656 	 */
3657 	switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
3658 	case SCMD_READ_CD:
3659 		/* calculate lba = current_lba + len_of_prev_cmd */
3660 		cmd->cmd_lba += (cmd->cmd_cdb[6] << 16) +
3661 		    (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
3662 		cdb_len = xfer_len/cmd->cmd_blksize;
3663 		cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)cdb_len;
3664 		/* re-adjust xfer count */
3665 		cmd->cmd_xfercount = cdb_len * cmd->cmd_blksize;
3666 		break;
3667 	case SCMD_WRITE_G5:
3668 	case SCMD_READ_G5:
3669 		/* calculate lba = current_lba + len_of_prev_cmd */
3670 		cmd->cmd_lba += (cmd->cmd_cdb[6] << 24) +
3671 		    (cmd->cmd_cdb[7] << 16) + (cmd->cmd_cdb[8] << 8) +
3672 		    cmd->cmd_cdb[9];
3673 		if (blk_size) {
3674 			xfer_len /= blk_size;
3675 		}
3676 		scsa2usb_fill_up_12byte_cdb_len(cmd, xfer_len, CDB_GROUP5);
3677 		break;
3678 	case SCMD_WRITE_G1:
3679 	case SCMD_WRITE_LONG:
3680 		/* calculate lba = current_lba + len_of_prev_cmd */
3681 		cmd->cmd_lba += (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
3682 		if (SCSA2USB_VALID_CDRW_BLKSZ(cmd->cmd_blksize)) {
3683 			blk_size = cmd->cmd_blksize;
3684 		}
3685 		cdb_len = xfer_len/blk_size;
3686 		scsa2usb_fill_up_cdb_len(cmd, cdb_len);
3687 		/* re-adjust xfer count */
3688 		cmd->cmd_xfercount = cdb_len * blk_size;
3689 		break;
3690 	default:
3691 		if (blk_size) {
3692 			xfer_len /= blk_size;
3693 		}
3694 		scsa2usb_fill_up_cdb_len(cmd, xfer_len);
3695 		cmd->cmd_lba += scsa2usbp->scsa2usb_max_bulk_xfer_size/blk_size;
3696 	}
3697 
3698 	/* fill in the lba */
3699 	scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
3700 
3701 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3702 	    "scsa2usb_setup_next_xfer:\n\tlba = 0x%x xfer_len = 0x%x "
3703 	    "xfercount = 0x%lx total = 0x%lx", cmd->cmd_lba, xfer_len,
3704 	    cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3705 }
3706 
3707 
3708 /*
3709  * take one request from the lun's waitQ and transport it
3710  */
3711 static void
3712 scsa2usb_transport_request(scsa2usb_state_t *scsa2usbp, uint_t lun)
3713 {
3714 	int			rval;
3715 	struct scsi_pkt		*pkt;
3716 	struct scsa2usb_cmd	*cmd, *arqcmd;
3717 
3718 	if ((cmd = (scsa2usb_cmd_t *)
3719 	    usba_rm_first_pvt_from_list(
3720 	    &scsa2usbp->scsa2usb_waitQ[lun])) == NULL) {
3721 
3722 		return;
3723 	}
3724 	pkt = cmd->cmd_pkt;
3725 
3726 	/*
3727 	 * if device has been disconnected, just complete it
3728 	 */
3729 	if (scsa2usbp->scsa2usb_dev_state == USB_DEV_DISCONNECTED) {
3730 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3731 		    "device not accessible");
3732 		pkt->pkt_reason = CMD_DEV_GONE;
3733 		SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3734 		scsa2usb_pkt_completion(scsa2usbp, pkt);
3735 
3736 		return;
3737 	}
3738 
3739 	USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3740 	    scsa2usbp->scsa2usb_log_handle,
3741 	    "scsa2usb_transport_request: cmd=0x%p bp=0x%p addr=0x%p",
3742 	    cmd, cmd->cmd_bp,
3743 	    (cmd->cmd_bp ? cmd->cmd_bp->b_un.b_addr : NULL));
3744 
3745 	rval = scsa2usb_cmd_transport(scsa2usbp, cmd);
3746 
3747 	USB_DPRINTF_L3(DPRINT_MASK_SCSA,
3748 	    scsa2usbp->scsa2usb_log_handle,
3749 	    "scsa2usb_transport_request: transport rval = %d",
3750 	    rval);
3751 
3752 	if (scsa2usbp->scsa2usb_cur_pkt == NULL) {
3753 
3754 		return;
3755 	}
3756 
3757 	ASSERT(pkt == scsa2usbp->scsa2usb_cur_pkt);
3758 
3759 	if (ddi_in_panic()) {
3760 		pkt->pkt_reason = CMD_CMPLT;
3761 		scsa2usb_pkt_completion(scsa2usbp, pkt);
3762 
3763 		return;
3764 	}
3765 
3766 	/*
3767 	 * start an auto-request sense iff
3768 	 * there was a check condition, we have enough
3769 	 * space in the status block, and we have not
3770 	 * faked an auto request sense
3771 	 */
3772 	if ((*(pkt->pkt_scbp) == STATUS_CHECK) &&
3773 	    (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) &&
3774 	    ((pkt->pkt_state & STATE_ARQ_DONE) == 0) &&
3775 	    (scsa2usb_create_arq_pkt(scsa2usbp,
3776 	    &pkt->pkt_address) == USB_SUCCESS)) {
3777 		arqcmd = scsa2usbp->scsa2usb_arq_cmd;
3778 
3779 		/*
3780 		 * copy the timeout from the
3781 		 * original packet
3782 		 * for lack of a better value
3783 		 */
3784 		arqcmd->cmd_pkt->pkt_time = pkt->pkt_time;
3785 		scsa2usb_prepare_pkt(scsa2usbp,
3786 			    arqcmd->cmd_pkt);
3787 
3788 		scsa2usbp->scsa2usb_cur_pkt = NULL;
3789 		if (scsa2usb_cmd_transport(
3790 		    scsa2usbp, arqcmd) == TRAN_ACCEPT) {
3791 
3792 			/* finish w/ this packet */
3793 			scsa2usb_complete_arq_pkt(
3794 			    scsa2usbp, arqcmd->cmd_pkt, cmd,
3795 			    scsa2usbp->scsa2usb_arq_bp);
3796 
3797 			/*
3798 			 * we have valid request sense
3799 			 * data so clear the pkt_reason
3800 			 */
3801 			pkt->pkt_reason = CMD_CMPLT;
3802 		}
3803 		scsa2usbp->scsa2usb_cur_pkt = pkt;
3804 		scsa2usb_delete_arq_pkt(scsa2usbp);
3805 	}
3806 
3807 	if ((rval != TRAN_ACCEPT) &&
3808 	    (pkt->pkt_reason == CMD_CMPLT)) {
3809 		pkt->pkt_reason = CMD_TRAN_ERR;
3810 	}
3811 
3812 	SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3813 	scsa2usb_pkt_completion(scsa2usbp, pkt);
3814 
3815 	ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
3816 }
3817 
3818 
3819 /*
3820  * scsa2usb_work_thread:
3821  *	The taskq thread that kicks off the transport (BO and CB/CBI)
3822  */
3823 static void
3824 scsa2usb_work_thread(void *arg)
3825 {
3826 	scsa2usb_state_t	*scsa2usbp = (scsa2usb_state_t *)arg;
3827 	uint_t			lun;
3828 	uint_t			count;
3829 
3830 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3831 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3832 	    "scsa2usb_work_thread start: thread_id=0x%x",
3833 	    scsa2usbp->scsa2usb_work_thread_id);
3834 
3835 	ASSERT(scsa2usbp->scsa2usb_work_thread_id == (kthread_t *)1);
3836 	scsa2usbp->scsa2usb_work_thread_id = curthread;
3837 
3838 	/* exclude ugen accesses */
3839 	while (scsa2usbp->scsa2usb_transport_busy) {
3840 		cv_wait(&scsa2usbp->scsa2usb_transport_busy_cv,
3841 		    &scsa2usbp->scsa2usb_mutex);
3842 	}
3843 	ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
3844 	scsa2usbp->scsa2usb_transport_busy++;
3845 	scsa2usbp->scsa2usb_busy_thread = curthread;
3846 
3847 	scsa2usb_raise_power(scsa2usbp);
3848 
3849 	/* reopen the pipes if necessary */
3850 	(void) scsa2usb_open_usb_pipes(scsa2usbp);
3851 
3852 	for (;;) {
3853 		ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
3854 		for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
3855 			scsa2usb_transport_request(scsa2usbp, lun);
3856 		}
3857 		count = 0;
3858 		for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
3859 			count += usba_list_entry_count(
3860 				&scsa2usbp->scsa2usb_waitQ[lun]);
3861 		}
3862 
3863 		if (count == 0) {
3864 
3865 			break;
3866 		}
3867 	}
3868 
3869 	scsa2usbp->scsa2usb_work_thread_id = 0;
3870 
3871 	ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
3872 
3873 	scsa2usbp->scsa2usb_transport_busy--;
3874 	scsa2usbp->scsa2usb_busy_thread = NULL;
3875 	cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
3876 
3877 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3878 	    "scsa2usb_work_thread: exit");
3879 
3880 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3881 
3882 	scsa2usb_pm_idle_component(scsa2usbp);
3883 }
3884 
3885 
3886 /*
3887  * scsa2usb_flush_waitQ:
3888  *	empties the entire waitQ with errors asap.
3889  *
3890  * It is called from scsa2usb_scsi_reset and scsa2usb_panic_callb.
3891  * If the device is reset; we should empty the waitQ right away.
3892  * If the system has paniced; we should empty the waitQ right away.
3893  *
3894  * CPR suspend will only succeed if device is idle. No need to call
3895  * this function for CPR suspend case.
3896  */
3897 static void
3898 scsa2usb_flush_waitQ(scsa2usb_state_t *scsa2usbp, uint_t lun,
3899     uchar_t error)
3900 {
3901 	struct scsi_pkt		*pkt;
3902 	struct scsa2usb_cmd	*cmd;
3903 	usba_list_entry_t	head;
3904 
3905 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3906 
3907 	usba_move_list(&scsa2usbp->scsa2usb_waitQ[lun], &head,
3908 	    scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
3909 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3910 
3911 	while ((cmd = (scsa2usb_cmd_t *)usba_rm_first_pvt_from_list(&head)) !=
3912 	    NULL) {
3913 		pkt = cmd->cmd_pkt;
3914 		pkt->pkt_reason = error;	/* set error */
3915 
3916 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3917 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP;
3918 		scsa2usb_pkt_completion(scsa2usbp, pkt);
3919 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
3920 	} /* end of while */
3921 }
3922 
3923 
3924 /*
3925  * scsa2usb_do_inquiry is performed before INIT CHILD and we have
3926  * to fake a few things normally done by SCSA
3927  */
3928 static void
3929 scsa2usb_do_inquiry(scsa2usb_state_t *scsa2usbp, uint_t target, uint_t lun)
3930 {
3931 	struct buf	*bp;
3932 	struct scsi_pkt *pkt;
3933 	struct scsi_address ap;
3934 	int		len = SCSA2USB_MAX_INQ_LEN;
3935 
3936 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3937 	    "scsa2usb_do_inquiry: %d bytes", len);
3938 
3939 	/* is it inquiry-challenged? */
3940 	if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3941 		(void) scsa2usb_fake_inquiry(scsa2usbp, NULL, lun);
3942 
3943 		return;
3944 	}
3945 
3946 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3947 
3948 	bzero(&ap, sizeof (struct scsi_address));
3949 	ap.a_hba_tran = scsa2usbp->scsa2usb_tran;
3950 	ap.a_target = target;
3951 	ap.a_lun = lun;
3952 
3953 	/* limit inquiry to 36 bytes */
3954 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3955 	if ((bp = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
3956 	    len, B_READ, SLEEP_FUNC, NULL)) == NULL) {
3957 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3958 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3959 		    scsa2usbp->scsa2usb_log_handle,
3960 		    "scsa2usb_do_inquiry: failed");
3961 
3962 		return;
3963 	}
3964 
3965 	pkt = scsi_init_pkt(&ap, NULL, bp, CDB_GROUP0, 1,
3966 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL);
3967 
3968 	RQ_MAKECOM_G0(pkt, FLAG_NOINTR, (char)SCMD_INQUIRY, 0, len);
3969 
3970 	pkt->pkt_comp = NULL;
3971 	pkt->pkt_time = 5;
3972 	bzero(bp->b_un.b_addr, len);
3973 
3974 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3975 	    "scsa2usb_do_inquiry:INQUIRY");
3976 
3977 	(void) scsi_transport(pkt);
3978 
3979 	if (pkt->pkt_reason) {
3980 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3981 		    scsa2usbp->scsa2usb_log_handle,
3982 		    "INQUIRY failed, cannot determine device type, "
3983 		    "pkt_reason=0x%x", pkt->pkt_reason);
3984 
3985 		/* not much hope for other cmds, reduce */
3986 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3987 		scsa2usbp->scsa2usb_attrs &=
3988 					~SCSA2USB_ATTRS_REDUCED_CMD;
3989 		(void) scsa2usb_fake_inquiry(scsa2usbp, NULL, lun);
3990 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
3991 	}
3992 
3993 	scsi_destroy_pkt(pkt);
3994 	scsi_free_consistent_buf(bp);
3995 
3996 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3997 }
3998 
3999 
4000 /*
4001  * scsa2usb_fake_inquiry:
4002  *    build an inquiry for a given device that doesnt like inquiry
4003  *    commands.
4004  */
4005 static int
4006 scsa2usb_fake_inquiry(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd,
4007     uint_t lun)
4008 {
4009 	usb_client_dev_data_t *dev_data = scsa2usbp->scsa2usb_dev_data;
4010 	struct scsi_inquiry *inqp;
4011 	int len;
4012 
4013 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4014 	    "scsa2usb_fake_inquiry:");
4015 
4016 	if (cmd) {
4017 		inqp = (struct scsi_inquiry *)cmd->cmd_bp->b_un.b_addr;
4018 	} else {
4019 		inqp = &scsa2usbp->scsa2usb_lun_inquiry[lun];
4020 	}
4021 	bzero(inqp, sizeof (struct scsi_inquiry));
4022 	for (len = 0; len < sizeof (inqp->inq_vid); len++) {
4023 		*(inqp->inq_vid + len) = ' ';
4024 	}
4025 
4026 	for (len = 0; len < sizeof (inqp->inq_pid); len++) {
4027 		*(inqp->inq_pid + len) = ' ';
4028 	}
4029 
4030 	inqp->inq_dtype = DTYPE_DIRECT;
4031 	inqp->inq_rmb = 1;
4032 	inqp->inq_ansi = 2;
4033 	inqp->inq_rdf = RDF_SCSI2;
4034 	inqp->inq_len = sizeof (struct scsi_inquiry)-4;
4035 
4036 	/* Fill in the Vendor id/Product id strings */
4037 	if (dev_data->dev_mfg) {
4038 		if ((len = strlen(dev_data->dev_mfg)) >
4039 		    sizeof (inqp->inq_vid)) {
4040 			len = sizeof (inqp->inq_vid);
4041 		}
4042 		bcopy(dev_data->dev_mfg, inqp->inq_vid, len);
4043 	}
4044 
4045 	if (dev_data->dev_product) {
4046 		if ((len = strlen(dev_data->dev_product)) >
4047 		    sizeof (inqp->inq_pid)) {
4048 			len = sizeof (inqp->inq_pid);
4049 		}
4050 		bcopy(dev_data->dev_product, inqp->inq_pid, len);
4051 	}
4052 
4053 	/* Set the Revision to the Device */
4054 	inqp->inq_revision[0] = 0x30 +
4055 		((dev_data->dev_descr->bcdDevice>>12) & 0xF);
4056 	inqp->inq_revision[1] = 0x30 +
4057 		((dev_data->dev_descr->bcdDevice>>8) & 0xF);
4058 	inqp->inq_revision[2] = 0x30 +
4059 		((dev_data->dev_descr->bcdDevice>>4) & 0xF);
4060 	inqp->inq_revision[3] = 0x30 +
4061 		((dev_data->dev_descr->bcdDevice) & 0xF);
4062 
4063 	/* Copy inquiry data in to soft state */
4064 	bcopy(inqp, &scsa2usbp->scsa2usb_lun_inquiry[lun],
4065 	    sizeof (struct scsi_inquiry));
4066 
4067 	return (sizeof (struct scsi_inquiry));
4068 }
4069 
4070 
4071 /*
4072  * scsa2usb_create_arq_pkt:
4073  *	Create and ARQ packet to get request sense data
4074  */
4075 static int
4076 scsa2usb_create_arq_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
4077 {
4078 	struct buf *bp;
4079 	scsa2usb_cmd_t *arq_cmd;
4080 
4081 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4082 	    "scsa2usb_create_arq_pkt: scsa2usbp: %p, ap: %p", scsa2usbp, ap);
4083 
4084 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4085 
4086 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4087 	if ((bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL,
4088 	    SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4089 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4090 
4091 		return (USB_FAILURE);
4092 	}
4093 
4094 	arq_cmd = PKT2CMD(scsi_init_pkt(ap, NULL, bp, CDB_GROUP0, 1,
4095 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL));
4096 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4097 
4098 	RQ_MAKECOM_G0(arq_cmd->cmd_pkt,
4099 	    FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON,
4100 	    (char)SCMD_REQUEST_SENSE, 0, (char)SENSE_LENGTH);
4101 
4102 	arq_cmd->cmd_pkt->pkt_ha_private = arq_cmd;
4103 	scsa2usbp->scsa2usb_arq_cmd = arq_cmd;
4104 	scsa2usbp->scsa2usb_arq_bp = bp;
4105 	arq_cmd->cmd_pkt->pkt_comp = NULL;
4106 	bzero(bp->b_un.b_addr, SENSE_LENGTH);
4107 
4108 	return (USB_SUCCESS);
4109 }
4110 
4111 
4112 /*
4113  * scsa2usb_delete_arq_pkt:
4114  *	Destroy the ARQ packet
4115  */
4116 static void
4117 scsa2usb_delete_arq_pkt(scsa2usb_state_t *scsa2usbp)
4118 {
4119 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4120 	    "scsa2usb_delete_arq_pkt: cmd: 0x%p", scsa2usbp->scsa2usb_arq_cmd);
4121 
4122 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4123 
4124 	if (scsa2usbp->scsa2usb_arq_cmd != NULL) {
4125 		scsi_destroy_pkt(scsa2usbp->scsa2usb_arq_cmd->cmd_pkt);
4126 		scsi_free_consistent_buf(scsa2usbp->scsa2usb_arq_bp);
4127 	}
4128 	scsa2usbp->scsa2usb_arq_cmd = NULL;
4129 	scsa2usbp->scsa2usb_arq_bp = NULL;
4130 }
4131 
4132 
4133 /*
4134  * scsa2usb_complete_arq_pkt:
4135  *	finish processing the arq packet
4136  */
4137 static void
4138 scsa2usb_complete_arq_pkt(scsa2usb_state_t *scsa2usbp,
4139     struct scsi_pkt *pkt, scsa2usb_cmd_t *ssp, struct buf *bp)
4140 {
4141 	scsa2usb_cmd_t		*sp = pkt->pkt_ha_private;
4142 	struct scsi_arq_status	*arqp;
4143 
4144 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4145 
4146 	arqp = (struct scsi_arq_status *)(ssp->cmd_pkt->pkt_scbp);
4147 	arqp->sts_rqpkt_status = *((struct scsi_status *)
4148 		(sp->cmd_pkt->pkt_scbp));
4149 	arqp->sts_rqpkt_reason = CMD_CMPLT;
4150 	arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
4151 	arqp->sts_rqpkt_statistics = arqp->sts_rqpkt_resid = 0;
4152 
4153 	/* is this meaningful sense data */
4154 	if (*(bp->b_un.b_addr) != 0) {
4155 		bcopy(bp->b_un.b_addr, &arqp->sts_sensedata, sp->cmd_scblen);
4156 		ssp->cmd_pkt->pkt_state |= STATE_ARQ_DONE;
4157 	}
4158 
4159 	/* we will not sense start cmd until we receive a NOT READY */
4160 	if (arqp->sts_sensedata.es_key == KEY_NOT_READY) {
4161 		scsa2usbp->scsa2usb_rcvd_not_ready = B_TRUE;
4162 	}
4163 }
4164 
4165 
4166 /*
4167  * Miscellaneous functions for any command/transport
4168  */
4169 /*
4170  * scsa2usb_open_usb_pipes:
4171  *	set up a pipe policy
4172  *	open usb bulk pipes (BO and CB/CBI)
4173  *	open usb interrupt pipe (CBI)
4174  */
4175 static int
4176 scsa2usb_open_usb_pipes(scsa2usb_state_t *scsa2usbp)
4177 {
4178 	int			rval;
4179 	usb_pipe_policy_t	policy;	/* bulk pipe policy */
4180 	size_t			sz;
4181 
4182 	ASSERT(scsa2usbp);
4183 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4184 
4185 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4186 	    "scsa2usb_open_usb_pipes: dip = 0x%p flag = 0x%x",
4187 	    scsa2usbp->scsa2usb_dip, scsa2usbp->scsa2usb_flags);
4188 
4189 	if (!(scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED)) {
4190 
4191 		/*
4192 		 * one pipe policy for all bulk pipes
4193 		 */
4194 		bzero(&policy, sizeof (usb_pipe_policy_t));
4195 		/* at least 2, for the normal and exceptional callbacks */
4196 		policy.pp_max_async_reqs = 1;
4197 
4198 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4199 		    "scsa2usb_open_usb_pipes: opening bulk pipes");
4200 
4201 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4202 
4203 		/* Open the USB bulk-in pipe */
4204 		if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4205 		    &scsa2usbp->scsa2usb_bulkin_ept, &policy, USB_FLAGS_SLEEP,
4206 		    &scsa2usbp->scsa2usb_bulkin_pipe)) != USB_SUCCESS) {
4207 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4208 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4209 			    scsa2usbp->scsa2usb_log_handle,
4210 			    "scsa2usb_open_usb_pipes: bulk/in pipe open "
4211 			    " failed rval = %d", rval);
4212 
4213 			return (USB_FAILURE);
4214 		}
4215 
4216 		/* Open the bulk-out pipe  using the same policy */
4217 		if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4218 		    &scsa2usbp->scsa2usb_bulkout_ept, &policy, USB_FLAGS_SLEEP,
4219 		    &scsa2usbp->scsa2usb_bulkout_pipe)) != USB_SUCCESS) {
4220 			usb_pipe_close(scsa2usbp->scsa2usb_dip,
4221 			    scsa2usbp->scsa2usb_bulkin_pipe,
4222 			    USB_FLAGS_SLEEP, NULL, NULL);
4223 
4224 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4225 			scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4226 
4227 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4228 			    scsa2usbp->scsa2usb_log_handle,
4229 			    "scsa2usb_open_usb_pipes: bulk/out pipe open"
4230 			    " failed rval = %d", rval);
4231 
4232 			return (USB_FAILURE);
4233 		}
4234 
4235 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4236 
4237 		/* open interrupt pipe for CBI protocol */
4238 		if (SCSA2USB_IS_CBI(scsa2usbp)) {
4239 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4240 
4241 			if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4242 			    &scsa2usbp->scsa2usb_intr_ept, &policy,
4243 			    USB_FLAGS_SLEEP, &scsa2usbp->scsa2usb_intr_pipe)) !=
4244 			    USB_SUCCESS) {
4245 				usb_pipe_close(scsa2usbp->scsa2usb_dip,
4246 				    scsa2usbp->scsa2usb_bulkin_pipe,
4247 				    USB_FLAGS_SLEEP, NULL, NULL);
4248 
4249 				usb_pipe_close(scsa2usbp->scsa2usb_dip,
4250 				    scsa2usbp->scsa2usb_bulkout_pipe,
4251 				    USB_FLAGS_SLEEP, NULL, NULL);
4252 
4253 				mutex_enter(&scsa2usbp->scsa2usb_mutex);
4254 				scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4255 				scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4256 
4257 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4258 				    scsa2usbp->scsa2usb_log_handle,
4259 				    "scsa2usb_open_usb_pipes: intr pipe open"
4260 				    " failed rval = %d", rval);
4261 
4262 				return (USB_FAILURE);
4263 			}
4264 
4265 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4266 		}
4267 
4268 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4269 
4270 		/* get the max transfer size of the bulk pipe */
4271 		if (usb_pipe_get_max_bulk_transfer_size(scsa2usbp->scsa2usb_dip,
4272 		    &sz) == USB_SUCCESS) {
4273 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4274 			scsa2usbp->scsa2usb_max_bulk_xfer_size = sz;
4275 		} else {
4276 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4277 			scsa2usbp->scsa2usb_max_bulk_xfer_size = DEV_BSIZE;
4278 		}
4279 
4280 		/* limit the xfer size */
4281 		scsa2usbp->scsa2usb_max_bulk_xfer_size = min(
4282 			scsa2usbp->scsa2usb_max_bulk_xfer_size,
4283 			scsa2usb_max_bulk_xfer_size);
4284 
4285 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4286 		    "scsa2usb_open_usb_pipes: max bulk transfer size = %lx",
4287 		    scsa2usbp->scsa2usb_max_bulk_xfer_size);
4288 
4289 		/* Set the pipes opened flag */
4290 		scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_PIPES_OPENED;
4291 
4292 		scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4293 
4294 		/* Set the state to NONE */
4295 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4296 	}
4297 
4298 	return (USB_SUCCESS);
4299 }
4300 
4301 
4302 /*
4303  * scsa2usb_close_usb_pipes:
4304  *	close all pipes synchronously
4305  */
4306 void
4307 scsa2usb_close_usb_pipes(scsa2usb_state_t *scsa2usbp)
4308 {
4309 	usb_flags_t flags = USB_FLAGS_SLEEP;
4310 
4311 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4312 	    "scsa2usb_close_usb_pipes: scsa2usb_state = 0x%p", scsa2usbp);
4313 
4314 	ASSERT(scsa2usbp);
4315 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4316 
4317 	if ((scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED) == 0) {
4318 
4319 		return;
4320 	}
4321 
4322 	scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_CLOSING;
4323 	/* to avoid races, reset the flag first */
4324 	scsa2usbp->scsa2usb_flags &= ~SCSA2USB_FLAGS_PIPES_OPENED;
4325 
4326 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4327 
4328 	usb_pipe_close(scsa2usbp->scsa2usb_dip,
4329 	    scsa2usbp->scsa2usb_bulkout_pipe, flags, NULL, NULL);
4330 
4331 	usb_pipe_close(scsa2usbp->scsa2usb_dip,
4332 	    scsa2usbp->scsa2usb_bulkin_pipe, flags, NULL, NULL);
4333 
4334 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4335 	if (SCSA2USB_IS_CBI(scsa2usbp)) {
4336 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4337 		usb_pipe_close(scsa2usbp->scsa2usb_dip,
4338 		    scsa2usbp->scsa2usb_intr_pipe, flags, NULL, NULL);
4339 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4340 	}
4341 	scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4342 	scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4343 	scsa2usbp->scsa2usb_intr_pipe = NULL;
4344 
4345 	scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4346 }
4347 
4348 
4349 /*
4350  * scsa2usb_fill_up_cdb_lba:
4351  *	fill up command CDBs' LBA part
4352  */
4353 static void
4354 scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *cmd, int lba)
4355 {
4356 	/* zero cdb1, lba bits so they won't get copied in the new cdb */
4357 	cmd->cmd_cdb[SCSA2USB_LUN] &= 0xE0;
4358 	cmd->cmd_cdb[SCSA2USB_LBA_0] = lba >> 24;
4359 	cmd->cmd_cdb[SCSA2USB_LBA_1] = lba >> 16;
4360 	cmd->cmd_cdb[SCSA2USB_LBA_2] = lba >> 8;
4361 	cmd->cmd_cdb[SCSA2USB_LBA_3] = (uchar_t)lba;
4362 	cmd->cmd_lba = lba;
4363 }
4364 
4365 
4366 /*
4367  * scsa2usb_fill_up_ReadCD_cdb_len:
4368  *	fill up READ_CD command CDBs' len part
4369  */
4370 static void
4371 scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4372 {
4373 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_0] = len >> 16;
4374 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_1] = len >> 8;
4375 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)len;
4376 	cmd->cmd_actual_len = (uchar_t)actual_len;
4377 }
4378 
4379 
4380 /*
4381  * scsa2usb_fill_up_12byte_cdb_len:
4382  *	fill up generic 12-byte command CDBs' len part
4383  */
4384 static void
4385 scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4386 {
4387 	cmd->cmd_cdb[6] = len >> 24;
4388 	cmd->cmd_cdb[7] = len >> 16;
4389 	cmd->cmd_cdb[8] = len >> 8;
4390 	cmd->cmd_cdb[9] = (uchar_t)len;
4391 	cmd->cmd_actual_len = (uchar_t)actual_len;
4392 }
4393 
4394 
4395 /*
4396  * scsa2usb_fill_up_cdb_len:
4397  *	fill up generic 10-byte command CDBs' len part
4398  */
4399 static void
4400 scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *cmd, int len)
4401 {
4402 	cmd->cmd_cdb[SCSA2USB_LEN_0] = len >> 8;
4403 	cmd->cmd_cdb[SCSA2USB_LEN_1] = (uchar_t)len;
4404 }
4405 
4406 
4407 /*
4408  * scsa2usb_read_cd_blk_size:
4409  *	For SCMD_READ_CD opcode (0xbe). Figure out the
4410  *	block size based on expected sector type field
4411  *	definition. See MMC SCSI Specs section 6.1.15
4412  *
4413  *	Based on the value of the "expected_sector_type"
4414  *	field, the block size could be different.
4415  */
4416 static int
4417 scsa2usb_read_cd_blk_size(uchar_t expected_sector_type)
4418 {
4419 	int blk_size;
4420 
4421 	switch (expected_sector_type) {
4422 	case READ_CD_EST_CDDA:
4423 		blk_size = CDROM_BLK_2352;
4424 		break;
4425 	case READ_CD_EST_MODE2:
4426 		blk_size = CDROM_BLK_2336;
4427 		break;
4428 	case READ_CD_EST_MODE2FORM2:
4429 		blk_size = CDROM_BLK_2324;
4430 		break;
4431 	case READ_CD_EST_MODE2FORM1:
4432 	case READ_CD_EST_ALLTYPE:
4433 	case READ_CD_EST_MODE1:
4434 	default:
4435 		blk_size = CDROM_BLK_2048;
4436 	}
4437 
4438 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL, "scsa2usb_read_cd_blk_size: "
4439 	    "est = 0x%x blk_size = %d", expected_sector_type, blk_size);
4440 
4441 	return (blk_size);
4442 }
4443 
4444 
4445 /* needed for esballoc_wait() */
4446 /*ARGSUSED*/
4447 static void
4448 scsa2usb_null_free(char *arg)
4449 {
4450 }
4451 
4452 static frtn_t fr = {
4453 	scsa2usb_null_free,
4454 	NULL
4455 };
4456 
4457 
4458 /*
4459  * scsa2usb_bp_to_mblk:
4460  *	Convert a bp to mblk_t. USBA framework understands mblk_t.
4461  */
4462 static mblk_t *
4463 scsa2usb_bp_to_mblk(scsa2usb_state_t *scsa2usbp)
4464 {
4465 	size_t		size;
4466 	mblk_t		*mp;
4467 	struct buf	*bp;
4468 	scsa2usb_cmd_t	*cmd = PKT2CMD(scsa2usbp->scsa2usb_cur_pkt);
4469 
4470 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4471 	    "scsa2usb_bp_to_mblk: ");
4472 
4473 	ASSERT(scsa2usbp->scsa2usb_cur_pkt);
4474 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4475 
4476 	bp = cmd->cmd_bp;
4477 
4478 	if (bp && (bp->b_bcount > 0)) {
4479 		size = ((bp->b_bcount > cmd->cmd_xfercount) ?
4480 				cmd->cmd_xfercount : bp->b_bcount);
4481 	} else {
4482 
4483 		return (NULL);
4484 	}
4485 
4486 	mp = esballoc_wait((uchar_t *)bp->b_un.b_addr + cmd->cmd_offset,
4487 						size, BPRI_LO, &fr);
4488 
4489 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4490 	    "scsa2usb_bp_to_mblk: "
4491 	    "mp=0x%p bp=0x%p pkt=0x%p off=0x%lx sz=%lu add=0x%p", mp,
4492 	    (void *)bp, scsa2usbp->scsa2usb_cur_pkt, cmd->cmd_offset,
4493 	    bp->b_bcount - cmd->cmd_offset,
4494 	    bp->b_un.b_addr);
4495 
4496 	mp->b_wptr += size;
4497 	cmd->cmd_offset += size;
4498 
4499 	return (mp);
4500 }
4501 
4502 
4503 /*
4504  * scsa2usb_handle_data_start:
4505  *	Initiate the data xfer. It could be IN/OUT direction.
4506  *
4507  *	Data IN:
4508  *		Send out the bulk-xfer request
4509  *		if rval implies STALL
4510  *			clear endpoint stall and reset bulk-in pipe
4511  *			handle data read in so far; set cmd->cmd_done
4512  *			also adjust data xfer length accordingly
4513  *		else other error
4514  *			report back to transport
4515  *			typically transport will call reset recovery
4516  *		else (no error)
4517  *			return success
4518  *
4519  *	Data OUT:
4520  *		Send out the bulk-xfer request
4521  *		if rval implies STALL
4522  *			clear endpoint stall and reset bulk-in pipe
4523  *			adjust data xfer length
4524  *		else other error
4525  *			report back to transport
4526  *			typically transport will call reset recovery
4527  *		else (no error)
4528  *			return success
4529  *
4530  *	NOTE: We call this function only if there is xfercount.
4531  */
4532 int
4533 scsa2usb_handle_data_start(scsa2usb_state_t *scsa2usbp,
4534     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4535 {
4536 	int		rval = USB_SUCCESS;
4537 	uint_t		ept_addr;
4538 	usb_flags_t	flags = USB_FLAGS_SLEEP;
4539 #ifdef	SCSA2USB_BULK_ONLY_TEST
4540 	usb_req_attrs_t	attrs = 0;
4541 #else
4542 	usb_req_attrs_t	attrs = USB_ATTRS_SHORT_XFER_OK;
4543 #endif
4544 
4545 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4546 	    "scsa2usb_handle_data_start: BEGIN cmd = %p, req = %p", cmd, req);
4547 
4548 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4549 
4550 	switch (cmd->cmd_dir) {
4551 	case USB_EP_DIR_IN:
4552 #ifdef	SCSA2USB_BULK_ONLY_TEST
4553 		/*
4554 		 * This case occurs when the host expects to receive
4555 		 * more data than the device actually transfers. Hi > Di
4556 		 */
4557 		if (scsa2usb_test_case_5) {
4558 			usb_bulk_req_t *req2;
4559 
4560 			req->bulk_len = cmd->cmd_xfercount - 1;
4561 			req->bulk_attributes = 0;
4562 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4563 			SCSA2USB_FREE_MSG(req->bulk_data);
4564 			req->bulk_data = allocb_wait(req->bulk_len, BPRI_LO,
4565 			    STR_NOSIG, NULL);
4566 
4567 			ASSERT(req->bulk_timeout);
4568 			rval = usb_pipe_bulk_xfer(
4569 			    scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4570 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4571 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4572 			    scsa2usbp->scsa2usb_log_handle, "rval = %x", rval);
4573 
4574 			req2 = scsa2usb_init_bulk_req(scsa2usbp,
4575 			    cmd->cmd_xfercount + 2,
4576 			    cmd->cmd_timeout, 0, flags);
4577 			req2->bulk_len = cmd->cmd_xfercount + 2;
4578 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4579 
4580 			ASSERT(req2->bulk_timeout);
4581 			rval = usb_pipe_bulk_xfer(
4582 			    scsa2usbp->scsa2usb_bulkin_pipe, req2, flags);
4583 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4584 
4585 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4586 			    scsa2usbp->scsa2usb_log_handle,
4587 			    "TEST 5: Hi > Di: rval = 0x%x", rval);
4588 			scsa2usb_test_case_5 = 0;
4589 			usb_free_bulk_req(req2);
4590 
4591 			return (rval);
4592 		}
4593 
4594 		/*
4595 		 * This happens when the host expects to send data to the
4596 		 * device while the device intends to send data to the host.
4597 		 */
4598 		if (scsa2usb_test_case_8 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) {
4599 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4600 			    scsa2usbp->scsa2usb_log_handle,
4601 			    "TEST 8: Hi <> Do: Step 2");
4602 			scsa2usb_test_mblk(scsa2usbp, B_TRUE);
4603 			scsa2usb_test_case_8 = 0;
4604 
4605 			return (rval);
4606 		}
4607 #endif	/* SCSA2USB_BULK_ONLY_TEST */
4608 
4609 		ept_addr = scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress;
4610 		req->bulk_len = cmd->cmd_xfercount;
4611 		req->bulk_attributes = attrs;
4612 		SCSA2USB_FREE_MSG(req->bulk_data);
4613 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4614 
4615 		req->bulk_data = esballoc_wait(
4616 				(uchar_t *)cmd->cmd_bp->b_un.b_addr +
4617 				cmd->cmd_offset,
4618 				req->bulk_len, BPRI_LO, &fr);
4619 
4620 		ASSERT(req->bulk_timeout);
4621 		rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe,
4622 								req, flags);
4623 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4624 
4625 		break;
4626 
4627 	case USB_EP_DIR_OUT:
4628 #ifdef	SCSA2USB_BULK_ONLY_TEST
4629 		/*
4630 		 * This happens when the host expects to receive data
4631 		 * from the device while the device intends to receive
4632 		 * data from the host.
4633 		 */
4634 		if (scsa2usb_test_case_10 &&
4635 		    (cmd->cmd_cdb[0] == SCMD_WRITE_G1)) {
4636 			req->bulk_len = CSW_LEN;
4637 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4638 
4639 			ASSERT(req->bulk_timeout);
4640 			rval = usb_pipe_bulk_xfer(
4641 			    scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4642 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4643 
4644 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4645 			    scsa2usbp->scsa2usb_log_handle,
4646 			    "TEST 10: Ho <> Di: done rval = 0x%x",  rval);
4647 			scsa2usb_test_case_10 = 0;
4648 
4649 			return (rval);
4650 		}
4651 #endif	/* SCSA2USB_BULK_ONLY_TEST */
4652 
4653 		req->bulk_data = scsa2usb_bp_to_mblk(scsa2usbp);
4654 		if (req->bulk_data == NULL) {
4655 
4656 			return (USB_FAILURE);
4657 		}
4658 
4659 #ifdef	SCSA2USB_BULK_ONLY_TEST
4660 		if (scsa2usb_test_case_11) {
4661 			/*
4662 			 * Host expects to send data to the device and
4663 			 * device doesn't expect to receive any data
4664 			 */
4665 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4666 			    scsa2usbp->scsa2usb_log_handle, "TEST 11: Ho > Do");
4667 
4668 			scsa2usb_test_mblk(scsa2usbp, B_FALSE);
4669 			scsa2usb_test_case_11 = 0;
4670 		}
4671 #endif	/* SCSA2USB_BULK_ONLY_TEST */
4672 
4673 		ept_addr = scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress;
4674 		req->bulk_len = req->bulk_data->b_wptr - req->bulk_data->b_rptr;
4675 		req->bulk_timeout = scsa2usb_bulk_timeout(cmd->cmd_timeout);
4676 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4677 
4678 		ASSERT(req->bulk_timeout);
4679 		rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe,
4680 								req, flags);
4681 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4682 		break;
4683 	}
4684 
4685 	USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4686 	    scsa2usbp->scsa2usb_log_handle,
4687 	    "scsa2usb_handle_data_start: rval=%d cr=%d", rval,
4688 	    req->bulk_completion_reason);
4689 
4690 	if (rval != USB_SUCCESS) {
4691 		/* Handle Errors now */
4692 		if (req->bulk_completion_reason == USB_CR_STALL) {
4693 			if (cmd->cmd_dir == USB_EP_DIR_IN) {
4694 				(void) scsa2usb_clear_ept_stall(
4695 				    scsa2usbp, ept_addr,
4696 				    scsa2usbp-> scsa2usb_bulkin_pipe,
4697 				    "bulk-in");
4698 			} else {
4699 				(void) scsa2usb_clear_ept_stall(
4700 				    scsa2usbp, ept_addr,
4701 				    scsa2usbp-> scsa2usb_bulkout_pipe,
4702 				    "bulk-out");
4703 			}
4704 		}
4705 
4706 		/* no more data to transfer after this */
4707 		cmd->cmd_done = 1;
4708 	}
4709 
4710 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4711 	    "scsa2usb_handle_data_start: END %s data rval = %d",
4712 	    (cmd->cmd_dir == USB_EP_DIR_IN) ? "bulk-in" : "bulk-out", rval);
4713 
4714 	return (rval);
4715 }
4716 
4717 
4718 /*
4719  * scsa2usb_handle_data_done:
4720  *	This function handles the completion of the data xfer.
4721  *	It also massages the inquiry data. This function may
4722  *	also be called after a stall.
4723  */
4724 void
4725 scsa2usb_handle_data_done(scsa2usb_state_t *scsa2usbp,
4726     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4727 {
4728 	struct buf	*bp = cmd->cmd_bp;
4729 	struct scsi_pkt	*pkt = scsa2usbp->scsa2usb_cur_pkt;
4730 	mblk_t		*data = req->bulk_data;
4731 	int		len = data ? (data->b_wptr - data->b_rptr) : 0;
4732 
4733 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4734 
4735 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4736 	    "scsa2usb_handle_data_done:\n\tcmd = 0x%p data = 0x%p len = 0x%x",
4737 	    cmd, data, len);
4738 
4739 	cmd->cmd_resid_xfercount = cmd->cmd_xfercount - len;
4740 
4741 	if (len)  {
4742 		uchar_t	*p;
4743 		scsa2usb_read_cap_t *cap;
4744 
4745 		switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
4746 		case SCMD_INQUIRY:
4747 			/*
4748 			 * cache a copy of the inquiry data for our own use
4749 			 * but ensure that we have at least up to
4750 			 * inq_revision, inq_serial is not required.
4751 			 * ignore inquiry data returned for inquiry commands
4752 			 * with SCSI-3 EVPD, CmdDt bits set.
4753 			 */
4754 			if (((cmd->cmd_cdb[SCSA2USB_LUN] & 0x1f) == 0) &&
4755 			    (len >= SCSA2USB_MAX_INQ_LEN)) {
4756 				bzero(&scsa2usbp->scsa2usb_lun_inquiry
4757 				    [pkt->pkt_address.a_lun],
4758 				    sizeof (struct scsi_inquiry));
4759 				bcopy(data->b_rptr,
4760 				    &scsa2usbp->scsa2usb_lun_inquiry
4761 				    [pkt->pkt_address.a_lun], len);
4762 			}
4763 
4764 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4765 			    scsa2usbp->scsa2usb_log_handle,
4766 			    "scsi inquiry type = 0x%x",
4767 			    scsa2usbp->scsa2usb_lun_inquiry
4768 			    [pkt->pkt_address.a_lun].inq_dtype);
4769 
4770 			cmd->cmd_done = 1;
4771 			goto handle_data;
4772 
4773 		case SCMD_READ_CAPACITY:
4774 			cap = (scsa2usb_read_cap_t *)data->b_rptr;
4775 
4776 			/* Figure out the logical block size */
4777 			if ((len >= sizeof (struct scsa2usb_read_cap)) &&
4778 			    (req->bulk_completion_reason == USB_CR_OK)) {
4779 				scsa2usbp->
4780 				    scsa2usb_lbasize[pkt->pkt_address.a_lun] =
4781 				    SCSA2USB_MK_32BIT(
4782 					    cap->scsa2usb_read_cap_blen3,
4783 					    cap->scsa2usb_read_cap_blen2,
4784 					    cap->scsa2usb_read_cap_blen1,
4785 					    cap->scsa2usb_read_cap_blen0);
4786 
4787 				USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4788 				    scsa2usbp->scsa2usb_log_handle,
4789 				    "lbasize=%d", scsa2usbp->
4790 				    scsa2usb_lbasize[pkt->pkt_address.a_lun]);
4791 			}
4792 			cmd->cmd_done = 1;
4793 			goto handle_data;
4794 
4795 		case SCMD_REQUEST_SENSE:
4796 			p = data->b_rptr;
4797 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4798 			    scsa2usbp->scsa2usb_log_handle,
4799 			    "cdb: %x rqsense: "
4800 			    "%x %x %x %x %x %x %x %x %x %x\n\t"
4801 			    "%x %x %x %x %x %x %x %x %x %x",
4802 			    cmd->cmd_cdb[0],
4803 			    p[0], p[1], p[2], p[3], p[4],
4804 			    p[5], p[6], p[7], p[8], p[9],
4805 			    p[10], p[11], p[12], p[13], p[14],
4806 			    p[15], p[16], p[17], p[18], p[19]);
4807 
4808 			scsa2usbp->scsa2usb_last_cmd.status = p[2];
4809 			cmd->cmd_done = 1;
4810 			/* FALLTHROUGH */
4811 
4812 		default:
4813 handle_data:
4814 			if (bp && len && (cmd->cmd_dir == USB_EP_DIR_IN)) {
4815 				/*
4816 				 * we don't have to copy the data, the
4817 				 * data pointers for the mblk_t for
4818 				 * the bulk-in xfer points to the
4819 				 * struct buf * data.
4820 				 */
4821 				cmd->cmd_offset += len;
4822 			}
4823 
4824 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4825 			    scsa2usbp->scsa2usb_log_handle,
4826 			    "len = 0x%x total = 0x%lx",
4827 			    len, cmd->cmd_total_xfercount);
4828 
4829 			/*
4830 			 * update total_xfercount now but it may be
4831 			 * adjusted after receiving the residue
4832 			 */
4833 			cmd->cmd_total_xfercount -= len;
4834 
4835 			if ((req->bulk_completion_reason != USB_CR_OK) ||
4836 			    (cmd->cmd_resid_xfercount != 0) ||
4837 			    (cmd->cmd_total_xfercount == 0)) {
4838 				/* set pkt_resid to total to be sure */
4839 				pkt->pkt_resid = cmd->cmd_total_xfercount;
4840 				cmd->cmd_done = 1;
4841 			}
4842 
4843 			break;
4844 		}
4845 	} else {
4846 		if (cmd->cmd_dir == USB_EP_DIR_OUT) {
4847 			if (cmd->cmd_total_xfercount == 0) {
4848 				cmd->cmd_done = 1;
4849 			}
4850 		}
4851 	}
4852 }
4853 
4854 
4855 /*
4856  * scsa2usb_init_bulk_req:
4857  *	Allocate (synchronously) and fill in a bulk-request
4858  */
4859 usb_bulk_req_t *
4860 scsa2usb_init_bulk_req(scsa2usb_state_t *scsa2usbp, size_t length,
4861     uint_t timeout, usb_req_attrs_t attrs, usb_flags_t flags)
4862 {
4863 	usb_bulk_req_t	*req;
4864 
4865 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4866 
4867 	req = usb_alloc_bulk_req(scsa2usbp->scsa2usb_dip, length,
4868 	    flags | USB_FLAGS_SLEEP);
4869 
4870 	req->bulk_len = length;			/* xfer length */
4871 	req->bulk_timeout = scsa2usb_bulk_timeout(timeout); /* xfer timeout */
4872 	req->bulk_attributes = attrs;		/* xfer attrs */
4873 	req->bulk_client_private = (usb_opaque_t)scsa2usbp; /* statep */
4874 
4875 	return (req);
4876 }
4877 
4878 
4879 /*
4880  * scsa2usb_bulk_timeout:
4881  *	ensure that bulk requests do not have infinite timeout values
4882  */
4883 int
4884 scsa2usb_bulk_timeout(int timeout)
4885 {
4886 	return ((timeout == 0) ? scsa2usb_long_timeout : timeout);
4887 }
4888 
4889 
4890 /*
4891  * scsa2usb_clear_ept_stall:
4892  *	clear endpoint stall and reset pipes
4893  */
4894 int
4895 scsa2usb_clear_ept_stall(scsa2usb_state_t *scsa2usbp, uint_t ept_addr,
4896     usb_pipe_handle_t ph, char *what)
4897 {
4898 	int rval;
4899 	dev_info_t *dip = scsa2usbp->scsa2usb_dip;
4900 
4901 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4902 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
4903 
4904 		return (USB_FAILURE);
4905 	}
4906 
4907 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4908 	rval = usb_clr_feature(dip, USB_DEV_REQ_RCPT_EP, 0, ept_addr,
4909 	    USB_FLAGS_SLEEP, NULL, NULL);
4910 
4911 	usb_pipe_reset(dip, ph, USB_FLAGS_SLEEP, NULL, NULL);
4912 
4913 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4914 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4915 	    "scsa2usb_clear_ept_stall: on %s: ept = 0x%x rval = %d",
4916 	    what, ept_addr, rval);
4917 
4918 	return (rval);
4919 }
4920 
4921 
4922 /*
4923  * scsa2usb_pkt_completion:
4924  *	Handle pkt completion.
4925  */
4926 static void
4927 scsa2usb_pkt_completion(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
4928 {
4929 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
4930 
4931 	ASSERT(pkt);
4932 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4933 
4934 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4935 	    "scsa2usb_pkt_completion:\n\tscsa2usbp = 0x%p "
4936 	    "reason=%d, status=%d state=0x%x stats=0x%x resid=0x%lx",
4937 	    scsa2usbp, pkt->pkt_reason, *(pkt->pkt_scbp),
4938 	    pkt->pkt_state, pkt->pkt_statistics, pkt->pkt_resid);
4939 
4940 	if (pkt->pkt_reason == CMD_CMPLT) {
4941 		pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
4942 					STATE_SENT_CMD | STATE_GOT_STATUS;
4943 		if (cmd->cmd_xfercount) {
4944 			pkt->pkt_state |= STATE_XFERRED_DATA;
4945 		}
4946 	} else {
4947 		pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
4948 					STATE_SENT_CMD;
4949 	}
4950 
4951 	/*
4952 	 * don't zap the current state when in panic as this will
4953 	 * make debugging harder
4954 	 */
4955 	if ((scsa2usbp->scsa2usb_cur_pkt == pkt) && !ddi_in_panic()) {
4956 		SCSA2USB_RESET_CUR_PKT(scsa2usbp);
4957 
4958 		/* save the last command */
4959 		bcopy(pkt->pkt_cdbp, scsa2usbp->scsa2usb_last_cmd.cdb,
4960 		    sizeof (scsa2usbp->scsa2usb_last_cmd.cdb));
4961 
4962 		/* reset the scsa2usb_last_cmd.status value */
4963 		if ((pkt->pkt_cdbp[0] != SCMD_REQUEST_SENSE) &&
4964 		    (pkt->pkt_cdbp[0] != SCMD_INQUIRY)) {
4965 			scsa2usbp->scsa2usb_last_cmd.status = 0;
4966 		}
4967 
4968 		/*
4969 		 * set pkt state to NONE *before* calling back as the target
4970 		 * driver will immediately submit the next packet
4971 		 */
4972 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4973 	}
4974 
4975 	if (pkt->pkt_comp) {
4976 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4977 		pkt->pkt_comp(pkt);
4978 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4979 
4980 	}
4981 }
4982 
4983 
4984 /*
4985  * Even handling functions:
4986  *
4987  * scsa2usb_reconnect_event_cb:
4988  *	event handling
4989  */
4990 static int
4991 scsa2usb_reconnect_event_cb(dev_info_t *dip)
4992 {
4993 	scsa2usb_state_t *scsa2usbp =
4994 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
4995 	dev_info_t	*cdip;
4996 	int		circ;
4997 	int		rval = USB_SUCCESS;
4998 
4999 	ASSERT(scsa2usbp != NULL);
5000 
5001 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5002 	    "scsa2usb_reconnect_event_cb: dip = 0x%p", dip);
5003 
5004 	scsa2usb_restore_device_state(dip, scsa2usbp);
5005 
5006 	USB_DPRINTF_L0(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5007 	    "Reinserted device is accessible again.");
5008 
5009 	ndi_devi_enter(dip, &circ);
5010 	for (cdip = ddi_get_child(dip); cdip; ) {
5011 		dev_info_t *next = ddi_get_next_sibling(cdip);
5012 
5013 		mutex_enter(&DEVI(cdip)->devi_lock);
5014 		DEVI_SET_DEVICE_REINSERTED(cdip);
5015 		mutex_exit(&DEVI(cdip)->devi_lock);
5016 
5017 		cdip = next;
5018 	}
5019 	ndi_devi_exit(dip, circ);
5020 
5021 	/* stop suppressing warnings */
5022 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5023 	scsa2usbp->scsa2usb_warning_given = B_FALSE;
5024 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5025 
5026 	if (scsa2usbp->scsa2usb_ugen_hdl) {
5027 		rval = usb_ugen_reconnect_ev_cb(
5028 			scsa2usbp->scsa2usb_ugen_hdl);
5029 	}
5030 
5031 	return (rval);
5032 }
5033 
5034 
5035 /*
5036  * scsa2usb_all_waitQs_empty:
5037  *	check if all waitQs empty
5038  */
5039 static int
5040 scsa2usb_all_waitQs_empty(scsa2usb_state_t *scsa2usbp)
5041 {
5042 	uint_t	lun;
5043 
5044 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
5045 		if (usba_list_entry_count(
5046 		    &scsa2usbp->scsa2usb_waitQ[lun])) {
5047 
5048 			return (USB_FAILURE);
5049 		}
5050 	}
5051 
5052 	return (USB_SUCCESS);
5053 }
5054 
5055 
5056 /*
5057  * scsa2usb_disconnect_event_cb:
5058  *	callback for disconnect events
5059  */
5060 static int
5061 scsa2usb_disconnect_event_cb(dev_info_t *dip)
5062 {
5063 	scsa2usb_state_t *scsa2usbp =
5064 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5065 	dev_info_t	*cdip;
5066 	int		circ, i;
5067 	int		rval = USB_SUCCESS;
5068 
5069 	ASSERT(scsa2usbp != NULL);
5070 
5071 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5072 	    "scsa2usb_disconnect_event_cb: dip = 0x%p", dip);
5073 
5074 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5075 	scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
5076 
5077 	/*
5078 	 * wait till the work thread is done, carry on regardless
5079 	 * if not.
5080 	 */
5081 	for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
5082 		if ((scsa2usbp->scsa2usb_work_thread_id == NULL) &&
5083 		    (scsa2usbp->scsa2usb_cur_pkt == NULL) &&
5084 		    (scsa2usb_all_waitQs_empty(scsa2usbp) ==
5085 		    USB_SUCCESS)) {
5086 
5087 			break;
5088 		}
5089 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5090 		delay(drv_usectohz(1000000));
5091 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5092 	}
5093 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5094 
5095 	ndi_devi_enter(dip, &circ);
5096 	for (cdip = ddi_get_child(dip); cdip; ) {
5097 		dev_info_t *next = ddi_get_next_sibling(cdip);
5098 
5099 		mutex_enter(&DEVI(cdip)->devi_lock);
5100 		DEVI_SET_DEVICE_REMOVED(cdip);
5101 		mutex_exit(&DEVI(cdip)->devi_lock);
5102 
5103 		cdip = next;
5104 	}
5105 	ndi_devi_exit(dip, circ);
5106 
5107 	if (scsa2usbp->scsa2usb_ugen_hdl) {
5108 		rval = usb_ugen_disconnect_ev_cb(
5109 					scsa2usbp->scsa2usb_ugen_hdl);
5110 	}
5111 
5112 	return (rval);
5113 }
5114 
5115 
5116 /*
5117  * PM support
5118  *
5119  * scsa2usb_create_pm_components:
5120  *	create the pm components required for power management
5121  *	no mutex is need when calling USBA interfaces
5122  */
5123 static void
5124 scsa2usb_create_pm_components(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
5125 {
5126 	scsa2usb_power_t *pm;
5127 	uint_t		pwr_states;
5128 
5129 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5130 
5131 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5132 	    "scsa2usb_create_pm_components: dip = 0x%p, scsa2usbp = 0x%p",
5133 	    dip, scsa2usbp);
5134 
5135 	/*
5136 	 * determine if this device is on the blacklist
5137 	 * or if a conf file entry has disabled PM
5138 	 */
5139 	if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_PM) == 0) {
5140 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5141 		    "device cannot be power managed");
5142 
5143 		return;
5144 	}
5145 
5146 	/* Allocate the PM state structure */
5147 	pm = kmem_zalloc(sizeof (scsa2usb_power_t), KM_SLEEP);
5148 
5149 	scsa2usbp->scsa2usb_pm = pm;
5150 	pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5151 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5152 
5153 	if (usb_create_pm_components(dip, &pwr_states) ==
5154 	    USB_SUCCESS) {
5155 		if (usb_handle_remote_wakeup(dip,
5156 		    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
5157 			pm->scsa2usb_wakeup_enabled = 1;
5158 		}
5159 
5160 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5161 		pm->scsa2usb_pwr_states = (uint8_t)pwr_states;
5162 		scsa2usb_raise_power(scsa2usbp);
5163 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5164 	}
5165 
5166 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5167 }
5168 
5169 
5170 /*
5171  * scsa2usb_raise_power:
5172  *	check if the device is using full power or not
5173  */
5174 static void
5175 scsa2usb_raise_power(scsa2usb_state_t *scsa2usbp)
5176 {
5177 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5178 	    "scsa2usb_raise_power:");
5179 
5180 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5181 
5182 	if (scsa2usbp->scsa2usb_pm) {
5183 		scsa2usb_pm_busy_component(scsa2usbp);
5184 		if (scsa2usbp->scsa2usb_pm->scsa2usb_current_power !=
5185 		    USB_DEV_OS_FULL_PWR) {
5186 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5187 			(void) pm_raise_power(scsa2usbp->scsa2usb_dip,
5188 			    0, USB_DEV_OS_FULL_PWR);
5189 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5190 		}
5191 	}
5192 }
5193 
5194 
5195 /*
5196  * functions to handle power transition for OS levels 0 -> 3
5197  */
5198 static int
5199 scsa2usb_pwrlvl0(scsa2usb_state_t *scsa2usbp)
5200 {
5201 	int	rval;
5202 
5203 	switch (scsa2usbp->scsa2usb_dev_state) {
5204 	case USB_DEV_ONLINE:
5205 		/* Deny the powerdown request if the device is busy */
5206 		if (scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy != 0) {
5207 
5208 			return (USB_FAILURE);
5209 		}
5210 
5211 		/*
5212 		 * stop polling on interrupt pipe
5213 		 */
5214 		scsa2usb_cbi_stop_intr_polling(scsa2usbp);
5215 
5216 		/* Issue USB D3 command to the device here */
5217 		rval = usb_set_device_pwrlvl3(scsa2usbp->scsa2usb_dip);
5218 		ASSERT(rval == USB_SUCCESS);
5219 
5220 		scsa2usbp->scsa2usb_dev_state = USB_DEV_PWRED_DOWN;
5221 
5222 		/* FALLTHRU */
5223 	case USB_DEV_DISCONNECTED:
5224 	case USB_DEV_SUSPENDED:
5225 	case USB_DEV_PWRED_DOWN:
5226 	default:
5227 		scsa2usbp->scsa2usb_pm->scsa2usb_current_power =
5228 						USB_DEV_OS_PWR_OFF;
5229 
5230 		return (USB_SUCCESS);
5231 	}
5232 }
5233 
5234 
5235 static int
5236 scsa2usb_pwrlvl1(scsa2usb_state_t *scsa2usbp)
5237 {
5238 	int	rval;
5239 
5240 	/* Issue USB D2 command to the device here */
5241 	rval = usb_set_device_pwrlvl2(scsa2usbp->scsa2usb_dip);
5242 	ASSERT(rval == USB_SUCCESS);
5243 
5244 	return (DDI_FAILURE);
5245 }
5246 
5247 
5248 static int
5249 scsa2usb_pwrlvl2(scsa2usb_state_t *scsa2usbp)
5250 {
5251 	int	rval;
5252 
5253 	/* Issue USB D1 command to the device here */
5254 	rval = usb_set_device_pwrlvl1(scsa2usbp->scsa2usb_dip);
5255 	ASSERT(rval == USB_SUCCESS);
5256 
5257 	return (DDI_FAILURE);
5258 }
5259 
5260 
5261 static int
5262 scsa2usb_pwrlvl3(scsa2usb_state_t *scsa2usbp)
5263 {
5264 	int	rval;
5265 
5266 	/*
5267 	 * PM framework tries to put us in full power
5268 	 * during system shutdown. If we are disconnected
5269 	 * return success anyways
5270 	 */
5271 	if (scsa2usbp->scsa2usb_dev_state != USB_DEV_DISCONNECTED) {
5272 		/* Issue USB D0 command to the device here */
5273 		rval = usb_set_device_pwrlvl0(scsa2usbp->scsa2usb_dip);
5274 		ASSERT(rval == USB_SUCCESS);
5275 
5276 		scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
5277 	}
5278 	scsa2usbp->scsa2usb_pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5279 
5280 	return (DDI_SUCCESS);
5281 }
5282 
5283 
5284 /*
5285  * scsa2usb_power:
5286  *	power entry point
5287  */
5288 /* ARGSUSED */
5289 static int
5290 scsa2usb_power(dev_info_t *dip, int comp, int level)
5291 {
5292 	scsa2usb_state_t	*scsa2usbp;
5293 	scsa2usb_power_t	*pm;
5294 	int			rval = DDI_FAILURE;
5295 
5296 	scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5297 
5298 	USB_DPRINTF_L3(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5299 	    "scsa2usb_power: Begin scsa2usbp (%p): level = %d",
5300 	    scsa2usbp, level);
5301 
5302 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5303 	if (SCSA2USB_BUSY(scsa2usbp)) {
5304 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5305 		    "scsa2usb_power: busy");
5306 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5307 
5308 		return (rval);
5309 	}
5310 
5311 	pm = scsa2usbp->scsa2usb_pm;
5312 	if (pm == NULL) {
5313 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5314 		    "scsa2usb_power: pm NULL");
5315 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5316 
5317 		return (rval);
5318 	}
5319 
5320 	/* check if we are transitioning to a legal power level */
5321 	if (USB_DEV_PWRSTATE_OK(pm->scsa2usb_pwr_states, level)) {
5322 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5323 		    "scsa2usb_power: illegal power level = %d "
5324 		    "pwr_states: %x", level, pm->scsa2usb_pwr_states);
5325 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5326 
5327 		return (rval);
5328 	}
5329 
5330 	switch (level) {
5331 	case USB_DEV_OS_PWR_OFF :
5332 		rval = scsa2usb_pwrlvl0(scsa2usbp);
5333 		break;
5334 	case USB_DEV_OS_PWR_1 :
5335 		rval = scsa2usb_pwrlvl1(scsa2usbp);
5336 		break;
5337 	case USB_DEV_OS_PWR_2 :
5338 		rval = scsa2usb_pwrlvl2(scsa2usbp);
5339 		break;
5340 	case USB_DEV_OS_FULL_PWR :
5341 		rval = scsa2usb_pwrlvl3(scsa2usbp);
5342 		break;
5343 	}
5344 
5345 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5346 
5347 	return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
5348 }
5349 
5350 
5351 static void
5352 scsa2usb_pm_busy_component(scsa2usb_state_t *scsa2usbp)
5353 {
5354 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5355 
5356 	if (scsa2usbp->scsa2usb_pm) {
5357 		scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy++;
5358 
5359 		USB_DPRINTF_L4(DPRINT_MASK_PM,
5360 		    scsa2usbp->scsa2usb_log_handle,
5361 		    "scsa2usb_pm_busy_component: %d",
5362 		    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5363 
5364 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5365 
5366 		if (pm_busy_component(scsa2usbp->scsa2usb_dip, 0) !=
5367 		    DDI_SUCCESS) {
5368 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5369 			ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5370 			scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5371 
5372 			USB_DPRINTF_L2(DPRINT_MASK_PM,
5373 			    scsa2usbp->scsa2usb_log_handle,
5374 			    "scsa2usb_pm_busy_component failed: %d",
5375 			    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5376 
5377 			return;
5378 		}
5379 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5380 	}
5381 }
5382 
5383 
5384 /*
5385  * scsa2usb_pm_idle_component:
5386  *	idles the device
5387  */
5388 static void
5389 scsa2usb_pm_idle_component(scsa2usb_state_t *scsa2usbp)
5390 {
5391 	ASSERT(!mutex_owned(&scsa2usbp->scsa2usb_mutex));
5392 
5393 	if (scsa2usbp->scsa2usb_pm) {
5394 		if (pm_idle_component(scsa2usbp->scsa2usb_dip, 0) ==
5395 		    DDI_SUCCESS) {
5396 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5397 			ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5398 			scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5399 
5400 			USB_DPRINTF_L4(DPRINT_MASK_PM,
5401 			    scsa2usbp->scsa2usb_log_handle,
5402 			    "scsa2usb_pm_idle_component: %d",
5403 			    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5404 
5405 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5406 		}
5407 	}
5408 }
5409 
5410 
5411 #ifdef	DEBUG
5412 /*
5413  * scsa2usb_print_cdb:
5414  *	prints CDB
5415  */
5416 void
5417 scsa2usb_print_cdb(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
5418 {
5419 	uchar_t *c = (uchar_t *)&cmd->cmd_cdb;
5420 
5421 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5422 	    "cmd = 0x%p opcode=%s "
5423 	    "cdb: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
5424 	    cmd, scsi_cname(cmd->cmd_cdb[SCSA2USB_OPCODE], scsa2usb_cmds),
5425 	    c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8],
5426 	    c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
5427 }
5428 #endif	/* DEBUG */
5429 
5430 
5431 #ifdef	SCSA2USB_BULK_ONLY_TEST
5432 /*
5433  * scsa2usb_test_mblk:
5434  *	This function sends a dummy data mblk_t to simulate
5435  *	the following test cases: 5 and 11.
5436  */
5437 static void
5438 scsa2usb_test_mblk(scsa2usb_state_t *scsa2usbp, boolean_t large)
5439 {
5440 	int			i, rval;
5441 	size_t			len;
5442 	usb_flags_t		flags = USB_FLAGS_SLEEP;
5443 	usb_bulk_req_t		*req;
5444 
5445 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5446 
5447 	/* should we create a larger mblk? */
5448 	len = (large == B_TRUE) ? DEV_BSIZE : USB_BULK_CBWCMD_LEN;
5449 
5450 	req = scsa2usb_init_bulk_req(scsa2usbp, len,
5451 		SCSA2USB_BULK_PIPE_TIMEOUT, 0, flags);
5452 
5453 	/* fill up the data mblk */
5454 	for (i = 0; i < len; i++) {
5455 		*req->bulk_data->b_wptr++ = (uchar_t)i;
5456 	}
5457 
5458 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5459 	ASSERT(req->bulk_timeout);
5460 	rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe, req, flags);
5461 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5462 
5463 	USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5464 	    "scsa2usb_test_mblk: Sent Data Out rval = 0x%x", rval);
5465 
5466 	usb_free_bulk_req(req);
5467 }
5468 #endif	/* SCSA2USB_BULK_ONLY_TEST */
5469