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