iscsi_tcp.c 62.1 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
 * 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>
M
Mike Christie 已提交
32
#include <linux/file.h>
33 34 35 36 37 38 39
#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>
40
#include <scsi/scsi_device.h>
41 42 43 44 45 46 47 48 49 50 51 52 53 54
#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
55
#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#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)
{
73 74
	ibuf->sg.page = virt_to_page(vbuf);
	ibuf->sg.offset = offset_in_page(vbuf);
75 76
	ibuf->sg.length = size;
	ibuf->sent = 0;
77
	ibuf->use_sendmsg = 1;
78 79 80 81 82
}

static inline void
iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
{
83 84 85
	ibuf->sg.page = sg->page;
	ibuf->sg.offset = sg->offset;
	ibuf->sg.length = sg->length;
86 87 88
	/*
	 * Fastpath: sg element fits into single page
	 */
M
Mike Christie 已提交
89
	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
90 91 92
		ibuf->use_sendmsg = 0;
	else
		ibuf->use_sendmsg = 1;
93 94 95 96 97 98 99 100 101 102 103 104 105 106
	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
107 108
iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
		 u8* crc)
109
{
110
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
111

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

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

121
	tcp_conn->in.zero_copy_hdr = 0;
122

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

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

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

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

158 159 160 161
		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);
162 163

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

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

	return 0;
}

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

192 193 194 195 196 197 198
	/* 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 已提交
199 200
	sc = ctask->sc;
	if (unlikely(!sc))
201
		return;
M
Mike Christie 已提交
202

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

/**
 * 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)
{
215 216 217
	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;
218
	struct iscsi_session *session = conn->session;
219
	struct scsi_cmnd *sc = ctask->sc;
220 221
	int datasn = be32_to_cpu(rhdr->datasn);

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

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

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

237
	tcp_ctask->exp_datasn++;
238

239
	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
240 241 242 243
	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);
244
		return ISCSI_ERR_DATA_OFFSET;
245
	}
246 247 248

	if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) {
		conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
249
		if (rhdr->flags & ISCSI_FLAG_DATA_UNDERFLOW) {
250 251 252 253 254 255 256 257 258
			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;
259
		} else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) {
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 288
			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;

289
	hdr = &r2t->dtask.hdr;
290 291 292 293 294
	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;
295 296
	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
	hdr->itt = ctask->hdr->itt;
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
	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;

312
	iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
313
			   sizeof(struct iscsi_hdr));
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 341

	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);
342 343
	} else {
		iscsi_buf_init_iov(&r2t->sendbuf,
344 345
			    (char*)sc->request_buffer + r2t->data_offset,
			    r2t->data_count);
346 347
		r2t->sg = NULL;
	}
348 349 350 351 352 353 354 355 356 357 358 359
}

/**
 * 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;
360 361 362
	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;
363 364 365
	int r2tsn = be32_to_cpu(rhdr->r2tsn);
	int rc;

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

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

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

382 383 384 385 386 387 388
	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;
	}
389

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

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

401 402 403 404 405
	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);

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

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

	iscsi_solicit_data_init(conn, ctask, r2t);

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

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

	return 0;
}

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

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

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

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

	/* calculate read padding */
463 464 465 466
	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);
467 468 469 470 471 472
	}

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

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

485
	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
486
	/* verify itt (itt encoding: age+cid+itt) */
487 488 489 490 491 492
	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;
493 494

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

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

510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
		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:
528 529 530 531 532
		/*
		 * 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
		 */
533
		if (ISCSI_DEF_MAX_RECV_SEG_LEN <
534 535 536 537
		    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,
538
			      ISCSI_DEF_MAX_RECV_SEG_LEN, opcode);
539 540 541 542
			rc = ISCSI_ERR_PROTO;
			break;
		}

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

	return rc;
557 558 559 560 561 562 563

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
	 */
564
	if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <=
565 566 567 568 569 570 571 572 573 574
	   (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;
575 576 577 578
}

