xref: /netbsd/sys/dev/iscsi/iscsi_pdu.h (revision 24d6dda1)
1 /*	$NetBSD: iscsi_pdu.h,v 1.4 2017/12/03 19:07:10 christos 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 ExpDataSN;
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 pduh_Opcode;
410 	uint8_t pduh_Flags;
411 	uint8_t pduh_OpcodeSpecific[2];
412 	uint8_t pduh_TotalAHSLength;
413 	uint8_t pduh_DataSegmentLength[3];
414 	uint64_t pduh_LUN;
415 	uint32_t pduh_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 	} pduh_p;
437 	uint32_t pduh_HeaderDigest;
438 } __packed;
439 
440 typedef struct pdu_header_s pdu_header_t;
441 
442 #endif /* !_ISCSI_PDU_H */
443