iscsi_tcp.c 60.3 KB
Newer Older
1 2 3 4 5
/*
 * iSCSI Initiator over TCP/IP Data-Path
 *
 * Copyright (C) 2004 Dmitry Yusupov
 * Copyright (C) 2004 Alex Aizman
6 7
 * Copyright (C) 2005 - 2006 Mike Christie
 * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 * maintained by open-iscsi@googlegroups.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * See the file COPYING included with this distribution for more details.
 *
 * Credits:
 *	Christoph Hellwig
 *	FUJITA Tomonori
 *	Arne Redlich
 *	Zhenyu Wang
 */

#include <linux/types.h>
#include <linux/list.h>
#include <linux/inet.h>
#include <linux/blkdev.h>
#include <linux/crypto.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <linux/scatterlist.h>
#include <net/tcp.h>
#include <scsi/scsi_cmnd.h>
39
#include <scsi/scsi_device.h>
40 41 42 43 44 45 46 47 48 49 50 51 52 53
#include <scsi/scsi_host.h>
#include <scsi/scsi.h>
#include <scsi/scsi_transport_iscsi.h>

#include "iscsi_tcp.h"

MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
	      "Alex Aizman <itn780@yahoo.com>");
MODULE_DESCRIPTION("iSCSI/TCP data-path");
MODULE_LICENSE("GPL");
/* #define DEBUG_TCP */
#define DEBUG_ASSERT

#ifdef DEBUG_TCP
54
#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#else
#define debug_tcp(fmt...)
#endif

#ifndef DEBUG_ASSERT
#ifdef BUG_ON
#undef BUG_ON
#endif
#define BUG_ON(expr)
#endif

static unsigned int iscsi_max_lun = 512;
module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);

static inline void
iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
{
72 73
	ibuf->sg.page = virt_to_page(vbuf);
	ibuf->sg.offset = offset_in_page(vbuf);
74 75
	ibuf->sg.length = size;
	ibuf->sent = 0;
76
	ibuf->use_sendmsg = 1;
77 78 79 80 81
}

static inline void
iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
{
82 83 84
	ibuf->sg.page = sg->page;
	ibuf->sg.offset = sg->offset;
	ibuf->sg.length = sg->length;
85 86 87
	/*
	 * Fastpath: sg element fits into single page
	 */
M
Mike Christie 已提交
88
	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
89 90 91
		ibuf->use_sendmsg = 0;
	else
		ibuf->use_sendmsg = 1;
92 93 94 95 96 97 98 99 100 101 102 103 104 105
	ibuf->sent = 0;
}

static inline int
iscsi_buf_left(struct iscsi_buf *ibuf)
{
	int rc;

	rc = ibuf->sg.length - ibuf->sent;
	BUG_ON(rc < 0);
	return rc;
}

static inline void
106 107
iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
		 u8* crc)
108
{
109
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
110

111
	crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc);
112
	buf->sg.length += sizeof(u32);
113 114 115
}

static inline int
116
iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn)
117
{
118
	struct sk_buff *skb = tcp_conn->in.skb;
119

120
	tcp_conn->in.zero_copy_hdr = 0;
121

122 123
	if (tcp_conn->in.copy >= tcp_conn->hdr_size &&
	    tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER) {
124 125 126 127 128
		/*
		 * Zero-copy PDU Header: using connection context
		 * to store header pointer.
		 */
		if (skb_shinfo(skb)->frag_list == NULL &&
129 130 131 132 133
		    !skb_shinfo(skb)->nr_frags) {
			tcp_conn->in.hdr = (struct iscsi_hdr *)
				((char*)skb->data + tcp_conn->in.offset);
			tcp_conn->in.zero_copy_hdr = 1;
		} else {
134 135
			/* ignoring return code since we checked
			 * in.copy before */
136 137 138
			skb_copy_bits(skb, tcp_conn->in.offset,
				&tcp_conn->hdr, tcp_conn->hdr_size);
			tcp_conn->in.hdr = &tcp_conn->hdr;
139
		}
140 141
		tcp_conn->in.offset += tcp_conn->hdr_size;
		tcp_conn->in.copy -= tcp_conn->hdr_size;
142 143 144 145 146 147 148 149 150
	} else {
		int hdr_remains;
		int copylen;

		/*
		 * PDU header scattered across SKB's,
		 * copying it... This'll happen quite rarely.
		 */

151 152
		if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER)
			tcp_conn->in.hdr_offset = 0;
153

154
		hdr_remains = tcp_conn->hdr_size - tcp_conn->in.hdr_offset;
155 156
		BUG_ON(hdr_remains <= 0);

157 158 159 160
		copylen = min(tcp_conn->in.copy, hdr_remains);
		skb_copy_bits(skb, tcp_conn->in.offset,
			(char*)&tcp_conn->hdr + tcp_conn->in.hdr_offset,
			copylen);
161 162

		debug_tcp("PDU gather offset %d bytes %d in.offset %d "
163 164
		       "in.copy %d\n", tcp_conn->in.hdr_offset, copylen,
		       tcp_conn->in.offset, tcp_conn->in.copy);
165

166 167
		tcp_conn->in.offset += copylen;
		tcp_conn->in.copy -= copylen;
168
		if (copylen < hdr_remains)  {
169 170
			tcp_conn->in_progress = IN_PROGRESS_HEADER_GATHER;
			tcp_conn->in.hdr_offset += copylen;
171 172
		        return -EAGAIN;
		}
173 174 175
		tcp_conn->in.hdr = &tcp_conn->hdr;
		tcp_conn->discontiguous_hdr_cnt++;
	        tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
176 177 178 179 180
	}

	return 0;
}

M
Mike Christie 已提交
181 182 183 184
/*
 * must be called with session lock
 */
static void
185
iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
186
{
187
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
188
	struct iscsi_r2t_info *r2t;
M
Mike Christie 已提交
189
	struct scsi_cmnd *sc;
190

191 192 193 194 195 196 197
	/* flush ctask's r2t queues */
	while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
			    sizeof(void*));
		debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n");
	}

M
Mike Christie 已提交
198 199
	sc = ctask->sc;
	if (unlikely(!sc))
200
		return;
M
Mike Christie 已提交
201

202 203
	tcp_ctask->xmstate = XMSTATE_IDLE;
	tcp_ctask->r2t = NULL;
204 205 206 207 208 209 210 211 212 213
}

/**
 * iscsi_data_rsp - SCSI Data-In Response processing
 * @conn: iscsi connection
 * @ctask: scsi command task
 **/
static int
iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
214 215 216
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
217
	struct iscsi_session *session = conn->session;
218
	struct scsi_cmnd *sc = ctask->sc;
219 220
	int datasn = be32_to_cpu(rhdr->datasn);

221
	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
222 223 224
	/*
	 * setup Data-In byte counter (gets decremented..)
	 */
225
	ctask->data_count = tcp_conn->in.datalen;
226

227
	if (tcp_conn->in.datalen == 0)
228 229
		return 0;

230 231 232
	if (tcp_ctask->exp_datasn != datasn) {
		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
		          __FUNCTION__, tcp_ctask->exp_datasn, datasn);
233
		return ISCSI_ERR_DATASN;
234
	}
235

236
	tcp_ctask->exp_datasn++;
237

238
	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
239 240 241 242
	if (tcp_ctask->data_offset + tcp_conn->in.datalen > sc->request_bufflen) {
		debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
		          __FUNCTION__, tcp_ctask->data_offset,
		          tcp_conn->in.datalen, sc->request_bufflen);
243
		return ISCSI_ERR_DATA_OFFSET;
244
	}
245 246 247

	if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) {
		conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
248
		if (rhdr->flags & ISCSI_FLAG_DATA_UNDERFLOW) {
249 250 251 252 253 254 255 256 257
			int res_count = be32_to_cpu(rhdr->residual_count);

			if (res_count > 0 &&
			    res_count <= sc->request_bufflen) {
				sc->resid = res_count;
				sc->result = (DID_OK << 16) | rhdr->cmd_status;
			} else
				sc->result = (DID_BAD_TARGET << 16) |
					rhdr->cmd_status;
258
		} else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) {
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
			sc->resid = be32_to_cpu(rhdr->residual_count);
			sc->result = (DID_OK << 16) | rhdr->cmd_status;
		} else
			sc->result = (DID_OK << 16) | rhdr->cmd_status;
	}

	conn->datain_pdus_cnt++;
	return 0;
}

/**
 * iscsi_solicit_data_init - initialize first Data-Out
 * @conn: iscsi connection
 * @ctask: scsi command task
 * @r2t: R2T info
 *
 * Notes:
 *	Initialize first Data-Out within this R2T sequence and finds
 *	proper data_offset within this SCSI command.
 *
 *	This function is called with connection lock taken.
 **/
static void
iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
			struct iscsi_r2t_info *r2t)
{
	struct iscsi_data *hdr;
	struct scsi_cmnd *sc = ctask->sc;

288
	hdr = &r2t->dtask.hdr;
289 290 291 292 293
	memset(hdr, 0, sizeof(struct iscsi_data));
	hdr->ttt = r2t->ttt;
	hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
	r2t->solicit_datasn++;
	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
294 295
	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
	hdr->itt = ctask->hdr->itt;
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
	hdr->exp_statsn = r2t->exp_statsn;
	hdr->offset = cpu_to_be32(r2t->data_offset);
	if (r2t->data_length > conn->max_xmit_dlength) {
		hton24(hdr->dlength, conn->max_xmit_dlength);
		r2t->data_count = conn->max_xmit_dlength;
		hdr->flags = 0;
	} else {
		hton24(hdr->dlength, r2t->data_length);
		r2t->data_count = r2t->data_length;
		hdr->flags = ISCSI_FLAG_CMD_FINAL;
	}
	conn->dataout_pdus_cnt++;

