sata.h revision 7a70ede882eacbae00c8d5209afb443e7755684c
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SATA_H
#define _SATA_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Generic SATA Host Adapter Implementation
*/
/* Statistics counters */
struct sata_port_stats {
};
typedef struct sata_port_stats sata_port_stats_t;
struct sata_drive_stats {
typedef struct sata_drive_stats sata_drive_stats_t;
struct sata_ctrl_stats {
};
typedef struct sata_ctrl_stats sata_ctrl_stats_t;
/*
* SATA HBA instance info structure
*/
struct sata_hba_inst {
/*
* HBA event flags:
* SATA_EVNT_MAIN
* SATA_EVNT_PWR_LEVEL_CHANGED
* SATA_EVNT_SKIP
*/
/*
* DEVCTL open flag:
* SATA_DEVCTL_SOPENED
* SATA_DEVCTL_EXOPENED
*/
/* 0 - not completed */
/* 1 - completed */
};
typedef struct sata_hba_inst sata_hba_inst_t;
/*
* SATA controller's device port info and state.
* This structure is pointed to by the sata_hba_inst.satahba_dev_port[x]
* where x is a device port number.
* cport_state holds port state flags, defined in sata_hba.h file.
* cport_event_flags holds SATA_EVNT_* flags defined in this file and in
* sata_hba.h file.
* cport_dev_type holds SATA_DTYPE_* types defined in sata_hba.h file.
*/
struct sata_cport_info {
/*
* Port state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_PSTATE_PWRON
* SATA_PSTATE_PWROFF
* SATA_PSTATE_SHUTDOWN
* SATA_PSTATE_FAILED
*/
/*
* Port event flags:
* SATA_EVNT_DEVICE_ATTACHED
* SATA_EVNT_DEVICE_DETACHED
* SATA_EVNT_LINK_LOST
* SATA_EVNT_LINK_ESTABLISHED
* SATA_EVNT_PORT_FAILED
* SATA_EVNT_PWR_LEVEL_CHANGED
*/
/*
* Attached device type:
* SATA_DTYPE_NONE
* SATA_DTYPE_ATADISK
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPINONCD
* SATA_DTYPE_PMULT
* SATA_DTYPE_UNKNOWN
*/
union {
} cport_devp;
/* lbolt value at link lost */
};
typedef struct sata_cport_info sata_cport_info_t;
/*
* Attached SATA drive info and state.
* This structure is pointed to by sata_cport_info's cport_sata_drive field
* when a drive is attached directly to a controller device port.
*/
struct sata_drive_info {
/*
* Drive state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_DSTATE_PWR_ACTIVE
* SATA_DSTATE_PWR_IDLE
* SATA_DSTATE_RESET
* SATA_DSTATE_FAILED
*/
/*
* drive event flags:
* SATA_EVNT_DRIVE_RESET
*/
/*
* Attached device type:
* SATA_DTYPE_ATADISK
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPINONCD
*/
};
typedef struct sata_drive_info sata_drive_info_t;
/* Port Multiplier & host port info and state */
struct sata_pmult_info {
/*
* PMult state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_PSTATE_FAILED
*/
};
typedef struct sata_pmult_info sata_pmult_info_t;
/* Port Multiplier's device port info & state */
struct sata_pmport_info {
/*
* Port state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_PSTATE_PWRON
* SATA_PSTATE_PWROFF
* SATA_PSTATE_SHUTDOWN
* SATA_PSTATE_FAILED
*/
/*
* Port event flags:
* SATA_EVNT_DEVICE_ATTACHED
* SATA_EVNT_DEVICE_DETACHED
* SATA_EVNT_LINK_LOST
* SATA_EVNT_LINK_ESTABLISHED
* SATA_EVNT_PORT_FAILED
* SATA_EVNT_PWR_LEVEL_CHANGED
*/
/*
* Attached device type:
* SATA_DTYPE_NONE
* SATA_DTYPE_ATADISK
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPINONCD
* SATA_DTYPE_UNKNOWN
*/
/* lbolt value at link lost */
};
typedef struct sata_pmport_info sata_pmport_info_t;
/*
* Port SSTATUS register (sata_port_scr sport_sstatus field).
* Link bits are valid only in port active state.
*/
/*
* Port state clear mask (cport_state and pmport_state fields).
* SATA_PSTATE_SHUTDOWN and power state are preserved.
*/
#define SATA_PORT_STATE_CLEAR_MASK (~(SATA_PSTATE_SHUTDOWN))
/*
* Valid i.e.supported device types mask (cport_dev_type, satadrv_type,
* pmult_dev_type fields).
*/
/*
* Device feature_support (satadrv_features_support)
*/
#define SATA_DEV_F_DMA 0x01
#define SATA_DEV_F_LBA28 0x02
#define SATA_DEV_F_LBA48 0x04
#define SATA_DEV_F_NCQ 0x08
#define SATA_DEV_F_SATA1 0x10
#define SATA_DEV_F_SATA2 0x20
/*
* Drive settings flags (satdrv_settings)
*/
/*
* Internal event and flags.
* These flags are set in the *_event_flags fields of various structures.
* Events and lock flags defined below are used internally by the
* SATA framework (they are not reported by SATA HBA drivers).
*/
#define SATA_EVNT_MAIN 0x80000000
#define SATA_EVNT_SKIP 0x40000000
#define SATA_EVNT_INPROC_DEVICE_RESET 0x08000000
#define SATA_EVNT_CLEAR_DEVICE_RESET 0x04000000
/*
* Lock flags - used to serialize configuration operations
* on ports and devices.
* SATA_EVNT_LOCK_PORT_BUSY is set by event daemon to prevent
* simultaneous cfgadm operations.
* SATA_APCTL_LOCK_PORT_BUSY is set by cfgadm ioctls to prevent
* simultaneous event processing.
*/
#define SATA_EVNT_LOCK_PORT_BUSY 0x00800000
#define SATA_APCTL_LOCK_PORT_BUSY 0x00400000
/* Mask for port events */
#define SATA_EVNT_PORT_EVENTS (SATA_EVNT_DEVICE_ATTACHED | \
/* Mask for drive events */
/* Delays and timeounts definitions */
#define SATA_DEVICE_IDENTIFY_RETRY 2
/*
* sata_scsi's hba_open_flag: field indicating open devctl instance.
* 0 = closed, 1 = shared open, 2 = exclusive open.
*/
#define SATA_DEVCTL_CLOSED 0
#define SATA_DEVCTL_SOPENED 1
#define SATA_DEVCTL_EXOPENED 2
/*
* sata_pkt_txlate structure contains info about resources allocated
* for the packet
* Address of this structure is stored in scsi_pkt.pkt_ha_private and
* in sata_pkt.sata_hba_private fields, so all three strucures are
* cross-linked, with sata_pkt_txlate as a centerpiece.
*/
typedef struct sata_pkt_txlate {
struct sata_hba_inst *txlt_sata_hba_inst;
struct scsi_pkt *txlt_scsi_pkt;
struct sata_pkt *txlt_sata_pkt;
/* cookies in the current DMA window */
/* procesed dma cookies in current DMA win */
int txlt_dma_cookie_list_len; /* alloc list len */
int txlt_num_dma_cookies; /* dma cookies in list */
/* temporary buffer access handle */
/*
* Additional scsi sense code definitions.
* These definition should eventually be moved to scsi header files.
*/
#define SD_SCSI_NO_ADD_SENSE 0x00
#define SD_SCSI_LU_NOT_READY 0x04
#define SD_SCSI_WRITE_ERROR 0x0c
#define SD_SCSI_UNREC_READ_ERROR 0x11
#define SD_SCSI_INVALID_COMMAND_CODE 0x20
#define SD_SCSI_LBA_OUT_OF_RANGE 0x21
#define SD_SCSI_INVALID_FIELD_IN_CDB 0x24
#define SD_SCSI_INVALID_FIELD_IN_PARAMETER_LIST 0x26
#define SD_SCSI_SAVING_PARAMS_NOT_SUP 0x39
/* SCSI defs missing from scsi headers */
/* Missing from sys/scsi/generic/commands.h */
#define SCMD_SYNCHRONIZE_CACHE_G1 0x91
/*
*/
/*
* Macros for accessing various structure fields
*
*/
#define SATA_TRAN(sata_hba_inst) \
#define SATA_DIP(sata_hba_inst) \
#define SATA_NUM_CPORTS(sata_hba_inst) \
#define SATA_QDEPTH(sata_hba_inst) \
#define SATA_FEATURES(sata_hba_inst) \
#define SATA_DMA_ATTR(sata_hba_inst) \
#define SATA_START_FUNC(sata_hba_inst) \
#define SATA_ABORT_FUNC(sata_hba_inst) \
#define SATA_RESET_DPORT_FUNC(sata_hba_inst) \
#define SATA_PORT_DEACTIVATE_FUNC(sata_hba_inst) \
NULL : \
#define SATA_PORT_ACTIVATE_FUNC(sata_hba_inst) \
NULL : \
#define SATA_PROBE_PORT_FUNC(sata_hba_inst) \
#define SATA_SELFTEST_FUNC(sata_hba_inst) \
#define SATA_CPORTINFO_DRV_TYPE(cportinfo) \
#define SATA_CPORTINFO_DRV_INFO(cportinfo) \
#define SATA_CPORTINFO_PMULT_INFO(cportinfo) \
#define SATA_TXLT_HBA_INST(spx) \
#define SATA_TXLT_CPORT(spx) \
#define SATA_TXLT_CPORT_MUTEX(spx) \
#define SATA_TXLT_TASKQ(spx) \
/*
* Minor number construction for devctl and attachment point nodes.
* All necessary information has to be encoded in NBITSMINOR32 bits.
*
* Devctl node minor number:
* ((controller_instance << SATA_CNTRL_INSTANCE_SHIFT) | SATA_DEVCTL_NODE)
*
* Attachment point node minor number has to include controller
* instance (7 bits), controller port number (5 bits) and port multiplier
* device port number (4 bits) and port multiplier device port
* indicator (1 bit). Additionally, a single bit is used to
* differentiate between attachment point node and device control node.
*
* Attachment point minor number:
* ((controller_instance << SATA_CNTRL_INSTANCE_SHIFT) | SATA_AP_NODE |
* [(port_multiplier_device_port << SATA_PMULT_PORT_SHIFT) | SATA_PMULT_AP] |
* (controller_port))
*
* 17 bits are used (if 64 instances of controllers are expected)
* bit 18 is reserved for future use.
*
* --------------------------------------------------------
* |17|16|15|14|13|12|11|10 |09|08|07|06|05|04|03|02|01|00|
* --------------------------------------------------------
* | R| c| c| c| c| c| c|a/d|pm|pp|pp|pp|pp|cp|cp|cp|cp|cp|
* --------------------------------------------------------
* Where:
* cp - device port number on the HBA SATA controller
* pp - device port number on the port multiplier
* pm - 0 - target attached to controller device port
* 1 - target attached to port multiplier's device port
* a/d - 0 - devctl node
* 1 - attachment point node
* c - controller number
* R - reserved bit
*/
#define SATA_PMULT_PORT_SHIFT 5
#define SATA_CNTRL_INSTANCE_SHIFT 11
/* Macro for creating devctl node minor number */
#define SATA_MAKE_DEVCTL_MINOR(controller_instance) \
((controller_instance << SATA_CNTRL_INSTANCE_SHIFT) | \
/* Macro for creating an attachment point node minor number */
(((cntrl_instance) << SATA_CNTRL_INSTANCE_SHIFT) | \
SATA_AP_NODE | SATA_PMULT_AP | \
(((cntrl_instance) << SATA_CNTRL_INSTANCE_SHIFT) | \
SATA_AP_NODE | cport))
/* Macro retrieving controller number from a minor number */
#define SATA_MINOR2INSTANCE(minor) \
/*
* Macro for creating an attachment point number from sata address.
* Address qualifier has to be one of:
* SATA_ADDR_DCPORT, SATA_ADDR_DPMPORT, SATA_ADDR_CPORT or SATA_ADDR_PMPORT
*/
(cport))
/*
* SCSI target number format
*
* -------------------------------
* | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| Bit number
* -------------------------------
* |pm|pp|pp|pp|pp|cp|cp|cp|cp|cp|
* -------------------------------
* Where:
* cp - device port number on the HBA SATA controller
* pp - device port number on the port multiplier
* pm - 0 - target attached to controller device port
* 1 - target attached to port multiplier's device port
*/
/* SATA ports to SCSI target number translation */
#define SCSI_TO_SATA_CPORT(scsi_target) \
#define SCSI_TO_SATA_PMPORT(scsi_target) \
#define SCSI_TO_SATA_ADDR_QUAL(scsi_target) \
/* Debug flags */
#if DEBUG
#define SATA_DEBUG
#define SATA_DBG_SCSI_IF 1
#define SATA_DBG_HBA_IF 2
#define SATA_DBG_NODES 4
#define SATA_DBG_IOCTL_IF 8
#define SATA_DBG_EVENTS 0x10
#define SATA_DBG_EVENTS_PROC 0x20
#define SATA_DBG_EVENTS_PROCPST 0x40
#define SATA_DBG_EVENTS_CNTRL 0x80
#define SATA_DBG_EVENTS_DAEMON 0x100
#define SATA_DBG_DMA_SETUP 0x400
extern int sata_debug_flag;
/* Debug macros */
if (sata_debug_flags & (flag)) { \
}
if (sata_debug_flags & (flag)) { \
}
if (sata_debug_flags & (flag)) { \
}
#else
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SATA_H */