// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * iSCSI over TCP/IP Data-Path lib
 *
 * Copyright (C) 2004 Dmitry Yusupov
 * Copyright (C) 2004 Alex Aizman
 * Copyright (C) 2005 - 2006 Mike Christie
 * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
 * maintained by open-iscsi@googlegroups.com
 *
 * Credits:
 *	Christoph Hellwig
 *	FUJITA Tomonori
 *	Arne Redlich
 *	Zhenyu Wang
 */

#include <linux/crc32c.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/inet.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <linux/scatterlist.h>
#include <linux/module.h>
#include <net/tcp.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi.h>
#include <scsi/scsi_transport_iscsi.h>
#include <trace/events/iscsi.h>

#include "iscsi_tcp.h"

MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
	      "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
	      "Alex Aizman <itn780@yahoo.com>");
MODULE_DESCRIPTION("iSCSI/TCP data-path");
MODULE_LICENSE("GPL");

static int iscsi_dbg_libtcp;
module_param_named(debug_libiscsi_tcp, iscsi_dbg_libtcp, int,
		   S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug_libiscsi_tcp, "Turn on debugging for libiscsi_tcp "
		 "module. Set to 1 to turn on, and zero to turn off. Default "
		 "is off.");

#define ISCSI_DBG_TCP(_conn, dbg_fmt, arg...)			\
	do {							\
		if (iscsi_dbg_libtcp)				\
			iscsi_conn_printk(KERN_INFO, _conn,	\
					     "%s " dbg_fmt,	\
					     __func__, ##arg);	\
		iscsi_dbg_trace(trace_iscsi_dbg_tcp,		\
				&(_conn)->cls_conn->dev,	\
				"%s " dbg_fmt, __func__, ##arg);\
	} while (0);

static int iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn,
				   struct iscsi_segment *segment);

/*
 * Scatterlist handling: inside the iscsi_segment, we
 * remember an index into the scatterlist, and set data/size
 * to the current scatterlist entry. For highmem pages, we
 * kmap as needed.
 *
 * Note that the page is unmapped when we return from
 * TCP's data_ready handler, so we may end up mapping and
 * unmapping the same page repeatedly. The whole reason
 * for this is that we shouldn't keep the page mapped
 * outside the softirq.
 */

/**
 * iscsi_tcp_segment_init_sg - init indicated scatterlist entry
 * @segment: the buffer object
 * @sg: scatterlist
 * @offset: byte offset into that sg entry
 *
 * This function sets up the segment so that subsequent
 * data is copied to the indicated sg entry, at the given
 * offset.
 */
static inline void
iscsi_tcp_segment_init_sg(struct iscsi_segment *segment,
			  struct scatterlist *sg, unsigned int offset)
{
	segment->sg = sg;
	segment->sg_offset = offset;
	segment->size = min(sg->length - offset,
			    segment->total_size - segment->total_copied);
	segment->data = NULL;
}

/**
 * iscsi_tcp_segment_map - map the current S/G page
 * @segment: iscsi_segment
 * @recv: 1 if called from recv path
 *
 * We only need to possibly kmap data if scatter lists are being used,
 * because the iscsi passthrough and internal IO paths will never use high
 * mem pages.
 */
static void iscsi_tcp_segment_map(struct iscsi_segment *segment, int recv)
{
	struct scatterlist *sg;

	if (segment->data != NULL || !segment->sg)
		return;

	sg = segment->sg;
	BUG_ON(segment->sg_mapped);
	BUG_ON(sg->length == 0);

	/*
	 * We always map for the recv path.
	 *
	 * If the page count is greater than one it is ok to send
	 * to the network layer's zero copy send path. If not we
	 * have to go the slow sendmsg path.
	 *
	 * Same goes for slab pages: skb_can_coalesce() allows
	 * coalescing neighboring slab objects into a single frag which
	 * triggers one of hardened usercopy checks.
	 */
	if (!recv && sendpage_ok(sg_page(sg)))
		return;

	if (recv) {
		segment->atomic_mapped = true;
		segment->sg_mapped = kmap_atomic(sg_page(sg));
	} else {
		segment->atomic_mapped = false;
		/* the xmit path can sleep with the page mapped so use kmap */
		segment->sg_mapped = kmap(sg_page(sg));
	}

	segment->data = segment->sg_mapped + sg->offset + segment->sg_offset;
}

void iscsi_tcp_segment_unmap(struct iscsi_segment *segment)
{
	if (segment->sg_mapped) {
		if (segment->atomic_mapped)
			kunmap_atomic(segment->sg_mapped);
		else
			kunmap(sg_page(segment->sg));
		segment->sg_mapped = NULL;
		segment->data = NULL;
	}
}
EXPORT_SYMBOL_GPL(iscsi_tcp_segment_unmap);

/*
 * Splice the digest buffer into the buffer
 */
static inline void
iscsi_tcp_segment_splice_digest(struct iscsi_segment *segment, void *digest)
{
	segment->data = digest;
	segment->digest_len = ISCSI_DIGEST_SIZE;
	segment->total_size += ISCSI_DIGEST_SIZE;
	segment->size = ISCSI_DIGEST_SIZE;
	segment->copied = 0;
	segment->sg = NULL;
	segment->crcp = NULL;
}

/**
 * iscsi_tcp_segment_done - check whether the segment is complete
 * @tcp_conn: iscsi tcp connection
 * @segment: iscsi segment to check
 * @recv: set to one of this is called from the recv path
 * @copied: number of bytes copied
 *
 * Check if we're done receiving this segment. If the receive
 * buffer is full but we expect more data, move on to the
 * next entry in the scatterlist.
 *
 * If the amount of data we received isn't a multiple of 4,
 * we will transparently receive the pad bytes, too.
 *
 * This function must be re-entrant.
 */
int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
			   struct iscsi_segment *segment, int recv,
			   unsigned copied)
{
	unsigned int pad;

	ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copied %u %u size %u %s\n",
		      segment->copied, copied, segment->size,
		      recv ? "recv" : "xmit");
	if (segment->crcp && copied) {
		if (segment->data) {
			*segment->crcp = crc32c(*segment->crcp,
						segment->data + segment->copied,
						copied);
		} else {
			const void *data;

			data = kmap_local_page(sg_page(segment->sg));
			*segment->crcp = crc32c(*segment->crcp,
						data + segment->copied +
						segment->sg_offset +
						segment->sg->offset,
						copied);
			kunmap_local(data);
		}
	}

	segment->copied += copied;
	if (segment->copied < segment->size) {
		iscsi_tcp_segment_map(segment, recv);
		return 0;
	}

	segment->total_copied += segment->copied;
	segment->copied = 0;
	segment->size = 0;

	/* Unmap the current scatterlist page, if there is one. */
	iscsi_tcp_segment_unmap(segment);

	/* Do we have more scatterlist entries? */
	ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "total copied %u total size %u\n",
		      segment->total_copied, segment->total_size);
	if (segment->total_copied < segment->total_size) {
		/* Proceed to the next entry in the scatterlist. */
		iscsi_tcp_segment_init_sg(segment, sg_next(segment->sg),
					  0);
		iscsi_tcp_segment_map(segment, recv);
		BUG_ON(segment->size == 0);
		return 0;
	}

	/* Do we need to handle padding? */
	if (!(tcp_conn->iscsi_conn->session->tt->caps & CAP_PADDING_OFFLOAD)) {
		pad = iscsi_padding(segment->total_copied);
		if (pad != 0) {
			ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
				      "consume %d pad bytes\n", pad);
			segment->total_size += pad;
			segment->size = pad;
			segment->data = segment->padbuf;
			return 0;
		}
	}

	/*
	 * Set us up for transferring the data digest. hdr digest
	 * is completely handled in hdr done function.
	 */
	if (segment->crcp) {
		put_unaligned_le32(~*segment->crcp, segment->digest);
		iscsi_tcp_segment_splice_digest(segment,
				 recv ? segment->recv_digest : segment->digest);
		return 0;
	}

	return 1;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_segment_done);

