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