iscsi_pdu.h revision 1.2 1 /* $NetBSD: iscsi_pdu.h,v 1.2 2014/06/21 03:42:52 dholland Exp $ */
2
3 /*-
4 * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 #ifndef _ISCSI_PDU_H
32 #define _ISCSI_PDU_H
33
34 #define BHS_SIZE 48 /* Basic Header Segment (without digest) */
35 #define PDU_HEADER_SIZE 52 /* PDU Header with Digest */
36
37 #define OP_IMMEDIATE 0x40 /* Bit 1 in Opcode field: immediate delivery */
38 #define OPCODE_MASK 0x3f /* Mask for opcode */
39
40 /* PDU Flags field */
41
42 #define FLAG_FINAL 0x80 /* Bit 0: Final PDU in sequence */
43 #define FLAG_TRANSIT 0x80 /* Bit 0: Transit to next login phase */
44 #define FLAG_CONTINUE 0x40 /* Bit 1: Continue PDU */
45 #define FLAG_ACK 0x40 /* Bit 1: Acknowledge */
46 #define FLAG_READ 0x40 /* Bit 1: Read Data */
47 #define FLAG_WRITE 0x20 /* Bit 2: Write Data */
48 #define FLAG_BIDI_OFLO 0x10 /* Bit 3: Bidirectional Read Residual Oflow */
49 #define FLAG_BIDI_UFLOW 0x08 /* Bit 4: Bidirectional Read Residual Uflow */
50 #define FLAG_OVERFLOW 0x04 /* Bit 5: Residual Overflow */
51 #define FLAG_UNDERFLOW 0x02 /* Bit 6: Residual Underflow */
52 #define FLAG_STATUS 0x01 /* Bit 7: Command Status is valid */
53
54 /* CSG/NSG flag field codes */
55
56 #define SG_SECURITY_NEGOTIATION 0
57 #define SG_LOGIN_OPERATIONAL_NEGOTIATION 1
58 #define SG_FULL_FEATURE_PHASE 3
59
60 #define CSG_SHIFT 2 /* shift factor for CSG field */
61 #define SG_MASK 3 /* mask for CSG (after shift) and NSG */
62
63 #define NEXT_PHASE(ph) ((!ph) ? 1 : 3) /* no phase 2 */
64
65 /* Task Management Function Codes (in Flags byte) */
66
67 #define ABORT_TASK 1
68 #define ABORT_TASK_SET 2
69 #define CLEAR_ACA 3
70 #define CLEAR_TASK_SET 4
71 #define LOGICAL_UNIT_RESET 5
72 #define TARGET_WARM_RESET 6
73 #define TARGET_COLD_RESET 7
74 #define TASK_REASSIGN 8
75
76 /* ISID T-Field (first byte) */
77
78 #define T_FORMAT_OUI 0x00
79 #define T_FORMAT_EN 0x40
80 #define T_FORMAT_RANDOM 0x80
81
82
83 /* Task Attributes */
84
85 #define ATTR_UNTAGGED 0
86 #define ATTR_SIMPLE 1
87 #define ATTR_ORDERED 2
88 #define ATTR_HEAD_OF_QUEUE 3
89 #define ATTR_ACA 4
90
91 /* Initiator Opcodes */
92
93 #define IOP_NOP_Out 0x00
94 #define IOP_SCSI_Command 0x01
95 #define IOP_SCSI_Task_Management 0x02
96 #define IOP_Login_Request 0x03
97 #define IOP_Text_Request 0x04
98 #define IOP_SCSI_Data_out 0x05
99 #define IOP_Logout_Request 0x06
100 #define IOP_SNACK_Request 0x10
101
102 /* Target Opcodes */
103
104 #define TOP_NOP_In 0x20
105 #define TOP_SCSI_Response 0x21
106 #define TOP_SCSI_Task_Management 0x22
107 #define TOP_Login_Response 0x23
108 #define TOP_Text_Response 0x24
109 #define TOP_SCSI_Data_in 0x25
110 #define TOP_Logout_Response 0x26
111 #define TOP_R2T 0x31
112 #define TOP_Asynchronous_Message 0x32
113 #define TOP_Reject 0x3f
114
115 /*
116 * The Opcode-dependent fields of the BHS, defined per PDU
117 */
118
119 /* Command + Response */
120
121 struct scsi_command_pdu_s
122 {
123 uint32_t ExpectedDataTransferLength;
124 uint32_t CmdSN;
125 uint32_t ExpStatSN;
126 uint8_t SCSI_CDB[16];
127 } __packed;
128
129 typedef struct scsi_command_pdu_s scsi_command_pdu_t;
130
131 struct scsi_response_pdu_s
132 {
133 uint32_t SNACKTag;
134 uint32_t StatSN;
135 uint32_t ExpCmdSN;
136 uint32_t MaxCmdSN;
137 uint32_t ExpStatSN;
138 uint32_t ReadResidualCount;
139 uint32_t ResidualCount;
140 } __packed;
141
142 typedef struct scsi_response_pdu_s scsi_response_pdu_t;
143
144
145 /* Task Management */
146
147 struct task_management_req_pdu_s
148 {
149 uint32_t ReferencedTaskTag;
150 uint32_t CmdSN;
151 uint32_t ExpStatSN;
152 uint32_t RefCmdSN;
153 uint32_t ExpDataSN;
154 uint8_t reserved[8];
155 } __packed;
156
157 typedef struct task_management_req_pdu_s task_management_req_pdu_t;
158
159
160 struct task_management_rsp_pdu_s
161 {
162 uint32_t reserved1;
163 uint32_t StatSN;
164 uint32_t ExpCmdSN;
165 uint32_t MaxCmdSN;
166 uint8_t reserved2[12];
167 } __packed;
168
169 typedef struct task_management_rsp_pdu_s task_management_rsp_pdu_t;
170
171
172 /* Data Out & In, R2T */
173
174 struct data_out_pdu_s
175 {
176 uint32_t TargetTransferTag;
177 uint32_t reserved1;
178 uint32_t ExpStatSN;
179 uint32_t reserved2;
180 uint32_t DataSN;
181 uint32_t BufferOffset;
182 uint32_t reserved3;
183 } __packed;
184
185 typedef struct data_out_pdu_s data_out_pdu_t;
186
187
188 struct data_in_pdu_s
189 {
190 uint32_t TargetTransferTag;
191 uint32_t StatSN;
192 uint32_t ExpCmdSN;
193 uint32_t MaxCmdSN;
194 uint32_t DataSN;
195 uint32_t BufferOffset;
196 uint32_t ResidualCount;
197 } __packed;
198
199 typedef struct data_in_pdu_s data_in_pdu_t;
200
201
202 struct r2t_pdu_s
203 {
204 uint32_t TargetTransferTag;
205 uint32_t StatSN;
206 uint32_t ExpCmdSN;
207 uint32_t MaxCmdSN;
208 uint32_t R2TSN;
209 uint32_t BufferOffset;
210 uint32_t DesiredDataTransferLength;
211 } __packed;
212
213 typedef struct r2t_pdu_s r2t_pdu_t;
214
215
216 /* Asynch message */
217
218 struct asynch_pdu_s
219 {
220 uint32_t reserved1;
221 uint32_t StatSN;
222 uint32_t ExpCmdSN;
223 uint32_t MaxCmdSN;
224 uint8_t AsyncEvent;
225 uint8_t AsyncVCode;
226 uint16_t Parameter1;
227 uint16_t Parameter2;
228 uint16_t Parameter3;
229 uint32_t reserved2;
230 } __packed;
231
232 typedef struct asynch_pdu_s asynch_pdu_t;
233
234
235 /* Text request / response */
236
237 struct text_req_pdu_s
238 {
239 uint32_t TargetTransferTag;
240 uint32_t CmdSN;
241 uint32_t ExpStatSN;
242 uint8_t reserved[16];
243 } __packed;
244
245 typedef struct text_req_pdu_s text_req_pdu_t;
246
247
248 struct text_rsp_pdu_s
249 {
250 uint32_t TargetTransferTag;
251 uint32_t StatSN;
252 uint32_t ExpCmdSN;
253 uint32_t MaxCmdSN;
254 uint8_t reserved[12];
255 } __packed;
256
257 typedef struct text_rsp_pdu_s text_rsp_pdu_t;
258
259
260 /* Login request / response */
261
262 struct login_req_pdu_s
263 {
264 uint16_t CID;
265 uint16_t reserved1;
266 uint32_t CmdSN;
267 uint32_t ExpStatSN;
268 uint8_t reserved2[16];
269 } __packed;
270
271 typedef struct login_req_pdu_s login_req_pdu_t;
272
273 /* Overlays LUN field in login request and response */
274 struct login_isid_s
275 {
276 uint8_t ISID_A;
277 uint16_t ISID_B;
278 uint8_t ISID_C;
279 uint16_t ISID_D;
280 uint16_t TSIH;
281 } __packed;
282
283 typedef struct login_isid_s login_isid_t;
284
285 struct login_rsp_pdu_s
286 {
287 uint32_t reserved1;
288 uint32_t StatSN;
289 uint32_t ExpCmdSN;
290 uint32_t MaxCmdSN;
291 uint8_t StatusClass;
292 uint8_t StatusDetail;
293 uint8_t reserved2[10];
294 } __packed;
295
296 typedef struct login_rsp_pdu_s login_rsp_pdu_t;
297
298
299 /* Logout request / response */
300
301 struct logout_req_pdu_s
302 {
303 uint16_t CID;
304 uint16_t reserved2;
305 uint32_t CmdSN;
306 uint32_t ExpStatSN;
307 uint8_t reserved3[16];
308 } __packed;
309
310 typedef struct logout_req_pdu_s logout_req_pdu_t;
311
312
313 struct logout_rsp_pdu_s
314 {
315 uint32_t reserved2;
316 uint32_t StatSN;
317 uint32_t ExpCmdSN;
318 uint32_t MaxCmdSN;
319 uint32_t reserved3;
320 uint16_t Time2Wait;
321 uint16_t Time2Retain;
322 uint32_t reserved4;
323 } __packed;
324
325 typedef struct logout_rsp_pdu_s logout_rsp_pdu_t;
326
327
328 /* SNACK request */
329
330 /* SNACK Types (in Flags field) */
331
332 #define SNACK_DATA_NAK 0
333 #define SNACK_STATUS_NAK 1
334 #define SNACK_DATA_ACK 2
335 #define SNACK_RDATA_NAK 3
336
337 struct snack_req_pdu_s
338 {
339 uint32_t TargetTransferTag;
340 uint32_t reserved1;
341 uint32_t ExpStatSN;
342 uint8_t reserved2[8];
343 uint32_t BegRun;
344 uint32_t RunLength;
345 } __packed;
346
347 typedef struct snack_req_pdu_s snack_req_pdu_t;
348
349
350 /* Reject */
351
352 #define REJECT_DIGEST_ERROR 2
353 #define REJECT_SNACK 3
354 #define REJECT_PROTOCOL_ERROR 4
355 #define REJECT_CMD_NOT_SUPPORTED 5
356 #define REJECT_IMMED_COMMAND 6
357 #define REJECT_TASK_IN_PROGRESS 7
358 #define REJECT_INVALID_DATA_ACK 8
359 #define REJECT_INVALID_PDU_FIELD 9
360 #define REJECT_LONG_OPERATION 10
361 #define REJECT_NEGOTIATION_RESET 11
362 #define REJECT_WAITING_FOR_LOGOUT 12
363
364
365 struct reject_pdu_s
366 {
367 uint32_t reserved2;
368 uint32_t StatSN;
369 uint32_t ExpCmdSN;
370 uint32_t MaxCmdSN;
371 uint8_t DataSN;
372 uint8_t reserved[8];
373 } __packed;
374
375 typedef struct reject_pdu_s reject_pdu_t;
376
377
378 /* NOP Out & In */
379
380 struct nop_out_pdu_s
381 {
382 uint32_t TargetTransferTag;
383 uint32_t CmdSN;
384 uint32_t ExpStatSN;
385 uint8_t reserved[16];
386 } __packed;
387
388 typedef struct nop_out_pdu_s nop_out_pdu_t;
389
390
391 struct nop_in_pdu_s
392 {
393 uint32_t TargetTransferTag;
394 uint32_t StatSN;
395 uint32_t ExpCmdSN;
396 uint32_t MaxCmdSN;
397 uint8_t reserved3[12];
398 } __packed;
399
400 typedef struct nop_in_pdu_s nop_in_pdu_t;
401
402
403 /*
404 * The complete PDU Header.
405 */
406
407 struct pdu_header_s
408 {
409 uint8_t Opcode;
410 uint8_t Flags;
411 uint8_t OpcodeSpecific[2];
412 uint8_t TotalAHSLength;
413 uint8_t DataSegmentLength[3];
414 uint64_t LUN;
415 uint32_t InitiatorTaskTag;
416 union
417 {
418 scsi_command_pdu_t command;
419 scsi_response_pdu_t response;
420 task_management_req_pdu_t task_req;
421 task_management_rsp_pdu_t task_rsp;
422 data_out_pdu_t data_out;
423 data_in_pdu_t data_in;
424 r2t_pdu_t r2t;
425 asynch_pdu_t asynch;
426 text_req_pdu_t text_req;
427 text_rsp_pdu_t text_rsp;
428 login_req_pdu_t login_req;
429 login_rsp_pdu_t login_rsp;
430 logout_req_pdu_t logout_req;
431 logout_rsp_pdu_t logout_rsp;
432 snack_req_pdu_t snack;
433 reject_pdu_t reject;
434 nop_out_pdu_t nop_out;
435 nop_in_pdu_t nop_in;
436 } p;
437 uint32_t HeaderDigest;
438 } __packed;
439
440 typedef struct pdu_header_s pdu_header_t;
441
442 #endif /* !_ISCSI_PDU_H */
443