#ifndef _SYS_USB_SCSA2USB_H
#define _SYS_USB_SCSA2USB_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/usb/usba/usbai_private.h>
#define SCSA2USB_MAX_CLONE 256
#define SCSA2USB_INITIAL_ALLOC 4
#define MAX_COMPAT_NAMES 1
#define SERIAL_NUM_LEN 64
#define SCSA2USB_SERIAL_LEN 12
#define SCSA2USB_MAX_LUNS 0x10
#define SCSA2USB_MAX_BULK_XFER_SIZE (64 * 1024)
#define MS_HAGIWARA_SYS_COM_VID 0x693
#define MS_HAGIWARA_SYSCOM_PID1 0x1
#define MS_HAGIWARA_SYSCOM_PID2 0x3
#define MS_HAGIWARA_SYSCOM_PID3 0x5
#define MS_HAGIWARA_SYSCOM_PID4 0x2
#define MS_HAGIWARA_SYSCOM_PID5 0x4
#define MS_IOMEGA_VID 0x59b
#define MS_IOMEGA_PID1_ZIP100 0x1
#define MS_IOMEGA_PID2_ZIP100 0x2
#define MS_IOMEGA_PID3_ZIP100 0x31
#define MS_IOMEGA_PID_ZIP250 0x30
#define MS_IOMEGA_PID_CLIK 0x60
#define MS_MITSUMI_VID 0x3ee
#define MS_MITSUMI_DEVICE_242 0x242
#define MS_MITSUMI_DEVICE_24 0x24
#define MS_YEDATA_VID 0x57b
#define MS_SMSC_VID 0x424
#define MS_SMSC_PID0 0xfdc
#define MS_NEODIO_VID 0xaec
#define MS_NEODIO_DEVICE_3050 0x3050
#define MS_SONY_FLASH_VID 0x54c
#define MS_SONY_FLASH_PID 0x8b
#define MS_TREK_FLASH_VID 0xa16
#define MS_TREK_FLASH_PID 0x9988
#define MS_PENN_FLASH_VID 0xd7d
#define MS_PENN_FLASH_PID 0x1320
#define MS_SIMPLETECH_VID 0x7c4
#define MS_SIMPLETECH_PID1 0xa400
#define MS_ADDONICS_CARD_READER_VID 0x7cc
#define MS_ADDONICS_CARD_READER_PID 0x320
#define MS_ACOMDATA_VID 0xc0b
#define MS_ACOMDATA_PID1 0x5fab
#define MS_OTI_VID 0xea0
#define MS_OTI_DEVICE_6828 0x6828
#define MS_SCANLOGIC_VID 0x04ce
#define MS_SCANLOGIC_PID1 0x0002
#define MS_SUPERTOP_VID 0x14cd
#define MS_SUPERTOP_DEVICE_6600 0x6600
#define MS_AIGO_VID 0xed1
#define MS_AIGO_DEVICE_6981 0x6981
#define MS_ALCOR_VID 0x58f
#define MS_ALCOR_PID0 0x6387
#define MS_TOSHIBA_VID 0x930
#define MS_TOSHIBA_PID0 0x6545
#define MS_PNY_VID 0x154b
#define MS_PNY_PID0 0x16
#define MS_WD_VID 0x1058
#define MS_WD_PID 0x1001
#define MS_INSYDE_VID 0xb1f
#define MS_INSYDE_PID_CDROM 0x03ea
#define MS_AMI_VID 0x46b
#define MS_AMI_VIRTUAL_FLOPPY 0xff40
#define SCSA2USB_ATTRS_GET_LUN 0x01
#define SCSA2USB_ATTRS_PM 0x02
#define SCSA2USB_ATTRS_START_STOP 0x04
#define SCSA2USB_ATTRS_GET_CONF 0x08
#define SCSA2USB_ATTRS_GET_PERF 0x10
#define SCSA2USB_ATTRS_BIG_TIMEOUT 0x40
#define SCSA2USB_ATTRS_DOORLOCK 0x80
#define SCSA2USB_ATTRS_RMB 0x100
#define SCSA2USB_ATTRS_MODE_SENSE 0x200
#define SCSA2USB_ATTRS_INQUIRY 0x400
#define SCSA2USB_ATTRS_USE_CSW_RESIDUE 0x800
#define SCSA2USB_ATTRS_NO_MEDIA_CHECK 0x1000
#define SCSA2USB_ATTRS_NO_CAP_ADJUST 0x2000
#define SCSA2USB_ATTRS_INQUIRY_EVPD 0x4000
#define SCSA2USB_ATTRS_REDUCED_CMD \
(SCSA2USB_ATTRS_DOORLOCK|SCSA2USB_ATTRS_MODE_SENSE| \
SCSA2USB_ATTRS_START_STOP|SCSA2USB_ATTRS_INQUIRY| \
SCSA2USB_ATTRS_USE_CSW_RESIDUE)
#define SCSA2USB_ALL_ATTRS 0xFFFF
#define SCSA2USB_MAX_INQ_LEN (offsetof(struct scsi_inquiry, inq_serial))
#ifndef SD_MODE_SENSE_PAGE3_CODE
#define SD_MODE_SENSE_PAGE3_CODE 0x03
#endif
#ifndef SD_MODE_SENSE_PAGE4_CODE
#define SD_MODE_SENSE_PAGE4_CODE 0x04
#endif
#define SD_MODE_SENSE_PAGE_MASK 0x3F
typedef struct scsa2usb_power {
int scsa2usb_pm_busy;
uint8_t scsa2usb_pwr_states;
uint8_t scsa2usb_wakeup_enabled;
uint8_t scsa2usb_current_power;
} scsa2usb_power_t;
#define LOEJECT 2
typedef struct scsa2usb_last_cmd {
uchar_t cdb[SCSI_CDB_SIZE];
uint_t status;
} scsa2usb_last_cmd_t;
typedef struct scsa2usb_ov {
int vid;
int pid;
int rev;
int subclass;
int protocol;
int pmoff;
int fake_removable;
int no_modesense;
int reduced_cmd_support;
} scsa2usb_ov_t;
typedef struct scsa2usb_state {
int scsa2usb_instance;
int scsa2usb_dev_state;
int scsa2usb_flags;
int scsa2usb_intfc_num;
dev_info_t *scsa2usb_dip;
scsa2usb_power_t *scsa2usb_pm;
int scsa2usb_transport_busy;
int scsa2usb_ugen_open_count;
kcondvar_t scsa2usb_transport_busy_cv;
struct proc *scsa2usb_busy_proc;
kmutex_t scsa2usb_mutex;
struct scsi_hba_tran *scsa2usb_tran;
struct scsi_pkt *scsa2usb_cur_pkt;
usba_list_entry_t scsa2usb_waitQ[SCSA2USB_MAX_LUNS];
struct scsa2usb_cmd *scsa2usb_arq_cmd;
struct buf *scsa2usb_arq_bp;
dev_info_t *scsa2usb_lun_dip[SCSA2USB_MAX_LUNS];
struct scsi_inquiry scsa2usb_lun_inquiry[SCSA2USB_MAX_LUNS];
usb_if_descr_t scsa2usb_intfc_descr;
usb_ep_xdescr_t scsa2usb_bulkin_xept;
usb_ep_xdescr_t scsa2usb_bulkout_xept;
usb_ep_xdescr_t scsa2usb_intr_xept;
usb_pipe_handle_t scsa2usb_default_pipe;
usb_pipe_handle_t scsa2usb_intr_pipe;
usb_pipe_handle_t scsa2usb_bulkin_pipe;
usb_pipe_handle_t scsa2usb_bulkout_pipe;
uint_t scsa2usb_pipe_state;
uint_t scsa2usb_tag;
uint_t scsa2usb_pkt_state;
uint_t scsa2usb_n_luns;
usb_log_handle_t scsa2usb_log_handle;
struct scsa2usb_cpr *scsa2usb_panic_info;
size_t scsa2usb_lbasize[SCSA2USB_MAX_LUNS];
size_t scsa2usb_totalsec[SCSA2USB_MAX_LUNS];
size_t scsa2usb_secsz[SCSA2USB_MAX_LUNS];
size_t scsa2usb_max_bulk_xfer_size;
usb_client_dev_data_t *scsa2usb_dev_data;
scsa2usb_last_cmd_t scsa2usb_last_cmd;
uint_t scsa2usb_attrs;
uint_t scsa2usb_cmd_protocol;
kthread_t *scsa2usb_work_thread_id;
uint_t scsa2usb_subclass_override;
uint_t scsa2usb_protocol_override;
char *scsa2usb_override_str;
boolean_t scsa2usb_warning_given;
boolean_t scsa2usb_rcvd_not_ready;
usb_ugen_hdl_t scsa2usb_ugen_hdl;
uint8_t scsa2usb_clones[SCSA2USB_MAX_CLONE];
} scsa2usb_state_t;
#define scsa2usb_bulkin_ept scsa2usb_bulkin_xept.uex_ep
#define scsa2usb_bulkout_ept scsa2usb_bulkout_xept.uex_ep
#define scsa2usb_intr_ept scsa2usb_intr_xept.uex_ep
_NOTE(MUTEX_PROTECTS_DATA(scsa2usb_state::scsa2usb_mutex, scsa2usb_state))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_instance))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_dip))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_arq_cmd))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_arq_bp))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_intr_ept))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_default_pipe))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_intr_pipe))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_bulkin_pipe))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_log_handle))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_intfc_num))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_dev_data))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_ugen_hdl))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_state::scsa2usb_pm))
_NOTE(SCHEME_PROTECTS_DATA("stable data", scsa2usb_power_t))
_NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_hba_tran_t))
_NOTE(SCHEME_PROTECTS_DATA("unshared data", usb_bulk_req_t))
#define SCSA2USB_PIPE_NORMAL 0x00
#define SCSA2USB_PIPE_CLOSING 0x01
#define SCSA2USB_PIPE_DEV_RESET 0x02
#define SCSA2USB_PKT_NONE 0
#define SCSA2USB_PKT_PROCESS_CSW 1
#define SCSA2USB_PKT_DO_COMP 2
#define SCSA2USB_FLAGS_PIPES_OPENED 0x001
#define SCSA2USB_FLAGS_HBA_ATTACH_SETUP 0x002
#define SCSA2USB_FLAGS_LOCKS_INIT 0x004
#define SCSA2USB_UNKNOWN_PROTOCOL 0x0000
#define SCSA2USB_CB_PROTOCOL 0x0001
#define SCSA2USB_CBI_PROTOCOL 0x0002
#define SCSA2USB_BULK_ONLY_PROTOCOL 0x0004
#define SCSA2USB_SCSI_CMDSET 0x1000
#define SCSA2USB_ATAPI_CMDSET 0x2000
#define SCSA2USB_UFI_CMDSET 0x4000
#define SCSA2USB_CMDSET_MASK 0x7000
#define SCSA2USB_IS_UFI_CMDSET(s) \
(((s)->scsa2usb_cmd_protocol & SCSA2USB_UFI_CMDSET))
#define SCSA2USB_IS_SCSI_CMDSET(s) \
(((s)->scsa2usb_cmd_protocol & SCSA2USB_SCSI_CMDSET))
#define SCSA2USB_IS_ATAPI_CMDSET(s) \
(((s)->scsa2usb_cmd_protocol & SCSA2USB_ATAPI_CMDSET))
#define SCSA2USB_IS_CB(s) \
(((s)->scsa2usb_cmd_protocol & SCSA2USB_CB_PROTOCOL))
#define SCSA2USB_IS_CBI(s) \
(((s)->scsa2usb_cmd_protocol & SCSA2USB_CBI_PROTOCOL))
#define SCSA2USB_IS_BULK_ONLY(s) \
(((s)->scsa2usb_cmd_protocol & SCSA2USB_BULK_ONLY_PROTOCOL))
#define SCSA2USB_DEVICE_ACCESS_OK(s) \
((s)->scsa2usb_dev_state == USB_DEV_ONLINE)
#define SCSA2USB_IN_RESET(s) \
(((s)->scsa2usb_pipe_state & SCSA2USB_PIPE_DEV_RESET) != 0)
#define SCSA2USB_BUSY(s) \
(((s)->scsa2usb_cur_pkt) || \
((s)->scsa2usb_pipe_state != SCSA2USB_PIPE_NORMAL) || \
((s)->scsa2usb_pkt_state != SCSA2USB_PKT_NONE))
#define SCSA2USB_CHK_CPR(s) \
(((s)->scsa2usb_dev_state == USB_DEV_SUSPENDED))
#define SCSA2USB_CHK_PANIC_CPR(s) \
(ddi_in_panic() || SCSA2USB_CHK_CPR(s))
#define SCSA2USB_RESET_CUR_PKT(s) \
(s)->scsa2usb_cur_pkt = NULL; \
(s)->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
#define SCSA2USB_PRINT_SYNC_MSG(m, s) \
if ((m) == B_TRUE) { \
USB_DPRINTF_L1(DPRINT_MASK_SCSA, (s)->scsa2usb_log_handle, \
"syncing not supported"); \
(m) = B_FALSE; \
}
#define SCSA2USB_CANCEL_CB(id) \
if ((id)) { \
(void) callb_delete((id)); \
(id) = 0; \
}
#define SCSA2USB_SET_PKT_DO_COMP_STATE(s) \
if ((s)->scsa2usb_cur_pkt) { \
(s)->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP; \
}
#define SCSA2USB_FREE_MSG(data) \
if ((data)) { \
freemsg((data)); \
}
#define SCSA2USB_FREE_BULK_REQ(req) \
if ((req)) { \
usb_free_bulk_req((req)); \
}
#define ADDR2TRAN(ap) ((ap)->a_hba_tran)
#define TRAN2SCSA2USB(tran) ((scsa2usb_state_t *)(tran)->tran_hba_private)
#define ADDR2SCSA2USB(ap) (TRAN2SCSA2USB(ADDR2TRAN(ap)))
#define PKT_PRIV_LEN 16
#define PKT_DEFAULT_TIMEOUT 5
#define RQ_MAKECOM_COMMON(pktp, flag, cmd) \
(pktp)->pkt_flags = (flag), \
((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \
((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \
(pktp)->pkt_address.a_lun
#define RQ_MAKECOM_G0(pktp, flag, cmd, addr, cnt) \
RQ_MAKECOM_COMMON((pktp), (flag), (cmd)), \
FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
#define SCSA2USB_JUST_ACCEPT 0
#define SCSA2USB_TRANSPORT 1
#define SCSA2USB_REJECT -1
typedef struct scsa2usb_cpr {
callb_cpr_t cpr;
struct scsa2usb_state *statep;
kmutex_t lockp;
} scsa2usb_cpr_t;
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_cpr_t::cpr))
_NOTE(DATA_READABLE_WITHOUT_LOCK(scsa2usb_cpr_t::statep))
typedef struct scsa2usb_cmd {
struct scsi_pkt *cmd_pkt;
struct buf *cmd_bp;
size_t cmd_xfercount;
size_t cmd_resid_xfercount;
int cmd_scblen;
int cmd_tag;
int cmd_timeout;
uchar_t cmd_cdb[SCSI_CDB_SIZE];
uchar_t cmd_dir;
uchar_t cmd_actual_len;
uchar_t cmd_cdblen;
struct scsi_arq_status cmd_scb;
size_t cmd_total_xfercount;
size_t cmd_offset;
uint64_t cmd_lba;
int cmd_done;
int cmd_blksize;
usba_list_entry_t cmd_waitQ;
} scsa2usb_cmd_t;
_NOTE(SCHEME_PROTECTS_DATA("unique per packet or safe sharing",
scsi_cdb scsi_status scsi_pkt buf scsa2usb_cmd scsi_arq_status))
_NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
#define SCSA2USB_OPCODE 0
#define SCSA2USB_LUN 1
#define SCSA2USB_LBA_0 2
#define SCSA2USB_LBA_1 3
#define SCSA2USB_LBA_2 4
#define SCSA2USB_LBA_3 5
#define SCSA2USB_LEN_0 7
#define SCSA2USB_LEN_1 8
#define SCSA2USB_LBA_6BYTE(pkt) \
(((pkt)->pkt_cdbp[1] & 0x1f) << 16) + \
((pkt)->pkt_cdbp[2] << 8) + (pkt)->pkt_cdbp[3]
#define SCSA2USB_LEN_6BYTE(pkt) (pkt)->pkt_cdbp[4]
#define SCSA2USB_LEN_10BYTE(pkt) \
((pkt)->pkt_cdbp[7] << 8) + (pkt)->pkt_cdbp[8]
#define SCSA2USB_LBA_10BYTE(pkt) \
((pkt)->pkt_cdbp[2] << 24) + ((pkt)->pkt_cdbp[3] << 16) + \
((pkt)->pkt_cdbp[4] << 8) + (pkt)->pkt_cdbp[5]
#define SCSA2USB_LEN_12BYTE(pkt) \
((pkt)->pkt_cdbp[6] << 24) + ((pkt)->pkt_cdbp[7] << 16) + \
((pkt)->pkt_cdbp[8] << 8) + (pkt)->pkt_cdbp[9]
#define SCSA2USB_LBA_12BYTE(pkt) \
((pkt)->pkt_cdbp[2] << 24) + ((pkt)->pkt_cdbp[3] << 16) + \
((pkt)->pkt_cdbp[4] << 8) + (pkt)->pkt_cdbp[5]
#define SCSA2USB_LEN_16BYTE(pkt) \
(((pkt)->pkt_cdbp[10] << 24) + ((pkt)->pkt_cdbp[11] << 16) + \
((pkt)->pkt_cdbp[12] << 8) + (pkt)->pkt_cdbp[13])
#define SCSA2USB_LBA_16BYTE(pkt) ((uint64_t)( \
((uint64_t)(pkt)->pkt_cdbp[2] << 56) + \
((uint64_t)(pkt)->pkt_cdbp[3] << 48) + \
((uint64_t)(pkt)->pkt_cdbp[4] << 40) + \
((uint64_t)(pkt)->pkt_cdbp[5] << 32) + \
((uint64_t)(pkt)->pkt_cdbp[6] << 24) + \
((uint64_t)(pkt)->pkt_cdbp[7] << 16) + \
((uint64_t)(pkt)->pkt_cdbp[8] << 8) + \
((uint64_t)(pkt)->pkt_cdbp[9])))
#define PKT2CMD(pkt) ((scsa2usb_cmd_t *)(pkt)->pkt_ha_private)
#define CMD2PKT(sp) ((sp)->cmd_pkt)
#define SCSA2USB_BULK_PIPE_TIMEOUT (2 * USB_PIPE_TIMEOUT)
#define SCSA2USB_DRAIN_TIMEOUT 60
#define SCSA2USB_STATUS_RETRIES 3
#define SCSA2USB_MAX_REQ_PER_LUN 6
typedef struct scsa2usb_read_cap {
uchar_t scsa2usb_read_cap_lba3;
uchar_t scsa2usb_read_cap_lba2;
uchar_t scsa2usb_read_cap_lba1;
uchar_t scsa2usb_read_cap_lba0;
uchar_t scsa2usb_read_cap_blen3;
uchar_t scsa2usb_read_cap_blen2;
uchar_t scsa2usb_read_cap_blen1;
uchar_t scsa2usb_read_cap_blen0;
} scsa2usb_read_cap_t;
#define SCSA2USB_MK_32BIT(a, b, c, d) \
(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
#define SCSA2USB_READ_CD_LEN_0 6
#define SCSA2USB_READ_CD_LEN_1 7
#define SCSA2USB_READ_CD_LEN_2 8
#define SCSA2USB_LEN_READ_CD(pkt) \
(((pkt)->pkt_cdbp[SCSA2USB_READ_CD_LEN_0] << 16) +\
((pkt)->pkt_cdbp[SCSA2USB_READ_CD_LEN_1] << 8) +\
(pkt)->pkt_cdbp[SCSA2USB_READ_CD_LEN_2])
#define SCSA2USB_CDRW_BLKSZ(bcount, len) ((bcount) / (len));
#define SCSA2USB_VALID_CDRW_BLKSZ(blksz) \
(((blksz) == CDROM_BLK_2048) || ((blksz) == CDROM_BLK_2352) || \
((blksz) == CDROM_BLK_2336) || ((blksz) == CDROM_BLK_2324) || \
((blksz) == 0))
#define DPRINT_MASK_SCSA 0x0001
#define DPRINT_MASK_ATTA 0x0002
#define DPRINT_MASK_EVENTS 0x0004
#define DPRINT_MASK_CALLBACKS 0x0008
#define DPRINT_MASK_TIMEOUT 0x0010
#define DPRINT_MASK_DUMPING 0x0020
#define DPRINT_MASK_PM 0x0040
#define DPRINT_MASK_ALL 0xffffffff
#ifdef DEBUG
#define SCSA2USB_PRINT_CDB scsa2usb_print_cdb
#else
#define SCSA2USB_PRINT_CDB(...) (void)(0)
#endif
#define SCSA2USB_MINOR_UGEN_BITS_MASK 0xff
#define SCSA2USB_MINOR_INSTANCE_MASK ~SCSA2USB_MINOR_UGEN_BITS_MASK
#define SCSA2USB_MINOR_INSTANCE_SHIFT 8
#define SCSA2USB_MINOR_TO_INSTANCE(minor) \
(((minor) & SCSA2USB_MINOR_INSTANCE_MASK) >> \
SCSA2USB_MINOR_INSTANCE_SHIFT)
#ifdef __cplusplus
}
#endif
#endif