17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5910cba4fScg  * Common Development and Distribution License (the "License").
6910cba4fScg  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  *
2142cac157SVincent Wang  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
227c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
23993e3fafSRobert Mustacchi  *
24fd826efaSJohn Levon  * Copyright 2019, Joyent, Inc.
25*10b633f4SJoshua M. Clulow  * Copyright 2019 Joshua M. Clulow <josh@sysmgr.org>
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #ifndef _SYS_USB_SCSA2USB_H
297c478bd9Sstevel@tonic-gate #define	_SYS_USB_SCSA2USB_H
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
337c478bd9Sstevel@tonic-gate extern "C" {
347c478bd9Sstevel@tonic-gate #endif
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <sys/usb/usba/usbai_private.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * SCSA2USB: This header file contains the internal structures
407c478bd9Sstevel@tonic-gate  * and variable definitions used in USB mass storage disk driver.
417c478bd9Sstevel@tonic-gate  */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 
4442cac157SVincent Wang #define	SCSA2USB_MAX_CLONE	256
457c478bd9Sstevel@tonic-gate #define	SCSA2USB_INITIAL_ALLOC	4	/* initial soft space alloc */
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #define	MAX_COMPAT_NAMES	1	/* max compatible names for children */
487c478bd9Sstevel@tonic-gate #define	SERIAL_NUM_LEN		64	/* for reading string descriptor */
497c478bd9Sstevel@tonic-gate #define	SCSA2USB_SERIAL_LEN	12	/* len of serial no in scsi_inquiry */
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #define	SCSA2USB_MAX_LUNS	0x10	/* maximum luns supported. */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate  * limit the max transfer size to under <= 64K. Some devices
557c478bd9Sstevel@tonic-gate  * have problems with large transfers
567c478bd9Sstevel@tonic-gate  */
577c478bd9Sstevel@tonic-gate #define	SCSA2USB_MAX_BULK_XFER_SIZE	(64 * 1024)
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /* Blacklist some vendors whose devices could cause problems */
607c478bd9Sstevel@tonic-gate #define	MS_HAGIWARA_SYS_COM_VID	0x693	/* VendorId of Hagiwara Sys-Com */
617c478bd9Sstevel@tonic-gate #define	MS_HAGIWARA_SYSCOM_PID1	0x1	/* PID for SmartMedia(SM) device */
627c478bd9Sstevel@tonic-gate #define	MS_HAGIWARA_SYSCOM_PID2	0x3	/* PID for CompactFlash(CF) device */
637c478bd9Sstevel@tonic-gate #define	MS_HAGIWARA_SYSCOM_PID3	0x5	/* PID for SM/CF Combo device */
647c478bd9Sstevel@tonic-gate #define	MS_HAGIWARA_SYSCOM_PID4	0x2	/* PID for new SM device */
657c478bd9Sstevel@tonic-gate #define	MS_HAGIWARA_SYSCOM_PID5	0x4	/* PID for new CF device */
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate #define	MS_IOMEGA_VID		0x59b	/* VendorId of Iomega */
687c478bd9Sstevel@tonic-gate #define	MS_IOMEGA_PID1_ZIP100	0x1	/* PID of an Older Iomega Zip100 */
697c478bd9Sstevel@tonic-gate #define	MS_IOMEGA_PID2_ZIP100	0x2	/* PID of Newer Iomega Zip100 */
707c478bd9Sstevel@tonic-gate #define	MS_IOMEGA_PID3_ZIP100	0x31	/* PID of Newer Iomega Zip100 */
717c478bd9Sstevel@tonic-gate #define	MS_IOMEGA_PID_ZIP250	0x30	/* PID of Newer Iomega Zip250 */
727c478bd9Sstevel@tonic-gate #define	MS_IOMEGA_PID_CLIK	0x60	/* PID of Iomega Clik! drive */
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate #define	MS_MITSUMI_VID		0x3ee	/* VendorId of Mitsumi Inc */
757c478bd9Sstevel@tonic-gate #define	MS_MITSUMI_DEVICE_242	0x242	/* bcdDevice of Mitsumi CR-4804TU */
767c478bd9Sstevel@tonic-gate #define	MS_MITSUMI_DEVICE_24	0x24	/* bcdDevice of Mitsumi CR-4802TU */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #define	MS_YEDATA_VID		0x57b	/* VendorId of Y-E Data Corp */
797c478bd9Sstevel@tonic-gate #define	MS_SMSC_VID		0x424	/* Vendor Id of SMSC */
807c478bd9Sstevel@tonic-gate #define	MS_SMSC_PID0		0xfdc	/* floppy from SMSC */
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate #define	MS_NEODIO_VID		0xaec	/* Neodio Technologies Corporation */
837c478bd9Sstevel@tonic-gate #define	MS_NEODIO_DEVICE_3050	0x3050	/* PID of ND3050/Soyo BayOne */
847c478bd9Sstevel@tonic-gate 					/* SM/CF/MS/SD */
857c478bd9Sstevel@tonic-gate #define	MS_SONY_FLASH_VID	0x54c	/* sony flash device */
867c478bd9Sstevel@tonic-gate #define	MS_SONY_FLASH_PID	0x8b
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate #define	MS_TREK_FLASH_VID	0xa16	/* Trek flash device */
897c478bd9Sstevel@tonic-gate #define	MS_TREK_FLASH_PID	0x9988
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #define	MS_PENN_FLASH_VID	0xd7d	/* Penn flash device */
927c478bd9Sstevel@tonic-gate #define	MS_PENN_FLASH_PID	0x1320
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate #define	MS_SIMPLETECH_VID	0x7c4	/* VendorId of Simpltech */
957c478bd9Sstevel@tonic-gate #define	MS_SIMPLETECH_PID1	0xa400	/* PID for UCF-100 device */
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate #define	MS_ADDONICS_CARD_READER_VID 0x7cc /* addonics */
987c478bd9Sstevel@tonic-gate #define	MS_ADDONICS_CARD_READER_PID 0x320
997c478bd9Sstevel@tonic-gate 
1002115f0c6Ssl #define	MS_ACOMDATA_VID		0xc0b	/* VendorId of DMI (Acomdata) */
1012115f0c6Ssl #define	MS_ACOMDATA_PID1	0x5fab	/* PID for 80GB USB/1394 disk */
1022115f0c6Ssl 
1032115f0c6Ssl #define	MS_OTI_VID		0xea0	/* VendorID of OTI */
1042115f0c6Ssl #define	MS_OTI_DEVICE_6828	0x6828	/* PID for 6828 flash disk */
1057c478bd9Sstevel@tonic-gate 
10663602c90Sfb #define	MS_SCANLOGIC_VID	0x04ce	/* VendorID of ScanLogic */
10763602c90Sfb #define	MS_SCANLOGIC_PID1	0x0002	/* SL USB Storage Device */
10863602c90Sfb 
1093fbbb872Ssl #define	MS_SUPERTOP_VID		0x14cd	/* Super Top USB 2.0 IDE enclosure */
1103fbbb872Ssl #define	MS_SUPERTOP_DEVICE_6600	0x6600
1113fbbb872Ssl 
11267318e4aSlg #define	MS_AIGO_VID		0xed1	/* VendorID of Aigo */
11367318e4aSlg #define	MS_AIGO_DEVICE_6981	0x6981	/* Aigo Miniking Device NEHFSP14 */
11467318e4aSlg 
115f0e30896Sguoqing zhu - Sun Microsystems - Beijing China #define	MS_ALCOR_VID	0x58f	/* Vendor ID of Alcor Micro Corp */
116f0e30896Sguoqing zhu - Sun Microsystems - Beijing China #define	MS_ALCOR_PID0	0x6387	/* PID for 6387 flash disk */
117f0e30896Sguoqing zhu - Sun Microsystems - Beijing China 
1185547f1d8SBinzi Cao - Sun Microsystems - Beijing China #define	MS_TOSHIBA_VID	0x930	/* Vendor ID of Toshiba Corp */
1195547f1d8SBinzi Cao - Sun Microsystems - Beijing China #define	MS_TOSHIBA_PID0	0x6545	/* Kingston DataTraveler / PNY Attache Stick */
1205547f1d8SBinzi Cao - Sun Microsystems - Beijing China 
1215547f1d8SBinzi Cao - Sun Microsystems - Beijing China #define	MS_PNY_VID	0x154b	/* Vendor ID of PNY Corp */
1225547f1d8SBinzi Cao - Sun Microsystems - Beijing China #define	MS_PNY_PID0	0x16	/* PNY floppy drive */
1235547f1d8SBinzi Cao - Sun Microsystems - Beijing China 
1248f588c83Sguoqing zhu - Sun Microsystems - Beijing China #define	MS_WD_VID	0x1058	/* Vendor ID of Western Digital */
1258f588c83Sguoqing zhu - Sun Microsystems - Beijing China #define	MS_WD_PID   0x1001  /* PID for Western Digital USB External HDD */
1268f588c83Sguoqing zhu - Sun Microsystems - Beijing China 
127df4cb6e0Ssl /*
128df4cb6e0Ssl  * The AMI virtual floppy device is not a real USB storage device, but
129df4cb6e0Ssl  * emulated by the SP firmware shipped together with important Sun x86
130df4cb6e0Ssl  * products such as Galaxy and Thumper platforms. The device causes
131df4cb6e0Ssl  * very long delay in boot process of these platforms which is a big
132df4cb6e0Ssl  * performance issue. Improvement in firmware may solve the issue, but
133df4cb6e0Ssl  * before the firmware is fixed, it needs to be taken care of by software
134df4cb6e0Ssl  * to avoid the huge impact on user experience.
135df4cb6e0Ssl  *
136df4cb6e0Ssl  * The long boot delay is caused by timeouts and retries of READ CAPACITY
137df4cb6e0Ssl  * command issued to the device. The device is a USB ufi subclass device
138df4cb6e0Ssl  * using CBI protocol. When READ CAPACITY command is issued, the device
139df4cb6e0Ssl  * returns STALL on the bulk endpoint during the data stage, however, it
140df4cb6e0Ssl  * doesn't return status on the intr pipe during status stage, so the intr
141df4cb6e0Ssl  * pipe can only fail with timeout.
142df4cb6e0Ssl  *
143df4cb6e0Ssl  * Reducing timeout value to 1 second can help a little bit, but the delay
144df4cb6e0Ssl  * is still noticeable, because the target driver would make many retries
145df4cb6e0Ssl  * for this command. It is not desirable to mess with the target driver
146df4cb6e0Ssl  * for a broken USB device. So adding the device to the scsa2usb blacklist
147df4cb6e0Ssl  * is the best choice we have.
148df4cb6e0Ssl  *
149df4cb6e0Ssl  * It is found that the READ CAPACITY failure only happens when there is
150df4cb6e0Ssl  * no media in the floppy drive. When there is a media, the device works
151df4cb6e0Ssl  * just fine. So READ CAPACITY command cannot be arbitrarily disabled.
152df4cb6e0Ssl  * Media status needs to be checked before issuing the command by sending
153df4cb6e0Ssl  * an additional TEST UNIT READY command. If TEST UNIT READY command
154df4cb6e0Ssl  * return STATUS_GOOD, it means the media is ready and then READ CAPACITY
155df4cb6e0Ssl  * can be issued.
156df4cb6e0Ssl  *
157df4cb6e0Ssl  * SCSA2USB_ATTRS_NO_MEDIA_CHECK is added below for this purpose. It is
158df4cb6e0Ssl  * overrided in scsa2usb.c for the AMI virtual floppy device to take care
159df4cb6e0Ssl  * of the special need.
160df4cb6e0Ssl  */
161df4cb6e0Ssl #define	MS_AMI_VID		0x46b	/* VendorId of AMI */
162df4cb6e0Ssl #define	MS_AMI_VIRTUAL_FLOPPY	0xff40	/* PID for AMI virtual floppy */
163df4cb6e0Ssl 
1647c478bd9Sstevel@tonic-gate /*
1657c478bd9Sstevel@tonic-gate  * List the attributes that need special case in the driver
1667c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_GET_LUN: Bulk Only Transport Get_Max_Lun class specific
1677c478bd9Sstevel@tonic-gate  *		command is not implemented by these devices
1687c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_PM: Some devices don't like being power managed.
1697c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_START_STOP: Some devices don't do anything with
1707c478bd9Sstevel@tonic-gate  *		SCMD_START_STOP opcode (for e.g. SmartMedia/CompactFlash/
1717c478bd9Sstevel@tonic-gate  *		Clik!/MemoryStick/MMC USB readers/writers.
1727c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_GET_CONF: SCMD_GET_CONFIGURATION is not supported
1737c478bd9Sstevel@tonic-gate  * SCMD_TEST_UNIT_READY: for floppies this needs to be converted to
1747c478bd9Sstevel@tonic-gate  *		SCMD_START_STOP as floppies don't support this
1757c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_GET_PERF: SCMD_GET_PERFORMANCE not supported by
1767c478bd9Sstevel@tonic-gate  *		Mitsumi's CD-RW devices.
1777c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_BIG_TIMEOUT: Mitsumi's CD-RW devices need large
1787c478bd9Sstevel@tonic-gate  *		timeout with SCMD_START_STOP cmd
1797c478bd9Sstevel@tonic-gate  * SCSA2USB_ATTRS_RMB: Pay attention to the device's RMB setting,
1807c478bd9Sstevel@tonic-gate  *		instead of automatically treating it as removable
1812115f0c6Ssl  * SCSA2USB_ATTRS_USE_CSW_RESIDUE: Some devices report false residue in
1822115f0c6Ssl  *		the CSW of bulk-only transfer status stage though data
1832115f0c6Ssl  *		was successfully transfered, so need to ignore residue.
184df4cb6e0Ssl  * SCSA2USB_ATTRS_NO_MEDIA_CHECK: AMI Virtual Floppy devices need to
185df4cb6e0Ssl  *		check if media is ready before issuing READ CAPACITY.
18663602c90Sfb  * SCSA2USB_ATTRS_NO_CAP_ADJUST: Some devices return total logical block number
187fd826efaSJohn Levon  *		instead of highest logical block address on READ_CAPACITY cmd.
1887c478bd9Sstevel@tonic-gate  *
1897c478bd9Sstevel@tonic-gate  * NOTE: If a device simply STALLs the GET_MAX_LUN BO class-specific command
1907c478bd9Sstevel@tonic-gate  * and recovers then it will not be added to the scsa2usb_blacklist[] table
1917c478bd9Sstevel@tonic-gate  * in scsa2usb.c. The other attributes will not be taken of the table unless
1927c478bd9Sstevel@tonic-gate  * their inclusion causes a recovery and retries (thus seriously affecting
1937c478bd9Sstevel@tonic-gate  * the driver performance).
1947c478bd9Sstevel@tonic-gate  */
1957c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_GET_LUN		0x01	/* GET_MAX_LUN (Bulk Only) */
1967c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_PM		0x02	/* Some don't support PM */
1977c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_START_STOP	0x04	/* SCMD_START_STOP */
1987c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_GET_CONF		0x08	/* SCMD_GET_CONFIGURATION */
1997c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_GET_PERF		0x10	/* SCMD_GET_PERFORMANCE */
2007c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_BIG_TIMEOUT	0x40	/* for SCMD_START_STOP */
2017c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_DOORLOCK		0x80	/* for SCMD_DOORLOCK */
2027c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_RMB		0x100	/* Pay attention to RMB */
2037c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_MODE_SENSE	0x200	/* SCMD_MODE_SENSE */
2047c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_INQUIRY		0x400	/* SCMD_INQUIRY */
2052115f0c6Ssl #define	SCSA2USB_ATTRS_USE_CSW_RESIDUE	0x800	/* for residue checking */
206df4cb6e0Ssl #define	SCSA2USB_ATTRS_NO_MEDIA_CHECK	0x1000	/* for media checking */
20763602c90Sfb #define	SCSA2USB_ATTRS_NO_CAP_ADJUST	0x2000	/* for CAPACITY adjusting */
2088f588c83Sguoqing zhu - Sun Microsystems - Beijing China #define	SCSA2USB_ATTRS_INQUIRY_EVPD	0x4000	/* SCMD_INQUIRY with evpd */
2097c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATTRS_REDUCED_CMD	\
2107c478bd9Sstevel@tonic-gate 	(SCSA2USB_ATTRS_DOORLOCK|SCSA2USB_ATTRS_MODE_SENSE| \
2112115f0c6Ssl 	SCSA2USB_ATTRS_START_STOP|SCSA2USB_ATTRS_INQUIRY| \
2122115f0c6Ssl 	SCSA2USB_ATTRS_USE_CSW_RESIDUE)
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate #define	SCSA2USB_ALL_ATTRS		0xFFFF	/* All of the above */
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate /* max inquiry length */
2177c478bd9Sstevel@tonic-gate #define	SCSA2USB_MAX_INQ_LEN (offsetof(struct scsi_inquiry, inq_serial))
2187c478bd9Sstevel@tonic-gate 
219910cba4fScg /* page code of scsi mode page */
220910cba4fScg #ifndef SD_MODE_SENSE_PAGE3_CODE
221910cba4fScg #define	SD_MODE_SENSE_PAGE3_CODE	0x03
222910cba4fScg #endif
223910cba4fScg 
224910cba4fScg #ifndef SD_MODE_SENSE_PAGE4_CODE
225910cba4fScg #define	SD_MODE_SENSE_PAGE4_CODE	0x04
226910cba4fScg #endif
227910cba4fScg 
22842e43e98Sguoqing zhu - Sun Microsystems - Beijing China #define	SD_MODE_SENSE_PAGE_MASK		0x3F
22942e43e98Sguoqing zhu - Sun Microsystems - Beijing China 
2307c478bd9Sstevel@tonic-gate /*
2317c478bd9Sstevel@tonic-gate  * PM support
2327c478bd9Sstevel@tonic-gate  */
2337c478bd9Sstevel@tonic-gate typedef struct scsa2usb_power  {
2347c478bd9Sstevel@tonic-gate 	/* device busy accounting */
2357c478bd9Sstevel@tonic-gate 	int		scsa2usb_pm_busy;
2367c478bd9Sstevel@tonic-gate 	/* this is the bit mask of the power states that device has */
2377c478bd9Sstevel@tonic-gate 	uint8_t		scsa2usb_pwr_states;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	uint8_t		scsa2usb_wakeup_enabled;
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	/* current power level the device is in */
2427c478bd9Sstevel@tonic-gate 	uint8_t		scsa2usb_current_power;
2437c478bd9Sstevel@tonic-gate } scsa2usb_power_t;
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate /*
2467c478bd9Sstevel@tonic-gate  * CPR support:
2477c478bd9Sstevel@tonic-gate  *	keep track of the last command issued to the drive. If it
2487c478bd9Sstevel@tonic-gate  *	was TUR or EJECT then allow issuing a CPR suspend.
2497c478bd9Sstevel@tonic-gate  */
2507c478bd9Sstevel@tonic-gate #define	LOEJECT	2		/* eject bit in start/stop cmd */
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate typedef struct scsa2usb_last_cmd {
2537c478bd9Sstevel@tonic-gate 	/* this is the cdb of the last command issued */
2547c478bd9Sstevel@tonic-gate 	uchar_t		cdb[SCSI_CDB_SIZE];
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	/* this is the status of the last command issued */
2577c478bd9Sstevel@tonic-gate 	uint_t		status;
2587c478bd9Sstevel@tonic-gate } scsa2usb_last_cmd_t;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate /*
2617c478bd9Sstevel@tonic-gate  * override values
2627c478bd9Sstevel@tonic-gate  *	These values may be set in scsa2usb.conf for particular devices
2637c478bd9Sstevel@tonic-gate  */
2647c478bd9Sstevel@tonic-gate typedef struct scsa2usb_ov {
2657c478bd9Sstevel@tonic-gate 	int	vid;		/* vendor id */
2667c478bd9Sstevel@tonic-gate 	int	pid;		/* product id */
2677c478bd9Sstevel@tonic-gate 	int	rev;		/* revision */
2687c478bd9Sstevel@tonic-gate 	int	subclass;	/* subclass override */
2697c478bd9Sstevel@tonic-gate 	int	protocol;	/* protocol override */
2707c478bd9Sstevel@tonic-gate 	int	pmoff;		/* power management override */
2710167b58cScg 	int	fake_removable;	/* removable device override */
2727c478bd9Sstevel@tonic-gate 	int	no_modesense;	/* no mode sense */
2737c478bd9Sstevel@tonic-gate 				/* no modesense, doorlock, PM, start/stop */
2747c478bd9Sstevel@tonic-gate 	int	reduced_cmd_support;
2757c478bd9Sstevel@tonic-gate } scsa2usb_ov_t;
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate /*
2797c478bd9Sstevel@tonic-gate  * Per bulk device "state" data structure.
2807c478bd9Sstevel@tonic-gate  */
2817c478bd9Sstevel@tonic-gate typedef struct scsa2usb_state {
2827c478bd9Sstevel@tonic-gate 	int			scsa2usb_instance;	/* Instance number    */
2837c478bd9Sstevel@tonic-gate 	int			scsa2usb_dev_state;	/* USB device state   */
284fd826efaSJohn Levon 	int			scsa2usb_flags;		/* Per instance flags */
2857c478bd9Sstevel@tonic-gate 	int			scsa2usb_intfc_num;	/* Interface number   */
2867c478bd9Sstevel@tonic-gate 	dev_info_t		*scsa2usb_dip;		/* Per device. info   */
2877c478bd9Sstevel@tonic-gate 	scsa2usb_power_t	*scsa2usb_pm;		/* PM state info */
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	int			scsa2usb_transport_busy; /* ugen/sd traffic */
2907c478bd9Sstevel@tonic-gate 	int			scsa2usb_ugen_open_count;
2917c478bd9Sstevel@tonic-gate 	kcondvar_t		scsa2usb_transport_busy_cv;
29242cac157SVincent Wang 	struct proc		*scsa2usb_busy_proc; /* owner of the hardware */
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	kmutex_t		scsa2usb_mutex;		/* Per instance lock  */
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	struct scsi_hba_tran	*scsa2usb_tran;		/* SCSI transport ptr */
2977c478bd9Sstevel@tonic-gate 	struct scsi_pkt		*scsa2usb_cur_pkt;	/* SCSI packet ptr    */
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	usba_list_entry_t	scsa2usb_waitQ[SCSA2USB_MAX_LUNS];
3007c478bd9Sstevel@tonic-gate 							/* waitQ list */
3017c478bd9Sstevel@tonic-gate 	struct scsa2usb_cmd	*scsa2usb_arq_cmd;	/* ARQ cmd */
3027c478bd9Sstevel@tonic-gate 	struct buf		*scsa2usb_arq_bp;	/* ARQ buf */
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	dev_info_t		*scsa2usb_lun_dip[SCSA2USB_MAX_LUNS];
3057c478bd9Sstevel@tonic-gate 						/* store devinfo per LUN  */
3067c478bd9Sstevel@tonic-gate 	struct scsi_inquiry	scsa2usb_lun_inquiry[SCSA2USB_MAX_LUNS];
3077c478bd9Sstevel@tonic-gate 						/* store inquiry per LUN  */
3087c478bd9Sstevel@tonic-gate 	usb_if_descr_t		scsa2usb_intfc_descr;	/* Interface descr    */
309993e3fafSRobert Mustacchi 	usb_ep_xdescr_t		scsa2usb_bulkin_xept;	/* Bulk In descriptor */
310993e3fafSRobert Mustacchi 	usb_ep_xdescr_t		scsa2usb_bulkout_xept;	/* Bulkout descriptor */
311993e3fafSRobert Mustacchi 	usb_ep_xdescr_t		scsa2usb_intr_xept;	/* Intr ept descr */
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	scsa2usb_default_pipe;	/* Default pipe	Hndle */
3147c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	scsa2usb_intr_pipe;	/* Intr polling Hndle */
3157c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	scsa2usb_bulkin_pipe;	/* Bulk Inpipe Handle */
3167c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	scsa2usb_bulkout_pipe;	/* Bulk Outpipe Hndle */
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_pipe_state;	/* resetting state */
3197c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_tag;		/* current tag */
3207c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_pkt_state;	/* packet state */
3217c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_n_luns;	/* number of luns */
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	usb_log_handle_t	scsa2usb_log_handle;	/* log handle */
3247c478bd9Sstevel@tonic-gate 	struct scsa2usb_cpr	*scsa2usb_panic_info;	/* for cpr info */
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	size_t			scsa2usb_lbasize[SCSA2USB_MAX_LUNS];
3277c478bd9Sstevel@tonic-gate 							/* sector size */
3287c478bd9Sstevel@tonic-gate 	size_t			scsa2usb_totalsec[SCSA2USB_MAX_LUNS];
3297c478bd9Sstevel@tonic-gate 							/* total sectors */
3307c478bd9Sstevel@tonic-gate 	size_t			scsa2usb_secsz[SCSA2USB_MAX_LUNS];
3317c478bd9Sstevel@tonic-gate 							/* sector size */
3327c478bd9Sstevel@tonic-gate 	size_t			scsa2usb_max_bulk_xfer_size; /* from HCD */
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t	*scsa2usb_dev_data;	/* USB registration */
3357c478bd9Sstevel@tonic-gate 	scsa2usb_last_cmd_t	scsa2usb_last_cmd;	/* last/prev command */
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_attrs;		/* for bad devices */
3387c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_cmd_protocol;	/* CMD protocol used */
3397c478bd9Sstevel@tonic-gate 	kthread_t		*scsa2usb_work_thread_id; /* handle commands */
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 				/* conf file override values */
3427c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_subclass_override;
3437c478bd9Sstevel@tonic-gate 	uint_t			scsa2usb_protocol_override;
3447c478bd9Sstevel@tonic-gate 	char			*scsa2usb_override_str;
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 				/* suppress repetitive disconnect warnings */
3477c478bd9Sstevel@tonic-gate 	boolean_t		scsa2usb_warning_given;
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	boolean_t		scsa2usb_rcvd_not_ready; /* received NOT */
3507c478bd9Sstevel@tonic-gate 							/* READY sense data */
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	usb_ugen_hdl_t		scsa2usb_ugen_hdl;	/* ugen support */
35342cac157SVincent Wang 
35442cac157SVincent Wang 	uint8_t			scsa2usb_clones[SCSA2USB_MAX_CLONE];
3557c478bd9Sstevel@tonic-gate } scsa2usb_state_t;
3567c478bd9Sstevel@tonic-gate 
357993e3fafSRobert Mustacchi /*
358993e3fafSRobert Mustacchi  * These macros were added as part of updating scsa2usb to support USB 3.0 and
359993e3fafSRobert Mustacchi  * newer devices to minimize driver changes. There's no reason these can't be
360993e3fafSRobert Mustacchi  * expanded by someone who wants to.
361993e3fafSRobert Mustacchi  */
362993e3fafSRobert Mustacchi #define	scsa2usb_bulkin_ept	scsa2usb_bulkin_xept.uex_ep
363993e3fafSRobert Mustacchi #define	scsa2usb_bulkout_ept	scsa2usb_bulkout_xept.uex_ep
364993e3fafSRobert Mustacchi #define	scsa2usb_intr_ept	scsa2usb_intr_xept.uex_ep
365993e3fafSRobert Mustacchi 
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate /* for warlock */
3687c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(scsa2usb_state::scsa2usb_mutex, scsa2usb_state))
3697c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_instance))
3707c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_dip))
3717c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_arq_cmd))
3727c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_arq_bp))
3737c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_intr_ept))
3747c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_default_pipe))
3757c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_intr_pipe))
3767c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_bulkin_pipe))
3777c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_log_handle))
3787c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_intfc_num))
3797c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_dev_data))
3807c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_ugen_hdl))
381496d8c83Sfrits _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_pm))
3827c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("stable data", scsa2usb_power_t))
3837c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_hba_tran_t))
3847c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unshared data", usb_bulk_req_t))
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate /* scsa2usb_pipe_state values */
3877c478bd9Sstevel@tonic-gate #define	SCSA2USB_PIPE_NORMAL		0x00	/* no reset or clearing	*/
3887c478bd9Sstevel@tonic-gate #define	SCSA2USB_PIPE_CLOSING		0x01	/* closing all pipes */
3897c478bd9Sstevel@tonic-gate #define	SCSA2USB_PIPE_DEV_RESET		0x02	/* device specific reset */
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate /* pkt xfer state machine */
3927c478bd9Sstevel@tonic-gate #define	SCSA2USB_PKT_NONE		0	/* device is idle */
3937c478bd9Sstevel@tonic-gate #define	SCSA2USB_PKT_PROCESS_CSW	1	/* device doing status again */
3947c478bd9Sstevel@tonic-gate #define	SCSA2USB_PKT_DO_COMP		2	/* device is done xfer */
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate /* scsa2usb_flags values */
3977c478bd9Sstevel@tonic-gate #define	SCSA2USB_FLAGS_PIPES_OPENED	0x001	/* usb pipes are open */
3987c478bd9Sstevel@tonic-gate #define	SCSA2USB_FLAGS_HBA_ATTACH_SETUP	0x002	/* scsi hba setup done */
3997c478bd9Sstevel@tonic-gate #define	SCSA2USB_FLAGS_LOCKS_INIT	0x004	/* basic inits done */
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /* scsa2usb_cmd_protocol values */
4027c478bd9Sstevel@tonic-gate #define	SCSA2USB_UNKNOWN_PROTOCOL	0x0000	/* unknown wire protocol */
4037c478bd9Sstevel@tonic-gate #define	SCSA2USB_CB_PROTOCOL		0x0001	/* CBI wire protocol */
4047c478bd9Sstevel@tonic-gate #define	SCSA2USB_CBI_PROTOCOL		0x0002	/* CBI w/ intr wire protocol */
4057c478bd9Sstevel@tonic-gate #define	SCSA2USB_BULK_ONLY_PROTOCOL	0x0004	/* Bulk Only wire protocol */
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate #define	SCSA2USB_SCSI_CMDSET		0x1000	/* SCSI command set followed */
4087c478bd9Sstevel@tonic-gate #define	SCSA2USB_ATAPI_CMDSET		0x2000	/* ATAPI command set followed */
4097c478bd9Sstevel@tonic-gate #define	SCSA2USB_UFI_CMDSET		0x4000	/* UFI command set followed */
4107c478bd9Sstevel@tonic-gate #define	SCSA2USB_CMDSET_MASK		0x7000	/* OR al the above */
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate #define	SCSA2USB_IS_UFI_CMDSET(s) \
4137c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cmd_protocol & SCSA2USB_UFI_CMDSET))
4147c478bd9Sstevel@tonic-gate #define	SCSA2USB_IS_SCSI_CMDSET(s) \
4157c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cmd_protocol & SCSA2USB_SCSI_CMDSET))
4167c478bd9Sstevel@tonic-gate #define	SCSA2USB_IS_ATAPI_CMDSET(s) \
4177c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cmd_protocol & SCSA2USB_ATAPI_CMDSET))
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate #define	SCSA2USB_IS_CB(s) \
4207c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cmd_protocol & SCSA2USB_CB_PROTOCOL))
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate #define	SCSA2USB_IS_CBI(s) \
4237c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cmd_protocol & SCSA2USB_CBI_PROTOCOL))
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate #define	SCSA2USB_IS_BULK_ONLY(s) \
4267c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cmd_protocol & SCSA2USB_BULK_ONLY_PROTOCOL))
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate /* check if it is ok to access the device and send command to it */
4297c478bd9Sstevel@tonic-gate #define	SCSA2USB_DEVICE_ACCESS_OK(s) \
4307c478bd9Sstevel@tonic-gate 	((s)->scsa2usb_dev_state == USB_DEV_ONLINE)
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate /* check if we are in any reset */
4337c478bd9Sstevel@tonic-gate #define	SCSA2USB_IN_RESET(s) \
4347c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_pipe_state & SCSA2USB_PIPE_DEV_RESET) != 0)
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate /* check if the device is busy */
4377c478bd9Sstevel@tonic-gate #define	SCSA2USB_BUSY(s) \
4387c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_cur_pkt) || \
4397c478bd9Sstevel@tonic-gate 	((s)->scsa2usb_pipe_state != SCSA2USB_PIPE_NORMAL) || \
4407c478bd9Sstevel@tonic-gate 	((s)->scsa2usb_pkt_state != SCSA2USB_PKT_NONE))
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate /* check if we're doing cpr */
4437c478bd9Sstevel@tonic-gate #define	SCSA2USB_CHK_CPR(s) \
4447c478bd9Sstevel@tonic-gate 	(((s)->scsa2usb_dev_state == USB_DEV_SUSPENDED))
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate /* check if we're either paniced or in cpr state */
4477c478bd9Sstevel@tonic-gate #define	SCSA2USB_CHK_PANIC_CPR(s) \
4487c478bd9Sstevel@tonic-gate 	(ddi_in_panic() || SCSA2USB_CHK_CPR(s))
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate /* reset scsa2usb state after pkt_comp is called */
4517c478bd9Sstevel@tonic-gate #define	SCSA2USB_RESET_CUR_PKT(s) \
4527c478bd9Sstevel@tonic-gate 	(s)->scsa2usb_cur_pkt = NULL; \
4537c478bd9Sstevel@tonic-gate 	(s)->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate /* print a panic sync message to the console */
4567c478bd9Sstevel@tonic-gate #define	SCSA2USB_PRINT_SYNC_MSG(m, s) \
4577c478bd9Sstevel@tonic-gate 	if ((m) == B_TRUE) { \
4588668df41Slg 		USB_DPRINTF_L1(DPRINT_MASK_SCSA, (s)->scsa2usb_log_handle, \
4597c478bd9Sstevel@tonic-gate 		    "syncing not supported"); \
4607c478bd9Sstevel@tonic-gate 		(m) = B_FALSE; \
4617c478bd9Sstevel@tonic-gate 	}
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate /* Cancel callbacks registered during attach time */
4647c478bd9Sstevel@tonic-gate #define	SCSA2USB_CANCEL_CB(id) \
4657c478bd9Sstevel@tonic-gate 	if ((id)) { \
4667c478bd9Sstevel@tonic-gate 		(void) callb_delete((id)); \
4677c478bd9Sstevel@tonic-gate 		(id) = 0; \
4687c478bd9Sstevel@tonic-gate 	}
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate /* Set SCSA2USB_PKT_DO_COMP state if there is active I/O */
4717c478bd9Sstevel@tonic-gate #define	SCSA2USB_SET_PKT_DO_COMP_STATE(s) \
4727c478bd9Sstevel@tonic-gate 	if ((s)->scsa2usb_cur_pkt) { \
4737c478bd9Sstevel@tonic-gate 		(s)->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP; \
4747c478bd9Sstevel@tonic-gate 	}
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate #define	SCSA2USB_FREE_MSG(data) \
4777c478bd9Sstevel@tonic-gate 	if ((data)) { \
4787c478bd9Sstevel@tonic-gate 		freemsg((data)); \
4797c478bd9Sstevel@tonic-gate 	}
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate #define	SCSA2USB_FREE_BULK_REQ(req) \
4827c478bd9Sstevel@tonic-gate 	if ((req)) { \
4837c478bd9Sstevel@tonic-gate 		usb_free_bulk_req((req));	/* Free request */ \
4847c478bd9Sstevel@tonic-gate 	}
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate /* SCSA related */
4887c478bd9Sstevel@tonic-gate #define	ADDR2TRAN(ap)		((ap)->a_hba_tran)
4897c478bd9Sstevel@tonic-gate #define	TRAN2SCSA2USB(tran)	((scsa2usb_state_t *)(tran)->tran_hba_private)
4907c478bd9Sstevel@tonic-gate #define	ADDR2SCSA2USB(ap)	(TRAN2SCSA2USB(ADDR2TRAN(ap)))
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate #define	PKT_PRIV_LEN		16
4937c478bd9Sstevel@tonic-gate 
494df4cb6e0Ssl #define	PKT_DEFAULT_TIMEOUT	5
495df4cb6e0Ssl 
4967c478bd9Sstevel@tonic-gate /*
4977c478bd9Sstevel@tonic-gate  * auto request sense
4987c478bd9Sstevel@tonic-gate  */
4997c478bd9Sstevel@tonic-gate #define	RQ_MAKECOM_COMMON(pktp, flag, cmd) \
5007c478bd9Sstevel@tonic-gate 	(pktp)->pkt_flags = (flag), \
5017c478bd9Sstevel@tonic-gate 	((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \
5027c478bd9Sstevel@tonic-gate 	((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \
5037c478bd9Sstevel@tonic-gate 	    (pktp)->pkt_address.a_lun
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate #define	RQ_MAKECOM_G0(pktp, flag, cmd, addr, cnt) \
5067c478bd9Sstevel@tonic-gate 	RQ_MAKECOM_COMMON((pktp), (flag), (cmd)), \
5077c478bd9Sstevel@tonic-gate 	FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
5087c478bd9Sstevel@tonic-gate 	FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate /* transport related */
5127c478bd9Sstevel@tonic-gate #define	SCSA2USB_JUST_ACCEPT	0
5137c478bd9Sstevel@tonic-gate #define	SCSA2USB_TRANSPORT	1
5147c478bd9Sstevel@tonic-gate #define	SCSA2USB_REJECT		-1
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate  * The scsa2usb_cpr_info data structure is used for cpr related
5187c478bd9Sstevel@tonic-gate  * callbacks. It is used for panic callbacks as well.
5197c478bd9Sstevel@tonic-gate  */
5207c478bd9Sstevel@tonic-gate typedef struct scsa2usb_cpr {
5217c478bd9Sstevel@tonic-gate 	callb_cpr_t		cpr;		/* for cpr related info */
5227c478bd9Sstevel@tonic-gate 	struct scsa2usb_state	*statep;	/* for scsa2usb state info */
5237c478bd9Sstevel@tonic-gate 	kmutex_t		lockp;		/* mutex used by cpr_info_t */
5247c478bd9Sstevel@tonic-gate } scsa2usb_cpr_t;
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_cpr_t::cpr))
5277c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_cpr_t::statep))
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate /*
5307c478bd9Sstevel@tonic-gate  * The scsa2usb_cmd data structure is defined here. It gets
5317c478bd9Sstevel@tonic-gate  * initialized per command that is sent to the device.
5327c478bd9Sstevel@tonic-gate  */
5337c478bd9Sstevel@tonic-gate typedef struct scsa2usb_cmd {
5347c478bd9Sstevel@tonic-gate 	struct scsi_pkt		*cmd_pkt;		/* copy of pkt ptr */
5357c478bd9Sstevel@tonic-gate 	struct	buf		*cmd_bp;		/* copy of bp ptr */
5367c478bd9Sstevel@tonic-gate 	size_t			cmd_xfercount;		/* current xfer count */
5377c478bd9Sstevel@tonic-gate 	size_t			cmd_resid_xfercount;	/* last xfer resid */
5387c478bd9Sstevel@tonic-gate 	int			cmd_scblen;		/* status length */
5397c478bd9Sstevel@tonic-gate 	int			cmd_tag;		/* tag */
5407c478bd9Sstevel@tonic-gate 	int			cmd_timeout;		/* copy of pkt_time */
5417c478bd9Sstevel@tonic-gate 	uchar_t			cmd_cdb[SCSI_CDB_SIZE];	/* CDB */
5427c478bd9Sstevel@tonic-gate 	uchar_t			cmd_dir;		/* direction */
543fd826efaSJohn Levon 	uchar_t			cmd_actual_len;		/* cdb len */
5447c478bd9Sstevel@tonic-gate 	uchar_t			cmd_cdblen;		/* requested  cdb len */
5457c478bd9Sstevel@tonic-gate 	struct scsi_arq_status	cmd_scb;		/* status, w/ arq */
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	/* used in multiple xfers */
5487c478bd9Sstevel@tonic-gate 	size_t			cmd_total_xfercount;	/* total xfer val */
5497c478bd9Sstevel@tonic-gate 	size_t			cmd_offset;		/* offset into buf */
550*10b633f4SJoshua M. Clulow 	uint64_t		cmd_lba;		/* current xfer lba */
5517c478bd9Sstevel@tonic-gate 	int			cmd_done;		/* command done? */
5527c478bd9Sstevel@tonic-gate 	int			cmd_blksize;		/* block size */
5537c478bd9Sstevel@tonic-gate 	usba_list_entry_t	cmd_waitQ;		/* waitQ element */
5547c478bd9Sstevel@tonic-gate } scsa2usb_cmd_t;
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate /* for warlock */
5577c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unique per packet or safe sharing",
5587c478bd9Sstevel@tonic-gate     scsi_cdb scsi_status scsi_pkt buf scsa2usb_cmd scsi_arq_status))
5597c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate /* scsa2usb_cdb position of fields in CDB */
5627c478bd9Sstevel@tonic-gate #define	SCSA2USB_OPCODE		0		/* Opcode field */
5637c478bd9Sstevel@tonic-gate #define	SCSA2USB_LUN		1		/* LUN field */
5647c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_0		2		/* LBA[0] field */
5657c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_1		3		/* LBA[1] field */
5667c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_2		4		/* LBA[2] field */
5677c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_3		5		/* LBA[3] field */
5687c478bd9Sstevel@tonic-gate #define	SCSA2USB_LEN_0		7		/* LEN[0] field */
5697c478bd9Sstevel@tonic-gate #define	SCSA2USB_LEN_1		8		/* LEN[1] field */
5707c478bd9Sstevel@tonic-gate 
571*10b633f4SJoshua M. Clulow /*
572*10b633f4SJoshua M. Clulow  * Extract LBA and length from 6, 10, 12, and 16-byte commands:
573*10b633f4SJoshua M. Clulow  */
5747c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_6BYTE(pkt) \
5757c478bd9Sstevel@tonic-gate 	(((pkt)->pkt_cdbp[1] & 0x1f) << 16) + \
5767c478bd9Sstevel@tonic-gate 	((pkt)->pkt_cdbp[2] << 8) + (pkt)->pkt_cdbp[3]
5777c478bd9Sstevel@tonic-gate #define	SCSA2USB_LEN_6BYTE(pkt)		(pkt)->pkt_cdbp[4]
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate #define	SCSA2USB_LEN_10BYTE(pkt) \
5807c478bd9Sstevel@tonic-gate 	((pkt)->pkt_cdbp[7] << 8) + (pkt)->pkt_cdbp[8]
5817c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_10BYTE(pkt) \
5827c478bd9Sstevel@tonic-gate 	((pkt)->pkt_cdbp[2] << 24) + ((pkt)->pkt_cdbp[3] << 16) + \
5837c478bd9Sstevel@tonic-gate 	    ((pkt)->pkt_cdbp[4] << 8) +  (pkt)->pkt_cdbp[5]
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate #define	SCSA2USB_LEN_12BYTE(pkt) \
5867c478bd9Sstevel@tonic-gate 	((pkt)->pkt_cdbp[6] << 24) + ((pkt)->pkt_cdbp[7] << 16) + \
5877c478bd9Sstevel@tonic-gate 	    ((pkt)->pkt_cdbp[8] << 8) +  (pkt)->pkt_cdbp[9]
5887c478bd9Sstevel@tonic-gate #define	SCSA2USB_LBA_12BYTE(pkt) \
5897c478bd9Sstevel@tonic-gate 	((pkt)->pkt_cdbp[2] << 24) + ((pkt)->pkt_cdbp[3] << 16) + \
5907c478bd9Sstevel@tonic-gate 	    ((pkt)->pkt_cdbp[4] << 8) +  (pkt)->pkt_cdbp[5]
5917c478bd9Sstevel@tonic-gate 
592*10b633f4SJoshua M. Clulow #define	SCSA2USB_LEN_16BYTE(pkt) \
593*10b633f4SJoshua M. Clulow 	(((pkt)->pkt_cdbp[10] << 24) + ((pkt)->pkt_cdbp[11] << 16) + \
594*10b633f4SJoshua M. Clulow 	    ((pkt)->pkt_cdbp[12] << 8) + (pkt)->pkt_cdbp[13])
595*10b633f4SJoshua M. Clulow #define	SCSA2USB_LBA_16BYTE(pkt) ((uint64_t)( \
596*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[2] << 56) + \
597*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[3] << 48) + \
598*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[4] << 40) + \
599*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[5] << 32) + \
600*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[6] << 24) + \
601*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[7] << 16) + \
602*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[8] << 8) + \
603*10b633f4SJoshua M. Clulow 	((uint64_t)(pkt)->pkt_cdbp[9])))
604*10b633f4SJoshua M. Clulow 
6057c478bd9Sstevel@tonic-gate /* macros to convert a pkt to cmd and vice-versa */
6067c478bd9Sstevel@tonic-gate #define	PKT2CMD(pkt)		((scsa2usb_cmd_t *)(pkt)->pkt_ha_private)
607*10b633f4SJoshua M. Clulow #define	CMD2PKT(sp)		((sp)->cmd_pkt)
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate /* bulk pipe default timeout value - how long the command to be tried? */
6107c478bd9Sstevel@tonic-gate #define	SCSA2USB_BULK_PIPE_TIMEOUT	(2 * USB_PIPE_TIMEOUT)
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate /* drain timeout in seconds on the work thread */
6137c478bd9Sstevel@tonic-gate #define	SCSA2USB_DRAIN_TIMEOUT		60
6147c478bd9Sstevel@tonic-gate 
6156d9a41ffSqz /* scsa2usb pkt xfer status phase retry times */
6166d9a41ffSqz #define	SCSA2USB_STATUS_RETRIES		3
6176d9a41ffSqz 
6187c478bd9Sstevel@tonic-gate /*
6197c478bd9Sstevel@tonic-gate  * limit on the number of requests that can be queued per LUN:
6207c478bd9Sstevel@tonic-gate  * 3 for untagged queueing, 1 for scsiwatch and a margin of 2
6217c478bd9Sstevel@tonic-gate  */
6227c478bd9Sstevel@tonic-gate #define	SCSA2USB_MAX_REQ_PER_LUN	6
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate /*
6257c478bd9Sstevel@tonic-gate  * The following data structure is used to save the values returned
6267c478bd9Sstevel@tonic-gate  * by the READ_CAPACITY command. lba is the max allowed logical block
6277c478bd9Sstevel@tonic-gate  * address and blen is max allowed block size.
6287c478bd9Sstevel@tonic-gate  */
6297c478bd9Sstevel@tonic-gate typedef struct scsa2usb_read_cap {
6307c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_lba3;		/* Max lba supported */
6317c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_lba2;
6327c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_lba1;
6337c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_lba0;
6347c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_blen3;	/* Max block size supported */
6357c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_blen2;
6367c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_blen1;
6377c478bd9Sstevel@tonic-gate 	uchar_t	scsa2usb_read_cap_blen0;
6387c478bd9Sstevel@tonic-gate } scsa2usb_read_cap_t;
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate #define	SCSA2USB_MK_32BIT(a, b, c, d) \
6417c478bd9Sstevel@tonic-gate 		(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate /* position of fields for SCMD_READ_CD CDB */
6447c478bd9Sstevel@tonic-gate #define	SCSA2USB_READ_CD_LEN_0	6	/* LEN[0] of SCMD_READ_CD */
6457c478bd9Sstevel@tonic-gate #define	SCSA2USB_READ_CD_LEN_1	7	/* LEN[1] of SCMD_READ_CD */
6467c478bd9Sstevel@tonic-gate #define	SCSA2USB_READ_CD_LEN_2	8	/* LEN[2] of SCMD_READ_CD */
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate /* macro to calculate LEN for SCMD_READ_CD command */
6497c478bd9Sstevel@tonic-gate #define	SCSA2USB_LEN_READ_CD(pkt) \
6507c478bd9Sstevel@tonic-gate 	(((pkt)->pkt_cdbp[SCSA2USB_READ_CD_LEN_0] << 16) +\
6517c478bd9Sstevel@tonic-gate 	    ((pkt)->pkt_cdbp[SCSA2USB_READ_CD_LEN_1] << 8) +\
6527c478bd9Sstevel@tonic-gate 	    (pkt)->pkt_cdbp[SCSA2USB_READ_CD_LEN_2])
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate /* Figure out Block Size before issuing a WRITE to CD-RW device */
6557c478bd9Sstevel@tonic-gate #define	SCSA2USB_CDRW_BLKSZ(bcount, len)	((bcount) / (len));
6567c478bd9Sstevel@tonic-gate #define	SCSA2USB_VALID_CDRW_BLKSZ(blksz) \
6577c478bd9Sstevel@tonic-gate 	(((blksz) == CDROM_BLK_2048) || ((blksz) == CDROM_BLK_2352) || \
6587c478bd9Sstevel@tonic-gate 	((blksz) == CDROM_BLK_2336) || ((blksz) == CDROM_BLK_2324) || \
6597c478bd9Sstevel@tonic-gate 	((blksz) == 0))
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate /* debug and error msg logging */
6627c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_SCSA	0x0001		/* for SCSA */
6637c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_ATTA	0x0002		/* for ATTA */
6647c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_EVENTS	0x0004		/* for event handling */
6657c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_CALLBACKS	0x0008		/* for callbacks  */
6667c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_TIMEOUT	0x0010		/* for timeouts */
6677c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_DUMPING	0x0020		/* for dumping */
6687c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_PM		0x0040		/* for pwr mgmt */
6697c478bd9Sstevel@tonic-gate #define	DPRINT_MASK_ALL		0xffffffff	/* for everything */
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate #ifdef	DEBUG
6727c478bd9Sstevel@tonic-gate #define	SCSA2USB_PRINT_CDB	scsa2usb_print_cdb
6737c478bd9Sstevel@tonic-gate #else
674679c9deaSJohn Levon #define	SCSA2USB_PRINT_CDB(...)	(void)(0)
6757c478bd9Sstevel@tonic-gate #endif
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate /* ugen support */
6787c478bd9Sstevel@tonic-gate #define	SCSA2USB_MINOR_UGEN_BITS_MASK	0xff
6797c478bd9Sstevel@tonic-gate #define	SCSA2USB_MINOR_INSTANCE_MASK	~SCSA2USB_MINOR_UGEN_BITS_MASK
6807c478bd9Sstevel@tonic-gate #define	SCSA2USB_MINOR_INSTANCE_SHIFT	8
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate #define	SCSA2USB_MINOR_TO_INSTANCE(minor)	\
6837c478bd9Sstevel@tonic-gate 		(((minor) & SCSA2USB_MINOR_INSTANCE_MASK) >> \
6847c478bd9Sstevel@tonic-gate 		SCSA2USB_MINOR_INSTANCE_SHIFT)
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate #ifdef __cplusplus
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate #endif
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate #endif	/* _SYS_USB_SCSA2USB_H */
691