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