	r2t->sent = 0;

311
	iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
312
			   sizeof(struct iscsi_hdr));
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

	if (sc->use_sg) {
		int i, sg_count = 0;
		struct scatterlist *sg = sc->request_buffer;

		r2t->sg = NULL;
		for (i = 0; i < sc->use_sg; i++, sg += 1) {
			/* FIXME: prefetch ? */
			if (sg_count + sg->length > r2t->data_offset) {
				int page_offset;

				/* sg page found! */

				/* offset within this page */
				page_offset = r2t->data_offset - sg_count;

				/* fill in this buffer */
				iscsi_buf_init_sg(&r2t->sendbuf, sg);
				r2t->sendbuf.sg.offset += page_offset;
				r2t->sendbuf.sg.length -= page_offset;

				/* xmit logic will continue with next one */
				r2t->sg = sg + 1;
				break;
			}
			sg_count += sg->length;
		}
		BUG_ON(r2t->sg == NULL);
341 342
	} else {
		iscsi_buf_init_iov(&r2t->sendbuf,
343 344
			    (char*)sc->request_buffer + r2t->data_offset,
			    r2t->data_count);
345 346
		r2t->sg = NULL;
	}
347 348 349 350 351 352 353 354 355 356 357 358
}

/**
 * iscsi_r2t_rsp - iSCSI R2T Response processing
 * @conn: iscsi connection
 * @ctask: scsi command task
 **/
static int
iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
	struct iscsi_r2t_info *r2t;
	struct iscsi_session *session = conn->session;
359 360 361
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
362 363 364
	int r2tsn = be32_to_cpu(rhdr->r2tsn);
	int rc;

365 366 367
	if (tcp_conn->in.datalen) {
		printk(KERN_ERR "iscsi_tcp: invalid R2t with datalen %d\n",
		       tcp_conn->in.datalen);
368
		return ISCSI_ERR_DATALEN;
369
	}
370

371 372 373
	if (tcp_ctask->exp_datasn != r2tsn){
		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
		          __FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
374
		return ISCSI_ERR_R2TSN;
375
	}
376 377 378

	/* fill-in new R2T associated with the task */
	spin_lock(&session->lock);
379 380
	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);

381 382 383 384 385 386 387
	if (!ctask->sc || ctask->mtask ||
	     session->state != ISCSI_STATE_LOGGED_IN) {
		printk(KERN_INFO "iscsi_tcp: dropping R2T itt %d in "
		       "recovery...\n", ctask->itt);
		spin_unlock(&session->lock);
		return 0;
	}
388

389
	rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
390 391 392 393
	BUG_ON(!rc);

	r2t->exp_statsn = rhdr->statsn;
	r2t->data_length = be32_to_cpu(rhdr->data_length);
394 395
	if (r2t->data_length == 0) {
		printk(KERN_ERR "iscsi_tcp: invalid R2T with zero data len\n");
396 397 398 399
		spin_unlock(&session->lock);
		return ISCSI_ERR_DATALEN;
	}

400 401 402 403 404
	if (r2t->data_length > session->max_burst)
		debug_scsi("invalid R2T with data len %u and max burst %u."
			   "Attempting to execute request.\n",
			    r2t->data_length, session->max_burst);

405
	r2t->data_offset = be32_to_cpu(rhdr->data_offset);
406
	if (r2t->data_offset + r2t->data_length > ctask->sc->request_bufflen) {
407
		spin_unlock(&session->lock);
408 409
		printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at "
		       "offset %u and total length %d\n", r2t->data_length,
410
		       r2t->data_offset, ctask->sc->request_bufflen);
411 412 413 414 415 416 417 418
		return ISCSI_ERR_DATALEN;
	}

	r2t->ttt = rhdr->ttt; /* no flip */
	r2t->solicit_datasn = 0;

	iscsi_solicit_data_init(conn, ctask, r2t);

419
	tcp_ctask->exp_datasn = r2tsn + 1;
420
	__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
421
	tcp_ctask->xmstate |= XMSTATE_SOL_HDR_INIT;
422
	list_move_tail(&ctask->running, &conn->xmitqueue);
423

424
	scsi_queue_work(session->host, &conn->xmitwork);
425 426 427 428 429 430 431
	conn->r2t_pdus_cnt++;
	spin_unlock(&session->lock);

	return 0;
}

static int
432
iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
433
{
434
	int rc = 0, opcode, ahslen;
435 436
	struct iscsi_hdr *hdr;
	struct iscsi_session *session = conn->session;
437 438
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	uint32_t cdgst, rdgst = 0, itt;
439

440
	hdr = tcp_conn->in.hdr;
441 442

	/* verify PDU length */
443 444
	tcp_conn->in.datalen = ntoh24(hdr->dlength);
	if (tcp_conn->in.datalen > conn->max_recv_dlength) {
445
		printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n",
446
		       tcp_conn->in.datalen, conn->max_recv_dlength);
447 448
		return ISCSI_ERR_DATALEN;
	}
449
	tcp_conn->data_copied = 0;
450 451

	/* read AHS */
452 453 454 455
	ahslen = hdr->hlength << 2;
	tcp_conn->in.offset += ahslen;
	tcp_conn->in.copy -= ahslen;
	if (tcp_conn->in.copy < 0) {
456
		printk(KERN_ERR "iscsi_tcp: can't handle AHS with length "
457
		       "%d bytes\n", ahslen);
458 459 460 461
		return ISCSI_ERR_AHSLEN;
	}

	/* calculate read padding */
462 463 464 465
	tcp_conn->in.padding = tcp_conn->in.datalen & (ISCSI_PAD_LEN-1);
	if (tcp_conn->in.padding) {
		tcp_conn->in.padding = ISCSI_PAD_LEN - tcp_conn->in.padding;
		debug_scsi("read padding %d bytes\n", tcp_conn->in.padding);
466 467 468 469 470 471
	}

	if (conn->hdrdgst_en) {
		struct scatterlist sg;

		sg_init_one(&sg, (u8 *)hdr,
472
			    sizeof(struct iscsi_hdr) + ahslen);
473 474
		crypto_hash_digest(&tcp_conn->rx_hash, &sg, sg.length,
				   (u8 *)&cdgst);
475
		rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
476
				     ahslen);
477
		if (cdgst != rdgst) {
478 479
			printk(KERN_ERR "iscsi_tcp: hdrdgst error "
			       "recv 0x%x calc 0x%x\n", rdgst, cdgst);
480 481
			return ISCSI_ERR_HDR_DGST;
		}
482 483
	}

484
	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
485
	/* verify itt (itt encoding: age+cid+itt) */
486 487 488 489 490 491
	rc = iscsi_verify_itt(conn, hdr, &itt);
	if (rc == ISCSI_ERR_NO_SCSI_CMD) {
		tcp_conn->in.datalen = 0; /* force drop */
		return 0;
	} else if (rc)
		return rc;
492 493

	debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n",
494 495
		  opcode, tcp_conn->in.offset, tcp_conn->in.copy,
		  ahslen, tcp_conn->in.datalen);
496

497 498 499 500
	switch(opcode) {
	case ISCSI_OP_SCSI_DATA_IN:
		tcp_conn->in.ctask = session->cmds[itt];
		rc = iscsi_data_rsp(conn, tcp_conn->in.ctask);
501 502
		if (rc)
			return rc;
503 504 505 506 507
		/* fall through */
	case ISCSI_OP_SCSI_CMD_RSP:
		tcp_conn->in.ctask = session->cmds[itt];
		if (tcp_conn->in.datalen)
			goto copy_hdr;
508

509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
		spin_lock(&session->lock);
		rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
		spin_unlock(&session->lock);
		break;
	case ISCSI_OP_R2T:
		tcp_conn->in.ctask = session->cmds[itt];
		if (ahslen)
			rc = ISCSI_ERR_AHSLEN;
		else if (tcp_conn->in.ctask->sc->sc_data_direction ==
								DMA_TO_DEVICE)
			rc = iscsi_r2t_rsp(conn, tcp_conn->in.ctask);
		else
			rc = ISCSI_ERR_PROTO;
		break;
	case ISCSI_OP_LOGIN_RSP:
	case ISCSI_OP_TEXT_RSP:
	case ISCSI_OP_REJECT:
	case ISCSI_OP_ASYNC_EVENT:
527 528 529 530 531
		/*
		 * It is possible that we could get a PDU with a buffer larger
		 * than 8K, but there are no targets that currently do this.
		 * For now we fail until we find a vendor that needs it
		 */
532
		if (ISCSI_DEF_MAX_RECV_SEG_LEN <
533 534 535 536
		    tcp_conn->in.datalen) {
			printk(KERN_ERR "iscsi_tcp: received buffer of len %u "
			      "but conn buffer is only %u (opcode %0x)\n",
			      tcp_conn->in.datalen,
537
			      ISCSI_DEF_MAX_RECV_SEG_LEN, opcode);
538 539 540 541
			rc = ISCSI_ERR_PROTO;
			break;
		}

542 543 544
		if (tcp_conn->in.datalen)
			goto copy_hdr;
	/* fall through */
545 546
	case ISCSI_OP_LOGOUT_RSP:
	case ISCSI_OP_NOOP_IN:
547 548 549 550 551 552 553
	case ISCSI_OP_SCSI_TMFUNC_RSP:
		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
		break;
	default:
		rc = ISCSI_ERR_BAD_OPCODE;
		break;
	}
554 555

	return rc;
556 557 558 559 560 561 562

copy_hdr:
	/*
	 * if we did zero copy for the header but we will need multiple
	 * skbs to complete the command then we have to copy the header
	 * for later use
	 */
563
	if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <=
