IB/srp: Fix residual handling
authorBart Van Assche <bvanassche@acm.org>
Wed, 9 Jul 2014 13:57:51 +0000 (15:57 +0200)
committerRoland Dreier <roland@purestorage.com>
Fri, 1 Aug 2014 22:21:51 +0000 (15:21 -0700)
From Documentation/scsi/scsi_mid_low_api.txt: "resid - an LLD should
set this signed integer to the requested transfer length (i.e.
'request_bufflen') less the number of bytes that are actually
transferred."  This means that resid > 0 in case of an underrun and
also that resid < 0 in case of an overrun.  Modify the SRP initiator
code such that it matches this requirement.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Reviewed-by: David Dillow <dave@thedillows.org>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/ulp/srp/ib_srp.c

index 767000811cf93c6aea99dc4ba217689311452939..7f5ee7fc02a66a152fb4be14d26e6f021482acf8 100644 (file)
@@ -1644,10 +1644,14 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                                     SCSI_SENSE_BUFFERSIZE));
                }
 
-               if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER))
-                       scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
-               else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
+               if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER))
                        scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
+               else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER))
+                       scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt));
+               else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER))
+                       scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
+               else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER))
+                       scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt));
 
                srp_free_req(target, req, scmnd,
                             be32_to_cpu(rsp->req_lim_delta));