// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 * This file contains the iSCSI Target DataIN value generation functions.
 *
 * (c) Copyright 2007-2013 Datera, Inc.
 *
 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
 *
 ******************************************************************************/

#include <linux/slab.h>
#include <scsi/iscsi_proto.h>
#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_seq_pdu_list.h"
#include "iscsi_target_erl1.h"
#include "iscsi_target_util.h"
#include "iscsi_target.h"
#include "iscsi_target_datain_values.h"

struct iscsi_datain_req *iscsit_allocate_datain_req(void)
{
	struct iscsi_datain_req *dr;

	dr = kmem_cache_zalloc(lio_dr_cache, GFP_ATOMIC);
	if (!dr) {
		pr_err("Unable to allocate memory for"
				" struct iscsi_datain_req\n");
		return NULL;
	}
	INIT_LIST_HEAD(&dr->cmd_datain_node);

	return dr;
}

void iscsit_attach_datain_req(struct iscsit_cmd *cmd, struct iscsi_datain_req *dr)
{
	spin_lock(&cmd->datain_lock);
	list_add_tail(&dr->cmd_datain_node, &cmd->datain_list);
	spin_unlock(&cmd->datain_lock);
}

void iscsit_free_datain_req(struct iscsit_cmd *cmd, struct iscsi_datain_req *dr)
{
	spin_lock(&cmd->datain_lock);
	list_del(&dr->cmd_datain_node);
	spin_unlock(&cmd->datain_lock);

	kmem_cache_free(lio_dr_cache, dr);
}

void iscsit_free_all_datain_reqs(struct iscsit_cmd *cmd)
{
	struct iscsi_datain_req *dr, *dr_tmp;

	spin_lock(&cmd->datain_lock);
	list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, cmd_datain_node) {
		list_del(&dr->cmd_datain_node);
		kmem_cache_free(lio_dr_cache, dr);
	}
	spin_unlock(&cmd->datain_lock);
}

struct iscsi_datain_req *iscsit_get_datain_req(struct iscsit_cmd *cmd)
{
	if (list_empty(&cmd->datain_list)) {
		pr_err("cmd->datain_list is empty for ITT:"
			" 0x%08x\n", cmd->init_task_tag);
		return NULL;
	}

	return list_first_entry(&cmd->datain_list, struct iscsi_datain_req,
				cmd_datain_node);
}

/*
 *	For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=Yes.
 */
static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes(
	struct iscsit_cmd *cmd,
	struct iscsi_datain *datain)
{
	u32 next_burst_len, read_data_done, read_data_left;
	struct iscsit_conn *conn = cmd->conn;
	struct iscsi_datain_req *dr;

	dr = iscsit_get_datain_req(cmd);
	if (!dr)
		return NULL;

	if (dr->recovery && dr->generate_recovery_values) {
		if (iscsit_create_recovery_datain_values_datasequenceinorder_yes(
					cmd, dr) < 0)
			return NULL;

		dr->generate_recovery_values = 0;
	}

	next_burst_len = (!dr->recovery) ?
			cmd->next_burst_len : dr->next_burst_len;
	read_data_done = (!dr->recovery) ?
			cmd->read_data_done : dr->read_data_done;

	read_data_left = (cmd->se_cmd.data_length - read_data_done);
	if (!read_data_left) {
		pr_err("ITT: 0x%08x read_data_left is zero!\n",
				cmd->init_task_tag);
		return NULL;
	}

	if ((read_data_left <= conn->conn_ops->MaxRecvDataSegmentLength) &&
	    (read_data_left <= (conn->sess->sess_ops->MaxBurstLength -
	     next_burst_len))) {
		datain->length = read_data_left;

		datain->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
			datain->flags |= ISCSI_FLAG_DATA_ACK;
	} else {
		if ((next_burst_len +
		     conn->conn_ops->MaxRecvDataSegmentLength) <
		     conn->sess->sess_ops->MaxBurstLength) {
			datain->length =
				conn->conn_ops->MaxRecvDataSegmentLength;
			next_burst_len += datain->length;
		} else {
			datain->length = (conn->sess->sess_ops->MaxBurstLength -
					  next_burst_len);
			next_burst_len = 0;

			datain->flags |= ISCSI_FLAG_CMD_FINAL;
			if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
				datain->flags |= ISCSI_FLAG_DATA_ACK;
		}
	}

	datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
	datain->offset = read_data_done;

	if (!dr->recovery) {
		cmd->next_burst_len = next_burst_len;
		cmd->read_data_done += datain->length;
	} else {
		dr->next_burst_len = next_burst_len;
		dr->read_data_done += datain->length;
	}

	if (!dr->recovery) {
		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
			dr->dr_complete = DATAIN_COMPLETE_NORMAL;

		return dr;
	}

	if (!dr->runlength) {
		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	} else {
		if ((dr->begrun + dr->runlength) == dr->data_sn) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	}

