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