xref: /titanic_44/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c (revision bc913c4cbc9594e8ca0a031ba908f496ef40bbca)
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 static uint_t	scsa2usb_errmask	= (uint_t)DPRINT_MASK_ALL;
380 static uint_t	scsa2usb_errlevel	= USB_LOG_L4;
381 static uint_t	scsa2usb_instance_debug = (uint_t)-1;
382 static uint_t	scsa2usb_scsi_bus_config_debug = 0;
383 static 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 static 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_L1(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_L1(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_L1(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_L1(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_L1(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 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
918 	scsa2usb_pm_idle_component(scsa2usbp);
919 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
920 
921 	/* log the conf file override string if there is one */
922 	if (scsa2usbp->scsa2usb_override_str) {
923 		USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
924 		    "scsa2usb.conf override: %s",
925 		    scsa2usbp->scsa2usb_override_str);
926 	}
927 
928 	if (usb_owns_device(dip)) {
929 		/* get a ugen handle */
930 		bzero(&usb_ugen_info, sizeof (usb_ugen_info));
931 		usb_ugen_info.usb_ugen_flags = 0;
932 		usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask =
933 				(dev_t)SCSA2USB_MINOR_UGEN_BITS_MASK;
934 		usb_ugen_info.usb_ugen_minor_node_instance_mask =
935 				(dev_t)~SCSA2USB_MINOR_UGEN_BITS_MASK;
936 		scsa2usbp->scsa2usb_ugen_hdl =
937 					usb_ugen_get_hdl(dip, &usb_ugen_info);
938 
939 		if (usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl, cmd) !=
940 		    USB_SUCCESS) {
941 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
942 			    scsa2usbp->scsa2usb_log_handle,
943 			    "usb_ugen_attach failed");
944 
945 			usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
946 			scsa2usbp->scsa2usb_ugen_hdl = NULL;
947 		}
948 	}
949 
950 	/* report device */
951 	ddi_report_dev(dip);
952 
953 	return (DDI_SUCCESS);
954 
955 fail:
956 	if (scsa2usbp) {
957 		(void) scsa2usb_cleanup(dip, scsa2usbp);
958 	}
959 
960 	return (DDI_FAILURE);
961 }
962 
963 
964 /*
965  * scsa2usb_detach:
966  *	detach or suspend driver instance
967  */
968 static int
969 scsa2usb_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
970 {
971 	scsi_hba_tran_t	*tran;
972 	scsa2usb_state_t *scsa2usbp;
973 	int rval;
974 
975 	tran = ddi_get_driver_private(dip);
976 	ASSERT(tran != NULL);
977 
978 	scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
979 	ASSERT(scsa2usbp);
980 
981 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
982 	    "scsa2usb_detach: dip = 0x%p, cmd = %d", dip, cmd);
983 
984 	switch (cmd) {
985 	case DDI_DETACH:
986 
987 		if (scsa2usb_cleanup(dip, scsa2usbp) != USB_SUCCESS) {
988 
989 			return (DDI_FAILURE);
990 		}
991 
992 		return (DDI_SUCCESS);
993 	case DDI_SUSPEND:
994 		rval = scsa2usb_cpr_suspend(dip);
995 
996 		return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
997 	default:
998 
999 		return (DDI_FAILURE);
1000 	}
1001 }
1002 
1003 
1004 /*
1005  * ugen support
1006  */
1007 /*
1008  * scsa2usb_ugen_open()
1009  * (all ugen opens and pipe opens are by definition exclusive so it is OK
1010  * to count opens)
1011  */
1012 static int
1013 scsa2usb_ugen_open(dev_t *devp, int flag, int sflag, cred_t *cr)
1014 {
1015 	scsa2usb_state_t *scsa2usbp;
1016 	int		rval;
1017 
1018 	if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1019 	    SCSA2USB_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) {
1020 		/* deferred detach */
1021 
1022 		return (ENXIO);
1023 	}
1024 
1025 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1026 	    "scsa2usb_ugen_open: dev_t=0x%lx", *devp);
1027 
1028 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1029 
1030 	/* if this is the first ugen open, check on transport busy */
1031 	if (scsa2usbp->scsa2usb_ugen_open_count == 0) {
1032 		while (scsa2usbp->scsa2usb_transport_busy ||
1033 		    (scsa2usb_all_waitQs_empty(scsa2usbp) !=
1034 		    USB_SUCCESS)) {
1035 			rval = cv_wait_sig(
1036 				&scsa2usbp->scsa2usb_transport_busy_cv,
1037 				&scsa2usbp->scsa2usb_mutex);
1038 			if (rval == 0) {
1039 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
1040 
1041 				return (EINTR);
1042 			}
1043 		}
1044 		scsa2usbp->scsa2usb_transport_busy++;
1045 		scsa2usbp->scsa2usb_busy_thread = curthread;
1046 	}
1047 	scsa2usbp->scsa2usb_ugen_open_count++;
1048 
1049 	scsa2usb_raise_power(scsa2usbp);
1050 
1051 	scsa2usb_close_usb_pipes(scsa2usbp);
1052 
1053 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1054 
1055 	rval = usb_ugen_open(scsa2usbp->scsa2usb_ugen_hdl, devp, flag,
1056 		sflag, cr);
1057 
1058 	if (rval) {
1059 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1060 
1061 		/* reopen the pipes */
1062 		if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1063 			scsa2usbp->scsa2usb_transport_busy--;
1064 			scsa2usbp->scsa2usb_busy_thread = NULL;
1065 			cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1066 		}
1067 		scsa2usb_pm_idle_component(scsa2usbp);
1068 
1069 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1070 	}
1071 
1072 	return (rval);
1073 }
1074 
1075 
1076 /*
1077  * scsa2usb_ugen_close()
1078  */
1079 static int
1080 scsa2usb_ugen_close(dev_t dev, int flag, int otype, cred_t *cr)
1081 {
1082 	int rval;
1083 
1084 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1085 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1086 
1087 	if (scsa2usbp == NULL) {
1088 
1089 		return (ENXIO);
1090 	}
1091 
1092 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1093 	    "scsa2usb_ugen_close: dev_t=0x%lx", dev);
1094 
1095 	rval = usb_ugen_close(scsa2usbp->scsa2usb_ugen_hdl, dev, flag,
1096 		otype, cr);
1097 
1098 	if (rval == 0) {
1099 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1100 
1101 		/* reopen the pipes */
1102 		if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1103 			scsa2usbp->scsa2usb_transport_busy--;
1104 			scsa2usbp->scsa2usb_busy_thread = NULL;
1105 			cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1106 		}
1107 		scsa2usb_pm_idle_component(scsa2usbp);
1108 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1109 	}
1110 
1111 	return (rval);
1112 }
1113 
1114 
1115 /*
1116  * scsa2usb_ugen_read/write()
1117  */
1118 /*ARGSUSED*/
1119 static int
1120 scsa2usb_ugen_read(dev_t dev, struct uio *uiop, cred_t *credp)
1121 {
1122 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1123 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1124 
1125 	if (scsa2usbp == NULL) {
1126 
1127 		return (ENXIO);
1128 	}
1129 
1130 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1131 	    "scsa2usb_ugen_read: dev_t=0x%lx", dev);
1132 
1133 
1134 	return (usb_ugen_read(scsa2usbp->scsa2usb_ugen_hdl, dev,
1135 					uiop, credp));
1136 }
1137 
1138 
1139 /*ARGSUSED*/
1140 static int
1141 scsa2usb_ugen_write(dev_t dev, struct uio *uiop, cred_t *credp)
1142 {
1143 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1144 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1145 
1146 	if (scsa2usbp == NULL) {
1147 
1148 		return (ENXIO);
1149 	}
1150 
1151 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1152 	    "scsa2usb_ugen_write: dev_t=0x%lx", dev);
1153 
1154 	return (usb_ugen_write(scsa2usbp->scsa2usb_ugen_hdl,
1155 					dev, uiop, credp));
1156 }
1157 
1158 
1159 /*
1160  * scsa2usb_ugen_poll
1161  */
1162 static int
1163 scsa2usb_ugen_poll(dev_t dev, short events,
1164     int anyyet,  short *reventsp, struct pollhead **phpp)
1165 {
1166 	scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1167 			SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1168 
1169 	if (scsa2usbp == NULL) {
1170 
1171 		return (ENXIO);
1172 	}
1173 
1174 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1175 	    "scsa2usb_ugen_poll: dev_t=0x%lx", dev);
1176 
1177 	return (usb_ugen_poll(scsa2usbp->scsa2usb_ugen_hdl, dev, events,
1178 					anyyet, reventsp, phpp));
1179 }
1180 
1181 
1182 /*
1183  * scsa2usb_cleanup:
1184  *	cleanup whatever attach has setup
1185  */
1186 static int
1187 scsa2usb_cleanup(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
1188 {
1189 	int		rval, i;
1190 	scsa2usb_power_t *pm;
1191 	uint_t		lun;
1192 
1193 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1194 	    "scsa2usb_cleanup:");
1195 
1196 	/* wait till the work thread is done */
1197 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1198 	for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
1199 		if (scsa2usbp->scsa2usb_work_thread_id == NULL) {
1200 
1201 			break;
1202 		}
1203 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1204 		delay(drv_usectohz(1000000));
1205 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1206 	}
1207 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1208 
1209 	if (i >= SCSA2USB_DRAIN_TIMEOUT) {
1210 
1211 		return (USB_FAILURE);
1212 	}
1213 
1214 	/*
1215 	 * Disable the event callbacks first, after this point, event
1216 	 * callbacks will never get called. Note we shouldn't hold
1217 	 * mutex while unregistering events because there may be a
1218 	 * competing event callback thread. Event callbacks are done
1219 	 * with ndi mutex held and this can cause a potential deadlock.
1220 	 */
1221 	usb_unregister_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events);
1222 
1223 	if (scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_LOCKS_INIT) {
1224 		/*
1225 		 * if a waitQ exists, get rid of it before destroying it
1226 		 */
1227 		for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
1228 			scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_TRAN_ERR);
1229 			usba_destroy_list(&scsa2usbp->scsa2usb_waitQ[lun]);
1230 		}
1231 
1232 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1233 		if (scsa2usbp->scsa2usb_flags &
1234 		    SCSA2USB_FLAGS_HBA_ATTACH_SETUP) {
1235 			(void) scsi_hba_detach(dip);
1236 			scsi_hba_tran_free(scsa2usbp->scsa2usb_tran);
1237 		}
1238 
1239 		if (scsa2usbp->scsa2usb_flags &
1240 		    SCSA2USB_FLAGS_PIPES_OPENED) {
1241 			scsa2usb_close_usb_pipes(scsa2usbp);
1242 		}
1243 
1244 		/* Lower the power */
1245 		pm = scsa2usbp->scsa2usb_pm;
1246 
1247 		if (pm && (scsa2usbp->scsa2usb_dev_state !=
1248 		    USB_DEV_DISCONNECTED)) {
1249 			if (pm->scsa2usb_wakeup_enabled) {
1250 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
1251 				(void) pm_raise_power(dip, 0,
1252 						USB_DEV_OS_FULL_PWR);
1253 
1254 				if ((rval = usb_handle_remote_wakeup(dip,
1255 				    USB_REMOTE_WAKEUP_DISABLE)) !=
1256 				    USB_SUCCESS) {
1257 					USB_DPRINTF_L1(DPRINT_MASK_SCSA,
1258 					    scsa2usbp->scsa2usb_log_handle,
1259 					    "disable remote wakeup failed "
1260 					    "(%d)", rval);
1261 				}
1262 			} else {
1263 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
1264 			}
1265 
1266 			(void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
1267 
1268 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
1269 		}
1270 
1271 		if (pm) {
1272 			kmem_free(pm, sizeof (scsa2usb_power_t));
1273 		}
1274 
1275 		if (scsa2usbp->scsa2usb_override_str) {
1276 			kmem_free(scsa2usbp->scsa2usb_override_str,
1277 			    strlen(scsa2usbp->scsa2usb_override_str) + 1);
1278 			scsa2usbp->scsa2usb_override_str = NULL;
1279 		}
1280 
1281 		/* remove the minor nodes */
1282 		ddi_remove_minor_node(dip, NULL);
1283 
1284 		/* Cancel the registered panic callback */
1285 		scsa2usb_panic_callb_fini(scsa2usbp);
1286 
1287 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1288 
1289 		mutex_destroy(&scsa2usbp->scsa2usb_mutex);
1290 		cv_destroy(&scsa2usbp->scsa2usb_transport_busy_cv);
1291 	}
1292 
1293 	usb_client_detach(scsa2usbp->scsa2usb_dip,
1294 				scsa2usbp->scsa2usb_dev_data);
1295 
1296 	if (scsa2usbp->scsa2usb_ugen_hdl) {
1297 		(void) usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
1298 							DDI_DETACH);
1299 		usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
1300 	}
1301 
1302 	usb_free_log_hdl(scsa2usbp->scsa2usb_log_handle);
1303 
1304 	ddi_prop_remove_all(dip);
1305 
1306 	ddi_soft_state_free(scsa2usb_statep, ddi_get_instance(dip));
1307 
1308 	return (USB_SUCCESS);
1309 }
1310 
1311 
1312 /*
1313  * scsa2usb_override:
1314  *	some devices may be attached even though their subclass or
1315  *	protocol info is not according to spec.
1316  *	these can be determined by the 'subclass-protocol-override'
1317  *	property set in the conf file.
1318  */
1319 static void
1320 scsa2usb_override(scsa2usb_state_t *scsa2usbp)
1321 {
1322 	scsa2usb_ov_t ov;
1323 	char	**override_str = NULL;
1324 	char	*override_str_cpy;
1325 	uint_t	override_str_len, override_str_cpy_len;
1326 	uint_t	i;
1327 	usb_dev_descr_t *descr = scsa2usbp->scsa2usb_dev_data->dev_descr;
1328 
1329 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
1330 
1331 	scsa2usbp->scsa2usb_subclass_override =
1332 	    scsa2usbp->scsa2usb_protocol_override = 0;
1333 
1334 	if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, scsa2usbp->scsa2usb_dip,
1335 	    DDI_PROP_DONTPASS, "attribute-override-list",
1336 	    &override_str, &override_str_len) != DDI_PROP_SUCCESS) {
1337 
1338 		return;
1339 	}
1340 
1341 	/* parse each string in the subclass-protocol-override property */
1342 	for (i = 0; i < override_str_len; i++) {
1343 
1344 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1345 		    "override_str[%d] = %s", i, override_str[i]);
1346 
1347 		/*
1348 		 * save a copy of the override string for possible
1349 		 * inclusion in soft state later
1350 		 */
1351 		override_str_cpy_len = strlen(override_str[i]) + 1;
1352 		override_str_cpy = kmem_zalloc(override_str_cpy_len, KM_SLEEP);
1353 		(void) strcpy(override_str_cpy, override_str[i]);
1354 
1355 		bzero(&ov, sizeof (scsa2usb_ov_t));
1356 
1357 		if (scsa2usb_parse_input_str(override_str[i], &ov,
1358 		    scsa2usbp) == USB_FAILURE) {
1359 			kmem_free(override_str_cpy, override_str_cpy_len);
1360 			continue;
1361 		}
1362 
1363 		/*
1364 		 * see if subclass/protocol needs to be overridden for device
1365 		 * or if device should not be power managed
1366 		 * if there'a a match, save the override string in soft state
1367 		 */
1368 		if (((descr->idVendor == (uint16_t)ov.vid) || (ov.vid == 0)) &&
1369 		    ((descr->idProduct == (uint16_t)ov.pid) || (ov.pid == 0)) &&
1370 		    ((descr->bcdDevice == (uint16_t)ov.rev) || (ov.rev == 0))) {
1371 			scsa2usbp->scsa2usb_subclass_override = ov.subclass;
1372 			scsa2usbp->scsa2usb_protocol_override = ov.protocol;
1373 
1374 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
1375 			    scsa2usbp->scsa2usb_log_handle,
1376 			    "vid=0x%x pid=0x%x rev=0x%x subclass=0x%x "
1377 			    "protocol=0x%x "
1378 			    "pmoff=%d not_removable=%d modesense=%d "
1379 			    "reduced-cmd-support=%d",
1380 			    ov.vid, ov.pid, ov.rev, ov.subclass, ov.protocol,
1381 			    ov.pmoff, ov.not_removable, ov.no_modesense,
1382 			    ov.reduced_cmd_support);
1383 
1384 			if (ov.pmoff) {
1385 				scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_PM;
1386 			}
1387 			if (ov.not_removable) {
1388 				scsa2usbp->scsa2usb_attrs &=
1389 				    ~SCSA2USB_ATTRS_RMB;
1390 			}
1391 			if (ov.no_modesense) {
1392 				scsa2usbp->scsa2usb_attrs &=
1393 				    ~SCSA2USB_ATTRS_MODE_SENSE;
1394 			}
1395 			if (ov.reduced_cmd_support) {
1396 				scsa2usbp->scsa2usb_attrs &=
1397 				    ~SCSA2USB_ATTRS_REDUCED_CMD;
1398 			}
1399 			scsa2usbp->scsa2usb_override_str = override_str_cpy;
1400 			break;
1401 		} else {
1402 			kmem_free(override_str_cpy, override_str_cpy_len);
1403 		}
1404 	}
1405 
1406 	ddi_prop_free(override_str);
1407 }
1408 
1409 
1410 /*
1411  * scsa2usb_parse_input_str:
1412  *	parse one conf file subclass-protocol-override string
1413  *	return vendor id, product id, revision, subclass, protocol
1414  *	function return is success or failure
1415  */
1416 static int
1417 scsa2usb_parse_input_str(char *str, scsa2usb_ov_t *ovp,
1418     scsa2usb_state_t *scsa2usbp)
1419 {
1420 	char		*input_field, *input_value;
1421 	char		*lasts;
1422 	uint_t		i;
1423 	u_longlong_t	value;
1424 
1425 	/* parse all the input pairs in the string */
1426 	for (input_field = scsa2usb_strtok_r(str, "=", &lasts);
1427 	    input_field != NULL;
1428 	    input_field = scsa2usb_strtok_r(lasts, "=", &lasts)) {
1429 
1430 		if ((input_value = scsa2usb_strtok_r(lasts, " ", &lasts)) ==
1431 		    NULL) {
1432 			scsa2usb_override_error("format", scsa2usbp);
1433 
1434 			return (USB_FAILURE);
1435 		}
1436 		/* if input value is a 'don't care', skip to the next pair */
1437 		if (strcmp(input_value, "*") == 0) {
1438 			continue;
1439 		}
1440 		if (strcasecmp(input_field, "vid") == 0) {
1441 			if (kobj_getvalue(input_value, &value) == -1) {
1442 				scsa2usb_override_error("vendor id", scsa2usbp);
1443 
1444 				return (USB_FAILURE);
1445 			}
1446 			ovp->vid = (int)value;
1447 		} else if (strcasecmp(input_field, "pid") == 0) {
1448 			if (kobj_getvalue(input_value, &value) == -1) {
1449 				scsa2usb_override_error("product id",
1450 				    scsa2usbp);
1451 
1452 				return (USB_FAILURE);
1453 			}
1454 			ovp->pid = (int)value;
1455 		} else if (strcasecmp(input_field, "rev") == 0) {
1456 			if (kobj_getvalue(input_value, &value) == -1) {
1457 				scsa2usb_override_error("revision id",
1458 				    scsa2usbp);
1459 
1460 				return (USB_FAILURE);
1461 			}
1462 			ovp->rev = (int)value;
1463 		} else if (strcasecmp(input_field, "subclass") == 0) {
1464 			for (i = 0; i < N_SCSA2USB_SUBC_OVERRIDE; i++) {
1465 				if (strcasecmp(input_value,
1466 				    scsa2usb_subclass[i].name) == 0) {
1467 					ovp->subclass =
1468 					    scsa2usb_subclass[i].value;
1469 					break;
1470 				}
1471 			}
1472 			if (ovp->subclass == 0) {
1473 				scsa2usb_override_error("subclass", scsa2usbp);
1474 
1475 				return (USB_FAILURE);
1476 			}
1477 		} else if (strcasecmp(input_field, "protocol") == 0) {
1478 			for (i = 0; i < N_SCSA2USB_PROT_OVERRIDE; i++) {
1479 				if (strcasecmp(input_value,
1480 				    scsa2usb_protocol[i].name) == 0) {
1481 					ovp->protocol =
1482 					    scsa2usb_protocol[i].value;
1483 					break;
1484 				}
1485 			}
1486 			if (ovp->protocol == 0) {
1487 				scsa2usb_override_error("protocol", scsa2usbp);
1488 
1489 				return (USB_FAILURE);
1490 			}
1491 		} else if (strcasecmp(input_field, "pm") == 0) {
1492 			if (strcasecmp(input_value, "off") == 0) {
1493 				ovp->pmoff = 1;
1494 				break;
1495 			} else {
1496 				scsa2usb_override_error("pm", scsa2usbp);
1497 
1498 				return (USB_FAILURE);
1499 			}
1500 		} else if (strcasecmp(input_field, "removable") == 0) {
1501 			if (strcasecmp(input_value, "false") == 0) {
1502 				ovp->not_removable = 1;
1503 				break;
1504 			} else {
1505 				scsa2usb_override_error("removable", scsa2usbp);
1506 
1507 				return (USB_FAILURE);
1508 			}
1509 		} else if (strcasecmp(input_field, "modesense") == 0) {
1510 			if (strcasecmp(input_value, "false") == 0) {
1511 				ovp->no_modesense = 1;
1512 				break;
1513 			} else {
1514 				scsa2usb_override_error("modesense",
1515 								scsa2usbp);
1516 
1517 				return (USB_FAILURE);
1518 			}
1519 		} else if (strcasecmp(input_field,
1520 		    "reduced-cmd-support") == 0) {
1521 			if (strcasecmp(input_value, "true") == 0) {
1522 				ovp->reduced_cmd_support = 1;
1523 				break;
1524 			} else {
1525 				scsa2usb_override_error(
1526 				    "reduced-cmd-support", scsa2usbp);
1527 
1528 				return (USB_FAILURE);
1529 			}
1530 		} else {
1531 			scsa2usb_override_error("entry", scsa2usbp);
1532 
1533 			return (USB_FAILURE);
1534 		}
1535 	}
1536 
1537 	return (USB_SUCCESS);
1538 }
1539 
1540 
1541 /*
1542  * scsa2usb_override_error:
1543  *	print an error message if conf file string is bad format
1544  */
1545 static void
1546 scsa2usb_override_error(char *input_field, scsa2usb_state_t *scsa2usbp)
1547 {
1548 	USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1549 	    "invalid %s in scsa2usb conf file entry", input_field);
1550 }
1551 
1552 /*
1553  * scsa2usb_strtok_r:
1554  *	parse a list of tokens
1555  */
1556 static char *
1557 scsa2usb_strtok_r(char *p, char *sep, char **lasts)
1558 {
1559 	char	*e;
1560 	char	*tok = NULL;
1561 
1562 	if (p == 0 || *p == 0) {
1563 
1564 		return (NULL);
1565 	}
1566 
1567 	e = p+strlen(p);
1568 
1569 	do {
1570 		if (strchr(sep, *p) != NULL) {
1571 			if (tok != NULL) {
1572 				*p = 0;
1573 				*lasts = p+1;
1574 
1575 				return (tok);
1576 			}
1577 		} else if (tok == NULL) {
1578 			tok = p;
1579 		}
1580 	} while (++p < e);
1581 
1582 	*lasts = NULL;
1583 
1584 	return (tok);
1585 }
1586 
1587 
1588 /*
1589  * scsa2usb_validate_attrs:
1590  *	many devices have BO/CB/CBI protocol support issues.
1591  *	use vendor/product info to reset the
1592  *	individual erroneous attributes
1593  *
1594  * NOTE: we look at only device at a time (at attach time)
1595  */
1596 static void
1597 scsa2usb_validate_attrs(scsa2usb_state_t *scsa2usbp)
1598 {
1599 	int i, mask;
1600 	usb_dev_descr_t *desc = scsa2usbp->scsa2usb_dev_data->dev_descr;
1601 
1602 	if (!SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1603 		scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_GET_LUN;
1604 	}
1605 
1606 	/* determine if this device is on the blacklist */
1607 	for (i = 0; i < N_SCSA2USB_BLACKLIST; i++) {
1608 		if ((scsa2usb_blacklist[i].idVendor == desc->idVendor) &&
1609 		    ((scsa2usb_blacklist[i].idProduct == desc->idProduct) ||
1610 		    (scsa2usb_blacklist[i].idProduct == X))) {
1611 			scsa2usbp->scsa2usb_attrs &=
1612 				~(scsa2usb_blacklist[i].attributes);
1613 			break;
1614 		}
1615 	}
1616 
1617 	/*
1618 	 * Mitsumi's CD-RW drives subclass isn't UFI.
1619 	 * But they support UFI command-set (this code ensures that)
1620 	 * NOTE: This is a special case, and is being called out so.
1621 	 */
1622 	if (desc->idVendor == MS_MITSUMI_VID) {
1623 		mask = scsa2usbp->scsa2usb_cmd_protocol & SCSA2USB_CMDSET_MASK;
1624 		if (mask) {
1625 			scsa2usbp->scsa2usb_cmd_protocol &= ~mask;
1626 		}
1627 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
1628 	}
1629 
1630 	if (scsa2usbp->scsa2usb_attrs != SCSA2USB_ALL_ATTRS) {
1631 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1632 		    scsa2usbp->scsa2usb_log_handle,
1633 		    "scsa2usb attributes modified: 0x%x",
1634 		    scsa2usbp->scsa2usb_attrs);
1635 	}
1636 }
1637 
1638 
1639 /*
1640  * scsa2usb_create_luns:
1641  *	check the number of luns but continue if the check fails,
1642  *	create child nodes for each lun
1643  */
1644 static void
1645 scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp)
1646 {
1647 	int		lun, rval;
1648 	char		*compatible[MAX_COMPAT_NAMES];	/* compatible names */
1649 	dev_info_t	*cdip;
1650 	uchar_t		dtype;
1651 	char		*node_name;
1652 	char		*driver_name = NULL;
1653 
1654 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1655 	    "scsa2usb_create_luns:");
1656 
1657 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1658 
1659 	/* Set n_luns to 1 by default (for floppies and other devices) */
1660 	scsa2usbp->scsa2usb_n_luns = 1;
1661 
1662 	/*
1663 	 * Check if there are any device out there which don't
1664 	 * support the GET_MAX_LUN command. If so, don't issue
1665 	 * control request to them.
1666 	 */
1667 	if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_LUN) == 0) {
1668 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1669 		    "get_max_lun cmd not supported");
1670 	} else {
1671 		if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1672 			scsa2usbp->scsa2usb_n_luns =
1673 				scsa2usb_bulk_only_get_max_lun(scsa2usbp);
1674 		}
1675 	}
1676 
1677 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1678 	    "scsa2usb_create_luns: %d luns found", scsa2usbp->scsa2usb_n_luns);
1679 
1680 	/*
1681 	 * create disk child for each lun
1682 	 */
1683 	for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
1684 		ASSERT(scsa2usbp->scsa2usb_lun_dip[lun] == NULL);
1685 
1686 		/* do an inquiry to get the dtype of this lun */
1687 		scsa2usb_do_inquiry(scsa2usbp, 0, lun);
1688 
1689 		dtype = scsa2usbp->scsa2usb_lun_inquiry[lun].
1690 						inq_dtype & DTYPE_MASK;
1691 
1692 		USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1693 		    "dtype[%d]=0x%x", lun, dtype);
1694 
1695 		driver_name = NULL;
1696 
1697 		switch (dtype) {
1698 		case DTYPE_DIRECT:
1699 		case DTYPE_RODIRECT:
1700 		case DTYPE_OPTICAL:
1701 			node_name = "disk";
1702 			driver_name = "sd";
1703 
1704 			break;
1705 		case DTYPE_SEQUENTIAL:
1706 			node_name = "tape";
1707 			driver_name = "st";
1708 
1709 			break;
1710 		case DTYPE_PRINTER:
1711 			node_name = "printer";
1712 
1713 			break;
1714 		case DTYPE_PROCESSOR:
1715 			node_name = "processor";
1716 
1717 			break;
1718 		case DTYPE_WORM:
1719 			node_name = "worm";
1720 
1721 			break;
1722 		case DTYPE_SCANNER:
1723 			node_name = "scanner";
1724 
1725 			break;
1726 		case DTYPE_CHANGER:
1727 			node_name = "changer";
1728 
1729 			break;
1730 		case DTYPE_COMM:
1731 			node_name = "comm";
1732 
1733 			break;
1734 		case DTYPE_ARRAY_CTRL:
1735 			node_name = "array_ctrl";
1736 
1737 			break;
1738 		case DTYPE_ESI:
1739 			node_name = "esi";
1740 			driver_name = "ses";
1741 
1742 			break;
1743 		default:
1744 			node_name = "generic";
1745 
1746 			break;
1747 		}
1748 
1749 		if (driver_name) {
1750 			compatible[0] = driver_name;
1751 		}
1752 
1753 		ndi_devi_alloc_sleep(scsa2usbp->scsa2usb_dip, node_name,
1754 		    (dnode_t)DEVI_SID_NODEID, &cdip);
1755 
1756 		/* attach target & lun properties */
1757 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0);
1758 		if (rval != DDI_PROP_SUCCESS) {
1759 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1760 			    scsa2usbp->scsa2usb_log_handle,
1761 			    "ndi_prop_update_int target failed %d", rval);
1762 			(void) ndi_devi_free(cdip);
1763 			continue;
1764 		}
1765 
1766 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", lun);
1767 		if (rval != DDI_PROP_SUCCESS) {
1768 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1769 			    scsa2usbp->scsa2usb_log_handle,
1770 			    "ndi_prop_update_int lun failed %d", rval);
1771 			ddi_prop_remove_all(cdip);
1772 			(void) ndi_devi_free(cdip);
1773 			continue;
1774 		}
1775 
1776 		if (driver_name) {
1777 			rval = ndi_prop_update_string_array(DDI_DEV_T_NONE,
1778 			    cdip, "compatible", (char **)compatible,
1779 			    MAX_COMPAT_NAMES);
1780 			if (rval != DDI_PROP_SUCCESS) {
1781 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1782 				    scsa2usbp->scsa2usb_log_handle,
1783 				    "ndi_prop_update_string_array failed %d",
1784 				    rval);
1785 				ddi_prop_remove_all(cdip);
1786 				(void) ndi_devi_free(cdip);
1787 				continue;
1788 			}
1789 		}
1790 
1791 		/*
1792 		 * add property "usb" so we always verify that it is our child
1793 		 */
1794 		rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb");
1795 		if (rval != DDI_PROP_SUCCESS) {
1796 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1797 			    scsa2usbp->scsa2usb_log_handle,
1798 			    "ndi_prop_create_boolean failed %d", rval);
1799 			ddi_prop_remove_all(cdip);
1800 			(void) ndi_devi_free(cdip);
1801 			continue;
1802 		}
1803 
1804 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1805 		(void) ddi_initchild(scsa2usbp->scsa2usb_dip, cdip);
1806 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1807 
1808 		usba_set_usba_device(cdip,
1809 			usba_get_usba_device(scsa2usbp->scsa2usb_dip));
1810 	}
1811 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1812 }
1813 
1814 
1815 /*
1816  * scsa2usb_is_usb:
1817  *	scsa2usb gets called for all possible sd children.
1818  *	we can only accept usb children
1819  */
1820 static int
1821 scsa2usb_is_usb(dev_info_t *dip)
1822 {
1823 	if (dip) {
1824 		return (ddi_prop_exists(DDI_DEV_T_ANY, dip,
1825 		    DDI_PROP_DONTPASS, "usb"));
1826 	}
1827 	return (0);
1828 }
1829 
1830 
1831 /*
1832  * Panic Stuff
1833  * scsa2usb_panic_callb_init:
1834  *	initialize PANIC callb and free allocated resources
1835  */
1836 static void
1837 scsa2usb_panic_callb_init(scsa2usb_state_t *scsa2usbp)
1838 {
1839 	/*
1840 	 * In case the system panics, the sync command flushes
1841 	 * dirty FS pages or buffers. This would cause a hang
1842 	 * in USB.
1843 	 * The reason for the failure is that we enter
1844 	 * polled mode (interrupts disabled) and HCD gets stuck
1845 	 * trying to execute bulk requests
1846 	 * The panic_callback registered below provides a warning
1847 	 * that a panic has occurred and from that point onwards, we
1848 	 * complete each request successfully and immediately. This
1849 	 * will fake successful syncing so at least the rest of the
1850 	 * filesystems complete syncing.
1851 	 */
1852 	scsa2usbp->scsa2usb_panic_info =
1853 		kmem_zalloc(sizeof (scsa2usb_cpr_t), KM_SLEEP);
1854 	mutex_init(&scsa2usbp->scsa2usb_panic_info->lockp,
1855 		NULL, MUTEX_DRIVER,
1856 		scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
1857 	scsa2usbp->scsa2usb_panic_info->statep = scsa2usbp;
1858 	scsa2usbp->scsa2usb_panic_info->cpr.cc_lockp =
1859 				&scsa2usbp->scsa2usb_panic_info->lockp;
1860 	scsa2usbp->scsa2usb_panic_info->cpr.cc_id =
1861 			callb_add(scsa2usb_panic_callb,
1862 			    (void *)scsa2usbp->scsa2usb_panic_info,
1863 			    CB_CL_PANIC, "scsa2usb");
1864 }
1865 
1866 
1867 /*
1868  * scsa2usb_panic_callb_fini:
1869  *	cancel out PANIC callb and free allocated resources
1870  */
1871 static void
1872 scsa2usb_panic_callb_fini(scsa2usb_state_t *scsa2usbp)
1873 {
1874 	if (scsa2usbp->scsa2usb_panic_info) {
1875 		SCSA2USB_CANCEL_CB(scsa2usbp->scsa2usb_panic_info->cpr.cc_id);
1876 		mutex_destroy(&scsa2usbp->scsa2usb_panic_info->lockp);
1877 		scsa2usbp->scsa2usb_panic_info->statep = NULL;
1878 		kmem_free(scsa2usbp->scsa2usb_panic_info,
1879 		    sizeof (scsa2usb_cpr_t));
1880 		scsa2usbp->scsa2usb_panic_info = NULL;
1881 	}
1882 }
1883 
1884 
1885 /*
1886  * scsa2usb_panic_callb:
1887  *	This routine is called when there is a system panic.
1888  */
1889 /* ARGSUSED */
1890 static boolean_t
1891 scsa2usb_panic_callb(void *arg, int code)
1892 {
1893 	scsa2usb_cpr_t *cpr_infop;
1894 	scsa2usb_state_t *scsa2usbp;
1895 	uint_t		lun;
1896 
1897 	_NOTE(NO_COMPETING_THREADS_NOW);
1898 	cpr_infop = (scsa2usb_cpr_t *)arg;
1899 	scsa2usbp = (scsa2usb_state_t *)cpr_infop->statep;
1900 
1901 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1902 	    "scsa2usb_panic_callb: code=%d", code);
1903 
1904 	/*
1905 	 * If we return error here, "sd" prints lots of error
1906 	 * messages and could retry the same pkt over and over again.
1907 	 * The sync recovery isn't "smooth" in that case. By faking
1908 	 * a success return, instead,  we force sync to complete.
1909 	 */
1910 	if (scsa2usbp->scsa2usb_cur_pkt) {
1911 		/*
1912 		 * Do not print the "no sync" warning here. it will then be
1913 		 * displayed before we actually start syncing. Also we don't
1914 		 * replace this code with a call to scsa2usb_pkt_completion().
1915 		 * NOTE: mutexes are disabled during panic.
1916 		 */
1917 		scsa2usbp->scsa2usb_cur_pkt->pkt_reason = CMD_CMPLT;
1918 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1919 		scsa2usb_pkt_completion(scsa2usbp, scsa2usbp->scsa2usb_cur_pkt);
1920 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1921 	}
1922 
1923 	/* get rid of waitQ */
1924 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
1925 		scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_CMPLT);
1926 	}
1927 
1928 	_NOTE(COMPETING_THREADS_NOW);
1929 
1930 	return (B_TRUE);
1931 }
1932 
1933 /*
1934  * scsa2usb_cpr_suspend
1935  *	determine if the device's state can be changed to SUSPENDED
1936  *	close pipes if there is no activity
1937  */
1938 /* ARGSUSED */
1939 static int
1940 scsa2usb_cpr_suspend(dev_info_t *dip)
1941 {
1942 	scsa2usb_state_t *scsa2usbp;
1943 	int	prev_state;
1944 	int	rval = USB_FAILURE;
1945 
1946 	scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
1947 
1948 	ASSERT(scsa2usbp != NULL);
1949 
1950 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1951 	    "scsa2usb_cpr_suspend:");
1952 
1953 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1954 	switch (scsa2usbp->scsa2usb_dev_state) {
1955 	case USB_DEV_ONLINE:
1956 	case USB_DEV_PWRED_DOWN:
1957 	case USB_DEV_DISCONNECTED:
1958 		prev_state = scsa2usbp->scsa2usb_dev_state;
1959 		scsa2usbp->scsa2usb_dev_state = USB_DEV_SUSPENDED;
1960 
1961 		/*
1962 		 * If the device is busy, we cannot suspend
1963 		 */
1964 		if (SCSA2USB_BUSY(scsa2usbp)) {
1965 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
1966 			    scsa2usbp->scsa2usb_log_handle,
1967 			    "scsa2usb_cpr_suspend: I/O active");
1968 
1969 			/* fall back to previous state */
1970 			scsa2usbp->scsa2usb_dev_state = prev_state;
1971 		} else {
1972 			rval = USB_SUCCESS;
1973 		}
1974 
1975 		break;
1976 	case USB_DEV_SUSPENDED:
1977 	default:
1978 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1979 		    "scsa2usb_cpr_suspend: Illegal dev state: %d",
1980 		    scsa2usbp->scsa2usb_dev_state);
1981 
1982 		break;
1983 	}
1984 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1985 
1986 	if ((rval == USB_SUCCESS) && scsa2usbp->scsa2usb_ugen_hdl) {
1987 		rval = usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
1988 							DDI_SUSPEND);
1989 	}
1990 
1991 	return (rval);
1992 }
1993 
1994 
1995 /*
1996  * scsa2usb_cpr_resume:
1997  *	restore device's state
1998  */
1999 static void
2000 scsa2usb_cpr_resume(dev_info_t *dip)
2001 {
2002 	scsa2usb_state_t *scsa2usbp =
2003 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2004 
2005 	ASSERT(scsa2usbp != NULL);
2006 
2007 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2008 	    "scsa2usb_cpr_resume: dip = 0x%p", dip);
2009 
2010 	scsa2usb_restore_device_state(dip, scsa2usbp);
2011 
2012 	if (scsa2usbp->scsa2usb_ugen_hdl) {
2013 		(void) usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl,
2014 							DDI_RESUME);
2015 	}
2016 }
2017 
2018 
2019 /*
2020  * scsa2usb_restore_device_state:
2021  *	- raise the device's power
2022  *	- reopen all the pipes
2023  */
2024 static void
2025 scsa2usb_restore_device_state(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
2026 {
2027 	uint_t	prev_state;
2028 
2029 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2030 	    "scsa2usb_restore_device_state:");
2031 
2032 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2033 	prev_state = scsa2usbp->scsa2usb_dev_state;
2034 
2035 	scsa2usb_raise_power(scsa2usbp);
2036 
2037 	ASSERT((prev_state == USB_DEV_DISCONNECTED) ||
2038 	    (prev_state == USB_DEV_SUSPENDED));
2039 
2040 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2041 
2042 	/* Check for the same device */
2043 	if (usb_check_same_device(dip, scsa2usbp->scsa2usb_log_handle,
2044 	    USB_LOG_L0, DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) {
2045 
2046 		/* change the flags to active */
2047 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2048 		scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
2049 
2050 		scsa2usb_pm_idle_component(scsa2usbp);
2051 
2052 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2053 
2054 		return;
2055 	}
2056 
2057 	USB_DPRINTF_L0(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2058 	    "Reinserted device is accessible again.");
2059 
2060 	/*
2061 	 * if the device had remote wakeup earlier,
2062 	 * enable it again
2063 	 */
2064 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2065 	if (scsa2usbp->scsa2usb_pm &&
2066 	    scsa2usbp->scsa2usb_pm->scsa2usb_wakeup_enabled) {
2067 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2068 		(void) usb_handle_remote_wakeup(scsa2usbp->scsa2usb_dip,
2069 		    USB_REMOTE_WAKEUP_ENABLE);
2070 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2071 	}
2072 
2073 	scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
2074 	scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
2075 
2076 	scsa2usb_pm_idle_component(scsa2usbp);
2077 
2078 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2079 }
2080 
2081 
2082 /*
2083  * SCSA entry points:
2084  *
2085  * scsa2usb_scsi_tgt_probe:
2086  * scsa functions are exported by means of the transport table
2087  * Issue a probe to get the inquiry data.
2088  */
2089 /* ARGSUSED */
2090 static int
2091 scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void))
2092 {
2093 	scsi_hba_tran_t *tran;
2094 	scsa2usb_state_t *scsa2usbp;
2095 	dev_info_t *dip = ddi_get_parent(sd->sd_dev);
2096 	int rval;
2097 
2098 	ASSERT(dip);
2099 
2100 	tran = ddi_get_driver_private(dip);
2101 	ASSERT(tran != NULL);
2102 	scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
2103 	ASSERT(scsa2usbp);
2104 
2105 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2106 	    "scsa2usb_scsi_tgt_probe:");
2107 
2108 	/* if device is disconnected (ie. pipes closed), fail immediately */
2109 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2110 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2111 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2112 
2113 		return (SCSIPROBE_FAILURE);
2114 	}
2115 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2116 
2117 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2118 	    "scsa2usb_scsi_tgt_probe: scsi_device = 0x%p", sd);
2119 
2120 	if ((rval = scsi_hba_probe(sd, waitfunc)) == SCSIPROBE_EXISTS) {
2121 		/*
2122 		 * fake the removable bit on all USB storage devices
2123 		 * unless overridden by a scsa2usb.conf entry
2124 		 */
2125 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2126 		if (scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB) {
2127 			_NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry))
2128 			sd->sd_inq->inq_rmb = 1;
2129 		}
2130 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2131 	}
2132 
2133 	return (rval);
2134 }
2135 
2136 
2137 /*
2138  * scsa2usb_scsi_tgt_init:
2139  *	check whether we created this child ourselves
2140  */
2141 /* ARGSUSED */
2142 static int
2143 scsa2usb_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip,
2144     scsi_hba_tran_t *tran, struct scsi_device *sd)
2145 {
2146 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2147 					tran->tran_hba_private;
2148 	int lun;
2149 	int t_len = sizeof (lun);
2150 
2151 	if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2152 	    DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2153 	    &t_len) != DDI_PROP_SUCCESS) {
2154 
2155 		return (DDI_FAILURE);
2156 	}
2157 
2158 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2159 	    "scsa2usb_scsi_tgt_init: %s, lun%d", ddi_driver_name(cdip), lun);
2160 
2161 	/* is this a child we created? */
2162 	if (scsa2usb_is_usb(cdip) == 0) {
2163 
2164 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2165 		    "scsa2usb_scsi_tgt_init: new child %s%d",
2166 		    ddi_driver_name(cdip), ddi_get_instance(cdip));
2167 
2168 		/*
2169 		 * add property "usb" so we can always verify that it
2170 		 * is our child
2171 		 */
2172 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb") !=
2173 		    DDI_PROP_SUCCESS) {
2174 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2175 			    scsa2usbp->scsa2usb_log_handle,
2176 			    "ndi_prop_create_boolean failed");
2177 
2178 			return (DDI_FAILURE);
2179 		}
2180 
2181 		usba_set_usba_device(cdip,
2182 			usba_get_usba_device(scsa2usbp->scsa2usb_dip));
2183 
2184 		/*
2185 		 * we don't store this dip in scsa2usb_lun_dip, there
2186 		 * might be multiple dips for the same device
2187 		 */
2188 
2189 		return (DDI_SUCCESS);
2190 	}
2191 
2192 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2193 	if ((lun >= scsa2usbp->scsa2usb_n_luns) ||
2194 	    (scsa2usbp->scsa2usb_lun_dip[lun] != NULL)) {
2195 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2196 
2197 		return (DDI_FAILURE);
2198 	}
2199 
2200 	scsa2usbp->scsa2usb_lun_dip[lun] = cdip;
2201 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2202 
2203 	return (DDI_SUCCESS);
2204 }
2205 
2206 
2207 /*
2208  * scsa2usb_scsi_tgt_free:
2209  */
2210 /* ARGSUSED */
2211 static void
2212 scsa2usb_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *cdip,
2213 	scsi_hba_tran_t *tran, struct scsi_device *sd)
2214 {
2215 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2216 					tran->tran_hba_private;
2217 	int lun;
2218 	int t_len = sizeof (lun);
2219 
2220 	/* is this our child? */
2221 	if (scsa2usb_is_usb(cdip) == 0) {
2222 
2223 		return;
2224 	}
2225 
2226 	if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2227 	    DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2228 	    &t_len) != DDI_PROP_SUCCESS) {
2229 
2230 		return;
2231 	}
2232 
2233 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2234 	    "scsa2usb_scsi_tgt_free: %s lun%d", ddi_driver_name(cdip), lun);
2235 
2236 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2237 	if (lun < scsa2usbp->scsa2usb_n_luns) {
2238 		if (scsa2usbp->scsa2usb_lun_dip[lun] == cdip) {
2239 			scsa2usbp->scsa2usb_lun_dip[lun] = NULL;
2240 		}
2241 	}
2242 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2243 }
2244 
2245 
2246 /*
2247  * bus enumeration entry points
2248  */
2249 static int
2250 scsa2usb_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2251     void *arg, dev_info_t **child)
2252 {
2253 	int	circ;
2254 	int	rval;
2255 
2256 	scsa2usb_state_t *scsa2usbp =
2257 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2258 
2259 	ASSERT(scsa2usbp != NULL);
2260 
2261 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2262 	    "scsa2usb_scsi_bus_config: op=%d", op);
2263 
2264 	if (scsa2usb_scsi_bus_config_debug) {
2265 		flag |= NDI_DEVI_DEBUG;
2266 	}
2267 
2268 	ndi_devi_enter(dip, &circ);
2269 	/* create children if necessary */
2270 	if (DEVI(dip)->devi_child == NULL) {
2271 		scsa2usb_create_luns(scsa2usbp);
2272 	}
2273 
2274 	rval = ndi_busop_bus_config(dip, flag, op, arg, child, 0);
2275 
2276 	ndi_devi_exit(dip, circ);
2277 
2278 	return (rval);
2279 }
2280 
2281 
2282 static int
2283 scsa2usb_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2284     void *arg)
2285 {
2286 	scsa2usb_state_t *scsa2usbp =
2287 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2288 
2289 	int		circular_count;
2290 	int		rval = NDI_SUCCESS;
2291 	uint_t		save_flag = flag;
2292 
2293 	ASSERT(scsa2usbp != NULL);
2294 
2295 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2296 	    "scsa2usb_scsi_bus_unconfig: op=%d", op);
2297 
2298 	if (scsa2usb_scsi_bus_config_debug) {
2299 		flag |= NDI_DEVI_DEBUG;
2300 	}
2301 
2302 	/*
2303 	 * first offline and if offlining successful, then
2304 	 * remove children
2305 	 */
2306 	if (op == BUS_UNCONFIG_ALL) {
2307 		flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG);
2308 	}
2309 
2310 	ndi_devi_enter(dip, &circular_count);
2311 	rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2312 
2313 	/*
2314 	 * If unconfig is successful and not part of modunload
2315 	 * daemon, attempt to remove children.
2316 	 */
2317 	if (op == BUS_UNCONFIG_ALL && rval == NDI_SUCCESS &&
2318 	    (flag & NDI_AUTODETACH) == 0) {
2319 		flag |= NDI_DEVI_REMOVE;
2320 		rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2321 	}
2322 	ndi_devi_exit(dip, circular_count);
2323 
2324 	if ((rval != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) &&
2325 	    (save_flag & NDI_DEVI_REMOVE)) {
2326 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2327 		if (scsa2usbp->scsa2usb_warning_given != B_TRUE) {
2328 			USB_DPRINTF_L0(DPRINT_MASK_SCSA,
2329 			    scsa2usbp->scsa2usb_log_handle,
2330 			    "Disconnected device was busy, "
2331 			    "please reconnect.");
2332 			scsa2usbp->scsa2usb_warning_given = B_TRUE;
2333 		}
2334 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2335 	}
2336 
2337 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2338 	    "scsa2usb_scsi_bus_unconfig: rval=%d", rval);
2339 
2340 	return (rval);
2341 }
2342 
2343 
2344 /*
2345  * scsa2usb_scsi_init_pkt:
2346  *	Set up the scsi_pkt for transport. Also initialize
2347  *	scsa2usb_cmd struct for the transport.
2348  *	NOTE: We do not do any DMA setup here as USBA framework
2349  *	does that for us.
2350  */
2351 static struct scsi_pkt *
2352 scsa2usb_scsi_init_pkt(struct scsi_address *ap,
2353     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
2354     int tgtlen, int flags, int (*callback)(), caddr_t arg)
2355 {
2356 	scsa2usb_cmd_t	 *cmd;
2357 	scsa2usb_state_t *scsa2usbp;
2358 	struct scsi_pkt	 *in_pkt = pkt;
2359 
2360 	ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
2361 
2362 	scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2363 
2364 	/* Print sync message */
2365 	if (ddi_in_panic()) {
2366 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2367 		SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2368 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2369 		/* continue so caller will not hang or complain */
2370 	}
2371 
2372 	/* allocate a pkt, if none already allocated */
2373 	if (pkt == NULL) {
2374 		if (statuslen < sizeof (struct scsi_arq_status)) {
2375 			statuslen = sizeof (struct scsi_arq_status);
2376 		}
2377 
2378 		pkt = scsi_hba_pkt_alloc(scsa2usbp->scsa2usb_dip, ap, cmdlen,
2379 			statuslen, tgtlen, sizeof (scsa2usb_cmd_t),
2380 			callback, arg);
2381 		if (pkt == NULL) {
2382 
2383 			return (NULL);
2384 		}
2385 
2386 		cmd = PKT2CMD(pkt);
2387 		cmd->cmd_pkt	= pkt; /* back link to pkt */
2388 		cmd->cmd_scblen	= statuslen;
2389 		cmd->cmd_cdblen	= (uchar_t)cmdlen;
2390 
2391 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2392 		cmd->cmd_tag	= scsa2usbp->scsa2usb_tag++;
2393 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2394 
2395 		cmd->cmd_bp	= bp;
2396 		pkt->pkt_scbp	= (opaque_t)&cmd->cmd_scb;
2397 
2398 		usba_init_list(&cmd->cmd_waitQ, (usb_opaque_t)cmd,
2399 			scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2400 	} else {
2401 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2402 		    "scsa2usb: pkt != NULL");
2403 
2404 		/* nothing to do */
2405 	}
2406 
2407 	if (bp) {
2408 		if ((bp_mapin_common(bp, (callback == SLEEP_FUNC) ?
2409 		    VM_SLEEP : VM_NOSLEEP)) == NULL) {
2410 			if (pkt != in_pkt) {
2411 				scsi_hba_pkt_free(ap, pkt);
2412 			}
2413 
2414 			return (NULL);
2415 		}
2416 
2417 		USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2418 		    scsa2usbp->scsa2usb_log_handle,
2419 		    "scsa2usb_scsi_init_pkt: mapped in 0x%p, addr=0x%p",
2420 		    bp, bp->b_un.b_addr);
2421 	}
2422 
2423 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2424 	    "scsa2usb_scsi_init_pkt: ap = 0x%p pkt: 0x%p\n\t"
2425 	    "bp = 0x%p cmdlen = %x stlen = 0x%x tlen = 0x%x flags = 0x%x",
2426 	    ap, pkt, bp, cmdlen, statuslen, tgtlen, flags);
2427 
2428 	return (pkt);
2429 }
2430 
2431 
2432 /*
2433  * scsa2usb_scsi_destroy_pkt:
2434  *	We are done with the packet. Get rid of it.
2435  */
2436 static void
2437 scsa2usb_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2438 {
2439 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
2440 	scsa2usb_state_t *scsa2usbp = ADDR2SCSA2USB(ap);
2441 
2442 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2443 	    "scsa2usb_scsi_destroy_pkt: pkt=0x%p", pkt);
2444 
2445 	usba_destroy_list(&cmd->cmd_waitQ);
2446 	scsi_hba_pkt_free(ap, pkt);
2447 }
2448 
2449 
2450 /*
2451  * scsa2usb_scsi_start:
2452  *	For each command being issued, build up the CDB
2453  *	and call scsi_transport to issue the command. This
2454  *	function is based on the assumption that USB allows
2455  *	a subset of SCSI commands. Other SCSI commands we fail.
2456  */
2457 static int
2458 scsa2usb_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2459 {
2460 	scsa2usb_cmd_t		*cmd;
2461 	scsa2usb_state_t	*scsa2usbp = ADDR2SCSA2USB(ap);
2462 	uint_t			lun = ap->a_lun;
2463 
2464 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2465 
2466 	cmd = PKT2CMD(pkt);
2467 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2468 	    "scsa2usb_scsi_start:\n\t"
2469 	    "bp: 0x%p ap: 0x%p pkt: 0x%p flag: 0x%x time: 0x%x\n\tcdb0: 0x%x "
2470 	    "dev_state: 0x%x pkt_state: 0x%x flags: 0x%x pipe_state: 0x%x",
2471 	    cmd->cmd_bp, ap, pkt, pkt->pkt_flags, pkt->pkt_time,
2472 	    pkt->pkt_cdbp[0], scsa2usbp->scsa2usb_dev_state,
2473 	    scsa2usbp->scsa2usb_pkt_state, scsa2usbp->scsa2usb_flags,
2474 	    scsa2usbp->scsa2usb_pipe_state);
2475 
2476 	if (pkt->pkt_time == 0) {
2477 		USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2478 		    "pkt submitted with 0 timeout which may cause indefinite "
2479 		    "hangs");
2480 	}
2481 
2482 	/*
2483 	 * if we are in panic, we are in polled mode, so we can just
2484 	 * accept the request, drop it and return
2485 	 * if we fail this request, the rest of the file systems do not
2486 	 * get synced
2487 	 */
2488 	if (ddi_in_panic()) {
2489 		extern int do_polled_io;
2490 
2491 		ASSERT(do_polled_io);
2492 		scsa2usb_prepare_pkt(scsa2usbp, pkt);
2493 		SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2494 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2495 
2496 		return (TRAN_ACCEPT);
2497 	}
2498 
2499 	/* we cannot do polling, this should not happen */
2500 	if (pkt->pkt_flags & FLAG_NOINTR) {
2501 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2502 		    "NOINTR packet: opcode = 0%x", pkt->pkt_cdbp[0]);
2503 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2504 
2505 		return (TRAN_BADPKT);
2506 	}
2507 
2508 	/* is there a ugen open? */
2509 	if (scsa2usbp->scsa2usb_ugen_open_count) {
2510 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2511 		    "ugen access in progress (count=%d)",
2512 		    scsa2usbp->scsa2usb_ugen_open_count);
2513 
2514 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2515 
2516 		return (TRAN_BUSY);
2517 	}
2518 
2519 	/* prepare packet */
2520 	scsa2usb_prepare_pkt(scsa2usbp, pkt);
2521 
2522 	/* just queue up the requests in the waitQ if below max */
2523 	if (usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]) >
2524 	    SCSA2USB_MAX_REQ_PER_LUN) {
2525 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2526 		    scsa2usbp->scsa2usb_log_handle,
2527 		    "scsa2usb_scsi_start: limit (%d) exceeded",
2528 		    SCSA2USB_MAX_REQ_PER_LUN);
2529 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2530 
2531 		return (TRAN_BUSY);
2532 	}
2533 
2534 	usba_add_to_list(&scsa2usbp->scsa2usb_waitQ[lun], &cmd->cmd_waitQ);
2535 
2536 	/* fire up a thread to start executing the protocol */
2537 	if (scsa2usbp->scsa2usb_work_thread_id == 0) {
2538 		if ((usb_async_req(scsa2usbp->scsa2usb_dip,
2539 		    scsa2usb_work_thread,
2540 		    (void *)scsa2usbp, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
2541 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2542 			    scsa2usbp->scsa2usb_log_handle,
2543 			    "no work thread started");
2544 
2545 			if (usba_rm_from_list(
2546 			    &scsa2usbp->scsa2usb_waitQ[lun],
2547 			    &cmd->cmd_waitQ) == USB_SUCCESS) {
2548 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
2549 
2550 				return (TRAN_BUSY);
2551 			} else {
2552 
2553 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
2554 
2555 				return (TRAN_ACCEPT);
2556 			}
2557 		}
2558 		scsa2usbp->scsa2usb_work_thread_id = (kthread_t *)1;
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 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2942 	    "scsa2usb_check_bulkonly_blacklist_attrs: opcode = %s",
2943 	    scsi_cname(opcode, scsa2usb_cmds));
2944 
2945 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
2946 
2947 	/*
2948 	 * decode and convert the packet
2949 	 * for most cmds, we can bcopy the cdb
2950 	 */
2951 	switch (opcode) {
2952 	case SCMD_DOORLOCK:
2953 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_DOORLOCK)) {
2954 
2955 			return (SCSA2USB_JUST_ACCEPT);
2956 
2957 		} else if (scsa2usbp->scsa2usb_lun_inquiry[cmd->cmd_pkt->
2958 		    pkt_address.a_lun].inq_rmb) {
2959 
2960 			break;
2961 		}
2962 
2963 		return (SCSA2USB_JUST_ACCEPT);
2964 
2965 	case SCMD_START_STOP:
2966 		/*
2967 		 * these devices don't have mechanics that spin the
2968 		 * media up and down. So, it doesn't make much sense
2969 		 * to issue this cmd.
2970 		 *
2971 		 * Furthermore, Hagiwara devices do not handle these
2972 		 * cmds well. just accept this command as success.
2973 		 */
2974 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
2975 
2976 			return (SCSA2USB_JUST_ACCEPT);
2977 
2978 		} else if (cmd->cmd_pkt->pkt_cdbp[4] & LOEJECT) {
2979 			/*
2980 			 * if the device is really a removable then
2981 			 * pass it on to the device, else just accept
2982 			 */
2983 			if (scsa2usbp->scsa2usb_lun_inquiry[cmd->cmd_pkt->
2984 			    pkt_address.a_lun].inq_rmb) {
2985 
2986 				break;
2987 			}
2988 
2989 			return (SCSA2USB_JUST_ACCEPT);
2990 
2991 		} else if (!scsa2usbp->scsa2usb_rcvd_not_ready) {
2992 			/*
2993 			 * if we have not received a NOT READY condition,
2994 			 * just accept since some device choke on this too.
2995 			 * we do have to let EJECT get through though
2996 			 */
2997 			return (SCSA2USB_JUST_ACCEPT);
2998 		}
2999 
3000 		break;
3001 	case SCMD_INQUIRY:
3002 		/*
3003 		 * Some devices do not handle the inquiry cmd well
3004 		 * so build an inquiry and accept this command as
3005 		 * success.
3006 		 */
3007 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3008 			uchar_t evpd = 0x01;
3009 
3010 			if (cmd->cmd_cdb[1] & evpd) {
3011 
3012 				return (SCSA2USB_REJECT);
3013 			}
3014 			cmd->cmd_pkt->pkt_resid -=
3015 					scsa2usb_fake_inquiry(scsa2usbp, cmd,
3016 					cmd->cmd_pkt->pkt_address.a_lun);
3017 			cmd->cmd_pkt->pkt_state |= STATE_XFERRED_DATA;
3018 
3019 			return (SCSA2USB_JUST_ACCEPT);
3020 		}
3021 		break;
3022 
3023 	/*
3024 	 * Fake accepting the following two Opcodes
3025 	 * (as the drive doesn't support it.)
3026 	 * These are needed by format command.
3027 	 */
3028 	case SCMD_RESERVE:
3029 	case SCMD_RELEASE:
3030 	case SCMD_PERSISTENT_RESERVE_IN:
3031 	case SCMD_PERSISTENT_RESERVE_OUT:
3032 
3033 		return (SCSA2USB_JUST_ACCEPT);
3034 
3035 	case SCMD_MODE_SENSE:
3036 	case SCMD_MODE_SELECT:
3037 	case SCMD_MODE_SENSE_G1:
3038 	case SCMD_MODE_SELECT_G1:
3039 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_MODE_SENSE)) {
3040 			if (cmd->cmd_bp) {
3041 				cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3042 								b_bcount;
3043 			}
3044 			scsa2usb_force_invalid_request(scsa2usbp, cmd);
3045 
3046 			return (SCSA2USB_JUST_ACCEPT);
3047 		}
3048 
3049 		break;
3050 	default:
3051 
3052 		break;
3053 	}
3054 
3055 	return (SCSA2USB_TRANSPORT);
3056 }
3057 
3058 
3059 /*
3060  * scsa2usb_handle_scsi_cmd_sub_class:
3061  *	prepare a scsi cmd
3062  *	returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT, SCSA2USB_JUST_ACCEPT
3063  */
3064 int
3065 scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *scsa2usbp,
3066     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3067 {
3068 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3069 	    "scsa2usb_handle_scsi_cmd_sub_class: cmd = 0x%p pkt = 0x%p",
3070 	    cmd, pkt);
3071 
3072 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3073 
3074 	bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3075 	cmd->cmd_cdb[SCSA2USB_OPCODE] = pkt->pkt_cdbp[0];   /* Set the opcode */
3076 	cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3077 
3078 	/*
3079 	 * decode and convert the packet
3080 	 * for most cmds, we can bcopy the cdb
3081 	 */
3082 	switch (pkt->pkt_cdbp[0]) {
3083 	case SCMD_FORMAT:
3084 		/*
3085 		 * SCMD_FORMAT used to limit cmd->cmd_xfercount
3086 		 * to 4 bytes, but this hangs
3087 		 * formatting dvd media using cdrecord (that is,
3088 		 * a SCSI FORMAT UNIT command with a parameter list > 4 bytes)
3089 		 * (bit 4 in cdb1 is the Fmtdata bit)
3090 		 */
3091 		if ((pkt->pkt_cdbp[1] & 0x10) && cmd->cmd_bp) {
3092 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3093 		} else {
3094 			cmd->cmd_xfercount = 4;
3095 		}
3096 		cmd->cmd_dir = CBW_DIR_OUT;
3097 		cmd->cmd_actual_len = CDB_GROUP0;
3098 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3099 		break;
3100 
3101 	case SCMD_INQUIRY:
3102 		cmd->cmd_dir = CBW_DIR_IN;
3103 		cmd->cmd_actual_len = CDB_GROUP0;
3104 		cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3105 		cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3106 		    min(SCSA2USB_MAX_INQ_LEN,
3107 		    cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3108 		break;
3109 
3110 	case SCMD_READ_CAPACITY:
3111 		cmd->cmd_dir = CBW_DIR_IN;
3112 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3113 		cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3114 		break;
3115 
3116 	/*
3117 	 * SCMD_READ/SCMD_WRITE are converted to G1 cmds
3118 	 * (as ATAPI devices don't recognize G0 commands)
3119 	 *
3120 	 * SCMD_READ_LONG/SCMD_WRITE_LONG are handled in
3121 	 * scsa2usb_rw_transport() along with other commands.
3122 	 *
3123 	 * USB Host Controllers cannot handle large (read/write)
3124 	 * xfers. We split the large request to chunks of
3125 	 * smaller ones to meet the HCD limitations.
3126 	 */
3127 	case SCMD_READ:
3128 	case SCMD_WRITE:
3129 	case SCMD_READ_G1:
3130 	case SCMD_WRITE_G1:
3131 	case SCMD_READ_G5:
3132 	case SCMD_WRITE_G5:
3133 	case SCMD_READ_LONG:
3134 	case SCMD_WRITE_LONG:
3135 	case SCMD_READ_CD:
3136 		switch (scsa2usbp->
3137 		    scsa2usb_lun_inquiry[pkt->pkt_address.a_lun].
3138 		    inq_dtype & DTYPE_MASK) {
3139 		case DTYPE_DIRECT:
3140 		case DTYPE_RODIRECT:
3141 		case DTYPE_OPTICAL:
3142 			return (scsa2usb_rw_transport(
3143 					scsa2usbp, pkt));
3144 		default:
3145 			bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3146 			if (cmd->cmd_bp) {
3147 				cmd->cmd_dir =
3148 				    (cmd->cmd_bp->b_flags & B_READ) ?
3149 				    CBW_DIR_IN : CBW_DIR_OUT;
3150 				cmd->cmd_xfercount =
3151 				    cmd->cmd_bp->b_bcount;
3152 			}
3153 			break;
3154 		}
3155 		break;
3156 
3157 	case SCMD_REQUEST_SENSE:
3158 		cmd->cmd_dir = CBW_DIR_IN;
3159 		cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3160 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3161 		cmd->cmd_actual_len = CDB_GROUP0;
3162 		break;
3163 
3164 	/*
3165 	 * do not convert SCMD_MODE_SENSE/SELECT to G1 cmds because
3166 	 * the mode header is different as well
3167 	 */
3168 
3169 	case SCMD_DOORLOCK:
3170 	case SCMD_START_STOP:
3171 	case SCMD_TEST_UNIT_READY:
3172 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3173 		break;
3174 
3175 	/*
3176 	 * Needed by zip protocol to reset the device
3177 	 */
3178 	case SCMD_SDIAG:
3179 	case SCMD_REZERO_UNIT:
3180 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3181 		cmd->cmd_actual_len = CDB_GROUP1;
3182 		break;
3183 
3184 	case SCMD_WRITE_VERIFY:
3185 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3186 		cmd->cmd_dir = CBW_DIR_OUT;
3187 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3188 		cmd->cmd_actual_len = CDB_GROUP1;
3189 		break;
3190 
3191 	/*
3192 	 * Next command does not have a SCSI equivalent as
3193 	 * it is vendor specific.
3194 	 * It was listed in the vendor's ATAPI Zip specs.
3195 	 */
3196 	case SCMD_READ_FORMAT_CAP:
3197 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3198 		cmd->cmd_dir = CBW_DIR_IN;
3199 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3200 		cmd->cmd_actual_len = CDB_GROUP1;
3201 		break;
3202 	case IOMEGA_CMD_CARTRIDGE_PROTECT:
3203 		cmd->cmd_dir = CBW_DIR_OUT;
3204 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3205 		cmd->cmd_cdb[SCSA2USB_LBA_2] &= ~1;	/* Make it even */
3206 		cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3207 		cmd->cmd_actual_len = CDB_GROUP0;
3208 		cmd->cmd_xfercount = pkt->pkt_cdbp[4]; /* Length of password */
3209 		break;
3210 
3211 	default:
3212 		/*
3213 		 * an unknown command may be a uscsi cmd which we
3214 		 * should let go thru without mapping
3215 		 */
3216 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3217 		if (cmd->cmd_bp) {
3218 			cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3219 						CBW_DIR_IN : CBW_DIR_OUT;
3220 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3221 		}
3222 
3223 		break;
3224 	} /* end of switch */
3225 
3226 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3227 	    "scsa2usb_handle_scsi_cmd_sub_class: opcode = 0x%x count = 0x%lx",
3228 	    pkt->pkt_cdbp[SCSA2USB_OPCODE], cmd->cmd_xfercount);
3229 
3230 	cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3231 
3232 	return (SCSA2USB_TRANSPORT);
3233 }
3234 
3235 
3236 /*
3237  * scsa2usb_check_ufi_blacklist_attrs:
3238  *	validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3239  *	if blacklisted attrs match accept the request
3240  *	attributes checked are:-
3241  *		SCSA2USB_ATTRS_GET_CONF
3242  *		SCSA2USB_ATTRS_GET_PERF
3243  *		SCSA2USB_ATTRS_GET_START_STOP
3244  */
3245 static int
3246 scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *scsa2usbp, uchar_t opcode,
3247     scsa2usb_cmd_t *cmd)
3248 {
3249 	int	rval = SCSA2USB_TRANSPORT;
3250 
3251 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3252 
3253 	switch (opcode) {
3254 	case SCMD_PRIN:
3255 	case SCMD_PROUT:
3256 		rval = SCSA2USB_JUST_ACCEPT;
3257 		break;
3258 	case SCMD_MODE_SENSE:
3259 	case SCMD_MODE_SELECT:
3260 		if (cmd->cmd_bp) {
3261 			cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3262 		}
3263 		scsa2usb_force_invalid_request(scsa2usbp, cmd);
3264 		rval = SCSA2USB_JUST_ACCEPT;
3265 		break;
3266 	case SCMD_GET_CONFIGURATION:
3267 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_CONF)) {
3268 			rval = SCSA2USB_JUST_ACCEPT;
3269 		}
3270 		break;
3271 	case SCMD_GET_PERFORMANCE:
3272 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_PERF)) {
3273 			rval = SCSA2USB_JUST_ACCEPT;
3274 		}
3275 		break;
3276 	case SCMD_START_STOP:
3277 		/*
3278 		 * some CB/CBI devices don't have mechanics that spin the
3279 		 * media up and down. So, it doesn't make much sense
3280 		 * to issue this cmd to those devices.
3281 		 */
3282 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3283 			rval = SCSA2USB_JUST_ACCEPT;
3284 		}
3285 		break;
3286 	default:
3287 		break;
3288 	}
3289 
3290 	return (rval);
3291 }
3292 
3293 
3294 /*
3295  * scsa2usb_handle_ufi_subclass_cmd:
3296  *	prepare a UFI cmd
3297  *	returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT
3298  */
3299 int
3300 scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *scsa2usbp,
3301     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3302 {
3303 	uchar_t opcode =  pkt->pkt_cdbp[0];
3304 
3305 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3306 	    "scsa2usb_handle_ufi_subclass_cmd: cmd = 0x%p pkt = 0x%p",
3307 	    cmd, pkt);
3308 
3309 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3310 
3311 	bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3312 	cmd->cmd_cdb[SCSA2USB_OPCODE] = opcode;   /* Set the opcode */
3313 	cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3314 
3315 	/*
3316 	 * decode and convert the packet if necessary
3317 	 * for most cmds, we can bcopy the cdb
3318 	 */
3319 	switch (opcode) {
3320 	case SCMD_FORMAT:
3321 		/* if parameter list is specified */
3322 		if (pkt->pkt_cdbp[1] & 0x10) {
3323 			cmd->cmd_xfercount =
3324 				(pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3325 			cmd->cmd_dir = USB_EP_DIR_OUT;
3326 			cmd->cmd_actual_len = CDB_GROUP5;
3327 		}
3328 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3329 		break;
3330 	case SCMD_INQUIRY:
3331 		cmd->cmd_dir = USB_EP_DIR_IN;
3332 		cmd->cmd_actual_len = CDB_GROUP0;
3333 		cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3334 		cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3335 		    min(SCSA2USB_MAX_INQ_LEN,
3336 		    cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3337 		break;
3338 	case SCMD_READ_CAPACITY:
3339 		cmd->cmd_dir = USB_EP_DIR_IN;
3340 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3341 		cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3342 		break;
3343 	case SCMD_REQUEST_SENSE:
3344 		cmd->cmd_dir = USB_EP_DIR_IN;
3345 		cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3346 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3347 		cmd->cmd_actual_len = CDB_GROUP0;
3348 		break;
3349 
3350 	/*
3351 	 * do not convert SCMD_MODE_SENSE/SELECT because the
3352 	 * mode header is different as well
3353 	 */
3354 
3355 	/*
3356 	 * see usb_bulkonly.c for comments on the next set of commands
3357 	 */
3358 	case SCMD_READ:
3359 	case SCMD_WRITE:
3360 	case SCMD_READ_G1:
3361 	case SCMD_WRITE_G1:
3362 	case SCMD_READ_G5:
3363 	case SCMD_WRITE_G5:
3364 	case SCMD_READ_LONG:
3365 	case SCMD_WRITE_LONG:
3366 	case SCMD_READ_CD:
3367 
3368 		return (scsa2usb_rw_transport(scsa2usbp, pkt));
3369 
3370 	case SCMD_TEST_UNIT_READY:
3371 		/*
3372 		 * Some CB/CBI devices may not support TUR.
3373 		 */
3374 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3375 		break;
3376 	case SCMD_READ_FORMAT_CAP:
3377 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3378 		cmd->cmd_dir = USB_EP_DIR_IN;
3379 		cmd->cmd_actual_len = CDB_GROUP1;
3380 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3381 		break;
3382 	case SCMD_WRITE_VERIFY:
3383 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3384 		cmd->cmd_dir = USB_EP_DIR_OUT;
3385 		cmd->cmd_actual_len = CDB_GROUP1;
3386 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3387 		break;
3388 	case SCMD_START_STOP:
3389 		/* A larger timeout is needed for 'flaky' CD-RW devices */
3390 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_BIG_TIMEOUT)) {
3391 			cmd->cmd_timeout = max(cmd->cmd_timeout,
3392 					20 * SCSA2USB_BULK_PIPE_TIMEOUT);
3393 		}
3394 		/* FALLTHRU */
3395 	default:
3396 		/*
3397 		 * all other commands don't need special mapping
3398 		 */
3399 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3400 		if (cmd->cmd_bp) {
3401 			cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3402 						CBW_DIR_IN : CBW_DIR_OUT;
3403 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3404 		}
3405 		break;
3406 
3407 	} /* end of switch */
3408 
3409 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3410 	    "scsa2usb_handle_ufi_subclass_cmd: opcode = 0x%x count = 0x%lx",
3411 	    opcode, cmd->cmd_xfercount);
3412 
3413 	cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3414 
3415 	return (SCSA2USB_TRANSPORT);
3416 }
3417 
3418 
3419 /*
3420  * scsa2usb_rw_transport:
3421  *	Handle splitting READ and WRITE requests to the
3422  *	device to a size that the host controller allows.
3423  *
3424  *	returns TRAN_* values and not USB_SUCCESS/FAILURE
3425  *
3426  * To support CD-R/CD-RW/DVD media, we need to support a
3427  * variety of block sizes for the different types of CD
3428  * data (audio, data, video, CD-XA, yellowbook, redbook etc.)
3429  *
3430  * Some of the block sizes used are:- 512, 1k, 2k, 2056, 2336
3431  * 2340, 2352, 2368, 2448, 2646, 2647 etc.
3432  *
3433  * NOTE: the driver could be entertaining a SCSI CDB that uses
3434  * any of the above listed block sizes at a given time, and a
3435  * totally different block size at any other given time for a
3436  * different CDB.
3437  *
3438  * We need to compute block size every time and figure out
3439  * matching LBA and LEN accordingly.
3440  *
3441  * Also UHCI has a limitation that it can only xfer 32k at a
3442  * given time. So, with "odd" sized blocks and a limitation of
3443  * how much we can xfer per shot, we need to compute xfer_count
3444  * as well each time.
3445  *
3446  * The same computation is also done in the function
3447  * scsa2usb_setup_next_xfer().	To save computing block_size in
3448  * this function, I am saving block_size in "cmd" now.
3449  */
3450 int
3451 scsa2usb_rw_transport(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
3452 {
3453 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
3454 	int lba, dir, opcode;
3455 	struct buf *bp = cmd->cmd_bp;
3456 	size_t len, xfer_count;
3457 	size_t blk_size;	/* calculate the block size to be used */
3458 	int sz;
3459 
3460 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3461 	    "scsa2usb_rw_transport:");
3462 
3463 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3464 
3465 	opcode = pkt->pkt_cdbp[0];
3466 	blk_size  = scsa2usbp->scsa2usb_lbasize[pkt->pkt_address.a_lun];
3467 						/* set to default */
3468 
3469 	switch (opcode) {
3470 	case SCMD_READ:
3471 		/*
3472 		 * Note that READ/WRITE(6) are not supported by the drive.
3473 		 * convert it into a 10 byte read/write.
3474 		 */
3475 		lba = SCSA2USB_LBA_6BYTE(pkt);
3476 		len = SCSA2USB_LEN_6BYTE(pkt);
3477 		opcode = SCMD_READ_G1;	/* Overwrite it w/ byte 10 cmd val */
3478 		dir = USB_EP_DIR_IN;
3479 		break;
3480 	case SCMD_WRITE:
3481 		lba = SCSA2USB_LBA_6BYTE(pkt);
3482 		len = SCSA2USB_LEN_6BYTE(pkt);
3483 		opcode = SCMD_WRITE_G1;	/* Overwrite it w/ byte 10 cmd val */
3484 		dir = USB_EP_DIR_OUT;
3485 		break;
3486 	case SCMD_READ_G1:
3487 	case SCMD_READ_LONG:
3488 		lba = SCSA2USB_LBA_10BYTE(pkt);
3489 		len = SCSA2USB_LEN_10BYTE(pkt);
3490 		dir = USB_EP_DIR_IN;
3491 		break;
3492 	case SCMD_WRITE_G1:
3493 	case SCMD_WRITE_LONG:
3494 		lba = SCSA2USB_LBA_10BYTE(pkt);
3495 		len = SCSA2USB_LEN_10BYTE(pkt);
3496 		dir = USB_EP_DIR_OUT;
3497 		if (len) {
3498 			sz = SCSA2USB_CDRW_BLKSZ(bp ? bp->b_bcount : 0, len);
3499 			if (SCSA2USB_VALID_CDRW_BLKSZ(sz)) {
3500 				blk_size = sz;	/* change it accordingly */
3501 			}
3502 		}
3503 		break;
3504 	case SCMD_READ_CD:
3505 		lba = SCSA2USB_LBA_10BYTE(pkt);
3506 		len = SCSA2USB_LEN_READ_CD(pkt);
3507 		dir = USB_EP_DIR_IN;
3508 
3509 		/* Figure out the block size */
3510 		blk_size = scsa2usb_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2);
3511 		break;
3512 	case SCMD_READ_G5:
3513 		lba = SCSA2USB_LBA_12BYTE(pkt);
3514 		len = SCSA2USB_LEN_12BYTE(pkt);
3515 		dir = USB_EP_DIR_IN;
3516 		break;
3517 	case SCMD_WRITE_G5:
3518 		lba = SCSA2USB_LBA_12BYTE(pkt);
3519 		len = SCSA2USB_LEN_12BYTE(pkt);
3520 		dir = USB_EP_DIR_OUT;
3521 		break;
3522 	}
3523 
3524 	cmd->cmd_total_xfercount = xfer_count = len * blk_size;
3525 
3526 	/* reduce xfer count if necessary */
3527 	if (blk_size &&
3528 	    (xfer_count > scsa2usbp->scsa2usb_max_bulk_xfer_size)) {
3529 		/*
3530 		 * For CD-RW devices reduce the xfer count based
3531 		 * on the block size used by these devices. The
3532 		 * block size could change for READ_CD and WRITE
3533 		 * opcodes.
3534 		 *
3535 		 * Also as UHCI allows a max xfer of 32k at a time;
3536 		 * compute the xfer_count based on the new block_size.
3537 		 *
3538 		 * The len part of the cdb changes as a result of that.
3539 		 */
3540 		if (SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3541 			xfer_count = ((scsa2usbp->scsa2usb_max_bulk_xfer_size/
3542 					blk_size) * blk_size);
3543 			len = xfer_count/blk_size;
3544 			xfer_count = blk_size * len;
3545 		} else {
3546 			xfer_count = scsa2usbp->scsa2usb_max_bulk_xfer_size;
3547 			len = xfer_count/blk_size;
3548 		}
3549 	}
3550 
3551 	cmd->cmd_xfercount = xfer_count;
3552 	cmd->cmd_dir = (uchar_t)dir;
3553 	cmd->cmd_blksize = blk_size;
3554 
3555 	/*
3556 	 * Having figure out the 'partial' xfer len based on he
3557 	 * block size; fill it in to the cmd->cmd_cdb
3558 	 */
3559 	cmd->cmd_cdb[SCSA2USB_OPCODE] = (uchar_t)opcode;
3560 	switch (opcode) {
3561 	case SCMD_READ_CD:
3562 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3563 		scsa2usb_fill_up_ReadCD_cdb_len(cmd, len, CDB_GROUP5);
3564 		break;
3565 	case SCMD_WRITE_G5:
3566 	case SCMD_READ_G5:
3567 		scsa2usb_fill_up_12byte_cdb_len(cmd, len, CDB_GROUP5);
3568 		break;
3569 	default:
3570 		scsa2usb_fill_up_cdb_len(cmd, len);
3571 		cmd->cmd_actual_len = CDB_GROUP1;
3572 		break;
3573 	}
3574 
3575 	scsa2usb_fill_up_cdb_lba(cmd, lba);
3576 
3577 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3578 	    "bcount=0x%lx lba=0x%x len=0x%lx xfercount=0x%lx total=0x%lx",
3579 	    bp ? bp->b_bcount : 0, lba, len, cmd->cmd_xfercount,
3580 	    cmd->cmd_total_xfercount);
3581 
3582 	/* Set the timeout value as per command request */
3583 	if ((opcode == SCMD_WRITE_G1) && SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3584 		/*
3585 		 * We increase the time as CD-RW writes have two things
3586 		 * to do. After writing out the data to the media, a
3587 		 * TOC needs to be filled up at the beginning of the media
3588 		 * This is when the write gets "finalized".
3589 		 * Hence the actual write could take longer than the
3590 		 * value specified in cmd->cmd_timeout.
3591 		 */
3592 		cmd->cmd_timeout *= 4;
3593 
3594 		USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3595 		    scsa2usbp->scsa2usb_log_handle,
3596 		    "new timeout value = 0x%x", cmd->cmd_timeout);
3597 	}
3598 
3599 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3600 	    "lba 0x%x len 0x%lx xfercount 0x%lx total 0x%lx",
3601 	    lba, len, cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3602 
3603 	return (SCSA2USB_TRANSPORT);
3604 }
3605 
3606 
3607 /*
3608  * scsa2usb_setup_next_xfer:
3609  *	For READs and WRITEs we split up the transfer in terms of
3610  *	HCD understood units. This function handles the split transfers.
3611  *
3612  * See comments in the previous function scsa2usb_rw_transport
3613  *
3614  * The lba computation was being done based on scsa2usb_max_bulk_xfer_size
3615  * earlier. With CD-RW devices, the xfer_count and the block_size may
3616  * no longer be a multiple of scsa2usb_max_bulk_xfer_size. So compute
3617  * xfer_count all over again. Adjust lba, based on the previous requests'
3618  * len. Find out the len and add it to cmd->cmd_lba to get the new lba
3619  */
3620 void
3621 scsa2usb_setup_next_xfer(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3622 {
3623 	int xfer_len = min(scsa2usbp->scsa2usb_max_bulk_xfer_size,
3624 			cmd->cmd_total_xfercount);
3625 	int cdb_len;
3626 	size_t blk_size;
3627 
3628 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3629 
3630 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3631 	    "scsa2usb_setup_next_xfer: opcode = 0x%x lba = 0x%x "
3632 	    "total count = 0x%lx", cmd->cmd_cdb[SCSA2USB_OPCODE],
3633 	    cmd->cmd_lba, cmd->cmd_total_xfercount);
3634 
3635 	ASSERT(cmd->cmd_total_xfercount > 0);
3636 	cmd->cmd_xfercount = xfer_len;
3637 	blk_size = scsa2usbp->scsa2usb_lbasize[
3638 				cmd->cmd_pkt->pkt_address.a_lun];
3639 
3640 	/*
3641 	 * For CD-RW devices reduce the xfer count based on the
3642 	 * block_size used by these devices. See changes below
3643 	 * where xfer_count is being adjusted.
3644 	 *
3645 	 * Also adjust len/lba based on the block_size and xfer_count.
3646 	 * NOTE: Always calculate lba first, as it based on previous
3647 	 * commands' values.
3648 	 */
3649 	switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
3650 	case SCMD_READ_CD:
3651 		/* calculate lba = current_lba + len_of_prev_cmd */
3652 		cmd->cmd_lba += (cmd->cmd_cdb[6] << 16) +
3653 		    (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
3654 		cdb_len = xfer_len/cmd->cmd_blksize;
3655 		cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)cdb_len;
3656 		/* re-adjust xfer count */
3657 		cmd->cmd_xfercount = cdb_len * cmd->cmd_blksize;
3658 		break;
3659 	case SCMD_WRITE_G5:
3660 	case SCMD_READ_G5:
3661 		/* calculate lba = current_lba + len_of_prev_cmd */
3662 		cmd->cmd_lba += (cmd->cmd_cdb[6] << 24) +
3663 		    (cmd->cmd_cdb[7] << 16) + (cmd->cmd_cdb[8] << 8) +
3664 		    cmd->cmd_cdb[9];
3665 		if (blk_size) {
3666 			xfer_len /= blk_size;
3667 		}
3668 		scsa2usb_fill_up_12byte_cdb_len(cmd, xfer_len, CDB_GROUP5);
3669 		break;
3670 	case SCMD_WRITE_G1:
3671 	case SCMD_WRITE_LONG:
3672 		/* calculate lba = current_lba + len_of_prev_cmd */
3673 		cmd->cmd_lba += (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
3674 		if (SCSA2USB_VALID_CDRW_BLKSZ(cmd->cmd_blksize)) {
3675 			blk_size = cmd->cmd_blksize;
3676 		}
3677 		cdb_len = xfer_len/blk_size;
3678 		scsa2usb_fill_up_cdb_len(cmd, cdb_len);
3679 		/* re-adjust xfer count */
3680 		cmd->cmd_xfercount = cdb_len * blk_size;
3681 		break;
3682 	default:
3683 		if (blk_size) {
3684 			xfer_len /= blk_size;
3685 		}
3686 		scsa2usb_fill_up_cdb_len(cmd, xfer_len);
3687 		cmd->cmd_lba += scsa2usbp->scsa2usb_max_bulk_xfer_size/blk_size;
3688 	}
3689 
3690 	/* fill in the lba */
3691 	scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
3692 
3693 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3694 	    "scsa2usb_setup_next_xfer:\n\tlba = 0x%x xfer_len = 0x%x "
3695 	    "xfercount = 0x%lx total = 0x%lx", cmd->cmd_lba, xfer_len,
3696 	    cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3697 }
3698 
3699 
3700 /*
3701  * take one request from the lun's waitQ and transport it
3702  */
3703 static void
3704 scsa2usb_transport_request(scsa2usb_state_t *scsa2usbp, uint_t lun)
3705 {
3706 	int			rval;
3707 	struct scsi_pkt		*pkt;
3708 	struct scsa2usb_cmd	*cmd, *arqcmd;
3709 
3710 	if ((cmd = (scsa2usb_cmd_t *)
3711 	    usba_rm_first_pvt_from_list(
3712 	    &scsa2usbp->scsa2usb_waitQ[lun])) == NULL) {
3713 
3714 		return;
3715 	}
3716 	pkt = cmd->cmd_pkt;
3717 
3718 	/*
3719 	 * if device has been disconnected, just complete it
3720 	 */
3721 	if (scsa2usbp->scsa2usb_dev_state == USB_DEV_DISCONNECTED) {
3722 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3723 		    "device not accessible");
3724 		pkt->pkt_reason = CMD_DEV_GONE;
3725 		SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3726 		scsa2usb_pkt_completion(scsa2usbp, pkt);
3727 
3728 		return;
3729 	}
3730 
3731 	USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3732 	    scsa2usbp->scsa2usb_log_handle,
3733 	    "scsa2usb_transport_request: cmd=0x%p bp=0x%p addr=0x%p",
3734 	    cmd, cmd->cmd_bp,
3735 	    (cmd->cmd_bp ? cmd->cmd_bp->b_un.b_addr : NULL));
3736 
3737 	rval = scsa2usb_cmd_transport(scsa2usbp, cmd);
3738 
3739 	USB_DPRINTF_L3(DPRINT_MASK_SCSA,
3740 	    scsa2usbp->scsa2usb_log_handle,
3741 	    "scsa2usb_transport_request: transport rval = %d",
3742 	    rval);
3743 
3744 	if (scsa2usbp->scsa2usb_cur_pkt == NULL) {
3745 
3746 		return;
3747 	}
3748 
3749 	ASSERT(pkt == scsa2usbp->scsa2usb_cur_pkt);
3750 
3751 	if (ddi_in_panic()) {
3752 		pkt->pkt_reason = CMD_CMPLT;
3753 		scsa2usb_pkt_completion(scsa2usbp, pkt);
3754 
3755 		return;
3756 	}
3757 
3758 	/*
3759 	 * start an auto-request sense iff
3760 	 * there was a check condition, we have enough
3761 	 * space in the status block, and we have not
3762 	 * faked an auto request sense
3763 	 */
3764 	if ((*(pkt->pkt_scbp) == STATUS_CHECK) &&
3765 	    (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) &&
3766 	    ((pkt->pkt_state & STATE_ARQ_DONE) == 0) &&
3767 	    (scsa2usb_create_arq_pkt(scsa2usbp,
3768 	    &pkt->pkt_address) == USB_SUCCESS)) {
3769 		arqcmd = scsa2usbp->scsa2usb_arq_cmd;
3770 
3771 		/*
3772 		 * copy the timeout from the
3773 		 * original packet
3774 		 * for lack of a better value
3775 		 */
3776 		arqcmd->cmd_pkt->pkt_time = pkt->pkt_time;
3777 		scsa2usb_prepare_pkt(scsa2usbp,
3778 			    arqcmd->cmd_pkt);
3779 
3780 		scsa2usbp->scsa2usb_cur_pkt = NULL;
3781 		if (scsa2usb_cmd_transport(
3782 		    scsa2usbp, arqcmd) == TRAN_ACCEPT) {
3783 
3784 			/* finish w/ this packet */
3785 			scsa2usb_complete_arq_pkt(
3786 			    scsa2usbp, arqcmd->cmd_pkt, cmd,
3787 			    scsa2usbp->scsa2usb_arq_bp);
3788 
3789 			/*
3790 			 * we have valid request sense
3791 			 * data so clear the pkt_reason
3792 			 */
3793 			pkt->pkt_reason = CMD_CMPLT;
3794 		}
3795 		scsa2usbp->scsa2usb_cur_pkt = pkt;
3796 		scsa2usb_delete_arq_pkt(scsa2usbp);
3797 	}
3798 
3799 	if ((rval != TRAN_ACCEPT) &&
3800 	    (pkt->pkt_reason == CMD_CMPLT)) {
3801 		pkt->pkt_reason = CMD_TRAN_ERR;
3802 	}
3803 
3804 	SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3805 	scsa2usb_pkt_completion(scsa2usbp, pkt);
3806 
3807 	ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
3808 }
3809 
3810 
3811 /*
3812  * scsa2usb_work_thread:
3813  *	The taskq thread that kicks off the transport (BO and CB/CBI)
3814  */
3815 static void
3816 scsa2usb_work_thread(void *arg)
3817 {
3818 	scsa2usb_state_t	*scsa2usbp = (scsa2usb_state_t *)arg;
3819 	uint_t			lun;
3820 	uint_t			count;
3821 
3822 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3823 	    "scsa2usb_work_thread:");
3824 
3825 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3826 	ASSERT(scsa2usbp->scsa2usb_work_thread_id == (kthread_t *)1);
3827 	scsa2usbp->scsa2usb_work_thread_id = curthread;
3828 
3829 	/* exclude ugen accesses */
3830 	while (scsa2usbp->scsa2usb_transport_busy) {
3831 		cv_wait(&scsa2usbp->scsa2usb_transport_busy_cv,
3832 		    &scsa2usbp->scsa2usb_mutex);
3833 	}
3834 	ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
3835 	scsa2usbp->scsa2usb_transport_busy++;
3836 	scsa2usbp->scsa2usb_busy_thread = curthread;
3837 
3838 	scsa2usb_raise_power(scsa2usbp);
3839 
3840 	/* reopen the pipes if necessary */
3841 	(void) scsa2usb_open_usb_pipes(scsa2usbp);
3842 
3843 	for (;;) {
3844 		ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
3845 		for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
3846 			scsa2usb_transport_request(scsa2usbp, lun);
3847 		}
3848 		count = 0;
3849 		for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
3850 			count += usba_list_entry_count(
3851 				&scsa2usbp->scsa2usb_waitQ[lun]);
3852 		}
3853 
3854 		if (count == 0) {
3855 
3856 			break;
3857 		}
3858 	}
3859 
3860 	scsa2usb_pm_idle_component(scsa2usbp);
3861 
3862 	scsa2usbp->scsa2usb_work_thread_id = 0;
3863 
3864 	ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
3865 
3866 	scsa2usbp->scsa2usb_transport_busy--;
3867 	scsa2usbp->scsa2usb_busy_thread = NULL;
3868 	cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
3869 
3870 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3871 
3872 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3873 	    "scsa2usb_work_thread: exit");
3874 }
3875 
3876 
3877 /*
3878  * scsa2usb_flush_waitQ:
3879  *	empties the entire waitQ with errors asap.
3880  *
3881  * It is called from scsa2usb_scsi_reset and scsa2usb_panic_callb.
3882  * If the device is reset; we should empty the waitQ right away.
3883  * If the system has paniced; we should empty the waitQ right away.
3884  *
3885  * CPR suspend will only succeed if device is idle. No need to call
3886  * this function for CPR suspend case.
3887  */
3888 static void
3889 scsa2usb_flush_waitQ(scsa2usb_state_t *scsa2usbp, uint_t lun,
3890     uchar_t error)
3891 {
3892 	struct scsi_pkt		*pkt;
3893 	struct scsa2usb_cmd	*cmd;
3894 	usba_list_entry_t	head;
3895 
3896 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3897 
3898 	usba_move_list(&scsa2usbp->scsa2usb_waitQ[lun], &head,
3899 	    scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
3900 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3901 
3902 	while ((cmd = (scsa2usb_cmd_t *)usba_rm_first_pvt_from_list(&head)) !=
3903 	    NULL) {
3904 		pkt = cmd->cmd_pkt;
3905 		pkt->pkt_reason = error;	/* set error */
3906 
3907 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3908 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP;
3909 		scsa2usb_pkt_completion(scsa2usbp, pkt);
3910 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
3911 	} /* end of while */
3912 }
3913 
3914 
3915 /*
3916  * scsa2usb_do_inquiry is performed before INIT CHILD and we have
3917  * to fake a few things normally done by SCSA
3918  */
3919 static void
3920 scsa2usb_do_inquiry(scsa2usb_state_t *scsa2usbp, uint_t target, uint_t lun)
3921 {
3922 	struct buf	*bp;
3923 	struct scsi_pkt *pkt;
3924 	struct scsi_address ap;
3925 	int		len = SCSA2USB_MAX_INQ_LEN;
3926 
3927 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3928 	    "scsa2usb_do_inquiry: %d bytes", len);
3929 
3930 	/* is it inquiry-challenged? */
3931 	if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3932 		(void) scsa2usb_fake_inquiry(scsa2usbp, NULL, lun);
3933 
3934 		return;
3935 	}
3936 
3937 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3938 
3939 	bzero(&ap, sizeof (struct scsi_address));
3940 	ap.a_hba_tran = scsa2usbp->scsa2usb_tran;
3941 	ap.a_target = target;
3942 	ap.a_lun = lun;
3943 
3944 	/* limit inquiry to 36 bytes */
3945 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3946 	if ((bp = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
3947 	    len, B_READ, SLEEP_FUNC, NULL)) == NULL) {
3948 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3949 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3950 		    scsa2usbp->scsa2usb_log_handle,
3951 		    "scsa2usb_do_inquiry: failed");
3952 
3953 		return;
3954 	}
3955 
3956 	pkt = scsi_init_pkt(&ap, NULL, bp, CDB_GROUP0, 1,
3957 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL);
3958 
3959 	RQ_MAKECOM_G0(pkt, FLAG_NOINTR, (char)SCMD_INQUIRY, 0, len);
3960 
3961 	pkt->pkt_comp = NULL;
3962 	pkt->pkt_time = 5;
3963 	bzero(bp->b_un.b_addr, len);
3964 
3965 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3966 	    "scsa2usb_do_inquiry:INQUIRY");
3967 
3968 	(void) scsi_transport(pkt);
3969 
3970 	if (pkt->pkt_reason) {
3971 		USB_DPRINTF_L0(DPRINT_MASK_SCSA,
3972 		    scsa2usbp->scsa2usb_log_handle,
3973 		    "INQUIRY failed, cannot determine device type, "
3974 		    "pkt_reason=0x%x", pkt->pkt_reason);
3975 
3976 		/* not much hope for other cmds, reduce */
3977 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3978 		scsa2usbp->scsa2usb_attrs &=
3979 					~SCSA2USB_ATTRS_REDUCED_CMD;
3980 		(void) scsa2usb_fake_inquiry(scsa2usbp, NULL, lun);
3981 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
3982 	}
3983 
3984 	scsi_destroy_pkt(pkt);
3985 	scsi_free_consistent_buf(bp);
3986 
3987 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3988 }
3989 
3990 
3991 /*
3992  * scsa2usb_fake_inquiry:
3993  *    build an inquiry for a given device that doesnt like inquiry
3994  *    commands.
3995  */
3996 static int
3997 scsa2usb_fake_inquiry(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd,
3998     uint_t lun)
3999 {
4000 	usb_client_dev_data_t *dev_data = scsa2usbp->scsa2usb_dev_data;
4001 	struct scsi_inquiry *inqp;
4002 	int len;
4003 
4004 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4005 	    "scsa2usb_fake_inquiry:");
4006 
4007 	if (cmd) {
4008 		inqp = (struct scsi_inquiry *)cmd->cmd_bp->b_un.b_addr;
4009 	} else {
4010 		inqp = &scsa2usbp->scsa2usb_lun_inquiry[lun];
4011 	}
4012 	bzero(inqp, sizeof (struct scsi_inquiry));
4013 	for (len = 0; len < sizeof (inqp->inq_vid); len++) {
4014 		*(inqp->inq_vid + len) = ' ';
4015 	}
4016 
4017 	for (len = 0; len < sizeof (inqp->inq_pid); len++) {
4018 		*(inqp->inq_pid + len) = ' ';
4019 	}
4020 
4021 	inqp->inq_dtype = DTYPE_DIRECT;
4022 	inqp->inq_rmb = 1;
4023 	inqp->inq_ansi = 2;
4024 	inqp->inq_rdf = RDF_SCSI2;
4025 	inqp->inq_len = sizeof (struct scsi_inquiry)-4;
4026 
4027 	/* Fill in the Vendor id/Product id strings */
4028 	if (dev_data->dev_mfg) {
4029 		if ((len = strlen(dev_data->dev_mfg)) >
4030 		    sizeof (inqp->inq_vid)) {
4031 			len = sizeof (inqp->inq_vid);
4032 		}
4033 		bcopy(dev_data->dev_mfg, inqp->inq_vid, len);
4034 	}
4035 
4036 	if (dev_data->dev_product) {
4037 		if ((len = strlen(dev_data->dev_product)) >
4038 		    sizeof (inqp->inq_pid)) {
4039 			len = sizeof (inqp->inq_pid);
4040 		}
4041 		bcopy(dev_data->dev_product, inqp->inq_pid, len);
4042 	}
4043 
4044 	/* Set the Revision to the Device */
4045 	inqp->inq_revision[0] = 0x30 +
4046 		((dev_data->dev_descr->bcdDevice>>12) & 0xF);
4047 	inqp->inq_revision[1] = 0x30 +
4048 		((dev_data->dev_descr->bcdDevice>>8) & 0xF);
4049 	inqp->inq_revision[2] = 0x30 +
4050 		((dev_data->dev_descr->bcdDevice>>4) & 0xF);
4051 	inqp->inq_revision[3] = 0x30 +
4052 		((dev_data->dev_descr->bcdDevice) & 0xF);
4053 
4054 	/* Copy inquiry data in to soft state */
4055 	bcopy(inqp, &scsa2usbp->scsa2usb_lun_inquiry[lun],
4056 	    sizeof (struct scsi_inquiry));
4057 
4058 	return (sizeof (struct scsi_inquiry));
4059 }
4060 
4061 
4062 /*
4063  * scsa2usb_create_arq_pkt:
4064  *	Create and ARQ packet to get request sense data
4065  */
4066 static int
4067 scsa2usb_create_arq_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
4068 {
4069 	struct buf *bp;
4070 	scsa2usb_cmd_t *arq_cmd;
4071 
4072 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4073 	    "scsa2usb_create_arq_pkt: scsa2usbp: %p, ap: %p", scsa2usbp, ap);
4074 
4075 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4076 
4077 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4078 	if ((bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL,
4079 	    SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4080 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4081 
4082 		return (USB_FAILURE);
4083 	}
4084 
4085 	arq_cmd = PKT2CMD(scsi_init_pkt(ap, NULL, bp, CDB_GROUP0, 1,
4086 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL));
4087 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4088 
4089 	RQ_MAKECOM_G0(arq_cmd->cmd_pkt,
4090 	    FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON,
4091 	    (char)SCMD_REQUEST_SENSE, 0, (char)SENSE_LENGTH);
4092 
4093 	arq_cmd->cmd_pkt->pkt_ha_private = arq_cmd;
4094 	scsa2usbp->scsa2usb_arq_cmd = arq_cmd;
4095 	scsa2usbp->scsa2usb_arq_bp = bp;
4096 	arq_cmd->cmd_pkt->pkt_comp = NULL;
4097 	bzero(bp->b_un.b_addr, SENSE_LENGTH);
4098 
4099 	return (USB_SUCCESS);
4100 }
4101 
4102 
4103 /*
4104  * scsa2usb_delete_arq_pkt:
4105  *	Destroy the ARQ packet
4106  */
4107 static void
4108 scsa2usb_delete_arq_pkt(scsa2usb_state_t *scsa2usbp)
4109 {
4110 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4111 	    "scsa2usb_delete_arq_pkt: cmd: 0x%p", scsa2usbp->scsa2usb_arq_cmd);
4112 
4113 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4114 
4115 	if (scsa2usbp->scsa2usb_arq_cmd != NULL) {
4116 		scsi_destroy_pkt(scsa2usbp->scsa2usb_arq_cmd->cmd_pkt);
4117 		scsi_free_consistent_buf(scsa2usbp->scsa2usb_arq_bp);
4118 	}
4119 	scsa2usbp->scsa2usb_arq_cmd = NULL;
4120 	scsa2usbp->scsa2usb_arq_bp = NULL;
4121 }
4122 
4123 
4124 /*
4125  * scsa2usb_complete_arq_pkt:
4126  *	finish processing the arq packet
4127  */
4128 static void
4129 scsa2usb_complete_arq_pkt(scsa2usb_state_t *scsa2usbp,
4130     struct scsi_pkt *pkt, scsa2usb_cmd_t *ssp, struct buf *bp)
4131 {
4132 	scsa2usb_cmd_t		*sp = pkt->pkt_ha_private;
4133 	struct scsi_arq_status	*arqp;
4134 
4135 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4136 
4137 	arqp = (struct scsi_arq_status *)(ssp->cmd_pkt->pkt_scbp);
4138 	arqp->sts_rqpkt_status = *((struct scsi_status *)
4139 		(sp->cmd_pkt->pkt_scbp));
4140 	arqp->sts_rqpkt_reason = CMD_CMPLT;
4141 	arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
4142 	arqp->sts_rqpkt_statistics = arqp->sts_rqpkt_resid = 0;
4143 
4144 	/* is this meaningful sense data */
4145 	if (*(bp->b_un.b_addr) != 0) {
4146 		bcopy(bp->b_un.b_addr, &arqp->sts_sensedata, sp->cmd_scblen);
4147 		ssp->cmd_pkt->pkt_state |= STATE_ARQ_DONE;
4148 	}
4149 
4150 	/* we will not sense start cmd until we receive a NOT READY */
4151 	if (arqp->sts_sensedata.es_key == KEY_NOT_READY) {
4152 		scsa2usbp->scsa2usb_rcvd_not_ready = B_TRUE;
4153 	}
4154 }
4155 
4156 
4157 /*
4158  * Miscellaneous functions for any command/transport
4159  */
4160 /*
4161  * scsa2usb_open_usb_pipes:
4162  *	set up a pipe policy
4163  *	open usb bulk pipes (BO and CB/CBI)
4164  *	open usb interrupt pipe (CBI)
4165  */
4166 static int
4167 scsa2usb_open_usb_pipes(scsa2usb_state_t *scsa2usbp)
4168 {
4169 	int			rval;
4170 	usb_pipe_policy_t	policy;	/* bulk pipe policy */
4171 	size_t			sz;
4172 
4173 	ASSERT(scsa2usbp);
4174 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4175 
4176 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4177 	    "scsa2usb_open_usb_pipes: dip = 0x%p flag = 0x%x",
4178 	    scsa2usbp->scsa2usb_dip, scsa2usbp->scsa2usb_flags);
4179 
4180 	if (!(scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED)) {
4181 
4182 		/*
4183 		 * one pipe policy for all bulk pipes
4184 		 */
4185 		bzero(&policy, sizeof (usb_pipe_policy_t));
4186 		/* at least 2, for the normal and exceptional callbacks */
4187 		policy.pp_max_async_reqs = 1;
4188 
4189 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4190 		    "scsa2usb_open_usb_pipes: opening bulk pipes");
4191 
4192 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4193 
4194 		/* Open the USB bulk-in pipe */
4195 		if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4196 		    &scsa2usbp->scsa2usb_bulkin_ept, &policy, USB_FLAGS_SLEEP,
4197 		    &scsa2usbp->scsa2usb_bulkin_pipe)) != USB_SUCCESS) {
4198 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4199 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4200 			    scsa2usbp->scsa2usb_log_handle,
4201 			    "scsa2usb_open_usb_pipes: bulk/in pipe open "
4202 			    " failed rval = %d", rval);
4203 
4204 			return (USB_FAILURE);
4205 		}
4206 
4207 		/* Open the bulk-out pipe  using the same policy */
4208 		if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4209 		    &scsa2usbp->scsa2usb_bulkout_ept, &policy, USB_FLAGS_SLEEP,
4210 		    &scsa2usbp->scsa2usb_bulkout_pipe)) != USB_SUCCESS) {
4211 			usb_pipe_close(scsa2usbp->scsa2usb_dip,
4212 			    scsa2usbp->scsa2usb_bulkin_pipe,
4213 			    USB_FLAGS_SLEEP, NULL, NULL);
4214 
4215 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4216 			scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4217 
4218 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4219 			    scsa2usbp->scsa2usb_log_handle,
4220 			    "scsa2usb_open_usb_pipes: bulk/out pipe open"
4221 			    " failed rval = %d", rval);
4222 
4223 			return (USB_FAILURE);
4224 		}
4225 
4226 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4227 
4228 		/* open interrupt pipe for CBI protocol */
4229 		if (SCSA2USB_IS_CBI(scsa2usbp)) {
4230 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4231 
4232 			if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4233 			    &scsa2usbp->scsa2usb_intr_ept, &policy,
4234 			    USB_FLAGS_SLEEP, &scsa2usbp->scsa2usb_intr_pipe)) !=
4235 			    USB_SUCCESS) {
4236 				usb_pipe_close(scsa2usbp->scsa2usb_dip,
4237 				    scsa2usbp->scsa2usb_bulkin_pipe,
4238 				    USB_FLAGS_SLEEP, NULL, NULL);
4239 
4240 				usb_pipe_close(scsa2usbp->scsa2usb_dip,
4241 				    scsa2usbp->scsa2usb_bulkout_pipe,
4242 				    USB_FLAGS_SLEEP, NULL, NULL);
4243 
4244 				mutex_enter(&scsa2usbp->scsa2usb_mutex);
4245 				scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4246 				scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4247 
4248 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4249 				    scsa2usbp->scsa2usb_log_handle,
4250 				    "scsa2usb_open_usb_pipes: intr pipe open"
4251 				    " failed rval = %d", rval);
4252 
4253 				return (USB_FAILURE);
4254 			}
4255 
4256 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4257 		}
4258 
4259 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4260 
4261 		/* get the max transfer size of the bulk pipe */
4262 		if (usb_pipe_get_max_bulk_transfer_size(scsa2usbp->scsa2usb_dip,
4263 		    &sz) == USB_SUCCESS) {
4264 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4265 			scsa2usbp->scsa2usb_max_bulk_xfer_size = sz;
4266 		} else {
4267 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4268 			scsa2usbp->scsa2usb_max_bulk_xfer_size = DEV_BSIZE;
4269 		}
4270 
4271 		/* limit the xfer size */
4272 		scsa2usbp->scsa2usb_max_bulk_xfer_size = min(
4273 			scsa2usbp->scsa2usb_max_bulk_xfer_size,
4274 			scsa2usb_max_bulk_xfer_size);
4275 
4276 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4277 		    "scsa2usb_open_usb_pipes: max bulk transfer size = %lx",
4278 		    scsa2usbp->scsa2usb_max_bulk_xfer_size);
4279 
4280 		/* Set the pipes opened flag */
4281 		scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_PIPES_OPENED;
4282 
4283 		scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4284 
4285 		/* Set the state to NONE */
4286 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4287 	}
4288 
4289 	return (USB_SUCCESS);
4290 }
4291 
4292 
4293 /*
4294  * scsa2usb_close_usb_pipes:
4295  *	close all pipes synchronously
4296  */
4297 void
4298 scsa2usb_close_usb_pipes(scsa2usb_state_t *scsa2usbp)
4299 {
4300 	usb_flags_t flags = USB_FLAGS_SLEEP;
4301 
4302 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4303 	    "scsa2usb_close_usb_pipes: scsa2usb_state = 0x%p", scsa2usbp);
4304 
4305 	ASSERT(scsa2usbp);
4306 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4307 
4308 	if ((scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED) == 0) {
4309 
4310 		return;
4311 	}
4312 
4313 	scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_CLOSING;
4314 	/* to avoid races, reset the flag first */
4315 	scsa2usbp->scsa2usb_flags &= ~SCSA2USB_FLAGS_PIPES_OPENED;
4316 
4317 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4318 
4319 	usb_pipe_close(scsa2usbp->scsa2usb_dip,
4320 	    scsa2usbp->scsa2usb_bulkout_pipe, flags, NULL, NULL);
4321 
4322 	usb_pipe_close(scsa2usbp->scsa2usb_dip,
4323 	    scsa2usbp->scsa2usb_bulkin_pipe, flags, NULL, NULL);
4324 
4325 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4326 	if (SCSA2USB_IS_CBI(scsa2usbp)) {
4327 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4328 		usb_pipe_close(scsa2usbp->scsa2usb_dip,
4329 		    scsa2usbp->scsa2usb_intr_pipe, flags, NULL, NULL);
4330 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4331 	}
4332 	scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4333 	scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4334 	scsa2usbp->scsa2usb_intr_pipe = NULL;
4335 
4336 	scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4337 }
4338 
4339 
4340 /*
4341  * scsa2usb_fill_up_cdb_lba:
4342  *	fill up command CDBs' LBA part
4343  */
4344 static void
4345 scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *cmd, int lba)
4346 {
4347 	/* zero cdb1, lba bits so they won't get copied in the new cdb */
4348 	cmd->cmd_cdb[SCSA2USB_LUN] &= 0xE0;
4349 	cmd->cmd_cdb[SCSA2USB_LBA_0] = lba >> 24;
4350 	cmd->cmd_cdb[SCSA2USB_LBA_1] = lba >> 16;
4351 	cmd->cmd_cdb[SCSA2USB_LBA_2] = lba >> 8;
4352 	cmd->cmd_cdb[SCSA2USB_LBA_3] = (uchar_t)lba;
4353 	cmd->cmd_lba = lba;
4354 }
4355 
4356 
4357 /*
4358  * scsa2usb_fill_up_ReadCD_cdb_len:
4359  *	fill up READ_CD command CDBs' len part
4360  */
4361 static void
4362 scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4363 {
4364 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_0] = len >> 16;
4365 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_1] = len >> 8;
4366 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)len;
4367 	cmd->cmd_actual_len = (uchar_t)actual_len;
4368 }
4369 
4370 
4371 /*
4372  * scsa2usb_fill_up_12byte_cdb_len:
4373  *	fill up generic 12-byte command CDBs' len part
4374  */
4375 static void
4376 scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4377 {
4378 	cmd->cmd_cdb[6] = len >> 24;
4379 	cmd->cmd_cdb[7] = len >> 16;
4380 	cmd->cmd_cdb[8] = len >> 8;
4381 	cmd->cmd_cdb[9] = (uchar_t)len;
4382 	cmd->cmd_actual_len = (uchar_t)actual_len;
4383 }
4384 
4385 
4386 /*
4387  * scsa2usb_fill_up_cdb_len:
4388  *	fill up generic 10-byte command CDBs' len part
4389  */
4390 static void
4391 scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *cmd, int len)
4392 {
4393 	cmd->cmd_cdb[SCSA2USB_LEN_0] = len >> 8;
4394 	cmd->cmd_cdb[SCSA2USB_LEN_1] = (uchar_t)len;
4395 }
4396 
4397 
4398 /*
4399  * scsa2usb_read_cd_blk_size:
4400  *	For SCMD_READ_CD opcode (0xbe). Figure out the
4401  *	block size based on expected sector type field
4402  *	definition. See MMC SCSI Specs section 6.1.15
4403  *
4404  *	Based on the value of the "expected_sector_type"
4405  *	field, the block size could be different.
4406  */
4407 static int
4408 scsa2usb_read_cd_blk_size(uchar_t expected_sector_type)
4409 {
4410 	int blk_size;
4411 
4412 	switch (expected_sector_type) {
4413 	case READ_CD_EST_CDDA:
4414 		blk_size = CDROM_BLK_2352;
4415 		break;
4416 	case READ_CD_EST_MODE2:
4417 		blk_size = CDROM_BLK_2336;
4418 		break;
4419 	case READ_CD_EST_MODE2FORM2:
4420 		blk_size = CDROM_BLK_2324;
4421 		break;
4422 	case READ_CD_EST_MODE2FORM1:
4423 	case READ_CD_EST_ALLTYPE:
4424 	case READ_CD_EST_MODE1:
4425 	default:
4426 		blk_size = CDROM_BLK_2048;
4427 	}
4428 
4429 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL, "scsa2usb_read_cd_blk_size: "
4430 	    "est = 0x%x blk_size = %d", expected_sector_type, blk_size);
4431 
4432 	return (blk_size);
4433 }
4434 
4435 
4436 /* needed for esballoc_wait() */
4437 /*ARGSUSED*/
4438 static void
4439 scsa2usb_null_free(char *arg)
4440 {
4441 }
4442 
4443 static frtn_t fr = {
4444 	scsa2usb_null_free,
4445 	NULL
4446 };
4447 
4448 
4449 /*
4450  * scsa2usb_bp_to_mblk:
4451  *	Convert a bp to mblk_t. USBA framework understands mblk_t.
4452  */
4453 static mblk_t *
4454 scsa2usb_bp_to_mblk(scsa2usb_state_t *scsa2usbp)
4455 {
4456 	size_t		size;
4457 	mblk_t		*mp;
4458 	struct buf	*bp;
4459 	scsa2usb_cmd_t	*cmd = PKT2CMD(scsa2usbp->scsa2usb_cur_pkt);
4460 
4461 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4462 	    "scsa2usb_bp_to_mblk: ");
4463 
4464 	ASSERT(scsa2usbp->scsa2usb_cur_pkt);
4465 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4466 
4467 	bp = cmd->cmd_bp;
4468 
4469 	if (bp && (bp->b_bcount > 0)) {
4470 		size = ((bp->b_bcount > cmd->cmd_xfercount) ?
4471 				cmd->cmd_xfercount : bp->b_bcount);
4472 	} else {
4473 
4474 		return (NULL);
4475 	}
4476 
4477 	mp = esballoc_wait((uchar_t *)bp->b_un.b_addr + cmd->cmd_offset,
4478 						size, BPRI_LO, &fr);
4479 
4480 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4481 	    "scsa2usb_bp_to_mblk: "
4482 	    "mp=0x%p bp=0x%p pkt=0x%p off=0x%lx sz=%lu add=0x%p", mp,
4483 	    (void *)bp, scsa2usbp->scsa2usb_cur_pkt, cmd->cmd_offset,
4484 	    bp->b_bcount - cmd->cmd_offset,
4485 	    bp->b_un.b_addr);
4486 
4487 	mp->b_wptr += size;
4488 	cmd->cmd_offset += size;
4489 
4490 	return (mp);
4491 }
4492 
4493 
4494 /*
4495  * scsa2usb_handle_data_start:
4496  *	Initiate the data xfer. It could be IN/OUT direction.
4497  *
4498  *	Data IN:
4499  *		Send out the bulk-xfer request
4500  *		if rval implies STALL
4501  *			clear endpoint stall and reset bulk-in pipe
4502  *			handle data read in so far; set cmd->cmd_done
4503  *			also adjust data xfer length accordingly
4504  *		else other error
4505  *			report back to transport
4506  *			typically transport will call reset recovery
4507  *		else (no error)
4508  *			return success
4509  *
4510  *	Data OUT:
4511  *		Send out the bulk-xfer request
4512  *		if rval implies STALL
4513  *			clear endpoint stall and reset bulk-in pipe
4514  *			adjust data xfer length
4515  *		else other error
4516  *			report back to transport
4517  *			typically transport will call reset recovery
4518  *		else (no error)
4519  *			return success
4520  *
4521  *	NOTE: We call this function only if there is xfercount.
4522  */
4523 int
4524 scsa2usb_handle_data_start(scsa2usb_state_t *scsa2usbp,
4525     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4526 {
4527 	int		rval = USB_SUCCESS;
4528 	uint_t		ept_addr;
4529 	usb_flags_t	flags = USB_FLAGS_SLEEP;
4530 #ifdef	SCSA2USB_BULK_ONLY_TEST
4531 	usb_req_attrs_t	attrs = 0;
4532 #else
4533 	usb_req_attrs_t	attrs = USB_ATTRS_SHORT_XFER_OK;
4534 #endif
4535 
4536 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4537 	    "scsa2usb_handle_data_start: BEGIN cmd = %p, req = %p", cmd, req);
4538 
4539 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4540 
4541 	switch (cmd->cmd_dir) {
4542 	case USB_EP_DIR_IN:
4543 #ifdef	SCSA2USB_BULK_ONLY_TEST
4544 		/*
4545 		 * This case occurs when the host expects to receive
4546 		 * more data than the device actually transfers. Hi > Di
4547 		 */
4548 		if (scsa2usb_test_case_5) {
4549 			usb_bulk_req_t *req2;
4550 
4551 			req->bulk_len = cmd->cmd_xfercount - 1;
4552 			req->bulk_attributes = 0;
4553 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4554 			SCSA2USB_FREE_MSG(req->bulk_data);
4555 			req->bulk_data = allocb_wait(req->bulk_len, BPRI_LO,
4556 			    STR_NOSIG, NULL);
4557 
4558 			ASSERT(req->bulk_timeout);
4559 			rval = usb_pipe_bulk_xfer(
4560 			    scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4561 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4562 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4563 			    scsa2usbp->scsa2usb_log_handle, "rval = %x", rval);
4564 
4565 			req2 = scsa2usb_init_bulk_req(scsa2usbp,
4566 			    cmd->cmd_xfercount + 2,
4567 			    cmd->cmd_timeout, 0, flags);
4568 			req2->bulk_len = cmd->cmd_xfercount + 2;
4569 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4570 
4571 			ASSERT(req2->bulk_timeout);
4572 			rval = usb_pipe_bulk_xfer(
4573 			    scsa2usbp->scsa2usb_bulkin_pipe, req2, flags);
4574 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4575 
4576 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4577 			    scsa2usbp->scsa2usb_log_handle,
4578 			    "TEST 5: Hi > Di: rval = 0x%x", rval);
4579 			scsa2usb_test_case_5 = 0;
4580 			usb_free_bulk_req(req2);
4581 
4582 			return (rval);
4583 		}
4584 
4585 		/*
4586 		 * This happens when the host expects to send data to the
4587 		 * device while the device intends to send data to the host.
4588 		 */
4589 		if (scsa2usb_test_case_8 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) {
4590 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4591 			    scsa2usbp->scsa2usb_log_handle,
4592 			    "TEST 8: Hi <> Do: Step 2");
4593 			scsa2usb_test_mblk(scsa2usbp, B_TRUE);
4594 			scsa2usb_test_case_8 = 0;
4595 
4596 			return (rval);
4597 		}
4598 #endif	/* SCSA2USB_BULK_ONLY_TEST */
4599 
4600 		ept_addr = scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress;
4601 		req->bulk_len = cmd->cmd_xfercount;
4602 		req->bulk_attributes = attrs;
4603 		SCSA2USB_FREE_MSG(req->bulk_data);
4604 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4605 
4606 		req->bulk_data = esballoc_wait(
4607 				(uchar_t *)cmd->cmd_bp->b_un.b_addr +
4608 				cmd->cmd_offset,
4609 				req->bulk_len, BPRI_LO, &fr);
4610 
4611 		ASSERT(req->bulk_timeout);
4612 		rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe,
4613 								req, flags);
4614 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4615 
4616 		break;
4617 
4618 	case USB_EP_DIR_OUT:
4619 #ifdef	SCSA2USB_BULK_ONLY_TEST
4620 		/*
4621 		 * This happens when the host expects to receive data
4622 		 * from the device while the device intends to receive
4623 		 * data from the host.
4624 		 */
4625 		if (scsa2usb_test_case_10 &&
4626 		    (cmd->cmd_cdb[0] == SCMD_WRITE_G1)) {
4627 			req->bulk_len = CSW_LEN;
4628 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4629 
4630 			ASSERT(req->bulk_timeout);
4631 			rval = usb_pipe_bulk_xfer(
4632 			    scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4633 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4634 
4635 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4636 			    scsa2usbp->scsa2usb_log_handle,
4637 			    "TEST 10: Ho <> Di: done rval = 0x%x",  rval);
4638 			scsa2usb_test_case_10 = 0;
4639 
4640 			return (rval);
4641 		}
4642 #endif	/* SCSA2USB_BULK_ONLY_TEST */
4643 
4644 		req->bulk_data = scsa2usb_bp_to_mblk(scsa2usbp);
4645 		if (req->bulk_data == NULL) {
4646 
4647 			return (USB_FAILURE);
4648 		}
4649 
4650 #ifdef	SCSA2USB_BULK_ONLY_TEST
4651 		if (scsa2usb_test_case_11) {
4652 			/*
4653 			 * Host expects to send data to the device and
4654 			 * device doesn't expect to receive any data
4655 			 */
4656 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4657 			    scsa2usbp->scsa2usb_log_handle, "TEST 11: Ho > Do");
4658 
4659 			scsa2usb_test_mblk(scsa2usbp, B_FALSE);
4660 			scsa2usb_test_case_11 = 0;
4661 		}
4662 #endif	/* SCSA2USB_BULK_ONLY_TEST */
4663 
4664 		ept_addr = scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress;
4665 		req->bulk_len = req->bulk_data->b_wptr - req->bulk_data->b_rptr;
4666 		req->bulk_timeout = scsa2usb_bulk_timeout(cmd->cmd_timeout);
4667 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4668 
4669 		ASSERT(req->bulk_timeout);
4670 		rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe,
4671 								req, flags);
4672 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4673 		break;
4674 	}
4675 
4676 	USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4677 	    scsa2usbp->scsa2usb_log_handle,
4678 	    "scsa2usb_handle_data_start: rval=%d cr=%d", rval,
4679 	    req->bulk_completion_reason);
4680 
4681 	if (rval != USB_SUCCESS) {
4682 		/* Handle Errors now */
4683 		if (req->bulk_completion_reason == USB_CR_STALL) {
4684 			if (cmd->cmd_dir == USB_EP_DIR_IN) {
4685 				(void) scsa2usb_clear_ept_stall(
4686 				    scsa2usbp, ept_addr,
4687 				    scsa2usbp-> scsa2usb_bulkin_pipe,
4688 				    "bulk-in");
4689 			} else {
4690 				(void) scsa2usb_clear_ept_stall(
4691 				    scsa2usbp, ept_addr,
4692 				    scsa2usbp-> scsa2usb_bulkout_pipe,
4693 				    "bulk-out");
4694 			}
4695 		}
4696 
4697 		/* no more data to transfer after this */
4698 		cmd->cmd_done = 1;
4699 	}
4700 
4701 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4702 	    "scsa2usb_handle_data_start: END %s data rval = %d",
4703 	    (cmd->cmd_dir == USB_EP_DIR_IN) ? "bulk-in" : "bulk-out", rval);
4704 
4705 	return (rval);
4706 }
4707 
4708 
4709 /*
4710  * scsa2usb_handle_data_done:
4711  *	This function handles the completion of the data xfer.
4712  *	It also massages the inquiry data. This function may
4713  *	also be called after a stall.
4714  */
4715 void
4716 scsa2usb_handle_data_done(scsa2usb_state_t *scsa2usbp,
4717     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4718 {
4719 	struct buf	*bp = cmd->cmd_bp;
4720 	struct scsi_pkt	*pkt = scsa2usbp->scsa2usb_cur_pkt;
4721 	mblk_t		*data = req->bulk_data;
4722 	int		len = data ? (data->b_wptr - data->b_rptr) : 0;
4723 
4724 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4725 
4726 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4727 	    "scsa2usb_handle_data_done:\n\tcmd = 0x%p data = 0x%p len = 0x%x",
4728 	    cmd, data, len);
4729 
4730 	cmd->cmd_resid_xfercount = cmd->cmd_xfercount - len;
4731 
4732 	if (len)  {
4733 		uchar_t	*p;
4734 		scsa2usb_read_cap_t *cap;
4735 
4736 		switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
4737 		case SCMD_INQUIRY:
4738 			/*
4739 			 * cache a copy of the inquiry data for our own use
4740 			 * but ensure that we have at least up to
4741 			 * inq_revision, inq_serial is not required.
4742 			 * ignore inquiry data returned for inquiry commands
4743 			 * with SCSI-3 EVPD, CmdDt bits set.
4744 			 */
4745 			if (((cmd->cmd_cdb[SCSA2USB_LUN] & 0x1f) == 0) &&
4746 			    (len >= SCSA2USB_MAX_INQ_LEN)) {
4747 				bzero(&scsa2usbp->scsa2usb_lun_inquiry
4748 				    [pkt->pkt_address.a_lun],
4749 				    sizeof (struct scsi_inquiry));
4750 				bcopy(data->b_rptr,
4751 				    &scsa2usbp->scsa2usb_lun_inquiry
4752 				    [pkt->pkt_address.a_lun], len);
4753 			}
4754 
4755 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4756 			    scsa2usbp->scsa2usb_log_handle,
4757 			    "scsi inquiry type = 0x%x",
4758 			    scsa2usbp->scsa2usb_lun_inquiry
4759 			    [pkt->pkt_address.a_lun].inq_dtype);
4760 
4761 			cmd->cmd_done = 1;
4762 			goto handle_data;
4763 
4764 		case SCMD_READ_CAPACITY:
4765 			cap = (scsa2usb_read_cap_t *)data->b_rptr;
4766 
4767 			/* Figure out the logical block size */
4768 			if ((len >= sizeof (struct scsa2usb_read_cap)) &&
4769 			    (req->bulk_completion_reason == USB_CR_OK)) {
4770 				scsa2usbp->
4771 				    scsa2usb_lbasize[pkt->pkt_address.a_lun] =
4772 				    SCSA2USB_MK_32BIT(
4773 					    cap->scsa2usb_read_cap_blen3,
4774 					    cap->scsa2usb_read_cap_blen2,
4775 					    cap->scsa2usb_read_cap_blen1,
4776 					    cap->scsa2usb_read_cap_blen0);
4777 
4778 				USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4779 				    scsa2usbp->scsa2usb_log_handle,
4780 				    "lbasize=%d", scsa2usbp->
4781 				    scsa2usb_lbasize[pkt->pkt_address.a_lun]);
4782 			}
4783 			cmd->cmd_done = 1;
4784 			goto handle_data;
4785 
4786 		case SCMD_REQUEST_SENSE:
4787 			p = data->b_rptr;
4788 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4789 			    scsa2usbp->scsa2usb_log_handle,
4790 			    "cdb: %x rqsense: "
4791 			    "%x %x %x %x %x %x %x %x %x %x\n\t"
4792 			    "%x %x %x %x %x %x %x %x %x %x",
4793 			    cmd->cmd_cdb[0],
4794 			    p[0], p[1], p[2], p[3], p[4],
4795 			    p[5], p[6], p[7], p[8], p[9],
4796 			    p[10], p[11], p[12], p[13], p[14],
4797 			    p[15], p[16], p[17], p[18], p[19]);
4798 
4799 			scsa2usbp->scsa2usb_last_cmd.status = p[2];
4800 			cmd->cmd_done = 1;
4801 			/* FALLTHROUGH */
4802 
4803 		default:
4804 handle_data:
4805 			if (bp && len && (cmd->cmd_dir == USB_EP_DIR_IN)) {
4806 				/*
4807 				 * we don't have to copy the data, the
4808 				 * data pointers for the mblk_t for
4809 				 * the bulk-in xfer points to the
4810 				 * struct buf * data.
4811 				 */
4812 				cmd->cmd_offset += len;
4813 			}
4814 
4815 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4816 			    scsa2usbp->scsa2usb_log_handle,
4817 			    "len = 0x%x total = 0x%lx",
4818 			    len, cmd->cmd_total_xfercount);
4819 
4820 			/*
4821 			 * update total_xfercount now but it may be
4822 			 * adjusted after receiving the residue
4823 			 */
4824 			cmd->cmd_total_xfercount -= len;
4825 
4826 			if ((req->bulk_completion_reason != USB_CR_OK) ||
4827 			    (cmd->cmd_resid_xfercount != 0) ||
4828 			    (cmd->cmd_total_xfercount == 0)) {
4829 				/* set pkt_resid to total to be sure */
4830 				pkt->pkt_resid = cmd->cmd_total_xfercount;
4831 				cmd->cmd_done = 1;
4832 			}
4833 
4834 			break;
4835 		}
4836 	} else {
4837 		if (cmd->cmd_dir == USB_EP_DIR_OUT) {
4838 			if (cmd->cmd_total_xfercount == 0) {
4839 				cmd->cmd_done = 1;
4840 			}
4841 		}
4842 	}
4843 }
4844 
4845 
4846 /*
4847  * scsa2usb_init_bulk_req:
4848  *	Allocate (synchronously) and fill in a bulk-request
4849  */
4850 usb_bulk_req_t *
4851 scsa2usb_init_bulk_req(scsa2usb_state_t *scsa2usbp, size_t length,
4852     uint_t timeout, usb_req_attrs_t attrs, usb_flags_t flags)
4853 {
4854 	usb_bulk_req_t	*req;
4855 
4856 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4857 
4858 	req = usb_alloc_bulk_req(scsa2usbp->scsa2usb_dip, length,
4859 	    flags | USB_FLAGS_SLEEP);
4860 
4861 	req->bulk_len = length;			/* xfer length */
4862 	req->bulk_timeout = scsa2usb_bulk_timeout(timeout); /* xfer timeout */
4863 	req->bulk_attributes = attrs;		/* xfer attrs */
4864 	req->bulk_client_private = (usb_opaque_t)scsa2usbp; /* statep */
4865 
4866 	return (req);
4867 }
4868 
4869 
4870 /*
4871  * scsa2usb_bulk_timeout:
4872  *	ensure that bulk requests do not have infinite timeout values
4873  */
4874 int
4875 scsa2usb_bulk_timeout(int timeout)
4876 {
4877 	return ((timeout == 0) ? scsa2usb_long_timeout : timeout);
4878 }
4879 
4880 
4881 /*
4882  * scsa2usb_clear_ept_stall:
4883  *	clear endpoint stall and reset pipes
4884  */
4885 int
4886 scsa2usb_clear_ept_stall(scsa2usb_state_t *scsa2usbp, uint_t ept_addr,
4887     usb_pipe_handle_t ph, char *what)
4888 {
4889 	int rval;
4890 	dev_info_t *dip = scsa2usbp->scsa2usb_dip;
4891 
4892 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4893 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
4894 
4895 		return (USB_FAILURE);
4896 	}
4897 
4898 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4899 	rval = usb_clr_feature(dip, USB_DEV_REQ_RCPT_EP, 0, ept_addr,
4900 	    USB_FLAGS_SLEEP, NULL, NULL);
4901 
4902 	usb_pipe_reset(dip, ph, USB_FLAGS_SLEEP, NULL, NULL);
4903 
4904 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4905 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4906 	    "scsa2usb_clear_ept_stall: on %s: ept = 0x%x rval = %d",
4907 	    what, ept_addr, rval);
4908 
4909 	return (rval);
4910 }
4911 
4912 
4913 /*
4914  * scsa2usb_pkt_completion:
4915  *	Handle pkt completion.
4916  */
4917 static void
4918 scsa2usb_pkt_completion(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
4919 {
4920 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
4921 
4922 	ASSERT(pkt);
4923 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4924 
4925 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4926 	    "scsa2usb_pkt_completion:\n\tscsa2usbp = 0x%p "
4927 	    "reason=%d, status=%d state=0x%x stats=0x%x resid=0x%lx",
4928 	    scsa2usbp, pkt->pkt_reason, *(pkt->pkt_scbp),
4929 	    pkt->pkt_state, pkt->pkt_statistics, pkt->pkt_resid);
4930 
4931 	if (pkt->pkt_reason == CMD_CMPLT) {
4932 		pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
4933 					STATE_SENT_CMD | STATE_GOT_STATUS;
4934 		if (cmd->cmd_xfercount) {
4935 			pkt->pkt_state |= STATE_XFERRED_DATA;
4936 		}
4937 	} else {
4938 		pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
4939 					STATE_SENT_CMD;
4940 	}
4941 
4942 	/*
4943 	 * don't zap the current state when in panic as this will
4944 	 * make debugging harder
4945 	 */
4946 	if ((scsa2usbp->scsa2usb_cur_pkt == pkt) && !ddi_in_panic()) {
4947 		SCSA2USB_RESET_CUR_PKT(scsa2usbp);
4948 
4949 		/* save the last command */
4950 		bcopy(pkt->pkt_cdbp, scsa2usbp->scsa2usb_last_cmd.cdb,
4951 		    sizeof (scsa2usbp->scsa2usb_last_cmd.cdb));
4952 
4953 		/* reset the scsa2usb_last_cmd.status value */
4954 		if ((pkt->pkt_cdbp[0] != SCMD_REQUEST_SENSE) &&
4955 		    (pkt->pkt_cdbp[0] != SCMD_INQUIRY)) {
4956 			scsa2usbp->scsa2usb_last_cmd.status = 0;
4957 		}
4958 
4959 		/*
4960 		 * set pkt state to NONE *before* calling back as the target
4961 		 * driver will immediately submit the next packet
4962 		 */
4963 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4964 	}
4965 
4966 	if (pkt->pkt_comp) {
4967 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4968 		pkt->pkt_comp(pkt);
4969 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4970 
4971 	}
4972 }
4973 
4974 
4975 /*
4976  * Even handling functions:
4977  *
4978  * scsa2usb_reconnect_event_cb:
4979  *	event handling
4980  */
4981 static int
4982 scsa2usb_reconnect_event_cb(dev_info_t *dip)
4983 {
4984 	scsa2usb_state_t *scsa2usbp =
4985 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
4986 	dev_info_t	*cdip;
4987 	int		circ;
4988 	int		rval = USB_SUCCESS;
4989 
4990 	ASSERT(scsa2usbp != NULL);
4991 
4992 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4993 	    "scsa2usb_reconnect_event_cb: dip = 0x%p", dip);
4994 
4995 	scsa2usb_restore_device_state(dip, scsa2usbp);
4996 
4997 	ndi_devi_enter(dip, &circ);
4998 	for (cdip = ddi_get_child(dip); cdip; ) {
4999 		dev_info_t *next = ddi_get_next_sibling(cdip);
5000 
5001 		mutex_enter(&DEVI(cdip)->devi_lock);
5002 		DEVI_SET_DEVICE_REINSERTED(cdip);
5003 		mutex_exit(&DEVI(cdip)->devi_lock);
5004 
5005 		cdip = next;
5006 	}
5007 	ndi_devi_exit(dip, circ);
5008 
5009 	/* stop suppressing warnings */
5010 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5011 	scsa2usbp->scsa2usb_warning_given = B_FALSE;
5012 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5013 
5014 	if (scsa2usbp->scsa2usb_ugen_hdl) {
5015 		rval = usb_ugen_reconnect_ev_cb(
5016 			scsa2usbp->scsa2usb_ugen_hdl);
5017 	}
5018 
5019 	return (rval);
5020 }
5021 
5022 
5023 /*
5024  * scsa2usb_all_waitQs_empty:
5025  *	check if all waitQs empty
5026  */
5027 static int
5028 scsa2usb_all_waitQs_empty(scsa2usb_state_t *scsa2usbp)
5029 {
5030 	uint_t	lun;
5031 
5032 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
5033 		if (usba_list_entry_count(
5034 		    &scsa2usbp->scsa2usb_waitQ[lun])) {
5035 
5036 			return (USB_FAILURE);
5037 		}
5038 	}
5039 
5040 	return (USB_SUCCESS);
5041 }
5042 
5043 
5044 /*
5045  * scsa2usb_disconnect_event_cb:
5046  *	callback for disconnect events
5047  */
5048 static int
5049 scsa2usb_disconnect_event_cb(dev_info_t *dip)
5050 {
5051 	scsa2usb_state_t *scsa2usbp =
5052 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5053 	dev_info_t	*cdip;
5054 	int		circ, i;
5055 	int		rval = USB_SUCCESS;
5056 
5057 	ASSERT(scsa2usbp != NULL);
5058 
5059 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5060 	    "scsa2usb_disconnect_event_cb: dip = 0x%p", dip);
5061 
5062 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5063 	scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
5064 
5065 	/*
5066 	 * wait till the work thread is done, carry on regardless
5067 	 * if not.
5068 	 */
5069 	for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
5070 		if ((scsa2usbp->scsa2usb_work_thread_id == NULL) &&
5071 		    (scsa2usbp->scsa2usb_cur_pkt == NULL) &&
5072 		    (scsa2usb_all_waitQs_empty(scsa2usbp) ==
5073 		    USB_SUCCESS)) {
5074 
5075 			break;
5076 		}
5077 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5078 		delay(drv_usectohz(1000000));
5079 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5080 	}
5081 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5082 
5083 	ndi_devi_enter(dip, &circ);
5084 	for (cdip = ddi_get_child(dip); cdip; ) {
5085 		dev_info_t *next = ddi_get_next_sibling(cdip);
5086 
5087 		mutex_enter(&DEVI(cdip)->devi_lock);
5088 		DEVI_SET_DEVICE_REMOVED(cdip);
5089 		mutex_exit(&DEVI(cdip)->devi_lock);
5090 
5091 		cdip = next;
5092 	}
5093 	ndi_devi_exit(dip, circ);
5094 
5095 	if (scsa2usbp->scsa2usb_ugen_hdl) {
5096 		rval = usb_ugen_disconnect_ev_cb(
5097 					scsa2usbp->scsa2usb_ugen_hdl);
5098 	}
5099 
5100 	return (rval);
5101 }
5102 
5103 
5104 /*
5105  * PM support
5106  *
5107  * scsa2usb_create_pm_components:
5108  *	create the pm components required for power management
5109  *	no mutex is need when calling USBA interfaces
5110  */
5111 static void
5112 scsa2usb_create_pm_components(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
5113 {
5114 	scsa2usb_power_t *pm;
5115 	uint_t		pwr_states;
5116 
5117 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5118 
5119 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5120 	    "scsa2usb_create_pm_components: dip = 0x%p, scsa2usbp = 0x%p",
5121 	    dip, scsa2usbp);
5122 
5123 	/*
5124 	 * determine if this device is on the blacklist
5125 	 * or if a conf file entry has disabled PM
5126 	 */
5127 	if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_PM) == 0) {
5128 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5129 		    "device cannot be power managed");
5130 
5131 		return;
5132 	}
5133 
5134 	/* Allocate the PM state structure */
5135 	pm = kmem_zalloc(sizeof (scsa2usb_power_t), KM_SLEEP);
5136 
5137 	scsa2usbp->scsa2usb_pm = pm;
5138 	pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5139 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5140 
5141 	if (usb_create_pm_components(dip, &pwr_states) ==
5142 	    USB_SUCCESS) {
5143 		if (usb_handle_remote_wakeup(dip,
5144 		    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
5145 			pm->scsa2usb_wakeup_enabled = 1;
5146 		}
5147 
5148 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5149 		pm->scsa2usb_pwr_states = (uint8_t)pwr_states;
5150 		scsa2usb_pm_busy_component(scsa2usbp);
5151 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5152 
5153 		(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
5154 	}
5155 
5156 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5157 }
5158 
5159 
5160 /*
5161  * scsa2usb_raise_power:
5162  *	check if the device is using full power or not
5163  */
5164 static void
5165 scsa2usb_raise_power(scsa2usb_state_t *scsa2usbp)
5166 {
5167 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5168 	    "scsa2usb_raise_power:");
5169 
5170 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5171 
5172 	if (scsa2usbp->scsa2usb_pm) {
5173 		scsa2usb_pm_busy_component(scsa2usbp);
5174 		if (scsa2usbp->scsa2usb_pm->scsa2usb_current_power ==
5175 		    USB_DEV_OS_PWR_OFF) {
5176 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5177 			(void) pm_raise_power(scsa2usbp->scsa2usb_dip,
5178 			    0, USB_DEV_OS_FULL_PWR);
5179 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5180 		}
5181 	}
5182 }
5183 
5184 
5185 /*
5186  * functions to handle power transition for OS levels 0 -> 3
5187  */
5188 static int
5189 scsa2usb_pwrlvl0(scsa2usb_state_t *scsa2usbp)
5190 {
5191 	int	rval;
5192 
5193 	switch (scsa2usbp->scsa2usb_dev_state) {
5194 	case USB_DEV_ONLINE:
5195 		/* Deny the powerdown request if the device is busy */
5196 		if (scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy != 0) {
5197 
5198 			return (USB_FAILURE);
5199 		}
5200 
5201 		/*
5202 		 * stop polling on interrupt pipe
5203 		 */
5204 		scsa2usb_cbi_stop_intr_polling(scsa2usbp);
5205 
5206 		/* Issue USB D3 command to the device here */
5207 		rval = usb_set_device_pwrlvl3(scsa2usbp->scsa2usb_dip);
5208 		ASSERT(rval == USB_SUCCESS);
5209 
5210 		scsa2usbp->scsa2usb_dev_state = USB_DEV_PWRED_DOWN;
5211 
5212 		/* FALLTHRU */
5213 	case USB_DEV_DISCONNECTED:
5214 	case USB_DEV_SUSPENDED:
5215 	case USB_DEV_PWRED_DOWN:
5216 	default:
5217 		scsa2usbp->scsa2usb_pm->scsa2usb_current_power =
5218 						USB_DEV_OS_PWR_OFF;
5219 
5220 		return (USB_SUCCESS);
5221 	}
5222 }
5223 
5224 
5225 static int
5226 scsa2usb_pwrlvl1(scsa2usb_state_t *scsa2usbp)
5227 {
5228 	int	rval;
5229 
5230 	/* Issue USB D2 command to the device here */
5231 	rval = usb_set_device_pwrlvl2(scsa2usbp->scsa2usb_dip);
5232 	ASSERT(rval == USB_SUCCESS);
5233 
5234 	return (DDI_FAILURE);
5235 }
5236 
5237 
5238 static int
5239 scsa2usb_pwrlvl2(scsa2usb_state_t *scsa2usbp)
5240 {
5241 	int	rval;
5242 
5243 	/* Issue USB D1 command to the device here */
5244 	rval = usb_set_device_pwrlvl1(scsa2usbp->scsa2usb_dip);
5245 	ASSERT(rval == USB_SUCCESS);
5246 
5247 	return (DDI_FAILURE);
5248 }
5249 
5250 
5251 static int
5252 scsa2usb_pwrlvl3(scsa2usb_state_t *scsa2usbp)
5253 {
5254 	int	rval;
5255 
5256 	/*
5257 	 * PM framework tries to put us in full power
5258 	 * during system shutdown. If we are disconnected
5259 	 * return success anyways
5260 	 */
5261 	if (scsa2usbp->scsa2usb_dev_state != USB_DEV_DISCONNECTED) {
5262 		/* Issue USB D0 command to the device here */
5263 		rval = usb_set_device_pwrlvl0(scsa2usbp->scsa2usb_dip);
5264 		ASSERT(rval == USB_SUCCESS);
5265 
5266 		scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
5267 	}
5268 	scsa2usbp->scsa2usb_pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5269 
5270 	return (DDI_SUCCESS);
5271 }
5272 
5273 
5274 /*
5275  * scsa2usb_power:
5276  *	power entry point
5277  */
5278 /* ARGSUSED */
5279 static int
5280 scsa2usb_power(dev_info_t *dip, int comp, int level)
5281 {
5282 	scsa2usb_state_t	*scsa2usbp;
5283 	scsa2usb_power_t	*pm;
5284 	int			rval = DDI_FAILURE;
5285 
5286 	scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5287 
5288 	USB_DPRINTF_L3(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5289 	    "scsa2usb_power: Begin scsa2usbp (%p): level = %d",
5290 	    scsa2usbp, level);
5291 
5292 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5293 	if (SCSA2USB_BUSY(scsa2usbp)) {
5294 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5295 		    "scsa2usb_power: busy");
5296 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5297 
5298 		return (rval);
5299 	}
5300 
5301 	pm = scsa2usbp->scsa2usb_pm;
5302 	if (pm == NULL) {
5303 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5304 		    "scsa2usb_power: pm NULL");
5305 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5306 
5307 		return (rval);
5308 	}
5309 
5310 	/* check if we are transitioning to a legal power level */
5311 	if (USB_DEV_PWRSTATE_OK(pm->scsa2usb_pwr_states, level)) {
5312 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5313 		    "scsa2usb_power: illegal power level = %d "
5314 		    "pwr_states: %x", level, pm->scsa2usb_pwr_states);
5315 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5316 
5317 		return (rval);
5318 	}
5319 
5320 	switch (level) {
5321 	case USB_DEV_OS_PWR_OFF :
5322 		rval = scsa2usb_pwrlvl0(scsa2usbp);
5323 		break;
5324 	case USB_DEV_OS_PWR_1 :
5325 		rval = scsa2usb_pwrlvl1(scsa2usbp);
5326 		break;
5327 	case USB_DEV_OS_PWR_2 :
5328 		rval = scsa2usb_pwrlvl2(scsa2usbp);
5329 		break;
5330 	case USB_DEV_OS_FULL_PWR :
5331 		rval = scsa2usb_pwrlvl3(scsa2usbp);
5332 		break;
5333 	}
5334 
5335 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5336 
5337 	return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
5338 }
5339 
5340 
5341 static void
5342 scsa2usb_pm_busy_component(scsa2usb_state_t *scsa2usb_statep)
5343 {
5344 	ASSERT(mutex_owned(&scsa2usb_statep->scsa2usb_mutex));
5345 
5346 	scsa2usb_statep->scsa2usb_pm->scsa2usb_pm_busy++;
5347 	mutex_exit(&scsa2usb_statep->scsa2usb_mutex);
5348 
5349 	if (pm_busy_component(scsa2usb_statep->scsa2usb_dip, 0) !=
5350 	    DDI_SUCCESS) {
5351 		mutex_enter(&scsa2usb_statep->scsa2usb_mutex);
5352 		ASSERT(scsa2usb_statep->scsa2usb_pm->scsa2usb_pm_busy > 0);
5353 		scsa2usb_statep->scsa2usb_pm->scsa2usb_pm_busy--;
5354 		mutex_exit(&scsa2usb_statep->scsa2usb_mutex);
5355 	}
5356 
5357 	mutex_enter(&scsa2usb_statep->scsa2usb_mutex);
5358 
5359 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usb_statep->scsa2usb_log_handle,
5360 	    "scsa2usb_pm_busy : %d",
5361 	    scsa2usb_statep->scsa2usb_pm->scsa2usb_pm_busy);
5362 }
5363 
5364 
5365 /*
5366  * scsa2usb_pm_idle_component:
5367  *	idles the device
5368  */
5369 static void
5370 scsa2usb_pm_idle_component(scsa2usb_state_t *scsa2usbp)
5371 {
5372 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5373 	if (scsa2usbp->scsa2usb_pm) {
5374 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5375 		if (pm_idle_component(scsa2usbp->scsa2usb_dip, 0) ==
5376 		    DDI_SUCCESS) {
5377 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5378 			ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5379 			scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5380 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5381 		}
5382 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5383 		USB_DPRINTF_L4(DPRINT_MASK_PM,
5384 		    scsa2usbp->scsa2usb_log_handle,
5385 		    "scsa2usb_pm_busy : %d",
5386 		    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5387 	}
5388 }
5389 
5390 
5391 #ifdef	DEBUG
5392 /*
5393  * scsa2usb_print_cdb:
5394  *	prints CDB
5395  */
5396 void
5397 scsa2usb_print_cdb(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
5398 {
5399 	uchar_t *c = (uchar_t *)&cmd->cmd_cdb;
5400 
5401 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5402 	    "cmd = 0x%p opcode=%s "
5403 	    "cdb: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
5404 	    cmd, scsi_cname(cmd->cmd_cdb[SCSA2USB_OPCODE], scsa2usb_cmds),
5405 	    c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8],
5406 	    c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
5407 }
5408 #endif	/* DEBUG */
5409 
5410 
5411 #ifdef	SCSA2USB_BULK_ONLY_TEST
5412 /*
5413  * scsa2usb_test_mblk:
5414  *	This function sends a dummy data mblk_t to simulate
5415  *	the following test cases: 5 and 11.
5416  */
5417 static void
5418 scsa2usb_test_mblk(scsa2usb_state_t *scsa2usbp, boolean_t large)
5419 {
5420 	int			i, rval;
5421 	size_t			len;
5422 	usb_flags_t		flags = USB_FLAGS_SLEEP;
5423 	usb_bulk_req_t		*req;
5424 
5425 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5426 
5427 	/* should we create a larger mblk? */
5428 	len = (large == B_TRUE) ? DEV_BSIZE : USB_BULK_CBWCMD_LEN;
5429 
5430 	req = scsa2usb_init_bulk_req(scsa2usbp, len,
5431 		SCSA2USB_BULK_PIPE_TIMEOUT, 0, flags);
5432 
5433 	/* fill up the data mblk */
5434 	for (i = 0; i < len; i++) {
5435 		*req->bulk_data->b_wptr++ = (uchar_t)i;
5436 	}
5437 
5438 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5439 	ASSERT(req->bulk_timeout);
5440 	rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe, req, flags);
5441 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5442 
5443 	USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5444 	    "scsa2usb_test_mblk: Sent Data Out rval = 0x%x", rval);
5445 
5446 	usb_free_bulk_req(req);
5447 }
5448 #endif	/* SCSA2USB_BULK_ONLY_TEST */
5449