/**
 * iscsi_tcp_segment_recv - copy data to segment
 * @tcp_conn: the iSCSI TCP connection
 * @segment: the buffer to copy to
 * @ptr: data pointer
 * @len: amount of data available
 *
 * This function copies up to @len bytes to the
 * given buffer, and returns the number of bytes
 * consumed, which can actually be less than @len.
 *
 * If CRC is enabled, the function will update the CRC while copying.
 * Combining these two operations doesn't buy us a lot (yet),
 * but in the future we could implement combined copy+crc,
 * just way we do for network layer checksums.
 */
static int
iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn,
		       struct iscsi_segment *segment, const void *ptr,
		       unsigned int len)
{
	unsigned int copy = 0, copied = 0;

	while (!iscsi_tcp_segment_done(tcp_conn, segment, 1, copy)) {
		if (copied == len) {
			ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
				      "copied %d bytes\n", len);
			break;
		}

		copy = min(len - copied, segment->size - segment->copied);
		ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copying %d\n", copy);
		memcpy(segment->data + segment->copied, ptr + copied, copy);
		copied += copy;
	}
	return copied;
}

inline void
iscsi_tcp_dgst_header(const void *hdr, size_t hdrlen,
		      unsigned char digest[ISCSI_DIGEST_SIZE])
{
	put_unaligned_le32(~crc32c(~0, hdr, hdrlen), digest);
}
EXPORT_SYMBOL_GPL(iscsi_tcp_dgst_header);

