3 Copyright (c) 2007 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
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 |= (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 |= ((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