aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi/libiscsi.h
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-04-06 22:13:41 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-04-14 15:09:00 -0400
commit7996a778ff8c717cb1a7a294475c59cc8f1e9fb8 (patch)
tree3d7ee67ad547a65ad10f5c7e41e20f6124ee249b /include/scsi/libiscsi.h
parent30a6c65236f9d26e3325cae468f330b833a3878c (diff)
[SCSI] iscsi: add libiscsi
There is a lot of code duplcited between iscsi_tcp and the upcoming iscsi_iser driver. This patch puts the duplicated code in a lib. There is more code to move around but this takes care of the basics. For iscsi_offload if they use the lib we will probably move some things around. For example in the queuecommand we will not assume that the LLD wants to do queue_work, but it is better to handle that later when we know for sure what iscsi_offload looks like (we could probably do this for iscsi_iser though to). Ideally I would like to get the iscsi_transports modules to a place where all they really have to do is put data on the wire, but how to do that will hopefully be more clear when we see other modules like iscsi_offload. Or maybe iscsi_offload will not use the lib and it will just be iscsi_iser and iscsi_tcp and maybe the iscsi_tcp_tgt if that is allowed in mainline. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'include/scsi/libiscsi.h')
-rw-r--r--include/scsi/libiscsi.h286
1 files changed, 286 insertions, 0 deletions
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
new file mode 100644
index 000000000000..830700a4ed69
--- /dev/null
+++ b/include/scsi/libiscsi.h
@@ -0,0 +1,286 @@
1/*
2 * iSCSI lib definitions
3 *
4 * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2004 - 2006 Mike Christie
6 * Copyright (C) 2004 - 2005 Dmitry Yusupov
7 * Copyright (C) 2004 - 2005 Alex Aizman
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 by
11 * 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,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23#ifndef LIBISCSI_H
24#define LIBISCSI_H
25
26#include <linux/types.h>
27#include <linux/mutex.h>
28#include <scsi/iscsi_proto.h>
29#include <scsi/iscsi_if.h>
30
31struct scsi_transport_template;
32struct scsi_device;
33struct Scsi_Host;
34struct scsi_cmnd;
35struct socket;
36struct iscsi_transport;
37struct iscsi_cls_session;
38struct iscsi_cls_conn;
39struct iscsi_session;
40struct iscsi_nopin;
41
42/* #define DEBUG_SCSI */
43#ifdef DEBUG_SCSI
44#define debug_scsi(fmt...) printk(KERN_INFO "scsi: " fmt)
45#else
46#define debug_scsi(fmt...)
47#endif
48
49#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */
50#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */
51#define ISCSI_CONN_MAX 1
52
53#define ISCSI_MGMT_ITT_OFFSET 0xa00
54
55#define ISCSI_DEF_CMD_PER_LUN 32
56#define ISCSI_MAX_CMD_PER_LUN 128
57
58/* Task Mgmt states */
59#define TMABORT_INITIAL 0x0
60#define TMABORT_SUCCESS 0x1
61#define TMABORT_FAILED 0x2
62#define TMABORT_TIMEDOUT 0x3
63
64/* Connection suspend "bit" */
65#define ISCSI_SUSPEND_BIT 1
66
67#define ISCSI_ITT_MASK (0xfff)
68#define ISCSI_CID_SHIFT 12
69#define ISCSI_CID_MASK (0xffff << ISCSI_CID_SHIFT)
70#define ISCSI_AGE_SHIFT 28
71#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT)
72
73struct iscsi_mgmt_task {
74 /*
75 * Becuae LLDs allocate their hdr differently, this is a pointer to
76 * that storage. It must be setup at session creation time.
77 */
78 struct iscsi_hdr *hdr;
79 char *data; /* mgmt payload */
80 int data_count; /* counts data to be sent */
81 uint32_t itt; /* this ITT */
82 void *dd_data; /* driver/transport data */
83 struct list_head running;
84};
85
86struct iscsi_cmd_task {
87 /*
88 * Becuae LLDs allocate their hdr differently, this is a pointer to
89 * that storage. It must be setup at session creation time.
90 */
91 struct iscsi_cmd *hdr;
92 int itt; /* this ITT */
93 int datasn; /* DataSN */
94
95 uint32_t unsol_datasn;
96 int imm_count; /* imm-data (bytes) */
97 int unsol_count; /* unsolicited (bytes)*/
98 int data_count; /* remaining Data-Out */
99 struct scsi_cmnd *sc; /* associated SCSI cmd*/
100 int total_length;
101 struct iscsi_conn *conn; /* used connection */
102 struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */
103
104 struct list_head running; /* running cmd list */
105 void *dd_data; /* driver/transport data */
106};
107
108struct iscsi_conn {
109 struct iscsi_cls_conn *cls_conn; /* ptr to class connection */
110 void *dd_data; /* iscsi_transport data */
111 struct iscsi_session *session; /* parent session */
112 /*
113 * LLDs should set this lock. It protects the transport recv
114 * code
115 */
116 rwlock_t *recv_lock;
117 /*
118 * conn_stop() flag: stop to recover, stop to terminate
119 */
120 int stop_stage;
121
122 /* iSCSI connection-wide sequencing */
123 uint32_t exp_statsn;
124
125 /* control data */
126 int id; /* CID */
127 struct list_head item; /* maintains list of conns */
128 int c_stage; /* connection state */
129 struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
130 struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
131 struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
132
133 /* xmit */
134 struct kfifo *immqueue; /* immediate xmit queue */
135 struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
136 struct list_head mgmt_run_list; /* list of control tasks */
137 struct kfifo *xmitqueue; /* data-path cmd queue */
138 struct list_head run_list; /* list of cmds in progress */
139 struct work_struct xmitwork; /* per-conn. xmit workqueue */
140 /*
141 * serializes connection xmit, access to kfifos:
142 * xmitqueue, immqueue, mgmtqueue
143 */
144 struct mutex xmitmutex;
145
146 unsigned long suspend_tx; /* suspend Tx */
147 unsigned long suspend_rx; /* suspend Rx */
148
149 /* abort */
150 wait_queue_head_t ehwait; /* used in eh_abort() */
151 struct iscsi_tm tmhdr;
152 struct timer_list tmabort_timer;
153 int tmabort_state; /* see TMABORT_INITIAL, etc.*/
154
155 /* negotiated params */
156 int max_recv_dlength; /* initiator_max_recv_dsl*/
157 int max_xmit_dlength; /* target_max_recv_dsl */
158 int hdrdgst_en;
159 int datadgst_en;
160
161 /* MIB-statistics */
162 uint64_t txdata_octets;
163 uint64_t rxdata_octets;
164 uint32_t scsicmd_pdus_cnt;
165 uint32_t dataout_pdus_cnt;
166 uint32_t scsirsp_pdus_cnt;
167 uint32_t datain_pdus_cnt;
168 uint32_t r2t_pdus_cnt;
169 uint32_t tmfcmd_pdus_cnt;
170 int32_t tmfrsp_pdus_cnt;
171
172 /* custom statistics */
173 uint32_t eh_abort_cnt;
174};
175
176struct iscsi_queue {
177 struct kfifo *queue; /* FIFO Queue */
178 void **pool; /* Pool of elements */
179 int max; /* Max number of elements */
180};
181
182struct iscsi_session {
183 /* iSCSI session-wide sequencing */
184 uint32_t cmdsn;
185 uint32_t exp_cmdsn;
186 uint32_t max_cmdsn;
187
188 /* configuration */
189 int initial_r2t_en;
190 int max_r2t;
191 int imm_data_en;
192 int first_burst;
193 int max_burst;
194 int time2wait;
195 int time2retain;
196 int pdu_inorder_en;
197 int dataseq_inorder_en;
198 int erl;
199 int ifmarker_en;
200 int ofmarker_en;
201
202 /* control data */
203 struct iscsi_transport *tt;
204 struct Scsi_Host *host;
205 struct iscsi_conn *leadconn; /* leading connection */
206 spinlock_t lock; /* protects session state, *
207 * sequence numbers, *
208 * session resources: *
209 * - cmdpool, *
210 * - mgmtpool, *
211 * - r2tpool */
212 int state; /* session state */
213 int recovery_failed;
214 struct list_head item;
215 int conn_cnt;
216 int age; /* counts session re-opens */
217
218 struct list_head connections; /* list of connections */
219 int cmds_max; /* size of cmds array */
220 struct iscsi_cmd_task **cmds; /* Original Cmds arr */
221 struct iscsi_queue cmdpool; /* PDU's pool */
222 int mgmtpool_max; /* size of mgmt array */
223 struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */
224 struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */
225};
226
227/*
228 * scsi host template
229 */
230extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth);
231extern int iscsi_eh_abort(struct scsi_cmnd *sc);
232extern int iscsi_eh_host_reset(struct scsi_cmnd *sc);
233extern int iscsi_queuecommand(struct scsi_cmnd *sc,
234 void (*done)(struct scsi_cmnd *));
235
236/*
237 * session management
238 */
239extern struct iscsi_cls_session *
240iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
241 int, int, uint32_t, uint32_t *);
242extern void iscsi_session_teardown(struct iscsi_cls_session *);
243extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
244extern void iscsi_start_session_recovery(struct iscsi_session *,
245 struct iscsi_conn *, int);
246extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
247
248#define session_to_cls(_sess) \
249 hostdata_session(_sess->host->hostdata)
250
251/*
252 * connection management
253 */
254extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *,
255 uint32_t);
256extern void iscsi_conn_teardown(struct iscsi_cls_conn *);
257extern int iscsi_conn_start(struct iscsi_cls_conn *);
258extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
259extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
260 int);
261extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
262
263/*
264 * pdu and task processing
265 */
266extern int iscsi_check_assign_cmdsn(struct iscsi_session *,
267 struct iscsi_nopin *);
268extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
269 struct iscsi_data *hdr,
270 int transport_data_cnt);
271extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
272 char *, uint32_t);
273extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
274 char *, int);
275extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
276 char *, int);
277extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *,
278 uint32_t *);
279
280/*
281 * generic helpers
282 */
283extern void iscsi_pool_free(struct iscsi_queue *, void **);
284extern int iscsi_pool_init(struct iscsi_queue *, int, void ***, int);
285
286#endif