564 565 566 567 568 569 570 571 572 573
	   (tcp_conn->in.datalen + tcp_conn->in.padding +
	    (conn->datadgst_en ? 4 : 0))) {
		debug_tcp("Copying header for later use. in.copy %d in.datalen"
			  " %d\n", tcp_conn->in.copy, tcp_conn->in.datalen);
		memcpy(&tcp_conn->hdr, tcp_conn->in.hdr,
		       sizeof(struct iscsi_hdr));
		tcp_conn->in.hdr = &tcp_conn->hdr;
		tcp_conn->in.zero_copy_hdr = 0;
	}
	return 0;
574 575 576 577
}

/**
 * iscsi_ctask_copy - copy skb bits to the destanation cmd task
578
 * @conn: iscsi tcp connection
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
 * @ctask: scsi command task
 * @buf: buffer to copy to
 * @buf_size: size of buffer
 * @offset: offset within the buffer
 *
 * Notes:
 *	The function calls skb_copy_bits() and updates per-connection and
 *	per-cmd byte counters.
 *
 *	Read counters (in bytes):
 *
 *	conn->in.offset		offset within in progress SKB
 *	conn->in.copy		left to copy from in progress SKB
 *				including padding
 *	conn->in.copied		copied already from in progress SKB
 *	conn->data_copied	copied already from in progress buffer
 *	ctask->sent		total bytes sent up to the MidLayer
 *	ctask->data_count	left to copy from in progress Data-In
 *	buf_left		left to copy from in progress buffer
 **/
static inline int
600
iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
601 602
		void *buf, int buf_size, int offset)
{
603 604
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	int buf_left = buf_size - (tcp_conn->data_copied + offset);
605
	unsigned size = min(tcp_conn->in.copy, buf_left);
606 607 608 609 610
	int rc;

	size = min(size, ctask->data_count);

	debug_tcp("ctask_copy %d bytes at offset %d copied %d\n",
611
	       size, tcp_conn->in.offset, tcp_conn->in.copied);
612 613

	BUG_ON(size <= 0);
614
	BUG_ON(tcp_ctask->sent + size > ctask->sc->request_bufflen);
615

616 617
	rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
			   (char*)buf + (offset + tcp_conn->data_copied), size);
618 619 620
	/* must fit into skb->len */
	BUG_ON(rc);

621 622 623 624 625
	tcp_conn->in.offset += size;
	tcp_conn->in.copy -= size;
	tcp_conn->in.copied += size;
	tcp_conn->data_copied += size;
	tcp_ctask->sent += size;
626 627
	ctask->data_count -= size;

628
	BUG_ON(tcp_conn->in.copy < 0);
629 630
	BUG_ON(ctask->data_count < 0);

631
	if (buf_size != (tcp_conn->data_copied + offset)) {
632
		if (!ctask->data_count) {
633
			BUG_ON(buf_size - tcp_conn->data_copied < 0);
634
			/* done with this PDU */
635
			return buf_size - tcp_conn->data_copied;
636 637 638 639 640
		}
		return -EAGAIN;
	}

	/* done with this buffer or with both - PDU and buffer */
641
	tcp_conn->data_copied = 0;
642 643 644 645 646
	return 0;
}

/**
 * iscsi_tcp_copy - copy skb bits to the destanation buffer
647
 * @conn: iscsi tcp connection
648 649 650 651 652 653
 *
 * Notes:
 *	The function calls skb_copy_bits() and updates per-connection
 *	byte counters.
 **/
static inline int
654
iscsi_tcp_copy(struct iscsi_conn *conn, int buf_size)
655
{
656
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
657 658
	int buf_left = buf_size - tcp_conn->data_copied;
	int size = min(tcp_conn->in.copy, buf_left);
659 660 661
	int rc;

	debug_tcp("tcp_copy %d bytes at offset %d copied %d\n",
662
	       size, tcp_conn->in.offset, tcp_conn->data_copied);
663 664
	BUG_ON(size <= 0);

665
	rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
666
			   (char*)conn->data + tcp_conn->data_copied, size);
667 668
	BUG_ON(rc);

669 670 671 672
	tcp_conn->in.offset += size;
	tcp_conn->in.copy -= size;
	tcp_conn->in.copied += size;
	tcp_conn->data_copied += size;
673

674
	if (buf_size != tcp_conn->data_copied)
675 676 677 678 679 680
		return -EAGAIN;

	return 0;
}

static inline void
681
partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg,
682
			 int offset, int length)
683 684 685 686 687 688
{
	struct scatterlist temp;

	memcpy(&temp, sg, sizeof(struct scatterlist));
	temp.offset = offset;
	temp.length = length;
689
	crypto_hash_update(desc, &temp, length);
690 691
}

692
static void
693
iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
694 695 696 697
{
	struct scatterlist tmp;

	sg_init_one(&tmp, buf, len);
698
	crypto_hash_update(&tcp_conn->rx_hash, &tmp, len);
699 700
}

701 702
static int iscsi_scsi_data_in(struct iscsi_conn *conn)
{
703 704 705
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_cmd_task *ctask = tcp_conn->in.ctask;
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
706
	struct scsi_cmnd *sc = ctask->sc;
707
	struct scatterlist *sg;
708 709 710 711 712 713 714 715 716
	int i, offset, rc = 0;

	BUG_ON((void*)ctask != sc->SCp.ptr);

	/*
	 * copying Data-In into the Scsi_Cmnd
	 */
	if (!sc->use_sg) {
		i = ctask->data_count;
717 718 719
		rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer,
				      sc->request_bufflen,
				      tcp_ctask->data_offset);
720 721
		if (rc == -EAGAIN)
			return rc;
722
		if (conn->datadgst_en)
723 724
			iscsi_recv_digest_update(tcp_conn, sc->request_buffer,
						 i);
725 726 727 728
		rc = 0;
		goto done;
	}

729
	offset = tcp_ctask->data_offset;
730 731
	sg = sc->request_buffer;

732 733
	if (tcp_ctask->data_offset)
		for (i = 0; i < tcp_ctask->sg_count; i++)
734 735 736 737 738
			offset -= sg[i].length;
	/* we've passed through partial sg*/
	if (offset < 0)
		offset = 0;

739
	for (i = tcp_ctask->sg_count; i < sc->use_sg; i++) {
740 741 742
		char *dest;

		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
743
		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
744 745 746 747 748 749 750 751
				      sg[i].length, offset);
		kunmap_atomic(dest, KM_SOFTIRQ0);
		if (rc == -EAGAIN)
			/* continue with the next SKB/PDU */
			return rc;
		if (!rc) {
			if (conn->datadgst_en) {
				if (!offset)
752
					crypto_hash_update(
753
							&tcp_conn->rx_hash,
754
							&sg[i], sg[i].length);
755
				else
756
					partial_sg_digest_update(
757
							&tcp_conn->rx_hash,
758
							&sg[i],
759 760 761 762
							sg[i].offset + offset,
							sg[i].length - offset);
			}
			offset = 0;
763
			tcp_ctask->sg_count++;
764 765 766 767 768 769 770
		}

		if (!ctask->data_count) {
			if (rc && conn->datadgst_en)
				/*
				 * data-in is complete, but buffer not...
				 */
771 772 773 774
				partial_sg_digest_update(&tcp_conn->rx_hash,
							 &sg[i],
							 sg[i].offset,
							 sg[i].length-rc);
775 776 777 778
			rc = 0;
			break;
		}

779
		if (!tcp_conn->in.copy)
780 781 782 783 784 785
			return -EAGAIN;
	}
	BUG_ON(ctask->data_count);

done:
	/* check for non-exceptional status */
786
	if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) {
787 788 789
		debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n",
			   (long)sc, sc->result, ctask->itt,
			   tcp_conn->in.hdr->flags);
790 791 792
		spin_lock(&conn->session->lock);
		__iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
		spin_unlock(&conn->session->lock);
793 794 795 796 797 798 799 800
	}

	return rc;
}

static int
iscsi_data_recv(struct iscsi_conn *conn)
{
801 802
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	int rc = 0, opcode;
803

804 805
	opcode = tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK;
	switch (opcode) {
806 807 808
	case ISCSI_OP_SCSI_DATA_IN:
		rc = iscsi_scsi_data_in(conn);
		break;
809
	case ISCSI_OP_SCSI_CMD_RSP:
810 811
	case ISCSI_OP_TEXT_RSP:
	case ISCSI_OP_LOGIN_RSP:
812 813
	case ISCSI_OP_ASYNC_EVENT:
	case ISCSI_OP_REJECT:
814 815 816 817
		/*
		 * Collect data segment to the connection's data
		 * placeholder
		 */
818
		if (iscsi_tcp_copy(conn, tcp_conn->in.datalen)) {
819 820 821 822
			rc = -EAGAIN;
			goto exit;
		}

823
		rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data,
824 825
					tcp_conn->in.datalen);
		if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP)
826
			iscsi_recv_digest_update(tcp_conn, conn->data,
827 828
			  			tcp_conn->in.datalen);
		break;
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848
	default:
		BUG_ON(1);
	}
exit:
	return rc;
}

/**
 * iscsi_tcp_data_recv - TCP receive in sendfile fashion
 * @rd_desc: read descriptor
 * @skb: socket buffer
 * @offset: offset in skb
 * @len: skb->len - offset
 **/
