OpenSolaris_b135/lib/fm/libdiskstatus/common/ds_scsi.h

Compare this file to the similar file:
Show the results in this format:

/*
 * 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
 * or http://www.opensolaris.org/os/licensing.
 * 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 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_DS_SCSI_H
#define	_DS_SCSI_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <sys/types.h>
#include <sys/byteorder.h>
#include <sys/scsi/scsi.h>

#include "ds_impl.h"

#ifdef	__cplusplus
extern "C" {
#endif

#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
#error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif

/*
 * Log page structures
 */
#pragma pack(1)

typedef struct scsi_log_header {
#if defined(_BIT_FIELDS_LTOH)
	uint8_t		lh_code : 6,
			__reserved : 2;
#else
	uint8_t		__reserved : 2,
			lh_code : 6;
#endif
	uint8_t		__reserved2;
	uint16_t	lh_length;
} scsi_log_header_t;

typedef struct scsi_log_parameter_header {
	uint16_t	lph_param;
#if defined(_BIT_FIELDS_LTOH)
	uint8_t		lph_lp	: 1,
			lph_lbin : 1,
			lph_tmc : 2,
			lph_etc	: 1,
			lph_tsd	: 1,
			lph_ds	: 1,
			lph_du	: 1;
#else
	uint8_t		lph_du	: 1,
			lph_ds	: 1,
			lph_tsd	: 1,
			lph_etc	: 1,
			lph_tmc	: 2,
			lph_lbin : 1,
			lph_lp	: 1;
#endif
	uint8_t		lph_length;
} scsi_log_parameter_header_t;

typedef struct scsi_supported_log_pages {
	scsi_log_header_t	slp_hdr;
	uchar_t			slp_pages[1];
} scsi_supported_log_pages_t;

typedef struct scsi_ie_log_param {
	scsi_log_parameter_header_t	ie_hdr;
	uchar_t				ie_asc;
	uchar_t				ie_ascq;
} scsi_ie_log_param_t;

/*
 * The SCSI-3 SPC document states that IE log page (0x2F) parameter 0
 * must have a length of at least 4 (including the length byte).
 */
#define	LOGPARAM_IE_MIN_LEN		2	/* the asc and ascq fields */

#define	INVALID_TEMPERATURE		0xff

#define	LOGPARAM_IE			0x0000

typedef struct scsi_temp_log_param {
	scsi_log_parameter_header_t	t_hdr;
	uchar_t				__reserved;
	uchar_t				t_temp;
} scsi_temp_log_param_t;

typedef struct scsi_selftest_log_param {
	scsi_log_parameter_header_t	st_hdr;
#if defined(_BIT_FIELDS_LTOH)
	uint8_t		st_results	: 4,
			__reserved1	: 1,
			st_testcode	: 3;
#else
	uint8_t		st_testcode	: 3,
			__reserved1	: 1,
			st_results	: 4;
#endif
	uint8_t		st_number;
	uint16_t	st_timestamp;
	uint64_t	st_lba;
#if defined(_BIT_FIELDS_LTOH)
	uint8_t		st_sensekey	: 4,
			__reserved2	: 4;
#else
	uint8_t		__reserved2	: 4,
			st_sensekey	: 4;
#endif
	uint8_t		st_asc;
	uint8_t		st_ascq;
	uint8_t		st_vendor;
} scsi_selftest_log_param_t;

/* The results field of the self-test log parameter */
#define	SELFTEST_OK			0x0
#define	SELFTEST_ABORT_REQUEST		0x1
#define	SELFTEST_ABORT_OTHER		0x2
#define	SELFTEST_FAILURE_INCOMPLETE	0x3
#define	SELFTEST_FAILURE_SEG_UNKNOWN	0x4
#define	SELFTEST_FAILURE_SEG_FIRST	0x5
#define	SELFTEST_FAILURE_SEG_SECOND	0x6
#define	SELFTEST_FAILURE_SEG_OTHER	0x7
#define	SELFTEST_INPROGRESS		0xf

#define	SELFTEST_COMPLETE(code)				\
	((code) == SELFTEST_OK ||			\
	((code) >= SELFTEST_FAILURE_INCOMPLETE &&	\
	((code) <= SELFTEST_FAILURE_SEG_OTHER)))

#define	LOGPARAM_TEMP_CURTEMP		0x0000
#define	LOGPARAM_TEMP_REFTEMP		0x0001

#define	LOGPARAM_TEMP_LEN	\
	(sizeof (scsi_temp_log_param_t) - \
	    sizeof (scsi_log_parameter_header_t))

/*
 * Mode sense/select page header information
 */
typedef struct scsi_ms_header {
	struct mode_header	ms_header;
	struct block_descriptor	ms_descriptor;
} scsi_ms_header_t;

typedef struct scsi_ms_header_g1 {
	struct mode_header_g1	ms_header;
	struct block_descriptor	ms_descriptor;
} scsi_ms_header_g1_t;

typedef struct scsi_ms_hdrs {
	int				ms_length;
	union {
		scsi_ms_header_t	g0;
		scsi_ms_header_g1_t	g1;
	} ms_hdr;
} scsi_ms_hdrs_t;