/**
 * iscsi_ctask_copy - copy skb bits to the destanation cmd task
579
 * @conn: iscsi tcp connection
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
 * @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
601
iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
602 603
		void *buf, int buf_size, int offset)
{
604 605
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	int buf_left = buf_size - (tcp_conn->data_copied + offset);
606
	unsigned size = min(tcp_conn->in.copy, buf_left);
607 608 609 610 611
	int rc;

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

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

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

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

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

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

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

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

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

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

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

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

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

	return 0;
}

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

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

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

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

702 703
static int iscsi_scsi_data_in(struct iscsi_conn *conn)
{
704 705 706
	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;
707
	struct scsi_cmnd *sc = ctask->sc;
708
	struct scatterlist *sg;
709 710 711 712 713 714 715 716 717
	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;
718 719 720
		rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer,
				      sc->request_bufflen,
				      tcp_ctask->data_offset);
721 722
		if (rc == -EAGAIN)
			return rc;
723
		if (conn->datadgst_en)
724 725
			iscsi_recv_digest_update(tcp_conn, sc->request_buffer,
						 i);
726 727 728 729
		rc = 0;
		goto done;
	}

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

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

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

		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
744
		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
745 746 747 748 749 750 751 752
				      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)
753
					crypto_hash_update(
754
							&tcp_conn->rx_hash,
755
							&sg[i], sg[i].length);
756
				else
757
					partial_sg_digest_update(
758
							&tcp_conn->rx_hash,
759
							&sg[i],
760 761 762 763
							sg[i].offset + offset,
							sg[i].length - offset);
			}
			offset = 0;
764
			tcp_ctask->sg_count++;
765 766 767 768 769 770 771
		}

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

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

done:
	/* check for non-exceptional status */
787
	if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) {
788 789 790
		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);
791 792 793
		spin_lock(&conn->session->lock);
		__iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
		spin_unlock(&conn->session->lock);
794 795 796 797 798 799 800 801
	}

	return rc;
}

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

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

824
		rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data,
825 826
					tcp_conn->in.datalen);
		if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP)
827
			iscsi_recv_digest_update(tcp_conn, conn->data,
828 829
			  			tcp_conn->in.datalen);
		break;
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
	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;
850
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
851 852 853 854 855 856 857 858
	int processed;
	char pad[ISCSI_PAD_LEN];
	struct scatterlist sg;

	/*
	 * Save current SKB and its offset in the corresponding
	 * connection context.
	 */
859 860 861 862 863 864
	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);
865 866

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

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

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

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

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

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

		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);
		}

922 923 924 925 926 927 928 929 930
		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));
931
		if (recv_digest != tcp_conn->in.datadgst) {
932 933
			debug_tcp("iscsi_tcp: data digest error!"
				  "0x%x != 0x%x\n", recv_digest,
934
				  tcp_conn->in.datadgst);
935 936 937 938 939
			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,
940 941
				  tcp_conn->in.datadgst);
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
942 943 944
		}
	}

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

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

		if (tcp_conn->in.padding)
			tcp_conn->in_progress = IN_PROGRESS_PAD_RECV;
		else if (conn->datadgst_en)
961
			tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
		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
981
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
982
		tcp_conn->data_copied = 0;
983 984 985
	}

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

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

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

again:
1001
	processed = tcp_conn->in.offset - offset;
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
	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);

1019 1020 1021 1022 1023 1024
	/*
	 * 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.
	 */
1025
	rd_desc.arg.data = conn;
1026
	rd_desc.count = 1;