static int
iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
		unsigned int offset, size_t len)
{
	int rc;
	struct iscsi_conn *conn = rd_desc->arg.data;
849
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
850 851 852 853 854 855 856 857
	int processed;
	char pad[ISCSI_PAD_LEN];
	struct scatterlist sg;

	/*
	 * Save current SKB and its offset in the corresponding
	 * connection context.
	 */
858 859 860 861 862 863
	tcp_conn->in.copy = skb->len - offset;
	tcp_conn->in.offset = offset;
	tcp_conn->in.skb = skb;
	tcp_conn->in.len = tcp_conn->in.copy;
	BUG_ON(tcp_conn->in.copy <= 0);
	debug_tcp("in %d bytes\n", tcp_conn->in.copy);
864 865

more:
866
	tcp_conn->in.copied = 0;
867 868 869 870 871 872 873
	rc = 0;

	if (unlikely(conn->suspend_rx)) {
		debug_tcp("conn %d Rx suspended!\n", conn->id);
		return 0;
	}

874 875 876
	if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER ||
	    tcp_conn->in_progress == IN_PROGRESS_HEADER_GATHER) {
		rc = iscsi_hdr_extract(tcp_conn);
877 878 879 880
		if (rc) {
		       if (rc == -EAGAIN)
				goto nomore;
		       else {
881
				iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
882 883 884 885 886 887 888
				return 0;
		       }
		}

		/*
		 * Verify and process incoming PDU header.
		 */
889 890
		rc = iscsi_tcp_hdr_recv(conn);
		if (!rc && tcp_conn->in.datalen) {
891
			if (conn->datadgst_en)
892
				crypto_hash_init(&tcp_conn->rx_hash);
893
			tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
894
		} else if (rc) {
895
			iscsi_conn_failure(conn, rc);
896 897 898 899
			return 0;
		}
	}

900 901
	if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV &&
	    tcp_conn->in.copy) {
902
		uint32_t recv_digest;
903

904
		debug_tcp("extra data_recv offset %d copy %d\n",
905
			  tcp_conn->in.offset, tcp_conn->in.copy);
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920

		if (!tcp_conn->data_copied) {
			if (tcp_conn->in.padding) {
				debug_tcp("padding -> %d\n",
					  tcp_conn->in.padding);
				memset(pad, 0, tcp_conn->in.padding);
				sg_init_one(&sg, pad, tcp_conn->in.padding);
				crypto_hash_update(&tcp_conn->rx_hash,
						   &sg, sg.length);
			}
			crypto_hash_final(&tcp_conn->rx_hash,
					  (u8 *) &tcp_conn->in.datadgst);
			debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
		}

921 922 923 924 925 926 927 928 929
		rc = iscsi_tcp_copy(conn, sizeof(uint32_t));
		if (rc) {
			if (rc == -EAGAIN)
				goto again;
			iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
			return 0;
		}

		memcpy(&recv_digest, conn->data, sizeof(uint32_t));
930
		if (recv_digest != tcp_conn->in.datadgst) {
931 932
			debug_tcp("iscsi_tcp: data digest error!"
				  "0x%x != 0x%x\n", recv_digest,
933
				  tcp_conn->in.datadgst);
934 935 936 937 938
			iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
			return 0;
		} else {
			debug_tcp("iscsi_tcp: data digest match!"
				  "0x%x == 0x%x\n", recv_digest,
939 940
				  tcp_conn->in.datadgst);
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
941 942 943
		}
	}

944
	if (tcp_conn->in_progress == IN_PROGRESS_DATA_RECV &&
945
	    tcp_conn->in.copy) {
946
		debug_tcp("data_recv offset %d copy %d\n",
947
		       tcp_conn->in.offset, tcp_conn->in.copy);
948 949 950

		rc = iscsi_data_recv(conn);
		if (rc) {
951
			if (rc == -EAGAIN)
952
				goto again;
953
			iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
954 955
			return 0;
		}
956 957 958 959

		if (tcp_conn->in.padding)
			tcp_conn->in_progress = IN_PROGRESS_PAD_RECV;
		else if (conn->datadgst_en)
960
			tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
		else
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
		tcp_conn->data_copied = 0;
	}

	if (tcp_conn->in_progress == IN_PROGRESS_PAD_RECV &&
	    tcp_conn->in.copy) {
		int copylen = min(tcp_conn->in.padding - tcp_conn->data_copied,
				  tcp_conn->in.copy);

		tcp_conn->in.copy -= copylen;
		tcp_conn->in.offset += copylen;
		tcp_conn->data_copied += copylen;

		if (tcp_conn->data_copied != tcp_conn->in.padding)
			tcp_conn->in_progress = IN_PROGRESS_PAD_RECV;
		else if (conn->datadgst_en)
			tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
		else
980
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
981
		tcp_conn->data_copied = 0;
982 983 984
	}

	debug_tcp("f, processed %d from out of %d padding %d\n",
985 986
	       tcp_conn->in.offset - offset, (int)len, tcp_conn->in.padding);
	BUG_ON(tcp_conn->in.offset - offset > len);
987

988
	if (tcp_conn->in.offset - offset != len) {
989
		debug_tcp("continue to process %d bytes\n",
990
		       (int)len - (tcp_conn->in.offset - offset));
991 992 993 994
		goto more;
	}

nomore:
995
	processed = tcp_conn->in.offset - offset;
996 997 998 999
	BUG_ON(processed == 0);
	return processed;

again:
1000
	processed = tcp_conn->in.offset - offset;
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
	debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n",
	          processed, (int)len, (int)rd_desc->count);
	BUG_ON(processed == 0);
	BUG_ON(processed > len);

	conn->rxdata_octets += processed;
	return processed;
}

static void
iscsi_tcp_data_ready(struct sock *sk, int flag)
{
	struct iscsi_conn *conn = sk->sk_user_data;
	read_descriptor_t rd_desc;

	read_lock(&sk->sk_callback_lock);

1018 1019 1020 1021 1022 1023
	/*
	 * Use rd_desc to pass 'conn' to iscsi_tcp_data_recv.
	 * We set count to 1 because we want the network layer to
	 * hand us all the skbs that are available. iscsi_tcp_data_recv
	 * handled pdus that cross buffers or pdus that still need data.
	 */
1024
	rd_desc.arg.data = conn;
1025
	rd_desc.count = 1;
1026 1027 1028 1029 1030 1031 1032 1033
	tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv);

	read_unlock(&sk->sk_callback_lock);
}

static void
iscsi_tcp_state_change(struct sock *sk)
{
1034
	struct iscsi_tcp_conn *tcp_conn;
1035 1036 1037 1038 1039 1040 1041 1042 1043
	struct iscsi_conn *conn;
	struct iscsi_session *session;
	void (*old_state_change)(struct sock *);

	read_lock(&sk->sk_callback_lock);

	conn = (struct iscsi_conn*)sk->sk_user_data;
	session = conn->session;

M
Mike Christie 已提交
1044 1045 1046
	if ((sk->sk_state == TCP_CLOSE_WAIT ||
	     sk->sk_state == TCP_CLOSE) &&
	    !atomic_read(&sk->sk_rmem_alloc)) {
1047 1048 1049 1050
		debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
	}

1051 1052
	tcp_conn = conn->dd_data;
	old_state_change = tcp_conn->old_state_change;
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066

	read_unlock(&sk->sk_callback_lock);

	old_state_change(sk);
}

/**
 * iscsi_write_space - Called when more output buffer space is available
 * @sk: socket space is available for
 **/
static void
iscsi_write_space(struct sock *sk)
{
	struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data;
1067 1068 1069
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;

	tcp_conn->old_write_space(sk);
1070
	debug_tcp("iscsi_write_space: cid %d\n", conn->id);
1071
	scsi_queue_work(conn->session->host, &conn->xmitwork);
1072 1073 1074 1075 1076
}

static void
iscsi_conn_set_callbacks(struct iscsi_conn *conn)
{
1077 1078
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct sock *sk = tcp_conn->sock->sk;
1079 1080 1081 1082

	/* assign new callbacks */
	write_lock_bh(&sk->sk_callback_lock);
	sk->sk_user_data = conn;
1083 1084 1085
	tcp_conn->old_data_ready = sk->sk_data_ready;
	tcp_conn->old_state_change = sk->sk_state_change;
	tcp_conn->old_write_space = sk->sk_write_space;
1086 1087 1088 1089 1090 1091 1092
	sk->sk_data_ready = iscsi_tcp_data_ready;
	sk->sk_state_change = iscsi_tcp_state_change;
	sk->sk_write_space = iscsi_write_space;
	write_unlock_bh(&sk->sk_callback_lock);
}

static void
1093
iscsi_conn_restore_callbacks(struct iscsi_tcp_conn *tcp_conn)
1094
{
1095
	struct sock *sk = tcp_conn->sock->sk;
1096 1097 1098 1099

	/* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
	write_lock_bh(&sk->sk_callback_lock);
	sk->sk_user_data    = NULL;
1100 1101 1102
	sk->sk_data_ready   = tcp_conn->old_data_ready;
	sk->sk_state_change = tcp_conn->old_state_change;
	sk->sk_write_space  = tcp_conn->old_write_space;
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
	sk->sk_no_check	 = 0;
	write_unlock_bh(&sk->sk_callback_lock);
}

/**
 * iscsi_send - generic send routine
 * @sk: kernel's socket
 * @buf: buffer to write from
 * @size: actual size to write
 * @flags: socket's flags
 */
static inline int
1115
iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
1116
{
1117 1118
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct socket *sk = tcp_conn->sock;
1119
	int offset = buf->sg.offset + buf->sent, res;
1120

1121 1122 1123 1124 1125 1126 1127 1128 1129
	/*
	 * if we got use_sg=0 or are sending something we kmallocd
	 * then we did not have to do kmap (kmap returns page_address)
	 *
	 * if we got use_sg > 0, but had to drop down, we do not
	 * set clustering so this should only happen for that
	 * slab case.
	 */
	if (buf->use_sendmsg)
1130
		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
1131
	else
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);

	if (res >= 0) {
		conn->txdata_octets += res;
		buf->sent += res;
		return res;
	}

	tcp_conn->sendpage_failures_cnt++;
	if (res == -EAGAIN)
		res = -ENOBUFS;
	else
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
	return res;
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167
}

