scsa2usb.h revision f0e308969424e7466232f0795ba1891698c3adf7
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_USB_SCSA2USB_H
#define _SYS_USB_SCSA2USB_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* SCSA2USB: This header file contains the internal structures
* and variable definitions used in USB mass storage disk driver.
*/
/*
* limit the max transfer size to under <= 64K. Some devices
* have problems with large transfers
*/
/* Blacklist some vendors whose devices could cause problems */
#define MS_SONY_FLASH_PID 0x8b
#define MS_TREK_FLASH_PID 0x9988
#define MS_PENN_FLASH_PID 0x1320
#define MS_ADDONICS_CARD_READER_PID 0x320
#define MS_SUPERTOP_DEVICE_6600 0x6600
/*
* The AMI virtual floppy device is not a real USB storage device, but
* emulated by the SP firmware shipped together with important Sun x86
* products such as Galaxy and Thumper platforms. The device causes
* very long delay in boot process of these platforms which is a big
* performance issue. Improvement in firmware may solve the issue, but
* before the firmware is fixed, it needs to be taken care of by software
* to avoid the huge impact on user experience.
*
* The long boot delay is caused by timeouts and retries of READ CAPACITY
* command issued to the device. The device is a USB ufi subclass device
* using CBI protocol. When READ CAPACITY command is issued, the device
* returns STALL on the bulk endpoint during the data stage, however, it
* doesn't return status on the intr pipe during status stage, so the intr
* pipe can only fail with timeout.
*
* Reducing timeout value to 1 second can help a little bit, but the delay
* is still noticeable, because the target driver would make many retries
* for this command. It is not desirable to mess with the target driver
* for a broken USB device. So adding the device to the scsa2usb blacklist
* is the best choice we have.
*
* It is found that the READ CAPACITY failure only happens when there is
* no media in the floppy drive. When there is a media, the device works
* just fine. So READ CAPACITY command cannot be arbitrarily disabled.
* Media status needs to be checked before issuing the command by sending
* an additional TEST UNIT READY command. If TEST UNIT READY command
* return STATUS_GOOD, it means the media is ready and then READ CAPACITY
* can be issued.
*
* SCSA2USB_ATTRS_NO_MEDIA_CHECK is added below for this purpose. It is
* overrided in scsa2usb.c for the AMI virtual floppy device to take care
* of the special need.
*/
/*
* List the attributes that need special case in the driver
* SCSA2USB_ATTRS_GET_LUN: Bulk Only Transport Get_Max_Lun class specific
* command is not implemented by these devices
* SCSA2USB_ATTRS_PM: Some devices don't like being power managed.
* SCSA2USB_ATTRS_START_STOP: Some devices don't do anything with
* SCMD_START_STOP opcode (for e.g. SmartMedia/CompactFlash/
* Clik!/MemoryStick/MMC USB readers/writers.
* SCSA2USB_ATTRS_GET_CONF: SCMD_GET_CONFIGURATION is not supported
* SCMD_TEST_UNIT_READY: for floppies this needs to be converted to
* SCMD_START_STOP as floppies don't support this
* SCSA2USB_ATTRS_GET_PERF: SCMD_GET_PERFORMANCE not supported by
* Mitsumi's CD-RW devices.
* SCSA2USB_ATTRS_BIG_TIMEOUT: Mitsumi's CD-RW devices need large
* timeout with SCMD_START_STOP cmd
* SCSA2USB_ATTRS_RMB: Pay attention to the device's RMB setting,
* instead of automatically treating it as removable
* SCSA2USB_ATTRS_USE_CSW_RESIDUE: Some devices report false residue in
* the CSW of bulk-only transfer status stage though data
* was successfully transfered, so need to ignore residue.
* SCSA2USB_ATTRS_NO_MEDIA_CHECK: AMI Virtual Floppy devices need to
* check if media is ready before issuing READ CAPACITY.
* SCSA2USB_ATTRS_NO_CAP_ADJUST: Some devices return total logical block number
* instead of highest logical block address on READ_CAPACITY cmd.
*
* NOTE: If a device simply STALLs the GET_MAX_LUN BO class-specific command
* and recovers then it will not be added to the scsa2usb_blacklist[] table
* in scsa2usb.c. The other attributes will not be taken of the table unless
* their inclusion causes a recovery and retries (thus seriously affecting
* the driver performance).
*/
#define SCSA2USB_ATTRS_REDUCED_CMD \
/* max inquiry length */
/* page code of scsi mode page */
#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
/*
* PM support
*/
typedef struct scsa2usb_power {
/* device busy accounting */
int scsa2usb_pm_busy;
/* this is the bit mask of the power states that device has */
/* current power level the device is in */
/*
* CPR support:
* keep track of the last command issued to the drive. If it
* was TUR or EJECT then allow issuing a CPR suspend.
*/
typedef struct scsa2usb_last_cmd {
/* this is the cdb of the last command issued */
/* this is the status of the last command issued */
/*
* override values
* These values may be set in scsa2usb.conf for particular devices
*/
typedef struct scsa2usb_ov {
int vid; /* vendor id */
int pid; /* product id */
int rev; /* revision */
int subclass; /* subclass override */
int protocol; /* protocol override */
int pmoff; /* power management override */
int fake_removable; /* removable device override */
int no_modesense; /* no mode sense */
int reduced_cmd_support;
/*
* Per bulk device "state" data structure.
*/
typedef struct scsa2usb_state {
int scsa2usb_instance; /* Instance number */
int scsa2usb_dev_state; /* USB device state */
int scsa2usb_flags; /* Per instance flags */
int scsa2usb_intfc_num; /* Interface number */
int scsa2usb_transport_busy; /* ugen/sd traffic */
/* waitQ list */
/* store devinfo per LUN */
/* store inquiry per LUN */
/* sector size */
/* total sectors */
/* sector size */
/* conf file override values */
char *scsa2usb_override_str;
/* suppress repetitive disconnect warnings */
/* READY sense data */
/* for warlock */
/* scsa2usb_pipe_state values */
/* pkt xfer state machine */
#define SCSA2USB_PKT_NONE 0 /* device is idle */
/* scsa2usb_flags values */
/* scsa2usb_cmd_protocol values */
#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))
/* check if it is ok to access the device and send command to it */
#define SCSA2USB_DEVICE_ACCESS_OK(s) \
((s)->scsa2usb_dev_state == USB_DEV_ONLINE)
/* check if we are in any reset */
#define SCSA2USB_IN_RESET(s) \
(((s)->scsa2usb_pipe_state & SCSA2USB_PIPE_DEV_RESET) != 0)
/* check if the device is busy */
#define SCSA2USB_BUSY(s) \
(((s)->scsa2usb_cur_pkt) || \
((s)->scsa2usb_pipe_state != SCSA2USB_PIPE_NORMAL) || \
((s)->scsa2usb_pkt_state != SCSA2USB_PKT_NONE))
/* check if we're doing cpr */
#define SCSA2USB_CHK_CPR(s) \
(((s)->scsa2usb_dev_state == USB_DEV_SUSPENDED))
/* check if we're either paniced or in cpr state */
#define SCSA2USB_CHK_PANIC_CPR(s) \
(ddi_in_panic() || SCSA2USB_CHK_CPR(s))
/* reset scsa2usb state after pkt_comp is called */
#define SCSA2USB_RESET_CUR_PKT(s) \
(s)->scsa2usb_cur_pkt = NULL; \
(s)->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
/* print a panic sync message to the console */
#define SCSA2USB_PRINT_SYNC_MSG(m, s) \
if ((m) == B_TRUE) { \
"syncing not supported"); \
(m) = B_FALSE; \
}
/* Cancel callbacks registered during attach time */
#define SCSA2USB_CANCEL_CB(id) \
if ((id)) { \
(void) callb_delete((id)); \
(id) = 0; \
}
/* Set SCSA2USB_PKT_DO_COMP state if there is active I/O */
#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)) { \
}
#define SCSA2USB_FREE_BULK_REQ(req) \
if ((req)) { \
}
/* SCSA related */
#define PKT_PRIV_LEN 16
#define PKT_DEFAULT_TIMEOUT 5
/*
* auto request sense
*/
/* transport related */
#define SCSA2USB_JUST_ACCEPT 0
#define SCSA2USB_TRANSPORT 1
#define SCSA2USB_REJECT -1
/*
* The scsa2usb_cpr_info data structure is used for cpr related
* callbacks. It is used for panic callbacks as well.
*/
typedef struct scsa2usb_cpr {
/*
* The scsa2usb_cmd data structure is defined here. It gets
* initialized per command that is sent to the device.
*/
typedef struct scsa2usb_cmd {
int cmd_scblen; /* status length */
int cmd_tag; /* tag */
int cmd_timeout; /* copy of pkt_time */
/* used in multiple xfers */
int cmd_lba; /* current xfer lba */
int cmd_done; /* command done? */
int cmd_blksize; /* block size */
/* for warlock */
/* scsa2usb_cdb position of fields in CDB */
#define SCSA2USB_OPCODE 0 /* Opcode field */
/* macros to calculate LBA for 6/10/12-byte commands */
#define SCSA2USB_LBA_6BYTE(pkt) \
#define SCSA2USB_LEN_10BYTE(pkt) \
#define SCSA2USB_LBA_10BYTE(pkt) \
#define SCSA2USB_LEN_12BYTE(pkt) \
#define SCSA2USB_LBA_12BYTE(pkt) \
/* macros to convert a pkt to cmd and vice-versa */
/* bulk pipe default timeout value - how long the command to be tried? */
/* drain timeout in seconds on the work thread */
#define SCSA2USB_DRAIN_TIMEOUT 60
/* scsa2usb pkt xfer status phase retry times */
#define SCSA2USB_STATUS_RETRIES 3
/*
* limit on the number of requests that can be queued per LUN:
* 3 for untagged queueing, 1 for scsiwatch and a margin of 2
*/
#define SCSA2USB_MAX_REQ_PER_LUN 6
/*
* The following data structure is used to save the values returned
* by the READ_CAPACITY command. lba is the max allowed logical block
* address and blen is max allowed block size.
*/
typedef struct scsa2usb_read_cap {
#define SCSA2USB_MK_32BIT(a, b, c, d) \
(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
/* position of fields for SCMD_READ_CD CDB */
/* macro to calculate LEN for SCMD_READ_CD command */
#define SCSA2USB_LEN_READ_CD(pkt) \
/* Figure out Block Size before issuing a WRITE to CD-RW device */
#define SCSA2USB_VALID_CDRW_BLKSZ(blksz) \
((blksz) == 0))
/* debug and error msg logging */
#ifdef DEBUG
#define SCSA2USB_PRINT_CDB scsa2usb_print_cdb
#else
#define SCSA2USB_PRINT_CDB 0 &&
#endif
/* ugen support */
#define SCSA2USB_MINOR_UGEN_BITS_MASK 0xff
#define SCSA2USB_MINOR_INSTANCE_SHIFT 8
#define SCSA2USB_MINOR_TO_INSTANCE(minor) \
(((minor) & SCSA2USB_MINOR_INSTANCE_MASK) >> \
#ifdef __cplusplus
}
#endif
#endif /* _SYS_USB_SCSA2USB_H */