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