Home | History | Annotate | Download | only in iscsitgtd
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _T10_SPC_H
     28 #define	_T10_SPC_H
     29 
     30 #ifdef __cplusplus
     31 extern "C" {
     32 #endif
     33 
     34 /*
     35  * []------------------------------------------------------------------[]
     36  * | SPC-3								|
     37  * []------------------------------------------------------------------[]
     38  */
     39 
     40 /*
     41  * FIXED_SENSE_ADDL_INFO_LEN is the length of INFORMATION field
     42  * in fixed format sense data
     43  */
     44 #define	FIXED_SENSE_ADDL_INFO_LEN 0xFFFFFFFF
     45 #define	INFORMATION_SENSE_DESCR sizeof (struct scsi_information_sense_descr)
     46 
     47 #include <sys/types.h>
     48 #include <netinet/in.h>
     49 #include <sys/scsi/generic/inquiry.h>
     50 #include <sys/scsi/generic/mode.h>
     51 
     52 /*
     53  * SPC Command Functions
     54  */
     55 void spc_tur(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
     56 void spc_request_sense(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
     57 void spc_unsupported(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
     58 void spc_inquiry(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     59 void spc_mselect(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     60 void spc_mselect_data(t10_cmd_t *cmd, emul_handle_t id, size_t offset,
     61     char *data, size_t data_len);
     62 void spc_report_luns(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     63 void spc_report_tpgs(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     64 void spc_msense(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     65 void spc_startstop(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     66 void spc_send_diag(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     67 
     68 /*
     69  * SPC Support Functions
     70  */
     71 void spc_cmd_offline(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
     72 void spc_sense_create(struct t10_cmd *cmd, int sense_key, int addl_sense_len);
     73 void spc_sense_ascq(struct t10_cmd *cmd, int asc, int ascq);
     74 void spc_sense_info(t10_cmd_t *cmd, uint64_t info);
     75 void spc_sense_flags(t10_cmd_t *cmd, int flags);
     76 void spc_sense_raw(t10_cmd_t *cmd, uchar_t *sense_buf, size_t sense_len);
     77 Boolean_t spc_decode_lu_addr(uint8_t *buf, int len, uint32_t *val);
     78 Boolean_t spc_encode_lu_addr(uint8_t *buf, int select_field, uint32_t lun);
     79 
     80 /*
     81  * SPC flags to use when setting various sense code flags
     82  */
     83 #define	SPC_SENSE_EOM	0x01
     84 #define	SPC_SENSE_FM	0x02
     85 #define	SPC_SENSE_ILI	0x04
     86 
     87 /*
     88  * []------------------------------------------------------------------[]
     89  * | SPC-3, revision 21c -- ASC/ASCQ values				|
     90  * | The full tables can be found in Appendix D (numerical order) or	|
     91  * | section 4.5.6 (alphabetical order). There are close to fifteen	|
     92  * | pages of values which will not be included here. Only those used	|
     93  * | by the code.							|
     94  * []------------------------------------------------------------------[]
     95  */
     96 #define	SPC_ASC_FM_DETECTED	0x00 /* file-mark detected */
     97 #define	SPC_ASCQ_FM_DETECTED	0x01
     98 
     99 #define	SPC_ASC_EOP		0x00 /* end-of-partition/medium detected */
    100 #define	SPC_ASCQ_EOP		0x02
    101 
    102 #define	SPC_ASC_IN_PROG		0x04
    103 #define	SPC_ASCQ_IN_PROG	0x07
    104 
    105 #define	SPC_ASC_WRITE_ERROR	0x0c
    106 #define	SPC_ASCQ_WRITE_ERROR	0x00
    107 
    108 #define	SPC_ASC_PARAM_LIST_LEN	0x1a /* Parameter List Length Error */
    109 #define	SPC_ASCQ_PARAM_LIST_LEN	0x00
    110 
    111 #define	SPC_ASC_MISCOMPARE	0x1d
    112 #define	SPC_ASCQ_MISCOMPARE	0x00
    113 
    114 #define	SPC_ASC_INVALID_LU	0x20
    115 #define	SPC_ASCQ_INVALID_LU	0x09
    116 
    117 #define	SPC_ASC_BLOCK_RANGE	0x21
    118 #define	SPC_ASCQ_BLOCK_RANGE	0x00
    119 
    120 #define	SPC_ASC_INVALID_FIELD_IN_PARAMETER_LIST		0x26
    121 #define	SPC_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST	0x00
    122 
    123 #define	SPC_ASC_INVALID_CDB	0x24
    124 #define	SPC_ASCQ_INVALID_CDB	0x00
    125 
    126 #define	SPC_ASC_PARAMETERS_CHANGED	0x2a
    127 #define	SPC_ASCQ_RES_PREEMPTED	0x03
    128 #define	SPC_ASCQ_RES_RELEASED	0x04
    129 
    130 #define	SPC_ASC_PWR_RESET	0x29
    131 #define	SPC_ASCQ_PWR_RESET	0x00
    132 
    133 #define	SPC_ASC_PWR_ON		0x29
    134 #define	SPC_ASCQ_PWR_ON		0x01
    135 
    136 #define	SPC_ASC_BUS_RESET	0x29
    137 #define	SPC_ASCQ_BUS_RESET	0x02
    138 
    139 #define	SPC_ASC_CAP_CHANGE	0x2a
    140 #define	SPC_ASCQ_CAP_CHANGE	0x09
    141 
    142 #define	SPC_ASC_DATA_PATH	0x41
    143 #define	SPC_ASCQ_DATA_PATH	0x00
    144 
    145 #define	SPC_ASC_MEMORY_OUT_OF	0x55 /* Auxillary Memory Out Of Space */
    146 #define	SPC_ASCQ_MEMORY_OUT_OF	0x00
    147 #define	SPC_ASCQ_RESERVATION_FAIL 0x02
    148 
    149 
    150 /*
    151  * []------------------------------------------------------------------[]
    152  * | SAM-3, revision 14, section 5.2 - Command descriptor block (CDB)	|
    153  * |									|
    154  * | "All CDBs shall contain a CONTROL byte (see table 21). The		|
    155  * | location of the CONTROL byte within a CDB depends on the CDB	|
    156  * | format (see SPC-3)."						|
    157  * |									|
    158  * | bits	meaning							|
    159  * | 6-7	vendor specific (we don't use so must be zero)		|
    160  * | 3-5	reserved must be zero					|
    161  * | 2		NACA (currently we don't support so must be zero)	|
    162  * | 1		Obsolete						|
    163  * | 0		Link (currently we don't support so must be zero)	|
    164  * |									|
    165  * | So, this means the control byte must be zero and therefore if	|
    166  * | this macro returns a non-zero value the emulation code should	|
    167  * | return a CHECK CONDITION with status set to ILLEGAL REQUEST	|
    168  * | and the additional sense code set to INVALID FIELD IN CDB.		|
    169  * |									|
    170  * | In the future this will likely change with support routines	|
    171  * | added for dealing with NACA and Linked commands.			|
    172  * []------------------------------------------------------------------[]
    173  */
    174 #define	SAM_CONTROL_BYTE_RESERVED(byte)	(byte)
    175 
    176 /* ---- Disable Block Descriptors ---- */
    177 #define	SPC_MODE_SENSE_DBD	0x8
    178 
    179 #define	SPC_GROUP4_SERVICE_ACTION_MASK	0x1f
    180 
    181 #define	SPC_SEND_DIAG_SELFTEST	0x04
    182 
    183 /*
    184  * []------------------------------------------------------------------[]
    185  * | SPC-3 revision 21c, section 6.4 -- INQUIRY				|
    186  * | Various defines. The structure for the inquiry command can be	|
    187  * | found in /usr/include/sys/scsi/generic/inquiry.h			|
    188  * []------------------------------------------------------------------[]
    189  */
    190 #define	SPC_INQUIRY_CODE_SET_BINARY	1
    191 #define	SPC_INQUIRY_CODE_SET_ASCII	2
    192 #define	SPC_INQUIRY_CODE_SET_UTF8	3
    193 
    194 /* ---- Table 82: Inquiry Version ----  */
    195 #define	SPC_INQ_VERS_NONE	0x00
    196 #define	SPC_INQ_VERS_OBSOLETE	0x02
    197 #define	SPC_INQ_VERS_SPC_1	0x03
    198 #define	SPC_INQ_VERS_SPC_2	0x04
    199 #define	SPC_INQ_VERS_SPC_3	0x05
    200 
    201 /* ---- INQUIRY Response Data Format field ---- */
    202 #define	SPC_INQ_RDF		0x02	/* all other values are OBSOLETE */
    203 
    204 /*
    205  * Table 85 -- Version descriptor values
    206  * There are many, many different values available, so we'll only include
    207  * those that we actually use.
    208  */
    209 #define	SPC_INQ_VD_SAM3		0x0076
    210 #define	SPC_INQ_VD_SPC3		0x0307
    211 #define	SPC_INQ_VD_SBC2		0x0322
    212 #define	SPC_INQ_VD_SSC3		0x0400
    213 #define	SPC_INQ_VD_OSD		0x0355
    214 
    215 /* --- Version Descriptor length details --- */
    216 #define	SPC_INQ_VD_IDX		0x3A
    217 #define	SPC_INQ_VD_LEN		0x10
    218 
    219 #define	SPC_INQ_PAGE0		0x00
    220 #define	SPC_INQ_PAGE80		0x80
    221 #define	SPC_INQ_PAGE83		0x83
    222 #define	SPC_INQ_PAGE86		0x86
    223 
    224 /* ---- REPORT LUNS select report has valid values of 0, 1, or 2 ---- */
    225 #define	SPC_RPT_LUNS_SELECT_MASK	0x03
    226 
    227 /* ---- Table 293: IDENTIFIER TYPE field ---- */
    228 #define	SPC_INQUIRY_ID_TYPE_T10ID	1	/* ref 7.6.4.3 */
    229 #define	SPC_INQUIRY_ID_TYPE_EUI		2	/* ref 7.6.4.4 */
    230 #define	SPC_INQUIRY_ID_TYPE_NAA		3	/* ref 7.6.4.5 */
    231 #define	SPC_INQUIRY_ID_TYPE_RELATIVE	4	/* ref 7.6.4.6 */
    232 #define	SPC_INQUIRY_ID_TYPE_TARG_PORT	5	/* ref 7.6.4.7 */
    233 #define	SPC_INQUIRY_ID_TYPE_LUN		6	/* ref 7.6.4.8 */
    234 #define	SPC_INQUIRY_ID_TYPE_MD5		7	/* ref 7.6.4.9 */
    235 #define	SPC_INQUIRY_ID_TYPE_SCSI	8	/* ref 7.6.4.10 */
    236 
    237 /* ---- Table 292: ASSOCIATION field ----  */
    238 #define	SPC_INQUIRY_ASSOC_LUN		0
    239 #define	SPC_INQUIRY_ASSOC_TARGPORT	1
    240 #define	SPC_INQUIRY_ASSOC_TARG		2
    241 
    242 /* ---- Table 80: Peripheral qualifier ---- */
    243 #define	SPC_INQUIRY_PERIPH_CONN		0
    244 #define	SPC_INQUIRY_PERIPH_DISCONN	1
    245 #define	SPC_INQUIRY_PERIPH_INVALID	3
    246 
    247 /* ---- Table 256: PROTOCOL IDENTIFIER values ---- */
    248 #define	SPC_INQUIRY_PROTOCOL_FC		0
    249 #define	SPC_INQUIRY_PROTOCOL_PSCSI	1
    250 #define	SPC_INQUIRY_PROTOCOL_SSA	2
    251 #define	SPC_INQUIRY_PROTOCOL_IEEE1394	3
    252 #define	SPC_INQUIRY_PROTOCOL_SCSIRDMA	4
    253 #define	SPC_INQUIRY_PROTOCOL_ISCSI	5
    254 #define	SPC_INQUIRY_PROTOCOL_SAS	6
    255 #define	SPC_INQUIRY_PROTOCOL_ADT	7
    256 #define	SPC_INQUIRY_PROTOCOL_ATA	8
    257 
    258 #define	SPC_DEFAULT_TPG	1
    259 
    260 /*
    261  * SPC-3, revision 21c, section 7.6.5
    262  * Extended INQUIRY Data VPD page
    263  */
    264 typedef struct extended_inq_data {
    265 	struct vpd_hdr	ei_hdr;
    266 #if defined(_BIT_FIELDS_LTOH)
    267 	uchar_t		ei_ref_chk	: 1,
    268 			ei_app_chk	: 1,
    269 			ei_grd_chk	: 1,
    270 			ei_rto		: 1,
    271 			ei_rsvd1	: 4;
    272 	uchar_t		ei_simpsup	: 1,
    273 			ei_ordsup	: 1,
    274 			ei_headsup	: 1,
    275 			ei_prior_sup	: 1,
    276 			ei_group_sup	: 1,
    277 			ei_rsvd2	: 3;
    278 	uchar_t		ei_v_sup	: 1,
    279 			ei_nv_sup	: 1,
    280 			ei_rsvd3	: 6;
    281 #elif defined(_BIT_FIELDS_HTOL)
    282 	uchar_t		ei_ref_rsvd1	: 4,
    283 			ei_rto		: 1,
    284 			ei_grd_chk	: 1,
    285 			ei_app_chk	: 1,
    286 			ei_ref_chk	: 1;
    287 	uchar_t		ei_rsvd2	: 2,
    288 			ei_group_sup	: 1,
    289 			ei_prior_sup	: 1,
    290 			ei_headsup	: 1,
    291 			ei_ordsup	: 1,
    292 			ei_simpsup	: 1;
    293 	uchar_t		ei_rsvd3	: 6,
    294 			ei_nv_sup	: 1,
    295 			ei_v_sup	: 1;
    296 #else
    297 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
    298 #endif
    299 	uchar_t		ei_rsv4[57];
    300 } extended_inq_data_t;
    301 
    302 
    303 /*
    304  * []------------------------------------------------------------------[]
    305  * | SPC-4 revision 1a, section 6.25 -- REPORT TARGET PORT GROUPS	|
    306  * | Structures and defines						|
    307  * []------------------------------------------------------------------[]
    308  */
    309 /*
    310  * The service action must be set to 0x0A. This command is really a
    311  * MAINTENANCE_IN command with a specific service action.
    312  */
    313 #define	SPC_MI_SVC_MASK		0x1f
    314 #define	SPC_MI_SVC_RTPG		0x0a
    315 
    316 /* ---- Table 167: Target port descriptor format ---- */
    317 typedef struct rtpg_targ_desc {
    318 	uchar_t		obsolete[2],
    319 			rel_tpi[2];
    320 } rtpg_targ_desc_t;
    321 
    322 /* ---- Table 164: Target port group descript format ---- */
    323 typedef struct rtpg_desc {
    324 #if defined(_BIT_FIELDS_LTOH)
    325 	uchar_t access_state	: 4,
    326 				: 3,
    327 		pref		: 1;
    328 	uchar_t	ao_sup		: 1,
    329 		an_sup		: 1,
    330 		s_sup		: 1,
    331 		u_sup		: 1,
    332 				: 3,
    333 		t_sup		: 1;
    334 #elif defined(_BIT_FIELDS_HTOL)
    335 	uchar_t	pref		: 1,
    336 				: 3,
    337 		access_state	: 4;
    338 	uchar_t	t_sup		: 1,
    339 				: 3,
    340 		u_sup		: 1,
    341 		s_sup		: 1,
    342 		an_sup		: 1,
    343 		ao_sup		: 1;
    344 #else
    345 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
    346 #endif
    347 	uchar_t			tpg[2],
    348 				reserve_1,
    349 				status_code,
    350 				vendor_spec,
    351 				tpg_cnt;
    352 	rtpg_targ_desc_t	targ_list[1];
    353 } rtpg_desc_t;
    354 
    355 /* ---- Table 163: parameter data format. ---- */
    356 typedef struct rtpg_data {
    357 	uchar_t		len[4];
    358 	rtpg_desc_t	desc_list[1];
    359 } rtpg_hdr_t;
    360 
    361 /*
    362  * []------------------------------------------------------------------[]
    363  * | SPC-3, revision 21c, section 6.6 -- LOG_SENSE			|
    364  * | Structure and defines						|
    365  * []------------------------------------------------------------------[]
    366  */
    367 #define	SSC_LOG_SP		0x01 /* save parameters */
    368 #define	SSC_LOG_PPC		0x02 /* parameter pointer control */
    369 #define	SPC_LOG_PAGE_MASK	0x3f
    370 
    371 /* ---- section 7.2.1, Table 192: Log Parameter ---- */
    372 typedef struct spc_log_select_param {
    373 	char	param_code[2];
    374 #if defined(_BIT_FIELDS_LTOH)
    375 	char	lp	: 1,	/* list parameter */
    376 		lbin	: 1,
    377 		tmc	: 2,	/* threshold met criteria */
    378 		etc	: 1,	/* enable threshold comparison */
    379 		tsd	: 1,	/* target save disable */
    380 		ds	: 1,	/* disable save */
    381 		du	: 1;	/* disable update */
    382 #elif defined(_BIT_FIELDS_HTOL)
    383 	char	du	: 1,	/* disable update */
    384 		ds	: 1,	/* disable save */
    385 		tsd	: 1,	/* target save disable */
    386 		etc	: 1,	/* enable threshold comparison */
    387 		tmc	: 2,	/* threshold met criteria */
    388 		lbin	: 1,
    389 		lp	: 1;	/* list parameter */
    390 #else
    391 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
    392 #endif
    393 	char	len;		/* length of bytes to follow */
    394 } spc_log_select_param_t;
    395 
    396 /* ---- section 7.2.12, table 218: Supported log pages ---- */
    397 typedef struct spc_log_supported_pages {
    398 	char	page_code,
    399 		resvd,
    400 		length[2],
    401 		list[1];
    402 } spc_log_supported_pages_t;
    403 
    404 /*
    405  * []------------------------------------------------------------------[]
    406  * | SPC-3, revision 21c, section 6.9 -- MODE_SENSE			|
    407  * | Structures and defines						|
    408  * []------------------------------------------------------------------[]
    409  */
    410 /* ---- Section 7.4.6, Table 241: Queue Algorithm Modifer field ---- */
    411 #define	SPC_QUEUE_RESTRICTED		0x00
    412 #define	SPC_QUEUE_UNRESTRICTED		0x01
    413 
    414 /* ---- Section 7.4.11, Table 250: Information Controller Page ---- */
    415 struct mode_info_ctrl {
    416 	struct mode_page	mode_page;
    417 	/*
    418 	 * Currently we don't sent any of this information and it's set
    419 	 * to zero's. We only care about the size.
    420 	 */
    421 	char			info_data[10];
    422 };
    423 
    424 #define	MODE_SENSE_PAGE3_CODE		0x03
    425 #define	MODE_SENSE_PAGE4_CODE		0x04
    426 #define	MODE_SENSE_CACHE		0x08
    427 #define	MODE_SENSE_CONTROL		0x0a
    428 #define	MODE_SENSE_COMPRESSION		0x0f
    429 #define	MODE_SENSE_DEV_CONFIG		0x10
    430 #define	MODE_SENSE_INFO_CTRL		0x1c
    431 #define	MODE_SENSE_SEND_ALL		0x3f
    432 
    433 /* -- Page Control Mask for Mode Sense -- */
    434 #define	SPC_MODE_SENSE_PAGE_CODE_MASK	0x3f
    435 #define	SPC_MODE_SENSE_PC_MASK		0xc0
    436 #define	SPC_MODE_SENSE_PC_SHIFT		6
    437 
    438 #define	SPC_PC_CURRENT_VALUES		0
    439 #define	SPC_PC_MODIFIABLE_VALUES	1
    440 #define	SPC_PC_DEFAULT_VALUES		2
    441 #define	SPC_PC_SAVED_VALUES		3
    442 
    443 #define	SCSI_REPORTLUNS_ADDRESS_SIZE			8
    444 #define	SCSI_REPORTLUNS_ADDRESS_MASK			0xC0
    445 #define	SCSI_REPORTLUNS_ADDRESS_PERIPHERAL		0x00
    446 #define	SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE		0x40
    447 #define	SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT		0x80
    448 #define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_UNIT		0xC0
    449 #define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_2B		0x00
    450 #define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_4B		0x10
    451 #define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_6B		0x20
    452 #define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_8B		0x30
    453 #define	SCSI_REPORTLUNS_ADDRESS_EXTENDED_MASK		0x30
    454 #define	SCSI_REPORTLUNS_SELECT_ALL			0x02
    455 
    456 #ifdef __cplusplus
    457 }
    458 #endif
    459 
    460 #endif /* _T10_SPC_H */
    461