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