/**
 * iscsi_sendhdr - send PDU Header via tcp_sendpage()
 * @conn: iscsi connection
 * @buf: buffer to write from
 * @datalen: lenght of data to be sent after the header
 *
 * Notes:
 *	(Tx, Fast Path)
 **/
static inline int
iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
{
	int flags = 0; /* MSG_DONTWAIT; */
	int res, size;

	size = buf->sg.length - buf->sent;
	BUG_ON(buf->sent + size > buf->sg.length);
	if (buf->sent + size != buf->sg.length || datalen)
		flags |= MSG_MORE;

1168
	res = iscsi_send(conn, buf, size, flags);
1169 1170 1171 1172 1173
	debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
	if (res >= 0) {
		if (size != res)
			return -EAGAIN;
		return 0;
1174
	}
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199

	return res;
}

/**
 * iscsi_sendpage - send one page of iSCSI Data-Out.
 * @conn: iscsi connection
 * @buf: buffer to write from
 * @count: remaining data
 * @sent: number of bytes sent
 *
 * Notes:
 *	(Tx, Fast Path)
 **/
static inline int
iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
	       int *count, int *sent)
{
	int flags = 0; /* MSG_DONTWAIT; */
	int res, size;

	size = buf->sg.length - buf->sent;
	BUG_ON(buf->sent + size > buf->sg.length);
	if (size > *count)
		size = *count;
M
Mike Christie 已提交
1200
	if (buf->sent + size != buf->sg.length || *count != size)
1201 1202
		flags |= MSG_MORE;

1203
	res = iscsi_send(conn, buf, size, flags);
1204 1205 1206 1207 1208 1209 1210 1211
	debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
		  size, buf->sent, *count, *sent, res);
	if (res >= 0) {
		*count -= res;
		*sent += res;
		if (size != res)
			return -EAGAIN;
		return 0;
1212
	}
1213 1214 1215 1216 1217

	return res;
}

static inline void
1218
iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
1219
		      struct iscsi_tcp_cmd_task *tcp_ctask)
1220
{
1221
	crypto_hash_init(&tcp_conn->tx_hash);
1222
	tcp_ctask->digest_count = 4;
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
}

/**
 * iscsi_solicit_data_cont - initialize next Data-Out
 * @conn: iscsi connection
 * @ctask: scsi command task
 * @r2t: R2T info
 * @left: bytes left to transfer
 *
 * Notes:
 *	Initialize next Data-Out within this R2T sequence and continue
 *	to process next Scatter-Gather element(if any) of this SCSI command.
 *
 *	Called under connection lock.
 **/
static void
iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
			struct iscsi_r2t_info *r2t, int left)
{
	struct iscsi_data *hdr;
	struct scsi_cmnd *sc = ctask->sc;
	int new_offset;

1246
	hdr = &r2t->dtask.hdr;
1247 1248 1249 1250 1251
	memset(hdr, 0, sizeof(struct iscsi_data));
	hdr->ttt = r2t->ttt;
	hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
	r2t->solicit_datasn++;
	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
1252 1253
	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
	hdr->itt = ctask->hdr->itt;
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
	hdr->exp_statsn = r2t->exp_statsn;
	new_offset = r2t->data_offset + r2t->sent;
	hdr->offset = cpu_to_be32(new_offset);
	if (left > conn->max_xmit_dlength) {
		hton24(hdr->dlength, conn->max_xmit_dlength);
		r2t->data_count = conn->max_xmit_dlength;
	} else {
		hton24(hdr->dlength, left);
		r2t->data_count = left;
		hdr->flags = ISCSI_FLAG_CMD_FINAL;
	}
	conn->dataout_pdus_cnt++;

1267
	iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
1268
			   sizeof(struct iscsi_hdr));
1269

1270 1271 1272 1273
	if (iscsi_buf_left(&r2t->sendbuf))
		return;

	if (sc->use_sg) {
1274 1275
		iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
		r2t->sg += 1;
1276 1277
	} else {
		iscsi_buf_init_iov(&r2t->sendbuf,
1278 1279
			    (char*)sc->request_buffer + new_offset,
			    r2t->data_count);
1280 1281
		r2t->sg = NULL;
	}
1282 1283
}

1284 1285
static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask,
			      unsigned long len)
1286
{
1287 1288 1289
	tcp_ctask->pad_count = len & (ISCSI_PAD_LEN - 1);
	if (!tcp_ctask->pad_count)
		return;
1290

1291 1292 1293
	tcp_ctask->pad_count = ISCSI_PAD_LEN - tcp_ctask->pad_count;
	debug_scsi("write padding %d bytes\n", tcp_ctask->pad_count);
	tcp_ctask->xmstate |= XMSTATE_W_PAD;
1294 1295 1296
}

/**
1297
 * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
1298 1299 1300 1301 1302
 * @conn: iscsi connection
 * @ctask: scsi command task
 * @sc: scsi command
 **/
static void
1303
iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1304
{
1305
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1306

1307
	BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
1308
	tcp_ctask->xmstate = XMSTATE_CMD_HDR_INIT;
1309 1310 1311
}

/**
1312
 * iscsi_tcp_mtask_xmit - xmit management(immediate) task
1313 1314 1315 1316 1317 1318 1319 1320
 * @conn: iscsi connection
 * @mtask: task management task
 *
 * Notes:
 *	The function can return -EAGAIN in which case caller must
 *	call it again later, or recover. '0' return code means successful
 *	xmit.
 *
1321 1322 1323 1324 1325
 *	Management xmit state machine consists of these states:
 *		XMSTATE_IMM_HDR_INIT	- calculate digest of PDU Header
 *		XMSTATE_IMM_HDR 	- PDU Header xmit in progress
 *		XMSTATE_IMM_DATA 	- PDU Data xmit in progress
 *		XMSTATE_IDLE		- management PDU is done
1326 1327
 **/
static int
1328
iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1329
{
1330
	struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
1331
	int rc;
1332 1333

	debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
1334
		conn->id, tcp_mtask->xmstate, mtask->itt);
1335

1336 1337 1338 1339 1340
	if (tcp_mtask->xmstate & XMSTATE_IMM_HDR_INIT) {
		iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
				   sizeof(struct iscsi_hdr));

		if (mtask->data_count) {
1341
			tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
1342 1343 1344 1345 1346
			iscsi_buf_init_iov(&tcp_mtask->sendbuf,
					   (char*)mtask->data,
					   mtask->data_count);
		}

1347
		if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
M
Mike Christie 已提交
1348
		    conn->stop_stage != STOP_CONN_RECOVER &&
1349
		    conn->hdrdgst_en)
1350 1351
			iscsi_hdr_digest(conn, &tcp_mtask->headbuf,
					(u8*)tcp_mtask->hdrext);
1352 1353 1354 1355 1356 1357 1358

		tcp_mtask->sent = 0;
		tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR_INIT;
		tcp_mtask->xmstate |= XMSTATE_IMM_HDR;
	}

	if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) {
1359 1360
		rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf,
				   mtask->data_count);
1361
		if (rc)
1362
			return rc;
1363
		tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR;
1364 1365
	}

1366
	if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) {
1367
		BUG_ON(!mtask->data_count);
1368
		tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA;
1369 1370 1371 1372
		/* FIXME: implement.
		 * Virtual buffer could be spreaded across multiple pages...
		 */
		do {
1373 1374 1375 1376 1377
			int rc;

			rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf,
					&mtask->data_count, &tcp_mtask->sent);
			if (rc) {
1378
				tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
1379
				return rc;
1380 1381 1382 1383
			}
		} while (mtask->data_count);
	}

1384
	BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE);
A
Al Viro 已提交
1385
	if (mtask->hdr->itt == RESERVED_ITT) {
1386 1387 1388 1389 1390 1391 1392 1393
		struct iscsi_session *session = conn->session;

		spin_lock_bh(&session->lock);
		list_del(&conn->mtask->running);
		__kfifo_put(session->mgmtpool.queue, (void*)&conn->mtask,
			    sizeof(void*));
		spin_unlock_bh(&session->lock);
	}
1394 1395 1396
	return 0;
}

1397 1398
static int
iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1399
{
1400 1401 1402
	struct scsi_cmnd *sc = ctask->sc;
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	int rc = 0;
1403

1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
	if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_INIT) {
		tcp_ctask->sent = 0;
		tcp_ctask->sg_count = 0;
		tcp_ctask->exp_datasn = 0;

		if (sc->sc_data_direction == DMA_TO_DEVICE) {
			if (sc->use_sg) {
				struct scatterlist *sg = sc->request_buffer;

				iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg);
				tcp_ctask->sg = sg + 1;
				tcp_ctask->bad_sg = sg + sc->use_sg;
			} else {
				iscsi_buf_init_iov(&tcp_ctask->sendbuf,
						   sc->request_buffer,
						   sc->request_bufflen);
				tcp_ctask->sg = NULL;
				tcp_ctask->bad_sg = NULL;
			}
1423

1424 1425 1426 1427 1428 1429
			debug_scsi("cmd [itt 0x%x total %d imm_data %d "
				   "unsol count %d, unsol offset %d]\n",
				   ctask->itt, sc->request_bufflen,
				   ctask->imm_count, ctask->unsol_count,
				   ctask->unsol_offset);
		}
1430

1431 1432 1433 1434 1435 1436 1437 1438
		iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr,
				  sizeof(struct iscsi_hdr));

		if (conn->hdrdgst_en)
			iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
					 (u8*)tcp_ctask->hdrext);
		tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_INIT;
		tcp_ctask->xmstate |= XMSTATE_CMD_HDR_XMIT;