static inline int
iscsi_tcp_dgst_verify(struct iscsi_tcp_conn *tcp_conn,
		      struct iscsi_segment *segment)
{
	if (!segment->digest_len)
		return 1;

	if (memcmp(segment->recv_digest, segment->digest,
		   segment->digest_len)) {
		ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "digest mismatch\n");
		return 0;
	}

	return 1;
}

/*
 * Helper function to set up segment buffer
 */
static inline void
__iscsi_segment_init(struct iscsi_segment *segment, size_t size,
		     iscsi_segment_done_fn_t *done, u32 *crcp)
{
	memset(segment, 0, sizeof(*segment));
	segment->total_size = size;
	segment->done = done;

	if (crcp) {
		segment->crcp = crcp;
		*crcp = ~0;
	}
}

inline void
iscsi_segment_init_linear(struct iscsi_segment *segment, void *data,
			  size_t size, iscsi_segment_done_fn_t *done, u32 *crcp)
{
	__iscsi_segment_init(segment, size, done, crcp);
	segment->data = data;
	segment->size = size;
}
EXPORT_SYMBOL_GPL(iscsi_segment_init_linear);

inline int
iscsi_segment_seek_sg(struct iscsi_segment *segment,
		      struct scatterlist *sg_list, unsigned int sg_count,
		      unsigned int offset, size_t size,
		      iscsi_segment_done_fn_t *done, u32 *crcp)
{
	struct scatterlist *sg;
	unsigned int i;

	__iscsi_segment_init(segment, size, done, crcp);
	for_each_sg(sg_list, sg, sg_count, i) {
		if (offset < sg->length) {
			iscsi_tcp_segment_init_sg(segment, sg, offset);
			return 0;
		}
		offset -= sg->length;
	}

	return ISCSI_ERR_DATA_OFFSET;
}
EXPORT_SYMBOL_GPL(iscsi_segment_seek_sg);

/**
 * iscsi_tcp_hdr_recv_prep - prep segment for hdr reception
 * @tcp_conn: iscsi connection to prep for
 *
 * This function always passes NULL for the crcp argument, because when this
 * function is called we do not yet know the final size of the header and want
 * to delay the digest processing until we know that.
 */
void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn)
{
	ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
		      "(%s)\n", tcp_conn->iscsi_conn->hdrdgst_en ?
		      "digest enabled" : "digest disabled");
	iscsi_segment_init_linear(&tcp_conn->in.segment,
				tcp_conn->in.hdr_buf, sizeof(struct iscsi_hdr),
				iscsi_tcp_hdr_recv_done, NULL);
}
EXPORT_SYMBOL_GPL(iscsi_tcp_hdr_recv_prep);

/*
 * Handle incoming reply to any other type of command
 */
static int
iscsi_tcp_data_recv_done(struct iscsi_tcp_conn *tcp_conn,
			 struct iscsi_segment *segment)
{
	struct iscsi_conn *conn = tcp_conn->iscsi_conn;
	int rc = 0;

	if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
		return ISCSI_ERR_DATA_DGST;

	rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr,
			conn->data, tcp_conn->in.datalen);
	if (rc)
		return rc;

	iscsi_tcp_hdr_recv_prep(tcp_conn);
	return 0;
}

static void
iscsi_tcp_data_recv_prep(struct iscsi_tcp_conn *tcp_conn)
{
	struct iscsi_conn *conn = tcp_conn->iscsi_conn;
	u32 *rx_crcp = NULL;

	if (conn->datadgst_en &&
	    !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
		rx_crcp = tcp_conn->rx_crcp;

	iscsi_segment_init_linear(&tcp_conn->in.segment,
				conn->data, tcp_conn->in.datalen,
				iscsi_tcp_data_recv_done, rx_crcp);
}

/**
 * iscsi_tcp_cleanup_task - free tcp_task resources
 * @task: iscsi task
 *
 * must be called with session back_lock
 */
void iscsi_tcp_cleanup_task(struct iscsi_task *task)
{
	struct iscsi_tcp_task *tcp_task = task->dd_data;
	struct iscsi_r2t_info *r2t;

	/* nothing to do for mgmt */
	if (!task->sc)
		return;

	spin_lock_bh(&tcp_task->queue2pool);
	/* flush task's r2t queues */
	while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
			    sizeof(void*));
		ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
	}

	r2t = tcp_task->r2t;
	if (r2t != NULL) {
		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
			    sizeof(void*));
		tcp_task->r2t = NULL;
	}
	spin_unlock_bh(&tcp_task->queue2pool);
}
EXPORT_SYMBOL_GPL(iscsi_tcp_cleanup_task);

/**
 * iscsi_tcp_data_in - SCSI Data-In Response processing
 * @conn: iscsi connection
 * @task: scsi command task
 */