1027 1028 1029 1030 1031 1032 1033 1034
	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)
{
1035
	struct iscsi_tcp_conn *tcp_conn;
1036 1037 1038 1039 1040 1041 1042 1043 1044
	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 已提交
1045 1046 1047
	if ((sk->sk_state == TCP_CLOSE_WAIT ||
	     sk->sk_state == TCP_CLOSE) &&
	    !atomic_read(&sk->sk_rmem_alloc)) {
1048 1049 1050 1051
		debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
	}

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

	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;
1068 1069 1070
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;

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

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

	/* assign new callbacks */
	write_lock_bh(&sk->sk_callback_lock);
	sk->sk_user_data = conn;
1084 1085 1086
	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;
1087 1088 1089 1090 1091 1092 1093
	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
1094
iscsi_conn_restore_callbacks(struct iscsi_tcp_conn *tcp_conn)
1095
{
1096
	struct sock *sk = tcp_conn->sock->sk;
1097 1098 1099 1100

	/* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
	write_lock_bh(&sk->sk_callback_lock);
	sk->sk_user_data    = NULL;
1101 1102 1103
	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;
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
	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
1116
iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
1117
{
1118 1119
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct socket *sk = tcp_conn->sock;
1120
	int offset = buf->sg.offset + buf->sent, res;
1121

1122 1123 1124 1125 1126 1127 1128 1129 1130
	/*
	 * 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)
1131
		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
1132
	else
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
		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;
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
}

/**
 * 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;

1169
	res = iscsi_send(conn, buf, size, flags);
1170 1171 1172 1173 1174
	debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
	if (res >= 0) {
		if (size != res)
			return -EAGAIN;
		return 0;
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 1200

	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 已提交
1201
	if (buf->sent + size != buf->sg.length || *count != size)
1202 1203
		flags |= MSG_MORE;

1204
	res = iscsi_send(conn, buf, size, flags);
1205 1206 1207 1208 1209 1210 1211 1212
	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;
1213
	}
1214 1215 1216 1217 1218

	return res;
}

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

/**
 * 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;

1247
	hdr = &r2t->dtask.hdr;
1248 1249 1250 1251 1252
	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;
1253 1254
	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
	hdr->itt = ctask->hdr->itt;
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
	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++;

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

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

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

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

1292 1293 1294
	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;
1295 1296 1297
}

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

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

/**
1313
 * iscsi_tcp_mtask_xmit - xmit management(immediate) task
1314 1315 1316 1317 1318 1319 1320 1321
 * @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.
 *
1322 1323 1324 1325 1326
 *	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
1327 1328
 **/
static int
1329
iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1330
{
1331
	struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
1332
	int rc;
1333 1334

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

1337 1338 1339 1340 1341
	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) {
1342
			tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
1343 1344 1345 1346 1347
			iscsi_buf_init_iov(&tcp_mtask->sendbuf,
					   (char*)mtask->data,
					   mtask->data_count);
		}

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

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

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

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

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

1385
	BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE);
A
Al Viro 已提交
1386
	if (mtask->hdr->itt == RESERVED_ITT) {
1387 1388 1389 1390 1391 1392 1393 1394
		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);
	}
1395 1396 1397
	return 0;
}

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

1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423
	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;
			}
1424

1425 1426 1427 1428 1429 1430
			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);
		}
1431

1432 1433 1434 1435 1436 1437 1438 1439
		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;
1440 1441
	}

1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453
	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);
1454

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

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

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

1476 1477 1478 1479
	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)
1480 1481 1482
			crypto_hash_update(&tcp_conn->tx_hash,
					   &tcp_ctask->sendbuf.sg,
					   tcp_ctask->sendbuf.sg.length);
1483 1484 1485 1486 1487 1488 1489 1490 1491
	} 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);
1492
	if (rc) {
1493 1494
		debug_scsi("padding send failed %d\n", rc);
		tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD;
1495
	}
1496
	return rc;
1497 1498
}

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

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

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

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

1519 1520 1521 1522 1523 1524 1525 1526
	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;
1527
	}
1528 1529
	return rc;
}
1530

1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547
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)
1548
			partial_sg_digest_update(&tcp_conn->tx_hash,
1549 1550 1551 1552 1553
				&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;
1554
		}
1555 1556 1557

		if (rc)
			return rc;
1558 1559
	}

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

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

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

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

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

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

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

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

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

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

1613 1614 1615 1616 1617 1618 1619
	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;
1620 1621
	}

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

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

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

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

1666 1667 1668
		if (conn->hdrdgst_en)
			iscsi_hdr_digest(conn, &r2t->headbuf,
					(u8*)dtask->hdrext);
1669 1670 1671 1672 1673 1674 1675 1676
		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;

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

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

1688 1689 1690 1691
		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);
1692 1693
	}

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

1698 1699 1700 1701 1702 1703
		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;
1704

1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
		/*
		 * 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;
		}
1715

1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728
		/*
		 * 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;
1729
		}
1730
		spin_unlock_bh(&session->lock);
1731 1732 1733 1734
	}
	return 0;
}

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 1774
/**
 * 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 (??)
 **/
1775
static int
1776
iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1777
{
1778
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1779 1780 1781
	int rc = 0;

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

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

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

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

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

	return rc;
}

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

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

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

1831 1832 1833 1834 1835
	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);
1836

1837 1838 1839
	tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
						  CRYPTO_ALG_ASYNC);
	tcp_conn->tx_hash.flags = 0;
1840 1841 1842 1843 1844
	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));
1845
		goto free_tcp_conn;
1846
	}
1847

1848 1849 1850
	tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
						  CRYPTO_ALG_ASYNC);
	tcp_conn->rx_hash.flags = 0;