	return dr;
}

/*
 *	For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=Yes.
 */
static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes(
	struct iscsit_cmd *cmd,
	struct iscsi_datain *datain)
{
	u32 offset, read_data_done, read_data_left, seq_send_order;
	struct iscsit_conn *conn = cmd->conn;
	struct iscsi_datain_req *dr;
	struct iscsi_seq *seq;

	dr = iscsit_get_datain_req(cmd);
	if (!dr)
		return NULL;

	if (dr->recovery && dr->generate_recovery_values) {
		if (iscsit_create_recovery_datain_values_datasequenceinorder_no(
					cmd, dr) < 0)
			return NULL;

		dr->generate_recovery_values = 0;
	}

	read_data_done = (!dr->recovery) ?
			cmd->read_data_done : dr->read_data_done;
	seq_send_order = (!dr->recovery) ?
			cmd->seq_send_order : dr->seq_send_order;

	read_data_left = (cmd->se_cmd.data_length - read_data_done);
	if (!read_data_left) {
		pr_err("ITT: 0x%08x read_data_left is zero!\n",
				cmd->init_task_tag);
		return NULL;
	}

	seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order);
	if (!seq)
		return NULL;

	seq->sent = 1;

	if (!dr->recovery && !seq->next_burst_len)
		seq->first_datasn = cmd->data_sn;

	offset = (seq->offset + seq->next_burst_len);

	if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
	     cmd->se_cmd.data_length) {
		datain->length = (cmd->se_cmd.data_length - offset);
		datain->offset = offset;

		datain->flags |= ISCSI_FLAG_CMD_FINAL;
		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
			datain->flags |= ISCSI_FLAG_DATA_ACK;

		seq->next_burst_len = 0;
		seq_send_order++;
	} else {
		if ((seq->next_burst_len +
		     conn->conn_ops->MaxRecvDataSegmentLength) <
		     conn->sess->sess_ops->MaxBurstLength) {
			datain->length =
				conn->conn_ops->MaxRecvDataSegmentLength;
			datain->offset = (seq->offset + seq->next_burst_len);

			seq->next_burst_len += datain->length;
		} else {
			datain->length = (conn->sess->sess_ops->MaxBurstLength -
					  seq->next_burst_len);
			datain->offset = (seq->offset + seq->next_burst_len);

			datain->flags |= ISCSI_FLAG_CMD_FINAL;
			if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
				datain->flags |= ISCSI_FLAG_DATA_ACK;

			seq->next_burst_len = 0;
			seq_send_order++;
		}
	}

	if ((read_data_done + datain->length) == cmd->se_cmd.data_length)
		datain->flags |= ISCSI_FLAG_DATA_STATUS;

	datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
	if (!dr->recovery) {
		cmd->seq_send_order = seq_send_order;
		cmd->read_data_done += datain->length;
	} else {
		dr->seq_send_order = seq_send_order;
		dr->read_data_done += datain->length;
	}

	if (!dr->recovery) {
		if (datain->flags & ISCSI_FLAG_CMD_FINAL)
			seq->last_datasn = datain->data_sn;
		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
			dr->dr_complete = DATAIN_COMPLETE_NORMAL;

		return dr;
	}

	if (!dr->runlength) {
		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	} else {
		if ((dr->begrun + dr->runlength) == dr->data_sn) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	}

	return dr;
}

/*
 *	For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=No.
 */
static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no(
	struct iscsit_cmd *cmd,
	struct iscsi_datain *datain)
{
	u32 next_burst_len, read_data_done, read_data_left;
	struct iscsit_conn *conn = cmd->conn;
	struct iscsi_datain_req *dr;
	struct iscsi_pdu *pdu;

	dr = iscsit_get_datain_req(cmd);
	if (!dr)
		return NULL;

	if (dr->recovery && dr->generate_recovery_values) {
		if (iscsit_create_recovery_datain_values_datasequenceinorder_yes(
					cmd, dr) < 0)
			return NULL;

		dr->generate_recovery_values = 0;
	}

	next_burst_len = (!dr->recovery) ?
			cmd->next_burst_len : dr->next_burst_len;
	read_data_done = (!dr->recovery) ?
			cmd->read_data_done : dr->read_data_done;

	read_data_left = (cmd->se_cmd.data_length - read_data_done);
	if (!read_data_left) {
		pr_err("ITT: 0x%08x read_data_left is zero!\n",
				cmd->init_task_tag);
		return dr;
	}

	pdu = iscsit_get_pdu_holder_for_seq(cmd, NULL);
	if (!pdu)
		return dr;

