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