1851 1852 1853 1854 1855
	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));
1856
		goto free_tx_tfm;
1857
	}
1858

1859
	return cls_conn;
1860

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

1870 1871 1872
static void
iscsi_tcp_release_conn(struct iscsi_conn *conn)
{
1873
	struct iscsi_session *session = conn->session;
1874
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1875
	struct socket *sock = tcp_conn->sock;
1876

1877
	if (!sock)
1878 1879
		return;

1880
	sock_hold(sock->sk);
1881
	iscsi_conn_restore_callbacks(tcp_conn);
1882
	sock_put(sock->sk);
1883

1884
	spin_lock_bh(&session->lock);
1885 1886
	tcp_conn->sock = NULL;
	conn->recv_lock = NULL;
1887 1888
	spin_unlock_bh(&session->lock);
	sockfd_put(sock);
1889 1890
}

1891
static void
1892
iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
1893
{
1894 1895
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1896

1897
	iscsi_tcp_release_conn(conn);
1898
	iscsi_conn_teardown(cls_conn);
1899

P
Pete Wyckoff 已提交
1900 1901 1902 1903
	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);
1904

1905 1906
	kfree(tcp_conn);
}
1907

1908 1909 1910 1911
static void
iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
1912
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1913 1914 1915

	iscsi_conn_stop(cls_conn, flag);
	iscsi_tcp_release_conn(conn);
1916
	tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1917 1918
}

1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958
static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock,
			      char *buf, int *port,
			      int (*getname)(struct socket *, struct sockaddr *,
					int *addrlen))
{
	struct sockaddr_storage *addr;
	struct sockaddr_in6 *sin6;
	struct sockaddr_in *sin;
	int rc = 0, len;

	addr = kmalloc(GFP_KERNEL, sizeof(*addr));
	if (!addr)
		return -ENOMEM;

	if (getname(sock, (struct sockaddr *) addr, &len)) {
		rc = -ENODEV;
		goto free_addr;
	}

	switch (addr->ss_family) {
	case AF_INET:
		sin = (struct sockaddr_in *)addr;
		spin_lock_bh(&conn->session->lock);
		sprintf(buf, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
		*port = be16_to_cpu(sin->sin_port);
		spin_unlock_bh(&conn->session->lock);
		break;
	case AF_INET6:
		sin6 = (struct sockaddr_in6 *)addr;
		spin_lock_bh(&conn->session->lock);
		sprintf(buf, NIP6_FMT, NIP6(sin6->sin6_addr));
		*port = be16_to_cpu(sin6->sin6_port);
		spin_unlock_bh(&conn->session->lock);
		break;
	}
free_addr:
	kfree(addr);
	return rc;
}

1959 1960
static int
iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1961
		    struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
1962 1963 1964 1965 1966 1967 1968
		    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;
1969

1970
	/* lookup for existing socket */
1971
	sock = sockfd_lookup((int)transport_eph, &err);
1972 1973 1974
	if (!sock) {
		printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
		return -EEXIST;
1975
	}
1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
	/*
	 * copy these values now because if we drop the session
	 * userspace may still want to query the values since we will
	 * be using them for the reconnect
	 */
	err = iscsi_tcp_get_addr(conn, sock, conn->portal_address,
				 &conn->portal_port, kernel_getpeername);
	if (err)
		goto free_socket;

	err = iscsi_tcp_get_addr(conn, sock, conn->local_address,
				&conn->local_port, kernel_getsockname);
	if (err)
		goto free_socket;
1990

1991 1992
	err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
	if (err)
1993
		goto free_socket;
1994

1995 1996
	/* bind iSCSI connection and socket */
	tcp_conn->sock = sock;
1997

1998 1999 2000 2001 2002
	/* setup Socket parameters */
	sk = sock->sk;
	sk->sk_reuse = 1;
	sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
	sk->sk_allocation = GFP_ATOMIC;
2003

2004
	/* FIXME: disable Nagle's algorithm */
2005

2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
	/*
	 * 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;
2017
	return 0;
2018 2019 2020 2021

free_socket:
	sockfd_put(sock);
	return err;
2022 2023
}

2024
/* called with host lock */
M
Mike Christie 已提交
2025
static void
2026
iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
2027
{
2028
	struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
2029
	tcp_mtask->xmstate = XMSTATE_IMM_HDR_INIT;
2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
}

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];
2043
		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2044 2045 2046 2047 2048 2049 2050 2051

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

		/* R2T pool */
