OpenSolaris_b135/cmd/iscsi/iscsitgtd/t10_spc.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 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _T10_SPC_H
#define	_T10_SPC_H

#ifdef __cplusplus
extern "C" {
#endif

/*
 * []------------------------------------------------------------------[]
 * | SPC-3								|
 * []------------------------------------------------------------------[]
 */

/*
 * FIXED_SENSE_ADDL_INFO_LEN is the length of INFORMATION field
 * in fixed format sense data
 */
#define	FIXED_SENSE_ADDL_INFO_LEN 0xFFFFFFFF
#define	INFORMATION_SENSE_DESCR sizeof (struct scsi_information_sense_descr)

#include <sys/types.h>
#include <netinet/in.h>
#include <sys/scsi/generic/inquiry.h>
#include <sys/scsi/generic/mode.h>

/*
 * SPC Command Functions
 */
void spc_tur(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
void spc_request_sense(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
void spc_unsupported(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
void spc_inquiry(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_mselect(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_mselect_data(t10_cmd_t *cmd, emul_handle_t id, size_t offset,
    char *data, size_t data_len);
void spc_report_luns(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_report_tpgs(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_msense(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_startstop(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_send_diag(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);

/*
 * SPC Support Functions
 */
void spc_cmd_offline(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
void spc_sense_create(struct t10_cmd *cmd, int sense_key, int addl_sense_len);
void spc_sense_ascq(struct t10_cmd *cmd, int asc, int ascq);
void spc_sense_info(t10_cmd_t *cmd, uint64_t info);
void spc_sense_flags(t10_cmd_t *cmd, int flags);
void spc_sense_raw(t10_cmd_t *cmd, uchar_t *sense_buf, size_t sense_len);
Boolean_t spc_decode_lu_addr(uint8_t *buf, int len, uint32_t *val);
Boolean_t spc_encode_lu_addr(uint8_t *buf, int select_field, uint32_t lun);

/*
 * SPC flags to use when setting various sense code flags
 */
#define	SPC_SENSE_EOM	0x01
#define	SPC_SENSE_FM	0x02
#define	SPC_SENSE_ILI	0x04

/*
 * []------------------------------------------------------------------[]
 * | SPC-3, revision 21c -- ASC/ASCQ values				|
 * | The full tables can be found in Appendix D (numerical order) or	|
 * | section 4.5.6 (alphabetical order). There are close to fifteen	|
 * | pages of values which will not be included here. Only those used	|
 * | by the code.							|
 * []------------------------------------------------------------------[]
 */
#define	SPC_ASC_FM_DETECTED	0x00 /* file-mark detected */
#define	SPC_ASCQ_FM_DETECTED	0x01

#define	SPC_ASC_EOP		0x00 /* end-of-partition/medium detected */
#define	SPC_ASCQ_EOP		0x02

#define	SPC_ASC_IN_PROG		0x04
#define	SPC_ASCQ_IN_PROG	0x07

#define	SPC_ASC_WRITE_ERROR	0x0c
#define	SPC_ASCQ_WRITE_ERROR	0x00

#define	SPC_ASC_PARAM_LIST_LEN	0x1a /* Parameter List Length Error */
#define	SPC_ASCQ_PARAM_LIST_LEN	0x00

#define	SPC_ASC_MISCOMPARE	0x1d
#define	SPC_ASCQ_MISCOMPARE	0x00

#define	SPC_ASC_INVALID_LU	0x20
#define	SPC_ASCQ_INVALID_LU	0x09

#define	SPC_ASC_BLOCK_RANGE	0x21
#define	SPC_ASCQ_BLOCK_RANGE	0x00

#define	SPC_ASC_INVALID_FIELD_IN_PARAMETER_LIST		0x26
#define	SPC_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST	0x00

#define	SPC_ASC_INVALID_CDB	0x24
#define	SPC_ASCQ_INVALID_CDB	0x00

#define	SPC_ASC_PARAMETERS_CHANGED	0x2a
#define	SPC_ASCQ_RES_PREEMPTED	0x03
#define	SPC_ASCQ_RES_RELEASED	0x04

#define	SPC_ASC_PWR_RESET	0x29
#define	SPC_ASCQ_PWR_RESET	0x00

#define	SPC_ASC_PWR_ON		0x29
#define	SPC_ASCQ_PWR_ON		0x01

#define	SPC_ASC_BUS_RESET	0x29
#define	SPC_ASCQ_BUS_RESET	0x02

#define	SPC_ASC_CAP_CHANGE	0x2a
#define	SPC_ASCQ_CAP_CHANGE	0x09

#define	SPC_ASC_DATA_PATH	0x41
#define	SPC_ASCQ_DATA_PATH	0x00

#define	SPC_ASC_MEMORY_OUT_OF	0x55 /* Auxillary Memory Out Of Space */
#define	SPC_ASCQ_MEMORY_OUT_OF	0x00
#define	SPC_ASCQ_RESERVATION_FAIL 0x02


/*
 * []------------------------------------------------------------------[]
 * | SAM-3, revision 14, section 5.2 - Command descriptor block (CDB)	|
 * |									|
 * | "All CDBs shall contain a CONTROL byte (see table 21). The		|
 * | location of the CONTROL byte within a CDB depends on the CDB	|
 * | format (see SPC-3)."						|
 * |									|
 * | bits	meaning							|
 * | 6-7	vendor specific (we don't use so must be zero)		|
 * | 3-5	reserved must be zero					|
 * | 2		NACA (currently we don't support so must be zero)	|
 * | 1		Obsolete						|
 * | 0		Link (currently we don't support so must be zero)	|
 * |									|
 * | So, this means the control byte must be zero and therefore if	|
 * | this macro returns a non-zero value the emulation code should	|
 * | return a CHECK CONDITION with status set to ILLEGAL REQUEST	|
 * | and the additional sense code set to INVALID FIELD IN CDB.		|
 * |									|
 * | In the future this will likely change with support routines	|
 * | added for dealing with NACA and Linked commands.			|
 * []------------------------------------------------------------------[]
 */
#define	SAM_CONTROL_BYTE_RESERVED(byte)	(byte)

/* ---- Disable Block Descriptors ---- */
#define	SPC_MODE_SENSE_DBD	0x8

#define	SPC_GROUP4_SERVICE_ACTION_MASK	0x1f

#define	SPC_SEND_DIAG_SELFTEST	0x04

/*
 * []------------------------------------------------------------------[]
 * | SPC-3 revision 21c, section 6.4 -- INQUIRY				|
 * | Various defines. The structure for the inquiry command can be	|
 * | found in /usr/include/sys/scsi/generic/inquiry.h			|
 * []------------------------------------------------------------------[]
 */
#define	SPC_INQUIRY_CODE_SET_BINARY	1
#define	SPC_INQUIRY_CODE_SET_ASCII	2
#define	SPC_INQUIRY_CODE_SET_UTF8	3

/* ---- Table 82: Inquiry Version ----  */
#define	SPC_INQ_VERS_NONE	0x00
#define	SPC_INQ_VERS_OBSOLETE	0x02
#define	SPC_INQ_VERS_SPC_1	0x03
#define	SPC_INQ_VERS_SPC_2	0x04
#define	SPC_INQ_VERS_SPC_3	0x05

/* ---- INQUIRY Response Data Format field ---- */
#define	SPC_INQ_RDF		0x02	/* all other values are OBSOLETE */

/*
 * Table 85 -- Version descriptor values
 * There are many, many different values available, so we'll only include
 * those that we actually use.
 */
#define	SPC_INQ_VD_SAM3		0x0076
#define	SPC_INQ_VD_SPC3		0x0307
#define	SPC_INQ_VD_SBC2		0x0322
#define	SPC_INQ_VD_SSC3		0x0400
#define	SPC_INQ_VD_OSD		0x0355

/* --- Version Descriptor length details --- */
#define	SPC_INQ_VD_IDX		0x3A
#define	SPC_INQ_VD_LEN		0x10

#define	SPC_INQ_PAGE0		0x00
#define	SPC_INQ_PAGE80		0x80
#define	SPC_INQ_PAGE83		0x83
#define	SPC_INQ_PAGE86		0x86

/* ---- REPORT LUNS select report has valid values of 0, 1, or 2 ---- */
#define	SPC_RPT_LUNS_SELECT_MASK	0x03

/* ---- Table 293: IDENTIFIER TYPE field ---- */
#define	SPC_INQUIRY_ID_TYPE_T10ID	1	/* ref 7.6.4.3 */
#define	SPC_INQUIRY_ID_TYPE_EUI		2	/* ref 7.6.4.4 */
#define	SPC_INQUIRY_ID_TYPE_NAA		3	/* ref 7.6.4.5 */
#define	SPC_INQUIRY_ID_TYPE_RELATIVE	4	/* ref 7.6.4.6 */
#define	SPC_INQUIRY_ID_TYPE_TARG_PORT	5	/* ref 7.6.4.7 */
#define	SPC_INQUIRY_ID_TYPE_LUN		6	/* ref 7.6.4.8 */
#define	SPC_INQUIRY_ID_TYPE_MD5		7	/* ref 7.6.4.9 */
#define	SPC_INQUIRY_ID_TYPE_SCSI	8	/* ref 7.6.4.10 */

/* ---- Table 292: ASSOCIATION field ----  */
#define	SPC_INQUIRY_ASSOC_LUN		0
#define	SPC_INQUIRY_ASSOC_TARGPORT	1
#define	SPC_INQUIRY_ASSOC_TARG		2

/* ---- Table 80: Peripheral qualifier ---- */
#define	SPC_INQUIRY_PERIPH_CONN		0
#define	SPC_INQUIRY_PERIPH_DISCONN	1
#define	SPC_INQUIRY_PERIPH_INVALID	3

/* ---- Table 256: PROTOCOL IDENTIFIER values ---- */
#define	SPC_INQUIRY_PROTOCOL_FC		0
#define	SPC_INQUIRY_PROTOCOL_PSCSI	1
#define	SPC_INQUIRY_PROTOCOL_SSA	2
#define	SPC_INQUIRY_PROTOCOL_IEEE1394	3
#define	SPC_INQUIRY_PROTOCOL_SCSIRDMA	4
#define	SPC_INQUIRY_PROTOCOL_ISCSI	5
#define	SPC_INQUIRY_PROTOCOL_SAS	6
#define	SPC_INQUIRY_PROTOCOL_ADT	7
#define	SPC_INQUIRY_PROTOCOL_ATA	8

#define	SPC_DEFAULT_TPG	1

/*
 * SPC-3, revision 21c, section 7.6.5
 * Extended INQUIRY Data VPD page
 */
typedef struct extended_inq_data {
	struct vpd_hdr	ei_hdr;
#if defined(_BIT_FIELDS_LTOH)
	uchar_t		ei_ref_chk	: 1,
			ei_app_chk	: 1,
			ei_grd_chk	: 1,
			ei_rto		: 1,
			ei_rsvd1	: 4;
	uchar_t		ei_simpsup	: 1,
			ei_ordsup	: 1,
			ei_headsup	: 1,
			ei_prior_sup	: 1,
			ei_group_sup	: 1,
			ei_rsvd2	: 3;
	uchar_t		ei_v_sup	: 1,
			ei_nv_sup	: 1,
			ei_rsvd3	: 6;
#elif defined(_BIT_FIELDS_HTOL)
	uchar_t		ei_ref_rsvd1	: 4,
			ei_rto		: 1,
			ei_grd_chk	: 1,
			ei_app_chk	: 1,
			ei_ref_chk	: 1;
	uchar_t		ei_rsvd2	: 2,
			ei_group_sup	: 1,
			ei_prior_sup	: 1,
			ei_headsup	: 1,
			ei_ordsup	: 1,
			ei_simpsup	: 1;
	uchar_t		ei_rsvd3	: 6,
			ei_nv_sup	: 1,
			ei_v_sup	: 1;
#else
#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif
	uchar_t		ei_rsv4[57];
} extended_inq_data_t;


/*
 * []------------------------------------------------------------------[]
 * | SPC-4 revision 1a, section 6.25 -- REPORT TARGET PORT GROUPS	|
 * | Structures and defines						|
 * []------------------------------------------------------------------[]
 */
/*
 * The service action must be set to 0x0A. This command is really a
 * MAINTENANCE_IN command with a specific service action.
 */
#define	SPC_MI_SVC_MASK		0x1f
#define	SPC_MI_SVC_RTPG		0x0a

/* ---- Table 167: Target port descriptor format ---- */
typedef struct rtpg_targ_desc {
	uchar_t		obsolete[2],
			rel_tpi[2];
} rtpg_targ_desc_t;

/* ---- Table 164: Target port group descript format ---- */
typedef struct rtpg_desc {
#if defined(_BIT_FIELDS_LTOH)
	uchar_t access_state	: 4,
				: 3,
		pref		: 1;
	uchar_t	ao_sup		: 1,
		an_sup		: 1,
		s_sup		: 1,
		u_sup		: 1,
				: 3,
		t_sup		: 1;
#elif defined(_BIT_FIELDS_HTOL)
	uchar_t	pref		: 1,
				: 3,
		access_state	: 4;
	uchar_t	t_sup		: 1,
				: 3,
		u_sup		: 1,
		s_sup		: 1,
		an_sup		: 1,
		ao_sup		: 1;
#else
#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif
	uchar_t			tpg[2],
				reserve_1,
				status_code,
				vendor_spec,
				tpg_cnt;
	rtpg_targ_desc_t	targ_list[1];
} rtpg_desc_t;

/* ---- Table 163: parameter data format. ---- */
typedef struct rtpg_data {
	uchar_t		len[4];
	rtpg_desc_t	desc_list[1];
} rtpg_hdr_t;

/*
 * []------------------------------------------------------------------[]
 * | SPC-3, revision 21c, section 6.6 -- LOG_SENSE			|
 * | Structure and defines						|
 * []------------------------------------------------------------------[]
 */
#define	SSC_LOG_SP		0x01 /* save parameters */
#define	SSC_LOG_PPC		0x02 /* parameter pointer control */
#define	SPC_LOG_PAGE_MASK	0x3f

/* ---- section 7.2.1, Table 192: Log Parameter ---- */
typedef struct spc_log_select_param {
	char	param_code[2];
#if defined(_BIT_FIELDS_LTOH)
	char	lp	: 1,	/* list parameter */
		lbin	: 1,
		tmc	: 2,	/* threshold met criteria */
		etc	: 1,	/* enable threshold comparison */
		tsd	: 1,	/* target save disable */
		ds	: 1,	/* disable save */
		du	: 1;	/* disable update */
#elif defined(_BIT_FIELDS_HTOL)
	char	du	: 1,	/* disable update */
		ds	: 1,	/* disable save */
		tsd	: 1,	/* target save disable */
		etc	: 1,	/* enable threshold comparison */
		tmc	: 2,	/* threshold met criteria */
		lbin	: 1,
		lp	: 1;	/* list parameter */
#else
#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif
	char	len;		/* length of bytes to follow */
} spc_log_select_param_t;

/* ---- section 7.2.12, table 218: Supported log pages ---- */
typedef struct spc_log_supported_pages {
	char	page_code,
		resvd,
		length[2],
		list[1];
} spc_log_supported_pages_t;

/*
 * []------------------------------------------------------------------[]
 * | SPC-3, revision 21c, section 6.9 -- MODE_SENSE			|
 * | Structures and defines						|
 * []------------------------------------------------------------------[]
 */
/* ---- Section 7.4.6, Table 241: Queue Algorithm Modifer field ---- */
#define	SPC_QUEUE_RESTRICTED		0x00
#define	SPC_QUEUE_UNRESTRICTED		0x01

/* ---- Section 7.4.11, Table 250: Information Controller Page ---- */
struct mode_info_ctrl {
	struct mode_page	mode_page;
	/*
	 * Currently we don't sent any of this information and it's set
	 * to zero's. We only care about the size.
	 */
	char			info_data[10];
};

#define	MODE_SENSE_PAGE3_CODE		0x03
#define	MODE_SENSE_PAGE4_CODE		0x04
#define	MODE_SENSE_CACHE		0x08
#define	MODE_SENSE_CONTROL		0x0a
#define	MODE_SENSE_COMPRESSION		0x0f
#define	MODE_SENSE_DEV_CONFIG		0x10
#define	MODE_SENSE_INFO_CTRL		0x1c
#define	MODE_SENSE_SEND_ALL		0x3f

/* -- Page Control Mask for Mode Sense -- */
#define	SPC_MODE_SENSE_PAGE_CODE_MASK	0x3f
#define	SPC_MODE_SENSE_PC_MASK		0xc0
#define	SPC_MODE_SENSE_PC_SHIFT		6

#define	SPC_PC_CURRENT_VALUES		0
#define	SPC_PC_MODIFIABLE_VALUES	1
#define	SPC_PC_DEFAULT_VALUES		2
#define	SPC_PC_SAVED_VALUES		3

#define	SCSI_REPORTLUNS_ADDRESS_SIZE			8
#define	SCSI_REPORTLUNS_ADDRESS_MASK			0xC0
#define	SCSI_REPORTLUNS_ADDRESS_PERIPHERAL		0x00
#define	SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE		0x40
#define	SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT		0x80
#define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_UNIT		0xC0
#define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_2B		0x00
#define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_4B		0x10
#define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_6B		0x20
#define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_8B		0x30
#define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_MASK		0x30
#define	SCSI_REPORTLUNS_SELECT_ALL			0x02

#ifdef __cplusplus
}
#endif

#endif /* _T10_SPC_H */