]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/IScsiDxe/IScsiProto.h
cac98c8b3d29d358ba2487030f7f50a286ca17ad
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiProto.h
1 /** @file
2 The header file of iSCSI Protocol that defines many specific data structures.
3
4 Copyright (c) 2004 - 2011, 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 Others Other errors as indicated.
954 **/
955 EFI_STATUS
956 IScsiExecuteScsiCommand (
957 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru,
958 IN UINT8 *Target,
959 IN UINT64 Lun,
960 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
961 );
962
963 /**
964 Reinstate the session on some error.
965
966 @param[in, out] Private The iSCSI driver data.
967
968 @retval EFI_SUCCES The session is reinstated from some error.
969 @retval Other Reinstatement failed.
970 **/
971 EFI_STATUS
972 IScsiSessionReinstatement (
973 IN OUT ISCSI_DRIVER_DATA *Private
974 );
975
976 /**
977 Initialize some session parameters before login.
978
979 @param[in, out] Session The iSCSI session.
980 @param[in] Recovery Whether the request is from a fresh new start or recovery.
981 **/
982 VOID
983 IScsiSessionInit (
984 IN OUT ISCSI_SESSION *Session,
985 IN BOOLEAN Recovery
986 );
987
988 /**
989 Abort the iSCSI session, that is, reset all the connection and free the
990 resources.
991
992 @param[in, out] Session The iSCSI session.
993
994 @retval EFI_SUCCES The session is aborted.
995 **/
996 EFI_STATUS
997 IScsiSessionAbort (
998 IN OUT ISCSI_SESSION *Session
999 );
1000
1001 #endif