1439 1440
	}

1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452
	if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_XMIT) {
		rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
		if (rc)
			return rc;
		tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_XMIT;

		if (sc->sc_data_direction != DMA_TO_DEVICE)
			return 0;

		if (ctask->imm_count) {
			tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
			iscsi_set_padding(tcp_ctask, ctask->imm_count);
1453

1454 1455 1456 1457 1458
			if (ctask->conn->datadgst_en) {
				iscsi_data_digest_init(ctask->conn->dd_data,
						       tcp_ctask);
				tcp_ctask->immdigest = 0;
			}
1459 1460
		}

1461 1462 1463 1464 1465
		if (ctask->unsol_count)
			tcp_ctask->xmstate |=
					XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
	}
	return rc;
1466 1467
}

1468 1469
static int
iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1470
{
1471
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1472 1473
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	int sent = 0, rc;
1474

1475 1476 1477 1478
	if (tcp_ctask->xmstate & XMSTATE_W_PAD) {
		iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
				   tcp_ctask->pad_count);
		if (conn->datadgst_en)
1479 1480 1481
			crypto_hash_update(&tcp_conn->tx_hash,
					   &tcp_ctask->sendbuf.sg,
					   tcp_ctask->sendbuf.sg.length);
1482 1483 1484 1485 1486 1487 1488 1489 1490
	} else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD))
		return 0;

	tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
	tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_PAD;
	debug_scsi("sending %d pad bytes for itt 0x%x\n",
		   tcp_ctask->pad_count, ctask->itt);
	rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
			   &sent);
1491
	if (rc) {
1492 1493
		debug_scsi("padding send failed %d\n", rc);
		tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD;
1494
	}
1495
	return rc;
1496 1497
}

1498 1499 1500
static int
iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
			struct iscsi_buf *buf, uint32_t *digest)
1501
{
1502 1503 1504
	struct iscsi_tcp_cmd_task *tcp_ctask;
	struct iscsi_tcp_conn *tcp_conn;
	int rc, sent = 0;
1505

1506 1507
	if (!conn->datadgst_en)
		return 0;
1508

1509 1510
	tcp_ctask = ctask->dd_data;
	tcp_conn = conn->dd_data;
1511

1512
	if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
1513
		crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest);
1514 1515 1516
		iscsi_buf_init_iov(buf, (char*)digest, 4);
	}
	tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
1517

1518 1519 1520 1521 1522 1523 1524 1525
	rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
	if (!rc)
		debug_scsi("sent digest 0x%x for itt 0x%x\n", *digest,
			  ctask->itt);
	else {
		debug_scsi("sending digest 0x%x failed for itt 0x%x!\n",
			  *digest, ctask->itt);
		tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST;
1526
	}
1527 1528
	return rc;
}
1529

1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546
static int
iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf,
		struct scatterlist **sg, int *sent, int *count,
		struct iscsi_buf *digestbuf, uint32_t *digest)
{
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	struct iscsi_conn *conn = ctask->conn;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	int rc, buf_sent, offset;

	while (*count) {
		buf_sent = 0;
		offset = sendbuf->sent;

		rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent);
		*sent = *sent + buf_sent;
		if (buf_sent && conn->datadgst_en)
1547
			partial_sg_digest_update(&tcp_conn->tx_hash,
1548 1549 1550 1551 1552
				&sendbuf->sg, sendbuf->sg.offset + offset,
				buf_sent);
		if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) {
			iscsi_buf_init_sg(sendbuf, *sg);
			*sg = *sg + 1;
1553
		}
1554 1555 1556

		if (rc)
			return rc;
1557 1558
	}

1559 1560 1561 1562 1563
	rc = iscsi_send_padding(conn, ctask);
	if (rc)
		return rc;

	return iscsi_send_digest(conn, ctask, digestbuf, digest);
1564 1565
}

1566 1567
static int
iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1568
{
1569
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1570
	struct iscsi_data_task *dtask;
1571
	int rc;
1572

1573 1574
	tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
	if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
1575 1576
		dtask = &tcp_ctask->unsol_dtask;

1577 1578 1579
		iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
		iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
				   sizeof(struct iscsi_hdr));
1580
		if (conn->hdrdgst_en)
1581
			iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1582
					(u8*)dtask->hdrext);
1583

1584
		tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
1585
		iscsi_set_padding(tcp_ctask, ctask->data_count);
1586
	}
1587 1588 1589

	rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count);
	if (rc) {
1590 1591
		tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
		tcp_ctask->xmstate |= XMSTATE_UNS_HDR;
1592
		return rc;
1593 1594
	}

1595 1596 1597 1598 1599 1600
	if (conn->datadgst_en) {
		dtask = &tcp_ctask->unsol_dtask;
		iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
		dtask->digest = 0;
	}

1601
	debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
1602
		   ctask->itt, ctask->unsol_count, tcp_ctask->sent);
1603 1604 1605
	return 0;
}

1606 1607
static int
iscsi_send_unsol_pdu(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1608
{
1609
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1610
	int rc;
1611

1612 1613 1614 1615 1616 1617 1618
	if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) {
		BUG_ON(!ctask->unsol_count);
		tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR;
send_hdr:
		rc = iscsi_send_unsol_hdr(conn, ctask);
		if (rc)
			return rc;
1619 1620
	}

1621 1622
	if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
		struct iscsi_data_task *dtask = &tcp_ctask->unsol_dtask;
1623
		int start = tcp_ctask->sent;
1624

1625 1626 1627
		rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
				     &tcp_ctask->sent, &ctask->data_count,
				     &dtask->digestbuf, &dtask->digest);
1628
		ctask->unsol_count -= tcp_ctask->sent - start;
1629 1630 1631
		if (rc)
			return rc;
		tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
1632
		/*
1633 1634
		 * Done with the Data-Out. Next, check if we need
		 * to send another unsolicited Data-Out.
1635
		 */
1636 1637 1638 1639
		if (ctask->unsol_count) {
			debug_scsi("sending more uns\n");
			tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
			goto send_hdr;
1640 1641 1642 1643 1644
		}
	}
	return 0;
}

1645 1646
static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
			      struct iscsi_cmd_task *ctask)
1647
{
1648
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1649 1650 1651
	struct iscsi_session *session = conn->session;
	struct iscsi_r2t_info *r2t;
	struct iscsi_data_task *dtask;
1652
	int left, rc;
1653

1654
	if (tcp_ctask->xmstate & XMSTATE_SOL_HDR_INIT) {
1655 1656
		if (!tcp_ctask->r2t) {
			spin_lock_bh(&session->lock);
1657 1658
			__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
				    sizeof(void*));
1659 1660
			spin_unlock_bh(&session->lock);
		}
1661 1662 1663
send_hdr:
		r2t = tcp_ctask->r2t;
		dtask = &r2t->dtask;
1664

1665 1666 1667
		if (conn->hdrdgst_en)
			iscsi_hdr_digest(conn, &r2t->headbuf,
					(u8*)dtask->hdrext);
1668 1669 1670 1671 1672 1673 1674 1675
		tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR_INIT;
		tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
	}

	if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
		r2t = tcp_ctask->r2t;
		dtask = &r2t->dtask;

1676
		rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1677
		if (rc)
1678
			return rc;
1679 1680
		tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
		tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1681 1682

		if (conn->datadgst_en) {
1683 1684
			iscsi_data_digest_init(conn->dd_data, tcp_ctask);
			dtask->digest = 0;
1685 1686
		}

1687 1688 1689 1690
		iscsi_set_padding(tcp_ctask, r2t->data_count);
		debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
			r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
			r2t->sent);
1691 1692
	}

1693 1694 1695
	if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) {
		r2t = tcp_ctask->r2t;
		dtask = &r2t->dtask;
1696

1697 1698 1699 1700 1701 1702
		rc = iscsi_send_data(ctask, &r2t->sendbuf, &r2t->sg,
				     &r2t->sent, &r2t->data_count,
				     &dtask->digestbuf, &dtask->digest);
		if (rc)
			return rc;
		tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1703

1704 1705 1706 1707 1708 1709 1710 1711 1712 1713
		/*
		 * Done with this Data-Out. Next, check if we have
		 * to send another Data-Out for this R2T.
		 */
		BUG_ON(r2t->data_length - r2t->sent < 0);
		left = r2t->data_length - r2t->sent;
		if (left) {
			iscsi_solicit_data_cont(conn, ctask, r2t, left);
			goto send_hdr;
		}
1714

1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727
		/*
		 * Done with this R2T. Check if there are more
		 * outstanding R2Ts ready to be processed.
		 */
		spin_lock_bh(&session->lock);
		tcp_ctask->r2t = NULL;
		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
			    sizeof(void*));
		if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t,
				sizeof(void*))) {
			tcp_ctask->r2t = r2t;
			spin_unlock_bh(&session->lock);
			goto send_hdr;
1728
		}
1729
		spin_unlock_bh(&session->lock);
1730 1731 1732 1733
	}
	return 0;
}

