2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2012 The FreeBSD Foundation
7 * This software was developed by Edward Tomasz Napierala under sponsorship
8 * from the FreeBSD Foundation.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #define CTASSERT(x) _CTASSERT(x, __LINE__)
39 #define _CTASSERT(x, y) __CTASSERT(x, y)
40 #define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1]
43 #define ISCSI_SNGT(x, y) ((int32_t)(x) - (int32_t)(y) > 0)
44 #define ISCSI_SNLT(x, y) ((int32_t)(x) - (int32_t)(y) < 0)
46 #define ISCSI_BHS_SIZE 48
47 #define ISCSI_HEADER_DIGEST_SIZE 4
48 #define ISCSI_DATA_DIGEST_SIZE 4
50 #define ISCSI_BHS_OPCODE_IMMEDIATE 0x40
52 #define ISCSI_BHS_OPCODE_NOP_OUT 0x00
53 #define ISCSI_BHS_OPCODE_SCSI_COMMAND 0x01
54 #define ISCSI_BHS_OPCODE_TASK_REQUEST 0x02
55 #define ISCSI_BHS_OPCODE_LOGIN_REQUEST 0x03
56 #define ISCSI_BHS_OPCODE_TEXT_REQUEST 0x04
57 #define ISCSI_BHS_OPCODE_SCSI_DATA_OUT 0x05
58 #define ISCSI_BHS_OPCODE_LOGOUT_REQUEST 0x06
60 #define ISCSI_BHS_OPCODE_NOP_IN 0x20
61 #define ISCSI_BHS_OPCODE_SCSI_RESPONSE 0x21
62 #define ISCSI_BHS_OPCODE_TASK_RESPONSE 0x22
63 #define ISCSI_BHS_OPCODE_LOGIN_RESPONSE 0x23
64 #define ISCSI_BHS_OPCODE_TEXT_RESPONSE 0x24
65 #define ISCSI_BHS_OPCODE_SCSI_DATA_IN 0x25
66 #define ISCSI_BHS_OPCODE_LOGOUT_RESPONSE 0x26
67 #define ISCSI_BHS_OPCODE_R2T 0x31
68 #define ISCSI_BHS_OPCODE_ASYNC_MESSAGE 0x32
69 #define ISCSI_BHS_OPCODE_REJECT 0x3f
73 uint8_t bhs_opcode_specific1[3];
74 uint8_t bhs_total_ahs_len;
75 uint8_t bhs_data_segment_len[3];
77 uint8_t bhs_inititator_task_tag[4];
78 uint8_t bhs_opcode_specific4[28];
80 CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE);
82 #define BHSSC_FLAGS_F 0x80
83 #define BHSSC_FLAGS_R 0x40
84 #define BHSSC_FLAGS_W 0x20
85 #define BHSSC_FLAGS_ATTR 0x07
87 #define BHSSC_FLAGS_ATTR_UNTAGGED 0
88 #define BHSSC_FLAGS_ATTR_SIMPLE 1
89 #define BHSSC_FLAGS_ATTR_ORDERED 2
90 #define BHSSC_FLAGS_ATTR_HOQ 3
91 #define BHSSC_FLAGS_ATTR_ACA 4
93 struct iscsi_bhs_scsi_command {
96 uint8_t bhssc_reserved[2];
97 uint8_t bhssc_total_ahs_len;
98 uint8_t bhssc_data_segment_len[3];
100 uint32_t bhssc_initiator_task_tag;
101 uint32_t bhssc_expected_data_transfer_length;
102 uint32_t bhssc_cmdsn;
103 uint32_t bhssc_expstatsn;
104 uint8_t bhssc_cdb[16];
106 CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE);
108 #define BHSSR_FLAGS_RESIDUAL_UNDERFLOW 0x02
109 #define BHSSR_FLAGS_RESIDUAL_OVERFLOW 0x04
111 #define BHSSR_RESPONSE_COMMAND_COMPLETED 0x00
113 struct iscsi_bhs_scsi_response {
114 uint8_t bhssr_opcode;
116 uint8_t bhssr_response;
117 uint8_t bhssr_status;
118 uint8_t bhssr_total_ahs_len;
119 uint8_t bhssr_data_segment_len[3];
120 uint16_t bhssr_status_qualifier;
121 uint16_t bhssr_reserved;
122 uint32_t bhssr_reserved2;
123 uint32_t bhssr_initiator_task_tag;
124 uint32_t bhssr_snack_tag;
125 uint32_t bhssr_statsn;
126 uint32_t bhssr_expcmdsn;
127 uint32_t bhssr_maxcmdsn;
128 uint32_t bhssr_expdatasn;
129 uint32_t bhssr_bidirectional_read_residual_count;
130 uint32_t bhssr_residual_count;
132 CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE);
134 #define BHSTMR_FUNCTION_ABORT_TASK 1
135 #define BHSTMR_FUNCTION_ABORT_TASK_SET 2
136 #define BHSTMR_FUNCTION_CLEAR_ACA 3
137 #define BHSTMR_FUNCTION_CLEAR_TASK_SET 4
138 #define BHSTMR_FUNCTION_LOGICAL_UNIT_RESET 5
139 #define BHSTMR_FUNCTION_TARGET_WARM_RESET 6
140 #define BHSTMR_FUNCTION_TARGET_COLD_RESET 7
141 #define BHSTMR_FUNCTION_TASK_REASSIGN 8
142 #define BHSTMR_FUNCTION_QUERY_TASK 9
143 #define BHSTMR_FUNCTION_QUERY_TASK_SET 10
144 #define BHSTMR_FUNCTION_I_T_NEXUS_RESET 11
145 #define BHSTMR_FUNCTION_QUERY_ASYNC_EVENT 12
147 struct iscsi_bhs_task_management_request {
148 uint8_t bhstmr_opcode;
149 uint8_t bhstmr_function;
150 uint8_t bhstmr_reserved[2];
151 uint8_t bhstmr_total_ahs_len;
152 uint8_t bhstmr_data_segment_len[3];
154 uint32_t bhstmr_initiator_task_tag;
155 uint32_t bhstmr_referenced_task_tag;
156 uint32_t bhstmr_cmdsn;
157 uint32_t bhstmr_expstatsn;
158 uint32_t bhstmr_refcmdsn;
159 uint32_t bhstmr_expdatasn;
160 uint64_t bhstmr_reserved2;
162 CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE);
164 #define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0
165 #define BHSTMR_RESPONSE_TASK_DOES_NOT_EXIST 1
166 #define BHSTMR_RESPONSE_LUN_DOES_NOT_EXIST 2
167 #define BHSTMR_RESPONSE_TASK_STILL_ALLEGIANT 3
168 #define BHSTMR_RESPONSE_TASK_ALL_REASS_NOT_SUPP 4
169 #define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5
170 #define BHSTMR_RESPONSE_FUNCTION_AUTH_FAIL 6
171 #define BHSTMR_RESPONSE_FUNCTION_SUCCEEDED 7
172 #define BHSTMR_RESPONSE_FUNCTION_REJECTED 255
174 struct iscsi_bhs_task_management_response {
175 uint8_t bhstmr_opcode;
176 uint8_t bhstmr_flags;
177 uint8_t bhstmr_response;
178 uint8_t bhstmr_reserved;
179 uint8_t bhstmr_total_ahs_len;
180 uint8_t bhstmr_data_segment_len[3];
181 uint8_t bhstmr_additional_reponse_information[3];
182 uint8_t bhstmr_reserved2[5];
183 uint32_t bhstmr_initiator_task_tag;
184 uint32_t bhstmr_reserved3;
185 uint32_t bhstmr_statsn;
186 uint32_t bhstmr_expcmdsn;
187 uint32_t bhstmr_maxcmdsn;
188 uint8_t bhstmr_reserved4[12];
190 CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE);
192 #define BHSLR_FLAGS_TRANSIT 0x80
193 #define BHSLR_FLAGS_CONTINUE 0x40
195 #define BHSLR_STAGE_SECURITY_NEGOTIATION 0
196 #define BHSLR_STAGE_OPERATIONAL_NEGOTIATION 1
197 #define BHSLR_STAGE_FULL_FEATURE_PHASE 3 /* Yes, 3. */
199 struct iscsi_bhs_login_request {
200 uint8_t bhslr_opcode;
202 uint8_t bhslr_version_max;
203 uint8_t bhslr_version_min;
204 uint8_t bhslr_total_ahs_len;
205 uint8_t bhslr_data_segment_len[3];
206 uint8_t bhslr_isid[6];
208 uint32_t bhslr_initiator_task_tag;
210 uint16_t bhslr_reserved;
211 uint32_t bhslr_cmdsn;
212 uint32_t bhslr_expstatsn;
213 uint8_t bhslr_reserved2[16];
215 CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE);
217 struct iscsi_bhs_login_response {
218 uint8_t bhslr_opcode;
220 uint8_t bhslr_version_max;
221 uint8_t bhslr_version_active;
222 uint8_t bhslr_total_ahs_len;
223 uint8_t bhslr_data_segment_len[3];
224 uint8_t bhslr_isid[6];
226 uint32_t bhslr_initiator_task_tag;
227 uint32_t bhslr_reserved;
228 uint32_t bhslr_statsn;
229 uint32_t bhslr_expcmdsn;
230 uint32_t bhslr_maxcmdsn;
231 uint8_t bhslr_status_class;
232 uint8_t bhslr_status_detail;
233 uint16_t bhslr_reserved2;
234 uint8_t bhslr_reserved3[8];
236 CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE);
238 #define BHSTR_FLAGS_FINAL 0x80
239 #define BHSTR_FLAGS_CONTINUE 0x40
241 struct iscsi_bhs_text_request {
242 uint8_t bhstr_opcode;
244 uint16_t bhstr_reserved;
245 uint8_t bhstr_total_ahs_len;
246 uint8_t bhstr_data_segment_len[3];
248 uint32_t bhstr_initiator_task_tag;
249 uint32_t bhstr_target_transfer_tag;
250 uint32_t bhstr_cmdsn;
251 uint32_t bhstr_expstatsn;
252 uint8_t bhstr_reserved2[16];
254 CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE);
256 struct iscsi_bhs_text_response {
257 uint8_t bhstr_opcode;
259 uint16_t bhstr_reserved;
260 uint8_t bhstr_total_ahs_len;
261 uint8_t bhstr_data_segment_len[3];
263 uint32_t bhstr_initiator_task_tag;
264 uint32_t bhstr_target_transfer_tag;
265 uint32_t bhstr_statsn;
266 uint32_t bhstr_expcmdsn;
267 uint32_t bhstr_maxcmdsn;
268 uint8_t bhstr_reserved2[12];
270 CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE);
272 #define BHSDO_FLAGS_F 0x80
274 struct iscsi_bhs_data_out {
275 uint8_t bhsdo_opcode;
277 uint8_t bhsdo_reserved[2];
278 uint8_t bhsdo_total_ahs_len;
279 uint8_t bhsdo_data_segment_len[3];
281 uint32_t bhsdo_initiator_task_tag;
282 uint32_t bhsdo_target_transfer_tag;
283 uint32_t bhsdo_reserved2;
284 uint32_t bhsdo_expstatsn;
285 uint32_t bhsdo_reserved3;
286 uint32_t bhsdo_datasn;
287 uint32_t bhsdo_buffer_offset;
288 uint32_t bhsdo_reserved4;
290 CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE);
292 #define BHSDI_FLAGS_F 0x80
293 #define BHSDI_FLAGS_A 0x40
294 #define BHSDI_FLAGS_O 0x04
295 #define BHSDI_FLAGS_U 0x02
296 #define BHSDI_FLAGS_S 0x01
298 struct iscsi_bhs_data_in {
299 uint8_t bhsdi_opcode;
301 uint8_t bhsdi_reserved;
302 uint8_t bhsdi_status;
303 uint8_t bhsdi_total_ahs_len;
304 uint8_t bhsdi_data_segment_len[3];
306 uint32_t bhsdi_initiator_task_tag;
307 uint32_t bhsdi_target_transfer_tag;
308 uint32_t bhsdi_statsn;
309 uint32_t bhsdi_expcmdsn;
310 uint32_t bhsdi_maxcmdsn;
311 uint32_t bhsdi_datasn;
312 uint32_t bhsdi_buffer_offset;
313 uint32_t bhsdi_residual_count;
315 CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE);
317 struct iscsi_bhs_r2t {
318 uint8_t bhsr2t_opcode;
319 uint8_t bhsr2t_flags;
320 uint16_t bhsr2t_reserved;
321 uint8_t bhsr2t_total_ahs_len;
322 uint8_t bhsr2t_data_segment_len[3];
324 uint32_t bhsr2t_initiator_task_tag;
325 uint32_t bhsr2t_target_transfer_tag;
326 uint32_t bhsr2t_statsn;
327 uint32_t bhsr2t_expcmdsn;
328 uint32_t bhsr2t_maxcmdsn;
329 uint32_t bhsr2t_r2tsn;
330 uint32_t bhsr2t_buffer_offset;
331 uint32_t bhsr2t_desired_data_transfer_length;
333 CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE);
335 struct iscsi_bhs_nop_out {
336 uint8_t bhsno_opcode;
338 uint16_t bhsno_reserved;
339 uint8_t bhsno_total_ahs_len;
340 uint8_t bhsno_data_segment_len[3];
342 uint32_t bhsno_initiator_task_tag;
343 uint32_t bhsno_target_transfer_tag;
344 uint32_t bhsno_cmdsn;
345 uint32_t bhsno_expstatsn;
346 uint8_t bhsno_reserved2[16];
348 CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE);
350 struct iscsi_bhs_nop_in {
351 uint8_t bhsni_opcode;
353 uint16_t bhsni_reserved;
354 uint8_t bhsni_total_ahs_len;
355 uint8_t bhsni_data_segment_len[3];
357 uint32_t bhsni_initiator_task_tag;
358 uint32_t bhsni_target_transfer_tag;
359 uint32_t bhsni_statsn;
360 uint32_t bhsni_expcmdsn;
361 uint32_t bhsni_maxcmdsn;
362 uint8_t bhsno_reserved2[12];
364 CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE);
366 #define BHSLR_REASON_CLOSE_SESSION 0
367 #define BHSLR_REASON_CLOSE_CONNECTION 1
368 #define BHSLR_REASON_REMOVE_FOR_RECOVERY 2
370 struct iscsi_bhs_logout_request {
371 uint8_t bhslr_opcode;
372 uint8_t bhslr_reason;
373 uint16_t bhslr_reserved;
374 uint8_t bhslr_total_ahs_len;
375 uint8_t bhslr_data_segment_len[3];
376 uint64_t bhslr_reserved2;
377 uint32_t bhslr_initiator_task_tag;
379 uint16_t bhslr_reserved3;
380 uint32_t bhslr_cmdsn;
381 uint32_t bhslr_expstatsn;
382 uint8_t bhslr_reserved4[16];
384 CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE);
386 #define BHSLR_RESPONSE_CLOSED_SUCCESSFULLY 0
387 #define BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED 2
389 struct iscsi_bhs_logout_response {
390 uint8_t bhslr_opcode;
392 uint8_t bhslr_response;
393 uint8_t bhslr_reserved;
394 uint8_t bhslr_total_ahs_len;
395 uint8_t bhslr_data_segment_len[3];
396 uint64_t bhslr_reserved2;
397 uint32_t bhslr_initiator_task_tag;
398 uint32_t bhslr_reserved3;
399 uint32_t bhslr_statsn;
400 uint32_t bhslr_expcmdsn;
401 uint32_t bhslr_maxcmdsn;
402 uint32_t bhslr_reserved4;
403 uint16_t bhslr_time2wait;
404 uint16_t bhslr_time2retain;
405 uint32_t bhslr_reserved5;
407 CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE);
409 #define BHSAM_EVENT_TARGET_REQUESTS_LOGOUT 1
410 #define BHSAM_EVENT_TARGET_TERMINATES_CONNECTION 2
411 #define BHSAM_EVENT_TARGET_TERMINATES_SESSION 3
413 struct iscsi_bhs_asynchronous_message {
414 uint8_t bhsam_opcode;
416 uint16_t bhsam_reserved;
417 uint8_t bhsam_total_ahs_len;
418 uint8_t bhsam_data_segment_len[3];
420 uint32_t bhsam_0xffffffff;
421 uint32_t bhsam_reserved2;
422 uint32_t bhsam_statsn;
423 uint32_t bhsam_expcmdsn;
424 uint32_t bhsam_maxcmdsn;
425 uint8_t bhsam_async_event;
426 uint8_t bhsam_async_vcode;
427 uint16_t bhsam_parameter1;
428 uint16_t bhsam_parameter2;
429 uint16_t bhsam_parameter3;
430 uint32_t bhsam_reserved3;
432 CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE);
434 #define BHSSR_REASON_DATA_DIGEST_ERROR 0x02
435 #define BHSSR_PROTOCOL_ERROR 0x04
436 #define BHSSR_COMMAND_NOT_SUPPORTED 0x05
437 #define BHSSR_INVALID_PDU_FIELD 0x09
439 struct iscsi_bhs_reject {
443 uint8_t bhsr_reserved;
444 uint8_t bhsr_total_ahs_len;
445 uint8_t bhsr_data_segment_len[3];
446 uint64_t bhsr_reserved2;
447 uint32_t bhsr_0xffffffff;
448 uint32_t bhsr_reserved3;
449 uint32_t bhsr_statsn;
450 uint32_t bhsr_expcmdsn;
451 uint32_t bhsr_maxcmdsn;
452 uint32_t bhsr_datasn_r2tsn;
453 uint32_t bhsr_reserved4;
454 uint32_t bhsr_reserved5;
456 CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE);
458 #endif /* !ISCSI_PROTO_H */