diff options
-rw-r--r-- | drivers/scsi/iscsi_tcp.h | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h new file mode 100644 index 000000000000..d23ae68fae0d --- /dev/null +++ b/drivers/scsi/iscsi_tcp.h | |||
@@ -0,0 +1,322 @@ | |||
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 | ||
74 | #define ISCSI_CMD_PER_LUN 128 | ||
75 | #define ISCSI_TCP_MAX_CMD_LEN 16 | ||
76 | |||
77 | #define ITT_MASK (0xfff) | ||
78 | #define CID_SHIFT 12 | ||
79 | #define CID_MASK (0xffff<<CID_SHIFT) | ||
80 | #define AGE_SHIFT 28 | ||
81 | #define AGE_MASK (0xf<<AGE_SHIFT) | ||
82 | |||
83 | struct iscsi_queue { | ||
84 | struct kfifo *queue; /* FIFO Queue */ | ||
85 | void **pool; /* Pool of elements */ | ||
86 | int max; /* Max number of elements */ | ||
87 | }; | ||
88 | |||
89 | struct iscsi_session; | ||
90 | struct iscsi_cmd_task; | ||
91 | struct iscsi_mgmt_task; | ||
92 | |||
93 | /* Socket connection recieve helper */ | ||
94 | struct iscsi_tcp_recv { | ||
95 | struct iscsi_hdr *hdr; | ||
96 | struct sk_buff *skb; | ||
97 | int offset; | ||
98 | int len; | ||
99 | int hdr_offset; | ||
100 | int copy; | ||
101 | int copied; | ||
102 | int padding; | ||
103 | struct iscsi_cmd_task *ctask; /* current cmd in progress */ | ||
104 | |||
105 | /* copied and flipped values */ | ||
106 | int opcode; | ||
107 | int flags; | ||
108 | int cmd_status; | ||
109 | int ahslen; | ||
110 | int datalen; | ||
111 | uint32_t itt; | ||
112 | int datadgst; | ||
113 | }; | ||
114 | |||
115 | struct iscsi_conn { | ||
116 | struct iscsi_hdr hdr; /* header placeholder */ | ||
117 | char hdrext[4*sizeof(__u16) + | ||
118 | sizeof(__u32)]; | ||
119 | int data_copied; | ||
120 | char *data; /* data placeholder */ | ||
121 | struct socket *sock; /* TCP socket */ | ||
122 | int data_size; /* actual recv_dlength */ | ||
123 | int stop_stage; /* conn_stop() flag: * | ||
124 | * stop to recover, * | ||
125 | * stop to terminate */ | ||
126 | /* iSCSI connection-wide sequencing */ | ||
127 | uint32_t exp_statsn; | ||
128 | int hdr_size; /* PDU header size */ | ||
129 | unsigned long suspend_rx; /* suspend Rx */ | ||
130 | |||
131 | struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */ | ||
132 | struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */ | ||
133 | |||
134 | /* control data */ | ||
135 | int senselen; /* scsi sense length */ | ||
136 | int id; /* CID */ | ||
137 | struct iscsi_tcp_recv in; /* TCP receive context */ | ||
138 | struct iscsi_session *session; /* parent session */ | ||
139 | struct list_head item; /* maintains list of conns */ | ||
140 | int in_progress; /* connection state machine */ | ||
141 | int c_stage; /* connection state */ | ||
142 | struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ | ||
143 | struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ | ||
144 | struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ | ||
145 | spinlock_t lock; /* FIXME: to be removed */ | ||
146 | |||
147 | /* old values for socket callbacks */ | ||
148 | void (*old_data_ready)(struct sock *, int); | ||
149 | void (*old_state_change)(struct sock *); | ||
150 | void (*old_write_space)(struct sock *); | ||
151 | |||
152 | /* xmit */ | ||
153 | struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */ | ||
154 | struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */ | ||
155 | struct kfifo *writequeue; /* write cmds for Data-Outs */ | ||
156 | struct kfifo *immqueue; /* immediate xmit queue */ | ||
157 | struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ | ||
158 | struct kfifo *xmitqueue; /* data-path cmd queue */ | ||
159 | struct work_struct xmitwork; /* per-conn. xmit workqueue */ | ||
160 | struct semaphore xmitsema; /* serializes connection xmit, | ||
161 | * access to kfifos: * | ||
162 | * xmitqueue, writequeue, * | ||
163 | * immqueue, mgmtqueue */ | ||
164 | unsigned long suspend_tx; /* suspend Tx */ | ||
165 | |||
166 | /* abort */ | ||
167 | wait_queue_head_t ehwait; /* used in eh_abort() */ | ||
168 | struct iscsi_tm tmhdr; | ||
169 | struct timer_list tmabort_timer; /* abort timer */ | ||
170 | int tmabort_state; /* see TMABORT_INITIAL, etc.*/ | ||
171 | |||
172 | /* negotiated params */ | ||
173 | int max_recv_dlength; | ||
174 | int max_xmit_dlength; | ||
175 | int hdrdgst_en; | ||
176 | int datadgst_en; | ||
177 | |||
178 | /* MIB-statistics */ | ||
179 | uint64_t txdata_octets; | ||
180 | uint64_t rxdata_octets; | ||
181 | uint32_t scsicmd_pdus_cnt; | ||
182 | uint32_t dataout_pdus_cnt; | ||
183 | uint32_t scsirsp_pdus_cnt; | ||
184 | uint32_t datain_pdus_cnt; | ||
185 | uint32_t r2t_pdus_cnt; | ||
186 | uint32_t tmfcmd_pdus_cnt; | ||
187 | int32_t tmfrsp_pdus_cnt; | ||
188 | |||
189 | /* custom statistics */ | ||
190 | uint32_t sendpage_failures_cnt; | ||
191 | uint32_t discontiguous_hdr_cnt; | ||
192 | uint32_t eh_abort_cnt; | ||
193 | }; | ||
194 | |||
195 | struct iscsi_session { | ||
196 | /* iSCSI session-wide sequencing */ | ||
197 | uint32_t cmdsn; | ||
198 | uint32_t exp_cmdsn; | ||
199 | uint32_t max_cmdsn; | ||
200 | |||
201 | /* configuration */ | ||
202 | int initial_r2t_en; | ||
203 | int max_r2t; | ||
204 | int imm_data_en; | ||
205 | int first_burst; | ||
206 | int max_burst; | ||
207 | int time2wait; | ||
208 | int time2retain; | ||
209 | int pdu_inorder_en; | ||
210 | int dataseq_inorder_en; | ||
211 | int erl; | ||
212 | int ifmarker_en; | ||
213 | int ofmarker_en; | ||
214 | |||
215 | /* control data */ | ||
216 | struct Scsi_Host *host; | ||
217 | int id; | ||
218 | struct iscsi_conn *leadconn; /* leading connection */ | ||
219 | spinlock_t lock; /* protects session state, * | ||
220 | * sequence numbers, * | ||
221 | * session resources: * | ||
222 | * - cmdpool, * | ||
223 | * - mgmtpool, * | ||
224 | * - r2tpool */ | ||
225 | int state; /* session state */ | ||
226 | struct list_head item; | ||
227 | void *auth_client; | ||
228 | int conn_cnt; | ||
229 | int age; /* counts session re-opens */ | ||
230 | |||
231 | struct list_head connections; /* list of connections */ | ||
232 | int cmds_max; /* size of cmds array */ | ||
233 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ | ||
234 | struct iscsi_queue cmdpool; /* PDU's pool */ | ||
235 | int mgmtpool_max; /* size of mgmt array */ | ||
236 | struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ | ||
237 | struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */ | ||
238 | }; | ||
239 | |||
240 | struct iscsi_buf { | ||
241 | struct scatterlist sg; | ||
242 | struct kvec iov; | ||
243 | unsigned int sent; | ||
244 | }; | ||
245 | |||
246 | struct iscsi_data_task { | ||
247 | struct iscsi_data hdr; /* PDU */ | ||
248 | char hdrext[sizeof(__u32)]; /* Header-Digest */ | ||
249 | struct list_head item; /* data queue item */ | ||
250 | struct iscsi_buf digestbuf; /* digest buffer */ | ||
251 | uint32_t digest; /* data digest */ | ||
252 | }; | ||
253 | #define ISCSI_DTASK_DEFAULT_MAX ISCSI_SG_TABLESIZE * PAGE_SIZE / 512 | ||
254 | |||
255 | struct iscsi_mgmt_task { | ||
256 | struct iscsi_hdr hdr; /* mgmt. PDU */ | ||
257 | char hdrext[sizeof(__u32)]; /* Header-Digest */ | ||
258 | char *data; /* mgmt payload */ | ||
259 | int xmstate; /* mgmt xmit progress */ | ||
260 | int data_count; /* counts data to be sent */ | ||
261 | struct iscsi_buf headbuf; /* header buffer */ | ||
262 | struct iscsi_buf sendbuf; /* in progress buffer */ | ||
263 | int sent; | ||
264 | uint32_t itt; /* this ITT */ | ||
265 | }; | ||
266 | |||
267 | struct iscsi_r2t_info { | ||
268 | __be32 ttt; /* copied from R2T */ | ||
269 | __be32 exp_statsn; /* copied from R2T */ | ||
270 | uint32_t data_length; /* copied from R2T */ | ||
271 | uint32_t data_offset; /* copied from R2T */ | ||
272 | struct iscsi_buf headbuf; /* Data-Out Header Buffer */ | ||
273 | struct iscsi_buf sendbuf; /* Data-Out in progress buffer*/ | ||
274 | int sent; /* R2T sequence progress */ | ||
275 | int data_count; /* DATA-Out payload progress */ | ||
276 | struct scatterlist *sg; /* per-R2T SG list */ | ||
277 | int solicit_datasn; | ||
278 | struct iscsi_data_task *dtask; /* which data task */ | ||
279 | }; | ||
280 | |||
281 | struct iscsi_cmd_task { | ||
282 | struct iscsi_cmd hdr; /* iSCSI PDU header */ | ||
283 | char hdrext[4*sizeof(__u16)+ /* AHS */ | ||
284 | sizeof(__u32)]; /* HeaderDigest */ | ||
285 | char pad[ISCSI_PAD_LEN]; | ||
286 | int itt; /* this ITT */ | ||
287 | int datasn; /* DataSN */ | ||
288 | struct iscsi_buf headbuf; /* header buf (xmit) */ | ||
289 | struct iscsi_buf sendbuf; /* in progress buffer*/ | ||
290 | int sent; | ||
291 | struct scatterlist *sg; /* per-cmd SG list */ | ||
292 | struct scatterlist *bad_sg; /* assert statement */ | ||
293 | int sg_count; /* SG's to process */ | ||
294 | uint32_t unsol_datasn; | ||
295 | uint32_t exp_r2tsn; | ||
296 | int xmstate; /* xmit xtate machine */ | ||
297 | int imm_count; /* imm-data (bytes) */ | ||
298 | int unsol_count; /* unsolicited (bytes)*/ | ||
299 | int r2t_data_count; /* R2T Data-Out bytes */ | ||
300 | int data_count; /* remaining Data-Out */ | ||
301 | int pad_count; /* padded bytes */ | ||
302 | struct scsi_cmnd *sc; /* associated SCSI cmd*/ | ||
303 | int total_length; | ||
304 | int data_offset; | ||
305 | struct iscsi_conn *conn; /* used connection */ | ||
306 | struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ | ||
307 | |||
308 | struct iscsi_r2t_info *r2t; /* in progress R2T */ | ||
309 | struct iscsi_queue r2tpool; | ||
310 | struct kfifo *r2tqueue; | ||
311 | struct iscsi_r2t_info **r2ts; | ||
312 | struct list_head dataqueue; /* Data-Out dataqueue */ | ||
313 | mempool_t *datapool; | ||
314 | uint32_t datadigest; /* for recover digest */ | ||
315 | int digest_count; | ||
316 | uint32_t immdigest; /* for imm data */ | ||
317 | struct iscsi_buf immbuf; /* for imm data digest */ | ||
318 | struct iscsi_data_task *dtask; /* data task in progress*/ | ||
319 | int digest_offset; /* for partial buff digest */ | ||
320 | }; | ||
321 | |||
322 | #endif /* ISCSI_H */ | ||