1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. 3 * Copyright (C) 2016 Intel Corporation. 4 * All rights reserved. 5 */ 6 7 /** 8 * \file 9 * iSCSI specification definitions 10 */ 11 12 #ifndef SPDK_ISCSI_SPEC_H 13 #define SPDK_ISCSI_SPEC_H 14 15 #include "spdk/stdinc.h" 16 17 #include "spdk/assert.h" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #define ISCSI_BHS_LEN 48 24 #define ISCSI_DIGEST_LEN 4 25 #define ISCSI_ALIGNMENT 4 26 27 /** support version - RFC3720(10.12.4) */ 28 #define ISCSI_VERSION 0x00 29 30 #define ISCSI_ALIGN(SIZE) \ 31 (((SIZE) + (ISCSI_ALIGNMENT - 1)) & ~(ISCSI_ALIGNMENT - 1)) 32 33 /** for authentication key (non encoded 1024bytes) RFC3720(5.1/11.1.4) */ 34 #define ISCSI_TEXT_MAX_VAL_LEN 8192 35 36 /** 37 * RFC 3720 5.1 38 * If not otherwise specified, the maximum length of a simple-value 39 * (not its encoded representation) is 255 bytes, not including the delimiter 40 * (comma or zero byte). 41 */ 42 #define ISCSI_TEXT_MAX_SIMPLE_VAL_LEN 255 43 44 #define ISCSI_TEXT_MAX_KEY_LEN 63 45 46 enum iscsi_op { 47 /* Initiator opcodes */ 48 ISCSI_OP_NOPOUT = 0x00, 49 ISCSI_OP_SCSI = 0x01, 50 ISCSI_OP_TASK = 0x02, 51 ISCSI_OP_LOGIN = 0x03, 52 ISCSI_OP_TEXT = 0x04, 53 ISCSI_OP_SCSI_DATAOUT = 0x05, 54 ISCSI_OP_LOGOUT = 0x06, 55 ISCSI_OP_SNACK = 0x10, 56 ISCSI_OP_VENDOR_1C = 0x1c, 57 ISCSI_OP_VENDOR_1D = 0x1d, 58 ISCSI_OP_VENDOR_1E = 0x1e, 59 60 /* Target opcodes */ 61 ISCSI_OP_NOPIN = 0x20, 62 ISCSI_OP_SCSI_RSP = 0x21, 63 ISCSI_OP_TASK_RSP = 0x22, 64 ISCSI_OP_LOGIN_RSP = 0x23, 65 ISCSI_OP_TEXT_RSP = 0x24, 66 ISCSI_OP_SCSI_DATAIN = 0x25, 67 ISCSI_OP_LOGOUT_RSP = 0x26, 68 ISCSI_OP_R2T = 0x31, 69 ISCSI_OP_ASYNC = 0x32, 70 ISCSI_OP_VENDOR_3C = 0x3c, 71 ISCSI_OP_VENDOR_3D = 0x3d, 72 ISCSI_OP_VENDOR_3E = 0x3e, 73 ISCSI_OP_REJECT = 0x3f, 74 }; 75 76 enum iscsi_task_func { 77 ISCSI_TASK_FUNC_ABORT_TASK = 1, 78 ISCSI_TASK_FUNC_ABORT_TASK_SET = 2, 79 ISCSI_TASK_FUNC_CLEAR_ACA = 3, 80 ISCSI_TASK_FUNC_CLEAR_TASK_SET = 4, 81 ISCSI_TASK_FUNC_LOGICAL_UNIT_RESET = 5, 82 ISCSI_TASK_FUNC_TARGET_WARM_RESET = 6, 83 ISCSI_TASK_FUNC_TARGET_COLD_RESET = 7, 84 ISCSI_TASK_FUNC_TASK_REASSIGN = 8, 85 }; 86 87 enum iscsi_task_func_resp { 88 ISCSI_TASK_FUNC_RESP_COMPLETE = 0, 89 ISCSI_TASK_FUNC_RESP_TASK_NOT_EXIST = 1, 90 ISCSI_TASK_FUNC_RESP_LUN_NOT_EXIST = 2, 91 ISCSI_TASK_FUNC_RESP_TASK_STILL_ALLEGIANT = 3, 92 ISCSI_TASK_FUNC_RESP_REASSIGNMENT_NOT_SUPPORTED = 4, 93 ISCSI_TASK_FUNC_RESP_FUNC_NOT_SUPPORTED = 5, 94 ISCSI_TASK_FUNC_RESP_AUTHORIZATION_FAILED = 6, 95 ISCSI_TASK_FUNC_REJECTED = 255 96 }; 97 98 struct iscsi_bhs { 99 uint8_t opcode : 6; 100 uint8_t immediate : 1; 101 uint8_t reserved : 1; 102 uint8_t flags; 103 uint8_t rsv[2]; 104 uint8_t total_ahs_len; 105 uint8_t data_segment_len[3]; 106 uint64_t lun; 107 uint32_t itt; 108 uint32_t ttt; 109 uint32_t stat_sn; 110 uint32_t exp_stat_sn; 111 uint32_t max_stat_sn; 112 uint8_t res3[12]; 113 }; 114 SPDK_STATIC_ASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_LEN, "ISCSI_BHS_LEN mismatch"); 115 116 struct iscsi_bhs_async { 117 uint8_t opcode : 6; /* opcode = 0x32 */ 118 uint8_t reserved : 2; 119 uint8_t flags; 120 uint8_t res[2]; 121 122 uint8_t total_ahs_len; 123 uint8_t data_segment_len[3]; 124 125 uint64_t lun; 126 uint32_t ffffffff; 127 uint32_t res3; 128 uint32_t stat_sn; 129 uint32_t exp_cmd_sn; 130 uint32_t max_cmd_sn; 131 uint8_t async_event; 132 uint8_t async_vcode; 133 uint16_t param1; 134 uint16_t param2; 135 uint16_t param3; 136 uint8_t res4[4]; 137 }; 138 139 struct iscsi_bhs_login_req { 140 uint8_t opcode : 6; /* opcode = 0x03 */ 141 uint8_t immediate : 1; 142 uint8_t reserved : 1; 143 uint8_t flags; 144 uint8_t version_max; 145 uint8_t version_min; 146 uint8_t total_ahs_len; 147 uint8_t data_segment_len[3]; 148 uint8_t isid[6]; 149 uint16_t tsih; 150 uint32_t itt; 151 uint16_t cid; 152 uint16_t res2; 153 uint32_t cmd_sn; 154 uint32_t exp_stat_sn; 155 uint8_t res3[16]; 156 }; 157 158 struct iscsi_bhs_login_rsp { 159 uint8_t opcode : 6; /* opcode = 0x23 */ 160 uint8_t reserved : 2; 161 uint8_t flags; 162 uint8_t version_max; 163 uint8_t version_act; 164 uint8_t total_ahs_len; 165 uint8_t data_segment_len[3]; 166 uint8_t isid[6]; 167 uint16_t tsih; 168 uint32_t itt; 169 uint32_t res2; 170 uint32_t stat_sn; 171 uint32_t exp_cmd_sn; 172 uint32_t max_cmd_sn; 173 uint8_t status_class; 174 uint8_t status_detail; 175 uint8_t res3[10]; 176 }; 177 178 struct iscsi_bhs_logout_req { 179 uint8_t opcode : 6; /* opcode = 0x06 */ 180 uint8_t immediate : 1; 181 uint8_t reserved : 1; 182 uint8_t reason : 7; 183 uint8_t reason_1 : 1; 184 uint8_t res[2]; 185 uint8_t total_ahs_len; 186 uint8_t data_segment_len[3]; 187 uint8_t res2[8]; 188 uint32_t itt; 189 uint16_t cid; 190 uint16_t res3; 191 uint32_t cmd_sn; 192 uint32_t exp_stat_sn; 193 uint8_t res4[16]; 194 }; 195 196 struct iscsi_bhs_logout_resp { 197 uint8_t opcode : 6; /* opcode = 0x26 */ 198 uint8_t reserved : 2; 199 uint8_t flags; 200 uint8_t response; 201 uint8_t res; 202 uint8_t total_ahs_len; 203 uint8_t data_segment_len[3]; 204 uint8_t res2[8]; 205 uint32_t itt; 206 uint32_t res3; 207 uint32_t stat_sn; 208 uint32_t exp_cmd_sn; 209 uint32_t max_cmd_sn; 210 uint32_t res4; 211 uint16_t time_2_wait; 212 uint16_t time_2_retain; 213 uint32_t res5; 214 }; 215 216 struct iscsi_bhs_nop_in { 217 uint8_t opcode : 6; /* opcode = 0x20 */ 218 uint8_t reserved : 2; 219 uint8_t flags; 220 uint8_t res[2]; 221 uint8_t total_ahs_len; 222 uint8_t data_segment_len[3]; 223 uint64_t lun; 224 uint32_t itt; 225 uint32_t ttt; 226 uint32_t stat_sn; 227 uint32_t exp_cmd_sn; 228 uint32_t max_cmd_sn; 229 uint8_t res3[12]; 230 }; 231 232 struct iscsi_bhs_nop_out { 233 uint8_t opcode : 6; /* opcode = 0x00 */ 234 uint8_t immediate : 1; 235 uint8_t reserved : 1; 236 uint8_t flags; 237 uint8_t res[2]; 238 uint8_t total_ahs_len; 239 uint8_t data_segment_len[3]; 240 uint64_t lun; 241 uint32_t itt; 242 uint32_t ttt; 243 uint32_t cmd_sn; 244 uint32_t exp_stat_sn; 245 uint8_t res4[16]; 246 }; 247 248 struct iscsi_bhs_r2t { 249 uint8_t opcode : 6; /* opcode = 0x31 */ 250 uint8_t reserved : 2; 251 uint8_t flags; 252 uint8_t rsv[2]; 253 uint8_t total_ahs_len; 254 uint8_t data_segment_len[3]; 255 uint64_t lun; 256 uint32_t itt; 257 uint32_t ttt; 258 uint32_t stat_sn; 259 uint32_t exp_cmd_sn; 260 uint32_t max_cmd_sn; 261 uint32_t r2t_sn; 262 uint32_t buffer_offset; 263 uint32_t desired_xfer_len; 264 }; 265 266 struct iscsi_bhs_reject { 267 uint8_t opcode : 6; /* opcode = 0x3f */ 268 uint8_t reserved : 2; 269 uint8_t flags; 270 uint8_t reason; 271 uint8_t res; 272 uint8_t total_ahs_len; 273 uint8_t data_segment_len[3]; 274 uint8_t res2[8]; 275 uint32_t ffffffff; 276 uint32_t res3; 277 uint32_t stat_sn; 278 uint32_t exp_cmd_sn; 279 uint32_t max_cmd_sn; 280 uint32_t data_sn; 281 uint8_t res4[8]; 282 }; 283 284 struct iscsi_bhs_scsi_req { 285 uint8_t opcode : 6; /* opcode = 0x01 */ 286 uint8_t immediate : 1; 287 uint8_t reserved : 1; 288 uint8_t attribute : 3; 289 uint8_t reserved2 : 2; 290 uint8_t write_bit : 1; 291 uint8_t read_bit : 1; 292 uint8_t final_bit : 1; 293 uint8_t res[2]; 294 uint8_t total_ahs_len; 295 uint8_t data_segment_len[3]; 296 uint64_t lun; 297 uint32_t itt; 298 uint32_t expected_data_xfer_len; 299 uint32_t cmd_sn; 300 uint32_t exp_stat_sn; 301 uint8_t cdb[16]; 302 }; 303 304 struct iscsi_bhs_scsi_resp { 305 uint8_t opcode : 6; /* opcode = 0x21 */ 306 uint8_t reserved : 2; 307 uint8_t flags; 308 uint8_t response; 309 uint8_t status; 310 uint8_t total_ahs_len; 311 uint8_t data_segment_len[3]; 312 uint8_t res4[8]; 313 uint32_t itt; 314 uint32_t snacktag; 315 uint32_t stat_sn; 316 uint32_t exp_cmd_sn; 317 uint32_t max_cmd_sn; 318 uint32_t exp_data_sn; 319 uint32_t bi_read_res_cnt; 320 uint32_t res_cnt; 321 }; 322 323 struct iscsi_bhs_data_in { 324 uint8_t opcode : 6; /* opcode = 0x05 */ 325 uint8_t reserved : 2; 326 uint8_t flags; 327 uint8_t res; 328 uint8_t status; 329 uint8_t total_ahs_len; 330 uint8_t data_segment_len[3]; 331 uint64_t lun; 332 uint32_t itt; 333 uint32_t ttt; 334 uint32_t stat_sn; 335 uint32_t exp_cmd_sn; 336 uint32_t max_cmd_sn; 337 uint32_t data_sn; 338 uint32_t buffer_offset; 339 uint32_t res_cnt; 340 }; 341 342 struct iscsi_bhs_data_out { 343 uint8_t opcode : 6; /* opcode = 0x25 */ 344 uint8_t reserved : 2; 345 uint8_t flags; 346 uint8_t res[2]; 347 uint8_t total_ahs_len; 348 uint8_t data_segment_len[3]; 349 uint64_t lun; 350 uint32_t itt; 351 uint32_t ttt; 352 uint32_t res3; 353 uint32_t exp_stat_sn; 354 uint32_t res4; 355 uint32_t data_sn; 356 uint32_t buffer_offset; 357 uint32_t res5; 358 }; 359 360 struct iscsi_bhs_snack_req { 361 uint8_t opcode : 6; /* opcode = 0x10 */ 362 uint8_t reserved : 2; 363 uint8_t flags; 364 uint8_t res[2]; 365 uint8_t total_ahs_len; 366 uint8_t data_segment_len[3]; 367 uint64_t lun; 368 uint32_t itt; 369 uint32_t ttt; 370 uint32_t res5; 371 uint32_t exp_stat_sn; 372 uint8_t res6[8]; 373 uint32_t beg_run; 374 uint32_t run_len; 375 }; 376 377 struct iscsi_bhs_task_req { 378 uint8_t opcode : 6; /* opcode = 0x02 */ 379 uint8_t immediate : 1; 380 uint8_t reserved : 1; 381 uint8_t flags; 382 uint8_t res[2]; 383 uint8_t total_ahs_len; 384 uint8_t data_segment_len[3]; 385 uint64_t lun; 386 uint32_t itt; 387 uint32_t ref_task_tag; 388 uint32_t cmd_sn; 389 uint32_t exp_stat_sn; 390 uint32_t ref_cmd_sn; 391 uint32_t exp_data_sn; 392 uint8_t res5[8]; 393 }; 394 395 struct iscsi_bhs_task_resp { 396 uint8_t opcode : 6; /* opcode = 0x22 */ 397 uint8_t reserved : 2; 398 uint8_t flags; 399 uint8_t response; 400 uint8_t res; 401 uint8_t total_ahs_len; 402 uint8_t data_segment_len[3]; 403 uint8_t res2[8]; 404 uint32_t itt; 405 uint32_t res3; 406 uint32_t stat_sn; 407 uint32_t exp_cmd_sn; 408 uint32_t max_cmd_sn; 409 uint8_t res4[12]; 410 }; 411 412 struct iscsi_bhs_text_req { 413 uint8_t opcode : 6; /* opcode = 0x04 */ 414 uint8_t immediate : 1; 415 uint8_t reserved : 1; 416 uint8_t flags; 417 uint8_t res[2]; 418 uint8_t total_ahs_len; 419 uint8_t data_segment_len[3]; 420 uint64_t lun; 421 uint32_t itt; 422 uint32_t ttt; 423 uint32_t cmd_sn; 424 uint32_t exp_stat_sn; 425 uint8_t res3[16]; 426 }; 427 428 struct iscsi_bhs_text_resp { 429 uint8_t opcode : 6; /* opcode = 0x24 */ 430 uint8_t reserved : 2; 431 uint8_t flags; 432 uint8_t res[2]; 433 uint8_t total_ahs_len; 434 uint8_t data_segment_len[3]; 435 uint64_t lun; 436 uint32_t itt; 437 uint32_t ttt; 438 uint32_t stat_sn; 439 uint32_t exp_cmd_sn; 440 uint32_t max_cmd_sn; 441 uint8_t res4[12]; 442 }; 443 444 /* generic flags */ 445 #define ISCSI_FLAG_FINAL 0x80 446 447 /* login flags */ 448 #define ISCSI_LOGIN_TRANSIT 0x80 449 #define ISCSI_LOGIN_CONTINUE 0x40 450 #define ISCSI_LOGIN_CURRENT_STAGE_MASK 0x0c 451 #define ISCSI_LOGIN_CURRENT_STAGE_0 0x04 452 #define ISCSI_LOGIN_CURRENT_STAGE_1 0x08 453 #define ISCSI_LOGIN_CURRENT_STAGE_3 0x0c 454 #define ISCSI_LOGIN_NEXT_STAGE_MASK 0x03 455 #define ISCSI_LOGIN_NEXT_STAGE_0 0x01 456 #define ISCSI_LOGIN_NEXT_STAGE_1 0x02 457 #define ISCSI_LOGIN_NEXT_STAGE_3 0x03 458 459 /* text flags */ 460 #define ISCSI_TEXT_CONTINUE 0x40 461 462 /* datain flags */ 463 #define ISCSI_DATAIN_ACKNOWLEDGE 0x40 464 #define ISCSI_DATAIN_OVERFLOW 0x04 465 #define ISCSI_DATAIN_UNDERFLOW 0x02 466 #define ISCSI_DATAIN_STATUS 0x01 467 468 /* SCSI resp flags */ 469 #define ISCSI_SCSI_BIDI_OVERFLOW 0x10 470 #define ISCSI_SCSI_BIDI_UNDERFLOW 0x08 471 #define ISCSI_SCSI_OVERFLOW 0x04 472 #define ISCSI_SCSI_UNDERFLOW 0x02 473 474 /* SCSI task flags */ 475 #define ISCSI_TASK_FUNCTION_MASK 0x7f 476 477 /* Reason for Reject */ 478 #define ISCSI_REASON_RESERVED 0x1 479 #define ISCSI_REASON_DATA_DIGEST_ERROR 0x2 480 #define ISCSI_REASON_DATA_SNACK_REJECT 0x3 481 #define ISCSI_REASON_PROTOCOL_ERROR 0x4 482 #define ISCSI_REASON_CMD_NOT_SUPPORTED 0x5 483 #define ISCSI_REASON_IMM_CMD_REJECT 0x6 484 #define ISCSI_REASON_TASK_IN_PROGRESS 0x7 485 #define ISCSI_REASON_INVALID_SNACK 0x8 486 #define ISCSI_REASON_INVALID_PDU_FIELD 0x9 487 #define ISCSI_REASON_LONG_OPERATION_REJECT 0xa 488 #define ISCSI_REASON_NEGOTIATION_RESET 0xb 489 #define ISCSI_REASON_WAIT_FOR_RESET 0xc 490 491 #define ISCSI_FLAG_SNACK_TYPE_DATA 0 492 #define ISCSI_FLAG_SNACK_TYPE_R2T 0 493 #define ISCSI_FLAG_SNACK_TYPE_STATUS 1 494 #define ISCSI_FLAG_SNACK_TYPE_DATA_ACK 2 495 #define ISCSI_FLAG_SNACK_TYPE_RDATA 3 496 #define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */ 497 498 struct iscsi_ahs { 499 /* 0-3 */ 500 uint8_t ahs_len[2]; 501 uint8_t ahs_type; 502 uint8_t ahs_specific1; 503 /* 4-x */ 504 uint8_t ahs_specific2[]; 505 }; 506 507 #define ISCSI_BHS_LOGIN_GET_TBIT(X) (!!(X & ISCSI_LOGIN_TRANSIT)) 508 #define ISCSI_BHS_LOGIN_GET_CBIT(X) (!!(X & ISCSI_LOGIN_CONTINUE)) 509 #define ISCSI_BHS_LOGIN_GET_CSG(X) ((X & ISCSI_LOGIN_CURRENT_STAGE_MASK) >> 2) 510 #define ISCSI_BHS_LOGIN_GET_NSG(X) (X & ISCSI_LOGIN_NEXT_STAGE_MASK) 511 512 #define ISCSI_CLASS_SUCCESS 0x00 513 #define ISCSI_CLASS_REDIRECT 0x01 514 #define ISCSI_CLASS_INITIATOR_ERROR 0x02 515 #define ISCSI_CLASS_TARGET_ERROR 0x03 516 517 /* Class (Success) detailed info: 0 */ 518 #define ISCSI_LOGIN_ACCEPT 0x00 519 520 /* Class (Redirection) detailed info: 1 */ 521 #define ISCSI_LOGIN_TARGET_TEMPORARILY_MOVED 0x01 522 #define ISCSI_LOGIN_TARGET_PERMANENTLY_MOVED 0x02 523 524 /* Class (Initiator Error) detailed info: 2 */ 525 #define ISCSI_LOGIN_INITIATOR_ERROR 0x00 526 #define ISCSI_LOGIN_AUTHENT_FAIL 0x01 527 #define ISCSI_LOGIN_AUTHORIZATION_FAIL 0x02 528 #define ISCSI_LOGIN_TARGET_NOT_FOUND 0x03 529 #define ISCSI_LOGIN_TARGET_REMOVED 0x04 530 #define ISCSI_LOGIN_UNSUPPORTED_VERSION 0x05 531 #define ISCSI_LOGIN_TOO_MANY_CONNECTIONS 0x06 532 #define ISCSI_LOGIN_MISSING_PARMS 0x07 533 #define ISCSI_LOGIN_CONN_ADD_FAIL 0x08 534 #define ISCSI_LOGIN_NOT_SUPPORTED_SESSION_TYPE 0x09 535 #define ISCSI_LOGIN_NO_SESSION 0x0a 536 #define ISCSI_LOGIN_INVALID_LOGIN_REQUEST 0x0b 537 538 /* Class (Target Error) detailed info: 3 */ 539 #define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00 540 #define ISCSI_LOGIN_STATUS_SERVICE_UNAVAILABLE 0x01 541 #define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02 542 543 #ifdef __cplusplus 544 } 545 #endif 546 547 #endif /* SPDK_ISCSI_SPEC_H */ 548