mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 21:26:31 +00:00
Residuals and write residuals counting fixes
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1742 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
+117
-95
@@ -71,7 +71,6 @@ static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess);
|
||||
static void req_cmnd_release(struct iscsi_cmnd *req);
|
||||
static int cmnd_insert_data_wait_hash(struct iscsi_cmnd *cmnd);
|
||||
static void __cmnd_abort(struct iscsi_cmnd *cmnd);
|
||||
static void iscsi_set_resid(struct iscsi_cmnd *rsp, bool bufflen_set);
|
||||
static void iscsi_cmnd_init_write(struct iscsi_cmnd *rsp, int flags);
|
||||
|
||||
static void req_del_from_write_timeout_list(struct iscsi_cmnd *req)
|
||||
@@ -720,6 +719,110 @@ static void iscsi_cmnd_init_write(struct iscsi_cmnd *rsp, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
static void iscsi_set_uni_resid(struct iscsi_cmnd *rsp,
|
||||
int exp_transf_len, int transf_len)
|
||||
{
|
||||
int resid;
|
||||
|
||||
resid = exp_transf_len - transf_len;
|
||||
if (unlikely(resid != 0)) {
|
||||
struct iscsi_scsi_rsp_hdr *rsp_hdr =
|
||||
(struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
|
||||
if (resid > 0) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
} else /* if (resid < 0) */ {
|
||||
resid = -resid;
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void iscsi_set_resid(struct iscsi_cmnd *rsp, bool no_read_transfer,
|
||||
bool no_write_transfer)
|
||||
{
|
||||
struct iscsi_cmnd *req = rsp->parent_req;
|
||||
struct scst_cmd *scst_cmd = req->scst_cmd;
|
||||
struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req);
|
||||
int resid, transf_len, exp_transf_len;
|
||||
|
||||
if ((req_hdr->flags & ISCSI_CMD_READ) &&
|
||||
(req_hdr->flags & ISCSI_CMD_WRITE)) {
|
||||
struct iscsi_scsi_rsp_hdr *rsp_hdr;
|
||||
int in_transf_len, in_exp_transf_len;
|
||||
|
||||
rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
|
||||
|
||||
if (likely(scst_cmd != NULL)) {
|
||||
exp_transf_len = scst_cmd_get_expected_transfer_len(scst_cmd);
|
||||
transf_len = scst_cmd_get_resp_data_len(scst_cmd);
|
||||
in_exp_transf_len = scst_cmd_get_expected_in_transfer_len(scst_cmd);
|
||||
in_transf_len = scst_cmd_get_in_bufflen(scst_cmd);
|
||||
} else {
|
||||
exp_transf_len = be32_to_cpu(req_hdr->data_length);
|
||||
transf_len = 0;
|
||||
in_exp_transf_len = cmnd_read_size(req);
|
||||
if (in_exp_transf_len < 0)
|
||||
in_exp_transf_len = 0;
|
||||
in_transf_len = 0;
|
||||
}
|
||||
if (unlikely(no_read_transfer))
|
||||
transf_len = 0;
|
||||
if (unlikely(no_write_transfer))
|
||||
in_transf_len = 0;
|
||||
|
||||
resid = exp_transf_len - transf_len;
|
||||
if (unlikely(resid != 0)) {
|
||||
if (resid > 0) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
} else /* if (resid < 0) */ {
|
||||
resid = -resid;
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
}
|
||||
}
|
||||
|
||||
resid = in_exp_transf_len - in_transf_len;
|
||||
if (unlikely(resid != 0)) {
|
||||
if (resid > 0) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_UNDERFLOW;
|
||||
rsp_hdr->bi_residual_count = cpu_to_be32(resid);
|
||||
} else /* if (resid < 0) */ {
|
||||
resid = -resid;
|
||||
rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_OVERFLOW;
|
||||
rsp_hdr->bi_residual_count = cpu_to_be32(resid);
|
||||
}
|
||||
}
|
||||
} else if (req_hdr->flags & ISCSI_CMD_READ) {
|
||||
if (likely(scst_cmd != NULL)) {
|
||||
exp_transf_len = scst_cmd_get_expected_transfer_len(scst_cmd);
|
||||
transf_len = scst_cmd_get_resp_data_len(scst_cmd);
|
||||
} else {
|
||||
exp_transf_len = be32_to_cpu(req_hdr->data_length);
|
||||
transf_len = 0;
|
||||
}
|
||||
if (unlikely(no_read_transfer))
|
||||
transf_len = 0;
|
||||
iscsi_set_uni_resid(rsp, exp_transf_len, transf_len);
|
||||
} else if (req_hdr->flags & ISCSI_CMD_WRITE) {
|
||||
if (scst_cmd != NULL) {
|
||||
exp_transf_len = scst_cmd_get_expected_transfer_len(scst_cmd);
|
||||
transf_len = scst_cmd_get_bufflen(scst_cmd);
|
||||
} else {
|
||||
exp_transf_len = be32_to_cpu(req_hdr->data_length);
|
||||
transf_len = 0;
|
||||
}
|
||||
if (unlikely(no_write_transfer))
|
||||
transf_len = 0;
|
||||
iscsi_set_uni_resid(rsp, exp_transf_len, transf_len);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
{
|
||||
struct iscsi_cmnd *rsp;
|
||||
@@ -731,7 +834,7 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
TRACE_DBG("req %p", req);
|
||||
|
||||
pdusize = req->conn->session->sess_params.max_xmit_data_length;
|
||||
expsize = req->read_size;
|
||||
expsize = scst_cmd_get_expected_transfer_len(req->scst_cmd);
|
||||
size = min(expsize, (u32)req->bufflen);
|
||||
offset = 0;
|
||||
sn = 0;
|
||||
@@ -754,8 +857,6 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
TRACE_DBG("offset %d, size %d", offset, size);
|
||||
rsp->pdu.datasize = size;
|
||||
if (send_status) {
|
||||
unsigned int scsisize;
|
||||
|
||||
TRACE_DBG("status %x", status);
|
||||
|
||||
EXTRACHECKS_BUG_ON((cmnd_hdr(req)->flags & ISCSI_CMD_WRITE) != 0);
|
||||
@@ -763,16 +864,7 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
rsp_hdr->flags = ISCSI_FLG_FINAL | ISCSI_FLG_STATUS;
|
||||
rsp_hdr->cmd_status = status;
|
||||
|
||||
scsisize = req->bufflen;
|
||||
if (scsisize < expsize) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
|
||||
size = expsize - scsisize;
|
||||
} else if (scsisize > expsize) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW;
|
||||
size = scsisize - expsize;
|
||||
} else
|
||||
size = 0;
|
||||
rsp_hdr->residual_count = cpu_to_be32(size);
|
||||
iscsi_set_uni_resid(rsp, expsize, req->bufflen);
|
||||
}
|
||||
list_add_tail(&rsp->write_list_entry, &send);
|
||||
break;
|
||||
@@ -794,7 +886,8 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
}
|
||||
|
||||
static void iscsi_init_status_rsp(struct iscsi_cmnd *rsp,
|
||||
int status, const u8 *sense_buf, int sense_len, bool bufflen_set)
|
||||
int status, const u8 *sense_buf, int sense_len,
|
||||
bool no_read_transfer, bool no_write_transfer)
|
||||
{
|
||||
struct iscsi_cmnd *req = rsp->parent_req;
|
||||
struct iscsi_scsi_rsp_hdr *rsp_hdr;
|
||||
@@ -829,14 +922,14 @@ static void iscsi_init_status_rsp(struct iscsi_cmnd *rsp,
|
||||
rsp->bufflen = 0;
|
||||
}
|
||||
|
||||
iscsi_set_resid(rsp, bufflen_set);
|
||||
iscsi_set_resid(rsp, no_read_transfer, no_write_transfer);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct iscsi_cmnd *create_status_rsp(struct iscsi_cmnd *req,
|
||||
int status, const u8 *sense_buf, int sense_len, bool bufflen_set)
|
||||
int status, const u8 *sense_buf, int sense_len, bool no_read_transfer)
|
||||
{
|
||||
struct iscsi_cmnd *rsp;
|
||||
|
||||
@@ -845,7 +938,8 @@ static inline struct iscsi_cmnd *create_status_rsp(struct iscsi_cmnd *req,
|
||||
rsp = iscsi_alloc_rsp(req);
|
||||
TRACE_DBG("rsp %p", rsp);
|
||||
|
||||
iscsi_init_status_rsp(rsp, status, sense_buf, sense_len, bufflen_set);
|
||||
iscsi_init_status_rsp(rsp, status, sense_buf, sense_len,
|
||||
no_read_transfer, false);
|
||||
|
||||
TRACE_EXIT_HRES((unsigned long)rsp);
|
||||
return rsp;
|
||||
@@ -861,7 +955,7 @@ static struct iscsi_cmnd *create_prelim_status_rsp(struct iscsi_cmnd *req,
|
||||
rsp = iscsi_alloc_main_rsp(req);
|
||||
TRACE_DBG("main rsp %p", rsp);
|
||||
|
||||
iscsi_init_status_rsp(rsp, status, sense_buf, sense_len, false);
|
||||
iscsi_init_status_rsp(rsp, status, sense_buf, sense_len, true, true);
|
||||
|
||||
TRACE_EXIT_HRES((unsigned long)rsp);
|
||||
return rsp;
|
||||
@@ -914,7 +1008,6 @@ static int create_preliminary_status_rsp(struct iscsi_cmnd *req,
|
||||
int status, const u8 *sense_buf, int sense_len)
|
||||
{
|
||||
int res = 0;
|
||||
struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req);
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -925,14 +1018,6 @@ static int create_preliminary_status_rsp(struct iscsi_cmnd *req,
|
||||
|
||||
req->scst_state = ISCSI_CMD_STATE_OUT_OF_SCST_PRELIM_COMPL;
|
||||
|
||||
if ((req_hdr->flags & ISCSI_CMD_READ) &&
|
||||
(req_hdr->flags & ISCSI_CMD_WRITE)) {
|
||||
int sz = cmnd_read_size(req);
|
||||
if (sz > 0)
|
||||
req->read_size = sz;
|
||||
} else if (req_hdr->flags & ISCSI_CMD_READ)
|
||||
req->read_size = be32_to_cpu(req_hdr->data_length);
|
||||
|
||||
create_prelim_status_rsp(req, status, sense_buf, sense_len);
|
||||
res = iscsi_preliminary_complete(req, req, true);
|
||||
|
||||
@@ -1270,68 +1355,6 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
static void iscsi_set_resid(struct iscsi_cmnd *rsp, bool bufflen_set)
|
||||
{
|
||||
struct iscsi_cmnd *req = rsp->parent_req;
|
||||
struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req);
|
||||
struct iscsi_scsi_rsp_hdr *rsp_hdr;
|
||||
int resid, resp_len, in_resp_len;
|
||||
|
||||
if ((req_hdr->flags & ISCSI_CMD_READ) &&
|
||||
(req_hdr->flags & ISCSI_CMD_WRITE)) {
|
||||
rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
|
||||
|
||||
if (bufflen_set) {
|
||||
resp_len = req->bufflen;
|
||||
if (req->scst_cmd != NULL)
|
||||
in_resp_len = scst_cmd_get_in_bufflen(req->scst_cmd);
|
||||
else
|
||||
in_resp_len = 0;
|
||||
} else {
|
||||
resp_len = 0;
|
||||
in_resp_len = 0;
|
||||
}
|
||||
|
||||
resid = be32_to_cpu(req_hdr->data_length) - in_resp_len;
|
||||
if (resid > 0) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
} else if (resid < 0) {
|
||||
resid = -resid;
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
}
|
||||
|
||||
resid = req->read_size - resp_len;
|
||||
if (resid > 0) {
|
||||
rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_UNDERFLOW;
|
||||
rsp_hdr->bi_residual_count = cpu_to_be32(resid);
|
||||
} else if (resid < 0) {
|
||||
resid = -resid;
|
||||
rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_OVERFLOW;
|
||||
rsp_hdr->bi_residual_count = cpu_to_be32(resid);
|
||||
}
|
||||
} else {
|
||||
if (bufflen_set)
|
||||
resp_len = req->bufflen;
|
||||
else
|
||||
resp_len = 0;
|
||||
|
||||
resid = req->read_size - resp_len;
|
||||
if (resid > 0) {
|
||||
rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
} else if (resid < 0) {
|
||||
rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
|
||||
resid = -resid;
|
||||
rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW;
|
||||
rsp_hdr->residual_count = cpu_to_be32(resid);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int iscsi_preliminary_complete(struct iscsi_cmnd *req,
|
||||
struct iscsi_cmnd *orig_req, bool get_data)
|
||||
{
|
||||
@@ -1835,7 +1858,6 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
|
||||
set_scst_preliminary_status_rsp(req, true,
|
||||
SCST_LOAD_SENSE(scst_sense_parameter_value_invalid));
|
||||
} else {
|
||||
req->read_size = sz;
|
||||
dir = SCST_DATA_BIDI;
|
||||
scst_cmd_set_expected(scst_cmd, dir, sz);
|
||||
scst_cmd_set_expected_in_transfer_len(scst_cmd,
|
||||
@@ -1845,9 +1867,9 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
|
||||
#endif
|
||||
}
|
||||
} else if (req_hdr->flags & ISCSI_CMD_READ) {
|
||||
req->read_size = be32_to_cpu(req_hdr->data_length);
|
||||
dir = SCST_DATA_READ;
|
||||
scst_cmd_set_expected(scst_cmd, dir, req->read_size);
|
||||
scst_cmd_set_expected(scst_cmd, dir,
|
||||
be32_to_cpu(req_hdr->data_length));
|
||||
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
|
||||
scst_cmd_set_tgt_need_alloc_data_buf(scst_cmd);
|
||||
#endif
|
||||
@@ -3193,13 +3215,13 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
|
||||
send_data_rsp(req, 0, 0);
|
||||
if (is_send_status) {
|
||||
rsp = create_status_rsp(req, status, sense,
|
||||
sense_len, true);
|
||||
sense_len, false);
|
||||
iscsi_cmnd_init_write(rsp, 0);
|
||||
}
|
||||
}
|
||||
} else if (is_send_status) {
|
||||
struct iscsi_cmnd *rsp;
|
||||
rsp = create_status_rsp(req, status, sense, sense_len, false);
|
||||
rsp = create_status_rsp(req, status, sense, sense_len, true);
|
||||
iscsi_cmnd_init_write(rsp, 0);
|
||||
}
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
|
||||
@@ -412,7 +412,6 @@ struct iscsi_cmnd {
|
||||
struct scst_cmd *scst_cmd;
|
||||
struct scst_aen *scst_aen;
|
||||
};
|
||||
unsigned int read_size;
|
||||
|
||||
struct iscsi_cmnd *main_rsp;
|
||||
};
|
||||
|
||||
@@ -1862,35 +1862,41 @@ static int q2t_pre_xmit_response(struct q2t_cmd *cmd,
|
||||
full_req_cnt = prm->req_cnt;
|
||||
|
||||
if (xmit_type & Q2T_XMIT_STATUS) {
|
||||
if (cmd->data_direction & SCST_DATA_READ) {
|
||||
int expected;
|
||||
if (IS_FWI2_CAPABLE(ha))
|
||||
expected = be32_to_cpu(cmd->
|
||||
atio.atio7.fcp_cmnd.data_length);
|
||||
if ((cmd->data_direction & SCST_DATA_READ) ||
|
||||
(cmd->data_direction & SCST_DATA_WRITE) ) {
|
||||
int expected = scst_cmd_get_expected_transfer_len(scst_cmd);
|
||||
/* Bidirectional transfers not supported (yet) */
|
||||
if (cmd->data_direction & SCST_DATA_READ)
|
||||
prm->residual = expected -
|
||||
scst_cmd_get_resp_data_len(scst_cmd);
|
||||
else if (likely(cmd->write_data_transferred))
|
||||
prm->residual = expected -
|
||||
scst_cmd_get_bufflen(scst_cmd);
|
||||
else
|
||||
expected = le32_to_cpu(cmd->
|
||||
atio.atio2x.data_length);
|
||||
prm->residual = expected -
|
||||
scst_cmd_get_resp_data_len(scst_cmd);
|
||||
if (prm->residual > 0) {
|
||||
TRACE_DBG("Residual underflow: %d (tag %lld, "
|
||||
"op %x, expected %d, resp_data_len "
|
||||
"%d, bufflen %d, rq_result %x)",
|
||||
prm->residual, scst_cmd->tag,
|
||||
scst_cmd->cdb[0], expected,
|
||||
scst_cmd_get_resp_data_len(scst_cmd),
|
||||
cmd->bufflen, prm->rq_result);
|
||||
prm->rq_result |= SS_RESIDUAL_UNDER;
|
||||
} else if (prm->residual < 0) {
|
||||
TRACE_DBG("Residual overflow: %d (tag %lld, "
|
||||
"op %x, expected %d, resp_data_len "
|
||||
"%d, bufflen %d, rq_result %x)",
|
||||
prm->residual, scst_cmd->tag,
|
||||
scst_cmd->cdb[0], expected,
|
||||
scst_cmd_get_resp_data_len(scst_cmd),
|
||||
cmd->bufflen, prm->rq_result);
|
||||
prm->rq_result |= SS_RESIDUAL_OVER;
|
||||
prm->residual = -prm->residual;
|
||||
prm->residual = expected;
|
||||
if (unlikely(prm->residual != 0)) {
|
||||
if (prm->residual > 0) {
|
||||
TRACE_DBG("Residual underflow: %d (tag "
|
||||
"%lld, op %x, expected %d, "
|
||||
"resp_data_len %d, bufflen %d, "
|
||||
"rq_result %x)", prm->residual,
|
||||
scst_cmd->tag, scst_cmd->cdb[0],
|
||||
expected,
|
||||
scst_cmd_get_resp_data_len(scst_cmd),
|
||||
cmd->bufflen, prm->rq_result);
|
||||
prm->rq_result |= SS_RESIDUAL_UNDER;
|
||||
} else /* if (prm->residual < 0) */ {
|
||||
TRACE_DBG("Residual overflow: %d (tag "
|
||||
"%lld, op %x, expected %d, "
|
||||
"resp_data_len %d, bufflen %d, "
|
||||
"rq_result %x)", prm->residual,
|
||||
scst_cmd->tag, scst_cmd->cdb[0],
|
||||
expected,
|
||||
scst_cmd_get_resp_data_len(scst_cmd),
|
||||
cmd->bufflen, prm->rq_result);
|
||||
prm->rq_result |= SS_RESIDUAL_OVER;
|
||||
prm->residual = -prm->residual;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2392,6 +2398,7 @@ static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
|
||||
{
|
||||
int res;
|
||||
struct q2t_cmd *cmd;
|
||||
int exp_len;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -2399,6 +2406,9 @@ static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
|
||||
|
||||
cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
|
||||
cmd->bufflen = scst_cmd_get_bufflen(scst_cmd);
|
||||
exp_len = scst_cmd_get_expected_transfer_len(scst_cmd);
|
||||
if (unlikely(cmd->bufflen > exp_len))
|
||||
cmd->bufflen = exp_len;
|
||||
cmd->sg = scst_cmd_get_sg(scst_cmd);
|
||||
cmd->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
|
||||
cmd->data_direction = scst_cmd_get_data_direction(scst_cmd);
|
||||
@@ -2885,6 +2895,8 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha, uint32_t handle,
|
||||
|
||||
if (unlikely(status != CTIO_SUCCESS))
|
||||
rx_status = SCST_RX_STATUS_ERROR;
|
||||
else
|
||||
cmd->write_data_transferred = 1;
|
||||
|
||||
TRACE_DBG("Data received, context %x, rx_status %d",
|
||||
context, rx_status);
|
||||
|
||||
@@ -198,6 +198,7 @@ struct q2t_cmd {
|
||||
unsigned int conf_compl_supported:1;/* to save extra sess dereferences */
|
||||
unsigned int free_sg:1;
|
||||
unsigned int aborted:1; /* Needed in case of SRR */
|
||||
unsigned int write_data_transferred:1;
|
||||
|
||||
struct scatterlist *sg; /* cmd data buffer SG vector */
|
||||
int sg_cnt; /* SG segments count */
|
||||
|
||||
@@ -1368,14 +1368,13 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
|
||||
cmd->host_status = host_byte(result);
|
||||
cmd->driver_status = driver_byte(result);
|
||||
if (unlikely(resid != 0)) {
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
if ((resid < 0) || (resid > cmd->resp_data_len)) {
|
||||
PRINT_ERROR("Wrong resid %d (cmd->resp_data_len=%d, "
|
||||
"op %x)", resid, cmd->resp_data_len,
|
||||
cmd->cdb[0]);
|
||||
} else
|
||||
#endif
|
||||
if ((cmd->data_direction & SCST_DATA_READ) &&
|
||||
(resid > 0) && (resid < cmd->resp_data_len))
|
||||
scst_set_resp_data_len(cmd, cmd->resp_data_len - resid);
|
||||
/*
|
||||
* We ignore write direction residue, because from our
|
||||
* initiator's POV we already transferred all the data.
|
||||
*/
|
||||
}
|
||||
|
||||
if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION)) {
|
||||
|
||||
Reference in New Issue
Block a user