1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * RFC 3720 (iSCSI) protocol data types
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2005 Dmitry Yusupov
6*4882a593Smuzhiyun * Copyright (C) 2005 Alex Aizman
7*4882a593Smuzhiyun * maintained by open-iscsi@googlegroups.com
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #ifndef ISCSI_PROTO_H
11*4882a593Smuzhiyun #define ISCSI_PROTO_H
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun #include <scsi/scsi.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define ISCSI_DRAFT20_VERSION 0x00
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /* default iSCSI listen port for incoming connections */
19*4882a593Smuzhiyun #define ISCSI_LISTEN_PORT 3260
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /* iSCSI header length */
22*4882a593Smuzhiyun #define ISCSI_HDR_LEN 48
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /* iSCSI CRC32C length */
25*4882a593Smuzhiyun #define ISCSI_CRC_LEN 4
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun /* Padding word length */
28*4882a593Smuzhiyun #define ISCSI_PAD_LEN 4
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun /*
31*4882a593Smuzhiyun * Serial Number Arithmetic, 32 bits, RFC1982
32*4882a593Smuzhiyun */
33*4882a593Smuzhiyun
iscsi_sna_lt(u32 n1,u32 n2)34*4882a593Smuzhiyun static inline int iscsi_sna_lt(u32 n1, u32 n2)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun return (s32)(n1 - n2) < 0;
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun
iscsi_sna_lte(u32 n1,u32 n2)39*4882a593Smuzhiyun static inline int iscsi_sna_lte(u32 n1, u32 n2)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun return (s32)(n1 - n2) <= 0;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
iscsi_sna_gt(u32 n1,u32 n2)44*4882a593Smuzhiyun static inline int iscsi_sna_gt(u32 n1, u32 n2)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun return (s32)(n1 - n2) > 0;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
iscsi_sna_gte(u32 n1,u32 n2)49*4882a593Smuzhiyun static inline int iscsi_sna_gte(u32 n1, u32 n2)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun return (s32)(n1 - n2) >= 0;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun * useful common(control and data pathes) macro
56*4882a593Smuzhiyun */
57*4882a593Smuzhiyun #define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
58*4882a593Smuzhiyun #define hton24(p, v) { \
59*4882a593Smuzhiyun p[0] = (((v) >> 16) & 0xFF); \
60*4882a593Smuzhiyun p[1] = (((v) >> 8) & 0xFF); \
61*4882a593Smuzhiyun p[2] = ((v) & 0xFF); \
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun #define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;}
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /* initiator tags; opaque for target */
66*4882a593Smuzhiyun typedef uint32_t __bitwise itt_t;
67*4882a593Smuzhiyun /* below makes sense only for initiator that created this tag */
68*4882a593Smuzhiyun #define build_itt(itt, age) ((__force itt_t)\
69*4882a593Smuzhiyun ((itt) | ((age) << ISCSI_AGE_SHIFT)))
70*4882a593Smuzhiyun #define get_itt(itt) ((__force uint32_t)(itt_t)(itt) & ISCSI_ITT_MASK)
71*4882a593Smuzhiyun #define RESERVED_ITT ((__force itt_t)0xffffffff)
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun * iSCSI Template Message Header
75*4882a593Smuzhiyun */
76*4882a593Smuzhiyun struct iscsi_hdr {
77*4882a593Smuzhiyun uint8_t opcode;
78*4882a593Smuzhiyun uint8_t flags; /* Final bit */
79*4882a593Smuzhiyun uint8_t rsvd2[2];
80*4882a593Smuzhiyun uint8_t hlength; /* AHSs total length */
81*4882a593Smuzhiyun uint8_t dlength[3]; /* Data length */
82*4882a593Smuzhiyun struct scsi_lun lun;
83*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag, opaque for target */
84*4882a593Smuzhiyun __be32 ttt; /* Target Task Tag */
85*4882a593Smuzhiyun __be32 statsn;
86*4882a593Smuzhiyun __be32 exp_statsn;
87*4882a593Smuzhiyun __be32 max_statsn;
88*4882a593Smuzhiyun uint8_t other[12];
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /************************* RFC 3720 Begin *****************************/
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun #define ISCSI_RESERVED_TAG 0xffffffff
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* Opcode encoding bits */
96*4882a593Smuzhiyun #define ISCSI_OP_RETRY 0x80
97*4882a593Smuzhiyun #define ISCSI_OP_IMMEDIATE 0x40
98*4882a593Smuzhiyun #define ISCSI_OPCODE_MASK 0x3F
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /* Initiator Opcode values */
101*4882a593Smuzhiyun #define ISCSI_OP_NOOP_OUT 0x00
102*4882a593Smuzhiyun #define ISCSI_OP_SCSI_CMD 0x01
103*4882a593Smuzhiyun #define ISCSI_OP_SCSI_TMFUNC 0x02
104*4882a593Smuzhiyun #define ISCSI_OP_LOGIN 0x03
105*4882a593Smuzhiyun #define ISCSI_OP_TEXT 0x04
106*4882a593Smuzhiyun #define ISCSI_OP_SCSI_DATA_OUT 0x05
107*4882a593Smuzhiyun #define ISCSI_OP_LOGOUT 0x06
108*4882a593Smuzhiyun #define ISCSI_OP_SNACK 0x10
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define ISCSI_OP_VENDOR1_CMD 0x1c
111*4882a593Smuzhiyun #define ISCSI_OP_VENDOR2_CMD 0x1d
112*4882a593Smuzhiyun #define ISCSI_OP_VENDOR3_CMD 0x1e
113*4882a593Smuzhiyun #define ISCSI_OP_VENDOR4_CMD 0x1f
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* Target Opcode values */
116*4882a593Smuzhiyun #define ISCSI_OP_NOOP_IN 0x20
117*4882a593Smuzhiyun #define ISCSI_OP_SCSI_CMD_RSP 0x21
118*4882a593Smuzhiyun #define ISCSI_OP_SCSI_TMFUNC_RSP 0x22
119*4882a593Smuzhiyun #define ISCSI_OP_LOGIN_RSP 0x23
120*4882a593Smuzhiyun #define ISCSI_OP_TEXT_RSP 0x24
121*4882a593Smuzhiyun #define ISCSI_OP_SCSI_DATA_IN 0x25
122*4882a593Smuzhiyun #define ISCSI_OP_LOGOUT_RSP 0x26
123*4882a593Smuzhiyun #define ISCSI_OP_R2T 0x31
124*4882a593Smuzhiyun #define ISCSI_OP_ASYNC_EVENT 0x32
125*4882a593Smuzhiyun #define ISCSI_OP_REJECT 0x3f
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun struct iscsi_ahs_hdr {
128*4882a593Smuzhiyun __be16 ahslength;
129*4882a593Smuzhiyun uint8_t ahstype;
130*4882a593Smuzhiyun uint8_t ahspec[5];
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun #define ISCSI_AHSTYPE_CDB 1
134*4882a593Smuzhiyun #define ISCSI_AHSTYPE_RLENGTH 2
135*4882a593Smuzhiyun #define ISCSI_CDB_SIZE 16
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /* iSCSI PDU Header */
138*4882a593Smuzhiyun struct iscsi_scsi_req {
139*4882a593Smuzhiyun uint8_t opcode;
140*4882a593Smuzhiyun uint8_t flags;
141*4882a593Smuzhiyun __be16 rsvd2;
142*4882a593Smuzhiyun uint8_t hlength;
143*4882a593Smuzhiyun uint8_t dlength[3];
144*4882a593Smuzhiyun struct scsi_lun lun;
145*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
146*4882a593Smuzhiyun __be32 data_length;
147*4882a593Smuzhiyun __be32 cmdsn;
148*4882a593Smuzhiyun __be32 exp_statsn;
149*4882a593Smuzhiyun uint8_t cdb[ISCSI_CDB_SIZE]; /* SCSI Command Block */
150*4882a593Smuzhiyun /* Additional Data (Command Dependent) */
151*4882a593Smuzhiyun };
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /* Command PDU flags */
154*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_FINAL 0x80
155*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_READ 0x40
156*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_WRITE 0x20
157*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /* SCSI Command Attribute values */
160*4882a593Smuzhiyun #define ISCSI_ATTR_UNTAGGED 0
161*4882a593Smuzhiyun #define ISCSI_ATTR_SIMPLE 1
162*4882a593Smuzhiyun #define ISCSI_ATTR_ORDERED 2
163*4882a593Smuzhiyun #define ISCSI_ATTR_HEAD_OF_QUEUE 3
164*4882a593Smuzhiyun #define ISCSI_ATTR_ACA 4
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun struct iscsi_rlength_ahdr {
167*4882a593Smuzhiyun __be16 ahslength;
168*4882a593Smuzhiyun uint8_t ahstype;
169*4882a593Smuzhiyun uint8_t reserved;
170*4882a593Smuzhiyun __be32 read_length;
171*4882a593Smuzhiyun };
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* Extended CDB AHS */
174*4882a593Smuzhiyun struct iscsi_ecdb_ahdr {
175*4882a593Smuzhiyun __be16 ahslength; /* CDB length - 15, including reserved byte */
176*4882a593Smuzhiyun uint8_t ahstype;
177*4882a593Smuzhiyun uint8_t reserved;
178*4882a593Smuzhiyun /* 4-byte aligned extended CDB spillover */
179*4882a593Smuzhiyun uint8_t ecdb[SCSI_MAX_VARLEN_CDB_SIZE - ISCSI_CDB_SIZE];
180*4882a593Smuzhiyun };
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* SCSI Response Header */
183*4882a593Smuzhiyun struct iscsi_scsi_rsp {
184*4882a593Smuzhiyun uint8_t opcode;
185*4882a593Smuzhiyun uint8_t flags;
186*4882a593Smuzhiyun uint8_t response;
187*4882a593Smuzhiyun uint8_t cmd_status;
188*4882a593Smuzhiyun uint8_t hlength;
189*4882a593Smuzhiyun uint8_t dlength[3];
190*4882a593Smuzhiyun uint8_t rsvd[8];
191*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
192*4882a593Smuzhiyun __be32 rsvd1;
193*4882a593Smuzhiyun __be32 statsn;
194*4882a593Smuzhiyun __be32 exp_cmdsn;
195*4882a593Smuzhiyun __be32 max_cmdsn;
196*4882a593Smuzhiyun __be32 exp_datasn;
197*4882a593Smuzhiyun __be32 bi_residual_count;
198*4882a593Smuzhiyun __be32 residual_count;
199*4882a593Smuzhiyun /* Response or Sense Data (optional) */
200*4882a593Smuzhiyun };
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* Command Response PDU flags */
203*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10
204*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08
205*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_OVERFLOW 0x04
206*4882a593Smuzhiyun #define ISCSI_FLAG_CMD_UNDERFLOW 0x02
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* iSCSI Status values. Valid if Rsp Selector bit is not set */
209*4882a593Smuzhiyun #define ISCSI_STATUS_CMD_COMPLETED 0
210*4882a593Smuzhiyun #define ISCSI_STATUS_TARGET_FAILURE 1
211*4882a593Smuzhiyun #define ISCSI_STATUS_SUBSYS_FAILURE 2
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun /* Asynchronous Event Header */
214*4882a593Smuzhiyun struct iscsi_async {
215*4882a593Smuzhiyun uint8_t opcode;
216*4882a593Smuzhiyun uint8_t flags;
217*4882a593Smuzhiyun uint8_t rsvd2[2];
218*4882a593Smuzhiyun uint8_t rsvd3;
219*4882a593Smuzhiyun uint8_t dlength[3];
220*4882a593Smuzhiyun struct scsi_lun lun;
221*4882a593Smuzhiyun uint8_t rsvd4[8];
222*4882a593Smuzhiyun __be32 statsn;
223*4882a593Smuzhiyun __be32 exp_cmdsn;
224*4882a593Smuzhiyun __be32 max_cmdsn;
225*4882a593Smuzhiyun uint8_t async_event;
226*4882a593Smuzhiyun uint8_t async_vcode;
227*4882a593Smuzhiyun __be16 param1;
228*4882a593Smuzhiyun __be16 param2;
229*4882a593Smuzhiyun __be16 param3;
230*4882a593Smuzhiyun uint8_t rsvd5[4];
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /* iSCSI Event Codes */
234*4882a593Smuzhiyun #define ISCSI_ASYNC_MSG_SCSI_EVENT 0
235*4882a593Smuzhiyun #define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1
236*4882a593Smuzhiyun #define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2
237*4882a593Smuzhiyun #define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3
238*4882a593Smuzhiyun #define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4
239*4882a593Smuzhiyun #define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun /* NOP-Out Message */
242*4882a593Smuzhiyun struct iscsi_nopout {
243*4882a593Smuzhiyun uint8_t opcode;
244*4882a593Smuzhiyun uint8_t flags;
245*4882a593Smuzhiyun __be16 rsvd2;
246*4882a593Smuzhiyun uint8_t rsvd3;
247*4882a593Smuzhiyun uint8_t dlength[3];
248*4882a593Smuzhiyun struct scsi_lun lun;
249*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
250*4882a593Smuzhiyun __be32 ttt; /* Target Transfer Tag */
251*4882a593Smuzhiyun __be32 cmdsn;
252*4882a593Smuzhiyun __be32 exp_statsn;
253*4882a593Smuzhiyun uint8_t rsvd4[16];
254*4882a593Smuzhiyun };
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun /* NOP-In Message */
257*4882a593Smuzhiyun struct iscsi_nopin {
258*4882a593Smuzhiyun uint8_t opcode;
259*4882a593Smuzhiyun uint8_t flags;
260*4882a593Smuzhiyun __be16 rsvd2;
261*4882a593Smuzhiyun uint8_t rsvd3;
262*4882a593Smuzhiyun uint8_t dlength[3];
263*4882a593Smuzhiyun struct scsi_lun lun;
264*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
265*4882a593Smuzhiyun __be32 ttt; /* Target Transfer Tag */
266*4882a593Smuzhiyun __be32 statsn;
267*4882a593Smuzhiyun __be32 exp_cmdsn;
268*4882a593Smuzhiyun __be32 max_cmdsn;
269*4882a593Smuzhiyun uint8_t rsvd4[12];
270*4882a593Smuzhiyun };
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* SCSI Task Management Message Header */
273*4882a593Smuzhiyun struct iscsi_tm {
274*4882a593Smuzhiyun uint8_t opcode;
275*4882a593Smuzhiyun uint8_t flags;
276*4882a593Smuzhiyun uint8_t rsvd1[2];
277*4882a593Smuzhiyun uint8_t hlength;
278*4882a593Smuzhiyun uint8_t dlength[3];
279*4882a593Smuzhiyun struct scsi_lun lun;
280*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
281*4882a593Smuzhiyun itt_t rtt; /* Reference Task Tag */
282*4882a593Smuzhiyun __be32 cmdsn;
283*4882a593Smuzhiyun __be32 exp_statsn;
284*4882a593Smuzhiyun __be32 refcmdsn;
285*4882a593Smuzhiyun __be32 exp_datasn;
286*4882a593Smuzhiyun uint8_t rsvd2[8];
287*4882a593Smuzhiyun };
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun #define ISCSI_FLAG_TM_FUNC_MASK 0x7F
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /* Function values */
292*4882a593Smuzhiyun #define ISCSI_TM_FUNC_ABORT_TASK 1
293*4882a593Smuzhiyun #define ISCSI_TM_FUNC_ABORT_TASK_SET 2
294*4882a593Smuzhiyun #define ISCSI_TM_FUNC_CLEAR_ACA 3
295*4882a593Smuzhiyun #define ISCSI_TM_FUNC_CLEAR_TASK_SET 4
296*4882a593Smuzhiyun #define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5
297*4882a593Smuzhiyun #define ISCSI_TM_FUNC_TARGET_WARM_RESET 6
298*4882a593Smuzhiyun #define ISCSI_TM_FUNC_TARGET_COLD_RESET 7
299*4882a593Smuzhiyun #define ISCSI_TM_FUNC_TASK_REASSIGN 8
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun #define ISCSI_TM_FUNC_VALUE(hdr) ((hdr)->flags & ISCSI_FLAG_TM_FUNC_MASK)
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun /* SCSI Task Management Response Header */
304*4882a593Smuzhiyun struct iscsi_tm_rsp {
305*4882a593Smuzhiyun uint8_t opcode;
306*4882a593Smuzhiyun uint8_t flags;
307*4882a593Smuzhiyun uint8_t response; /* see Response values below */
308*4882a593Smuzhiyun uint8_t qualifier;
309*4882a593Smuzhiyun uint8_t hlength;
310*4882a593Smuzhiyun uint8_t dlength[3];
311*4882a593Smuzhiyun uint8_t rsvd2[8];
312*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
313*4882a593Smuzhiyun itt_t rtt; /* Reference Task Tag */
314*4882a593Smuzhiyun __be32 statsn;
315*4882a593Smuzhiyun __be32 exp_cmdsn;
316*4882a593Smuzhiyun __be32 max_cmdsn;
317*4882a593Smuzhiyun uint8_t rsvd3[12];
318*4882a593Smuzhiyun };
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun /* Response values */
321*4882a593Smuzhiyun #define ISCSI_TMF_RSP_COMPLETE 0x00
322*4882a593Smuzhiyun #define ISCSI_TMF_RSP_NO_TASK 0x01
323*4882a593Smuzhiyun #define ISCSI_TMF_RSP_NO_LUN 0x02
324*4882a593Smuzhiyun #define ISCSI_TMF_RSP_TASK_ALLEGIANT 0x03
325*4882a593Smuzhiyun #define ISCSI_TMF_RSP_NO_FAILOVER 0x04
326*4882a593Smuzhiyun #define ISCSI_TMF_RSP_NOT_SUPPORTED 0x05
327*4882a593Smuzhiyun #define ISCSI_TMF_RSP_AUTH_FAILED 0x06
328*4882a593Smuzhiyun #define ISCSI_TMF_RSP_REJECTED 0xff
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /* Ready To Transfer Header */
331*4882a593Smuzhiyun struct iscsi_r2t_rsp {
332*4882a593Smuzhiyun uint8_t opcode;
333*4882a593Smuzhiyun uint8_t flags;
334*4882a593Smuzhiyun uint8_t rsvd2[2];
335*4882a593Smuzhiyun uint8_t hlength;
336*4882a593Smuzhiyun uint8_t dlength[3];
337*4882a593Smuzhiyun struct scsi_lun lun;
338*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
339*4882a593Smuzhiyun __be32 ttt; /* Target Transfer Tag */
340*4882a593Smuzhiyun __be32 statsn;
341*4882a593Smuzhiyun __be32 exp_cmdsn;
342*4882a593Smuzhiyun __be32 max_cmdsn;
343*4882a593Smuzhiyun __be32 r2tsn;
344*4882a593Smuzhiyun __be32 data_offset;
345*4882a593Smuzhiyun __be32 data_length;
346*4882a593Smuzhiyun };
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun /* SCSI Data Hdr */
349*4882a593Smuzhiyun struct iscsi_data {
350*4882a593Smuzhiyun uint8_t opcode;
351*4882a593Smuzhiyun uint8_t flags;
352*4882a593Smuzhiyun uint8_t rsvd2[2];
353*4882a593Smuzhiyun uint8_t rsvd3;
354*4882a593Smuzhiyun uint8_t dlength[3];
355*4882a593Smuzhiyun struct scsi_lun lun;
356*4882a593Smuzhiyun itt_t itt;
357*4882a593Smuzhiyun __be32 ttt;
358*4882a593Smuzhiyun __be32 rsvd4;
359*4882a593Smuzhiyun __be32 exp_statsn;
360*4882a593Smuzhiyun __be32 rsvd5;
361*4882a593Smuzhiyun __be32 datasn;
362*4882a593Smuzhiyun __be32 offset;
363*4882a593Smuzhiyun __be32 rsvd6;
364*4882a593Smuzhiyun /* Payload */
365*4882a593Smuzhiyun };
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun /* SCSI Data Response Hdr */
368*4882a593Smuzhiyun struct iscsi_data_rsp {
369*4882a593Smuzhiyun uint8_t opcode;
370*4882a593Smuzhiyun uint8_t flags;
371*4882a593Smuzhiyun uint8_t rsvd2;
372*4882a593Smuzhiyun uint8_t cmd_status;
373*4882a593Smuzhiyun uint8_t hlength;
374*4882a593Smuzhiyun uint8_t dlength[3];
375*4882a593Smuzhiyun struct scsi_lun lun;
376*4882a593Smuzhiyun itt_t itt;
377*4882a593Smuzhiyun __be32 ttt;
378*4882a593Smuzhiyun __be32 statsn;
379*4882a593Smuzhiyun __be32 exp_cmdsn;
380*4882a593Smuzhiyun __be32 max_cmdsn;
381*4882a593Smuzhiyun __be32 datasn;
382*4882a593Smuzhiyun __be32 offset;
383*4882a593Smuzhiyun __be32 residual_count;
384*4882a593Smuzhiyun };
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun /* Data Response PDU flags */
387*4882a593Smuzhiyun #define ISCSI_FLAG_DATA_ACK 0x40
388*4882a593Smuzhiyun #define ISCSI_FLAG_DATA_OVERFLOW 0x04
389*4882a593Smuzhiyun #define ISCSI_FLAG_DATA_UNDERFLOW 0x02
390*4882a593Smuzhiyun #define ISCSI_FLAG_DATA_STATUS 0x01
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* Text Header */
393*4882a593Smuzhiyun struct iscsi_text {
394*4882a593Smuzhiyun uint8_t opcode;
395*4882a593Smuzhiyun uint8_t flags;
396*4882a593Smuzhiyun uint8_t rsvd2[2];
397*4882a593Smuzhiyun uint8_t hlength;
398*4882a593Smuzhiyun uint8_t dlength[3];
399*4882a593Smuzhiyun uint8_t rsvd4[8];
400*4882a593Smuzhiyun itt_t itt;
401*4882a593Smuzhiyun __be32 ttt;
402*4882a593Smuzhiyun __be32 cmdsn;
403*4882a593Smuzhiyun __be32 exp_statsn;
404*4882a593Smuzhiyun uint8_t rsvd5[16];
405*4882a593Smuzhiyun /* Text - key=value pairs */
406*4882a593Smuzhiyun };
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun #define ISCSI_FLAG_TEXT_CONTINUE 0x40
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun /* Text Response Header */
411*4882a593Smuzhiyun struct iscsi_text_rsp {
412*4882a593Smuzhiyun uint8_t opcode;
413*4882a593Smuzhiyun uint8_t flags;
414*4882a593Smuzhiyun uint8_t rsvd2[2];
415*4882a593Smuzhiyun uint8_t hlength;
416*4882a593Smuzhiyun uint8_t dlength[3];
417*4882a593Smuzhiyun uint8_t rsvd4[8];
418*4882a593Smuzhiyun itt_t itt;
419*4882a593Smuzhiyun __be32 ttt;
420*4882a593Smuzhiyun __be32 statsn;
421*4882a593Smuzhiyun __be32 exp_cmdsn;
422*4882a593Smuzhiyun __be32 max_cmdsn;
423*4882a593Smuzhiyun uint8_t rsvd5[12];
424*4882a593Smuzhiyun /* Text Response - key:value pairs */
425*4882a593Smuzhiyun };
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun /* Login Header */
428*4882a593Smuzhiyun struct iscsi_login_req {
429*4882a593Smuzhiyun uint8_t opcode;
430*4882a593Smuzhiyun uint8_t flags;
431*4882a593Smuzhiyun uint8_t max_version; /* Max. version supported */
432*4882a593Smuzhiyun uint8_t min_version; /* Min. version supported */
433*4882a593Smuzhiyun uint8_t hlength;
434*4882a593Smuzhiyun uint8_t dlength[3];
435*4882a593Smuzhiyun uint8_t isid[6]; /* Initiator Session ID */
436*4882a593Smuzhiyun __be16 tsih; /* Target Session Handle */
437*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
438*4882a593Smuzhiyun __be16 cid;
439*4882a593Smuzhiyun __be16 rsvd3;
440*4882a593Smuzhiyun __be32 cmdsn;
441*4882a593Smuzhiyun __be32 exp_statsn;
442*4882a593Smuzhiyun uint8_t rsvd5[16];
443*4882a593Smuzhiyun };
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun /* Login PDU flags */
446*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_TRANSIT 0x80
447*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_CONTINUE 0x40
448*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */
449*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_CURRENT_STAGE1 0x04
450*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_CURRENT_STAGE2 0x08
451*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_CURRENT_STAGE3 0x0C
452*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */
453*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_NEXT_STAGE1 0x01
454*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_NEXT_STAGE2 0x02
455*4882a593Smuzhiyun #define ISCSI_FLAG_LOGIN_NEXT_STAGE3 0x03
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun #define ISCSI_LOGIN_CURRENT_STAGE(flags) \
458*4882a593Smuzhiyun ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2)
459*4882a593Smuzhiyun #define ISCSI_LOGIN_NEXT_STAGE(flags) \
460*4882a593Smuzhiyun (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK)
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /* Login Response Header */
463*4882a593Smuzhiyun struct iscsi_login_rsp {
464*4882a593Smuzhiyun uint8_t opcode;
465*4882a593Smuzhiyun uint8_t flags;
466*4882a593Smuzhiyun uint8_t max_version; /* Max. version supported */
467*4882a593Smuzhiyun uint8_t active_version; /* Active version */
468*4882a593Smuzhiyun uint8_t hlength;
469*4882a593Smuzhiyun uint8_t dlength[3];
470*4882a593Smuzhiyun uint8_t isid[6]; /* Initiator Session ID */
471*4882a593Smuzhiyun __be16 tsih; /* Target Session Handle */
472*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
473*4882a593Smuzhiyun __be32 rsvd3;
474*4882a593Smuzhiyun __be32 statsn;
475*4882a593Smuzhiyun __be32 exp_cmdsn;
476*4882a593Smuzhiyun __be32 max_cmdsn;
477*4882a593Smuzhiyun uint8_t status_class; /* see Login RSP ststus classes below */
478*4882a593Smuzhiyun uint8_t status_detail; /* see Login RSP Status details below */
479*4882a593Smuzhiyun uint8_t rsvd4[10];
480*4882a593Smuzhiyun };
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* Login stage (phase) codes for CSG, NSG */
483*4882a593Smuzhiyun #define ISCSI_INITIAL_LOGIN_STAGE -1
484*4882a593Smuzhiyun #define ISCSI_SECURITY_NEGOTIATION_STAGE 0
485*4882a593Smuzhiyun #define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1
486*4882a593Smuzhiyun #define ISCSI_FULL_FEATURE_PHASE 3
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun /* Login Status response classes */
489*4882a593Smuzhiyun #define ISCSI_STATUS_CLS_SUCCESS 0x00
490*4882a593Smuzhiyun #define ISCSI_STATUS_CLS_REDIRECT 0x01
491*4882a593Smuzhiyun #define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02
492*4882a593Smuzhiyun #define ISCSI_STATUS_CLS_TARGET_ERR 0x03
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun /* Login Status response detail codes */
495*4882a593Smuzhiyun /* Class-0 (Success) */
496*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_ACCEPT 0x00
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun /* Class-1 (Redirection) */
499*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01
500*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun /* Class-2 (Initiator Error) */
503*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_INIT_ERR 0x00
504*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01
505*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02
506*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03
507*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04
508*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_NO_VERSION 0x05
509*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06
510*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07
511*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08
512*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09
513*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a
514*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun /* Class-3 (Target Error) */
517*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00
518*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01
519*4882a593Smuzhiyun #define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun /* Logout Header */
522*4882a593Smuzhiyun struct iscsi_logout {
523*4882a593Smuzhiyun uint8_t opcode;
524*4882a593Smuzhiyun uint8_t flags;
525*4882a593Smuzhiyun uint8_t rsvd1[2];
526*4882a593Smuzhiyun uint8_t hlength;
527*4882a593Smuzhiyun uint8_t dlength[3];
528*4882a593Smuzhiyun uint8_t rsvd2[8];
529*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
530*4882a593Smuzhiyun __be16 cid;
531*4882a593Smuzhiyun uint8_t rsvd3[2];
532*4882a593Smuzhiyun __be32 cmdsn;
533*4882a593Smuzhiyun __be32 exp_statsn;
534*4882a593Smuzhiyun uint8_t rsvd4[16];
535*4882a593Smuzhiyun };
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun /* Logout PDU flags */
538*4882a593Smuzhiyun #define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* logout reason_code values */
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun #define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0
543*4882a593Smuzhiyun #define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1
544*4882a593Smuzhiyun #define ISCSI_LOGOUT_REASON_RECOVERY 2
545*4882a593Smuzhiyun #define ISCSI_LOGOUT_REASON_AEN_REQUEST 3
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun /* Logout Response Header */
548*4882a593Smuzhiyun struct iscsi_logout_rsp {
549*4882a593Smuzhiyun uint8_t opcode;
550*4882a593Smuzhiyun uint8_t flags;
551*4882a593Smuzhiyun uint8_t response; /* see Logout response values below */
552*4882a593Smuzhiyun uint8_t rsvd2;
553*4882a593Smuzhiyun uint8_t hlength;
554*4882a593Smuzhiyun uint8_t dlength[3];
555*4882a593Smuzhiyun uint8_t rsvd3[8];
556*4882a593Smuzhiyun itt_t itt; /* Initiator Task Tag */
557*4882a593Smuzhiyun __be32 rsvd4;
558*4882a593Smuzhiyun __be32 statsn;
559*4882a593Smuzhiyun __be32 exp_cmdsn;
560*4882a593Smuzhiyun __be32 max_cmdsn;
561*4882a593Smuzhiyun __be32 rsvd5;
562*4882a593Smuzhiyun __be16 t2wait;
563*4882a593Smuzhiyun __be16 t2retain;
564*4882a593Smuzhiyun __be32 rsvd6;
565*4882a593Smuzhiyun };
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun /* logout response status values */
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun #define ISCSI_LOGOUT_SUCCESS 0
570*4882a593Smuzhiyun #define ISCSI_LOGOUT_CID_NOT_FOUND 1
571*4882a593Smuzhiyun #define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2
572*4882a593Smuzhiyun #define ISCSI_LOGOUT_CLEANUP_FAILED 3
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /* SNACK Header */
575*4882a593Smuzhiyun struct iscsi_snack {
576*4882a593Smuzhiyun uint8_t opcode;
577*4882a593Smuzhiyun uint8_t flags;
578*4882a593Smuzhiyun uint8_t rsvd2[2];
579*4882a593Smuzhiyun uint8_t hlength;
580*4882a593Smuzhiyun uint8_t dlength[3];
581*4882a593Smuzhiyun uint8_t lun[8];
582*4882a593Smuzhiyun itt_t itt;
583*4882a593Smuzhiyun __be32 ttt;
584*4882a593Smuzhiyun uint8_t rsvd3[4];
585*4882a593Smuzhiyun __be32 exp_statsn;
586*4882a593Smuzhiyun uint8_t rsvd4[8];
587*4882a593Smuzhiyun __be32 begrun;
588*4882a593Smuzhiyun __be32 runlength;
589*4882a593Smuzhiyun };
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun /* SNACK PDU flags */
592*4882a593Smuzhiyun #define ISCSI_FLAG_SNACK_TYPE_DATA 0
593*4882a593Smuzhiyun #define ISCSI_FLAG_SNACK_TYPE_R2T 0
594*4882a593Smuzhiyun #define ISCSI_FLAG_SNACK_TYPE_STATUS 1
595*4882a593Smuzhiyun #define ISCSI_FLAG_SNACK_TYPE_DATA_ACK 2
596*4882a593Smuzhiyun #define ISCSI_FLAG_SNACK_TYPE_RDATA 3
597*4882a593Smuzhiyun #define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun /* Reject Message Header */
600*4882a593Smuzhiyun struct iscsi_reject {
601*4882a593Smuzhiyun uint8_t opcode;
602*4882a593Smuzhiyun uint8_t flags;
603*4882a593Smuzhiyun uint8_t reason;
604*4882a593Smuzhiyun uint8_t rsvd2;
605*4882a593Smuzhiyun uint8_t hlength;
606*4882a593Smuzhiyun uint8_t dlength[3];
607*4882a593Smuzhiyun uint8_t rsvd3[8];
608*4882a593Smuzhiyun __be32 ffffffff;
609*4882a593Smuzhiyun uint8_t rsvd4[4];
610*4882a593Smuzhiyun __be32 statsn;
611*4882a593Smuzhiyun __be32 exp_cmdsn;
612*4882a593Smuzhiyun __be32 max_cmdsn;
613*4882a593Smuzhiyun __be32 datasn;
614*4882a593Smuzhiyun uint8_t rsvd5[8];
615*4882a593Smuzhiyun /* Text - Rejected hdr */
616*4882a593Smuzhiyun };
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun /* Reason for Reject */
619*4882a593Smuzhiyun #define ISCSI_REASON_CMD_BEFORE_LOGIN 1
620*4882a593Smuzhiyun #define ISCSI_REASON_DATA_DIGEST_ERROR 2
621*4882a593Smuzhiyun #define ISCSI_REASON_DATA_SNACK_REJECT 3
622*4882a593Smuzhiyun #define ISCSI_REASON_PROTOCOL_ERROR 4
623*4882a593Smuzhiyun #define ISCSI_REASON_CMD_NOT_SUPPORTED 5
624*4882a593Smuzhiyun #define ISCSI_REASON_IMM_CMD_REJECT 6
625*4882a593Smuzhiyun #define ISCSI_REASON_TASK_IN_PROGRESS 7
626*4882a593Smuzhiyun #define ISCSI_REASON_INVALID_SNACK 8
627*4882a593Smuzhiyun #define ISCSI_REASON_BOOKMARK_INVALID 9
628*4882a593Smuzhiyun #define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10
629*4882a593Smuzhiyun #define ISCSI_REASON_NEGOTIATION_RESET 11
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun /* Max. number of Key=Value pairs in a text message */
632*4882a593Smuzhiyun #define MAX_KEY_VALUE_PAIRS 8192
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun /* maximum length for text keys/values */
635*4882a593Smuzhiyun #define KEY_MAXLEN 64
636*4882a593Smuzhiyun #define VALUE_MAXLEN 255
637*4882a593Smuzhiyun #define TARGET_NAME_MAXLEN VALUE_MAXLEN
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun #define ISCSI_DEF_MAX_RECV_SEG_LEN 8192
640*4882a593Smuzhiyun #define ISCSI_MIN_MAX_RECV_SEG_LEN 512
641*4882a593Smuzhiyun #define ISCSI_MAX_MAX_RECV_SEG_LEN 16777215
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun #define ISCSI_DEF_FIRST_BURST_LEN 65536
644*4882a593Smuzhiyun #define ISCSI_MIN_FIRST_BURST_LEN 512
645*4882a593Smuzhiyun #define ISCSI_MAX_FIRST_BURST_LEN 16777215
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun #define ISCSI_DEF_MAX_BURST_LEN 262144
648*4882a593Smuzhiyun #define ISCSI_MIN_MAX_BURST_LEN 512
649*4882a593Smuzhiyun #define ISCSI_MAX_MAX_BURST_LEN 16777215
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun #define ISCSI_DEF_TIME2WAIT 2
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun #define ISCSI_NAME_LEN 224
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun /************************* RFC 3720 End *****************************/
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun #endif /* ISCSI_PROTO_H */
658