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