xref: /freebsd/sys/dev/iscsi/iscsi_proto.h (revision 545ddfbe7d4fe8adfb862903b24eac1d5896c1ef)
1 /*-
2  * Copyright (c) 2012 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Edward Tomasz Napierala under sponsorship
6  * from the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 #ifndef ISCSI_PROTO_H
33 #define	ISCSI_PROTO_H
34 
35 #ifndef CTASSERT
36 #define CTASSERT(x)		_CTASSERT(x, __LINE__)
37 #define _CTASSERT(x, y)		__CTASSERT(x, y)
38 #define __CTASSERT(x, y)	typedef char __assert_ ## y [(x) ? 1 : -1]
39 #endif
40 
41 #define	ISCSI_SNGT(x, y)	((int32_t)(x) - (int32_t)(y) > 0)
42 #define	ISCSI_SNLT(x, y)	((int32_t)(x) - (int32_t)(y) < 0)
43 
44 #define	ISCSI_BHS_SIZE			48
45 #define	ISCSI_HEADER_DIGEST_SIZE	4
46 #define	ISCSI_DATA_DIGEST_SIZE		4
47 
48 #define	ISCSI_BHS_OPCODE_IMMEDIATE	0x40
49 
50 #define	ISCSI_BHS_OPCODE_NOP_OUT	0x00
51 #define	ISCSI_BHS_OPCODE_SCSI_COMMAND	0x01
52 #define	ISCSI_BHS_OPCODE_TASK_REQUEST	0x02
53 #define	ISCSI_BHS_OPCODE_LOGIN_REQUEST	0x03
54 #define	ISCSI_BHS_OPCODE_TEXT_REQUEST	0x04
55 #define	ISCSI_BHS_OPCODE_SCSI_DATA_OUT	0x05
56 #define	ISCSI_BHS_OPCODE_LOGOUT_REQUEST	0x06
57 
58 #define	ISCSI_BHS_OPCODE_NOP_IN		0x20
59 #define	ISCSI_BHS_OPCODE_SCSI_RESPONSE	0x21
60 #define	ISCSI_BHS_OPCODE_TASK_RESPONSE	0x22
61 #define	ISCSI_BHS_OPCODE_LOGIN_RESPONSE	0x23
62 #define	ISCSI_BHS_OPCODE_TEXT_RESPONSE	0x24
63 #define	ISCSI_BHS_OPCODE_SCSI_DATA_IN	0x25
64 #define	ISCSI_BHS_OPCODE_LOGOUT_RESPONSE	0x26
65 #define	ISCSI_BHS_OPCODE_R2T		0x31
66 #define	ISCSI_BHS_OPCODE_ASYNC_MESSAGE	0x32
67 #define	ISCSI_BHS_OPCODE_REJECT		0x3f
68 
69 struct iscsi_bhs {
70 	uint8_t		bhs_opcode;
71 	uint8_t		bhs_opcode_specific1[3];
72 	uint8_t		bhs_total_ahs_len;
73 	uint8_t		bhs_data_segment_len[3];
74 	uint64_t	bhs_lun;
75 	uint8_t		bhs_inititator_task_tag[4];
76 	uint8_t		bhs_opcode_specific4[28];
77 };
78 CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE);
79 
80 #define	BHSSC_FLAGS_F		0x80
81 #define	BHSSC_FLAGS_R		0x40
82 #define	BHSSC_FLAGS_W		0x20
83 #define	BHSSC_FLAGS_ATTR	0x07
84 
85 #define	BHSSC_FLAGS_ATTR_UNTAGGED	0
86 #define	BHSSC_FLAGS_ATTR_SIMPLE		1
87 #define	BHSSC_FLAGS_ATTR_ORDERED	2
88 #define	BHSSC_FLAGS_ATTR_HOQ		3
89 #define	BHSSC_FLAGS_ATTR_ACA		4
90 
91 struct iscsi_bhs_scsi_command {
92 	uint8_t		bhssc_opcode;
93 	uint8_t		bhssc_flags;
94 	uint8_t		bhssc_reserved[2];
95 	uint8_t		bhssc_total_ahs_len;
96 	uint8_t		bhssc_data_segment_len[3];
97 	uint64_t	bhssc_lun;
98 	uint32_t	bhssc_initiator_task_tag;
99 	uint32_t	bhssc_expected_data_transfer_length;
100 	uint32_t	bhssc_cmdsn;
101 	uint32_t	bhssc_expstatsn;
102 	uint8_t		bhssc_cdb[16];
103 };
104 CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE);
105 
106 #define	BHSSR_FLAGS_RESIDUAL_UNDERFLOW		0x02
107 #define	BHSSR_FLAGS_RESIDUAL_OVERFLOW		0x04
108 
109 #define	BHSSR_RESPONSE_COMMAND_COMPLETED	0x00
110 
111 struct iscsi_bhs_scsi_response {
112 	uint8_t		bhssr_opcode;
113 	uint8_t		bhssr_flags;
114 	uint8_t		bhssr_response;
115 	uint8_t		bhssr_status;
116 	uint8_t		bhssr_total_ahs_len;
117 	uint8_t		bhssr_data_segment_len[3];
118 	uint64_t	bhssr_reserved;
119 	uint32_t	bhssr_initiator_task_tag;
120 	uint32_t	bhssr_snack_tag;
121 	uint32_t	bhssr_statsn;
122 	uint32_t	bhssr_expcmdsn;
123 	uint32_t	bhssr_maxcmdsn;
124 	uint32_t	bhssr_expdatasn;
125 	uint32_t	bhssr_bidirectional_read_residual_count;
126 	uint32_t	bhssr_residual_count;
127 };
128 CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE);
129 
130 #define	BHSTMR_FUNCTION_ABORT_TASK		1
131 #define	BHSTMR_FUNCTION_ABORT_TASK_SET		2
132 #define	BHSTMR_FUNCTION_CLEAR_ACA		3
133 #define	BHSTMR_FUNCTION_CLEAR_TASK_SET		4
134 #define	BHSTMR_FUNCTION_LOGICAL_UNIT_RESET	5
135 #define	BHSTMR_FUNCTION_TARGET_WARM_RESET	6
136 #define	BHSTMR_FUNCTION_TARGET_COLD_RESET	7
137 #define	BHSTMR_FUNCTION_TASK_REASSIGN		8
138 
139 struct iscsi_bhs_task_management_request {
140 	uint8_t		bhstmr_opcode;
141 	uint8_t		bhstmr_function;
142 	uint8_t		bhstmr_reserved[2];
143 	uint8_t		bhstmr_total_ahs_len;
144 	uint8_t		bhstmr_data_segment_len[3];
145 	uint64_t	bhstmr_lun;
146 	uint32_t	bhstmr_initiator_task_tag;
147 	uint32_t	bhstmr_referenced_task_tag;
148 	uint32_t	bhstmr_cmdsn;
149 	uint32_t	bhstmr_expstatsn;
150 	uint32_t	bhstmr_refcmdsn;
151 	uint32_t	bhstmr_expdatasn;
152 	uint64_t	bhstmr_reserved2;
153 };
154 CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE);
155 
156 #define	BHSTMR_RESPONSE_FUNCTION_COMPLETE	0
157 #define	BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED	5
158 
159 struct iscsi_bhs_task_management_response {
160 	uint8_t		bhstmr_opcode;
161 	uint8_t		bhstmr_flags;
162 	uint8_t		bhstmr_response;
163 	uint8_t		bhstmr_reserved;
164 	uint8_t		bhstmr_total_ahs_len;
165 	uint8_t		bhstmr_data_segment_len[3];
166 	uint64_t	bhstmr_reserved2;
167 	uint32_t	bhstmr_initiator_task_tag;
168 	uint32_t	bhstmr_reserved3;
169 	uint32_t	bhstmr_statsn;
170 	uint32_t	bhstmr_expcmdsn;
171 	uint32_t	bhstmr_maxcmdsn;
172 	uint8_t		bhstmr_reserved4[12];
173 };
174 CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE);
175 
176 #define	BHSLR_FLAGS_TRANSIT		0x80
177 #define	BHSLR_FLAGS_CONTINUE		0x40
178 
179 #define	BHSLR_STAGE_SECURITY_NEGOTIATION	0
180 #define	BHSLR_STAGE_OPERATIONAL_NEGOTIATION	1
181 #define	BHSLR_STAGE_FULL_FEATURE_PHASE		3 /* Yes, 3. */
182 
183 struct iscsi_bhs_login_request {
184 	uint8_t		bhslr_opcode;
185 	uint8_t		bhslr_flags;
186 	uint8_t		bhslr_version_max;
187 	uint8_t		bhslr_version_min;
188 	uint8_t		bhslr_total_ahs_len;
189 	uint8_t		bhslr_data_segment_len[3];
190 	uint8_t		bhslr_isid[6];
191 	uint16_t	bhslr_tsih;
192 	uint32_t	bhslr_initiator_task_tag;
193 	uint16_t	bhslr_cid;
194 	uint16_t	bhslr_reserved;
195 	uint32_t	bhslr_cmdsn;
196 	uint32_t	bhslr_expstatsn;
197 	uint8_t		bhslr_reserved2[16];
198 };
199 CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE);
200 
201 struct iscsi_bhs_login_response {
202 	uint8_t		bhslr_opcode;
203 	uint8_t		bhslr_flags;
204 	uint8_t		bhslr_version_max;
205 	uint8_t		bhslr_version_active;
206 	uint8_t		bhslr_total_ahs_len;
207 	uint8_t		bhslr_data_segment_len[3];
208 	uint8_t		bhslr_isid[6];
209 	uint16_t	bhslr_tsih;
210 	uint32_t	bhslr_initiator_task_tag;
211 	uint32_t	bhslr_reserved;
212 	uint32_t	bhslr_statsn;
213 	uint32_t	bhslr_expcmdsn;
214 	uint32_t	bhslr_maxcmdsn;
215 	uint8_t		bhslr_status_class;
216 	uint8_t		bhslr_status_detail;
217 	uint16_t	bhslr_reserved2;
218 	uint8_t		bhslr_reserved3[8];
219 };
220 CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE);
221 
222 #define	BHSTR_FLAGS_FINAL		0x80
223 #define	BHSTR_FLAGS_CONTINUE		0x40
224 
225 struct iscsi_bhs_text_request {
226 	uint8_t		bhstr_opcode;
227 	uint8_t		bhstr_flags;
228 	uint16_t	bhstr_reserved;
229 	uint8_t		bhstr_total_ahs_len;
230 	uint8_t		bhstr_data_segment_len[3];
231 	uint64_t	bhstr_lun;
232 	uint32_t	bhstr_initiator_task_tag;
233 	uint32_t	bhstr_target_transfer_tag;
234 	uint32_t	bhstr_cmdsn;
235 	uint32_t	bhstr_expstatsn;
236 	uint8_t		bhstr_reserved2[16];
237 };
238 CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE);
239 
240 struct iscsi_bhs_text_response {
241 	uint8_t		bhstr_opcode;
242 	uint8_t		bhstr_flags;
243 	uint16_t	bhstr_reserved;
244 	uint8_t		bhstr_total_ahs_len;
245 	uint8_t		bhstr_data_segment_len[3];
246 	uint64_t	bhstr_lun;
247 	uint32_t	bhstr_initiator_task_tag;
248 	uint32_t	bhstr_target_transfer_tag;
249 	uint32_t	bhstr_statsn;
250 	uint32_t	bhstr_expcmdsn;
251 	uint32_t	bhstr_maxcmdsn;
252 	uint8_t		bhstr_reserved2[12];
253 };
254 CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE);
255 
256 #define	BHSDO_FLAGS_F	0x80
257 
258 struct iscsi_bhs_data_out {
259 	uint8_t		bhsdo_opcode;
260 	uint8_t		bhsdo_flags;
261 	uint8_t		bhsdo_reserved[2];
262 	uint8_t		bhsdo_total_ahs_len;
263 	uint8_t		bhsdo_data_segment_len[3];
264 	uint64_t	bhsdo_lun;
265 	uint32_t	bhsdo_initiator_task_tag;
266 	uint32_t	bhsdo_target_transfer_tag;
267 	uint32_t	bhsdo_reserved2;
268 	uint32_t	bhsdo_expstatsn;
269 	uint32_t	bhsdo_reserved3;
270 	uint32_t	bhsdo_datasn;
271 	uint32_t	bhsdo_buffer_offset;
272 	uint32_t	bhsdo_reserved4;
273 };
274 CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE);
275 
276 #define	BHSDI_FLAGS_F	0x80
277 #define	BHSDI_FLAGS_A	0x40
278 #define	BHSDI_FLAGS_O	0x04
279 #define	BHSDI_FLAGS_U	0x02
280 #define	BHSDI_FLAGS_S	0x01
281 
282 struct iscsi_bhs_data_in {
283 	uint8_t		bhsdi_opcode;
284 	uint8_t		bhsdi_flags;
285 	uint8_t		bhsdi_reserved;
286 	uint8_t		bhsdi_status;
287 	uint8_t		bhsdi_total_ahs_len;
288 	uint8_t		bhsdi_data_segment_len[3];
289 	uint64_t	bhsdi_lun;
290 	uint32_t	bhsdi_initiator_task_tag;
291 	uint32_t	bhsdi_target_transfer_tag;
292 	uint32_t	bhsdi_statsn;
293 	uint32_t	bhsdi_expcmdsn;
294 	uint32_t	bhsdi_maxcmdsn;
295 	uint32_t	bhsdi_datasn;
296 	uint32_t	bhsdi_buffer_offset;
297 	uint32_t	bhsdi_residual_count;
298 };
299 CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE);
300 
301 struct iscsi_bhs_r2t {
302 	uint8_t		bhsr2t_opcode;
303 	uint8_t		bhsr2t_flags;
304 	uint16_t	bhsr2t_reserved;
305 	uint8_t		bhsr2t_total_ahs_len;
306 	uint8_t		bhsr2t_data_segment_len[3];
307 	uint64_t	bhsr2t_lun;
308 	uint32_t	bhsr2t_initiator_task_tag;
309 	uint32_t	bhsr2t_target_transfer_tag;
310 	uint32_t	bhsr2t_statsn;
311 	uint32_t	bhsr2t_expcmdsn;
312 	uint32_t	bhsr2t_maxcmdsn;
313 	uint32_t	bhsr2t_r2tsn;
314 	uint32_t	bhsr2t_buffer_offset;
315 	uint32_t	bhsr2t_desired_data_transfer_length;
316 };
317 CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE);
318 
319 struct iscsi_bhs_nop_out {
320 	uint8_t		bhsno_opcode;
321 	uint8_t		bhsno_flags;
322 	uint16_t	bhsno_reserved;
323 	uint8_t		bhsno_total_ahs_len;
324 	uint8_t		bhsno_data_segment_len[3];
325 	uint64_t	bhsno_lun;
326 	uint32_t	bhsno_initiator_task_tag;
327 	uint32_t	bhsno_target_transfer_tag;
328 	uint32_t	bhsno_cmdsn;
329 	uint32_t	bhsno_expstatsn;
330 	uint8_t		bhsno_reserved2[16];
331 };
332 CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE);
333 
334 struct iscsi_bhs_nop_in {
335 	uint8_t		bhsni_opcode;
336 	uint8_t		bhsni_flags;
337 	uint16_t	bhsni_reserved;
338 	uint8_t		bhsni_total_ahs_len;
339 	uint8_t		bhsni_data_segment_len[3];
340 	uint64_t	bhsni_lun;
341 	uint32_t	bhsni_initiator_task_tag;
342 	uint32_t	bhsni_target_transfer_tag;
343 	uint32_t	bhsni_statsn;
344 	uint32_t	bhsni_expcmdsn;
345 	uint32_t	bhsni_maxcmdsn;
346 	uint8_t		bhsno_reserved2[12];
347 };
348 CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE);
349 
350 #define	BHSLR_REASON_CLOSE_SESSION		0
351 #define	BHSLR_REASON_CLOSE_CONNECTION		1
352 #define	BHSLR_REASON_REMOVE_FOR_RECOVERY	2
353 
354 struct iscsi_bhs_logout_request {
355 	uint8_t		bhslr_opcode;
356 	uint8_t		bhslr_reason;
357 	uint16_t	bhslr_reserved;
358 	uint8_t		bhslr_total_ahs_len;
359 	uint8_t		bhslr_data_segment_len[3];
360 	uint64_t	bhslr_reserved2;
361 	uint32_t	bhslr_initiator_task_tag;
362 	uint16_t	bhslr_cid;
363 	uint16_t	bhslr_reserved3;
364 	uint32_t	bhslr_cmdsn;
365 	uint32_t	bhslr_expstatsn;
366 	uint8_t		bhslr_reserved4[16];
367 };
368 CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE);
369 
370 #define	BHSLR_RESPONSE_CLOSED_SUCCESSFULLY	0
371 #define	BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED	2
372 
373 struct iscsi_bhs_logout_response {
374 	uint8_t		bhslr_opcode;
375 	uint8_t		bhslr_flags;
376 	uint8_t		bhslr_response;
377 	uint8_t		bhslr_reserved;
378 	uint8_t		bhslr_total_ahs_len;
379 	uint8_t		bhslr_data_segment_len[3];
380 	uint64_t	bhslr_reserved2;
381 	uint32_t	bhslr_initiator_task_tag;
382 	uint32_t	bhslr_reserved3;
383 	uint32_t	bhslr_statsn;
384 	uint32_t	bhslr_expcmdsn;
385 	uint32_t	bhslr_maxcmdsn;
386 	uint32_t	bhslr_reserved4;
387 	uint16_t	bhslr_time2wait;
388 	uint16_t	bhslr_time2retain;
389 	uint32_t	bhslr_reserved5;
390 };
391 CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE);
392 
393 #define	BHSAM_EVENT_TARGET_REQUESTS_LOGOUT		1
394 #define	BHSAM_EVENT_TARGET_TERMINATES_CONNECTION	2
395 #define	BHSAM_EVENT_TARGET_TERMINATES_SESSION		3
396 
397 struct iscsi_bhs_asynchronous_message {
398 	uint8_t		bhsam_opcode;
399 	uint8_t		bhsam_flags;
400 	uint16_t	bhsam_reserved;
401 	uint8_t		bhsam_total_ahs_len;
402 	uint8_t		bhsam_data_segment_len[3];
403 	uint64_t	bhsam_lun;
404 	uint32_t	bhsam_0xffffffff;
405 	uint32_t	bhsam_reserved2;
406 	uint32_t	bhsam_statsn;
407 	uint32_t	bhsam_expcmdsn;
408 	uint32_t	bhsam_maxcmdsn;
409 	uint8_t		bhsam_async_event;
410 	uint8_t		bhsam_async_vcode;
411 	uint16_t	bhsam_parameter1;
412 	uint16_t	bhsam_parameter2;
413 	uint16_t	bhsam_parameter3;
414 	uint32_t	bhsam_reserved3;
415 };
416 CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE);
417 
418 #define BHSSR_REASON_DATA_DIGEST_ERROR	0x02
419 #define BHSSR_PROTOCOL_ERROR		0x04
420 #define BHSSR_COMMAND_NOT_SUPPORTED	0x05
421 #define BHSSR_INVALID_PDU_FIELD		0x09
422 
423 struct iscsi_bhs_reject {
424 	uint8_t		bhsr_opcode;
425 	uint8_t		bhsr_flags;
426 	uint8_t		bhsr_reason;
427 	uint8_t		bhsr_reserved;
428 	uint8_t		bhsr_total_ahs_len;
429 	uint8_t		bhsr_data_segment_len[3];
430 	uint64_t	bhsr_reserved2;
431 	uint32_t	bhsr_0xffffffff;
432 	uint32_t	bhsr_reserved3;
433 	uint32_t	bhsr_statsn;
434 	uint32_t	bhsr_expcmdsn;
435 	uint32_t	bhsr_maxcmdsn;
436 	uint32_t	bhsr_datasn_r2tsn;
437 	uint32_t	bhsr_reserved4;
438 	uint32_t	bhsr_reserved5;
439 };
440 CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE);
441 
442 #endif /* !ISCSI_PROTO_H */
443