aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <jejb@titanic.(none)>2005-09-08 10:37:35 -0400
committerJames Bottomley <jejb@titanic.(none)>2005-09-08 10:37:35 -0400
commitf5c7f03113fc9c547012cf403aec4b534d575ef0 (patch)
tree255bd4ff0c5a9314be427cf0695349ac432f9d7c
parentcaf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff)
parent471417c9cfb4c2574e2c03bf2273fe12f5388a8e (diff)
Merge HEAD from ../scsi-iscsi-2.6
-rw-r--r--drivers/scsi/Kconfig25
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/iscsi_tcp.c3627
-rw-r--r--drivers/scsi/iscsi_tcp.h322
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c1379
-rw-r--r--include/scsi/iscsi_if.h245
-rw-r--r--include/scsi/iscsi_proto.h566
-rw-r--r--include/scsi/scsi_transport_iscsi.h202
8 files changed, 5972 insertions, 395 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 2d21265e650b..1c60c568e911 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -229,12 +229,35 @@ config SCSI_FC_ATTRS
229 229
230config SCSI_ISCSI_ATTRS 230config SCSI_ISCSI_ATTRS
231 tristate "iSCSI Transport Attributes" 231 tristate "iSCSI Transport Attributes"
232 depends on SCSI 232 depends on SCSI && NET
233 help 233 help
234 If you wish to export transport-specific information about 234 If you wish to export transport-specific information about
235 each attached iSCSI device to sysfs, say Y. 235 each attached iSCSI device to sysfs, say Y.
236 Otherwise, say N. 236 Otherwise, say N.
237 237
238config ISCSI_TCP
239 tristate "iSCSI Initiator over TCP/IP"
240 depends on SCSI && INET && SCSI_ISCSI_ATTRS
241 select CRYPTO
242 select CRYPTO_MD5
243 select CRYPTO_CRC32C
244 help
245 The iSCSI Driver provides a host with the ability to access storage
246 through an IP network. The driver uses the iSCSI protocol to transport
247 SCSI requests and responses over a TCP/IP network between the host
248 (the "initiator") and "targets". Architecturally, the iSCSI driver
249 combines with the host's TCP/IP stack, network drivers, and Network
250 Interface Card (NIC) to provide the same functions as a SCSI or a
251 Fibre Channel (FC) adapter driver with a Host Bus Adapter (HBA).
252
253 To compile this driver as a module, choose M here: the
254 module will be called iscsi_tcp.
255
256 The userspace component needed to initialize the driver, documentation,
257 and sample configuration files can be found here:
258
259 http://linux-iscsi.sf.net
260
238endmenu 261endmenu
239 262
240menu "SCSI low-level drivers" 263menu "SCSI low-level drivers"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 4b4fd94c2674..2349f902b48a 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_SCSI_SPI_ATTRS) += scsi_transport_spi.o
32obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o 32obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
33obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o 33obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
34 34
35obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o
35obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o 36obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o
36obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o 37obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
37obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o 38obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
new file mode 100644
index 000000000000..810e5e59658f
--- /dev/null
+++ b/drivers/scsi/iscsi_tcp.c
@@ -0,0 +1,3627 @@
1/*
2 * iSCSI Initiator over TCP/IP Data-Path
3 *
4 * Copyright (C) 2004 Dmitry Yusupov
5 * Copyright (C) 2004 Alex Aizman
6 * Copyright (C) 2005 Mike Christie
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 * Credits:
22 * Christoph Hellwig
23 * FUJITA Tomonori
24 * Arne Redlich
25 * Zhenyu Wang
26 */
27
28#include <linux/types.h>
29#include <linux/list.h>
30#include <linux/inet.h>
31#include <linux/blkdev.h>
32#include <linux/crypto.h>
33#include <linux/delay.h>
34#include <linux/kfifo.h>
35#include <linux/scatterlist.h>
36#include <net/tcp.h>
37#include <scsi/scsi_cmnd.h>
38#include <scsi/scsi_device.h>
39#include <scsi/scsi_eh.h>
40#include <scsi/scsi_request.h>
41#include <scsi/scsi_tcq.h>
42#include <scsi/scsi_host.h>
43#include <scsi/scsi.h>
44#include <scsi/scsi_transport_iscsi.h>
45
46#include "iscsi_tcp.h"
47
48MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
49 "Alex Aizman <itn780@yahoo.com>");
50MODULE_DESCRIPTION("iSCSI/TCP data-path");
51MODULE_LICENSE("GPL");
52
53/* #define DEBUG_TCP */
54/* #define DEBUG_SCSI */
55#define DEBUG_ASSERT
56
57#ifdef DEBUG_TCP
58#define debug_tcp(fmt...) printk(KERN_DEBUG "tcp: " fmt)
59#else
60#define debug_tcp(fmt...)
61#endif
62
63#ifdef DEBUG_SCSI
64#define debug_scsi(fmt...) printk(KERN_DEBUG "scsi: " fmt)
65#else
66#define debug_scsi(fmt...)
67#endif
68
69#ifndef DEBUG_ASSERT
70#ifdef BUG_ON
71#undef BUG_ON
72#endif
73#define BUG_ON(expr)
74#endif
75
76#define INVALID_SN_DELTA 0xffff
77
78static unsigned int iscsi_max_lun = 512;
79module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
80
81/* global data */
82static kmem_cache_t *taskcache;
83
84static inline void
85iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size)
86{
87 sg_init_one(&ibuf->sg, (u8 *)vbuf, size);
88 ibuf->sent = 0;
89}
90
91static inline void
92iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
93{
94 ibuf->sg.page = (void*)vbuf;
95 ibuf->sg.offset = (unsigned int)-1;
96 ibuf->sg.length = size;
97 ibuf->sent = 0;
98}
99
100static inline void*
101iscsi_buf_iov_base(struct iscsi_buf *ibuf)
102{
103 return (char*)ibuf->sg.page + ibuf->sent;
104}
105
106static inline void
107iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
108{
109 /*
110 * Fastpath: sg element fits into single page
111 */
112 if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2) {
113 ibuf->sg.page = sg->page;
114 ibuf->sg.offset = sg->offset;
115 ibuf->sg.length = sg->length;
116 } else
117 iscsi_buf_init_iov(ibuf, page_address(sg->page), sg->length);
118 ibuf->sent = 0;
119}
120
121static inline int
122iscsi_buf_left(struct iscsi_buf *ibuf)
123{
124 int rc;
125
126 rc = ibuf->sg.length - ibuf->sent;
127 BUG_ON(rc < 0);
128 return rc;
129}
130
131static inline void
132iscsi_buf_init_hdr(struct iscsi_conn *conn, struct iscsi_buf *ibuf,
133 char *vbuf, u8 *crc)
134{
135 iscsi_buf_init_virt(ibuf, vbuf, sizeof(struct iscsi_hdr));
136 if (conn->hdrdgst_en) {
137 crypto_digest_digest(conn->tx_tfm, &ibuf->sg, 1, crc);
138 ibuf->sg.length += sizeof(uint32_t);
139 }
140}
141
142static void
143iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
144{
145 struct iscsi_session *session = conn->session;
146 unsigned long flags;
147
148 spin_lock_irqsave(&session->lock, flags);
149 if (session->conn_cnt == 1 || session->leadconn == conn)
150 session->state = ISCSI_STATE_FAILED;
151 spin_unlock_irqrestore(&session->lock, flags);
152 set_bit(SUSPEND_BIT, &conn->suspend_tx);
153 set_bit(SUSPEND_BIT, &conn->suspend_rx);
154 iscsi_conn_error(iscsi_handle(conn), err);
155}
156
157static inline int
158iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
159{
160 uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn);
161 uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn);
162
163 if (max_cmdsn < exp_cmdsn -1 &&
164 max_cmdsn > exp_cmdsn - INVALID_SN_DELTA)
165 return ISCSI_ERR_MAX_CMDSN;
166 if (max_cmdsn > session->max_cmdsn ||
167 max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA)
168 session->max_cmdsn = max_cmdsn;
169 if (exp_cmdsn > session->exp_cmdsn ||
170 exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA)
171 session->exp_cmdsn = exp_cmdsn;
172
173 return 0;
174}
175
176static inline int
177iscsi_hdr_extract(struct iscsi_conn *conn)
178{
179 struct sk_buff *skb = conn->in.skb;
180
181 if (conn->in.copy >= conn->hdr_size &&
182 conn->in_progress == IN_PROGRESS_WAIT_HEADER) {
183 /*
184 * Zero-copy PDU Header: using connection context
185 * to store header pointer.
186 */
187 if (skb_shinfo(skb)->frag_list == NULL &&
188 !skb_shinfo(skb)->nr_frags)
189 conn->in.hdr = (struct iscsi_hdr *)
190 ((char*)skb->data + conn->in.offset);
191 else {
192 /* ignoring return code since we checked
193 * in.copy before */
194 skb_copy_bits(skb, conn->in.offset,
195 &conn->hdr, conn->hdr_size);
196 conn->in.hdr = &conn->hdr;
197 }
198 conn->in.offset += conn->hdr_size;
199 conn->in.copy -= conn->hdr_size;
200 } else {
201 int hdr_remains;
202 int copylen;
203
204 /*
205 * PDU header scattered across SKB's,
206 * copying it... This'll happen quite rarely.
207 */
208
209 if (conn->in_progress == IN_PROGRESS_WAIT_HEADER)
210 conn->in.hdr_offset = 0;
211
212 hdr_remains = conn->hdr_size - conn->in.hdr_offset;
213 BUG_ON(hdr_remains <= 0);
214
215 copylen = min(conn->in.copy, hdr_remains);
216 skb_copy_bits(skb, conn->in.offset,
217 (char*)&conn->hdr + conn->in.hdr_offset, copylen);
218
219 debug_tcp("PDU gather offset %d bytes %d in.offset %d "
220 "in.copy %d\n", conn->in.hdr_offset, copylen,
221 conn->in.offset, conn->in.copy);
222
223 conn->in.offset += copylen;
224 conn->in.copy -= copylen;
225 if (copylen < hdr_remains) {
226 conn->in_progress = IN_PROGRESS_HEADER_GATHER;
227 conn->in.hdr_offset += copylen;
228 return -EAGAIN;
229 }
230 conn->in.hdr = &conn->hdr;
231 conn->discontiguous_hdr_cnt++;
232 conn->in_progress = IN_PROGRESS_WAIT_HEADER;
233 }
234
235 return 0;
236}
237
238static inline void
239iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
240{
241 struct scsi_cmnd *sc = ctask->sc;
242 struct iscsi_session *session = conn->session;
243
244 spin_lock(&session->lock);
245 if (unlikely(!sc)) {
246 spin_unlock(&session->lock);
247 return;
248 }
249 if (sc->sc_data_direction == DMA_TO_DEVICE) {
250 struct iscsi_data_task *dtask, *n;
251 /* WRITE: cleanup Data-Out's if any */
252 spin_lock(&conn->lock);
253 list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) {
254 list_del(&dtask->item);
255 mempool_free(dtask, ctask->datapool);
256 }
257 spin_unlock(&conn->lock);
258 }
259 ctask->xmstate = XMSTATE_IDLE;
260 ctask->r2t = NULL;
261 ctask->sc = NULL;
262 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
263 spin_unlock(&session->lock);
264}
265
266/**
267 * iscsi_cmd_rsp - SCSI Command Response processing
268 * @conn: iscsi connection
269 * @ctask: scsi command task
270 **/
271static int
272iscsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
273{
274 int rc;
275 struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)conn->in.hdr;
276 struct iscsi_session *session = conn->session;
277 struct scsi_cmnd *sc = ctask->sc;
278
279 rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
280 if (rc) {
281 sc->result = (DID_ERROR << 16);
282 goto out;
283 }
284
285 conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
286
287 sc->result = (DID_OK << 16) | rhdr->cmd_status;
288
289 if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) {
290 sc->result = (DID_ERROR << 16);
291 goto out;
292 }
293
294 if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION && conn->senselen) {
295 int sensecopy = min(conn->senselen, SCSI_SENSE_BUFFERSIZE);
296
297 memcpy(sc->sense_buffer, conn->data + 2, sensecopy);
298 debug_scsi("copied %d bytes of sense\n", sensecopy);
299 }
300
301 if (sc->sc_data_direction == DMA_TO_DEVICE)
302 goto out;
303
304 if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
305 int res_count = be32_to_cpu(rhdr->residual_count);
306
307 if (res_count > 0 && res_count <= sc->request_bufflen)
308 sc->resid = res_count;
309 else
310 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
311 } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
312 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
313 else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW)
314 sc->resid = be32_to_cpu(rhdr->residual_count);
315
316out:
317 debug_scsi("done [sc %lx res %d itt 0x%x]\n",
318 (long)sc, sc->result, ctask->itt);
319 conn->scsirsp_pdus_cnt++;
320 iscsi_ctask_cleanup(conn, ctask);
321 sc->scsi_done(sc);
322 return rc;
323}
324
325/**
326 * iscsi_data_rsp - SCSI Data-In Response processing
327 * @conn: iscsi connection
328 * @ctask: scsi command task
329 **/
330static int
331iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
332{
333 int rc;
334 struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)conn->in.hdr;
335 struct iscsi_session *session = conn->session;
336 int datasn = be32_to_cpu(rhdr->datasn);
337
338 rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
339 if (rc)
340 return rc;
341 /*
342 * setup Data-In byte counter (gets decremented..)
343 */
344 ctask->data_count = conn->in.datalen;
345
346 if (conn->in.datalen == 0)
347 return 0;
348
349 if (ctask->datasn != datasn)
350 return ISCSI_ERR_DATASN;
351
352 ctask->datasn++;
353
354 ctask->data_offset = be32_to_cpu(rhdr->offset);
355 if (ctask->data_offset + conn->in.datalen > ctask->total_length)
356 return ISCSI_ERR_DATA_OFFSET;
357
358 if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) {
359 struct scsi_cmnd *sc = ctask->sc;
360
361 conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
362 if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
363 int res_count = be32_to_cpu(rhdr->residual_count);
364
365 if (res_count > 0 &&
366 res_count <= sc->request_bufflen) {
367 sc->resid = res_count;
368 sc->result = (DID_OK << 16) | rhdr->cmd_status;
369 } else
370 sc->result = (DID_BAD_TARGET << 16) |
371 rhdr->cmd_status;
372 } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
373 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
374 else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
375 sc->resid = be32_to_cpu(rhdr->residual_count);
376 sc->result = (DID_OK << 16) | rhdr->cmd_status;
377 } else
378 sc->result = (DID_OK << 16) | rhdr->cmd_status;
379 }
380
381 conn->datain_pdus_cnt++;
382 return 0;
383}
384
385/**
386 * iscsi_solicit_data_init - initialize first Data-Out
387 * @conn: iscsi connection
388 * @ctask: scsi command task
389 * @r2t: R2T info
390 *
391 * Notes:
392 * Initialize first Data-Out within this R2T sequence and finds
393 * proper data_offset within this SCSI command.
394 *
395 * This function is called with connection lock taken.
396 **/
397static void
398iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
399 struct iscsi_r2t_info *r2t)
400{
401 struct iscsi_data *hdr;
402 struct iscsi_data_task *dtask;
403 struct scsi_cmnd *sc = ctask->sc;
404
405 dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
406 BUG_ON(!dtask);
407 hdr = &dtask->hdr;
408 memset(hdr, 0, sizeof(struct iscsi_data));
409 hdr->ttt = r2t->ttt;
410 hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
411 r2t->solicit_datasn++;
412 hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
413 memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
414 hdr->itt = ctask->hdr.itt;
415 hdr->exp_statsn = r2t->exp_statsn;
416 hdr->offset = cpu_to_be32(r2t->data_offset);
417 if (r2t->data_length > conn->max_xmit_dlength) {
418 hton24(hdr->dlength, conn->max_xmit_dlength);
419 r2t->data_count = conn->max_xmit_dlength;
420 hdr->flags = 0;
421 } else {
422 hton24(hdr->dlength, r2t->data_length);
423 r2t->data_count = r2t->data_length;
424 hdr->flags = ISCSI_FLAG_CMD_FINAL;
425 }
426 conn->dataout_pdus_cnt++;
427
428 r2t->sent = 0;
429
430 iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr,
431 (u8 *)dtask->hdrext);
432
433 r2t->dtask = dtask;
434
435 if (sc->use_sg) {
436 int i, sg_count = 0;
437 struct scatterlist *sg = sc->request_buffer;
438
439 r2t->sg = NULL;
440 for (i = 0; i < sc->use_sg; i++, sg += 1) {
441 /* FIXME: prefetch ? */
442 if (sg_count + sg->length > r2t->data_offset) {
443 int page_offset;
444
445 /* sg page found! */
446
447 /* offset within this page */
448 page_offset = r2t->data_offset - sg_count;
449
450 /* fill in this buffer */
451 iscsi_buf_init_sg(&r2t->sendbuf, sg);
452 r2t->sendbuf.sg.offset += page_offset;
453 r2t->sendbuf.sg.length -= page_offset;
454
455 /* xmit logic will continue with next one */
456 r2t->sg = sg + 1;
457 break;
458 }
459 sg_count += sg->length;
460 }
461 BUG_ON(r2t->sg == NULL);
462 } else
463 iscsi_buf_init_iov(&ctask->sendbuf,
464 (char*)sc->request_buffer + r2t->data_offset,
465 r2t->data_count);
466
467 list_add(&dtask->item, &ctask->dataqueue);
468}
469
470/**
471 * iscsi_r2t_rsp - iSCSI R2T Response processing
472 * @conn: iscsi connection
473 * @ctask: scsi command task
474 **/
475static int
476iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
477{
478 struct iscsi_r2t_info *r2t;
479 struct iscsi_session *session = conn->session;
480 struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)conn->in.hdr;
481 int r2tsn = be32_to_cpu(rhdr->r2tsn);
482 int rc;
483
484 if (conn->in.ahslen)
485 return ISCSI_ERR_AHSLEN;
486
487 if (conn->in.datalen)
488 return ISCSI_ERR_DATALEN;
489
490 if (ctask->exp_r2tsn && ctask->exp_r2tsn != r2tsn)
491 return ISCSI_ERR_R2TSN;
492
493 rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
494 if (rc)
495 return rc;
496
497 /* FIXME: use R2TSN to detect missing R2T */
498
499 /* fill-in new R2T associated with the task */
500 spin_lock(&session->lock);
501 if (!ctask->sc || ctask->mtask ||
502 session->state != ISCSI_STATE_LOGGED_IN) {
503 printk(KERN_INFO "iscsi_tcp: dropping R2T itt %d in "
504 "recovery...\n", ctask->itt);
505 spin_unlock(&session->lock);
506 return 0;
507 }
508 rc = __kfifo_get(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
509 BUG_ON(!rc);
510
511 r2t->exp_statsn = rhdr->statsn;
512 r2t->data_length = be32_to_cpu(rhdr->data_length);
513 if (r2t->data_length == 0 ||
514 r2t->data_length > session->max_burst) {
515 spin_unlock(&session->lock);
516 return ISCSI_ERR_DATALEN;
517 }
518
519 r2t->data_offset = be32_to_cpu(rhdr->data_offset);
520 if (r2t->data_offset + r2t->data_length > ctask->total_length) {
521 spin_unlock(&session->lock);
522 return ISCSI_ERR_DATALEN;
523 }
524
525 r2t->ttt = rhdr->ttt; /* no flip */
526 r2t->solicit_datasn = 0;
527
528 iscsi_solicit_data_init(conn, ctask, r2t);
529
530 ctask->exp_r2tsn = r2tsn + 1;
531 ctask->xmstate |= XMSTATE_SOL_HDR;
532 __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*));
533 __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*));
534
535 schedule_work(&conn->xmitwork);
536 conn->r2t_pdus_cnt++;
537 spin_unlock(&session->lock);
538
539 return 0;
540}
541
542static int
543iscsi_hdr_recv(struct iscsi_conn *conn)
544{
545 int rc = 0;
546 struct iscsi_hdr *hdr;
547 struct iscsi_cmd_task *ctask;
548 struct iscsi_session *session = conn->session;
549 uint32_t cdgst, rdgst = 0;
550
551 hdr = conn->in.hdr;
552
553 /* verify PDU length */
554 conn->in.datalen = ntoh24(hdr->dlength);
555 if (conn->in.datalen > conn->max_recv_dlength) {
556 printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n",
557 conn->in.datalen, conn->max_recv_dlength);
558 return ISCSI_ERR_DATALEN;
559 }
560 conn->data_copied = 0;
561
562 /* read AHS */
563 conn->in.ahslen = hdr->hlength*(4*sizeof(__u16));
564 conn->in.offset += conn->in.ahslen;
565 conn->in.copy -= conn->in.ahslen;
566 if (conn->in.copy < 0) {
567 printk(KERN_ERR "iscsi_tcp: can't handle AHS with length "
568 "%d bytes\n", conn->in.ahslen);
569 return ISCSI_ERR_AHSLEN;
570 }
571
572 /* calculate read padding */
573 conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1);
574 if (conn->in.padding) {
575 conn->in.padding = ISCSI_PAD_LEN - conn->in.padding;
576 debug_scsi("read padding %d bytes\n", conn->in.padding);
577 }
578
579 if (conn->hdrdgst_en) {
580 struct scatterlist sg;
581
582 sg_init_one(&sg, (u8 *)hdr,
583 sizeof(struct iscsi_hdr) + conn->in.ahslen);
584 crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
585 rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
586 conn->in.ahslen);
587 }
588
589 /* save opcode for later */
590 conn->in.opcode = hdr->opcode;
591
592 /* verify itt (itt encoding: age+cid+itt) */
593 if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
594 if ((hdr->itt & AGE_MASK) !=
595 (session->age << AGE_SHIFT)) {
596 printk(KERN_ERR "iscsi_tcp: received itt %x expected "
597 "session age (%x)\n", hdr->itt,
598 session->age & AGE_MASK);
599 return ISCSI_ERR_BAD_ITT;
600 }
601
602 if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) {
603 printk(KERN_ERR "iscsi_tcp: received itt %x, expected "
604 "CID (%x)\n", hdr->itt, conn->id);
605 return ISCSI_ERR_BAD_ITT;
606 }
607 conn->in.itt = hdr->itt & ITT_MASK;
608 } else
609 conn->in.itt = hdr->itt;
610
611 debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n",
612 hdr->opcode, conn->in.offset, conn->in.copy,
613 conn->in.ahslen, conn->in.datalen);
614
615 if (conn->in.itt < session->cmds_max) {
616 if (conn->hdrdgst_en && cdgst != rdgst) {
617 printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
618 "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
619 cdgst);
620 return ISCSI_ERR_HDR_DGST;
621 }
622
623 ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];
624
625 if (!ctask->sc) {
626 printk(KERN_INFO "iscsi_tcp: dropping ctask with "
627 "itt 0x%x\n", ctask->itt);
628 conn->in.datalen = 0; /* force drop */
629 return 0;
630 }
631
632 if (ctask->sc->SCp.phase != session->age) {
633 printk(KERN_ERR "iscsi_tcp: ctask's session age %d, "
634 "expected %d\n", ctask->sc->SCp.phase,
635 session->age);
636 return ISCSI_ERR_SESSION_FAILED;
637 }
638
639 conn->in.ctask = ctask;
640
641 debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n",
642 hdr->opcode, conn->id, (long)ctask->sc,
643 ctask->itt, conn->in.datalen);
644
645 switch(conn->in.opcode) {
646 case ISCSI_OP_SCSI_CMD_RSP:
647 BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
648 if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE)
649 rc = iscsi_cmd_rsp(conn, ctask);
650 else if (!conn->in.datalen)
651 rc = iscsi_cmd_rsp(conn, ctask);
652 else
653 /*
654 * got sense or response data; copying PDU
655 * Header to the connection's header
656 * placeholder
657 */
658 memcpy(&conn->hdr, hdr,
659 sizeof(struct iscsi_hdr));
660 break;
661 case ISCSI_OP_SCSI_DATA_IN:
662 BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
663 /* save flags for non-exceptional status */
664 conn->in.flags = hdr->flags;
665 /* save cmd_status for sense data */
666 conn->in.cmd_status =
667 ((struct iscsi_data_rsp*)hdr)->cmd_status;
668 rc = iscsi_data_rsp(conn, ctask);
669 break;
670 case ISCSI_OP_R2T:
671 BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
672 if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE &&
673 ctask->sc->sc_data_direction == DMA_TO_DEVICE)
674 rc = iscsi_r2t_rsp(conn, ctask);
675 else
676 rc = ISCSI_ERR_PROTO;
677 break;
678 case ISCSI_OP_NOOP_IN:
679 case ISCSI_OP_TEXT_RSP:
680 case ISCSI_OP_LOGOUT_RSP:
681 case ISCSI_OP_ASYNC_EVENT:
682 case ISCSI_OP_REJECT:
683 rc = iscsi_check_assign_cmdsn(session,
684 (struct iscsi_nopin*)hdr);
685 if (rc)
686 break;
687
688 /* update ExpStatSN */
689 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
690 if (!conn->in.datalen) {
691 struct iscsi_mgmt_task *mtask;
692
693 rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
694 NULL, 0);
695 mtask = (struct iscsi_mgmt_task *)
696 session->mgmt_cmds[conn->in.itt -
697 ISCSI_MGMT_ITT_OFFSET];
698 if (conn->login_mtask != mtask) {
699 spin_lock(&session->lock);
700 __kfifo_put(session->mgmtpool.queue,
701 (void*)&mtask, sizeof(void*));
702 spin_unlock(&session->lock);
703 }
704 }
705 break;
706 default:
707 rc = ISCSI_ERR_BAD_OPCODE;
708 break;
709 }
710 } else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET &&
711 conn->in.itt < ISCSI_MGMT_ITT_OFFSET +
712 session->mgmtpool_max) {
713 struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *)
714 session->mgmt_cmds[conn->in.itt -
715 ISCSI_MGMT_ITT_OFFSET];
716
717 debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
718 conn->in.opcode, conn->id, mtask->itt,
719 conn->in.datalen);
720
721 switch(conn->in.opcode) {
722 case ISCSI_OP_LOGIN_RSP:
723 case ISCSI_OP_TEXT_RSP:
724 rc = iscsi_check_assign_cmdsn(session,
725 (struct iscsi_nopin*)hdr);
726 if (rc)
727 break;
728
729 if (!conn->in.datalen) {
730 rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
731 NULL, 0);
732 if (conn->login_mtask != mtask) {
733 spin_lock(&session->lock);
734 __kfifo_put(session->mgmtpool.queue,
735 (void*)&mtask, sizeof(void*));
736 spin_unlock(&session->lock);
737 }
738 }
739 break;
740 case ISCSI_OP_SCSI_TMFUNC_RSP:
741 rc = iscsi_check_assign_cmdsn(session,
742 (struct iscsi_nopin*)hdr);
743 if (rc)
744 break;
745
746 if (conn->in.datalen || conn->in.ahslen) {
747 rc = ISCSI_ERR_PROTO;
748 break;
749 }
750 conn->tmfrsp_pdus_cnt++;
751 spin_lock(&session->lock);
752 if (conn->tmabort_state == TMABORT_INITIAL) {
753 __kfifo_put(session->mgmtpool.queue,
754 (void*)&mtask, sizeof(void*));
755 conn->tmabort_state =
756 ((struct iscsi_tm_rsp *)hdr)->
757 response == SCSI_TCP_TM_RESP_COMPLETE ?
758 TMABORT_SUCCESS:TMABORT_FAILED;
759 /* unblock eh_abort() */
760 wake_up(&conn->ehwait);
761 }
762 spin_unlock(&session->lock);
763 break;
764 default:
765 rc = ISCSI_ERR_BAD_OPCODE;
766 break;
767 }
768 } else if (conn->in.itt == ISCSI_RESERVED_TAG) {
769 if (conn->in.opcode == ISCSI_OP_NOOP_IN && !conn->in.datalen) {
770 rc = iscsi_check_assign_cmdsn(session,
771 (struct iscsi_nopin*)hdr);
772 if (!rc)
773 rc = iscsi_recv_pdu(iscsi_handle(conn),
774 hdr, NULL, 0);
775 }
776 else
777 rc = ISCSI_ERR_BAD_OPCODE;
778 } else
779 rc = ISCSI_ERR_BAD_ITT;
780
781 return rc;
782}
783
784/**
785 * iscsi_ctask_copy - copy skb bits to the destanation cmd task
786 * @conn: iscsi connection
787 * @ctask: scsi command task
788 * @buf: buffer to copy to
789 * @buf_size: size of buffer
790 * @offset: offset within the buffer
791 *
792 * Notes:
793 * The function calls skb_copy_bits() and updates per-connection and
794 * per-cmd byte counters.
795 *
796 * Read counters (in bytes):
797 *
798 * conn->in.offset offset within in progress SKB
799 * conn->in.copy left to copy from in progress SKB
800 * including padding
801 * conn->in.copied copied already from in progress SKB
802 * conn->data_copied copied already from in progress buffer
803 * ctask->sent total bytes sent up to the MidLayer
804 * ctask->data_count left to copy from in progress Data-In
805 * buf_left left to copy from in progress buffer
806 **/
807static inline int
808iscsi_ctask_copy(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
809 void *buf, int buf_size, int offset)
810{
811 int buf_left = buf_size - (conn->data_copied + offset);
812 int size = min(conn->in.copy, buf_left);
813 int rc;
814
815 size = min(size, ctask->data_count);
816
817 debug_tcp("ctask_copy %d bytes at offset %d copied %d\n",
818 size, conn->in.offset, conn->in.copied);
819
820 BUG_ON(size <= 0);
821 BUG_ON(ctask->sent + size > ctask->total_length);
822
823 rc = skb_copy_bits(conn->in.skb, conn->in.offset,
824 (char*)buf + (offset + conn->data_copied), size);
825 /* must fit into skb->len */
826 BUG_ON(rc);
827
828 conn->in.offset += size;
829 conn->in.copy -= size;
830 conn->in.copied += size;
831 conn->data_copied += size;
832 ctask->sent += size;
833 ctask->data_count -= size;
834
835 BUG_ON(conn->in.copy < 0);
836 BUG_ON(ctask->data_count < 0);
837
838 if (buf_size != (conn->data_copied + offset)) {
839 if (!ctask->data_count) {
840 BUG_ON(buf_size - conn->data_copied < 0);
841 /* done with this PDU */
842 return buf_size - conn->data_copied;
843 }
844 return -EAGAIN;
845 }
846
847 /* done with this buffer or with both - PDU and buffer */
848 conn->data_copied = 0;
849 return 0;
850}
851
852/**
853 * iscsi_tcp_copy - copy skb bits to the destanation buffer
854 * @conn: iscsi connection
855 * @buf: buffer to copy to
856 * @buf_size: number of bytes to copy
857 *
858 * Notes:
859 * The function calls skb_copy_bits() and updates per-connection
860 * byte counters.
861 **/
862static inline int
863iscsi_tcp_copy(struct iscsi_conn *conn, void *buf, int buf_size)
864{
865 int buf_left = buf_size - conn->data_copied;
866 int size = min(conn->in.copy, buf_left);
867 int rc;
868
869 debug_tcp("tcp_copy %d bytes at offset %d copied %d\n",
870 size, conn->in.offset, conn->data_copied);
871 BUG_ON(size <= 0);
872
873 rc = skb_copy_bits(conn->in.skb, conn->in.offset,
874 (char*)buf + conn->data_copied, size);
875 BUG_ON(rc);
876
877 conn->in.offset += size;
878 conn->in.copy -= size;
879 conn->in.copied += size;
880 conn->data_copied += size;
881
882 if (buf_size != conn->data_copied)
883 return -EAGAIN;
884
885 return 0;
886}
887
888static inline void
889partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg,
890 int offset, int length)
891{
892 struct scatterlist temp;
893
894 memcpy(&temp, sg, sizeof(struct scatterlist));
895 temp.offset = offset;
896 temp.length = length;
897 crypto_digest_update(conn->data_rx_tfm, &temp, 1);
898}
899
900static int iscsi_scsi_data_in(struct iscsi_conn *conn)
901{
902 struct iscsi_cmd_task *ctask = conn->in.ctask;
903 struct scsi_cmnd *sc = ctask->sc;
904 struct scatterlist tmp, *sg;
905 int i, offset, rc = 0;
906
907 BUG_ON((void*)ctask != sc->SCp.ptr);
908
909 /*
910 * copying Data-In into the Scsi_Cmnd
911 */
912 if (!sc->use_sg) {
913 i = ctask->data_count;
914 rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer,
915 sc->request_bufflen, ctask->data_offset);
916 if (rc == -EAGAIN)
917 return rc;
918 if (conn->datadgst_en) {
919 sg_init_one(&tmp, sc->request_buffer, i);
920 crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
921 }
922 rc = 0;
923 goto done;
924 }
925
926 offset = ctask->data_offset;
927 sg = sc->request_buffer;
928
929 if (ctask->data_offset)
930 for (i = 0; i < ctask->sg_count; i++)
931 offset -= sg[i].length;
932 /* we've passed through partial sg*/
933 if (offset < 0)
934 offset = 0;
935
936 for (i = ctask->sg_count; i < sc->use_sg; i++) {
937 char *dest;
938
939 dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
940 rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset,
941 sg[i].length, offset);
942 kunmap_atomic(dest, KM_SOFTIRQ0);
943 if (rc == -EAGAIN)
944 /* continue with the next SKB/PDU */
945 return rc;
946 if (!rc) {
947 if (conn->datadgst_en) {
948 if (!offset)
949 crypto_digest_update(conn->data_rx_tfm,
950 &sg[i], 1);
951 else
952 partial_sg_digest_update(conn, &sg[i],
953 sg[i].offset + offset,
954 sg[i].length - offset);
955 }
956 offset = 0;
957 ctask->sg_count++;
958 }
959
960 if (!ctask->data_count) {
961 if (rc && conn->datadgst_en)
962 /*
963 * data-in is complete, but buffer not...
964 */
965 partial_sg_digest_update(conn, &sg[i],
966 sg[i].offset, sg[i].length-rc);
967 rc = 0;
968 break;
969 }
970
971 if (!conn->in.copy)
972 return -EAGAIN;
973 }
974 BUG_ON(ctask->data_count);
975
976done:
977 /* check for non-exceptional status */
978 if (conn->in.flags & ISCSI_FLAG_DATA_STATUS) {
979 debug_scsi("done [sc %lx res %d itt 0x%x]\n",
980 (long)sc, sc->result, ctask->itt);
981 conn->scsirsp_pdus_cnt++;
982 iscsi_ctask_cleanup(conn, ctask);
983 sc->scsi_done(sc);
984 }
985
986 return rc;
987}
988
989static int
990iscsi_data_recv(struct iscsi_conn *conn)
991{
992 struct iscsi_session *session = conn->session;
993 int rc = 0;
994
995 switch(conn->in.opcode) {
996 case ISCSI_OP_SCSI_DATA_IN:
997 rc = iscsi_scsi_data_in(conn);
998 break;
999 case ISCSI_OP_SCSI_CMD_RSP: {
1000 /*
1001 * SCSI Sense Data:
1002 * copying the entire Data Segment.
1003 */
1004 if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) {
1005 rc = -EAGAIN;
1006 goto exit;
1007 }
1008
1009 /*
1010 * check for sense
1011 */
1012 conn->in.hdr = &conn->hdr;
1013 conn->senselen = (conn->data[0] << 8) | conn->data[1];
1014 rc = iscsi_cmd_rsp(conn, conn->in.ctask);
1015 }
1016 break;
1017 case ISCSI_OP_TEXT_RSP:
1018 case ISCSI_OP_LOGIN_RSP:
1019 case ISCSI_OP_NOOP_IN: {
1020 struct iscsi_mgmt_task *mtask = NULL;
1021
1022 if (conn->in.itt != ISCSI_RESERVED_TAG)
1023 mtask = (struct iscsi_mgmt_task *)
1024 session->mgmt_cmds[conn->in.itt -
1025 ISCSI_MGMT_ITT_OFFSET];
1026
1027 /*
1028 * Collect data segment to the connection's data
1029 * placeholder
1030 */
1031 if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) {
1032 rc = -EAGAIN;
1033 goto exit;
1034 }
1035
1036 rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
1037 conn->data, conn->in.datalen);
1038
1039 if (mtask && conn->login_mtask != mtask) {
1040 spin_lock(&session->lock);
1041 __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
1042 sizeof(void*));
1043 spin_unlock(&session->lock);
1044 }
1045 }
1046 break;
1047 default:
1048 BUG_ON(1);
1049 }
1050exit:
1051 return rc;
1052}
1053
1054/**
1055 * iscsi_tcp_data_recv - TCP receive in sendfile fashion
1056 * @rd_desc: read descriptor
1057 * @skb: socket buffer
1058 * @offset: offset in skb
1059 * @len: skb->len - offset
1060 **/
1061static int
1062iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
1063 unsigned int offset, size_t len)
1064{
1065 int rc;
1066 struct iscsi_conn *conn = rd_desc->arg.data;
1067 int start = skb_headlen(skb);
1068 int processed;
1069 char pad[ISCSI_PAD_LEN];
1070 struct scatterlist sg;
1071
1072 /*
1073 * Save current SKB and its offset in the corresponding
1074 * connection context.
1075 */
1076 conn->in.copy = start - offset;
1077 conn->in.offset = offset;
1078 conn->in.skb = skb;
1079 conn->in.len = conn->in.copy;
1080 BUG_ON(conn->in.copy <= 0);
1081 debug_tcp("in %d bytes\n", conn->in.copy);
1082
1083more:
1084 conn->in.copied = 0;
1085 rc = 0;
1086
1087 if (unlikely(conn->suspend_rx)) {
1088 debug_tcp("conn %d Rx suspended!\n", conn->id);
1089 return 0;
1090 }
1091
1092 if (conn->in_progress == IN_PROGRESS_WAIT_HEADER ||
1093 conn->in_progress == IN_PROGRESS_HEADER_GATHER) {
1094 rc = iscsi_hdr_extract(conn);
1095 if (rc) {
1096 if (rc == -EAGAIN)
1097 goto nomore;
1098 else {
1099 iscsi_conn_failure(conn, rc);
1100 return 0;
1101 }
1102 }
1103
1104 /*
1105 * Verify and process incoming PDU header.
1106 */
1107 rc = iscsi_hdr_recv(conn);
1108 if (!rc && conn->in.datalen) {
1109 if (conn->datadgst_en &&
1110 conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
1111 BUG_ON(!conn->data_rx_tfm);
1112 crypto_digest_init(conn->data_rx_tfm);
1113 }
1114 conn->in_progress = IN_PROGRESS_DATA_RECV;
1115 } else if (rc) {
1116 iscsi_conn_failure(conn, rc);
1117 return 0;
1118 }
1119 }
1120
1121 if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
1122 debug_tcp("extra data_recv offset %d copy %d\n",
1123 conn->in.offset, conn->in.copy);
1124 if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
1125 uint32_t recv_digest;
1126 skb_copy_bits(conn->in.skb, conn->in.offset,
1127 &recv_digest, 4);
1128 conn->in.offset += 4;
1129 conn->in.copy -= 4;
1130 if (recv_digest != conn->in.datadgst) {
1131 debug_tcp("iscsi_tcp: data digest error!"
1132 "0x%x != 0x%x\n", recv_digest,
1133 conn->in.datadgst);
1134 iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
1135 return 0;
1136 } else {
1137 debug_tcp("iscsi_tcp: data digest match!"
1138 "0x%x == 0x%x\n", recv_digest,
1139 conn->in.datadgst);
1140 conn->in_progress = IN_PROGRESS_WAIT_HEADER;
1141 }
1142 }
1143 }
1144
1145 if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) {
1146
1147 debug_tcp("data_recv offset %d copy %d\n",
1148 conn->in.offset, conn->in.copy);
1149
1150 rc = iscsi_data_recv(conn);
1151 if (rc) {
1152 if (rc == -EAGAIN) {
1153 rd_desc->count = conn->in.datalen -
1154 conn->in.ctask->data_count;
1155 goto again;
1156 }
1157 iscsi_conn_failure(conn, rc);
1158 return 0;
1159 }
1160 conn->in.copy -= conn->in.padding;
1161 conn->in.offset += conn->in.padding;
1162 if (conn->datadgst_en &&
1163 conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
1164 if (conn->in.padding) {
1165 debug_tcp("padding -> %d\n", conn->in.padding);
1166 memset(pad, 0, conn->in.padding);
1167 sg_init_one(&sg, pad, conn->in.padding);
1168 crypto_digest_update(conn->data_rx_tfm, &sg, 1);
1169 }
1170 crypto_digest_final(conn->data_rx_tfm,
1171 (u8 *) & conn->in.datadgst);
1172 debug_tcp("rx digest 0x%x\n", conn->in.datadgst);
1173 conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
1174 } else
1175 conn->in_progress = IN_PROGRESS_WAIT_HEADER;
1176 }
1177
1178 debug_tcp("f, processed %d from out of %d padding %d\n",
1179 conn->in.offset - offset, (int)len, conn->in.padding);
1180 BUG_ON(conn->in.offset - offset > len);
1181
1182 if (conn->in.offset - offset != len) {
1183 debug_tcp("continue to process %d bytes\n",
1184 (int)len - (conn->in.offset - offset));
1185 goto more;
1186 }
1187
1188nomore:
1189 processed = conn->in.offset - offset;
1190 BUG_ON(processed == 0);
1191 return processed;
1192
1193again:
1194 processed = conn->in.offset - offset;
1195 debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n",
1196 processed, (int)len, (int)rd_desc->count);
1197 BUG_ON(processed == 0);
1198 BUG_ON(processed > len);
1199
1200 conn->rxdata_octets += processed;
1201 return processed;
1202}
1203
1204static void
1205iscsi_tcp_data_ready(struct sock *sk, int flag)
1206{
1207 struct iscsi_conn *conn = sk->sk_user_data;
1208 read_descriptor_t rd_desc;
1209
1210 read_lock(&sk->sk_callback_lock);
1211
1212 /* use rd_desc to pass 'conn' to iscsi_tcp_data_recv */
1213 rd_desc.arg.data = conn;
1214 rd_desc.count = 0;
1215 tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv);
1216
1217 read_unlock(&sk->sk_callback_lock);
1218}
1219
1220static void
1221iscsi_tcp_state_change(struct sock *sk)
1222{
1223 struct iscsi_conn *conn;
1224 struct iscsi_session *session;
1225 void (*old_state_change)(struct sock *);
1226
1227 read_lock(&sk->sk_callback_lock);
1228
1229 conn = (struct iscsi_conn*)sk->sk_user_data;
1230 session = conn->session;
1231
1232 if (sk->sk_state == TCP_CLOSE_WAIT ||
1233 sk->sk_state == TCP_CLOSE) {
1234 debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
1235 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1236 }
1237
1238 old_state_change = conn->old_state_change;
1239
1240 read_unlock(&sk->sk_callback_lock);
1241
1242 old_state_change(sk);
1243}
1244
1245/**
1246 * iscsi_write_space - Called when more output buffer space is available
1247 * @sk: socket space is available for
1248 **/
1249static void
1250iscsi_write_space(struct sock *sk)
1251{
1252 struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data;
1253 conn->old_write_space(sk);
1254 debug_tcp("iscsi_write_space: cid %d\n", conn->id);
1255 clear_bit(SUSPEND_BIT, &conn->suspend_tx);
1256 schedule_work(&conn->xmitwork);
1257}
1258
1259static void
1260iscsi_conn_set_callbacks(struct iscsi_conn *conn)
1261{
1262 struct sock *sk = conn->sock->sk;
1263
1264 /* assign new callbacks */
1265 write_lock_bh(&sk->sk_callback_lock);
1266 sk->sk_user_data = conn;
1267 conn->old_data_ready = sk->sk_data_ready;
1268 conn->old_state_change = sk->sk_state_change;
1269 conn->old_write_space = sk->sk_write_space;
1270 sk->sk_data_ready = iscsi_tcp_data_ready;
1271 sk->sk_state_change = iscsi_tcp_state_change;
1272 sk->sk_write_space = iscsi_write_space;
1273 write_unlock_bh(&sk->sk_callback_lock);
1274}
1275
1276static void
1277iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
1278{
1279 struct sock *sk = conn->sock->sk;
1280
1281 /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
1282 write_lock_bh(&sk->sk_callback_lock);
1283 sk->sk_user_data = NULL;
1284 sk->sk_data_ready = conn->old_data_ready;
1285 sk->sk_state_change = conn->old_state_change;
1286 sk->sk_write_space = conn->old_write_space;
1287 sk->sk_no_check = 0;
1288 write_unlock_bh(&sk->sk_callback_lock);
1289}
1290
1291/**
1292 * iscsi_send - generic send routine
1293 * @sk: kernel's socket
1294 * @buf: buffer to write from
1295 * @size: actual size to write
1296 * @flags: socket's flags
1297 *
1298 * Notes:
1299 * depending on buffer will use tcp_sendpage() or tcp_sendmsg().
1300 * buf->sg.offset == -1 tells us that buffer is non S/G and forces
1301 * to use tcp_sendmsg().
1302 */
1303static inline int
1304iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags)
1305{
1306 int res;
1307
1308 if ((int)buf->sg.offset >= 0) {
1309 int offset = buf->sg.offset + buf->sent;
1310
1311 /* tcp_sendpage */
1312 res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags);
1313 } else {
1314 struct msghdr msg;
1315
1316 buf->iov.iov_base = iscsi_buf_iov_base(buf);
1317 buf->iov.iov_len = size;
1318
1319 memset(&msg, 0, sizeof(struct msghdr));
1320
1321 /* tcp_sendmsg */
1322 res = kernel_sendmsg(sk, &msg, &buf->iov, 1, size);
1323 }
1324
1325 return res;
1326}
1327
1328/**
1329 * iscsi_sendhdr - send PDU Header via tcp_sendpage()
1330 * @conn: iscsi connection
1331 * @buf: buffer to write from
1332 * @datalen: lenght of data to be sent after the header
1333 *
1334 * Notes:
1335 * (Tx, Fast Path)
1336 **/
1337static inline int
1338iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
1339{
1340 struct socket *sk = conn->sock;
1341 int flags = 0; /* MSG_DONTWAIT; */
1342 int res, size;
1343
1344 size = buf->sg.length - buf->sent;
1345 BUG_ON(buf->sent + size > buf->sg.length);
1346 if (buf->sent + size != buf->sg.length || datalen)
1347 flags |= MSG_MORE;
1348
1349 res = iscsi_send(sk, buf, size, flags);
1350 debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
1351 if (res >= 0) {
1352 conn->txdata_octets += res;
1353 buf->sent += res;
1354 if (size != res)
1355 return -EAGAIN;
1356 return 0;
1357 } else if (res == -EAGAIN) {
1358 conn->sendpage_failures_cnt++;
1359 set_bit(SUSPEND_BIT, &conn->suspend_tx);
1360 } else if (res == -EPIPE)
1361 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1362
1363 return res;
1364}
1365
1366/**
1367 * iscsi_sendpage - send one page of iSCSI Data-Out.
1368 * @conn: iscsi connection
1369 * @buf: buffer to write from
1370 * @count: remaining data
1371 * @sent: number of bytes sent
1372 *
1373 * Notes:
1374 * (Tx, Fast Path)
1375 **/
1376static inline int
1377iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
1378 int *count, int *sent)
1379{
1380 struct socket *sk = conn->sock;
1381 int flags = 0; /* MSG_DONTWAIT; */
1382 int res, size;
1383
1384 size = buf->sg.length - buf->sent;
1385 BUG_ON(buf->sent + size > buf->sg.length);
1386 if (size > *count)
1387 size = *count;
1388 if (buf->sent + size != buf->sg.length)
1389 flags |= MSG_MORE;
1390
1391 res = iscsi_send(sk, buf, size, flags);
1392 debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
1393 size, buf->sent, *count, *sent, res);
1394 if (res >= 0) {
1395 conn->txdata_octets += res;
1396 buf->sent += res;
1397 *count -= res;
1398 *sent += res;
1399 if (size != res)
1400 return -EAGAIN;
1401 return 0;
1402 } else if (res == -EAGAIN) {
1403 conn->sendpage_failures_cnt++;
1404 set_bit(SUSPEND_BIT, &conn->suspend_tx);
1405 } else if (res == -EPIPE)
1406 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1407
1408 return res;
1409}
1410
1411static inline void
1412iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1413{
1414 BUG_ON(!conn->data_tx_tfm);
1415 crypto_digest_init(conn->data_tx_tfm);
1416 ctask->digest_count = 4;
1417}
1418
1419static inline void
1420iscsi_buf_data_digest_update(struct iscsi_conn *conn, struct iscsi_buf *buf)
1421{
1422 struct scatterlist sg;
1423
1424 if (buf->sg.offset != -1)
1425 crypto_digest_update(conn->data_tx_tfm, &buf->sg, 1);
1426 else {
1427 sg_init_one(&sg, (char *)buf->sg.page, buf->sg.length);
1428 crypto_digest_update(conn->data_tx_tfm, &sg, 1);
1429 }
1430}
1431
1432static inline int
1433iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1434 struct iscsi_buf *buf, uint32_t *digest, int final)
1435{
1436 int rc = 0;
1437 int sent = 0;
1438
1439 if (final)
1440 crypto_digest_final(conn->data_tx_tfm, (u8*)digest);
1441
1442 iscsi_buf_init_virt(buf, (char*)digest, 4);
1443 rc = iscsi_sendpage(conn, buf, &ctask->digest_count, &sent);
1444 if (rc) {
1445 ctask->datadigest = *digest;
1446 ctask->xmstate |= XMSTATE_DATA_DIGEST;
1447 } else
1448 ctask->digest_count = 4;
1449 return rc;
1450}
1451
1452/**
1453 * iscsi_solicit_data_cont - initialize next Data-Out
1454 * @conn: iscsi connection
1455 * @ctask: scsi command task
1456 * @r2t: R2T info
1457 * @left: bytes left to transfer
1458 *
1459 * Notes:
1460 * Initialize next Data-Out within this R2T sequence and continue
1461 * to process next Scatter-Gather element(if any) of this SCSI command.
1462 *
1463 * Called under connection lock.
1464 **/
1465static void
1466iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1467 struct iscsi_r2t_info *r2t, int left)
1468{
1469 struct iscsi_data *hdr;
1470 struct iscsi_data_task *dtask;
1471 struct scsi_cmnd *sc = ctask->sc;
1472 int new_offset;
1473
1474 dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
1475 BUG_ON(!dtask);
1476 hdr = &dtask->hdr;
1477 memset(hdr, 0, sizeof(struct iscsi_data));
1478 hdr->ttt = r2t->ttt;
1479 hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
1480 r2t->solicit_datasn++;
1481 hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
1482 memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
1483 hdr->itt = ctask->hdr.itt;
1484 hdr->exp_statsn = r2t->exp_statsn;
1485 new_offset = r2t->data_offset + r2t->sent;
1486 hdr->offset = cpu_to_be32(new_offset);
1487 if (left > conn->max_xmit_dlength) {
1488 hton24(hdr->dlength, conn->max_xmit_dlength);
1489 r2t->data_count = conn->max_xmit_dlength;
1490 } else {
1491 hton24(hdr->dlength, left);
1492 r2t->data_count = left;
1493 hdr->flags = ISCSI_FLAG_CMD_FINAL;
1494 }
1495 conn->dataout_pdus_cnt++;
1496
1497 iscsi_buf_init_hdr(conn, &r2t->headbuf, (char*)hdr,
1498 (u8 *)dtask->hdrext);
1499
1500 r2t->dtask = dtask;
1501
1502 if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) {
1503 BUG_ON(ctask->bad_sg == r2t->sg);
1504 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
1505 r2t->sg += 1;
1506 } else
1507 iscsi_buf_init_iov(&ctask->sendbuf,
1508 (char*)sc->request_buffer + new_offset,
1509 r2t->data_count);
1510
1511 list_add(&dtask->item, &ctask->dataqueue);
1512}
1513
1514static void
1515iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1516{
1517 struct iscsi_data *hdr;
1518 struct iscsi_data_task *dtask;
1519
1520 dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
1521 BUG_ON(!dtask);
1522 hdr = &dtask->hdr;
1523 memset(hdr, 0, sizeof(struct iscsi_data));
1524 hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
1525 hdr->datasn = cpu_to_be32(ctask->unsol_datasn);
1526 ctask->unsol_datasn++;
1527 hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
1528 memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
1529 hdr->itt = ctask->hdr.itt;
1530 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
1531 hdr->offset = cpu_to_be32(ctask->total_length -
1532 ctask->r2t_data_count -
1533 ctask->unsol_count);
1534 if (ctask->unsol_count > conn->max_xmit_dlength) {
1535 hton24(hdr->dlength, conn->max_xmit_dlength);
1536 ctask->data_count = conn->max_xmit_dlength;
1537 hdr->flags = 0;
1538 } else {
1539 hton24(hdr->dlength, ctask->unsol_count);
1540 ctask->data_count = ctask->unsol_count;
1541 hdr->flags = ISCSI_FLAG_CMD_FINAL;
1542 }
1543
1544 iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)hdr,
1545 (u8 *)dtask->hdrext);
1546
1547 list_add(&dtask->item, &ctask->dataqueue);
1548
1549 ctask->dtask = dtask;
1550}
1551
1552/**
1553 * iscsi_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
1554 * @conn: iscsi connection
1555 * @ctask: scsi command task
1556 * @sc: scsi command
1557 **/
1558static void
1559iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1560 struct scsi_cmnd *sc)
1561{
1562 struct iscsi_session *session = conn->session;
1563
1564 BUG_ON(__kfifo_len(ctask->r2tqueue));
1565
1566 ctask->sc = sc;
1567 ctask->conn = conn;
1568 ctask->hdr.opcode = ISCSI_OP_SCSI_CMD;
1569 ctask->hdr.flags = ISCSI_ATTR_SIMPLE;
1570 int_to_scsilun(sc->device->lun, (struct scsi_lun *)ctask->hdr.lun);
1571 ctask->hdr.itt = ctask->itt | (conn->id << CID_SHIFT) |
1572 (session->age << AGE_SHIFT);
1573 ctask->hdr.data_length = cpu_to_be32(sc->request_bufflen);
1574 ctask->hdr.cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++;
1575 ctask->hdr.exp_statsn = cpu_to_be32(conn->exp_statsn);
1576 memcpy(ctask->hdr.cdb, sc->cmnd, sc->cmd_len);
1577 memset(&ctask->hdr.cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
1578
1579 ctask->mtask = NULL;
1580 ctask->sent = 0;
1581 ctask->sg_count = 0;
1582
1583 ctask->total_length = sc->request_bufflen;
1584
1585 if (sc->sc_data_direction == DMA_TO_DEVICE) {
1586 ctask->exp_r2tsn = 0;
1587 ctask->hdr.flags |= ISCSI_FLAG_CMD_WRITE;
1588 BUG_ON(ctask->total_length == 0);
1589 if (sc->use_sg) {
1590 struct scatterlist *sg = sc->request_buffer;
1591
1592 iscsi_buf_init_sg(&ctask->sendbuf,
1593 &sg[ctask->sg_count++]);
1594 ctask->sg = sg;
1595 ctask->bad_sg = sg + sc->use_sg;
1596 } else {
1597 iscsi_buf_init_iov(&ctask->sendbuf, sc->request_buffer,
1598 sc->request_bufflen);
1599 }
1600
1601 /*
1602 * Write counters:
1603 *
1604 * imm_count bytes to be sent right after
1605 * SCSI PDU Header
1606 *
1607 * unsol_count bytes(as Data-Out) to be sent
1608 * without R2T ack right after
1609 * immediate data
1610 *
1611 * r2t_data_count bytes to be sent via R2T ack's
1612 *
1613 * pad_count bytes to be sent as zero-padding
1614 */
1615 ctask->imm_count = 0;
1616 ctask->unsol_count = 0;
1617 ctask->unsol_datasn = 0;
1618 ctask->xmstate = XMSTATE_W_HDR;
1619 /* calculate write padding */
1620 ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1);
1621 if (ctask->pad_count) {
1622 ctask->pad_count = ISCSI_PAD_LEN - ctask->pad_count;
1623 debug_scsi("write padding %d bytes\n",
1624 ctask->pad_count);
1625 ctask->xmstate |= XMSTATE_W_PAD;
1626 }
1627 if (session->imm_data_en) {
1628 if (ctask->total_length >= session->first_burst)
1629 ctask->imm_count = min(session->first_burst,
1630 conn->max_xmit_dlength);
1631 else
1632 ctask->imm_count = min(ctask->total_length,
1633 conn->max_xmit_dlength);
1634 hton24(ctask->hdr.dlength, ctask->imm_count);
1635 ctask->xmstate |= XMSTATE_IMM_DATA;
1636 } else
1637 zero_data(ctask->hdr.dlength);
1638
1639 if (!session->initial_r2t_en)
1640 ctask->unsol_count = min(session->first_burst,
1641 ctask->total_length) - ctask->imm_count;
1642 if (!ctask->unsol_count)
1643 /* No unsolicit Data-Out's */
1644 ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL;
1645 else
1646 ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
1647
1648 ctask->r2t_data_count = ctask->total_length -
1649 ctask->imm_count -
1650 ctask->unsol_count;
1651
1652 debug_scsi("cmd [itt %x total %d imm %d imm_data %d "
1653 "r2t_data %d]\n",
1654 ctask->itt, ctask->total_length, ctask->imm_count,
1655 ctask->unsol_count, ctask->r2t_data_count);
1656 } else {
1657 ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL;
1658 if (sc->sc_data_direction == DMA_FROM_DEVICE)
1659 ctask->hdr.flags |= ISCSI_FLAG_CMD_READ;
1660 ctask->datasn = 0;
1661 ctask->xmstate = XMSTATE_R_HDR;
1662 zero_data(ctask->hdr.dlength);
1663 }
1664
1665 iscsi_buf_init_hdr(conn, &ctask->headbuf, (char*)&ctask->hdr,
1666 (u8 *)ctask->hdrext);
1667 conn->scsicmd_pdus_cnt++;
1668}
1669
1670/**
1671 * iscsi_mtask_xmit - xmit management(immediate) task
1672 * @conn: iscsi connection
1673 * @mtask: task management task
1674 *
1675 * Notes:
1676 * The function can return -EAGAIN in which case caller must
1677 * call it again later, or recover. '0' return code means successful
1678 * xmit.
1679 *
1680 * Management xmit state machine consists of two states:
1681 * IN_PROGRESS_IMM_HEAD - PDU Header xmit in progress
1682 * IN_PROGRESS_IMM_DATA - PDU Data xmit in progress
1683 **/
1684static int
1685iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1686{
1687
1688 debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
1689 conn->id, mtask->xmstate, mtask->itt);
1690
1691 if (mtask->xmstate & XMSTATE_IMM_HDR) {
1692 mtask->xmstate &= ~XMSTATE_IMM_HDR;
1693 if (mtask->data_count)
1694 mtask->xmstate |= XMSTATE_IMM_DATA;
1695 if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) {
1696 mtask->xmstate |= XMSTATE_IMM_HDR;
1697 if (mtask->data_count)
1698 mtask->xmstate &= ~XMSTATE_IMM_DATA;
1699 return -EAGAIN;
1700 }
1701 }
1702
1703 if (mtask->xmstate & XMSTATE_IMM_DATA) {
1704 BUG_ON(!mtask->data_count);
1705 mtask->xmstate &= ~XMSTATE_IMM_DATA;
1706 /* FIXME: implement.
1707 * Virtual buffer could be spreaded across multiple pages...
1708 */
1709 do {
1710 if (iscsi_sendpage(conn, &mtask->sendbuf,
1711 &mtask->data_count, &mtask->sent)) {
1712 mtask->xmstate |= XMSTATE_IMM_DATA;
1713 return -EAGAIN;
1714 }
1715 } while (mtask->data_count);
1716 }
1717
1718 BUG_ON(mtask->xmstate != XMSTATE_IDLE);
1719 return 0;
1720}
1721
1722static inline int
1723handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1724{
1725 ctask->xmstate &= ~XMSTATE_R_HDR;
1726 if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
1727 BUG_ON(ctask->xmstate != XMSTATE_IDLE);
1728 return 0; /* wait for Data-In */
1729 }
1730 ctask->xmstate |= XMSTATE_R_HDR;
1731 return -EAGAIN;
1732}
1733
1734static inline int
1735handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1736{
1737 ctask->xmstate &= ~XMSTATE_W_HDR;
1738 if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
1739 ctask->xmstate |= XMSTATE_W_HDR;
1740 return -EAGAIN;
1741 }
1742 return 0;
1743}
1744
1745static inline int
1746handle_xmstate_data_digest(struct iscsi_conn *conn,
1747 struct iscsi_cmd_task *ctask)
1748{
1749 ctask->xmstate &= ~XMSTATE_DATA_DIGEST;
1750 debug_tcp("resent data digest 0x%x\n", ctask->datadigest);
1751 if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
1752 &ctask->datadigest, 0)) {
1753 ctask->xmstate |= XMSTATE_DATA_DIGEST;
1754 debug_tcp("resent data digest 0x%x fail!\n",
1755 ctask->datadigest);
1756 return -EAGAIN;
1757 }
1758 return 0;
1759}
1760
1761static inline int
1762handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1763{
1764 BUG_ON(!ctask->imm_count);
1765 ctask->xmstate &= ~XMSTATE_IMM_DATA;
1766
1767 if (conn->datadgst_en) {
1768 iscsi_data_digest_init(conn, ctask);
1769 ctask->immdigest = 0;
1770 }
1771
1772 for (;;) {
1773 if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->imm_count,
1774 &ctask->sent)) {
1775 ctask->xmstate |= XMSTATE_IMM_DATA;
1776 if (conn->datadgst_en) {
1777 crypto_digest_final(conn->data_tx_tfm,
1778 (u8*)&ctask->immdigest);
1779 debug_tcp("tx imm sendpage fail 0x%x\n",
1780 ctask->datadigest);
1781 }
1782 return -EAGAIN;
1783 }
1784 if (conn->datadgst_en)
1785 iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
1786
1787 if (!ctask->imm_count)
1788 break;
1789 iscsi_buf_init_sg(&ctask->sendbuf,
1790 &ctask->sg[ctask->sg_count++]);
1791 }
1792
1793 if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) {
1794 if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
1795 &ctask->immdigest, 1)) {
1796 debug_tcp("sending imm digest 0x%x fail!\n",
1797 ctask->immdigest);
1798 return -EAGAIN;
1799 }
1800 debug_tcp("sending imm digest 0x%x\n", ctask->immdigest);
1801 }
1802
1803 return 0;
1804}
1805
1806static inline int
1807handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1808{
1809 struct iscsi_data_task *dtask;
1810
1811 ctask->xmstate |= XMSTATE_UNS_DATA;
1812 if (ctask->xmstate & XMSTATE_UNS_INIT) {
1813 iscsi_unsolicit_data_init(conn, ctask);
1814 BUG_ON(!ctask->dtask);
1815 dtask = ctask->dtask;
1816
1817 ctask->xmstate &= ~XMSTATE_UNS_INIT;
1818 }
1819 if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) {
1820 ctask->xmstate &= ~XMSTATE_UNS_DATA;
1821 ctask->xmstate |= XMSTATE_UNS_HDR;
1822 return -EAGAIN;
1823 }
1824
1825 debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
1826 ctask->itt, ctask->unsol_count, ctask->sent);
1827 return 0;
1828}
1829
1830static inline int
1831handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1832{
1833 struct iscsi_data_task *dtask = ctask->dtask;
1834
1835 BUG_ON(!ctask->data_count);
1836 ctask->xmstate &= ~XMSTATE_UNS_DATA;
1837
1838 if (conn->datadgst_en) {
1839 iscsi_data_digest_init(conn, ctask);
1840 dtask->digest = 0;
1841 }
1842
1843 for (;;) {
1844 int start = ctask->sent;
1845
1846 if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->data_count,
1847 &ctask->sent)) {
1848 ctask->unsol_count -= ctask->sent - start;
1849 ctask->xmstate |= XMSTATE_UNS_DATA;
1850 /* will continue with this ctask later.. */
1851 if (conn->datadgst_en) {
1852 crypto_digest_final(conn->data_tx_tfm,
1853 (u8 *)&dtask->digest);
1854 debug_tcp("tx uns data fail 0x%x\n",
1855 dtask->digest);
1856 }
1857 return -EAGAIN;
1858 }
1859
1860 BUG_ON(ctask->sent > ctask->total_length);
1861 ctask->unsol_count -= ctask->sent - start;
1862
1863 /*
1864 * XXX:we may run here with un-initial sendbuf.
1865 * so pass it
1866 */
1867 if (conn->datadgst_en && ctask->sent - start > 0)
1868 iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
1869
1870 if (!ctask->data_count)
1871 break;
1872 iscsi_buf_init_sg(&ctask->sendbuf,
1873 &ctask->sg[ctask->sg_count++]);
1874 }
1875 BUG_ON(ctask->unsol_count < 0);
1876
1877 /*
1878 * Done with the Data-Out. Next, check if we need
1879 * to send another unsolicited Data-Out.
1880 */
1881 if (ctask->unsol_count) {
1882 if (conn->datadgst_en) {
1883 if (iscsi_digest_final_send(conn, ctask,
1884 &dtask->digestbuf,
1885 &dtask->digest, 1)) {
1886 debug_tcp("send uns digest 0x%x fail\n",
1887 dtask->digest);
1888 return -EAGAIN;
1889 }
1890 debug_tcp("sending uns digest 0x%x, more uns\n",
1891 dtask->digest);
1892 }
1893 ctask->xmstate |= XMSTATE_UNS_INIT;
1894 return 1;
1895 }
1896
1897 if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) {
1898 if (iscsi_digest_final_send(conn, ctask,
1899 &dtask->digestbuf,
1900 &dtask->digest, 1)) {
1901 debug_tcp("send last uns digest 0x%x fail\n",
1902 dtask->digest);
1903 return -EAGAIN;
1904 }
1905 debug_tcp("sending uns digest 0x%x\n",dtask->digest);
1906 }
1907
1908 return 0;
1909}
1910
1911static inline int
1912handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1913{
1914 struct iscsi_session *session = conn->session;
1915 struct iscsi_r2t_info *r2t = ctask->r2t;
1916 struct iscsi_data_task *dtask = r2t->dtask;
1917 int left;
1918
1919 ctask->xmstate &= ~XMSTATE_SOL_DATA;
1920 ctask->dtask = dtask;
1921
1922 if (conn->datadgst_en) {
1923 iscsi_data_digest_init(conn, ctask);
1924 dtask->digest = 0;
1925 }
1926solicit_again:
1927 /*
1928 * send Data-Out whitnin this R2T sequence.
1929 */
1930 if (!r2t->data_count)
1931 goto data_out_done;
1932
1933 if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) {
1934 ctask->xmstate |= XMSTATE_SOL_DATA;
1935 /* will continue with this ctask later.. */
1936 if (conn->datadgst_en) {
1937 crypto_digest_final(conn->data_tx_tfm,
1938 (u8 *)&dtask->digest);
1939 debug_tcp("r2t data send fail 0x%x\n", dtask->digest);
1940 }
1941 return -EAGAIN;
1942 }
1943
1944 BUG_ON(r2t->data_count < 0);
1945 if (conn->datadgst_en)
1946 iscsi_buf_data_digest_update(conn, &r2t->sendbuf);
1947
1948 if (r2t->data_count) {
1949 BUG_ON(ctask->sc->use_sg == 0);
1950 if (!iscsi_buf_left(&r2t->sendbuf)) {
1951 BUG_ON(ctask->bad_sg == r2t->sg);
1952 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
1953 r2t->sg += 1;
1954 }
1955 goto solicit_again;
1956 }
1957
1958data_out_done:
1959 /*
1960 * Done with this Data-Out. Next, check if we have
1961 * to send another Data-Out for this R2T.
1962 */
1963 BUG_ON(r2t->data_length - r2t->sent < 0);
1964 left = r2t->data_length - r2t->sent;
1965 if (left) {
1966 if (conn->datadgst_en) {
1967 if (iscsi_digest_final_send(conn, ctask,
1968 &dtask->digestbuf,
1969 &dtask->digest, 1)) {
1970 debug_tcp("send r2t data digest 0x%x"
1971 "fail\n", dtask->digest);
1972 return -EAGAIN;
1973 }
1974 debug_tcp("r2t data send digest 0x%x\n",
1975 dtask->digest);
1976 }
1977 iscsi_solicit_data_cont(conn, ctask, r2t, left);
1978 ctask->xmstate |= XMSTATE_SOL_DATA;
1979 ctask->xmstate &= ~XMSTATE_SOL_HDR;
1980 return 1;
1981 }
1982
1983 /*
1984 * Done with this R2T. Check if there are more
1985 * outstanding R2Ts ready to be processed.
1986 */
1987 BUG_ON(ctask->r2t_data_count - r2t->data_length < 0);
1988 if (conn->datadgst_en) {
1989 if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
1990 &dtask->digest, 1)) {
1991 debug_tcp("send last r2t data digest 0x%x"
1992 "fail\n", dtask->digest);
1993 return -EAGAIN;
1994 }
1995 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
1996 }
1997
1998 ctask->r2t_data_count -= r2t->data_length;
1999 ctask->r2t = NULL;
2000 spin_lock_bh(&session->lock);
2001 __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
2002 spin_unlock_bh(&session->lock);
2003 if (__kfifo_get(ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
2004 ctask->r2t = r2t;
2005 ctask->xmstate |= XMSTATE_SOL_DATA;
2006 ctask->xmstate &= ~XMSTATE_SOL_HDR;
2007 return 1;
2008 }
2009
2010 return 0;
2011}
2012
2013static inline int
2014handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
2015{
2016 struct iscsi_data_task *dtask = ctask->dtask;
2017 int sent;
2018
2019 ctask->xmstate &= ~XMSTATE_W_PAD;
2020 iscsi_buf_init_virt(&ctask->sendbuf, (char*)&ctask->pad,
2021 ctask->pad_count);
2022 if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->pad_count, &sent)) {
2023 ctask->xmstate |= XMSTATE_W_PAD;
2024 return -EAGAIN;
2025 }
2026
2027 if (conn->datadgst_en) {
2028 iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
2029 /* imm data? */
2030 if (!dtask) {
2031 if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
2032 &ctask->immdigest, 1)) {
2033 debug_tcp("send padding digest 0x%x"
2034 "fail!\n", ctask->immdigest);
2035 return -EAGAIN;
2036 }
2037 debug_tcp("done with padding, digest 0x%x\n",
2038 ctask->datadigest);
2039 } else {
2040 if (iscsi_digest_final_send(conn, ctask,
2041 &dtask->digestbuf,
2042 &dtask->digest, 1)) {
2043 debug_tcp("send padding digest 0x%x"
2044 "fail\n", dtask->digest);
2045 return -EAGAIN;
2046 }
2047 debug_tcp("done with padding, digest 0x%x\n",
2048 dtask->digest);
2049 }
2050 }
2051
2052 return 0;
2053}
2054
2055static int
2056iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
2057{
2058 int rc = 0;
2059
2060 debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n",
2061 conn->id, ctask->xmstate, ctask->itt);
2062
2063 /*
2064 * serialize with TMF AbortTask
2065 */
2066 if (ctask->mtask)
2067 return rc;
2068
2069 if (ctask->xmstate & XMSTATE_R_HDR) {
2070 rc = handle_xmstate_r_hdr(conn, ctask);
2071 return rc;
2072 }
2073
2074 if (ctask->xmstate & XMSTATE_W_HDR) {
2075 rc = handle_xmstate_w_hdr(conn, ctask);
2076 if (rc)
2077 return rc;
2078 }
2079
2080 /* XXX: for data digest xmit recover */
2081 if (ctask->xmstate & XMSTATE_DATA_DIGEST) {
2082 rc = handle_xmstate_data_digest(conn, ctask);
2083 if (rc)
2084 return rc;
2085 }
2086
2087 if (ctask->xmstate & XMSTATE_IMM_DATA) {
2088 rc = handle_xmstate_imm_data(conn, ctask);
2089 if (rc)
2090 return rc;
2091 }
2092
2093 if (ctask->xmstate & XMSTATE_UNS_HDR) {
2094 BUG_ON(!ctask->unsol_count);
2095 ctask->xmstate &= ~XMSTATE_UNS_HDR;
2096unsolicit_head_again:
2097 rc = handle_xmstate_uns_hdr(conn, ctask);
2098 if (rc)
2099 return rc;
2100 }
2101
2102 if (ctask->xmstate & XMSTATE_UNS_DATA) {
2103 rc = handle_xmstate_uns_data(conn, ctask);
2104 if (rc == 1)
2105 goto unsolicit_head_again;
2106 else if (rc)
2107 return rc;
2108 goto done;
2109 }
2110
2111 if (ctask->xmstate & XMSTATE_SOL_HDR) {
2112 struct iscsi_r2t_info *r2t;
2113
2114 ctask->xmstate &= ~XMSTATE_SOL_HDR;
2115 ctask->xmstate |= XMSTATE_SOL_DATA;
2116 if (!ctask->r2t)
2117 __kfifo_get(ctask->r2tqueue, (void*)&ctask->r2t,
2118 sizeof(void*));
2119solicit_head_again:
2120 r2t = ctask->r2t;
2121
2122 if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
2123 ctask->xmstate &= ~XMSTATE_SOL_DATA;
2124 ctask->xmstate |= XMSTATE_SOL_HDR;
2125 return -EAGAIN;
2126 }
2127
2128 debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
2129 r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
2130 r2t->sent);
2131 }
2132
2133 if (ctask->xmstate & XMSTATE_SOL_DATA) {
2134 rc = handle_xmstate_sol_data(conn, ctask);
2135 if (rc == 1)
2136 goto solicit_head_again;
2137 if (rc)
2138 return rc;
2139 }
2140
2141done:
2142 /*
2143 * Last thing to check is whether we need to send write
2144 * padding. Note that we check for xmstate equality, not just the bit.
2145 */
2146 if (ctask->xmstate == XMSTATE_W_PAD)
2147 rc = handle_xmstate_w_pad(conn, ctask);
2148
2149 return rc;
2150}
2151
2152/**
2153 * iscsi_data_xmit - xmit any command into the scheduled connection
2154 * @conn: iscsi connection
2155 *
2156 * Notes:
2157 * The function can return -EAGAIN in which case the caller must
2158 * re-schedule it again later or recover. '0' return code means
2159 * successful xmit.
2160 **/
2161static int
2162iscsi_data_xmit(struct iscsi_conn *conn)
2163{
2164 if (unlikely(conn->suspend_tx)) {
2165 debug_tcp("conn %d Tx suspended!\n", conn->id);
2166 return 0;
2167 }
2168
2169 /*
2170 * Transmit in the following order:
2171 *
2172 * 1) un-finished xmit (ctask or mtask)
2173 * 2) immediate control PDUs
2174 * 3) write data
2175 * 4) SCSI commands
2176 * 5) non-immediate control PDUs
2177 *
2178 * No need to lock around __kfifo_get as long as
2179 * there's one producer and one consumer.
2180 */
2181
2182 BUG_ON(conn->ctask && conn->mtask);
2183
2184 if (conn->ctask) {
2185 if (iscsi_ctask_xmit(conn, conn->ctask))
2186 goto again;
2187 /* done with this in-progress ctask */
2188 conn->ctask = NULL;
2189 }
2190 if (conn->mtask) {
2191 if (iscsi_mtask_xmit(conn, conn->mtask))
2192 goto again;
2193 /* done with this in-progress mtask */
2194 conn->mtask = NULL;
2195 }
2196
2197 /* process immediate first */
2198 if (unlikely(__kfifo_len(conn->immqueue))) {
2199 struct iscsi_session *session = conn->session;
2200 while (__kfifo_get(conn->immqueue, (void*)&conn->mtask,
2201 sizeof(void*))) {
2202 if (iscsi_mtask_xmit(conn, conn->mtask))
2203 goto again;
2204
2205 if (conn->mtask->hdr.itt ==
2206 cpu_to_be32(ISCSI_RESERVED_TAG)) {
2207 spin_lock_bh(&session->lock);
2208 __kfifo_put(session->mgmtpool.queue,
2209 (void*)&conn->mtask, sizeof(void*));
2210 spin_unlock_bh(&session->lock);
2211 }
2212 }
2213 /* done with this mtask */
2214 conn->mtask = NULL;
2215 }
2216
2217 /* process write queue */
2218 while (__kfifo_get(conn->writequeue, (void*)&conn->ctask,
2219 sizeof(void*))) {
2220 if (iscsi_ctask_xmit(conn, conn->ctask))
2221 goto again;
2222 }
2223
2224 /* process command queue */
2225 while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask,
2226 sizeof(void*))) {
2227 if (iscsi_ctask_xmit(conn, conn->ctask))
2228 goto again;
2229 }
2230 /* done with this ctask */
2231 conn->ctask = NULL;
2232
2233 /* process the rest control plane PDUs, if any */
2234 if (unlikely(__kfifo_len(conn->mgmtqueue))) {
2235 struct iscsi_session *session = conn->session;
2236
2237 while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask,
2238 sizeof(void*))) {
2239 if (iscsi_mtask_xmit(conn, conn->mtask))
2240 goto again;
2241
2242 if (conn->mtask->hdr.itt ==
2243 cpu_to_be32(ISCSI_RESERVED_TAG)) {
2244 spin_lock_bh(&session->lock);
2245 __kfifo_put(session->mgmtpool.queue,
2246 (void*)&conn->mtask,
2247 sizeof(void*));
2248 spin_unlock_bh(&session->lock);
2249 }
2250 }
2251 /* done with this mtask */
2252 conn->mtask = NULL;
2253 }
2254
2255 return 0;
2256
2257again:
2258 if (unlikely(conn->suspend_tx))
2259 return 0;
2260
2261 return -EAGAIN;
2262}
2263
2264static void
2265iscsi_xmitworker(void *data)
2266{
2267 struct iscsi_conn *conn = data;
2268
2269 /*
2270 * serialize Xmit worker on a per-connection basis.
2271 */
2272 down(&conn->xmitsema);
2273 if (iscsi_data_xmit(conn))
2274 schedule_work(&conn->xmitwork);
2275 up(&conn->xmitsema);
2276}
2277
2278#define FAILURE_BAD_HOST 1
2279#define FAILURE_SESSION_FAILED 2
2280#define FAILURE_SESSION_FREED 3
2281#define FAILURE_WINDOW_CLOSED 4
2282#define FAILURE_SESSION_TERMINATE 5
2283
2284static int
2285iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
2286{
2287 struct Scsi_Host *host;
2288 int reason = 0;
2289 struct iscsi_session *session;
2290 struct iscsi_conn *conn = NULL;
2291 struct iscsi_cmd_task *ctask = NULL;
2292
2293 sc->scsi_done = done;
2294 sc->result = 0;
2295
2296 host = sc->device->host;
2297 session = iscsi_hostdata(host->hostdata);
2298 BUG_ON(host != session->host);
2299
2300 spin_lock(&session->lock);
2301
2302 if (session->state != ISCSI_STATE_LOGGED_IN) {
2303 if (session->state == ISCSI_STATE_FAILED) {
2304 reason = FAILURE_SESSION_FAILED;
2305 goto reject;
2306 } else if (session->state == ISCSI_STATE_TERMINATE) {
2307 reason = FAILURE_SESSION_TERMINATE;
2308 goto fault;
2309 }
2310 reason = FAILURE_SESSION_FREED;
2311 goto fault;
2312 }
2313
2314 /*
2315 * Check for iSCSI window and take care of CmdSN wrap-around
2316 */
2317 if ((int)(session->max_cmdsn - session->cmdsn) < 0) {
2318 reason = FAILURE_WINDOW_CLOSED;
2319 goto reject;
2320 }
2321
2322 conn = session->leadconn;
2323
2324 __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
2325 BUG_ON(ctask->sc);
2326
2327 sc->SCp.phase = session->age;
2328 sc->SCp.ptr = (char*)ctask;
2329 iscsi_cmd_init(conn, ctask, sc);
2330
2331 __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*));
2332 debug_scsi(
2333 "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n",
2334 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
2335 conn->id, (long)sc, ctask->itt, sc->request_bufflen,
2336 session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
2337 spin_unlock(&session->lock);
2338
2339 if (!in_interrupt() && !down_trylock(&conn->xmitsema)) {
2340 spin_unlock_irq(host->host_lock);
2341 if (iscsi_data_xmit(conn))
2342 schedule_work(&conn->xmitwork);
2343 up(&conn->xmitsema);
2344 spin_lock_irq(host->host_lock);
2345 } else
2346 schedule_work(&conn->xmitwork);
2347
2348 return 0;
2349
2350reject:
2351 spin_unlock(&session->lock);
2352 debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason);
2353 return SCSI_MLQUEUE_HOST_BUSY;
2354
2355fault:
2356 spin_unlock(&session->lock);
2357 printk(KERN_ERR "iscsi_tcp: cmd 0x%x is not queued (%d)\n",
2358 sc->cmnd[0], reason);
2359 sc->sense_buffer[0] = 0x70;
2360 sc->sense_buffer[2] = NOT_READY;
2361 sc->sense_buffer[7] = 0x6;
2362 sc->sense_buffer[12] = 0x08;
2363 sc->sense_buffer[13] = 0x00;
2364 sc->result = (DID_NO_CONNECT << 16);
2365 sc->resid = sc->request_bufflen;
2366 sc->scsi_done(sc);
2367 return 0;
2368}
2369
2370static int
2371iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
2372{
2373 int i;
2374
2375 *items = kmalloc(max * sizeof(void*), GFP_KERNEL);
2376 if (*items == NULL)
2377 return -ENOMEM;
2378
2379 q->max = max;
2380 q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL);
2381 if (q->pool == NULL) {
2382 kfree(*items);
2383 return -ENOMEM;
2384 }
2385
2386 q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
2387 GFP_KERNEL, NULL);
2388 if (q->queue == ERR_PTR(-ENOMEM)) {
2389 kfree(q->pool);
2390 kfree(*items);
2391 return -ENOMEM;
2392 }
2393
2394 for (i = 0; i < max; i++) {
2395 q->pool[i] = kmalloc(item_size, GFP_KERNEL);
2396 if (q->pool[i] == NULL) {
2397 int j;
2398
2399 for (j = 0; j < i; j++)
2400 kfree(q->pool[j]);
2401
2402 kfifo_free(q->queue);
2403 kfree(q->pool);
2404 kfree(*items);
2405 return -ENOMEM;
2406 }
2407 memset(q->pool[i], 0, item_size);
2408 (*items)[i] = q->pool[i];
2409 __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
2410 }
2411 return 0;
2412}
2413
2414static void
2415iscsi_pool_free(struct iscsi_queue *q, void **items)
2416{
2417 int i;
2418
2419 for (i = 0; i < q->max; i++)
2420 kfree(items[i]);
2421 kfree(q->pool);
2422 kfree(items);
2423}
2424
2425static iscsi_connh_t
2426iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
2427{
2428 struct iscsi_session *session = iscsi_ptr(sessionh);
2429 struct iscsi_conn *conn = NULL;
2430
2431 conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
2432 if (conn == NULL)
2433 goto conn_alloc_fail;
2434 memset(conn, 0, sizeof(struct iscsi_conn));
2435
2436 conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
2437 conn->in_progress = IN_PROGRESS_WAIT_HEADER;
2438 conn->id = conn_idx;
2439 conn->exp_statsn = 0;
2440 conn->tmabort_state = TMABORT_INITIAL;
2441
2442 /* initial operational parameters */
2443 conn->hdr_size = sizeof(struct iscsi_hdr);
2444 conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
2445 conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
2446
2447 spin_lock_init(&conn->lock);
2448
2449 /* initialize general xmit PDU commands queue */
2450 conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
2451 GFP_KERNEL, NULL);
2452 if (conn->xmitqueue == ERR_PTR(-ENOMEM))
2453 goto xmitqueue_alloc_fail;
2454
2455 /* initialize write response PDU commands queue */
2456 conn->writequeue = kfifo_alloc(session->cmds_max * sizeof(void*),
2457 GFP_KERNEL, NULL);
2458 if (conn->writequeue == ERR_PTR(-ENOMEM))
2459 goto writequeue_alloc_fail;
2460
2461 /* initialize general immediate & non-immediate PDU commands queue */
2462 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
2463 GFP_KERNEL, NULL);
2464 if (conn->immqueue == ERR_PTR(-ENOMEM))
2465 goto immqueue_alloc_fail;
2466
2467 conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
2468 GFP_KERNEL, NULL);
2469 if (conn->mgmtqueue == ERR_PTR(-ENOMEM))
2470 goto mgmtqueue_alloc_fail;
2471
2472 INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn);
2473
2474 /* allocate login_mtask used for the login/text sequences */
2475 spin_lock_bh(&session->lock);
2476 if (!__kfifo_get(session->mgmtpool.queue,
2477 (void*)&conn->login_mtask,
2478 sizeof(void*))) {
2479 spin_unlock_bh(&session->lock);
2480 goto login_mtask_alloc_fail;
2481 }
2482 spin_unlock_bh(&session->lock);
2483
2484 /* allocate initial PDU receive place holder */
2485 if (conn->data_size <= PAGE_SIZE)
2486 conn->data = kmalloc(conn->data_size, GFP_KERNEL);
2487 else
2488 conn->data = (void*)__get_free_pages(GFP_KERNEL,
2489 get_order(conn->data_size));
2490 if (!conn->data)
2491 goto max_recv_dlenght_alloc_fail;
2492
2493 init_timer(&conn->tmabort_timer);
2494 init_MUTEX(&conn->xmitsema);
2495 init_waitqueue_head(&conn->ehwait);
2496
2497 return iscsi_handle(conn);
2498
2499max_recv_dlenght_alloc_fail:
2500 spin_lock_bh(&session->lock);
2501 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
2502 sizeof(void*));
2503 spin_unlock_bh(&session->lock);
2504login_mtask_alloc_fail:
2505 kfifo_free(conn->mgmtqueue);
2506mgmtqueue_alloc_fail:
2507 kfifo_free(conn->immqueue);
2508immqueue_alloc_fail:
2509 kfifo_free(conn->writequeue);
2510writequeue_alloc_fail:
2511 kfifo_free(conn->xmitqueue);
2512xmitqueue_alloc_fail:
2513 kfree(conn);
2514conn_alloc_fail:
2515 return iscsi_handle(NULL);
2516}
2517
2518static void
2519iscsi_conn_destroy(iscsi_connh_t connh)
2520{
2521 struct iscsi_conn *conn = iscsi_ptr(connh);
2522 struct iscsi_session *session = conn->session;
2523
2524 down(&conn->xmitsema);
2525 set_bit(SUSPEND_BIT, &conn->suspend_tx);
2526 if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
2527 struct sock *sk = conn->sock->sk;
2528
2529 /*
2530 * conn_start() has never been called!
2531 * need to cleanup the socket.
2532 */
2533 write_lock_bh(&sk->sk_callback_lock);
2534 set_bit(SUSPEND_BIT, &conn->suspend_rx);
2535 write_unlock_bh(&sk->sk_callback_lock);
2536
2537 sock_hold(conn->sock->sk);
2538 iscsi_conn_restore_callbacks(conn);
2539 sock_put(conn->sock->sk);
2540 sock_release(conn->sock);
2541 conn->sock = NULL;
2542 }
2543
2544 spin_lock_bh(&session->lock);
2545 conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
2546 if (session->leadconn == conn) {
2547 /*
2548 * leading connection? then give up on recovery.
2549 */
2550 session->state = ISCSI_STATE_TERMINATE;
2551 wake_up(&conn->ehwait);
2552 }
2553 spin_unlock_bh(&session->lock);
2554
2555 up(&conn->xmitsema);
2556
2557 /*
2558 * Block until all in-progress commands for this connection
2559 * time out or fail.
2560 */
2561 for (;;) {
2562 spin_lock_bh(&conn->lock);
2563 if (!session->host->host_busy) { /* OK for ERL == 0 */
2564 spin_unlock_bh(&conn->lock);
2565 break;
2566 }
2567 spin_unlock_bh(&conn->lock);
2568 msleep_interruptible(500);
2569 printk("conn_destroy(): host_busy %d host_failed %d\n",
2570 session->host->host_busy, session->host->host_failed);
2571 /*
2572 * force eh_abort() to unblock
2573 */
2574 wake_up(&conn->ehwait);
2575 }
2576
2577 /* now free crypto */
2578 if (conn->hdrdgst_en || conn->datadgst_en) {
2579 if (conn->tx_tfm)
2580 crypto_free_tfm(conn->tx_tfm);
2581 if (conn->rx_tfm)
2582 crypto_free_tfm(conn->rx_tfm);
2583 if (conn->data_tx_tfm)
2584 crypto_free_tfm(conn->data_tx_tfm);
2585 if (conn->data_rx_tfm)
2586 crypto_free_tfm(conn->data_rx_tfm);
2587 }
2588
2589 /* free conn->data, size = MaxRecvDataSegmentLength */
2590 if (conn->data_size <= PAGE_SIZE)
2591 kfree(conn->data);
2592 else
2593 free_pages((unsigned long)conn->data,
2594 get_order(conn->data_size));
2595
2596 spin_lock_bh(&session->lock);
2597 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
2598 sizeof(void*));
2599 list_del(&conn->item);
2600 if (list_empty(&session->connections))
2601 session->leadconn = NULL;
2602 if (session->leadconn && session->leadconn == conn)
2603 session->leadconn = container_of(session->connections.next,
2604 struct iscsi_conn, item);
2605
2606 if (session->leadconn == NULL)
2607 /* none connections exits.. reset sequencing */
2608 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
2609 spin_unlock_bh(&session->lock);
2610
2611 kfifo_free(conn->xmitqueue);
2612 kfifo_free(conn->writequeue);
2613 kfifo_free(conn->immqueue);
2614 kfifo_free(conn->mgmtqueue);
2615 kfree(conn);
2616}
2617
2618static int
2619iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
2620 uint32_t transport_fd, int is_leading)
2621{
2622 struct iscsi_session *session = iscsi_ptr(sessionh);
2623 struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = iscsi_ptr(connh);
2624 struct sock *sk;
2625 struct socket *sock;
2626 int err;
2627
2628 /* lookup for existing socket */
2629 sock = sockfd_lookup(transport_fd, &err);
2630 if (!sock) {
2631 printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
2632 return -EEXIST;
2633 }
2634
2635 /* lookup for existing connection */
2636 spin_lock_bh(&session->lock);
2637 list_for_each_entry(tmp, &session->connections, item) {
2638 if (tmp == conn) {
2639 if (conn->c_stage != ISCSI_CONN_STOPPED ||
2640 conn->stop_stage == STOP_CONN_TERM) {
2641 printk(KERN_ERR "iscsi_tcp: can't bind "
2642 "non-stopped connection (%d:%d)\n",
2643 conn->c_stage, conn->stop_stage);
2644 spin_unlock_bh(&session->lock);
2645 return -EIO;
2646 }
2647 break;
2648 }
2649 }
2650 if (tmp != conn) {
2651 /* bind new iSCSI connection to session */
2652 conn->session = session;
2653
2654 list_add(&conn->item, &session->connections);
2655 }
2656 spin_unlock_bh(&session->lock);
2657
2658 if (conn->stop_stage != STOP_CONN_SUSPEND) {
2659 /* bind iSCSI connection and socket */
2660 conn->sock = sock;
2661
2662 /* setup Socket parameters */
2663 sk = sock->sk;
2664 sk->sk_reuse = 1;
2665 sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
2666 sk->sk_allocation = GFP_ATOMIC;
2667
2668 /* FIXME: disable Nagle's algorithm */
2669
2670 /*
2671 * Intercept TCP callbacks for sendfile like receive
2672 * processing.
2673 */
2674 iscsi_conn_set_callbacks(conn);
2675
2676 /*
2677 * set receive state machine into initial state
2678 */
2679 conn->in_progress = IN_PROGRESS_WAIT_HEADER;
2680 }
2681
2682 if (is_leading)
2683 session->leadconn = conn;
2684
2685 /*
2686 * Unblock xmitworker(), Login Phase will pass through.
2687 */
2688 clear_bit(SUSPEND_BIT, &conn->suspend_rx);
2689 clear_bit(SUSPEND_BIT, &conn->suspend_tx);
2690
2691 return 0;
2692}
2693
2694static int
2695iscsi_conn_start(iscsi_connh_t connh)
2696{
2697 struct iscsi_conn *conn = iscsi_ptr(connh);
2698 struct iscsi_session *session = conn->session;
2699 struct sock *sk;
2700
2701 /* FF phase warming up... */
2702
2703 if (session == NULL) {
2704 printk(KERN_ERR "iscsi_tcp: can't start unbound connection\n");
2705 return -EPERM;
2706 }
2707
2708 sk = conn->sock->sk;
2709
2710 write_lock_bh(&sk->sk_callback_lock);
2711 spin_lock_bh(&session->lock);
2712 conn->c_stage = ISCSI_CONN_STARTED;
2713 session->state = ISCSI_STATE_LOGGED_IN;
2714
2715 switch(conn->stop_stage) {
2716 case STOP_CONN_RECOVER:
2717 /*
2718 * unblock eh_abort() if it is blocked. re-try all
2719 * commands after successful recovery
2720 */
2721 session->conn_cnt++;
2722 conn->stop_stage = 0;
2723 conn->tmabort_state = TMABORT_INITIAL;
2724 session->age++;
2725 wake_up(&conn->ehwait);
2726 break;
2727 case STOP_CONN_TERM:
2728 session->conn_cnt++;
2729 conn->stop_stage = 0;
2730 break;
2731 case STOP_CONN_SUSPEND:
2732 conn->stop_stage = 0;
2733 clear_bit(SUSPEND_BIT, &conn->suspend_rx);
2734 clear_bit(SUSPEND_BIT, &conn->suspend_tx);
2735 break;
2736 default:
2737 break;
2738 }
2739 spin_unlock_bh(&session->lock);
2740 write_unlock_bh(&sk->sk_callback_lock);
2741
2742 return 0;
2743}
2744
2745static void
2746iscsi_conn_stop(iscsi_connh_t connh, int flag)
2747{
2748 struct iscsi_conn *conn = iscsi_ptr(connh);
2749 struct iscsi_session *session = conn->session;
2750 struct sock *sk;
2751 unsigned long flags;
2752
2753 BUG_ON(!conn->sock);
2754 sk = conn->sock->sk;
2755 write_lock_bh(&sk->sk_callback_lock);
2756 set_bit(SUSPEND_BIT, &conn->suspend_rx);
2757 write_unlock_bh(&sk->sk_callback_lock);
2758
2759 down(&conn->xmitsema);
2760
2761 spin_lock_irqsave(session->host->host_lock, flags);
2762 spin_lock(&session->lock);
2763 conn->stop_stage = flag;
2764 conn->c_stage = ISCSI_CONN_STOPPED;
2765 set_bit(SUSPEND_BIT, &conn->suspend_tx);
2766
2767 if (flag != STOP_CONN_SUSPEND)
2768 session->conn_cnt--;
2769
2770 if (session->conn_cnt == 0 || session->leadconn == conn)
2771 session->state = ISCSI_STATE_FAILED;
2772
2773 spin_unlock(&session->lock);
2774 spin_unlock_irqrestore(session->host->host_lock, flags);
2775
2776 if (flag == STOP_CONN_TERM || flag == STOP_CONN_RECOVER) {
2777 struct iscsi_cmd_task *ctask;
2778 struct iscsi_mgmt_task *mtask;
2779
2780 /*
2781 * Socket must go now.
2782 */
2783 sock_hold(conn->sock->sk);
2784 iscsi_conn_restore_callbacks(conn);
2785 sock_put(conn->sock->sk);
2786
2787 /*
2788 * flush xmit queues.
2789 */
2790 spin_lock_bh(&session->lock);
2791 while (__kfifo_get(conn->writequeue, (void*)&ctask,
2792 sizeof(void*)) ||
2793 __kfifo_get(conn->xmitqueue, (void*)&ctask,
2794 sizeof(void*))) {
2795 struct iscsi_r2t_info *r2t;
2796
2797 /*
2798 * flush ctask's r2t queues
2799 */
2800 while (__kfifo_get(ctask->r2tqueue, (void*)&r2t,
2801 sizeof(void*)))
2802 __kfifo_put(ctask->r2tpool.queue, (void*)&r2t,
2803 sizeof(void*));
2804
2805 spin_unlock_bh(&session->lock);
2806 local_bh_disable();
2807 iscsi_ctask_cleanup(conn, ctask);
2808 local_bh_enable();
2809 spin_lock_bh(&session->lock);
2810 }
2811 conn->ctask = NULL;
2812 while (__kfifo_get(conn->immqueue, (void*)&mtask,
2813 sizeof(void*)) ||
2814 __kfifo_get(conn->mgmtqueue, (void*)&mtask,
2815 sizeof(void*))) {
2816 __kfifo_put(session->mgmtpool.queue,
2817 (void*)&mtask, sizeof(void*));
2818 }
2819 conn->mtask = NULL;
2820 spin_unlock_bh(&session->lock);
2821
2822 /*
2823 * release socket only after we stopped data_xmit()
2824 * activity and flushed all outstandings
2825 */
2826 sock_release(conn->sock);
2827 conn->sock = NULL;
2828
2829 /*
2830 * for connection level recovery we should not calculate
2831 * header digest. conn->hdr_size used for optimization
2832 * in hdr_extract() and will be re-negotiated at
2833 * set_param() time.
2834 */
2835 if (flag == STOP_CONN_RECOVER)
2836 conn->hdr_size = sizeof(struct iscsi_hdr);
2837 }
2838 up(&conn->xmitsema);
2839}
2840
2841static int
2842iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
2843 char *data, uint32_t data_size)
2844{
2845 struct iscsi_session *session = conn->session;
2846 struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
2847 struct iscsi_mgmt_task *mtask;
2848
2849 spin_lock_bh(&session->lock);
2850 if (session->state == ISCSI_STATE_TERMINATE) {
2851 spin_unlock_bh(&session->lock);
2852 return -EPERM;
2853 }
2854 if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
2855 hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
2856 /*
2857 * Login and Text are sent serially, in
2858 * request-followed-by-response sequence.
2859 * Same mtask can be used. Same ITT must be used.
2860 * Note that login_mtask is preallocated at conn_create().
2861 */
2862 mtask = conn->login_mtask;
2863 else {
2864 BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
2865 BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
2866
2867 if (!__kfifo_get(session->mgmtpool.queue,
2868 (void*)&mtask, sizeof(void*))) {
2869 spin_unlock_bh(&session->lock);
2870 return -ENOSPC;
2871 }
2872 }
2873
2874 /*
2875 * pre-format CmdSN and ExpStatSN for outgoing PDU.
2876 */
2877 if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
2878 hdr->itt = mtask->itt | (conn->id << CID_SHIFT) |
2879 (session->age << AGE_SHIFT);
2880 nop->cmdsn = cpu_to_be32(session->cmdsn);
2881 if (conn->c_stage == ISCSI_CONN_STARTED &&
2882 !(hdr->opcode & ISCSI_OP_IMMEDIATE))
2883 session->cmdsn++;
2884 } else
2885 /* do not advance CmdSN */
2886 nop->cmdsn = cpu_to_be32(session->cmdsn);
2887
2888 nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
2889
2890 memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr));
2891
2892 if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE ||
2893 conn->stop_stage == STOP_CONN_RECOVER)
2894 iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr,
2895 sizeof(struct iscsi_hdr));
2896 else
2897 /* this will update header digest */
2898 iscsi_buf_init_hdr(conn, &mtask->headbuf, (char*)&mtask->hdr,
2899 (u8 *)mtask->hdrext);
2900
2901 spin_unlock_bh(&session->lock);
2902
2903 if (data_size) {
2904 memcpy(mtask->data, data, data_size);
2905 mtask->data_count = data_size;
2906 } else
2907 mtask->data_count = 0;
2908
2909 mtask->xmstate = XMSTATE_IMM_HDR;
2910
2911 if (mtask->data_count) {
2912 iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data,
2913 mtask->data_count);
2914 }
2915
2916 debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
2917 hdr->opcode, hdr->itt, data_size);
2918
2919 /*
2920 * since send_pdu() could be called at least from two contexts,
2921 * we need to serialize __kfifo_put, so we don't have to take
2922 * additional lock on fast data-path
2923 */
2924 if (hdr->opcode & ISCSI_OP_IMMEDIATE)
2925 __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*));
2926 else
2927 __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
2928
2929 schedule_work(&conn->xmitwork);
2930
2931 return 0;
2932}
2933
2934static int
2935iscsi_eh_host_reset(struct scsi_cmnd *sc)
2936{
2937 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
2938 struct iscsi_conn *conn = ctask->conn;
2939 struct iscsi_session *session = conn->session;
2940
2941 spin_lock_bh(&session->lock);
2942 if (session->state == ISCSI_STATE_TERMINATE) {
2943 debug_scsi("failing host reset: session terminated "
2944 "[CID %d age %d]", conn->id, session->age);
2945 spin_unlock_bh(&session->lock);
2946 return FAILED;
2947 }
2948 spin_unlock_bh(&session->lock);
2949
2950 debug_scsi("failing connection CID %d due to SCSI host reset "
2951 "[itt 0x%x age %d]", conn->id, ctask->itt,
2952 session->age);
2953 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
2954
2955 return SUCCESS;
2956}
2957
2958static void
2959iscsi_tmabort_timedout(unsigned long data)
2960{
2961 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data;
2962 struct iscsi_conn *conn = ctask->conn;
2963 struct iscsi_session *session = conn->session;
2964
2965 spin_lock(&session->lock);
2966 if (conn->tmabort_state == TMABORT_INITIAL) {
2967 __kfifo_put(session->mgmtpool.queue,
2968 (void*)&ctask->mtask, sizeof(void*));
2969 conn->tmabort_state = TMABORT_TIMEDOUT;
2970 debug_scsi("tmabort timedout [sc %lx itt 0x%x]\n",
2971 (long)ctask->sc, ctask->itt);
2972 /* unblock eh_abort() */
2973 wake_up(&conn->ehwait);
2974 }
2975 spin_unlock(&session->lock);
2976}
2977
2978static int
2979iscsi_eh_abort(struct scsi_cmnd *sc)
2980{
2981 int rc;
2982 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
2983 struct iscsi_conn *conn = ctask->conn;
2984 struct iscsi_session *session = conn->session;
2985
2986 conn->eh_abort_cnt++;
2987 debug_scsi("aborting [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
2988
2989 /*
2990 * two cases for ERL=0 here:
2991 *
2992 * 1) connection-level failure;
2993 * 2) recovery due protocol error;
2994 */
2995 down(&conn->xmitsema);
2996 spin_lock_bh(&session->lock);
2997 if (session->state != ISCSI_STATE_LOGGED_IN) {
2998 if (session->state == ISCSI_STATE_TERMINATE) {
2999 spin_unlock_bh(&session->lock);
3000 up(&conn->xmitsema);
3001 goto failed;
3002 }
3003 spin_unlock_bh(&session->lock);
3004 } else {
3005 struct iscsi_tm *hdr = &conn->tmhdr;
3006
3007 /*
3008 * Still LOGGED_IN...
3009 */
3010
3011 if (!ctask->sc || sc->SCp.phase != session->age) {
3012 /*
3013 * 1) ctask completed before time out. But session
3014 * is still ok => Happy Retry.
3015 * 2) session was re-open during time out of ctask.
3016 */
3017 spin_unlock_bh(&session->lock);
3018 up(&conn->xmitsema);
3019 goto success;
3020 }
3021 conn->tmabort_state = TMABORT_INITIAL;
3022 spin_unlock_bh(&session->lock);
3023
3024 /*
3025 * ctask timed out but session is OK
3026 * ERL=0 requires task mgmt abort to be issued on each
3027 * failed command. requests must be serialized.
3028 */
3029 memset(hdr, 0, sizeof(struct iscsi_tm));
3030 hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
3031 hdr->flags = ISCSI_TM_FUNC_ABORT_TASK;
3032 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3033 memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
3034 hdr->rtt = ctask->hdr.itt;
3035 hdr->refcmdsn = ctask->hdr.cmdsn;
3036
3037 rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr,
3038 NULL, 0);
3039 if (rc) {
3040 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
3041 debug_scsi("abort sent failure [itt 0x%x]", ctask->itt);
3042 } else {
3043 struct iscsi_r2t_info *r2t;
3044
3045 /*
3046 * TMF abort vs. TMF response race logic
3047 */
3048 spin_lock_bh(&session->lock);
3049 ctask->mtask = (struct iscsi_mgmt_task *)
3050 session->mgmt_cmds[(hdr->itt & ITT_MASK) -
3051 ISCSI_MGMT_ITT_OFFSET];
3052 /*
3053 * have to flush r2tqueue to avoid r2t leaks
3054 */
3055 while (__kfifo_get(ctask->r2tqueue, (void*)&r2t,
3056 sizeof(void*))) {
3057 __kfifo_put(ctask->r2tpool.queue, (void*)&r2t,
3058 sizeof(void*));
3059 }
3060 if (conn->tmabort_state == TMABORT_INITIAL) {
3061 conn->tmfcmd_pdus_cnt++;
3062 conn->tmabort_timer.expires = 3*HZ + jiffies;
3063 conn->tmabort_timer.function =
3064 iscsi_tmabort_timedout;
3065 conn->tmabort_timer.data = (unsigned long)ctask;
3066 add_timer(&conn->tmabort_timer);
3067 debug_scsi("abort sent [itt 0x%x]", ctask->itt);
3068 } else {
3069 if (!ctask->sc ||
3070 conn->tmabort_state == TMABORT_SUCCESS) {
3071 conn->tmabort_state = TMABORT_INITIAL;
3072 spin_unlock_bh(&session->lock);
3073 up(&conn->xmitsema);
3074 goto success;
3075 }
3076 conn->tmabort_state = TMABORT_INITIAL;
3077 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
3078 }
3079 spin_unlock_bh(&session->lock);
3080 }
3081 }
3082 up(&conn->xmitsema);
3083
3084
3085 /*
3086 * block eh thread until:
3087 *
3088 * 1) abort response;
3089 * 2) abort timeout;
3090 * 3) session re-opened;
3091 * 4) session terminated;
3092 */
3093 for (;;) {
3094 int p_state = session->state;
3095
3096 rc = wait_event_interruptible(conn->ehwait,
3097 (p_state == ISCSI_STATE_LOGGED_IN ?
3098 (session->state == ISCSI_STATE_TERMINATE ||
3099 conn->tmabort_state != TMABORT_INITIAL) :
3100 (session->state == ISCSI_STATE_TERMINATE ||
3101 session->state == ISCSI_STATE_LOGGED_IN)));
3102 if (rc) {
3103 /* shutdown.. */
3104 session->state = ISCSI_STATE_TERMINATE;
3105 goto failed;
3106 }
3107
3108 if (signal_pending(current))
3109 flush_signals(current);
3110
3111 if (session->state == ISCSI_STATE_TERMINATE)
3112 goto failed;
3113
3114 spin_lock_bh(&session->lock);
3115 if (sc->SCp.phase == session->age &&
3116 (conn->tmabort_state == TMABORT_TIMEDOUT ||
3117 conn->tmabort_state == TMABORT_FAILED)) {
3118 conn->tmabort_state = TMABORT_INITIAL;
3119 if (!ctask->sc) {
3120 /*
3121 * ctask completed before tmf abort response or
3122 * time out.
3123 * But session is still ok => Happy Retry.
3124 */
3125 spin_unlock_bh(&session->lock);
3126 break;
3127 }
3128 spin_unlock_bh(&session->lock);
3129 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
3130 continue;
3131 }
3132 spin_unlock_bh(&session->lock);
3133 break;
3134 }
3135
3136success:
3137 debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
3138 rc = SUCCESS;
3139 goto exit;
3140
3141failed:
3142 debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
3143 rc = FAILED;
3144
3145exit:
3146 del_timer_sync(&conn->tmabort_timer);
3147
3148 down(&conn->xmitsema);
3149 if (conn->sock) {
3150 struct sock *sk = conn->sock->sk;
3151
3152 write_lock_bh(&sk->sk_callback_lock);
3153 iscsi_ctask_cleanup(conn, ctask);
3154 write_unlock_bh(&sk->sk_callback_lock);
3155 }
3156 up(&conn->xmitsema);
3157 return rc;
3158}
3159
3160static int
3161iscsi_r2tpool_alloc(struct iscsi_session *session)
3162{
3163 int i;
3164 int cmd_i;
3165
3166 /*
3167 * initialize per-task: R2T pool and xmit queue
3168 */
3169 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
3170 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
3171
3172 /*
3173 * pre-allocated x4 as much r2ts to handle race when
3174 * target acks DataOut faster than we data_xmit() queues
3175 * could replenish r2tqueue.
3176 */
3177
3178 /* R2T pool */
3179 if (iscsi_pool_init(&ctask->r2tpool, session->max_r2t * 4,
3180 (void***)&ctask->r2ts, sizeof(struct iscsi_r2t_info))) {
3181 goto r2t_alloc_fail;
3182 }
3183
3184 /* R2T xmit queue */
3185 ctask->r2tqueue = kfifo_alloc(
3186 session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
3187 if (ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
3188 iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts);
3189 goto r2t_alloc_fail;
3190 }
3191
3192 /*
3193 * number of
3194 * Data-Out PDU's within R2T-sequence can be quite big;
3195 * using mempool
3196 */
3197 ctask->datapool = mempool_create(ISCSI_DTASK_DEFAULT_MAX,
3198 mempool_alloc_slab, mempool_free_slab, taskcache);
3199 if (ctask->datapool == NULL) {
3200 kfifo_free(ctask->r2tqueue);
3201 iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts);
3202 goto r2t_alloc_fail;
3203 }
3204 INIT_LIST_HEAD(&ctask->dataqueue);
3205 }
3206
3207 return 0;
3208
3209r2t_alloc_fail:
3210 for (i = 0; i < cmd_i; i++) {
3211 mempool_destroy(session->cmds[i]->datapool);
3212 kfifo_free(session->cmds[i]->r2tqueue);
3213 iscsi_pool_free(&session->cmds[i]->r2tpool,
3214 (void**)session->cmds[i]->r2ts);
3215 }
3216 return -ENOMEM;
3217}
3218
3219static void
3220iscsi_r2tpool_free(struct iscsi_session *session)
3221{
3222 int i;
3223
3224 for (i = 0; i < session->cmds_max; i++) {
3225 mempool_destroy(session->cmds[i]->datapool);
3226 kfifo_free(session->cmds[i]->r2tqueue);
3227 iscsi_pool_free(&session->cmds[i]->r2tpool,
3228 (void**)session->cmds[i]->r2ts);
3229 }
3230}
3231
3232static struct scsi_host_template iscsi_sht = {
3233 .name = "iSCSI Initiator over TCP/IP, v."
3234 ISCSI_VERSION_STR,
3235 .queuecommand = iscsi_queuecommand,
3236 .can_queue = ISCSI_XMIT_CMDS_MAX - 1,
3237 .sg_tablesize = ISCSI_SG_TABLESIZE,
3238 .cmd_per_lun = ISCSI_CMD_PER_LUN,
3239 .eh_abort_handler = iscsi_eh_abort,
3240 .eh_host_reset_handler = iscsi_eh_host_reset,
3241 .use_clustering = DISABLE_CLUSTERING,
3242 .proc_name = "iscsi_tcp",
3243 .this_id = -1,
3244};
3245
3246static iscsi_sessionh_t
3247iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
3248{
3249 int cmd_i;
3250 struct iscsi_session *session;
3251
3252 session = iscsi_hostdata(host->hostdata);
3253 memset(session, 0, sizeof(struct iscsi_session));
3254
3255 session->host = host;
3256 session->id = host->host_no;
3257 session->state = ISCSI_STATE_LOGGED_IN;
3258 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
3259 session->cmds_max = ISCSI_XMIT_CMDS_MAX;
3260 session->cmdsn = initial_cmdsn;
3261 session->exp_cmdsn = initial_cmdsn + 1;
3262 session->max_cmdsn = initial_cmdsn + 1;
3263 session->max_r2t = 1;
3264
3265 /* initialize SCSI PDU commands pool */
3266 if (iscsi_pool_init(&session->cmdpool, session->cmds_max,
3267 (void***)&session->cmds, sizeof(struct iscsi_cmd_task)))
3268 goto cmdpool_alloc_fail;
3269
3270 /* pre-format cmds pool with ITT */
3271 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++)
3272 session->cmds[cmd_i]->itt = cmd_i;
3273
3274 spin_lock_init(&session->lock);
3275 INIT_LIST_HEAD(&session->connections);
3276
3277 /* initialize immediate command pool */
3278 if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
3279 (void***)&session->mgmt_cmds, sizeof(struct iscsi_mgmt_task)))
3280 goto mgmtpool_alloc_fail;
3281
3282
3283 /* pre-format immediate cmds pool with ITT */
3284 for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
3285 session->mgmt_cmds[cmd_i]->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
3286 session->mgmt_cmds[cmd_i]->data = kmalloc(
3287 DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL);
3288 if (!session->mgmt_cmds[cmd_i]->data) {
3289 int j;
3290
3291 for (j = 0; j < cmd_i; j++)
3292 kfree(session->mgmt_cmds[j]->data);
3293 goto immdata_alloc_fail;
3294 }
3295 }
3296
3297 if (iscsi_r2tpool_alloc(session))
3298 goto r2tpool_alloc_fail;
3299
3300 return iscsi_handle(session);
3301
3302r2tpool_alloc_fail:
3303 for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
3304 kfree(session->mgmt_cmds[cmd_i]->data);
3305 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
3306immdata_alloc_fail:
3307mgmtpool_alloc_fail:
3308 iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
3309cmdpool_alloc_fail:
3310 return iscsi_handle(NULL);
3311}
3312
3313static void
3314iscsi_session_destroy(iscsi_sessionh_t sessionh)
3315{
3316 int cmd_i;
3317 struct iscsi_data_task *dtask, *n;
3318 struct iscsi_session *session = iscsi_ptr(sessionh);
3319
3320 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
3321 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
3322 list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) {
3323 list_del(&dtask->item);
3324 mempool_free(dtask, ctask->datapool);
3325 }
3326 }
3327
3328 for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
3329 kfree(session->mgmt_cmds[cmd_i]->data);
3330
3331 iscsi_r2tpool_free(session);
3332 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
3333 iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
3334}
3335
3336static int
3337iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
3338 uint32_t value)
3339{
3340 struct iscsi_conn *conn = iscsi_ptr(connh);
3341 struct iscsi_session *session = conn->session;
3342
3343 spin_lock_bh(&session->lock);
3344 if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
3345 conn->stop_stage != STOP_CONN_RECOVER) {
3346 printk(KERN_ERR "iscsi_tcp: can not change parameter [%d]\n",
3347 param);
3348 spin_unlock_bh(&session->lock);
3349 return 0;
3350 }
3351 spin_unlock_bh(&session->lock);
3352
3353 switch(param) {
3354 case ISCSI_PARAM_MAX_RECV_DLENGTH: {
3355 char *saveptr = conn->data;
3356 int flags = GFP_KERNEL;
3357
3358 if (conn->data_size >= value) {
3359 conn->max_recv_dlength = value;
3360 break;
3361 }
3362
3363 spin_lock_bh(&session->lock);
3364 if (conn->stop_stage == STOP_CONN_RECOVER)
3365 flags = GFP_ATOMIC;
3366 spin_unlock_bh(&session->lock);
3367
3368 if (value <= PAGE_SIZE)
3369 conn->data = kmalloc(value, flags);
3370 else
3371 conn->data = (void*)__get_free_pages(flags,
3372 get_order(value));
3373 if (conn->data == NULL) {
3374 conn->data = saveptr;
3375 return -ENOMEM;
3376 }
3377 if (conn->data_size <= PAGE_SIZE)
3378 kfree(saveptr);
3379 else
3380 free_pages((unsigned long)saveptr,
3381 get_order(conn->data_size));
3382 conn->max_recv_dlength = value;
3383 conn->data_size = value;
3384 }
3385 break;
3386 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
3387 conn->max_xmit_dlength = value;
3388 break;
3389 case ISCSI_PARAM_HDRDGST_EN:
3390 conn->hdrdgst_en = value;
3391 conn->hdr_size = sizeof(struct iscsi_hdr);
3392 if (conn->hdrdgst_en) {
3393 conn->hdr_size += sizeof(__u32);
3394 if (!conn->tx_tfm)
3395 conn->tx_tfm = crypto_alloc_tfm("crc32c", 0);
3396 if (!conn->tx_tfm)
3397 return -ENOMEM;
3398 if (!conn->rx_tfm)
3399 conn->rx_tfm = crypto_alloc_tfm("crc32c", 0);
3400 if (!conn->rx_tfm) {
3401 crypto_free_tfm(conn->tx_tfm);
3402 return -ENOMEM;
3403 }
3404 } else {
3405 if (conn->tx_tfm)
3406 crypto_free_tfm(conn->tx_tfm);
3407 if (conn->rx_tfm)
3408 crypto_free_tfm(conn->rx_tfm);
3409 }
3410 break;
3411 case ISCSI_PARAM_DATADGST_EN:
3412 conn->datadgst_en = value;
3413 if (conn->datadgst_en) {
3414 if (!conn->data_tx_tfm)
3415 conn->data_tx_tfm =
3416 crypto_alloc_tfm("crc32c", 0);
3417 if (!conn->data_tx_tfm)
3418 return -ENOMEM;
3419 if (!conn->data_rx_tfm)
3420 conn->data_rx_tfm =
3421 crypto_alloc_tfm("crc32c", 0);
3422 if (!conn->data_rx_tfm) {
3423 crypto_free_tfm(conn->data_tx_tfm);
3424 return -ENOMEM;
3425 }
3426 } else {
3427 if (conn->data_tx_tfm)
3428 crypto_free_tfm(conn->data_tx_tfm);
3429 if (conn->data_rx_tfm)
3430 crypto_free_tfm(conn->data_rx_tfm);
3431 }
3432 break;
3433 case ISCSI_PARAM_INITIAL_R2T_EN:
3434 session->initial_r2t_en = value;
3435 break;
3436 case ISCSI_PARAM_MAX_R2T:
3437 if (session->max_r2t == roundup_pow_of_two(value))
3438 break;
3439 iscsi_r2tpool_free(session);
3440 session->max_r2t = value;
3441 if (session->max_r2t & (session->max_r2t - 1))
3442 session->max_r2t = roundup_pow_of_two(session->max_r2t);
3443 if (iscsi_r2tpool_alloc(session))
3444 return -ENOMEM;
3445 break;
3446 case ISCSI_PARAM_IMM_DATA_EN:
3447 session->imm_data_en = value;
3448 break;
3449 case ISCSI_PARAM_FIRST_BURST:
3450 session->first_burst = value;
3451 break;
3452 case ISCSI_PARAM_MAX_BURST:
3453 session->max_burst = value;
3454 break;
3455 case ISCSI_PARAM_PDU_INORDER_EN:
3456 session->pdu_inorder_en = value;
3457 break;
3458 case ISCSI_PARAM_DATASEQ_INORDER_EN:
3459 session->dataseq_inorder_en = value;
3460 break;
3461 case ISCSI_PARAM_ERL:
3462 session->erl = value;
3463 break;
3464 case ISCSI_PARAM_IFMARKER_EN:
3465 BUG_ON(value);
3466 session->ifmarker_en = value;
3467 break;
3468 case ISCSI_PARAM_OFMARKER_EN:
3469 BUG_ON(value);
3470 session->ofmarker_en = value;
3471 break;
3472 default:
3473 break;
3474 }
3475
3476 return 0;
3477}
3478
3479static int
3480iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
3481 uint32_t *value)
3482{
3483 struct iscsi_conn *conn = iscsi_ptr(connh);
3484 struct iscsi_session *session = conn->session;
3485
3486 switch(param) {
3487 case ISCSI_PARAM_MAX_RECV_DLENGTH:
3488 *value = conn->max_recv_dlength;
3489 break;
3490 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
3491 *value = conn->max_xmit_dlength;
3492 break;
3493 case ISCSI_PARAM_HDRDGST_EN:
3494 *value = conn->hdrdgst_en;
3495 break;
3496 case ISCSI_PARAM_DATADGST_EN:
3497 *value = conn->datadgst_en;
3498 break;
3499 case ISCSI_PARAM_INITIAL_R2T_EN:
3500 *value = session->initial_r2t_en;
3501 break;
3502 case ISCSI_PARAM_MAX_R2T:
3503 *value = session->max_r2t;
3504 break;
3505 case ISCSI_PARAM_IMM_DATA_EN:
3506 *value = session->imm_data_en;
3507 break;
3508 case ISCSI_PARAM_FIRST_BURST:
3509 *value = session->first_burst;
3510 break;
3511 case ISCSI_PARAM_MAX_BURST:
3512 *value = session->max_burst;
3513 break;
3514 case ISCSI_PARAM_PDU_INORDER_EN:
3515 *value = session->pdu_inorder_en;
3516 break;
3517 case ISCSI_PARAM_DATASEQ_INORDER_EN:
3518 *value = session->dataseq_inorder_en;
3519 break;
3520 case ISCSI_PARAM_ERL:
3521 *value = session->erl;
3522 break;
3523 case ISCSI_PARAM_IFMARKER_EN:
3524 *value = session->ifmarker_en;
3525 break;
3526 case ISCSI_PARAM_OFMARKER_EN:
3527 *value = session->ofmarker_en;
3528 break;
3529 default:
3530 return ISCSI_ERR_PARAM_NOT_FOUND;
3531 }
3532
3533 return 0;
3534}
3535
3536static void
3537iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
3538{
3539 struct iscsi_conn *conn = iscsi_ptr(connh);
3540
3541 stats->txdata_octets = conn->txdata_octets;
3542 stats->rxdata_octets = conn->rxdata_octets;
3543 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
3544 stats->dataout_pdus = conn->dataout_pdus_cnt;
3545 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
3546 stats->datain_pdus = conn->datain_pdus_cnt;
3547 stats->r2t_pdus = conn->r2t_pdus_cnt;
3548 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
3549 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
3550 stats->custom_length = 3;
3551 strcpy(stats->custom[0].desc, "tx_sendpage_failures");
3552 stats->custom[0].value = conn->sendpage_failures_cnt;
3553 strcpy(stats->custom[1].desc, "rx_discontiguous_hdr");
3554 stats->custom[1].value = conn->discontiguous_hdr_cnt;
3555 strcpy(stats->custom[2].desc, "eh_abort_cnt");
3556 stats->custom[2].value = conn->eh_abort_cnt;
3557}
3558
3559static int
3560iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data,
3561 uint32_t data_size)
3562{
3563 struct iscsi_conn *conn = iscsi_ptr(connh);
3564 int rc;
3565
3566 down(&conn->xmitsema);
3567 rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
3568 up(&conn->xmitsema);
3569
3570 return rc;
3571}
3572
3573static struct iscsi_transport iscsi_tcp_transport = {
3574 .owner = THIS_MODULE,
3575 .name = "tcp",
3576 .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
3577 | CAP_DATADGST,
3578 .host_template = &iscsi_sht,
3579 .hostdata_size = sizeof(struct iscsi_session),
3580 .max_conn = 1,
3581 .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
3582 .create_session = iscsi_session_create,
3583 .destroy_session = iscsi_session_destroy,
3584 .create_conn = iscsi_conn_create,
3585 .bind_conn = iscsi_conn_bind,
3586 .destroy_conn = iscsi_conn_destroy,
3587 .set_param = iscsi_conn_set_param,
3588 .get_param = iscsi_conn_get_param,
3589 .start_conn = iscsi_conn_start,
3590 .stop_conn = iscsi_conn_stop,
3591 .send_pdu = iscsi_conn_send_pdu,
3592 .get_stats = iscsi_conn_get_stats,
3593};
3594
3595static int __init
3596iscsi_tcp_init(void)
3597{
3598 int error;
3599
3600 if (iscsi_max_lun < 1) {
3601 printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
3602 return -EINVAL;
3603 }
3604 iscsi_tcp_transport.max_lun = iscsi_max_lun;
3605
3606 taskcache = kmem_cache_create("iscsi_taskcache",
3607 sizeof(struct iscsi_data_task), 0,
3608 SLAB_HWCACHE_ALIGN | SLAB_NO_REAP, NULL, NULL);
3609 if (!taskcache)
3610 return -ENOMEM;
3611
3612 error = iscsi_register_transport(&iscsi_tcp_transport);
3613 if (error)
3614 kmem_cache_destroy(taskcache);
3615
3616 return error;
3617}
3618
3619static void __exit
3620iscsi_tcp_exit(void)
3621{
3622 iscsi_unregister_transport(&iscsi_tcp_transport);
3623 kmem_cache_destroy(taskcache);
3624}
3625
3626module_init(iscsi_tcp_init);
3627module_exit(iscsi_tcp_exit);
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
83struct iscsi_queue {
84 struct kfifo *queue; /* FIFO Queue */
85 void **pool; /* Pool of elements */
86 int max; /* Max number of elements */
87};
88
89struct iscsi_session;
90struct iscsi_cmd_task;
91struct iscsi_mgmt_task;
92
93/* Socket connection recieve helper */
94struct 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
115struct 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
195struct 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
240struct iscsi_buf {
241 struct scatterlist sg;
242 struct kvec iov;
243 unsigned int sent;
244};
245
246struct 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
255struct 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
267struct 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
281struct 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 */
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 8bb8222ea589..f189ce7541ff 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1,8 +1,10 @@
1/* 1/*
2 * iSCSI transport class definitions 2 * iSCSI transport class definitions
3 * 3 *
4 * Copyright (C) IBM Corporation, 2004 4 * Copyright (C) IBM Corporation, 2004
5 * Copyright (C) Mike Christie, 2004 5 * Copyright (C) Mike Christie, 2004 - 2005
6 * Copyright (C) Dmitry Yusupov, 2004 - 2005
7 * Copyright (C) Alex Aizman, 2004 - 2005
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -19,370 +21,1253 @@
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 22 */
21#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/mempool.h>
25#include <net/tcp.h>
22#include <scsi/scsi.h> 26#include <scsi/scsi.h>
23#include <scsi/scsi_host.h> 27#include <scsi/scsi_host.h>
24#include <scsi/scsi_device.h> 28#include <scsi/scsi_device.h>
25#include <scsi/scsi_transport.h> 29#include <scsi/scsi_transport.h>
26#include <scsi/scsi_transport_iscsi.h> 30#include <scsi/scsi_transport_iscsi.h>
31#include <scsi/iscsi_if.h>
27 32
28#define ISCSI_SESSION_ATTRS 20 33#define ISCSI_SESSION_ATTRS 8
29#define ISCSI_HOST_ATTRS 2 34#define ISCSI_CONN_ATTRS 6
30 35
31struct iscsi_internal { 36struct iscsi_internal {
32 struct scsi_transport_template t; 37 struct scsi_transport_template t;
33 struct iscsi_function_template *fnt; 38 struct iscsi_transport *iscsi_transport;
39 struct list_head list;
40 /*
41 * List of sessions for this transport
42 */
43 struct list_head sessions;
44 /*
45 * lock to serialize access to the sessions list which must
46 * be taken after the rx_queue_sema
47 */
48 spinlock_t session_lock;
49 /*
50 * based on transport capabilities, at register time we set these
51 * bits to tell the transport class it wants attributes displayed
52 * in sysfs or that it can support different iSCSI Data-Path
53 * capabilities
54 */
55 uint32_t param_mask;
56
57 struct class_device cdev;
34 /* 58 /*
35 * We do not have any private or other attrs. 59 * We do not have any private or other attrs.
36 */ 60 */
61 struct transport_container conn_cont;
62 struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
63 struct transport_container session_cont;
37 struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; 64 struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
38 struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
39}; 65};
40 66
41#define to_iscsi_internal(tmpl) container_of(tmpl, struct iscsi_internal, t) 67/*
68 * list of registered transports and lock that must
69 * be held while accessing list. The iscsi_transport_lock must
70 * be acquired after the rx_queue_sema.
71 */
72static LIST_HEAD(iscsi_transports);
73static DEFINE_SPINLOCK(iscsi_transport_lock);
74
75#define to_iscsi_internal(tmpl) \
76 container_of(tmpl, struct iscsi_internal, t)
77
78#define cdev_to_iscsi_internal(_cdev) \
79 container_of(_cdev, struct iscsi_internal, cdev)
80
81static void iscsi_transport_release(struct class_device *cdev)
82{
83 struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
84 kfree(priv);
85}
42 86
43static DECLARE_TRANSPORT_CLASS(iscsi_transport_class, 87/*
44 "iscsi_transport", 88 * iscsi_transport_class represents the iscsi_transports that are
89 * registered.
90 */
91static struct class iscsi_transport_class = {
92 .name = "iscsi_transport",
93 .release = iscsi_transport_release,
94};
95
96static ssize_t
97show_transport_handle(struct class_device *cdev, char *buf)
98{
99 struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
100 return sprintf(buf, "%llu", (unsigned long long)iscsi_handle(priv->iscsi_transport));
101}
102static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
103
104#define show_transport_attr(name, format) \
105static ssize_t \
106show_transport_##name(struct class_device *cdev, char *buf) \
107{ \
108 struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); \
109 return sprintf(buf, format"\n", priv->iscsi_transport->name); \
110} \
111static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
112
113show_transport_attr(caps, "0x%x");
114show_transport_attr(max_lun, "%d");
115show_transport_attr(max_conn, "%d");
116show_transport_attr(max_cmd_len, "%d");
117
118static struct attribute *iscsi_transport_attrs[] = {
119 &class_device_attr_handle.attr,
120 &class_device_attr_caps.attr,
121 &class_device_attr_max_lun.attr,
122 &class_device_attr_max_conn.attr,
123 &class_device_attr_max_cmd_len.attr,
124 NULL,
125};
126
127static struct attribute_group iscsi_transport_group = {
128 .attrs = iscsi_transport_attrs,
129};
130
131static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
132 "iscsi_session",
45 NULL, 133 NULL,
46 NULL, 134 NULL,
47 NULL); 135 NULL);
48 136
49static DECLARE_TRANSPORT_CLASS(iscsi_host_class, 137static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
50 "iscsi_host", 138 "iscsi_connection",
51 NULL, 139 NULL,
52 NULL, 140 NULL,
53 NULL); 141 NULL);
142
143static struct sock *nls;
144static int daemon_pid;
145static DECLARE_MUTEX(rx_queue_sema);
146
147struct mempool_zone {
148 mempool_t *pool;
149 atomic_t allocated;
150 int size;
151 int hiwat;
152 struct list_head freequeue;
153 spinlock_t freelock;
154};
155
156static struct mempool_zone z_reply;
157
54/* 158/*
55 * iSCSI target and session attrs 159 * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
160 * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
161 * so daemon will notice OOM on NETLINK tranposrt level and will
162 * be able to predict or change operational behavior
56 */ 163 */
57#define iscsi_session_show_fn(field, format) \ 164#define Z_MAX_REPLY 8
58 \ 165#define Z_HIWAT_REPLY 6
59static ssize_t \ 166#define Z_MAX_PDU 8
60show_session_##field(struct class_device *cdev, char *buf) \ 167#define Z_HIWAT_PDU 6
61{ \ 168#define Z_MAX_ERROR 16
62 struct scsi_target *starget = transport_class_to_starget(cdev); \ 169#define Z_HIWAT_ERROR 12
63 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 170
64 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ 171struct iscsi_if_conn {
65 \ 172 struct list_head conn_list; /* item in connlist */
66 if (i->fnt->get_##field) \ 173 struct list_head session_list; /* item in session->connections */
67 i->fnt->get_##field(starget); \ 174 iscsi_connh_t connh;
68 return snprintf(buf, 20, format"\n", iscsi_##field(starget)); \ 175 int active; /* must be accessed with the connlock */
176 struct Scsi_Host *host; /* originated shost */
177 struct device dev; /* sysfs transport/container device */
178 struct iscsi_transport *transport;
179 struct mempool_zone z_error;
180 struct mempool_zone z_pdu;
181 struct list_head freequeue;
182};
183
184#define iscsi_dev_to_if_conn(_dev) \
185 container_of(_dev, struct iscsi_if_conn, dev)
186
187#define iscsi_cdev_to_if_conn(_cdev) \
188 iscsi_dev_to_if_conn(_cdev->dev)
189
190static LIST_HEAD(connlist);
191static DEFINE_SPINLOCK(connlock);
192
193struct iscsi_if_session {
194 struct list_head list; /* item in session_list */
195 struct list_head connections;
196 iscsi_sessionh_t sessionh;
197 struct iscsi_transport *transport;
198 struct device dev; /* sysfs transport/container device */
199};
200
201#define iscsi_dev_to_if_session(_dev) \
202 container_of(_dev, struct iscsi_if_session, dev)
203
204#define iscsi_cdev_to_if_session(_cdev) \
205 iscsi_dev_to_if_session(_cdev->dev)
206
207#define iscsi_if_session_to_shost(_session) \
208 dev_to_shost(_session->dev.parent)
209
210static struct iscsi_if_conn*
211iscsi_if_find_conn(uint64_t key)
212{
213 unsigned long flags;
214 struct iscsi_if_conn *conn;
215
216 spin_lock_irqsave(&connlock, flags);
217 list_for_each_entry(conn, &connlist, conn_list)
218 if (conn->connh == key) {
219 spin_unlock_irqrestore(&connlock, flags);
220 return conn;
221 }
222 spin_unlock_irqrestore(&connlock, flags);
223 return NULL;
69} 224}
70 225
71#define iscsi_session_rd_attr(field, format) \ 226static struct iscsi_internal *
72 iscsi_session_show_fn(field, format) \ 227iscsi_if_transport_lookup(struct iscsi_transport *tt)
73static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_##field, NULL); 228{
229 struct iscsi_internal *priv;
230 unsigned long flags;
231
232 spin_lock_irqsave(&iscsi_transport_lock, flags);
233 list_for_each_entry(priv, &iscsi_transports, list) {
234 if (tt == priv->iscsi_transport) {
235 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
236 return priv;
237 }
238 }
239 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
240 return NULL;
241}
74 242
75iscsi_session_rd_attr(tpgt, "%hu"); 243static inline struct list_head *skb_to_lh(struct sk_buff *skb)
76iscsi_session_rd_attr(tsih, "%2x"); 244{
77iscsi_session_rd_attr(max_recv_data_segment_len, "%u"); 245 return (struct list_head *)&skb->cb;
78iscsi_session_rd_attr(max_burst_len, "%u"); 246}
79iscsi_session_rd_attr(first_burst_len, "%u");
80iscsi_session_rd_attr(def_time2wait, "%hu");
81iscsi_session_rd_attr(def_time2retain, "%hu");
82iscsi_session_rd_attr(max_outstanding_r2t, "%hu");
83iscsi_session_rd_attr(erl, "%d");
84 247
248static void*
249mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
250{
251 struct mempool_zone *zone = pool_data;
85 252
86#define iscsi_session_show_bool_fn(field) \ 253 return alloc_skb(zone->size, gfp_mask);
87 \
88static ssize_t \
89show_session_bool_##field(struct class_device *cdev, char *buf) \
90{ \
91 struct scsi_target *starget = transport_class_to_starget(cdev); \
92 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
93 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
94 \
95 if (i->fnt->get_##field) \
96 i->fnt->get_##field(starget); \
97 \
98 if (iscsi_##field(starget)) \
99 return sprintf(buf, "Yes\n"); \
100 return sprintf(buf, "No\n"); \
101} 254}
102 255
103#define iscsi_session_rd_bool_attr(field) \ 256static void
104 iscsi_session_show_bool_fn(field) \ 257mempool_zone_free_skb(void *element, void *pool_data)
105static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_bool_##field, NULL); 258{
259 kfree_skb(element);
260}
106 261
107iscsi_session_rd_bool_attr(initial_r2t); 262static void
108iscsi_session_rd_bool_attr(immediate_data); 263mempool_zone_complete(struct mempool_zone *zone)
109iscsi_session_rd_bool_attr(data_pdu_in_order); 264{
110iscsi_session_rd_bool_attr(data_sequence_in_order); 265 unsigned long flags;
266 struct list_head *lh, *n;
111 267
112#define iscsi_session_show_digest_fn(field) \ 268 spin_lock_irqsave(&zone->freelock, flags);
113 \ 269 list_for_each_safe(lh, n, &zone->freequeue) {
114static ssize_t \ 270 struct sk_buff *skb = (struct sk_buff *)((char *)lh -
115show_##field(struct class_device *cdev, char *buf) \ 271 offsetof(struct sk_buff, cb));
116{ \ 272 if (!skb_shared(skb)) {
117 struct scsi_target *starget = transport_class_to_starget(cdev); \ 273 list_del(skb_to_lh(skb));
118 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 274 mempool_free(skb, zone->pool);
119 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ 275 atomic_dec(&zone->allocated);
120 \ 276 }
121 if (i->fnt->get_##field) \ 277 }
122 i->fnt->get_##field(starget); \ 278 spin_unlock_irqrestore(&zone->freelock, flags);
123 \
124 if (iscsi_##field(starget)) \
125 return sprintf(buf, "CRC32C\n"); \
126 return sprintf(buf, "None\n"); \
127} 279}
128 280
129#define iscsi_session_rd_digest_attr(field) \ 281static int
130 iscsi_session_show_digest_fn(field) \ 282mempool_zone_init(struct mempool_zone *zp, unsigned max, unsigned size,
131static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 283 unsigned hiwat)
284{
285 zp->pool = mempool_create(max, mempool_zone_alloc_skb,
286 mempool_zone_free_skb, zp);
287 if (!zp->pool)
288 return -ENOMEM;
132 289
133iscsi_session_rd_digest_attr(header_digest); 290 zp->size = size;
134iscsi_session_rd_digest_attr(data_digest); 291 zp->hiwat = hiwat;
135 292
136static ssize_t 293 INIT_LIST_HEAD(&zp->freequeue);
137show_port(struct class_device *cdev, char *buf) 294 spin_lock_init(&zp->freelock);
295 atomic_set(&zp->allocated, 0);
296
297 return 0;
298}
299
300
301static struct sk_buff*
302mempool_zone_get_skb(struct mempool_zone *zone)
138{ 303{
139 struct scsi_target *starget = transport_class_to_starget(cdev); 304 struct sk_buff *skb;
140 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 305
141 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); 306 skb = mempool_alloc(zone->pool, GFP_ATOMIC);
307 if (skb)
308 atomic_inc(&zone->allocated);
309 return skb;
310}
142 311
143 if (i->fnt->get_port) 312static int
144 i->fnt->get_port(starget); 313iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
314{
315 unsigned long flags;
316 int rc;
145 317
146 return snprintf(buf, 20, "%hu\n", ntohs(iscsi_port(starget))); 318 skb_get(skb);
319 rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
320 if (rc < 0) {
321 mempool_free(skb, zone->pool);
322 printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
323 return rc;
324 }
325
326 spin_lock_irqsave(&zone->freelock, flags);
327 list_add(skb_to_lh(skb), &zone->freequeue);
328 spin_unlock_irqrestore(&zone->freelock, flags);
329
330 return 0;
147} 331}
148static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
149 332
150static ssize_t 333int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr,
151show_ip_address(struct class_device *cdev, char *buf) 334 char *data, uint32_t data_size)
152{ 335{
153 struct scsi_target *starget = transport_class_to_starget(cdev); 336 struct nlmsghdr *nlh;
154 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 337 struct sk_buff *skb;
155 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); 338 struct iscsi_uevent *ev;
339 struct iscsi_if_conn *conn;
340 char *pdu;
341 int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
342 data_size);
343
344 conn = iscsi_if_find_conn(connh);
345 BUG_ON(!conn);
346
347 mempool_zone_complete(&conn->z_pdu);
348
349 skb = mempool_zone_get_skb(&conn->z_pdu);
350 if (!skb) {
351 iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED);
352 printk(KERN_ERR "iscsi%d: can not deliver control PDU: OOM\n",
353 conn->host->host_no);
354 return -ENOMEM;
355 }
156 356
157 if (i->fnt->get_ip_address) 357 nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
158 i->fnt->get_ip_address(starget); 358 ev = NLMSG_DATA(nlh);
359 memset(ev, 0, sizeof(*ev));
360 ev->transport_handle = iscsi_handle(conn->transport);
361 ev->type = ISCSI_KEVENT_RECV_PDU;
362 if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)
363 ev->iferror = -ENOMEM;
364 ev->r.recv_req.conn_handle = connh;
365 pdu = (char*)ev + sizeof(*ev);
366 memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
367 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
159 368
160 if (iscsi_addr_type(starget) == AF_INET) 369 return iscsi_unicast_skb(&conn->z_pdu, skb);
161 return sprintf(buf, "%u.%u.%u.%u\n",
162 NIPQUAD(iscsi_sin_addr(starget)));
163 else if(iscsi_addr_type(starget) == AF_INET6)
164 return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
165 NIP6(iscsi_sin6_addr(starget)));
166 return -EINVAL;
167} 370}
168static CLASS_DEVICE_ATTR(ip_address, S_IRUGO, show_ip_address, NULL); 371EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
169 372
170static ssize_t 373void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error)
171show_isid(struct class_device *cdev, char *buf)
172{ 374{
173 struct scsi_target *starget = transport_class_to_starget(cdev); 375 struct nlmsghdr *nlh;
174 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 376 struct sk_buff *skb;
175 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); 377 struct iscsi_uevent *ev;
378 struct iscsi_if_conn *conn;
379 int len = NLMSG_SPACE(sizeof(*ev));
380
381 conn = iscsi_if_find_conn(connh);
382 BUG_ON(!conn);
383
384 mempool_zone_complete(&conn->z_error);
385
386 skb = mempool_zone_get_skb(&conn->z_error);
387 if (!skb) {
388 printk(KERN_ERR "iscsi%d: gracefully ignored conn error (%d)\n",
389 conn->host->host_no, error);
390 return;
391 }
392
393 nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
394 ev = NLMSG_DATA(nlh);
395 ev->transport_handle = iscsi_handle(conn->transport);
396 ev->type = ISCSI_KEVENT_CONN_ERROR;
397 if (atomic_read(&conn->z_error.allocated) >= conn->z_error.hiwat)
398 ev->iferror = -ENOMEM;
399 ev->r.connerror.error = error;
400 ev->r.connerror.conn_handle = connh;
176 401
177 if (i->fnt->get_isid) 402 iscsi_unicast_skb(&conn->z_error, skb);
178 i->fnt->get_isid(starget);
179 403
180 return sprintf(buf, "%02x%02x%02x%02x%02x%02x\n", 404 printk(KERN_INFO "iscsi%d: detected conn error (%d)\n",
181 iscsi_isid(starget)[0], iscsi_isid(starget)[1], 405 conn->host->host_no, error);
182 iscsi_isid(starget)[2], iscsi_isid(starget)[3], 406}
183 iscsi_isid(starget)[4], iscsi_isid(starget)[5]); 407EXPORT_SYMBOL_GPL(iscsi_conn_error);
408
409static int
410iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
411 void *payload, int size)
412{
413 struct sk_buff *skb;
414 struct nlmsghdr *nlh;
415 int len = NLMSG_SPACE(size);
416 int flags = multi ? NLM_F_MULTI : 0;
417 int t = done ? NLMSG_DONE : type;
418
419 mempool_zone_complete(&z_reply);
420
421 skb = mempool_zone_get_skb(&z_reply);
422 /*
423 * FIXME:
424 * user is supposed to react on iferror == -ENOMEM;
425 * see iscsi_if_rx().
426 */
427 BUG_ON(!skb);
428
429 nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
430 nlh->nlmsg_flags = flags;
431 memcpy(NLMSG_DATA(nlh), payload, size);
432 return iscsi_unicast_skb(&z_reply, skb);
184} 433}
185static CLASS_DEVICE_ATTR(isid, S_IRUGO, show_isid, NULL);
186 434
187/* 435/*
188 * This is used for iSCSI names. Normally, we follow 436 * iSCSI Session's hostdata organization:
189 * the transport class convention of having the lld 437 *
190 * set the field, but in these cases the value is 438 * *------------------* <== host->hostdata
191 * too large. 439 * | transport |
440 * |------------------| <== iscsi_hostdata(host->hostdata)
441 * | transport's data |
442 * |------------------| <== hostdata_session(host->hostdata)
443 * | interface's data |
444 * *------------------*
192 */ 445 */
193#define iscsi_session_show_str_fn(field) \ 446
194 \ 447#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \
195static ssize_t \ 448 _t->hostdata_size % sizeof(unsigned long) + \
196show_session_str_##field(struct class_device *cdev, char *buf) \ 449 sizeof(struct iscsi_if_session))
197{ \ 450
198 ssize_t ret = 0; \ 451#define hostdata_session(_hostdata) ((void*)_hostdata + sizeof(unsigned long) + \
199 struct scsi_target *starget = transport_class_to_starget(cdev); \ 452 ((struct iscsi_transport *) \
200 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 453 iscsi_ptr(*(uint64_t *)_hostdata))->hostdata_size)
201 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ 454
202 \ 455static void iscsi_if_session_dev_release(struct device *dev)
203 if (i->fnt->get_##field) \ 456{
204 ret = i->fnt->get_##field(starget, buf, PAGE_SIZE); \ 457 struct iscsi_if_session *session = iscsi_dev_to_if_session(dev);
205 return ret; \ 458 struct iscsi_transport *transport = session->transport;
459 struct Scsi_Host *shost = iscsi_if_session_to_shost(session);
460 struct iscsi_if_conn *conn, *tmp;
461 unsigned long flags;
462
463 /* now free connections */
464 spin_lock_irqsave(&connlock, flags);
465 list_for_each_entry_safe(conn, tmp, &session->connections,
466 session_list) {
467 list_del(&conn->session_list);
468 mempool_destroy(conn->z_pdu.pool);
469 mempool_destroy(conn->z_error.pool);
470 kfree(conn);
471 }
472 spin_unlock_irqrestore(&connlock, flags);
473 scsi_host_put(shost);
474 module_put(transport->owner);
475}
476
477static int
478iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
479{
480 struct iscsi_transport *transport = priv->iscsi_transport;
481 struct iscsi_if_session *session;
482 struct Scsi_Host *shost;
483 unsigned long flags;
484 int error;
485
486 if (!try_module_get(transport->owner))
487 return -EPERM;
488
489 shost = scsi_host_alloc(transport->host_template,
490 hostdata_privsize(transport));
491 if (!shost) {
492 ev->r.c_session_ret.session_handle = iscsi_handle(NULL);
493 printk(KERN_ERR "iscsi: can not allocate SCSI host for "
494 "session\n");
495 error = -ENOMEM;
496 goto out_module_put;
497 }
498 shost->max_id = 1;
499 shost->max_channel = 0;
500 shost->max_lun = transport->max_lun;
501 shost->max_cmd_len = transport->max_cmd_len;
502 shost->transportt = &priv->t;
503
504 /* store struct iscsi_transport in hostdata */
505 *(uint64_t*)shost->hostdata = ev->transport_handle;
506
507 ev->r.c_session_ret.session_handle = transport->create_session(
508 ev->u.c_session.initial_cmdsn, shost);
509 if (ev->r.c_session_ret.session_handle == iscsi_handle(NULL)) {
510 error = 0;
511 goto out_host_put;
512 }
513
514 /* host_no becomes assigned SID */
515 ev->r.c_session_ret.sid = shost->host_no;
516 /* initialize session */
517 session = hostdata_session(shost->hostdata);
518 INIT_LIST_HEAD(&session->connections);
519 INIT_LIST_HEAD(&session->list);
520 session->sessionh = ev->r.c_session_ret.session_handle;
521 session->transport = transport;
522
523 error = scsi_add_host(shost, NULL);
524 if (error)
525 goto out_destroy_session;
526
527 /*
528 * this is released in the dev's release function)
529 */
530 scsi_host_get(shost);
531 snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);
532 session->dev.parent = &shost->shost_gendev;
533 session->dev.release = iscsi_if_session_dev_release;
534 error = device_register(&session->dev);
535 if (error) {
536 printk(KERN_ERR "iscsi: could not register session%d's dev\n",
537 shost->host_no);
538 goto out_remove_host;
539 }
540 transport_register_device(&session->dev);
541
542 /* add this session to the list of active sessions */
543 spin_lock_irqsave(&priv->session_lock, flags);
544 list_add(&session->list, &priv->sessions);
545 spin_unlock_irqrestore(&priv->session_lock, flags);
546
547 return 0;
548
549out_remove_host:
550 scsi_remove_host(shost);
551out_destroy_session:
552 transport->destroy_session(ev->r.c_session_ret.session_handle);
553 ev->r.c_session_ret.session_handle = iscsi_handle(NULL);
554out_host_put:
555 scsi_host_put(shost);
556out_module_put:
557 module_put(transport->owner);
558 return error;
559}
560
561static int
562iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
563{
564 struct iscsi_transport *transport = priv->iscsi_transport;
565 struct Scsi_Host *shost;
566 struct iscsi_if_session *session;
567 unsigned long flags;
568 struct iscsi_if_conn *conn;
569 int error = 0;
570
571 shost = scsi_host_lookup(ev->u.d_session.sid);
572 if (shost == ERR_PTR(-ENXIO))
573 return -EEXIST;
574 session = hostdata_session(shost->hostdata);
575
576 /* check if we have active connections */
577 spin_lock_irqsave(&connlock, flags);
578 list_for_each_entry(conn, &session->connections, session_list) {
579 if (conn->active) {
580 printk(KERN_ERR "iscsi%d: can not destroy session: "
581 "has active connection (%p)\n",
582 shost->host_no, iscsi_ptr(conn->connh));
583 spin_unlock_irqrestore(&connlock, flags);
584 error = EIO;
585 goto out_release_ref;
586 }
587 }
588 spin_unlock_irqrestore(&connlock, flags);
589
590 scsi_remove_host(shost);
591 transport->destroy_session(ev->u.d_session.session_handle);
592 transport_unregister_device(&session->dev);
593 device_unregister(&session->dev);
594
595 /* remove this session from the list of active sessions */
596 spin_lock_irqsave(&priv->session_lock, flags);
597 list_del(&session->list);
598 spin_unlock_irqrestore(&priv->session_lock, flags);
599
600 /* ref from host alloc */
601 scsi_host_put(shost);
602out_release_ref:
603 /* ref from host lookup */
604 scsi_host_put(shost);
605 return error;
606}
607
608static void iscsi_if_conn_dev_release(struct device *dev)
609{
610 struct iscsi_if_conn *conn = iscsi_dev_to_if_conn(dev);
611 struct Scsi_Host *shost = conn->host;
612
613 scsi_host_put(shost);
614}
615
616static int
617iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
618{
619 struct iscsi_if_session *session;
620 struct Scsi_Host *shost;
621 struct iscsi_if_conn *conn;
622 unsigned long flags;
623 int error;
624
625 shost = scsi_host_lookup(ev->u.c_conn.sid);
626 if (shost == ERR_PTR(-ENXIO))
627 return -EEXIST;
628 session = hostdata_session(shost->hostdata);
629
630 conn = kmalloc(sizeof(struct iscsi_if_conn), GFP_KERNEL);
631 if (!conn) {
632 error = -ENOMEM;
633 goto out_release_ref;
634 }
635 memset(conn, 0, sizeof(struct iscsi_if_conn));
636 INIT_LIST_HEAD(&conn->session_list);
637 INIT_LIST_HEAD(&conn->conn_list);
638 conn->host = shost;
639 conn->transport = transport;
640
641 error = mempool_zone_init(&conn->z_pdu, Z_MAX_PDU,
642 NLMSG_SPACE(sizeof(struct iscsi_uevent) +
643 sizeof(struct iscsi_hdr) +
644 DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
645 Z_HIWAT_PDU);
646 if (error) {
647 printk(KERN_ERR "iscsi%d: can not allocate pdu zone for new "
648 "conn\n", shost->host_no);
649 goto out_free_conn;
650 }
651 error = mempool_zone_init(&conn->z_error, Z_MAX_ERROR,
652 NLMSG_SPACE(sizeof(struct iscsi_uevent)),
653 Z_HIWAT_ERROR);
654 if (error) {
655 printk(KERN_ERR "iscsi%d: can not allocate error zone for "
656 "new conn\n", shost->host_no);
657 goto out_free_pdu_pool;
658 }
659
660 ev->r.handle = transport->create_conn(ev->u.c_conn.session_handle,
661 ev->u.c_conn.cid);
662 if (!ev->r.handle) {
663 error = -ENODEV;
664 goto out_free_error_pool;
665 }
666
667 conn->connh = ev->r.handle;
668
669 /*
670 * this is released in the dev's release function
671 */
672 if (!scsi_host_get(shost))
673 goto out_destroy_conn;
674 snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
675 shost->host_no, ev->u.c_conn.cid);
676 conn->dev.parent = &session->dev;
677 conn->dev.release = iscsi_if_conn_dev_release;
678 error = device_register(&conn->dev);
679 if (error) {
680 printk(KERN_ERR "iscsi%d: could not register connections%u "
681 "dev\n", shost->host_no, ev->u.c_conn.cid);
682 goto out_release_parent_ref;
683 }
684 transport_register_device(&conn->dev);
685
686 spin_lock_irqsave(&connlock, flags);
687 list_add(&conn->conn_list, &connlist);
688 list_add(&conn->session_list, &session->connections);
689 conn->active = 1;
690 spin_unlock_irqrestore(&connlock, flags);
691
692 scsi_host_put(shost);
693 return 0;
694
695out_release_parent_ref:
696 scsi_host_put(shost);
697out_destroy_conn:
698 transport->destroy_conn(ev->r.handle);
699out_free_error_pool:
700 mempool_destroy(conn->z_error.pool);
701out_free_pdu_pool:
702 mempool_destroy(conn->z_pdu.pool);
703out_free_conn:
704 kfree(conn);
705out_release_ref:
706 scsi_host_put(shost);
707 return error;
206} 708}
207 709
208#define iscsi_session_rd_str_attr(field) \ 710static int
209 iscsi_session_show_str_fn(field) \ 711iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
210static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_str_##field, NULL); 712{
713 unsigned long flags;
714 struct iscsi_if_conn *conn;
715
716 conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle);
717 if (!conn)
718 return -EEXIST;
719
720 transport->destroy_conn(ev->u.d_conn.conn_handle);
721
722 spin_lock_irqsave(&connlock, flags);
723 conn->active = 0;
724 list_del(&conn->conn_list);
725 spin_unlock_irqrestore(&connlock, flags);
726
727 transport_unregister_device(&conn->dev);
728 device_unregister(&conn->dev);
729 return 0;
730}
731
732static int
733iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb,
734 struct nlmsghdr *nlh)
735{
736 struct iscsi_uevent *ev = NLMSG_DATA(nlh);
737 struct iscsi_stats *stats;
738 struct sk_buff *skbstat;
739 struct iscsi_if_conn *conn;
740 struct nlmsghdr *nlhstat;
741 struct iscsi_uevent *evstat;
742 int len = NLMSG_SPACE(sizeof(*ev) +
743 sizeof(struct iscsi_stats) +
744 sizeof(struct iscsi_stats_custom) *
745 ISCSI_STATS_CUSTOM_MAX);
746 int err = 0;
747
748 conn = iscsi_if_find_conn(ev->u.get_stats.conn_handle);
749 if (!conn)
750 return -EEXIST;
751
752 do {
753 int actual_size;
754
755 mempool_zone_complete(&conn->z_pdu);
756
757 skbstat = mempool_zone_get_skb(&conn->z_pdu);
758 if (!skbstat) {
759 printk(KERN_ERR "iscsi%d: can not deliver stats: OOM\n",
760 conn->host->host_no);
761 return -ENOMEM;
762 }
763
764 nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0,
765 (len - sizeof(*nlhstat)), 0);
766 evstat = NLMSG_DATA(nlhstat);
767 memset(evstat, 0, sizeof(*evstat));
768 evstat->transport_handle = iscsi_handle(conn->transport);
769 evstat->type = nlh->nlmsg_type;
770 if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)
771 evstat->iferror = -ENOMEM;
772 evstat->u.get_stats.conn_handle =
773 ev->u.get_stats.conn_handle;
774 stats = (struct iscsi_stats *)
775 ((char*)evstat + sizeof(*evstat));
776 memset(stats, 0, sizeof(*stats));
777
778 transport->get_stats(ev->u.get_stats.conn_handle, stats);
779 actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) +
780 sizeof(struct iscsi_stats) +
781 sizeof(struct iscsi_stats_custom) *
782 stats->custom_length);
783 actual_size -= sizeof(*nlhstat);
784 actual_size = NLMSG_LENGTH(actual_size);
785 skb_trim(skb, NLMSG_ALIGN(actual_size));
786 nlhstat->nlmsg_len = actual_size;
787
788 err = iscsi_unicast_skb(&conn->z_pdu, skbstat);
789 } while (err < 0 && err != -ECONNREFUSED);
790
791 return err;
792}
793
794static int
795iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
796{
797 int err = 0;
798 struct iscsi_uevent *ev = NLMSG_DATA(nlh);
799 struct iscsi_transport *transport = NULL;
800 struct iscsi_internal *priv;
801
802 if (NETLINK_CREDS(skb)->uid)
803 return -EPERM;
804
805 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
806 if (!priv)
807 return -EINVAL;
808 transport = priv->iscsi_transport;
809
810 daemon_pid = NETLINK_CREDS(skb)->pid;
811
812 switch (nlh->nlmsg_type) {
813 case ISCSI_UEVENT_CREATE_SESSION:
814 err = iscsi_if_create_session(priv, ev);
815 break;
816 case ISCSI_UEVENT_DESTROY_SESSION:
817 err = iscsi_if_destroy_session(priv, ev);
818 break;
819 case ISCSI_UEVENT_CREATE_CONN:
820 err = iscsi_if_create_conn(transport, ev);
821 break;
822 case ISCSI_UEVENT_DESTROY_CONN:
823 err = iscsi_if_destroy_conn(transport, ev);
824 break;
825 case ISCSI_UEVENT_BIND_CONN:
826 if (!iscsi_if_find_conn(ev->u.b_conn.conn_handle))
827 return -EEXIST;
828 ev->r.retcode = transport->bind_conn(
829 ev->u.b_conn.session_handle,
830 ev->u.b_conn.conn_handle,
831 ev->u.b_conn.transport_fd,
832 ev->u.b_conn.is_leading);
833 break;
834 case ISCSI_UEVENT_SET_PARAM:
835 if (!iscsi_if_find_conn(ev->u.set_param.conn_handle))
836 return -EEXIST;
837 ev->r.retcode = transport->set_param(
838 ev->u.set_param.conn_handle,
839 ev->u.set_param.param, ev->u.set_param.value);
840 break;
841 case ISCSI_UEVENT_START_CONN:
842 if (!iscsi_if_find_conn(ev->u.start_conn.conn_handle))
843 return -EEXIST;
844 ev->r.retcode = transport->start_conn(
845 ev->u.start_conn.conn_handle);
846 break;
847 case ISCSI_UEVENT_STOP_CONN:
848 if (!iscsi_if_find_conn(ev->u.stop_conn.conn_handle))
849 return -EEXIST;
850 transport->stop_conn(ev->u.stop_conn.conn_handle,
851 ev->u.stop_conn.flag);
852 break;
853 case ISCSI_UEVENT_SEND_PDU:
854 if (!iscsi_if_find_conn(ev->u.send_pdu.conn_handle))
855 return -EEXIST;
856 ev->r.retcode = transport->send_pdu(
857 ev->u.send_pdu.conn_handle,
858 (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
859 (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
860 ev->u.send_pdu.data_size);
861 break;
862 case ISCSI_UEVENT_GET_STATS:
863 err = iscsi_if_get_stats(transport, skb, nlh);
864 break;
865 default:
866 err = -EINVAL;
867 break;
868 }
869
870 return err;
871}
872
873/* Get message from skb (based on rtnetlink_rcv_skb). Each message is
874 * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are
875 * discarded silently. */
876static void
877iscsi_if_rx(struct sock *sk, int len)
878{
879 struct sk_buff *skb;
211 880
212iscsi_session_rd_str_attr(target_name); 881 down(&rx_queue_sema);
213iscsi_session_rd_str_attr(target_alias); 882 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
883 while (skb->len >= NLMSG_SPACE(0)) {
884 int err;
885 uint32_t rlen;
886 struct nlmsghdr *nlh;
887 struct iscsi_uevent *ev;
888
889 nlh = (struct nlmsghdr *)skb->data;
890 if (nlh->nlmsg_len < sizeof(*nlh) ||
891 skb->len < nlh->nlmsg_len) {
892 break;
893 }
894 ev = NLMSG_DATA(nlh);
895 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
896 if (rlen > skb->len)
897 rlen = skb->len;
898 err = iscsi_if_recv_msg(skb, nlh);
899 if (err) {
900 ev->type = ISCSI_KEVENT_IF_ERROR;
901 ev->iferror = err;
902 }
903 do {
904 /*
905 * special case for GET_STATS:
906 * on success - sending reply and stats from
907 * inside of if_recv_msg(),
908 * on error - fall through.
909 */
910 if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
911 break;
912 err = iscsi_if_send_reply(
913 NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
914 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
915 if (atomic_read(&z_reply.allocated) >=
916 z_reply.hiwat)
917 ev->iferror = -ENOMEM;
918 } while (err < 0 && err != -ECONNREFUSED);
919 skb_pull(skb, rlen);
920 }
921 kfree_skb(skb);
922 }
923 up(&rx_queue_sema);
924}
214 925
215/* 926/*
216 * iSCSI host attrs 927 * iSCSI connection attrs
217 */ 928 */
929#define iscsi_conn_int_attr_show(param, format) \
930static ssize_t \
931show_conn_int_param_##param(struct class_device *cdev, char *buf) \
932{ \
933 uint32_t value = 0; \
934 struct iscsi_if_conn *conn = iscsi_cdev_to_if_conn(cdev); \
935 struct iscsi_internal *priv; \
936 \
937 priv = to_iscsi_internal(conn->host->transportt); \
938 if (priv->param_mask & (1 << param)) \
939 priv->iscsi_transport->get_param(conn->connh, param, &value); \
940 return snprintf(buf, 20, format"\n", value); \
941}
942
943#define iscsi_conn_int_attr(field, param, format) \
944 iscsi_conn_int_attr_show(param, format) \
945static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL);
946
947iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
948iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
949iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
950iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
951iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
952iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
218 953
219/* 954/*
220 * Again, this is used for iSCSI names. Normally, we follow 955 * iSCSI session attrs
221 * the transport class convention of having the lld set
222 * the field, but in these cases the value is too large.
223 */ 956 */
224#define iscsi_host_show_str_fn(field) \ 957#define iscsi_session_int_attr_show(param, format) \
225 \
226static ssize_t \ 958static ssize_t \
227show_host_str_##field(struct class_device *cdev, char *buf) \ 959show_session_int_param_##param(struct class_device *cdev, char *buf) \
228{ \ 960{ \
229 int ret = 0; \ 961 uint32_t value = 0; \
230 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 962 struct iscsi_if_session *session = iscsi_cdev_to_if_session(cdev); \
231 struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \ 963 struct Scsi_Host *shost = iscsi_if_session_to_shost(session); \
964 struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
965 struct iscsi_if_conn *conn = NULL; \
966 unsigned long flags; \
967 \
968 spin_lock_irqsave(&connlock, flags); \
969 if (!list_empty(&session->connections)) \
970 conn = list_entry(session->connections.next, \
971 struct iscsi_if_conn, session_list); \
972 spin_unlock_irqrestore(&connlock, flags); \
232 \ 973 \
233 if (i->fnt->get_##field) \ 974 if (conn && (priv->param_mask & (1 << param))) \
234 ret = i->fnt->get_##field(shost, buf, PAGE_SIZE); \ 975 priv->iscsi_transport->get_param(conn->connh, param, &value);\
235 return ret; \ 976 return snprintf(buf, 20, format"\n", value); \
236} 977}
237 978
238#define iscsi_host_rd_str_attr(field) \ 979#define iscsi_session_int_attr(field, param, format) \
239 iscsi_host_show_str_fn(field) \ 980 iscsi_session_int_attr_show(param, format) \
240static CLASS_DEVICE_ATTR(field, S_IRUGO, show_host_str_##field, NULL); 981static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL);
241 982
242iscsi_host_rd_str_attr(initiator_name); 983iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
243iscsi_host_rd_str_attr(initiator_alias); 984iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
985iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d");
986iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u");
987iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
988iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
989iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
990iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
244 991
245#define SETUP_SESSION_RD_ATTR(field) \ 992#define SETUP_SESSION_RD_ATTR(field, param) \
246 if (i->fnt->show_##field) { \ 993 if (priv->param_mask & (1 << param)) { \
247 i->session_attrs[count] = &class_device_attr_##field; \ 994 priv->session_attrs[count] = &class_device_attr_##field;\
248 count++; \ 995 count++; \
249 } 996 }
250 997
251#define SETUP_HOST_RD_ATTR(field) \ 998#define SETUP_CONN_RD_ATTR(field, param) \
252 if (i->fnt->show_##field) { \ 999 if (priv->param_mask & (1 << param)) { \
253 i->host_attrs[count] = &class_device_attr_##field; \ 1000 priv->conn_attrs[count] = &class_device_attr_##field; \
254 count++; \ 1001 count++; \
255 } 1002 }
256 1003
257static int iscsi_host_match(struct attribute_container *cont, 1004static int iscsi_is_session_dev(const struct device *dev)
258 struct device *dev) 1005{
1006 return dev->release == iscsi_if_session_dev_release;
1007}
1008
1009static int iscsi_session_match(struct attribute_container *cont,
1010 struct device *dev)
259{ 1011{
1012 struct iscsi_if_session *session;
260 struct Scsi_Host *shost; 1013 struct Scsi_Host *shost;
261 struct iscsi_internal *i; 1014 struct iscsi_internal *priv;
1015
1016 if (!iscsi_is_session_dev(dev))
1017 return 0;
262 1018
263 if (!scsi_is_host_device(dev)) 1019 session = iscsi_dev_to_if_session(dev);
1020 shost = iscsi_if_session_to_shost(session);
1021 if (!shost->transportt)
264 return 0; 1022 return 0;
265 1023
266 shost = dev_to_shost(dev); 1024 priv = to_iscsi_internal(shost->transportt);
267 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1025 if (priv->session_cont.ac.class != &iscsi_session_class.class)
268 != &iscsi_host_class.class)
269 return 0; 1026 return 0;
270 1027
271 i = to_iscsi_internal(shost->transportt); 1028 return &priv->session_cont.ac == cont;
272
273 return &i->t.host_attrs.ac == cont;
274} 1029}
275 1030
276static int iscsi_target_match(struct attribute_container *cont, 1031static int iscsi_is_conn_dev(const struct device *dev)
277 struct device *dev)
278{ 1032{
1033 return dev->release == iscsi_if_conn_dev_release;
1034}
1035
1036static int iscsi_conn_match(struct attribute_container *cont,
1037 struct device *dev)
1038{
1039 struct iscsi_if_conn *conn;
279 struct Scsi_Host *shost; 1040 struct Scsi_Host *shost;
280 struct iscsi_internal *i; 1041 struct iscsi_internal *priv;
281 1042
282 if (!scsi_is_target_device(dev)) 1043 if (!iscsi_is_conn_dev(dev))
283 return 0; 1044 return 0;
284 1045
285 shost = dev_to_shost(dev->parent); 1046 conn = iscsi_dev_to_if_conn(dev);
286 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1047 shost = conn->host;
287 != &iscsi_host_class.class) 1048 if (!shost->transportt)
288 return 0; 1049 return 0;
289 1050
290 i = to_iscsi_internal(shost->transportt); 1051 priv = to_iscsi_internal(shost->transportt);
291 1052 if (priv->conn_cont.ac.class != &iscsi_connection_class.class)
292 return &i->t.target_attrs.ac == cont; 1053 return 0;
293}
294
295struct scsi_transport_template *
296iscsi_attach_transport(struct iscsi_function_template *fnt)
297{
298 struct iscsi_internal *i = kmalloc(sizeof(struct iscsi_internal),
299 GFP_KERNEL);
300 int count = 0;
301
302 if (unlikely(!i))
303 return NULL;
304
305 memset(i, 0, sizeof(struct iscsi_internal));
306 i->fnt = fnt;
307
308 i->t.target_attrs.ac.attrs = &i->session_attrs[0];
309 i->t.target_attrs.ac.class = &iscsi_transport_class.class;
310 i->t.target_attrs.ac.match = iscsi_target_match;
311 transport_container_register(&i->t.target_attrs);
312 i->t.target_size = sizeof(struct iscsi_class_session);
313
314 SETUP_SESSION_RD_ATTR(tsih);
315 SETUP_SESSION_RD_ATTR(isid);
316 SETUP_SESSION_RD_ATTR(header_digest);
317 SETUP_SESSION_RD_ATTR(data_digest);
318 SETUP_SESSION_RD_ATTR(target_name);
319 SETUP_SESSION_RD_ATTR(target_alias);
320 SETUP_SESSION_RD_ATTR(port);
321 SETUP_SESSION_RD_ATTR(tpgt);
322 SETUP_SESSION_RD_ATTR(ip_address);
323 SETUP_SESSION_RD_ATTR(initial_r2t);
324 SETUP_SESSION_RD_ATTR(immediate_data);
325 SETUP_SESSION_RD_ATTR(max_recv_data_segment_len);
326 SETUP_SESSION_RD_ATTR(max_burst_len);
327 SETUP_SESSION_RD_ATTR(first_burst_len);
328 SETUP_SESSION_RD_ATTR(def_time2wait);
329 SETUP_SESSION_RD_ATTR(def_time2retain);
330 SETUP_SESSION_RD_ATTR(max_outstanding_r2t);
331 SETUP_SESSION_RD_ATTR(data_pdu_in_order);
332 SETUP_SESSION_RD_ATTR(data_sequence_in_order);
333 SETUP_SESSION_RD_ATTR(erl);
334 1054
335 BUG_ON(count > ISCSI_SESSION_ATTRS); 1055 return &priv->conn_cont.ac == cont;
336 i->session_attrs[count] = NULL; 1056}
1057
1058int iscsi_register_transport(struct iscsi_transport *tt)
1059{
1060 struct iscsi_internal *priv;
1061 unsigned long flags;
1062 int count = 0, err;
1063
1064 BUG_ON(!tt);
1065
1066 priv = iscsi_if_transport_lookup(tt);
1067 if (priv)
1068 return -EEXIST;
1069
1070 priv = kmalloc(sizeof(*priv), GFP_KERNEL);
1071 if (!priv)
1072 return -ENOMEM;
1073 memset(priv, 0, sizeof(*priv));
1074 INIT_LIST_HEAD(&priv->list);
1075 INIT_LIST_HEAD(&priv->sessions);
1076 spin_lock_init(&priv->session_lock);
1077 priv->iscsi_transport = tt;
1078
1079 priv->cdev.class = &iscsi_transport_class;
1080 snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
1081 err = class_device_register(&priv->cdev);
1082 if (err)
1083 goto free_priv;
1084
1085 err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
1086 if (err)
1087 goto unregister_cdev;
1088
1089 /* setup parameters mask */
1090 priv->param_mask = 0xFFFFFFFF;
1091 if (!(tt->caps & CAP_MULTI_R2T))
1092 priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T);
1093 if (!(tt->caps & CAP_HDRDGST))
1094 priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN);
1095 if (!(tt->caps & CAP_DATADGST))
1096 priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN);
1097 if (!(tt->caps & CAP_MARKERS)) {
1098 priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN);
1099 priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN);
1100 }
337 1101
338 i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 1102 /* connection parameters */
339 i->t.host_attrs.ac.class = &iscsi_host_class.class; 1103 priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
340 i->t.host_attrs.ac.match = iscsi_host_match; 1104 priv->conn_cont.ac.class = &iscsi_connection_class.class;
341 transport_container_register(&i->t.host_attrs); 1105 priv->conn_cont.ac.match = iscsi_conn_match;
342 i->t.host_size = 0; 1106 transport_container_register(&priv->conn_cont);
343 1107
1108 SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
1109 SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
1110 SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN);
1111 SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN);
1112 SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN);
1113 SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN);
1114
1115 BUG_ON(count > ISCSI_CONN_ATTRS);
1116 priv->conn_attrs[count] = NULL;
344 count = 0; 1117 count = 0;
345 SETUP_HOST_RD_ATTR(initiator_name);
346 SETUP_HOST_RD_ATTR(initiator_alias);
347 1118
348 BUG_ON(count > ISCSI_HOST_ATTRS); 1119 /* session parameters */
349 i->host_attrs[count] = NULL; 1120 priv->session_cont.ac.attrs = &priv->session_attrs[0];
1121 priv->session_cont.ac.class = &iscsi_session_class.class;
1122 priv->session_cont.ac.match = iscsi_session_match;
1123 transport_container_register(&priv->session_cont);
1124
1125 SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
1126 SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
1127 SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
1128 SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST);
1129 SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST);
1130 SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
1131 SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN)
1132 SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL);
1133
1134 BUG_ON(count > ISCSI_SESSION_ATTRS);
1135 priv->session_attrs[count] = NULL;
1136
1137 spin_lock_irqsave(&iscsi_transport_lock, flags);
1138 list_add(&priv->list, &iscsi_transports);
1139 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1140
1141 printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
1142 return 0;
350 1143
351 return &i->t; 1144unregister_cdev:
1145 class_device_unregister(&priv->cdev);
1146free_priv:
1147 kfree(priv);
1148 return err;
352} 1149}
1150EXPORT_SYMBOL_GPL(iscsi_register_transport);
1151
1152int iscsi_unregister_transport(struct iscsi_transport *tt)
1153{
1154 struct iscsi_internal *priv;
1155 unsigned long flags;
1156
1157 BUG_ON(!tt);
1158
1159 down(&rx_queue_sema);
1160
1161 priv = iscsi_if_transport_lookup(tt);
1162 BUG_ON (!priv);
1163
1164 spin_lock_irqsave(&priv->session_lock, flags);
1165 if (!list_empty(&priv->sessions)) {
1166 spin_unlock_irqrestore(&priv->session_lock, flags);
1167 up(&rx_queue_sema);
1168 return -EPERM;
1169 }
1170 spin_unlock_irqrestore(&priv->session_lock, flags);
1171
1172 spin_lock_irqsave(&iscsi_transport_lock, flags);
1173 list_del(&priv->list);
1174 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1175
1176 transport_container_unregister(&priv->conn_cont);
1177 transport_container_unregister(&priv->session_cont);
1178
1179 sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
1180 class_device_unregister(&priv->cdev);
1181 up(&rx_queue_sema);
353 1182
354EXPORT_SYMBOL(iscsi_attach_transport); 1183 return 0;
1184}
1185EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
355 1186
356void iscsi_release_transport(struct scsi_transport_template *t) 1187static int
1188iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
357{ 1189{
358 struct iscsi_internal *i = to_iscsi_internal(t); 1190 struct netlink_notify *n = ptr;
1191
1192 if (event == NETLINK_URELEASE &&
1193 n->protocol == NETLINK_ISCSI && n->pid) {
1194 struct iscsi_if_conn *conn;
1195 unsigned long flags;
1196
1197 mempool_zone_complete(&z_reply);
1198 spin_lock_irqsave(&connlock, flags);
1199 list_for_each_entry(conn, &connlist, conn_list) {
1200 mempool_zone_complete(&conn->z_error);
1201 mempool_zone_complete(&conn->z_pdu);
1202 }
1203 spin_unlock_irqrestore(&connlock, flags);
1204 }
359 1205
360 transport_container_unregister(&i->t.target_attrs); 1206 return NOTIFY_DONE;
361 transport_container_unregister(&i->t.host_attrs);
362
363 kfree(i);
364} 1207}
365 1208
366EXPORT_SYMBOL(iscsi_release_transport); 1209static struct notifier_block iscsi_nl_notifier = {
1210 .notifier_call = iscsi_rcv_nl_event,
1211};
367 1212
368static __init int iscsi_transport_init(void) 1213static __init int iscsi_transport_init(void)
369{ 1214{
370 int err = transport_class_register(&iscsi_transport_class); 1215 int err;
371 1216
1217 err = class_register(&iscsi_transport_class);
372 if (err) 1218 if (err)
373 return err; 1219 return err;
374 return transport_class_register(&iscsi_host_class); 1220
1221 err = transport_class_register(&iscsi_connection_class);
1222 if (err)
1223 goto unregister_transport_class;
1224
1225 err = transport_class_register(&iscsi_session_class);
1226 if (err)
1227 goto unregister_conn_class;
1228
1229 err = netlink_register_notifier(&iscsi_nl_notifier);
1230 if (err)
1231 goto unregister_session_class;
1232
1233 nls = netlink_kernel_create(NETLINK_ISCSI, iscsi_if_rx);
1234 if (!nls) {
1235 err = -ENOBUFS;
1236 goto unregister_notifier;
1237 }
1238
1239 err = mempool_zone_init(&z_reply, Z_MAX_REPLY,
1240 NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
1241 if (!err)
1242 return 0;
1243
1244 sock_release(nls->sk_socket);
1245unregister_notifier:
1246 netlink_unregister_notifier(&iscsi_nl_notifier);
1247unregister_session_class:
1248 transport_class_unregister(&iscsi_session_class);
1249unregister_conn_class:
1250 transport_class_unregister(&iscsi_connection_class);
1251unregister_transport_class:
1252 class_unregister(&iscsi_transport_class);
1253 return err;
375} 1254}
376 1255
377static void __exit iscsi_transport_exit(void) 1256static void __exit iscsi_transport_exit(void)
378{ 1257{
379 transport_class_unregister(&iscsi_host_class); 1258 mempool_destroy(z_reply.pool);
380 transport_class_unregister(&iscsi_transport_class); 1259 sock_release(nls->sk_socket);
1260 netlink_unregister_notifier(&iscsi_nl_notifier);
1261 transport_class_unregister(&iscsi_connection_class);
1262 transport_class_unregister(&iscsi_session_class);
1263 class_unregister(&iscsi_transport_class);
381} 1264}
382 1265
383module_init(iscsi_transport_init); 1266module_init(iscsi_transport_init);
384module_exit(iscsi_transport_exit); 1267module_exit(iscsi_transport_exit);
385 1268
386MODULE_AUTHOR("Mike Christie"); 1269MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
387MODULE_DESCRIPTION("iSCSI Transport Attributes"); 1270 "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
1271 "Alex Aizman <itn780@yahoo.com>");
1272MODULE_DESCRIPTION("iSCSI Transport Interface");
388MODULE_LICENSE("GPL"); 1273MODULE_LICENSE("GPL");
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
new file mode 100644
index 000000000000..be1bc792ab18
--- /dev/null
+++ b/include/scsi/iscsi_if.h
@@ -0,0 +1,245 @@
1/*
2 * iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc)
3 *
4 * Copyright (C) 2005 Dmitry Yusupov
5 * Copyright (C) 2005 Alex Aizman
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_IF_H
22#define ISCSI_IF_H
23
24#include <scsi/iscsi_proto.h>
25
26#define UEVENT_BASE 10
27#define KEVENT_BASE 100
28#define ISCSI_ERR_BASE 1000
29
30enum iscsi_uevent_e {
31 ISCSI_UEVENT_UNKNOWN = 0,
32
33 /* down events */
34 ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1,
35 ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2,
36 ISCSI_UEVENT_CREATE_CONN = UEVENT_BASE + 3,
37 ISCSI_UEVENT_DESTROY_CONN = UEVENT_BASE + 4,
38 ISCSI_UEVENT_BIND_CONN = UEVENT_BASE + 5,
39 ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 6,
40 ISCSI_UEVENT_START_CONN = UEVENT_BASE + 7,
41 ISCSI_UEVENT_STOP_CONN = UEVENT_BASE + 8,
42 ISCSI_UEVENT_SEND_PDU = UEVENT_BASE + 9,
43 ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10,
44 ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11,
45
46 /* up events */
47 ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
48 ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2,
49 ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3,
50};
51
52struct iscsi_uevent {
53 uint32_t type; /* k/u events type */
54 uint32_t iferror; /* carries interface or resource errors */
55 uint64_t transport_handle;
56
57 union {
58 /* messages u -> k */
59 struct msg_create_session {
60 uint32_t initial_cmdsn;
61 } c_session;
62 struct msg_destroy_session {
63 uint64_t session_handle;
64 uint32_t sid;
65 } d_session;
66 struct msg_create_conn {
67 uint64_t session_handle;
68 uint32_t cid;
69 uint32_t sid;
70 } c_conn;
71 struct msg_bind_conn {
72 uint64_t session_handle;
73 uint64_t conn_handle;
74 uint32_t transport_fd;
75 uint32_t is_leading;
76 } b_conn;
77 struct msg_destroy_conn {
78 uint64_t conn_handle;
79 uint32_t cid;
80 } d_conn;
81 struct msg_send_pdu {
82 uint32_t hdr_size;
83 uint32_t data_size;
84 uint64_t conn_handle;
85 } send_pdu;
86 struct msg_set_param {
87 uint64_t conn_handle;
88 uint32_t param; /* enum iscsi_param */
89 uint32_t value;
90 } set_param;
91 struct msg_start_conn {
92 uint64_t conn_handle;
93 } start_conn;
94 struct msg_stop_conn {
95 uint64_t conn_handle;
96 uint32_t flag;
97 } stop_conn;
98 struct msg_get_stats {
99 uint64_t conn_handle;
100 } get_stats;
101 } u;
102 union {
103 /* messages k -> u */
104 uint64_t handle;
105 int retcode;
106 struct msg_create_session_ret {
107 uint64_t session_handle;
108 uint32_t sid;
109 } c_session_ret;
110 struct msg_recv_req {
111 uint64_t recv_handle;
112 uint64_t conn_handle;
113 } recv_req;
114 struct msg_conn_error {
115 uint64_t conn_handle;
116 uint32_t error; /* enum iscsi_err */
117 } connerror;
118 } r;
119} __attribute__ ((aligned (sizeof(uint64_t))));
120
121/*
122 * Common error codes
123 */
124enum iscsi_err {
125 ISCSI_OK = 0,
126
127 ISCSI_ERR_DATASN = ISCSI_ERR_BASE + 1,
128 ISCSI_ERR_DATA_OFFSET = ISCSI_ERR_BASE + 2,
129 ISCSI_ERR_MAX_CMDSN = ISCSI_ERR_BASE + 3,
130 ISCSI_ERR_EXP_CMDSN = ISCSI_ERR_BASE + 4,
131 ISCSI_ERR_BAD_OPCODE = ISCSI_ERR_BASE + 5,
132 ISCSI_ERR_DATALEN = ISCSI_ERR_BASE + 6,
133 ISCSI_ERR_AHSLEN = ISCSI_ERR_BASE + 7,
134 ISCSI_ERR_PROTO = ISCSI_ERR_BASE + 8,
135 ISCSI_ERR_LUN = ISCSI_ERR_BASE + 9,
136 ISCSI_ERR_BAD_ITT = ISCSI_ERR_BASE + 10,
137 ISCSI_ERR_CONN_FAILED = ISCSI_ERR_BASE + 11,
138 ISCSI_ERR_R2TSN = ISCSI_ERR_BASE + 12,
139 ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13,
140 ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14,
141 ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15,
142 ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16
143};
144
145/*
146 * iSCSI Parameters (RFC3720)
147 */
148enum iscsi_param {
149 ISCSI_PARAM_MAX_RECV_DLENGTH = 0,
150 ISCSI_PARAM_MAX_XMIT_DLENGTH = 1,
151 ISCSI_PARAM_HDRDGST_EN = 2,
152 ISCSI_PARAM_DATADGST_EN = 3,
153 ISCSI_PARAM_INITIAL_R2T_EN = 4,
154 ISCSI_PARAM_MAX_R2T = 5,
155 ISCSI_PARAM_IMM_DATA_EN = 6,
156 ISCSI_PARAM_FIRST_BURST = 7,
157 ISCSI_PARAM_MAX_BURST = 8,
158 ISCSI_PARAM_PDU_INORDER_EN = 9,
159 ISCSI_PARAM_DATASEQ_INORDER_EN = 10,
160 ISCSI_PARAM_ERL = 11,
161 ISCSI_PARAM_IFMARKER_EN = 12,
162 ISCSI_PARAM_OFMARKER_EN = 13,
163};
164#define ISCSI_PARAM_MAX 14
165
166typedef uint64_t iscsi_sessionh_t; /* iSCSI Data-Path session handle */
167typedef uint64_t iscsi_connh_t; /* iSCSI Data-Path connection handle */
168
169#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
170#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
171#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
172
173/*
174 * These flags presents iSCSI Data-Path capabilities.
175 */
176#define CAP_RECOVERY_L0 0x1
177#define CAP_RECOVERY_L1 0x2
178#define CAP_RECOVERY_L2 0x4
179#define CAP_MULTI_R2T 0x8
180#define CAP_HDRDGST 0x10
181#define CAP_DATADGST 0x20
182#define CAP_MULTI_CONN 0x40
183#define CAP_TEXT_NEGO 0x80
184#define CAP_MARKERS 0x100
185
186/*
187 * These flags describes reason of stop_conn() call
188 */
189#define STOP_CONN_TERM 0x1
190#define STOP_CONN_SUSPEND 0x2
191#define STOP_CONN_RECOVER 0x3
192
193#define ISCSI_STATS_CUSTOM_MAX 32
194#define ISCSI_STATS_CUSTOM_DESC_MAX 64
195struct iscsi_stats_custom {
196 char desc[ISCSI_STATS_CUSTOM_DESC_MAX];
197 uint64_t value;
198};
199
200/*
201 * struct iscsi_stats - iSCSI Statistics (iSCSI MIB)
202 *
203 * Note: this structure contains counters collected on per-connection basis.
204 */
205struct iscsi_stats {
206 /* octets */
207 uint64_t txdata_octets;
208 uint64_t rxdata_octets;
209
210 /* xmit pdus */
211 uint32_t noptx_pdus;
212 uint32_t scsicmd_pdus;
213 uint32_t tmfcmd_pdus;
214 uint32_t login_pdus;
215 uint32_t text_pdus;
216 uint32_t dataout_pdus;
217 uint32_t logout_pdus;
218 uint32_t snack_pdus;
219
220 /* recv pdus */
221 uint32_t noprx_pdus;
222 uint32_t scsirsp_pdus;
223 uint32_t tmfrsp_pdus;
224 uint32_t textrsp_pdus;
225 uint32_t datain_pdus;
226 uint32_t logoutrsp_pdus;
227 uint32_t r2t_pdus;
228 uint32_t async_pdus;
229 uint32_t rjt_pdus;
230
231 /* errors */
232 uint32_t digest_err;
233 uint32_t timeout_err;
234
235 /*
236 * iSCSI Custom Statistics support, i.e. Transport could
237 * extend existing MIB statistics with its own specific statistics
238 * up to ISCSI_STATS_CUSTOM_MAX
239 */
240 uint32_t custom_length;
241 struct iscsi_stats_custom custom[0]
242 __attribute__ ((aligned (sizeof(uint64_t))));
243};
244
245#endif
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h
new file mode 100644
index 000000000000..6c08551c79f5
--- /dev/null
+++ b/include/scsi/iscsi_proto.h
@@ -0,0 +1,566 @@
1/*
2 * RFC 3720 (iSCSI) protocol data types
3 *
4 * Copyright (C) 2005 Dmitry Yusupov
5 * Copyright (C) 2005 Alex Aizman
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_PROTO_H
22#define ISCSI_PROTO_H
23
24#define ISCSI_VERSION_STR "0.3"
25#define ISCSI_DATE_STR "22-Apr-2005"
26#define ISCSI_DRAFT20_VERSION 0x00
27
28/* default iSCSI listen port for incoming connections */
29#define ISCSI_LISTEN_PORT 3260
30
31/* Padding word length */
32#define PAD_WORD_LEN 4
33
34/*
35 * useful common(control and data pathes) macro
36 */
37#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
38#define hton24(p, v) { \
39 p[0] = (((v) >> 16) & 0xFF); \
40 p[1] = (((v) >> 8) & 0xFF); \
41 p[2] = ((v) & 0xFF); \
42}
43#define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;}
44
45/*
46 * iSCSI Template Message Header
47 */
48struct iscsi_hdr {
49 uint8_t opcode;
50 uint8_t flags; /* Final bit */
51 uint8_t rsvd2[2];
52 uint8_t hlength; /* AHSs total length */
53 uint8_t dlength[3]; /* Data length */
54 uint8_t lun[8];
55 __be32 itt; /* Initiator Task Tag */
56 __be32 ttt; /* Target Task Tag */
57 __be32 statsn;
58 __be32 exp_statsn;
59 uint8_t other[16];
60};
61
62/************************* RFC 3720 Begin *****************************/
63
64#define ISCSI_RESERVED_TAG 0xffffffff
65
66/* Opcode encoding bits */
67#define ISCSI_OP_RETRY 0x80
68#define ISCSI_OP_IMMEDIATE 0x40
69#define ISCSI_OPCODE_MASK 0x3F
70
71/* Initiator Opcode values */
72#define ISCSI_OP_NOOP_OUT 0x00
73#define ISCSI_OP_SCSI_CMD 0x01
74#define ISCSI_OP_SCSI_TMFUNC 0x02
75#define ISCSI_OP_LOGIN 0x03
76#define ISCSI_OP_TEXT 0x04
77#define ISCSI_OP_SCSI_DATA_OUT 0x05
78#define ISCSI_OP_LOGOUT 0x06
79#define ISCSI_OP_SNACK 0x10
80
81/* Target Opcode values */
82#define ISCSI_OP_NOOP_IN 0x20
83#define ISCSI_OP_SCSI_CMD_RSP 0x21
84#define ISCSI_OP_SCSI_TMFUNC_RSP 0x22
85#define ISCSI_OP_LOGIN_RSP 0x23
86#define ISCSI_OP_TEXT_RSP 0x24
87#define ISCSI_OP_SCSI_DATA_IN 0x25
88#define ISCSI_OP_LOGOUT_RSP 0x26
89#define ISCSI_OP_R2T 0x31
90#define ISCSI_OP_ASYNC_EVENT 0x32
91#define ISCSI_OP_REJECT 0x3f
92
93/* iSCSI PDU Header */
94struct iscsi_cmd {
95 uint8_t opcode;
96 uint8_t flags;
97 uint8_t rsvd2;
98 uint8_t cmdrn;
99 uint8_t hlength;
100 uint8_t dlength[3];
101 uint8_t lun[8];
102 __be32 itt; /* Initiator Task Tag */
103 __be32 data_length;
104 __be32 cmdsn;
105 __be32 exp_statsn;
106 uint8_t cdb[16]; /* SCSI Command Block */
107 /* Additional Data (Command Dependent) */
108};
109
110/* Command PDU flags */
111#define ISCSI_FLAG_CMD_FINAL 0x80
112#define ISCSI_FLAG_CMD_READ 0x40
113#define ISCSI_FLAG_CMD_WRITE 0x20
114#define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */
115
116/* SCSI Command Attribute values */
117#define ISCSI_ATTR_UNTAGGED 0
118#define ISCSI_ATTR_SIMPLE 1
119#define ISCSI_ATTR_ORDERED 2
120#define ISCSI_ATTR_HEAD_OF_QUEUE 3
121#define ISCSI_ATTR_ACA 4
122
123/* SCSI Response Header */
124struct iscsi_cmd_rsp {
125 uint8_t opcode;
126 uint8_t flags;
127 uint8_t response;
128 uint8_t cmd_status;
129 uint8_t hlength;
130 uint8_t dlength[3];
131 uint8_t rsvd[8];
132 __be32 itt; /* Initiator Task Tag */
133 __be32 rsvd1;
134 __be32 statsn;
135 __be32 exp_cmdsn;
136 __be32 max_cmdsn;
137 __be32 exp_datasn;
138 __be32 bi_residual_count;
139 __be32 residual_count;
140 /* Response or Sense Data (optional) */
141};
142
143/* Command Response PDU flags */
144#define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10
145#define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08
146#define ISCSI_FLAG_CMD_OVERFLOW 0x04
147#define ISCSI_FLAG_CMD_UNDERFLOW 0x02
148
149/* iSCSI Status values. Valid if Rsp Selector bit is not set */
150#define ISCSI_STATUS_CMD_COMPLETED 0
151#define ISCSI_STATUS_TARGET_FAILURE 1
152#define ISCSI_STATUS_SUBSYS_FAILURE 2
153
154/* Asynchronous Event Header */
155struct iscsi_async {
156 uint8_t opcode;
157 uint8_t flags;
158 uint8_t rsvd2[2];
159 uint8_t rsvd3;
160 uint8_t dlength[3];
161 uint8_t lun[8];
162 uint8_t rsvd4[8];
163 __be32 statsn;
164 __be32 exp_cmdsn;
165 __be32 max_cmdsn;
166 uint8_t async_event;
167 uint8_t async_vcode;
168 __be16 param1;
169 __be16 param2;
170 __be16 param3;
171 uint8_t rsvd5[4];
172};
173
174/* iSCSI Event Codes */
175#define ISCSI_ASYNC_MSG_SCSI_EVENT 0
176#define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1
177#define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2
178#define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3
179#define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4
180#define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255
181
182/* NOP-Out Message */
183struct iscsi_nopout {
184 uint8_t opcode;
185 uint8_t flags;
186 __be16 rsvd2;
187 uint8_t rsvd3;
188 uint8_t dlength[3];
189 uint8_t lun[8];
190 __be32 itt; /* Initiator Task Tag */
191 __be32 ttt; /* Target Transfer Tag */
192 __be32 cmdsn;
193 __be32 exp_statsn;
194 uint8_t rsvd4[16];
195};
196
197/* NOP-In Message */
198struct iscsi_nopin {
199 uint8_t opcode;
200 uint8_t flags;
201 __be16 rsvd2;
202 uint8_t rsvd3;
203 uint8_t dlength[3];
204 uint8_t lun[8];
205 __be32 itt; /* Initiator Task Tag */
206 __be32 ttt; /* Target Transfer Tag */
207 __be32 statsn;
208 __be32 exp_cmdsn;
209 __be32 max_cmdsn;
210 uint8_t rsvd4[12];
211};
212
213/* SCSI Task Management Message Header */
214struct iscsi_tm {
215 uint8_t opcode;
216 uint8_t flags;
217 uint8_t rsvd1[2];
218 uint8_t hlength;
219 uint8_t dlength[3];
220 uint8_t lun[8];
221 __be32 itt; /* Initiator Task Tag */
222 __be32 rtt; /* Reference Task Tag */
223 __be32 cmdsn;
224 __be32 exp_statsn;
225 __be32 refcmdsn;
226 __be32 exp_datasn;
227 uint8_t rsvd2[8];
228};
229
230#define ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK 0x7F
231
232/* Function values */
233#define ISCSI_TM_FUNC_ABORT_TASK 1
234#define ISCSI_TM_FUNC_ABORT_TASK_SET 2
235#define ISCSI_TM_FUNC_CLEAR_ACA 3
236#define ISCSI_TM_FUNC_CLEAR_TASK_SET 4
237#define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5
238#define ISCSI_TM_FUNC_TARGET_WARM_RESET 6
239#define ISCSI_TM_FUNC_TARGET_COLD_RESET 7
240#define ISCSI_TM_FUNC_TASK_REASSIGN 8
241
242/* SCSI Task Management Response Header */
243struct iscsi_tm_rsp {
244 uint8_t opcode;
245 uint8_t flags;
246 uint8_t response; /* see Response values below */
247 uint8_t qualifier;
248 uint8_t hlength;
249 uint8_t dlength[3];
250 uint8_t rsvd2[8];
251 __be32 itt; /* Initiator Task Tag */
252 __be32 rtt; /* Reference Task Tag */
253 __be32 statsn;
254 __be32 exp_cmdsn;
255 __be32 max_cmdsn;
256 uint8_t rsvd3[12];
257};
258
259/* Response values */
260#define SCSI_TCP_TM_RESP_COMPLETE 0x00
261#define SCSI_TCP_TM_RESP_NO_TASK 0x01
262#define SCSI_TCP_TM_RESP_NO_LUN 0x02
263#define SCSI_TCP_TM_RESP_TASK_ALLEGIANT 0x03
264#define SCSI_TCP_TM_RESP_NO_FAILOVER 0x04
265#define SCSI_TCP_TM_RESP_NOT_SUPPORTED 0x05
266#define SCSI_TCP_TM_RESP_AUTH_FAILED 0x06
267#define SCSI_TCP_TM_RESP_REJECTED 0xff
268
269/* Ready To Transfer Header */
270struct iscsi_r2t_rsp {
271 uint8_t opcode;
272 uint8_t flags;
273 uint8_t rsvd2[2];
274 uint8_t hlength;
275 uint8_t dlength[3];
276 uint8_t lun[8];
277 __be32 itt; /* Initiator Task Tag */
278 __be32 ttt; /* Target Transfer Tag */
279 __be32 statsn;
280 __be32 exp_cmdsn;
281 __be32 max_cmdsn;
282 __be32 r2tsn;
283 __be32 data_offset;
284 __be32 data_length;
285};
286
287/* SCSI Data Hdr */
288struct iscsi_data {
289 uint8_t opcode;
290 uint8_t flags;
291 uint8_t rsvd2[2];
292 uint8_t rsvd3;
293 uint8_t dlength[3];
294 uint8_t lun[8];
295 __be32 itt;
296 __be32 ttt;
297 __be32 rsvd4;
298 __be32 exp_statsn;
299 __be32 rsvd5;
300 __be32 datasn;
301 __be32 offset;
302 __be32 rsvd6;
303 /* Payload */
304};
305
306/* SCSI Data Response Hdr */
307struct iscsi_data_rsp {
308 uint8_t opcode;
309 uint8_t flags;
310 uint8_t rsvd2;
311 uint8_t cmd_status;
312 uint8_t hlength;
313 uint8_t dlength[3];
314 uint8_t lun[8];
315 __be32 itt;
316 __be32 ttt;
317 __be32 statsn;
318 __be32 exp_cmdsn;
319 __be32 max_cmdsn;
320 __be32 datasn;
321 __be32 offset;
322 __be32 residual_count;
323};
324
325/* Data Response PDU flags */
326#define ISCSI_FLAG_DATA_ACK 0x40
327#define ISCSI_FLAG_DATA_OVERFLOW 0x04
328#define ISCSI_FLAG_DATA_UNDERFLOW 0x02
329#define ISCSI_FLAG_DATA_STATUS 0x01
330
331/* Text Header */
332struct iscsi_text {
333 uint8_t opcode;
334 uint8_t flags;
335 uint8_t rsvd2[2];
336 uint8_t hlength;
337 uint8_t dlength[3];
338 uint8_t rsvd4[8];
339 __be32 itt;
340 __be32 ttt;
341 __be32 cmdsn;
342 __be32 exp_statsn;
343 uint8_t rsvd5[16];
344 /* Text - key=value pairs */
345};
346
347#define ISCSI_FLAG_TEXT_CONTINUE 0x40
348
349/* Text Response Header */
350struct iscsi_text_rsp {
351 uint8_t opcode;
352 uint8_t flags;
353 uint8_t rsvd2[2];
354 uint8_t hlength;
355 uint8_t dlength[3];
356 uint8_t rsvd4[8];
357 __be32 itt;
358 __be32 ttt;
359 __be32 statsn;
360 __be32 exp_cmdsn;
361 __be32 max_cmdsn;
362 uint8_t rsvd5[12];
363 /* Text Response - key:value pairs */
364};
365
366/* Login Header */
367struct iscsi_login {
368 uint8_t opcode;
369 uint8_t flags;
370 uint8_t max_version; /* Max. version supported */
371 uint8_t min_version; /* Min. version supported */
372 uint8_t hlength;
373 uint8_t dlength[3];
374 uint8_t isid[6]; /* Initiator Session ID */
375 __be16 tsih; /* Target Session Handle */
376 __be32 itt; /* Initiator Task Tag */
377 __be16 cid;
378 __be16 rsvd3;
379 __be32 cmdsn;
380 __be32 exp_statsn;
381 uint8_t rsvd5[16];
382};
383
384/* Login PDU flags */
385#define ISCSI_FLAG_LOGIN_TRANSIT 0x80
386#define ISCSI_FLAG_LOGIN_CONTINUE 0x40
387#define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */
388#define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */
389
390#define ISCSI_LOGIN_CURRENT_STAGE(flags) \
391 ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2)
392#define ISCSI_LOGIN_NEXT_STAGE(flags) \
393 (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK)
394
395/* Login Response Header */
396struct iscsi_login_rsp {
397 uint8_t opcode;
398 uint8_t flags;
399 uint8_t max_version; /* Max. version supported */
400 uint8_t active_version; /* Active version */
401 uint8_t hlength;
402 uint8_t dlength[3];
403 uint8_t isid[6]; /* Initiator Session ID */
404 __be16 tsih; /* Target Session Handle */
405 __be32 itt; /* Initiator Task Tag */
406 __be32 rsvd3;
407 __be32 statsn;
408 __be32 exp_cmdsn;
409 __be32 max_cmdsn;
410 uint8_t status_class; /* see Login RSP ststus classes below */
411 uint8_t status_detail; /* see Login RSP Status details below */
412 uint8_t rsvd4[10];
413};
414
415/* Login stage (phase) codes for CSG, NSG */
416#define ISCSI_INITIAL_LOGIN_STAGE -1
417#define ISCSI_SECURITY_NEGOTIATION_STAGE 0
418#define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1
419#define ISCSI_FULL_FEATURE_PHASE 3
420
421/* Login Status response classes */
422#define ISCSI_STATUS_CLS_SUCCESS 0x00
423#define ISCSI_STATUS_CLS_REDIRECT 0x01
424#define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02
425#define ISCSI_STATUS_CLS_TARGET_ERR 0x03
426
427/* Login Status response detail codes */
428/* Class-0 (Success) */
429#define ISCSI_LOGIN_STATUS_ACCEPT 0x00
430
431/* Class-1 (Redirection) */
432#define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01
433#define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02
434
435/* Class-2 (Initiator Error) */
436#define ISCSI_LOGIN_STATUS_INIT_ERR 0x00
437#define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01
438#define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02
439#define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03
440#define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04
441#define ISCSI_LOGIN_STATUS_NO_VERSION 0x05
442#define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06
443#define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07
444#define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08
445#define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09
446#define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a
447#define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b
448
449/* Class-3 (Target Error) */
450#define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00
451#define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01
452#define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02
453
454/* Logout Header */
455struct iscsi_logout {
456 uint8_t opcode;
457 uint8_t flags;
458 uint8_t rsvd1[2];
459 uint8_t hlength;
460 uint8_t dlength[3];
461 uint8_t rsvd2[8];
462 __be32 itt; /* Initiator Task Tag */
463 __be16 cid;
464 uint8_t rsvd3[2];
465 __be32 cmdsn;
466 __be32 exp_statsn;
467 uint8_t rsvd4[16];
468};
469
470/* Logout PDU flags */
471#define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F
472
473/* logout reason_code values */
474
475#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0
476#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1
477#define ISCSI_LOGOUT_REASON_RECOVERY 2
478#define ISCSI_LOGOUT_REASON_AEN_REQUEST 3
479
480/* Logout Response Header */
481struct iscsi_logout_rsp {
482 uint8_t opcode;
483 uint8_t flags;
484 uint8_t response; /* see Logout response values below */
485 uint8_t rsvd2;
486 uint8_t hlength;
487 uint8_t dlength[3];
488 uint8_t rsvd3[8];
489 __be32 itt; /* Initiator Task Tag */
490 __be32 rsvd4;
491 __be32 statsn;
492 __be32 exp_cmdsn;
493 __be32 max_cmdsn;
494 __be32 rsvd5;
495 __be16 t2wait;
496 __be16 t2retain;
497 __be32 rsvd6;
498};
499
500/* logout response status values */
501
502#define ISCSI_LOGOUT_SUCCESS 0
503#define ISCSI_LOGOUT_CID_NOT_FOUND 1
504#define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2
505#define ISCSI_LOGOUT_CLEANUP_FAILED 3
506
507/* SNACK Header */
508struct iscsi_snack {
509 uint8_t opcode;
510 uint8_t flags;
511 uint8_t rsvd2[14];
512 __be32 itt;
513 __be32 begrun;
514 __be32 runlength;
515 __be32 exp_statsn;
516 __be32 rsvd3;
517 __be32 exp_datasn;
518 uint8_t rsvd6[8];
519};
520
521/* SNACK PDU flags */
522#define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */
523
524/* Reject Message Header */
525struct iscsi_reject {
526 uint8_t opcode;
527 uint8_t flags;
528 uint8_t reason;
529 uint8_t rsvd2;
530 uint8_t rsvd3;
531 uint8_t dlength[3];
532 uint8_t rsvd4[16];
533 __be32 statsn;
534 __be32 exp_cmdsn;
535 __be32 max_cmdsn;
536 __be32 datasn;
537 uint8_t rsvd5[8];
538 /* Text - Rejected hdr */
539};
540
541/* Reason for Reject */
542#define CMD_BEFORE_LOGIN 1
543#define DATA_DIGEST_ERROR 2
544#define DATA_SNACK_REJECT 3
545#define ISCSI_PROTOCOL_ERROR 4
546#define CMD_NOT_SUPPORTED 5
547#define IMM_CMD_REJECT 6
548#define TASK_IN_PROGRESS 7
549#define INVALID_SNACK 8
550#define BOOKMARK_REJECTED 9
551#define BOOKMARK_NO_RESOURCES 10
552#define NEGOTIATION_RESET 11
553
554/* Max. number of Key=Value pairs in a text message */
555#define MAX_KEY_VALUE_PAIRS 8192
556
557/* maximum length for text keys/values */
558#define KEY_MAXLEN 64
559#define VALUE_MAXLEN 255
560#define TARGET_NAME_MAXLEN VALUE_MAXLEN
561
562#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192
563
564/************************* RFC 3720 End *****************************/
565
566#endif /* ISCSI_PROTO_H */
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 1b26a6c0aa2a..f25041c386ec 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -1,8 +1,10 @@
1/* 1/*
2 * iSCSI transport class definitions 2 * iSCSI transport class definitions
3 * 3 *
4 * Copyright (C) IBM Corporation, 2004 4 * Copyright (C) IBM Corporation, 2004
5 * Copyright (C) Mike Christie, 2004 5 * Copyright (C) Mike Christie, 2004 - 2005
6 * Copyright (C) Dmitry Yusupov, 2004 - 2005
7 * Copyright (C) Alex Aizman, 2004 - 2005
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -21,158 +23,64 @@
21#ifndef SCSI_TRANSPORT_ISCSI_H 23#ifndef SCSI_TRANSPORT_ISCSI_H
22#define SCSI_TRANSPORT_ISCSI_H 24#define SCSI_TRANSPORT_ISCSI_H
23 25
24#include <linux/config.h> 26#include <scsi/iscsi_if.h>
25#include <linux/in6.h>
26#include <linux/in.h>
27
28struct scsi_transport_template;
29 27
30struct iscsi_class_session { 28/**
31 uint8_t isid[6]; 29 * struct iscsi_transport - iSCSI Transport template
32 uint16_t tsih; 30 *
33 int header_digest; /* 1 CRC32, 0 None */ 31 * @name: transport name
34 int data_digest; /* 1 CRC32, 0 None */ 32 * @caps: iSCSI Data-Path capabilities
35 uint16_t tpgt; 33 * @create_session: create new iSCSI session object
36 union { 34 * @destroy_session: destroy existing iSCSI session object
37 struct in6_addr sin6_addr; 35 * @create_conn: create new iSCSI connection
38 struct in_addr sin_addr; 36 * @bind_conn: associate this connection with existing iSCSI session
39 } u; 37 * and specified transport descriptor
40 sa_family_t addr_type; /* must be AF_INET or AF_INET6 */ 38 * @destroy_conn: destroy inactive iSCSI connection
41 uint16_t port; /* must be in network byte order */ 39 * @set_param: set iSCSI Data-Path operational parameter
42 int initial_r2t; /* 1 Yes, 0 No */ 40 * @start_conn: set connection to be operational
43 int immediate_data; /* 1 Yes, 0 No */ 41 * @stop_conn: suspend/recover/terminate connection
44 uint32_t max_recv_data_segment_len; 42 * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
45 uint32_t max_burst_len; 43 *
46 uint32_t first_burst_len; 44 * Template API provided by iSCSI Transport
47 uint16_t def_time2wait; 45 */
48 uint16_t def_time2retain; 46struct iscsi_transport {
49 uint16_t max_outstanding_r2t; 47 struct module *owner;
50 int data_pdu_in_order; /* 1 Yes, 0 No */ 48 char *name;
51 int data_sequence_in_order; /* 1 Yes, 0 No */ 49 unsigned int caps;
52 int erl; 50 struct scsi_host_template *host_template;
51 int hostdata_size;
52 int max_lun;
53 unsigned int max_conn;
54 unsigned int max_cmd_len;
55 iscsi_sessionh_t (*create_session) (uint32_t initial_cmdsn,
56 struct Scsi_Host *shost);
57 void (*destroy_session) (iscsi_sessionh_t session);
58 iscsi_connh_t (*create_conn) (iscsi_sessionh_t session, uint32_t cid);
59 int (*bind_conn) (iscsi_sessionh_t session, iscsi_connh_t conn,
60 uint32_t transport_fd, int is_leading);
61 int (*start_conn) (iscsi_connh_t conn);
62 void (*stop_conn) (iscsi_connh_t conn, int flag);
63 void (*destroy_conn) (iscsi_connh_t conn);
64 int (*set_param) (iscsi_connh_t conn, enum iscsi_param param,
65 uint32_t value);
66 int (*get_param) (iscsi_connh_t conn, enum iscsi_param param,
67 uint32_t *value);
68 int (*send_pdu) (iscsi_connh_t conn, struct iscsi_hdr *hdr,
69 char *data, uint32_t data_size);
70 void (*get_stats) (iscsi_connh_t conn, struct iscsi_stats *stats);
53}; 71};
54 72
55/* 73/*
56 * accessor macros 74 * transport registration upcalls
57 */ 75 */
58#define iscsi_isid(x) \ 76extern int iscsi_register_transport(struct iscsi_transport *tt);
59 (((struct iscsi_class_session *)&(x)->starget_data)->isid) 77extern int iscsi_unregister_transport(struct iscsi_transport *tt);
60#define iscsi_tsih(x) \
61 (((struct iscsi_class_session *)&(x)->starget_data)->tsih)
62#define iscsi_header_digest(x) \
63 (((struct iscsi_class_session *)&(x)->starget_data)->header_digest)
64#define iscsi_data_digest(x) \
65 (((struct iscsi_class_session *)&(x)->starget_data)->data_digest)
66#define iscsi_port(x) \
67 (((struct iscsi_class_session *)&(x)->starget_data)->port)
68#define iscsi_addr_type(x) \
69 (((struct iscsi_class_session *)&(x)->starget_data)->addr_type)
70#define iscsi_sin_addr(x) \
71 (((struct iscsi_class_session *)&(x)->starget_data)->u.sin_addr)
72#define iscsi_sin6_addr(x) \
73 (((struct iscsi_class_session *)&(x)->starget_data)->u.sin6_addr)
74#define iscsi_tpgt(x) \
75 (((struct iscsi_class_session *)&(x)->starget_data)->tpgt)
76#define iscsi_initial_r2t(x) \
77 (((struct iscsi_class_session *)&(x)->starget_data)->initial_r2t)
78#define iscsi_immediate_data(x) \
79 (((struct iscsi_class_session *)&(x)->starget_data)->immediate_data)
80#define iscsi_max_recv_data_segment_len(x) \
81 (((struct iscsi_class_session *)&(x)->starget_data)->max_recv_data_segment_len)
82#define iscsi_max_burst_len(x) \
83 (((struct iscsi_class_session *)&(x)->starget_data)->max_burst_len)
84#define iscsi_first_burst_len(x) \
85 (((struct iscsi_class_session *)&(x)->starget_data)->first_burst_len)
86#define iscsi_def_time2wait(x) \
87 (((struct iscsi_class_session *)&(x)->starget_data)->def_time2wait)
88#define iscsi_def_time2retain(x) \
89 (((struct iscsi_class_session *)&(x)->starget_data)->def_time2retain)
90#define iscsi_max_outstanding_r2t(x) \
91 (((struct iscsi_class_session *)&(x)->starget_data)->max_outstanding_r2t)
92#define iscsi_data_pdu_in_order(x) \
93 (((struct iscsi_class_session *)&(x)->starget_data)->data_pdu_in_order)
94#define iscsi_data_sequence_in_order(x) \
95 (((struct iscsi_class_session *)&(x)->starget_data)->data_sequence_in_order)
96#define iscsi_erl(x) \
97 (((struct iscsi_class_session *)&(x)->starget_data)->erl)
98 78
99/* 79/*
100 * The functions by which the transport class and the driver communicate 80 * control plane upcalls
101 */ 81 */
102struct iscsi_function_template { 82extern void iscsi_conn_error(iscsi_connh_t conn, enum iscsi_err error);
103 /* 83extern int iscsi_recv_pdu(iscsi_connh_t conn, struct iscsi_hdr *hdr,
104 * target attrs 84 char *data, uint32_t data_size);
105 */
106 void (*get_isid)(struct scsi_target *);
107 void (*get_tsih)(struct scsi_target *);
108 void (*get_header_digest)(struct scsi_target *);
109 void (*get_data_digest)(struct scsi_target *);
110 void (*get_port)(struct scsi_target *);
111 void (*get_tpgt)(struct scsi_target *);
112 /*
113 * In get_ip_address the lld must set the address and
114 * the address type
115 */
116 void (*get_ip_address)(struct scsi_target *);
117 /*
118 * The lld should snprintf the name or alias to the buffer
119 */
120 ssize_t (*get_target_name)(struct scsi_target *, char *, ssize_t);
121 ssize_t (*get_target_alias)(struct scsi_target *, char *, ssize_t);
122 void (*get_initial_r2t)(struct scsi_target *);
123 void (*get_immediate_data)(struct scsi_target *);
124 void (*get_max_recv_data_segment_len)(struct scsi_target *);
125 void (*get_max_burst_len)(struct scsi_target *);
126 void (*get_first_burst_len)(struct scsi_target *);
127 void (*get_def_time2wait)(struct scsi_target *);
128 void (*get_def_time2retain)(struct scsi_target *);
129 void (*get_max_outstanding_r2t)(struct scsi_target *);
130 void (*get_data_pdu_in_order)(struct scsi_target *);
131 void (*get_data_sequence_in_order)(struct scsi_target *);
132 void (*get_erl)(struct scsi_target *);
133
134 /*
135 * host atts
136 */
137
138 /*
139 * The lld should snprintf the name or alias to the buffer
140 */
141 ssize_t (*get_initiator_alias)(struct Scsi_Host *, char *, ssize_t);
142 ssize_t (*get_initiator_name)(struct Scsi_Host *, char *, ssize_t);
143 /*
144 * The driver sets these to tell the transport class it
145 * wants the attributes displayed in sysfs. If the show_ flag
146 * is not set, the attribute will be private to the transport
147 * class. We could probably just test if a get_ fn was set
148 * since we only use the values for sysfs but this is how
149 * fc does it too.
150 */
151 unsigned long show_isid:1;
152 unsigned long show_tsih:1;
153 unsigned long show_header_digest:1;
154 unsigned long show_data_digest:1;
155 unsigned long show_port:1;
156 unsigned long show_tpgt:1;
157 unsigned long show_ip_address:1;
158 unsigned long show_target_name:1;
159 unsigned long show_target_alias:1;
160 unsigned long show_initial_r2t:1;
161 unsigned long show_immediate_data:1;
162 unsigned long show_max_recv_data_segment_len:1;
163 unsigned long show_max_burst_len:1;
164 unsigned long show_first_burst_len:1;
165 unsigned long show_def_time2wait:1;
166 unsigned long show_def_time2retain:1;
167 unsigned long show_max_outstanding_r2t:1;
168 unsigned long show_data_pdu_in_order:1;
169 unsigned long show_data_sequence_in_order:1;
170 unsigned long show_erl:1;
171 unsigned long show_initiator_name:1;
172 unsigned long show_initiator_alias:1;
173};
174
175struct scsi_transport_template *iscsi_attach_transport(struct iscsi_function_template *);
176void iscsi_release_transport(struct scsi_transport_template *);
177 85
178#endif 86#endif