Re: [PATCH v2 1/3] scsi_cmnd: Introduce scsi_transfer_length helper

Mike Christie
2014-06-23T21:24:31Z

On 06/11/2014 04:09 AM, Sagi Grimberg wrote:
> In case protection information exists on the wire
> scsi transports should include it in the transfer
> byte count (even if protection information does not
> exist in the host memory space). This helper will
> compute the total transfer length from the scsi
> command data length and protection attributes.
>
> Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> ---
> include/scsi/scsi_cmnd.h | 17 +++++++++++++++++
> 1 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
> index dd7c998..a100c6e 100644
> --- a/include/scsi/scsi_cmnd.h
> +++ b/include/scsi/scsi_cmnd.h
> @@ -7,6 +7,7 @@
> #include <linux/types.h>
> #include <linux/timer.h>
> #include <linux/scatterlist.h>
> +#include <scsi/scsi_device.h>
>
> struct Scsi_Host;
> struct scsi_device;
> @@ -306,4 +307,20 @@ static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
> cmd->result = (cmd->result & 0x00ffffff) | (status << 24);
> }
>
> +static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
> +{
> + unsigned int xfer_len = blk_rq_bytes(scmd->request);

Can you do bidi and dif/dix? If so, then instead of using blk_rq_bytes
directly should it use the scsi_out/scsi_in macros and access the length
through the scsi_data_buffer?

This does not fix Christoph's bug in the other mail. Just noticed it
while looking at the code.

> + unsigned int prot_op = scsi_get_prot_op(scmd);
> + unsigned int sector_size = scmd->device->sector_size;
> +
> + switch (prot_op) {
> + case SCSI_PROT_NORMAL:
> + case SCSI_PROT_WRITE_STRIP:
> + case SCSI_PROT_READ_INSERT:
> + return xfer_len;
> + }
> +
> + return xfer_len + (xfer_len >> ilog2(sector_size)) * 8;
> +}
> +
> #endif /* _SCSI_SCSI_CMND_H */
>