| From 1e0823146443a8b3e5cef6f4b3e57cd9edce1b70 Mon Sep 17 00:00:00 2001 |
| From: Bart Van Assche <bvanassche@acm.org> |
| Date: Tue, 5 Nov 2019 13:46:32 -0800 |
| Subject: [PATCH] RDMA/srpt: Report the SCSI residual to the initiator |
| |
| commit e88982ad1bb12db699de96fbc07096359ef6176c upstream. |
| |
| The code added by this patch is similar to the code that already exists in |
| ibmvscsis_determine_resid(). This patch has been tested by running the |
| following command: |
| |
| strace sg_raw -r 1k /dev/sdb 12 00 00 00 60 00 -o inquiry.bin |& |
| grep resid= |
| |
| Link: https://lore.kernel.org/r/20191105214632.183302-1-bvanassche@acm.org |
| Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") |
| Signed-off-by: Bart Van Assche <bvanassche@acm.org> |
| Acked-by: Honggang Li <honli@redhat.com> |
| Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c |
| index 1a039f16d315..7b9ff07d9118 100644 |
| --- a/drivers/infiniband/ulp/srpt/ib_srpt.c |
| +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c |
| @@ -1364,9 +1364,11 @@ static int srpt_build_cmd_rsp(struct srpt_rdma_ch *ch, |
| struct srpt_send_ioctx *ioctx, u64 tag, |
| int status) |
| { |
| + struct se_cmd *cmd = &ioctx->cmd; |
| struct srp_rsp *srp_rsp; |
| const u8 *sense_data; |
| int sense_data_len, max_sense_len; |
| + u32 resid = cmd->residual_count; |
| |
| /* |
| * The lowest bit of all SAM-3 status codes is zero (see also |
| @@ -1388,6 +1390,28 @@ static int srpt_build_cmd_rsp(struct srpt_rdma_ch *ch, |
| srp_rsp->tag = tag; |
| srp_rsp->status = status; |
| |
| + if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { |
| + if (cmd->data_direction == DMA_TO_DEVICE) { |
| + /* residual data from an underflow write */ |
| + srp_rsp->flags = SRP_RSP_FLAG_DOUNDER; |
| + srp_rsp->data_out_res_cnt = cpu_to_be32(resid); |
| + } else if (cmd->data_direction == DMA_FROM_DEVICE) { |
| + /* residual data from an underflow read */ |
| + srp_rsp->flags = SRP_RSP_FLAG_DIUNDER; |
| + srp_rsp->data_in_res_cnt = cpu_to_be32(resid); |
| + } |
| + } else if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { |
| + if (cmd->data_direction == DMA_TO_DEVICE) { |
| + /* residual data from an overflow write */ |
| + srp_rsp->flags = SRP_RSP_FLAG_DOOVER; |
| + srp_rsp->data_out_res_cnt = cpu_to_be32(resid); |
| + } else if (cmd->data_direction == DMA_FROM_DEVICE) { |
| + /* residual data from an overflow read */ |
| + srp_rsp->flags = SRP_RSP_FLAG_DIOVER; |
| + srp_rsp->data_in_res_cnt = cpu_to_be32(resid); |
| + } |
| + } |
| + |
| if (sense_data_len) { |
| BUILD_BUG_ON(MIN_MAX_RSP_SIZE <= sizeof(*srp_rsp)); |
| max_sense_len = ch->max_ti_iu_len - sizeof(*srp_rsp); |
| -- |
| 2.7.4 |
| |