static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
{
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_tcp_task *tcp_task = task->dd_data;
	struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
	int datasn = be32_to_cpu(rhdr->datasn);
	unsigned total_in_length = task->sc->sdb.length;

	/*
	 * lib iscsi will update this in the completion handling if there
	 * is status.
	 */
	if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS))
		iscsi_update_cmdsn(conn->session, (struct iscsi_nopin*)rhdr);

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

	if (tcp_task->exp_datasn != datasn) {
		ISCSI_DBG_TCP(conn, "task->exp_datasn(%d) != rhdr->datasn(%d)"
			      "\n", tcp_task->exp_datasn, datasn);
		return ISCSI_ERR_DATASN;
	}

	tcp_task->exp_datasn++;

	tcp_task->data_offset = be32_to_cpu(rhdr->offset);
	if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) {
		ISCSI_DBG_TCP(conn, "data_offset(%d) + data_len(%d) > "
			      "total_length_in(%d)\n", tcp_task->data_offset,
			      tcp_conn->in.datalen, total_in_length);
		return ISCSI_ERR_DATA_OFFSET;
	}

	conn->datain_pdus_cnt++;
	return 0;
}

/**
 * iscsi_tcp_r2t_rsp - iSCSI R2T Response processing
 * @conn: iscsi connection
 * @hdr: PDU header
 */
static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
{
	struct iscsi_session *session = conn->session;
	struct iscsi_tcp_task *tcp_task;
	struct iscsi_tcp_conn *tcp_conn;
	struct iscsi_r2t_rsp *rhdr;
	struct iscsi_r2t_info *r2t;
	struct iscsi_task *task;
	u32 data_length;
	u32 data_offset;
	int r2tsn;
	int rc;

	spin_lock(&session->back_lock);
	task = iscsi_itt_to_ctask(conn, hdr->itt);
	if (!task) {
		spin_unlock(&session->back_lock);
		return ISCSI_ERR_BAD_ITT;
	} else if (task->sc->sc_data_direction != DMA_TO_DEVICE) {
		spin_unlock(&session->back_lock);
		return ISCSI_ERR_PROTO;
	}
	/*
	 * A bad target might complete the cmd before we have handled R2Ts
	 * so get a ref to the task that will be dropped in the xmit path.
	 */
	if (task->state != ISCSI_TASK_RUNNING) {
		spin_unlock(&session->back_lock);
		/* Let the path that got the early rsp complete it */
		return 0;
	}
	task->last_xfer = jiffies;
	if (!iscsi_get_task(task)) {
		spin_unlock(&session->back_lock);
		/* Let the path that got the early rsp complete it */
		return 0;
	}

	tcp_conn = conn->dd_data;
	rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
	/* fill-in new R2T associated with the task */
	iscsi_update_cmdsn(session, (struct iscsi_nopin *)rhdr);
	spin_unlock(&session->back_lock);

	if (tcp_conn->in.datalen) {
		iscsi_conn_printk(KERN_ERR, conn,
				  "invalid R2t with datalen %d\n",
				  tcp_conn->in.datalen);
		rc = ISCSI_ERR_DATALEN;
		goto put_task;
	}

	tcp_task = task->dd_data;
	r2tsn = be32_to_cpu(rhdr->r2tsn);
	if (tcp_task->exp_datasn != r2tsn){
		ISCSI_DBG_TCP(conn, "task->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
			      tcp_task->exp_datasn, r2tsn);
		rc = ISCSI_ERR_R2TSN;
		goto put_task;
	}

	if (session->state != ISCSI_STATE_LOGGED_IN) {
		iscsi_conn_printk(KERN_INFO, conn,
				  "dropping R2T itt %d in recovery.\n",
				  task->itt);
		rc = 0;
		goto put_task;
	}

	data_length = be32_to_cpu(rhdr->data_length);
	if (data_length == 0) {
		iscsi_conn_printk(KERN_ERR, conn,
				  "invalid R2T with zero data len\n");
		rc = ISCSI_ERR_DATALEN;
		goto put_task;
	}

	if (data_length > session->max_burst)
		ISCSI_DBG_TCP(conn, "invalid R2T with data len %u and max "
			      "burst %u. Attempting to execute request.\n",
			      data_length, session->max_burst);

	data_offset = be32_to_cpu(rhdr->data_offset);
	if (data_offset + data_length > task->sc->sdb.length) {
		iscsi_conn_printk(KERN_ERR, conn,
				  "invalid R2T with data len %u at offset %u "
				  "and total length %d\n", data_length,
				  data_offset, task->sc->sdb.length);
		rc = ISCSI_ERR_DATALEN;
		goto put_task;
	}

	spin_lock(&tcp_task->pool2queue);
	rc = kfifo_out(&tcp_task->r2tpool.queue, (void *)&r2t, sizeof(void *));
	if (!rc) {
		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
				  "Target has sent more R2Ts than it "
				  "negotiated for or driver has leaked.\n");
		spin_unlock(&tcp_task->pool2queue);
		rc = ISCSI_ERR_PROTO;
		goto put_task;
	}

	r2t->exp_statsn = rhdr->statsn;
	r2t->data_length = data_length;
	r2t->data_offset = data_offset;

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

	tcp_task->exp_datasn = r2tsn + 1;
	kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
	conn->r2t_pdus_cnt++;
	spin_unlock(&tcp_task->pool2queue);

	iscsi_requeue_task(task);
	return 0;