2052 2053 2054
		if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4,
				    (void***)&tcp_ctask->r2ts,
				    sizeof(struct iscsi_r2t_info))) {
2055 2056 2057 2058
			goto r2t_alloc_fail;
		}

		/* R2T xmit queue */
2059
		tcp_ctask->r2tqueue = kfifo_alloc(
2060
		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
2061 2062 2063
		if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
			iscsi_pool_free(&tcp_ctask->r2tpool,
					(void**)tcp_ctask->r2ts);
2064 2065 2066 2067 2068 2069 2070 2071
			goto r2t_alloc_fail;
		}
	}

	return 0;

r2t_alloc_fail:
	for (i = 0; i < cmd_i; i++) {
2072 2073 2074 2075 2076 2077
		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);
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087
	}
	return -ENOMEM;
}

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

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

2091 2092 2093
		kfifo_free(tcp_ctask->r2tqueue);
		iscsi_pool_free(&tcp_ctask->r2tpool,
				(void**)tcp_ctask->r2ts);
2094 2095 2096 2097
	}
}

static int
2098
iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2099
		     char *buf, int buflen)
2100
{
2101
	struct iscsi_conn *conn = cls_conn->dd_data;
2102
	struct iscsi_session *session = conn->session;
2103
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2104
	int value;
2105 2106 2107

	switch(param) {
	case ISCSI_PARAM_HDRDGST_EN:
2108
		iscsi_set_param(cls_conn, param, buf, buflen);
2109
		tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
2110
		if (conn->hdrdgst_en)
2111
			tcp_conn->hdr_size += sizeof(__u32);
2112 2113
		break;
	case ISCSI_PARAM_DATADGST_EN:
2114
		iscsi_set_param(cls_conn, param, buf, buflen);
2115 2116
		tcp_conn->sendpage = conn->datadgst_en ?
			sock_no_sendpage : tcp_conn->sock->ops->sendpage;
2117 2118
		break;
	case ISCSI_PARAM_MAX_R2T:
2119
		sscanf(buf, "%d", &value);
2120 2121 2122
		if (session->max_r2t == roundup_pow_of_two(value))
			break;
		iscsi_r2tpool_free(session);
2123
		iscsi_set_param(cls_conn, param, buf, buflen);
2124 2125 2126 2127 2128 2129
		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:
2130
		return iscsi_set_param(cls_conn, param, buf, buflen);
2131 2132 2133 2134 2135 2136
	}

	return 0;
}

static int
2137 2138
iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
			 enum iscsi_param param, char *buf)
2139
{
2140
	struct iscsi_conn *conn = cls_conn->dd_data;
2141
	int len;
2142 2143

	switch(param) {
2144
	case ISCSI_PARAM_CONN_PORT:
2145 2146 2147
		spin_lock_bh(&conn->session->lock);
		len = sprintf(buf, "%hu\n", conn->portal_port);
		spin_unlock_bh(&conn->session->lock);
2148
		break;
2149
	case ISCSI_PARAM_CONN_ADDRESS:
2150 2151 2152
		spin_lock_bh(&conn->session->lock);
		len = sprintf(buf, "%s\n", conn->portal_address);
		spin_unlock_bh(&conn->session->lock);
2153 2154
		break;
	default:
2155
		return iscsi_conn_get_param(cls_conn, param, buf);
2156 2157 2158 2159 2160
	}

	return len;
}

2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183
static int
iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
			 char *buf)
{
        struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
	int len;

	switch (param) {
	case ISCSI_HOST_PARAM_IPADDRESS:
		spin_lock_bh(&session->lock);
		if (!session->leadconn)
			len = -ENODEV;
		else
			len = sprintf(buf, "%s\n",
				     session->leadconn->local_address);
		spin_unlock_bh(&session->lock);
		break;
	default:
		return iscsi_host_get_param(shost, param, buf);
	}
	return len;
}

2184
static void
2185
iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
2186
{
2187
	struct iscsi_conn *conn = cls_conn->dd_data;
2188
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200

	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");
2201
	stats->custom[0].value = tcp_conn->sendpage_failures_cnt;
2202
	strcpy(stats->custom[1].desc, "rx_discontiguous_hdr");
2203
	stats->custom[1].value = tcp_conn->discontiguous_hdr_cnt;
2204 2205 2206 2207
	strcpy(stats->custom[2].desc, "eh_abort_cnt");
	stats->custom[2].value = conn->eh_abort_cnt;
}

