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