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.
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.
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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * Copyright 2016 Joyent, Inc.
26 * Copyright (c) 2016 by Delphix. All rights reserved.
31 * scsa2usb bridge nexus driver:
33 * This driver supports the following wire transports:
34 * a. Bulk Only transport (see usb_ms_bulkonly.c)
35 * b. CB transport (see usb_ms_cbi.c)
36 * c. CBI transport with interrupt status completion (see usb_ms_cbi.c)
38 * It handles the following command sets:
40 * b. ATAPI command set (subset of SCSI command set)
41 * c. UFI command set (
42 * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf)
44 * For details on USB Mass Storage Class overview:
45 * http://www.usb.org/developers/devclass_docs/usbmassover_11.pdf
48 #include <sys/usb/usba/usbai_version.h>
49 #include <sys/scsi/scsi.h>
51 #include <sys/sunndi.h>
52 #include <sys/esunddi.h>
53 #include <sys/callb.h>
55 #include <sys/kobj_lex.h>
56 #include <sys/strsubr.h>
57 #include <sys/strsun.h>
58 #include <sys/sysmacros.h>
60 #include <sys/usb/usba.h>
61 #include <sys/usb/clients/ugen/usb_ugen.h>
62 #include <sys/usb/usba/usba_ugen.h>
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>
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 *,
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
*,
84 static int scsa2usb_do_tur(scsa2usb_state_t
*, struct scsi_address
*);
86 /* override property handling */
87 static void scsa2usb_override(scsa2usb_state_t
*);
88 static int scsa2usb_parse_input_str(char *, scsa2usb_ov_t
*,
90 static void scsa2usb_override_error(char *, scsa2usb_state_t
*);
91 static char *scsa2usb_strtok_r(char *, char *, char **);
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);
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
*,
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 *);
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
,
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
*);
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
*);
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
*);
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
*);
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
*);
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
*);
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
*);
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
*);
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
*);
188 /* external functions for Bulk only (BO) support */
189 extern int scsa2usb_bulk_only_transport(scsa2usb_state_t
*,
191 extern int scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t
*);
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
*);
199 static char *scsa2usb_cmds
[] = {
229 "\112geteventnotify",
231 "\116stop/play_scan",
238 "\133closetrksession",
257 * Mass-Storage devices masquerade as "sd" disks.
259 * These devices may not support all SCSI CDBs in their
260 * entirety due to their hardware implementation limitations.
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)
266 #define X ((uint16_t)(-1))
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
},
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
},
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
},
286 /* Iomega Zip250 drive */
287 {MS_IOMEGA_VID
, MS_IOMEGA_PID_ZIP250
, 0, SCSA2USB_ATTRS_GET_LUN
},
289 /* Iomega Clik! drive */
290 {MS_IOMEGA_VID
, MS_IOMEGA_PID_CLIK
, 0,
291 SCSA2USB_ATTRS_GET_LUN
| SCSA2USB_ATTRS_START_STOP
},
293 /* Kingston DataTraveler Stick / PNY Attache Stick */
294 {MS_TOSHIBA_VID
, MS_TOSHIBA_PID0
, 0,
295 SCSA2USB_ATTRS_GET_LUN
},
297 /* PNY Floppy drive */
298 {MS_PNY_VID
, MS_PNY_PID0
, 0,
299 SCSA2USB_ATTRS_GET_LUN
},
301 /* SMSC floppy Device - and its clones */
302 {MS_SMSC_VID
, X
, 0, SCSA2USB_ATTRS_START_STOP
},
304 /* Hagiwara SmartMedia Device */
305 {MS_HAGIWARA_SYS_COM_VID
, MS_HAGIWARA_SYSCOM_PID1
, 0,
306 SCSA2USB_ATTRS_GET_LUN
| SCSA2USB_ATTRS_START_STOP
},
308 /* Hagiwara CompactFlash Device */
309 {MS_HAGIWARA_SYS_COM_VID
, MS_HAGIWARA_SYSCOM_PID2
, 0,
310 SCSA2USB_ATTRS_GET_LUN
| SCSA2USB_ATTRS_START_STOP
},
312 /* Hagiwara SmartMedia/CompactFlash Combo Device */
313 {MS_HAGIWARA_SYS_COM_VID
, MS_HAGIWARA_SYSCOM_PID3
, 0,
314 SCSA2USB_ATTRS_START_STOP
},
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
},
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
},
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
},
328 /* Neodio Technologies Corporation SM/CF/MS/SD Combo Device */
329 {MS_NEODIO_VID
, MS_NEODIO_DEVICE_3050
, 0,
330 SCSA2USB_ATTRS_MODE_SENSE
},
332 /* dumb flash devices */
333 {MS_SONY_FLASH_VID
, MS_SONY_FLASH_PID
, 0,
334 SCSA2USB_ATTRS_REDUCED_CMD
},
336 {MS_TREK_FLASH_VID
, MS_TREK_FLASH_PID
, 0,
337 SCSA2USB_ATTRS_REDUCED_CMD
},
339 {MS_PENN_FLASH_VID
, MS_PENN_FLASH_PID
, 0,
340 SCSA2USB_ATTRS_REDUCED_CMD
},
342 /* SimpleTech UCF-100 CF Device */
343 {MS_SIMPLETECH_VID
, MS_SIMPLETECH_PID1
, 0,
344 SCSA2USB_ATTRS_REDUCED_CMD
},
346 {MS_ADDONICS_CARD_READER_VID
, MS_ADDONICS_CARD_READER_PID
,
347 0, SCSA2USB_ATTRS_REDUCED_CMD
},
349 /* Acomdata 80GB USB/1394 Hard Disk */
350 {MS_ACOMDATA_VID
, MS_ACOMDATA_PID1
, 0,
351 SCSA2USB_ATTRS_USE_CSW_RESIDUE
},
353 /* OTi6828 Flash Disk */
354 {MS_OTI_VID
, MS_OTI_DEVICE_6828
, 0,
355 SCSA2USB_ATTRS_USE_CSW_RESIDUE
},
357 /* AMI Virtual Floppy */
358 {MS_AMI_VID
, MS_AMI_VIRTUAL_FLOPPY
, 0,
359 SCSA2USB_ATTRS_NO_MEDIA_CHECK
},
361 /* ScanLogic USB Storage Device */
362 {MS_SCANLOGIC_VID
, MS_SCANLOGIC_PID1
, 0,
363 SCSA2USB_ATTRS_NO_CAP_ADJUST
},
365 /* Super Top USB 2.0 IDE Device */
366 {MS_SUPERTOP_VID
, MS_SUPERTOP_DEVICE_6600
, 0,
367 SCSA2USB_ATTRS_USE_CSW_RESIDUE
},
369 /* Aigo Miniking Device NEHFSP14 */
370 {MS_AIGO_VID
, MS_AIGO_DEVICE_6981
, 0,
371 SCSA2USB_ATTRS_USE_CSW_RESIDUE
},
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
},
377 /* Western Digital External HDD */
378 {MS_WD_VID
, MS_WD_PID
, 0,
379 SCSA2USB_ATTRS_INQUIRY_EVPD
}
383 #define N_SCSA2USB_BLACKLIST (sizeof (scsa2usb_blacklist))/ \
384 sizeof (struct blacklist)
387 * Attribute values can be overridden by values
388 * contained in the scsa2usb.conf file.
389 * These arrays define possible user input values.
392 struct scsa2usb_subclass_protocol_override
{
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
}
403 static struct scsa2usb_subclass_protocol_override scsa2usb_subclass
[] = {
404 {"SCSI", SCSA2USB_SCSI_CMDSET
},
405 {"ATAPI", SCSA2USB_ATAPI_CMDSET
},
406 {"UFI", SCSA2USB_UFI_CMDSET
}
410 #define N_SCSA2USB_SUBC_OVERRIDE (sizeof (scsa2usb_subclass))/ \
411 sizeof (struct scsa2usb_subclass_protocol_override)
413 #define N_SCSA2USB_PROT_OVERRIDE (sizeof (scsa2usb_protocol))/ \
414 sizeof (struct scsa2usb_subclass_protocol_override)
416 /* global variables */
417 static void *scsa2usb_statep
; /* for soft state */
418 static boolean_t scsa2usb_sync_message
= B_TRUE
; /* for syncing */
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
;
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.
433 uint_t scsa2usb_max_bulk_xfer_size
= SCSA2USB_MAX_BULK_XFER_SIZE
;
436 #ifdef SCSA2USB_BULK_ONLY_TEST
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.
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
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;
450 static void scsa2usb_test_mblk(scsa2usb_state_t
*, boolean_t
);
451 #endif /* SCSA2USB_BULK_ONLY_TEST */
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 *,
460 /* scsa2usb cb_ops */
461 static struct cb_ops scsa2usb_cbops
= {
462 scsa2usb_ugen_open
, /* open */
463 scsa2usb_ugen_close
, /* close */
464 nodev
, /* strategy */
467 scsa2usb_ugen_read
, /* read */
468 scsa2usb_ugen_write
, /* write */
473 scsa2usb_ugen_poll
, /* poll */
474 ddi_prop_op
, /* prop_op */
478 nodev
, /* int (*cb_aread)() */
479 nodev
/* int (*cb_awrite)() */
482 /* modloading support */
483 static struct dev_ops scsa2usb_ops
= {
484 DEVO_REV
, /* devo_rev, */
486 scsa2usb_info
, /* info */
487 nulldev
, /* identify */
489 scsa2usb_attach
, /* attach */
490 scsa2usb_detach
, /* detach */
492 &scsa2usb_cbops
, /* driver operations */
493 NULL
, /* bus operations */
494 scsa2usb_power
, /* power */
495 ddi_quiesce_not_needed
, /* quiesce */
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 */
504 static struct modlinkage modlinkage
= {
505 MODREV_1
, (void *)&modldrv
, NULL
509 static usb_event_t scsa2usb_events
= {
510 scsa2usb_disconnect_event_cb
,
511 scsa2usb_reconnect_event_cb
,
520 if (((rval
= ddi_soft_state_init(&scsa2usb_statep
,
521 sizeof (scsa2usb_state_t
), SCSA2USB_INITIAL_ALLOC
)) != 0)) {
526 if ((rval
= scsi_hba_init(&modlinkage
)) != 0) {
527 ddi_soft_state_fini(&scsa2usb_statep
);
532 if ((rval
= mod_install(&modlinkage
)) != 0) {
533 scsi_hba_fini(&modlinkage
);
534 ddi_soft_state_fini(&scsa2usb_statep
);
548 if ((rval
= mod_remove(&modlinkage
)) == 0) {
549 scsi_hba_fini(&modlinkage
);
550 ddi_soft_state_fini(&scsa2usb_statep
);
558 _info(struct modinfo
*modinfop
)
560 return (mod_info(&modlinkage
, modinfop
));
566 * Get minor number, soft state structure etc.
570 scsa2usb_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
,
571 void *arg
, void **result
)
573 scsa2usb_state_t
*scsa2usbp
= NULL
;
574 int error
= DDI_FAILURE
;
575 int instance
= SCSA2USB_MINOR_TO_INSTANCE(getminor((dev_t
)arg
));
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
;
588 case DDI_INFO_DEVT2INSTANCE
:
589 *result
= (void *)(uintptr_t)instance
;
603 * Allocate a "scsi_hba_tran" - call scsi_hba_tran_alloc()
604 * Invoke scsi_hba_attach_setup
605 * Get the serialno of the device
607 * Create disk child(ren)
609 * Create and register panic callback
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.
615 scsa2usb_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
617 int instance
= ddi_get_instance(dip
);
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
;
629 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, NULL
,
630 "scsa2usb_attach: dip = 0x%p", (void *)dip
);
636 scsa2usb_cpr_resume(dip
);
638 return (DDI_SUCCESS
);
640 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, NULL
,
641 "scsa2usb_attach: failed");
643 return (DDI_FAILURE
);
646 /* Allocate softc information */
647 if (ddi_soft_state_zalloc(scsa2usb_statep
, instance
) != DDI_SUCCESS
) {
648 ddi_prop_remove_all(dip
);
650 return (DDI_FAILURE
);
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
);
660 return (DDI_FAILURE
);
663 scsa2usbp
->scsa2usb_dip
= dip
;
664 scsa2usbp
->scsa2usb_instance
= instance
;
666 /* allocate a log handle for debug/error messages */
667 scsa2usbp
->scsa2usb_log_handle
= log_handle
=
668 usb_alloc_log_hdl(dip
, "s2u",
670 &scsa2usb_errmask
, &scsa2usb_instance_debug
,
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");
680 if (usb_get_dev_data(dip
, &dev_data
, USB_PARSE_LVL_IF
, 0) !=
682 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
683 "usb_get_dev_data failed");
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
);
693 for (lun
= 0; lun
< SCSA2USB_MAX_LUNS
; lun
++) {
694 usba_init_list(&scsa2usbp
->scsa2usb_waitQ
[lun
], NULL
,
695 dev_data
->dev_iblock_cookie
);
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
;
704 /* save the default pipe handle */
705 scsa2usbp
->scsa2usb_default_pipe
= dev_data
->dev_default_ph
;
707 /* basic inits are done */
708 scsa2usbp
->scsa2usb_flags
|= SCSA2USB_FLAGS_LOCKS_INIT
;
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
);
715 interface
= dev_data
->dev_curr_if
;
716 scsa2usbp
->scsa2usb_intfc_num
= dev_data
->dev_curr_if
;
718 /* now find out relevant descriptors for alternate 0 */
719 altif_data
= &dev_data
->dev_curr_cfg
->cfg_if
[interface
].if_alt
[0];
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
);
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
);
736 scsa2usbp
->scsa2usb_intfc_descr
= altif_data
->altif_descr
;
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 if (usb_ep_xdescr_fill(USB_EP_XDESCR_CURRENT_VERSION
,
742 dip
, ep_data
, &scsa2usbp
->scsa2usb_bulkout_xept
) !=
745 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
750 if ((ep_data
= usb_lookup_ep_data(dip
, dev_data
, interface
, 0, 0,
751 USB_EP_ATTR_BULK
, USB_EP_DIR_IN
)) != NULL
) {
752 if (usb_ep_xdescr_fill(USB_EP_XDESCR_CURRENT_VERSION
,
753 dip
, ep_data
, &scsa2usbp
->scsa2usb_bulkin_xept
) !=
756 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
761 if ((ep_data
= usb_lookup_ep_data(dip
, dev_data
, interface
, 0, 0,
762 USB_EP_ATTR_INTR
, USB_EP_DIR_IN
)) != NULL
) {
763 if (usb_ep_xdescr_fill(USB_EP_XDESCR_CURRENT_VERSION
,
764 dip
, ep_data
, &scsa2usbp
->scsa2usb_intr_xept
) !=
767 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
774 * check here for protocol and subclass supported by this driver
776 * first check if conf file has override values
777 * Note: override values are not used if supplied values are legal
779 scsa2usb_override(scsa2usbp
);
781 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, log_handle
,
782 "protocol=0x%x override=0x%x subclass=0x%x override=0x%x",
783 scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceProtocol
,
784 scsa2usbp
->scsa2usb_protocol_override
,
785 scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceSubClass
,
786 scsa2usbp
->scsa2usb_subclass_override
);
788 switch (scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceProtocol
) {
789 case USB_PROTO_MS_CBI
:
790 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_CB_PROTOCOL
;
792 case USB_PROTO_MS_CBI_WC
:
793 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_CBI_PROTOCOL
;
795 case USB_PROTO_MS_ISD_1999_SILICN
:
796 case USB_PROTO_MS_BULK_ONLY
:
797 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_BULK_ONLY_PROTOCOL
;
800 if (scsa2usbp
->scsa2usb_protocol_override
) {
801 scsa2usbp
->scsa2usb_cmd_protocol
|=
802 scsa2usbp
->scsa2usb_protocol_override
;
803 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
804 "overriding protocol %x",
805 scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceProtocol
);
809 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
810 "unsupported protocol = %x",
811 scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceProtocol
);
812 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
817 switch (scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceSubClass
) {
818 case USB_SUBCLS_MS_SCSI
: /* transparent SCSI */
819 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_SCSI_CMDSET
;
821 case USB_SUBCLS_MS_SFF8020I
:
822 case USB_SUBCLS_MS_SFF8070I
:
823 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_ATAPI_CMDSET
;
825 case USB_SUBCLS_MS_UFI
: /* UFI */
826 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_UFI_CMDSET
;
829 if (scsa2usbp
->scsa2usb_subclass_override
) {
830 scsa2usbp
->scsa2usb_cmd_protocol
|=
831 scsa2usbp
->scsa2usb_subclass_override
;
832 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
833 "overriding subclass %x",
834 scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceSubClass
);
838 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
839 "unsupported subclass = %x",
840 scsa2usbp
->scsa2usb_intfc_descr
.bInterfaceSubClass
);
841 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
846 /* check that we have the right set of endpoint descriptors */
847 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp
) || SCSA2USB_IS_CB(scsa2usbp
)) {
848 if ((scsa2usbp
->scsa2usb_bulkout_ept
.bLength
== 0) ||
849 (scsa2usbp
->scsa2usb_bulkin_ept
.bLength
== 0)) {
852 } else if (SCSA2USB_IS_CBI(scsa2usbp
)) {
853 if ((scsa2usbp
->scsa2usb_bulkout_ept
.bLength
== 0) ||
854 (scsa2usbp
->scsa2usb_bulkin_ept
.bLength
== 0) ||
855 (scsa2usbp
->scsa2usb_intr_ept
.bLength
== 0)) {
860 if (ept_check
== B_FALSE
) {
861 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
862 "scsa2usb%d doesn't support minimum required endpoints",
864 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
870 * Validate the black-listed attributes
872 scsa2usb_validate_attrs(scsa2usbp
);
874 /* Print the serial number from the registration data */
875 if (scsa2usbp
->scsa2usb_dev_data
->dev_serial
) {
876 USB_DPRINTF_L4(DPRINT_MASK_SCSA
,
877 scsa2usbp
->scsa2usb_log_handle
, "Serial Number = %s",
878 scsa2usbp
->scsa2usb_dev_data
->dev_serial
);
882 * Allocate a SCSA transport structure
884 tran
= scsi_hba_tran_alloc(dip
, SCSI_HBA_CANSLEEP
);
885 scsa2usbp
->scsa2usb_tran
= tran
;
888 * initialize transport structure
890 tran
->tran_hba_private
= scsa2usbp
;
891 tran
->tran_tgt_private
= NULL
;
892 tran
->tran_tgt_init
= scsa2usb_scsi_tgt_init
;
893 tran
->tran_tgt_probe
= scsa2usb_scsi_tgt_probe
;
894 tran
->tran_tgt_free
= scsa2usb_scsi_tgt_free
;
895 tran
->tran_start
= scsa2usb_scsi_start
;
896 tran
->tran_abort
= scsa2usb_scsi_abort
;
897 tran
->tran_reset
= scsa2usb_scsi_reset
;
898 tran
->tran_getcap
= scsa2usb_scsi_getcap
;
899 tran
->tran_setcap
= scsa2usb_scsi_setcap
;
900 tran
->tran_init_pkt
= scsa2usb_scsi_init_pkt
;
901 tran
->tran_destroy_pkt
= scsa2usb_scsi_destroy_pkt
;
902 tran
->tran_dmafree
= NULL
;
903 tran
->tran_sync_pkt
= NULL
;
904 tran
->tran_reset_notify
= NULL
;
905 tran
->tran_get_bus_addr
= NULL
;
906 tran
->tran_get_name
= NULL
;
907 tran
->tran_quiesce
= NULL
;
908 tran
->tran_unquiesce
= NULL
;
909 tran
->tran_bus_reset
= NULL
;
910 tran
->tran_add_eventcall
= NULL
;
911 tran
->tran_get_eventcookie
= NULL
;
912 tran
->tran_post_event
= NULL
;
913 tran
->tran_remove_eventcall
= NULL
;
914 tran
->tran_bus_config
= scsa2usb_scsi_bus_config
;
915 tran
->tran_bus_unconfig
= scsa2usb_scsi_bus_unconfig
;
918 * register with SCSA as an HBA
919 * Note that the dma attributes are from parent nexus
921 if (scsi_hba_attach_setup(dip
, usba_get_hc_dma_attr(dip
), tran
, 0)) {
922 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
923 "scsi_hba_attach_setup failed");
924 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
929 scsa2usbp
->scsa2usb_flags
|= SCSA2USB_FLAGS_HBA_ATTACH_SETUP
;
931 /* create minor node */
932 if (ddi_create_minor_node(dip
, "scsa2usb", S_IFCHR
,
933 instance
<< SCSA2USB_MINOR_INSTANCE_SHIFT
,
934 DDI_NT_SCSI_NEXUS
, 0) != DDI_SUCCESS
) {
935 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
936 "scsi_attach: ddi_create_minor_node failed");
937 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
942 /* open pipes and set scsa2usb_flags */
943 if (scsa2usb_open_usb_pipes(scsa2usbp
) == USB_FAILURE
) {
944 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
945 "error opening pipes");
946 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
951 /* set default block size. updated after read cap cmd */
952 for (lun
= 0; lun
< SCSA2USB_MAX_LUNS
; lun
++) {
953 scsa2usbp
->scsa2usb_lbasize
[lun
] = DEV_BSIZE
;
956 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
958 /* initialize PANIC callback */
959 scsa2usb_panic_callb_init(scsa2usbp
);
961 /* finally we are all done 'initializing' the device */
962 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
963 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_ONLINE
;
965 /* enable PM, mutex needs to be held across this */
966 scsa2usb_create_pm_components(dip
, scsa2usbp
);
967 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
969 /* register for connect/disconnect events */
970 if (usb_register_event_cbs(scsa2usbp
->scsa2usb_dip
, &scsa2usb_events
,
972 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, log_handle
,
973 "error cb registering");
977 /* free the dev_data tree, we no longer need it */
978 usb_free_descr_tree(dip
, dev_data
);
980 scsa2usb_pm_idle_component(scsa2usbp
);
982 /* log the conf file override string if there is one */
983 if (scsa2usbp
->scsa2usb_override_str
) {
984 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
985 "scsa2usb.conf override: %s",
986 scsa2usbp
->scsa2usb_override_str
);
989 if (usb_owns_device(dip
)) {
990 /* get a ugen handle */
991 bzero(&usb_ugen_info
, sizeof (usb_ugen_info
));
992 usb_ugen_info
.usb_ugen_flags
= 0;
993 usb_ugen_info
.usb_ugen_minor_node_ugen_bits_mask
=
994 (dev_t
)SCSA2USB_MINOR_UGEN_BITS_MASK
;
995 usb_ugen_info
.usb_ugen_minor_node_instance_mask
=
996 (dev_t
)~SCSA2USB_MINOR_UGEN_BITS_MASK
;
997 scsa2usbp
->scsa2usb_ugen_hdl
=
998 usb_ugen_get_hdl(dip
, &usb_ugen_info
);
1000 if (usb_ugen_attach(scsa2usbp
->scsa2usb_ugen_hdl
, cmd
) !=
1002 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1003 scsa2usbp
->scsa2usb_log_handle
,
1004 "usb_ugen_attach failed");
1006 usb_ugen_release_hdl(scsa2usbp
->scsa2usb_ugen_hdl
);
1007 scsa2usbp
->scsa2usb_ugen_hdl
= NULL
;
1012 ddi_report_dev(dip
);
1014 return (DDI_SUCCESS
);
1018 (void) scsa2usb_cleanup(dip
, scsa2usbp
);
1021 return (DDI_FAILURE
);
1027 * detach or suspend driver instance
1030 scsa2usb_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
1032 scsi_hba_tran_t
*tran
;
1033 scsa2usb_state_t
*scsa2usbp
;
1036 tran
= ddi_get_driver_private(dip
);
1037 ASSERT(tran
!= NULL
);
1039 scsa2usbp
= (scsa2usb_state_t
*)tran
->tran_hba_private
;
1042 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1043 "scsa2usb_detach: dip = 0x%p, cmd = %d", (void *)dip
, cmd
);
1048 if (scsa2usb_cleanup(dip
, scsa2usbp
) != USB_SUCCESS
) {
1050 return (DDI_FAILURE
);
1053 return (DDI_SUCCESS
);
1055 rval
= scsa2usb_cpr_suspend(dip
);
1057 return ((rval
== USB_SUCCESS
) ? DDI_SUCCESS
: DDI_FAILURE
);
1060 return (DDI_FAILURE
);
1068 * scsa2usb_ugen_open()
1069 * (all ugen opens and pipe opens are by definition exclusive so it is OK
1073 scsa2usb_ugen_open(dev_t
*devp
, int flag
, int sflag
, cred_t
*cr
)
1075 scsa2usb_state_t
*scsa2usbp
;
1078 if ((scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
,
1079 SCSA2USB_MINOR_TO_INSTANCE(getminor(*devp
)))) == NULL
) {
1080 /* deferred detach */
1085 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1086 "scsa2usb_ugen_open: dev_t=0x%lx", *devp
);
1088 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1090 /* if this is the first ugen open, check on transport busy */
1091 if (scsa2usbp
->scsa2usb_busy_proc
!= curproc
) {
1092 while (scsa2usbp
->scsa2usb_transport_busy
||
1093 (scsa2usb_all_waitQs_empty(scsa2usbp
) !=
1096 &scsa2usbp
->scsa2usb_transport_busy_cv
,
1097 &scsa2usbp
->scsa2usb_mutex
);
1099 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1104 scsa2usbp
->scsa2usb_transport_busy
++;
1105 scsa2usbp
->scsa2usb_busy_proc
= curproc
;
1108 scsa2usbp
->scsa2usb_ugen_open_count
++;
1110 scsa2usb_raise_power(scsa2usbp
);
1112 scsa2usb_close_usb_pipes(scsa2usbp
);
1114 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1116 rval
= usb_ugen_open(scsa2usbp
->scsa2usb_ugen_hdl
, devp
, flag
,
1120 * if usb_ugen_open() succeeded, we'll change the minor number
1121 * so that we can keep track of every open()/close() issued by
1122 * the userland processes. We need to pick a minor number that
1123 * is not used by the ugen framework
1126 usb_ugen_hdl_impl_t
*usb_ugen_hdl_impl
;
1127 ugen_state_t
*ugenp
;
1128 int ugen_minor
, clone
;
1130 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1133 (usb_ugen_hdl_impl_t
*)scsa2usbp
->scsa2usb_ugen_hdl
;
1134 ugenp
= usb_ugen_hdl_impl
->hdl_ugenp
;
1136 /* 'clone' is bigger than any ugen minor in use */
1137 for (clone
= ugenp
->ug_minor_node_table_index
+ 1;
1138 clone
< SCSA2USB_MAX_CLONE
; clone
++) {
1139 if (!scsa2usbp
->scsa2usb_clones
[clone
])
1143 if (clone
>= SCSA2USB_MAX_CLONE
) {
1144 cmn_err(CE_WARN
, "scsa2usb_ugen_open: too many clones");
1146 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1150 ugen_minor
= getminor(*devp
) & SCSA2USB_MINOR_UGEN_BITS_MASK
;
1151 *devp
= makedevice(getmajor(*devp
),
1152 (scsa2usbp
->scsa2usb_instance
1153 << SCSA2USB_MINOR_INSTANCE_SHIFT
)
1156 /* save the ugen minor */
1157 scsa2usbp
->scsa2usb_clones
[clone
] = (uint8_t)ugen_minor
;
1158 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1159 "scsa2usb_ugen_open: new dev=%lx, old minor=%x",
1162 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1168 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1170 /* reopen the pipes */
1171 if (--scsa2usbp
->scsa2usb_ugen_open_count
== 0) {
1172 scsa2usbp
->scsa2usb_transport_busy
--;
1173 scsa2usbp
->scsa2usb_busy_proc
= NULL
;
1174 cv_signal(&scsa2usbp
->scsa2usb_transport_busy_cv
);
1176 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1178 scsa2usb_pm_idle_component(scsa2usbp
);
1186 * scsa2usb_ugen_close()
1189 scsa2usb_ugen_close(dev_t dev
, int flag
, int otype
, cred_t
*cr
)
1192 int ugen_minor
, clone
;
1194 scsa2usb_state_t
*scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
,
1195 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev
)));
1197 if (scsa2usbp
== NULL
) {
1202 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1203 "scsa2usb_ugen_close: dev_t=0x%lx", dev
);
1205 clone
= getminor(dev
) & SCSA2USB_MINOR_UGEN_BITS_MASK
;
1206 ugen_minor
= scsa2usbp
->scsa2usb_clones
[clone
];
1207 dev
= makedevice(getmajor(dev
),
1208 (scsa2usbp
->scsa2usb_instance
<< SCSA2USB_MINOR_INSTANCE_SHIFT
)
1210 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1211 "scsa2usb_ugen_close: old dev=%lx", dev
);
1212 rval
= usb_ugen_close(scsa2usbp
->scsa2usb_ugen_hdl
, dev
, flag
,
1216 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1218 scsa2usbp
->scsa2usb_clones
[clone
] = 0;
1219 /* reopen the pipes */
1220 if (--scsa2usbp
->scsa2usb_ugen_open_count
== 0) {
1221 scsa2usbp
->scsa2usb_transport_busy
--;
1222 scsa2usbp
->scsa2usb_busy_proc
= NULL
;
1223 cv_signal(&scsa2usbp
->scsa2usb_transport_busy_cv
);
1225 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1227 scsa2usb_pm_idle_component(scsa2usbp
);
1235 * scsa2usb_ugen_read/write()
1239 scsa2usb_ugen_read(dev_t dev
, struct uio
*uiop
, cred_t
*credp
)
1241 int clone
, ugen_minor
;
1242 scsa2usb_state_t
*scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
,
1243 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev
)));
1245 if (scsa2usbp
== NULL
) {
1250 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1251 "scsa2usb_ugen_read: dev_t=0x%lx", dev
);
1253 clone
= getminor(dev
) & SCSA2USB_MINOR_UGEN_BITS_MASK
;
1254 ugen_minor
= scsa2usbp
->scsa2usb_clones
[clone
];
1255 dev
= makedevice(getmajor(dev
),
1256 (scsa2usbp
->scsa2usb_instance
<< SCSA2USB_MINOR_INSTANCE_SHIFT
)
1259 return (usb_ugen_read(scsa2usbp
->scsa2usb_ugen_hdl
, dev
,
1266 scsa2usb_ugen_write(dev_t dev
, struct uio
*uiop
, cred_t
*credp
)
1268 int clone
, ugen_minor
;
1269 scsa2usb_state_t
*scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
,
1270 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev
)));
1272 if (scsa2usbp
== NULL
) {
1277 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1278 "scsa2usb_ugen_write: dev_t=0x%lx", dev
);
1280 clone
= getminor(dev
) & SCSA2USB_MINOR_UGEN_BITS_MASK
;
1281 ugen_minor
= scsa2usbp
->scsa2usb_clones
[clone
];
1282 dev
= makedevice(getmajor(dev
),
1283 (scsa2usbp
->scsa2usb_instance
<< SCSA2USB_MINOR_INSTANCE_SHIFT
)
1286 return (usb_ugen_write(scsa2usbp
->scsa2usb_ugen_hdl
,
1292 * scsa2usb_ugen_poll
1295 scsa2usb_ugen_poll(dev_t dev
, short events
,
1296 int anyyet
, short *reventsp
, struct pollhead
**phpp
)
1298 int clone
, ugen_minor
;
1299 scsa2usb_state_t
*scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
,
1300 SCSA2USB_MINOR_TO_INSTANCE(getminor(dev
)));
1302 if (scsa2usbp
== NULL
) {
1307 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1308 "scsa2usb_ugen_poll: dev_t=0x%lx", dev
);
1310 clone
= getminor(dev
) & SCSA2USB_MINOR_UGEN_BITS_MASK
;
1311 ugen_minor
= scsa2usbp
->scsa2usb_clones
[clone
];
1312 dev
= makedevice(getmajor(dev
),
1313 (scsa2usbp
->scsa2usb_instance
<< SCSA2USB_MINOR_INSTANCE_SHIFT
)
1316 return (usb_ugen_poll(scsa2usbp
->scsa2usb_ugen_hdl
, dev
, events
,
1317 anyyet
, reventsp
, phpp
));
1323 * cleanup whatever attach has setup
1326 scsa2usb_cleanup(dev_info_t
*dip
, scsa2usb_state_t
*scsa2usbp
)
1329 scsa2usb_power_t
*pm
;
1332 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1333 "scsa2usb_cleanup:");
1335 /* wait till the work thread is done */
1336 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1337 for (i
= 0; i
< SCSA2USB_DRAIN_TIMEOUT
; i
++) {
1338 if (scsa2usbp
->scsa2usb_work_thread_id
== NULL
) {
1342 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1344 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1346 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1348 if (i
>= SCSA2USB_DRAIN_TIMEOUT
) {
1350 return (USB_FAILURE
);
1354 * Disable the event callbacks first, after this point, event
1355 * callbacks will never get called. Note we shouldn't hold
1356 * mutex while unregistering events because there may be a
1357 * competing event callback thread. Event callbacks are done
1358 * with ndi mutex held and this can cause a potential deadlock.
1360 usb_unregister_event_cbs(scsa2usbp
->scsa2usb_dip
, &scsa2usb_events
);
1362 if (scsa2usbp
->scsa2usb_flags
& SCSA2USB_FLAGS_LOCKS_INIT
) {
1364 * if a waitQ exists, get rid of it before destroying it
1366 for (lun
= 0; lun
< SCSA2USB_MAX_LUNS
; lun
++) {
1367 scsa2usb_flush_waitQ(scsa2usbp
, lun
, CMD_TRAN_ERR
);
1368 usba_destroy_list(&scsa2usbp
->scsa2usb_waitQ
[lun
]);
1371 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1372 if (scsa2usbp
->scsa2usb_flags
&
1373 SCSA2USB_FLAGS_HBA_ATTACH_SETUP
) {
1374 (void) scsi_hba_detach(dip
);
1375 scsi_hba_tran_free(scsa2usbp
->scsa2usb_tran
);
1378 if (scsa2usbp
->scsa2usb_flags
&
1379 SCSA2USB_FLAGS_PIPES_OPENED
) {
1380 scsa2usb_close_usb_pipes(scsa2usbp
);
1383 /* Lower the power */
1384 pm
= scsa2usbp
->scsa2usb_pm
;
1386 if (pm
&& (scsa2usbp
->scsa2usb_dev_state
!=
1387 USB_DEV_DISCONNECTED
)) {
1388 if (pm
->scsa2usb_wakeup_enabled
) {
1389 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1390 (void) pm_raise_power(dip
, 0,
1391 USB_DEV_OS_FULL_PWR
);
1393 if ((rval
= usb_handle_remote_wakeup(dip
,
1394 USB_REMOTE_WAKEUP_DISABLE
)) !=
1396 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1397 scsa2usbp
->scsa2usb_log_handle
,
1398 "disable remote wakeup failed "
1402 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1405 (void) pm_lower_power(dip
, 0, USB_DEV_OS_PWR_OFF
);
1407 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1411 kmem_free(pm
, sizeof (scsa2usb_power_t
));
1414 if (scsa2usbp
->scsa2usb_override_str
) {
1415 kmem_free(scsa2usbp
->scsa2usb_override_str
,
1416 strlen(scsa2usbp
->scsa2usb_override_str
) + 1);
1417 scsa2usbp
->scsa2usb_override_str
= NULL
;
1420 /* remove the minor nodes */
1421 ddi_remove_minor_node(dip
, NULL
);
1423 /* Cancel the registered panic callback */
1424 scsa2usb_panic_callb_fini(scsa2usbp
);
1426 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1428 mutex_destroy(&scsa2usbp
->scsa2usb_mutex
);
1429 cv_destroy(&scsa2usbp
->scsa2usb_transport_busy_cv
);
1432 usb_client_detach(scsa2usbp
->scsa2usb_dip
,
1433 scsa2usbp
->scsa2usb_dev_data
);
1435 if (scsa2usbp
->scsa2usb_ugen_hdl
) {
1436 (void) usb_ugen_detach(scsa2usbp
->scsa2usb_ugen_hdl
,
1438 usb_ugen_release_hdl(scsa2usbp
->scsa2usb_ugen_hdl
);
1441 usb_free_log_hdl(scsa2usbp
->scsa2usb_log_handle
);
1443 ddi_prop_remove_all(dip
);
1445 ddi_soft_state_free(scsa2usb_statep
, ddi_get_instance(dip
));
1447 return (USB_SUCCESS
);
1452 * scsa2usb_override:
1453 * some devices may be attached even though their subclass or
1454 * protocol info is not according to spec.
1455 * these can be determined by the 'subclass-protocol-override'
1456 * property set in the conf file.
1459 scsa2usb_override(scsa2usb_state_t
*scsa2usbp
)
1462 char **override_str
= NULL
;
1463 char *override_str_cpy
;
1464 uint_t override_str_len
, override_str_cpy_len
;
1466 usb_dev_descr_t
*descr
= scsa2usbp
->scsa2usb_dev_data
->dev_descr
;
1468 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
1470 scsa2usbp
->scsa2usb_subclass_override
=
1471 scsa2usbp
->scsa2usb_protocol_override
= 0;
1473 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY
, scsa2usbp
->scsa2usb_dip
,
1474 DDI_PROP_DONTPASS
, "attribute-override-list",
1475 &override_str
, &override_str_len
) != DDI_PROP_SUCCESS
) {
1480 /* parse each string in the subclass-protocol-override property */
1481 for (i
= 0; i
< override_str_len
; i
++) {
1483 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1484 "override_str[%d] = %s", i
, override_str
[i
]);
1487 * save a copy of the override string for possible
1488 * inclusion in soft state later
1490 override_str_cpy_len
= strlen(override_str
[i
]) + 1;
1491 override_str_cpy
= kmem_zalloc(override_str_cpy_len
, KM_SLEEP
);
1492 (void) strcpy(override_str_cpy
, override_str
[i
]);
1494 bzero(&ov
, sizeof (scsa2usb_ov_t
));
1496 if (scsa2usb_parse_input_str(override_str
[i
], &ov
,
1497 scsa2usbp
) == USB_FAILURE
) {
1498 kmem_free(override_str_cpy
, override_str_cpy_len
);
1503 * see if subclass/protocol needs to be overridden for device
1504 * or if device should not be power managed
1505 * if there'a a match, save the override string in soft state
1507 if (((descr
->idVendor
== (uint16_t)ov
.vid
) || (ov
.vid
== 0)) &&
1508 ((descr
->idProduct
== (uint16_t)ov
.pid
) || (ov
.pid
== 0)) &&
1509 ((descr
->bcdDevice
== (uint16_t)ov
.rev
) || (ov
.rev
== 0))) {
1510 scsa2usbp
->scsa2usb_subclass_override
= ov
.subclass
;
1511 scsa2usbp
->scsa2usb_protocol_override
= ov
.protocol
;
1513 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1514 scsa2usbp
->scsa2usb_log_handle
,
1515 "vid=0x%x pid=0x%x rev=0x%x subclass=0x%x "
1517 "pmoff=%d fake_removable=%d modesense=%d "
1518 "reduced-cmd-support=%d",
1519 ov
.vid
, ov
.pid
, ov
.rev
, ov
.subclass
, ov
.protocol
,
1520 ov
.pmoff
, ov
.fake_removable
, ov
.no_modesense
,
1521 ov
.reduced_cmd_support
);
1524 scsa2usbp
->scsa2usb_attrs
&= ~SCSA2USB_ATTRS_PM
;
1526 if (ov
.fake_removable
) {
1527 scsa2usbp
->scsa2usb_attrs
&=
1528 ~SCSA2USB_ATTRS_RMB
;
1530 if (ov
.no_modesense
) {
1531 scsa2usbp
->scsa2usb_attrs
&=
1532 ~SCSA2USB_ATTRS_MODE_SENSE
;
1534 if (ov
.reduced_cmd_support
) {
1535 scsa2usbp
->scsa2usb_attrs
&=
1536 ~SCSA2USB_ATTRS_REDUCED_CMD
;
1538 scsa2usbp
->scsa2usb_override_str
= override_str_cpy
;
1541 kmem_free(override_str_cpy
, override_str_cpy_len
);
1545 ddi_prop_free(override_str
);
1550 * scsa2usb_parse_input_str:
1551 * parse one conf file subclass-protocol-override string
1552 * return vendor id, product id, revision, subclass, protocol
1553 * function return is success or failure
1556 scsa2usb_parse_input_str(char *str
, scsa2usb_ov_t
*ovp
,
1557 scsa2usb_state_t
*scsa2usbp
)
1559 char *input_field
, *input_value
;
1564 /* parse all the input pairs in the string */
1565 for (input_field
= scsa2usb_strtok_r(str
, "=", &lasts
);
1566 input_field
!= NULL
;
1567 input_field
= scsa2usb_strtok_r(lasts
, "=", &lasts
)) {
1569 if ((input_value
= scsa2usb_strtok_r(lasts
, " ", &lasts
)) ==
1571 scsa2usb_override_error("format", scsa2usbp
);
1573 return (USB_FAILURE
);
1575 /* if input value is a 'don't care', skip to the next pair */
1576 if (strcmp(input_value
, "*") == 0) {
1579 if (strcasecmp(input_field
, "vid") == 0) {
1580 if (kobj_getvalue(input_value
, &value
) == -1) {
1581 scsa2usb_override_error("vendor id", scsa2usbp
);
1583 return (USB_FAILURE
);
1585 ovp
->vid
= (int)value
;
1586 } else if (strcasecmp(input_field
, "pid") == 0) {
1587 if (kobj_getvalue(input_value
, &value
) == -1) {
1588 scsa2usb_override_error("product id",
1591 return (USB_FAILURE
);
1593 ovp
->pid
= (int)value
;
1594 } else if (strcasecmp(input_field
, "rev") == 0) {
1595 if (kobj_getvalue(input_value
, &value
) == -1) {
1596 scsa2usb_override_error("revision id",
1599 return (USB_FAILURE
);
1601 ovp
->rev
= (int)value
;
1602 } else if (strcasecmp(input_field
, "subclass") == 0) {
1603 for (i
= 0; i
< N_SCSA2USB_SUBC_OVERRIDE
; i
++) {
1604 if (strcasecmp(input_value
,
1605 scsa2usb_subclass
[i
].name
) == 0) {
1607 scsa2usb_subclass
[i
].value
;
1611 if (ovp
->subclass
== 0) {
1612 scsa2usb_override_error("subclass", scsa2usbp
);
1614 return (USB_FAILURE
);
1616 } else if (strcasecmp(input_field
, "protocol") == 0) {
1617 for (i
= 0; i
< N_SCSA2USB_PROT_OVERRIDE
; i
++) {
1618 if (strcasecmp(input_value
,
1619 scsa2usb_protocol
[i
].name
) == 0) {
1621 scsa2usb_protocol
[i
].value
;
1625 if (ovp
->protocol
== 0) {
1626 scsa2usb_override_error("protocol", scsa2usbp
);
1628 return (USB_FAILURE
);
1630 } else if (strcasecmp(input_field
, "pm") == 0) {
1631 if (strcasecmp(input_value
, "off") == 0) {
1635 scsa2usb_override_error("pm", scsa2usbp
);
1637 return (USB_FAILURE
);
1639 } else if (strcasecmp(input_field
, "removable") == 0) {
1640 if (strcasecmp(input_value
, "true") == 0) {
1641 ovp
->fake_removable
= 1;
1644 scsa2usb_override_error("removable", scsa2usbp
);
1646 return (USB_FAILURE
);
1648 } else if (strcasecmp(input_field
, "modesense") == 0) {
1649 if (strcasecmp(input_value
, "false") == 0) {
1650 ovp
->no_modesense
= 1;
1653 scsa2usb_override_error("modesense",
1656 return (USB_FAILURE
);
1658 } else if (strcasecmp(input_field
,
1659 "reduced-cmd-support") == 0) {
1660 if (strcasecmp(input_value
, "true") == 0) {
1661 ovp
->reduced_cmd_support
= 1;
1664 scsa2usb_override_error(
1665 "reduced-cmd-support", scsa2usbp
);
1667 return (USB_FAILURE
);
1670 scsa2usb_override_error(input_field
, scsa2usbp
);
1672 return (USB_FAILURE
);
1676 return (USB_SUCCESS
);
1681 * scsa2usb_override_error:
1682 * print an error message if conf file string is bad format
1685 scsa2usb_override_error(char *input_field
, scsa2usb_state_t
*scsa2usbp
)
1687 USB_DPRINTF_L1(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1688 "invalid %s in scsa2usb.conf file entry", input_field
);
1692 * scsa2usb_strtok_r:
1693 * parse a list of tokens
1696 scsa2usb_strtok_r(char *p
, char *sep
, char **lasts
)
1701 if (p
== 0 || *p
== 0) {
1709 if (strchr(sep
, *p
) != NULL
) {
1716 } else if (tok
== NULL
) {
1728 * scsa2usb_validate_attrs:
1729 * many devices have BO/CB/CBI protocol support issues.
1730 * use vendor/product info to reset the
1731 * individual erroneous attributes
1733 * NOTE: we look at only device at a time (at attach time)
1736 scsa2usb_validate_attrs(scsa2usb_state_t
*scsa2usbp
)
1739 usb_dev_descr_t
*desc
= scsa2usbp
->scsa2usb_dev_data
->dev_descr
;
1741 if (!SCSA2USB_IS_BULK_ONLY(scsa2usbp
)) {
1742 scsa2usbp
->scsa2usb_attrs
&= ~SCSA2USB_ATTRS_GET_LUN
;
1745 /* determine if this device is on the blacklist */
1746 for (i
= 0; i
< N_SCSA2USB_BLACKLIST
; i
++) {
1747 if ((scsa2usb_blacklist
[i
].idVendor
== desc
->idVendor
) &&
1748 ((scsa2usb_blacklist
[i
].idProduct
== desc
->idProduct
) ||
1749 (scsa2usb_blacklist
[i
].idProduct
== X
))) {
1750 scsa2usbp
->scsa2usb_attrs
&=
1751 ~(scsa2usb_blacklist
[i
].attributes
);
1757 * Mitsumi's CD-RW drives subclass isn't UFI.
1758 * But they support UFI command-set (this code ensures that)
1759 * NOTE: This is a special case, and is being called out so.
1761 if (desc
->idVendor
== MS_MITSUMI_VID
) {
1762 mask
= scsa2usbp
->scsa2usb_cmd_protocol
& SCSA2USB_CMDSET_MASK
;
1764 scsa2usbp
->scsa2usb_cmd_protocol
&= ~mask
;
1766 scsa2usbp
->scsa2usb_cmd_protocol
|= SCSA2USB_UFI_CMDSET
;
1769 if (scsa2usbp
->scsa2usb_attrs
!= SCSA2USB_ALL_ATTRS
) {
1770 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1771 scsa2usbp
->scsa2usb_log_handle
,
1772 "scsa2usb attributes modified: 0x%x",
1773 scsa2usbp
->scsa2usb_attrs
);
1779 * scsa2usb_create_luns:
1780 * check the number of luns but continue if the check fails,
1781 * create child nodes for each lun
1784 scsa2usb_create_luns(scsa2usb_state_t
*scsa2usbp
)
1787 char *compatible
[MAX_COMPAT_NAMES
]; /* compatible names */
1791 char *driver_name
= NULL
;
1793 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1794 "scsa2usb_create_luns:");
1796 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1798 /* Set n_luns to 1 by default (for floppies and other devices) */
1799 scsa2usbp
->scsa2usb_n_luns
= 1;
1802 * Check if there are any device out there which don't
1803 * support the GET_MAX_LUN command. If so, don't issue
1804 * control request to them.
1806 if ((scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_GET_LUN
) == 0) {
1807 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1808 "get_max_lun cmd not supported");
1810 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp
)) {
1811 scsa2usbp
->scsa2usb_n_luns
=
1812 scsa2usb_bulk_only_get_max_lun(scsa2usbp
);
1816 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1817 "scsa2usb_create_luns: %d luns found", scsa2usbp
->scsa2usb_n_luns
);
1820 * create disk child for each lun
1822 for (lun
= 0; lun
< scsa2usbp
->scsa2usb_n_luns
; lun
++) {
1823 ASSERT(scsa2usbp
->scsa2usb_lun_dip
[lun
] == NULL
);
1825 /* do an inquiry to get the dtype of this lun */
1826 scsa2usb_do_inquiry(scsa2usbp
, 0, lun
);
1828 dtype
= scsa2usbp
->scsa2usb_lun_inquiry
[lun
].
1829 inq_dtype
& DTYPE_MASK
;
1831 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
1832 "dtype[%d]=0x%x", lun
, dtype
);
1838 case DTYPE_RODIRECT
:
1844 case DTYPE_SEQUENTIAL
:
1850 node_name
= "printer";
1853 case DTYPE_PROCESSOR
:
1854 node_name
= "processor";
1862 node_name
= "scanner";
1866 node_name
= "changer";
1873 case DTYPE_ARRAY_CTRL
:
1874 node_name
= "array_ctrl";
1879 driver_name
= "ses";
1883 node_name
= "generic";
1889 compatible
[0] = driver_name
;
1892 ndi_devi_alloc_sleep(scsa2usbp
->scsa2usb_dip
, node_name
,
1893 (pnode_t
)DEVI_SID_NODEID
, &cdip
);
1895 /* attach target & lun properties */
1896 rval
= ndi_prop_update_int(DDI_DEV_T_NONE
, cdip
, "target", 0);
1897 if (rval
!= DDI_PROP_SUCCESS
) {
1898 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1899 scsa2usbp
->scsa2usb_log_handle
,
1900 "ndi_prop_update_int target failed %d", rval
);
1901 (void) ndi_devi_free(cdip
);
1905 rval
= ndi_prop_create_boolean(DDI_DEV_T_NONE
, cdip
,
1907 if (rval
!= DDI_PROP_SUCCESS
) {
1908 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1909 scsa2usbp
->scsa2usb_log_handle
,
1910 "ndi_prop_create_boolean hotpluggable failed %d",
1912 ddi_prop_remove_all(cdip
);
1913 (void) ndi_devi_free(cdip
);
1917 * Some devices don't support LOG SENSE, so tells
1918 * sd driver not to send this command.
1920 rval
= ndi_prop_update_int(DDI_DEV_T_NONE
, cdip
,
1922 if (rval
!= DDI_PROP_SUCCESS
) {
1923 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1924 scsa2usbp
->scsa2usb_log_handle
,
1925 "ndi_prop_update_int pm-capable failed %d", rval
);
1926 ddi_prop_remove_all(cdip
);
1927 (void) ndi_devi_free(cdip
);
1931 rval
= ndi_prop_update_int(DDI_DEV_T_NONE
, cdip
, "lun", lun
);
1932 if (rval
!= DDI_PROP_SUCCESS
) {
1933 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1934 scsa2usbp
->scsa2usb_log_handle
,
1935 "ndi_prop_update_int lun failed %d", rval
);
1936 ddi_prop_remove_all(cdip
);
1937 (void) ndi_devi_free(cdip
);
1942 rval
= ndi_prop_update_string_array(DDI_DEV_T_NONE
,
1943 cdip
, "compatible", (char **)compatible
,
1945 if (rval
!= DDI_PROP_SUCCESS
) {
1946 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1947 scsa2usbp
->scsa2usb_log_handle
,
1948 "ndi_prop_update_string_array failed %d",
1950 ddi_prop_remove_all(cdip
);
1951 (void) ndi_devi_free(cdip
);
1957 * add property "usb" so we always verify that it is our child
1959 rval
= ndi_prop_create_boolean(DDI_DEV_T_NONE
, cdip
, "usb");
1960 if (rval
!= DDI_PROP_SUCCESS
) {
1961 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
1962 scsa2usbp
->scsa2usb_log_handle
,
1963 "ndi_prop_create_boolean failed %d", rval
);
1964 ddi_prop_remove_all(cdip
);
1965 (void) ndi_devi_free(cdip
);
1969 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1970 (void) ddi_initchild(scsa2usbp
->scsa2usb_dip
, cdip
);
1971 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
1973 usba_set_usba_device(cdip
,
1974 usba_get_usba_device(scsa2usbp
->scsa2usb_dip
));
1976 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
1982 * scsa2usb gets called for all possible sd children.
1983 * we can only accept usb children
1986 scsa2usb_is_usb(dev_info_t
*dip
)
1989 return (ddi_prop_exists(DDI_DEV_T_ANY
, dip
,
1990 DDI_PROP_DONTPASS
, "usb"));
1998 * scsa2usb_panic_callb_init:
1999 * initialize PANIC callb and free allocated resources
2002 scsa2usb_panic_callb_init(scsa2usb_state_t
*scsa2usbp
)
2005 * In case the system panics, the sync command flushes
2006 * dirty FS pages or buffers. This would cause a hang
2008 * The reason for the failure is that we enter
2009 * polled mode (interrupts disabled) and HCD gets stuck
2010 * trying to execute bulk requests
2011 * The panic_callback registered below provides a warning
2012 * that a panic has occurred and from that point onwards, we
2013 * complete each request successfully and immediately. This
2014 * will fake successful syncing so at least the rest of the
2015 * filesystems complete syncing.
2017 scsa2usbp
->scsa2usb_panic_info
=
2018 kmem_zalloc(sizeof (scsa2usb_cpr_t
), KM_SLEEP
);
2019 mutex_init(&scsa2usbp
->scsa2usb_panic_info
->lockp
,
2021 scsa2usbp
->scsa2usb_dev_data
->dev_iblock_cookie
);
2022 scsa2usbp
->scsa2usb_panic_info
->statep
= scsa2usbp
;
2023 scsa2usbp
->scsa2usb_panic_info
->cpr
.cc_lockp
=
2024 &scsa2usbp
->scsa2usb_panic_info
->lockp
;
2025 scsa2usbp
->scsa2usb_panic_info
->cpr
.cc_id
=
2026 callb_add(scsa2usb_panic_callb
,
2027 (void *)scsa2usbp
->scsa2usb_panic_info
,
2028 CB_CL_PANIC
, "scsa2usb");
2033 * scsa2usb_panic_callb_fini:
2034 * cancel out PANIC callb and free allocated resources
2037 scsa2usb_panic_callb_fini(scsa2usb_state_t
*scsa2usbp
)
2039 if (scsa2usbp
->scsa2usb_panic_info
) {
2040 SCSA2USB_CANCEL_CB(scsa2usbp
->scsa2usb_panic_info
->cpr
.cc_id
);
2041 mutex_destroy(&scsa2usbp
->scsa2usb_panic_info
->lockp
);
2042 scsa2usbp
->scsa2usb_panic_info
->statep
= NULL
;
2043 kmem_free(scsa2usbp
->scsa2usb_panic_info
,
2044 sizeof (scsa2usb_cpr_t
));
2045 scsa2usbp
->scsa2usb_panic_info
= NULL
;
2051 * scsa2usb_panic_callb:
2052 * This routine is called when there is a system panic.
2056 scsa2usb_panic_callb(void *arg
, int code
)
2058 scsa2usb_cpr_t
*cpr_infop
;
2059 scsa2usb_state_t
*scsa2usbp
;
2062 _NOTE(NO_COMPETING_THREADS_NOW
);
2063 cpr_infop
= (scsa2usb_cpr_t
*)arg
;
2064 scsa2usbp
= (scsa2usb_state_t
*)cpr_infop
->statep
;
2066 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2067 "scsa2usb_panic_callb: code=%d", code
);
2070 * If we return error here, "sd" prints lots of error
2071 * messages and could retry the same pkt over and over again.
2072 * The sync recovery isn't "smooth" in that case. By faking
2073 * a success return, instead, we force sync to complete.
2075 if (scsa2usbp
->scsa2usb_cur_pkt
) {
2077 * Do not print the "no sync" warning here. it will then be
2078 * displayed before we actually start syncing. Also we don't
2079 * replace this code with a call to scsa2usb_pkt_completion().
2080 * NOTE: mutexes are disabled during panic.
2082 scsa2usbp
->scsa2usb_cur_pkt
->pkt_reason
= CMD_CMPLT
;
2083 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2084 scsa2usb_pkt_completion(scsa2usbp
, scsa2usbp
->scsa2usb_cur_pkt
);
2085 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2088 /* get rid of waitQ */
2089 for (lun
= 0; lun
< SCSA2USB_MAX_LUNS
; lun
++) {
2090 scsa2usb_flush_waitQ(scsa2usbp
, lun
, CMD_CMPLT
);
2093 _NOTE(COMPETING_THREADS_NOW
);
2099 * scsa2usb_cpr_suspend
2100 * determine if the device's state can be changed to SUSPENDED
2101 * close pipes if there is no activity
2105 scsa2usb_cpr_suspend(dev_info_t
*dip
)
2107 scsa2usb_state_t
*scsa2usbp
;
2109 int rval
= USB_FAILURE
;
2111 scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
2113 ASSERT(scsa2usbp
!= NULL
);
2115 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2116 "scsa2usb_cpr_suspend:");
2118 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2119 switch (scsa2usbp
->scsa2usb_dev_state
) {
2120 case USB_DEV_ONLINE
:
2121 case USB_DEV_PWRED_DOWN
:
2122 case USB_DEV_DISCONNECTED
:
2123 prev_state
= scsa2usbp
->scsa2usb_dev_state
;
2124 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_SUSPENDED
;
2127 * If the device is busy, we cannot suspend
2129 if (SCSA2USB_BUSY(scsa2usbp
)) {
2130 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
2131 scsa2usbp
->scsa2usb_log_handle
,
2132 "scsa2usb_cpr_suspend: I/O active");
2134 /* fall back to previous state */
2135 scsa2usbp
->scsa2usb_dev_state
= prev_state
;
2141 case USB_DEV_SUSPENDED
:
2143 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2144 "scsa2usb_cpr_suspend: Illegal dev state: %d",
2145 scsa2usbp
->scsa2usb_dev_state
);
2149 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2151 if ((rval
== USB_SUCCESS
) && scsa2usbp
->scsa2usb_ugen_hdl
) {
2152 rval
= usb_ugen_detach(scsa2usbp
->scsa2usb_ugen_hdl
,
2161 * scsa2usb_cpr_resume:
2162 * restore device's state
2165 scsa2usb_cpr_resume(dev_info_t
*dip
)
2167 scsa2usb_state_t
*scsa2usbp
=
2168 ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
2170 ASSERT(scsa2usbp
!= NULL
);
2172 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2173 "scsa2usb_cpr_resume: dip = 0x%p", (void *)dip
);
2175 scsa2usb_restore_device_state(dip
, scsa2usbp
);
2177 if (scsa2usbp
->scsa2usb_ugen_hdl
) {
2178 (void) usb_ugen_attach(scsa2usbp
->scsa2usb_ugen_hdl
,
2185 * scsa2usb_restore_device_state:
2186 * - raise the device's power
2187 * - reopen all the pipes
2190 scsa2usb_restore_device_state(dev_info_t
*dip
, scsa2usb_state_t
*scsa2usbp
)
2194 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2195 "scsa2usb_restore_device_state:");
2197 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2198 prev_state
= scsa2usbp
->scsa2usb_dev_state
;
2200 scsa2usb_raise_power(scsa2usbp
);
2202 ASSERT((prev_state
== USB_DEV_DISCONNECTED
) ||
2203 (prev_state
== USB_DEV_SUSPENDED
));
2205 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2207 /* Check for the same device */
2208 if (usb_check_same_device(dip
, scsa2usbp
->scsa2usb_log_handle
,
2209 USB_LOG_L0
, DPRINT_MASK_ALL
, USB_CHK_ALL
, NULL
) != USB_SUCCESS
) {
2211 /* change the flags to active */
2212 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2213 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_DISCONNECTED
;
2214 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2216 scsa2usb_pm_idle_component(scsa2usbp
);
2222 * if the device had remote wakeup earlier,
2225 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2226 if (scsa2usbp
->scsa2usb_pm
&&
2227 scsa2usbp
->scsa2usb_pm
->scsa2usb_wakeup_enabled
) {
2228 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2229 (void) usb_handle_remote_wakeup(scsa2usbp
->scsa2usb_dip
,
2230 USB_REMOTE_WAKEUP_ENABLE
);
2231 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2234 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_ONLINE
;
2235 scsa2usbp
->scsa2usb_pkt_state
= SCSA2USB_PKT_NONE
;
2236 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2238 scsa2usb_pm_idle_component(scsa2usbp
);
2243 * SCSA entry points:
2245 * scsa2usb_scsi_tgt_probe:
2246 * scsa functions are exported by means of the transport table
2247 * Issue a probe to get the inquiry data.
2251 scsa2usb_scsi_tgt_probe(struct scsi_device
*sd
, int (*waitfunc
)(void))
2253 scsi_hba_tran_t
*tran
;
2254 scsa2usb_state_t
*scsa2usbp
;
2255 dev_info_t
*dip
= ddi_get_parent(sd
->sd_dev
);
2260 tran
= ddi_get_driver_private(dip
);
2261 ASSERT(tran
!= NULL
);
2262 scsa2usbp
= (scsa2usb_state_t
*)tran
->tran_hba_private
;
2265 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2266 "scsa2usb_scsi_tgt_probe:");
2268 /* if device is disconnected (ie. pipes closed), fail immediately */
2269 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2270 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp
))) {
2271 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2273 return (SCSIPROBE_FAILURE
);
2275 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2277 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2278 "scsa2usb_scsi_tgt_probe: scsi_device = 0x%p", (void *)sd
);
2280 if ((rval
= scsi_hba_probe(sd
, waitfunc
)) == SCSIPROBE_EXISTS
) {
2282 * respect the removable bit on all USB storage devices
2283 * unless overridden by a scsa2usb.conf entry
2285 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2286 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_RMB
)) {
2287 _NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry
))
2288 sd
->sd_inq
->inq_rmb
= 1;
2290 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2298 * scsa2usb_scsi_tgt_init:
2299 * check whether we created this child ourselves
2303 scsa2usb_scsi_tgt_init(dev_info_t
*dip
, dev_info_t
*cdip
,
2304 scsi_hba_tran_t
*tran
, struct scsi_device
*sd
)
2306 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)
2307 tran
->tran_hba_private
;
2309 int t_len
= sizeof (lun
);
2311 if (ddi_prop_op(DDI_DEV_T_ANY
, cdip
, PROP_LEN_AND_VAL_BUF
,
2312 DDI_PROP_DONTPASS
|DDI_PROP_CANSLEEP
, "lun", (caddr_t
)&lun
,
2313 &t_len
) != DDI_PROP_SUCCESS
) {
2315 return (DDI_FAILURE
);
2318 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2319 "scsa2usb_scsi_tgt_init: %s, lun%d", ddi_driver_name(cdip
), lun
);
2321 /* is this a child we created? */
2322 if (scsa2usb_is_usb(cdip
) == 0) {
2324 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2325 "scsa2usb_scsi_tgt_init: new child %s%d",
2326 ddi_driver_name(cdip
), ddi_get_instance(cdip
));
2329 * add property "usb" so we can always verify that it
2332 if (ndi_prop_create_boolean(DDI_DEV_T_NONE
, cdip
, "usb") !=
2334 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
2335 scsa2usbp
->scsa2usb_log_handle
,
2336 "ndi_prop_create_boolean failed");
2338 return (DDI_FAILURE
);
2341 usba_set_usba_device(cdip
,
2342 usba_get_usba_device(scsa2usbp
->scsa2usb_dip
));
2345 * we don't store this dip in scsa2usb_lun_dip, there
2346 * might be multiple dips for the same device
2349 return (DDI_SUCCESS
);
2352 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2353 if ((lun
>= scsa2usbp
->scsa2usb_n_luns
) ||
2354 (scsa2usbp
->scsa2usb_lun_dip
[lun
] != NULL
)) {
2355 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2357 return (DDI_FAILURE
);
2360 scsa2usbp
->scsa2usb_lun_dip
[lun
] = cdip
;
2361 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2363 return (DDI_SUCCESS
);
2368 * scsa2usb_scsi_tgt_free:
2372 scsa2usb_scsi_tgt_free(dev_info_t
*hba_dip
, dev_info_t
*cdip
,
2373 scsi_hba_tran_t
*tran
, struct scsi_device
*sd
)
2375 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)
2376 tran
->tran_hba_private
;
2378 int t_len
= sizeof (lun
);
2380 /* is this our child? */
2381 if (scsa2usb_is_usb(cdip
) == 0) {
2386 if (ddi_prop_op(DDI_DEV_T_ANY
, cdip
, PROP_LEN_AND_VAL_BUF
,
2387 DDI_PROP_DONTPASS
|DDI_PROP_CANSLEEP
, "lun", (caddr_t
)&lun
,
2388 &t_len
) != DDI_PROP_SUCCESS
) {
2393 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2394 "scsa2usb_scsi_tgt_free: %s lun%d", ddi_driver_name(cdip
), lun
);
2396 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2397 if (lun
< scsa2usbp
->scsa2usb_n_luns
) {
2398 if (scsa2usbp
->scsa2usb_lun_dip
[lun
] == cdip
) {
2399 scsa2usbp
->scsa2usb_lun_dip
[lun
] = NULL
;
2402 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2407 * bus enumeration entry points
2410 scsa2usb_scsi_bus_config(dev_info_t
*dip
, uint_t flag
, ddi_bus_config_op_t op
,
2411 void *arg
, dev_info_t
**child
)
2416 scsa2usb_state_t
*scsa2usbp
=
2417 ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
2419 ASSERT(scsa2usbp
!= NULL
);
2421 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2422 "scsa2usb_scsi_bus_config: op=%d", op
);
2424 if (scsa2usb_scsi_bus_config_debug
) {
2425 flag
|= NDI_DEVI_DEBUG
;
2428 ndi_devi_enter(dip
, &circ
);
2429 /* create children if necessary */
2430 if (DEVI(dip
)->devi_child
== NULL
) {
2431 scsa2usb_create_luns(scsa2usbp
);
2434 rval
= ndi_busop_bus_config(dip
, flag
, op
, arg
, child
, 0);
2436 ndi_devi_exit(dip
, circ
);
2443 scsa2usb_scsi_bus_unconfig(dev_info_t
*dip
, uint_t flag
, ddi_bus_config_op_t op
,
2446 scsa2usb_state_t
*scsa2usbp
=
2447 ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
2450 int rval
= NDI_SUCCESS
;
2451 uint_t save_flag
= flag
;
2453 ASSERT(scsa2usbp
!= NULL
);
2455 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2456 "scsa2usb_scsi_bus_unconfig: op=%d", op
);
2458 if (scsa2usb_scsi_bus_config_debug
) {
2459 flag
|= NDI_DEVI_DEBUG
;
2463 * first offline and if offlining successful, then
2466 if (op
== BUS_UNCONFIG_ALL
) {
2467 flag
&= ~(NDI_DEVI_REMOVE
| NDI_UNCONFIG
);
2470 ndi_devi_enter(dip
, &circular_count
);
2471 rval
= ndi_busop_bus_unconfig(dip
, flag
, op
, arg
);
2474 * If unconfig is successful and not part of modunload
2475 * daemon, attempt to remove children.
2477 if (op
== BUS_UNCONFIG_ALL
&& rval
== NDI_SUCCESS
&&
2478 (flag
& NDI_AUTODETACH
) == 0) {
2479 flag
|= NDI_DEVI_REMOVE
;
2480 rval
= ndi_busop_bus_unconfig(dip
, flag
, op
, arg
);
2482 ndi_devi_exit(dip
, circular_count
);
2484 if ((rval
!= NDI_SUCCESS
) && (op
== BUS_UNCONFIG_ALL
) &&
2485 (save_flag
& NDI_DEVI_REMOVE
)) {
2486 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2487 if (scsa2usbp
->scsa2usb_warning_given
!= B_TRUE
) {
2488 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
2489 scsa2usbp
->scsa2usb_log_handle
,
2490 "Disconnected device was busy, "
2491 "please reconnect.");
2492 scsa2usbp
->scsa2usb_warning_given
= B_TRUE
;
2494 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2497 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2498 "scsa2usb_scsi_bus_unconfig: rval=%d", rval
);
2505 * scsa2usb_scsi_init_pkt:
2506 * Set up the scsi_pkt for transport. Also initialize
2507 * scsa2usb_cmd struct for the transport.
2508 * NOTE: We do not do any DMA setup here as USBA framework
2511 static struct scsi_pkt
*
2512 scsa2usb_scsi_init_pkt(struct scsi_address
*ap
,
2513 struct scsi_pkt
*pkt
, struct buf
*bp
, int cmdlen
, int statuslen
,
2514 int tgtlen
, int flags
, int (*callback
)(), caddr_t arg
)
2516 scsa2usb_cmd_t
*cmd
;
2517 scsa2usb_state_t
*scsa2usbp
;
2518 struct scsi_pkt
*in_pkt
= pkt
;
2520 ASSERT(callback
== NULL_FUNC
|| callback
== SLEEP_FUNC
);
2522 scsa2usbp
= (scsa2usb_state_t
*)ADDR2SCSA2USB(ap
);
2524 /* Print sync message */
2525 if (ddi_in_panic()) {
2526 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2527 SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message
, scsa2usbp
);
2528 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2529 /* continue so caller will not hang or complain */
2532 /* allocate a pkt, if none already allocated */
2534 if (statuslen
< sizeof (struct scsi_arq_status
)) {
2535 statuslen
= sizeof (struct scsi_arq_status
);
2538 pkt
= scsi_hba_pkt_alloc(scsa2usbp
->scsa2usb_dip
, ap
, cmdlen
,
2539 statuslen
, tgtlen
, sizeof (scsa2usb_cmd_t
),
2547 cmd
->cmd_pkt
= pkt
; /* back link to pkt */
2548 cmd
->cmd_scblen
= statuslen
;
2549 cmd
->cmd_cdblen
= (uchar_t
)cmdlen
;
2551 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2552 cmd
->cmd_tag
= scsa2usbp
->scsa2usb_tag
++;
2553 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2557 * The buffer size of cmd->cmd_scb is constrained
2558 * to sizeof (struct scsi_arq_status), if the scblen
2559 * is bigger than that, we use pkt->pkt_scbp directly.
2561 if (cmd
->cmd_scblen
== sizeof (struct scsi_arq_status
)) {
2562 pkt
->pkt_scbp
= (opaque_t
)&cmd
->cmd_scb
;
2565 usba_init_list(&cmd
->cmd_waitQ
, (usb_opaque_t
)cmd
,
2566 scsa2usbp
->scsa2usb_dev_data
->dev_iblock_cookie
);
2568 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2569 "scsa2usb: pkt != NULL");
2574 if (bp
&& (bp
->b_bcount
!= 0)) {
2575 if ((bp_mapin_common(bp
, (callback
== SLEEP_FUNC
) ?
2576 VM_SLEEP
: VM_NOSLEEP
)) == NULL
) {
2577 if (pkt
!= in_pkt
) {
2578 scsi_hba_pkt_free(ap
, pkt
);
2584 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
2585 scsa2usbp
->scsa2usb_log_handle
,
2586 "scsa2usb_scsi_init_pkt: mapped in 0x%p, addr=0x%p",
2587 (void *)bp
, (void *)bp
->b_un
.b_addr
);
2590 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2591 "scsa2usb_scsi_init_pkt: ap = 0x%p pkt: 0x%p\n\t"
2592 "bp = 0x%p cmdlen = %x stlen = 0x%x tlen = 0x%x flags = 0x%x",
2593 (void *)ap
, (void *)pkt
, (void *)bp
, cmdlen
, statuslen
,
2601 * scsa2usb_scsi_destroy_pkt:
2602 * We are done with the packet. Get rid of it.
2605 scsa2usb_scsi_destroy_pkt(struct scsi_address
*ap
, struct scsi_pkt
*pkt
)
2607 scsa2usb_cmd_t
*cmd
= PKT2CMD(pkt
);
2608 scsa2usb_state_t
*scsa2usbp
= ADDR2SCSA2USB(ap
);
2610 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2611 "scsa2usb_scsi_destroy_pkt: pkt=0x%p", (void *)pkt
);
2613 usba_destroy_list(&cmd
->cmd_waitQ
);
2614 scsi_hba_pkt_free(ap
, pkt
);
2619 * scsa2usb_scsi_start:
2620 * For each command being issued, build up the CDB
2621 * and call scsi_transport to issue the command. This
2622 * function is based on the assumption that USB allows
2623 * a subset of SCSI commands. Other SCSI commands we fail.
2626 scsa2usb_scsi_start(struct scsi_address
*ap
, struct scsi_pkt
*pkt
)
2628 scsa2usb_cmd_t
*cmd
;
2629 scsa2usb_state_t
*scsa2usbp
= ADDR2SCSA2USB(ap
);
2630 uint_t lun
= ap
->a_lun
;
2632 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2635 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2636 "scsa2usb_scsi_start:\n\t"
2637 "bp: 0x%p ap: 0x%p pkt: 0x%p flag: 0x%x time: 0x%x\n\tcdb0: 0x%x "
2638 "dev_state: 0x%x pkt_state: 0x%x flags: 0x%x pipe_state: 0x%x",
2639 (void *)cmd
->cmd_bp
, (void *)ap
, (void *)pkt
, pkt
->pkt_flags
,
2640 pkt
->pkt_time
, pkt
->pkt_cdbp
[0], scsa2usbp
->scsa2usb_dev_state
,
2641 scsa2usbp
->scsa2usb_pkt_state
, scsa2usbp
->scsa2usb_flags
,
2642 scsa2usbp
->scsa2usb_pipe_state
);
2644 if (pkt
->pkt_time
== 0) {
2645 USB_DPRINTF_L1(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2646 "pkt submitted with 0 timeout which may cause indefinite "
2651 * if we are in panic, we are in polled mode, so we can just
2652 * accept the request, drop it and return
2653 * if we fail this request, the rest of the file systems do not
2656 if (ddi_in_panic()) {
2657 extern int do_polled_io
;
2659 ASSERT(do_polled_io
);
2660 scsa2usb_prepare_pkt(scsa2usbp
, pkt
);
2661 SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message
, scsa2usbp
);
2662 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2664 return (TRAN_ACCEPT
);
2667 /* we cannot do polling, this should not happen */
2668 if (pkt
->pkt_flags
& FLAG_NOINTR
) {
2669 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2670 "NOINTR packet: opcode = 0%x", pkt
->pkt_cdbp
[0]);
2671 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2673 return (TRAN_BADPKT
);
2676 /* prepare packet */
2677 scsa2usb_prepare_pkt(scsa2usbp
, pkt
);
2679 /* just queue up the requests in the waitQ if below max */
2680 if (usba_list_entry_count(&scsa2usbp
->scsa2usb_waitQ
[lun
]) >
2681 SCSA2USB_MAX_REQ_PER_LUN
) {
2682 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
2683 scsa2usbp
->scsa2usb_log_handle
,
2684 "scsa2usb_scsi_start: limit (%d) exceeded",
2685 SCSA2USB_MAX_REQ_PER_LUN
);
2686 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2691 usba_add_to_list(&scsa2usbp
->scsa2usb_waitQ
[lun
], &cmd
->cmd_waitQ
);
2693 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2694 "scsa2usb_work_thread_id=0x%p, count=%d, lun=%d",
2695 (void *)scsa2usbp
->scsa2usb_work_thread_id
,
2696 usba_list_entry_count(&scsa2usbp
->scsa2usb_waitQ
[lun
]), lun
);
2698 /* fire up a thread to start executing the protocol */
2699 if (scsa2usbp
->scsa2usb_work_thread_id
== 0) {
2700 if ((usb_async_req(scsa2usbp
->scsa2usb_dip
,
2701 scsa2usb_work_thread
,
2702 (void *)scsa2usbp
, USB_FLAGS_SLEEP
)) != USB_SUCCESS
) {
2703 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
2704 scsa2usbp
->scsa2usb_log_handle
,
2705 "no work thread started");
2707 if (usba_rm_from_list(
2708 &scsa2usbp
->scsa2usb_waitQ
[lun
],
2709 &cmd
->cmd_waitQ
) == USB_SUCCESS
) {
2710 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2715 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2717 return (TRAN_ACCEPT
);
2720 scsa2usbp
->scsa2usb_work_thread_id
= (kthread_t
*)1;
2723 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2725 return (TRAN_ACCEPT
);
2730 * scsa2usb_scsi_abort:
2731 * Issue SCSI abort command. This function is a NOP.
2735 scsa2usb_scsi_abort(struct scsi_address
*ap
, struct scsi_pkt
*pkt
)
2737 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)ADDR2SCSA2USB(ap
);
2739 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2740 "scsa2usb_scsi_abort: pkt = %p", (void *)pkt
);
2742 /* if device is disconnected (ie. pipes closed), fail immediately */
2743 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2744 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp
))) {
2745 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2750 /* flush waitQ if target and lun match */
2751 if ((ap
->a_target
== pkt
->pkt_address
.a_target
) &&
2752 (ap
->a_lun
== pkt
->pkt_address
.a_lun
)) {
2753 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2754 scsa2usb_flush_waitQ(scsa2usbp
, ap
->a_lun
, CMD_ABORTED
);
2755 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2757 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2764 * scsa2usb_scsi_reset:
2765 * device reset may turn the device into a brick and bus reset
2766 * is not applicable.
2767 * just flush the waitQ
2768 * We return success, always.
2772 scsa2usb_scsi_reset(struct scsi_address
*ap
, int level
)
2774 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)ADDR2SCSA2USB(ap
);
2776 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2777 "scsa2usb_scsi_reset: ap = 0x%p, level = %d", (void *)ap
, level
);
2780 scsa2usb_flush_waitQ(scsa2usbp
, ap
->a_lun
, CMD_RESET
);
2787 * scsa2usb_scsi_getcap:
2788 * Get SCSI capabilities.
2792 scsa2usb_scsi_getcap(struct scsi_address
*ap
, char *cap
, int whom
)
2796 size_t dev_bsize_cap
;
2797 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)ADDR2SCSA2USB(ap
);
2801 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2802 "scsa2usb_scsi_getcap: invalid arg, "
2803 "cap = 0x%p whom = %d", (void *)cap
, whom
);
2808 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2809 "scsa2usb_scsi_getcap: cap = %s", cap
);
2811 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2813 /* if device is disconnected (ie. pipes closed), fail immediately */
2814 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp
))) {
2816 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2821 cidx
= scsi_hba_lookup_capstr(cap
);
2823 case SCSI_CAP_GEOMETRY
:
2824 /* Just check and fail immediately if zero, rarely happens */
2825 if (scsa2usbp
->scsa2usb_secsz
[ap
->a_lun
] == 0) {
2826 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
2827 scsa2usbp
->scsa2usb_log_handle
,
2828 "scsa2usb_scsi_getcap failed:"
2829 "scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0");
2830 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2835 dev_bsize_cap
= scsa2usbp
->scsa2usb_totalsec
[ap
->a_lun
];
2837 if (scsa2usbp
->scsa2usb_secsz
[ap
->a_lun
] > DEV_BSIZE
) {
2839 scsa2usbp
->scsa2usb_secsz
[ap
->a_lun
] / DEV_BSIZE
;
2840 } else if (scsa2usbp
->scsa2usb_secsz
[ap
->a_lun
] <
2843 DEV_BSIZE
/ scsa2usbp
->scsa2usb_secsz
[ap
->a_lun
];
2846 if (dev_bsize_cap
< 65536 * 2 * 18) { /* < ~1GB */
2847 /* unlabeled floppy, 18k per cylinder */
2848 rval
= ((2 << 16) | 18);
2849 } else if (dev_bsize_cap
< 65536 * 64 * 32) { /* < 64GB */
2850 /* 1024k per cylinder */
2851 rval
= ((64 << 16) | 32);
2852 } else if (dev_bsize_cap
< 65536 * 255 * 63) { /* < ~500GB */
2853 /* ~8m per cylinder */
2854 rval
= ((255 << 16) | 63);
2855 } else { /* .. 8TB */
2856 /* 64m per cylinder */
2857 rval
= ((512 << 16) | 256);
2861 case SCSI_CAP_DMA_MAX
:
2862 rval
= scsa2usbp
->scsa2usb_max_bulk_xfer_size
;
2864 case SCSI_CAP_SCSI_VERSION
:
2865 rval
= SCSI_VERSION_2
;
2867 case SCSI_CAP_INTERCONNECT_TYPE
:
2868 rval
= INTERCONNECT_USB
;
2872 case SCSI_CAP_UNTAGGED_QING
:
2876 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2877 "scsa2usb_scsi_getcap: unsupported cap = %s", cap
);
2881 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2882 "scsa2usb_scsi_getcap: cap = %s, returned = %d", cap
, rval
);
2884 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2891 * scsa2usb_scsi_setcap:
2892 * Set SCSI capabilities.
2896 scsa2usb_scsi_setcap(struct scsi_address
*ap
, char *cap
, int value
, int whom
)
2898 int rval
= -1; /* default is cap undefined */
2900 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)ADDR2SCSA2USB(ap
);
2903 if (cap
== NULL
|| whom
== 0) {
2904 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2905 "scsa2usb_scsi_setcap: invalid arg");
2910 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
2911 /* if device is disconnected (ie. pipes closed), fail immediately */
2912 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp
))) {
2913 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2918 cidx
= scsi_hba_lookup_capstr(cap
);
2919 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2920 "scsa2usb_scsi_setcap: ap = 0x%p value = 0x%x whom = 0x%x "
2921 "cidx = 0x%x", (void *)ap
, value
, whom
, cidx
);
2924 case SCSI_CAP_SECTOR_SIZE
:
2926 scsa2usbp
->scsa2usb_secsz
[ap
->a_lun
] = value
;
2929 case SCSI_CAP_TOTAL_SECTORS
:
2931 scsa2usbp
->scsa2usb_totalsec
[ap
->a_lun
] = value
;
2937 case SCSI_CAP_DMA_MAX
:
2938 case SCSI_CAP_SCSI_VERSION
:
2939 case SCSI_CAP_INTERCONNECT_TYPE
:
2940 case SCSI_CAP_UNTAGGED_QING
:
2941 /* supported but not settable */
2945 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2946 "scsa2usb_scsi_setcap: unsupported cap = %s", cap
);
2950 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
2957 * scsa2usb - cmd and transport stuff
2960 * scsa2usb_prepare_pkt:
2961 * initialize some fields of the pkt and cmd
2962 * (the pkt may have been resubmitted/retried)
2965 scsa2usb_prepare_pkt(scsa2usb_state_t
*scsa2usbp
, struct scsi_pkt
*pkt
)
2967 scsa2usb_cmd_t
*cmd
= PKT2CMD(pkt
);
2969 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
2970 "scsa2usb_prepare_pkt: pkt=0x%p cdb: 0x%x (%s)",
2971 (void *)pkt
, pkt
->pkt_cdbp
[0],
2972 scsi_cname(pkt
->pkt_cdbp
[0], scsa2usb_cmds
));
2974 pkt
->pkt_reason
= CMD_CMPLT
; /* Set reason to pkt_complete */
2975 pkt
->pkt_state
= 0; /* Reset next three fields */
2976 pkt
->pkt_statistics
= 0;
2978 bzero(pkt
->pkt_scbp
, cmd
->cmd_scblen
); /* Set status to good */
2981 cmd
->cmd_timeout
= pkt
->pkt_time
;
2982 cmd
->cmd_xfercount
= 0; /* Reset the fields */
2983 cmd
->cmd_total_xfercount
= 0;
2987 cmd
->cmd_offset
= 0;
2988 cmd
->cmd_actual_len
= cmd
->cmd_cdblen
;
2994 * scsa2usb_force_invalid_request
2997 scsa2usb_force_invalid_request(scsa2usb_state_t
*scsa2usbp
,
2998 scsa2usb_cmd_t
*cmd
)
3000 struct scsi_arq_status
*arqp
;
3002 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3003 "scsa2usb_force_invalid_request: pkt = 0x%p", (void *)cmd
->cmd_pkt
);
3005 if (cmd
->cmd_scblen
>= sizeof (struct scsi_arq_status
)) {
3006 arqp
= (struct scsi_arq_status
*)cmd
->cmd_pkt
->pkt_scbp
;
3007 bzero(arqp
, cmd
->cmd_scblen
);
3009 arqp
->sts_status
.sts_chk
= 1;
3010 arqp
->sts_rqpkt_reason
= CMD_CMPLT
;
3011 arqp
->sts_rqpkt_state
= STATE_XFERRED_DATA
|
3012 STATE_GOT_BUS
| STATE_GOT_STATUS
;
3013 arqp
->sts_sensedata
.es_valid
= 1;
3014 arqp
->sts_sensedata
.es_class
= 7;
3015 arqp
->sts_sensedata
.es_key
= KEY_ILLEGAL_REQUEST
;
3017 cmd
->cmd_pkt
->pkt_state
= STATE_ARQ_DONE
|
3018 STATE_GOT_BUS
| STATE_GOT_BUS
| STATE_GOT_BUS
|
3022 uchar_t
*p
= (uchar_t
*)(&arqp
->sts_sensedata
);
3023 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
3024 scsa2usbp
->scsa2usb_log_handle
,
3026 "%x %x %x %x %x %x %x %x %x %x "
3027 "%x %x %x %x %x %x %x %x %x %x",
3028 cmd
->cmd_pkt
->pkt_cdbp
[0],
3029 p
[0], p
[1], p
[2], p
[3], p
[4],
3030 p
[5], p
[6], p
[7], p
[8], p
[9],
3031 p
[10], p
[11], p
[12], p
[13], p
[14],
3032 p
[15], p
[16], p
[17], p
[18], p
[19]);
3041 * scsa2usb_cmd_transport:
3044 scsa2usb_cmd_transport(scsa2usb_state_t
*scsa2usbp
, scsa2usb_cmd_t
*cmd
)
3046 int rval
, transport
;
3047 struct scsi_pkt
*pkt
;
3049 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3050 "scsa2usb_cmd_transport: pkt: 0x%p, cur_pkt = 0x%p",
3051 (void *)cmd
->cmd_pkt
, (void *)scsa2usbp
->scsa2usb_cur_pkt
);
3053 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3054 ASSERT(scsa2usbp
->scsa2usb_cur_pkt
== NULL
);
3056 pkt
= scsa2usbp
->scsa2usb_cur_pkt
= cmd
->cmd_pkt
;
3058 /* check black-listed attrs first */
3059 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp
)) {
3060 transport
= scsa2usb_check_bulkonly_blacklist_attrs(scsa2usbp
,
3061 cmd
, pkt
->pkt_cdbp
[0]);
3062 } else if (SCSA2USB_IS_CB(scsa2usbp
) || SCSA2USB_IS_CBI(scsa2usbp
)) {
3063 transport
= scsa2usb_check_ufi_blacklist_attrs(scsa2usbp
,
3064 pkt
->pkt_cdbp
[0], cmd
);
3067 /* just accept the command or return error */
3068 if (transport
== SCSA2USB_JUST_ACCEPT
) {
3069 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp
);
3071 return (TRAN_ACCEPT
);
3072 } else if (transport
== SCSA2USB_REJECT
) {
3073 return (TRAN_FATAL_ERROR
);
3076 /* check command set next */
3077 if (SCSA2USB_IS_SCSI_CMDSET(scsa2usbp
) ||
3078 SCSA2USB_IS_ATAPI_CMDSET(scsa2usbp
)) {
3080 scsa2usb_handle_scsi_cmd_sub_class(scsa2usbp
, cmd
, pkt
);
3081 } else if (SCSA2USB_IS_UFI_CMDSET(scsa2usbp
)) {
3083 scsa2usb_handle_ufi_subclass_cmd(scsa2usbp
, cmd
, pkt
);
3085 transport
= SCSA2USB_REJECT
;
3088 switch (transport
) {
3089 case SCSA2USB_TRANSPORT
:
3090 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp
)) {
3091 rval
= scsa2usb_bulk_only_transport(scsa2usbp
, cmd
);
3092 } else if (SCSA2USB_IS_CB(scsa2usbp
) ||
3093 SCSA2USB_IS_CBI(scsa2usbp
)) {
3094 rval
= scsa2usb_cbi_transport(scsa2usbp
, cmd
);
3096 rval
= TRAN_FATAL_ERROR
;
3099 case SCSA2USB_JUST_ACCEPT
:
3100 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp
);
3104 rval
= TRAN_FATAL_ERROR
;
3112 * scsa2usb_check_bulkonly_blacklist_attrs:
3113 * validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3114 * if blacklisted attrs match accept the request
3115 * attributes checked are:-
3116 * SCSA2USB_ATTRS_START_STOP
3119 scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t
*scsa2usbp
,
3120 scsa2usb_cmd_t
*cmd
, uchar_t opcode
)
3122 struct scsi_inquiry
*inq
=
3123 &scsa2usbp
->scsa2usb_lun_inquiry
[cmd
->cmd_pkt
->pkt_address
.a_lun
];
3125 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3126 "scsa2usb_check_bulkonly_blacklist_attrs: opcode = %s",
3127 scsi_cname(opcode
, scsa2usb_cmds
));
3129 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3132 * decode and convert the packet
3133 * for most cmds, we can bcopy the cdb
3137 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_DOORLOCK
)) {
3139 return (SCSA2USB_JUST_ACCEPT
);
3142 * only lock the door for CD and DVD drives
3144 } else if ((inq
->inq_dtype
== DTYPE_RODIRECT
) ||
3145 (inq
->inq_dtype
== DTYPE_OPTICAL
)) {
3153 return (SCSA2USB_JUST_ACCEPT
);
3155 case SCMD_START_STOP
: /* SCMD_LOAD for sequential devices */
3157 * these devices don't have mechanics that spin the
3158 * media up and down. So, it doesn't make much sense
3159 * to issue this cmd.
3161 * Furthermore, Hagiwara devices do not handle these
3162 * cmds well. just accept this command as success.
3164 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_START_STOP
)) {
3166 return (SCSA2USB_JUST_ACCEPT
);
3168 } else if (inq
->inq_dtype
== DTYPE_SEQUENTIAL
) {
3170 * In case of USB tape device, we need to send the
3171 * command to the device to unload the media.
3175 } else if (cmd
->cmd_pkt
->pkt_cdbp
[4] & LOEJECT
) {
3177 * if the device is really a removable then
3178 * pass it on to the device, else just accept
3185 return (SCSA2USB_JUST_ACCEPT
);
3187 } else if (!scsa2usbp
->scsa2usb_rcvd_not_ready
) {
3189 * if we have not received a NOT READY condition,
3190 * just accept since some device choke on this too.
3191 * we do have to let EJECT get through though
3193 return (SCSA2USB_JUST_ACCEPT
);
3199 * Some devices do not handle the inquiry cmd well
3200 * so build an inquiry and accept this command as
3203 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_INQUIRY
)) {
3204 uchar_t evpd
= 0x01;
3205 unsigned int bufsize
;
3208 if (cmd
->cmd_pkt
->pkt_cdbp
[1] & evpd
)
3209 return (SCSA2USB_REJECT
);
3211 scsa2usb_fake_inquiry(scsa2usbp
, inq
);
3213 /* Copy no more than requested */
3214 count
= MIN(cmd
->cmd_bp
->b_bcount
,
3215 sizeof (struct scsi_inquiry
));
3216 bufsize
= cmd
->cmd_pkt
->pkt_cdbp
[4];
3217 count
= MIN(count
, bufsize
);
3218 bcopy(inq
, cmd
->cmd_bp
->b_un
.b_addr
, count
);
3220 cmd
->cmd_pkt
->pkt_resid
= bufsize
- count
;
3221 cmd
->cmd_pkt
->pkt_state
|= STATE_XFERRED_DATA
;
3223 return (SCSA2USB_JUST_ACCEPT
);
3224 } else if (!(scsa2usbp
->scsa2usb_attrs
&
3225 SCSA2USB_ATTRS_INQUIRY_EVPD
)) {
3227 * Some devices do not handle the inquiry cmd with
3228 * evpd bit set well, e.g. some devices return the
3229 * same page 0x83 data which will cause the generated
3230 * devid by sd is not unique, thus return CHECK
3231 * CONDITION directly to sd.
3233 uchar_t evpd
= 0x01;
3235 if (!(cmd
->cmd_pkt
->pkt_cdbp
[1] & evpd
))
3239 cmd
->cmd_pkt
->pkt_resid
= cmd
->cmd_bp
->
3242 scsa2usb_force_invalid_request(scsa2usbp
, cmd
);
3244 return (SCSA2USB_JUST_ACCEPT
);
3248 * Fake accepting the following Opcodes
3249 * (as most drives don't support these)
3250 * These are needed by format command.
3254 case SCMD_PERSISTENT_RESERVE_IN
:
3255 case SCMD_PERSISTENT_RESERVE_OUT
:
3257 return (SCSA2USB_JUST_ACCEPT
);
3259 case SCMD_MODE_SENSE
:
3260 case SCMD_MODE_SELECT
:
3261 case SCMD_MODE_SENSE_G1
:
3262 case SCMD_MODE_SELECT_G1
:
3263 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_MODE_SENSE
)) {
3265 cmd
->cmd_pkt
->pkt_resid
= cmd
->cmd_bp
->
3268 scsa2usb_force_invalid_request(scsa2usbp
, cmd
);
3270 return (SCSA2USB_JUST_ACCEPT
);
3279 return (SCSA2USB_TRANSPORT
);
3284 * scsa2usb_handle_scsi_cmd_sub_class:
3285 * prepare a scsi cmd
3286 * returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT, SCSA2USB_JUST_ACCEPT
3289 scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t
*scsa2usbp
,
3290 scsa2usb_cmd_t
*cmd
, struct scsi_pkt
*pkt
)
3292 uchar_t evpd
= 0x01;
3293 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3294 "scsa2usb_handle_scsi_cmd_sub_class: cmd = 0x%p pkt = 0x%p",
3295 (void *)cmd
, (void *)pkt
);
3297 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3299 bzero(&cmd
->cmd_cdb
, SCSI_CDB_SIZE
);
3300 cmd
->cmd_cdb
[SCSA2USB_OPCODE
] = pkt
->pkt_cdbp
[0]; /* Set the opcode */
3301 cmd
->cmd_cdb
[SCSA2USB_LUN
] = pkt
->pkt_cdbp
[1];
3304 * decode and convert the packet
3305 * for most cmds, we can bcopy the cdb
3307 switch (pkt
->pkt_cdbp
[0]) {
3310 * SCMD_FORMAT used to limit cmd->cmd_xfercount
3311 * to 4 bytes, but this hangs
3312 * formatting dvd media using cdrecord (that is,
3313 * a SCSI FORMAT UNIT command with a parameter list > 4 bytes)
3314 * (bit 4 in cdb1 is the Fmtdata bit)
3316 if ((pkt
->pkt_cdbp
[1] & 0x10) && cmd
->cmd_bp
) {
3317 cmd
->cmd_xfercount
= cmd
->cmd_bp
->b_bcount
;
3319 cmd
->cmd_xfercount
= 4;
3321 cmd
->cmd_dir
= CBW_DIR_OUT
;
3322 cmd
->cmd_actual_len
= CDB_GROUP0
;
3323 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3327 cmd
->cmd_dir
= CBW_DIR_IN
;
3328 cmd
->cmd_actual_len
= CDB_GROUP0
;
3329 cmd
->cmd_cdb
[SCSA2USB_LBA_0
] = pkt
->pkt_cdbp
[2];
3332 * If vpd pages data is limited to maximum SCSA2USB_MAX_INQ_LEN,
3333 * the page data may be truncated, which may cause some issues
3334 * such as making the unique page 0x83 or 0x80 data from
3335 * different devices become the same. So don't limit return
3336 * length for vpd page inquiry cmd.
3337 * Another, in order to maintain compatibility, the original
3338 * length limitation for standard inquiry retains here. It
3339 * can be removed in future if it is verified that enough
3340 * devices can work well.
3342 if (pkt
->pkt_cdbp
[1] & evpd
) {
3343 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = cmd
->cmd_xfercount
=
3344 (cmd
->cmd_bp
? cmd
->cmd_bp
->b_bcount
: 0);
3346 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = cmd
->cmd_xfercount
=
3347 min(SCSA2USB_MAX_INQ_LEN
,
3348 cmd
->cmd_bp
? cmd
->cmd_bp
->b_bcount
: 0);
3352 case SCMD_READ_CAPACITY
:
3353 cmd
->cmd_dir
= CBW_DIR_IN
;
3354 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3355 cmd
->cmd_xfercount
= sizeof (scsa2usb_read_cap_t
);
3359 * SCMD_READ/SCMD_WRITE are converted to G1 cmds
3360 * (as ATAPI devices don't recognize G0 commands)
3362 * SCMD_READ_LONG/SCMD_WRITE_LONG are handled in
3363 * scsa2usb_rw_transport() along with other commands.
3365 * USB Host Controllers cannot handle large (read/write)
3366 * xfers. We split the large request to chunks of
3367 * smaller ones to meet the HCD limitations.
3375 case SCMD_READ_LONG
:
3376 case SCMD_WRITE_LONG
:
3379 scsa2usb_lun_inquiry
[pkt
->pkt_address
.a_lun
].
3380 inq_dtype
& DTYPE_MASK
) {
3382 case DTYPE_RODIRECT
:
3384 return (scsa2usb_rw_transport(
3387 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3390 (cmd
->cmd_bp
->b_flags
& B_READ
) ?
3391 CBW_DIR_IN
: CBW_DIR_OUT
;
3392 cmd
->cmd_xfercount
=
3393 cmd
->cmd_bp
->b_bcount
;
3399 case SCMD_REQUEST_SENSE
:
3400 cmd
->cmd_dir
= CBW_DIR_IN
;
3401 cmd
->cmd_xfercount
= pkt
->pkt_cdbp
[4];
3402 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = pkt
->pkt_cdbp
[4];
3403 cmd
->cmd_actual_len
= CDB_GROUP0
;
3407 case SCMD_START_STOP
:
3408 case SCMD_TEST_UNIT_READY
:
3409 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3413 * Needed by zip protocol to reset the device
3416 case SCMD_REZERO_UNIT
:
3417 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3418 cmd
->cmd_actual_len
= CDB_GROUP1
;
3421 case SCMD_WRITE_VERIFY
:
3422 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3423 cmd
->cmd_dir
= CBW_DIR_OUT
;
3424 cmd
->cmd_xfercount
= (pkt
->pkt_cdbp
[7] << 8) | pkt
->pkt_cdbp
[8];
3425 cmd
->cmd_actual_len
= CDB_GROUP1
;
3429 * Next command does not have a SCSI equivalent as
3430 * it is vendor specific.
3431 * It was listed in the vendor's ATAPI Zip specs.
3433 case SCMD_READ_FORMAT_CAP
:
3434 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3435 cmd
->cmd_dir
= CBW_DIR_IN
;
3436 cmd
->cmd_xfercount
= (pkt
->pkt_cdbp
[7] << 8) | pkt
->pkt_cdbp
[8];
3437 cmd
->cmd_actual_len
= CDB_GROUP1
;
3439 case IOMEGA_CMD_CARTRIDGE_PROTECT
:
3440 cmd
->cmd_dir
= CBW_DIR_OUT
;
3441 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = pkt
->pkt_cdbp
[4];
3442 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] &= ~1; /* Make it even */
3443 cmd
->cmd_cdb
[SCSA2USB_LUN
] = pkt
->pkt_cdbp
[1];
3444 cmd
->cmd_actual_len
= CDB_GROUP0
;
3445 cmd
->cmd_xfercount
= pkt
->pkt_cdbp
[4]; /* Length of password */
3449 * Do not convert SCMD_MODE_SENSE/SELECT to G1 cmds because
3450 * the mode header is different as well. USB devices don't
3451 * support 0x03 & 0x04 mode pages, which are already obsoleted
3452 * by SPC-2 specification.
3454 case SCMD_MODE_SENSE
:
3455 case SCMD_MODE_SELECT
:
3456 if (((pkt
->pkt_cdbp
[2] & SD_MODE_SENSE_PAGE_MASK
)
3457 == SD_MODE_SENSE_PAGE3_CODE
) ||
3458 ((pkt
->pkt_cdbp
[2] & SD_MODE_SENSE_PAGE_MASK
)
3459 == SD_MODE_SENSE_PAGE4_CODE
)) {
3461 cmd
->cmd_pkt
->pkt_resid
= cmd
->cmd_bp
->b_bcount
;
3463 scsa2usb_force_invalid_request(scsa2usbp
, cmd
);
3464 return (SCSA2USB_JUST_ACCEPT
);
3470 * an unknown command may be a uscsi cmd which we
3471 * should let go thru without mapping
3473 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3475 cmd
->cmd_dir
= (cmd
->cmd_bp
->b_flags
& B_READ
) ?
3476 CBW_DIR_IN
: CBW_DIR_OUT
;
3477 cmd
->cmd_xfercount
= cmd
->cmd_bp
->b_bcount
;
3481 } /* end of switch */
3483 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3484 "scsa2usb_handle_scsi_cmd_sub_class: opcode = 0x%x count = 0x%lx",
3485 pkt
->pkt_cdbp
[SCSA2USB_OPCODE
], cmd
->cmd_xfercount
);
3487 cmd
->cmd_total_xfercount
= cmd
->cmd_xfercount
;
3489 return (SCSA2USB_TRANSPORT
);
3494 * scsa2usb_do_tur is performed before READ CAPACITY command is issued.
3495 * It returns media status, 0 for media ready, -1 for media not ready
3499 scsa2usb_do_tur(scsa2usb_state_t
*scsa2usbp
, struct scsi_address
*ap
)
3501 struct scsi_pkt
*pkt
;
3502 scsa2usb_cmd_t
*turcmd
;
3505 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3506 "scsa2usb_do_tur:");
3508 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3510 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
3511 if ((pkt
= scsi_init_pkt(ap
, NULL
, NULL
, CDB_GROUP0
, 1,
3512 PKT_PRIV_LEN
, PKT_CONSISTENT
, SLEEP_FUNC
, NULL
)) == NULL
) {
3513 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
3514 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
3515 scsa2usbp
->scsa2usb_log_handle
,
3516 "scsa2usb_do_tur: init pkt failed");
3521 RQ_MAKECOM_G0(pkt
, FLAG_HEAD
| FLAG_NODISCON
,
3522 (char)SCMD_TEST_UNIT_READY
, 0, 0);
3524 pkt
->pkt_comp
= NULL
;
3525 pkt
->pkt_time
= PKT_DEFAULT_TIMEOUT
;
3526 turcmd
= PKT2CMD(pkt
);
3528 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
3529 scsa2usb_prepare_pkt(scsa2usbp
, turcmd
->cmd_pkt
);
3531 if (scsa2usb_cmd_transport(scsa2usbp
, turcmd
) != TRAN_ACCEPT
) {
3532 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
3533 scsa2usbp
->scsa2usb_log_handle
,
3534 "scsa2usb_do_tur: cmd transport failed, "
3535 "pkt_reason=0x%x", turcmd
->cmd_pkt
->pkt_reason
);
3536 } else if (*(turcmd
->cmd_pkt
->pkt_scbp
) != STATUS_GOOD
) {
3538 * Theoretically, the sense data should be retrieved and
3539 * sense key be checked when check condition happens. If
3540 * the sense key is UNIT ATTENTION, TEST UNIT READY cmd
3541 * needs to be sent again to clear the UNIT ATTENTION and
3542 * another TUR to be sent to get the real media status.
3543 * But the AMI virtual floppy device simply cannot recover
3544 * from UNIT ATTENTION by re-sending a TUR cmd, so it
3545 * doesn't make any difference whether to check sense key
3546 * or not. Just ignore sense key checking here and assume
3547 * the device is NOT READY.
3549 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
3550 scsa2usbp
->scsa2usb_log_handle
,
3551 "scsa2usb_do_tur: media not ready");
3556 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
3557 scsi_destroy_pkt(pkt
);
3558 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
3565 * scsa2usb_check_ufi_blacklist_attrs:
3566 * validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3567 * if blacklisted attrs match accept the request
3568 * attributes checked are:-
3569 * SCSA2USB_ATTRS_GET_CONF
3570 * SCSA2USB_ATTRS_GET_PERF
3571 * SCSA2USB_ATTRS_GET_START_STOP
3574 scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t
*scsa2usbp
, uchar_t opcode
,
3575 scsa2usb_cmd_t
*cmd
)
3577 int rval
= SCSA2USB_TRANSPORT
;
3579 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3584 rval
= SCSA2USB_JUST_ACCEPT
;
3586 case SCMD_MODE_SENSE
:
3587 case SCMD_MODE_SELECT
:
3589 cmd
->cmd_pkt
->pkt_resid
= cmd
->cmd_bp
->b_bcount
;
3591 scsa2usb_force_invalid_request(scsa2usbp
, cmd
);
3592 rval
= SCSA2USB_JUST_ACCEPT
;
3594 case SCMD_GET_CONFIGURATION
:
3595 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_GET_CONF
)) {
3596 rval
= SCSA2USB_JUST_ACCEPT
;
3599 case SCMD_GET_PERFORMANCE
:
3600 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_GET_PERF
)) {
3601 rval
= SCSA2USB_JUST_ACCEPT
;
3604 case SCMD_START_STOP
:
3606 * some CB/CBI devices don't have mechanics that spin the
3607 * media up and down. So, it doesn't make much sense
3608 * to issue this cmd to those devices.
3610 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_START_STOP
)) {
3611 rval
= SCSA2USB_JUST_ACCEPT
;
3614 case SCMD_READ_CAPACITY
:
3616 * Some devices don't support READ CAPACITY command
3617 * when media is not ready. Need to check media status
3618 * before issuing the cmd to such device.
3620 if (!(scsa2usbp
->scsa2usb_attrs
&
3621 SCSA2USB_ATTRS_NO_MEDIA_CHECK
)) {
3622 struct scsi_pkt
*pkt
= cmd
->cmd_pkt
;
3624 ASSERT(scsa2usbp
->scsa2usb_cur_pkt
== pkt
);
3625 scsa2usbp
->scsa2usb_cur_pkt
= NULL
;
3627 if (scsa2usb_do_tur(scsa2usbp
,
3628 &pkt
->pkt_address
) != 0) {
3629 /* media not ready, force cmd invalid */
3631 cmd
->cmd_pkt
->pkt_resid
=
3632 cmd
->cmd_bp
->b_bcount
;
3634 scsa2usb_force_invalid_request(scsa2usbp
, cmd
);
3635 rval
= SCSA2USB_JUST_ACCEPT
;
3638 scsa2usbp
->scsa2usb_cur_pkt
= pkt
;
3650 * scsa2usb_handle_ufi_subclass_cmd:
3652 * returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT
3655 scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t
*scsa2usbp
,
3656 scsa2usb_cmd_t
*cmd
, struct scsi_pkt
*pkt
)
3658 uchar_t opcode
= pkt
->pkt_cdbp
[0];
3660 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3661 "scsa2usb_handle_ufi_subclass_cmd: cmd = 0x%p pkt = 0x%p",
3662 (void *)cmd
, (void *)pkt
);
3664 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3666 bzero(&cmd
->cmd_cdb
, SCSI_CDB_SIZE
);
3667 cmd
->cmd_cdb
[SCSA2USB_OPCODE
] = opcode
; /* Set the opcode */
3668 cmd
->cmd_cdb
[SCSA2USB_LUN
] = pkt
->pkt_cdbp
[1];
3671 * decode and convert the packet if necessary
3672 * for most cmds, we can bcopy the cdb
3676 /* if parameter list is specified */
3677 if (pkt
->pkt_cdbp
[1] & 0x10) {
3678 cmd
->cmd_xfercount
=
3679 (pkt
->pkt_cdbp
[7] << 8) | pkt
->pkt_cdbp
[8];
3680 cmd
->cmd_dir
= USB_EP_DIR_OUT
;
3681 cmd
->cmd_actual_len
= CDB_GROUP5
;
3683 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3686 cmd
->cmd_dir
= USB_EP_DIR_IN
;
3687 cmd
->cmd_actual_len
= CDB_GROUP0
;
3688 cmd
->cmd_cdb
[SCSA2USB_LBA_0
] = pkt
->pkt_cdbp
[2];
3689 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = cmd
->cmd_xfercount
=
3690 min(SCSA2USB_MAX_INQ_LEN
,
3691 cmd
->cmd_bp
? cmd
->cmd_bp
->b_bcount
: 0);
3693 case SCMD_READ_CAPACITY
:
3694 cmd
->cmd_dir
= USB_EP_DIR_IN
;
3695 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3696 cmd
->cmd_xfercount
= sizeof (scsa2usb_read_cap_t
);
3698 case SCMD_REQUEST_SENSE
:
3699 cmd
->cmd_dir
= USB_EP_DIR_IN
;
3700 cmd
->cmd_xfercount
= pkt
->pkt_cdbp
[4];
3701 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = pkt
->pkt_cdbp
[4];
3702 cmd
->cmd_actual_len
= CDB_GROUP0
;
3706 * do not convert SCMD_MODE_SENSE/SELECT because the
3707 * mode header is different as well
3711 * see usb_bulkonly.c for comments on the next set of commands
3719 case SCMD_READ_LONG
:
3720 case SCMD_WRITE_LONG
:
3723 return (scsa2usb_rw_transport(scsa2usbp
, pkt
));
3725 case SCMD_TEST_UNIT_READY
:
3727 * Some CB/CBI devices may not support TUR.
3729 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3731 case SCMD_READ_FORMAT_CAP
:
3732 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3733 cmd
->cmd_dir
= USB_EP_DIR_IN
;
3734 cmd
->cmd_actual_len
= CDB_GROUP1
;
3735 cmd
->cmd_xfercount
= (pkt
->pkt_cdbp
[7] << 8) | pkt
->pkt_cdbp
[8];
3737 case SCMD_WRITE_VERIFY
:
3738 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3739 cmd
->cmd_dir
= USB_EP_DIR_OUT
;
3740 cmd
->cmd_actual_len
= CDB_GROUP1
;
3741 cmd
->cmd_xfercount
= (pkt
->pkt_cdbp
[7] << 8) | pkt
->pkt_cdbp
[8];
3743 case SCMD_START_STOP
:
3744 /* A larger timeout is needed for 'flaky' CD-RW devices */
3745 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_BIG_TIMEOUT
)) {
3746 cmd
->cmd_timeout
= max(cmd
->cmd_timeout
,
3747 20 * SCSA2USB_BULK_PIPE_TIMEOUT
);
3752 * all other commands don't need special mapping
3754 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3756 cmd
->cmd_dir
= (cmd
->cmd_bp
->b_flags
& B_READ
) ?
3757 CBW_DIR_IN
: CBW_DIR_OUT
;
3758 cmd
->cmd_xfercount
= cmd
->cmd_bp
->b_bcount
;
3762 } /* end of switch */
3764 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3765 "scsa2usb_handle_ufi_subclass_cmd: opcode = 0x%x count = 0x%lx",
3766 opcode
, cmd
->cmd_xfercount
);
3768 cmd
->cmd_total_xfercount
= cmd
->cmd_xfercount
;
3770 return (SCSA2USB_TRANSPORT
);
3775 * scsa2usb_rw_transport:
3776 * Handle splitting READ and WRITE requests to the
3777 * device to a size that the host controller allows.
3779 * returns TRAN_* values and not USB_SUCCESS/FAILURE
3781 * To support CD-R/CD-RW/DVD media, we need to support a
3782 * variety of block sizes for the different types of CD
3783 * data (audio, data, video, CD-XA, yellowbook, redbook etc.)
3785 * Some of the block sizes used are:- 512, 1k, 2k, 2056, 2336
3786 * 2340, 2352, 2368, 2448, 2646, 2647 etc.
3788 * NOTE: the driver could be entertaining a SCSI CDB that uses
3789 * any of the above listed block sizes at a given time, and a
3790 * totally different block size at any other given time for a
3793 * We need to compute block size every time and figure out
3794 * matching LBA and LEN accordingly.
3796 * Also UHCI has a limitation that it can only xfer 32k at a
3797 * given time. So, with "odd" sized blocks and a limitation of
3798 * how much we can xfer per shot, we need to compute xfer_count
3799 * as well each time.
3801 * The same computation is also done in the function
3802 * scsa2usb_setup_next_xfer(). To save computing block_size in
3803 * this function, I am saving block_size in "cmd" now.
3806 scsa2usb_rw_transport(scsa2usb_state_t
*scsa2usbp
, struct scsi_pkt
*pkt
)
3808 scsa2usb_cmd_t
*cmd
= PKT2CMD(pkt
);
3809 int lba
, dir
, opcode
;
3810 struct buf
*bp
= cmd
->cmd_bp
;
3811 size_t len
, xfer_count
;
3812 size_t blk_size
; /* calculate the block size to be used */
3815 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3816 "scsa2usb_rw_transport:");
3818 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3820 opcode
= pkt
->pkt_cdbp
[0];
3821 blk_size
= scsa2usbp
->scsa2usb_lbasize
[pkt
->pkt_address
.a_lun
];
3822 /* set to default */
3827 * Note that READ/WRITE(6) are not supported by the drive.
3828 * convert it into a 10 byte read/write.
3830 lba
= SCSA2USB_LBA_6BYTE(pkt
);
3831 len
= SCSA2USB_LEN_6BYTE(pkt
);
3832 opcode
= SCMD_READ_G1
; /* Overwrite it w/ byte 10 cmd val */
3833 dir
= USB_EP_DIR_IN
;
3836 lba
= SCSA2USB_LBA_6BYTE(pkt
);
3837 len
= SCSA2USB_LEN_6BYTE(pkt
);
3838 opcode
= SCMD_WRITE_G1
; /* Overwrite it w/ byte 10 cmd val */
3839 dir
= USB_EP_DIR_OUT
;
3842 case SCMD_READ_LONG
:
3843 lba
= SCSA2USB_LBA_10BYTE(pkt
);
3844 len
= SCSA2USB_LEN_10BYTE(pkt
);
3845 dir
= USB_EP_DIR_IN
;
3848 case SCMD_WRITE_LONG
:
3849 lba
= SCSA2USB_LBA_10BYTE(pkt
);
3850 len
= SCSA2USB_LEN_10BYTE(pkt
);
3851 dir
= USB_EP_DIR_OUT
;
3853 sz
= SCSA2USB_CDRW_BLKSZ(bp
? bp
->b_bcount
: 0, len
);
3854 if (SCSA2USB_VALID_CDRW_BLKSZ(sz
)) {
3855 blk_size
= sz
; /* change it accordingly */
3860 lba
= SCSA2USB_LBA_10BYTE(pkt
);
3861 len
= SCSA2USB_LEN_READ_CD(pkt
);
3862 dir
= USB_EP_DIR_IN
;
3864 /* Figure out the block size */
3865 blk_size
= scsa2usb_read_cd_blk_size(pkt
->pkt_cdbp
[1] >> 2);
3868 lba
= SCSA2USB_LBA_12BYTE(pkt
);
3869 len
= SCSA2USB_LEN_12BYTE(pkt
);
3870 dir
= USB_EP_DIR_IN
;
3873 lba
= SCSA2USB_LBA_12BYTE(pkt
);
3874 len
= SCSA2USB_LEN_12BYTE(pkt
);
3875 dir
= USB_EP_DIR_OUT
;
3879 cmd
->cmd_total_xfercount
= xfer_count
= len
* blk_size
;
3881 /* reduce xfer count if necessary */
3883 (xfer_count
> scsa2usbp
->scsa2usb_max_bulk_xfer_size
)) {
3885 * For CD-RW devices reduce the xfer count based
3886 * on the block size used by these devices. The
3887 * block size could change for READ_CD and WRITE
3890 * Also as UHCI allows a max xfer of 32k at a time;
3891 * compute the xfer_count based on the new block_size.
3893 * The len part of the cdb changes as a result of that.
3895 if (SCSA2USB_VALID_CDRW_BLKSZ(blk_size
)) {
3896 xfer_count
= ((scsa2usbp
->scsa2usb_max_bulk_xfer_size
/
3897 blk_size
) * blk_size
);
3898 len
= xfer_count
/blk_size
;
3899 xfer_count
= blk_size
* len
;
3901 xfer_count
= scsa2usbp
->scsa2usb_max_bulk_xfer_size
;
3902 len
= xfer_count
/blk_size
;
3906 cmd
->cmd_xfercount
= xfer_count
;
3907 cmd
->cmd_dir
= (uchar_t
)dir
;
3908 cmd
->cmd_blksize
= (int)blk_size
;
3911 * Having figured out the 'partial' xfer len based on the
3912 * block size; fill it in to the cmd->cmd_cdb
3914 cmd
->cmd_cdb
[SCSA2USB_OPCODE
] = (uchar_t
)opcode
;
3917 bcopy(pkt
->pkt_cdbp
, &cmd
->cmd_cdb
, cmd
->cmd_cdblen
);
3918 scsa2usb_fill_up_ReadCD_cdb_len(cmd
, len
, CDB_GROUP5
);
3922 scsa2usb_fill_up_12byte_cdb_len(cmd
, len
, CDB_GROUP5
);
3925 scsa2usb_fill_up_cdb_len(cmd
, len
);
3926 cmd
->cmd_actual_len
= CDB_GROUP1
;
3930 scsa2usb_fill_up_cdb_lba(cmd
, lba
);
3932 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3933 "bcount=0x%lx lba=0x%x len=0x%lx xfercount=0x%lx total=0x%lx",
3934 bp
? bp
->b_bcount
: 0, lba
, len
, cmd
->cmd_xfercount
,
3935 cmd
->cmd_total_xfercount
);
3937 /* Set the timeout value as per command request */
3938 if ((opcode
== SCMD_WRITE_G1
) && SCSA2USB_VALID_CDRW_BLKSZ(blk_size
)) {
3940 * We increase the time as CD-RW writes have two things
3941 * to do. After writing out the data to the media, a
3942 * TOC needs to be filled up at the beginning of the media
3943 * This is when the write gets "finalized".
3944 * Hence the actual write could take longer than the
3945 * value specified in cmd->cmd_timeout.
3947 cmd
->cmd_timeout
*= 4;
3949 USB_DPRINTF_L4(DPRINT_MASK_SCSA
,
3950 scsa2usbp
->scsa2usb_log_handle
,
3951 "new timeout value = 0x%x", cmd
->cmd_timeout
);
3954 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3955 "lba 0x%x len 0x%lx xfercount 0x%lx total 0x%lx",
3956 lba
, len
, cmd
->cmd_xfercount
, cmd
->cmd_total_xfercount
);
3958 return (SCSA2USB_TRANSPORT
);
3963 * scsa2usb_setup_next_xfer:
3964 * For READs and WRITEs we split up the transfer in terms of
3965 * HCD understood units. This function handles the split transfers.
3967 * See comments in the previous function scsa2usb_rw_transport
3969 * The lba computation was being done based on scsa2usb_max_bulk_xfer_size
3970 * earlier. With CD-RW devices, the xfer_count and the block_size may
3971 * no longer be a multiple of scsa2usb_max_bulk_xfer_size. So compute
3972 * xfer_count all over again. Adjust lba, based on the previous requests'
3973 * len. Find out the len and add it to cmd->cmd_lba to get the new lba
3976 scsa2usb_setup_next_xfer(scsa2usb_state_t
*scsa2usbp
, scsa2usb_cmd_t
*cmd
)
3978 int xfer_len
= min(scsa2usbp
->scsa2usb_max_bulk_xfer_size
,
3979 cmd
->cmd_total_xfercount
);
3983 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
3985 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
3986 "scsa2usb_setup_next_xfer: opcode = 0x%x lba = 0x%x "
3987 "total count = 0x%lx", cmd
->cmd_cdb
[SCSA2USB_OPCODE
],
3988 cmd
->cmd_lba
, cmd
->cmd_total_xfercount
);
3990 ASSERT(cmd
->cmd_total_xfercount
> 0);
3991 cmd
->cmd_xfercount
= xfer_len
;
3992 blk_size
= scsa2usbp
->scsa2usb_lbasize
[
3993 cmd
->cmd_pkt
->pkt_address
.a_lun
];
3996 * For CD-RW devices reduce the xfer count based on the
3997 * block_size used by these devices. See changes below
3998 * where xfer_count is being adjusted.
4000 * Also adjust len/lba based on the block_size and xfer_count.
4001 * NOTE: Always calculate lba first, as it based on previous
4004 switch (cmd
->cmd_cdb
[SCSA2USB_OPCODE
]) {
4006 /* calculate lba = current_lba + len_of_prev_cmd */
4007 cmd
->cmd_lba
+= (cmd
->cmd_cdb
[6] << 16) +
4008 (cmd
->cmd_cdb
[7] << 8) + cmd
->cmd_cdb
[8];
4009 cdb_len
= xfer_len
/cmd
->cmd_blksize
;
4010 cmd
->cmd_cdb
[SCSA2USB_READ_CD_LEN_2
] = (uchar_t
)cdb_len
;
4011 /* re-adjust xfer count */
4012 cmd
->cmd_xfercount
= cdb_len
* cmd
->cmd_blksize
;
4016 /* calculate lba = current_lba + len_of_prev_cmd */
4017 cmd
->cmd_lba
+= (cmd
->cmd_cdb
[6] << 24) +
4018 (cmd
->cmd_cdb
[7] << 16) + (cmd
->cmd_cdb
[8] << 8) +
4021 xfer_len
/= blk_size
;
4023 scsa2usb_fill_up_12byte_cdb_len(cmd
, xfer_len
, CDB_GROUP5
);
4026 case SCMD_WRITE_LONG
:
4027 /* calculate lba = current_lba + len_of_prev_cmd */
4028 cmd
->cmd_lba
+= (cmd
->cmd_cdb
[7] << 8) + cmd
->cmd_cdb
[8];
4029 if (SCSA2USB_VALID_CDRW_BLKSZ(cmd
->cmd_blksize
)) {
4030 blk_size
= cmd
->cmd_blksize
;
4032 cdb_len
= xfer_len
/blk_size
;
4033 scsa2usb_fill_up_cdb_len(cmd
, cdb_len
);
4034 /* re-adjust xfer count */
4035 cmd
->cmd_xfercount
= cdb_len
* blk_size
;
4039 xfer_len
/= blk_size
;
4041 scsa2usb_fill_up_cdb_len(cmd
, xfer_len
);
4042 cmd
->cmd_lba
+= scsa2usbp
->scsa2usb_max_bulk_xfer_size
/blk_size
;
4045 /* fill in the lba */
4046 scsa2usb_fill_up_cdb_lba(cmd
, cmd
->cmd_lba
);
4048 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4049 "scsa2usb_setup_next_xfer:\n\tlba = 0x%x xfer_len = 0x%x "
4050 "xfercount = 0x%lx total = 0x%lx", cmd
->cmd_lba
, xfer_len
,
4051 cmd
->cmd_xfercount
, cmd
->cmd_total_xfercount
);
4056 * take one request from the lun's waitQ and transport it
4059 scsa2usb_transport_request(scsa2usb_state_t
*scsa2usbp
, uint_t lun
)
4062 struct scsi_pkt
*pkt
;
4063 struct scsa2usb_cmd
*cmd
, *arqcmd
;
4065 if ((cmd
= (scsa2usb_cmd_t
*)
4066 usba_rm_first_pvt_from_list(
4067 &scsa2usbp
->scsa2usb_waitQ
[lun
])) == NULL
) {
4074 * if device has been disconnected, just complete it
4076 if (scsa2usbp
->scsa2usb_dev_state
== USB_DEV_DISCONNECTED
) {
4077 USB_DPRINTF_L2(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4078 "device not accessible");
4079 pkt
->pkt_reason
= CMD_DEV_GONE
;
4080 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp
);
4081 scsa2usb_pkt_completion(scsa2usbp
, pkt
);
4086 USB_DPRINTF_L4(DPRINT_MASK_SCSA
,
4087 scsa2usbp
->scsa2usb_log_handle
,
4088 "scsa2usb_transport_request: cmd=0x%p bp=0x%p addr=0x%p",
4089 (void *)cmd
, (void *)cmd
->cmd_bp
,
4090 (void *)(cmd
->cmd_bp
? cmd
->cmd_bp
->b_un
.b_addr
: NULL
));
4092 rval
= scsa2usb_cmd_transport(scsa2usbp
, cmd
);
4094 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
4095 scsa2usbp
->scsa2usb_log_handle
,
4096 "scsa2usb_transport_request: transport rval = %d",
4099 if (scsa2usbp
->scsa2usb_cur_pkt
== NULL
) {
4104 ASSERT(pkt
== scsa2usbp
->scsa2usb_cur_pkt
);
4106 if (ddi_in_panic()) {
4107 pkt
->pkt_reason
= CMD_CMPLT
;
4108 scsa2usb_pkt_completion(scsa2usbp
, pkt
);
4114 * start an auto-request sense iff
4115 * there was a check condition, we have enough
4116 * space in the status block, and we have not
4117 * faked an auto request sense
4119 if ((*(pkt
->pkt_scbp
) == STATUS_CHECK
) &&
4120 (cmd
->cmd_scblen
>= sizeof (struct scsi_arq_status
)) &&
4121 ((pkt
->pkt_state
& STATE_ARQ_DONE
) == 0) &&
4122 (scsa2usb_create_arq_pkt(scsa2usbp
,
4123 &pkt
->pkt_address
) == USB_SUCCESS
)) {
4124 arqcmd
= scsa2usbp
->scsa2usb_arq_cmd
;
4127 * copy the timeout from the
4129 * for lack of a better value
4131 arqcmd
->cmd_pkt
->pkt_time
= pkt
->pkt_time
;
4132 scsa2usb_prepare_pkt(scsa2usbp
,
4135 scsa2usbp
->scsa2usb_cur_pkt
= NULL
;
4136 if (scsa2usb_cmd_transport(
4137 scsa2usbp
, arqcmd
) == TRAN_ACCEPT
) {
4139 /* finish w/ this packet */
4140 scsa2usb_complete_arq_pkt(
4141 scsa2usbp
, arqcmd
->cmd_pkt
, cmd
,
4142 scsa2usbp
->scsa2usb_arq_bp
);
4145 * we have valid request sense
4146 * data so clear the pkt_reason
4148 pkt
->pkt_reason
= CMD_CMPLT
;
4150 scsa2usbp
->scsa2usb_cur_pkt
= pkt
;
4151 scsa2usb_delete_arq_pkt(scsa2usbp
);
4154 if ((rval
!= TRAN_ACCEPT
) &&
4155 (pkt
->pkt_reason
== CMD_CMPLT
)) {
4156 pkt
->pkt_reason
= CMD_TRAN_ERR
;
4159 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp
);
4160 scsa2usb_pkt_completion(scsa2usbp
, pkt
);
4162 ASSERT(scsa2usbp
->scsa2usb_cur_pkt
== NULL
);
4167 * scsa2usb_work_thread:
4168 * The taskq thread that kicks off the transport (BO and CB/CBI)
4171 scsa2usb_work_thread(void *arg
)
4173 scsa2usb_state_t
*scsa2usbp
= (scsa2usb_state_t
*)arg
;
4177 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4178 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4179 "scsa2usb_work_thread start: thread_id=0x%p",
4180 (void *)scsa2usbp
->scsa2usb_work_thread_id
);
4182 ASSERT(scsa2usbp
->scsa2usb_work_thread_id
== (kthread_t
*)1);
4183 scsa2usbp
->scsa2usb_work_thread_id
= curthread
;
4185 /* exclude ugen accesses */
4186 while (scsa2usbp
->scsa2usb_transport_busy
) {
4187 cv_wait(&scsa2usbp
->scsa2usb_transport_busy_cv
,
4188 &scsa2usbp
->scsa2usb_mutex
);
4190 ASSERT(scsa2usbp
->scsa2usb_ugen_open_count
== 0);
4191 scsa2usbp
->scsa2usb_transport_busy
++;
4192 scsa2usbp
->scsa2usb_busy_proc
= curproc
;
4194 scsa2usb_raise_power(scsa2usbp
);
4196 /* reopen the pipes if necessary */
4197 (void) scsa2usb_open_usb_pipes(scsa2usbp
);
4200 ASSERT(scsa2usbp
->scsa2usb_ugen_open_count
== 0);
4201 for (lun
= 0; lun
< scsa2usbp
->scsa2usb_n_luns
; lun
++) {
4202 scsa2usb_transport_request(scsa2usbp
, lun
);
4205 for (lun
= 0; lun
< SCSA2USB_MAX_LUNS
; lun
++) {
4206 count
+= usba_list_entry_count(
4207 &scsa2usbp
->scsa2usb_waitQ
[lun
]);
4216 scsa2usbp
->scsa2usb_work_thread_id
= 0;
4218 ASSERT(scsa2usbp
->scsa2usb_ugen_open_count
== 0);
4220 scsa2usbp
->scsa2usb_transport_busy
--;
4221 scsa2usbp
->scsa2usb_busy_proc
= NULL
;
4222 cv_signal(&scsa2usbp
->scsa2usb_transport_busy_cv
);
4224 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4225 "scsa2usb_work_thread: exit");
4227 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4229 scsa2usb_pm_idle_component(scsa2usbp
);
4234 * scsa2usb_flush_waitQ:
4235 * empties the entire waitQ with errors asap.
4237 * It is called from scsa2usb_scsi_reset and scsa2usb_panic_callb.
4238 * If the device is reset; we should empty the waitQ right away.
4239 * If the system has paniced; we should empty the waitQ right away.
4241 * CPR suspend will only succeed if device is idle. No need to call
4242 * this function for CPR suspend case.
4245 scsa2usb_flush_waitQ(scsa2usb_state_t
*scsa2usbp
, uint_t lun
,
4248 struct scsi_pkt
*pkt
;
4249 struct scsa2usb_cmd
*cmd
;
4250 usba_list_entry_t head
;
4252 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4254 usba_move_list(&scsa2usbp
->scsa2usb_waitQ
[lun
], &head
,
4255 scsa2usbp
->scsa2usb_dev_data
->dev_iblock_cookie
);
4256 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4258 while ((cmd
= (scsa2usb_cmd_t
*)usba_rm_first_pvt_from_list(&head
)) !=
4261 pkt
->pkt_reason
= error
; /* set error */
4263 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4264 scsa2usbp
->scsa2usb_pkt_state
= SCSA2USB_PKT_DO_COMP
;
4265 scsa2usb_pkt_completion(scsa2usbp
, pkt
);
4266 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4267 } /* end of while */
4272 * scsa2usb_do_inquiry is performed before INIT CHILD and we have
4273 * to fake a few things normally done by SCSA
4276 scsa2usb_do_inquiry(scsa2usb_state_t
*scsa2usbp
, uint_t target
, uint_t lun
)
4279 struct scsi_pkt
*pkt
;
4280 struct scsi_address ap
;
4281 int len
= SCSA2USB_MAX_INQ_LEN
;
4283 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4284 "scsa2usb_do_inquiry: %d bytes", len
);
4286 /* is it inquiry-challenged? */
4287 if (!(scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_INQUIRY
)) {
4288 scsa2usb_fake_inquiry(scsa2usbp
,
4289 &scsa2usbp
->scsa2usb_lun_inquiry
[lun
]);
4293 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4295 bzero(&ap
, sizeof (struct scsi_address
));
4296 ap
.a_hba_tran
= scsa2usbp
->scsa2usb_tran
;
4297 ap
.a_target
= (ushort_t
)target
;
4298 ap
.a_lun
= (uchar_t
)lun
;
4300 /* limit inquiry to 36 bytes */
4301 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4302 if ((bp
= scsi_alloc_consistent_buf(&ap
, NULL
,
4303 len
, B_READ
, SLEEP_FUNC
, NULL
)) == NULL
) {
4304 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4305 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
4306 scsa2usbp
->scsa2usb_log_handle
,
4307 "scsa2usb_do_inquiry: failed");
4312 pkt
= scsi_init_pkt(&ap
, NULL
, bp
, CDB_GROUP0
, 1,
4313 PKT_PRIV_LEN
, PKT_CONSISTENT
, SLEEP_FUNC
, NULL
);
4315 RQ_MAKECOM_G0(pkt
, FLAG_NOINTR
, (char)SCMD_INQUIRY
, 0, (char)len
);
4317 pkt
->pkt_comp
= NULL
;
4319 bzero(bp
->b_un
.b_addr
, len
);
4321 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4322 "scsa2usb_do_inquiry:INQUIRY");
4324 (void) scsi_transport(pkt
);
4326 if (pkt
->pkt_reason
) {
4327 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
4328 scsa2usbp
->scsa2usb_log_handle
,
4329 "INQUIRY failed, cannot determine device type, "
4330 "pkt_reason=0x%x", pkt
->pkt_reason
);
4332 /* not much hope for other cmds, reduce */
4333 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4334 scsa2usbp
->scsa2usb_attrs
&=
4335 ~SCSA2USB_ATTRS_REDUCED_CMD
;
4336 scsa2usb_fake_inquiry(scsa2usbp
,
4337 &scsa2usbp
->scsa2usb_lun_inquiry
[lun
]);
4338 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4341 scsi_destroy_pkt(pkt
);
4342 scsi_free_consistent_buf(bp
);
4344 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4349 * scsa2usb_fake_inquiry:
4350 * build an inquiry for a given device that doesnt like inquiry
4354 scsa2usb_fake_inquiry(scsa2usb_state_t
*scsa2usbp
, struct scsi_inquiry
*inqp
)
4356 usb_client_dev_data_t
*dev_data
= scsa2usbp
->scsa2usb_dev_data
;
4359 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4360 "scsa2usb_fake_inquiry:");
4362 bzero(inqp
, sizeof (struct scsi_inquiry
));
4363 for (len
= 0; len
< sizeof (inqp
->inq_vid
); len
++) {
4364 *(inqp
->inq_vid
+ len
) = ' ';
4367 for (len
= 0; len
< sizeof (inqp
->inq_pid
); len
++) {
4368 *(inqp
->inq_pid
+ len
) = ' ';
4371 inqp
->inq_dtype
= DTYPE_DIRECT
;
4374 inqp
->inq_rdf
= RDF_SCSI2
;
4375 inqp
->inq_len
= sizeof (struct scsi_inquiry
)-4;
4377 /* Fill in the Vendor id/Product id strings */
4378 if (dev_data
->dev_mfg
) {
4379 if ((len
= strlen(dev_data
->dev_mfg
)) >
4380 sizeof (inqp
->inq_vid
)) {
4381 len
= sizeof (inqp
->inq_vid
);
4383 bcopy(dev_data
->dev_mfg
, inqp
->inq_vid
, len
);
4386 if (dev_data
->dev_product
) {
4387 if ((len
= strlen(dev_data
->dev_product
)) >
4388 sizeof (inqp
->inq_pid
)) {
4389 len
= sizeof (inqp
->inq_pid
);
4391 bcopy(dev_data
->dev_product
, inqp
->inq_pid
, len
);
4394 /* Set the Revision to the Device */
4395 inqp
->inq_revision
[0] = 0x30 +
4396 ((dev_data
->dev_descr
->bcdDevice
>>12) & 0xF);
4397 inqp
->inq_revision
[1] = 0x30 +
4398 ((dev_data
->dev_descr
->bcdDevice
>>8) & 0xF);
4399 inqp
->inq_revision
[2] = 0x30 +
4400 ((dev_data
->dev_descr
->bcdDevice
>>4) & 0xF);
4401 inqp
->inq_revision
[3] = 0x30 +
4402 ((dev_data
->dev_descr
->bcdDevice
) & 0xF);
4407 * scsa2usb_create_arq_pkt:
4408 * Create and ARQ packet to get request sense data
4411 scsa2usb_create_arq_pkt(scsa2usb_state_t
*scsa2usbp
, struct scsi_address
*ap
)
4414 scsa2usb_cmd_t
*arq_cmd
;
4416 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4417 "scsa2usb_create_arq_pkt: scsa2usbp: %p, ap: %p",
4418 (void *)scsa2usbp
, (void *)ap
);
4420 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4422 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4423 if ((bp
= scsi_alloc_consistent_buf(ap
, NULL
,
4424 SENSE_LENGTH
, B_READ
, SLEEP_FUNC
, NULL
)) == NULL
) {
4425 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4427 return (USB_FAILURE
);
4430 arq_cmd
= PKT2CMD(scsi_init_pkt(ap
, NULL
, bp
, CDB_GROUP0
, 1,
4431 PKT_PRIV_LEN
, PKT_CONSISTENT
, SLEEP_FUNC
, NULL
));
4432 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4434 RQ_MAKECOM_G0(arq_cmd
->cmd_pkt
,
4435 FLAG_SENSING
| FLAG_HEAD
| FLAG_NODISCON
,
4436 (char)SCMD_REQUEST_SENSE
, 0, (char)SENSE_LENGTH
);
4438 arq_cmd
->cmd_pkt
->pkt_ha_private
= arq_cmd
;
4439 scsa2usbp
->scsa2usb_arq_cmd
= arq_cmd
;
4440 scsa2usbp
->scsa2usb_arq_bp
= bp
;
4441 arq_cmd
->cmd_pkt
->pkt_comp
= NULL
;
4442 bzero(bp
->b_un
.b_addr
, SENSE_LENGTH
);
4444 return (USB_SUCCESS
);
4449 * scsa2usb_delete_arq_pkt:
4450 * Destroy the ARQ packet
4453 scsa2usb_delete_arq_pkt(scsa2usb_state_t
*scsa2usbp
)
4455 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4456 "scsa2usb_delete_arq_pkt: cmd: 0x%p",
4457 (void *)scsa2usbp
->scsa2usb_arq_cmd
);
4459 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4461 if (scsa2usbp
->scsa2usb_arq_cmd
!= NULL
) {
4462 scsi_destroy_pkt(scsa2usbp
->scsa2usb_arq_cmd
->cmd_pkt
);
4463 scsi_free_consistent_buf(scsa2usbp
->scsa2usb_arq_bp
);
4465 scsa2usbp
->scsa2usb_arq_cmd
= NULL
;
4466 scsa2usbp
->scsa2usb_arq_bp
= NULL
;
4471 * scsa2usb_complete_arq_pkt:
4472 * finish processing the arq packet
4475 scsa2usb_complete_arq_pkt(scsa2usb_state_t
*scsa2usbp
,
4476 struct scsi_pkt
*pkt
, scsa2usb_cmd_t
*ssp
, struct buf
*bp
)
4478 scsa2usb_cmd_t
*sp
= pkt
->pkt_ha_private
;
4479 struct scsi_arq_status
*arqp
;
4481 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4483 arqp
= (struct scsi_arq_status
*)(ssp
->cmd_pkt
->pkt_scbp
);
4484 arqp
->sts_rqpkt_status
= *((struct scsi_status
*)
4485 (sp
->cmd_pkt
->pkt_scbp
));
4486 arqp
->sts_rqpkt_reason
= CMD_CMPLT
;
4487 arqp
->sts_rqpkt_state
|= STATE_XFERRED_DATA
;
4488 arqp
->sts_rqpkt_statistics
= arqp
->sts_rqpkt_resid
= 0;
4490 /* is this meaningful sense data */
4491 if (*(bp
->b_un
.b_addr
) != 0) {
4492 bcopy(bp
->b_un
.b_addr
, &arqp
->sts_sensedata
, SENSE_LENGTH
);
4493 ssp
->cmd_pkt
->pkt_state
|= STATE_ARQ_DONE
;
4496 /* we will not sense start cmd until we receive a NOT READY */
4497 if (arqp
->sts_sensedata
.es_key
== KEY_NOT_READY
) {
4498 scsa2usbp
->scsa2usb_rcvd_not_ready
= B_TRUE
;
4504 * Miscellaneous functions for any command/transport
4507 * scsa2usb_open_usb_pipes:
4508 * set up a pipe policy
4509 * open usb bulk pipes (BO and CB/CBI)
4510 * open usb interrupt pipe (CBI)
4513 scsa2usb_open_usb_pipes(scsa2usb_state_t
*scsa2usbp
)
4516 usb_pipe_policy_t policy
; /* bulk pipe policy */
4520 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4522 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4523 "scsa2usb_open_usb_pipes: dip = 0x%p flag = 0x%x",
4524 (void *)scsa2usbp
->scsa2usb_dip
, scsa2usbp
->scsa2usb_flags
);
4526 if (!(scsa2usbp
->scsa2usb_flags
& SCSA2USB_FLAGS_PIPES_OPENED
)) {
4529 * one pipe policy for all bulk pipes
4531 bzero(&policy
, sizeof (usb_pipe_policy_t
));
4532 /* at least 2, for the normal and exceptional callbacks */
4533 policy
.pp_max_async_reqs
= 1;
4535 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4536 "scsa2usb_open_usb_pipes: opening bulk pipes");
4538 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4540 /* Open the USB bulk-in pipe */
4541 if ((rval
= usb_pipe_xopen(scsa2usbp
->scsa2usb_dip
,
4542 &scsa2usbp
->scsa2usb_bulkin_xept
, &policy
, USB_FLAGS_SLEEP
,
4543 &scsa2usbp
->scsa2usb_bulkin_pipe
)) != USB_SUCCESS
) {
4544 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4545 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
4546 scsa2usbp
->scsa2usb_log_handle
,
4547 "scsa2usb_open_usb_pipes: bulk/in pipe open "
4548 " failed rval = %d", rval
);
4550 return (USB_FAILURE
);
4553 /* Open the bulk-out pipe using the same policy */
4554 if ((rval
= usb_pipe_xopen(scsa2usbp
->scsa2usb_dip
,
4555 &scsa2usbp
->scsa2usb_bulkout_xept
, &policy
, USB_FLAGS_SLEEP
,
4556 &scsa2usbp
->scsa2usb_bulkout_pipe
)) != USB_SUCCESS
) {
4557 usb_pipe_close(scsa2usbp
->scsa2usb_dip
,
4558 scsa2usbp
->scsa2usb_bulkin_pipe
,
4559 USB_FLAGS_SLEEP
, NULL
, NULL
);
4561 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4562 scsa2usbp
->scsa2usb_bulkin_pipe
= NULL
;
4564 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
4565 scsa2usbp
->scsa2usb_log_handle
,
4566 "scsa2usb_open_usb_pipes: bulk/out pipe open"
4567 " failed rval = %d", rval
);
4569 return (USB_FAILURE
);
4572 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4574 /* open interrupt pipe for CBI protocol */
4575 if (SCSA2USB_IS_CBI(scsa2usbp
)) {
4576 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4578 if ((rval
= usb_pipe_xopen(scsa2usbp
->scsa2usb_dip
,
4579 &scsa2usbp
->scsa2usb_intr_xept
, &policy
,
4580 USB_FLAGS_SLEEP
, &scsa2usbp
->scsa2usb_intr_pipe
)) !=
4582 usb_pipe_close(scsa2usbp
->scsa2usb_dip
,
4583 scsa2usbp
->scsa2usb_bulkin_pipe
,
4584 USB_FLAGS_SLEEP
, NULL
, NULL
);
4586 usb_pipe_close(scsa2usbp
->scsa2usb_dip
,
4587 scsa2usbp
->scsa2usb_bulkout_pipe
,
4588 USB_FLAGS_SLEEP
, NULL
, NULL
);
4590 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4591 scsa2usbp
->scsa2usb_bulkin_pipe
= NULL
;
4592 scsa2usbp
->scsa2usb_bulkout_pipe
= NULL
;
4594 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
4595 scsa2usbp
->scsa2usb_log_handle
,
4596 "scsa2usb_open_usb_pipes: intr pipe open"
4597 " failed rval = %d", rval
);
4599 return (USB_FAILURE
);
4602 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4605 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4607 /* get the max transfer size of the bulk pipe */
4608 if (usb_pipe_get_max_bulk_transfer_size(scsa2usbp
->scsa2usb_dip
,
4609 &sz
) == USB_SUCCESS
) {
4610 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4611 scsa2usbp
->scsa2usb_max_bulk_xfer_size
= sz
;
4613 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4614 scsa2usbp
->scsa2usb_max_bulk_xfer_size
= DEV_BSIZE
;
4617 /* limit the xfer size */
4618 scsa2usbp
->scsa2usb_max_bulk_xfer_size
= min(
4619 scsa2usbp
->scsa2usb_max_bulk_xfer_size
,
4620 scsa2usb_max_bulk_xfer_size
);
4622 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4623 "scsa2usb_open_usb_pipes: max bulk transfer size = %lx",
4624 scsa2usbp
->scsa2usb_max_bulk_xfer_size
);
4626 /* Set the pipes opened flag */
4627 scsa2usbp
->scsa2usb_flags
|= SCSA2USB_FLAGS_PIPES_OPENED
;
4629 scsa2usbp
->scsa2usb_pipe_state
= SCSA2USB_PIPE_NORMAL
;
4631 /* Set the state to NONE */
4632 scsa2usbp
->scsa2usb_pkt_state
= SCSA2USB_PKT_NONE
;
4635 return (USB_SUCCESS
);
4640 * scsa2usb_close_usb_pipes:
4641 * close all pipes synchronously
4644 scsa2usb_close_usb_pipes(scsa2usb_state_t
*scsa2usbp
)
4646 usb_flags_t flags
= USB_FLAGS_SLEEP
;
4648 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4649 "scsa2usb_close_usb_pipes: scsa2usb_state = 0x%p",
4653 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4655 if ((scsa2usbp
->scsa2usb_flags
& SCSA2USB_FLAGS_PIPES_OPENED
) == 0) {
4660 scsa2usbp
->scsa2usb_pipe_state
= SCSA2USB_PIPE_CLOSING
;
4661 /* to avoid races, reset the flag first */
4662 scsa2usbp
->scsa2usb_flags
&= ~SCSA2USB_FLAGS_PIPES_OPENED
;
4664 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4666 usb_pipe_close(scsa2usbp
->scsa2usb_dip
,
4667 scsa2usbp
->scsa2usb_bulkout_pipe
, flags
, NULL
, NULL
);
4669 usb_pipe_close(scsa2usbp
->scsa2usb_dip
,
4670 scsa2usbp
->scsa2usb_bulkin_pipe
, flags
, NULL
, NULL
);
4672 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4673 if (SCSA2USB_IS_CBI(scsa2usbp
)) {
4674 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4675 usb_pipe_close(scsa2usbp
->scsa2usb_dip
,
4676 scsa2usbp
->scsa2usb_intr_pipe
, flags
, NULL
, NULL
);
4677 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4679 scsa2usbp
->scsa2usb_bulkout_pipe
= NULL
;
4680 scsa2usbp
->scsa2usb_bulkin_pipe
= NULL
;
4681 scsa2usbp
->scsa2usb_intr_pipe
= NULL
;
4683 scsa2usbp
->scsa2usb_pipe_state
= SCSA2USB_PIPE_NORMAL
;
4688 * scsa2usb_fill_up_cdb_lba:
4689 * fill up command CDBs' LBA part
4692 scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t
*cmd
, int lba
)
4694 /* zero cdb1, lba bits so they won't get copied in the new cdb */
4695 cmd
->cmd_cdb
[SCSA2USB_LUN
] &= 0xE0;
4696 cmd
->cmd_cdb
[SCSA2USB_LBA_0
] = lba
>> 24;
4697 cmd
->cmd_cdb
[SCSA2USB_LBA_1
] = lba
>> 16;
4698 cmd
->cmd_cdb
[SCSA2USB_LBA_2
] = lba
>> 8;
4699 cmd
->cmd_cdb
[SCSA2USB_LBA_3
] = (uchar_t
)lba
;
4705 * scsa2usb_fill_up_ReadCD_cdb_len:
4706 * fill up READ_CD command CDBs' len part
4709 scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t
*cmd
, int len
, int actual_len
)
4711 cmd
->cmd_cdb
[SCSA2USB_READ_CD_LEN_0
] = len
>> 16;
4712 cmd
->cmd_cdb
[SCSA2USB_READ_CD_LEN_1
] = len
>> 8;
4713 cmd
->cmd_cdb
[SCSA2USB_READ_CD_LEN_2
] = (uchar_t
)len
;
4714 cmd
->cmd_actual_len
= (uchar_t
)actual_len
;
4719 * scsa2usb_fill_up_12byte_cdb_len:
4720 * fill up generic 12-byte command CDBs' len part
4723 scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t
*cmd
, int len
, int actual_len
)
4725 cmd
->cmd_cdb
[6] = len
>> 24;
4726 cmd
->cmd_cdb
[7] = len
>> 16;
4727 cmd
->cmd_cdb
[8] = len
>> 8;
4728 cmd
->cmd_cdb
[9] = (uchar_t
)len
;
4729 cmd
->cmd_actual_len
= (uchar_t
)actual_len
;
4734 * scsa2usb_fill_up_cdb_len:
4735 * fill up generic 10-byte command CDBs' len part
4738 scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t
*cmd
, int len
)
4740 cmd
->cmd_cdb
[SCSA2USB_LEN_0
] = len
>> 8;
4741 cmd
->cmd_cdb
[SCSA2USB_LEN_1
] = (uchar_t
)len
;
4746 * scsa2usb_read_cd_blk_size:
4747 * For SCMD_READ_CD opcode (0xbe). Figure out the
4748 * block size based on expected sector type field
4749 * definition. See MMC SCSI Specs section 6.1.15
4751 * Based on the value of the "expected_sector_type"
4752 * field, the block size could be different.
4755 scsa2usb_read_cd_blk_size(uchar_t expected_sector_type
)
4759 switch (expected_sector_type
) {
4760 case READ_CD_EST_CDDA
:
4761 blk_size
= CDROM_BLK_2352
;
4763 case READ_CD_EST_MODE2
:
4764 blk_size
= CDROM_BLK_2336
;
4766 case READ_CD_EST_MODE2FORM2
:
4767 blk_size
= CDROM_BLK_2324
;
4769 case READ_CD_EST_MODE2FORM1
:
4770 case READ_CD_EST_ALLTYPE
:
4771 case READ_CD_EST_MODE1
:
4773 blk_size
= CDROM_BLK_2048
;
4776 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, NULL
, "scsa2usb_read_cd_blk_size: "
4777 "est = 0x%x blk_size = %d", expected_sector_type
, blk_size
);
4784 * scsa2usb_bp_to_mblk:
4785 * Convert a bp to mblk_t. USBA framework understands mblk_t.
4788 scsa2usb_bp_to_mblk(scsa2usb_state_t
*scsa2usbp
)
4793 scsa2usb_cmd_t
*cmd
= PKT2CMD(scsa2usbp
->scsa2usb_cur_pkt
);
4795 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4796 "scsa2usb_bp_to_mblk: ");
4798 ASSERT(scsa2usbp
->scsa2usb_cur_pkt
);
4799 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4803 if (bp
&& (bp
->b_bcount
> 0)) {
4804 size
= ((bp
->b_bcount
> cmd
->cmd_xfercount
) ?
4805 cmd
->cmd_xfercount
: bp
->b_bcount
);
4811 mp
= esballoc_wait((uchar_t
*)bp
->b_un
.b_addr
+ cmd
->cmd_offset
,
4812 size
, BPRI_LO
, &frnop
);
4814 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4815 "scsa2usb_bp_to_mblk: "
4816 "mp=0x%p bp=0x%p pkt=0x%p off=0x%lx sz=%lu add=0x%p",
4817 (void *)mp
, (void *)bp
, (void *)scsa2usbp
->scsa2usb_cur_pkt
,
4818 cmd
->cmd_offset
, bp
->b_bcount
- cmd
->cmd_offset
,
4819 (void *)bp
->b_un
.b_addr
);
4822 cmd
->cmd_offset
+= size
;
4829 * scsa2usb_handle_data_start:
4830 * Initiate the data xfer. It could be IN/OUT direction.
4833 * Send out the bulk-xfer request
4834 * if rval implies STALL
4835 * clear endpoint stall and reset bulk-in pipe
4836 * handle data read in so far; set cmd->cmd_done
4837 * also adjust data xfer length accordingly
4839 * report back to transport
4840 * typically transport will call reset recovery
4845 * Send out the bulk-xfer request
4846 * if rval implies STALL
4847 * clear endpoint stall and reset bulk-in pipe
4848 * adjust data xfer length
4850 * report back to transport
4851 * typically transport will call reset recovery
4855 * NOTE: We call this function only if there is xfercount.
4858 scsa2usb_handle_data_start(scsa2usb_state_t
*scsa2usbp
,
4859 scsa2usb_cmd_t
*cmd
, usb_bulk_req_t
*req
)
4861 int rval
= USB_SUCCESS
;
4863 usb_flags_t flags
= USB_FLAGS_SLEEP
;
4864 #ifdef SCSA2USB_BULK_ONLY_TEST
4865 usb_req_attrs_t attrs
= 0;
4867 usb_req_attrs_t attrs
= USB_ATTRS_SHORT_XFER_OK
;
4870 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
4871 "scsa2usb_handle_data_start: BEGIN cmd = %p, req = %p",
4872 (void *)cmd
, (void *)req
);
4874 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
4876 switch (cmd
->cmd_dir
) {
4878 #ifdef SCSA2USB_BULK_ONLY_TEST
4880 * This case occurs when the host expects to receive
4881 * more data than the device actually transfers. Hi > Di
4883 if (scsa2usb_test_case_5
) {
4884 usb_bulk_req_t
*req2
;
4886 req
->bulk_len
= cmd
->cmd_xfercount
- 1;
4887 req
->bulk_attributes
= 0;
4888 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4889 SCSA2USB_FREE_MSG(req
->bulk_data
);
4890 req
->bulk_data
= allocb_wait(req
->bulk_len
, BPRI_LO
,
4893 ASSERT(req
->bulk_timeout
);
4894 rval
= usb_pipe_bulk_xfer(
4895 scsa2usbp
->scsa2usb_bulkin_pipe
, req
, flags
);
4896 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4897 USB_DPRINTF_L1(DPRINT_MASK_SCSA
,
4898 scsa2usbp
->scsa2usb_log_handle
, "rval = %x", rval
);
4900 req2
= scsa2usb_init_bulk_req(scsa2usbp
,
4901 cmd
->cmd_xfercount
+ 2,
4902 cmd
->cmd_timeout
, 0, flags
);
4903 req2
->bulk_len
= cmd
->cmd_xfercount
+ 2;
4904 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4906 ASSERT(req2
->bulk_timeout
);
4907 rval
= usb_pipe_bulk_xfer(
4908 scsa2usbp
->scsa2usb_bulkin_pipe
, req2
, flags
);
4909 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4911 USB_DPRINTF_L1(DPRINT_MASK_SCSA
,
4912 scsa2usbp
->scsa2usb_log_handle
,
4913 "TEST 5: Hi > Di: rval = 0x%x", rval
);
4914 scsa2usb_test_case_5
= 0;
4915 usb_free_bulk_req(req2
);
4921 * This happens when the host expects to send data to the
4922 * device while the device intends to send data to the host.
4924 if (scsa2usb_test_case_8
&& (cmd
->cmd_cdb
[0] == SCMD_READ_G1
)) {
4925 USB_DPRINTF_L1(DPRINT_MASK_SCSA
,
4926 scsa2usbp
->scsa2usb_log_handle
,
4927 "TEST 8: Hi <> Do: Step 2");
4928 scsa2usb_test_mblk(scsa2usbp
, B_TRUE
);
4929 scsa2usb_test_case_8
= 0;
4933 #endif /* SCSA2USB_BULK_ONLY_TEST */
4935 ept_addr
= scsa2usbp
->scsa2usb_bulkin_ept
.bEndpointAddress
;
4936 req
->bulk_len
= cmd
->cmd_xfercount
;
4937 req
->bulk_attributes
= attrs
;
4938 SCSA2USB_FREE_MSG(req
->bulk_data
);
4939 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4941 req
->bulk_data
= esballoc_wait(
4942 (uchar_t
*)cmd
->cmd_bp
->b_un
.b_addr
+
4944 req
->bulk_len
, BPRI_LO
, &frnop
);
4946 ASSERT(req
->bulk_timeout
);
4947 rval
= usb_pipe_bulk_xfer(scsa2usbp
->scsa2usb_bulkin_pipe
,
4949 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4953 case USB_EP_DIR_OUT
:
4954 #ifdef SCSA2USB_BULK_ONLY_TEST
4956 * This happens when the host expects to receive data
4957 * from the device while the device intends to receive
4958 * data from the host.
4960 if (scsa2usb_test_case_10
&&
4961 (cmd
->cmd_cdb
[0] == SCMD_WRITE_G1
)) {
4962 req
->bulk_len
= CSW_LEN
;
4963 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
4965 ASSERT(req
->bulk_timeout
);
4966 rval
= usb_pipe_bulk_xfer(
4967 scsa2usbp
->scsa2usb_bulkin_pipe
, req
, flags
);
4968 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
4970 USB_DPRINTF_L1(DPRINT_MASK_SCSA
,
4971 scsa2usbp
->scsa2usb_log_handle
,
4972 "TEST 10: Ho <> Di: done rval = 0x%x", rval
);
4973 scsa2usb_test_case_10
= 0;
4977 #endif /* SCSA2USB_BULK_ONLY_TEST */
4979 req
->bulk_data
= scsa2usb_bp_to_mblk(scsa2usbp
);
4980 if (req
->bulk_data
== NULL
) {
4982 return (USB_FAILURE
);
4985 #ifdef SCSA2USB_BULK_ONLY_TEST
4986 if (scsa2usb_test_case_11
) {
4988 * Host expects to send data to the device and
4989 * device doesn't expect to receive any data
4991 USB_DPRINTF_L1(DPRINT_MASK_SCSA
,
4992 scsa2usbp
->scsa2usb_log_handle
, "TEST 11: Ho > Do");
4994 scsa2usb_test_mblk(scsa2usbp
, B_FALSE
);
4995 scsa2usb_test_case_11
= 0;
4997 #endif /* SCSA2USB_BULK_ONLY_TEST */
4999 ept_addr
= scsa2usbp
->scsa2usb_bulkout_ept
.bEndpointAddress
;
5000 req
->bulk_len
= MBLKL(req
->bulk_data
);
5001 req
->bulk_timeout
= scsa2usb_bulk_timeout(cmd
->cmd_timeout
);
5002 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5004 ASSERT(req
->bulk_timeout
);
5005 rval
= usb_pipe_bulk_xfer(scsa2usbp
->scsa2usb_bulkout_pipe
,
5007 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5011 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
5012 scsa2usbp
->scsa2usb_log_handle
,
5013 "scsa2usb_handle_data_start: rval=%d cr=%d", rval
,
5014 req
->bulk_completion_reason
);
5016 if (rval
!= USB_SUCCESS
) {
5017 /* Handle Errors now */
5018 if (req
->bulk_completion_reason
== USB_CR_STALL
) {
5019 if (cmd
->cmd_dir
== USB_EP_DIR_IN
) {
5020 (void) scsa2usb_clear_ept_stall(
5021 scsa2usbp
, ept_addr
,
5022 scsa2usbp
-> scsa2usb_bulkin_pipe
,
5025 (void) scsa2usb_clear_ept_stall(
5026 scsa2usbp
, ept_addr
,
5027 scsa2usbp
-> scsa2usb_bulkout_pipe
,
5032 /* no more data to transfer after this */
5036 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5037 "scsa2usb_handle_data_start: END %s data rval = %d",
5038 (cmd
->cmd_dir
== USB_EP_DIR_IN
) ? "bulk-in" : "bulk-out", rval
);
5045 * scsa2usb_handle_data_done:
5046 * This function handles the completion of the data xfer.
5047 * It also massages the inquiry data. This function may
5048 * also be called after a stall.
5051 scsa2usb_handle_data_done(scsa2usb_state_t
*scsa2usbp
,
5052 scsa2usb_cmd_t
*cmd
, usb_bulk_req_t
*req
)
5054 struct buf
*bp
= cmd
->cmd_bp
;
5055 struct scsi_pkt
*pkt
= scsa2usbp
->scsa2usb_cur_pkt
;
5056 mblk_t
*data
= req
->bulk_data
;
5057 int len
= data
? MBLKL(data
) : 0;
5060 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5062 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5063 "scsa2usb_handle_data_done:\n\tcmd = 0x%p data = 0x%p len = 0x%x",
5064 (void *)cmd
, (void *)data
, len
);
5066 cmd
->cmd_resid_xfercount
= cmd
->cmd_xfercount
- len
;
5071 scsa2usb_read_cap_t
*cap
;
5072 struct scsi_inquiry
*inq
;
5074 switch (cmd
->cmd_cdb
[SCSA2USB_OPCODE
]) {
5077 * cache a copy of the inquiry data for our own use
5078 * but ensure that we have at least up to
5079 * inq_revision, inq_serial is not required.
5080 * ignore inquiry data returned for inquiry commands
5081 * with SCSI-3 EVPD, CmdDt bits set.
5083 if (((cmd
->cmd_cdb
[SCSA2USB_LUN
] & 0x1f) == 0) &&
5084 (len
>= SCSA2USB_MAX_INQ_LEN
)) {
5085 inq
= (struct scsi_inquiry
*)data
->b_rptr
;
5086 dtype
= inq
->inq_dtype
& DTYPE_MASK
;
5088 * scsi framework sends zero byte write(10) cmd
5089 * to (Simplified) direct-access devices with
5090 * inquiry version > 2 for reservation changes.
5091 * But some USB devices don't support zero byte
5092 * write(10) even though they have inquiry
5093 * version > 2. Considering scsa2usb driver
5094 * doesn't support reservation and all the
5095 * reservation cmds are being faked, we fake
5096 * the inquiry version to 0 to make scsi
5097 * framework send test unit ready cmd which is
5098 * supported by all the usb devices.
5100 if (((dtype
== DTYPE_DIRECT
) ||
5101 (dtype
== DTYPE_RBC
)) &&
5102 (inq
->inq_ansi
> 2)) {
5106 bzero(&scsa2usbp
->scsa2usb_lun_inquiry
5107 [pkt
->pkt_address
.a_lun
],
5108 sizeof (struct scsi_inquiry
));
5110 &scsa2usbp
->scsa2usb_lun_inquiry
5111 [pkt
->pkt_address
.a_lun
], len
);
5114 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
5115 scsa2usbp
->scsa2usb_log_handle
,
5116 "scsi inquiry type = 0x%x",
5117 scsa2usbp
->scsa2usb_lun_inquiry
5118 [pkt
->pkt_address
.a_lun
].inq_dtype
);
5123 case SCMD_READ_CAPACITY
:
5124 cap
= (scsa2usb_read_cap_t
*)data
->b_rptr
;
5126 /* Figure out the logical block size */
5127 if ((len
>= sizeof (struct scsa2usb_read_cap
)) &&
5128 (req
->bulk_completion_reason
== USB_CR_OK
)) {
5130 scsa2usb_lbasize
[pkt
->pkt_address
.a_lun
] =
5132 cap
->scsa2usb_read_cap_blen3
,
5133 cap
->scsa2usb_read_cap_blen2
,
5134 cap
->scsa2usb_read_cap_blen1
,
5135 cap
->scsa2usb_read_cap_blen0
);
5137 max_lba
= SCSA2USB_MK_32BIT(
5138 cap
->scsa2usb_read_cap_lba3
,
5139 cap
->scsa2usb_read_cap_lba2
,
5140 cap
->scsa2usb_read_cap_lba1
,
5141 cap
->scsa2usb_read_cap_lba0
);
5144 * Some devices return total logical block
5145 * number instead of highest logical block
5146 * address. Adjust the value by minus 1.
5148 if (max_lba
> 0 && (scsa2usbp
->scsa2usb_attrs
&
5149 SCSA2USB_ATTRS_NO_CAP_ADJUST
) == 0) {
5151 cap
->scsa2usb_read_cap_lba0
=
5152 (uchar_t
)(max_lba
& 0xFF);
5153 cap
->scsa2usb_read_cap_lba1
=
5154 (uchar_t
)(max_lba
>> 8 & 0xFF);
5155 cap
->scsa2usb_read_cap_lba2
=
5156 (uchar_t
)(max_lba
>> 16 & 0xFF);
5157 cap
->scsa2usb_read_cap_lba3
=
5158 (uchar_t
)(max_lba
>> 24 & 0xFF);
5161 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
5162 scsa2usbp
->scsa2usb_log_handle
,
5163 "bytes in each logical block=0x%lx,"
5164 "number of total logical blocks=0x%x",
5166 scsa2usb_lbasize
[pkt
->pkt_address
.a_lun
],
5172 case SCMD_REQUEST_SENSE
:
5174 USB_DPRINTF_L2(DPRINT_MASK_SCSA
,
5175 scsa2usbp
->scsa2usb_log_handle
,
5177 "%x %x %x %x %x %x %x %x %x %x\n\t"
5178 "%x %x %x %x %x %x %x %x %x %x",
5180 p
[0], p
[1], p
[2], p
[3], p
[4],
5181 p
[5], p
[6], p
[7], p
[8], p
[9],
5182 p
[10], p
[11], p
[12], p
[13], p
[14],
5183 p
[15], p
[16], p
[17], p
[18], p
[19]);
5185 scsa2usbp
->scsa2usb_last_cmd
.status
= p
[2];
5191 if (bp
&& len
&& (cmd
->cmd_dir
== USB_EP_DIR_IN
)) {
5193 * we don't have to copy the data, the
5194 * data pointers for the mblk_t for
5195 * the bulk-in xfer points to the
5196 * struct buf * data.
5198 cmd
->cmd_offset
+= len
;
5201 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
5202 scsa2usbp
->scsa2usb_log_handle
,
5203 "len = 0x%x total = 0x%lx offset = 0x%lx",
5204 len
, cmd
->cmd_total_xfercount
, cmd
->cmd_offset
);
5207 * update total_xfercount now but it may be
5208 * adjusted after receiving the residue
5210 cmd
->cmd_total_xfercount
-= len
;
5212 if ((req
->bulk_completion_reason
!= USB_CR_OK
) ||
5213 (cmd
->cmd_resid_xfercount
!= 0) ||
5214 (cmd
->cmd_total_xfercount
== 0)) {
5215 /* set pkt_resid to total to be sure */
5216 pkt
->pkt_resid
= cmd
->cmd_total_xfercount
;
5223 if (cmd
->cmd_dir
== USB_EP_DIR_OUT
) {
5224 if (cmd
->cmd_total_xfercount
== 0) {
5233 * scsa2usb_init_bulk_req:
5234 * Allocate (synchronously) and fill in a bulk-request
5237 scsa2usb_init_bulk_req(scsa2usb_state_t
*scsa2usbp
, size_t length
,
5238 uint_t timeout
, usb_req_attrs_t attrs
, usb_flags_t flags
)
5240 usb_bulk_req_t
*req
;
5242 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5244 req
= usb_alloc_bulk_req(scsa2usbp
->scsa2usb_dip
, length
,
5245 flags
| USB_FLAGS_SLEEP
);
5247 req
->bulk_len
= (uint_t
)length
; /* xfer length */
5248 req
->bulk_timeout
= scsa2usb_bulk_timeout(timeout
); /* xfer timeout */
5249 req
->bulk_attributes
= attrs
; /* xfer attrs */
5250 req
->bulk_client_private
= (usb_opaque_t
)scsa2usbp
; /* statep */
5257 * scsa2usb_bulk_timeout:
5258 * ensure that bulk requests do not have infinite timeout values
5261 scsa2usb_bulk_timeout(int timeout
)
5263 return ((timeout
== 0) ? scsa2usb_long_timeout
: timeout
);
5268 * scsa2usb_clear_ept_stall:
5269 * clear endpoint stall and reset pipes
5272 scsa2usb_clear_ept_stall(scsa2usb_state_t
*scsa2usbp
, uint_t ept_addr
,
5273 usb_pipe_handle_t ph
, char *what
)
5276 dev_info_t
*dip
= scsa2usbp
->scsa2usb_dip
;
5278 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5279 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp
))) {
5281 return (USB_FAILURE
);
5284 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5285 rval
= usb_clr_feature(dip
, USB_DEV_REQ_RCPT_EP
, 0, ept_addr
,
5286 USB_FLAGS_SLEEP
, NULL
, NULL
);
5288 usb_pipe_reset(dip
, ph
, USB_FLAGS_SLEEP
, NULL
, NULL
);
5290 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5291 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5292 "scsa2usb_clear_ept_stall: on %s: ept = 0x%x rval = %d",
5293 what
, ept_addr
, rval
);
5300 * scsa2usb_pkt_completion:
5301 * Handle pkt completion.
5304 scsa2usb_pkt_completion(scsa2usb_state_t
*scsa2usbp
, struct scsi_pkt
*pkt
)
5306 scsa2usb_cmd_t
*cmd
= PKT2CMD(pkt
);
5310 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5312 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5313 "scsa2usb_pkt_completion:\n\tscsa2usbp = 0x%p "
5314 "reason=%d, status=%d state=0x%x stats=0x%x resid=0x%lx",
5315 (void *)scsa2usbp
, pkt
->pkt_reason
, *(pkt
->pkt_scbp
),
5316 pkt
->pkt_state
, pkt
->pkt_statistics
, pkt
->pkt_resid
);
5318 if (pkt
->pkt_reason
== CMD_CMPLT
) {
5319 pkt
->pkt_state
|= STATE_GOT_BUS
| STATE_GOT_TARGET
|
5320 STATE_SENT_CMD
| STATE_GOT_STATUS
;
5321 if (cmd
->cmd_xfercount
) {
5322 pkt
->pkt_state
|= STATE_XFERRED_DATA
;
5325 pkt
->pkt_state
|= STATE_GOT_BUS
| STATE_GOT_TARGET
|
5330 * don't zap the current state when in panic as this will
5331 * make debugging harder
5333 if ((scsa2usbp
->scsa2usb_cur_pkt
== pkt
) && !ddi_in_panic()) {
5334 SCSA2USB_RESET_CUR_PKT(scsa2usbp
);
5336 len
= sizeof (scsa2usbp
->scsa2usb_last_cmd
.cdb
);
5337 bzero(scsa2usbp
->scsa2usb_last_cmd
.cdb
, len
);
5339 len
= (len
< cmd
->cmd_cdblen
) ? len
: cmd
->cmd_cdblen
;
5340 USB_DPRINTF_L3(DPRINT_MASK_SCSA
,
5341 scsa2usbp
->scsa2usb_log_handle
,
5342 "scsa2usb_pkt_completion: save last cmd, len=%ld", len
);
5344 /* save the last command */
5345 bcopy(pkt
->pkt_cdbp
, scsa2usbp
->scsa2usb_last_cmd
.cdb
, len
);
5347 /* reset the scsa2usb_last_cmd.status value */
5348 if ((pkt
->pkt_cdbp
[0] != SCMD_REQUEST_SENSE
) &&
5349 (pkt
->pkt_cdbp
[0] != SCMD_INQUIRY
)) {
5350 scsa2usbp
->scsa2usb_last_cmd
.status
= 0;
5354 * set pkt state to NONE *before* calling back as the target
5355 * driver will immediately submit the next packet
5357 scsa2usbp
->scsa2usb_pkt_state
= SCSA2USB_PKT_NONE
;
5360 if (pkt
->pkt_comp
) {
5361 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5362 scsi_hba_pkt_comp(pkt
);
5363 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5370 * Even handling functions:
5372 * scsa2usb_reconnect_event_cb:
5376 scsa2usb_reconnect_event_cb(dev_info_t
*dip
)
5378 scsa2usb_state_t
*scsa2usbp
=
5379 ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
5382 int rval
= USB_SUCCESS
;
5384 ASSERT(scsa2usbp
!= NULL
);
5386 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5387 "scsa2usb_reconnect_event_cb: dip = 0x%p", (void *)dip
);
5389 scsa2usb_restore_device_state(dip
, scsa2usbp
);
5391 USB_DPRINTF_L0(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5392 "Reinserted device is accessible again.");
5394 ndi_devi_enter(dip
, &circ
);
5395 for (cdip
= ddi_get_child(dip
); cdip
; ) {
5396 dev_info_t
*next
= ddi_get_next_sibling(cdip
);
5398 mutex_enter(&DEVI(cdip
)->devi_lock
);
5399 DEVI_SET_DEVICE_REINSERTED(cdip
);
5400 mutex_exit(&DEVI(cdip
)->devi_lock
);
5404 ndi_devi_exit(dip
, circ
);
5406 /* stop suppressing warnings */
5407 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5408 scsa2usbp
->scsa2usb_warning_given
= B_FALSE
;
5409 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5411 if (scsa2usbp
->scsa2usb_ugen_hdl
) {
5412 rval
= usb_ugen_reconnect_ev_cb(
5413 scsa2usbp
->scsa2usb_ugen_hdl
);
5421 * scsa2usb_all_waitQs_empty:
5422 * check if all waitQs empty
5425 scsa2usb_all_waitQs_empty(scsa2usb_state_t
*scsa2usbp
)
5429 for (lun
= 0; lun
< SCSA2USB_MAX_LUNS
; lun
++) {
5430 if (usba_list_entry_count(
5431 &scsa2usbp
->scsa2usb_waitQ
[lun
])) {
5433 return (USB_FAILURE
);
5437 return (USB_SUCCESS
);
5442 * scsa2usb_disconnect_event_cb:
5443 * callback for disconnect events
5446 scsa2usb_disconnect_event_cb(dev_info_t
*dip
)
5448 scsa2usb_state_t
*scsa2usbp
=
5449 ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
5452 int rval
= USB_SUCCESS
;
5454 ASSERT(scsa2usbp
!= NULL
);
5456 USB_DPRINTF_L4(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5457 "scsa2usb_disconnect_event_cb: dip = 0x%p", (void *)dip
);
5459 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5460 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_DISCONNECTED
;
5463 * wait till the work thread is done, carry on regardless
5466 for (i
= 0; i
< SCSA2USB_DRAIN_TIMEOUT
; i
++) {
5467 if ((scsa2usbp
->scsa2usb_work_thread_id
== NULL
) &&
5468 (scsa2usbp
->scsa2usb_cur_pkt
== NULL
) &&
5469 (scsa2usb_all_waitQs_empty(scsa2usbp
) ==
5474 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5476 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5478 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5480 ndi_devi_enter(dip
, &circ
);
5481 for (cdip
= ddi_get_child(dip
); cdip
; ) {
5482 dev_info_t
*next
= ddi_get_next_sibling(cdip
);
5484 mutex_enter(&DEVI(cdip
)->devi_lock
);
5485 DEVI_SET_DEVICE_REMOVED(cdip
);
5486 mutex_exit(&DEVI(cdip
)->devi_lock
);
5490 ndi_devi_exit(dip
, circ
);
5492 if (scsa2usbp
->scsa2usb_ugen_hdl
) {
5493 rval
= usb_ugen_disconnect_ev_cb(
5494 scsa2usbp
->scsa2usb_ugen_hdl
);
5504 * scsa2usb_create_pm_components:
5505 * create the pm components required for power management
5506 * no mutex is need when calling USBA interfaces
5509 scsa2usb_create_pm_components(dev_info_t
*dip
, scsa2usb_state_t
*scsa2usbp
)
5511 scsa2usb_power_t
*pm
;
5514 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5516 USB_DPRINTF_L4(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5517 "scsa2usb_create_pm_components: dip = 0x%p, scsa2usbp = 0x%p",
5518 (void *)dip
, (void *)scsa2usbp
);
5521 * determine if this device is on the blacklist
5522 * or if a conf file entry has disabled PM
5524 if ((scsa2usbp
->scsa2usb_attrs
& SCSA2USB_ATTRS_PM
) == 0) {
5525 USB_DPRINTF_L2(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5526 "device cannot be power managed");
5531 /* Allocate the PM state structure */
5532 pm
= kmem_zalloc(sizeof (scsa2usb_power_t
), KM_SLEEP
);
5534 scsa2usbp
->scsa2usb_pm
= pm
;
5535 pm
->scsa2usb_current_power
= USB_DEV_OS_FULL_PWR
;
5536 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5538 if (usb_create_pm_components(dip
, &pwr_states
) ==
5540 if (usb_handle_remote_wakeup(dip
,
5541 USB_REMOTE_WAKEUP_ENABLE
) == USB_SUCCESS
) {
5542 pm
->scsa2usb_wakeup_enabled
= 1;
5545 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5546 pm
->scsa2usb_pwr_states
= (uint8_t)pwr_states
;
5547 scsa2usb_raise_power(scsa2usbp
);
5548 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5551 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5556 * scsa2usb_raise_power:
5557 * check if the device is using full power or not
5560 scsa2usb_raise_power(scsa2usb_state_t
*scsa2usbp
)
5562 USB_DPRINTF_L4(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5563 "scsa2usb_raise_power:");
5565 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5567 if (scsa2usbp
->scsa2usb_pm
) {
5568 scsa2usb_pm_busy_component(scsa2usbp
);
5569 if (scsa2usbp
->scsa2usb_pm
->scsa2usb_current_power
!=
5570 USB_DEV_OS_FULL_PWR
) {
5571 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5572 (void) pm_raise_power(scsa2usbp
->scsa2usb_dip
,
5573 0, USB_DEV_OS_FULL_PWR
);
5574 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5581 * functions to handle power transition for OS levels 0 -> 3
5584 scsa2usb_pwrlvl0(scsa2usb_state_t
*scsa2usbp
)
5588 switch (scsa2usbp
->scsa2usb_dev_state
) {
5589 case USB_DEV_ONLINE
:
5590 /* Deny the powerdown request if the device is busy */
5591 if (scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
!= 0) {
5593 return (USB_FAILURE
);
5597 * stop polling on interrupt pipe
5599 scsa2usb_cbi_stop_intr_polling(scsa2usbp
);
5601 /* Issue USB D3 command to the device here */
5602 rval
= usb_set_device_pwrlvl3(scsa2usbp
->scsa2usb_dip
);
5603 ASSERT(rval
== USB_SUCCESS
);
5605 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_PWRED_DOWN
;
5608 case USB_DEV_DISCONNECTED
:
5609 case USB_DEV_SUSPENDED
:
5610 case USB_DEV_PWRED_DOWN
:
5612 scsa2usbp
->scsa2usb_pm
->scsa2usb_current_power
=
5615 return (USB_SUCCESS
);
5621 scsa2usb_pwrlvl1(scsa2usb_state_t
*scsa2usbp
)
5625 /* Issue USB D2 command to the device here */
5626 rval
= usb_set_device_pwrlvl2(scsa2usbp
->scsa2usb_dip
);
5627 ASSERT(rval
== USB_SUCCESS
);
5629 return (DDI_FAILURE
);
5634 scsa2usb_pwrlvl2(scsa2usb_state_t
*scsa2usbp
)
5638 /* Issue USB D1 command to the device here */
5639 rval
= usb_set_device_pwrlvl1(scsa2usbp
->scsa2usb_dip
);
5640 ASSERT(rval
== USB_SUCCESS
);
5642 return (DDI_FAILURE
);
5647 scsa2usb_pwrlvl3(scsa2usb_state_t
*scsa2usbp
)
5652 * PM framework tries to put us in full power
5653 * during system shutdown. If we are disconnected
5654 * return success anyways
5656 if (scsa2usbp
->scsa2usb_dev_state
!= USB_DEV_DISCONNECTED
) {
5657 /* Issue USB D0 command to the device here */
5658 rval
= usb_set_device_pwrlvl0(scsa2usbp
->scsa2usb_dip
);
5659 ASSERT(rval
== USB_SUCCESS
);
5661 scsa2usbp
->scsa2usb_dev_state
= USB_DEV_ONLINE
;
5663 scsa2usbp
->scsa2usb_pm
->scsa2usb_current_power
= USB_DEV_OS_FULL_PWR
;
5665 return (DDI_SUCCESS
);
5675 scsa2usb_power(dev_info_t
*dip
, int comp
, int level
)
5677 scsa2usb_state_t
*scsa2usbp
;
5678 scsa2usb_power_t
*pm
;
5679 int rval
= DDI_FAILURE
;
5681 scsa2usbp
= ddi_get_soft_state(scsa2usb_statep
, ddi_get_instance(dip
));
5683 USB_DPRINTF_L3(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5684 "scsa2usb_power: Begin scsa2usbp (%p): level = %d",
5685 (void *)scsa2usbp
, level
);
5687 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5688 if (SCSA2USB_BUSY(scsa2usbp
)) {
5689 USB_DPRINTF_L2(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5690 "scsa2usb_power: busy");
5691 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5696 pm
= scsa2usbp
->scsa2usb_pm
;
5698 USB_DPRINTF_L2(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5699 "scsa2usb_power: pm NULL");
5700 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5705 /* check if we are transitioning to a legal power level */
5706 if (USB_DEV_PWRSTATE_OK(pm
->scsa2usb_pwr_states
, level
)) {
5707 USB_DPRINTF_L2(DPRINT_MASK_PM
, scsa2usbp
->scsa2usb_log_handle
,
5708 "scsa2usb_power: illegal power level = %d "
5709 "pwr_states: %x", level
, pm
->scsa2usb_pwr_states
);
5710 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5716 case USB_DEV_OS_PWR_OFF
:
5717 rval
= scsa2usb_pwrlvl0(scsa2usbp
);
5719 case USB_DEV_OS_PWR_1
:
5720 rval
= scsa2usb_pwrlvl1(scsa2usbp
);
5722 case USB_DEV_OS_PWR_2
:
5723 rval
= scsa2usb_pwrlvl2(scsa2usbp
);
5725 case USB_DEV_OS_FULL_PWR
:
5726 rval
= scsa2usb_pwrlvl3(scsa2usbp
);
5730 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5732 return ((rval
== USB_SUCCESS
) ? DDI_SUCCESS
: DDI_FAILURE
);
5737 scsa2usb_pm_busy_component(scsa2usb_state_t
*scsa2usbp
)
5739 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5741 if (scsa2usbp
->scsa2usb_pm
) {
5742 scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
++;
5744 USB_DPRINTF_L4(DPRINT_MASK_PM
,
5745 scsa2usbp
->scsa2usb_log_handle
,
5746 "scsa2usb_pm_busy_component: %d",
5747 scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
);
5749 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5751 if (pm_busy_component(scsa2usbp
->scsa2usb_dip
, 0) !=
5753 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5754 ASSERT(scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
> 0);
5755 scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
--;
5757 USB_DPRINTF_L2(DPRINT_MASK_PM
,
5758 scsa2usbp
->scsa2usb_log_handle
,
5759 "scsa2usb_pm_busy_component failed: %d",
5760 scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
);
5764 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5770 * scsa2usb_pm_idle_component:
5774 scsa2usb_pm_idle_component(scsa2usb_state_t
*scsa2usbp
)
5776 ASSERT(!mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5778 if (scsa2usbp
->scsa2usb_pm
) {
5779 if (pm_idle_component(scsa2usbp
->scsa2usb_dip
, 0) ==
5781 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5782 ASSERT(scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
> 0);
5783 scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
--;
5785 USB_DPRINTF_L4(DPRINT_MASK_PM
,
5786 scsa2usbp
->scsa2usb_log_handle
,
5787 "scsa2usb_pm_idle_component: %d",
5788 scsa2usbp
->scsa2usb_pm
->scsa2usb_pm_busy
);
5790 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5798 * scsa2usb_print_cdb:
5802 scsa2usb_print_cdb(scsa2usb_state_t
*scsa2usbp
, scsa2usb_cmd_t
*cmd
)
5804 uchar_t
*c
= (uchar_t
*)&cmd
->cmd_cdb
;
5806 USB_DPRINTF_L3(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5807 "cmd = 0x%p opcode=%s "
5808 "cdb: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
5810 scsi_cname(cmd
->cmd_cdb
[SCSA2USB_OPCODE
], scsa2usb_cmds
),
5811 c
[0], c
[1], c
[2], c
[3], c
[4], c
[5], c
[6], c
[7], c
[8],
5812 c
[9], c
[10], c
[11], c
[12], c
[13], c
[14], c
[15]);
5817 #ifdef SCSA2USB_BULK_ONLY_TEST
5819 * scsa2usb_test_mblk:
5820 * This function sends a dummy data mblk_t to simulate
5821 * the following test cases: 5 and 11.
5824 scsa2usb_test_mblk(scsa2usb_state_t
*scsa2usbp
, boolean_t large
)
5828 usb_flags_t flags
= USB_FLAGS_SLEEP
;
5829 usb_bulk_req_t
*req
;
5831 ASSERT(mutex_owned(&scsa2usbp
->scsa2usb_mutex
));
5833 /* should we create a larger mblk? */
5834 len
= (large
== B_TRUE
) ? DEV_BSIZE
: USB_BULK_CBWCMD_LEN
;
5836 req
= scsa2usb_init_bulk_req(scsa2usbp
, len
,
5837 SCSA2USB_BULK_PIPE_TIMEOUT
, 0, flags
);
5839 /* fill up the data mblk */
5840 for (i
= 0; i
< len
; i
++) {
5841 *req
->bulk_data
->b_wptr
++ = (uchar_t
)i
;
5844 mutex_exit(&scsa2usbp
->scsa2usb_mutex
);
5845 ASSERT(req
->bulk_timeout
);
5846 rval
= usb_pipe_bulk_xfer(scsa2usbp
->scsa2usb_bulkout_pipe
, req
, flags
);
5847 mutex_enter(&scsa2usbp
->scsa2usb_mutex
);
5849 USB_DPRINTF_L1(DPRINT_MASK_SCSA
, scsa2usbp
->scsa2usb_log_handle
,
5850 "scsa2usb_test_mblk: Sent Data Out rval = 0x%x", rval
);
5852 usb_free_bulk_req(req
);
5854 #endif /* SCSA2USB_BULK_ONLY_TEST */