xref: /illumos-gate/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c (revision 3636ae5408a4c1fb68954277f99be72f62e3489e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Copyright 2016 Joyent, Inc.
26  * Copyright (c) 2016 by Delphix. All rights reserved.
27  * Copyright 2019 Joshua M. Clulow <josh@sysmgr.org>
28  */
29 
30 
31 /*
32  * scsa2usb bridge nexus driver:
33  *
34  * This driver supports the following wire transports:
35  * a. Bulk Only transport (see usb_ms_bulkonly.c)
36  * b. CB transport (see usb_ms_cbi.c)
37  * c. CBI transport with interrupt status completion (see usb_ms_cbi.c)
38  *
39  * It handles the following command sets:
40  * a. SCSI
41  * b. ATAPI command set (subset of SCSI command set)
42  * c. UFI command set (
43  *	http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf)
44  *
45  * For details on USB Mass Storage Class overview:
46  *	http://www.usb.org/developers/devclass_docs/usbmassover_11.pdf
47  */
48 #if defined(lint) && !defined(DEBUG)
49 #define	DEBUG	1
50 #endif
51 
52 #include <sys/usb/usba/usbai_version.h>
53 #include <sys/scsi/scsi.h>
54 #include <sys/cdio.h>
55 #include <sys/sunndi.h>
56 #include <sys/esunddi.h>
57 #include <sys/callb.h>
58 #include <sys/kobj.h>
59 #include <sys/kobj_lex.h>
60 #include <sys/strsubr.h>
61 #include <sys/strsun.h>
62 #include <sys/sysmacros.h>
63 
64 #include <sys/usb/usba.h>
65 #include <sys/usb/clients/ugen/usb_ugen.h>
66 #include <sys/usb/usba/usba_ugen.h>
67 
68 #include <sys/usb/usba/usba_private.h>
69 #include <sys/usb/usba/usba_ugend.h>
70 #include <sys/usb/clients/mass_storage/usb_bulkonly.h>
71 #include <sys/usb/scsa2usb/scsa2usb.h>
72 
73 /*
74  * Function Prototypes
75  */
76 static int	scsa2usb_attach(dev_info_t *, ddi_attach_cmd_t);
77 static int	scsa2usb_info(dev_info_t *, ddi_info_cmd_t, void *,
78 						void **);
79 static int	scsa2usb_detach(dev_info_t *, ddi_detach_cmd_t);
80 static int	scsa2usb_cleanup(dev_info_t *, scsa2usb_state_t *);
81 static void	scsa2usb_detect_quirks(scsa2usb_state_t *);
82 static void	scsa2usb_create_luns(scsa2usb_state_t *);
83 static int	scsa2usb_is_usb(dev_info_t *);
84 static void	scsa2usb_fake_inquiry(scsa2usb_state_t *,
85 		    struct scsi_inquiry *);
86 static void	scsa2usb_do_inquiry(scsa2usb_state_t *,
87 						uint_t, uint_t);
88 static int	scsa2usb_do_tur(scsa2usb_state_t *, struct scsi_address *);
89 
90 /* override property handling */
91 static void	scsa2usb_override(scsa2usb_state_t *);
92 static int	scsa2usb_parse_input_str(char *, scsa2usb_ov_t *,
93 		    scsa2usb_state_t *);
94 static void	scsa2usb_override_error(char *, scsa2usb_state_t *);
95 static char	*scsa2usb_strtok_r(char *, char *, char **);
96 
97 
98 /* PANIC callback handling */
99 static void	scsa2usb_panic_callb_init(scsa2usb_state_t *);
100 static void	scsa2usb_panic_callb_fini(scsa2usb_state_t *);
101 static boolean_t scsa2usb_panic_callb(void *, int);
102 
103 /* SCSA support */
104 static int	scsa2usb_scsi_tgt_probe(struct scsi_device *, int (*)(void));
105 static int	scsa2usb_scsi_tgt_init(dev_info_t *, dev_info_t *,
106 		    scsi_hba_tran_t *, struct scsi_device *);
107 static void	scsa2usb_scsi_tgt_free(dev_info_t *, dev_info_t *,
108 		    scsi_hba_tran_t *, struct scsi_device *);
109 static struct	scsi_pkt *scsa2usb_scsi_init_pkt(struct scsi_address *,
110 		    struct scsi_pkt *, struct buf *, int, int,
111 		    int, int, int (*)(), caddr_t);
112 static void	scsa2usb_scsi_destroy_pkt(struct scsi_address *,
113 		    struct scsi_pkt *);
114 static int	scsa2usb_scsi_start(struct scsi_address *, struct scsi_pkt *);
115 static int	scsa2usb_scsi_abort(struct scsi_address *, struct scsi_pkt *);
116 static int	scsa2usb_scsi_reset(struct scsi_address *, int);
117 static int	scsa2usb_scsi_getcap(struct scsi_address *, char *, int);
118 static int	scsa2usb_scsi_setcap(struct scsi_address *, char *, int, int);
119 static int	scsa2usb_scsi_bus_config(dev_info_t *, uint_t,
120 		    ddi_bus_config_op_t, void *, dev_info_t **);
121 static int	scsa2usb_scsi_bus_unconfig(dev_info_t *, uint_t,
122 		    ddi_bus_config_op_t, void *);
123 
124 /* functions for command and transport support */
125 static void	scsa2usb_prepare_pkt(scsa2usb_state_t *, struct scsi_pkt *);
126 static int	scsa2usb_cmd_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
127 static int	scsa2usb_check_bulkonly_quirks(scsa2usb_state_t *,
128 		    scsa2usb_cmd_t *);
129 static int	scsa2usb_check_ufi_quirks(scsa2usb_state_t *,
130 		    scsa2usb_cmd_t *);
131 static int	scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *,
132 		    scsa2usb_cmd_t *, struct scsi_pkt *);
133 static int	scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *,
134 		    scsa2usb_cmd_t *, struct scsi_pkt *);
135 
136 /* waitQ handling */
137 static void	scsa2usb_work_thread(void *);
138 static void	scsa2usb_transport_request(scsa2usb_state_t *, uint_t);
139 static void	scsa2usb_flush_waitQ(scsa2usb_state_t *, uint_t, uchar_t);
140 static int	scsa2usb_all_waitQs_empty(scsa2usb_state_t *);
141 
142 /* auto request sense handling */
143 static int	scsa2usb_create_arq_pkt(scsa2usb_state_t *,
144 		    struct scsi_address *);
145 static void	scsa2usb_delete_arq_pkt(scsa2usb_state_t *);
146 static void	scsa2usb_complete_arq_pkt(scsa2usb_state_t *, struct scsi_pkt *,
147 		    scsa2usb_cmd_t *, struct buf *);
148 
149 /* utility functions for any transport */
150 static int	scsa2usb_open_usb_pipes(scsa2usb_state_t *);
151 void		scsa2usb_close_usb_pipes(scsa2usb_state_t *);
152 
153 static void	scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *, int);
154 static void	scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *, uint64_t);
155 static void	scsa2usb_fill_up_g4_cdb_lba(scsa2usb_cmd_t *, uint64_t);
156 static void	scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *, int, int);
157 static void	scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *, int, int);
158 static void	scsa2usb_fill_up_16byte_cdb_len(scsa2usb_cmd_t *, int, int);
159 static int	scsa2usb_read_cd_blk_size(uchar_t);
160 int		scsa2usb_rw_transport(scsa2usb_state_t *, struct scsi_pkt *);
161 void		scsa2usb_setup_next_xfer(scsa2usb_state_t *, scsa2usb_cmd_t *);
162 
163 static mblk_t	*scsa2usb_bp_to_mblk(scsa2usb_state_t *);
164 int		scsa2usb_handle_data_start(scsa2usb_state_t *,
165 		    scsa2usb_cmd_t *, usb_bulk_req_t *);
166 void		scsa2usb_handle_data_done(scsa2usb_state_t *,
167 		    scsa2usb_cmd_t *cmd, usb_bulk_req_t *);
168 
169 usb_bulk_req_t *scsa2usb_init_bulk_req(scsa2usb_state_t *,
170 			    size_t, uint_t, usb_req_attrs_t, usb_flags_t);
171 int		scsa2usb_bulk_timeout(int);
172 int		scsa2usb_clear_ept_stall(scsa2usb_state_t *, uint_t,
173 		    usb_pipe_handle_t, char *);
174 static void	scsa2usb_pkt_completion(scsa2usb_state_t *, struct scsi_pkt *);
175 
176 /* event handling */
177 static int	scsa2usb_reconnect_event_cb(dev_info_t *);
178 static int	scsa2usb_disconnect_event_cb(dev_info_t *);
179 static int	scsa2usb_cpr_suspend(dev_info_t *);
180 static void	scsa2usb_cpr_resume(dev_info_t *);
181 static void	scsa2usb_restore_device_state(dev_info_t *, scsa2usb_state_t *);
182 
183 /* PM handling */
184 static void	scsa2usb_create_pm_components(dev_info_t *, scsa2usb_state_t *);
185 static void	scsa2usb_raise_power(scsa2usb_state_t *);
186 static int	scsa2usb_pwrlvl0(scsa2usb_state_t *);
187 static int	scsa2usb_pwrlvl1(scsa2usb_state_t *);
188 static int	scsa2usb_pwrlvl2(scsa2usb_state_t *);
189 static int	scsa2usb_pwrlvl3(scsa2usb_state_t *);
190 static int	scsa2usb_power(dev_info_t *, int comp, int level);
191 static void	scsa2usb_pm_busy_component(scsa2usb_state_t *);
192 static void	scsa2usb_pm_idle_component(scsa2usb_state_t *);
193 
194 /* external functions for Bulk only (BO) support */
195 extern int	scsa2usb_bulk_only_transport(scsa2usb_state_t *,
196 		    scsa2usb_cmd_t *);
197 extern int	scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *);
198 
199 /* external functions for CB/CBI support */
200 extern int	scsa2usb_cbi_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
201 extern void	scsa2usb_cbi_stop_intr_polling(scsa2usb_state_t *);
202 
203 
204 /* cmd decoding */
205 static char *scsa2usb_cmds[] = {
206 	"\000tur",
207 	"\001rezero",
208 	"\003rqsense",
209 	"\004format",
210 	"\014cartprot",
211 	"\022inquiry",
212 	"\026tranlba",
213 	"\030fmtverify",
214 	"\032modesense",
215 	"\033start",
216 	"\035snddiag",
217 	"\036doorlock",
218 	"\043formatcap",
219 	"\045readcap",
220 	"\050read10",
221 	"\052write10",
222 	"\053seek10",
223 	"\056writeverify",
224 	"\057verify",
225 	"\065synchcache",
226 	"\076readlong",
227 	"\077writelong",
228 	"\102readsubchan",
229 	"\103readtoc",
230 	"\104readhdr",
231 	"\105playaudio10",
232 	"\107playaudio_msf",
233 	"\110playaudio_ti",
234 	"\111playtrk_r10",
235 	"\112geteventnotify",
236 	"\113pause_resume",
237 	"\116stop/play_scan",
238 	"\121readdiscinfo",
239 	"\122readtrkinfo",
240 	"\123reservedtrk",
241 	"\124sendopcinfo",
242 	"\125modeselect",
243 	"\132modesense",
244 	"\133closetrksession",
245 	"\135sendcuesheet",
246 	"\136prin",
247 	"\137prout",
248 	"\210read16",
249 	"\212write16",
250 	"\241blankcd",
251 	"\245playaudio12",
252 	"\250read12",
253 	"\251playtrk12",
254 	"\252write12",
255 	"\254getperf",
256 	"\271readcdmsf",
257 	"\273setcdspeed",
258 	"\275mechanism_sts",
259 	"\276readcd",
260 	NULL
261 };
262 
263 
264 /*
265  * Mass-Storage devices masquerade as "sd" disks.  These devices may not
266  * support all SCSI CDBs in their entirety due to implementation
267  * limitations.
268  *
269  * The following table contains a list of quirks for devices that are known to
270  * misbehave.  See the comments in scsa2usb.h for a description of each
271  * quirk attribute.
272  */
273 
274 /*
275  * Either the product ID (q_pid) or the revision number (q_rev) can be a
276  * wildcard match using this constant:
277  */
278 #define	X	UINT16_MAX
279 
280 static struct quirk {
281 	uint16_t	q_vid;	/* Vendor ID */
282 	uint16_t	q_pid;	/* Product ID */
283 	uint16_t	q_rev;	/* Device revision number in BCD */
284 	uint16_t	q_attr;	/* Quirk attributes for this device */
285 } scsa2usb_quirks[] = {
286 	/* Iomega Zip100 drive (prototype) with flaky bridge */
287 	{MS_IOMEGA_VID, MS_IOMEGA_PID1_ZIP100, X,
288 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
289 
290 	/* Iomega Zip100 drive (newer model) with flaky bridge */
291 	{MS_IOMEGA_VID, MS_IOMEGA_PID2_ZIP100, X,
292 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
293 
294 	/* Iomega Zip100 drive (newer model) with flaky bridge */
295 	{MS_IOMEGA_VID, MS_IOMEGA_PID3_ZIP100, X,
296 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
297 
298 	/* Iomega Zip250 drive */
299 	{MS_IOMEGA_VID, MS_IOMEGA_PID_ZIP250, X, SCSA2USB_ATTRS_GET_LUN},
300 
301 	/* Iomega Clik! drive */
302 	{MS_IOMEGA_VID, MS_IOMEGA_PID_CLIK, X,
303 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
304 
305 	/* Kingston DataTraveler Stick / PNY Attache Stick */
306 	{MS_TOSHIBA_VID, MS_TOSHIBA_PID0, X,
307 	    SCSA2USB_ATTRS_GET_LUN},
308 
309 	/* PNY Floppy drive */
310 	{MS_PNY_VID, MS_PNY_PID0, X,
311 	    SCSA2USB_ATTRS_GET_LUN},
312 
313 	/* SMSC floppy Device - and its clones */
314 	{MS_SMSC_VID, X, X, SCSA2USB_ATTRS_START_STOP},
315 
316 	/* Hagiwara SmartMedia Device */
317 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID1, X,
318 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
319 
320 	/* Hagiwara CompactFlash Device */
321 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID2, X,
322 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
323 
324 	/* Hagiwara SmartMedia/CompactFlash Combo Device */
325 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID3, X,
326 	    SCSA2USB_ATTRS_START_STOP},
327 
328 	/* Hagiwara new SM Device */
329 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID4, X,
330 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
331 
332 	/* Hagiwara new CF Device */
333 	{MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID5, X,
334 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
335 
336 	/* Mitsumi CD-RW Device(s) */
337 	{MS_MITSUMI_VID, X, X, SCSA2USB_ATTRS_BIG_TIMEOUT |
338 	    SCSA2USB_ATTRS_GET_CONF | SCSA2USB_ATTRS_GET_PERF},
339 
340 	/* Neodio Technologies Corporation SM/CF/MS/SD Combo Device */
341 	{MS_NEODIO_VID, MS_NEODIO_DEVICE_3050, X,
342 	    SCSA2USB_ATTRS_MODE_SENSE },
343 
344 	/* dumb flash devices */
345 	{MS_SONY_FLASH_VID, MS_SONY_FLASH_PID, X,
346 	    SCSA2USB_ATTRS_REDUCED_CMD},
347 
348 	{MS_TREK_FLASH_VID, MS_TREK_FLASH_PID, X,
349 	    SCSA2USB_ATTRS_REDUCED_CMD},
350 
351 	{MS_PENN_FLASH_VID, MS_PENN_FLASH_PID, X,
352 	    SCSA2USB_ATTRS_REDUCED_CMD},
353 
354 	/* SimpleTech UCF-100 CF Device */
355 	{MS_SIMPLETECH_VID, MS_SIMPLETECH_PID1, X,
356 	    SCSA2USB_ATTRS_REDUCED_CMD},
357 
358 	{MS_ADDONICS_CARD_READER_VID, MS_ADDONICS_CARD_READER_PID,
359 	    X, SCSA2USB_ATTRS_REDUCED_CMD},
360 
361 	/* Acomdata 80GB USB/1394 Hard Disk */
362 	{MS_ACOMDATA_VID, MS_ACOMDATA_PID1, X,
363 	    SCSA2USB_ATTRS_USE_CSW_RESIDUE},
364 
365 	/* OTi6828 Flash Disk */
366 	{MS_OTI_VID, MS_OTI_DEVICE_6828, X,
367 	    SCSA2USB_ATTRS_USE_CSW_RESIDUE},
368 
369 	/* AMI Virtual Floppy */
370 	{MS_AMI_VID, MS_AMI_VIRTUAL_FLOPPY, X,
371 	    SCSA2USB_ATTRS_NO_MEDIA_CHECK},
372 
373 	/* ScanLogic USB Storage Device */
374 	{MS_SCANLOGIC_VID, MS_SCANLOGIC_PID1, X,
375 	    SCSA2USB_ATTRS_NO_CAP_ADJUST},
376 
377 	/* Super Top USB 2.0 IDE Device */
378 	{MS_SUPERTOP_VID, MS_SUPERTOP_DEVICE_6600, X,
379 	    SCSA2USB_ATTRS_USE_CSW_RESIDUE},
380 
381 	/* Aigo Miniking Device NEHFSP14 */
382 	{MS_AIGO_VID, MS_AIGO_DEVICE_6981, X,
383 	    SCSA2USB_ATTRS_USE_CSW_RESIDUE},
384 
385 	/* Alcor Micro Corp 6387 flash disk */
386 	{MS_ALCOR_VID, MS_ALCOR_PID0, X,
387 	    SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_USE_CSW_RESIDUE},
388 
389 	/* Western Digital External HDD */
390 	{MS_WD_VID, MS_WD_PID, X,
391 	    SCSA2USB_ATTRS_INQUIRY_EVPD},
392 
393 	/* 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 = scsa2usb_strtok_r(str, "=", &lasts);
1580 	    input_field != NULL;
1581 	    input_field = scsa2usb_strtok_r(lasts, "=", &lasts)) {
1582 
1583 		if ((input_value = scsa2usb_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  * scsa2usb_strtok_r:
1707  *	parse a list of tokens
1708  */
1709 static char *
1710 scsa2usb_strtok_r(char *p, char *sep, char **lasts)
1711 {
1712 	char	*e;
1713 	char	*tok = NULL;
1714 
1715 	if (p == 0 || *p == 0) {
1716 
1717 		return (NULL);
1718 	}
1719 
1720 	e = p+strlen(p);
1721 
1722 	do {
1723 		if (strchr(sep, *p) != NULL) {
1724 			if (tok != NULL) {
1725 				*p = 0;
1726 				*lasts = p+1;
1727 
1728 				return (tok);
1729 			}
1730 		} else if (tok == NULL) {
1731 			tok = p;
1732 		}
1733 	} while (++p < e);
1734 
1735 	*lasts = NULL;
1736 
1737 	return (tok);
1738 }
1739 
1740 
1741 /*
1742  * Some devices are not complete or compatible implementations of the USB mass
1743  * storage protocols, and need special handling.  This routine checks various
1744  * aspects of the device against internal lists of quirky hardware.
1745  */
1746 static void
1747 scsa2usb_detect_quirks(scsa2usb_state_t *scsa2usbp)
1748 {
1749 	int mask;
1750 	usb_dev_descr_t *desc = scsa2usbp->scsa2usb_dev_data->dev_descr;
1751 
1752 	if (!SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1753 		scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_GET_LUN;
1754 	}
1755 
1756 	/*
1757 	 * Determine if this device is on the quirks list:
1758 	 */
1759 	for (uint_t i = 0; i < ARRAY_SIZE(scsa2usb_quirks); i++) {
1760 		struct quirk *q = &scsa2usb_quirks[i];
1761 
1762 		if (q->q_vid == desc->idVendor &&
1763 		    (q->q_pid == desc->idProduct || q->q_pid == X) &&
1764 		    (q->q_rev == desc->bcdDevice || q->q_rev == X)) {
1765 			/*
1766 			 * Remove any attribute bits specified in the quirks
1767 			 * table:
1768 			 */
1769 			scsa2usbp->scsa2usb_attrs &= ~(q->q_attr);
1770 			break;
1771 		}
1772 	}
1773 
1774 	/*
1775 	 * Mitsumi's CD-RW drives subclass isn't UFI.
1776 	 * But they support UFI command-set (this code ensures that)
1777 	 * NOTE: This is a special case, and is being called out so.
1778 	 */
1779 	if (desc->idVendor == MS_MITSUMI_VID) {
1780 		mask = scsa2usbp->scsa2usb_cmd_protocol & SCSA2USB_CMDSET_MASK;
1781 		if (mask) {
1782 			scsa2usbp->scsa2usb_cmd_protocol &= ~mask;
1783 		}
1784 		scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
1785 	}
1786 
1787 	if (scsa2usbp->scsa2usb_attrs != SCSA2USB_ALL_ATTRS) {
1788 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1789 		    scsa2usbp->scsa2usb_log_handle,
1790 		    "scsa2usb attributes modified: 0x%x",
1791 		    scsa2usbp->scsa2usb_attrs);
1792 	}
1793 }
1794 
1795 
1796 /*
1797  * scsa2usb_create_luns:
1798  *	check the number of luns but continue if the check fails,
1799  *	create child nodes for each lun
1800  */
1801 static void
1802 scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp)
1803 {
1804 	int		lun, rval;
1805 	char		*compatible[MAX_COMPAT_NAMES];	/* compatible names */
1806 	dev_info_t	*cdip;
1807 	uchar_t		dtype;
1808 	char		*node_name;
1809 	char		*driver_name = NULL;
1810 
1811 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1812 	    "scsa2usb_create_luns:");
1813 
1814 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
1815 
1816 	/* Set n_luns to 1 by default (for floppies and other devices) */
1817 	scsa2usbp->scsa2usb_n_luns = 1;
1818 
1819 	/*
1820 	 * Check if there are any device out there which don't
1821 	 * support the GET_MAX_LUN command. If so, don't issue
1822 	 * control request to them.
1823 	 */
1824 	if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_LUN) == 0) {
1825 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1826 		    "get_max_lun cmd not supported");
1827 	} else {
1828 		if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1829 			scsa2usbp->scsa2usb_n_luns =
1830 			    scsa2usb_bulk_only_get_max_lun(scsa2usbp);
1831 		}
1832 	}
1833 
1834 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1835 	    "scsa2usb_create_luns: %d luns found", scsa2usbp->scsa2usb_n_luns);
1836 
1837 	/*
1838 	 * create disk child for each lun
1839 	 */
1840 	for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
1841 		ASSERT(scsa2usbp->scsa2usb_lun_dip[lun] == NULL);
1842 
1843 		/* do an inquiry to get the dtype of this lun */
1844 		scsa2usb_do_inquiry(scsa2usbp, 0, lun);
1845 
1846 		dtype = scsa2usbp->scsa2usb_lun_inquiry[lun].
1847 		    inq_dtype & DTYPE_MASK;
1848 
1849 		USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1850 		    "dtype[%d]=0x%x", lun, dtype);
1851 
1852 		driver_name = NULL;
1853 
1854 		switch (dtype) {
1855 		case DTYPE_DIRECT:
1856 		case DTYPE_RODIRECT:
1857 		case DTYPE_OPTICAL:
1858 			node_name = "disk";
1859 			driver_name = "sd";
1860 
1861 			break;
1862 		case DTYPE_SEQUENTIAL:
1863 			node_name = "tape";
1864 			driver_name = "st";
1865 
1866 			break;
1867 		case DTYPE_PRINTER:
1868 			node_name = "printer";
1869 
1870 			break;
1871 		case DTYPE_PROCESSOR:
1872 			node_name = "processor";
1873 
1874 			break;
1875 		case DTYPE_WORM:
1876 			node_name = "worm";
1877 
1878 			break;
1879 		case DTYPE_SCANNER:
1880 			node_name = "scanner";
1881 
1882 			break;
1883 		case DTYPE_CHANGER:
1884 			node_name = "changer";
1885 
1886 			break;
1887 		case DTYPE_COMM:
1888 			node_name = "comm";
1889 
1890 			break;
1891 		case DTYPE_ARRAY_CTRL:
1892 			node_name = "array_ctrl";
1893 
1894 			break;
1895 		case DTYPE_ESI:
1896 			node_name = "esi";
1897 			driver_name = "ses";
1898 
1899 			break;
1900 		default:
1901 			node_name = "generic";
1902 
1903 			break;
1904 		}
1905 
1906 		if (driver_name) {
1907 			compatible[0] = driver_name;
1908 		}
1909 
1910 		ndi_devi_alloc_sleep(scsa2usbp->scsa2usb_dip, node_name,
1911 		    (pnode_t)DEVI_SID_NODEID, &cdip);
1912 
1913 		/* attach target & lun properties */
1914 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0);
1915 		if (rval != DDI_PROP_SUCCESS) {
1916 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1917 			    scsa2usbp->scsa2usb_log_handle,
1918 			    "ndi_prop_update_int target failed %d", rval);
1919 			(void) ndi_devi_free(cdip);
1920 			continue;
1921 		}
1922 
1923 		rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip,
1924 		    "hotpluggable");
1925 		if (rval != DDI_PROP_SUCCESS) {
1926 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1927 			    scsa2usbp->scsa2usb_log_handle,
1928 			    "ndi_prop_create_boolean hotpluggable failed %d",
1929 			    rval);
1930 			ddi_prop_remove_all(cdip);
1931 			(void) ndi_devi_free(cdip);
1932 			continue;
1933 		}
1934 		/*
1935 		 * Some devices don't support LOG SENSE, so tells
1936 		 * sd driver not to send this command.
1937 		 */
1938 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
1939 		    "pm-capable", 1);
1940 		if (rval != DDI_PROP_SUCCESS) {
1941 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1942 			    scsa2usbp->scsa2usb_log_handle,
1943 			    "ndi_prop_update_int pm-capable failed %d", rval);
1944 			ddi_prop_remove_all(cdip);
1945 			(void) ndi_devi_free(cdip);
1946 			continue;
1947 		}
1948 
1949 		rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", lun);
1950 		if (rval != DDI_PROP_SUCCESS) {
1951 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1952 			    scsa2usbp->scsa2usb_log_handle,
1953 			    "ndi_prop_update_int lun failed %d", rval);
1954 			ddi_prop_remove_all(cdip);
1955 			(void) ndi_devi_free(cdip);
1956 			continue;
1957 		}
1958 
1959 		if (driver_name) {
1960 			rval = ndi_prop_update_string_array(DDI_DEV_T_NONE,
1961 			    cdip, "compatible", (char **)compatible,
1962 			    MAX_COMPAT_NAMES);
1963 			if (rval != DDI_PROP_SUCCESS) {
1964 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1965 				    scsa2usbp->scsa2usb_log_handle,
1966 				    "ndi_prop_update_string_array failed %d",
1967 				    rval);
1968 				ddi_prop_remove_all(cdip);
1969 				(void) ndi_devi_free(cdip);
1970 				continue;
1971 			}
1972 		}
1973 
1974 		/*
1975 		 * add property "usb" so we always verify that it is our child
1976 		 */
1977 		rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb");
1978 		if (rval != DDI_PROP_SUCCESS) {
1979 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1980 			    scsa2usbp->scsa2usb_log_handle,
1981 			    "ndi_prop_create_boolean failed %d", rval);
1982 			ddi_prop_remove_all(cdip);
1983 			(void) ndi_devi_free(cdip);
1984 			continue;
1985 		}
1986 
1987 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
1988 		(void) ddi_initchild(scsa2usbp->scsa2usb_dip, cdip);
1989 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
1990 
1991 		usba_set_usba_device(cdip,
1992 		    usba_get_usba_device(scsa2usbp->scsa2usb_dip));
1993 	}
1994 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
1995 }
1996 
1997 
1998 /*
1999  * scsa2usb_is_usb:
2000  *	scsa2usb gets called for all possible sd children.
2001  *	we can only accept usb children
2002  */
2003 static int
2004 scsa2usb_is_usb(dev_info_t *dip)
2005 {
2006 	if (dip) {
2007 		return (ddi_prop_exists(DDI_DEV_T_ANY, dip,
2008 		    DDI_PROP_DONTPASS, "usb"));
2009 	}
2010 	return (0);
2011 }
2012 
2013 
2014 /*
2015  * Panic Stuff
2016  * scsa2usb_panic_callb_init:
2017  *	initialize PANIC callb and free allocated resources
2018  */
2019 static void
2020 scsa2usb_panic_callb_init(scsa2usb_state_t *scsa2usbp)
2021 {
2022 	/*
2023 	 * In case the system panics, the sync command flushes
2024 	 * dirty FS pages or buffers. This would cause a hang
2025 	 * in USB.
2026 	 * The reason for the failure is that we enter
2027 	 * polled mode (interrupts disabled) and HCD gets stuck
2028 	 * trying to execute bulk requests
2029 	 * The panic_callback registered below provides a warning
2030 	 * that a panic has occurred and from that point onwards, we
2031 	 * complete each request successfully and immediately. This
2032 	 * will fake successful syncing so at least the rest of the
2033 	 * filesystems complete syncing.
2034 	 */
2035 	scsa2usbp->scsa2usb_panic_info =
2036 	    kmem_zalloc(sizeof (scsa2usb_cpr_t), KM_SLEEP);
2037 	mutex_init(&scsa2usbp->scsa2usb_panic_info->lockp,
2038 	    NULL, MUTEX_DRIVER,
2039 	    scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2040 	scsa2usbp->scsa2usb_panic_info->statep = scsa2usbp;
2041 	scsa2usbp->scsa2usb_panic_info->cpr.cc_lockp =
2042 	    &scsa2usbp->scsa2usb_panic_info->lockp;
2043 	scsa2usbp->scsa2usb_panic_info->cpr.cc_id =
2044 	    callb_add(scsa2usb_panic_callb,
2045 	    (void *)scsa2usbp->scsa2usb_panic_info,
2046 	    CB_CL_PANIC, "scsa2usb");
2047 }
2048 
2049 
2050 /*
2051  * scsa2usb_panic_callb_fini:
2052  *	cancel out PANIC callb and free allocated resources
2053  */
2054 static void
2055 scsa2usb_panic_callb_fini(scsa2usb_state_t *scsa2usbp)
2056 {
2057 	if (scsa2usbp->scsa2usb_panic_info) {
2058 		SCSA2USB_CANCEL_CB(scsa2usbp->scsa2usb_panic_info->cpr.cc_id);
2059 		mutex_destroy(&scsa2usbp->scsa2usb_panic_info->lockp);
2060 		scsa2usbp->scsa2usb_panic_info->statep = NULL;
2061 		kmem_free(scsa2usbp->scsa2usb_panic_info,
2062 		    sizeof (scsa2usb_cpr_t));
2063 		scsa2usbp->scsa2usb_panic_info = NULL;
2064 	}
2065 }
2066 
2067 
2068 /*
2069  * scsa2usb_panic_callb:
2070  *	This routine is called when there is a system panic.
2071  */
2072 /* ARGSUSED */
2073 static boolean_t
2074 scsa2usb_panic_callb(void *arg, int code)
2075 {
2076 	scsa2usb_cpr_t *cpr_infop;
2077 	scsa2usb_state_t *scsa2usbp;
2078 	uint_t		lun;
2079 
2080 	_NOTE(NO_COMPETING_THREADS_NOW);
2081 	cpr_infop = (scsa2usb_cpr_t *)arg;
2082 	scsa2usbp = (scsa2usb_state_t *)cpr_infop->statep;
2083 
2084 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2085 	    "scsa2usb_panic_callb: code=%d", code);
2086 
2087 	/*
2088 	 * If we return error here, "sd" prints lots of error
2089 	 * messages and could retry the same pkt over and over again.
2090 	 * The sync recovery isn't "smooth" in that case. By faking
2091 	 * a success return, instead,  we force sync to complete.
2092 	 */
2093 	if (scsa2usbp->scsa2usb_cur_pkt) {
2094 		/*
2095 		 * Do not print the "no sync" warning here. it will then be
2096 		 * displayed before we actually start syncing. Also we don't
2097 		 * replace this code with a call to scsa2usb_pkt_completion().
2098 		 * NOTE: mutexes are disabled during panic.
2099 		 */
2100 		scsa2usbp->scsa2usb_cur_pkt->pkt_reason = CMD_CMPLT;
2101 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2102 		scsa2usb_pkt_completion(scsa2usbp, scsa2usbp->scsa2usb_cur_pkt);
2103 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2104 	}
2105 
2106 	/* get rid of waitQ */
2107 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
2108 		scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_CMPLT);
2109 	}
2110 
2111 #ifndef lint
2112 	_NOTE(COMPETING_THREADS_NOW);
2113 #endif
2114 
2115 	return (B_TRUE);
2116 }
2117 
2118 /*
2119  * scsa2usb_cpr_suspend
2120  *	determine if the device's state can be changed to SUSPENDED
2121  *	close pipes if there is no activity
2122  */
2123 /* ARGSUSED */
2124 static int
2125 scsa2usb_cpr_suspend(dev_info_t *dip)
2126 {
2127 	scsa2usb_state_t *scsa2usbp;
2128 	int	prev_state;
2129 	int	rval = USB_FAILURE;
2130 
2131 	scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2132 
2133 	ASSERT(scsa2usbp != NULL);
2134 
2135 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2136 	    "scsa2usb_cpr_suspend:");
2137 
2138 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2139 	switch (scsa2usbp->scsa2usb_dev_state) {
2140 	case USB_DEV_ONLINE:
2141 	case USB_DEV_PWRED_DOWN:
2142 	case USB_DEV_DISCONNECTED:
2143 		prev_state = scsa2usbp->scsa2usb_dev_state;
2144 		scsa2usbp->scsa2usb_dev_state = USB_DEV_SUSPENDED;
2145 
2146 		/*
2147 		 * If the device is busy, we cannot suspend
2148 		 */
2149 		if (SCSA2USB_BUSY(scsa2usbp)) {
2150 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2151 			    scsa2usbp->scsa2usb_log_handle,
2152 			    "scsa2usb_cpr_suspend: I/O active");
2153 
2154 			/* fall back to previous state */
2155 			scsa2usbp->scsa2usb_dev_state = prev_state;
2156 		} else {
2157 			rval = USB_SUCCESS;
2158 		}
2159 
2160 		break;
2161 	case USB_DEV_SUSPENDED:
2162 	default:
2163 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2164 		    "scsa2usb_cpr_suspend: Illegal dev state: %d",
2165 		    scsa2usbp->scsa2usb_dev_state);
2166 
2167 		break;
2168 	}
2169 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2170 
2171 	if ((rval == USB_SUCCESS) && scsa2usbp->scsa2usb_ugen_hdl) {
2172 		rval = usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
2173 		    DDI_SUSPEND);
2174 	}
2175 
2176 	return (rval);
2177 }
2178 
2179 
2180 /*
2181  * scsa2usb_cpr_resume:
2182  *	restore device's state
2183  */
2184 static void
2185 scsa2usb_cpr_resume(dev_info_t *dip)
2186 {
2187 	scsa2usb_state_t *scsa2usbp =
2188 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2189 
2190 	ASSERT(scsa2usbp != NULL);
2191 
2192 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2193 	    "scsa2usb_cpr_resume: dip = 0x%p", (void *)dip);
2194 
2195 	scsa2usb_restore_device_state(dip, scsa2usbp);
2196 
2197 	if (scsa2usbp->scsa2usb_ugen_hdl) {
2198 		(void) usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl,
2199 		    DDI_RESUME);
2200 	}
2201 }
2202 
2203 
2204 /*
2205  * scsa2usb_restore_device_state:
2206  *	- raise the device's power
2207  *	- reopen all the pipes
2208  */
2209 static void
2210 scsa2usb_restore_device_state(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
2211 {
2212 	uint_t	prev_state;
2213 
2214 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2215 	    "scsa2usb_restore_device_state:");
2216 
2217 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2218 	prev_state = scsa2usbp->scsa2usb_dev_state;
2219 
2220 	scsa2usb_raise_power(scsa2usbp);
2221 
2222 	ASSERT((prev_state == USB_DEV_DISCONNECTED) ||
2223 	    (prev_state == USB_DEV_SUSPENDED));
2224 
2225 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2226 
2227 	/* Check for the same device */
2228 	if (usb_check_same_device(dip, scsa2usbp->scsa2usb_log_handle,
2229 	    USB_LOG_L0, DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) {
2230 
2231 		/* change the flags to active */
2232 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2233 		scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
2234 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2235 
2236 		scsa2usb_pm_idle_component(scsa2usbp);
2237 
2238 		return;
2239 	}
2240 
2241 	/*
2242 	 * if the device had remote wakeup earlier,
2243 	 * enable it again
2244 	 */
2245 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2246 	if (scsa2usbp->scsa2usb_pm &&
2247 	    scsa2usbp->scsa2usb_pm->scsa2usb_wakeup_enabled) {
2248 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2249 		(void) usb_handle_remote_wakeup(scsa2usbp->scsa2usb_dip,
2250 		    USB_REMOTE_WAKEUP_ENABLE);
2251 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2252 	}
2253 
2254 	scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
2255 	scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
2256 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2257 
2258 	scsa2usb_pm_idle_component(scsa2usbp);
2259 }
2260 
2261 
2262 /*
2263  * SCSA entry points:
2264  *
2265  * scsa2usb_scsi_tgt_probe:
2266  * scsa functions are exported by means of the transport table
2267  * Issue a probe to get the inquiry data.
2268  */
2269 /* ARGSUSED */
2270 static int
2271 scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void))
2272 {
2273 	scsi_hba_tran_t *tran;
2274 	scsa2usb_state_t *scsa2usbp;
2275 	dev_info_t *dip = ddi_get_parent(sd->sd_dev);
2276 	int	rval;
2277 
2278 	ASSERT(dip);
2279 
2280 	tran = ddi_get_driver_private(dip);
2281 	ASSERT(tran != NULL);
2282 	scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
2283 	ASSERT(scsa2usbp);
2284 
2285 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2286 	    "scsa2usb_scsi_tgt_probe:");
2287 
2288 	/* if device is disconnected (ie. pipes closed), fail immediately */
2289 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2290 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2291 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2292 
2293 		return (SCSIPROBE_FAILURE);
2294 	}
2295 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2296 
2297 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2298 	    "scsa2usb_scsi_tgt_probe: scsi_device = 0x%p", (void *)sd);
2299 
2300 	if ((rval = scsi_hba_probe(sd, waitfunc)) == SCSIPROBE_EXISTS) {
2301 		/*
2302 		 * respect the removable bit on all USB storage devices
2303 		 * unless overridden by a scsa2usb.conf entry
2304 		 */
2305 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2306 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB)) {
2307 			_NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry))
2308 			sd->sd_inq->inq_rmb = 1;
2309 		}
2310 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2311 	}
2312 
2313 	return (rval);
2314 }
2315 
2316 
2317 /*
2318  * scsa2usb_scsi_tgt_init:
2319  *	check whether we created this child ourselves
2320  */
2321 /* ARGSUSED */
2322 static int
2323 scsa2usb_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip,
2324     scsi_hba_tran_t *tran, struct scsi_device *sd)
2325 {
2326 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2327 	    tran->tran_hba_private;
2328 	int lun;
2329 	int t_len = sizeof (lun);
2330 
2331 	if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2332 	    DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2333 	    &t_len) != DDI_PROP_SUCCESS) {
2334 
2335 		return (DDI_FAILURE);
2336 	}
2337 
2338 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2339 	    "scsa2usb_scsi_tgt_init: %s, lun%d", ddi_driver_name(cdip), lun);
2340 
2341 	/* is this a child we created? */
2342 	if (scsa2usb_is_usb(cdip) == 0) {
2343 
2344 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2345 		    "scsa2usb_scsi_tgt_init: new child %s%d",
2346 		    ddi_driver_name(cdip), ddi_get_instance(cdip));
2347 
2348 		/*
2349 		 * add property "usb" so we can always verify that it
2350 		 * is our child
2351 		 */
2352 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb") !=
2353 		    DDI_PROP_SUCCESS) {
2354 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2355 			    scsa2usbp->scsa2usb_log_handle,
2356 			    "ndi_prop_create_boolean failed");
2357 
2358 			return (DDI_FAILURE);
2359 		}
2360 
2361 		usba_set_usba_device(cdip,
2362 		    usba_get_usba_device(scsa2usbp->scsa2usb_dip));
2363 
2364 		/*
2365 		 * we don't store this dip in scsa2usb_lun_dip, there
2366 		 * might be multiple dips for the same device
2367 		 */
2368 
2369 		return (DDI_SUCCESS);
2370 	}
2371 
2372 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2373 	if ((lun >= scsa2usbp->scsa2usb_n_luns) ||
2374 	    (scsa2usbp->scsa2usb_lun_dip[lun] != NULL)) {
2375 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2376 
2377 		return (DDI_FAILURE);
2378 	}
2379 
2380 	scsa2usbp->scsa2usb_lun_dip[lun] = cdip;
2381 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2382 
2383 	return (DDI_SUCCESS);
2384 }
2385 
2386 
2387 /*
2388  * scsa2usb_scsi_tgt_free:
2389  */
2390 /* ARGSUSED */
2391 static void
2392 scsa2usb_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *cdip,
2393     scsi_hba_tran_t *tran, struct scsi_device *sd)
2394 {
2395 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2396 	    tran->tran_hba_private;
2397 	int lun;
2398 	int t_len = sizeof (lun);
2399 
2400 	/* is this our child? */
2401 	if (scsa2usb_is_usb(cdip) == 0) {
2402 
2403 		return;
2404 	}
2405 
2406 	if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2407 	    DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2408 	    &t_len) != DDI_PROP_SUCCESS) {
2409 
2410 		return;
2411 	}
2412 
2413 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2414 	    "scsa2usb_scsi_tgt_free: %s lun%d", ddi_driver_name(cdip), lun);
2415 
2416 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2417 	if (lun < scsa2usbp->scsa2usb_n_luns) {
2418 		if (scsa2usbp->scsa2usb_lun_dip[lun] == cdip) {
2419 			scsa2usbp->scsa2usb_lun_dip[lun] = NULL;
2420 		}
2421 	}
2422 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2423 }
2424 
2425 
2426 /*
2427  * bus enumeration entry points
2428  */
2429 static int
2430 scsa2usb_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2431     void *arg, dev_info_t **child)
2432 {
2433 	int	circ;
2434 	int	rval;
2435 
2436 	scsa2usb_state_t *scsa2usbp =
2437 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2438 
2439 	ASSERT(scsa2usbp != NULL);
2440 
2441 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2442 	    "scsa2usb_scsi_bus_config: op=%d", op);
2443 
2444 	if (scsa2usb_scsi_bus_config_debug) {
2445 		flag |= NDI_DEVI_DEBUG;
2446 	}
2447 
2448 	ndi_devi_enter(dip, &circ);
2449 	/* create children if necessary */
2450 	if (DEVI(dip)->devi_child == NULL) {
2451 		scsa2usb_create_luns(scsa2usbp);
2452 	}
2453 
2454 	rval = ndi_busop_bus_config(dip, flag, op, arg, child, 0);
2455 
2456 	ndi_devi_exit(dip, circ);
2457 
2458 	return (rval);
2459 }
2460 
2461 
2462 static int
2463 scsa2usb_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2464     void *arg)
2465 {
2466 	scsa2usb_state_t *scsa2usbp =
2467 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2468 
2469 	int		circular_count;
2470 	int		rval = NDI_SUCCESS;
2471 	uint_t		save_flag = flag;
2472 
2473 	ASSERT(scsa2usbp != NULL);
2474 
2475 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2476 	    "scsa2usb_scsi_bus_unconfig: op=%d", op);
2477 
2478 	if (scsa2usb_scsi_bus_config_debug) {
2479 		flag |= NDI_DEVI_DEBUG;
2480 	}
2481 
2482 	/*
2483 	 * first offline and if offlining successful, then
2484 	 * remove children
2485 	 */
2486 	if (op == BUS_UNCONFIG_ALL) {
2487 		flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG);
2488 	}
2489 
2490 	ndi_devi_enter(dip, &circular_count);
2491 	rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2492 
2493 	/*
2494 	 * If unconfig is successful and not part of modunload
2495 	 * daemon, attempt to remove children.
2496 	 */
2497 	if (op == BUS_UNCONFIG_ALL && rval == NDI_SUCCESS &&
2498 	    (flag & NDI_AUTODETACH) == 0) {
2499 		flag |= NDI_DEVI_REMOVE;
2500 		rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2501 	}
2502 	ndi_devi_exit(dip, circular_count);
2503 
2504 	if ((rval != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) &&
2505 	    (save_flag & NDI_DEVI_REMOVE)) {
2506 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2507 		if (scsa2usbp->scsa2usb_warning_given != B_TRUE) {
2508 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2509 			    scsa2usbp->scsa2usb_log_handle,
2510 			    "Disconnected device was busy, "
2511 			    "please reconnect.");
2512 			scsa2usbp->scsa2usb_warning_given = B_TRUE;
2513 		}
2514 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2515 	}
2516 
2517 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2518 	    "scsa2usb_scsi_bus_unconfig: rval=%d", rval);
2519 
2520 	return (rval);
2521 }
2522 
2523 
2524 /*
2525  * scsa2usb_scsi_init_pkt:
2526  *	Set up the scsi_pkt for transport. Also initialize
2527  *	scsa2usb_cmd struct for the transport.
2528  *	NOTE: We do not do any DMA setup here as USBA framework
2529  *	does that for us.
2530  */
2531 static struct scsi_pkt *
2532 scsa2usb_scsi_init_pkt(struct scsi_address *ap,
2533     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
2534     int tgtlen, int flags, int (*callback)(), caddr_t arg)
2535 {
2536 	scsa2usb_cmd_t	 *cmd;
2537 	scsa2usb_state_t *scsa2usbp;
2538 	struct scsi_pkt	 *in_pkt = pkt;
2539 
2540 	ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
2541 
2542 	scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2543 
2544 	/* Print sync message */
2545 	if (ddi_in_panic()) {
2546 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2547 		SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2548 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2549 		/* continue so caller will not hang or complain */
2550 	}
2551 
2552 	/* allocate a pkt, if none already allocated */
2553 	if (pkt == NULL) {
2554 		if (statuslen < sizeof (struct scsi_arq_status)) {
2555 			statuslen = sizeof (struct scsi_arq_status);
2556 		}
2557 
2558 		pkt = scsi_hba_pkt_alloc(scsa2usbp->scsa2usb_dip, ap, cmdlen,
2559 		    statuslen, tgtlen, sizeof (scsa2usb_cmd_t),
2560 		    callback, arg);
2561 		if (pkt == NULL) {
2562 
2563 			return (NULL);
2564 		}
2565 
2566 		cmd = PKT2CMD(pkt);
2567 		cmd->cmd_pkt	= pkt; /* back link to pkt */
2568 		cmd->cmd_scblen	= statuslen;
2569 		cmd->cmd_cdblen	= (uchar_t)cmdlen;
2570 
2571 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2572 		cmd->cmd_tag	= scsa2usbp->scsa2usb_tag++;
2573 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2574 
2575 		cmd->cmd_bp	= bp;
2576 		/*
2577 		 * The buffer size of cmd->cmd_scb is constrained
2578 		 * to sizeof (struct scsi_arq_status), if the scblen
2579 		 * is bigger than that, we use pkt->pkt_scbp directly.
2580 		 */
2581 		if (cmd->cmd_scblen == sizeof (struct scsi_arq_status)) {
2582 			pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
2583 		}
2584 
2585 		usba_init_list(&cmd->cmd_waitQ, (usb_opaque_t)cmd,
2586 		    scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2587 	} else {
2588 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2589 		    "scsa2usb: pkt != NULL");
2590 
2591 		/* nothing to do */
2592 	}
2593 
2594 	if (bp && (bp->b_bcount != 0)) {
2595 		if ((bp_mapin_common(bp, (callback == SLEEP_FUNC) ?
2596 		    VM_SLEEP : VM_NOSLEEP)) == NULL) {
2597 			if (pkt != in_pkt) {
2598 				scsi_hba_pkt_free(ap, pkt);
2599 			}
2600 
2601 			return (NULL);
2602 		}
2603 
2604 		USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2605 		    scsa2usbp->scsa2usb_log_handle,
2606 		    "scsa2usb_scsi_init_pkt: mapped in 0x%p, addr=0x%p",
2607 		    (void *)bp, (void *)bp->b_un.b_addr);
2608 	}
2609 
2610 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2611 	    "scsa2usb_scsi_init_pkt: ap = 0x%p pkt: 0x%p\n\t"
2612 	    "bp = 0x%p cmdlen = %x stlen = 0x%x tlen = 0x%x flags = 0x%x",
2613 	    (void *)ap, (void *)pkt, (void *)bp, cmdlen, statuslen,
2614 	    tgtlen, flags);
2615 
2616 	return (pkt);
2617 }
2618 
2619 
2620 /*
2621  * scsa2usb_scsi_destroy_pkt:
2622  *	We are done with the packet. Get rid of it.
2623  */
2624 static void
2625 scsa2usb_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2626 {
2627 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
2628 	scsa2usb_state_t *scsa2usbp = ADDR2SCSA2USB(ap);
2629 
2630 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2631 	    "scsa2usb_scsi_destroy_pkt: pkt=0x%p", (void *)pkt);
2632 
2633 	usba_destroy_list(&cmd->cmd_waitQ);
2634 	scsi_hba_pkt_free(ap, pkt);
2635 }
2636 
2637 
2638 /*
2639  * scsa2usb_scsi_start:
2640  *	For each command being issued, build up the CDB
2641  *	and call scsi_transport to issue the command. This
2642  *	function is based on the assumption that USB allows
2643  *	a subset of SCSI commands. Other SCSI commands we fail.
2644  */
2645 static int
2646 scsa2usb_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2647 {
2648 	scsa2usb_cmd_t		*cmd;
2649 	scsa2usb_state_t	*scsa2usbp = ADDR2SCSA2USB(ap);
2650 	uint_t			lun = ap->a_lun;
2651 
2652 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2653 
2654 	cmd = PKT2CMD(pkt);
2655 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2656 	    "scsa2usb_scsi_start:\n\t"
2657 	    "bp: 0x%p ap: 0x%p pkt: 0x%p flag: 0x%x time: 0x%x\n\tcdb0: 0x%x "
2658 	    "dev_state: 0x%x pkt_state: 0x%x flags: 0x%x pipe_state: 0x%x",
2659 	    (void *)cmd->cmd_bp, (void *)ap, (void *)pkt, pkt->pkt_flags,
2660 	    pkt->pkt_time, pkt->pkt_cdbp[0], scsa2usbp->scsa2usb_dev_state,
2661 	    scsa2usbp->scsa2usb_pkt_state, scsa2usbp->scsa2usb_flags,
2662 	    scsa2usbp->scsa2usb_pipe_state);
2663 
2664 	if (pkt->pkt_time == 0) {
2665 		USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2666 		    "pkt submitted with 0 timeout which may cause indefinite "
2667 		    "hangs");
2668 	}
2669 
2670 	/*
2671 	 * if we are in panic, we are in polled mode, so we can just
2672 	 * accept the request, drop it and return
2673 	 * if we fail this request, the rest of the file systems do not
2674 	 * get synced
2675 	 */
2676 	if (ddi_in_panic()) {
2677 		extern int do_polled_io;
2678 
2679 		ASSERT(do_polled_io);
2680 		scsa2usb_prepare_pkt(scsa2usbp, pkt);
2681 		SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2682 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2683 
2684 		return (TRAN_ACCEPT);
2685 	}
2686 
2687 	/* we cannot do polling, this should not happen */
2688 	if (pkt->pkt_flags & FLAG_NOINTR) {
2689 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2690 		    "NOINTR packet: opcode = 0%x", pkt->pkt_cdbp[0]);
2691 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2692 
2693 		return (TRAN_BADPKT);
2694 	}
2695 
2696 	/* prepare packet */
2697 	scsa2usb_prepare_pkt(scsa2usbp, pkt);
2698 
2699 	/* just queue up the requests in the waitQ if below max */
2700 	if (usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]) >
2701 	    SCSA2USB_MAX_REQ_PER_LUN) {
2702 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2703 		    scsa2usbp->scsa2usb_log_handle,
2704 		    "scsa2usb_scsi_start: limit (%d) exceeded",
2705 		    SCSA2USB_MAX_REQ_PER_LUN);
2706 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2707 
2708 		return (TRAN_BUSY);
2709 	}
2710 
2711 	usba_add_to_list(&scsa2usbp->scsa2usb_waitQ[lun], &cmd->cmd_waitQ);
2712 
2713 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2714 	    "scsa2usb_work_thread_id=0x%p, count=%d, lun=%d",
2715 	    (void *)scsa2usbp->scsa2usb_work_thread_id,
2716 	    usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]), lun);
2717 
2718 	/* fire up a thread to start executing the protocol */
2719 	if (scsa2usbp->scsa2usb_work_thread_id == 0) {
2720 		if ((usb_async_req(scsa2usbp->scsa2usb_dip,
2721 		    scsa2usb_work_thread,
2722 		    (void *)scsa2usbp, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
2723 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2724 			    scsa2usbp->scsa2usb_log_handle,
2725 			    "no work thread started");
2726 
2727 			if (usba_rm_from_list(
2728 			    &scsa2usbp->scsa2usb_waitQ[lun],
2729 			    &cmd->cmd_waitQ) == USB_SUCCESS) {
2730 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
2731 
2732 				return (TRAN_BUSY);
2733 			} else {
2734 
2735 				mutex_exit(&scsa2usbp->scsa2usb_mutex);
2736 
2737 				return (TRAN_ACCEPT);
2738 			}
2739 		}
2740 		scsa2usbp->scsa2usb_work_thread_id = (kthread_t *)1;
2741 	}
2742 
2743 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2744 
2745 	return (TRAN_ACCEPT);
2746 }
2747 
2748 
2749 /*
2750  * scsa2usb_scsi_abort:
2751  *	Issue SCSI abort command. This function is a NOP.
2752  */
2753 /* ARGSUSED */
2754 static int
2755 scsa2usb_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
2756 {
2757 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2758 
2759 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2760 	    "scsa2usb_scsi_abort: pkt = %p", (void *)pkt);
2761 
2762 	/* if device is disconnected (ie. pipes closed), fail immediately */
2763 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2764 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2765 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2766 
2767 		return (0);
2768 	}
2769 
2770 	/* flush waitQ if target and lun match */
2771 	if ((ap->a_target == pkt->pkt_address.a_target) &&
2772 	    (ap->a_lun == pkt->pkt_address.a_lun)) {
2773 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2774 		scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_ABORTED);
2775 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
2776 	}
2777 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2778 
2779 	return (0);
2780 }
2781 
2782 
2783 /*
2784  * scsa2usb_scsi_reset:
2785  *	device reset may turn the device into a brick and bus reset
2786  *	is not applicable.
2787  *	just flush the waitQ
2788  *	We return success, always.
2789  */
2790 /* ARGSUSED */
2791 static int
2792 scsa2usb_scsi_reset(struct scsi_address *ap, int level)
2793 {
2794 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2795 
2796 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2797 	    "scsa2usb_scsi_reset: ap = 0x%p, level = %d", (void *)ap, level);
2798 
2799 	/* flush waitQ */
2800 	scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_RESET);
2801 
2802 	return (1);
2803 }
2804 
2805 
2806 /*
2807  * scsa2usb_scsi_getcap:
2808  *	Get SCSI capabilities.
2809  */
2810 /* ARGSUSED */
2811 static int
2812 scsa2usb_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
2813 {
2814 	int rval = -1;
2815 	uint_t cidx;
2816 	size_t dev_bsize_cap;
2817 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2818 	ASSERT(scsa2usbp);
2819 
2820 	if (cap == NULL) {
2821 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2822 		    "scsa2usb_scsi_getcap: invalid arg, "
2823 		    "cap = 0x%p whom = %d", (void *)cap, whom);
2824 
2825 		return (rval);
2826 	}
2827 
2828 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2829 	    "scsa2usb_scsi_getcap: cap = %s", cap);
2830 
2831 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2832 
2833 	/* if device is disconnected (ie. pipes closed), fail immediately */
2834 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2835 
2836 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2837 
2838 		return (rval);
2839 	}
2840 
2841 	cidx =	scsi_hba_lookup_capstr(cap);
2842 	switch (cidx) {
2843 	case SCSI_CAP_GEOMETRY:
2844 		/* Just check and fail immediately if zero, rarely happens */
2845 		if (scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0) {
2846 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2847 			    scsa2usbp->scsa2usb_log_handle,
2848 			    "scsa2usb_scsi_getcap failed:"
2849 			    "scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0");
2850 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
2851 
2852 			return (rval);
2853 		}
2854 
2855 		dev_bsize_cap = scsa2usbp->scsa2usb_totalsec[ap->a_lun];
2856 
2857 		if (scsa2usbp->scsa2usb_secsz[ap->a_lun] > DEV_BSIZE) {
2858 			dev_bsize_cap *=
2859 			    scsa2usbp->scsa2usb_secsz[ap->a_lun] / DEV_BSIZE;
2860 		} else if (scsa2usbp->scsa2usb_secsz[ap->a_lun] <
2861 		    DEV_BSIZE) {
2862 			dev_bsize_cap /=
2863 			    DEV_BSIZE / scsa2usbp->scsa2usb_secsz[ap->a_lun];
2864 		}
2865 
2866 		if (dev_bsize_cap < 65536 * 2 * 18) {		/* < ~1GB */
2867 			/* unlabeled floppy, 18k per cylinder */
2868 			rval = ((2 << 16) | 18);
2869 		} else if (dev_bsize_cap < 65536 * 64 * 32) {	/* < 64GB */
2870 			/* 1024k per cylinder */
2871 			rval = ((64 << 16) | 32);
2872 		} else if (dev_bsize_cap < 65536 * 255 * 63) {	/* < ~500GB */
2873 			/* ~8m per cylinder */
2874 			rval = ((255 << 16) | 63);
2875 		} else {					/* .. 8TB */
2876 			/* 64m per cylinder */
2877 			rval = ((512 << 16) | 256);
2878 		}
2879 		break;
2880 
2881 	case SCSI_CAP_DMA_MAX:
2882 		rval = scsa2usbp->scsa2usb_max_bulk_xfer_size;
2883 		break;
2884 	case SCSI_CAP_SCSI_VERSION:
2885 		rval = SCSI_VERSION_2;
2886 		break;
2887 	case SCSI_CAP_INTERCONNECT_TYPE:
2888 		rval = INTERCONNECT_USB;
2889 		break;
2890 	case SCSI_CAP_ARQ:
2891 		/* FALLTHRU */
2892 	case SCSI_CAP_UNTAGGED_QING:
2893 		rval = 1;
2894 		break;
2895 	default:
2896 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2897 		    "scsa2usb_scsi_getcap: unsupported cap = %s", cap);
2898 		break;
2899 	}
2900 
2901 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2902 	    "scsa2usb_scsi_getcap: cap = %s, returned = %d", cap, rval);
2903 
2904 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2905 
2906 	return (rval);
2907 }
2908 
2909 
2910 /*
2911  * scsa2usb_scsi_setcap:
2912  *	Set SCSI capabilities.
2913  */
2914 /* ARGSUSED */
2915 static int
2916 scsa2usb_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
2917 {
2918 	int rval = -1; /* default is cap undefined */
2919 	uint_t cidx;
2920 	scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2921 	ASSERT(scsa2usbp);
2922 
2923 	if (cap == NULL || whom == 0) {
2924 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2925 		    "scsa2usb_scsi_setcap: invalid arg");
2926 
2927 		return (rval);
2928 	}
2929 
2930 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
2931 	/* if device is disconnected (ie. pipes closed), fail immediately */
2932 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2933 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
2934 
2935 		return (rval);
2936 	}
2937 
2938 	cidx =	scsi_hba_lookup_capstr(cap);
2939 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2940 	    "scsa2usb_scsi_setcap: ap = 0x%p value = 0x%x whom = 0x%x "
2941 	    "cidx = 0x%x", (void *)ap, value, whom, cidx);
2942 
2943 	switch (cidx) {
2944 	case SCSI_CAP_SECTOR_SIZE:
2945 		if (value) {
2946 			scsa2usbp->scsa2usb_secsz[ap->a_lun] = value;
2947 		}
2948 		break;
2949 	case SCSI_CAP_TOTAL_SECTORS:
2950 		if (value) {
2951 			scsa2usbp->scsa2usb_totalsec[ap->a_lun] = value;
2952 		}
2953 		break;
2954 	case SCSI_CAP_ARQ:
2955 		rval = 1;
2956 		break;
2957 	case SCSI_CAP_DMA_MAX:
2958 	case SCSI_CAP_SCSI_VERSION:
2959 	case SCSI_CAP_INTERCONNECT_TYPE:
2960 	case SCSI_CAP_UNTAGGED_QING:
2961 		/* supported but not settable */
2962 		rval = 0;
2963 		break;
2964 	default:
2965 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2966 		    "scsa2usb_scsi_setcap: unsupported cap = %s", cap);
2967 		break;
2968 	}
2969 
2970 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
2971 
2972 	return (rval);
2973 }
2974 
2975 
2976 /*
2977  * scsa2usb - cmd and transport stuff
2978  */
2979 /*
2980  * scsa2usb_prepare_pkt:
2981  *	initialize some fields of the pkt and cmd
2982  *	(the pkt may have been resubmitted/retried)
2983  */
2984 static void
2985 scsa2usb_prepare_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
2986 {
2987 	scsa2usb_cmd_t	*cmd = PKT2CMD(pkt);
2988 
2989 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2990 	    "scsa2usb_prepare_pkt: pkt=0x%p cdb: 0x%x (%s)",
2991 	    (void *)pkt, pkt->pkt_cdbp[0],
2992 	    scsi_cname(pkt->pkt_cdbp[0], scsa2usb_cmds));
2993 
2994 	pkt->pkt_reason = CMD_CMPLT;	/* Set reason to pkt_complete */
2995 	pkt->pkt_state = 0;		/* Reset next three fields */
2996 	pkt->pkt_statistics = 0;
2997 	pkt->pkt_resid = 0;
2998 	bzero(pkt->pkt_scbp, cmd->cmd_scblen); /* Set status to good */
2999 
3000 	if (cmd) {
3001 		cmd->cmd_timeout = pkt->pkt_time;
3002 		cmd->cmd_xfercount = 0;		/* Reset the fields */
3003 		cmd->cmd_total_xfercount = 0;
3004 		cmd->cmd_lba = 0;
3005 		cmd->cmd_done = 0;
3006 		cmd->cmd_dir = 0;
3007 		cmd->cmd_offset = 0;
3008 		cmd->cmd_actual_len = cmd->cmd_cdblen;
3009 	}
3010 }
3011 
3012 
3013 /*
3014  * scsa2usb_force_invalid_request
3015  */
3016 static void
3017 scsa2usb_force_invalid_request(scsa2usb_state_t *scsa2usbp,
3018     scsa2usb_cmd_t *cmd)
3019 {
3020 	struct scsi_arq_status	*arqp;
3021 
3022 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3023 	    "scsa2usb_force_invalid_request: pkt = 0x%p", (void *)cmd->cmd_pkt);
3024 
3025 	if (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) {
3026 		arqp = (struct scsi_arq_status *)cmd->cmd_pkt->pkt_scbp;
3027 		bzero(arqp, cmd->cmd_scblen);
3028 
3029 		arqp->sts_status.sts_chk = 1;
3030 		arqp->sts_rqpkt_reason = CMD_CMPLT;
3031 		arqp->sts_rqpkt_state = STATE_XFERRED_DATA |
3032 		    STATE_GOT_BUS | STATE_GOT_STATUS;
3033 		arqp->sts_sensedata.es_valid = 1;
3034 		arqp->sts_sensedata.es_class = 7;
3035 		arqp->sts_sensedata.es_key = KEY_ILLEGAL_REQUEST;
3036 
3037 		cmd->cmd_pkt->pkt_state = STATE_ARQ_DONE |
3038 		    STATE_GOT_BUS | STATE_GOT_BUS | STATE_GOT_BUS |
3039 		    STATE_GOT_STATUS;
3040 #ifdef DEBUG
3041 		{
3042 			uchar_t *p = (uchar_t *)(&arqp->sts_sensedata);
3043 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3044 			    scsa2usbp->scsa2usb_log_handle,
3045 			    "cdb: %x rqsense: "
3046 			    "%x %x %x %x %x %x %x %x %x %x "
3047 			    "%x %x %x %x %x %x %x %x %x %x",
3048 			    cmd->cmd_pkt->pkt_cdbp[0],
3049 			    p[0], p[1], p[2], p[3], p[4],
3050 			    p[5], p[6], p[7], p[8], p[9],
3051 			    p[10], p[11], p[12], p[13], p[14],
3052 			    p[15], p[16], p[17], p[18], p[19]);
3053 		}
3054 #endif
3055 
3056 	}
3057 }
3058 
3059 
3060 static int
3061 scsa2usb_cmd_transport(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3062 {
3063 	int rval, transport;
3064 	struct scsi_pkt *pkt;
3065 
3066 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3067 	    "scsa2usb_cmd_transport: pkt: 0x%p, cur_pkt = 0x%p",
3068 	    (void *)cmd->cmd_pkt, (void *)scsa2usbp->scsa2usb_cur_pkt);
3069 
3070 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3071 	ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
3072 
3073 	pkt = scsa2usbp->scsa2usb_cur_pkt = cmd->cmd_pkt;
3074 
3075 	/*
3076 	 * Check per-device quirks first:
3077 	 */
3078 	if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
3079 		transport = scsa2usb_check_bulkonly_quirks(scsa2usbp, cmd);
3080 	} else if (SCSA2USB_IS_CB(scsa2usbp) || SCSA2USB_IS_CBI(scsa2usbp)) {
3081 		transport = scsa2usb_check_ufi_quirks(scsa2usbp, cmd);
3082 	} else {
3083 		return (TRAN_FATAL_ERROR);
3084 	}
3085 
3086 	/* just accept the command or return error */
3087 	if (transport == SCSA2USB_JUST_ACCEPT) {
3088 		SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3089 
3090 		return (TRAN_ACCEPT);
3091 	} else if (transport == SCSA2USB_REJECT) {
3092 		return (TRAN_FATAL_ERROR);
3093 	}
3094 
3095 	/* check command set next */
3096 	if (SCSA2USB_IS_SCSI_CMDSET(scsa2usbp) ||
3097 	    SCSA2USB_IS_ATAPI_CMDSET(scsa2usbp)) {
3098 		transport =
3099 		    scsa2usb_handle_scsi_cmd_sub_class(scsa2usbp, cmd, pkt);
3100 	} else if (SCSA2USB_IS_UFI_CMDSET(scsa2usbp)) {
3101 		transport =
3102 		    scsa2usb_handle_ufi_subclass_cmd(scsa2usbp, cmd, pkt);
3103 	} else {
3104 		transport = SCSA2USB_REJECT;
3105 	}
3106 
3107 	switch (transport) {
3108 	case SCSA2USB_TRANSPORT:
3109 		if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
3110 			rval = scsa2usb_bulk_only_transport(scsa2usbp, cmd);
3111 		} else if (SCSA2USB_IS_CB(scsa2usbp) ||
3112 		    SCSA2USB_IS_CBI(scsa2usbp)) {
3113 			rval = scsa2usb_cbi_transport(scsa2usbp, cmd);
3114 		} else {
3115 			rval = TRAN_FATAL_ERROR;
3116 		}
3117 		break;
3118 	case SCSA2USB_JUST_ACCEPT:
3119 		SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3120 		rval = TRAN_ACCEPT;
3121 		break;
3122 	default:
3123 		rval = TRAN_FATAL_ERROR;
3124 	}
3125 
3126 	return (rval);
3127 }
3128 
3129 
3130 /*
3131  * Check this Bulk Only command against the quirks for this particular device.
3132  * Returns a transport disposition.
3133  */
3134 int
3135 scsa2usb_check_bulkonly_quirks(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3136 {
3137 	struct scsi_inquiry *inq =
3138 	    &scsa2usbp->scsa2usb_lun_inquiry[cmd->cmd_pkt->pkt_address.a_lun];
3139 
3140 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3141 
3142 	/*
3143 	 * decode and convert the packet
3144 	 * for most cmds, we can bcopy the cdb
3145 	 */
3146 	switch (cmd->cmd_pkt->pkt_cdbp[0]) {
3147 	case SCMD_DOORLOCK:
3148 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_DOORLOCK)) {
3149 
3150 			return (SCSA2USB_JUST_ACCEPT);
3151 
3152 		/*
3153 		 * only lock the door for CD and DVD drives
3154 		 */
3155 		} else if ((inq->inq_dtype == DTYPE_RODIRECT) ||
3156 		    (inq->inq_dtype == DTYPE_OPTICAL)) {
3157 
3158 			if (inq->inq_rmb) {
3159 
3160 				break;
3161 			}
3162 		}
3163 
3164 		return (SCSA2USB_JUST_ACCEPT);
3165 
3166 	case SCMD_START_STOP:	/* SCMD_LOAD for sequential devices */
3167 		/*
3168 		 * these devices don't have mechanics that spin the
3169 		 * media up and down. So, it doesn't make much sense
3170 		 * to issue this cmd.
3171 		 *
3172 		 * Furthermore, Hagiwara devices do not handle these
3173 		 * cmds well. just accept this command as success.
3174 		 */
3175 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3176 
3177 			return (SCSA2USB_JUST_ACCEPT);
3178 
3179 		} else if (inq->inq_dtype == DTYPE_SEQUENTIAL) {
3180 			/*
3181 			 * In case of USB tape device, we need to send the
3182 			 * command to the device to unload the media.
3183 			 */
3184 			break;
3185 
3186 		} else if (cmd->cmd_pkt->pkt_cdbp[4] & LOEJECT) {
3187 			/*
3188 			 * if the device is really a removable then
3189 			 * pass it on to the device, else just accept
3190 			 */
3191 			if (inq->inq_rmb) {
3192 
3193 				break;
3194 			}
3195 
3196 			return (SCSA2USB_JUST_ACCEPT);
3197 
3198 		} else if (!scsa2usbp->scsa2usb_rcvd_not_ready) {
3199 			/*
3200 			 * if we have not received a NOT READY condition,
3201 			 * just accept since some device choke on this too.
3202 			 * we do have to let EJECT get through though
3203 			 */
3204 			return (SCSA2USB_JUST_ACCEPT);
3205 		}
3206 
3207 		break;
3208 	case SCMD_INQUIRY:
3209 		/*
3210 		 * Some devices do not handle the inquiry cmd well
3211 		 * so build an inquiry and accept this command as
3212 		 * success.
3213 		 */
3214 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3215 			uchar_t evpd = 0x01;
3216 			unsigned int bufsize;
3217 			int count;
3218 
3219 			if (cmd->cmd_pkt->pkt_cdbp[1] & evpd)
3220 				return (SCSA2USB_REJECT);
3221 
3222 			scsa2usb_fake_inquiry(scsa2usbp, inq);
3223 
3224 			/* Copy no more than requested */
3225 			count = MIN(cmd->cmd_bp->b_bcount,
3226 			    sizeof (struct scsi_inquiry));
3227 			bufsize = cmd->cmd_pkt->pkt_cdbp[4];
3228 			count = MIN(count, bufsize);
3229 			bcopy(inq, cmd->cmd_bp->b_un.b_addr, count);
3230 
3231 			cmd->cmd_pkt->pkt_resid = bufsize - count;
3232 			cmd->cmd_pkt->pkt_state |= STATE_XFERRED_DATA;
3233 
3234 			return (SCSA2USB_JUST_ACCEPT);
3235 		} else if (!(scsa2usbp->scsa2usb_attrs &
3236 		    SCSA2USB_ATTRS_INQUIRY_EVPD)) {
3237 			/*
3238 			 * Some devices do not handle the inquiry cmd with
3239 			 * evpd bit set well, e.g. some devices return the
3240 			 * same page 0x83 data which will cause the generated
3241 			 * devid by sd is not unique, thus return CHECK
3242 			 * CONDITION directly to sd.
3243 			 */
3244 			uchar_t evpd = 0x01;
3245 
3246 			if (!(cmd->cmd_pkt->pkt_cdbp[1] & evpd))
3247 				break;
3248 
3249 			if (cmd->cmd_bp) {
3250 				cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3251 				    b_bcount;
3252 			}
3253 			scsa2usb_force_invalid_request(scsa2usbp, cmd);
3254 
3255 			return (SCSA2USB_JUST_ACCEPT);
3256 		}
3257 		break;
3258 	/*
3259 	 * Fake accepting the following  Opcodes
3260 	 * (as most drives don't support these)
3261 	 * These are needed by format command.
3262 	 */
3263 	case SCMD_RESERVE:
3264 	case SCMD_RELEASE:
3265 	case SCMD_PERSISTENT_RESERVE_IN:
3266 	case SCMD_PERSISTENT_RESERVE_OUT:
3267 
3268 		return (SCSA2USB_JUST_ACCEPT);
3269 
3270 	case SCMD_MODE_SENSE:
3271 	case SCMD_MODE_SELECT:
3272 	case SCMD_MODE_SENSE_G1:
3273 	case SCMD_MODE_SELECT_G1:
3274 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_MODE_SENSE)) {
3275 			if (cmd->cmd_bp) {
3276 				cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3277 				    b_bcount;
3278 			}
3279 			scsa2usb_force_invalid_request(scsa2usbp, cmd);
3280 
3281 			return (SCSA2USB_JUST_ACCEPT);
3282 		}
3283 
3284 		break;
3285 	default:
3286 
3287 		break;
3288 	}
3289 
3290 	return (SCSA2USB_TRANSPORT);
3291 }
3292 
3293 
3294 /*
3295  * scsa2usb_handle_scsi_cmd_sub_class:
3296  *	prepare a scsi cmd
3297  *	returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT, SCSA2USB_JUST_ACCEPT
3298  */
3299 int
3300 scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *scsa2usbp,
3301     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3302 {
3303 	uchar_t evpd = 0x01;
3304 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3305 	    "scsa2usb_handle_scsi_cmd_sub_class: cmd = 0x%p pkt = 0x%p",
3306 	    (void *)cmd, (void *)pkt);
3307 
3308 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3309 
3310 	bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3311 	cmd->cmd_cdb[SCSA2USB_OPCODE] = pkt->pkt_cdbp[0];   /* Set the opcode */
3312 	cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3313 
3314 	/*
3315 	 * decode and convert the packet
3316 	 * for most cmds, we can bcopy the cdb
3317 	 */
3318 	switch (pkt->pkt_cdbp[0]) {
3319 	case SCMD_FORMAT:
3320 		/*
3321 		 * SCMD_FORMAT used to limit cmd->cmd_xfercount
3322 		 * to 4 bytes, but this hangs
3323 		 * formatting dvd media using cdrecord (that is,
3324 		 * a SCSI FORMAT UNIT command with a parameter list > 4 bytes)
3325 		 * (bit 4 in cdb1 is the Fmtdata bit)
3326 		 */
3327 		if ((pkt->pkt_cdbp[1] & 0x10) && cmd->cmd_bp) {
3328 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3329 		} else {
3330 			cmd->cmd_xfercount = 4;
3331 		}
3332 		cmd->cmd_dir = CBW_DIR_OUT;
3333 		cmd->cmd_actual_len = CDB_GROUP0;
3334 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3335 		break;
3336 
3337 	case SCMD_INQUIRY:
3338 		cmd->cmd_dir = CBW_DIR_IN;
3339 		cmd->cmd_actual_len = CDB_GROUP0;
3340 		cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3341 
3342 		/*
3343 		 * If vpd pages data is limited to maximum SCSA2USB_MAX_INQ_LEN,
3344 		 * the page data may be truncated, which may cause some issues
3345 		 * such as making the unique page 0x83 or 0x80 data from
3346 		 * different devices become the same. So don't limit return
3347 		 * length for vpd page inquiry cmd.
3348 		 * Another, in order to maintain compatibility, the original
3349 		 * length limitation for standard inquiry retains here. It
3350 		 * can be removed in future if it is verified that enough
3351 		 * devices can work well.
3352 		 */
3353 		if (pkt->pkt_cdbp[1] & evpd) {
3354 			cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3355 			    (cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3356 		} else {
3357 			cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3358 			    min(SCSA2USB_MAX_INQ_LEN,
3359 			    cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3360 		}
3361 		break;
3362 
3363 	case SCMD_READ_CAPACITY:
3364 		cmd->cmd_dir = CBW_DIR_IN;
3365 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3366 		cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3367 		break;
3368 
3369 	/*
3370 	 * SCMD_READ/SCMD_WRITE are converted to G1 cmds
3371 	 * (as ATAPI devices don't recognize G0 commands)
3372 	 *
3373 	 * SCMD_READ_LONG/SCMD_WRITE_LONG are handled in
3374 	 * scsa2usb_rw_transport() along with other commands.
3375 	 *
3376 	 * USB Host Controllers cannot handle large (read/write)
3377 	 * xfers. We split the large request to chunks of
3378 	 * smaller ones to meet the HCD limitations.
3379 	 */
3380 	case SCMD_READ:
3381 	case SCMD_WRITE:
3382 	case SCMD_READ_G1:
3383 	case SCMD_WRITE_G1:
3384 	case SCMD_READ_G4:
3385 	case SCMD_WRITE_G4:
3386 	case SCMD_READ_G5:
3387 	case SCMD_WRITE_G5:
3388 	case SCMD_READ_LONG:
3389 	case SCMD_WRITE_LONG:
3390 	case SCMD_READ_CD:
3391 		switch (scsa2usbp->
3392 		    scsa2usb_lun_inquiry[pkt->pkt_address.a_lun].
3393 		    inq_dtype & DTYPE_MASK) {
3394 		case DTYPE_DIRECT:
3395 		case DTYPE_RODIRECT:
3396 		case DTYPE_OPTICAL:
3397 			return (scsa2usb_rw_transport(
3398 			    scsa2usbp, pkt));
3399 		default:
3400 			bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3401 			if (cmd->cmd_bp) {
3402 				cmd->cmd_dir =
3403 				    (cmd->cmd_bp->b_flags & B_READ) ?
3404 				    CBW_DIR_IN : CBW_DIR_OUT;
3405 				cmd->cmd_xfercount =
3406 				    cmd->cmd_bp->b_bcount;
3407 			}
3408 			break;
3409 		}
3410 		break;
3411 
3412 	case SCMD_REQUEST_SENSE:
3413 		cmd->cmd_dir = CBW_DIR_IN;
3414 		cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3415 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3416 		cmd->cmd_actual_len = CDB_GROUP0;
3417 		break;
3418 
3419 	case SCMD_DOORLOCK:
3420 	case SCMD_START_STOP:
3421 	case SCMD_TEST_UNIT_READY:
3422 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3423 		break;
3424 
3425 	/*
3426 	 * Needed by zip protocol to reset the device
3427 	 */
3428 	case SCMD_SDIAG:
3429 	case SCMD_REZERO_UNIT:
3430 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3431 		cmd->cmd_actual_len = CDB_GROUP1;
3432 		break;
3433 
3434 	case SCMD_WRITE_VERIFY:
3435 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3436 		cmd->cmd_dir = CBW_DIR_OUT;
3437 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3438 		cmd->cmd_actual_len = CDB_GROUP1;
3439 		break;
3440 
3441 	/*
3442 	 * Next command does not have a SCSI equivalent as
3443 	 * it is vendor specific.
3444 	 * It was listed in the vendor's ATAPI Zip specs.
3445 	 */
3446 	case SCMD_READ_FORMAT_CAP:
3447 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3448 		cmd->cmd_dir = CBW_DIR_IN;
3449 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3450 		cmd->cmd_actual_len = CDB_GROUP1;
3451 		break;
3452 	case IOMEGA_CMD_CARTRIDGE_PROTECT:
3453 		cmd->cmd_dir = CBW_DIR_OUT;
3454 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3455 		cmd->cmd_cdb[SCSA2USB_LBA_2] &= ~1;	/* Make it even */
3456 		cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3457 		cmd->cmd_actual_len = CDB_GROUP0;
3458 		cmd->cmd_xfercount = pkt->pkt_cdbp[4]; /* Length of password */
3459 		break;
3460 
3461 	/*
3462 	 * Do not convert SCMD_MODE_SENSE/SELECT to G1 cmds because
3463 	 * the mode header is different as well. USB devices don't
3464 	 * support 0x03 & 0x04 mode pages, which are already obsoleted
3465 	 * by SPC-2 specification.
3466 	 */
3467 	case SCMD_MODE_SENSE:
3468 	case SCMD_MODE_SELECT:
3469 		if (((pkt->pkt_cdbp[2] & SD_MODE_SENSE_PAGE_MASK)
3470 		    == SD_MODE_SENSE_PAGE3_CODE) ||
3471 		    ((pkt->pkt_cdbp[2] & SD_MODE_SENSE_PAGE_MASK)
3472 		    == SD_MODE_SENSE_PAGE4_CODE)) {
3473 			if (cmd->cmd_bp) {
3474 				cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3475 			}
3476 			scsa2usb_force_invalid_request(scsa2usbp, cmd);
3477 			return (SCSA2USB_JUST_ACCEPT);
3478 		}
3479 		/* FALLTHROUGH */
3480 
3481 	default:
3482 		/*
3483 		 * an unknown command may be a uscsi cmd which we
3484 		 * should let go thru without mapping
3485 		 */
3486 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3487 		if (cmd->cmd_bp) {
3488 			cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3489 			    CBW_DIR_IN : CBW_DIR_OUT;
3490 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3491 		}
3492 
3493 		break;
3494 	} /* end of switch */
3495 
3496 	USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3497 	    "scsa2usb_handle_scsi_cmd_sub_class: opcode = 0x%x count = 0x%lx",
3498 	    pkt->pkt_cdbp[SCSA2USB_OPCODE], cmd->cmd_xfercount);
3499 
3500 	cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3501 
3502 	return (SCSA2USB_TRANSPORT);
3503 }
3504 
3505 
3506 /*
3507  * scsa2usb_do_tur is performed before READ CAPACITY command is issued.
3508  * It returns media status, 0 for media ready, -1 for media not ready
3509  * or other errors.
3510  */
3511 static int
3512 scsa2usb_do_tur(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
3513 {
3514 	struct scsi_pkt		*pkt;
3515 	scsa2usb_cmd_t		*turcmd;
3516 	int			rval = -1;
3517 
3518 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3519 	    "scsa2usb_do_tur:");
3520 
3521 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3522 
3523 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3524 	if ((pkt = scsi_init_pkt(ap, NULL, NULL, CDB_GROUP0, 1,
3525 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL)) == NULL) {
3526 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
3527 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3528 		    scsa2usbp->scsa2usb_log_handle,
3529 		    "scsa2usb_do_tur: init pkt failed");
3530 
3531 		return (rval);
3532 	}
3533 
3534 	RQ_MAKECOM_G0(pkt, FLAG_HEAD | FLAG_NODISCON,
3535 	    (char)SCMD_TEST_UNIT_READY, 0, 0);
3536 
3537 	pkt->pkt_comp = NULL;
3538 	pkt->pkt_time = PKT_DEFAULT_TIMEOUT;
3539 	turcmd = PKT2CMD(pkt);
3540 
3541 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3542 	scsa2usb_prepare_pkt(scsa2usbp, turcmd->cmd_pkt);
3543 
3544 	if (scsa2usb_cmd_transport(scsa2usbp, turcmd) != TRAN_ACCEPT) {
3545 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3546 		    scsa2usbp->scsa2usb_log_handle,
3547 		    "scsa2usb_do_tur: cmd transport failed, "
3548 		    "pkt_reason=0x%x", turcmd->cmd_pkt->pkt_reason);
3549 	} else if (*(turcmd->cmd_pkt->pkt_scbp) != STATUS_GOOD) {
3550 		/*
3551 		 * Theoretically, the sense data should be retrieved and
3552 		 * sense key be checked when check condition happens. If
3553 		 * the sense key is UNIT ATTENTION, TEST UNIT READY cmd
3554 		 * needs to be sent again to clear the UNIT ATTENTION and
3555 		 * another TUR to be sent to get the real media status.
3556 		 * But the AMI virtual floppy device simply cannot recover
3557 		 * from UNIT ATTENTION by re-sending a TUR cmd, so it
3558 		 * doesn't make any difference whether to check sense key
3559 		 * or not. Just ignore sense key checking here and assume
3560 		 * the device is NOT READY.
3561 		 */
3562 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3563 		    scsa2usbp->scsa2usb_log_handle,
3564 		    "scsa2usb_do_tur: media not ready");
3565 	} else {
3566 		rval = 0;
3567 	}
3568 
3569 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
3570 	scsi_destroy_pkt(pkt);
3571 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
3572 
3573 	return (rval);
3574 }
3575 
3576 
3577 /*
3578  * Check this UFI command against the quirks for this particular device.
3579  * Returns a transport disposition.
3580  */
3581 static int
3582 scsa2usb_check_ufi_quirks(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3583 {
3584 	int rval = SCSA2USB_TRANSPORT;
3585 
3586 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3587 
3588 	switch (cmd->cmd_pkt->pkt_cdbp[0]) {
3589 	case SCMD_PRIN:
3590 	case SCMD_PROUT:
3591 		rval = SCSA2USB_JUST_ACCEPT;
3592 		break;
3593 	case SCMD_MODE_SENSE:
3594 	case SCMD_MODE_SELECT:
3595 		if (cmd->cmd_bp) {
3596 			cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3597 		}
3598 		scsa2usb_force_invalid_request(scsa2usbp, cmd);
3599 		rval = SCSA2USB_JUST_ACCEPT;
3600 		break;
3601 	case SCMD_GET_CONFIGURATION:
3602 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_CONF)) {
3603 			rval = SCSA2USB_JUST_ACCEPT;
3604 		}
3605 		break;
3606 	case SCMD_GET_PERFORMANCE:
3607 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_PERF)) {
3608 			rval = SCSA2USB_JUST_ACCEPT;
3609 		}
3610 		break;
3611 	case SCMD_START_STOP:
3612 		/*
3613 		 * some CB/CBI devices don't have mechanics that spin the
3614 		 * media up and down. So, it doesn't make much sense
3615 		 * to issue this cmd to those devices.
3616 		 */
3617 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3618 			rval = SCSA2USB_JUST_ACCEPT;
3619 		}
3620 		break;
3621 	case SCMD_READ_CAPACITY:
3622 		/*
3623 		 * Some devices don't support READ CAPACITY command
3624 		 * when media is not ready. Need to check media status
3625 		 * before issuing the cmd to such device.
3626 		 */
3627 		if (!(scsa2usbp->scsa2usb_attrs &
3628 		    SCSA2USB_ATTRS_NO_MEDIA_CHECK)) {
3629 			struct scsi_pkt *pkt = cmd->cmd_pkt;
3630 
3631 			ASSERT(scsa2usbp->scsa2usb_cur_pkt == pkt);
3632 			scsa2usbp->scsa2usb_cur_pkt = NULL;
3633 
3634 			if (scsa2usb_do_tur(scsa2usbp,
3635 			    &pkt->pkt_address) != 0) {
3636 				/* media not ready, force cmd invalid */
3637 				if (cmd->cmd_bp) {
3638 					cmd->cmd_pkt->pkt_resid =
3639 					    cmd->cmd_bp->b_bcount;
3640 				}
3641 				scsa2usb_force_invalid_request(scsa2usbp, cmd);
3642 				rval = SCSA2USB_JUST_ACCEPT;
3643 			}
3644 
3645 			scsa2usbp->scsa2usb_cur_pkt = pkt;
3646 		}
3647 		break;
3648 	default:
3649 		break;
3650 	}
3651 
3652 	return (rval);
3653 }
3654 
3655 
3656 /*
3657  * scsa2usb_handle_ufi_subclass_cmd:
3658  *	prepare a UFI cmd
3659  *	returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT
3660  */
3661 int
3662 scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *scsa2usbp,
3663     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3664 {
3665 	uchar_t opcode = pkt->pkt_cdbp[0];
3666 
3667 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3668 	    "scsa2usb_handle_ufi_subclass_cmd: cmd = 0x%p pkt = 0x%p",
3669 	    (void *)cmd, (void *)pkt);
3670 
3671 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3672 
3673 	bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3674 	cmd->cmd_cdb[SCSA2USB_OPCODE] = opcode;   /* Set the opcode */
3675 	cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3676 
3677 	/*
3678 	 * decode and convert the packet if necessary
3679 	 * for most cmds, we can bcopy the cdb
3680 	 */
3681 	switch (opcode) {
3682 	case SCMD_FORMAT:
3683 		/* if parameter list is specified */
3684 		if (pkt->pkt_cdbp[1] & 0x10) {
3685 			cmd->cmd_xfercount =
3686 			    (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3687 			cmd->cmd_dir = USB_EP_DIR_OUT;
3688 			cmd->cmd_actual_len = CDB_GROUP5;
3689 		}
3690 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3691 		break;
3692 	case SCMD_INQUIRY:
3693 		cmd->cmd_dir = USB_EP_DIR_IN;
3694 		cmd->cmd_actual_len = CDB_GROUP0;
3695 		cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3696 		cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3697 		    min(SCSA2USB_MAX_INQ_LEN,
3698 		    cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3699 		break;
3700 	case SCMD_READ_CAPACITY:
3701 		cmd->cmd_dir = USB_EP_DIR_IN;
3702 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3703 		cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3704 		break;
3705 	case SCMD_REQUEST_SENSE:
3706 		cmd->cmd_dir = USB_EP_DIR_IN;
3707 		cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3708 		cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3709 		cmd->cmd_actual_len = CDB_GROUP0;
3710 		break;
3711 
3712 	/*
3713 	 * do not convert SCMD_MODE_SENSE/SELECT because the
3714 	 * mode header is different as well
3715 	 */
3716 
3717 	/*
3718 	 * see usb_bulkonly.c for comments on the next set of commands
3719 	 */
3720 	case SCMD_READ:
3721 	case SCMD_WRITE:
3722 	case SCMD_READ_G1:
3723 	case SCMD_WRITE_G1:
3724 	case SCMD_READ_G4:
3725 	case SCMD_WRITE_G4:
3726 	case SCMD_READ_G5:
3727 	case SCMD_WRITE_G5:
3728 	case SCMD_READ_LONG:
3729 	case SCMD_WRITE_LONG:
3730 	case SCMD_READ_CD:
3731 		return (scsa2usb_rw_transport(scsa2usbp, pkt));
3732 
3733 	case SCMD_TEST_UNIT_READY:
3734 		/*
3735 		 * Some CB/CBI devices may not support TUR.
3736 		 */
3737 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3738 		break;
3739 	case SCMD_READ_FORMAT_CAP:
3740 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3741 		cmd->cmd_dir = USB_EP_DIR_IN;
3742 		cmd->cmd_actual_len = CDB_GROUP1;
3743 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3744 		break;
3745 	case SCMD_WRITE_VERIFY:
3746 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3747 		cmd->cmd_dir = USB_EP_DIR_OUT;
3748 		cmd->cmd_actual_len = CDB_GROUP1;
3749 		cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3750 		break;
3751 	case SCMD_START_STOP:
3752 		/* A larger timeout is needed for 'flaky' CD-RW devices */
3753 		if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_BIG_TIMEOUT)) {
3754 			cmd->cmd_timeout = max(cmd->cmd_timeout,
3755 			    20 * SCSA2USB_BULK_PIPE_TIMEOUT);
3756 		}
3757 		/* FALLTHRU */
3758 	default:
3759 		/*
3760 		 * all other commands don't need special mapping
3761 		 */
3762 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3763 		if (cmd->cmd_bp) {
3764 			cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3765 			    CBW_DIR_IN : CBW_DIR_OUT;
3766 			cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3767 		}
3768 		break;
3769 
3770 	} /* end of switch */
3771 
3772 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3773 	    "scsa2usb_handle_ufi_subclass_cmd: opcode = 0x%x count = 0x%lx",
3774 	    opcode, cmd->cmd_xfercount);
3775 
3776 	cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3777 
3778 	return (SCSA2USB_TRANSPORT);
3779 }
3780 
3781 
3782 /*
3783  * scsa2usb_rw_transport:
3784  *	Handle splitting READ and WRITE requests to the
3785  *	device to a size that the host controller allows.
3786  *
3787  *	returns TRAN_* values and not USB_SUCCESS/FAILURE
3788  *
3789  * To support CD-R/CD-RW/DVD media, we need to support a
3790  * variety of block sizes for the different types of CD
3791  * data (audio, data, video, CD-XA, yellowbook, redbook etc.)
3792  *
3793  * Some of the block sizes used are:- 512, 1k, 2k, 2056, 2336
3794  * 2340, 2352, 2368, 2448, 2646, 2647 etc.
3795  *
3796  * NOTE: the driver could be entertaining a SCSI CDB that uses
3797  * any of the above listed block sizes at a given time, and a
3798  * totally different block size at any other given time for a
3799  * different CDB.
3800  *
3801  * We need to compute block size every time and figure out
3802  * matching LBA and LEN accordingly.
3803  *
3804  * Also UHCI has a limitation that it can only xfer 32k at a
3805  * given time. So, with "odd" sized blocks and a limitation of
3806  * how much we can xfer per shot, we need to compute xfer_count
3807  * as well each time.
3808  *
3809  * The same computation is also done in the function
3810  * scsa2usb_setup_next_xfer().	To save computing block_size in
3811  * this function, I am saving block_size in "cmd" now.
3812  */
3813 int
3814 scsa2usb_rw_transport(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
3815 {
3816 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
3817 	int dir, opcode;
3818 	uint64_t lba;
3819 	struct buf *bp = cmd->cmd_bp;
3820 	size_t len, xfer_count;
3821 	size_t blk_size;	/* calculate the block size to be used */
3822 	int sz;
3823 
3824 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3825 	    "scsa2usb_rw_transport:");
3826 
3827 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3828 
3829 	opcode = pkt->pkt_cdbp[0];
3830 	blk_size = scsa2usbp->scsa2usb_lbasize[pkt->pkt_address.a_lun];
3831 						/* set to default */
3832 
3833 	switch (opcode) {
3834 	case SCMD_READ:
3835 		/*
3836 		 * Note that READ/WRITE(6) are not supported by the drive.
3837 		 * convert it into a 10 byte read/write.
3838 		 */
3839 		lba = SCSA2USB_LBA_6BYTE(pkt);
3840 		len = SCSA2USB_LEN_6BYTE(pkt);
3841 		opcode = SCMD_READ_G1;	/* Overwrite it w/ byte 10 cmd val */
3842 		dir = USB_EP_DIR_IN;
3843 		break;
3844 	case SCMD_WRITE:
3845 		lba = SCSA2USB_LBA_6BYTE(pkt);
3846 		len = SCSA2USB_LEN_6BYTE(pkt);
3847 		opcode = SCMD_WRITE_G1;	/* Overwrite it w/ byte 10 cmd val */
3848 		dir = USB_EP_DIR_OUT;
3849 		break;
3850 	case SCMD_READ_G1:
3851 	case SCMD_READ_LONG:
3852 		lba = SCSA2USB_LBA_10BYTE(pkt);
3853 		len = SCSA2USB_LEN_10BYTE(pkt);
3854 		dir = USB_EP_DIR_IN;
3855 		break;
3856 	case SCMD_WRITE_G1:
3857 	case SCMD_WRITE_LONG:
3858 		lba = SCSA2USB_LBA_10BYTE(pkt);
3859 		len = SCSA2USB_LEN_10BYTE(pkt);
3860 		dir = USB_EP_DIR_OUT;
3861 		if (len > 0) {
3862 			sz = SCSA2USB_CDRW_BLKSZ(bp != NULL ?
3863 			    bp->b_bcount : 0, len);
3864 			if (SCSA2USB_VALID_CDRW_BLKSZ(sz)) {
3865 				blk_size = sz;	/* change it accordingly */
3866 			}
3867 		}
3868 		break;
3869 	case SCMD_READ_CD:
3870 		lba = SCSA2USB_LBA_10BYTE(pkt);
3871 		len = SCSA2USB_LEN_READ_CD(pkt);
3872 		dir = USB_EP_DIR_IN;
3873 
3874 		/* Figure out the block size */
3875 		blk_size = scsa2usb_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2);
3876 		break;
3877 	case SCMD_READ_G4:
3878 		lba = SCSA2USB_LBA_16BYTE(pkt);
3879 		len = SCSA2USB_LEN_16BYTE(pkt);
3880 		dir = USB_EP_DIR_IN;
3881 		break;
3882 	case SCMD_WRITE_G4:
3883 		lba = SCSA2USB_LBA_16BYTE(pkt);
3884 		len = SCSA2USB_LEN_16BYTE(pkt);
3885 		dir = USB_EP_DIR_OUT;
3886 		break;
3887 	case SCMD_READ_G5:
3888 		lba = SCSA2USB_LBA_12BYTE(pkt);
3889 		len = SCSA2USB_LEN_12BYTE(pkt);
3890 		dir = USB_EP_DIR_IN;
3891 		break;
3892 	case SCMD_WRITE_G5:
3893 		lba = SCSA2USB_LBA_12BYTE(pkt);
3894 		len = SCSA2USB_LEN_12BYTE(pkt);
3895 		dir = USB_EP_DIR_OUT;
3896 		break;
3897 	}
3898 
3899 	cmd->cmd_total_xfercount = xfer_count = len * blk_size;
3900 
3901 	/* reduce xfer count if necessary */
3902 	if (blk_size != 0 &&
3903 	    xfer_count > scsa2usbp->scsa2usb_max_bulk_xfer_size) {
3904 		/*
3905 		 * For CD-RW devices reduce the xfer count based
3906 		 * on the block size used by these devices. The
3907 		 * block size could change for READ_CD and WRITE
3908 		 * opcodes.
3909 		 *
3910 		 * Also as UHCI allows a max xfer of 32k at a time;
3911 		 * compute the xfer_count based on the new block_size.
3912 		 *
3913 		 * The len part of the cdb changes as a result of that.
3914 		 */
3915 		if (SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3916 			xfer_count = (scsa2usbp->scsa2usb_max_bulk_xfer_size /
3917 			    blk_size) * blk_size;
3918 			len = xfer_count / blk_size;
3919 			xfer_count = blk_size * len;
3920 		} else {
3921 			xfer_count = scsa2usbp->scsa2usb_max_bulk_xfer_size;
3922 			len = xfer_count / blk_size;
3923 		}
3924 	}
3925 
3926 	cmd->cmd_xfercount = xfer_count;
3927 	cmd->cmd_dir = (uchar_t)dir;
3928 	cmd->cmd_blksize = (int)blk_size;
3929 
3930 	/*
3931 	 * Having figured out the 'partial' xfer len based on the
3932 	 * block size; fill it in to the cmd->cmd_cdb
3933 	 */
3934 	cmd->cmd_cdb[SCSA2USB_OPCODE] = (uchar_t)opcode;
3935 	switch (opcode) {
3936 	case SCMD_READ_CD:
3937 		bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3938 		scsa2usb_fill_up_ReadCD_cdb_len(cmd, len, CDB_GROUP5);
3939 		scsa2usb_fill_up_cdb_lba(cmd, lba);
3940 		break;
3941 	case SCMD_WRITE_G4:
3942 	case SCMD_READ_G4:
3943 		scsa2usb_fill_up_16byte_cdb_len(cmd, len, CDB_GROUP4);
3944 		scsa2usb_fill_up_g4_cdb_lba(cmd, lba);
3945 		break;
3946 	case SCMD_WRITE_G5:
3947 	case SCMD_READ_G5:
3948 		scsa2usb_fill_up_12byte_cdb_len(cmd, len, CDB_GROUP5);
3949 		scsa2usb_fill_up_cdb_lba(cmd, lba);
3950 		break;
3951 	default:
3952 		scsa2usb_fill_up_cdb_len(cmd, len);
3953 		cmd->cmd_actual_len = CDB_GROUP1;
3954 		scsa2usb_fill_up_cdb_lba(cmd, lba);
3955 		break;
3956 	}
3957 
3958 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3959 	    "bcount=0x%lx lba=0x%x len=0x%lx xfercount=0x%lx total=0x%lx",
3960 	    bp ? bp->b_bcount : 0, lba, len, cmd->cmd_xfercount,
3961 	    cmd->cmd_total_xfercount);
3962 
3963 	/* Set the timeout value as per command request */
3964 	if ((opcode == SCMD_WRITE_G1) && SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3965 		/*
3966 		 * We increase the time as CD-RW writes have two things
3967 		 * to do. After writing out the data to the media, a
3968 		 * TOC needs to be filled up at the beginning of the media
3969 		 * This is when the write gets "finalized".
3970 		 * Hence the actual write could take longer than the
3971 		 * value specified in cmd->cmd_timeout.
3972 		 */
3973 		cmd->cmd_timeout *= 4;
3974 
3975 		USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3976 		    scsa2usbp->scsa2usb_log_handle,
3977 		    "new timeout value = 0x%x", cmd->cmd_timeout);
3978 	}
3979 
3980 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3981 	    "lba 0x%x len 0x%lx xfercount 0x%lx total 0x%lx",
3982 	    lba, len, cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3983 
3984 	return (SCSA2USB_TRANSPORT);
3985 }
3986 
3987 
3988 /*
3989  * scsa2usb_setup_next_xfer:
3990  *	For READs and WRITEs we split up the transfer in terms of
3991  *	HCD understood units. This function handles the split transfers.
3992  *
3993  * See comments in the previous function scsa2usb_rw_transport
3994  *
3995  * The lba computation was being done based on scsa2usb_max_bulk_xfer_size
3996  * earlier. With CD-RW devices, the xfer_count and the block_size may
3997  * no longer be a multiple of scsa2usb_max_bulk_xfer_size. So compute
3998  * xfer_count all over again. Adjust lba, based on the previous requests'
3999  * len. Find out the len and add it to cmd->cmd_lba to get the new lba
4000  */
4001 void
4002 scsa2usb_setup_next_xfer(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
4003 {
4004 	int xfer_len = min(scsa2usbp->scsa2usb_max_bulk_xfer_size,
4005 	    cmd->cmd_total_xfercount);
4006 	int cdb_len;
4007 	size_t blk_size;
4008 
4009 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4010 
4011 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4012 	    "scsa2usb_setup_next_xfer: opcode = 0x%x lba = 0x%x "
4013 	    "total count = 0x%lx", cmd->cmd_cdb[SCSA2USB_OPCODE],
4014 	    cmd->cmd_lba, cmd->cmd_total_xfercount);
4015 
4016 	ASSERT(cmd->cmd_total_xfercount > 0);
4017 	cmd->cmd_xfercount = xfer_len;
4018 	blk_size = scsa2usbp->scsa2usb_lbasize[
4019 	    cmd->cmd_pkt->pkt_address.a_lun];
4020 
4021 	/*
4022 	 * For CD-RW devices reduce the xfer count based on the
4023 	 * block_size used by these devices. See changes below
4024 	 * where xfer_count is being adjusted.
4025 	 *
4026 	 * Also adjust len/lba based on the block_size and xfer_count.
4027 	 * NOTE: Always calculate lba first, as it based on previous
4028 	 * commands' values.
4029 	 */
4030 	switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
4031 	case SCMD_READ_CD:
4032 		/* calculate lba = current_lba + len_of_prev_cmd */
4033 		cmd->cmd_lba += (cmd->cmd_cdb[6] << 16) +
4034 		    (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
4035 		cdb_len = xfer_len / cmd->cmd_blksize;
4036 		cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)cdb_len;
4037 		/* re-adjust xfer count */
4038 		cmd->cmd_xfercount = cdb_len * cmd->cmd_blksize;
4039 		scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
4040 		break;
4041 	case SCMD_WRITE_G4:
4042 	case SCMD_READ_G4:
4043 		/* calculate lba = current_lba + len_of_prev_cmd */
4044 		cmd->cmd_lba += (cmd->cmd_cdb[10] << 24) +
4045 		    (cmd->cmd_cdb[11] << 16) + (cmd->cmd_cdb[12] << 8) +
4046 		    cmd->cmd_cdb[13];
4047 		if (blk_size != 0) {
4048 			xfer_len /= blk_size;
4049 		}
4050 		scsa2usb_fill_up_16byte_cdb_len(cmd, xfer_len, CDB_GROUP5);
4051 		scsa2usb_fill_up_g4_cdb_lba(cmd, cmd->cmd_lba);
4052 		break;
4053 	case SCMD_WRITE_G5:
4054 	case SCMD_READ_G5:
4055 		/* calculate lba = current_lba + len_of_prev_cmd */
4056 		cmd->cmd_lba += (cmd->cmd_cdb[6] << 24) +
4057 		    (cmd->cmd_cdb[7] << 16) + (cmd->cmd_cdb[8] << 8) +
4058 		    cmd->cmd_cdb[9];
4059 		if (blk_size != 0) {
4060 			xfer_len /= blk_size;
4061 		}
4062 		scsa2usb_fill_up_12byte_cdb_len(cmd, xfer_len, CDB_GROUP5);
4063 		scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
4064 		break;
4065 	case SCMD_WRITE_G1:
4066 	case SCMD_WRITE_LONG:
4067 		/* calculate lba = current_lba + len_of_prev_cmd */
4068 		cmd->cmd_lba += (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
4069 		if (SCSA2USB_VALID_CDRW_BLKSZ(cmd->cmd_blksize)) {
4070 			blk_size = cmd->cmd_blksize;
4071 		}
4072 		cdb_len = xfer_len / blk_size;
4073 		scsa2usb_fill_up_cdb_len(cmd, cdb_len);
4074 		/* re-adjust xfer count */
4075 		cmd->cmd_xfercount = cdb_len * blk_size;
4076 		scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
4077 		break;
4078 	default:
4079 		if (blk_size != 0) {
4080 			xfer_len /= blk_size;
4081 		}
4082 		scsa2usb_fill_up_cdb_len(cmd, xfer_len);
4083 		cmd->cmd_lba += scsa2usbp->scsa2usb_max_bulk_xfer_size /
4084 		    blk_size;
4085 		scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
4086 		break;
4087 	}
4088 
4089 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4090 	    "scsa2usb_setup_next_xfer:\n\tlba = 0x%x xfer_len = 0x%x "
4091 	    "xfercount = 0x%lx total = 0x%lx", cmd->cmd_lba, xfer_len,
4092 	    cmd->cmd_xfercount, cmd->cmd_total_xfercount);
4093 }
4094 
4095 
4096 /*
4097  * take one request from the lun's waitQ and transport it
4098  */
4099 static void
4100 scsa2usb_transport_request(scsa2usb_state_t *scsa2usbp, uint_t lun)
4101 {
4102 	int			rval;
4103 	struct scsi_pkt		*pkt;
4104 	struct scsa2usb_cmd	*cmd, *arqcmd;
4105 
4106 	if ((cmd = (scsa2usb_cmd_t *)
4107 	    usba_rm_first_pvt_from_list(
4108 	    &scsa2usbp->scsa2usb_waitQ[lun])) == NULL) {
4109 
4110 		return;
4111 	}
4112 	pkt = cmd->cmd_pkt;
4113 
4114 	/*
4115 	 * if device has been disconnected, just complete it
4116 	 */
4117 	if (scsa2usbp->scsa2usb_dev_state == USB_DEV_DISCONNECTED) {
4118 		USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4119 		    "device not accessible");
4120 		pkt->pkt_reason = CMD_DEV_GONE;
4121 		SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
4122 		scsa2usb_pkt_completion(scsa2usbp, pkt);
4123 
4124 		return;
4125 	}
4126 
4127 	USB_DPRINTF_L4(DPRINT_MASK_SCSA,
4128 	    scsa2usbp->scsa2usb_log_handle,
4129 	    "scsa2usb_transport_request: cmd=0x%p bp=0x%p addr=0x%p",
4130 	    (void *)cmd, (void *)cmd->cmd_bp,
4131 	    (void *)(cmd->cmd_bp ? cmd->cmd_bp->b_un.b_addr : NULL));
4132 
4133 	rval = scsa2usb_cmd_transport(scsa2usbp, cmd);
4134 
4135 	USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4136 	    scsa2usbp->scsa2usb_log_handle,
4137 	    "scsa2usb_transport_request: transport rval = %d",
4138 	    rval);
4139 
4140 	if (scsa2usbp->scsa2usb_cur_pkt == NULL) {
4141 
4142 		return;
4143 	}
4144 
4145 	ASSERT(pkt == scsa2usbp->scsa2usb_cur_pkt);
4146 
4147 	if (ddi_in_panic()) {
4148 		pkt->pkt_reason = CMD_CMPLT;
4149 		scsa2usb_pkt_completion(scsa2usbp, pkt);
4150 
4151 		return;
4152 	}
4153 
4154 	/*
4155 	 * start an auto-request sense iff
4156 	 * there was a check condition, we have enough
4157 	 * space in the status block, and we have not
4158 	 * faked an auto request sense
4159 	 */
4160 	if ((*(pkt->pkt_scbp) == STATUS_CHECK) &&
4161 	    (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) &&
4162 	    ((pkt->pkt_state & STATE_ARQ_DONE) == 0) &&
4163 	    (scsa2usb_create_arq_pkt(scsa2usbp,
4164 	    &pkt->pkt_address) == USB_SUCCESS)) {
4165 		arqcmd = scsa2usbp->scsa2usb_arq_cmd;
4166 
4167 		/*
4168 		 * copy the timeout from the
4169 		 * original packet
4170 		 * for lack of a better value
4171 		 */
4172 		arqcmd->cmd_pkt->pkt_time = pkt->pkt_time;
4173 		scsa2usb_prepare_pkt(scsa2usbp,
4174 		    arqcmd->cmd_pkt);
4175 
4176 		scsa2usbp->scsa2usb_cur_pkt = NULL;
4177 		if (scsa2usb_cmd_transport(
4178 		    scsa2usbp, arqcmd) == TRAN_ACCEPT) {
4179 
4180 			/* finish w/ this packet */
4181 			scsa2usb_complete_arq_pkt(
4182 			    scsa2usbp, arqcmd->cmd_pkt, cmd,
4183 			    scsa2usbp->scsa2usb_arq_bp);
4184 
4185 			/*
4186 			 * we have valid request sense
4187 			 * data so clear the pkt_reason
4188 			 */
4189 			pkt->pkt_reason = CMD_CMPLT;
4190 		}
4191 		scsa2usbp->scsa2usb_cur_pkt = pkt;
4192 		scsa2usb_delete_arq_pkt(scsa2usbp);
4193 	}
4194 
4195 	if ((rval != TRAN_ACCEPT) &&
4196 	    (pkt->pkt_reason == CMD_CMPLT)) {
4197 		pkt->pkt_reason = CMD_TRAN_ERR;
4198 	}
4199 
4200 	SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
4201 	scsa2usb_pkt_completion(scsa2usbp, pkt);
4202 
4203 	ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
4204 }
4205 
4206 
4207 /*
4208  * scsa2usb_work_thread:
4209  *	The taskq thread that kicks off the transport (BO and CB/CBI)
4210  */
4211 static void
4212 scsa2usb_work_thread(void *arg)
4213 {
4214 	scsa2usb_state_t	*scsa2usbp = (scsa2usb_state_t *)arg;
4215 	uint_t			lun;
4216 	uint_t			count;
4217 
4218 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4219 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4220 	    "scsa2usb_work_thread start: thread_id=0x%p",
4221 	    (void *)scsa2usbp->scsa2usb_work_thread_id);
4222 
4223 	ASSERT(scsa2usbp->scsa2usb_work_thread_id == (kthread_t *)1);
4224 	scsa2usbp->scsa2usb_work_thread_id = curthread;
4225 
4226 	/* exclude ugen accesses */
4227 	while (scsa2usbp->scsa2usb_transport_busy) {
4228 		cv_wait(&scsa2usbp->scsa2usb_transport_busy_cv,
4229 		    &scsa2usbp->scsa2usb_mutex);
4230 	}
4231 	ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4232 	scsa2usbp->scsa2usb_transport_busy++;
4233 	scsa2usbp->scsa2usb_busy_proc = curproc;
4234 
4235 	scsa2usb_raise_power(scsa2usbp);
4236 
4237 	/* reopen the pipes if necessary */
4238 	(void) scsa2usb_open_usb_pipes(scsa2usbp);
4239 
4240 	for (;;) {
4241 		ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4242 		for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
4243 			scsa2usb_transport_request(scsa2usbp, lun);
4244 		}
4245 		count = 0;
4246 		for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
4247 			count += usba_list_entry_count(
4248 			    &scsa2usbp->scsa2usb_waitQ[lun]);
4249 		}
4250 
4251 		if (count == 0) {
4252 
4253 			break;
4254 		}
4255 	}
4256 
4257 	scsa2usbp->scsa2usb_work_thread_id = 0;
4258 
4259 	ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4260 
4261 	scsa2usbp->scsa2usb_transport_busy--;
4262 	scsa2usbp->scsa2usb_busy_proc = NULL;
4263 	cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
4264 
4265 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4266 	    "scsa2usb_work_thread: exit");
4267 
4268 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4269 
4270 	scsa2usb_pm_idle_component(scsa2usbp);
4271 }
4272 
4273 
4274 /*
4275  * scsa2usb_flush_waitQ:
4276  *	empties the entire waitQ with errors asap.
4277  *
4278  * It is called from scsa2usb_scsi_reset and scsa2usb_panic_callb.
4279  * If the device is reset; we should empty the waitQ right away.
4280  * If the system has paniced; we should empty the waitQ right away.
4281  *
4282  * CPR suspend will only succeed if device is idle. No need to call
4283  * this function for CPR suspend case.
4284  */
4285 static void
4286 scsa2usb_flush_waitQ(scsa2usb_state_t *scsa2usbp, uint_t lun,
4287     uchar_t error)
4288 {
4289 	struct scsi_pkt		*pkt;
4290 	struct scsa2usb_cmd	*cmd;
4291 	usba_list_entry_t	head;
4292 
4293 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4294 
4295 	usba_move_list(&scsa2usbp->scsa2usb_waitQ[lun], &head,
4296 	    scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
4297 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4298 
4299 	while ((cmd = (scsa2usb_cmd_t *)usba_rm_first_pvt_from_list(&head)) !=
4300 	    NULL) {
4301 		pkt = cmd->cmd_pkt;
4302 		pkt->pkt_reason = error;	/* set error */
4303 
4304 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4305 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP;
4306 		scsa2usb_pkt_completion(scsa2usbp, pkt);
4307 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4308 	} /* end of while */
4309 }
4310 
4311 
4312 /*
4313  * scsa2usb_do_inquiry is performed before INIT CHILD and we have
4314  * to fake a few things normally done by SCSA
4315  */
4316 static void
4317 scsa2usb_do_inquiry(scsa2usb_state_t *scsa2usbp, uint_t target, uint_t lun)
4318 {
4319 	struct buf	*bp;
4320 	struct scsi_pkt *pkt;
4321 	struct scsi_address ap;
4322 	int		len = SCSA2USB_MAX_INQ_LEN;
4323 
4324 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4325 	    "scsa2usb_do_inquiry: %d bytes", len);
4326 
4327 	/* is it inquiry-challenged? */
4328 	if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
4329 		scsa2usb_fake_inquiry(scsa2usbp,
4330 		    &scsa2usbp->scsa2usb_lun_inquiry[lun]);
4331 		return;
4332 	}
4333 
4334 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4335 
4336 	bzero(&ap, sizeof (struct scsi_address));
4337 	ap.a_hba_tran = scsa2usbp->scsa2usb_tran;
4338 	ap.a_target = (ushort_t)target;
4339 	ap.a_lun = (uchar_t)lun;
4340 
4341 	/* limit inquiry to 36 bytes */
4342 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4343 	if ((bp = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
4344 	    len, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4345 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4346 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4347 		    scsa2usbp->scsa2usb_log_handle,
4348 		    "scsa2usb_do_inquiry: failed");
4349 
4350 		return;
4351 	}
4352 
4353 	pkt = scsi_init_pkt(&ap, NULL, bp, CDB_GROUP0, 1,
4354 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL);
4355 
4356 	RQ_MAKECOM_G0(pkt, FLAG_NOINTR, (char)SCMD_INQUIRY, 0, (char)len);
4357 
4358 	pkt->pkt_comp = NULL;
4359 	pkt->pkt_time = 5;
4360 	bzero(bp->b_un.b_addr, len);
4361 
4362 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4363 	    "scsa2usb_do_inquiry:INQUIRY");
4364 
4365 	(void) scsi_transport(pkt);
4366 
4367 	if (pkt->pkt_reason) {
4368 		USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4369 		    scsa2usbp->scsa2usb_log_handle,
4370 		    "INQUIRY failed, cannot determine device type, "
4371 		    "pkt_reason=0x%x", pkt->pkt_reason);
4372 
4373 		/* not much hope for other cmds, reduce */
4374 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4375 		scsa2usbp->scsa2usb_attrs &=
4376 		    ~SCSA2USB_ATTRS_REDUCED_CMD;
4377 		scsa2usb_fake_inquiry(scsa2usbp,
4378 		    &scsa2usbp->scsa2usb_lun_inquiry[lun]);
4379 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4380 	}
4381 
4382 	scsi_destroy_pkt(pkt);
4383 	scsi_free_consistent_buf(bp);
4384 
4385 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4386 }
4387 
4388 
4389 /*
4390  * scsa2usb_fake_inquiry:
4391  *    build an inquiry for a given device that doesnt like inquiry
4392  *    commands.
4393  */
4394 static void
4395 scsa2usb_fake_inquiry(scsa2usb_state_t *scsa2usbp, struct scsi_inquiry *inqp)
4396 {
4397 	usb_client_dev_data_t *dev_data = scsa2usbp->scsa2usb_dev_data;
4398 	int len;
4399 
4400 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4401 	    "scsa2usb_fake_inquiry:");
4402 
4403 	bzero(inqp, sizeof (struct scsi_inquiry));
4404 	for (len = 0; len < sizeof (inqp->inq_vid); len++) {
4405 		*(inqp->inq_vid + len) = ' ';
4406 	}
4407 
4408 	for (len = 0; len < sizeof (inqp->inq_pid); len++) {
4409 		*(inqp->inq_pid + len) = ' ';
4410 	}
4411 
4412 	inqp->inq_dtype = DTYPE_DIRECT;
4413 	inqp->inq_rmb = 1;
4414 	inqp->inq_ansi = 2;
4415 	inqp->inq_rdf = RDF_SCSI2;
4416 	inqp->inq_len = sizeof (struct scsi_inquiry)-4;
4417 
4418 	/* Fill in the Vendor id/Product id strings */
4419 	if (dev_data->dev_mfg) {
4420 		if ((len = strlen(dev_data->dev_mfg)) >
4421 		    sizeof (inqp->inq_vid)) {
4422 			len = sizeof (inqp->inq_vid);
4423 		}
4424 		bcopy(dev_data->dev_mfg, inqp->inq_vid, len);
4425 	}
4426 
4427 	if (dev_data->dev_product) {
4428 		if ((len = strlen(dev_data->dev_product)) >
4429 		    sizeof (inqp->inq_pid)) {
4430 			len = sizeof (inqp->inq_pid);
4431 		}
4432 		bcopy(dev_data->dev_product, inqp->inq_pid, len);
4433 	}
4434 
4435 	/* Set the Revision to the Device */
4436 	inqp->inq_revision[0] = 0x30 +
4437 	    ((dev_data->dev_descr->bcdDevice>>12) & 0xF);
4438 	inqp->inq_revision[1] = 0x30 +
4439 	    ((dev_data->dev_descr->bcdDevice>>8) & 0xF);
4440 	inqp->inq_revision[2] = 0x30 +
4441 	    ((dev_data->dev_descr->bcdDevice>>4) & 0xF);
4442 	inqp->inq_revision[3] = 0x30 +
4443 	    ((dev_data->dev_descr->bcdDevice) & 0xF);
4444 }
4445 
4446 
4447 /*
4448  * scsa2usb_create_arq_pkt:
4449  *	Create and ARQ packet to get request sense data
4450  */
4451 static int
4452 scsa2usb_create_arq_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
4453 {
4454 	struct buf *bp;
4455 	scsa2usb_cmd_t *arq_cmd;
4456 
4457 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4458 	    "scsa2usb_create_arq_pkt: scsa2usbp: %p, ap: %p",
4459 	    (void *)scsa2usbp, (void *)ap);
4460 
4461 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4462 
4463 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4464 	if ((bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL,
4465 	    SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4466 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4467 
4468 		return (USB_FAILURE);
4469 	}
4470 
4471 	arq_cmd = PKT2CMD(scsi_init_pkt(ap, NULL, bp, CDB_GROUP0, 1,
4472 	    PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL));
4473 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4474 
4475 	RQ_MAKECOM_G0(arq_cmd->cmd_pkt,
4476 	    FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON,
4477 	    (char)SCMD_REQUEST_SENSE, 0, (char)SENSE_LENGTH);
4478 
4479 	arq_cmd->cmd_pkt->pkt_ha_private = arq_cmd;
4480 	scsa2usbp->scsa2usb_arq_cmd = arq_cmd;
4481 	scsa2usbp->scsa2usb_arq_bp = bp;
4482 	arq_cmd->cmd_pkt->pkt_comp = NULL;
4483 	bzero(bp->b_un.b_addr, SENSE_LENGTH);
4484 
4485 	return (USB_SUCCESS);
4486 }
4487 
4488 
4489 /*
4490  * scsa2usb_delete_arq_pkt:
4491  *	Destroy the ARQ packet
4492  */
4493 static void
4494 scsa2usb_delete_arq_pkt(scsa2usb_state_t *scsa2usbp)
4495 {
4496 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4497 	    "scsa2usb_delete_arq_pkt: cmd: 0x%p",
4498 	    (void *)scsa2usbp->scsa2usb_arq_cmd);
4499 
4500 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4501 
4502 	if (scsa2usbp->scsa2usb_arq_cmd != NULL) {
4503 		scsi_destroy_pkt(scsa2usbp->scsa2usb_arq_cmd->cmd_pkt);
4504 		scsi_free_consistent_buf(scsa2usbp->scsa2usb_arq_bp);
4505 	}
4506 	scsa2usbp->scsa2usb_arq_cmd = NULL;
4507 	scsa2usbp->scsa2usb_arq_bp = NULL;
4508 }
4509 
4510 
4511 /*
4512  * scsa2usb_complete_arq_pkt:
4513  *	finish processing the arq packet
4514  */
4515 static void
4516 scsa2usb_complete_arq_pkt(scsa2usb_state_t *scsa2usbp,
4517     struct scsi_pkt *pkt, scsa2usb_cmd_t *ssp, struct buf *bp)
4518 {
4519 	scsa2usb_cmd_t		*sp = pkt->pkt_ha_private;
4520 	struct scsi_arq_status	*arqp;
4521 
4522 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4523 
4524 	arqp = (struct scsi_arq_status *)(ssp->cmd_pkt->pkt_scbp);
4525 	arqp->sts_rqpkt_status = *((struct scsi_status *)
4526 	    (sp->cmd_pkt->pkt_scbp));
4527 	arqp->sts_rqpkt_reason = CMD_CMPLT;
4528 	arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
4529 	arqp->sts_rqpkt_statistics = arqp->sts_rqpkt_resid = 0;
4530 
4531 	/* is this meaningful sense data */
4532 	if (*(bp->b_un.b_addr) != 0) {
4533 		bcopy(bp->b_un.b_addr, &arqp->sts_sensedata, SENSE_LENGTH);
4534 		ssp->cmd_pkt->pkt_state |= STATE_ARQ_DONE;
4535 	}
4536 
4537 	/* we will not sense start cmd until we receive a NOT READY */
4538 	if (arqp->sts_sensedata.es_key == KEY_NOT_READY) {
4539 		scsa2usbp->scsa2usb_rcvd_not_ready = B_TRUE;
4540 	}
4541 }
4542 
4543 
4544 /*
4545  * Miscellaneous functions for any command/transport
4546  */
4547 /*
4548  * scsa2usb_open_usb_pipes:
4549  *	set up a pipe policy
4550  *	open usb bulk pipes (BO and CB/CBI)
4551  *	open usb interrupt pipe (CBI)
4552  */
4553 static int
4554 scsa2usb_open_usb_pipes(scsa2usb_state_t *scsa2usbp)
4555 {
4556 	int			rval;
4557 	usb_pipe_policy_t	policy;	/* bulk pipe policy */
4558 	size_t			sz;
4559 
4560 	ASSERT(scsa2usbp);
4561 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4562 
4563 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4564 	    "scsa2usb_open_usb_pipes: dip = 0x%p flag = 0x%x",
4565 	    (void *)scsa2usbp->scsa2usb_dip, scsa2usbp->scsa2usb_flags);
4566 
4567 	if (!(scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED)) {
4568 
4569 		/*
4570 		 * one pipe policy for all bulk pipes
4571 		 */
4572 		bzero(&policy, sizeof (usb_pipe_policy_t));
4573 		/* at least 2, for the normal and exceptional callbacks */
4574 		policy.pp_max_async_reqs = 1;
4575 
4576 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4577 		    "scsa2usb_open_usb_pipes: opening bulk pipes");
4578 
4579 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4580 
4581 		/* Open the USB bulk-in pipe */
4582 		if ((rval = usb_pipe_xopen(scsa2usbp->scsa2usb_dip,
4583 		    &scsa2usbp->scsa2usb_bulkin_xept, &policy, USB_FLAGS_SLEEP,
4584 		    &scsa2usbp->scsa2usb_bulkin_pipe)) != USB_SUCCESS) {
4585 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4586 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4587 			    scsa2usbp->scsa2usb_log_handle,
4588 			    "scsa2usb_open_usb_pipes: bulk/in pipe open "
4589 			    " failed rval = %d", rval);
4590 
4591 			return (USB_FAILURE);
4592 		}
4593 
4594 		/* Open the bulk-out pipe  using the same policy */
4595 		if ((rval = usb_pipe_xopen(scsa2usbp->scsa2usb_dip,
4596 		    &scsa2usbp->scsa2usb_bulkout_xept, &policy, USB_FLAGS_SLEEP,
4597 		    &scsa2usbp->scsa2usb_bulkout_pipe)) != USB_SUCCESS) {
4598 			usb_pipe_close(scsa2usbp->scsa2usb_dip,
4599 			    scsa2usbp->scsa2usb_bulkin_pipe,
4600 			    USB_FLAGS_SLEEP, NULL, NULL);
4601 
4602 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4603 			scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4604 
4605 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4606 			    scsa2usbp->scsa2usb_log_handle,
4607 			    "scsa2usb_open_usb_pipes: bulk/out pipe open"
4608 			    " failed rval = %d", rval);
4609 
4610 			return (USB_FAILURE);
4611 		}
4612 
4613 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4614 
4615 		/* open interrupt pipe for CBI protocol */
4616 		if (SCSA2USB_IS_CBI(scsa2usbp)) {
4617 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4618 
4619 			if ((rval = usb_pipe_xopen(scsa2usbp->scsa2usb_dip,
4620 			    &scsa2usbp->scsa2usb_intr_xept, &policy,
4621 			    USB_FLAGS_SLEEP, &scsa2usbp->scsa2usb_intr_pipe)) !=
4622 			    USB_SUCCESS) {
4623 				usb_pipe_close(scsa2usbp->scsa2usb_dip,
4624 				    scsa2usbp->scsa2usb_bulkin_pipe,
4625 				    USB_FLAGS_SLEEP, NULL, NULL);
4626 
4627 				usb_pipe_close(scsa2usbp->scsa2usb_dip,
4628 				    scsa2usbp->scsa2usb_bulkout_pipe,
4629 				    USB_FLAGS_SLEEP, NULL, NULL);
4630 
4631 				mutex_enter(&scsa2usbp->scsa2usb_mutex);
4632 				scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4633 				scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4634 
4635 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4636 				    scsa2usbp->scsa2usb_log_handle,
4637 				    "scsa2usb_open_usb_pipes: intr pipe open"
4638 				    " failed rval = %d", rval);
4639 
4640 				return (USB_FAILURE);
4641 			}
4642 
4643 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4644 		}
4645 
4646 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4647 
4648 		/* get the max transfer size of the bulk pipe */
4649 		if (usb_pipe_get_max_bulk_transfer_size(scsa2usbp->scsa2usb_dip,
4650 		    &sz) == USB_SUCCESS) {
4651 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4652 			scsa2usbp->scsa2usb_max_bulk_xfer_size = sz;
4653 		} else {
4654 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4655 			scsa2usbp->scsa2usb_max_bulk_xfer_size = DEV_BSIZE;
4656 		}
4657 
4658 		/* limit the xfer size */
4659 		scsa2usbp->scsa2usb_max_bulk_xfer_size = min(
4660 		    scsa2usbp->scsa2usb_max_bulk_xfer_size,
4661 		    scsa2usb_max_bulk_xfer_size);
4662 
4663 		USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4664 		    "scsa2usb_open_usb_pipes: max bulk transfer size = %lx",
4665 		    scsa2usbp->scsa2usb_max_bulk_xfer_size);
4666 
4667 		/* Set the pipes opened flag */
4668 		scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_PIPES_OPENED;
4669 
4670 		scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4671 
4672 		/* Set the state to NONE */
4673 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4674 	}
4675 
4676 	return (USB_SUCCESS);
4677 }
4678 
4679 
4680 /*
4681  * scsa2usb_close_usb_pipes:
4682  *	close all pipes synchronously
4683  */
4684 void
4685 scsa2usb_close_usb_pipes(scsa2usb_state_t *scsa2usbp)
4686 {
4687 	usb_flags_t flags = USB_FLAGS_SLEEP;
4688 
4689 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4690 	    "scsa2usb_close_usb_pipes: scsa2usb_state = 0x%p",
4691 	    (void *)scsa2usbp);
4692 
4693 	ASSERT(scsa2usbp);
4694 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4695 
4696 	if ((scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED) == 0) {
4697 
4698 		return;
4699 	}
4700 
4701 	scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_CLOSING;
4702 	/* to avoid races, reset the flag first */
4703 	scsa2usbp->scsa2usb_flags &= ~SCSA2USB_FLAGS_PIPES_OPENED;
4704 
4705 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
4706 
4707 	usb_pipe_close(scsa2usbp->scsa2usb_dip,
4708 	    scsa2usbp->scsa2usb_bulkout_pipe, flags, NULL, NULL);
4709 
4710 	usb_pipe_close(scsa2usbp->scsa2usb_dip,
4711 	    scsa2usbp->scsa2usb_bulkin_pipe, flags, NULL, NULL);
4712 
4713 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
4714 	if (SCSA2USB_IS_CBI(scsa2usbp)) {
4715 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
4716 		usb_pipe_close(scsa2usbp->scsa2usb_dip,
4717 		    scsa2usbp->scsa2usb_intr_pipe, flags, NULL, NULL);
4718 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
4719 	}
4720 	scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4721 	scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4722 	scsa2usbp->scsa2usb_intr_pipe = NULL;
4723 
4724 	scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4725 }
4726 
4727 
4728 /*
4729  * scsa2usb_fill_up_cdb_lba:
4730  *	fill up command CDBs' LBA part
4731  */
4732 static void
4733 scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *cmd, uint64_t lba)
4734 {
4735 	/* zero cdb1, lba bits so they won't get copied in the new cdb */
4736 	cmd->cmd_cdb[SCSA2USB_LUN] &= 0xE0;
4737 	cmd->cmd_cdb[SCSA2USB_LBA_0] = lba >> 24;
4738 	cmd->cmd_cdb[SCSA2USB_LBA_1] = lba >> 16;
4739 	cmd->cmd_cdb[SCSA2USB_LBA_2] = lba >> 8;
4740 	cmd->cmd_cdb[SCSA2USB_LBA_3] = (uchar_t)lba;
4741 	cmd->cmd_lba = lba;
4742 }
4743 
4744 
4745 /*
4746  * scsa2usb_fill_up_g4_cdb_lba:
4747  *	fill in the CDB for a Group 4 command (16-byte CDB)
4748  */
4749 static void
4750 scsa2usb_fill_up_g4_cdb_lba(scsa2usb_cmd_t *cmd, uint64_t lba)
4751 {
4752 	/* zero cdb1, lba bits so they won't get copied in the new cdb */
4753 	cmd->cmd_cdb[SCSA2USB_LUN] &= 0xE0;
4754 	cmd->cmd_cdb[2] = lba >> 56;
4755 	cmd->cmd_cdb[3] = lba >> 48;
4756 	cmd->cmd_cdb[4] = lba >> 40;
4757 	cmd->cmd_cdb[5] = lba >> 32;
4758 	cmd->cmd_cdb[6] = lba >> 24;
4759 	cmd->cmd_cdb[7] = lba >> 16;
4760 	cmd->cmd_cdb[8] = lba >> 8;
4761 	cmd->cmd_cdb[9] = lba;
4762 	cmd->cmd_lba = lba;
4763 }
4764 
4765 
4766 /*
4767  * scsa2usb_fill_up_ReadCD_cdb_len:
4768  *	fill up READ_CD command CDBs' len part
4769  */
4770 static void
4771 scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4772 {
4773 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_0] = len >> 16;
4774 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_1] = len >> 8;
4775 	cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)len;
4776 	cmd->cmd_actual_len = (uchar_t)actual_len;
4777 }
4778 
4779 
4780 /*
4781  * scsa2usb_fill_up_16byte_cdb_len:
4782  *	populate CDB length field for SCMD_WRITE_G4 and SCMD_READ_G4
4783  */
4784 static void
4785 scsa2usb_fill_up_16byte_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4786 {
4787 	cmd->cmd_cdb[10] = len >> 24;
4788 	cmd->cmd_cdb[11] = len >> 16;
4789 	cmd->cmd_cdb[12] = len >> 8;
4790 	cmd->cmd_cdb[13] = len;
4791 	cmd->cmd_actual_len = actual_len;
4792 }
4793 
4794 
4795 /*
4796  * scsa2usb_fill_up_12byte_cdb_len:
4797  *	fill up generic 12-byte command CDBs' len part
4798  */
4799 static void
4800 scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4801 {
4802 	cmd->cmd_cdb[6] = len >> 24;
4803 	cmd->cmd_cdb[7] = len >> 16;
4804 	cmd->cmd_cdb[8] = len >> 8;
4805 	cmd->cmd_cdb[9] = (uchar_t)len;
4806 	cmd->cmd_actual_len = (uchar_t)actual_len;
4807 }
4808 
4809 
4810 /*
4811  * scsa2usb_fill_up_cdb_len:
4812  *	fill up generic 10-byte command CDBs' len part
4813  */
4814 static void
4815 scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *cmd, int len)
4816 {
4817 	cmd->cmd_cdb[SCSA2USB_LEN_0] = len >> 8;
4818 	cmd->cmd_cdb[SCSA2USB_LEN_1] = (uchar_t)len;
4819 }
4820 
4821 
4822 /*
4823  * scsa2usb_read_cd_blk_size:
4824  *	For SCMD_READ_CD opcode (0xbe). Figure out the
4825  *	block size based on expected sector type field
4826  *	definition. See MMC SCSI Specs section 6.1.15
4827  *
4828  *	Based on the value of the "expected_sector_type"
4829  *	field, the block size could be different.
4830  */
4831 static int
4832 scsa2usb_read_cd_blk_size(uchar_t expected_sector_type)
4833 {
4834 	int blk_size;
4835 
4836 	switch (expected_sector_type) {
4837 	case READ_CD_EST_CDDA:
4838 		blk_size = CDROM_BLK_2352;
4839 		break;
4840 	case READ_CD_EST_MODE2:
4841 		blk_size = CDROM_BLK_2336;
4842 		break;
4843 	case READ_CD_EST_MODE2FORM2:
4844 		blk_size = CDROM_BLK_2324;
4845 		break;
4846 	case READ_CD_EST_MODE2FORM1:
4847 	case READ_CD_EST_ALLTYPE:
4848 	case READ_CD_EST_MODE1:
4849 	default:
4850 		blk_size = CDROM_BLK_2048;
4851 	}
4852 
4853 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL, "scsa2usb_read_cd_blk_size: "
4854 	    "est = 0x%x blk_size = %d", expected_sector_type, blk_size);
4855 
4856 	return (blk_size);
4857 }
4858 
4859 
4860 /*
4861  * scsa2usb_bp_to_mblk:
4862  *	Convert a bp to mblk_t. USBA framework understands mblk_t.
4863  */
4864 static mblk_t *
4865 scsa2usb_bp_to_mblk(scsa2usb_state_t *scsa2usbp)
4866 {
4867 	size_t		size;
4868 	mblk_t		*mp;
4869 	struct buf	*bp;
4870 	scsa2usb_cmd_t	*cmd = PKT2CMD(scsa2usbp->scsa2usb_cur_pkt);
4871 
4872 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4873 	    "scsa2usb_bp_to_mblk: ");
4874 
4875 	ASSERT(scsa2usbp->scsa2usb_cur_pkt);
4876 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4877 
4878 	bp = cmd->cmd_bp;
4879 
4880 	if (bp && (bp->b_bcount > 0)) {
4881 		size = ((bp->b_bcount > cmd->cmd_xfercount) ?
4882 		    cmd->cmd_xfercount : bp->b_bcount);
4883 	} else {
4884 
4885 		return (NULL);
4886 	}
4887 
4888 	mp = esballoc_wait((uchar_t *)bp->b_un.b_addr + cmd->cmd_offset,
4889 	    size, BPRI_LO, &frnop);
4890 
4891 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4892 	    "scsa2usb_bp_to_mblk: "
4893 	    "mp=0x%p bp=0x%p pkt=0x%p off=0x%lx sz=%lu add=0x%p",
4894 	    (void *)mp, (void *)bp, (void *)scsa2usbp->scsa2usb_cur_pkt,
4895 	    cmd->cmd_offset, bp->b_bcount - cmd->cmd_offset,
4896 	    (void *)bp->b_un.b_addr);
4897 
4898 	mp->b_wptr += size;
4899 	cmd->cmd_offset += size;
4900 
4901 	return (mp);
4902 }
4903 
4904 
4905 /*
4906  * scsa2usb_handle_data_start:
4907  *	Initiate the data xfer. It could be IN/OUT direction.
4908  *
4909  *	Data IN:
4910  *		Send out the bulk-xfer request
4911  *		if rval implies STALL
4912  *			clear endpoint stall and reset bulk-in pipe
4913  *			handle data read in so far; set cmd->cmd_done
4914  *			also adjust data xfer length accordingly
4915  *		else other error
4916  *			report back to transport
4917  *			typically transport will call reset recovery
4918  *		else (no error)
4919  *			return success
4920  *
4921  *	Data OUT:
4922  *		Send out the bulk-xfer request
4923  *		if rval implies STALL
4924  *			clear endpoint stall and reset bulk-in pipe
4925  *			adjust data xfer length
4926  *		else other error
4927  *			report back to transport
4928  *			typically transport will call reset recovery
4929  *		else (no error)
4930  *			return success
4931  *
4932  *	NOTE: We call this function only if there is xfercount.
4933  */
4934 int
4935 scsa2usb_handle_data_start(scsa2usb_state_t *scsa2usbp,
4936     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4937 {
4938 	int		rval = USB_SUCCESS;
4939 	uint_t		ept_addr;
4940 	usb_flags_t	flags = USB_FLAGS_SLEEP;
4941 #ifdef	SCSA2USB_BULK_ONLY_TEST
4942 	usb_req_attrs_t	attrs = 0;
4943 #else
4944 	usb_req_attrs_t	attrs = USB_ATTRS_SHORT_XFER_OK;
4945 #endif
4946 
4947 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4948 	    "scsa2usb_handle_data_start: BEGIN cmd = %p, req = %p",
4949 	    (void *)cmd, (void *)req);
4950 
4951 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4952 
4953 	switch (cmd->cmd_dir) {
4954 	case USB_EP_DIR_IN:
4955 #ifdef	SCSA2USB_BULK_ONLY_TEST
4956 		/*
4957 		 * This case occurs when the host expects to receive
4958 		 * more data than the device actually transfers. Hi > Di
4959 		 */
4960 		if (scsa2usb_test_case_5) {
4961 			usb_bulk_req_t *req2;
4962 
4963 			req->bulk_len = cmd->cmd_xfercount - 1;
4964 			req->bulk_attributes = 0;
4965 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4966 			SCSA2USB_FREE_MSG(req->bulk_data);
4967 			req->bulk_data = allocb_wait(req->bulk_len, BPRI_LO,
4968 			    STR_NOSIG, NULL);
4969 
4970 			ASSERT(req->bulk_timeout);
4971 			rval = usb_pipe_bulk_xfer(
4972 			    scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4973 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4974 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4975 			    scsa2usbp->scsa2usb_log_handle, "rval = %x", rval);
4976 
4977 			req2 = scsa2usb_init_bulk_req(scsa2usbp,
4978 			    cmd->cmd_xfercount + 2,
4979 			    cmd->cmd_timeout, 0, flags);
4980 			req2->bulk_len = cmd->cmd_xfercount + 2;
4981 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
4982 
4983 			ASSERT(req2->bulk_timeout);
4984 			rval = usb_pipe_bulk_xfer(
4985 			    scsa2usbp->scsa2usb_bulkin_pipe, req2, flags);
4986 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
4987 
4988 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4989 			    scsa2usbp->scsa2usb_log_handle,
4990 			    "TEST 5: Hi > Di: rval = 0x%x", rval);
4991 			scsa2usb_test_case_5 = 0;
4992 			usb_free_bulk_req(req2);
4993 
4994 			return (rval);
4995 		}
4996 
4997 		/*
4998 		 * This happens when the host expects to send data to the
4999 		 * device while the device intends to send data to the host.
5000 		 */
5001 		if (scsa2usb_test_case_8 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) {
5002 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
5003 			    scsa2usbp->scsa2usb_log_handle,
5004 			    "TEST 8: Hi <> Do: Step 2");
5005 			scsa2usb_test_mblk(scsa2usbp, B_TRUE);
5006 			scsa2usb_test_case_8 = 0;
5007 
5008 			return (rval);
5009 		}
5010 #endif	/* SCSA2USB_BULK_ONLY_TEST */
5011 
5012 		ept_addr = scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress;
5013 		req->bulk_len = cmd->cmd_xfercount;
5014 		req->bulk_attributes = attrs;
5015 		SCSA2USB_FREE_MSG(req->bulk_data);
5016 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5017 
5018 		req->bulk_data = esballoc_wait(
5019 		    (uchar_t *)cmd->cmd_bp->b_un.b_addr +
5020 		    cmd->cmd_offset,
5021 		    req->bulk_len, BPRI_LO, &frnop);
5022 
5023 		ASSERT(req->bulk_timeout);
5024 		rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe,
5025 		    req, flags);
5026 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5027 
5028 		break;
5029 
5030 	case USB_EP_DIR_OUT:
5031 #ifdef	SCSA2USB_BULK_ONLY_TEST
5032 		/*
5033 		 * This happens when the host expects to receive data
5034 		 * from the device while the device intends to receive
5035 		 * data from the host.
5036 		 */
5037 		if (scsa2usb_test_case_10 &&
5038 		    (cmd->cmd_cdb[0] == SCMD_WRITE_G1)) {
5039 			req->bulk_len = CSW_LEN;
5040 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5041 
5042 			ASSERT(req->bulk_timeout);
5043 			rval = usb_pipe_bulk_xfer(
5044 			    scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
5045 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5046 
5047 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
5048 			    scsa2usbp->scsa2usb_log_handle,
5049 			    "TEST 10: Ho <> Di: done rval = 0x%x",  rval);
5050 			scsa2usb_test_case_10 = 0;
5051 
5052 			return (rval);
5053 		}
5054 #endif	/* SCSA2USB_BULK_ONLY_TEST */
5055 
5056 		req->bulk_data = scsa2usb_bp_to_mblk(scsa2usbp);
5057 		if (req->bulk_data == NULL) {
5058 
5059 			return (USB_FAILURE);
5060 		}
5061 
5062 #ifdef	SCSA2USB_BULK_ONLY_TEST
5063 		if (scsa2usb_test_case_11) {
5064 			/*
5065 			 * Host expects to send data to the device and
5066 			 * device doesn't expect to receive any data
5067 			 */
5068 			USB_DPRINTF_L1(DPRINT_MASK_SCSA,
5069 			    scsa2usbp->scsa2usb_log_handle, "TEST 11: Ho > Do");
5070 
5071 			scsa2usb_test_mblk(scsa2usbp, B_FALSE);
5072 			scsa2usb_test_case_11 = 0;
5073 		}
5074 #endif	/* SCSA2USB_BULK_ONLY_TEST */
5075 
5076 		ept_addr = scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress;
5077 		req->bulk_len = MBLKL(req->bulk_data);
5078 		req->bulk_timeout = scsa2usb_bulk_timeout(cmd->cmd_timeout);
5079 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5080 
5081 		ASSERT(req->bulk_timeout);
5082 		rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe,
5083 		    req, flags);
5084 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5085 		break;
5086 	}
5087 
5088 	USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5089 	    scsa2usbp->scsa2usb_log_handle,
5090 	    "scsa2usb_handle_data_start: rval=%d cr=%d", rval,
5091 	    req->bulk_completion_reason);
5092 
5093 	if (rval != USB_SUCCESS) {
5094 		/* Handle Errors now */
5095 		if (req->bulk_completion_reason == USB_CR_STALL) {
5096 			if (cmd->cmd_dir == USB_EP_DIR_IN) {
5097 				(void) scsa2usb_clear_ept_stall(
5098 				    scsa2usbp, ept_addr,
5099 				    scsa2usbp-> scsa2usb_bulkin_pipe,
5100 				    "bulk-in");
5101 			} else {
5102 				(void) scsa2usb_clear_ept_stall(
5103 				    scsa2usbp, ept_addr,
5104 				    scsa2usbp-> scsa2usb_bulkout_pipe,
5105 				    "bulk-out");
5106 			}
5107 		}
5108 
5109 		/* no more data to transfer after this */
5110 		cmd->cmd_done = 1;
5111 	}
5112 
5113 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5114 	    "scsa2usb_handle_data_start: END %s data rval = %d",
5115 	    (cmd->cmd_dir == USB_EP_DIR_IN) ? "bulk-in" : "bulk-out", rval);
5116 
5117 	return (rval);
5118 }
5119 
5120 
5121 /*
5122  * scsa2usb_handle_data_done:
5123  *	This function handles the completion of the data xfer.
5124  *	It also massages the inquiry data. This function may
5125  *	also be called after a stall.
5126  */
5127 void
5128 scsa2usb_handle_data_done(scsa2usb_state_t *scsa2usbp,
5129     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
5130 {
5131 	struct buf	*bp = cmd->cmd_bp;
5132 	struct scsi_pkt	*pkt = scsa2usbp->scsa2usb_cur_pkt;
5133 	mblk_t		*data = req->bulk_data;
5134 	int		len = data ? MBLKL(data) : 0;
5135 	uint32_t	max_lba;
5136 
5137 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5138 
5139 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5140 	    "scsa2usb_handle_data_done:\n\tcmd = 0x%p data = 0x%p len = 0x%x",
5141 	    (void *)cmd, (void *)data, len);
5142 
5143 	cmd->cmd_resid_xfercount = cmd->cmd_xfercount - len;
5144 
5145 	if (len)  {
5146 		uchar_t	*p;
5147 		uchar_t dtype;
5148 		scsa2usb_read_cap_t *cap;
5149 		struct scsi_inquiry *inq;
5150 
5151 		switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
5152 		case SCMD_INQUIRY:
5153 			/*
5154 			 * cache a copy of the inquiry data for our own use
5155 			 * but ensure that we have at least up to
5156 			 * inq_revision, inq_serial is not required.
5157 			 * ignore inquiry data returned for inquiry commands
5158 			 * with SCSI-3 EVPD, CmdDt bits set.
5159 			 */
5160 			if (((cmd->cmd_cdb[SCSA2USB_LUN] & 0x1f) == 0) &&
5161 			    (len >= SCSA2USB_MAX_INQ_LEN)) {
5162 				inq = (struct scsi_inquiry *)data->b_rptr;
5163 				dtype = inq->inq_dtype & DTYPE_MASK;
5164 				/*
5165 				 * scsi framework sends zero byte write(10) cmd
5166 				 * to (Simplified) direct-access devices with
5167 				 * inquiry version > 2 for reservation changes.
5168 				 * But some USB devices don't support zero byte
5169 				 * write(10) even though they have inquiry
5170 				 * version > 2. Considering scsa2usb driver
5171 				 * doesn't support reservation and all the
5172 				 * reservation cmds are being faked, we fake
5173 				 * the inquiry version to 0 to make scsi
5174 				 * framework send test unit ready cmd which is
5175 				 * supported by all the usb devices.
5176 				 */
5177 				if (((dtype == DTYPE_DIRECT) ||
5178 				    (dtype == DTYPE_RBC)) &&
5179 				    (inq->inq_ansi > 2)) {
5180 					inq->inq_ansi = 0;
5181 				}
5182 
5183 				bzero(&scsa2usbp->scsa2usb_lun_inquiry
5184 				    [pkt->pkt_address.a_lun],
5185 				    sizeof (struct scsi_inquiry));
5186 				bcopy(data->b_rptr,
5187 				    &scsa2usbp->scsa2usb_lun_inquiry
5188 				    [pkt->pkt_address.a_lun], len);
5189 			}
5190 
5191 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5192 			    scsa2usbp->scsa2usb_log_handle,
5193 			    "scsi inquiry type = 0x%x",
5194 			    scsa2usbp->scsa2usb_lun_inquiry
5195 			    [pkt->pkt_address.a_lun].inq_dtype);
5196 
5197 			cmd->cmd_done = 1;
5198 			goto handle_data;
5199 
5200 		case SCMD_READ_CAPACITY:
5201 			cap = (scsa2usb_read_cap_t *)data->b_rptr;
5202 
5203 			/* Figure out the logical block size */
5204 			if ((len >= sizeof (struct scsa2usb_read_cap)) &&
5205 			    (req->bulk_completion_reason == USB_CR_OK)) {
5206 				scsa2usbp->
5207 				    scsa2usb_lbasize[pkt->pkt_address.a_lun] =
5208 				    SCSA2USB_MK_32BIT(
5209 				    cap->scsa2usb_read_cap_blen3,
5210 				    cap->scsa2usb_read_cap_blen2,
5211 				    cap->scsa2usb_read_cap_blen1,
5212 				    cap->scsa2usb_read_cap_blen0);
5213 
5214 				max_lba = SCSA2USB_MK_32BIT(
5215 				    cap->scsa2usb_read_cap_lba3,
5216 				    cap->scsa2usb_read_cap_lba2,
5217 				    cap->scsa2usb_read_cap_lba1,
5218 				    cap->scsa2usb_read_cap_lba0);
5219 
5220 				/*
5221 				 * Some devices return total logical block
5222 				 * number instead of highest logical block
5223 				 * address. Adjust the value by minus 1.
5224 				 */
5225 				if (max_lba > 0 && (scsa2usbp->scsa2usb_attrs &
5226 				    SCSA2USB_ATTRS_NO_CAP_ADJUST) == 0) {
5227 					max_lba -= 1;
5228 					cap->scsa2usb_read_cap_lba0 =
5229 					    (uchar_t)(max_lba & 0xFF);
5230 					cap->scsa2usb_read_cap_lba1 =
5231 					    (uchar_t)(max_lba >> 8 & 0xFF);
5232 					cap->scsa2usb_read_cap_lba2 =
5233 					    (uchar_t)(max_lba >> 16 & 0xFF);
5234 					cap->scsa2usb_read_cap_lba3 =
5235 					    (uchar_t)(max_lba >> 24 & 0xFF);
5236 				}
5237 
5238 				USB_DPRINTF_L2(DPRINT_MASK_SCSA,
5239 				    scsa2usbp->scsa2usb_log_handle,
5240 				    "bytes in each logical block=0x%lx,"
5241 				    "number of total logical blocks=0x%x",
5242 				    scsa2usbp->
5243 				    scsa2usb_lbasize[pkt->pkt_address.a_lun],
5244 				    max_lba + 1);
5245 			}
5246 			cmd->cmd_done = 1;
5247 			goto handle_data;
5248 
5249 		case SCMD_REQUEST_SENSE:
5250 			p = data->b_rptr;
5251 			USB_DPRINTF_L2(DPRINT_MASK_SCSA,
5252 			    scsa2usbp->scsa2usb_log_handle,
5253 			    "cdb: %x rqsense: "
5254 			    "%x %x %x %x %x %x %x %x %x %x\n\t"
5255 			    "%x %x %x %x %x %x %x %x %x %x",
5256 			    cmd->cmd_cdb[0],
5257 			    p[0], p[1], p[2], p[3], p[4],
5258 			    p[5], p[6], p[7], p[8], p[9],
5259 			    p[10], p[11], p[12], p[13], p[14],
5260 			    p[15], p[16], p[17], p[18], p[19]);
5261 
5262 			scsa2usbp->scsa2usb_last_cmd.status = p[2];
5263 			cmd->cmd_done = 1;
5264 			/* FALLTHROUGH */
5265 
5266 		default:
5267 handle_data:
5268 			if (bp && len && (cmd->cmd_dir == USB_EP_DIR_IN)) {
5269 				/*
5270 				 * we don't have to copy the data, the
5271 				 * data pointers for the mblk_t for
5272 				 * the bulk-in xfer points to the
5273 				 * struct buf * data.
5274 				 */
5275 				cmd->cmd_offset += len;
5276 			}
5277 
5278 			USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5279 			    scsa2usbp->scsa2usb_log_handle,
5280 			    "len = 0x%x total = 0x%lx offset = 0x%lx",
5281 			    len, cmd->cmd_total_xfercount, cmd->cmd_offset);
5282 
5283 			/*
5284 			 * update total_xfercount now but it may be
5285 			 * adjusted after receiving the residue
5286 			 */
5287 			cmd->cmd_total_xfercount -= len;
5288 
5289 			if ((req->bulk_completion_reason != USB_CR_OK) ||
5290 			    (cmd->cmd_resid_xfercount != 0) ||
5291 			    (cmd->cmd_total_xfercount == 0)) {
5292 				/* set pkt_resid to total to be sure */
5293 				pkt->pkt_resid = cmd->cmd_total_xfercount;
5294 				cmd->cmd_done = 1;
5295 			}
5296 
5297 			break;
5298 		}
5299 	} else {
5300 		if (cmd->cmd_dir == USB_EP_DIR_OUT) {
5301 			if (cmd->cmd_total_xfercount == 0) {
5302 				cmd->cmd_done = 1;
5303 			}
5304 		}
5305 	}
5306 }
5307 
5308 
5309 /*
5310  * scsa2usb_init_bulk_req:
5311  *	Allocate (synchronously) and fill in a bulk-request
5312  */
5313 usb_bulk_req_t *
5314 scsa2usb_init_bulk_req(scsa2usb_state_t *scsa2usbp, size_t length,
5315     uint_t timeout, usb_req_attrs_t attrs, usb_flags_t flags)
5316 {
5317 	usb_bulk_req_t	*req;
5318 
5319 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5320 
5321 	req = usb_alloc_bulk_req(scsa2usbp->scsa2usb_dip, length,
5322 	    flags | USB_FLAGS_SLEEP);
5323 
5324 	req->bulk_len = (uint_t)length;			/* xfer length */
5325 	req->bulk_timeout = scsa2usb_bulk_timeout(timeout); /* xfer timeout */
5326 	req->bulk_attributes = attrs;		/* xfer attrs */
5327 	req->bulk_client_private = (usb_opaque_t)scsa2usbp; /* statep */
5328 
5329 	return (req);
5330 }
5331 
5332 
5333 /*
5334  * scsa2usb_bulk_timeout:
5335  *	ensure that bulk requests do not have infinite timeout values
5336  */
5337 int
5338 scsa2usb_bulk_timeout(int timeout)
5339 {
5340 	return ((timeout == 0) ? scsa2usb_long_timeout : timeout);
5341 }
5342 
5343 
5344 /*
5345  * scsa2usb_clear_ept_stall:
5346  *	clear endpoint stall and reset pipes
5347  */
5348 int
5349 scsa2usb_clear_ept_stall(scsa2usb_state_t *scsa2usbp, uint_t ept_addr,
5350     usb_pipe_handle_t ph, char *what)
5351 {
5352 	int rval;
5353 	dev_info_t *dip = scsa2usbp->scsa2usb_dip;
5354 
5355 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5356 	if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
5357 
5358 		return (USB_FAILURE);
5359 	}
5360 
5361 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5362 	rval = usb_clr_feature(dip, USB_DEV_REQ_RCPT_EP, 0, ept_addr,
5363 	    USB_FLAGS_SLEEP, NULL, NULL);
5364 
5365 	usb_pipe_reset(dip, ph, USB_FLAGS_SLEEP, NULL, NULL);
5366 
5367 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5368 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5369 	    "scsa2usb_clear_ept_stall: on %s: ept = 0x%x rval = %d",
5370 	    what, ept_addr, rval);
5371 
5372 	return (rval);
5373 }
5374 
5375 
5376 /*
5377  * scsa2usb_pkt_completion:
5378  *	Handle pkt completion.
5379  */
5380 static void
5381 scsa2usb_pkt_completion(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
5382 {
5383 	scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
5384 	size_t len;
5385 
5386 	ASSERT(pkt);
5387 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5388 
5389 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5390 	    "scsa2usb_pkt_completion:\n\tscsa2usbp = 0x%p "
5391 	    "reason=%d, status=%d state=0x%x stats=0x%x resid=0x%lx",
5392 	    (void *)scsa2usbp, pkt->pkt_reason, *(pkt->pkt_scbp),
5393 	    pkt->pkt_state, pkt->pkt_statistics, pkt->pkt_resid);
5394 
5395 	if (pkt->pkt_reason == CMD_CMPLT) {
5396 		pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
5397 		    STATE_SENT_CMD | STATE_GOT_STATUS;
5398 		if (cmd->cmd_xfercount) {
5399 			pkt->pkt_state |= STATE_XFERRED_DATA;
5400 		}
5401 	} else {
5402 		pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
5403 		    STATE_SENT_CMD;
5404 	}
5405 
5406 	/*
5407 	 * don't zap the current state when in panic as this will
5408 	 * make debugging harder
5409 	 */
5410 	if ((scsa2usbp->scsa2usb_cur_pkt == pkt) && !ddi_in_panic()) {
5411 		SCSA2USB_RESET_CUR_PKT(scsa2usbp);
5412 
5413 		len = sizeof (scsa2usbp->scsa2usb_last_cmd.cdb);
5414 		bzero(scsa2usbp->scsa2usb_last_cmd.cdb, len);
5415 
5416 		len = (len < cmd->cmd_cdblen) ? len : cmd->cmd_cdblen;
5417 		USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5418 		    scsa2usbp->scsa2usb_log_handle,
5419 		    "scsa2usb_pkt_completion: save last cmd, len=%ld", len);
5420 
5421 		/* save the last command */
5422 		bcopy(pkt->pkt_cdbp, scsa2usbp->scsa2usb_last_cmd.cdb, len);
5423 
5424 		/* reset the scsa2usb_last_cmd.status value */
5425 		if ((pkt->pkt_cdbp[0] != SCMD_REQUEST_SENSE) &&
5426 		    (pkt->pkt_cdbp[0] != SCMD_INQUIRY)) {
5427 			scsa2usbp->scsa2usb_last_cmd.status = 0;
5428 		}
5429 
5430 		/*
5431 		 * set pkt state to NONE *before* calling back as the target
5432 		 * driver will immediately submit the next packet
5433 		 */
5434 		scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
5435 	}
5436 
5437 	if (pkt->pkt_comp) {
5438 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5439 		scsi_hba_pkt_comp(pkt);
5440 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5441 
5442 	}
5443 }
5444 
5445 
5446 /*
5447  * Even handling functions:
5448  *
5449  * scsa2usb_reconnect_event_cb:
5450  *	event handling
5451  */
5452 static int
5453 scsa2usb_reconnect_event_cb(dev_info_t *dip)
5454 {
5455 	scsa2usb_state_t *scsa2usbp =
5456 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5457 	dev_info_t	*cdip;
5458 	int		circ;
5459 	int		rval = USB_SUCCESS;
5460 
5461 	ASSERT(scsa2usbp != NULL);
5462 
5463 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5464 	    "scsa2usb_reconnect_event_cb: dip = 0x%p", (void *)dip);
5465 
5466 	scsa2usb_restore_device_state(dip, scsa2usbp);
5467 
5468 	USB_DPRINTF_L0(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5469 	    "Reinserted device is accessible again.");
5470 
5471 	ndi_devi_enter(dip, &circ);
5472 	for (cdip = ddi_get_child(dip); cdip; ) {
5473 		dev_info_t *next = ddi_get_next_sibling(cdip);
5474 
5475 		mutex_enter(&DEVI(cdip)->devi_lock);
5476 		DEVI_SET_DEVICE_REINSERTED(cdip);
5477 		mutex_exit(&DEVI(cdip)->devi_lock);
5478 
5479 		cdip = next;
5480 	}
5481 	ndi_devi_exit(dip, circ);
5482 
5483 	/* stop suppressing warnings */
5484 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5485 	scsa2usbp->scsa2usb_warning_given = B_FALSE;
5486 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5487 
5488 	if (scsa2usbp->scsa2usb_ugen_hdl) {
5489 		rval = usb_ugen_reconnect_ev_cb(
5490 		    scsa2usbp->scsa2usb_ugen_hdl);
5491 	}
5492 
5493 	return (rval);
5494 }
5495 
5496 
5497 /*
5498  * scsa2usb_all_waitQs_empty:
5499  *	check if all waitQs empty
5500  */
5501 static int
5502 scsa2usb_all_waitQs_empty(scsa2usb_state_t *scsa2usbp)
5503 {
5504 	uint_t	lun;
5505 
5506 	for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
5507 		if (usba_list_entry_count(
5508 		    &scsa2usbp->scsa2usb_waitQ[lun])) {
5509 
5510 			return (USB_FAILURE);
5511 		}
5512 	}
5513 
5514 	return (USB_SUCCESS);
5515 }
5516 
5517 
5518 /*
5519  * scsa2usb_disconnect_event_cb:
5520  *	callback for disconnect events
5521  */
5522 static int
5523 scsa2usb_disconnect_event_cb(dev_info_t *dip)
5524 {
5525 	scsa2usb_state_t *scsa2usbp =
5526 	    ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5527 	dev_info_t	*cdip;
5528 	int		circ, i;
5529 	int		rval = USB_SUCCESS;
5530 
5531 	ASSERT(scsa2usbp != NULL);
5532 
5533 	USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5534 	    "scsa2usb_disconnect_event_cb: dip = 0x%p", (void *)dip);
5535 
5536 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5537 	scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
5538 
5539 	/*
5540 	 * wait till the work thread is done, carry on regardless
5541 	 * if not.
5542 	 */
5543 	for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
5544 		if ((scsa2usbp->scsa2usb_work_thread_id == NULL) &&
5545 		    (scsa2usbp->scsa2usb_cur_pkt == NULL) &&
5546 		    (scsa2usb_all_waitQs_empty(scsa2usbp) ==
5547 		    USB_SUCCESS)) {
5548 
5549 			break;
5550 		}
5551 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5552 		delay(drv_usectohz(1000000));
5553 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5554 	}
5555 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5556 
5557 	ndi_devi_enter(dip, &circ);
5558 	for (cdip = ddi_get_child(dip); cdip; ) {
5559 		dev_info_t *next = ddi_get_next_sibling(cdip);
5560 
5561 		mutex_enter(&DEVI(cdip)->devi_lock);
5562 		DEVI_SET_DEVICE_REMOVED(cdip);
5563 		mutex_exit(&DEVI(cdip)->devi_lock);
5564 
5565 		cdip = next;
5566 	}
5567 	ndi_devi_exit(dip, circ);
5568 
5569 	if (scsa2usbp->scsa2usb_ugen_hdl) {
5570 		rval = usb_ugen_disconnect_ev_cb(
5571 		    scsa2usbp->scsa2usb_ugen_hdl);
5572 	}
5573 
5574 	return (rval);
5575 }
5576 
5577 
5578 /*
5579  * PM support
5580  *
5581  * scsa2usb_create_pm_components:
5582  *	create the pm components required for power management
5583  *	no mutex is need when calling USBA interfaces
5584  */
5585 static void
5586 scsa2usb_create_pm_components(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
5587 {
5588 	scsa2usb_power_t *pm;
5589 	uint_t		pwr_states;
5590 
5591 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5592 
5593 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5594 	    "scsa2usb_create_pm_components: dip = 0x%p, scsa2usbp = 0x%p",
5595 	    (void *)dip, (void *)scsa2usbp);
5596 
5597 	/*
5598 	 * Check if power management is disabled by a per-device quirk:
5599 	 */
5600 	if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_PM) == 0) {
5601 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5602 		    "device cannot be power managed");
5603 		return;
5604 	}
5605 
5606 	/* Allocate the PM state structure */
5607 	pm = kmem_zalloc(sizeof (scsa2usb_power_t), KM_SLEEP);
5608 
5609 	scsa2usbp->scsa2usb_pm = pm;
5610 	pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5611 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5612 
5613 	if (usb_create_pm_components(dip, &pwr_states) ==
5614 	    USB_SUCCESS) {
5615 		if (usb_handle_remote_wakeup(dip,
5616 		    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
5617 			pm->scsa2usb_wakeup_enabled = 1;
5618 		}
5619 
5620 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5621 		pm->scsa2usb_pwr_states = (uint8_t)pwr_states;
5622 		scsa2usb_raise_power(scsa2usbp);
5623 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5624 	}
5625 
5626 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5627 }
5628 
5629 
5630 /*
5631  * scsa2usb_raise_power:
5632  *	check if the device is using full power or not
5633  */
5634 static void
5635 scsa2usb_raise_power(scsa2usb_state_t *scsa2usbp)
5636 {
5637 	USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5638 	    "scsa2usb_raise_power:");
5639 
5640 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5641 
5642 	if (scsa2usbp->scsa2usb_pm) {
5643 		scsa2usb_pm_busy_component(scsa2usbp);
5644 		if (scsa2usbp->scsa2usb_pm->scsa2usb_current_power !=
5645 		    USB_DEV_OS_FULL_PWR) {
5646 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5647 			(void) pm_raise_power(scsa2usbp->scsa2usb_dip,
5648 			    0, USB_DEV_OS_FULL_PWR);
5649 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5650 		}
5651 	}
5652 }
5653 
5654 
5655 /*
5656  * functions to handle power transition for OS levels 0 -> 3
5657  */
5658 static int
5659 scsa2usb_pwrlvl0(scsa2usb_state_t *scsa2usbp)
5660 {
5661 	int	rval;
5662 
5663 	switch (scsa2usbp->scsa2usb_dev_state) {
5664 	case USB_DEV_ONLINE:
5665 		/* Deny the powerdown request if the device is busy */
5666 		if (scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy != 0) {
5667 
5668 			return (USB_FAILURE);
5669 		}
5670 
5671 		/*
5672 		 * stop polling on interrupt pipe
5673 		 */
5674 		scsa2usb_cbi_stop_intr_polling(scsa2usbp);
5675 
5676 		/* Issue USB D3 command to the device here */
5677 		rval = usb_set_device_pwrlvl3(scsa2usbp->scsa2usb_dip);
5678 		ASSERT(rval == USB_SUCCESS);
5679 
5680 		scsa2usbp->scsa2usb_dev_state = USB_DEV_PWRED_DOWN;
5681 
5682 		/* FALLTHRU */
5683 	case USB_DEV_DISCONNECTED:
5684 	case USB_DEV_SUSPENDED:
5685 	case USB_DEV_PWRED_DOWN:
5686 	default:
5687 		scsa2usbp->scsa2usb_pm->scsa2usb_current_power =
5688 		    USB_DEV_OS_PWR_OFF;
5689 
5690 		return (USB_SUCCESS);
5691 	}
5692 }
5693 
5694 
5695 static int
5696 scsa2usb_pwrlvl1(scsa2usb_state_t *scsa2usbp)
5697 {
5698 	int	rval;
5699 
5700 	/* Issue USB D2 command to the device here */
5701 	rval = usb_set_device_pwrlvl2(scsa2usbp->scsa2usb_dip);
5702 	ASSERT(rval == USB_SUCCESS);
5703 
5704 	return (DDI_FAILURE);
5705 }
5706 
5707 
5708 static int
5709 scsa2usb_pwrlvl2(scsa2usb_state_t *scsa2usbp)
5710 {
5711 	int	rval;
5712 
5713 	/* Issue USB D1 command to the device here */
5714 	rval = usb_set_device_pwrlvl1(scsa2usbp->scsa2usb_dip);
5715 	ASSERT(rval == USB_SUCCESS);
5716 
5717 	return (DDI_FAILURE);
5718 }
5719 
5720 
5721 static int
5722 scsa2usb_pwrlvl3(scsa2usb_state_t *scsa2usbp)
5723 {
5724 	int	rval;
5725 
5726 	/*
5727 	 * PM framework tries to put us in full power
5728 	 * during system shutdown. If we are disconnected
5729 	 * return success anyways
5730 	 */
5731 	if (scsa2usbp->scsa2usb_dev_state != USB_DEV_DISCONNECTED) {
5732 		/* Issue USB D0 command to the device here */
5733 		rval = usb_set_device_pwrlvl0(scsa2usbp->scsa2usb_dip);
5734 		ASSERT(rval == USB_SUCCESS);
5735 
5736 		scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
5737 	}
5738 	scsa2usbp->scsa2usb_pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5739 
5740 	return (DDI_SUCCESS);
5741 }
5742 
5743 
5744 /*
5745  * scsa2usb_power:
5746  *	power entry point
5747  */
5748 /* ARGSUSED */
5749 static int
5750 scsa2usb_power(dev_info_t *dip, int comp, int level)
5751 {
5752 	scsa2usb_state_t	*scsa2usbp;
5753 	scsa2usb_power_t	*pm;
5754 	int			rval = DDI_FAILURE;
5755 
5756 	scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5757 
5758 	USB_DPRINTF_L3(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5759 	    "scsa2usb_power: Begin scsa2usbp (%p): level = %d",
5760 	    (void *)scsa2usbp, level);
5761 
5762 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5763 	if (SCSA2USB_BUSY(scsa2usbp)) {
5764 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5765 		    "scsa2usb_power: busy");
5766 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5767 
5768 		return (rval);
5769 	}
5770 
5771 	pm = scsa2usbp->scsa2usb_pm;
5772 	if (pm == NULL) {
5773 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5774 		    "scsa2usb_power: pm NULL");
5775 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5776 
5777 		return (rval);
5778 	}
5779 
5780 	/* check if we are transitioning to a legal power level */
5781 	if (USB_DEV_PWRSTATE_OK(pm->scsa2usb_pwr_states, level)) {
5782 		USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5783 		    "scsa2usb_power: illegal power level = %d "
5784 		    "pwr_states: %x", level, pm->scsa2usb_pwr_states);
5785 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5786 
5787 		return (rval);
5788 	}
5789 
5790 	switch (level) {
5791 	case USB_DEV_OS_PWR_OFF :
5792 		rval = scsa2usb_pwrlvl0(scsa2usbp);
5793 		break;
5794 	case USB_DEV_OS_PWR_1 :
5795 		rval = scsa2usb_pwrlvl1(scsa2usbp);
5796 		break;
5797 	case USB_DEV_OS_PWR_2 :
5798 		rval = scsa2usb_pwrlvl2(scsa2usbp);
5799 		break;
5800 	case USB_DEV_OS_FULL_PWR :
5801 		rval = scsa2usb_pwrlvl3(scsa2usbp);
5802 		break;
5803 	}
5804 
5805 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5806 
5807 	return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
5808 }
5809 
5810 
5811 static void
5812 scsa2usb_pm_busy_component(scsa2usb_state_t *scsa2usbp)
5813 {
5814 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5815 
5816 	if (scsa2usbp->scsa2usb_pm) {
5817 		scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy++;
5818 
5819 		USB_DPRINTF_L4(DPRINT_MASK_PM,
5820 		    scsa2usbp->scsa2usb_log_handle,
5821 		    "scsa2usb_pm_busy_component: %d",
5822 		    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5823 
5824 		mutex_exit(&scsa2usbp->scsa2usb_mutex);
5825 
5826 		if (pm_busy_component(scsa2usbp->scsa2usb_dip, 0) !=
5827 		    DDI_SUCCESS) {
5828 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5829 			ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5830 			scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5831 
5832 			USB_DPRINTF_L2(DPRINT_MASK_PM,
5833 			    scsa2usbp->scsa2usb_log_handle,
5834 			    "scsa2usb_pm_busy_component failed: %d",
5835 			    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5836 
5837 			return;
5838 		}
5839 		mutex_enter(&scsa2usbp->scsa2usb_mutex);
5840 	}
5841 }
5842 
5843 
5844 /*
5845  * scsa2usb_pm_idle_component:
5846  *	idles the device
5847  */
5848 static void
5849 scsa2usb_pm_idle_component(scsa2usb_state_t *scsa2usbp)
5850 {
5851 	ASSERT(!mutex_owned(&scsa2usbp->scsa2usb_mutex));
5852 
5853 	if (scsa2usbp->scsa2usb_pm) {
5854 		if (pm_idle_component(scsa2usbp->scsa2usb_dip, 0) ==
5855 		    DDI_SUCCESS) {
5856 			mutex_enter(&scsa2usbp->scsa2usb_mutex);
5857 			ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5858 			scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5859 
5860 			USB_DPRINTF_L4(DPRINT_MASK_PM,
5861 			    scsa2usbp->scsa2usb_log_handle,
5862 			    "scsa2usb_pm_idle_component: %d",
5863 			    scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5864 
5865 			mutex_exit(&scsa2usbp->scsa2usb_mutex);
5866 		}
5867 	}
5868 }
5869 
5870 
5871 #ifdef	DEBUG
5872 /*
5873  * scsa2usb_print_cdb:
5874  *	prints CDB
5875  */
5876 void
5877 scsa2usb_print_cdb(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
5878 {
5879 	uchar_t *c = (uchar_t *)&cmd->cmd_cdb;
5880 
5881 	USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5882 	    "cmd = 0x%p opcode=%s "
5883 	    "cdb: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
5884 	    (void *)cmd,
5885 	    scsi_cname(cmd->cmd_cdb[SCSA2USB_OPCODE], scsa2usb_cmds),
5886 	    c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8],
5887 	    c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
5888 }
5889 #endif	/* DEBUG */
5890 
5891 
5892 #ifdef	SCSA2USB_BULK_ONLY_TEST
5893 /*
5894  * scsa2usb_test_mblk:
5895  *	This function sends a dummy data mblk_t to simulate
5896  *	the following test cases: 5 and 11.
5897  */
5898 static void
5899 scsa2usb_test_mblk(scsa2usb_state_t *scsa2usbp, boolean_t large)
5900 {
5901 	int			i, rval;
5902 	size_t			len;
5903 	usb_flags_t		flags = USB_FLAGS_SLEEP;
5904 	usb_bulk_req_t		*req;
5905 
5906 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5907 
5908 	/* should we create a larger mblk? */
5909 	len = (large == B_TRUE) ? DEV_BSIZE : USB_BULK_CBWCMD_LEN;
5910 
5911 	req = scsa2usb_init_bulk_req(scsa2usbp, len,
5912 	    SCSA2USB_BULK_PIPE_TIMEOUT, 0, flags);
5913 
5914 	/* fill up the data mblk */
5915 	for (i = 0; i < len; i++) {
5916 		*req->bulk_data->b_wptr++ = (uchar_t)i;
5917 	}
5918 
5919 	mutex_exit(&scsa2usbp->scsa2usb_mutex);
5920 	ASSERT(req->bulk_timeout);
5921 	rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe, req, flags);
5922 	mutex_enter(&scsa2usbp->scsa2usb_mutex);
5923 
5924 	USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5925 	    "scsa2usb_test_mblk: Sent Data Out rval = 0x%x", rval);
5926 
5927 	usb_free_bulk_req(req);
5928 }
5929 #endif	/* SCSA2USB_BULK_ONLY_TEST */
5930