提交 a188e7e9 编写于 作者: L Linus Torvalds

Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

Pull scsi target updates from Nicholas Bellinger:
 "Things have been calm for the most part with no new fabric drivers in
  flight for v3.7 (we're up to eight now !), so this update is primarily
  focused on addressing a few long-standing items within target-core and
  iscsi-target fabric code.

  The highlights include:

   - target: Simplify fabric sense data length handling (roland)
   - qla2xxx: Fix endianness of task management response code (roland)
   - target: fix truncation of mode data, support zero allocation length
     (paolo)
   - target: Properly support zero-length commands in normal processing
     path (paolo)
   - iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT
     PDU (ronnie + nab)
   - iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG
     demo-mode (ronnie + nab)
   - target/file: Re-enable optional fd_buffered_io=1 operation (nab +
     hch)
   - iscsi-target: Add MaxXmitDataSegmenthLength forr target ->
     initiator MDRSL declaration (nab)
   - target: Add target_submit_cmd_map_sgls for SGL fabric memory
     passthrough (nab + hch)
   - tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls (hch +
     nab)
   - tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls (nab
     + hch)

  The last series for adding a new target_submit_cmd_map_sgls() fabric
  caller (as requested by hch) that accepts pre-allocated SGL memory
  (using existing logic), along with converting tcm_loop + tcm_vhost has
  only been in -next for the last days, but has gotten enough review
  +testing and is clear enough a mechanical change that I think it's
  reasonable to merge for -rc1 code.

  Thanks again to everyone who contributed this round! Extra special
  thanks to Roland (PureStorage) for tracking down the qla2xxx target
  TMR response code endian issue, and to Paolo (Redhat) for resolving
  the long standing zero-length CDB issues within target-core between
  virtual and pSCSI backends."

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (44 commits)
  iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout values
  iscsit: proper endianess conversions
  iscsit: use the itt_t abstract type
  iscsit: add missing endianess conversion in iscsit_check_inaddr_any
  iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp
  iscsit: mark various functions static
  target/iscsi: precedence bug in iscsit_set_dataout_sequence_values()
  target/usb-gadget: strlen() doesn't count the terminator
  target/usb-gadget: remove duplicate initialization
  tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls
  target: Add control CDB READ payload zero work-around
  tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls
  target: Add target_submit_cmd_map_sgls for SGL fabric memory passthrough
  iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode
  iscsi-target: Change iscsi_target_seq_pdu_list.c to honor MaxXmitDataSegmentLength
  iscsi-target: Add MaxXmitDataSegmentLength connection recovery check
  iscsi-target: Convert incoming PDU payload checks to MaxXmitDataSegmentLength
  iscsi-target: Enable MaxXmitDataSegmentLength operation in login path
  iscsi-target: Add base MaxXmitDataSegmentLength code
  target/file: Re-enable optional fd_buffered_io=1 operation
  ...
......@@ -402,8 +402,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n"
buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n"
buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n"
buf += " .get_fabric_sense_len = " + fabric_mod_name + "_get_fabric_sense_len,\n"
buf += " .set_fabric_sense_len = " + fabric_mod_name + "_set_fabric_sense_len,\n"
buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n"
buf += " /*\n"
buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
......@@ -906,20 +904,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
buf += "}\n\n"
bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
if re.search('get_fabric_sense_len\)\(', fo):
buf += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void)\n"
buf += "{\n"
buf += " return 0;\n"
buf += "}\n\n"
bufi += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void);\n"
if re.search('set_fabric_sense_len\)\(', fo):
buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n"
buf += "{\n"
buf += " return 0;\n"
buf += "}\n\n"
bufi += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *, u32);\n"
if re.search('is_state_remove\)\(', fo):
buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
buf += "{\n"
......
......@@ -3564,16 +3564,6 @@ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd)
return srpt_get_cmd_state(ioctx);
}
static u16 srpt_set_fabric_sense_len(struct se_cmd *cmd, u32 sense_length)
{
return 0;
}
static u16 srpt_get_fabric_sense_len(void)
{
return 0;
}
/**
* srpt_parse_i_port_id() - Parse an initiator port ID.
* @name: ASCII representation of a 128-bit initiator port ID.
......@@ -3953,8 +3943,6 @@ static struct target_core_fabric_ops srpt_template = {
.queue_data_in = srpt_queue_response,
.queue_status = srpt_queue_status,
.queue_tm_rsp = srpt_queue_response,
.get_fabric_sense_len = srpt_get_fabric_sense_len,
.set_fabric_sense_len = srpt_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
......
......@@ -1403,7 +1403,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
ctio->u.status1.scsi_status =
__constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID);
ctio->u.status1.response_len = __constant_cpu_to_le16(8);
((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code);
ctio->u.status1.sense_data[0] = resp_code;
qla2x00_start_iocbs(ha, ha->req);
}
......
......@@ -735,17 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
static u16 tcm_qla2xxx_get_fabric_sense_len(void)
{
return 0;
}
static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd,
u32 sense_length)
{
return 0;
}
/* Local pointer to allocated TCM configfs fabric module */
struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
......@@ -1691,8 +1680,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = {
.queue_data_in = tcm_qla2xxx_queue_data_in,
.queue_status = tcm_qla2xxx_queue_status,
.queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp,
.get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len,
.set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
......@@ -1740,8 +1727,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
.queue_data_in = tcm_qla2xxx_queue_data_in,
.queue_status = tcm_qla2xxx_queue_status,
.queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp,
.get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len,
.set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
......
此差异已折叠。
......@@ -38,4 +38,9 @@ extern struct kmem_cache *lio_cmd_cache;
extern struct kmem_cache *lio_qr_cache;
extern struct kmem_cache *lio_r2t_cache;
extern struct idr sess_idr;
extern struct mutex auth_id_lock;
extern spinlock_t sess_idr_lock;
#endif /*** ISCSI_TARGET_H ***/
......@@ -135,7 +135,7 @@ static struct configfs_attribute *lio_target_portal_attrs[] = {
#define MAX_PORTAL_LEN 256
struct se_tpg_np *lio_target_call_addnptotpg(
static struct se_tpg_np *lio_target_call_addnptotpg(
struct se_portal_group *se_tpg,
struct config_group *group,
const char *name)
......@@ -1034,6 +1034,9 @@ TPG_PARAM_ATTR(ImmediateData, S_IRUGO | S_IWUSR);
DEF_TPG_PARAM(MaxRecvDataSegmentLength);
TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR);
DEF_TPG_PARAM(MaxXmitDataSegmentLength);
TPG_PARAM_ATTR(MaxXmitDataSegmentLength, S_IRUGO | S_IWUSR);
DEF_TPG_PARAM(MaxBurstLength);
TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR);
......@@ -1079,6 +1082,7 @@ static struct configfs_attribute *lio_target_tpg_param_attrs[] = {
&iscsi_tpg_param_InitialR2T.attr,
&iscsi_tpg_param_ImmediateData.attr,
&iscsi_tpg_param_MaxRecvDataSegmentLength.attr,
&iscsi_tpg_param_MaxXmitDataSegmentLength.attr,
&iscsi_tpg_param_MaxBurstLength.attr,
&iscsi_tpg_param_FirstBurstLength.attr,
&iscsi_tpg_param_DefaultTime2Wait.attr,
......@@ -1166,7 +1170,7 @@ static struct configfs_attribute *lio_target_tpg_attrs[] = {
/* Start items for lio_target_tiqn_cit */
struct se_portal_group *lio_target_tiqn_addtpg(
static struct se_portal_group *lio_target_tiqn_addtpg(
struct se_wwn *wwn,
struct config_group *group,
const char *name)
......@@ -1216,7 +1220,7 @@ struct se_portal_group *lio_target_tiqn_addtpg(
return NULL;
}
void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
{
struct iscsi_portal_group *tpg;
struct iscsi_tiqn *tiqn;
......@@ -1248,7 +1252,7 @@ static struct configfs_attribute *lio_target_wwn_attrs[] = {
NULL,
};
struct se_wwn *lio_target_call_coreaddtiqn(
static struct se_wwn *lio_target_call_coreaddtiqn(
struct target_fabric_configfs *tf,
struct config_group *group,
const char *name)
......@@ -1296,7 +1300,7 @@ struct se_wwn *lio_target_call_coreaddtiqn(
return &tiqn->tiqn_wwn;
}
void lio_target_call_coredeltiqn(
static void lio_target_call_coredeltiqn(
struct se_wwn *wwn)
{
struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
......@@ -1471,7 +1475,8 @@ static u32 iscsi_get_task_tag(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
return cmd->init_task_tag;
/* only used for printks or comparism with ->ref_task_tag */
return (__force u32)cmd->init_task_tag;
}
static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
......@@ -1542,29 +1547,6 @@ static int lio_queue_status(struct se_cmd *se_cmd)
return 0;
}
static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
{
unsigned char *buffer = se_cmd->sense_buffer;
/*
* From RFC-3720 10.4.7. Data Segment - Sense and Response Data Segment
* 16-bit SenseLength.
*/
buffer[0] = ((sense_length >> 8) & 0xff);
buffer[1] = (sense_length & 0xff);
/*
* Return two byte offset into allocated sense_buffer.
*/
return 2;
}
static u16 lio_get_fabric_sense_len(void)
{
/*
* Return two byte offset into allocated sense_buffer.
*/
return 2;
}
static int lio_queue_tm_rsp(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
......@@ -1748,8 +1730,6 @@ int iscsi_target_register_configfs(void)
fabric->tf_ops.queue_data_in = &lio_queue_data_in;
fabric->tf_ops.queue_status = &lio_queue_status;
fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp;
fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len;
fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len;
/*
* Setup function pointers for generic logic in target_core_fabric_configfs.c
*/
......
......@@ -25,10 +25,10 @@
#define NA_DATAOUT_TIMEOUT_RETRIES 5
#define NA_DATAOUT_TIMEOUT_RETRIES_MAX 15
#define NA_DATAOUT_TIMEOUT_RETRIES_MIN 1
#define NA_NOPIN_TIMEOUT 5
#define NA_NOPIN_TIMEOUT 15
#define NA_NOPIN_TIMEOUT_MAX 60
#define NA_NOPIN_TIMEOUT_MIN 3
#define NA_NOPIN_RESPONSE_TIMEOUT 5
#define NA_NOPIN_RESPONSE_TIMEOUT 30
#define NA_NOPIN_RESPONSE_TIMEOUT_MAX 60
#define NA_NOPIN_RESPONSE_TIMEOUT_MIN 3
#define NA_RANDOM_DATAIN_PDU_OFFSETS 0
......@@ -239,6 +239,7 @@ struct iscsi_conn_ops {
u8 HeaderDigest; /* [0,1] == [None,CRC32C] */
u8 DataDigest; /* [0,1] == [None,CRC32C] */
u32 MaxRecvDataSegmentLength; /* [512..2**24-1] */
u32 MaxXmitDataSegmentLength; /* [512..2**24-1] */
u8 OFMarker; /* [0,1] == [No,Yes] */
u8 IFMarker; /* [0,1] == [No,Yes] */
u32 OFMarkInt; /* [1..65535] */
......@@ -360,7 +361,7 @@ struct iscsi_cmd {
/* Command flags */
enum cmd_flags_table cmd_flags;
/* Initiator Task Tag assigned from Initiator */
u32 init_task_tag;
itt_t init_task_tag;
/* Target Transfer Tag assigned from Target */
u32 targ_xfer_tag;
/* CmdSN assigned from Initiator */
......@@ -478,7 +479,6 @@ struct iscsi_cmd {
struct iscsi_tmr_req {
bool task_reassign:1;
u32 ref_cmd_sn;
u32 exp_data_sn;
struct iscsi_cmd *ref_cmd;
struct iscsi_conn_recovery *conn_recovery;
......@@ -505,7 +505,7 @@ struct iscsi_conn {
u32 auth_id;
u32 conn_flags;
/* Used for iscsi_tx_login_rsp() */
u32 login_itt;
itt_t login_itt;
u32 exp_statsn;
/* Per connection status sequence number */
u32 stat_sn;
......@@ -578,6 +578,7 @@ struct iscsi_conn_recovery {
u16 cid;
u32 cmd_count;
u32 maxrecvdatasegmentlength;
u32 maxxmitdatasegmentlength;
int ready_for_reallegiance;
struct list_head conn_recovery_cmd_list;
spinlock_t conn_recovery_cmd_lock;
......@@ -597,7 +598,7 @@ struct iscsi_session {
/* state session is currently in */
u32 session_state;
/* session wide counter: initiator assigned task tag */
u32 init_task_tag;
itt_t init_task_tag;
/* session wide counter: target assigned task tag */
u32 targ_xfer_tag;
u32 cmdsn_window;
......@@ -663,7 +664,7 @@ struct iscsi_login {
u8 version_max;
char isid[6];
u32 cmd_sn;
u32 init_task_tag;
itt_t init_task_tag;
u32 initial_exp_statsn;
u32 rsp_length;
u16 cid;
......
......@@ -48,9 +48,9 @@ void iscsit_set_dataout_sequence_values(
if (cmd->unsolicited_data) {
cmd->seq_start_offset = cmd->write_data_done;
cmd->seq_end_offset = (cmd->write_data_done +
(cmd->se_cmd.data_length >
conn->sess->sess_ops->FirstBurstLength) ?
conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length);
((cmd->se_cmd.data_length >
conn->sess->sess_ops->FirstBurstLength) ?
conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length));
return;
}
......@@ -95,14 +95,15 @@ static int iscsit_dataout_within_command_recovery_check(
*/
if (conn->sess->sess_ops->DataSequenceInOrder) {
if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
(cmd->write_data_done != hdr->offset))
cmd->write_data_done != be32_to_cpu(hdr->offset))
goto dump;
cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
} else {
struct iscsi_seq *seq;
seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
payload_length);
if (!seq)
return DATAOUT_CANNOT_RECOVER;
/*
......@@ -111,15 +112,15 @@ static int iscsit_dataout_within_command_recovery_check(
cmd->seq_ptr = seq;
if (conn->sess->sess_ops->DataPDUInOrder) {
if ((seq->status ==
DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
((seq->offset != hdr->offset) ||
(seq->data_sn != hdr->datasn)))
if (seq->status ==
DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
(seq->offset != be32_to_cpu(hdr->offset) ||
seq->data_sn != be32_to_cpu(hdr->datasn)))
goto dump;
} else {
if ((seq->status ==
DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
(seq->data_sn != hdr->datasn))
if (seq->status ==
DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
seq->data_sn != be32_to_cpu(hdr->datasn))
goto dump;
}
......@@ -148,12 +149,12 @@ static int iscsit_dataout_check_unsolicited_sequence(
u32 payload_length = ntoh24(hdr->dlength);
if ((hdr->offset < cmd->seq_start_offset) ||
((hdr->offset + payload_length) > cmd->seq_end_offset)) {
if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
pr_err("Command ITT: 0x%08x with Offset: %u,"
" Length: %u outside of Unsolicited Sequence %u:%u while"
" DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
hdr->offset, payload_length, cmd->seq_start_offset,
be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
cmd->seq_end_offset);
return DATAOUT_CANNOT_RECOVER;
}
......@@ -236,12 +237,12 @@ static int iscsit_dataout_check_sequence(
* fullfilling an Recovery R2T, it's best to just dump the
* payload here, instead of erroring out.
*/
if ((hdr->offset < cmd->seq_start_offset) ||
((hdr->offset + payload_length) > cmd->seq_end_offset)) {
if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
pr_err("Command ITT: 0x%08x with Offset: %u,"
" Length: %u outside of Sequence %u:%u while"
" DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
hdr->offset, payload_length, cmd->seq_start_offset,
be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
cmd->seq_end_offset);
if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
......@@ -251,7 +252,8 @@ static int iscsit_dataout_check_sequence(
next_burst_len = (cmd->next_burst_len + payload_length);
} else {
seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
payload_length);
if (!seq)
return DATAOUT_CANNOT_RECOVER;
/*
......@@ -366,16 +368,16 @@ static int iscsit_dataout_check_datasn(
data_sn = seq->data_sn;
}
if (hdr->datasn > data_sn) {
if (be32_to_cpu(hdr->datasn) > data_sn) {
pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
" higher than expected 0x%08x.\n", cmd->init_task_tag,
hdr->datasn, data_sn);
be32_to_cpu(hdr->datasn), data_sn);
recovery = 1;
goto recover;
} else if (hdr->datasn < data_sn) {
} else if (be32_to_cpu(hdr->datasn) < data_sn) {
pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
" lower than expected 0x%08x, discarding payload.\n",
cmd->init_task_tag, hdr->datasn, data_sn);
cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn);
dump = 1;
goto dump;
}
......@@ -415,26 +417,27 @@ static int iscsit_dataout_pre_datapduinorder_yes(
* error has occured and fail the connection.
*/
if (conn->sess->sess_ops->DataSequenceInOrder) {
if (hdr->offset != cmd->write_data_done) {
if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
pr_err("Command ITT: 0x%08x, received offset"
" %u different than expected %u.\n", cmd->init_task_tag,
hdr->offset, cmd->write_data_done);
be32_to_cpu(hdr->offset), cmd->write_data_done);
recovery = 1;
goto recover;
}
} else {
struct iscsi_seq *seq = cmd->seq_ptr;
if (hdr->offset > seq->offset) {
if (be32_to_cpu(hdr->offset) > seq->offset) {
pr_err("Command ITT: 0x%08x, received offset"
" %u greater than expected %u.\n", cmd->init_task_tag,
hdr->offset, seq->offset);
be32_to_cpu(hdr->offset), seq->offset);
recovery = 1;
goto recover;
} else if (hdr->offset < seq->offset) {
} else if (be32_to_cpu(hdr->offset) < seq->offset) {
pr_err("Command ITT: 0x%08x, received offset"
" %u less than expected %u, discarding payload.\n",
cmd->init_task_tag, hdr->offset, seq->offset);
cmd->init_task_tag, be32_to_cpu(hdr->offset),
seq->offset);
dump = 1;
goto dump;
}
......@@ -453,7 +456,7 @@ static int iscsit_dataout_pre_datapduinorder_yes(
return DATAOUT_CANNOT_RECOVER;
return (recovery) ? iscsit_recover_dataout_sequence(cmd,
hdr->offset, payload_length) :
be32_to_cpu(hdr->offset), payload_length) :
(dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
}
......@@ -465,7 +468,8 @@ static int iscsit_dataout_pre_datapduinorder_no(
struct iscsi_data *hdr = (struct iscsi_data *) buf;
u32 payload_length = ntoh24(hdr->dlength);
pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length);
pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset),
payload_length);
if (!pdu)
return DATAOUT_CANNOT_RECOVER;
......@@ -479,7 +483,7 @@ static int iscsit_dataout_pre_datapduinorder_no(
case ISCSI_PDU_RECEIVED_OK:
pr_err("Command ITT: 0x%08x received already gotten"
" Offset: %u, Length: %u\n", cmd->init_task_tag,
hdr->offset, payload_length);
be32_to_cpu(hdr->offset), payload_length);
return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
default:
return DATAOUT_CANNOT_RECOVER;
......@@ -553,7 +557,7 @@ static int iscsit_dataout_post_crc_passed(
if (cmd->unsolicited_data) {
if ((cmd->first_burst_len + payload_length) ==
conn->sess->sess_ops->FirstBurstLength) {
if (iscsit_dataout_update_r2t(cmd, hdr->offset,
if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset),
payload_length) < 0)
return DATAOUT_CANNOT_RECOVER;
send_r2t = 1;
......@@ -561,7 +565,8 @@ static int iscsit_dataout_post_crc_passed(
if (!conn->sess->sess_ops->DataPDUInOrder) {
ret = iscsit_dataout_update_datapduinorder_no(cmd,
hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL));
be32_to_cpu(hdr->datasn),
(hdr->flags & ISCSI_FLAG_CMD_FINAL));
if (ret == DATAOUT_CANNOT_RECOVER)
return ret;
}
......@@ -586,7 +591,8 @@ static int iscsit_dataout_post_crc_passed(
if (conn->sess->sess_ops->DataSequenceInOrder) {
if ((cmd->next_burst_len + payload_length) ==
conn->sess->sess_ops->MaxBurstLength) {
if (iscsit_dataout_update_r2t(cmd, hdr->offset,
if (iscsit_dataout_update_r2t(cmd,
be32_to_cpu(hdr->offset),
payload_length) < 0)
return DATAOUT_CANNOT_RECOVER;
send_r2t = 1;
......@@ -594,7 +600,7 @@ static int iscsit_dataout_post_crc_passed(
if (!conn->sess->sess_ops->DataPDUInOrder) {
ret = iscsit_dataout_update_datapduinorder_no(
cmd, hdr->datasn,
cmd, be32_to_cpu(hdr->datasn),
(hdr->flags & ISCSI_FLAG_CMD_FINAL));
if (ret == DATAOUT_CANNOT_RECOVER)
return ret;
......@@ -610,7 +616,8 @@ static int iscsit_dataout_post_crc_passed(
if ((seq->next_burst_len + payload_length) ==
seq->xfer_len) {
if (iscsit_dataout_update_r2t(cmd, hdr->offset,
if (iscsit_dataout_update_r2t(cmd,
be32_to_cpu(hdr->offset),
payload_length) < 0)
return DATAOUT_CANNOT_RECOVER;
send_r2t = 1;
......@@ -618,7 +625,7 @@ static int iscsit_dataout_post_crc_passed(
if (!conn->sess->sess_ops->DataPDUInOrder) {
ret = iscsit_dataout_update_datapduinorder_no(
cmd, hdr->datasn,
cmd, be32_to_cpu(hdr->datasn),
(hdr->flags & ISCSI_FLAG_CMD_FINAL));
if (ret == DATAOUT_CANNOT_RECOVER)
return ret;
......@@ -678,14 +685,15 @@ static int iscsit_dataout_post_crc_failed(
}
recover:
return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length);
return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset),
payload_length);
}
/*
* Called from iscsit_handle_data_out() before DataOUT Payload is received
* and CRC computed.
*/
extern int iscsit_check_pre_dataout(
int iscsit_check_pre_dataout(
struct iscsi_cmd *cmd,
unsigned char *buf)
{
......@@ -789,7 +797,7 @@ static void iscsit_handle_time2retain_timeout(unsigned long data)
target_put_session(sess->se_sess);
}
extern void iscsit_start_time2retain_handler(struct iscsi_session *sess)
void iscsit_start_time2retain_handler(struct iscsi_session *sess)
{
int tpg_active;
/*
......@@ -822,7 +830,7 @@ extern void iscsit_start_time2retain_handler(struct iscsi_session *sess)
/*
* Called with spin_lock_bh(&struct se_portal_group->session_lock) held
*/
extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
{
struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
......@@ -926,7 +934,7 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn)
}
}
extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
{
spin_lock_bh(&conn->state_lock);
if (atomic_read(&conn->connection_exit)) {
......
......@@ -466,7 +466,7 @@ static int iscsit_handle_recovery_datain(
int iscsit_handle_recovery_datain_or_r2t(
struct iscsi_conn *conn,
unsigned char *buf,
u32 init_task_tag,
itt_t init_task_tag,
u32 targ_xfer_tag,
u32 begrun,
u32 runlength)
......@@ -498,7 +498,7 @@ int iscsit_handle_recovery_datain_or_r2t(
/* #warning FIXME: Status SNACK needs to be dependent on OPCODE!!! */
int iscsit_handle_status_snack(
struct iscsi_conn *conn,
u32 init_task_tag,
itt_t init_task_tag,
u32 targ_xfer_tag,
u32 begrun,
u32 runlength)
......
......@@ -7,8 +7,8 @@ extern int iscsit_create_recovery_datain_values_datasequenceinorder_yes(
extern int iscsit_create_recovery_datain_values_datasequenceinorder_no(
struct iscsi_cmd *, struct iscsi_datain_req *);
extern int iscsit_handle_recovery_datain_or_r2t(struct iscsi_conn *, unsigned char *,
u32, u32, u32, u32);
extern int iscsit_handle_status_snack(struct iscsi_conn *, u32, u32,
itt_t, u32, u32, u32);
extern int iscsit_handle_status_snack(struct iscsi_conn *, itt_t, u32,
u32, u32);
extern int iscsit_handle_data_ack(struct iscsi_conn *, u32, u32, u32);
extern int iscsit_dataout_datapduinorder_no_fbit(struct iscsi_cmd *, struct iscsi_pdu *);
......
......@@ -36,7 +36,7 @@
*/
void iscsit_create_conn_recovery_datain_values(
struct iscsi_cmd *cmd,
u32 exp_data_sn)
__be32 exp_data_sn)
{
u32 data_sn = 0;
struct iscsi_conn *conn = cmd->conn;
......@@ -44,7 +44,7 @@ void iscsit_create_conn_recovery_datain_values(
cmd->next_burst_len = 0;
cmd->read_data_done = 0;
while (exp_data_sn > data_sn) {
while (be32_to_cpu(exp_data_sn) > data_sn) {
if ((cmd->next_burst_len +
conn->conn_ops->MaxRecvDataSegmentLength) <
conn->sess->sess_ops->MaxBurstLength) {
......@@ -193,15 +193,13 @@ int iscsit_remove_active_connection_recovery_entry(
return 0;
}
int iscsit_remove_inactive_connection_recovery_entry(
static void iscsit_remove_inactive_connection_recovery_entry(
struct iscsi_conn_recovery *cr,
struct iscsi_session *sess)
{
spin_lock(&sess->cr_i_lock);
list_del(&cr->cr_list);
spin_unlock(&sess->cr_i_lock);
return 0;
}
/*
......@@ -421,6 +419,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
cr->cid = conn->cid;
cr->cmd_count = cmd_count;
cr->maxrecvdatasegmentlength = conn->conn_ops->MaxRecvDataSegmentLength;
cr->maxxmitdatasegmentlength = conn->conn_ops->MaxXmitDataSegmentLength;
cr->sess = conn->sess;
iscsit_attach_inactive_connection_recovery_entry(conn->sess, cr);
......
#ifndef ISCSI_TARGET_ERL2_H
#define ISCSI_TARGET_ERL2_H
extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, u32);
extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, __be32);
extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *);
extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry(
struct iscsi_session *, u16);
......
......@@ -39,10 +39,6 @@
#include "iscsi_target.h"
#include "iscsi_target_parameters.h"
extern struct idr sess_idr;
extern struct mutex auth_id_lock;
extern spinlock_t sess_idr_lock;
static int iscsi_login_init_conn(struct iscsi_conn *conn)
{
INIT_LIST_HEAD(&conn->conn_list);
......@@ -196,10 +192,10 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
static void iscsi_login_set_conn_values(
struct iscsi_session *sess,
struct iscsi_conn *conn,
u16 cid)
__be16 cid)
{
conn->sess = sess;
conn->cid = cid;
conn->cid = be16_to_cpu(cid);
/*
* Generate a random Status sequence number (statsn) for the new
* iSCSI connection.
......@@ -234,7 +230,7 @@ static int iscsi_login_zero_tsih_s1(
iscsi_login_set_conn_values(sess, conn, pdu->cid);
sess->init_task_tag = pdu->itt;
memcpy(&sess->isid, pdu->isid, 6);
sess->exp_cmd_sn = pdu->cmdsn;
sess->exp_cmd_sn = be32_to_cpu(pdu->cmdsn);
INIT_LIST_HEAD(&sess->sess_conn_list);
INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list);
INIT_LIST_HEAD(&sess->cr_active_list);
......@@ -275,7 +271,7 @@ static int iscsi_login_zero_tsih_s1(
* The FFP CmdSN window values will be allocated from the TPG's
* Initiator Node's ACL once the login has been successfully completed.
*/
sess->max_cmd_sn = pdu->cmdsn;
sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn);
sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
if (!sess->sess_ops) {
......@@ -453,7 +449,7 @@ static int iscsi_login_non_zero_tsih_s2(
(sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED))
continue;
if (!memcmp(sess_p->isid, pdu->isid, 6) &&
(sess_p->tsih == pdu->tsih)) {
(sess_p->tsih == be16_to_cpu(pdu->tsih))) {
iscsit_inc_session_usage_count(sess_p);
iscsit_stop_time2retain_timer(sess_p);
sess = sess_p;
......@@ -955,11 +951,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
}
pdu = (struct iscsi_login_req *) buffer;
pdu->cid = be16_to_cpu(pdu->cid);
pdu->tsih = be16_to_cpu(pdu->tsih);
pdu->itt = be32_to_cpu(pdu->itt);
pdu->cmdsn = be32_to_cpu(pdu->cmdsn);
pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn);
/*
* Used by iscsit_tx_login_rsp() for Login Resonses PDUs
* when Status-Class != 0.
......
......@@ -44,7 +44,7 @@ void convert_null_to_semi(char *buf, int len)
buf[i] = ';';
}
int strlen_semi(char *buf)
static int strlen_semi(char *buf)
{
int i = 0;
......@@ -339,14 +339,14 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
hton24(login_rsp->dlength, login->rsp_length);
memcpy(login_rsp->isid, login->isid, 6);
login_rsp->tsih = cpu_to_be16(login->tsih);
login_rsp->itt = cpu_to_be32(login->init_task_tag);
login_rsp->itt = login->init_task_tag;
login_rsp->statsn = cpu_to_be32(conn->stat_sn++);
login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
" ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
" %u\n", login_rsp->flags, ntohl(login_rsp->itt),
" %u\n", login_rsp->flags, (__force u32)login_rsp->itt,
ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn),
ntohl(login_rsp->statsn), login->rsp_length);
......@@ -360,12 +360,9 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
return -1;
login->rsp_length = 0;
login_rsp->tsih = be16_to_cpu(login_rsp->tsih);
login_rsp->itt = be32_to_cpu(login_rsp->itt);
login_rsp->statsn = be32_to_cpu(login_rsp->statsn);
mutex_lock(&sess->cmdsn_mutex);
login_rsp->exp_cmdsn = be32_to_cpu(sess->exp_cmd_sn);
login_rsp->max_cmdsn = be32_to_cpu(sess->max_cmd_sn);
login_rsp->exp_cmdsn = cpu_to_be32(sess->exp_cmd_sn);
login_rsp->max_cmdsn = cpu_to_be32(sess->max_cmd_sn);
mutex_unlock(&sess->cmdsn_mutex);
return 0;
......@@ -381,11 +378,6 @@ static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_log
login_req = (struct iscsi_login_req *) login->req;
payload_length = ntoh24(login_req->dlength);
login_req->tsih = be16_to_cpu(login_req->tsih);
login_req->itt = be32_to_cpu(login_req->itt);
login_req->cid = be16_to_cpu(login_req->cid);
login_req->cmdsn = be32_to_cpu(login_req->cmdsn);
login_req->exp_statsn = be32_to_cpu(login_req->exp_statsn);
pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
" CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n",
......@@ -550,7 +542,7 @@ static int iscsi_target_handle_csg_zero(
SENDER_INITIATOR|SENDER_RECEIVER,
login->req_buf,
payload_length,
conn->param_list);
conn);
if (ret < 0)
return -1;
......@@ -627,7 +619,7 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log
SENDER_INITIATOR|SENDER_RECEIVER,
login->req_buf,
payload_length,
conn->param_list);
conn);
if (ret < 0)
return -1;
......@@ -762,11 +754,11 @@ static int iscsi_target_locate_portal(
login->version_min = login_req->min_version;
login->version_max = login_req->max_version;
memcpy(login->isid, login_req->isid, 6);
login->cmd_sn = login_req->cmdsn;
login->cmd_sn = be32_to_cpu(login_req->cmdsn);
login->init_task_tag = login_req->itt;
login->initial_exp_statsn = login_req->exp_statsn;
login->cid = login_req->cid;
login->tsih = login_req->tsih;
login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn);
login->cid = be16_to_cpu(login_req->cid);
login->tsih = be16_to_cpu(login_req->tsih);
if (iscsi_target_get_initial_payload(conn, login) < 0)
return -1;
......@@ -1000,7 +992,6 @@ struct iscsi_login *iscsi_target_init_negotiation(
* Locates Target Portal from NP -> Target IQN
*/
if (iscsi_target_locate_portal(np, conn, login) < 0) {
pr_err("iSCSI Login negotiation failed.\n");
goto out;
}
......
......@@ -334,6 +334,13 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
if (!param)
goto out;
param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
INITIAL_MAXXMITDATASEGMENTLENGTH,
PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
TYPERANGE_512_TO_16777215, USE_ALL);
if (!param)
goto out;
param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
INITIAL_MAXRECVDATASEGMENTLENGTH,
PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
......@@ -467,6 +474,8 @@ int iscsi_set_keys_to_negotiate(
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
continue;
} else if (!strcmp(param->name, MAXBURSTLENGTH)) {
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
......@@ -1056,7 +1065,8 @@ static char *iscsi_check_valuelist_for_support(
return proposer_values;
}
static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
struct iscsi_conn *conn)
{
u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
char *negoitated_value = NULL;
......@@ -1131,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
return -1;
}
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
SET_PSTATE_REPLY_OPTIONAL(param);
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
struct iscsi_param *param_mxdsl;
unsigned long long tmp;
int rc;
rc = strict_strtoull(param->value, 0, &tmp);
if (rc < 0)
return -1;
conn->conn_ops->MaxRecvDataSegmentLength = tmp;
pr_debug("Saving op->MaxRecvDataSegmentLength from"
" original initiator received value: %u\n",
conn->conn_ops->MaxRecvDataSegmentLength);
param_mxdsl = iscsi_find_param_from_key(
MAXXMITDATASEGMENTLENGTH,
conn->param_list);
if (!param_mxdsl)
return -1;
rc = iscsi_update_param_value(param,
param_mxdsl->value);
if (rc < 0)
return -1;
pr_debug("Updated %s to target MXDSL value: %s\n",
param->name, param->value);
}
} else if (IS_TYPE_NUMBER_RANGE(param)) {
negoitated_value = iscsi_get_value_from_number_range(
param, value);
......@@ -1526,8 +1563,9 @@ int iscsi_decode_text_input(
u8 sender,
char *textbuf,
u32 length,
struct iscsi_param_list *param_list)
struct iscsi_conn *conn)
{
struct iscsi_param_list *param_list = conn->param_list;
char *tmpbuf, *start = NULL, *end = NULL;
tmpbuf = kzalloc(length + 1, GFP_KERNEL);
......@@ -1585,7 +1623,7 @@ int iscsi_decode_text_input(
}
SET_PSTATE_RESPONSE_GOT(param);
} else {
if (iscsi_check_acceptor_state(param, value) < 0) {
if (iscsi_check_acceptor_state(param, value, conn) < 0) {
kfree(tmpbuf);
return -1;
}
......@@ -1720,6 +1758,18 @@ void iscsi_set_connection_parameters(
pr_debug("---------------------------------------------------"
"---------------\n");
list_for_each_entry(param, &param_list->param_list, p_list) {
/*
* Special case to set MAXXMITDATASEGMENTLENGTH from the
* target requested MaxRecvDataSegmentLength, even though
* this key is not sent over the wire.
*/
if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
ops->MaxXmitDataSegmentLength =
simple_strtoul(param->value, &tmpptr, 0);
pr_debug("MaxXmitDataSegmentLength: %s\n",
param->value);
}
if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
continue;
if (!strcmp(param->name, AUTHMETHOD)) {
......@@ -1734,10 +1784,13 @@ void iscsi_set_connection_parameters(
pr_debug("DataDigest: %s\n",
param->value);
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
ops->MaxRecvDataSegmentLength =
simple_strtoul(param->value, &tmpptr, 0);
pr_debug("MaxRecvDataSegmentLength: %s\n",
param->value);
/*
* At this point iscsi_check_acceptor_state() will have
* set ops->MaxRecvDataSegmentLength from the original
* initiator provided value.
*/
pr_debug("MaxRecvDataSegmentLength: %u\n",
ops->MaxRecvDataSegmentLength);
} else if (!strcmp(param->name, OFMARKER)) {
ops->OFMarker = !strcmp(param->value, YES);
pr_debug("OFMarker: %s\n",
......
......@@ -36,7 +36,7 @@ extern void iscsi_release_param_list(struct iscsi_param_list *);
extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *);
extern int iscsi_extract_key_value(char *, char **, char **);
extern int iscsi_update_param_value(struct iscsi_param *, char *);
extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *);
extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
struct iscsi_param_list *);
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
......@@ -70,6 +70,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
#define INITIALR2T "InitialR2T"
#define IMMEDIATEDATA "ImmediateData"
#define MAXRECVDATASEGMENTLENGTH "MaxRecvDataSegmentLength"
#define MAXXMITDATASEGMENTLENGTH "MaxXmitDataSegmentLength"
#define MAXBURSTLENGTH "MaxBurstLength"
#define FIRSTBURSTLENGTH "FirstBurstLength"
#define DEFAULTTIME2WAIT "DefaultTime2Wait"
......@@ -113,6 +114,10 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
#define INITIAL_INITIALR2T YES
#define INITIAL_IMMEDIATEDATA YES
#define INITIAL_MAXRECVDATASEGMENTLENGTH "8192"
/*
* Match outgoing MXDSL default to incoming Open-iSCSI default
*/
#define INITIAL_MAXXMITDATASEGMENTLENGTH "262144"
#define INITIAL_MAXBURSTLENGTH "262144"
#define INITIAL_FIRSTBURSTLENGTH "65536"
#define INITIAL_DEFAULTTIME2WAIT "2"
......
......@@ -219,8 +219,14 @@ static void iscsit_determine_counts_for_list(
int check_immediate = 0;
u32 burstlength = 0, offset = 0;
u32 unsolicited_data_length = 0;
u32 mdsl;
struct iscsi_conn *conn = cmd->conn;
if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
else
mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
if ((bl->type == PDULIST_IMMEDIATE) ||
(bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
check_immediate = 1;
......@@ -243,14 +249,13 @@ static void iscsit_determine_counts_for_list(
continue;
}
if (unsolicited_data_length > 0) {
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
>= cmd->se_cmd.data_length) {
if ((offset + mdsl) >= cmd->se_cmd.data_length) {
unsolicited_data_length -=
(cmd->se_cmd.data_length - offset);
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
if ((offset + mdsl)
>= conn->sess->sess_ops->FirstBurstLength) {
unsolicited_data_length -=
(conn->sess->sess_ops->FirstBurstLength -
......@@ -262,17 +267,15 @@ static void iscsit_determine_counts_for_list(
continue;
}
offset += conn->conn_ops->MaxRecvDataSegmentLength;
unsolicited_data_length -=
conn->conn_ops->MaxRecvDataSegmentLength;
offset += mdsl;
unsolicited_data_length -= mdsl;
continue;
}
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->se_cmd.data_length) {
if ((offset + mdsl) >= cmd->se_cmd.data_length) {
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
if ((burstlength + mdsl) >=
conn->sess->sess_ops->MaxBurstLength) {
offset += (conn->sess->sess_ops->MaxBurstLength -
burstlength);
......@@ -281,8 +284,8 @@ static void iscsit_determine_counts_for_list(
continue;
}
burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
offset += conn->conn_ops->MaxRecvDataSegmentLength;
burstlength += mdsl;
offset += mdsl;
}
}
......@@ -296,12 +299,17 @@ static int iscsit_do_build_pdu_and_seq_lists(
struct iscsi_build_list *bl)
{
int check_immediate = 0, datapduinorder, datasequenceinorder;
u32 burstlength = 0, offset = 0, i = 0;
u32 burstlength = 0, offset = 0, i = 0, mdsl;
u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0;
struct iscsi_conn *conn = cmd->conn;
struct iscsi_pdu *pdu = cmd->pdu_list;
struct iscsi_seq *seq = cmd->seq_list;
if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
else
mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
datapduinorder = conn->sess->sess_ops->DataPDUInOrder;
datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder;
......@@ -348,9 +356,7 @@ static int iscsit_do_build_pdu_and_seq_lists(
continue;
}
if (unsolicited_data_length > 0) {
if ((offset +
conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->se_cmd.data_length) {
if ((offset + mdsl) >= cmd->se_cmd.data_length) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
pdu[i].length =
......@@ -367,8 +373,7 @@ static int iscsit_do_build_pdu_and_seq_lists(
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((offset +
conn->conn_ops->MaxRecvDataSegmentLength) >=
if ((offset + mdsl) >=
conn->sess->sess_ops->FirstBurstLength) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
......@@ -396,17 +401,14 @@ static int iscsit_do_build_pdu_and_seq_lists(
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
pdu[i++].length =
conn->conn_ops->MaxRecvDataSegmentLength;
pdu[i++].length = mdsl;
}
burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
offset += conn->conn_ops->MaxRecvDataSegmentLength;
unsolicited_data_length -=
conn->conn_ops->MaxRecvDataSegmentLength;
burstlength += mdsl;
offset += mdsl;
unsolicited_data_length -= mdsl;
continue;
}
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->se_cmd.data_length) {
if ((offset + mdsl) >= cmd->se_cmd.data_length) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
pdu[i].length = (cmd->se_cmd.data_length - offset);
......@@ -420,7 +422,7 @@ static int iscsit_do_build_pdu_and_seq_lists(
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
if ((burstlength + mdsl) >=
conn->sess->sess_ops->MaxBurstLength) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
......@@ -445,11 +447,10 @@ static int iscsit_do_build_pdu_and_seq_lists(
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
pdu[i++].length =
conn->conn_ops->MaxRecvDataSegmentLength;
pdu[i++].length = mdsl;
}
burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
offset += conn->conn_ops->MaxRecvDataSegmentLength;
burstlength += mdsl;
offset += mdsl;
}
if (!datasequenceinorder) {
......
......@@ -50,21 +50,20 @@ u8 iscsit_tmr_abort_task(
if (!ref_cmd) {
pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
" %hu.\n", hdr->rtt, conn->cid);
return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) &&
(hdr->refcmdsn <= conn->sess->max_cmd_sn)) ?
return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn &&
be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ?
ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
}
if (ref_cmd->cmd_sn != hdr->refcmdsn) {
if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {
pr_err("RefCmdSN 0x%08x does not equal"
" task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
hdr->refcmdsn, ref_cmd->cmd_sn);
return ISCSI_TMF_RSP_REJECTED;
}
se_tmr->ref_task_tag = hdr->rtt;
se_tmr->ref_task_tag = (__force u32)hdr->rtt;
tmr_req->ref_cmd = ref_cmd;
tmr_req->ref_cmd_sn = hdr->refcmdsn;
tmr_req->exp_data_sn = hdr->exp_datasn;
tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn);
return ISCSI_TMF_RSP_COMPLETE;
}
......@@ -146,7 +145,7 @@ u8 iscsit_tmr_task_reassign(
}
/*
* Temporary check to prevent connection recovery for
* connections with a differing MaxRecvDataSegmentLength.
* connections with a differing Max*DataSegmentLength.
*/
if (cr->maxrecvdatasegmentlength !=
conn->conn_ops->MaxRecvDataSegmentLength) {
......@@ -155,6 +154,13 @@ u8 iscsit_tmr_task_reassign(
" TMR TASK_REASSIGN.\n");
return ISCSI_TMF_RSP_REJECTED;
}
if (cr->maxxmitdatasegmentlength !=
conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("Unable to perform connection recovery for"
" differing MaxXmitDataSegmentLength, rejecting"
" TMR TASK_REASSIGN.\n");
return ISCSI_TMF_RSP_REJECTED;
}
ref_lun = scsilun_to_int(&hdr->lun);
if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) {
......@@ -164,10 +170,9 @@ u8 iscsit_tmr_task_reassign(
return ISCSI_TMF_RSP_REJECTED;
}
se_tmr->ref_task_tag = hdr->rtt;
se_tmr->ref_task_tag = (__force u32)hdr->rtt;
tmr_req->ref_cmd = ref_cmd;
tmr_req->ref_cmd_sn = hdr->refcmdsn;
tmr_req->exp_data_sn = hdr->exp_datasn;
tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn);
tmr_req->conn_recovery = cr;
tmr_req->task_reassign = 1;
/*
......@@ -455,7 +460,7 @@ static int iscsit_task_reassign_complete(
* Right now the only one that its really needed for is
* connection recovery releated TASK_REASSIGN.
*/
extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
{
struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
......@@ -470,7 +475,7 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *con
/*
* Nothing to do here, but leave it for good measure. :-)
*/
int iscsit_task_reassign_prepare_read(
static int iscsit_task_reassign_prepare_read(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
......@@ -545,7 +550,7 @@ static void iscsit_task_reassign_prepare_unsolicited_dataout(
}
}
int iscsit_task_reassign_prepare_write(
static int iscsit_task_reassign_prepare_write(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
......
......@@ -677,6 +677,12 @@ int iscsit_ta_generate_node_acls(
pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
if (flag == 1 && a->cache_dynamic_acls == 0) {
pr_debug("Explicitly setting cache_dynamic_acls=1 when "
"generate_node_acls=1\n");
a->cache_dynamic_acls = 1;
}
return 0;
}
......@@ -716,6 +722,12 @@ int iscsit_ta_cache_dynamic_acls(
return -EINVAL;
}
if (a->generate_node_acls == 1 && flag == 0) {
pr_debug("Skipping cache_dynamic_acls=0 when"
" generate_node_acls=1\n");
return 0;
}
a->cache_dynamic_acls = flag;
pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
" ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
......
......@@ -40,7 +40,7 @@ static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts)
spin_unlock(&active_ts_lock);
}
extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
{
spin_lock(&inactive_ts_lock);
list_add_tail(&ts->ts_list, &inactive_ts_list);
......@@ -76,7 +76,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void)
return ts;
}
extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
int iscsi_allocate_thread_sets(u32 thread_pair_count)
{
int allocated_thread_pair_count = 0, i, thread_id;
struct iscsi_thread_set *ts = NULL;
......@@ -140,7 +140,7 @@ extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
return allocated_thread_pair_count;
}
extern void iscsi_deallocate_thread_sets(void)
void iscsi_deallocate_thread_sets(void)
{
u32 released_count = 0;
struct iscsi_thread_set *ts = NULL;
......
......@@ -5,7 +5,6 @@
* Defines for thread sets.
*/
extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *);
extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *);
extern int iscsi_allocate_thread_sets(u32);
extern void iscsi_deallocate_thread_sets(void);
extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *);
......
......@@ -274,14 +274,14 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm
int iscsit_sequence_cmd(
struct iscsi_conn *conn,
struct iscsi_cmd *cmd,
u32 cmdsn)
__be32 cmdsn)
{
int ret;
int cmdsn_ret;
mutex_lock(&conn->sess->cmdsn_mutex);
cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, cmdsn);
cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, be32_to_cpu(cmdsn));
switch (cmdsn_ret) {
case CMDSN_NORMAL_OPERATION:
ret = iscsit_execute_cmd(cmd, 0);
......@@ -289,7 +289,7 @@ int iscsit_sequence_cmd(
iscsit_execute_ooo_cmdsns(conn->sess);
break;
case CMDSN_HIGHER_THAN_EXP:
ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, cmdsn);
ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn));
break;
case CMDSN_LOWER_THAN_EXP:
cmd->i_state = ISTATE_REMOVE;
......@@ -351,7 +351,7 @@ int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf)
struct iscsi_cmd *iscsit_find_cmd_from_itt(
struct iscsi_conn *conn,
u32 init_task_tag)
itt_t init_task_tag)
{
struct iscsi_cmd *cmd;
......@@ -371,7 +371,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt(
struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
struct iscsi_conn *conn,
u32 init_task_tag,
itt_t init_task_tag,
u32 length)
{
struct iscsi_cmd *cmd;
......@@ -417,7 +417,7 @@ int iscsit_find_cmd_for_recovery(
struct iscsi_session *sess,
struct iscsi_cmd **cmd_ptr,
struct iscsi_conn_recovery **cr_ptr,
u32 init_task_tag)
itt_t init_task_tag)
{
struct iscsi_cmd *cmd = NULL;
struct iscsi_conn_recovery *cr;
......@@ -855,7 +855,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response)
cmd->iscsi_opcode = ISCSI_OP_NOOP_IN;
state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE :
ISTATE_SEND_NOPIN_NO_RESPONSE;
cmd->init_task_tag = 0xFFFFFFFF;
cmd->init_task_tag = RESERVED_ITT;
spin_lock_bh(&conn->sess->ttt_lock);
cmd->targ_xfer_tag = (want_response) ? conn->sess->targ_xfer_tag++ :
0xFFFFFFFF;
......@@ -1222,7 +1222,7 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta
hdr->opcode = ISCSI_OP_LOGIN_RSP;
hdr->status_class = status_class;
hdr->status_detail = status_detail;
hdr->itt = cpu_to_be32(conn->login_itt);
hdr->itt = conn->login_itt;
iov.iov_base = &iscsi_hdr;
iov.iov_len = ISCSI_HDR_LEN;
......
......@@ -12,14 +12,14 @@ extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn);
int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn);
extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *);
extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, u32);
extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t);
extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *,
u32, u32);
itt_t, u32);
extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32);
extern int iscsit_find_cmd_for_recovery(struct iscsi_session *, struct iscsi_cmd **,
struct iscsi_conn_recovery **, u32);
struct iscsi_conn_recovery **, itt_t);
extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *);
extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
......
......@@ -166,7 +166,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
struct tcm_loop_tpg *tl_tpg;
struct scatterlist *sgl_bidi = NULL;
u32 sgl_bidi_count = 0;
int ret;
int rc;
tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
......@@ -187,12 +187,6 @@ static void tcm_loop_submission_work(struct work_struct *work)
set_host_byte(sc, DID_ERROR);
goto out_done;
}
transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo,
tl_nexus->se_sess,
scsi_bufflen(sc), sc->sc_data_direction,
tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]);
if (scsi_bidi_cmnd(sc)) {
struct scsi_data_buffer *sdb = scsi_in(sc);
......@@ -201,56 +195,16 @@ static void tcm_loop_submission_work(struct work_struct *work)
se_cmd->se_cmd_flags |= SCF_BIDI;
}
if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) {
kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd,
&tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun,
scsi_bufflen(sc), tcm_loop_sam_attr(sc),
sc->sc_data_direction, 0,
scsi_sglist(sc), scsi_sg_count(sc),
sgl_bidi, sgl_bidi_count);
if (rc < 0) {
set_host_byte(sc, DID_NO_CONNECT);
goto out_done;
}
/*
* Because some userspace code via scsi-generic do not memset their
* associated read buffers, go ahead and do that here for type
* non-data CDBs. Also note that this is currently guaranteed to be a
* single SGL for this case by target core in
* target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer().
*/
if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
se_cmd->data_direction == DMA_FROM_DEVICE) {
struct scatterlist *sg = scsi_sglist(sc);
unsigned char *buf = kmap(sg_page(sg)) + sg->offset;
if (buf != NULL) {
memset(buf, 0, sg->length);
kunmap(sg_page(sg));
}
}
ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd);
if (ret == -ENOMEM) {
transport_send_check_condition_and_sense(se_cmd,
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
} else if (ret < 0) {
if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
tcm_loop_queue_status(se_cmd);
else
transport_send_check_condition_and_sense(se_cmd,
se_cmd->scsi_sense_reason, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
}
ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
if (ret) {
transport_send_check_condition_and_sense(se_cmd,
se_cmd->scsi_sense_reason, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
}
transport_handle_cdb_direct(se_cmd);
return;
out_done:
......@@ -846,16 +800,6 @@ static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
{
return 0;
}
static u16 tcm_loop_get_fabric_sense_len(void)
{
return 0;
}
static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
{
switch (tl_hba->tl_proto_id) {
......@@ -1373,8 +1317,6 @@ static int tcm_loop_register_configfs(void)
fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
fabric->tf_ops.queue_status = &tcm_loop_queue_status;
fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
/*
* Setup function pointers for generic logic in target_core_fabric_configfs.c
......
......@@ -660,8 +660,7 @@ static void session_reconnect_expired(struct sbp_session *sess)
spin_lock_bh(&sess->lock);
list_for_each_entry_safe(login, temp, &sess->login_list, link) {
login->sess = NULL;
list_del(&login->link);
list_add_tail(&login->link, &login_list);
list_move_tail(&login->link, &login_list);
}
spin_unlock_bh(&sess->lock);
......@@ -1847,16 +1846,6 @@ static int sbp_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
static u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
{
return 0;
}
static u16 sbp_get_fabric_sense_len(void)
{
return 0;
}
static int sbp_check_stop_free(struct se_cmd *se_cmd)
{
struct sbp_target_request *req = container_of(se_cmd,
......@@ -2068,7 +2057,7 @@ static int sbp_update_unit_directory(struct sbp_tport *tport)
return ret;
}
static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict)
static ssize_t sbp_parse_wwn(const char *name, u64 *wwn)
{
const char *cp;
char c, nibble;
......@@ -2088,7 +2077,7 @@ static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict)
err = 3;
if (isdigit(c))
nibble = c - '0';
else if (isxdigit(c) && (islower(c) || !strict))
else if (isxdigit(c))
nibble = tolower(c) - 'a' + 10;
else
goto fail;
......@@ -2117,7 +2106,7 @@ static struct se_node_acl *sbp_make_nodeacl(
u64 guid = 0;
u32 nexus_depth = 1;
if (sbp_parse_wwn(name, &guid, 1) < 0)
if (sbp_parse_wwn(name, &guid) < 0)
return ERR_PTR(-EINVAL);
se_nacl_new = sbp_alloc_fabric_acl(se_tpg);
......@@ -2253,7 +2242,7 @@ static struct se_wwn *sbp_make_tport(
struct sbp_tport *tport;
u64 guid = 0;
if (sbp_parse_wwn(name, &guid, 1) < 0)
if (sbp_parse_wwn(name, &guid) < 0)
return ERR_PTR(-EINVAL);
tport = kzalloc(sizeof(*tport), GFP_KERNEL);
......@@ -2534,8 +2523,6 @@ static struct target_core_fabric_ops sbp_ops = {
.queue_data_in = sbp_queue_data_in,
.queue_status = sbp_queue_status,
.queue_tm_rsp = sbp_queue_tm_rsp,
.get_fabric_sense_len = sbp_get_fabric_sense_len,
.set_fabric_sense_len = sbp_set_fabric_sense_len,
.check_stop_free = sbp_check_stop_free,
.fabric_make_wwn = sbp_make_tport,
......@@ -2556,9 +2543,9 @@ static int sbp_register_configfs(void)
int ret;
fabric = target_fabric_configfs_init(THIS_MODULE, "sbp");
if (!fabric) {
if (IS_ERR(fabric)) {
pr_err("target_fabric_configfs_init() failed\n");
return -ENOMEM;
return PTR_ERR(fabric);
}
fabric->tf_ops = sbp_ops;
......
......@@ -344,7 +344,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
*/
rtpi = get_unaligned_be16(ptr + 2);
/*
* Locate the matching relative target port identifer
* Locate the matching relative target port identifier
* for the struct se_device storage object.
*/
spin_lock(&dev->se_port_lock);
......
......@@ -457,14 +457,6 @@ static int target_fabric_tf_ops_check(
pr_err("Missing tfo->queue_tm_rsp()\n");
return -EINVAL;
}
if (!tfo->set_fabric_sense_len) {
pr_err("Missing tfo->set_fabric_sense_len()\n");
return -EINVAL;
}
if (!tfo->get_fabric_sense_len) {
pr_err("Missing tfo->get_fabric_sense_len()\n");
return -EINVAL;
}
/*
* We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn()
* tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
......@@ -1208,7 +1200,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
" Target Node Endpoint: %s\n", tfo->get_fabric_name(),
tfo->tpg_get_wwn(se_tpg));
len += sprintf(page+len, "SPC-3 Reservation: Relative Port"
" Identifer Tag: %hu %s Portal Group Tag: %hu"
" Identifier Tag: %hu %s Portal Group Tag: %hu"
" %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi,
tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg),
tfo->get_fabric_name(), lun->unpacked_lun);
......@@ -3132,6 +3124,7 @@ static int __init target_core_init_configfs(void)
GFP_KERNEL);
if (!target_cg->default_groups) {
pr_err("Unable to allocate target_cg->default_groups\n");
ret = -ENOMEM;
goto out_global;
}
......@@ -3147,6 +3140,7 @@ static int __init target_core_init_configfs(void)
GFP_KERNEL);
if (!hba_cg->default_groups) {
pr_err("Unable to allocate hba_cg->default_groups\n");
ret = -ENOMEM;
goto out_global;
}
config_group_init_type_name(&alua_group,
......@@ -3162,6 +3156,7 @@ static int __init target_core_init_configfs(void)
GFP_KERNEL);
if (!alua_cg->default_groups) {
pr_err("Unable to allocate alua_cg->default_groups\n");
ret = -ENOMEM;
goto out_global;
}
......@@ -3173,14 +3168,17 @@ static int __init target_core_init_configfs(void)
* Add core/alua/lu_gps/default_lu_gp
*/
lu_gp = core_alua_allocate_lu_gp("default_lu_gp", 1);
if (IS_ERR(lu_gp))
if (IS_ERR(lu_gp)) {
ret = -ENOMEM;
goto out_global;
}
lu_gp_cg = &alua_lu_gps_group;
lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
GFP_KERNEL);
if (!lu_gp_cg->default_groups) {
pr_err("Unable to allocate lu_gp_cg->default_groups\n");
ret = -ENOMEM;
goto out_global;
}
......
......@@ -531,7 +531,7 @@ static struct se_port *core_alloc_port(struct se_device *dev)
}
again:
/*
* Allocate the next RELATIVE TARGET PORT IDENTIFER for this struct se_device
* Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device
* Here is the table from spc4r17 section 7.7.3.8.
*
* Table 473 -- RELATIVE TARGET PORT IDENTIFIER field
......@@ -548,7 +548,7 @@ static struct se_port *core_alloc_port(struct se_device *dev)
list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) {
/*
* Make sure RELATIVE TARGET PORT IDENTIFER is unique
* Make sure RELATIVE TARGET PORT IDENTIFIER is unique
* for 16-bit wrap..
*/
if (port->sep_rtpi == port_tmp->sep_rtpi)
......@@ -595,7 +595,7 @@ static void core_export_port(
}
dev->dev_port_count++;
port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFER */
port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */
}
/*
......@@ -988,8 +988,9 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag)
return -EINVAL;
}
if (flag && dev->transport->fua_write_emulated == 0) {
pr_err("fua_write_emulated not supported\n");
if (flag &&
dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
pr_err("emulate_fua_write not supported for pSCSI\n");
return -EINVAL;
}
dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag;
......@@ -1019,8 +1020,9 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
pr_err("Illegal value %d\n", flag);
return -EINVAL;
}
if (flag && dev->transport->write_cache_emulated == 0) {
pr_err("write_cache_emulated not supported\n");
if (flag &&
dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
pr_err("emulate_write_cache not supported for pSCSI\n");
return -EINVAL;
}
dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag;
......
......@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/fs.h>
......
......@@ -338,7 +338,7 @@ u32 iscsi_get_pr_transport_id_len(
* 00b: iSCSI Initiator device TransportID format
*/
if (pr_reg->isid_present_at_reg) {
len += 5; /* For ",i,0x" ASCII seperator */
len += 5; /* For ",i,0x" ASCII separator */
len += 7; /* For iSCSI Initiator Session ID + Null terminator */
*format_code = 1;
} else
......@@ -415,20 +415,20 @@ char *iscsi_parse_pr_out_transport_id(
*out_tid_len = (add_len + 4);
}
/*
* Check for ',i,0x' seperator between iSCSI Name and iSCSI Initiator
* Check for ',i,0x' separator between iSCSI Name and iSCSI Initiator
* Session ID as defined in Table 390 - iSCSI initiator port TransportID
* format.
*/
if (format_code == 0x40) {
p = strstr(&buf[4], ",i,0x");
if (!p) {
pr_err("Unable to locate \",i,0x\" seperator"
pr_err("Unable to locate \",i,0x\" separator"
" for Initiator port identifier: %s\n",
&buf[4]);
return NULL;
}
*p = '\0'; /* Terminate iSCSI Name */
p += 5; /* Skip over ",i,0x" seperator */
p += 5; /* Skip over ",i,0x" separator */
*port_nexus_ptr = p;
/*
......
......@@ -125,6 +125,19 @@ static struct se_device *fd_create_virtdevice(
* of pure timestamp updates.
*/
flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
/*
* Optionally allow fd_buffered_io=1 to be enabled for people
* who want use the fs buffer cache as an WriteCache mechanism.
*
* This means that in event of a hard failure, there is a risk
* of silent data-loss if the SCSI client has *not* performed a
* forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE
* to write-out the entire device cache.
*/
if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n");
flags &= ~O_DSYNC;
}
file = filp_open(fd_dev->fd_dev_name, flags, 0600);
if (IS_ERR(file)) {
......@@ -188,6 +201,12 @@ static struct se_device *fd_create_virtdevice(
if (!dev)
goto fail;
if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
" with FDBD_HAS_BUFFERED_IO_WCE\n");
dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
}
fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
fd_dev->fd_queue_depth = dev->queue_depth;
......@@ -407,6 +426,7 @@ enum {
static match_table_t tokens = {
{Opt_fd_dev_name, "fd_dev_name=%s"},
{Opt_fd_dev_size, "fd_dev_size=%s"},
{Opt_fd_buffered_io, "fd_buffered_io=%d"},
{Opt_err, NULL}
};
......@@ -418,7 +438,7 @@ static ssize_t fd_set_configfs_dev_params(
struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
char *orig, *ptr, *arg_p, *opts;
substring_t args[MAX_OPT_ARGS];
int ret = 0, token;
int ret = 0, arg, token;
opts = kstrdup(page, GFP_KERNEL);
if (!opts)
......@@ -459,6 +479,19 @@ static ssize_t fd_set_configfs_dev_params(
" bytes\n", fd_dev->fd_dev_size);
fd_dev->fbd_flags |= FBDF_HAS_SIZE;
break;
case Opt_fd_buffered_io:
match_int(args, &arg);
if (arg != 1) {
pr_err("bogus fd_buffered_io=%d value\n", arg);
ret = -EINVAL;
goto out;
}
pr_debug("FILEIO: Using buffered I/O"
" operations for struct fd_dev\n");
fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE;
break;
default:
break;
}
......@@ -490,8 +523,10 @@ static ssize_t fd_show_configfs_dev_params(
ssize_t bl = 0;
bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
bl += sprintf(b + bl, " File: %s Size: %llu Mode: O_DSYNC\n",
fd_dev->fd_dev_name, fd_dev->fd_dev_size);
bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n",
fd_dev->fd_dev_name, fd_dev->fd_dev_size,
(fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ?
"Buffered-WCE" : "O_DSYNC");
return bl;
}
......@@ -546,8 +581,6 @@ static struct se_subsystem_api fileio_template = {
.name = "fileio",
.owner = THIS_MODULE,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
.write_cache_emulated = 1,
.fua_write_emulated = 1,
.attach_hba = fd_attach_hba,
.detach_hba = fd_detach_hba,
.allocate_virtdevice = fd_allocate_virtdevice,
......
......@@ -14,6 +14,7 @@
#define FBDF_HAS_PATH 0x01
#define FBDF_HAS_SIZE 0x02
#define FDBD_HAS_BUFFERED_IO_WCE 0x04
struct fd_dev {
u32 fbd_flags;
......
......@@ -454,14 +454,11 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
ret = -EEXIST;
goto out;
}
arg_p = match_strdup(&args[0]);
if (!arg_p) {
ret = -ENOMEM;
if (match_strlcpy(ib_dev->ibd_udev_path, &args[0],
SE_UDEV_PATH_LEN) == 0) {
ret = -EINVAL;
break;
}
snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
"%s", arg_p);
kfree(arg_p);
pr_debug("IBLOCK: Referencing UDEV path: %s\n",
ib_dev->ibd_udev_path);
ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
......@@ -657,6 +654,12 @@ static int iblock_execute_rw(struct se_cmd *cmd)
goto fail;
cmd->priv = ibr;
if (!sgl_nents) {
atomic_set(&ibr->pending, 1);
iblock_complete_cmd(cmd);
return 0;
}
bio = iblock_get_bio(cmd, block_lba, sgl_nents);
if (!bio)
goto fail_free_ibr;
......@@ -769,8 +772,6 @@ static struct se_subsystem_api iblock_template = {
.name = "iblock",
.owner = THIS_MODULE,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
.write_cache_emulated = 1,
.fua_write_emulated = 1,
.attach_hba = iblock_attach_hba,
.detach_hba = iblock_detach_hba,
.allocate_virtdevice = iblock_allocate_virtdevice,
......
......@@ -197,10 +197,10 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
struct se_portal_group *tpg = sess->se_tpg;
struct se_portal_group *tpg;
int ret = 0, rc;
if (!sess || !tpg)
if (!sess || !sess->se_tpg)
goto out;
rc = target_check_scsi2_reservation_conflict(cmd);
if (rc == 1)
......@@ -228,6 +228,7 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
dev->dev_res_bin_isid = 0;
dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
}
tpg = sess->se_tpg;
pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
" MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
......@@ -245,7 +246,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
struct se_portal_group *tpg = sess->se_tpg;
struct se_portal_group *tpg;
int ret = 0, rc;
if ((cmd->t_task_cdb[1] & 0x01) &&
......@@ -260,7 +261,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
* This is currently the case for target_core_mod passthrough struct se_cmd
* ops
*/
if (!sess || !tpg)
if (!sess || !sess->se_tpg)
goto out;
rc = target_check_scsi2_reservation_conflict(cmd);
if (rc == 1)
......@@ -272,6 +273,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
}
ret = 0;
tpg = sess->se_tpg;
spin_lock(&dev->dev_reservation_lock);
if (dev->dev_reserved_node_acl &&
(dev->dev_reserved_node_acl != sess->se_node_acl)) {
......@@ -1620,7 +1622,7 @@ static int core_scsi3_decode_spec_i_port(
goto out;
}
/*
* Locate the desination initiator ACL to be registered
* Locate the destination initiator ACL to be registered
* from the decoded fabric module specific TransportID
* at *i_str.
*/
......@@ -4257,7 +4259,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
buf[off++] = (port->sep_rtpi & 0xff);
} else
off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFER */
off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */
/*
* Now, have the $FABRIC_MOD fill in the protocol identifier
......
......@@ -264,7 +264,7 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev,
" length zero!\n");
break;
}
pr_debug("T10 VPD Identifer Length: %d\n", ident_len);
pr_debug("T10 VPD Identifier Length: %d\n", ident_len);
vpd = kzalloc(sizeof(struct t10_vpd), GFP_KERNEL);
if (!vpd) {
......
......@@ -40,8 +40,9 @@
static int sbc_emulate_readcapacity(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
unsigned char *buf;
unsigned long long blocks_long = dev->transport->get_blocks(dev);
unsigned char *rbuf;
unsigned char buf[8];
u32 blocks;
if (blocks_long >= 0x00000000ffffffff)
......@@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
else
blocks = (u32)blocks_long;
buf = transport_kmap_data_sg(cmd);
buf[0] = (blocks >> 24) & 0xff;
buf[1] = (blocks >> 16) & 0xff;
buf[2] = (blocks >> 8) & 0xff;
......@@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
transport_kunmap_data_sg(cmd);
rbuf = transport_kmap_data_sg(cmd);
if (rbuf) {
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
}
target_complete_cmd(cmd, GOOD);
return 0;
......@@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
unsigned char *buf;
unsigned char *rbuf;
unsigned char buf[32];
unsigned long long blocks = dev->transport->get_blocks(dev);
buf = transport_kmap_data_sg(cmd);
memset(buf, 0, sizeof(buf));
buf[0] = (blocks >> 56) & 0xff;
buf[1] = (blocks >> 48) & 0xff;
buf[2] = (blocks >> 40) & 0xff;
......@@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
buf[14] = 0x80;
transport_kunmap_data_sg(cmd);
rbuf = transport_kmap_data_sg(cmd);
if (rbuf) {
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
}
target_complete_cmd(cmd, GOOD);
return 0;
......
......@@ -600,30 +600,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg;
unsigned char *buf, *map_buf;
unsigned char *rbuf;
unsigned char *cdb = cmd->t_task_cdb;
unsigned char buf[SE_INQUIRY_BUF];
int p, ret;
map_buf = transport_kmap_data_sg(cmd);
/*
* If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we
* know we actually allocated a full page. Otherwise, if the
* data buffer is too small, allocate a temporary buffer so we
* don't have to worry about overruns in all our INQUIRY
* emulation handling.
*/
if (cmd->data_length < SE_INQUIRY_BUF &&
(cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL);
if (!buf) {
transport_kunmap_data_sg(cmd);
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM;
}
} else {
buf = map_buf;
}
if (dev == tpg->tpg_virt_lun0.lun_se_dev)
buf[0] = 0x3f; /* Not connected */
else
......@@ -655,11 +636,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
ret = -EINVAL;
out:
if (buf != map_buf) {
memcpy(map_buf, buf, cmd->data_length);
kfree(buf);
rbuf = transport_kmap_data_sg(cmd);
if (rbuf) {
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
}
transport_kunmap_data_sg(cmd);
if (!ret)
target_complete_cmd(cmd, GOOD);
......@@ -803,7 +784,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
unsigned char *rbuf;
int type = dev->transport->get_device_type(dev);
int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
int offset = ten ? 8 : 4;
u32 offset = ten ? 8 : 4;
int length = 0;
unsigned char buf[SE_MODE_PAGE_BUF];
......@@ -836,6 +817,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
offset -= 2;
buf[0] = (offset >> 8) & 0xff;
buf[1] = offset & 0xff;
offset += 2;
if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
(cmd->se_deve &&
......@@ -845,13 +827,10 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
(dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
spc_modesense_dpofua(&buf[3], type);
if ((offset + 2) > cmd->data_length)
offset = cmd->data_length;
} else {
offset -= 1;
buf[0] = offset & 0xff;
offset += 1;
if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
(cmd->se_deve &&
......@@ -861,14 +840,13 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
(dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
spc_modesense_dpofua(&buf[2], type);
if ((offset + 1) > cmd->data_length)
offset = cmd->data_length;
}
rbuf = transport_kmap_data_sg(cmd);
memcpy(rbuf, buf, offset);
transport_kunmap_data_sg(cmd);
if (rbuf) {
memcpy(rbuf, buf, min(offset, cmd->data_length));
transport_kunmap_data_sg(cmd);
}
target_complete_cmd(cmd, GOOD);
return 0;
......
......@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
......
......@@ -303,7 +303,7 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
}
/*
* Here we only create demo-mode MappedLUNs from the active
* TPG LUNs if the fabric is not explictly asking for
* TPG LUNs if the fabric is not explicitly asking for
* tpg_check_demo_mode_login_only() == 1.
*/
if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only == NULL) ||
......
......@@ -55,8 +55,6 @@
#include "target_core_pr.h"
#include "target_core_ua.h"
static int sub_api_initialized;
static struct workqueue_struct *target_completion_wq;
static struct kmem_cache *se_sess_cache;
struct kmem_cache *se_ua_cache;
......@@ -195,6 +193,7 @@ u32 scsi_get_new_index(scsi_index_t type)
void transport_subsystem_check_init(void)
{
int ret;
static int sub_api_initialized;
if (sub_api_initialized)
return;
......@@ -211,12 +210,7 @@ void transport_subsystem_check_init(void)
if (ret != 0)
pr_err("Unable to load target_core_pscsi\n");
ret = request_module("target_core_stgt");
if (ret != 0)
pr_err("Unable to load target_core_stgt\n");
sub_api_initialized = 1;
return;
}
struct se_session *transport_init_session(void)
......@@ -573,9 +567,7 @@ static void target_complete_failure_work(struct work_struct *work)
*/
static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
{
unsigned char *buffer = cmd->sense_buffer;
struct se_device *dev = cmd->se_dev;
u32 offset = 0;
WARN_ON(!cmd->se_lun);
......@@ -585,14 +577,11 @@ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
return NULL;
offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER);
/* Automatically padded */
cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n",
dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);
return &buffer[offset];
return cmd->sense_buffer;
}
void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
......@@ -969,7 +958,7 @@ int
transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83)
{
static const char hex_str[] = "0123456789abcdef";
int j = 0, i = 4; /* offset to start of the identifer */
int j = 0, i = 4; /* offset to start of the identifier */
/*
* The VPD Code Set (encoding)
......@@ -1466,8 +1455,9 @@ int transport_handle_cdb_direct(
}
EXPORT_SYMBOL(transport_handle_cdb_direct);
/**
* target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
/*
* target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized
* se_cmd + use pre-allocated SGL memory.
*
* @se_cmd: command descriptor to submit
* @se_sess: associated se_sess for endpoint
......@@ -1478,6 +1468,10 @@ EXPORT_SYMBOL(transport_handle_cdb_direct);
* @task_addr: SAM task attribute
* @data_dir: DMA data direction
* @flags: flags for command submission from target_sc_flags_tables
* @sgl: struct scatterlist memory for unidirectional mapping
* @sgl_count: scatterlist count for unidirectional mapping
* @sgl_bidi: struct scatterlist memory for bidirectional READ mapping
* @sgl_bidi_count: scatterlist count for bidirectional READ mapping
*
* Returns non zero to signal active I/O shutdown failure. All other
* setup exceptions will be returned as a SCSI CHECK_CONDITION response,
......@@ -1485,10 +1479,12 @@ EXPORT_SYMBOL(transport_handle_cdb_direct);
*
* This may only be called from process context, and also currently
* assumes internal allocation of fabric payload buffer by target-core.
**/
int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
*/
int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess,
unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
u32 data_length, int task_attr, int data_dir, int flags)
u32 data_length, int task_attr, int data_dir, int flags,
struct scatterlist *sgl, u32 sgl_count,
struct scatterlist *sgl_bidi, u32 sgl_bidi_count)
{
struct se_portal_group *se_tpg;
int rc;
......@@ -1535,7 +1531,42 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
transport_generic_request_failure(se_cmd);
return 0;
}
/*
* When a non zero sgl_count has been passed perform SGL passthrough
* mapping for pre-allocated fabric memory instead of having target
* core perform an internal SGL allocation..
*/
if (sgl_count != 0) {
BUG_ON(!sgl);
/*
* A work-around for tcm_loop as some userspace code via
* scsi-generic do not memset their associated read buffers,
* so go ahead and do that here for type non-data CDBs. Also
* note that this is currently guaranteed to be a single SGL
* for this case by target core in target_setup_cmd_from_cdb()
* -> transport_generic_cmd_sequencer().
*/
if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
se_cmd->data_direction == DMA_FROM_DEVICE) {
unsigned char *buf = NULL;
if (sgl)
buf = kmap(sg_page(sgl)) + sgl->offset;
if (buf) {
memset(buf, 0, sgl->length);
kunmap(sg_page(sgl));
}
}
rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count,
sgl_bidi, sgl_bidi_count);
if (rc != 0) {
transport_generic_request_failure(se_cmd);
return 0;
}
}
/*
* Check if we need to delay processing because of ALUA
* Active/NonOptimized primary access state..
......@@ -1545,6 +1576,38 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
transport_handle_cdb_direct(se_cmd);
return 0;
}
EXPORT_SYMBOL(target_submit_cmd_map_sgls);
/*
* target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
*
* @se_cmd: command descriptor to submit
* @se_sess: associated se_sess for endpoint
* @cdb: pointer to SCSI CDB
* @sense: pointer to SCSI sense buffer
* @unpacked_lun: unpacked LUN to reference for struct se_lun
* @data_length: fabric expected data transfer length
* @task_addr: SAM task attribute
* @data_dir: DMA data direction
* @flags: flags for command submission from target_sc_flags_tables
*
* Returns non zero to signal active I/O shutdown failure. All other
* setup exceptions will be returned as a SCSI CHECK_CONDITION response,
* but still return zero here.
*
* This may only be called from process context, and also currently
* assumes internal allocation of fabric payload buffer by target-core.
*
* It also assumes interal target core SGL memory allocation.
*/
int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
u32 data_length, int task_attr, int data_dir, int flags)
{
return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense,
unpacked_lun, data_length, task_attr, data_dir,
flags, NULL, 0, NULL, 0);
}
EXPORT_SYMBOL(target_submit_cmd);
static void target_complete_tmr_failure(struct work_struct *work)
......@@ -2300,23 +2363,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
if (ret < 0)
goto out_fail;
}
/*
* If this command doesn't have any payload and we don't have to call
* into the fabric for data transfers, go ahead and complete it right
* away.
*/
if (!cmd->data_length &&
cmd->t_task_cdb[0] != REQUEST_SENSE &&
cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {
spin_lock_irq(&cmd->t_state_lock);
cmd->t_state = TRANSPORT_COMPLETE;
cmd->transport_state |= CMD_T_ACTIVE;
spin_unlock_irq(&cmd->t_state_lock);
INIT_WORK(&cmd->work, target_complete_ok_work);
queue_work(target_completion_wq, &cmd->work);
return 0;
}
atomic_inc(&cmd->t_fe_count);
......@@ -2771,7 +2817,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
spin_lock_irqsave(&cmd->t_state_lock, flags);
cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
pr_debug("wait_for_tasks: Stopped wait_for_compltion("
pr_debug("wait_for_tasks: Stopped wait_for_completion("
"&cmd->t_transport_stop_comp) for ITT: 0x%08x\n",
cmd->se_tfo->get_task_tag(cmd));
......@@ -2810,7 +2856,6 @@ int transport_send_check_condition_and_sense(
{
unsigned char *buffer = cmd->sense_buffer;
unsigned long flags;
int offset;
u8 asc = 0, ascq = 0;
spin_lock_irqsave(&cmd->t_state_lock, flags);
......@@ -2826,14 +2871,7 @@ int transport_send_check_condition_and_sense(
if (!from_transport)
cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE;
/*
* Data Segment and SenseLength of the fabric response PDU.
*
* TRANSPORT_SENSE_BUFFER is now set to SCSI_SENSE_BUFFERSIZE
* from include/scsi/scsi_cmnd.h
*/
offset = cmd->se_tfo->set_fabric_sense_len(cmd,
TRANSPORT_SENSE_BUFFER);
/*
* Actual SENSE DATA, see SPC-3 7.23.2 SPC_SENSE_KEY_OFFSET uses
* SENSE KEY values from include/scsi/scsi.h
......@@ -2841,151 +2879,151 @@ int transport_send_check_condition_and_sense(
switch (reason) {
case TCM_NON_EXISTENT_LUN:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT NOT SUPPORTED */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x25;
buffer[SPC_ASC_KEY_OFFSET] = 0x25;
break;
case TCM_UNSUPPORTED_SCSI_OPCODE:
case TCM_SECTOR_COUNT_TOO_MANY:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID COMMAND OPERATION CODE */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x20;
buffer[SPC_ASC_KEY_OFFSET] = 0x20;
break;
case TCM_UNKNOWN_MODE_PAGE:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
buffer[SPC_ASC_KEY_OFFSET] = 0x24;
break;
case TCM_CHECK_CONDITION_ABORT_CMD:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* BUS DEVICE RESET FUNCTION OCCURRED */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x29;
buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x03;
buffer[SPC_ASC_KEY_OFFSET] = 0x29;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x03;
break;
case TCM_INCORRECT_AMOUNT_OF_DATA:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c;
buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
/* NOT ENOUGH UNSOLICITED DATA */
buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0d;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d;
break;
case TCM_INVALID_CDB_FIELD:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
buffer[SPC_ASC_KEY_OFFSET] = 0x24;
break;
case TCM_INVALID_PARAMETER_LIST:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN PARAMETER LIST */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26;
buffer[SPC_ASC_KEY_OFFSET] = 0x26;
break;
case TCM_UNEXPECTED_UNSOLICITED_DATA:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c;
buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
/* UNEXPECTED_UNSOLICITED_DATA */
buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0c;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c;
break;
case TCM_SERVICE_CRC_ERROR:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* PROTOCOL SERVICE CRC ERROR */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x47;
buffer[SPC_ASC_KEY_OFFSET] = 0x47;
/* N/A */
buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x05;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x05;
break;
case TCM_SNACK_REJECTED:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* READ ERROR */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x11;
buffer[SPC_ASC_KEY_OFFSET] = 0x11;
/* FAILED RETRANSMISSION REQUEST */
buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x13;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x13;
break;
case TCM_WRITE_PROTECTED:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* DATA PROTECT */
buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
/* WRITE PROTECTED */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27;
buffer[SPC_ASC_KEY_OFFSET] = 0x27;
break;
case TCM_ADDRESS_OUT_OF_RANGE:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL BLOCK ADDRESS OUT OF RANGE */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21;
buffer[SPC_ASC_KEY_OFFSET] = 0x21;
break;
case TCM_CHECK_CONDITION_UNIT_ATTENTION:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* UNIT ATTENTION */
buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
buffer[offset+SPC_ASC_KEY_OFFSET] = asc;
buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq;
buffer[SPC_ASC_KEY_OFFSET] = asc;
buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
break;
case TCM_CHECK_CONDITION_NOT_READY:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* Not Ready */
buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY;
buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
transport_get_sense_codes(cmd, &asc, &ascq);
buffer[offset+SPC_ASC_KEY_OFFSET] = asc;
buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq;
buffer[SPC_ASC_KEY_OFFSET] = asc;
buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
break;
case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
default:
/* CURRENT ERROR */
buffer[offset] = 0x70;
buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT COMMUNICATION FAILURE */
buffer[offset+SPC_ASC_KEY_OFFSET] = 0x80;
buffer[SPC_ASC_KEY_OFFSET] = 0x80;
break;
}
/*
......@@ -2996,7 +3034,7 @@ int transport_send_check_condition_and_sense(
* Automatically padded, this value is encoded in the fabric's
* data_length response PDU containing the SCSI defined sense data.
*/
cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
after_reason:
return cmd->se_tfo->queue_status(cmd);
......
......@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/slab.h>
......
......@@ -495,16 +495,6 @@ static void ft_set_default_node_attr(struct se_node_acl *se_nacl)
{
}
static u16 ft_get_fabric_sense_len(void)
{
return 0;
}
static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len)
{
return 0;
}
static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
{
struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr;
......@@ -542,8 +532,6 @@ static struct target_core_fabric_ops ft_fabric_ops = {
.queue_data_in = ft_queue_data_in,
.queue_status = ft_queue_status,
.queue_tm_rsp = ft_queue_tm_resp,
.get_fabric_sense_len = ft_get_fabric_sense_len,
.set_fabric_sense_len = ft_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
......
......@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/slab.h>
......@@ -328,11 +327,12 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
*/
void ft_invl_hw_context(struct ft_cmd *cmd)
{
struct fc_seq *seq = cmd->seq;
struct fc_seq *seq;
struct fc_exch *ep = NULL;
struct fc_lport *lport = NULL;
BUG_ON(!cmd);
seq = cmd->seq;
/* Cleanup the DDP context in HW if DDP was setup */
if (cmd->was_ddp_setup && seq) {
......
......@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/slab.h>
......
......@@ -1472,16 +1472,6 @@ static int usbg_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
{
return 0;
}
static u16 usbg_get_fabric_sense_len(void)
{
return 0;
}
static const char *usbg_check_wwn(const char *name)
{
const char *n;
......@@ -1822,7 +1812,7 @@ static ssize_t tcm_usbg_tpg_store_nexus(
ret = tcm_usbg_drop_nexus(tpg);
return (!ret) ? count : ret;
}
if (strlen(page) > USBG_NAMELEN) {
if (strlen(page) >= USBG_NAMELEN) {
pr_err("Emulated NAA Sas Address: %s, exceeds"
" max: %d\n", page, USBG_NAMELEN);
return -EINVAL;
......@@ -1907,8 +1897,6 @@ static struct target_core_fabric_ops usbg_ops = {
.queue_data_in = usbg_send_read_response,
.queue_status = usbg_send_status_response,
.queue_tm_rsp = usbg_queue_tm_rsp,
.get_fabric_sense_len = usbg_get_fabric_sense_len,
.set_fabric_sense_len = usbg_set_fabric_sense_len,
.check_stop_free = usbg_check_stop_free,
.fabric_make_wwn = usbg_make_tport,
......@@ -1968,7 +1956,6 @@ static void usbg_deregister_configfs(void)
static struct usb_interface_descriptor bot_intf_desc = {
.bLength = sizeof(bot_intf_desc),
.bDescriptorType = USB_DT_INTERFACE,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bAlternateSetting = USB_G_ALT_INT_BBB,
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
......
......@@ -330,17 +330,6 @@ static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd,
u32 sense_length)
{
return 0;
}
static u16 tcm_vhost_get_fabric_sense_len(void)
{
return 0;
}
static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
{
struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
......@@ -426,10 +415,7 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
{
struct tcm_vhost_cmd *tv_cmd;
struct tcm_vhost_nexus *tv_nexus;
struct se_portal_group *se_tpg = &tv_tpg->se_tpg;
struct se_session *se_sess;
struct se_cmd *se_cmd;
int sam_task_attr;
tv_nexus = tv_tpg->tpg_nexus;
if (!tv_nexus) {
......@@ -445,23 +431,11 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
}
INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
tv_cmd->tvc_tag = v_req->tag;
tv_cmd->tvc_task_attr = v_req->task_attr;
tv_cmd->tvc_exp_data_len = exp_data_len;
tv_cmd->tvc_data_direction = data_direction;
tv_cmd->tvc_nexus = tv_nexus;
se_cmd = &tv_cmd->tvc_se_cmd;
/*
* Locate the SAM Task Attr from virtio_scsi_cmd_req
*/
sam_task_attr = v_req->task_attr;
/*
* Initialize struct se_cmd descriptor from TCM infrastructure
*/
transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len,
data_direction, sam_task_attr,
&tv_cmd->tvc_sense_buf[0]);
#if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */
if (bidi)
se_cmd->se_cmd_flags |= SCF_BIDI;
#endif
return tv_cmd;
}
......@@ -560,37 +534,10 @@ static void tcm_vhost_submission_work(struct work_struct *work)
{
struct tcm_vhost_cmd *tv_cmd =
container_of(work, struct tcm_vhost_cmd, work);
struct tcm_vhost_nexus *tv_nexus;
struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL;
int rc, sg_no_bidi = 0;
/*
* Locate the struct se_lun pointer based on v_req->lun, and
* attach it to struct se_cmd
*/
rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun);
if (rc < 0) {
pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun);
transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd,
tv_cmd->tvc_se_cmd.scsi_sense_reason, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
}
rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb);
if (rc == -ENOMEM) {
transport_send_check_condition_and_sense(se_cmd,
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
} else if (rc < 0) {
if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
tcm_vhost_queue_status(se_cmd);
else
transport_send_check_condition_and_sense(se_cmd,
se_cmd->scsi_sense_reason, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
}
if (tv_cmd->tvc_sgl_count) {
sg_ptr = tv_cmd->tvc_sgl;
......@@ -608,17 +555,19 @@ static void tcm_vhost_submission_work(struct work_struct *work)
} else {
sg_ptr = NULL;
}
rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr,
tv_cmd->tvc_sgl_count, sg_bidi_ptr,
sg_no_bidi);
tv_nexus = tv_cmd->tvc_nexus;
rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,
tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0],
tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len,
tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction,
0, sg_ptr, tv_cmd->tvc_sgl_count,
sg_bidi_ptr, sg_no_bidi);
if (rc < 0) {
transport_send_check_condition_and_sense(se_cmd,
se_cmd->scsi_sense_reason, 0);
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
transport_generic_free_cmd(se_cmd, 0);
return;
}
transport_handle_cdb_direct(se_cmd);
}
static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
......@@ -1531,8 +1480,6 @@ static struct target_core_fabric_ops tcm_vhost_ops = {
.queue_data_in = tcm_vhost_queue_data_in,
.queue_status = tcm_vhost_queue_status,
.queue_tm_rsp = tcm_vhost_queue_tm_rsp,
.get_fabric_sense_len = tcm_vhost_get_fabric_sense_len,
.set_fabric_sense_len = tcm_vhost_set_fabric_sense_len,
/*
* Setup callers for generic logic in target_core_fabric_configfs.c
*/
......
......@@ -5,6 +5,12 @@
struct tcm_vhost_cmd {
/* Descriptor from vhost_get_vq_desc() for virt_queue segment */
int tvc_vq_desc;
/* virtio-scsi initiator task attribute */
int tvc_task_attr;
/* virtio-scsi initiator data direction */
enum dma_data_direction tvc_data_direction;
/* Expected data transfer length from virtio-scsi header */
u32 tvc_exp_data_len;
/* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */
u64 tvc_tag;
/* The number of scatterlists associated with this cmd */
......@@ -17,6 +23,8 @@ struct tcm_vhost_cmd {
struct virtio_scsi_cmd_resp __user *tvc_resp;
/* Pointer to vhost_scsi for our device */
struct vhost_scsi *tvc_vhost;
/* Pointer to vhost nexus memory */
struct tcm_vhost_nexus *tvc_nexus;
/* The TCM I/O descriptor that is accessed via container_of() */
struct se_cmd tvc_se_cmd;
/* work item used for cmwq dispatch to tcm_vhost_submission_work() */
......
......@@ -13,9 +13,6 @@ struct se_subsystem_api {
u8 transport_type;
unsigned int fua_write_emulated : 1;
unsigned int write_cache_emulated : 1;
int (*attach_hba)(struct se_hba *, u32);
void (*detach_hba)(struct se_hba *);
int (*pmode_enable_hba)(struct se_hba *, unsigned long);
......
......@@ -62,8 +62,6 @@ struct target_core_fabric_ops {
int (*queue_data_in)(struct se_cmd *);
int (*queue_status)(struct se_cmd *);
int (*queue_tm_rsp)(struct se_cmd *);
u16 (*set_fabric_sense_len)(struct se_cmd *, u32);
u16 (*get_fabric_sense_len)(void);
/*
* fabric module calls for target_core_fabric_configfs.c
*/
......@@ -102,6 +100,9 @@ void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *,
struct se_session *, u32, int, int, unsigned char *);
int transport_lookup_cmd_lun(struct se_cmd *, u32);
int target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *);
int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *,
unsigned char *, unsigned char *, u32, u32, int, int, int,
struct scatterlist *, u32, struct scatterlist *, u32);
int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
unsigned char *, u32, u32, int, int, int);
int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册