xref: /onnv-gate/usr/src/uts/common/sys/iscsi_protocol.h (revision 2314:4fe9bb63bd02)
1*2314Smcneal /*
2*2314Smcneal  * CDDL HEADER START
3*2314Smcneal  *
4*2314Smcneal  * The contents of this file are subject to the terms of the
5*2314Smcneal  * Common Development and Distribution License (the "License").
6*2314Smcneal  * You may not use this file except in compliance with the License.
7*2314Smcneal  *
8*2314Smcneal  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2314Smcneal  * or http://www.opensolaris.org/os/licensing.
10*2314Smcneal  * See the License for the specific language governing permissions
11*2314Smcneal  * and limitations under the License.
12*2314Smcneal  *
13*2314Smcneal  * When distributing Covered Code, include this CDDL HEADER in each
14*2314Smcneal  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2314Smcneal  * If applicable, add the following below this CDDL HEADER, with the
16*2314Smcneal  * fields enclosed by brackets "[]" replaced with your own identifying
17*2314Smcneal  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2314Smcneal  *
19*2314Smcneal  * CDDL HEADER END
20*2314Smcneal  */
21*2314Smcneal /*
22*2314Smcneal  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*2314Smcneal  * Use is subject to license terms.
24*2314Smcneal  */
25*2314Smcneal 
26*2314Smcneal #ifndef _ISCSI_PROTOCOL_H
27*2314Smcneal #define	_ISCSI_PROTOCOL_H
28*2314Smcneal 
29*2314Smcneal #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*2314Smcneal 
31*2314Smcneal #ifdef __cplusplus
32*2314Smcneal extern "C" {
33*2314Smcneal #endif
34*2314Smcneal 
35*2314Smcneal /*
36*2314Smcneal  * iSCSI connection daemon
37*2314Smcneal  * Copyright (C) 2001 Cisco Systems, Inc.
38*2314Smcneal  * All rights reserved.
39*2314Smcneal  *
40*2314Smcneal  * This file sets up definitions of messages and constants used by the
41*2314Smcneal  * iSCSI protocol.
42*2314Smcneal  *
43*2314Smcneal  */
44*2314Smcneal 
45*2314Smcneal #include <sys/types.h>
46*2314Smcneal #include <sys/isa_defs.h>
47*2314Smcneal 
48*2314Smcneal #define	ISCSI_MAX_NAME_LEN	224
49*2314Smcneal 
50*2314Smcneal /* prototypes for iscsi_crc.c */
51*2314Smcneal uint32_t iscsi_crc32c(void *address, unsigned long length);
52*2314Smcneal uint32_t iscsi_crc32c_continued(void *address, unsigned long length,
53*2314Smcneal     uint32_t crc);
54*2314Smcneal 
55*2314Smcneal /* iSCSI listen port for incoming connections */
56*2314Smcneal #define	ISCSI_LISTEN_PORT 3260
57*2314Smcneal 
58*2314Smcneal /* assumes a pointer to a 3-byte array */
59*2314Smcneal #define	ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
60*2314Smcneal 
61*2314Smcneal /* assumes a pointer to a 3 byte array, and an integer value */
62*2314Smcneal #define	hton24(p, v) {\
63*2314Smcneal 	p[0] = (((v) >> 16) & 0xFF); \
64*2314Smcneal 	p[1] = (((v) >> 8) & 0xFF); \
65*2314Smcneal 	p[2] = ((v) & 0xFF); \
66*2314Smcneal }
67*2314Smcneal 
68*2314Smcneal 
69*2314Smcneal /* for Login min, max, active version fields */
70*2314Smcneal #define	ISCSI_MIN_VERSION	0x00
71*2314Smcneal #define	ISCSI_DRAFT8_VERSION    0x02
72*2314Smcneal #define	ISCSI_DRAFT20_VERSION   0x00
73*2314Smcneal #define	ISCSI_MAX_VERSION	0x02
74*2314Smcneal 
75*2314Smcneal /* Min. and Max. length of a PDU we can support */
76*2314Smcneal #define	ISCSI_MIN_PDU_LENGTH	(8 << 9)	/* 4KB */
77*2314Smcneal #define	ISCSI_MAX_PDU_LENGTH	(0xffffffff)	/* Huge */
78*2314Smcneal 
79*2314Smcneal /* Padding word length */
80*2314Smcneal #define	ISCSI_PAD_WORD_LEN		4
81*2314Smcneal 
82*2314Smcneal /* Max. number of Key=Value pairs in a text message */
83*2314Smcneal #define	ISCSI_MAX_KEY_VALUE_PAIRS	8192
84*2314Smcneal 
85*2314Smcneal /* text separtor between key value pairs exhanged in login */
86*2314Smcneal #define	ISCSI_TEXT_SEPARATOR	'='
87*2314Smcneal 
88*2314Smcneal /* Sun's initiator session ID */
89*2314Smcneal #define	ISCSI_SUN_ISID_0	0x40	/* ISID - EN format */
90*2314Smcneal #define	ISCSI_SUN_ISID_1	0x00	/* Sec B */
91*2314Smcneal #define	ISCSI_SUN_ISID_2	0x00	/* Sec B */
92*2314Smcneal #define	ISCSI_SUN_ISID_3	0x2A	/* Sec C - 42 = Sun's EN */
93*2314Smcneal 
94*2314Smcneal /* Reserved value for initiator/target task tag */
95*2314Smcneal #define	ISCSI_RSVD_TASK_TAG	0xffffffff
96*2314Smcneal 
97*2314Smcneal /* maximum length for text keys/values */
98*2314Smcneal #define	KEY_MAXLEN 64
99*2314Smcneal #define	VALUE_MAXLEN 255
100*2314Smcneal #define	TARGET_NAME_MAXLEN    VALUE_MAXLEN
101*2314Smcneal 
102*2314Smcneal #define	ISCSI_DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192
103*2314Smcneal 
104*2314Smcneal /* most PDU types have a final bit */
105*2314Smcneal #define	ISCSI_FLAG_FINAL		0x80
106*2314Smcneal 
107*2314Smcneal /*
108*2314Smcneal  * Strings used during SendTargets requests
109*2314Smcneal  */
110*2314Smcneal #define	ISCSI_TEXT_SEPARATOR	'='
111*2314Smcneal #define	TARGETNAME "TargetName="
112*2314Smcneal #define	TARGETADDRESS "TargetAddress="
113*2314Smcneal 
114*2314Smcneal /* iSCSI Template Message Header */
115*2314Smcneal typedef struct _iscsi_hdr {
116*2314Smcneal 	uint8_t opcode;
117*2314Smcneal 	uint8_t flags;	/* Final bit */
118*2314Smcneal 	uint8_t rsvd2[2];
119*2314Smcneal 	uint8_t hlength;	/* AHSs total length */
120*2314Smcneal 	uint8_t dlength[3];	/* Data length */
121*2314Smcneal 	uint8_t lun[8];
122*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
123*2314Smcneal 	uint8_t		rsvd3[8];
124*2314Smcneal 	uint32_t	expstatsn;
125*2314Smcneal 	uint8_t		other[16];
126*2314Smcneal } iscsi_hdr_t;
127*2314Smcneal 
128*2314Smcneal typedef struct _iscsi_rsp_hdr {
129*2314Smcneal 	uint8_t		opcode;
130*2314Smcneal 	uint8_t		flags;
131*2314Smcneal 	uint8_t		rsvd1[3];
132*2314Smcneal 	uint8_t		dlength[3];
133*2314Smcneal 	uint8_t		rsvd2[8];
134*2314Smcneal 	uint32_t	itt;
135*2314Smcneal 	uint8_t		rsvd3[4];
136*2314Smcneal 	uint32_t	statsn;
137*2314Smcneal 	uint32_t	expcmdsn;
138*2314Smcneal 	uint32_t	maxcmdsn;
139*2314Smcneal 	uint8_t		rsvd4[12];
140*2314Smcneal } iscsi_rsp_hdr_t;
141*2314Smcneal 
142*2314Smcneal /* Opcode encoding bits */
143*2314Smcneal #define	ISCSI_OP_RETRY			0x80
144*2314Smcneal #define	ISCSI_OP_IMMEDIATE		0x40
145*2314Smcneal #define	ISCSI_OPCODE_MASK		0x3F
146*2314Smcneal 
147*2314Smcneal /* Client to Server Message Opcode values */
148*2314Smcneal #define	ISCSI_OP_NOOP_OUT		0x00
149*2314Smcneal #define	ISCSI_OP_SCSI_CMD		0x01
150*2314Smcneal #define	ISCSI_OP_SCSI_TASK_MGT_MSG	0x02
151*2314Smcneal #define	ISCSI_OP_LOGIN_CMD		0x03
152*2314Smcneal #define	ISCSI_OP_TEXT_CMD		0x04
153*2314Smcneal #define	ISCSI_OP_SCSI_DATA		0x05
154*2314Smcneal #define	ISCSI_OP_LOGOUT_CMD		0x06
155*2314Smcneal #define	ISCSI_OP_SNACK_CMD		0x10
156*2314Smcneal 
157*2314Smcneal /* Server to Client Message Opcode values */
158*2314Smcneal #define	ISCSI_OP_NOOP_IN		0x20
159*2314Smcneal #define	ISCSI_OP_SCSI_RSP		0x21
160*2314Smcneal #define	ISCSI_OP_SCSI_TASK_MGT_RSP	0x22
161*2314Smcneal #define	ISCSI_OP_LOGIN_RSP		0x23
162*2314Smcneal #define	ISCSI_OP_TEXT_RSP		0x24
163*2314Smcneal #define	ISCSI_OP_SCSI_DATA_RSP		0x25
164*2314Smcneal #define	ISCSI_OP_LOGOUT_RSP		0x26
165*2314Smcneal #define	ISCSI_OP_RTT_RSP		0x31
166*2314Smcneal #define	ISCSI_OP_ASYNC_EVENT		0x32
167*2314Smcneal #define	ISCSI_OP_REJECT_MSG		0x3f
168*2314Smcneal 
169*2314Smcneal 
170*2314Smcneal /* SCSI Command Header */
171*2314Smcneal typedef struct _iscsi_scsi_cmd_hdr {
172*2314Smcneal 	uint8_t opcode;
173*2314Smcneal 	uint8_t flags;
174*2314Smcneal 	uint8_t rsvd[2];
175*2314Smcneal 	uint8_t hlength;
176*2314Smcneal 	uint8_t dlength[3];
177*2314Smcneal 	uint8_t lun[8];
178*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
179*2314Smcneal 	uint32_t data_length;
180*2314Smcneal 	uint32_t cmdsn;
181*2314Smcneal 	uint32_t expstatsn;
182*2314Smcneal 	uint8_t scb[16];	/* SCSI Command Block */
183*2314Smcneal 	/*
184*2314Smcneal 	 * Additional Data (Command Dependent)
185*2314Smcneal 	 */
186*2314Smcneal } iscsi_scsi_cmd_hdr_t;
187*2314Smcneal 
188*2314Smcneal /* Command PDU flags */
189*2314Smcneal #define	ISCSI_FLAG_CMD_READ		0x40
190*2314Smcneal #define	ISCSI_FLAG_CMD_WRITE		0x20
191*2314Smcneal #define	ISCSI_FLAG_CMD_ATTR_MASK	0x07	/* 3 bits */
192*2314Smcneal 
193*2314Smcneal /* SCSI Command Attribute values */
194*2314Smcneal #define	ISCSI_ATTR_UNTAGGED		0
195*2314Smcneal #define	ISCSI_ATTR_SIMPLE		1
196*2314Smcneal #define	ISCSI_ATTR_ORDERED		2
197*2314Smcneal #define	ISCSI_ATTR_HEAD_OF_QUEUE	3
198*2314Smcneal #define	ISCSI_ATTR_ACA			4
199*2314Smcneal 
200*2314Smcneal 
201*2314Smcneal /* SCSI Response Header */
202*2314Smcneal typedef struct _iscsi_scsi_rsp_hdr {
203*2314Smcneal 	uint8_t opcode;
204*2314Smcneal 	uint8_t flags;
205*2314Smcneal 	uint8_t response;
206*2314Smcneal 	uint8_t cmd_status;
207*2314Smcneal 	uint8_t hlength;
208*2314Smcneal 	uint8_t dlength[3];
209*2314Smcneal 	uint8_t rsvd[8];
210*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
211*2314Smcneal 	uint32_t rsvd1;
212*2314Smcneal 	uint32_t statsn;
213*2314Smcneal 	uint32_t expcmdsn;
214*2314Smcneal 	uint32_t maxcmdsn;
215*2314Smcneal 	uint32_t expdatasn;
216*2314Smcneal 	uint32_t bi_residual_count;
217*2314Smcneal 	uint32_t residual_count;
218*2314Smcneal 	/*
219*2314Smcneal 	 * Response or Sense Data (optional)
220*2314Smcneal 	 */
221*2314Smcneal } iscsi_scsi_rsp_hdr_t;
222*2314Smcneal 
223*2314Smcneal /* 10.2.2.3 - Extended CDB Additional Header Segment */
224*2314Smcneal 
225*2314Smcneal typedef struct _iscsi_addl_hdr {
226*2314Smcneal 	iscsi_scsi_cmd_hdr_t ahs_isch;
227*2314Smcneal 	uint8_t ahs_hlen_hi;
228*2314Smcneal 	uint8_t ahs_hlen_lo;
229*2314Smcneal 	uint8_t ahs_key;
230*2314Smcneal 	uint8_t ahs_resv;
231*2314Smcneal 	uint8_t ahs_extscb[4];
232*2314Smcneal } iscsi_addl_hdr_t;
233*2314Smcneal 
234*2314Smcneal /* Command Response PDU flags */
235*2314Smcneal #define	ISCSI_FLAG_CMD_BIDI_OVERFLOW	0x10
236*2314Smcneal #define	ISCSI_FLAG_CMD_BIDI_UNDERFLOW	0x08
237*2314Smcneal #define	ISCSI_FLAG_CMD_OVERFLOW		0x04
238*2314Smcneal #define	ISCSI_FLAG_CMD_UNDERFLOW	0x02
239*2314Smcneal 
240*2314Smcneal /* iSCSI Status values. Valid if Rsp Selector bit is not set */
241*2314Smcneal #define	ISCSI_STATUS_CMD_COMPLETED	0
242*2314Smcneal #define	ISCSI_STATUS_TARGET_FAILURE	1
243*2314Smcneal #define	ISCSI_STATUS_SUBSYS_FAILURE	2
244*2314Smcneal 
245*2314Smcneal 
246*2314Smcneal /* Asynchronous Event Header */
247*2314Smcneal typedef struct _iscsi_async_evt_hdr {
248*2314Smcneal 	uint8_t opcode;
249*2314Smcneal 	uint8_t flags;
250*2314Smcneal 	uint8_t rsvd2[2];
251*2314Smcneal 	uint8_t rsvd3;
252*2314Smcneal 	uint8_t dlength[3];
253*2314Smcneal 	uint8_t lun[8];
254*2314Smcneal 	uint8_t rsvd4[8];
255*2314Smcneal 	uint32_t statsn;
256*2314Smcneal 	uint32_t expcmdsn;
257*2314Smcneal 	uint32_t maxcmdsn;
258*2314Smcneal 	uint8_t async_event;
259*2314Smcneal 	uint8_t async_vcode;
260*2314Smcneal 	uint16_t param1;
261*2314Smcneal 	uint16_t param2;
262*2314Smcneal 	uint16_t param3;
263*2314Smcneal 	uint8_t rsvd5[4];
264*2314Smcneal } iscsi_async_evt_hdr_t;
265*2314Smcneal 
266*2314Smcneal /* iSCSI Event Indicator values */
267*2314Smcneal #define	ISCSI_ASYNC_EVENT_SCSI_EVENT			0
268*2314Smcneal #define	ISCSI_ASYNC_EVENT_REQUEST_LOGOUT		1
269*2314Smcneal #define	ISCSI_ASYNC_EVENT_DROPPING_CONNECTION		2
270*2314Smcneal #define	ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS	3
271*2314Smcneal #define	ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION		4
272*2314Smcneal #define	ISCSI_ASYNC_EVENT_VENDOR_SPECIFIC		255
273*2314Smcneal 
274*2314Smcneal 
275*2314Smcneal /* NOP-Out Message */
276*2314Smcneal typedef struct _iscsi_nop_out_hdr {
277*2314Smcneal 	uint8_t opcode;
278*2314Smcneal 	uint8_t flags;
279*2314Smcneal 	uint16_t rsvd2;
280*2314Smcneal 	uint8_t rsvd3;
281*2314Smcneal 	uint8_t dlength[3];
282*2314Smcneal 	uint8_t lun[8];
283*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
284*2314Smcneal 	uint32_t ttt;	/* Target Transfer Tag */
285*2314Smcneal 	uint32_t cmdsn;
286*2314Smcneal 	uint32_t expstatsn;
287*2314Smcneal 	uint8_t rsvd4[16];
288*2314Smcneal } iscsi_nop_out_hdr_t;
289*2314Smcneal 
290*2314Smcneal 
291*2314Smcneal /* NOP-In Message */
292*2314Smcneal typedef struct _iscsi_nop_in_hdr {
293*2314Smcneal 	uint8_t opcode;
294*2314Smcneal 	uint8_t flags;
295*2314Smcneal 	uint16_t rsvd2;
296*2314Smcneal 	uint8_t rsvd3;
297*2314Smcneal 	uint8_t dlength[3];
298*2314Smcneal 	uint8_t lun[8];
299*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
300*2314Smcneal 	uint32_t ttt;	/* Target Transfer Tag */
301*2314Smcneal 	uint32_t statsn;
302*2314Smcneal 	uint32_t expcmdsn;
303*2314Smcneal 	uint32_t maxcmdsn;
304*2314Smcneal 	uint8_t rsvd4[12];
305*2314Smcneal } iscsi_nop_in_hdr_t;
306*2314Smcneal 
307*2314Smcneal /* SCSI Task Management Message Header */
308*2314Smcneal typedef struct _iscsi_scsi_task_mgt_hdr {
309*2314Smcneal 	uint8_t opcode;
310*2314Smcneal 	uint8_t function;
311*2314Smcneal 	uint8_t rsvd1[2];
312*2314Smcneal 	uint8_t hlength;
313*2314Smcneal 	uint8_t dlength[3];
314*2314Smcneal 	uint8_t lun[8];
315*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
316*2314Smcneal 	uint32_t rtt;	/* Reference Task Tag */
317*2314Smcneal 	uint32_t cmdsn;
318*2314Smcneal 	uint32_t expstatsn;
319*2314Smcneal 	uint32_t refcmdsn;
320*2314Smcneal 	uint32_t expdatasn;
321*2314Smcneal 	uint8_t rsvd2[8];
322*2314Smcneal } iscsi_scsi_task_mgt_hdr_t;
323*2314Smcneal 
324*2314Smcneal #define	ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK  0x7F
325*2314Smcneal 
326*2314Smcneal /* Function values */
327*2314Smcneal #define	ISCSI_TM_FUNC_ABORT_TASK		1
328*2314Smcneal #define	ISCSI_TM_FUNC_ABORT_TASK_SET		2
329*2314Smcneal #define	ISCSI_TM_FUNC_CLEAR_ACA			3
330*2314Smcneal #define	ISCSI_TM_FUNC_CLEAR_TASK_SET		4
331*2314Smcneal #define	ISCSI_TM_FUNC_LOGICAL_UNIT_RESET	5
332*2314Smcneal #define	ISCSI_TM_FUNC_TARGET_WARM_RESET		6
333*2314Smcneal #define	ISCSI_TM_FUNC_TARGET_COLD_RESET		7
334*2314Smcneal #define	ISCSI_TM_FUNC_TASK_REASSIGN		8
335*2314Smcneal 
336*2314Smcneal 
337*2314Smcneal /* SCSI Task Management Response Header */
338*2314Smcneal typedef struct _iscsi_scsi_task_mgt_rsp_hdr {
339*2314Smcneal 	uint8_t opcode;
340*2314Smcneal 	uint8_t flags;
341*2314Smcneal 	uint8_t response;	/* see Response values below */
342*2314Smcneal 	uint8_t qualifier;
343*2314Smcneal 	uint8_t hlength;
344*2314Smcneal 	uint8_t dlength[3];
345*2314Smcneal 	uint8_t rsvd2[8];
346*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
347*2314Smcneal 	uint32_t rtt;	/* Reference Task Tag */
348*2314Smcneal 	uint32_t statsn;
349*2314Smcneal 	uint32_t expcmdsn;
350*2314Smcneal 	uint32_t maxcmdsn;
351*2314Smcneal 	uint8_t rsvd3[12];
352*2314Smcneal } iscsi_scsi_task_mgt_rsp_hdr_t;
353*2314Smcneal 
354*2314Smcneal 
355*2314Smcneal /* Response values */
356*2314Smcneal #define	SCSI_TCP_TM_RESP_COMPLETE	0x00
357*2314Smcneal #define	SCSI_TCP_TM_RESP_NO_TASK	0x01
358*2314Smcneal #define	SCSI_TCP_TM_RESP_NO_LUN		0x02
359*2314Smcneal #define	SCSI_TCP_TM_RESP_TASK_ALLEGIANT	0x03
360*2314Smcneal #define	SCSI_TCP_TM_RESP_NO_FAILOVER	0x04
361*2314Smcneal #define	SCSI_TCP_TM_RESP_IN_PRGRESS	0x05
362*2314Smcneal #define	SCSI_TCP_TM_RESP_REJECTED	0xff
363*2314Smcneal 
364*2314Smcneal /* Ready To Transfer Header */
365*2314Smcneal typedef struct _iscsi_rtt_hdr {
366*2314Smcneal 	uint8_t opcode;
367*2314Smcneal 	uint8_t flags;
368*2314Smcneal 	uint8_t rsvd2[2];
369*2314Smcneal 	uint8_t rsvd3[12];
370*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
371*2314Smcneal 	uint32_t ttt;	/* Target Transfer Tag */
372*2314Smcneal 	uint32_t statsn;
373*2314Smcneal 	uint32_t expcmdsn;
374*2314Smcneal 	uint32_t maxcmdsn;
375*2314Smcneal 	uint32_t rttsn;
376*2314Smcneal 	uint32_t data_offset;
377*2314Smcneal 	uint32_t data_length;
378*2314Smcneal } iscsi_rtt_hdr_t;
379*2314Smcneal 
380*2314Smcneal 
381*2314Smcneal /* SCSI Data Hdr */
382*2314Smcneal typedef struct _iscsi_data_hdr {
383*2314Smcneal 	uint8_t opcode;
384*2314Smcneal 	uint8_t flags;
385*2314Smcneal 	uint8_t rsvd2[2];
386*2314Smcneal 	uint8_t rsvd3;
387*2314Smcneal 	uint8_t dlength[3];
388*2314Smcneal 	uint8_t lun[8];
389*2314Smcneal 	uint32_t itt;
390*2314Smcneal 	uint32_t ttt;
391*2314Smcneal 	uint32_t rsvd4;
392*2314Smcneal 	uint32_t expstatsn;
393*2314Smcneal 	uint32_t rsvd5;
394*2314Smcneal 	uint32_t datasn;
395*2314Smcneal 	uint32_t offset;
396*2314Smcneal 	uint32_t rsvd6;
397*2314Smcneal 	/*
398*2314Smcneal 	 * Payload
399*2314Smcneal 	 */
400*2314Smcneal } iscsi_data_hdr_t;
401*2314Smcneal 
402*2314Smcneal /* SCSI Data Response Hdr */
403*2314Smcneal typedef struct _iscsi_data_rsp_hdr {
404*2314Smcneal 	uint8_t opcode;
405*2314Smcneal 	uint8_t flags;
406*2314Smcneal 	uint8_t rsvd2;
407*2314Smcneal 	uint8_t cmd_status;
408*2314Smcneal 	uint8_t hlength;
409*2314Smcneal 	uint8_t dlength[3];
410*2314Smcneal 	uint8_t lun[8];
411*2314Smcneal 	uint32_t itt;
412*2314Smcneal 	uint32_t ttt;
413*2314Smcneal 	uint32_t statsn;
414*2314Smcneal 	uint32_t expcmdsn;
415*2314Smcneal 	uint32_t maxcmdsn;
416*2314Smcneal 	uint32_t datasn;
417*2314Smcneal 	uint32_t offset;
418*2314Smcneal 	uint32_t residual_count;
419*2314Smcneal } iscsi_data_rsp_hdr_t;
420*2314Smcneal 
421*2314Smcneal /* Data Response PDU flags */
422*2314Smcneal #define	ISCSI_FLAG_DATA_ACK		0x40
423*2314Smcneal #define	ISCSI_FLAG_DATA_OVERFLOW	0x04
424*2314Smcneal #define	ISCSI_FLAG_DATA_UNDERFLOW	0x02
425*2314Smcneal #define	ISCSI_FLAG_DATA_STATUS		0x01
426*2314Smcneal 
427*2314Smcneal 
428*2314Smcneal /* Text Header */
429*2314Smcneal typedef struct _iscsi_text_hdr {
430*2314Smcneal 	uint8_t opcode;
431*2314Smcneal 	uint8_t flags;
432*2314Smcneal 	uint8_t rsvd2[2];
433*2314Smcneal 	uint8_t hlength;
434*2314Smcneal 	uint8_t dlength[3];
435*2314Smcneal 	uint8_t rsvd4[8];
436*2314Smcneal 	uint32_t itt;
437*2314Smcneal 	uint32_t ttt;
438*2314Smcneal 	uint32_t cmdsn;
439*2314Smcneal 	uint32_t expstatsn;
440*2314Smcneal 	uint8_t rsvd5[16];
441*2314Smcneal 	/*
442*2314Smcneal 	 * Text - key=value pairs
443*2314Smcneal 	 */
444*2314Smcneal } iscsi_text_hdr_t;
445*2314Smcneal 
446*2314Smcneal #define	ISCSI_FLAG_TEXT_CONTINUE	0x40
447*2314Smcneal 
448*2314Smcneal /* Text Response Header */
449*2314Smcneal typedef struct _iscsi_text_rsp_hdr {
450*2314Smcneal 	uint8_t opcode;
451*2314Smcneal 	uint8_t flags;
452*2314Smcneal 	uint8_t rsvd2[2];
453*2314Smcneal 	uint8_t hlength;
454*2314Smcneal 	uint8_t dlength[3];
455*2314Smcneal 	uint8_t rsvd4[8];
456*2314Smcneal 	uint32_t itt;
457*2314Smcneal 	uint32_t ttt;
458*2314Smcneal 	uint32_t statsn;
459*2314Smcneal 	uint32_t expcmdsn;
460*2314Smcneal 	uint32_t maxcmdsn;
461*2314Smcneal 	uint8_t rsvd5[12];
462*2314Smcneal 	/*
463*2314Smcneal 	 * Text Response - key:value pairs
464*2314Smcneal 	 */
465*2314Smcneal } iscsi_text_rsp_hdr_t;
466*2314Smcneal 
467*2314Smcneal /* Login Header */
468*2314Smcneal typedef struct _iscsi_login_hdr {
469*2314Smcneal 	uint8_t opcode;
470*2314Smcneal 	uint8_t flags;
471*2314Smcneal 	uint8_t max_version;	/* Max. version supported */
472*2314Smcneal 	uint8_t min_version;	/* Min. version supported */
473*2314Smcneal 	uint8_t hlength;
474*2314Smcneal 	uint8_t dlength[3];
475*2314Smcneal 	uint8_t isid[6];	/* Initiator Session ID */
476*2314Smcneal 	uint16_t tsid;	/* Target Session ID */
477*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
478*2314Smcneal 	uint16_t cid;
479*2314Smcneal 	uint16_t rsvd3;
480*2314Smcneal 	uint32_t cmdsn;
481*2314Smcneal 	uint32_t expstatsn;
482*2314Smcneal 	uint8_t rsvd5[16];
483*2314Smcneal } iscsi_login_hdr_t;
484*2314Smcneal 
485*2314Smcneal /* Login PDU flags */
486*2314Smcneal #define	ISCSI_FLAG_LOGIN_TRANSIT		0x80
487*2314Smcneal #define	ISCSI_FLAG_LOGIN_CONTINUE		0x40
488*2314Smcneal #define	ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK	0x0C	/* 2 bits */
489*2314Smcneal #define	ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK	0x03	/* 2 bits */
490*2314Smcneal 
491*2314Smcneal #define	ISCSI_LOGIN_CURRENT_STAGE(flags) \
492*2314Smcneal 	((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2)
493*2314Smcneal #define	ISCSI_LOGIN_NEXT_STAGE(flags) \
494*2314Smcneal 	(flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK)
495*2314Smcneal 
496*2314Smcneal 
497*2314Smcneal /* Login Response Header */
498*2314Smcneal typedef struct _iscsi_login_rsp_hdr {
499*2314Smcneal 	uint8_t opcode;
500*2314Smcneal 	uint8_t flags;
501*2314Smcneal 	uint8_t max_version;	/* Max. version supported */
502*2314Smcneal 	uint8_t active_version;	/* Active version */
503*2314Smcneal 	uint8_t hlength;
504*2314Smcneal 	uint8_t dlength[3];
505*2314Smcneal 	uint8_t isid[6];	/* Initiator Session ID */
506*2314Smcneal 	uint16_t tsid;	/* Target Session ID */
507*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
508*2314Smcneal 	uint32_t rsvd3;
509*2314Smcneal 	uint32_t statsn;
510*2314Smcneal 	uint32_t expcmdsn;
511*2314Smcneal 	uint32_t maxcmdsn;
512*2314Smcneal 	uint8_t status_class;	/* see Login RSP ststus classes below */
513*2314Smcneal 	uint8_t status_detail;	/* see Login RSP Status details below */
514*2314Smcneal 	uint8_t rsvd4[10];
515*2314Smcneal } iscsi_login_rsp_hdr_t;
516*2314Smcneal 
517*2314Smcneal /* Login stage (phase) codes for CSG, NSG */
518*2314Smcneal #define	ISCSI_SECURITY_NEGOTIATION_STAGE	0
519*2314Smcneal #define	ISCSI_OP_PARMS_NEGOTIATION_STAGE	1
520*2314Smcneal #define	ISCSI_FULL_FEATURE_PHASE		3
521*2314Smcneal 
522*2314Smcneal /* Login Status response classes */
523*2314Smcneal #define	ISCSI_STATUS_CLASS_SUCCESS		0x00
524*2314Smcneal #define	ISCSI_STATUS_CLASS_REDIRECT		0x01
525*2314Smcneal #define	ISCSI_STATUS_CLASS_INITIATOR_ERR	0x02
526*2314Smcneal #define	ISCSI_STATUS_CLASS_TARGET_ERR		0x03
527*2314Smcneal 
528*2314Smcneal /* Login Status response detail codes */
529*2314Smcneal /* Class-0 (Success) */
530*2314Smcneal #define	ISCSI_LOGIN_STATUS_ACCEPT		0x00
531*2314Smcneal 
532*2314Smcneal /* Class-1 (Redirection) */
533*2314Smcneal #define	ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP	0x01
534*2314Smcneal #define	ISCSI_LOGIN_STATUS_TGT_MOVED_PERM	0x02
535*2314Smcneal 
536*2314Smcneal /* Class-2 (Initiator Error) */
537*2314Smcneal #define	ISCSI_LOGIN_STATUS_INIT_ERR		0x00
538*2314Smcneal #define	ISCSI_LOGIN_STATUS_AUTH_FAILED		0x01
539*2314Smcneal #define	ISCSI_LOGIN_STATUS_TGT_FORBIDDEN	0x02
540*2314Smcneal #define	ISCSI_LOGIN_STATUS_TGT_NOT_FOUND	0x03
541*2314Smcneal #define	ISCSI_LOGIN_STATUS_TGT_REMOVED		0x04
542*2314Smcneal #define	ISCSI_LOGIN_STATUS_NO_VERSION		0x05
543*2314Smcneal #define	ISCSI_LOGIN_STATUS_ISID_ERROR		0x06
544*2314Smcneal #define	ISCSI_LOGIN_STATUS_MISSING_FIELDS	0x07
545*2314Smcneal #define	ISCSI_LOGIN_STATUS_CONN_ADD_FAILED	0x08
546*2314Smcneal #define	ISCSI_LOGIN_STATUS_NO_SESSION_TYPE	0x09
547*2314Smcneal #define	ISCSI_LOGIN_STATUS_NO_SESSION		0x0a
548*2314Smcneal #define	ISCSI_LOGIN_STATUS_INVALID_REQUEST	0x0b
549*2314Smcneal 
550*2314Smcneal /* Class-3 (Target Error) */
551*2314Smcneal #define	ISCSI_LOGIN_STATUS_TARGET_ERROR		0x00
552*2314Smcneal #define	ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE	0x01
553*2314Smcneal #define	ISCSI_LOGIN_STATUS_NO_RESOURCES		0x02
554*2314Smcneal 
555*2314Smcneal /* Logout Header */
556*2314Smcneal typedef struct _iscsi_logout_hdr {
557*2314Smcneal 	uint8_t opcode;
558*2314Smcneal 	uint8_t flags;
559*2314Smcneal 	uint8_t rsvd1[2];
560*2314Smcneal 	uint8_t hlength;
561*2314Smcneal 	uint8_t dlength[3];
562*2314Smcneal 	uint8_t rsvd2[8];
563*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
564*2314Smcneal 	uint16_t cid;
565*2314Smcneal 	uint8_t rsvd3[2];
566*2314Smcneal 	uint32_t cmdsn;
567*2314Smcneal 	uint32_t expstatsn;
568*2314Smcneal 	uint8_t rsvd4[16];
569*2314Smcneal } iscsi_logout_hdr_t;
570*2314Smcneal 
571*2314Smcneal /* Logout PDU flags */
572*2314Smcneal #define	ISCSI_FLAG_LOGOUT_REASON_MASK		0x7F
573*2314Smcneal 
574*2314Smcneal /* logout reason_code values */
575*2314Smcneal 
576*2314Smcneal #define	ISCSI_LOGOUT_REASON_CLOSE_SESSION	0
577*2314Smcneal #define	ISCSI_LOGOUT_REASON_CLOSE_CONNECTION	1
578*2314Smcneal #define	ISCSI_LOGOUT_REASON_RECOVERY		2
579*2314Smcneal #define	ISCSI_LOGOUT_REASON_AEN_REQUEST		3
580*2314Smcneal 
581*2314Smcneal /* Logout Response Header */
582*2314Smcneal typedef struct _iscsi_logout_rsp_hdr {
583*2314Smcneal 	uint8_t opcode;
584*2314Smcneal 	uint8_t flags;
585*2314Smcneal 	uint8_t response;	/* see Logout response values below */
586*2314Smcneal 	uint8_t rsvd2;
587*2314Smcneal 	uint8_t hlength;
588*2314Smcneal 	uint8_t dlength[3];
589*2314Smcneal 	uint8_t rsvd3[8];
590*2314Smcneal 	uint32_t itt;	/* Initiator Task Tag */
591*2314Smcneal 	uint32_t rsvd4;
592*2314Smcneal 	uint32_t statsn;
593*2314Smcneal 	uint32_t expcmdsn;
594*2314Smcneal 	uint32_t maxcmdsn;
595*2314Smcneal 	uint32_t rsvd5;
596*2314Smcneal 	uint16_t t2wait;
597*2314Smcneal 	uint16_t t2retain;
598*2314Smcneal 	uint32_t rsvd6;
599*2314Smcneal } iscsi_logout_rsp_hdr_t;
600*2314Smcneal 
601*2314Smcneal /* logout response status values */
602*2314Smcneal 
603*2314Smcneal #define	ISCSI_LOGOUT_SUCCESS		  0
604*2314Smcneal #define	ISCSI_LOGOUT_CID_NOT_FOUND	  1
605*2314Smcneal #define	ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2
606*2314Smcneal #define	ISCSI_LOGOUT_CLEANUP_FAILED	  3
607*2314Smcneal 
608*2314Smcneal 
609*2314Smcneal /* SNACK Header */
610*2314Smcneal typedef struct _iscsi_snack_hdr {
611*2314Smcneal 	uint8_t opcode;
612*2314Smcneal 	uint8_t flags;
613*2314Smcneal 	uint8_t rsvd2[14];
614*2314Smcneal 	uint32_t itt;
615*2314Smcneal 	uint32_t begrun;
616*2314Smcneal 	uint32_t runlength;
617*2314Smcneal 	uint32_t expstatsn;
618*2314Smcneal 	uint32_t rsvd3;
619*2314Smcneal 	uint32_t expdatasn;
620*2314Smcneal 	uint8_t rsvd6[8];
621*2314Smcneal } iscsi_snack_hdr_t;
622*2314Smcneal 
623*2314Smcneal /* SNACK PDU flags */
624*2314Smcneal #define	ISCSI_FLAG_SNACK_TYPE_MASK	0x0F	/* 4 bits */
625*2314Smcneal 
626*2314Smcneal /* Reject Message Header */
627*2314Smcneal typedef struct _iscsi_reject_rsp_hdr {
628*2314Smcneal 	uint8_t opcode;
629*2314Smcneal 	uint8_t flags;
630*2314Smcneal 	uint8_t reason;
631*2314Smcneal 	uint8_t rsvd2;
632*2314Smcneal 	uint8_t rsvd3;
633*2314Smcneal 	uint8_t dlength[3];
634*2314Smcneal 	uint8_t rsvd4[16];
635*2314Smcneal 	uint32_t statsn;
636*2314Smcneal 	uint32_t expcmdsn;
637*2314Smcneal 	uint32_t maxcmdsn;
638*2314Smcneal 	uint32_t datasn;
639*2314Smcneal 	uint8_t rsvd5[8];
640*2314Smcneal 	/*
641*2314Smcneal 	 * Text - Rejected hdr
642*2314Smcneal 	 */
643*2314Smcneal } iscsi_reject_rsp_hdr_t;
644*2314Smcneal 
645*2314Smcneal /* Reason for Reject */
646*2314Smcneal #define	ISCSI_REJECT_CMD_BEFORE_LOGIN		1
647*2314Smcneal #define	ISCSI_REJECT_DATA_DIGEST_ERROR		2
648*2314Smcneal #define	ISCSI_REJECT_SNACK_REJECT		3
649*2314Smcneal #define	ISCSI_REJECT_PROTOCOL_ERROR		4
650*2314Smcneal #define	ISCSI_REJECT_CMD_NOT_SUPPORTED		5
651*2314Smcneal #define	ISCSI_REJECT_IMM_CMD_REJECT		6
652*2314Smcneal #define	ISCSI_REJECT_TASK_IN_PROGRESS		7
653*2314Smcneal #define	ISCSI_REJECT_INVALID_DATA_ACK		8
654*2314Smcneal #define	ISCSI_REJECT_INVALID_PDU_FIELD		9
655*2314Smcneal #define	ISCSI_REJECT_LONG_OPERATION_REJECT	10
656*2314Smcneal #define	ISCSI_REJECT_NEGOTIATION_RESET		11
657*2314Smcneal #define	ISCSI_REJECT_WAITING_FOR_LOGOUT		12
658*2314Smcneal 
659*2314Smcneal /* Defaults as defined by the iSCSI specification */
660*2314Smcneal #define	ISCSI_DEFAULT_IMMEDIATE_DATA		TRUE
661*2314Smcneal #define	ISCSI_DEFAULT_INITIALR2T		TRUE
662*2314Smcneal #define	ISCSI_DEFAULT_FIRST_BURST_LENGTH	(64 * 1024) /* 64kbytes */
663*2314Smcneal #define	ISCSI_DEFAULT_MAX_BURST_LENGTH		(256 * 1024) /* 256kbytes */
664*2314Smcneal #define	ISCSI_DEFAULT_DATA_PDU_IN_ORDER		TRUE
665*2314Smcneal #define	ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER	TRUE
666*2314Smcneal #define	ISCSI_DEFAULT_TIME_TO_WAIT		2 /* 2 seconds */
667*2314Smcneal #define	ISCSI_DEFAULT_TIME_TO_RETAIN		20 /* 20 seconds */
668*2314Smcneal #define	ISCSI_DEFAULT_HEADER_DIGEST		ISCSI_DIGEST_NONE
669*2314Smcneal #define	ISCSI_DEFAULT_DATA_DIGEST		ISCSI_DIGEST_NONE
670*2314Smcneal #define	ISCSI_DEFAULT_MAX_RECV_SEG_LEN		(64 * 1024)
671*2314Smcneal #define	ISCSI_DEFAULT_MAX_XMIT_SEG_LEN		(8 * 1024)
672*2314Smcneal #define	ISCSI_DEFAULT_MAX_CONNECTIONS		1
673*2314Smcneal #define	ISCSI_DEFAULT_MAX_OUT_R2T		1
674*2314Smcneal #define	ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL	0
675*2314Smcneal #define	ISCSI_DEFAULT_IFMARKER			FALSE
676*2314Smcneal #define	ISCSI_DEFAULT_OFMARKER			FALSE
677*2314Smcneal 
678*2314Smcneal /*
679*2314Smcneal  * Maximum values from the iSCSI specification
680*2314Smcneal  */
681*2314Smcneal #define	ISCSI_MAX_HEADER_DIGEST			3
682*2314Smcneal #define	ISCSI_MAX_DATA_DIGEST			3
683*2314Smcneal #define	ISCSI_MAX_TIME2RETAIN			3600
684*2314Smcneal #define	ISCSI_MAX_TIME2WAIT			3600
685*2314Smcneal #define	ISCSI_MAX_ERROR_RECOVERY_LEVEL		2
686*2314Smcneal #define	ISCSI_MAX_FIRST_BURST_LENGTH		0xffffff
687*2314Smcneal #define	ISCSI_MAX_BURST_LENGTH			0xffffff
688*2314Smcneal #define	ISCSI_MAX_CONNECTIONS			65535
689*2314Smcneal #define	ISCSI_MAX_OUTSTANDING_R2T		65535
690*2314Smcneal #define	ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH	0xffffff
691*2314Smcneal #define	ISCSI_MAX_TPGT_VALUE			65535 /* 16 bit numeric */
692*2314Smcneal 
693*2314Smcneal /*
694*2314Smcneal  * iqn and eui name prefixes and related defines
695*2314Smcneal  */
696*2314Smcneal #define	ISCSI_IQN_NAME_PREFIX			"iqn"
697*2314Smcneal #define	ISCSI_EUI_NAME_PREFIX			"eui"
698*2314Smcneal #define	ISCSI_EUI_NAME_LEN			20 /* eui. plus 16 octets */
699*2314Smcneal 
700*2314Smcneal #ifdef __cplusplus
701*2314Smcneal }
702*2314Smcneal #endif
703*2314Smcneal 
704*2314Smcneal #endif /* _ISCSI_PROTOCOL_H */
705