3 Copyright (c) 2004 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Protocol definitions for iSCSI driver, mainly from RFC3720.
22 #ifndef _ISCSI_PROTO_H_
23 #define _ISCSI_PROTO_H_
25 #include <protocol/ScsiPassThruExt.h>
28 // RFC 1982 Serial Number Arithmetic, SERIAL_BITS = 32
30 #define ISCSI_SEQ_EQ(s1, s2) ((s1) == (s2))
31 #define ISCSI_SEQ_LT(s1, s2) \
33 (((INT32) (s1) < (INT32) (s2)) && (s2 - s1) < (1 << 31)) || \
34 (((INT32) (s1) > (INT32) (s2)) && (s1 - s2) > (1 << 31)) \
36 #define ISCSI_SEQ_GT(s1, s2) \
38 (((INT32) (s1) < (INT32) (s2)) && (s2 - s1) > (1 << 31)) || \
39 (((INT32) (s1) > (INT32) (s2)) && (s1 - s2) < (1 << 31)) \
42 #define ISCSI_WELL_KNOWN_PORT 3260
43 #define ISCSI_MAX_CONNS_PER_SESSION 1
45 #define DEFAULT_MAX_RECV_DATA_SEG_LEN 8192
46 #define MAX_RECV_DATA_SEG_LEN_IN_FFP 65536
47 #define DEFAULT_MAX_OUTSTANDING_R2T 1
49 #define ISCSI_VERSION_MAX 0x00
50 #define ISCSI_VERSION_MIN 0x00
52 #define ISID_BYTE_0 0 // OUI format
54 #define ISID_BYTE_2 0xaa
55 #define ISID_BYTE_3 0x1
57 #define ISCSI_KEY_AUTH_METHOD "AuthMethod"
58 #define ISCSI_KEY_HEADER_DIGEST "HeaderDigest"
59 #define ISCSI_KEY_DATA_DIGEST "DataDigest"
60 #define ISCSI_KEY_MAX_CONNECTIONS "MaxConnections"
61 #define ISCSI_KEY_TARGET_NAME "TargetName"
62 #define ISCSI_KEY_INITIATOR_NAME "InitiatorName"
63 #define ISCSI_KEY_TARGET_ALIAS "TargetAlias"
64 #define ISCSI_KEY_INITIATOR_ALIAS "InitiatorAlias"
65 #define ISCSI_KEY_TARGET_ADDRESS "TargetAddress"
66 #define ISCSI_KEY_INITIAL_R2T "InitialR2T"
67 #define ISCSI_KEY_IMMEDIATE_DATA "ImmediateData"
68 #define ISCSI_KEY_TARGET_PORTAL_GROUP_TAG "TargetPortalGroupTag"
69 #define ISCSI_KEY_MAX_BURST_LENGTH "MaxBurstLength"
70 #define ISCSI_KEY_FIRST_BURST_LENGTH "FirstBurstLength"
71 #define ISCSI_KEY_DEFAULT_TIME2WAIT "DefaultTime2Wait"
72 #define ISCSI_KEY_DEFAULT_TIME2RETAIN "DefaultTime2Retain"
73 #define ISCSI_KEY_MAX_OUTSTANDING_R2T "MaxOutstandingR2T"
74 #define ISCSI_KEY_DATA_PDU_IN_ORDER "DataPDUInOrder"
75 #define ISCSI_KEY_DATA_SEQUENCE_IN_ORDER "DataSequenceInOrder"
76 #define ISCSI_KEY_ERROR_RECOVERY_LEVEL "ErrorRecoveryLevel"
77 #define ISCSI_KEY_SESSION_TYPE "SessionType"
78 #define ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH "MaxRecvDataSegmentLength"
80 #define ISCSI_KEY_VALUE_NONE "None"
83 // connection state for initiator
91 CONN_STATE_LOGOUT_REQUESTED
,
92 CONN_STATE_CLEANUP_WAIT
,
97 // session state for initiator
101 SESSION_STATE_LOGGED_IN
,
111 #define ISCSI_RESERVED_TAG 0xffffffff
113 #define ISCSI_REQ_IMMEDIATE 0x40
114 #define ISCSI_OPCODE_MASK 0x3F
116 #define ISCSI_SET_OPCODE(PduHdr, Op, Flgs) ((((ISCSI_BASIC_HEADER *) (PduHdr))->OpCode) = ((Op) | (Flgs)))
117 #define ISCSI_GET_OPCODE(PduHdr) ((((ISCSI_BASIC_HEADER *) (PduHdr))->OpCode) & ISCSI_OPCODE_MASK)
118 #define ISCSI_CHECK_OPCODE(PduHdr, Op) ((((PduHdr)->OpCode) & ISCSI_OPCODE_MASK) == (Op))
119 #define ISCSI_IMMEDIATE_ON(PduHdr) ((PduHdr)->OpCode & ISCSI_REQ_IMMEDIATE)
120 #define ISCSI_SET_FLAG(PduHdr, Flag) (((ISCSI_BASIC_HEADER *) (PduHdr))->Flags |= (BOOLEAN)(Flag))
121 #define ISCSI_CLEAR_FLAG(PduHdr, Flag) (((ISCSI_BASIC_HEADER *) (PduHdr))->Flags &= ~(Flag))
122 #define ISCSI_FLAG_ON(PduHdr, Flag) ((((ISCSI_BASIC_HEADER *) (PduHdr))->Flags & (Flag)) == (Flag))
123 #define ISCSI_SET_STAGES(PduHdr, Cur, Nxt) ((PduHdr)->Flags = (UINT8) ((PduHdr)->Flags | ((Cur) << 2 | (Nxt))))
124 #define ISCSI_GET_CURRENT_STAGE(PduHdr) (((PduHdr)->Flags >> 2) & 0x3)
125 #define ISCSI_GET_NEXT_STAGE(PduHdr) (((PduHdr)->Flags) & 0x3)
127 #define ISCSI_GET_PAD_LEN(DataLen) ((~(DataLen) + 1) & 0x3)
128 #define ISCSI_ROUNDUP(DataLen) (((DataLen) + 3) &~(0x3))
130 #define HTON24(Dst, Src) \
132 (Dst)[0] = (UINT8) (((Src) >> 16) & 0xFF); \
133 (Dst)[1] = (UINT8) (((Src) >> 8) & 0xFF); \
134 (Dst)[2] = (UINT8) ((Src) & 0xFF); \
137 #define NTOH24(src) (((src)[0] << 16) | ((src)[1] << 8) | ((src)[2]))
139 #define ISCSI_GET_DATASEG_LEN(PduHdr) NTOH24 (((ISCSI_BASIC_HEADER *) (PduHdr))->DataSegmentLength)
140 #define ISCSI_SET_DATASEG_LEN(PduHdr, Len) HTON24 (((ISCSI_BASIC_HEADER *) (PduHdr))->DataSegmentLength, (Len))
145 #define ISCSI_OPCODE_NOP_OUT 0x00
146 #define ISCSI_OPCODE_SCSI_CMD 0x01
147 #define ISCSI_OPCODE_SCSI_TMF_REQ 0x02
148 #define ISCSI_OPCODE_LOGIN_REQ 0x03
149 #define ISCSI_OPCODE_TEXT_REQ 0x04
150 #define ISCSI_OPCODE_SCSI_DATA_OUT 0x05
151 #define ISCSI_OPCODE_LOGOUT_REQ 0x06
152 #define ISCSI_OPCODE_SNACK_REQ 0x10
153 #define ISCSI_OPCODE_VENDOR_I0 0x1c
154 #define ISCSI_OPCODE_VENDOR_I1 0x1d
155 #define ISCSI_OPCODE_VENDOR_I2 0x1e
160 #define ISCSI_OPCODE_NOP_IN 0x20
161 #define ISCSI_OPCODE_SCSI_RSP 0x21
162 #define ISCSI_OPCODE_SCSI_TMF_RSP 0x22
163 #define ISCSI_OPCODE_LOGIN_RSP 0x23
164 #define ISCSI_OPCODE_TEXT_RSP 0x24
165 #define ISCSI_OPCODE_SCSI_DATA_IN 0x25
166 #define ISCSI_OPCODE_LOGOUT_RSP 0x26
167 #define ISCSI_OPCODE_R2T 0x31
168 #define ISCSI_OPCODE_ASYNC_MSG 0x32
169 #define ISCSI_OPCODE_VENDOR_T0 0x3c
170 #define ISCSI_OPCODE_VENDOR_T1 0x3d
171 #define ISCSI_OPCODE_VENDOR_T2 0x3e
172 #define ISCSI_OPCODE_REJECT 0x3f
174 #define ISCSI_BHS_FLAG_FINAL 0x80
177 // iSCSI Basic Header Segment
179 typedef struct _ISCSI_BASIC_HEADER
{
182 UINT16 OpCodeSpecific1
;
183 UINT8 TotalAHSLength
;
184 UINT8 DataSegmentLength
[3];
186 UINT32 InitiatorTaskTag
;
187 UINT32 OpCodeSpecific2
[7];
188 } ISCSI_BASIC_HEADER
;
191 // Defined AHS types, others are reserved.
193 #define ISCSI_AHS_TYPE_EXT_CDB 0x1
194 #define ISCSI_AHS_TYPE_BI_EXP_READ_DATA_LEN 0x2
196 typedef struct _ISCSI_ADDTIONAL_HEADER
{
199 UINT8 TypeSpecific
[1];
200 } ISCSI_ADDITIONAL_HEADER
;
202 typedef struct _ISCSI_BI_EXP_READ_DATA_LEN_AHS
{
206 UINT32 ExpReadDataLength
;
207 } ISCSI_BI_EXP_READ_DATA_LEN_AHS
;
209 #define SCSI_CMD_PDU_FLAG_READ 0x40
210 #define SCSI_CMD_PDU_FLAG_WRITE 0x20
212 #define ISCSI_CMD_PDU_TASK_ATTR_MASK 0x07
217 #define ISCSI_TASK_ATTR_UNTAGGED 0x00
218 #define ISCSI_TASK_ATTR_SIMPLE 0x01
219 #define ISCSI_TASK_ATTR_ORDERD 0x02
220 #define ISCSI_TASK_ATTR_HOQ 0x03
221 #define ISCSI_TASK_ATTR_ACA 0x04
226 typedef struct _SCSI_COMMAND
{
230 UINT8 TotalAHSLength
;
231 UINT8 DataSegmentLength
[3];
233 UINT32 InitiatorTaskTag
;
234 UINT32 ExpDataXferLength
;
241 // flag bit definitions in SCSI response
243 #define SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW 0x10
244 #define SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW 0x08
245 #define SCSI_RSP_PDU_FLAG_OVERFLOW 0x04
246 #define SCSI_RSP_PDU_FLAG_UNDERFLOW 0x02
249 // iSCSI service response codes
251 #define ISCSI_SERVICE_RSP_COMMAND_COMPLETE_AT_TARGET 0x00
252 #define ISCSI_SERVICE_RSP_TARGET_FAILURE 0x01
257 typedef struct _SCSI_RESPONSE
{
262 UINT8 TotalAHSLength
;
263 UINT8 DataSegmentLength
[3];
265 UINT32 InitiatorTaskTag
;
271 UINT32 BiReadResidualCount
;
272 UINT32 ResidualCount
;
275 typedef struct _ISCSI_SENSE_DATA
{
281 // iSCSI Task Managment Function Request
283 typedef struct _ISCSI_TMF_REQUEST
{
287 UINT8 TotalAHSLength
;
288 UINT8 DataSegmentLength
[3];
290 UINT32 InitiatorTaskTag
;
291 UINT32 ReferencedTaskTag
;
299 #define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_COMPLETE 0
300 #define ISCSI_TMF_RSP_PDU_RSP_TASK_NOT_EXIST 1
301 #define ISCSI_TMF_RSP_PDU_RSP_LUN_NOT_EXIST 2
302 #define ISCSI_TMF_RSP_PDU_RSP_TASK_STILL_ALLEGIANT 3
303 #define ISCSI_TMF_RSP_PDU_RSP_TASK_REASSGIN_NOT_SUPPORTED 4
304 #define ISCSI_TMF_RSP_PDU_RSP_NOT_SUPPORTED 5
305 #define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_AHTH_FAILED 6
306 #define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_REJECTED 255
309 // iSCSI Task Management Function Response
311 typedef struct _ISCSI_TMF_RESPONSE
{
316 UINT8 TotalAHSLength
;
317 UINT8 DataSegmentLength
[3];
319 UINT32 InitiatorTaskTag
;
325 } ISCSI_TMF_RESPONSE
;
330 typedef struct _ISCSI_SCSI_DATA_OUT
{
333 UINT8 TotalAHSLength
;
334 UINT8 DataSegmentLength
[3];
336 UINT32 InitiatorTaskTag
;
337 UINT32 TargetTransferTag
;
344 } ISCSI_SCSI_DATA_OUT
;
346 #define SCSI_DATA_IN_PDU_FLAG_ACKKNOWLEDGE 0x40
347 #define SCSI_DATA_IN_PDU_FLAG_OVERFLOW SCSI_RSP_PDU_FLAG_OVERFLOW
348 #define SCSI_DATA_IN_PDU_FLAG_UNDERFLOW SCSI_RSP_PDU_FLAG_UNDERFLOW
349 #define SCSI_DATA_IN_PDU_FLAG_STATUS_VALID 0x01
353 typedef struct _ISCSI_SCSI_DATA_IN
{
358 UINT8 TotalAHSLength
;
359 UINT8 DataSegmentLength
[3];
361 UINT32 InitiatorTaskTag
;
362 UINT32 TargetTransferTag
;
368 UINT32 ResidualCount
;
369 } ISCSI_SCSI_DATA_IN
;
371 #define ISCSI_GET_BUFFER_OFFSET(PduHdr) NTOHL (((ISCSI_SCSI_DATA_IN *) (PduHdr))->BufferOffset)
375 typedef struct _ISCSI_READY_TO_TRANSFER
{
378 UINT8 TotalAHSLength
;
379 UINT8 DataSegmentLength
[3];
381 UINT32 InitiatorTaskTag
;
382 UINT32 TargetTransferTag
;
388 UINT32 DesiredDataTransferLength
;
389 } ISCSI_READY_TO_TRANSFER
;
391 typedef struct _ISCSI_ASYNC_MESSAGE
{
394 UINT8 TotalAHSLength
;
395 UINT8 DataSegmentLength
[3];
397 UINT32 InitiatorTaskTag
;
408 } ISCSI_ASYNC_MESSAGE
;
410 #define ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT 0x80
411 #define ISCSI_LOGIN_REQ_PDU_FLAG_CONTINUE 0x40
416 typedef struct _ISCSI_LOGIN_REQUEST
{
421 UINT8 TotalAHSLength
;
422 UINT8 DataSegmentLength
[3];
425 UINT32 InitiatorTaskTag
;
431 } ISCSI_LOGIN_REQUEST
;
433 #define ISCSI_LOGIN_RSP_PDU_FLAG_TRANSIT ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT
434 #define ISCSI_LOGIN_RSP_PDU_FLAG_CONTINUE ISCSI_LOGIN_REQ_PDU_FLAG_CONTINUE
436 #define ISCSI_LOGIN_STATUS_SUCCESS 0
437 #define ISCSI_LOGIN_STATUS_REDIRECTION 1
438 #define ISCSI_LOGIN_STATUS_INITIATOR_ERROR 2
439 #define ISCSI_LOGIN_STATUS_TARGET_ERROR 3
444 typedef struct _ISCSI_LOGIN_RESPONSE
{
449 UINT8 TotalAHSLength
;
450 UINT8 DataSegmentLength
[3];
453 UINT32 InitiatorTaskTag
;
461 } ISCSI_LOGIN_RESPONSE
;
463 #define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0
464 #define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1
465 #define ISCSI_LOGOUT_REASON_REMOVE_CONNECTION_FOR_RECOVERY 2
470 typedef struct _ISCSI_LOGOUT_REQUEST
{
474 UINT8 TotalAHSLength
;
475 UINT8 DataSegmentLength
[3];
477 UINT32 InitiatorTaskTag
;
483 } ISCSI_LOGOUT_REQUEST
;
485 #define ISCSI_LOGOUT_RESPONSE_SESSION_CLOSED_SUCCESS 0
486 #define ISCSI_LOGOUT_RESPONSE_CID_NOT_FOUND 1
487 #define ISCSI_LOGOUT_RESPONSE_RECOVERY_NOT_SUPPORTED 2
488 #define ISCSI_LOGOUT_RESPONSE_CLEANUP_FAILED 3
493 typedef struct _ISCSI_LOGOUT_RESPONSE
{
498 UINT8 TotalAHSLength
;
499 UINT8 DataSegmentLength
[3];
501 UINT32 InitiatorTaskTag
;
510 } ISCSI_LOGOUT_RESPONSE
;
512 #define ISCSI_SNACK_REQUEST_TYPE_DATA_OR_R2T 0
513 #define ISCSI_SNACK_REQUEST_TYPE_STATUS 1
514 #define ISCSI_SNACK_REQUEST_TYPE_DATA_ACK 2
515 #define ISCSI_SNACK_REQUEST_TYPE_RDATA 3
520 typedef struct _ISCSI_SNACK_REQUEST
{
524 UINT8 TotalAHSLength
;
525 UINT8 DataSegmentLength
[3];
527 UINT32 InitiatorTaskTag
;
528 UINT32 TargetTransferTag
;
534 } ISCSI_SNACK_REQUEST
;
539 typedef struct _ISCSI_REJECT
{
544 UINT8 TotalAHSLength
;
545 UINT8 DataSegmentLength
[3];
547 UINT32 InitiatorTaskTag
;
559 typedef struct _ISCSI_NOP_OUT
{
562 UINT8 TotalAHSLength
;
563 UINT8 DataSegmentLength
[3];
565 UINT32 InitiatorTaskTag
;
566 UINT32 TargetTransferTag
;
575 typedef struct _ISCSI_NOP_IN
{
578 UINT8 TotalAHSLength
;
579 UINT8 DataSegmentLength
[3];
581 UINT32 InitiatorTaskTag
;
582 UINT32 TargetTransferTag
;
589 #define ISCSI_SECURITY_NEGOTIATION 0
590 #define ISCSI_LOGIN_OPERATIONAL_NEGOTIATION 1
591 #define ISCSI_FULL_FEATURE_PHASE 3
598 typedef struct _ISCSI_XFER_CONTEXT
{
599 UINT32 TargetTransferTag
;
601 UINT32 DesiredLength
;
603 } ISCSI_XFER_CONTEXT
;
605 typedef struct _ISCSI_IN_BUFFER_CONTEXT
{
608 } ISCSI_IN_BUFFER_CONTEXT
;
610 typedef struct _ISCSI_TCB
{
613 BOOLEAN SoFarInOrder
;
615 BOOLEAN FbitReceived
;
620 UINT32 InitiatorTaskTag
;
624 ISCSI_XFER_CONTEXT XferContext
;
626 ISCSI_CONNECTION
*Conn
;
629 typedef struct _ISCSI_KEY_VALUE_PAIR
{
634 } ISCSI_KEY_VALUE_PAIR
;
637 // function prototypes.
640 IScsiAttatchConnection (
641 IN ISCSI_SESSION
*Session
,
642 IN ISCSI_CONNECTION
*Conn
646 IScsiDetatchConnection (
647 IN ISCSI_CONNECTION
*Conn
652 IN ISCSI_CONNECTION
*Conn
656 IScsiCreateConnection (
657 IN ISCSI_DRIVER_DATA
*Private
,
658 IN ISCSI_SESSION
*Session
662 IScsiDestroyConnection (
663 IN ISCSI_CONNECTION
*Conn
668 IN ISCSI_DRIVER_DATA
*Private
673 IN ISCSI_CONNECTION
*Conn
677 IScsiReceiveLoginRsp (
678 IN ISCSI_CONNECTION
*Conn
682 IScsiAddKeyValuePair (
689 IScsiPrepareLoginReq (
690 IN ISCSI_CONNECTION
*Conn
694 IScsiProcessLoginRsp (
695 IN ISCSI_CONNECTION
*Conn
,
700 IScsiUpdateTargetAddress (
701 IN ISCSI_SESSION
*Session
,
713 IN ISCSI_CONNECTION
*Conn
,
715 IN ISCSI_IN_BUFFER_CONTEXT
*Context
, OPTIONAL
716 IN BOOLEAN HeaderDigest
,
717 IN BOOLEAN DataDigest
,
718 IN EFI_EVENT TimeoutEvent OPTIONAL
723 IN ISCSI_CONNECTION
*Conn
,
729 IN ISCSI_CONNECTION
*Conn
,
740 IScsiBuildKeyValueList (
746 IScsiGetValueByKeyFromList (
747 IN NET_LIST_ENTRY
*KeyValueList
,
752 IScsiFreeKeyValueList (
753 IN NET_LIST_ENTRY
*KeyValueList
763 IScsiExecuteScsiCommand (
764 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*PassThru
,
767 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
771 IScsiSessionReinstatement (
772 IN ISCSI_DRIVER_DATA
*Private
777 IN ISCSI_SESSION
*Session
,
783 IN ISCSI_SESSION
*Session