1/*
2 * iSCSI Initiator TCP Transport
3 * Copyright (C) 2004 Dmitry Yusupov
4 * Copyright (C) 2004 Alex Aizman
5 * Copyright (C) 2005 - 2006 Mike Christie
6 * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
7 * maintained by open-iscsi@googlegroups.com
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * See the file COPYING included with this distribution for more details.
20 */
21
22#ifndef ISCSI_TCP_H
23#define ISCSI_TCP_H
24
25#include <scsi/libiscsi.h>
26
27/* Socket's Receive state machine */
28#define IN_PROGRESS_WAIT_HEADER		0x0
29#define IN_PROGRESS_HEADER_GATHER	0x1
30#define IN_PROGRESS_DATA_RECV		0x2
31#define IN_PROGRESS_DDIGEST_RECV	0x3
32
33/* xmit state machine */
34#define XMSTATE_IDLE			0x0
35#define XMSTATE_R_HDR			0x1
36#define XMSTATE_W_HDR			0x2
37#define XMSTATE_IMM_HDR			0x4
38#define XMSTATE_IMM_DATA		0x8
39#define XMSTATE_UNS_INIT		0x10
40#define XMSTATE_UNS_HDR			0x20
41#define XMSTATE_UNS_DATA		0x40
42#define XMSTATE_SOL_HDR			0x80
43#define XMSTATE_SOL_DATA		0x100
44#define XMSTATE_W_PAD			0x200
45#define XMSTATE_W_RESEND_PAD		0x400
46#define XMSTATE_W_RESEND_DATA_DIGEST	0x800
47
48#define ISCSI_PAD_LEN			4
49#define ISCSI_SG_TABLESIZE		SG_ALL
50#define ISCSI_TCP_MAX_CMD_LEN		16
51
52struct crypto_hash;
53struct socket;
54
55/* Socket connection recieve helper */
56struct iscsi_tcp_recv {
57	struct iscsi_hdr	*hdr;
58	struct sk_buff		*skb;
59	int			offset;
60	int			len;
61	int			hdr_offset;
62	int			copy;
63	int			copied;
64	int			padding;
65	struct iscsi_cmd_task	*ctask;		/* current cmd in progress */
66
67	/* copied and flipped values */
68	int			datalen;
69	int			datadgst;
70	char			zero_copy_hdr;
71};
72
73struct iscsi_tcp_conn {
74	struct iscsi_conn	*iscsi_conn;
75	struct socket		*sock;
76	struct iscsi_hdr	hdr;		/* header placeholder */
77	char			hdrext[4*sizeof(__u16) +
78				    sizeof(__u32)];
79	int			data_copied;
80	int			stop_stage;	/* conn_stop() flag: *
81						 * stop to recover,  *
82						 * stop to terminate */
83	/* iSCSI connection-wide sequencing */
84	int			hdr_size;	/* PDU header size */
85
86	/* control data */
87	struct iscsi_tcp_recv	in;		/* TCP receive context */
88	int			in_progress;	/* connection state machine */
89
90	/* old values for socket callbacks */
91	void			(*old_data_ready)(struct sock *, int);
92	void			(*old_state_change)(struct sock *);
93	void			(*old_write_space)(struct sock *);
94
95	/* data and header digests */
96	struct hash_desc	tx_hash;	/* CRC32C (Tx) */
97	struct hash_desc	rx_hash;	/* CRC32C (Rx) */
98
99	/* MIB custom statistics */
100	uint32_t		sendpage_failures_cnt;
101	uint32_t		discontiguous_hdr_cnt;
102
103	ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
104};
105
106struct iscsi_buf {
107	struct scatterlist	sg;
108	unsigned int		sent;
109	char			use_sendmsg;
110};
111
112struct iscsi_data_task {
113	struct iscsi_data	hdr;			/* PDU */
114	char			hdrext[sizeof(__u32)];	/* Header-Digest */
115	struct iscsi_buf	digestbuf;		/* digest buffer */
116	uint32_t		digest;			/* data digest */
117};
118
119struct iscsi_tcp_mgmt_task {
120	struct iscsi_hdr	hdr;
121	char			hdrext[sizeof(__u32)]; /* Header-Digest */
122	int			xmstate;	/* mgmt xmit progress */
123	struct iscsi_buf	headbuf;	/* header buffer */
124	struct iscsi_buf	sendbuf;	/* in progress buffer */
125	int			sent;
126};
127
128struct iscsi_r2t_info {
129	__be32			ttt;		/* copied from R2T */
130	__be32			exp_statsn;	/* copied from R2T */
131	uint32_t		data_length;	/* copied from R2T */
132	uint32_t		data_offset;	/* copied from R2T */
133	struct iscsi_buf	headbuf;	/* Data-Out Header Buffer */
134	struct iscsi_buf	sendbuf;	/* Data-Out in progress buffer*/
135	int			sent;		/* R2T sequence progress */
136	int			data_count;	/* DATA-Out payload progress */
137	struct scatterlist	*sg;		/* per-R2T SG list */
138	int			solicit_datasn;
139	struct iscsi_data_task   dtask;        /* which data task */
140};
141
142struct iscsi_tcp_cmd_task {
143	struct iscsi_cmd	hdr;
144	char			hdrext[4*sizeof(__u16)+	/* AHS */
145				    sizeof(__u32)];	/* HeaderDigest */
146	char			pad[ISCSI_PAD_LEN];
147	int			pad_count;		/* padded bytes */
148	struct iscsi_buf	headbuf;		/* header buf (xmit) */
149	struct iscsi_buf	sendbuf;		/* in progress buffer*/
150	int			xmstate;		/* xmit xtate machine */
151	int			sent;
152	struct scatterlist	*sg;			/* per-cmd SG list  */
153	struct scatterlist	*bad_sg;		/* assert statement */
154	int			sg_count;		/* SG's to process  */
155	uint32_t		exp_r2tsn;
156	int			data_offset;
157	struct iscsi_r2t_info	*r2t;			/* in progress R2T    */
158	struct iscsi_queue	r2tpool;
159	struct kfifo		*r2tqueue;
160	struct iscsi_r2t_info	**r2ts;
161	int			digest_count;
162	uint32_t		immdigest;		/* for imm data */
163	struct iscsi_buf	immbuf;			/* for imm data digest */
164	struct iscsi_data_task	unsol_dtask;	/* unsol data task */
165};
166
167#endif /* ISCSI_H */
168