2 * Copyright (c) 2012 The FreeBSD Foundation
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
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]
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)
44 #define ISCSI_BHS_SIZE 48
45 #define ISCSI_HEADER_DIGEST_SIZE 4
46 #define ISCSI_DATA_DIGEST_SIZE 4
48 #define ISCSI_BHS_OPCODE_IMMEDIATE 0x40
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
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
71 uint8_t bhs_opcode_specific1[3];
72 uint8_t bhs_total_ahs_len;
73 uint8_t bhs_data_segment_len[3];
75 uint8_t bhs_inititator_task_tag[4];
76 uint8_t bhs_opcode_specific4[28];
78 CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE);
80 #define BHSSC_FLAGS_F 0x80
81 #define BHSSC_FLAGS_R 0x40
82 #define BHSSC_FLAGS_W 0x20
83 #define BHSSC_FLAGS_ATTR 0x07
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
91 struct iscsi_bhs_scsi_command {
94 uint8_t bhssc_reserved[2];
95 uint8_t bhssc_total_ahs_len;
96 uint8_t bhssc_data_segment_len[3];
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];
104 CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE);
106 #define BHSSR_FLAGS_RESIDUAL_UNDERFLOW 0x02
107 #define BHSSR_FLAGS_RESIDUAL_OVERFLOW 0x04
109 #define BHSSR_RESPONSE_COMMAND_COMPLETED 0x00
111 struct iscsi_bhs_scsi_response {
112 uint8_t bhssr_opcode;
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;
128 CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE);
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
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];
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;
154 CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE);
156 #define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0
157 #define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5
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];
174 CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE);
176 #define BHSLR_FLAGS_TRANSIT 0x80
177 #define BHSLR_FLAGS_CONTINUE 0x40
179 #define BHSLR_STAGE_SECURITY_NEGOTIATION 0
180 #define BHSLR_STAGE_OPERATIONAL_NEGOTIATION 1
181 #define BHSLR_STAGE_FULL_FEATURE_PHASE 3 /* Yes, 3. */
183 struct iscsi_bhs_login_request {
184 uint8_t bhslr_opcode;
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];
192 uint32_t bhslr_initiator_task_tag;
194 uint16_t bhslr_reserved;
195 uint32_t bhslr_cmdsn;
196 uint32_t bhslr_expstatsn;
197 uint8_t bhslr_reserved2[16];
199 CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE);
201 struct iscsi_bhs_login_response {
202 uint8_t bhslr_opcode;
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];
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];
220 CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE);
222 #define BHSTR_FLAGS_FINAL 0x80
223 #define BHSTR_FLAGS_CONTINUE 0x40
225 struct iscsi_bhs_text_request {
226 uint8_t bhstr_opcode;
228 uint16_t bhstr_reserved;
229 uint8_t bhstr_total_ahs_len;
230 uint8_t bhstr_data_segment_len[3];
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];
238 CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE);
240 struct iscsi_bhs_text_response {
241 uint8_t bhstr_opcode;
243 uint16_t bhstr_reserved;
244 uint8_t bhstr_total_ahs_len;
245 uint8_t bhstr_data_segment_len[3];
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];
254 CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE);
256 #define BHSDO_FLAGS_F 0x80
258 struct iscsi_bhs_data_out {
259 uint8_t bhsdo_opcode;
261 uint8_t bhsdo_reserved[2];
262 uint8_t bhsdo_total_ahs_len;
263 uint8_t bhsdo_data_segment_len[3];
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;
274 CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE);
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
282 struct iscsi_bhs_data_in {
283 uint8_t bhsdi_opcode;
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];
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;
299 CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE);
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];
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;
317 CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE);
319 struct iscsi_bhs_nop_out {
320 uint8_t bhsno_opcode;
322 uint16_t bhsno_reserved;
323 uint8_t bhsno_total_ahs_len;
324 uint8_t bhsno_data_segment_len[3];
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];
332 CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE);
334 struct iscsi_bhs_nop_in {
335 uint8_t bhsni_opcode;
337 uint16_t bhsni_reserved;
338 uint8_t bhsni_total_ahs_len;
339 uint8_t bhsni_data_segment_len[3];
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];
348 CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE);
350 #define BHSLR_REASON_CLOSE_SESSION 0
351 #define BHSLR_REASON_CLOSE_CONNECTION 1
352 #define BHSLR_REASON_REMOVE_FOR_RECOVERY 2
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;
363 uint16_t bhslr_reserved3;
364 uint32_t bhslr_cmdsn;
365 uint32_t bhslr_expstatsn;
366 uint8_t bhslr_reserved4[16];
368 CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE);
370 #define BHSLR_RESPONSE_CLOSED_SUCCESSFULLY 0
371 #define BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED 2
373 struct iscsi_bhs_logout_response {
374 uint8_t bhslr_opcode;
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;
391 CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE);
393 #define BHSAM_EVENT_TARGET_REQUESTS_LOGOUT 1
394 #define BHSAM_EVENT_TARGET_TERMINATES_CONNECTION 2
395 #define BHSAM_EVENT_TARGET_TERMINATES_SESSION 3
397 struct iscsi_bhs_asynchronous_message {
398 uint8_t bhsam_opcode;
400 uint16_t bhsam_reserved;
401 uint8_t bhsam_total_ahs_len;
402 uint8_t bhsam_data_segment_len[3];
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;
416 CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE);
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
423 struct iscsi_bhs_reject {
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;
440 CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE);
442 #endif /* !ISCSI_PROTO_H */