1/*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32#ifndef ISCSI_PROTO_H 33#define ISCSI_PROTO_H 34 35#ifndef CTASSERT 36#define CTASSERT(x) _CTASSERT(x, __LINE__) 37#define _CTASSERT(x, y) __CTASSERT(x, y) 38#define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1] 39#endif 40 41#define ISCSI_SNGT(x, y) ((int32_t)(x) - (int32_t)(y) > 0) 42#define ISCSI_SNLT(x, y) ((int32_t)(x) - (int32_t)(y) < 0) 43 44#define ISCSI_BHS_SIZE 48 45#define ISCSI_HEADER_DIGEST_SIZE 4 46#define ISCSI_DATA_DIGEST_SIZE 4 47 48#define ISCSI_BHS_OPCODE_IMMEDIATE 0x40 49 50#define ISCSI_BHS_OPCODE_NOP_OUT 0x00 51#define ISCSI_BHS_OPCODE_SCSI_COMMAND 0x01 52#define ISCSI_BHS_OPCODE_TASK_REQUEST 0x02 53#define ISCSI_BHS_OPCODE_LOGIN_REQUEST 0x03 54#define ISCSI_BHS_OPCODE_TEXT_REQUEST 0x04 55#define ISCSI_BHS_OPCODE_SCSI_DATA_OUT 0x05 56#define ISCSI_BHS_OPCODE_LOGOUT_REQUEST 0x06 57 58#define ISCSI_BHS_OPCODE_NOP_IN 0x20 59#define ISCSI_BHS_OPCODE_SCSI_RESPONSE 0x21 60#define ISCSI_BHS_OPCODE_TASK_RESPONSE 0x22 61#define ISCSI_BHS_OPCODE_LOGIN_RESPONSE 0x23 62#define ISCSI_BHS_OPCODE_TEXT_RESPONSE 0x24 63#define ISCSI_BHS_OPCODE_SCSI_DATA_IN 0x25 64#define ISCSI_BHS_OPCODE_LOGOUT_RESPONSE 0x26 65#define ISCSI_BHS_OPCODE_R2T 0x31 66#define ISCSI_BHS_OPCODE_ASYNC_MESSAGE 0x32 67#define ISCSI_BHS_OPCODE_REJECT 0x3f 68 69struct iscsi_bhs { 70 uint8_t bhs_opcode; 71 uint8_t bhs_opcode_specific1[3]; 72 uint8_t bhs_total_ahs_len; 73 uint8_t bhs_data_segment_len[3]; 74 uint64_t bhs_lun; 75 uint8_t bhs_inititator_task_tag[4]; 76 uint8_t bhs_opcode_specific4[28]; 77}; 78CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE); 79 80#define BHSSC_FLAGS_F 0x80 81#define BHSSC_FLAGS_R 0x40 82#define BHSSC_FLAGS_W 0x20 83#define BHSSC_FLAGS_ATTR 0x07 84 85#define BHSSC_FLAGS_ATTR_UNTAGGED 0 86#define BHSSC_FLAGS_ATTR_SIMPLE 1 87#define BHSSC_FLAGS_ATTR_ORDERED 2 88#define BHSSC_FLAGS_ATTR_HOQ 3 89#define BHSSC_FLAGS_ATTR_ACA 4 90 91struct iscsi_bhs_scsi_command { 92 uint8_t bhssc_opcode; 93 uint8_t bhssc_flags; 94 uint8_t bhssc_reserved[2]; 95 uint8_t bhssc_total_ahs_len; 96 uint8_t bhssc_data_segment_len[3]; 97 uint64_t bhssc_lun; 98 uint32_t bhssc_initiator_task_tag; 99 uint32_t bhssc_expected_data_transfer_length; 100 uint32_t bhssc_cmdsn; 101 uint32_t bhssc_expstatsn; 102 uint8_t bhssc_cdb[16]; 103}; 104CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE); 105 106#define BHSSR_FLAGS_RESIDUAL_UNDERFLOW 0x02 107#define BHSSR_FLAGS_RESIDUAL_OVERFLOW 0x04 108 109#define BHSSR_RESPONSE_COMMAND_COMPLETED 0x00 110 111struct iscsi_bhs_scsi_response { 112 uint8_t bhssr_opcode; 113 uint8_t bhssr_flags; 114 uint8_t bhssr_response; 115 uint8_t bhssr_status; 116 uint8_t bhssr_total_ahs_len; 117 uint8_t bhssr_data_segment_len[3]; 118 uint16_t bhssr_status_qualifier; 119 uint16_t bhssr_reserved; 120 uint32_t bhssr_reserved2; 121 uint32_t bhssr_initiator_task_tag; 122 uint32_t bhssr_snack_tag; 123 uint32_t bhssr_statsn; 124 uint32_t bhssr_expcmdsn; 125 uint32_t bhssr_maxcmdsn; 126 uint32_t bhssr_expdatasn; 127 uint32_t bhssr_bidirectional_read_residual_count; 128 uint32_t bhssr_residual_count; 129}; 130CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE); 131 132#define BHSTMR_FUNCTION_ABORT_TASK 1 133#define BHSTMR_FUNCTION_ABORT_TASK_SET 2 134#define BHSTMR_FUNCTION_CLEAR_ACA 3 135#define BHSTMR_FUNCTION_CLEAR_TASK_SET 4 136#define BHSTMR_FUNCTION_LOGICAL_UNIT_RESET 5 137#define BHSTMR_FUNCTION_TARGET_WARM_RESET 6 138#define BHSTMR_FUNCTION_TARGET_COLD_RESET 7 139#define BHSTMR_FUNCTION_TASK_REASSIGN 8 140#define BHSTMR_FUNCTION_QUERY_TASK 9 141#define BHSTMR_FUNCTION_QUERY_TASK_SET 10 142#define BHSTMR_FUNCTION_I_T_NEXUS_RESET 11 143#define BHSTMR_FUNCTION_QUERY_ASYNC_EVENT 12 144 145struct iscsi_bhs_task_management_request { 146 uint8_t bhstmr_opcode; 147 uint8_t bhstmr_function; 148 uint8_t bhstmr_reserved[2]; 149 uint8_t bhstmr_total_ahs_len; 150 uint8_t bhstmr_data_segment_len[3]; 151 uint64_t bhstmr_lun; 152 uint32_t bhstmr_initiator_task_tag; 153 uint32_t bhstmr_referenced_task_tag; 154 uint32_t bhstmr_cmdsn; 155 uint32_t bhstmr_expstatsn; 156 uint32_t bhstmr_refcmdsn; 157 uint32_t bhstmr_expdatasn; 158 uint64_t bhstmr_reserved2; 159}; 160CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE); 161 162#define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0 163#define BHSTMR_RESPONSE_TASK_DOES_NOT_EXIST 1 164#define BHSTMR_RESPONSE_LUN_DOES_NOT_EXIST 2 165#define BHSTMR_RESPONSE_TASK_STILL_ALLEGIANT 3 166#define BHSTMR_RESPONSE_TASK_ALL_REASS_NOT_SUPP 4 167#define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5 168#define BHSTMR_RESPONSE_FUNCTION_AUTH_FAIL 6 169#define BHSTMR_RESPONSE_FUNCTION_SUCCEEDED 7 170#define BHSTMR_RESPONSE_FUNCTION_REJECTED 255 171 172struct iscsi_bhs_task_management_response { 173 uint8_t bhstmr_opcode; 174 uint8_t bhstmr_flags; 175 uint8_t bhstmr_response; 176 uint8_t bhstmr_reserved; 177 uint8_t bhstmr_total_ahs_len; 178 uint8_t bhstmr_data_segment_len[3]; 179 uint8_t bhstmr_additional_reponse_information[3]; 180 uint8_t bhstmr_reserved2[5]; 181 uint32_t bhstmr_initiator_task_tag; 182 uint32_t bhstmr_reserved3; 183 uint32_t bhstmr_statsn; 184 uint32_t bhstmr_expcmdsn; 185 uint32_t bhstmr_maxcmdsn; 186 uint8_t bhstmr_reserved4[12]; 187}; 188CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE); 189 190#define BHSLR_FLAGS_TRANSIT 0x80 191#define BHSLR_FLAGS_CONTINUE 0x40 192 193#define BHSLR_STAGE_SECURITY_NEGOTIATION 0 194#define BHSLR_STAGE_OPERATIONAL_NEGOTIATION 1 195#define BHSLR_STAGE_FULL_FEATURE_PHASE 3 /* Yes, 3. */ 196 197struct iscsi_bhs_login_request { 198 uint8_t bhslr_opcode; 199 uint8_t bhslr_flags; 200 uint8_t bhslr_version_max; 201 uint8_t bhslr_version_min; 202 uint8_t bhslr_total_ahs_len; 203 uint8_t bhslr_data_segment_len[3]; 204 uint8_t bhslr_isid[6]; 205 uint16_t bhslr_tsih; 206 uint32_t bhslr_initiator_task_tag; 207 uint16_t bhslr_cid; 208 uint16_t bhslr_reserved; 209 uint32_t bhslr_cmdsn; 210 uint32_t bhslr_expstatsn; 211 uint8_t bhslr_reserved2[16]; 212}; 213CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE); 214 215struct iscsi_bhs_login_response { 216 uint8_t bhslr_opcode; 217 uint8_t bhslr_flags; 218 uint8_t bhslr_version_max; 219 uint8_t bhslr_version_active; 220 uint8_t bhslr_total_ahs_len; 221 uint8_t bhslr_data_segment_len[3]; 222 uint8_t bhslr_isid[6]; 223 uint16_t bhslr_tsih; 224 uint32_t bhslr_initiator_task_tag; 225 uint32_t bhslr_reserved; 226 uint32_t bhslr_statsn; 227 uint32_t bhslr_expcmdsn; 228 uint32_t bhslr_maxcmdsn; 229 uint8_t bhslr_status_class; 230 uint8_t bhslr_status_detail; 231 uint16_t bhslr_reserved2; 232 uint8_t bhslr_reserved3[8]; 233}; 234CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE); 235 236#define BHSTR_FLAGS_FINAL 0x80 237#define BHSTR_FLAGS_CONTINUE 0x40 238 239struct iscsi_bhs_text_request { 240 uint8_t bhstr_opcode; 241 uint8_t bhstr_flags; 242 uint16_t bhstr_reserved; 243 uint8_t bhstr_total_ahs_len; 244 uint8_t bhstr_data_segment_len[3]; 245 uint64_t bhstr_lun; 246 uint32_t bhstr_initiator_task_tag; 247 uint32_t bhstr_target_transfer_tag; 248 uint32_t bhstr_cmdsn; 249 uint32_t bhstr_expstatsn; 250 uint8_t bhstr_reserved2[16]; 251}; 252CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE); 253 254struct iscsi_bhs_text_response { 255 uint8_t bhstr_opcode; 256 uint8_t bhstr_flags; 257 uint16_t bhstr_reserved; 258 uint8_t bhstr_total_ahs_len; 259 uint8_t bhstr_data_segment_len[3]; 260 uint64_t bhstr_lun; 261 uint32_t bhstr_initiator_task_tag; 262 uint32_t bhstr_target_transfer_tag; 263 uint32_t bhstr_statsn; 264 uint32_t bhstr_expcmdsn; 265 uint32_t bhstr_maxcmdsn; 266 uint8_t bhstr_reserved2[12]; 267}; 268CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE); 269 270#define BHSDO_FLAGS_F 0x80 271 272struct iscsi_bhs_data_out { 273 uint8_t bhsdo_opcode; 274 uint8_t bhsdo_flags; 275 uint8_t bhsdo_reserved[2]; 276 uint8_t bhsdo_total_ahs_len; 277 uint8_t bhsdo_data_segment_len[3]; 278 uint64_t bhsdo_lun; 279 uint32_t bhsdo_initiator_task_tag; 280 uint32_t bhsdo_target_transfer_tag; 281 uint32_t bhsdo_reserved2; 282 uint32_t bhsdo_expstatsn; 283 uint32_t bhsdo_reserved3; 284 uint32_t bhsdo_datasn; 285 uint32_t bhsdo_buffer_offset; 286 uint32_t bhsdo_reserved4; 287}; 288CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE); 289 290#define BHSDI_FLAGS_F 0x80 291#define BHSDI_FLAGS_A 0x40 292#define BHSDI_FLAGS_O 0x04 293#define BHSDI_FLAGS_U 0x02 294#define BHSDI_FLAGS_S 0x01 295 296struct iscsi_bhs_data_in { 297 uint8_t bhsdi_opcode; 298 uint8_t bhsdi_flags; 299 uint8_t bhsdi_reserved; 300 uint8_t bhsdi_status; 301 uint8_t bhsdi_total_ahs_len; 302 uint8_t bhsdi_data_segment_len[3]; 303 uint64_t bhsdi_lun; 304 uint32_t bhsdi_initiator_task_tag; 305 uint32_t bhsdi_target_transfer_tag; 306 uint32_t bhsdi_statsn; 307 uint32_t bhsdi_expcmdsn; 308 uint32_t bhsdi_maxcmdsn; 309 uint32_t bhsdi_datasn; 310 uint32_t bhsdi_buffer_offset; 311 uint32_t bhsdi_residual_count; 312}; 313CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE); 314 315struct iscsi_bhs_r2t { 316 uint8_t bhsr2t_opcode; 317 uint8_t bhsr2t_flags; 318 uint16_t bhsr2t_reserved; 319 uint8_t bhsr2t_total_ahs_len; 320 uint8_t bhsr2t_data_segment_len[3]; 321 uint64_t bhsr2t_lun; 322 uint32_t bhsr2t_initiator_task_tag; 323 uint32_t bhsr2t_target_transfer_tag; 324 uint32_t bhsr2t_statsn; 325 uint32_t bhsr2t_expcmdsn; 326 uint32_t bhsr2t_maxcmdsn; 327 uint32_t bhsr2t_r2tsn; 328 uint32_t bhsr2t_buffer_offset; 329 uint32_t bhsr2t_desired_data_transfer_length; 330}; 331CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE); 332 333struct iscsi_bhs_nop_out { 334 uint8_t bhsno_opcode; 335 uint8_t bhsno_flags; 336 uint16_t bhsno_reserved; 337 uint8_t bhsno_total_ahs_len; 338 uint8_t bhsno_data_segment_len[3]; 339 uint64_t bhsno_lun; 340 uint32_t bhsno_initiator_task_tag; 341 uint32_t bhsno_target_transfer_tag; 342 uint32_t bhsno_cmdsn; 343 uint32_t bhsno_expstatsn; 344 uint8_t bhsno_reserved2[16]; 345}; 346CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE); 347 348struct iscsi_bhs_nop_in { 349 uint8_t bhsni_opcode; 350 uint8_t bhsni_flags; 351 uint16_t bhsni_reserved; 352 uint8_t bhsni_total_ahs_len; 353 uint8_t bhsni_data_segment_len[3]; 354 uint64_t bhsni_lun; 355 uint32_t bhsni_initiator_task_tag; 356 uint32_t bhsni_target_transfer_tag; 357 uint32_t bhsni_statsn; 358 uint32_t bhsni_expcmdsn; 359 uint32_t bhsni_maxcmdsn; 360 uint8_t bhsno_reserved2[12]; 361}; 362CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE); 363 364#define BHSLR_REASON_CLOSE_SESSION 0 365#define BHSLR_REASON_CLOSE_CONNECTION 1 366#define BHSLR_REASON_REMOVE_FOR_RECOVERY 2 367 368struct iscsi_bhs_logout_request { 369 uint8_t bhslr_opcode; 370 uint8_t bhslr_reason; 371 uint16_t bhslr_reserved; 372 uint8_t bhslr_total_ahs_len; 373 uint8_t bhslr_data_segment_len[3]; 374 uint64_t bhslr_reserved2; 375 uint32_t bhslr_initiator_task_tag; 376 uint16_t bhslr_cid; 377 uint16_t bhslr_reserved3; 378 uint32_t bhslr_cmdsn; 379 uint32_t bhslr_expstatsn; 380 uint8_t bhslr_reserved4[16]; 381}; 382CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE); 383 384#define BHSLR_RESPONSE_CLOSED_SUCCESSFULLY 0 385#define BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED 2 386 387struct iscsi_bhs_logout_response { 388 uint8_t bhslr_opcode; 389 uint8_t bhslr_flags; 390 uint8_t bhslr_response; 391 uint8_t bhslr_reserved; 392 uint8_t bhslr_total_ahs_len; 393 uint8_t bhslr_data_segment_len[3]; 394 uint64_t bhslr_reserved2; 395 uint32_t bhslr_initiator_task_tag; 396 uint32_t bhslr_reserved3; 397 uint32_t bhslr_statsn; 398 uint32_t bhslr_expcmdsn; 399 uint32_t bhslr_maxcmdsn; 400 uint32_t bhslr_reserved4; 401 uint16_t bhslr_time2wait; 402 uint16_t bhslr_time2retain; 403 uint32_t bhslr_reserved5; 404}; 405CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE); 406 407#define BHSAM_EVENT_TARGET_REQUESTS_LOGOUT 1 408#define BHSAM_EVENT_TARGET_TERMINATES_CONNECTION 2 409#define BHSAM_EVENT_TARGET_TERMINATES_SESSION 3 410 411struct iscsi_bhs_asynchronous_message { 412 uint8_t bhsam_opcode; 413 uint8_t bhsam_flags; 414 uint16_t bhsam_reserved; 415 uint8_t bhsam_total_ahs_len; 416 uint8_t bhsam_data_segment_len[3]; 417 uint64_t bhsam_lun; 418 uint32_t bhsam_0xffffffff; 419 uint32_t bhsam_reserved2; 420 uint32_t bhsam_statsn; 421 uint32_t bhsam_expcmdsn; 422 uint32_t bhsam_maxcmdsn; 423 uint8_t bhsam_async_event; 424 uint8_t bhsam_async_vcode; 425 uint16_t bhsam_parameter1; 426 uint16_t bhsam_parameter2; 427 uint16_t bhsam_parameter3; 428 uint32_t bhsam_reserved3; 429}; 430CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE); 431 432#define BHSSR_REASON_DATA_DIGEST_ERROR 0x02 433#define BHSSR_PROTOCOL_ERROR 0x04 434#define BHSSR_COMMAND_NOT_SUPPORTED 0x05 435#define BHSSR_INVALID_PDU_FIELD 0x09 436 437struct iscsi_bhs_reject { 438 uint8_t bhsr_opcode; 439 uint8_t bhsr_flags; 440 uint8_t bhsr_reason; 441 uint8_t bhsr_reserved; 442 uint8_t bhsr_total_ahs_len; 443 uint8_t bhsr_data_segment_len[3]; 444 uint64_t bhsr_reserved2; 445 uint32_t bhsr_0xffffffff; 446 uint32_t bhsr_reserved3; 447 uint32_t bhsr_statsn; 448 uint32_t bhsr_expcmdsn; 449 uint32_t bhsr_maxcmdsn; 450 uint32_t bhsr_datasn_r2tsn; 451 uint32_t bhsr_reserved4; 452 uint32_t bhsr_reserved5; 453}; 454CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE); 455 456#endif /* !ISCSI_PROTO_H */ 457