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