1e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger/*******************************************************************************
2e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * This file contains the iSCSI Target DataIN value generation functions.
3e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *
4e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *
6e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *
8e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
9e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *
10e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * This program is free software; you can redistribute it and/or modify
11e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * it under the terms of the GNU General Public License as published by
12e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * the Free Software Foundation; either version 2 of the License, or
13e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * (at your option) any later version.
14e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *
15e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * This program is distributed in the hope that it will be useful,
16e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * but WITHOUT ANY WARRANTY; without even the implied warranty of
17e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger * GNU General Public License for more details.
19e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger ******************************************************************************/
20e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
21e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include <scsi/iscsi_proto.h>
22e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
23e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include "iscsi_target_core.h"
24e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include "iscsi_target_seq_pdu_list.h"
25e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include "iscsi_target_erl1.h"
26e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include "iscsi_target_util.h"
27e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include "iscsi_target.h"
28e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger#include "iscsi_target_datain_values.h"
29e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
30e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstruct iscsi_datain_req *iscsit_allocate_datain_req(void)
31e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
32e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr;
33e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
34e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	dr = kmem_cache_zalloc(lio_dr_cache, GFP_ATOMIC);
35e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr) {
36e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pr_err("Unable to allocate memory for"
37e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				" struct iscsi_datain_req\n");
38e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
39e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
40e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	INIT_LIST_HEAD(&dr->dr_list);
41e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
42e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return dr;
43e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
44e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
45e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingervoid iscsit_attach_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr)
46e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
47e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	spin_lock(&cmd->datain_lock);
48e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	list_add_tail(&dr->dr_list, &cmd->datain_list);
49e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	spin_unlock(&cmd->datain_lock);
50e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
51e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
52e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingervoid iscsit_free_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr)
53e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
54e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	spin_lock(&cmd->datain_lock);
55e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	list_del(&dr->dr_list);
56e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	spin_unlock(&cmd->datain_lock);
57e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
58e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	kmem_cache_free(lio_dr_cache, dr);
59e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
60e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
61e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingervoid iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd)
62e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
63e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr, *dr_tmp;
64e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
65e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	spin_lock(&cmd->datain_lock);
66e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, dr_list) {
67e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		list_del(&dr->dr_list);
68e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		kmem_cache_free(lio_dr_cache, dr);
69e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
70e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	spin_unlock(&cmd->datain_lock);
71e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
72e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
73e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstruct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *cmd)
74e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
75e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr;
76e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
77e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (list_empty(&cmd->datain_list)) {
78e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pr_err("cmd->datain_list is empty for ITT:"
79e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			" 0x%08x\n", cmd->init_task_tag);
80e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
81e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
82e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	list_for_each_entry(dr, &cmd->datain_list, dr_list)
83e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		break;
84e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
85e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return dr;
86e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
87e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
88e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger/*
89e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *	For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=Yes.
90e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger */
91e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstatic struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes(
92e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_cmd *cmd,
93e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain *datain)
94e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
95e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	u32 next_burst_len, read_data_done, read_data_left;
96e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_conn *conn = cmd->conn;
97e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr;
98e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
99e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	dr = iscsit_get_datain_req(cmd);
100e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr)
101e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
102e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
103e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (dr->recovery && dr->generate_recovery_values) {
104e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (iscsit_create_recovery_datain_values_datasequenceinorder_yes(
105e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger					cmd, dr) < 0)
106e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			return NULL;
107e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
108e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->generate_recovery_values = 0;
109e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
110e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
111e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	next_burst_len = (!dr->recovery) ?
112e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->next_burst_len : dr->next_burst_len;
113e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_done = (!dr->recovery) ?
114e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->read_data_done : dr->read_data_done;
115e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
116e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_left = (cmd->data_length - read_data_done);
117e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!read_data_left) {
118e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pr_err("ITT: 0x%08x read_data_left is zero!\n",
119e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				cmd->init_task_tag);
120e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
121e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
122e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
123e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if ((read_data_left <= conn->conn_ops->MaxRecvDataSegmentLength) &&
124e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	    (read_data_left <= (conn->sess->sess_ops->MaxBurstLength -
125e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	     next_burst_len))) {
126e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		datain->length = read_data_left;
127e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
128e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		datain->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
129e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
130e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->flags |= ISCSI_FLAG_DATA_ACK;
131e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
132e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((next_burst_len +
133e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		     conn->conn_ops->MaxRecvDataSegmentLength) <
134e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		     conn->sess->sess_ops->MaxBurstLength) {
135e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->length =
136e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				conn->conn_ops->MaxRecvDataSegmentLength;
137e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			next_burst_len += datain->length;
138e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		} else {
139e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->length = (conn->sess->sess_ops->MaxBurstLength -
140e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger					  next_burst_len);
141e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			next_burst_len = 0;
142e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
143e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->flags |= ISCSI_FLAG_CMD_FINAL;
144e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
145e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				datain->flags |= ISCSI_FLAG_DATA_ACK;
146e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
147e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
148e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
149e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
150e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->offset = read_data_done;
151e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
152e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
153e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->next_burst_len = next_burst_len;
154e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->read_data_done += datain->length;
155e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
156e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->next_burst_len = next_burst_len;
157e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->read_data_done += datain->length;
158e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
159e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
160e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
161e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
162e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete = DATAIN_COMPLETE_NORMAL;
163e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
164e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return dr;
165e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
166e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
167e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->runlength) {
168e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
169e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
170e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
171e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
172e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
173e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
174e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
175e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((dr->begrun + dr->runlength) == dr->data_sn) {
176e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
177e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
178e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
179e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
180e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
181e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
182e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
183e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return dr;
184e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
185e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
186e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger/*
187e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *	For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=Yes.
188e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger */
189e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstatic struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes(
190e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_cmd *cmd,
191e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain *datain)
192e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
193e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	u32 offset, read_data_done, read_data_left, seq_send_order;
194e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_conn *conn = cmd->conn;
195e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr;
196e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_seq *seq;
197e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
198e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	dr = iscsit_get_datain_req(cmd);
199e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr)
200e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
201e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
202e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (dr->recovery && dr->generate_recovery_values) {
203e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (iscsit_create_recovery_datain_values_datasequenceinorder_no(
204e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger					cmd, dr) < 0)
205e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			return NULL;
206e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
207e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->generate_recovery_values = 0;
208e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
209e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
210e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_done = (!dr->recovery) ?
211e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->read_data_done : dr->read_data_done;
212e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	seq_send_order = (!dr->recovery) ?
213e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->seq_send_order : dr->seq_send_order;
214e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
215e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_left = (cmd->data_length - read_data_done);
216e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!read_data_left) {
217e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pr_err("ITT: 0x%08x read_data_left is zero!\n",
218e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				cmd->init_task_tag);
219e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
220e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
221e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
222e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order);
223e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!seq)
224e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
225e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
226e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	seq->sent = 1;
227e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
228e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery && !seq->next_burst_len)
229e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq->first_datasn = cmd->data_sn;
230e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
231e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	offset = (seq->offset + seq->next_burst_len);
232e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
233e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
234e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	     cmd->data_length) {
235e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		datain->length = (cmd->data_length - offset);
236e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		datain->offset = offset;
237e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
238e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		datain->flags |= ISCSI_FLAG_CMD_FINAL;
239e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
240e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->flags |= ISCSI_FLAG_DATA_ACK;
241e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
242e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq->next_burst_len = 0;
243e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq_send_order++;
244e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
245e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((seq->next_burst_len +
246e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		     conn->conn_ops->MaxRecvDataSegmentLength) <
247e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		     conn->sess->sess_ops->MaxBurstLength) {
248e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->length =
249e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				conn->conn_ops->MaxRecvDataSegmentLength;
250e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->offset = (seq->offset + seq->next_burst_len);
251e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
252e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			seq->next_burst_len += datain->length;
253e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		} else {
254e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->length = (conn->sess->sess_ops->MaxBurstLength -
255e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger					  seq->next_burst_len);
256e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->offset = (seq->offset + seq->next_burst_len);
257e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
258e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			datain->flags |= ISCSI_FLAG_CMD_FINAL;
259e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
260e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				datain->flags |= ISCSI_FLAG_DATA_ACK;
261e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
262e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			seq->next_burst_len = 0;
263e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			seq_send_order++;
264e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
265e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
266e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
267e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if ((read_data_done + datain->length) == cmd->data_length)
268e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		datain->flags |= ISCSI_FLAG_DATA_STATUS;
269e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
270e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
271e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
272e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->seq_send_order = seq_send_order;
273e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->read_data_done += datain->length;
274e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
275e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->seq_send_order = seq_send_order;
276e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->read_data_done += datain->length;
277e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
278e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
279e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
280e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_CMD_FINAL)
281e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			seq->last_datasn = datain->data_sn;
282e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
283e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete = DATAIN_COMPLETE_NORMAL;
284e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
285e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return dr;
286e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
287e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
288e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->runlength) {
289e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
290e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
291e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
292e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
293e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
294e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
295e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
296e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((dr->begrun + dr->runlength) == dr->data_sn) {
297e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
298e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
299e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
300e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
301e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
302e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
303e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
304e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return dr;
305e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
306e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
307e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger/*
308e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *	For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=No.
309e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger */
310e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstatic struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no(
311e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_cmd *cmd,
312e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain *datain)
313e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
314e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	u32 next_burst_len, read_data_done, read_data_left;
315e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_conn *conn = cmd->conn;
316e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr;
317e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_pdu *pdu;
318e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
319e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	dr = iscsit_get_datain_req(cmd);
320e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr)
321e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
322e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
323e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (dr->recovery && dr->generate_recovery_values) {
324e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (iscsit_create_recovery_datain_values_datasequenceinorder_yes(
325e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger					cmd, dr) < 0)
326e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			return NULL;
327e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
328e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->generate_recovery_values = 0;
329e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
330e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
331e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	next_burst_len = (!dr->recovery) ?
332e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->next_burst_len : dr->next_burst_len;
333e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_done = (!dr->recovery) ?
334e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->read_data_done : dr->read_data_done;
335e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
336e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_left = (cmd->data_length - read_data_done);
337e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!read_data_left) {
338e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pr_err("ITT: 0x%08x read_data_left is zero!\n",
339e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				cmd->init_task_tag);
340e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return dr;
341e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
342e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
343e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	pdu = iscsit_get_pdu_holder_for_seq(cmd, NULL);
344e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!pdu)
345e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return dr;
346e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
347e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if ((read_data_done + pdu->length) == cmd->data_length) {
348e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
349e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
350e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			pdu->flags |= ISCSI_FLAG_DATA_ACK;
351e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
352e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		next_burst_len = 0;
353e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
354e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) <
355e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		     conn->sess->sess_ops->MaxBurstLength)
356e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			next_burst_len += pdu->length;
357e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		else {
358e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			pdu->flags |= ISCSI_FLAG_CMD_FINAL;
359e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
360e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				pdu->flags |= ISCSI_FLAG_DATA_ACK;
361e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
362e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			next_burst_len = 0;
363e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
364e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
365e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
366e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
367e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
368e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->next_burst_len = next_burst_len;
369e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->read_data_done += pdu->length;
370e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
371e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->next_burst_len = next_burst_len;
372e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->read_data_done += pdu->length;
373e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
374e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
375e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->flags = pdu->flags;
376e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->length = pdu->length;
377e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->offset = pdu->offset;
378e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->data_sn = pdu->data_sn;
379e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
380e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
381e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
382e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete = DATAIN_COMPLETE_NORMAL;
383e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
384e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return dr;
385e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
386e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
387e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->runlength) {
388e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
389e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
390e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
391e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
392e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
393e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
394e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
395e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((dr->begrun + dr->runlength) == dr->data_sn) {
396e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
397e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
398e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
399e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
400e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
401e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
402e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
403e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return dr;
404e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
405e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
406e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger/*
407e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger *	For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=No.
408e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger */
409e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstatic struct iscsi_datain_req *iscsit_set_datain_values_no_and_no(
410e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_cmd *cmd,
411e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain *datain)
412e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
413e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	u32 read_data_done, read_data_left, seq_send_order;
414e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_conn *conn = cmd->conn;
415e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain_req *dr;
416e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_pdu *pdu;
417e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_seq *seq = NULL;
418e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
419e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	dr = iscsit_get_datain_req(cmd);
420e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr)
421e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
422e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
423e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (dr->recovery && dr->generate_recovery_values) {
424e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (iscsit_create_recovery_datain_values_datasequenceinorder_no(
425e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger					cmd, dr) < 0)
426e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			return NULL;
427e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
428e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->generate_recovery_values = 0;
429e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
430e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
431e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_done = (!dr->recovery) ?
432e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->read_data_done : dr->read_data_done;
433e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	seq_send_order = (!dr->recovery) ?
434e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			cmd->seq_send_order : dr->seq_send_order;
435e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
436e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	read_data_left = (cmd->data_length - read_data_done);
437e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!read_data_left) {
438e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pr_err("ITT: 0x%08x read_data_left is zero!\n",
439e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				cmd->init_task_tag);
440e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
441e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
442e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
443e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order);
444e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!seq)
445e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
446e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
447e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	seq->sent = 1;
448e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
449e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery && !seq->next_burst_len)
450e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq->first_datasn = cmd->data_sn;
451e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
452e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	pdu = iscsit_get_pdu_holder_for_seq(cmd, seq);
453e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!pdu)
454e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return NULL;
455e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
456e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (seq->pdu_send_order == seq->pdu_count) {
457e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pdu->flags |= ISCSI_FLAG_CMD_FINAL;
458e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
459e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			pdu->flags |= ISCSI_FLAG_DATA_ACK;
460e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
461e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq->next_burst_len = 0;
462e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq_send_order++;
463e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else
464e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		seq->next_burst_len += pdu->length;
465e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
466e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if ((read_data_done + pdu->length) == cmd->data_length)
467e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		pdu->flags |= ISCSI_FLAG_DATA_STATUS;
468e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
469e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
470e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
471e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->seq_send_order = seq_send_order;
472e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		cmd->read_data_done += pdu->length;
473e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
474e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->seq_send_order = seq_send_order;
475e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		dr->read_data_done += pdu->length;
476e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
477e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
478e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->flags = pdu->flags;
479e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->length = pdu->length;
480e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->offset = pdu->offset;
481e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	datain->data_sn = pdu->data_sn;
482e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
483e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->recovery) {
484e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_CMD_FINAL)
485e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			seq->last_datasn = datain->data_sn;
486e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS)
487e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete = DATAIN_COMPLETE_NORMAL;
488e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
489e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return dr;
490e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
491e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
492e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (!dr->runlength) {
493e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
494e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
495e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
496e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
497e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
498e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
499e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	} else {
500e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		if ((dr->begrun + dr->runlength) == dr->data_sn) {
501e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			dr->dr_complete =
502e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger			    (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
503e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
504e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger				DATAIN_COMPLETE_CONNECTION_RECOVERY;
505e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		}
506e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	}
507e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
508e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return dr;
509e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
510e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
511e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellingerstruct iscsi_datain_req *iscsit_get_datain_values(
512e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_cmd *cmd,
513e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_datain *datain)
514e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger{
515e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	struct iscsi_conn *conn = cmd->conn;
516e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
517e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	if (conn->sess->sess_ops->DataSequenceInOrder &&
518e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	    conn->sess->sess_ops->DataPDUInOrder)
519e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return iscsit_set_datain_values_yes_and_yes(cmd, datain);
520e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	else if (!conn->sess->sess_ops->DataSequenceInOrder &&
521e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		  conn->sess->sess_ops->DataPDUInOrder)
522e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return iscsit_set_datain_values_no_and_yes(cmd, datain);
523e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	else if (conn->sess->sess_ops->DataSequenceInOrder &&
524e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		 !conn->sess->sess_ops->DataPDUInOrder)
525e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return iscsit_set_datain_values_yes_and_no(cmd, datain);
526e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	else if (!conn->sess->sess_ops->DataSequenceInOrder &&
527e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		   !conn->sess->sess_ops->DataPDUInOrder)
528e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger		return iscsit_set_datain_values_no_and_no(cmd, datain);
529e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger
530e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger	return NULL;
531e48354ce078c079996f89d715dfa44814b4eba01Nicholas Bellinger}
532