put_task:
	iscsi_put_task(task);
	return rc;
}

/*
 * Handle incoming reply to DataIn command
 */
static int
iscsi_tcp_process_data_in(struct iscsi_tcp_conn *tcp_conn,
			  struct iscsi_segment *segment)
{
	struct iscsi_conn *conn = tcp_conn->iscsi_conn;
	struct iscsi_hdr *hdr = tcp_conn->in.hdr;
	int rc;

	if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
		return ISCSI_ERR_DATA_DGST;

	/* check for non-exceptional status */
	if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
		rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
		if (rc)
			return rc;
	}

	iscsi_tcp_hdr_recv_prep(tcp_conn);
	return 0;
}

/**
 * iscsi_tcp_hdr_dissect - process PDU header
 * @conn: iSCSI connection
 * @hdr: PDU header
 *
 * This function analyzes the header of the PDU received,
 * and performs several sanity checks. If the PDU is accompanied
 * by data, the receive buffer is set up to copy the incoming data
 * to the correct location.
 */
static int
iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
{
	int rc = 0, opcode, ahslen;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_task *task;

	/* verify PDU length */
	tcp_conn->in.datalen = ntoh24(hdr->dlength);
	if (tcp_conn->in.datalen > conn->max_recv_dlength) {
		iscsi_conn_printk(KERN_ERR, conn,
				  "iscsi_tcp: datalen %d > %d\n",
				  tcp_conn->in.datalen, conn->max_recv_dlength);
		return ISCSI_ERR_DATALEN;
	}

	/* Additional header segments. So far, we don't
	 * process additional headers.
	 */
	ahslen = hdr->hlength << 2;

	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
	/* verify itt (itt encoding: age+cid+itt) */
	rc = iscsi_verify_itt(conn, hdr->itt);
	if (rc)
		return rc;

	ISCSI_DBG_TCP(conn, "opcode 0x%x ahslen %d datalen %d\n",
		      opcode, ahslen, tcp_conn->in.datalen);

	switch(opcode) {
	case ISCSI_OP_SCSI_DATA_IN:
		spin_lock(&conn->session->back_lock);
		task = iscsi_itt_to_ctask(conn, hdr->itt);
		if (!task)
			rc = ISCSI_ERR_BAD_ITT;
		else
			rc = iscsi_tcp_data_in(conn, task);
		if (rc) {
			spin_unlock(&conn->session->back_lock);
			break;
		}

		if (tcp_conn->in.datalen) {
			struct iscsi_tcp_task *tcp_task = task->dd_data;
			u32 *rx_crcp = NULL;
			struct scsi_data_buffer *sdb = &task->sc->sdb;

			/*
			 * Setup copy of Data-In into the struct scsi_cmnd
			 * Scatterlist case:
			 * We set up the iscsi_segment to point to the next
			 * scatterlist entry to copy to. As we go along,
			 * we move on to the next scatterlist entry and
			 * update the digest per-entry.
			 */
			if (conn->datadgst_en &&
			    !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
				rx_crcp = tcp_conn->rx_crcp;

			ISCSI_DBG_TCP(conn, "iscsi_tcp_begin_data_in( "
				     "offset=%d, datalen=%d)\n",
				      tcp_task->data_offset,
				      tcp_conn->in.datalen);
			task->last_xfer = jiffies;
			rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
						   sdb->table.sgl,
						   sdb->table.nents,
						   tcp_task->data_offset,
						   tcp_conn->in.datalen,
						   iscsi_tcp_process_data_in,
						   rx_crcp);
			spin_unlock(&conn->session->back_lock);
			return rc;
		}
		rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
		spin_unlock(&conn->session->back_lock);
		break;
	case ISCSI_OP_SCSI_CMD_RSP:
		if (tcp_conn->in.datalen) {
			iscsi_tcp_data_recv_prep(tcp_conn);
			return 0;
		}
		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
		break;
	case ISCSI_OP_R2T:
		if (ahslen) {
			rc = ISCSI_ERR_AHSLEN;
			break;
		}
		rc = iscsi_tcp_r2t_rsp(conn, hdr);
		break;
	case ISCSI_OP_LOGIN_RSP:
	case ISCSI_OP_TEXT_RSP:
	case ISCSI_OP_REJECT:
	case ISCSI_OP_ASYNC_EVENT:
		/*
		 * 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
		 */
		if (ISCSI_DEF_MAX_RECV_SEG_LEN < tcp_conn->in.datalen) {
			iscsi_conn_printk(KERN_ERR, conn,
					  "iscsi_tcp: received buffer of "
					  "len %u but conn buffer is only %u "
					  "(opcode %0x)\n",
					  tcp_conn->in.datalen,
					  ISCSI_DEF_MAX_RECV_SEG_LEN, opcode);
			rc = ISCSI_ERR_PROTO;
			break;
		}

		/* If there's data coming in with the response,
		 * receive it to the connection's buffer.
		 */
		if (tcp_conn->in.datalen) {
			iscsi_tcp_data_recv_prep(tcp_conn);
			return 0;
		}
		fallthrough;
	case ISCSI_OP_LOGOUT_RSP:
	case ISCSI_OP_NOOP_IN:
	case ISCSI_OP_SCSI_TMFUNC_RSP:
		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
		break;
	default:
		rc = ISCSI_ERR_BAD_OPCODE;
		break;
	}

	if (rc == 0) {
		/* Anything that comes with data should have
		 * been handled above. */
		if (tcp_conn->in.datalen)
			return ISCSI_ERR_PROTO;
		iscsi_tcp_hdr_recv_prep(tcp_conn);
	}

	return rc;
}