2208 2209 2210
static struct iscsi_cls_session *
iscsi_tcp_session_create(struct iscsi_transport *iscsit,
			 struct scsi_transport_template *scsit,
2211
			 uint16_t cmds_max, uint16_t qdepth,
2212
			 uint32_t initial_cmdsn, uint32_t *hostno)
2213
{
2214 2215 2216 2217
	struct iscsi_cls_session *cls_session;
	struct iscsi_session *session;
	uint32_t hn;
	int cmd_i;
2218

2219
	cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
2220 2221 2222 2223 2224 2225
					 sizeof(struct iscsi_tcp_cmd_task),
					 sizeof(struct iscsi_tcp_mgmt_task),
					 initial_cmdsn, &hn);
	if (!cls_session)
		return NULL;
	*hostno = hn;
2226

2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255
	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);
2256 2257
}

2258 2259 2260 2261 2262 2263
static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
{
	blk_queue_dma_alignment(sdev->request_queue, 0);
	return 0;
}

2264
static struct scsi_host_template iscsi_sht = {
2265
	.name			= "iSCSI Initiator over TCP/IP",
2266 2267
	.queuecommand           = iscsi_queuecommand,
	.change_queue_depth	= iscsi_change_queue_depth,
2268
	.can_queue		= ISCSI_DEF_XMIT_CMDS_MAX - 1,
2269
	.sg_tablesize		= ISCSI_SG_TABLESIZE,
2270
	.max_sectors		= 0xFFFF,
2271 2272 2273 2274
	.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,
2275
	.slave_configure        = iscsi_tcp_slave_configure,
2276 2277 2278 2279
	.proc_name		= "iscsi_tcp",
	.this_id		= -1,
};

2280 2281 2282 2283 2284
static struct iscsi_transport iscsi_tcp_transport = {
	.owner			= THIS_MODULE,
	.name			= "tcp",
	.caps			= CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
				  | CAP_DATADGST,
2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297
	.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 |
2298
				  ISCSI_CONN_ADDRESS |
2299 2300 2301
				  ISCSI_EXP_STATSN |
				  ISCSI_PERSISTENT_PORT |
				  ISCSI_PERSISTENT_ADDRESS |
2302 2303 2304
				  ISCSI_TARGET_NAME | ISCSI_TPGT |
				  ISCSI_USERNAME | ISCSI_PASSWORD |
				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,
2305
	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
2306
				  ISCSI_HOST_INITIATOR_NAME,
2307
	.host_template		= &iscsi_sht,
2308
	.conndata_size		= sizeof(struct iscsi_conn),
2309 2310
	.max_conn		= 1,
	.max_cmd_len		= ISCSI_TCP_MAX_CMD_LEN,
2311 2312 2313 2314 2315 2316 2317
	/* 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,
2318
	.set_param		= iscsi_conn_set_param,
2319
	.get_conn_param		= iscsi_tcp_conn_get_param,
2320
	.get_session_param	= iscsi_session_get_param,
2321
	.start_conn		= iscsi_conn_start,
2322
	.stop_conn		= iscsi_tcp_conn_stop,
2323
	/* iscsi host params */
2324
	.get_host_param		= iscsi_tcp_host_get_param,
2325
	.set_host_param		= iscsi_host_set_param,
2326
	/* IO */
2327 2328
	.send_pdu		= iscsi_conn_send_pdu,
	.get_stats		= iscsi_conn_get_stats,
2329 2330 2331 2332 2333 2334
	.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 已提交
2335
	.session_recovery_timedout = iscsi_session_recovery_timedout,
2336 2337 2338 2339 2340 2341
};

static int __init
iscsi_tcp_init(void)
{
	if (iscsi_max_lun < 1) {
O
Or Gerlitz 已提交
2342 2343
		printk(KERN_ERR "iscsi_tcp: Invalid max_lun value of %u\n",
		       iscsi_max_lun);
2344 2345 2346 2347
		return -EINVAL;
	}
	iscsi_tcp_transport.max_lun = iscsi_max_lun;

2348
	if (!iscsi_register_transport(&iscsi_tcp_transport))
2349
		return -ENODEV;
2350

2351
	return 0;
2352 2353 2354 2355 2356 2357 2358 2359 2360 2361
}

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

module_init(iscsi_tcp_init);
module_exit(iscsi_tcp_exit);