Commit | Line | Data |
---|---|---|
c213ca07 AA |
1 | /* |
2 | * iSCSI Initiator TCP Transport | |
3 | * Copyright (C) 2004 Dmitry Yusupov | |
4 | * Copyright (C) 2004 Alex Aizman | |
5 | * Copyright (C) 2005 Mike Christie | |
6 | * maintained by open-iscsi@googlegroups.com | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published | |
10 | * by the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * See the file COPYING included with this distribution for more details. | |
19 | */ | |
20 | ||
21 | #ifndef ISCSI_TCP_H | |
22 | #define ISCSI_TCP_H | |
23 | ||
24 | /* Session's states */ | |
25 | #define ISCSI_STATE_FREE 1 | |
26 | #define ISCSI_STATE_LOGGED_IN 2 | |
27 | #define ISCSI_STATE_FAILED 3 | |
28 | #define ISCSI_STATE_TERMINATE 4 | |
29 | ||
30 | /* Connection's states */ | |
31 | #define ISCSI_CONN_INITIAL_STAGE 0 | |
32 | #define ISCSI_CONN_STARTED 1 | |
33 | #define ISCSI_CONN_STOPPED 2 | |
34 | #define ISCSI_CONN_CLEANUP_WAIT 3 | |
35 | ||
36 | /* Connection suspend "bit" */ | |
37 | #define SUSPEND_BIT 1 | |
38 | ||
39 | /* Socket's Receive state machine */ | |
40 | #define IN_PROGRESS_WAIT_HEADER 0x0 | |
41 | #define IN_PROGRESS_HEADER_GATHER 0x1 | |
42 | #define IN_PROGRESS_DATA_RECV 0x2 | |
43 | #define IN_PROGRESS_DDIGEST_RECV 0x3 | |
44 | ||
45 | /* Task Mgmt states */ | |
46 | #define TMABORT_INITIAL 0x0 | |
47 | #define TMABORT_SUCCESS 0x1 | |
48 | #define TMABORT_FAILED 0x2 | |
49 | #define TMABORT_TIMEDOUT 0x3 | |
50 | ||
51 | /* xmit state machine */ | |
52 | #define XMSTATE_IDLE 0x0 | |
53 | #define XMSTATE_R_HDR 0x1 | |
54 | #define XMSTATE_W_HDR 0x2 | |
55 | #define XMSTATE_IMM_HDR 0x4 | |
56 | #define XMSTATE_IMM_DATA 0x8 | |
57 | #define XMSTATE_UNS_INIT 0x10 | |
58 | #define XMSTATE_UNS_HDR 0x20 | |
59 | #define XMSTATE_UNS_DATA 0x40 | |
60 | #define XMSTATE_SOL_HDR 0x80 | |
61 | #define XMSTATE_SOL_DATA 0x100 | |
62 | #define XMSTATE_W_PAD 0x200 | |
63 | #define XMSTATE_DATA_DIGEST 0x400 | |
64 | ||
65 | #define ISCSI_CONN_MAX 1 | |
66 | #define ISCSI_CONN_RCVBUF_MIN 262144 | |
67 | #define ISCSI_CONN_SNDBUF_MIN 262144 | |
68 | #define ISCSI_PAD_LEN 4 | |
69 | #define ISCSI_R2T_MAX 16 | |
70 | #define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */ | |
71 | #define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */ | |
72 | #define ISCSI_MGMT_ITT_OFFSET 0xa00 | |
73 | #define ISCSI_SG_TABLESIZE SG_ALL | |
9e3961ba MC |
74 | #define ISCSI_DEF_CMD_PER_LUN 32 |
75 | #define ISCSI_MAX_CMD_PER_LUN 128 | |
c213ca07 AA |
76 | #define ISCSI_TCP_MAX_CMD_LEN 16 |
77 | ||
78 | #define ITT_MASK (0xfff) | |
79 | #define CID_SHIFT 12 | |
80 | #define CID_MASK (0xffff<<CID_SHIFT) | |
81 | #define AGE_SHIFT 28 | |
82 | #define AGE_MASK (0xf<<AGE_SHIFT) | |
83 | ||
84 | struct iscsi_queue { | |
85 | struct kfifo *queue; /* FIFO Queue */ | |
86 | void **pool; /* Pool of elements */ | |
87 | int max; /* Max number of elements */ | |
88 | }; | |
89 | ||
90 | struct iscsi_session; | |
91 | struct iscsi_cmd_task; | |
92 | struct iscsi_mgmt_task; | |
93 | ||
94 | /* Socket connection recieve helper */ | |
95 | struct iscsi_tcp_recv { | |
96 | struct iscsi_hdr *hdr; | |
97 | struct sk_buff *skb; | |
98 | int offset; | |
99 | int len; | |
100 | int hdr_offset; | |
101 | int copy; | |
102 | int copied; | |
103 | int padding; | |
104 | struct iscsi_cmd_task *ctask; /* current cmd in progress */ | |
105 | ||
106 | /* copied and flipped values */ | |
107 | int opcode; | |
108 | int flags; | |
109 | int cmd_status; | |
110 | int ahslen; | |
111 | int datalen; | |
112 | uint32_t itt; | |
113 | int datadgst; | |
114 | }; | |
115 | ||
7b7232f3 MC |
116 | struct iscsi_cls_conn; |
117 | ||
c213ca07 | 118 | struct iscsi_conn { |
7b7232f3 | 119 | struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ |
c213ca07 AA |
120 | struct iscsi_hdr hdr; /* header placeholder */ |
121 | char hdrext[4*sizeof(__u16) + | |
122 | sizeof(__u32)]; | |
123 | int data_copied; | |
124 | char *data; /* data placeholder */ | |
125 | struct socket *sock; /* TCP socket */ | |
126 | int data_size; /* actual recv_dlength */ | |
127 | int stop_stage; /* conn_stop() flag: * | |
128 | * stop to recover, * | |
129 | * stop to terminate */ | |
130 | /* iSCSI connection-wide sequencing */ | |
131 | uint32_t exp_statsn; | |
132 | int hdr_size; /* PDU header size */ | |
133 | unsigned long suspend_rx; /* suspend Rx */ | |
134 | ||
135 | struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */ | |
136 | struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */ | |
137 | ||
138 | /* control data */ | |
139 | int senselen; /* scsi sense length */ | |
140 | int id; /* CID */ | |
141 | struct iscsi_tcp_recv in; /* TCP receive context */ | |
142 | struct iscsi_session *session; /* parent session */ | |
143 | struct list_head item; /* maintains list of conns */ | |
144 | int in_progress; /* connection state machine */ | |
145 | int c_stage; /* connection state */ | |
146 | struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ | |
147 | struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ | |
148 | struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ | |
c213ca07 AA |
149 | |
150 | /* old values for socket callbacks */ | |
151 | void (*old_data_ready)(struct sock *, int); | |
152 | void (*old_state_change)(struct sock *); | |
153 | void (*old_write_space)(struct sock *); | |
154 | ||
155 | /* xmit */ | |
156 | struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */ | |
157 | struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */ | |
158 | struct kfifo *writequeue; /* write cmds for Data-Outs */ | |
159 | struct kfifo *immqueue; /* immediate xmit queue */ | |
160 | struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ | |
161 | struct kfifo *xmitqueue; /* data-path cmd queue */ | |
162 | struct work_struct xmitwork; /* per-conn. xmit workqueue */ | |
0b950672 | 163 | struct mutex xmitmutex; /* serializes connection xmit, |
c213ca07 AA |
164 | * access to kfifos: * |
165 | * xmitqueue, writequeue, * | |
166 | * immqueue, mgmtqueue */ | |
167 | unsigned long suspend_tx; /* suspend Tx */ | |
168 | ||
169 | /* abort */ | |
170 | wait_queue_head_t ehwait; /* used in eh_abort() */ | |
171 | struct iscsi_tm tmhdr; | |
172 | struct timer_list tmabort_timer; /* abort timer */ | |
173 | int tmabort_state; /* see TMABORT_INITIAL, etc.*/ | |
174 | ||
175 | /* negotiated params */ | |
176 | int max_recv_dlength; | |
177 | int max_xmit_dlength; | |
178 | int hdrdgst_en; | |
179 | int datadgst_en; | |
180 | ||
181 | /* MIB-statistics */ | |
182 | uint64_t txdata_octets; | |
183 | uint64_t rxdata_octets; | |
184 | uint32_t scsicmd_pdus_cnt; | |
185 | uint32_t dataout_pdus_cnt; | |
186 | uint32_t scsirsp_pdus_cnt; | |
187 | uint32_t datain_pdus_cnt; | |
188 | uint32_t r2t_pdus_cnt; | |
189 | uint32_t tmfcmd_pdus_cnt; | |
190 | int32_t tmfrsp_pdus_cnt; | |
191 | ||
192 | /* custom statistics */ | |
193 | uint32_t sendpage_failures_cnt; | |
194 | uint32_t discontiguous_hdr_cnt; | |
195 | uint32_t eh_abort_cnt; | |
56851698 FT |
196 | |
197 | ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int); | |
c213ca07 AA |
198 | }; |
199 | ||
200 | struct iscsi_session { | |
201 | /* iSCSI session-wide sequencing */ | |
202 | uint32_t cmdsn; | |
203 | uint32_t exp_cmdsn; | |
204 | uint32_t max_cmdsn; | |
205 | ||
206 | /* configuration */ | |
207 | int initial_r2t_en; | |
208 | int max_r2t; | |
209 | int imm_data_en; | |
210 | int first_burst; | |
211 | int max_burst; | |
212 | int time2wait; | |
213 | int time2retain; | |
214 | int pdu_inorder_en; | |
215 | int dataseq_inorder_en; | |
216 | int erl; | |
217 | int ifmarker_en; | |
218 | int ofmarker_en; | |
219 | ||
220 | /* control data */ | |
221 | struct Scsi_Host *host; | |
222 | int id; | |
223 | struct iscsi_conn *leadconn; /* leading connection */ | |
224 | spinlock_t lock; /* protects session state, * | |
225 | * sequence numbers, * | |
226 | * session resources: * | |
227 | * - cmdpool, * | |
228 | * - mgmtpool, * | |
229 | * - r2tpool */ | |
230 | int state; /* session state */ | |
231 | struct list_head item; | |
232 | void *auth_client; | |
233 | int conn_cnt; | |
234 | int age; /* counts session re-opens */ | |
235 | ||
236 | struct list_head connections; /* list of connections */ | |
237 | int cmds_max; /* size of cmds array */ | |
238 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ | |
239 | struct iscsi_queue cmdpool; /* PDU's pool */ | |
240 | int mgmtpool_max; /* size of mgmt array */ | |
241 | struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ | |
242 | struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */ | |
243 | }; | |
244 | ||
245 | struct iscsi_buf { | |
246 | struct scatterlist sg; | |
c213ca07 | 247 | unsigned int sent; |
7cae5159 | 248 | char use_sendmsg; |
c213ca07 AA |
249 | }; |
250 | ||
251 | struct iscsi_data_task { | |
252 | struct iscsi_data hdr; /* PDU */ | |
253 | char hdrext[sizeof(__u32)]; /* Header-Digest */ | |
254 | struct list_head item; /* data queue item */ | |
255 | struct iscsi_buf digestbuf; /* digest buffer */ | |
256 | uint32_t digest; /* data digest */ | |
257 | }; | |
258 | #define ISCSI_DTASK_DEFAULT_MAX ISCSI_SG_TABLESIZE * PAGE_SIZE / 512 | |
259 | ||
260 | struct iscsi_mgmt_task { | |
261 | struct iscsi_hdr hdr; /* mgmt. PDU */ | |
262 | char hdrext[sizeof(__u32)]; /* Header-Digest */ | |
263 | char *data; /* mgmt payload */ | |
264 | int xmstate; /* mgmt xmit progress */ | |
265 | int data_count; /* counts data to be sent */ | |
266 | struct iscsi_buf headbuf; /* header buffer */ | |
267 | struct iscsi_buf sendbuf; /* in progress buffer */ | |
268 | int sent; | |
269 | uint32_t itt; /* this ITT */ | |
270 | }; | |
271 | ||
272 | struct iscsi_r2t_info { | |
273 | __be32 ttt; /* copied from R2T */ | |
274 | __be32 exp_statsn; /* copied from R2T */ | |
275 | uint32_t data_length; /* copied from R2T */ | |
276 | uint32_t data_offset; /* copied from R2T */ | |
277 | struct iscsi_buf headbuf; /* Data-Out Header Buffer */ | |
278 | struct iscsi_buf sendbuf; /* Data-Out in progress buffer*/ | |
279 | int sent; /* R2T sequence progress */ | |
280 | int data_count; /* DATA-Out payload progress */ | |
281 | struct scatterlist *sg; /* per-R2T SG list */ | |
282 | int solicit_datasn; | |
283 | struct iscsi_data_task *dtask; /* which data task */ | |
284 | }; | |
285 | ||
286 | struct iscsi_cmd_task { | |
287 | struct iscsi_cmd hdr; /* iSCSI PDU header */ | |
288 | char hdrext[4*sizeof(__u16)+ /* AHS */ | |
289 | sizeof(__u32)]; /* HeaderDigest */ | |
290 | char pad[ISCSI_PAD_LEN]; | |
291 | int itt; /* this ITT */ | |
292 | int datasn; /* DataSN */ | |
293 | struct iscsi_buf headbuf; /* header buf (xmit) */ | |
294 | struct iscsi_buf sendbuf; /* in progress buffer*/ | |
295 | int sent; | |
296 | struct scatterlist *sg; /* per-cmd SG list */ | |
297 | struct scatterlist *bad_sg; /* assert statement */ | |
298 | int sg_count; /* SG's to process */ | |
299 | uint32_t unsol_datasn; | |
300 | uint32_t exp_r2tsn; | |
301 | int xmstate; /* xmit xtate machine */ | |
302 | int imm_count; /* imm-data (bytes) */ | |
303 | int unsol_count; /* unsolicited (bytes)*/ | |
304 | int r2t_data_count; /* R2T Data-Out bytes */ | |
305 | int data_count; /* remaining Data-Out */ | |
306 | int pad_count; /* padded bytes */ | |
307 | struct scsi_cmnd *sc; /* associated SCSI cmd*/ | |
308 | int total_length; | |
309 | int data_offset; | |
310 | struct iscsi_conn *conn; /* used connection */ | |
311 | struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ | |
312 | ||
313 | struct iscsi_r2t_info *r2t; /* in progress R2T */ | |
314 | struct iscsi_queue r2tpool; | |
315 | struct kfifo *r2tqueue; | |
316 | struct iscsi_r2t_info **r2ts; | |
317 | struct list_head dataqueue; /* Data-Out dataqueue */ | |
318 | mempool_t *datapool; | |
319 | uint32_t datadigest; /* for recover digest */ | |
320 | int digest_count; | |
321 | uint32_t immdigest; /* for imm data */ | |
322 | struct iscsi_buf immbuf; /* for imm data digest */ | |
323 | struct iscsi_data_task *dtask; /* data task in progress*/ | |
324 | int digest_offset; /* for partial buff digest */ | |
325 | }; | |
326 | ||
327 | #endif /* ISCSI_H */ |