/**
 * iscsi_tcp_hdr_recv_done - process PDU header
 * @tcp_conn: iSCSI TCP connection
 * @segment: the buffer segment being processed
 *
 * This is the callback invoked when the PDU header has
 * been received. If the header is followed by additional
 * header segments, we go back for more data.
 */
static int
iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn,
			struct iscsi_segment *segment)
{
	struct iscsi_conn *conn = tcp_conn->iscsi_conn;
	struct iscsi_hdr *hdr;

	/* Check if there are additional header segments
	 * *prior* to computing the digest, because we
	 * may need to go back to the caller for more.
	 */
	hdr = (struct iscsi_hdr *) tcp_conn->in.hdr_buf;
	if (segment->copied == sizeof(struct iscsi_hdr) && hdr->hlength) {
		/* Bump the header length - the caller will
		 * just loop around and get the AHS for us, and
		 * call again. */
		unsigned int ahslen = hdr->hlength << 2;

		/* Make sure we don't overflow */
		if (sizeof(*hdr) + ahslen > sizeof(tcp_conn->in.hdr_buf))
			return ISCSI_ERR_AHSLEN;

		segment->total_size += ahslen;
		segment->size += ahslen;
		return 0;
	}

	/* We're done processing the header. See if we're doing
	 * header digests; if so, set up the recv_digest buffer
	 * and go back for more. */
	if (conn->hdrdgst_en &&
	    !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) {
		if (segment->digest_len == 0) {
			/*
			 * Even if we offload the digest processing we
			 * splice it in so we can increment the skb/segment
			 * counters in preparation for the data segment.
			 */
			iscsi_tcp_segment_splice_digest(segment,
							segment->recv_digest);
			return 0;
		}

		iscsi_tcp_dgst_header(hdr,
				      segment->total_copied - ISCSI_DIGEST_SIZE,
				      segment->digest);

		if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
			return ISCSI_ERR_HDR_DGST;
	}

	tcp_conn->in.hdr = hdr;
	return iscsi_tcp_hdr_dissect(conn, hdr);
}

/**
 * iscsi_tcp_recv_segment_is_hdr - tests if we are reading in a header
 * @tcp_conn: iscsi tcp conn
 *
 * returns non zero if we are currently processing or setup to process
 * a header.
 */
inline int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn)
{
	return tcp_conn->in.segment.done == iscsi_tcp_hdr_recv_done;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_recv_segment_is_hdr);

/**
 * iscsi_tcp_recv_skb - Process skb
 * @conn: iscsi connection
 * @skb: network buffer with header and/or data segment
 * @offset: offset in skb
 * @offloaded: bool indicating if transfer was offloaded
 * @status: iscsi TCP status result
 *
 * Will return status of transfer in @status. And will return
 * number of bytes copied.
 */
