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