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