int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
		       unsigned int offset, bool offloaded, int *status)
{
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_segment *segment = &tcp_conn->in.segment;
	struct skb_seq_state seq;
	unsigned int consumed = 0;
	int rc = 0;

	ISCSI_DBG_TCP(conn, "in %d bytes\n", skb->len - offset);
	/*
	 * Update for each skb instead of pdu, because over slow networks a
	 * data_in's data could take a while to read in. We also want to
	 * account for r2ts.
	 */
	conn->last_recv = jiffies;

	if (unlikely(test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags))) {
		ISCSI_DBG_TCP(conn, "Rx suspended!\n");
		*status = ISCSI_TCP_SUSPENDED;
		return 0;
	}

	if (offloaded) {
		segment->total_copied = segment->total_size;
		goto segment_done;
	}

	skb_prepare_seq_read(skb, offset, skb->len, &seq);
	while (1) {
		unsigned int avail;
		const u8 *ptr;

		avail = skb_seq_read(consumed, &ptr, &seq);
		if (avail == 0) {
			ISCSI_DBG_TCP(conn, "no more data avail. Consumed %d\n",
				      consumed);
			*status = ISCSI_TCP_SKB_DONE;
			goto skb_done;
		}
		BUG_ON(segment->copied >= segment->size);

		ISCSI_DBG_TCP(conn, "skb %p ptr=%p avail=%u\n", skb, ptr,
			      avail);
		rc = iscsi_tcp_segment_recv(tcp_conn, segment, ptr, avail);
		BUG_ON(rc == 0);
		consumed += rc;

		if (segment->total_copied >= segment->total_size) {
			skb_abort_seq_read(&seq);
			goto segment_done;
		}
	}

segment_done:
	*status = ISCSI_TCP_SEGMENT_DONE;
	ISCSI_DBG_TCP(conn, "segment done\n");
	rc = segment->done(tcp_conn, segment);
	if (rc != 0) {
		*status = ISCSI_TCP_CONN_ERR;
		ISCSI_DBG_TCP(conn, "Error receiving PDU, errno=%d\n", rc);
		iscsi_conn_failure(conn, rc);
		return 0;
	}
	/* The done() functions sets up the next segment. */

skb_done:
	conn->rxdata_octets += consumed;
	return consumed;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_recv_skb);

/**
 * iscsi_tcp_task_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
 * @task: scsi command task
 */
int iscsi_tcp_task_init(struct iscsi_task *task)
{
	struct iscsi_tcp_task *tcp_task = task->dd_data;
	struct iscsi_conn *conn = task->conn;
	struct scsi_cmnd *sc = task->sc;
	int err;

	if (!sc) {
		/*
		 * mgmt tasks do not have a scatterlist since they come
		 * in from the iscsi interface.
		 */
		ISCSI_DBG_TCP(conn, "mtask deq [itt 0x%x]\n", task->itt);

		return conn->session->tt->init_pdu(task, 0, task->data_count);
	}

	BUG_ON(kfifo_len(&tcp_task->r2tqueue));
	tcp_task->exp_datasn = 0;

	/* Prepare PDU, optionally w/ immediate data */
	ISCSI_DBG_TCP(conn, "task deq [itt 0x%x imm %d unsol %d]\n",
		      task->itt, task->imm_count, task->unsol_r2t.data_length);

	err = conn->session->tt->init_pdu(task, 0, task->imm_count);
	if (err)
		return err;
	task->imm_count = 0;
	return 0;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_task_init);

static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
{
	struct iscsi_tcp_task *tcp_task = task->dd_data;
	struct iscsi_r2t_info *r2t = NULL;

	if (iscsi_task_has_unsol_data(task))
		r2t = &task->unsol_r2t;
	else {
		spin_lock_bh(&tcp_task->queue2pool);
		if (tcp_task->r2t) {
			r2t = tcp_task->r2t;
			/* Continue with this R2T? */
			if (r2t->data_length <= r2t->sent) {
				ISCSI_DBG_TCP(task->conn,
					      "  done with r2t %p\n", r2t);
				kfifo_in(&tcp_task->r2tpool.queue,
					    (void *)&tcp_task->r2t,
					    sizeof(void *));
				tcp_task->r2t = r2t = NULL;
			}
		}

		if (r2t == NULL) {
			if (kfifo_out(&tcp_task->r2tqueue,
			    (void *)&tcp_task->r2t, sizeof(void *)) !=
			    sizeof(void *))
				r2t = NULL;
			else
				r2t = tcp_task->r2t;
		}
		spin_unlock_bh(&tcp_task->queue2pool);
	}

	return r2t;
}

/**
 * iscsi_tcp_task_xmit - xmit normal PDU task
 * @task: iscsi command task
 *
 * We're expected to return 0 when everything was transmitted successfully,
 * -EAGAIN if there's still data in the queue, or != 0 for any other kind
 * of error.
 */
