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@xxxxxxxxxxxx> > Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx> > --- > 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 */ > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html