diff options
Diffstat (limited to 'include/scsi/libiscsi.h')
-rw-r--r-- | include/scsi/libiscsi.h | 107 |
1 files changed, 52 insertions, 55 deletions
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index cd3ca63d4fb1..5e75bb7f311c 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define LIBISCSI_H | 24 | #define LIBISCSI_H |
25 | 25 | ||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/wait.h> | ||
27 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
28 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
29 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <scsi/iscsi_if.h> | 32 | #include <scsi/iscsi_if.h> |
32 | 33 | ||
33 | struct scsi_transport_template; | 34 | struct scsi_transport_template; |
35 | struct scsi_host_template; | ||
34 | struct scsi_device; | 36 | struct scsi_device; |
35 | struct Scsi_Host; | 37 | struct Scsi_Host; |
36 | struct scsi_cmnd; | 38 | struct scsi_cmnd; |
@@ -40,6 +42,7 @@ struct iscsi_cls_session; | |||
40 | struct iscsi_cls_conn; | 42 | struct iscsi_cls_conn; |
41 | struct iscsi_session; | 43 | struct iscsi_session; |
42 | struct iscsi_nopin; | 44 | struct iscsi_nopin; |
45 | struct device; | ||
43 | 46 | ||
44 | /* #define DEBUG_SCSI */ | 47 | /* #define DEBUG_SCSI */ |
45 | #ifdef DEBUG_SCSI | 48 | #ifdef DEBUG_SCSI |
@@ -49,9 +52,7 @@ struct iscsi_nopin; | |||
49 | #endif | 52 | #endif |
50 | 53 | ||
51 | #define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ | 54 | #define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ |
52 | #define ISCSI_MGMT_CMDS_MAX 16 /* must be power of 2 */ | 55 | #define ISCSI_MGMT_CMDS_MAX 15 |
53 | |||
54 | #define ISCSI_MGMT_ITT_OFFSET 0xa00 | ||
55 | 56 | ||
56 | #define ISCSI_DEF_CMD_PER_LUN 32 | 57 | #define ISCSI_DEF_CMD_PER_LUN 32 |
57 | #define ISCSI_MAX_CMD_PER_LUN 128 | 58 | #define ISCSI_MAX_CMD_PER_LUN 128 |
@@ -69,7 +70,10 @@ enum { | |||
69 | /* Connection suspend "bit" */ | 70 | /* Connection suspend "bit" */ |
70 | #define ISCSI_SUSPEND_BIT 1 | 71 | #define ISCSI_SUSPEND_BIT 1 |
71 | 72 | ||
72 | #define ISCSI_ITT_MASK (0xfff) | 73 | #define ISCSI_ITT_MASK (0x1fff) |
74 | #define ISCSI_TOTAL_CMDS_MAX 4096 | ||
75 | /* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ | ||
76 | #define ISCSI_TOTAL_CMDS_MIN 16 | ||
73 | #define ISCSI_AGE_SHIFT 28 | 77 | #define ISCSI_AGE_SHIFT 28 |
74 | #define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) | 78 | #define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) |
75 | 79 | ||
@@ -82,18 +86,6 @@ enum { | |||
82 | ISCSI_DIGEST_SIZE = sizeof(__u32), | 86 | ISCSI_DIGEST_SIZE = sizeof(__u32), |
83 | }; | 87 | }; |
84 | 88 | ||
85 | struct iscsi_mgmt_task { | ||
86 | /* | ||
87 | * Becuae LLDs allocate their hdr differently, this is a pointer to | ||
88 | * that storage. It must be setup at session creation time. | ||
89 | */ | ||
90 | struct iscsi_hdr *hdr; | ||
91 | char *data; /* mgmt payload */ | ||
92 | unsigned data_count; /* counts data to be sent */ | ||
93 | uint32_t itt; /* this ITT */ | ||
94 | void *dd_data; /* driver/transport data */ | ||
95 | struct list_head running; | ||
96 | }; | ||
97 | 89 | ||
98 | enum { | 90 | enum { |
99 | ISCSI_TASK_COMPLETED, | 91 | ISCSI_TASK_COMPLETED, |
@@ -101,7 +93,7 @@ enum { | |||
101 | ISCSI_TASK_RUNNING, | 93 | ISCSI_TASK_RUNNING, |
102 | }; | 94 | }; |
103 | 95 | ||
104 | struct iscsi_cmd_task { | 96 | struct iscsi_task { |
105 | /* | 97 | /* |
106 | * Because LLDs allocate their hdr differently, this is a pointer | 98 | * Because LLDs allocate their hdr differently, this is a pointer |
107 | * and length to that storage. It must be setup at session | 99 | * and length to that storage. It must be setup at session |
@@ -118,6 +110,7 @@ struct iscsi_cmd_task { | |||
118 | /* offset in unsolicited stream (bytes); */ | 110 | /* offset in unsolicited stream (bytes); */ |
119 | unsigned unsol_offset; | 111 | unsigned unsol_offset; |
120 | unsigned data_count; /* remaining Data-Out */ | 112 | unsigned data_count; /* remaining Data-Out */ |
113 | char *data; /* mgmt payload */ | ||
121 | struct scsi_cmnd *sc; /* associated SCSI cmd*/ | 114 | struct scsi_cmnd *sc; /* associated SCSI cmd*/ |
122 | struct iscsi_conn *conn; /* used connection */ | 115 | struct iscsi_conn *conn; /* used connection */ |
123 | 116 | ||
@@ -128,9 +121,9 @@ struct iscsi_cmd_task { | |||
128 | void *dd_data; /* driver/transport data */ | 121 | void *dd_data; /* driver/transport data */ |
129 | }; | 122 | }; |
130 | 123 | ||
131 | static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask) | 124 | static inline void* iscsi_next_hdr(struct iscsi_task *task) |
132 | { | 125 | { |
133 | return (void*)ctask->hdr + ctask->hdr_len; | 126 | return (void*)task->hdr + task->hdr_len; |
134 | } | 127 | } |
135 | 128 | ||
136 | /* Connection's states */ | 129 | /* Connection's states */ |
@@ -146,11 +139,6 @@ struct iscsi_conn { | |||
146 | void *dd_data; /* iscsi_transport data */ | 139 | void *dd_data; /* iscsi_transport data */ |
147 | struct iscsi_session *session; /* parent session */ | 140 | struct iscsi_session *session; /* parent session */ |
148 | /* | 141 | /* |
149 | * LLDs should set this lock. It protects the transport recv | ||
150 | * code | ||
151 | */ | ||
152 | rwlock_t *recv_lock; | ||
153 | /* | ||
154 | * conn_stop() flag: stop to recover, stop to terminate | 142 | * conn_stop() flag: stop to recover, stop to terminate |
155 | */ | 143 | */ |
156 | int stop_stage; | 144 | int stop_stage; |
@@ -159,7 +147,7 @@ struct iscsi_conn { | |||
159 | unsigned long last_ping; | 147 | unsigned long last_ping; |
160 | int ping_timeout; | 148 | int ping_timeout; |
161 | int recv_timeout; | 149 | int recv_timeout; |
162 | struct iscsi_mgmt_task *ping_mtask; | 150 | struct iscsi_task *ping_task; |
163 | 151 | ||
164 | /* iSCSI connection-wide sequencing */ | 152 | /* iSCSI connection-wide sequencing */ |
165 | uint32_t exp_statsn; | 153 | uint32_t exp_statsn; |
@@ -175,9 +163,8 @@ struct iscsi_conn { | |||
175 | * should always fit in this buffer | 163 | * should always fit in this buffer |
176 | */ | 164 | */ |
177 | char *data; | 165 | char *data; |
178 | struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ | 166 | struct iscsi_task *login_task; /* mtask used for login/text */ |
179 | struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ | 167 | struct iscsi_task *task; /* xmit task in progress */ |
180 | struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ | ||
181 | 168 | ||
182 | /* xmit */ | 169 | /* xmit */ |
183 | struct list_head mgmtqueue; /* mgmt (control) xmit queue */ | 170 | struct list_head mgmtqueue; /* mgmt (control) xmit queue */ |
@@ -208,9 +195,6 @@ struct iscsi_conn { | |||
208 | /* remote portal currently connected to */ | 195 | /* remote portal currently connected to */ |
209 | int portal_port; | 196 | int portal_port; |
210 | char portal_address[ISCSI_ADDRESS_BUF_LEN]; | 197 | char portal_address[ISCSI_ADDRESS_BUF_LEN]; |
211 | /* local address */ | ||
212 | int local_port; | ||
213 | char local_address[ISCSI_ADDRESS_BUF_LEN]; | ||
214 | 198 | ||
215 | /* MIB-statistics */ | 199 | /* MIB-statistics */ |
216 | uint64_t txdata_octets; | 200 | uint64_t txdata_octets; |
@@ -246,6 +230,7 @@ enum { | |||
246 | }; | 230 | }; |
247 | 231 | ||
248 | struct iscsi_session { | 232 | struct iscsi_session { |
233 | struct iscsi_cls_session *cls_session; | ||
249 | /* | 234 | /* |
250 | * Syncs up the scsi eh thread with the iscsi eh thread when sending | 235 | * Syncs up the scsi eh thread with the iscsi eh thread when sending |
251 | * task management functions. This must be taken before the session | 236 | * task management functions. This must be taken before the session |
@@ -281,10 +266,8 @@ struct iscsi_session { | |||
281 | char *password; | 266 | char *password; |
282 | char *password_in; | 267 | char *password_in; |
283 | char *targetname; | 268 | char *targetname; |
269 | char *ifacename; | ||
284 | char *initiatorname; | 270 | char *initiatorname; |
285 | /* hw address or netdev iscsi connection is bound to */ | ||
286 | char *hwaddress; | ||
287 | char *netdev; | ||
288 | /* control data */ | 271 | /* control data */ |
289 | struct iscsi_transport *tt; | 272 | struct iscsi_transport *tt; |
290 | struct Scsi_Host *host; | 273 | struct Scsi_Host *host; |
@@ -298,12 +281,20 @@ struct iscsi_session { | |||
298 | int state; /* session state */ | 281 | int state; /* session state */ |
299 | int age; /* counts session re-opens */ | 282 | int age; /* counts session re-opens */ |
300 | 283 | ||
284 | int scsi_cmds_max; /* max scsi commands */ | ||
301 | int cmds_max; /* size of cmds array */ | 285 | int cmds_max; /* size of cmds array */ |
302 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ | 286 | struct iscsi_task **cmds; /* Original Cmds arr */ |
303 | struct iscsi_pool cmdpool; /* PDU's pool */ | 287 | struct iscsi_pool cmdpool; /* PDU's pool */ |
304 | int mgmtpool_max; /* size of mgmt array */ | 288 | }; |
305 | struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ | 289 | |
306 | struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */ | 290 | struct iscsi_host { |
291 | char *initiatorname; | ||
292 | /* hw address or netdev iscsi connection is bound to */ | ||
293 | char *hwaddress; | ||
294 | char *netdev; | ||
295 | /* local address */ | ||
296 | int local_port; | ||
297 | char local_address[ISCSI_ADDRESS_BUF_LEN]; | ||
307 | }; | 298 | }; |
308 | 299 | ||
309 | /* | 300 | /* |
@@ -316,42 +307,44 @@ extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); | |||
316 | extern int iscsi_queuecommand(struct scsi_cmnd *sc, | 307 | extern int iscsi_queuecommand(struct scsi_cmnd *sc, |
317 | void (*done)(struct scsi_cmnd *)); | 308 | void (*done)(struct scsi_cmnd *)); |
318 | 309 | ||
319 | |||
320 | /* | 310 | /* |
321 | * iSCSI host helpers. | 311 | * iSCSI host helpers. |
322 | */ | 312 | */ |
313 | #define iscsi_host_priv(_shost) \ | ||
314 | (shost_priv(_shost) + sizeof(struct iscsi_host)) | ||
315 | |||
323 | extern int iscsi_host_set_param(struct Scsi_Host *shost, | 316 | extern int iscsi_host_set_param(struct Scsi_Host *shost, |
324 | enum iscsi_host_param param, char *buf, | 317 | enum iscsi_host_param param, char *buf, |
325 | int buflen); | 318 | int buflen); |
326 | extern int iscsi_host_get_param(struct Scsi_Host *shost, | 319 | extern int iscsi_host_get_param(struct Scsi_Host *shost, |
327 | enum iscsi_host_param param, char *buf); | 320 | enum iscsi_host_param param, char *buf); |
321 | extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); | ||
322 | extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, | ||
323 | int dd_data_size, uint16_t qdepth); | ||
324 | extern void iscsi_host_remove(struct Scsi_Host *shost); | ||
325 | extern void iscsi_host_free(struct Scsi_Host *shost); | ||
328 | 326 | ||
329 | /* | 327 | /* |
330 | * session management | 328 | * session management |
331 | */ | 329 | */ |
332 | extern struct iscsi_cls_session * | 330 | extern struct iscsi_cls_session * |
333 | iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *, | 331 | iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, |
334 | uint16_t, uint16_t, int, int, uint32_t, uint32_t *); | 332 | uint16_t, int, uint32_t, unsigned int); |
335 | extern void iscsi_session_teardown(struct iscsi_cls_session *); | 333 | extern void iscsi_session_teardown(struct iscsi_cls_session *); |
336 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); | ||
337 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); | 334 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); |
338 | extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | 335 | extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, |
339 | enum iscsi_param param, char *buf, int buflen); | 336 | enum iscsi_param param, char *buf, int buflen); |
340 | extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | 337 | extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, |
341 | enum iscsi_param param, char *buf); | 338 | enum iscsi_param param, char *buf); |
342 | 339 | ||
343 | #define session_to_cls(_sess) \ | ||
344 | hostdata_session(_sess->host->hostdata) | ||
345 | |||
346 | #define iscsi_session_printk(prefix, _sess, fmt, a...) \ | 340 | #define iscsi_session_printk(prefix, _sess, fmt, a...) \ |
347 | iscsi_cls_session_printk(prefix, \ | 341 | iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a) |
348 | (struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a) | ||
349 | 342 | ||
350 | /* | 343 | /* |
351 | * connection management | 344 | * connection management |
352 | */ | 345 | */ |
353 | extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, | 346 | extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, |
354 | uint32_t); | 347 | int, uint32_t); |
355 | extern void iscsi_conn_teardown(struct iscsi_cls_conn *); | 348 | extern void iscsi_conn_teardown(struct iscsi_cls_conn *); |
356 | extern int iscsi_conn_start(struct iscsi_cls_conn *); | 349 | extern int iscsi_conn_start(struct iscsi_cls_conn *); |
357 | extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); | 350 | extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); |
@@ -360,25 +353,29 @@ extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, | |||
360 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); | 353 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); |
361 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | 354 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, |
362 | enum iscsi_param param, char *buf); | 355 | enum iscsi_param param, char *buf); |
356 | extern void iscsi_suspend_tx(struct iscsi_conn *conn); | ||
363 | 357 | ||
364 | #define iscsi_conn_printk(prefix, _c, fmt, a...) \ | 358 | #define iscsi_conn_printk(prefix, _c, fmt, a...) \ |
365 | iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a) | 359 | iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ |
360 | fmt, ##a) | ||
366 | 361 | ||
367 | /* | 362 | /* |
368 | * pdu and task processing | 363 | * pdu and task processing |
369 | */ | 364 | */ |
370 | extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); | 365 | extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); |
371 | extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *, | 366 | extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *, |
372 | struct iscsi_data *hdr); | 367 | struct iscsi_data *hdr); |
373 | extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, | 368 | extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, |
374 | char *, uint32_t); | 369 | char *, uint32_t); |
375 | extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, | 370 | extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, |
376 | char *, int); | 371 | char *, int); |
377 | extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, | 372 | extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, |
378 | uint32_t *); | 373 | char *, int); |
379 | extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); | 374 | extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); |
380 | extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, | 375 | extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); |
381 | struct iscsi_mgmt_task *mtask); | 376 | extern void iscsi_requeue_task(struct iscsi_task *task); |
377 | extern void iscsi_put_task(struct iscsi_task *task); | ||
378 | extern void __iscsi_get_task(struct iscsi_task *task); | ||
382 | 379 | ||
383 | /* | 380 | /* |
384 | * generic helpers | 381 | * generic helpers |