int iscsi_tcp_task_xmit(struct iscsi_task *task)
{
	struct iscsi_conn *conn = task->conn;
	struct iscsi_session *session = conn->session;
	struct iscsi_r2t_info *r2t;
	int rc = 0;

flush:
	/* Flush any pending data first. */
	rc = session->tt->xmit_pdu(task);
	if (rc < 0)
		return rc;

	/* mgmt command */
	if (!task->sc) {
		if (task->hdr->itt == RESERVED_ITT)
			iscsi_put_task(task);
		return 0;
	}

	/* Are we done already? */
	if (task->sc->sc_data_direction != DMA_TO_DEVICE)
		return 0;

	r2t = iscsi_tcp_get_curr_r2t(task);
	if (r2t == NULL) {
		/* Waiting for more R2Ts to arrive. */
		ISCSI_DBG_TCP(conn, "no R2Ts yet\n");
		return 0;
	}

	rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_DATA_OUT);
	if (rc)
		return rc;
	iscsi_prep_data_out_pdu(task, r2t, (struct iscsi_data *) task->hdr);

	ISCSI_DBG_TCP(conn, "sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n",
		      r2t, r2t->datasn - 1, task->hdr->itt,
		      r2t->data_offset + r2t->sent, r2t->data_count);

	rc = conn->session->tt->init_pdu(task, r2t->data_offset + r2t->sent,
					 r2t->data_count);
	if (rc) {
		iscsi_conn_failure(conn, ISCSI_ERR_XMIT_FAILED);
		return rc;
	}

	r2t->sent += r2t->data_count;
	goto flush;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_task_xmit);

struct iscsi_cls_conn *
iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size,
		      uint32_t conn_idx)

{
	struct iscsi_conn *conn;
	struct iscsi_cls_conn *cls_conn;
	struct iscsi_tcp_conn *tcp_conn;

	cls_conn = iscsi_conn_setup(cls_session,
				    sizeof(*tcp_conn) + dd_data_size, conn_idx);
	if (!cls_conn)
		return NULL;
	conn = cls_conn->dd_data;
	/*
	 * due to strange issues with iser these are not set
	 * in iscsi_conn_setup
	 */
	conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;

	tcp_conn = conn->dd_data;
	tcp_conn->iscsi_conn = conn;
	tcp_conn->dd_data = conn->dd_data + sizeof(*tcp_conn);
	return cls_conn;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_conn_setup);

void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn)
{
	iscsi_conn_teardown(cls_conn);
}
EXPORT_SYMBOL_GPL(iscsi_tcp_conn_teardown);

int iscsi_tcp_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_task *task = session->cmds[cmd_i];
		struct iscsi_tcp_task *tcp_task = task->dd_data;

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

		/* R2T pool */
		if (iscsi_pool_init(&tcp_task->r2tpool,
				    session->max_r2t * 2, NULL,
				    sizeof(struct iscsi_r2t_info))) {
			goto r2t_alloc_fail;
		}

		/* R2T xmit queue */
		if (kfifo_alloc(&tcp_task->r2tqueue,
		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
			iscsi_pool_free(&tcp_task->r2tpool);
			goto r2t_alloc_fail;
		}
		spin_lock_init(&tcp_task->pool2queue);
		spin_lock_init(&tcp_task->queue2pool);
	}

	return 0;

r2t_alloc_fail:
	for (i = 0; i < cmd_i; i++) {
		struct iscsi_task *task = session->cmds[i];
		struct iscsi_tcp_task *tcp_task = task->dd_data;

		kfifo_free(&tcp_task->r2tqueue);
		iscsi_pool_free(&tcp_task->r2tpool);
	}
	return -ENOMEM;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_r2tpool_alloc);

void iscsi_tcp_r2tpool_free(struct iscsi_session *session)
{
	int i;

	for (i = 0; i < session->cmds_max; i++) {
		struct iscsi_task *task = session->cmds[i];
		struct iscsi_tcp_task *tcp_task = task->dd_data;

		kfifo_free(&tcp_task->r2tqueue);
		iscsi_pool_free(&tcp_task->r2tpool);
	}
}
EXPORT_SYMBOL_GPL(iscsi_tcp_r2tpool_free);

int iscsi_tcp_set_max_r2t(struct iscsi_conn *conn, char *buf)
{
	struct iscsi_session *session = conn->session;
	unsigned short r2ts = 0;

	sscanf(buf, "%hu", &r2ts);
	if (session->max_r2t == r2ts)
		return 0;

	if (!r2ts || !is_power_of_2(r2ts))
		return -EINVAL;

	session->max_r2t = r2ts;
	iscsi_tcp_r2tpool_free(session);
	return iscsi_tcp_r2tpool_alloc(session);
}
EXPORT_SYMBOL_GPL(iscsi_tcp_set_max_r2t);

void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
			      struct iscsi_stats *stats)
{
	struct iscsi_conn *conn = cls_conn->dd_data;

	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;
}
EXPORT_SYMBOL_GPL(iscsi_tcp_conn_get_stats);
