@@ -2123,16 +2123,16 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
*full_req_cnt = prm->req_cnt;
- if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
- prm->residual = se_cmd->residual_count;
+ if (cmd->residual < 0) {
+ prm->residual = -(cmd->residual);
ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x305c,
"Residual underflow: %d (tag %lld, op %x, bufflen %d, rq_result %x)\n",
prm->residual, se_cmd->tag,
se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0,
cmd->bufflen, prm->rq_result);
prm->rq_result |= SS_RESIDUAL_UNDER;
- } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
- prm->residual = se_cmd->residual_count;
+ } else if (cmd->residual > 0) {
+ prm->residual = cmd->residual;
ql_dbg(ql_dbg_io, vha, 0x305d,
"Residual overflow: %d (tag %lld, op %x, bufflen %d, rq_result %x)\n",
prm->residual, se_cmd->tag, se_cmd->t_task_cdb ?
@@ -1007,6 +1007,7 @@ struct qla_tgt_cmd {
uint32_t unpacked_lun;
enum dma_data_direction dma_data_direction;
uint32_t reset_count;
+ int residual; /* + = over, - = under */
uint16_t loop_id; /* to save extra sess dereferences */
struct qla_tgt *tgt; /* to save extra sess dereferences */
@@ -265,6 +265,15 @@ static void tcm_qla2xxx_complete_mcmd(struct work_struct *work)
transport_generic_free_cmd(&mcmd->se_cmd, 0);
}
+static void tcm_qla2xxx_check_resid(struct se_cmd *se_cmd,
+ struct qla_tgt_cmd *cmd)
+{
+ if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT)
+ cmd->residual = -(se_cmd->residual_count);
+ else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT)
+ cmd->residual = se_cmd->residual_count;
+}
+
/*
* Called from qla_target_template->free_mcmd(), and will call
* tcm_qla2xxx_release_cmd() via normal struct target_core_fabric_ops
@@ -701,6 +710,8 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
cmd->blk_sz = se_cmd->se_dev->dev_attrib.block_size;
se_cmd->pi_err = 0;
+ tcm_qla2xxx_check_resid(se_cmd, cmd);
+
/*
* Now queue completed DATA_IN the qla2xxx LLD and response ring
*/
@@ -739,6 +750,9 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
cmd->bufflen = 0;
}
+
+ tcm_qla2xxx_check_resid(se_cmd, cmd);
+
/*
* Now queue status response to qla2xxx LLD code and response ring
*/