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