	if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) {
		pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
			pdu->flags |= ISCSI_FLAG_DATA_ACK;

		next_burst_len = 0;
	} else {
		if ((next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) <
		     conn->sess->sess_ops->MaxBurstLength)
			next_burst_len += pdu->length;
		else {
			pdu->flags |= ISCSI_FLAG_CMD_FINAL;
			if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
				pdu->flags |= ISCSI_FLAG_DATA_ACK;

			next_burst_len = 0;
		}
	}

	pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
	if (!dr->recovery) {
		cmd->next_burst_len = next_burst_len;
		cmd->read_data_done += pdu->length;
	} else {
		dr->next_burst_len = next_burst_len;
		dr->read_data_done += pdu->length;
	}

	datain->flags = pdu->flags;
	datain->length = pdu->length;
	datain->offset = pdu->offset;
	datain->data_sn = pdu->data_sn;

	if (!dr->recovery) {
		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
			dr->dr_complete = DATAIN_COMPLETE_NORMAL;

		return dr;
	}

	if (!dr->runlength) {
		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	} else {
		if ((dr->begrun + dr->runlength) == dr->data_sn) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	}

	return dr;
}

/*
 *	For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=No.
 */
static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no(
	struct iscsit_cmd *cmd,
	struct iscsi_datain *datain)
{
	u32 read_data_done, read_data_left, seq_send_order;
	struct iscsit_conn *conn = cmd->conn;
	struct iscsi_datain_req *dr;
	struct iscsi_pdu *pdu;
	struct iscsi_seq *seq = NULL;

	dr = iscsit_get_datain_req(cmd);
	if (!dr)
		return NULL;

	if (dr->recovery && dr->generate_recovery_values) {
		if (iscsit_create_recovery_datain_values_datasequenceinorder_no(
					cmd, dr) < 0)
			return NULL;

		dr->generate_recovery_values = 0;
	}

	read_data_done = (!dr->recovery) ?
			cmd->read_data_done : dr->read_data_done;
	seq_send_order = (!dr->recovery) ?
			cmd->seq_send_order : dr->seq_send_order;

	read_data_left = (cmd->se_cmd.data_length - read_data_done);
	if (!read_data_left) {
		pr_err("ITT: 0x%08x read_data_left is zero!\n",
				cmd->init_task_tag);
		return NULL;
	}

	seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order);
	if (!seq)
		return NULL;

	seq->sent = 1;

	if (!dr->recovery && !seq->next_burst_len)
		seq->first_datasn = cmd->data_sn;

	pdu = iscsit_get_pdu_holder_for_seq(cmd, seq);
	if (!pdu)
		return NULL;

	if (seq->pdu_send_order == seq->pdu_count) {
		pdu->flags |= ISCSI_FLAG_CMD_FINAL;
		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
			pdu->flags |= ISCSI_FLAG_DATA_ACK;

		seq->next_burst_len = 0;
		seq_send_order++;
	} else
		seq->next_burst_len += pdu->length;

	if ((read_data_done + pdu->length) == cmd->se_cmd.data_length)
		pdu->flags |= ISCSI_FLAG_DATA_STATUS;

	pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
	if (!dr->recovery) {
		cmd->seq_send_order = seq_send_order;
		cmd->read_data_done += pdu->length;
	} else {
		dr->seq_send_order = seq_send_order;
		dr->read_data_done += pdu->length;
	}

	datain->flags = pdu->flags;
	datain->length = pdu->length;
	datain->offset = pdu->offset;
	datain->data_sn = pdu->data_sn;

	if (!dr->recovery) {
		if (datain->flags & ISCSI_FLAG_CMD_FINAL)
			seq->last_datasn = datain->data_sn;
		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
			dr->dr_complete = DATAIN_COMPLETE_NORMAL;

		return dr;
	}

	if (!dr->runlength) {
		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	} else {
		if ((dr->begrun + dr->runlength) == dr->data_sn) {
			dr->dr_complete =
			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
				DATAIN_COMPLETE_CONNECTION_RECOVERY;
		}
	}

	return dr;
}

struct iscsi_datain_req *iscsit_get_datain_values(
	struct iscsit_cmd *cmd,
	struct iscsi_datain *datain)
{
	struct iscsit_conn *conn = cmd->conn;

	if (conn->sess->sess_ops->DataSequenceInOrder &&
	    conn->sess->sess_ops->DataPDUInOrder)
		return iscsit_set_datain_values_yes_and_yes(cmd, datain);
	else if (!conn->sess->sess_ops->DataSequenceInOrder &&
		  conn->sess->sess_ops->DataPDUInOrder)
		return iscsit_set_datain_values_no_and_yes(cmd, datain);
	else if (conn->sess->sess_ops->DataSequenceInOrder &&
		 !conn->sess->sess_ops->DataPDUInOrder)
		return iscsit_set_datain_values_yes_and_no(cmd, datain);
	else if (!conn->sess->sess_ops->DataSequenceInOrder &&
		   !conn->sess->sess_ops->DataPDUInOrder)
		return iscsit_set_datain_values_no_and_no(cmd, datain);

	return NULL;
}
EXPORT_SYMBOL(iscsit_get_datain_values);