1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773
/**
 * iscsi_tcp_ctask_xmit - xmit normal PDU task
 * @conn: iscsi connection
 * @ctask: iscsi command task
 *
 * Notes:
 *	The function can return -EAGAIN in which case caller must
 *	call it again later, or recover. '0' return code means successful
 *	xmit.
 *	The function is devided to logical helpers (above) for the different
 *	xmit stages.
 *
 *iscsi_send_cmd_hdr()
 *	XMSTATE_CMD_HDR_INIT - prepare Header and Data buffers Calculate
 *	                       Header Digest
 *	XMSTATE_CMD_HDR_XMIT - Transmit header in progress
 *
 *iscsi_send_padding
 *	XMSTATE_W_PAD        - Prepare and send pading
 *	XMSTATE_W_RESEND_PAD - retry send pading
 *
 *iscsi_send_digest
 *	XMSTATE_W_RESEND_DATA_DIGEST - Finalize and send Data Digest
 *	XMSTATE_W_RESEND_DATA_DIGEST - retry sending digest
 *
 *iscsi_send_unsol_hdr
 *	XMSTATE_UNS_INIT     - prepare un-solicit data header and digest
 *	XMSTATE_UNS_HDR      - send un-solicit header
 *
 *iscsi_send_unsol_pdu
 *	XMSTATE_UNS_DATA     - send un-solicit data in progress
 *
 *iscsi_send_sol_pdu
 *	XMSTATE_SOL_HDR_INIT - solicit data header and digest initialize
 *	XMSTATE_SOL_HDR      - send solicit header
 *	XMSTATE_SOL_DATA     - send solicit data
 *
 *iscsi_tcp_ctask_xmit
 *	XMSTATE_IMM_DATA     - xmit managment data (??)
 **/
1774
static int
1775
iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1776
{
1777
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1778 1779 1780
	int rc = 0;

	debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n",
1781
		conn->id, tcp_ctask->xmstate, ctask->itt);
1782

1783 1784 1785 1786 1787
	rc = iscsi_send_cmd_hdr(conn, ctask);
	if (rc)
		return rc;
	if (ctask->sc->sc_data_direction != DMA_TO_DEVICE)
		return 0;
1788

1789
	if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) {
1790 1791 1792
		rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
				     &tcp_ctask->sent, &ctask->imm_count,
				     &tcp_ctask->immbuf, &tcp_ctask->immdigest);
1793 1794
		if (rc)
			return rc;
1795
		tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
1796 1797
	}

1798 1799 1800
	rc = iscsi_send_unsol_pdu(conn, ctask);
	if (rc)
		return rc;
1801

1802 1803 1804
	rc = iscsi_send_sol_pdu(conn, ctask);
	if (rc)
		return rc;
1805 1806 1807 1808

	return rc;
}

1809 1810
static struct iscsi_cls_conn *
iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1811
{
1812 1813 1814
	struct iscsi_conn *conn;
	struct iscsi_cls_conn *cls_conn;
	struct iscsi_tcp_conn *tcp_conn;
1815

1816 1817 1818 1819
	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
	if (!cls_conn)
		return NULL;
	conn = cls_conn->dd_data;
1820
	/*
1821 1822
	 * due to strange issues with iser these are not set
	 * in iscsi_conn_setup
1823
	 */
1824
	conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
1825

1826 1827 1828
	tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL);
	if (!tcp_conn)
		goto tcp_conn_alloc_fail;
1829

1830 1831 1832 1833 1834
	conn->dd_data = tcp_conn;
	tcp_conn->iscsi_conn = conn;
	tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
	/* initial operational parameters */
	tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1835

1836 1837 1838
	tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
						  CRYPTO_ALG_ASYNC);
	tcp_conn->tx_hash.flags = 0;
1839 1840 1841 1842 1843
	if (IS_ERR(tcp_conn->tx_hash.tfm)) {
		printk(KERN_ERR "Could not create connection due to crc32c "
		       "loading error %ld. Make sure the crc32c module is "
		       "built as a module or into the kernel\n",
			PTR_ERR(tcp_conn->tx_hash.tfm));
1844
		goto free_tcp_conn;
1845
	}
1846

1847 1848 1849
	tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
						  CRYPTO_ALG_ASYNC);
	tcp_conn->rx_hash.flags = 0;
1850 1851 1852 1853 1854
	if (IS_ERR(tcp_conn->rx_hash.tfm)) {
		printk(KERN_ERR "Could not create connection due to crc32c "
		       "loading error %ld. Make sure the crc32c module is "
		       "built as a module or into the kernel\n",
			PTR_ERR(tcp_conn->rx_hash.tfm));
1855
		goto free_tx_tfm;
1856
	}
1857

1858
	return cls_conn;
1859

1860
free_tx_tfm:
1861
	crypto_free_hash(tcp_conn->tx_hash.tfm);
1862 1863
free_tcp_conn:
	kfree(tcp_conn);
1864 1865 1866
tcp_conn_alloc_fail:
	iscsi_conn_teardown(cls_conn);
	return NULL;
1867 1868
}

1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885
static void
iscsi_tcp_release_conn(struct iscsi_conn *conn)
{
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;

	if (!tcp_conn->sock)
		return;

	sock_hold(tcp_conn->sock->sk);
	iscsi_conn_restore_callbacks(tcp_conn);
	sock_put(tcp_conn->sock->sk);

	sock_release(tcp_conn->sock);
	tcp_conn->sock = NULL;
	conn->recv_lock = NULL;
}

1886
static void
1887
iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
1888
{
1889 1890
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1891

1892
	iscsi_tcp_release_conn(conn);
1893
	iscsi_conn_teardown(cls_conn);
1894

P
Pete Wyckoff 已提交
1895 1896 1897 1898
	if (tcp_conn->tx_hash.tfm)
		crypto_free_hash(tcp_conn->tx_hash.tfm);
	if (tcp_conn->rx_hash.tfm)
		crypto_free_hash(tcp_conn->rx_hash.tfm);
1899

1900 1901
	kfree(tcp_conn);
}
1902

1903 1904 1905 1906
static void
iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
1907
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1908 1909 1910

	iscsi_conn_stop(cls_conn, flag);
	iscsi_tcp_release_conn(conn);
1911
	tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1912 1913
}

1914 1915
static int
iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1916
		    struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
1917 1918 1919 1920 1921 1922 1923
		    int is_leading)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct sock *sk;
	struct socket *sock;
	int err;
1924

1925
	/* lookup for existing socket */
1926
	sock = sockfd_lookup((int)transport_eph, &err);
1927 1928 1929
	if (!sock) {
		printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
		return -EEXIST;
1930 1931
	}

1932 1933 1934
	err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
	if (err)
		return err;
1935

1936 1937
	/* bind iSCSI connection and socket */
	tcp_conn->sock = sock;
1938

1939 1940 1941 1942 1943
	/* setup Socket parameters */
	sk = sock->sk;
	sk->sk_reuse = 1;
	sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
	sk->sk_allocation = GFP_ATOMIC;
1944

1945
	/* FIXME: disable Nagle's algorithm */
1946

1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957
	/*
	 * Intercept TCP callbacks for sendfile like receive
	 * processing.
	 */
	conn->recv_lock = &sk->sk_callback_lock;
	iscsi_conn_set_callbacks(conn);
	tcp_conn->sendpage = tcp_conn->sock->ops->sendpage;
	/*
	 * set receive state machine into initial state
	 */
	tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
1958 1959 1960 1961

	return 0;
}

1962
/* called with host lock */
M
Mike Christie 已提交
1963
static void
1964
iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1965
{
1966
	struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
1967
	tcp_mtask->xmstate = XMSTATE_IMM_HDR_INIT;
1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980
}

static int
iscsi_r2tpool_alloc(struct iscsi_session *session)
{
	int i;
	int cmd_i;

	/*
	 * initialize per-task: R2T pool and xmit queue
	 */
	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
	        struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
1981
		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1982 1983 1984 1985 1986 1987 1988 1989

		/*
		 * pre-allocated x4 as much r2ts to handle race when
		 * target acks DataOut faster than we data_xmit() queues
		 * could replenish r2tqueue.
		 */

		/* R2T pool */
1990 1991 1992
		if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4,
				    (void***)&tcp_ctask->r2ts,
				    sizeof(struct iscsi_r2t_info))) {
1993 1994 1995 1996
			goto r2t_alloc_fail;
		}

		/* R2T xmit queue */
1997
		tcp_ctask->r2tqueue = kfifo_alloc(
1998
		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
1999 2000 2001
		if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
			iscsi_pool_free(&tcp_ctask->r2tpool,
					(void**)tcp_ctask->r2ts);
2002 2003 2004 2005 2006 2007 2008 2009
			goto r2t_alloc_fail;
		}
	}

	return 0;

r2t_alloc_fail:
	for (i = 0; i < cmd_i; i++) {
2010 2011 2012 2013 2014 2015
		struct iscsi_cmd_task *ctask = session->cmds[i];
		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;

		kfifo_free(tcp_ctask->r2tqueue);
		iscsi_pool_free(&tcp_ctask->r2tpool,
				(void**)tcp_ctask->r2ts);
2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
	}
	return -ENOMEM;
}

static void
iscsi_r2tpool_free(struct iscsi_session *session)
{
	int i;

	for (i = 0; i < session->cmds_max; i++) {
2026 2027
		struct iscsi_cmd_task *ctask = session->cmds[i];
		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2028

2029 2030 2031
		kfifo_free(tcp_ctask->r2tqueue);
		iscsi_pool_free(&tcp_ctask->r2tpool,
				(void**)tcp_ctask->r2ts);
2032 2033 2034 2035
	}
}

static int
2036
iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2037
		     char *buf, int buflen)
