1171568Sscottl/*-
2211095Sdes * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il>
3171568Sscottl * All rights reserved.
4171568Sscottl *
5171568Sscottl * Redistribution and use in source and binary forms, with or without
6171568Sscottl * modification, are permitted provided that the following conditions
7171568Sscottl * are met:
8171568Sscottl * 1. Redistributions of source code must retain the above copyright
9171568Sscottl *    notice, this list of conditions and the following disclaimer.
10171568Sscottl * 2. Redistributions in binary form must reproduce the above copyright
11171568Sscottl *    notice, this list of conditions and the following disclaimer in the
12171568Sscottl *    documentation and/or other materials provided with the distribution.
13171568Sscottl *
14171568Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15171568Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16171568Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17171568Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18171568Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19171568Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20171568Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21171568Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22171568Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23171568Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24171568Sscottl * SUCH DAMAGE.
25171568Sscottl *
26171568Sscottl * $FreeBSD$
27171568Sscottl */
28171568Sscottl/*
29211095Sdes | $Id: iscsi.h 743 2009-08-08 10:54:53Z danny $
30171568Sscottl */
31171568Sscottl#define	TRUE	1
32171568Sscottl#define FALSE	0
33171568Sscottl#ifndef _KERNEL
34171568Sscottltypedef int boolean_t;
35171568Sscottl#endif
36171568Sscottl
37171568Sscottl#include <cam/cam.h>
38171568Sscottl
39171568Sscottl#define ISCSIDEV	"iscsi"
40211095Sdes#define ISCSI_MAX_TARGETS	64
41171568Sscottl/*
42171568Sscottl | iSCSI commands
43171568Sscottl */
44171568Sscottl
45171568Sscottl/*
46171568Sscottl | Initiator Opcodes:
47171568Sscottl */
48171568Sscottl#define ISCSI_NOP_OUT		0x00
49171568Sscottl#define ISCSI_SCSI_CMD		0x01
50171568Sscottl#define ISCSI_TASK_CMD		0x02
51171568Sscottl#define ISCSI_LOGIN_CMD		0x03
52171568Sscottl#define ISCSI_TEXT_CMD		0x04
53171568Sscottl#define ISCSI_WRITE_DATA	0x05
54171568Sscottl#define ISCSI_LOGOUT_CMD	0x06
55171568Sscottl#define ISCSI_SNACK		0x10
56171568Sscottl/*
57171568Sscottl | Target Opcodes:
58171568Sscottl */
59171568Sscottl#define ISCSI_NOP_IN		0x20
60171568Sscottl#define ISCSI_SCSI_RSP		0x21
61171568Sscottl#define ISCSI_TASK_RSP		0x22
62171568Sscottl#define ISCSI_LOGIN_RSP		0x23
63171568Sscottl#define ISCSI_TEXT_RSP		0x24
64171568Sscottl#define ISCSI_READ_DATA		0x25
65171568Sscottl#define ISCSI_LOGOUT_RSP	0x26
66171568Sscottl#define ISCSI_R2T		0x31
67171568Sscottl#define ISCSI_ASYNC		0x32
68171568Sscottl#define ISCSI_REJECT		0x3f
69171568Sscottl/*
70171568Sscottl | PDU stuff
71171568Sscottl */
72171568Sscottl/*
73171568Sscottl | BHS Basic Header Segment
74171568Sscottl */
75171568Sscottltypedef struct bhs {
76171568Sscottl     // the order is network byte order!
77171568Sscottl     u_char	opcode:6;
78171568Sscottl     u_char	I:1;
79171568Sscottl     u_char	_:1;
80171568Sscottl     u_char	__:7;
81171568Sscottl     u_char	F:1;			// Final bit
82171568Sscottl     u_char	___[2];
83171568Sscottl
84171568Sscottl     u_int	AHSLength:8;		// in 4byte words
85171568Sscottl     u_int	DSLength:24;		// in bytes
86171568Sscottl
87171568Sscottl     u_int	LUN[2];			// or Opcode-specific fields
88171568Sscottl     u_int	itt;
89171568Sscottl     u_int	OpcodeSpecificFields[7];
90171568Sscottl#define	CmdSN		OpcodeSpecificFields[1]
91171568Sscottl#define	ExpStSN		OpcodeSpecificFields[2]
92171568Sscottl#define MaxCmdSN	OpcodeSpecificFields[3]
93171568Sscottl} bhs_t;
94171568Sscottl
95171568Sscottltypedef struct ahs {
96171568Sscottl     u_int	len:16;
97171568Sscottl     u_int	type:8;
98171568Sscottl     u_int	spec:8;
99171568Sscottl     char	data[0];
100171568Sscottl} ahs_t;
101171568Sscottl
102171568Sscottltypedef struct {
103171568Sscottl     // Sequence Numbers
104171568Sscottl     // (computers were invented to count, right?)
105171568Sscottl     int	cmd;
106171568Sscottl     int	expcmd;
107171568Sscottl     int	maxcmd;
108171568Sscottl} req_sn_t;
109171568Sscottl
110171568Sscottltypedef struct {
111171568Sscottl     // Sequence Numbers
112171568Sscottl     // (computers were invented to count, right?)
113171568Sscottl     int	stat;
114171568Sscottl     int	expcmd;
115171568Sscottl     int	maxcmd;
116171568Sscottl} rsp_sn_t;
117171568Sscottl
118171568Sscottltypedef struct scsi_req {
119171568Sscottl     u_char	opcode:6; // 0x01
120171568Sscottl     u_char	I:1;
121171568Sscottl     u_char	_:1;
122171568Sscottl
123171568Sscottl     u_char	attr:3;
124171568Sscottl     u_char	_0:2;
125171568Sscottl     u_char	W:1;
126171568Sscottl     u_char	R:1;
127171568Sscottl     u_char	F:1;
128171568Sscottl#define		iSCSI_TASK_UNTAGGED	0
129171568Sscottl#define		iSCSI_TASK_SIMPLE	1
130171568Sscottl#define		iSCSI_TASK_ORDER	2
131171568Sscottl#define		iSCSI_TASK_HOFQ		3
132171568Sscottl#define		iSCSI_TASK_ACA		4
133171568Sscottl     char	_1[2];
134171568Sscottl     int	len;
135171568Sscottl     int	lun[2];
136171568Sscottl     int	itt;
137171568Sscottl     int	edtlen;		// expectect data transfere length
138171568Sscottl     int	cmdSN;
139171568Sscottl     int	extStatSN;
140171568Sscottl     int	cdb[4];
141171568Sscottl} scsi_req_t;
142171568Sscottl
143171568Sscottltypedef struct scsi_rsp {
144171568Sscottl     char	opcode;	// 0x21
145171568Sscottl     u_char	flag;
146171568Sscottl     u_char	response;
147171568Sscottl     u_char	status;
148171568Sscottl
149171568Sscottl     int	len;
150171568Sscottl     int	_[2];
151171568Sscottl     int	itt;
152171568Sscottl     int	stag;
153171568Sscottl     rsp_sn_t	sn;
154171568Sscottl     int	expdatasn;
155171568Sscottl     int	bdrcnt;	// bidirectional residual count
156171568Sscottl     int	rcnt;	// residual count
157171568Sscottl} scsi_rsp_t;
158171568Sscottl
159171568Sscottltypedef struct nop_out {
160171568Sscottl     // the order is network byte order!
161171568Sscottl     u_char	opcode:6;
162171568Sscottl     u_char	I:1;
163171568Sscottl     u_char	_:1;
164171568Sscottl     u_char	__:7;
165171568Sscottl     u_char	F:1;			// Final bit
166171568Sscottl     u_char	___[2];
167171568Sscottl
168171568Sscottl     u_int	len;
169171568Sscottl     u_int	lun[2];
170171568Sscottl     u_int	itt;
171171568Sscottl     u_int	ttt;
172171568Sscottl     req_sn_t	sn;
173171568Sscottl     u_int	mbz[3];
174171568Sscottl} nop_out_t;
175171568Sscottl
176171568Sscottltypedef struct nop_in {
177171568Sscottl     // the order is network byte order!
178171568Sscottl     u_char	opcode:6;
179171568Sscottl     u_char	I:1;
180171568Sscottl     u_char	_:1;
181171568Sscottl     u_char	__:7;
182171568Sscottl     u_char	F:1;			// Final bit
183171568Sscottl     u_char	___[2];
184171568Sscottl
185171568Sscottl     u_int	len;
186171568Sscottl     u_int	lun[2];
187171568Sscottl     u_int	itt;
188171568Sscottl     u_int	ttt;
189171568Sscottl     rsp_sn_t	sn;
190171568Sscottl     u_int	____[2];
191171568Sscottl
192171568Sscottl} nop_in_t;
193171568Sscottl
194171568Sscottltypedef struct r2t {
195171568Sscottl     u_char	opcode:6;
196171568Sscottl     u_char	I:1;
197171568Sscottl     u_char	_:1;
198171568Sscottl     u_char	__:7;
199171568Sscottl     u_char	F:1;			// Final bit
200171568Sscottl     u_char	___[2];
201171568Sscottl
202171568Sscottl     u_int	len;
203171568Sscottl     u_int	lun[2];
204171568Sscottl     u_int	itt;
205171568Sscottl     u_int	ttt;
206171568Sscottl     rsp_sn_t	sn;
207171568Sscottl     u_int	r2tSN;
208171568Sscottl     u_int	bo;
209171568Sscottl     u_int	ddtl;
210171568Sscottl} r2t_t;
211171568Sscottl
212171568Sscottltypedef struct data_out {
213171568Sscottl     u_char	opcode:6;
214171568Sscottl     u_char	I:1;
215171568Sscottl     u_char	_:1;
216171568Sscottl     u_char	__:7;
217171568Sscottl     u_char	F:1;			// Final bit
218171568Sscottl     u_char	___[2];
219171568Sscottl
220171568Sscottl     u_int	len;
221171568Sscottl     u_int	lun[2];
222171568Sscottl     u_int	itt;
223171568Sscottl     u_int	ttt;
224171568Sscottl     rsp_sn_t	sn;
225171568Sscottl     u_int	dsn;	// data seq. number
226171568Sscottl     u_int	bo;
227171568Sscottl     u_int	____;
228171568Sscottl} data_out_t;
229171568Sscottl
230171568Sscottltypedef struct data_in {
231171568Sscottl     u_char	opcode:6;
232171568Sscottl     u_char	I:1;
233171568Sscottl     u_char	_:1;
234171568Sscottl
235171568Sscottl     u_char	S:1;
236171568Sscottl     u_char	U:1;
237171568Sscottl     u_char	O:1;
238171568Sscottl     u_char	__:3;
239171568Sscottl     u_char	A:1;
240171568Sscottl     u_char	F:1;			// Final bit
241171568Sscottl     u_char	___[1];
242171568Sscottl     u_char	status;
243171568Sscottl
244171568Sscottl     u_int	len;
245171568Sscottl     u_int	lun[2];
246171568Sscottl     u_int	itt;
247171568Sscottl     u_int	ttt;
248171568Sscottl     rsp_sn_t	sn;
249171568Sscottl     u_int	dataSN;
250171568Sscottl     u_int	bo;
251171568Sscottl     u_int	____;
252171568Sscottl} data_in_t;
253171568Sscottl
254171568Sscottltypedef struct reject {
255171568Sscottl     u_char	opcode:6;
256171568Sscottl     u_char	_:2;
257171568Sscottl     u_char	F:1;
258171568Sscottl     u_char	__:7;
259171568Sscottl     u_char	reason;
260171568Sscottl     u_char	___;
261171568Sscottl
262171568Sscottl     u_int	len;
263171568Sscottl     u_int	____[2];
264171568Sscottl     u_int	tt[2];	// must be -1
265171568Sscottl     rsp_sn_t	sn;
266171568Sscottl     u_int	dataSN;	// or R2TSN or reserved
267171568Sscottl     u_int	_____[2];
268171568Sscottl} reject_t;
269171568Sscottl
270171568Sscottltypedef struct async {
271171568Sscottl     u_char	opcode:6;
272171568Sscottl     u_char	_:2;
273171568Sscottl     u_char	F:1;
274171568Sscottl     u_char	__:7;
275171568Sscottl     u_char	___[2];
276171568Sscottl
277171568Sscottl     u_int	len;
278171568Sscottl     u_int	lun[2];
279171568Sscottl     u_int	itt;	// must be -1
280171568Sscottl     u_int	____;
281171568Sscottl     rsp_sn_t	sn;
282171568Sscottl
283171568Sscottl     u_char	asyncEvent;
284171568Sscottl     u_char	asyncVCode;
285171568Sscottl     u_char	param1[2];
286171568Sscottl     u_char	param2[2];
287171568Sscottl     u_char	param3[2];
288171568Sscottl
289171568Sscottl     u_int	_____;
290171568Sscottl
291171568Sscottl} async_t;
292171568Sscottl
293185289Sscottltypedef struct login_req {
294185289Sscottl     char	cmd;	// 0x03
295185289Sscottl
296185289Sscottl     u_char	NSG:2;
297185289Sscottl     u_char	CSG:2;
298185289Sscottl     u_char	_:2;
299185289Sscottl     u_char	C:1;
300185289Sscottl     u_char	T:1;
301185289Sscottl
302185289Sscottl     char	v_max;
303185289Sscottl     char	v_min;
304185289Sscottl
305185289Sscottl     int	len;	// remapped via standard bhs
306185289Sscottl     char	isid[6];
307185289Sscottl     short	tsih;
308185289Sscottl     int	itt;	// Initiator Task Tag;
309185289Sscottl
310185289Sscottl     int	CID:16;
311185289Sscottl     int	rsv:16;
312185289Sscottl
313185289Sscottl     int	cmdSN;
314185289Sscottl     int	expStatSN;
315185289Sscottl     int	unused[4];
316185289Sscottl} login_req_t;
317185289Sscottl
318185289Sscottltypedef struct login_rsp {
319185289Sscottl     char	cmd;	// 0x23
320185289Sscottl     u_char	NSG:2;
321185289Sscottl     u_char	CSG:2;
322185289Sscottl     u_char	_1:2;
323185289Sscottl     u_char	C:1;
324185289Sscottl     u_char	T:1;
325185289Sscottl
326185289Sscottl     char	v_max;
327185289Sscottl     char	v_act;
328185289Sscottl
329185289Sscottl     int	len;	// remapped via standard bhs
330185289Sscottl     char	isid[6];
331185289Sscottl     short	tsih;
332185289Sscottl     int	itt;	// Initiator Task Tag;
333185289Sscottl     int	_2;
334185289Sscottl     rsp_sn_t	sn;
335185289Sscottl     int	status:16;
336185289Sscottl     int	_3:16;
337185289Sscottl     int	_4[2];
338185289Sscottl} login_rsp_t;
339185289Sscottl
340185289Sscottltypedef struct text_req {
341185289Sscottl     char	cmd;	// 0x04
342185289Sscottl
343185289Sscottl     u_char	_1:6;
344185289Sscottl     u_char	C:1;	// Continuation
345185289Sscottl     u_char	F:1;	// Final
346185289Sscottl     char	_2[2];
347185289Sscottl
348185289Sscottl     int	len;
349185289Sscottl     int	itt;		// Initiator Task Tag
350185289Sscottl     int	LUN[2];
351185289Sscottl     int	ttt;		// Target Transfer Tag
352185289Sscottl     int	cmdSN;
353185289Sscottl     int	expStatSN;
354185289Sscottl     int	unused[4];
355185289Sscottl} text_req_t;
356185289Sscottl
357185289Sscottltypedef struct logout_req {
358185289Sscottl     char	cmd;	// 0x06
359185289Sscottl     char	reason;	// 0 - close session
360185289Sscottl     			// 1 - close connection
361185289Sscottl     			// 2 - remove the connection for recovery
362185289Sscottl     char	_2[2];
363185289Sscottl
364185289Sscottl     int	len;
365185289Sscottl     int	_r[2];
366185289Sscottl     int	itt;	// Initiator Task Tag;
367185289Sscottl
368185289Sscottl     u_int	CID:16;
369185289Sscottl     u_int	rsv:16;
370185289Sscottl
371185289Sscottl     int	cmdSN;
372185289Sscottl     int	expStatSN;
373185289Sscottl     int	unused[4];
374185289Sscottl} logout_req_t;
375185289Sscottl
376185289Sscottltypedef struct logout_rsp {
377185289Sscottl     char	cmd;	// 0x26
378185289Sscottl     char	cbits;
379185289Sscottl     char	_1[2];
380185289Sscottl     int	len;
381185289Sscottl     int	_2[2];
382185289Sscottl     int	itt;
383185289Sscottl     int	_3;
384185289Sscottl     rsp_sn_t	sn;
385185289Sscottl     short	time2wait;
386185289Sscottl     short	time2retain;
387185289Sscottl     int	_4;
388185289Sscottl} logout_rsp_t;
389185289Sscottl
390171568Sscottlunion ipdu_u {
391171568Sscottl     bhs_t	bhs;
392171568Sscottl     scsi_req_t	scsi_req;
393171568Sscottl     scsi_rsp_t	scsi_rsp;
394171568Sscottl     nop_out_t	nop_out;
395171568Sscottl     nop_in_t	nop_in;
396171568Sscottl     r2t_t	r2t;
397171568Sscottl     data_out_t	data_out;
398171568Sscottl     data_in_t	data_in;
399171568Sscottl     reject_t	reject;
400171568Sscottl     async_t	async;
401171568Sscottl};
402171568Sscottl
403171568Sscottl/*
404171568Sscottl | Sequence Numbers
405171568Sscottl */
406171568Sscottltypedef struct {
407171568Sscottl     u_int	itt;
408171568Sscottl     u_int      cmd;
409171568Sscottl     u_int      expCmd;
410171568Sscottl     u_int      maxCmd;
411171568Sscottl     u_int      stat;
412171568Sscottl     u_int      expStat;
413171568Sscottl     u_int      data;
414171568Sscottl} sn_t;
415171568Sscottl
416171568Sscottl/*
417171568Sscottl | in-core version of a Protocol Data Unit
418171568Sscottl */
419171568Sscottltypedef struct {
420171568Sscottl     union ipdu_u	ipdu;
421211095Sdes     u_int		hdr_dig;	// header digest
422171568Sscottl
423211095Sdes     ahs_t		*ahs_addr;
424171568Sscottl     u_int		ahs_len;
425171568Sscottl     u_int		ahs_size;	// the allocated size
426171568Sscottl
427211095Sdes     u_char		*ds_addr;
428171568Sscottl     u_int		ds_len;
429171568Sscottl     u_int		ds_size;	// the allocated size
430171568Sscottl     u_int		ds_dig;		// data digest
431171568Sscottl} pdu_t;
432171568Sscottl
433171568Sscottltypedef struct opvals {
434171568Sscottl     int	port;
435171568Sscottl     int	tags;
436171568Sscottl     int	maxluns;
437171568Sscottl     int	sockbufsize;
438171568Sscottl
439171568Sscottl     int	maxConnections;
440171568Sscottl     int	maxRecvDataSegmentLength;
441171568Sscottl     int	maxXmitDataSegmentLength; // pseudo ...
442171568Sscottl     int	maxBurstLength;
443171568Sscottl     int	firstBurstLength;
444171568Sscottl     int	defaultTime2Wait;
445171568Sscottl     int	defaultTime2Retain;
446171568Sscottl     int	maxOutstandingR2T;
447171568Sscottl     int	errorRecoveryLevel;
448171568Sscottl     int	targetPortalGroupTag;
449171568Sscottl
450171568Sscottl     boolean_t	initialR2T;
451171568Sscottl     boolean_t	immediateData;
452171568Sscottl     boolean_t	dataPDUInOrder;
453171568Sscottl     boolean_t	dataSequenceInOrder;
454171568Sscottl     char	*headerDigest;
455171568Sscottl     char	*dataDigest;
456171568Sscottl     char	*sessionType;
457171568Sscottl     char	*sendTargets;
458171568Sscottl     char	*targetAddress;
459171568Sscottl     char	*targetAlias;
460171568Sscottl     char	*targetName;
461171568Sscottl     char	*initiatorName;
462171568Sscottl     char	*initiatorAlias;
463171568Sscottl     char	*authMethod;
464171568Sscottl     char	*chapSecret;
465171568Sscottl     char	*chapIName;
466171568Sscottl     char	*chapDigest;
467171568Sscottl     char	*tgtChapName;
468171568Sscottl     char	*tgtChapSecret;
469171568Sscottl     int	tgtChallengeLen;
470171568Sscottl     u_char	tgtChapID;
471171568Sscottl     char	*tgtChapDigest;
472171568Sscottl     char	*iqn;
473211095Sdes     char	*pidfile;
474171568Sscottl} isc_opt_t;
475171568Sscottl
476171568Sscottl/*
477171568Sscottl | ioctl
478171568Sscottl */
479171568Sscottl#define ISCSISETSES	_IOR('i', 1, int)
480171568Sscottl#define ISCSISETSOC	_IOW('i', 2, int)
481171568Sscottl#define ISCSISETOPT	_IOW('i', 5, isc_opt_t)
482171568Sscottl#define ISCSIGETOPT	_IOR('i', 6, isc_opt_t)
483171568Sscottl
484171568Sscottl#define ISCSISEND	_IOW('i', 10, pdu_t)
485171568Sscottl#define ISCSIRECV	_IOWR('i', 11, pdu_t)
486171568Sscottl
487171568Sscottl#define ISCSIPING	_IO('i', 20)
488171568Sscottl#define ISCSISIGNAL	_IOW('i', 21, int *)
489171568Sscottl
490171568Sscottl#define ISCSISTART	_IO('i', 30)
491171568Sscottl#define ISCSIRESTART	_IO('i', 31)
492171568Sscottl#define ISCSISTOP	_IO('i', 32)
493171568Sscottl
494171568Sscottltypedef struct iscsi_cam {
495171568Sscottl     path_id_t		path_id;
496171568Sscottl     target_id_t	target_id;
497171568Sscottl     int		target_nluns;
498171568Sscottl} iscsi_cam_t;
499171568Sscottl
500171568Sscottl#define ISCSIGETCAM	_IOR('i', 33, iscsi_cam_t)
501