typedef struct scsi_ie_page {
	struct mode_page ie_mp;
#if defined(_BIT_FIELDS_LTOH)
	uint8_t		ie_logerr	: 1,	/* Errors should be logged */
			__reserved1	: 1,
			ie_test		: 1,	/* Enable test gen of IEs */
			ie_dexcpt	: 1,	/* Disable exceptions */
			ie_ewasc	: 1,	/* Enable warning generation */
			ie_ebf		: 1,	/* enable backgrnd functions */
			__reserved2	: 1,
			ie_perf		: 1;	/* No delays during excptns */
	uint8_t		ie_mrie		: 4,	/* Method/reporting excptons */
			__reserved3	: 4;
#else
	uint8_t		ie_perf		: 1,	/* No delays during excptons */
			__reserved2	: 1,
			ie_ebf		: 1,	/* enable background funcs */
			ie_ewasc	: 1,	/* Enable warning generation */
			ie_dexcpt	: 1,	/* Disable exceptions */
			ie_test		: 1,	/* Enable test gen of IEs */
			__reserved1	: 1,
			ie_logerr	: 1;	/* Errors should be logged */
	uint8_t		__reserved3	: 4,
			ie_mrie		: 4;	/* Method of report excptns */
#endif
	uint32_t	ie_interval_timer;	/* reporting interval for IEs */
	uint32_t	ie_report_count;	/* # of times to report an IE */
} scsi_ie_page_t;

#pragma pack()

#define	MODEPAGE_INFO_EXCPT_LEN	(sizeof (scsi_ie_page_t))

#define	IEC_IE_ENABLED(ies) ((ies).ie_dexcpt == 0)
#define	IEC_IE_CHANGEABLE(ies) ((ies).ie_dexcpt == 1)
#define	IEC_MRIE_CHANGEABLE(ies) ((ies).ie_mrie == 0xf)
#define	IEC_PERF_CHANGEABLE(ies) ((ies).ie_perf == 1)
#define	IEC_EWASC_CHANGEABLE(ies) ((ies).ie_ewasc == 1)
#define	IEC_TEST_CHANGEABLE(ies) ((ies).ie_test == 1)
#define	IEC_RPTCNT_CHANGEABLE(ies) ((ies).ie_report_count == BE_32(0xffffffff))
#define	IEC_LOGERR_CHANGEABLE(ies) ((ies).ie_logerr == 1)

/*
 * Values for the MRIE field of the informational exceptions control mode page
 */
#define	IE_REPORT_NONE			0
#define	IE_REPORT_ASYNCH		1
#define	IE_REPORT_UNIT_ATTN		2
#define	IE_REPORT_RECOV_ERR_COND	3
#define	IE_REPORT_RECOV_ERR_ALWAYS	4
#define	IE_REPORT_NO_SENSE		5
#define	IE_REPORT_ON_REQUEST		6

/*
 * Constants in support of the CONTROL MODE mode page (page 0xA)
 */
#define	MODEPAGE_CTRL_MODE_LEN	(sizeof (struct mode_control_scsi3))
#define	GLTSD_CHANGEABLE(chg)	((chg).gltsd == 1)

#define	LOGPAGE_SELFTEST_MIN_PARAM_CODE	0x0001
#define	LOGPAGE_SELFTEST_MAX_PARAM_CODE	0x0014

#define	LOGPAGE_SELFTEST_PARAM_LEN \
	((sizeof (scsi_selftest_log_param_t)) - \
	    (sizeof (scsi_log_parameter_header_t)))

/*
 * Macro to extract the length of a mode sense page
 * as returned by a target.
 */
#define	MODESENSE_PAGE_LEN(p)	(((int)((struct mode_page *)p)->length) + \
					sizeof (struct mode_page))

/*
 * Mode Select options
 */
#define	MODE_SELECT_SP			0x01
#define	MODE_SELECT_PF			0x10


/*
 * Mode Sense Page Control
 */
#define	PC_CURRENT		(0 << 6)
#define	PC_CHANGEABLE		(1 << 6)
#define	PC_DEFAULT		(2 << 6)
#define	PC_SAVED		(3 << 6)

/*
 * Log Sense Page Control
 */
#define	PC_CUMULATIVE		(1 << 6)

/*
 * LOG page codes
 */
#define	LOGPAGE_SUPP_LIST	0x00
#define	LOGPAGE_TEMP		0x0d
#define	LOGPAGE_SELFTEST	0x10
#define	LOGPAGE_IE		0x2f

/* ASC constants */
#define	ASC_INVALID_OPCODE				0x20
#define	ASC_INVALID_CDB_FIELD				0x24
#define	ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED	0x5d

/* ASCQ constants */
#define	ASCQ_INVALID_OPCODE	0

/* Error tests */
#define	SCSI_INVALID_OPCODE(s, a, aq) \
	(((s) == KEY_ILLEGAL_REQUEST) && ((a) == ASC_INVALID_OPCODE) && \
	((aq) == ASCQ_INVALID_OPCODE))

#define	MODE_PAGE_UNSUPPORTED(s, a, aq) \
	(((s) == KEY_ILLEGAL_REQUEST) && ((a) == ASC_INVALID_CDB_FIELD))

/* command length to use */
#define	MODE_CMD_LEN_UNKNOWN		0
#define	MODE_CMD_LEN_6			1
#define	MODE_CMD_LEN_10			2

/* supported modepages bitmask */
#define	MODEPAGE_SUPP_IEC		0x1

/* supported logpages bitmask */
#define	LOGPAGE_SUPP_IE			0x1
#define	LOGPAGE_SUPP_TEMP		0x2
#define	LOGPAGE_SUPP_SELFTEST		0x4

#define	MSG_BUFLEN	256

/*
 * For SCSI commands which want to accept arbitrary length responses, we need to
 * allocate an appropriate sized buffer.  The maximum length is USHRT_MAX,
 * because some devices return nothing if the buffer length is too big.
 */
#define	MAX_BUFLEN(type)	(USHRT_MAX - sizeof (type))

extern ds_transport_t ds_scsi_uscsi_transport;
extern ds_transport_t ds_scsi_sim_transport;

#ifdef	__cplusplus
}
#endif

#endif	/* _DS_SCSI_H */