2038
{
2039
	struct iscsi_conn *conn = cls_conn->dd_data;
2040
	struct iscsi_session *session = conn->session;
2041
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2042
	int value;
2043 2044 2045

	switch(param) {
	case ISCSI_PARAM_HDRDGST_EN:
2046
		iscsi_set_param(cls_conn, param, buf, buflen);
2047
		tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
2048
		if (conn->hdrdgst_en)
2049
			tcp_conn->hdr_size += sizeof(__u32);
2050 2051
		break;
	case ISCSI_PARAM_DATADGST_EN:
2052
		iscsi_set_param(cls_conn, param, buf, buflen);
2053 2054
		tcp_conn->sendpage = conn->datadgst_en ?
			sock_no_sendpage : tcp_conn->sock->ops->sendpage;
2055 2056
		break;
	case ISCSI_PARAM_MAX_R2T:
2057
		sscanf(buf, "%d", &value);
2058 2059 2060
		if (session->max_r2t == roundup_pow_of_two(value))
			break;
		iscsi_r2tpool_free(session);
2061
		iscsi_set_param(cls_conn, param, buf, buflen);
2062 2063 2064 2065 2066 2067
		if (session->max_r2t & (session->max_r2t - 1))
			session->max_r2t = roundup_pow_of_two(session->max_r2t);
		if (iscsi_r2tpool_alloc(session))
			return -ENOMEM;
		break;
	default:
2068
		return iscsi_set_param(cls_conn, param, buf, buflen);
2069 2070 2071 2072 2073 2074
	}

	return 0;
}

static int
2075 2076
iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
			 enum iscsi_param param, char *buf)
2077
{
2078
	struct iscsi_conn *conn = cls_conn->dd_data;
2079
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2080
	struct inet_sock *inet;
2081 2082 2083
	struct ipv6_pinfo *np;
	struct sock *sk;
	int len;
2084 2085

	switch(param) {
2086
	case ISCSI_PARAM_CONN_PORT:
2087
		if (!tcp_conn->sock)
2088 2089
			return -EINVAL;

2090
		inet = inet_sk(tcp_conn->sock->sk);
2091
		len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport));
2092
		break;
2093
	case ISCSI_PARAM_CONN_ADDRESS:
2094
		if (!tcp_conn->sock)
2095 2096
			return -EINVAL;

2097
		sk = tcp_conn->sock->sk;
2098 2099
		if (sk->sk_family == PF_INET) {
			inet = inet_sk(sk);
2100
			len = sprintf(buf, NIPQUAD_FMT "\n",
2101 2102 2103
				      NIPQUAD(inet->daddr));
		} else {
			np = inet6_sk(sk);
2104
			len = sprintf(buf, NIP6_FMT "\n", NIP6(np->daddr));
2105 2106 2107
		}
		break;
	default:
2108
		return iscsi_conn_get_param(cls_conn, param, buf);
2109 2110 2111 2112 2113
	}

	return len;
}

2114
static void
2115
iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
2116
{
2117
	struct iscsi_conn *conn = cls_conn->dd_data;
2118
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130

	stats->txdata_octets = conn->txdata_octets;
	stats->rxdata_octets = conn->rxdata_octets;
	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
	stats->dataout_pdus = conn->dataout_pdus_cnt;
	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
	stats->datain_pdus = conn->datain_pdus_cnt;
	stats->r2t_pdus = conn->r2t_pdus_cnt;
	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
	stats->custom_length = 3;
	strcpy(stats->custom[0].desc, "tx_sendpage_failures");
2131
	stats->custom[0].value = tcp_conn->sendpage_failures_cnt;
2132
	strcpy(stats->custom[1].desc, "rx_discontiguous_hdr");
2133
	stats->custom[1].value = tcp_conn->discontiguous_hdr_cnt;
2134 2135 2136 2137
	strcpy(stats->custom[2].desc, "eh_abort_cnt");
	stats->custom[2].value = conn->eh_abort_cnt;
}

2138 2139 2140
static struct iscsi_cls_session *
iscsi_tcp_session_create(struct iscsi_transport *iscsit,
			 struct scsi_transport_template *scsit,
2141
			 uint16_t cmds_max, uint16_t qdepth,
2142
			 uint32_t initial_cmdsn, uint32_t *hostno)
2143
{
2144 2145 2146 2147
	struct iscsi_cls_session *cls_session;
	struct iscsi_session *session;
	uint32_t hn;
	int cmd_i;
2148

2149
	cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
2150 2151 2152 2153 2154 2155
					 sizeof(struct iscsi_tcp_cmd_task),
					 sizeof(struct iscsi_tcp_mgmt_task),
					 initial_cmdsn, &hn);
	if (!cls_session)
		return NULL;
	*hostno = hn;
2156

2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185
	session = class_to_transport_session(cls_session);
	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
		struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;

		ctask->hdr = &tcp_ctask->hdr;
	}

	for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
		struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
		struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;

		mtask->hdr = &tcp_mtask->hdr;
	}

	if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session)))
		goto r2tpool_alloc_fail;

	return cls_session;

r2tpool_alloc_fail:
	iscsi_session_teardown(cls_session);
	return NULL;
}

static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
{
	iscsi_r2tpool_free(class_to_transport_session(cls_session));
	iscsi_session_teardown(cls_session);
2186 2187
}

2188 2189 2190 2191 2192 2193
static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
{
	blk_queue_dma_alignment(sdev->request_queue, 0);
	return 0;
}

2194
static struct scsi_host_template iscsi_sht = {
2195
	.name			= "iSCSI Initiator over TCP/IP",
2196 2197
	.queuecommand           = iscsi_queuecommand,
	.change_queue_depth	= iscsi_change_queue_depth,
2198
	.can_queue		= ISCSI_DEF_XMIT_CMDS_MAX - 1,
2199
	.sg_tablesize		= ISCSI_SG_TABLESIZE,
2200
	.max_sectors		= 0xFFFF,
2201 2202 2203 2204
	.cmd_per_lun		= ISCSI_DEF_CMD_PER_LUN,
	.eh_abort_handler       = iscsi_eh_abort,
	.eh_host_reset_handler	= iscsi_eh_host_reset,
	.use_clustering         = DISABLE_CLUSTERING,
2205
	.slave_configure        = iscsi_tcp_slave_configure,
2206 2207 2208 2209
	.proc_name		= "iscsi_tcp",
	.this_id		= -1,
};

2210 2211 2212 2213 2214
static struct iscsi_transport iscsi_tcp_transport = {
	.owner			= THIS_MODULE,
	.name			= "tcp",
	.caps			= CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
				  | CAP_DATADGST,
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
	.param_mask		= ISCSI_MAX_RECV_DLENGTH |
				  ISCSI_MAX_XMIT_DLENGTH |
				  ISCSI_HDRDGST_EN |
				  ISCSI_DATADGST_EN |
				  ISCSI_INITIAL_R2T_EN |
				  ISCSI_MAX_R2T |
				  ISCSI_IMM_DATA_EN |
				  ISCSI_FIRST_BURST |
				  ISCSI_MAX_BURST |
				  ISCSI_PDU_INORDER_EN |
				  ISCSI_DATASEQ_INORDER_EN |
				  ISCSI_ERL |
				  ISCSI_CONN_PORT |
2228
				  ISCSI_CONN_ADDRESS |
2229 2230 2231
				  ISCSI_EXP_STATSN |
				  ISCSI_PERSISTENT_PORT |
				  ISCSI_PERSISTENT_ADDRESS |
2232 2233 2234
				  ISCSI_TARGET_NAME | ISCSI_TPGT |
				  ISCSI_USERNAME | ISCSI_PASSWORD |
				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,
2235 2236
	.host_param_mask	= ISCSI_HOST_HWADDRESS |
				  ISCSI_HOST_INITIATOR_NAME,
2237
	.host_template		= &iscsi_sht,
2238
	.conndata_size		= sizeof(struct iscsi_conn),
2239 2240
	.max_conn		= 1,
	.max_cmd_len		= ISCSI_TCP_MAX_CMD_LEN,
2241 2242 2243 2244 2245 2246 2247
	/* session management */
	.create_session		= iscsi_tcp_session_create,
	.destroy_session	= iscsi_tcp_session_destroy,
	/* connection management */
	.create_conn		= iscsi_tcp_conn_create,
	.bind_conn		= iscsi_tcp_conn_bind,
	.destroy_conn		= iscsi_tcp_conn_destroy,
2248
	.set_param		= iscsi_conn_set_param,
2249
	.get_conn_param		= iscsi_tcp_conn_get_param,
2250
	.get_session_param	= iscsi_session_get_param,
2251
	.start_conn		= iscsi_conn_start,
2252
	.stop_conn		= iscsi_tcp_conn_stop,
2253 2254 2255
	/* iscsi host params */
	.get_host_param		= iscsi_host_get_param,
	.set_host_param		= iscsi_host_set_param,
2256
	/* IO */
2257 2258
	.send_pdu		= iscsi_conn_send_pdu,
	.get_stats		= iscsi_conn_get_stats,
2259 2260 2261 2262 2263 2264
	.init_cmd_task		= iscsi_tcp_cmd_init,
	.init_mgmt_task		= iscsi_tcp_mgmt_init,
	.xmit_cmd_task		= iscsi_tcp_ctask_xmit,
	.xmit_mgmt_task		= iscsi_tcp_mtask_xmit,
	.cleanup_cmd_task	= iscsi_tcp_cleanup_ctask,
	/* recovery */
M
Mike Christie 已提交
2265
	.session_recovery_timedout = iscsi_session_recovery_timedout,
2266 2267 2268 2269 2270 2271
};

static int __init
iscsi_tcp_init(void)
{
	if (iscsi_max_lun < 1) {
O
Or Gerlitz 已提交
2272 2273
		printk(KERN_ERR "iscsi_tcp: Invalid max_lun value of %u\n",
		       iscsi_max_lun);
2274 2275 2276 2277
		return -EINVAL;
	}
	iscsi_tcp_transport.max_lun = iscsi_max_lun;

2278
	if (!iscsi_register_transport(&iscsi_tcp_transport))
2279
		return -ENODEV;
2280

2281
	return 0;
2282 2283 2284 2285 2286 2287 2288 2289 2290 2291
}

static void __exit
iscsi_tcp_exit(void)
{
	iscsi_unregister_transport(&iscsi_tcp_transport);
}

module_init(iscsi_tcp_init);
module_exit(iscsi_tcp_exit);