1 /** @file 2 The header file of iSCSI Protocol that defines many specific data structures. 3 4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #ifndef _ISCSI_PROTO_H_ 16 #define _ISCSI_PROTO_H_ 17 18 #include <Protocol/ScsiPassThruExt.h> 19 20 // 21 // RFC 1982 Serial Number Arithmetic, SERIAL_BITS = 32 22 // 23 #define ISCSI_SEQ_EQ(s1, s2) ((s1) == (s2)) 24 #define ISCSI_SEQ_LT(s1, s2) \ 25 ( \ 26 (((INT32) (s1) < (INT32) (s2)) && (s2 - s1) < ((UINT32) 1 << 31)) || \ 27 (((INT32) (s1) > (INT32) (s2)) && (s1 - s2) > ((UINT32) 1 << 31)) \ 28 ) 29 #define ISCSI_SEQ_GT(s1, s2) \ 30 ( \ 31 (((INT32) (s1) < (INT32) (s2)) && (s2 - s1) > ((UINT32) 1 << 31)) || \ 32 (((INT32) (s1) > (INT32) (s2)) && (s1 - s2) < ((UINT32) 1 << 31)) \ 33 ) 34 35 #define ISCSI_WELL_KNOWN_PORT 3260 36 #define ISCSI_MAX_CONNS_PER_SESSION 1 37 38 #define DEFAULT_MAX_RECV_DATA_SEG_LEN 8192 39 #define MAX_RECV_DATA_SEG_LEN_IN_FFP 65536 40 #define DEFAULT_MAX_OUTSTANDING_R2T 1 41 42 #define ISCSI_VERSION_MAX 0x00 43 #define ISCSI_VERSION_MIN 0x00 44 45 #define ISCSI_KEY_AUTH_METHOD "AuthMethod" 46 #define ISCSI_KEY_HEADER_DIGEST "HeaderDigest" 47 #define ISCSI_KEY_DATA_DIGEST "DataDigest" 48 #define ISCSI_KEY_MAX_CONNECTIONS "MaxConnections" 49 #define ISCSI_KEY_TARGET_NAME "TargetName" 50 #define ISCSI_KEY_INITIATOR_NAME "InitiatorName" 51 #define ISCSI_KEY_TARGET_ALIAS "TargetAlias" 52 #define ISCSI_KEY_INITIATOR_ALIAS "InitiatorAlias" 53 #define ISCSI_KEY_TARGET_ADDRESS "TargetAddress" 54 #define ISCSI_KEY_INITIAL_R2T "InitialR2T" 55 #define ISCSI_KEY_IMMEDIATE_DATA "ImmediateData" 56 #define ISCSI_KEY_TARGET_PORTAL_GROUP_TAG "TargetPortalGroupTag" 57 #define ISCSI_KEY_MAX_BURST_LENGTH "MaxBurstLength" 58 #define ISCSI_KEY_FIRST_BURST_LENGTH "FirstBurstLength" 59 #define ISCSI_KEY_DEFAULT_TIME2WAIT "DefaultTime2Wait" 60 #define ISCSI_KEY_DEFAULT_TIME2RETAIN "DefaultTime2Retain" 61 #define ISCSI_KEY_MAX_OUTSTANDING_R2T "MaxOutstandingR2T" 62 #define ISCSI_KEY_DATA_PDU_IN_ORDER "DataPDUInOrder" 63 #define ISCSI_KEY_DATA_SEQUENCE_IN_ORDER "DataSequenceInOrder" 64 #define ISCSI_KEY_ERROR_RECOVERY_LEVEL "ErrorRecoveryLevel" 65 #define ISCSI_KEY_SESSION_TYPE "SessionType" 66 #define ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH "MaxRecvDataSegmentLength" 67 68 #define ISCSI_KEY_VALUE_NONE "None" 69 70 /// 71 /// connection state for initiator 72 /// 73 74 #define CONN_STATE_FREE 0 75 #define CONN_STATE_XPT_WAIT 1 76 #define CONN_STATE_IN_LOGIN 2 77 #define CONN_STATE_LOGGED_IN 3 78 #define CONN_STATE_IN_LOGOUT 4 79 #define CONN_STATE_LOGOUT_REQUESTED 5 80 #define CONN_STATE_CLEANUP_WAIT 6 81 #define CONN_STATE_IN_CLEANUP 7 82 83 /// 84 /// session state for initiator 85 /// 86 #define SESSION_STATE_FREE 0 87 #define SESSION_STATE_LOGGED_IN 1 88 #define SESSION_STATE_FAILED 2 89 90 typedef enum { 91 DataIn = 0, 92 DataOut = 1, 93 DataBi = 2 94 } DATA_DIRECTION; 95 96 #define ISCSI_RESERVED_TAG 0xffffffff 97 98 #define ISCSI_REQ_IMMEDIATE 0x40 99 #define ISCSI_OPCODE_MASK 0x3F 100 101 #define ISCSI_SET_OPCODE(PduHdr, Op, Flgs) ((((ISCSI_BASIC_HEADER *) (PduHdr))->OpCode) = ((Op) | (Flgs))) 102 #define ISCSI_GET_OPCODE(PduHdr) ((((ISCSI_BASIC_HEADER *) (PduHdr))->OpCode) & ISCSI_OPCODE_MASK) 103 #define ISCSI_CHECK_OPCODE(PduHdr, Op) ((((PduHdr)->OpCode) & ISCSI_OPCODE_MASK) == (Op)) 104 #define ISCSI_IMMEDIATE_ON(PduHdr) ((PduHdr)->OpCode & ISCSI_REQ_IMMEDIATE) 105 #define ISCSI_SET_FLAG(PduHdr, Flag) (((ISCSI_BASIC_HEADER *) (PduHdr))->Flags |= (BOOLEAN)(Flag)) 106 #define ISCSI_CLEAR_FLAG(PduHdr, Flag) (((ISCSI_BASIC_HEADER *) (PduHdr))->Flags &= ~(Flag)) 107 #define ISCSI_FLAG_ON(PduHdr, Flag) ((((ISCSI_BASIC_HEADER *) (PduHdr))->Flags & (Flag)) == (Flag)) 108 #define ISCSI_SET_STAGES(PduHdr, Cur, Nxt) ((PduHdr)->Flags = (UINT8) ((PduHdr)->Flags | ((Cur) << 2 | (Nxt)))) 109 #define ISCSI_GET_CURRENT_STAGE(PduHdr) (((PduHdr)->Flags >> 2) & 0x3) 110 #define ISCSI_GET_NEXT_STAGE(PduHdr) (((PduHdr)->Flags) & 0x3) 111 112 #define ISCSI_GET_PAD_LEN(DataLen) ((~(DataLen) + 1) & 0x3) 113 #define ISCSI_ROUNDUP(DataLen) (((DataLen) + 3) &~(0x3)) 114 115 #define HTON24(Dst, Src) \ 116 do { \ 117 (Dst)[0] = (UINT8) (((Src) >> 16) & 0xFF); \ 118 (Dst)[1] = (UINT8) (((Src) >> 8) & 0xFF); \ 119 (Dst)[2] = (UINT8) ((Src) & 0xFF); \ 120 } while (0); 121 122 #define NTOH24(src) (((src)[0] << 16) | ((src)[1] << 8) | ((src)[2])) 123 124 #define ISCSI_GET_DATASEG_LEN(PduHdr) NTOH24 (((ISCSI_BASIC_HEADER *) (PduHdr))->DataSegmentLength) 125 #define ISCSI_SET_DATASEG_LEN(PduHdr, Len) HTON24 (((ISCSI_BASIC_HEADER *) (PduHdr))->DataSegmentLength, (Len)) 126 127 // 128 // initiator opcodes 129 // 130 #define ISCSI_OPCODE_NOP_OUT 0x00 131 #define ISCSI_OPCODE_SCSI_CMD 0x01 132 #define ISCSI_OPCODE_SCSI_TMF_REQ 0x02 133 #define ISCSI_OPCODE_LOGIN_REQ 0x03 134 #define ISCSI_OPCODE_TEXT_REQ 0x04 135 #define ISCSI_OPCODE_SCSI_DATA_OUT 0x05 136 #define ISCSI_OPCODE_LOGOUT_REQ 0x06 137 #define ISCSI_OPCODE_SNACK_REQ 0x10 138 #define ISCSI_OPCODE_VENDOR_I0 0x1c 139 #define ISCSI_OPCODE_VENDOR_I1 0x1d 140 #define ISCSI_OPCODE_VENDOR_I2 0x1e 141 142 // 143 // target opcodes 144 // 145 #define ISCSI_OPCODE_NOP_IN 0x20 146 #define ISCSI_OPCODE_SCSI_RSP 0x21 147 #define ISCSI_OPCODE_SCSI_TMF_RSP 0x22 148 #define ISCSI_OPCODE_LOGIN_RSP 0x23 149 #define ISCSI_OPCODE_TEXT_RSP 0x24 150 #define ISCSI_OPCODE_SCSI_DATA_IN 0x25 151 #define ISCSI_OPCODE_LOGOUT_RSP 0x26 152 #define ISCSI_OPCODE_R2T 0x31 153 #define ISCSI_OPCODE_ASYNC_MSG 0x32 154 #define ISCSI_OPCODE_VENDOR_T0 0x3c 155 #define ISCSI_OPCODE_VENDOR_T1 0x3d 156 #define ISCSI_OPCODE_VENDOR_T2 0x3e 157 #define ISCSI_OPCODE_REJECT 0x3f 158 159 #define ISCSI_BHS_FLAG_FINAL 0x80 160 161 /// 162 /// iSCSI Basic Header Segment 163 /// 164 typedef struct _ISCSI_BASIC_HEADER { 165 UINT8 OpCode; 166 UINT8 Flags; 167 UINT16 OpCodeSpecific1; 168 UINT8 TotalAHSLength; 169 UINT8 DataSegmentLength[3]; 170 UINT8 Lun[8]; 171 UINT32 InitiatorTaskTag; 172 UINT32 OpCodeSpecific2[7]; 173 } ISCSI_BASIC_HEADER; 174 175 // 176 // Defined AHS types, others are reserved. 177 // 178 #define ISCSI_AHS_TYPE_EXT_CDB 0x1 179 #define ISCSI_AHS_TYPE_BI_EXP_READ_DATA_LEN 0x2 180 181 typedef struct _ISCSI_ADDTIONAL_HEADER { 182 UINT16 Length; 183 UINT8 Type; 184 UINT8 TypeSpecific[1]; 185 } ISCSI_ADDITIONAL_HEADER; 186 187 typedef struct _ISCSI_BI_EXP_READ_DATA_LEN_AHS { 188 UINT16 Length; 189 UINT8 Type; 190 UINT8 Reserved; 191 UINT32 ExpReadDataLength; 192 } ISCSI_BI_EXP_READ_DATA_LEN_AHS; 193 194 #define SCSI_CMD_PDU_FLAG_READ 0x40 195 #define SCSI_CMD_PDU_FLAG_WRITE 0x20 196 197 #define ISCSI_CMD_PDU_TASK_ATTR_MASK 0x07 198 199 // 200 // task attributes 201 // 202 #define ISCSI_TASK_ATTR_UNTAGGED 0x00 203 #define ISCSI_TASK_ATTR_SIMPLE 0x01 204 #define ISCSI_TASK_ATTR_ORDERD 0x02 205 #define ISCSI_TASK_ATTR_HOQ 0x03 206 #define ISCSI_TASK_ATTR_ACA 0x04 207 208 /// 209 /// SCSI Command 210 /// 211 typedef struct _SCSI_COMMAND { 212 UINT8 OpCode; 213 UINT8 Flags; 214 UINT16 Reserved; 215 UINT8 TotalAHSLength; 216 UINT8 DataSegmentLength[3]; 217 UINT8 Lun[8]; 218 UINT32 InitiatorTaskTag; 219 UINT32 ExpDataXferLength; 220 UINT32 CmdSN; 221 UINT32 ExpStatSN; 222 UINT8 Cdb[16]; 223 } SCSI_COMMAND; 224 225 // 226 // flag bit definitions in SCSI response 227 // 228 #define SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW 0x10 229 #define SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW 0x08 230 #define SCSI_RSP_PDU_FLAG_OVERFLOW 0x04 231 #define SCSI_RSP_PDU_FLAG_UNDERFLOW 0x02 232 233 // 234 // iSCSI service response codes 235 // 236 #define ISCSI_SERVICE_RSP_COMMAND_COMPLETE_AT_TARGET 0x00 237 #define ISCSI_SERVICE_RSP_TARGET_FAILURE 0x01 238 239 /// 240 /// SCSI Response 241 /// 242 typedef struct _SCSI_RESPONSE { 243 UINT8 OpCode; 244 UINT8 Flags; 245 UINT8 Response; 246 UINT8 Status; 247 UINT8 TotalAHSLength; 248 UINT8 DataSegmentLength[3]; 249 UINT8 Reserved[8]; 250 UINT32 InitiatorTaskTag; 251 UINT32 SNACKTag; 252 UINT32 StatSN; 253 UINT32 ExpCmdSN; 254 UINT32 MaxCmdSN; 255 UINT32 ExpDataSN; 256 UINT32 BiReadResidualCount; 257 UINT32 ResidualCount; 258 } SCSI_RESPONSE; 259 260 typedef struct _ISCSI_SENSE_DATA { 261 UINT16 Length; 262 UINT8 Data[2]; 263 } ISCSI_SENSE_DATA; 264 265 /// 266 /// iSCSI Task Managment Function Request 267 /// 268 typedef struct _ISCSI_TMF_REQUEST { 269 UINT8 OpCode; 270 UINT8 Fuction; 271 UINT16 Reserved1; 272 UINT8 TotalAHSLength; 273 UINT8 DataSegmentLength[3]; 274 UINT8 Lun[8]; 275 UINT32 InitiatorTaskTag; 276 UINT32 ReferencedTaskTag; 277 UINT32 CmdSN; 278 UINT32 ExpStatSN; 279 UINT32 RefCmdSN; 280 UINT32 ExpDataSN; 281 UINT32 Reserved2[2]; 282 } ISCSI_TMF_REQUEST; 283 284 #define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_COMPLETE 0 285 #define ISCSI_TMF_RSP_PDU_RSP_TASK_NOT_EXIST 1 286 #define ISCSI_TMF_RSP_PDU_RSP_LUN_NOT_EXIST 2 287 #define ISCSI_TMF_RSP_PDU_RSP_TASK_STILL_ALLEGIANT 3 288 #define ISCSI_TMF_RSP_PDU_RSP_TASK_REASSGIN_NOT_SUPPORTED 4 289 #define ISCSI_TMF_RSP_PDU_RSP_NOT_SUPPORTED 5 290 #define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_AHTH_FAILED 6 291 #define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_REJECTED 255 292 293 /// 294 /// iSCSI Task Management Function Response 295 /// 296 typedef struct _ISCSI_TMF_RESPONSE { 297 UINT8 OpCode; 298 UINT8 Reserved1; 299 UINT8 Response; 300 UINT8 Reserved2; 301 UINT8 TotalAHSLength; 302 UINT8 DataSegmentLength[3]; 303 UINT32 Reserver3[2]; 304 UINT32 InitiatorTaskTag; 305 UINT32 Reserved4; 306 UINT32 StatSN; 307 UINT32 ExpCmdSN; 308 UINT32 MaxCmdSN; 309 UINT32 Reserved[3]; 310 } ISCSI_TMF_RESPONSE; 311 312 /// 313 /// SCSI Data-Out 314 /// 315 typedef struct _ISCSI_SCSI_DATA_OUT { 316 UINT8 OpCode; 317 UINT8 Reserved1[3]; 318 UINT8 TotalAHSLength; 319 UINT8 DataSegmentLength[3]; 320 UINT8 Lun[8]; 321 UINT32 InitiatorTaskTag; 322 UINT32 TargetTransferTag; 323 UINT32 Reserved2; 324 UINT32 ExpStatSN; 325 UINT32 Reserved3; 326 UINT32 DataSN; 327 UINT32 BufferOffset; 328 UINT32 Reserved4; 329 } ISCSI_SCSI_DATA_OUT; 330 331 #define SCSI_DATA_IN_PDU_FLAG_ACKKNOWLEDGE 0x40 332 #define SCSI_DATA_IN_PDU_FLAG_OVERFLOW SCSI_RSP_PDU_FLAG_OVERFLOW 333 #define SCSI_DATA_IN_PDU_FLAG_UNDERFLOW SCSI_RSP_PDU_FLAG_UNDERFLOW 334 #define SCSI_DATA_IN_PDU_FLAG_STATUS_VALID 0x01 335 336 /// 337 /// SCSI Data-In 338 /// 339 typedef struct _ISCSI_SCSI_DATA_IN { 340 UINT8 OpCode; 341 UINT8 Flags; 342 UINT8 Reserved1; 343 UINT8 Status; 344 UINT8 TotalAHSLength; 345 UINT8 DataSegmentLength[3]; 346 UINT8 Lun[8]; 347 UINT32 InitiatorTaskTag; 348 UINT32 TargetTransferTag; 349 UINT32 StatSN; 350 UINT32 ExpCmdSN; 351 UINT32 MaxCmdSN; 352 UINT32 DataSN; 353 UINT32 BufferOffset; 354 UINT32 ResidualCount; 355 } ISCSI_SCSI_DATA_IN; 356 357 #define ISCSI_GET_BUFFER_OFFSET(PduHdr) NTOHL (((ISCSI_SCSI_DATA_IN *) (PduHdr))->BufferOffset) 358 359 /// 360 /// Ready To Transfer 361 /// 362 typedef struct _ISCSI_READY_TO_TRANSFER { 363 UINT8 OpCode; 364 UINT8 Reserved1[3]; 365 UINT8 TotalAHSLength; 366 UINT8 DataSegmentLength[3]; 367 UINT8 Lun[8]; 368 UINT32 InitiatorTaskTag; 369 UINT32 TargetTransferTag; 370 UINT32 StatSN; 371 UINT32 ExpCmdSN; 372 UINT32 MaxCmdSN; 373 UINT32 R2TSeqNum; 374 UINT32 BufferOffset; 375 UINT32 DesiredDataTransferLength; 376 } ISCSI_READY_TO_TRANSFER; 377 378 typedef struct _ISCSI_ASYNC_MESSAGE { 379 UINT8 OpCode; 380 UINT8 Reserved1[8]; 381 UINT8 TotalAHSLength; 382 UINT8 DataSegmentLength[3]; 383 UINT8 Lun[8]; 384 UINT32 InitiatorTaskTag; 385 UINT32 Reserved2; 386 UINT32 StatSN; 387 UINT32 ExpCmdSN; 388 UINT32 MaxCmdSN; 389 UINT8 AsyncEvent; 390 UINT8 AsyncVCode; 391 UINT16 Parameter1; 392 UINT16 Parameter2; 393 UINT16 Parameter3; 394 UINT32 Reserved3; 395 } ISCSI_ASYNC_MESSAGE; 396 397 #define ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT 0x80 398 #define ISCSI_LOGIN_REQ_PDU_FLAG_CONTINUE 0x40 399 400 /// 401 /// Login Request 402 /// 403 typedef struct _ISCSI_LOGIN_REQUEST { 404 UINT8 OpCode; 405 UINT8 Flags; 406 UINT8 VersionMax; 407 UINT8 VersionMin; 408 UINT8 TotalAHSLength; 409 UINT8 DataSegmentLength[3]; 410 UINT8 Isid[6]; 411 UINT16 Tsih; 412 UINT32 InitiatorTaskTag; 413 UINT16 Cid; 414 UINT16 Reserved1; 415 UINT32 CmdSN; 416 UINT32 ExpStatSN; 417 UINT32 Reserved2[4]; 418 } ISCSI_LOGIN_REQUEST; 419 420 #define ISCSI_LOGIN_RSP_PDU_FLAG_TRANSIT ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT 421 #define ISCSI_LOGIN_RSP_PDU_FLAG_CONTINUE ISCSI_LOGIN_REQ_PDU_FLAG_CONTINUE 422 423 #define ISCSI_LOGIN_STATUS_SUCCESS 0 424 #define ISCSI_LOGIN_STATUS_REDIRECTION 1 425 #define ISCSI_LOGIN_STATUS_INITIATOR_ERROR 2 426 #define ISCSI_LOGIN_STATUS_TARGET_ERROR 3 427 428 /// 429 /// Login Response 430 /// 431 typedef struct _ISCSI_LOGIN_RESPONSE { 432 UINT8 OpCode; 433 UINT8 Flags; 434 UINT8 VersionMax; 435 UINT8 VersionActive; 436 UINT8 TotalAHSLength; 437 UINT8 DataSegmentLength[3]; 438 UINT8 Isid[6]; 439 UINT16 Tsih; 440 UINT32 InitiatorTaskTag; 441 UINT32 Reserved1; 442 UINT32 StatSN; 443 UINT32 ExpCmdSN; 444 UINT32 MaxCmdSN; 445 UINT8 StatusClass; 446 UINT8 StatusDetail; 447 UINT8 Reserved2[10]; 448 } ISCSI_LOGIN_RESPONSE; 449 450 #define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0 451 #define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1 452 #define ISCSI_LOGOUT_REASON_REMOVE_CONNECTION_FOR_RECOVERY 2 453 454 /// 455 /// Logout Request 456 /// 457 typedef struct _ISCSI_LOGOUT_REQUEST { 458 UINT8 OpCode; 459 UINT8 ReasonCode; 460 UINT16 Reserved1; 461 UINT8 TotalAHSLength; 462 UINT8 DataSegmentLength[3]; 463 UINT32 Reserved2[2]; 464 UINT32 InitiatorTaskTag; 465 UINT16 Cid; 466 UINT16 Reserved3; 467 UINT32 CmdSN; 468 UINT32 ExpStatSN; 469 UINT32 Reserved4[4]; 470 } ISCSI_LOGOUT_REQUEST; 471 472 #define ISCSI_LOGOUT_RESPONSE_SESSION_CLOSED_SUCCESS 0 473 #define ISCSI_LOGOUT_RESPONSE_CID_NOT_FOUND 1 474 #define ISCSI_LOGOUT_RESPONSE_RECOVERY_NOT_SUPPORTED 2 475 #define ISCSI_LOGOUT_RESPONSE_CLEANUP_FAILED 3 476 477 /// 478 /// Logout Response 479 /// 480 typedef struct _ISCSI_LOGOUT_RESPONSE { 481 UINT8 OpCode; 482 UINT8 Reserved1; 483 UINT8 Response; 484 UINT8 Reserved2; 485 UINT8 TotalAHSLength; 486 UINT8 DataSegmentLength[3]; 487 UINT32 Reserved3[2]; 488 UINT32 InitiatorTaskTag; 489 UINT32 Reserved4; 490 UINT32 StatSN; 491 UINT32 ExpCmdSN; 492 UINT32 MaxCmdSN; 493 UINT32 Reserved5; 494 UINT16 Time2Wait; 495 UINT16 Time2Retain; 496 UINT32 Reserved6; 497 } ISCSI_LOGOUT_RESPONSE; 498 499 #define ISCSI_SNACK_REQUEST_TYPE_DATA_OR_R2T 0 500 #define ISCSI_SNACK_REQUEST_TYPE_STATUS 1 501 #define ISCSI_SNACK_REQUEST_TYPE_DATA_ACK 2 502 #define ISCSI_SNACK_REQUEST_TYPE_RDATA 3 503 504 /// 505 /// SNACK Request 506 /// 507 typedef struct _ISCSI_SNACK_REQUEST { 508 UINT8 OpCode; 509 UINT8 Type; 510 UINT16 Reserved1; 511 UINT8 TotalAHSLength; 512 UINT8 DataSegmentLength[3]; 513 UINT8 Lun[8]; 514 UINT32 InitiatorTaskTag; 515 UINT32 TargetTransferTag; 516 UINT32 Reserved2; 517 UINT32 ExpStatSN; 518 UINT32 Reserved[2]; 519 UINT32 BegRun; 520 UINT32 RunLength; 521 } ISCSI_SNACK_REQUEST; 522 523 /// 524 /// Reject 525 /// 526 typedef struct _ISCSI_REJECT { 527 UINT8 OpCode; 528 UINT8 Reserved1; 529 UINT8 Reason; 530 UINT8 Reserved2; 531 UINT8 TotalAHSLength; 532 UINT8 DataSegmentLength[3]; 533 UINT32 Reserved3[2]; 534 UINT32 InitiatorTaskTag; 535 UINT32 Reserved4; 536 UINT32 StatSN; 537 UINT32 ExpCmdSN; 538 UINT32 MaxCmdSN; 539 UINT32 DataSN; 540 UINT32 Reserved5[2]; 541 } ISCSI_REJECT; 542 543 /// 544 /// NOP-Out 545 /// 546 typedef struct _ISCSI_NOP_OUT { 547 UINT8 OpCode; 548 UINT8 Reserved1[3]; 549 UINT8 TotalAHSLength; 550 UINT8 DataSegmentLength[3]; 551 UINT8 Lun[8]; 552 UINT32 InitiatorTaskTag; 553 UINT32 TargetTransferTag; 554 UINT32 CmdSN; 555 UINT32 ExpStatSN; 556 UINT32 Reserved2[4]; 557 } ISCSI_NOP_OUT; 558 559 /// 560 /// NOP-In 561 /// 562 typedef struct _ISCSI_NOP_IN { 563 UINT8 OpCode; 564 UINT8 Reserved1[3]; 565 UINT8 TotalAHSLength; 566 UINT8 DataSegmentLength[3]; 567 UINT8 Lun[8]; 568 UINT32 InitiatorTaskTag; 569 UINT32 TargetTransferTag; 570 UINT32 StatSN; 571 UINT32 ExpCmdSN; 572 UINT32 MaxCmdSN; 573 UINT32 Reserved2[3]; 574 } ISCSI_NOP_IN; 575 576 #define ISCSI_SECURITY_NEGOTIATION 0 577 #define ISCSI_LOGIN_OPERATIONAL_NEGOTIATION 1 578 #define ISCSI_FULL_FEATURE_PHASE 3 579 580 typedef enum { 581 IScsiDigestNone, 582 IScsiDigestCRC32 583 } ISCSI_DIGEST_TYPE; 584 585 typedef struct _ISCSI_XFER_CONTEXT { 586 UINT32 TargetTransferTag; 587 UINT32 Offset; 588 UINT32 DesiredLength; 589 UINT32 ExpDataSN; 590 } ISCSI_XFER_CONTEXT; 591 592 typedef struct _ISCSI_IN_BUFFER_CONTEXT { 593 UINT8 *InData; 594 UINT32 InDataLen; 595 } ISCSI_IN_BUFFER_CONTEXT; 596 597 typedef struct _ISCSI_TCB { 598 LIST_ENTRY Link; 599 600 BOOLEAN SoFarInOrder; 601 UINT32 ExpDataSN; 602 BOOLEAN FbitReceived; 603 BOOLEAN StatusXferd; 604 UINT32 ActiveR2Ts; 605 UINT32 Response; 606 CHAR8 *Reason; 607 UINT32 InitiatorTaskTag; 608 UINT32 CmdSN; 609 UINT32 SNACKTag; 610 611 ISCSI_XFER_CONTEXT XferContext; 612 613 ISCSI_CONNECTION *Conn; 614 } ISCSI_TCB; 615 616 typedef struct _ISCSI_KEY_VALUE_PAIR { 617 LIST_ENTRY List; 618 619 CHAR8 *Key; 620 CHAR8 *Value; 621 } ISCSI_KEY_VALUE_PAIR; 622 623 /** 624 Attach the iSCSI connection to the iSCSI session. 625 626 @param[in, out] Session The iSCSI session. 627 @param[in, out] Conn The iSCSI connection. 628 **/ 629 VOID 630 IScsiAttatchConnection ( 631 IN OUT ISCSI_SESSION *Session, 632 IN OUT ISCSI_CONNECTION *Conn 633 ); 634 635 /** 636 Detach the iSCSI connection from the session it belongs to. 637 638 @param[in, out] Conn The iSCSI connection. 639 **/ 640 VOID 641 IScsiDetatchConnection ( 642 IN OUT ISCSI_CONNECTION *Conn 643 ); 644 645 /** 646 This function does the iSCSI connection login. 647 648 @param[in, out] Conn The iSCSI connection to login. 649 650 @retval EFI_SUCCESS The iSCSI connection is logged into the iSCSI target. 651 @retval EFI_TIMEOUT Timeout happened during the login procedure. 652 @retval Others Other errors as indicated. 653 **/ 654 EFI_STATUS 655 IScsiConnLogin ( 656 IN OUT ISCSI_CONNECTION *Conn 657 ); 658 659 /** 660 Create a TCP connection for the iSCSI session. 661 662 @param[in] Private The iSCSI driver data. 663 @param[in] Session Maximum CmdSN from the target. 664 665 @return The newly created iSCSI connection. 666 **/ 667 ISCSI_CONNECTION * 668 IScsiCreateConnection ( 669 IN ISCSI_DRIVER_DATA *Private, 670 IN ISCSI_SESSION *Session 671 ); 672 673 /** 674 Destroy an iSCSI connection. 675 676 @param[in] Conn The connection to destroy. 677 **/ 678 VOID 679 IScsiDestroyConnection ( 680 IN ISCSI_CONNECTION *Conn 681 ); 682 683 /** 684 Login the iSCSI session. 685 686 @param[in] Private The iSCSI driver data. 687 688 @retval EFI_SUCCESS The iSCSI session login procedure finished. 689 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 690 @retval EFI_NO_MEDIA There was a media error. 691 @retval Others Other errors as indicated. 692 693 **/ 694 EFI_STATUS 695 IScsiSessionLogin ( 696 IN ISCSI_DRIVER_DATA *Private 697 ); 698 699 /** 700 Build and send the iSCSI login request to the iSCSI target according to 701 the current login stage. 702 703 @param[in] Conn The connection in the iSCSI login phase. 704 705 @retval EFI_SUCCESS The iSCSI login request PDU is built and sent on this 706 connection. 707 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 708 @retval EFI_DEVICE_ERROR Some kind of device error happened. 709 **/ 710 EFI_STATUS 711 IScsiSendLoginReq ( 712 IN ISCSI_CONNECTION *Conn 713 ); 714 715 /** 716 Receive and process the iSCSI login response. 717 718 @param[in] Conn The connection in the iSCSI login phase. 719 720 @retval EFI_SUCCESS The iSCSI login response PDU is received and processed. 721 @retval Others Other errors as indicated. 722 **/ 723 EFI_STATUS 724 IScsiReceiveLoginRsp ( 725 IN ISCSI_CONNECTION *Conn 726 ); 727 728 /** 729 Add an iSCSI key-value pair as a string into the data segment of the Login Request PDU. 730 The DataSegmentLength and the actual size of the net buffer containing this PDU will be 731 updated. 732 733 @param[in, out] Pdu The iSCSI PDU whose data segment the key-value pair will 734 be added to. 735 @param[in] Key The key name string. 736 @param[in] Value The value string. 737 738 @retval EFI_SUCCESS The key-valu pair is added to the PDU's datasegment and 739 the correspondence length fields are updated. 740 @retval EFI_OUT_OF_RESOURCES There is not enough space in the PDU to add the key-value 741 pair. 742 **/ 743 EFI_STATUS 744 IScsiAddKeyValuePair ( 745 IN OUT NET_BUF *Pdu, 746 IN CHAR8 *Key, 747 IN CHAR8 *Value 748 ); 749 750 /** 751 Prepare the iSCSI login request to be sent according to the current login status. 752 753 @param[in, out] Conn The connection in the iSCSI login phase. 754 755 @return The pointer to the net buffer containing the iSCSI login request built. 756 @retval Others Other errors as indicated. 757 **/ 758 NET_BUF * 759 IScsiPrepareLoginReq ( 760 IN OUT ISCSI_CONNECTION *Conn 761 ); 762 763 /** 764 Process the iSCSI Login Response. 765 766 @param[in, out] Conn The connection on which the iSCSI login response is received. 767 @param[in, out] Pdu The iSCSI login response PDU. 768 769 @retval EFI_SUCCESS The iSCSI login response PDU is processed and all check are passed. 770 @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error happened. 771 @retval EFI_MEDIA_CHANGED Target is redirected. 772 @retval Others Other errors as indicated. 773 **/ 774 EFI_STATUS 775 IScsiProcessLoginRsp ( 776 IN OUT ISCSI_CONNECTION *Conn, 777 IN OUT NET_BUF *Pdu 778 ); 779 780 /** 781 Updated the target information according the data received in the iSCSI 782 login response with an target redirection status. 783 784 @param[in, out] Session The iSCSI session. 785 @param[in] Data The data segment which should contain the 786 TargetAddress key-value list. 787 @param[in] Len Length of the data. 788 789 @retval EFI_SUCCESS The target address is updated. 790 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 791 @retval EFI_NOT_FOUND The TargetAddress key is not found. 792 @retval Others Other errors as indicated. 793 **/ 794 EFI_STATUS 795 IScsiUpdateTargetAddress ( 796 IN OUT ISCSI_SESSION *Session, 797 IN CHAR8 *Data, 798 IN UINT32 Len 799 ); 800 801 /** 802 The callback function to free the net buffer list. 803 804 @param[in] Arg The opaque parameter. 805 **/ 806 VOID 807 EFIAPI 808 IScsiFreeNbufList ( 809 VOID *Arg 810 ); 811 812 /** 813 Receive an iSCSI response PDU. An iSCSI response PDU contains an iSCSI PDU header and 814 an optional data segment. The two parts will be put into two blocks of buffers in the 815 net buffer. The digest check will be conducted in this function if needed and the digests 816 will be trimmed from the PDU buffer. 817 818 @param[in] Conn The iSCSI connection to receive data from. 819 @param[out] Pdu The received iSCSI pdu. 820 @param[in] Context The context used to describe information on the caller provided 821 buffer to receive data segment of the iSCSI pdu, it's optional. 822 @param[in] HeaderDigest Whether there will be header digest received. 823 @param[in] DataDigest Whether there will be data digest. 824 @param[in] TimeoutEvent The timeout event, it's optional. 825 826 @retval EFI_SUCCESS An iSCSI pdu is received. 827 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 828 @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error happened. 829 @retval Others Other errors as indicated. 830 **/ 831 EFI_STATUS 832 IScsiReceivePdu ( 833 IN ISCSI_CONNECTION *Conn, 834 OUT NET_BUF **Pdu, 835 IN ISCSI_IN_BUFFER_CONTEXT *Context, OPTIONAL 836 IN BOOLEAN HeaderDigest, 837 IN BOOLEAN DataDigest, 838 IN EFI_EVENT TimeoutEvent OPTIONAL 839 ); 840 841 /** 842 Check and get the result of the prameter negotiation. 843 844 @param[in, out] Conn The connection in iSCSI login. 845 846 @retval EFI_SUCCESS The parmeter check is passed and negotiation is finished. 847 @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error happened. 848 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 849 **/ 850 EFI_STATUS 851 IScsiCheckOpParams ( 852 IN OUT ISCSI_CONNECTION *Conn 853 ); 854 855 /** 856 Fill the oprational prameters. 857 858 @param[in] Conn The connection in iSCSI login. 859 @param[in, out] Pdu The iSCSI login request PDU to fill the parameters. 860 861 @retval EFI_SUCCESS The parmeters are filled into the iSCSI login request PDU. 862 **/ 863 EFI_STATUS 864 IScsiFillOpParams ( 865 IN ISCSI_CONNECTION *Conn, 866 IN OUT NET_BUF *Pdu 867 ); 868 869 /** 870 Pad the iSCSI AHS or data segment to an integer number of 4 byte words. 871 872 @param[in, out] Pdu The iSCSI pdu which contains segments to pad. 873 @param[in] Len The length of the last semgnet in the PDU. 874 875 @retval EFI_SUCCESS The segment is padded or no need to pad it. 876 @retval EFI_OUT_OF_RESOURCES There is not enough remaining free space to add the 877 padding bytes. 878 **/ 879 EFI_STATUS 880 IScsiPadSegment ( 881 IN OUT NET_BUF *Pdu, 882 IN UINT32 Len 883 ); 884 885 /** 886 Build a key-value list from the data segment. 887 888 @param[in] Data The data segment containing the key-value pairs. 889 @param[in] Len Length of the data segment. 890 891 @return The key-value list. 892 @retval NULL Other errors as indicated. 893 **/ 894 LIST_ENTRY * 895 IScsiBuildKeyValueList ( 896 IN CHAR8 *Data, 897 IN UINT32 Len 898 ); 899 900 /** 901 Get the value string by the key name from the key-value list. If found, 902 the key-value entry will be removed from the list. 903 904 @param[in, out] KeyValueList The key-value list. 905 @param[in] Key The key name to find. 906 907 @return The value string. 908 **/ 909 CHAR8 * 910 IScsiGetValueByKeyFromList ( 911 IN OUT LIST_ENTRY *KeyValueList, 912 IN CHAR8 *Key 913 ); 914 915 /** 916 Free the key-value list. 917 918 @param[in] KeyValueList The key-value list. 919 **/ 920 VOID 921 IScsiFreeKeyValueList ( 922 IN LIST_ENTRY *KeyValueList 923 ); 924 925 /** 926 Normalize the iSCSI name according to RFC. 927 928 @param[in, out] Name The iSCSI name. 929 @param[in] Len length of the iSCSI name. 930 931 @retval EFI_SUCCESS The iSCSI name is valid and normalized. 932 @retval EFI_PROTOCOL_ERROR The iSCSI name is mal-formatted or not in the IQN format. 933 **/ 934 EFI_STATUS 935 IScsiNormalizeName ( 936 IN OUT CHAR8 *Name, 937 IN UINTN Len 938 ); 939 940 /** 941 Execute the SCSI command issued through the EXT SCSI PASS THRU protocol. 942 943 @param[in] PassThru The EXT SCSI PASS THRU protocol. 944 @param[in] Target The target ID. 945 @param[in] Lun The LUN. 946 @param[in, out] Packet The request packet containing IO request, SCSI command 947 buffer and buffers to read/write. 948 949 @retval EFI_SUCCES The SCSI command is executed and the result is updated to 950 the Packet. 951 @retval EFI_DEVICE_ERROR Session state was not as required. 952 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 953 @retval EFI_NOT_READY The target can not accept new commands. 954 @retval Others Other errors as indicated. 955 **/ 956 EFI_STATUS 957 IScsiExecuteScsiCommand ( 958 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru, 959 IN UINT8 *Target, 960 IN UINT64 Lun, 961 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet 962 ); 963 964 /** 965 Reinstate the session on some error. 966 967 @param[in, out] Private The iSCSI driver data. 968 969 @retval EFI_SUCCES The session is reinstated from some error. 970 @retval Other Reinstatement failed. 971 **/ 972 EFI_STATUS 973 IScsiSessionReinstatement ( 974 IN OUT ISCSI_DRIVER_DATA *Private 975 ); 976 977 /** 978 Initialize some session parameters before login. 979 980 @param[in, out] Session The iSCSI session. 981 @param[in] Recovery Whether the request is from a fresh new start or recovery. 982 **/ 983 VOID 984 IScsiSessionInit ( 985 IN OUT ISCSI_SESSION *Session, 986 IN BOOLEAN Recovery 987 ); 988 989 /** 990 Abort the iSCSI session, that is, reset all the connection and free the 991 resources. 992 993 @param[in, out] Session The iSCSI session. 994 995 @retval EFI_SUCCES The session is aborted. 996 **/ 997 EFI_STATUS 998 IScsiSessionAbort ( 999 IN OUT ISCSI_SESSION *Session 1000 ); 1001 1002 #endif 1003