target: add unknown size flag to target_submit_cmd()
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Tue, 10 Jan 2012 13:16:59 +0000 (14:16 +0100)
committerNicholas Bellinger <nab@linux-iscsi.org>
Sun, 15 Apr 2012 00:40:03 +0000 (17:40 -0700)
The UASP protocol does not inform the target device upfront how much
data it should expect so we have to learn in from the CDB.  So in order
to handle this case, add a TARGET_SCF_UNKNOWN_SIZE to target_submit_cmd()
and perform an explictly assignment for se_cmd->data_length from the
extracted CDB size in transport_generic_cmd_sequencer().

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_transport.c
include/target/target_core_base.h

index 443704f84fd5d5cf235ffeffc5038213c1f18106..25c67c800f3d443ffe9966faf8fbb0c40d8ca915 100644 (file)
@@ -1701,6 +1701,8 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
         */
        transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
                                data_length, data_dir, task_attr, sense);
+       if (flags & TARGET_SCF_UNKNOWN_SIZE)
+               se_cmd->unknown_data_length = 1;
        /*
         * Obtain struct se_cmd->cmd_kref reference and add new cmd to
         * se_sess->sess_cmd_list.  A second kref_get here is necessary
@@ -3142,6 +3144,9 @@ static int transport_generic_cmd_sequencer(
                goto out_unsupported_cdb;
        }
 
+       if (cmd->unknown_data_length)
+               cmd->data_length = size;
+
        if (size != cmd->data_length) {
                pr_warn("TARGET_CORE[%s]: Expected Transfer Length:"
                        " %u does not match SCSI CDB Length: %u for SAM Opcode:"
index edb51f6544f8be02d2758b6dd562e3e276e7074e..6a02c99d54a53a08c5b2787d1986e0ff4f12141d 100644 (file)
@@ -233,6 +233,7 @@ enum tcm_sense_reason_table {
 enum target_sc_flags_table {
        TARGET_SCF_BIDI_OP              = 0x01,
        TARGET_SCF_ACK_KREF             = 0x02,
+       TARGET_SCF_UNKNOWN_SIZE         = 0x04,
 };
 
 /* fabric independent task management function values */
@@ -537,6 +538,7 @@ struct se_cmd {
        /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */
        unsigned                check_release:1;
        unsigned                cmd_wait_set:1;
+       unsigned                unknown_data_length:1;
        /* See se_cmd_flags_table */
        u32                     se_cmd_flags;
        u32                     se_ordered_id;