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