Merge remote-tracking branches 'asoc/topic/adav80x', 'asoc/topic/adsp', 'asoc/topic...
[cascardo/linux.git] / include / scsi / scsi_cmnd.h
index 73f3490..522a5f2 100644 (file)
 #include <scsi/scsi_device.h>
 
 struct Scsi_Host;
-struct scsi_device;
 struct scsi_driver;
 
+#include <scsi/scsi_device.h>
+
 /*
  * MAX_COMMAND_SIZE is:
  * The longest fixed-length SCSI CDB as per the SCSI standard.
@@ -81,6 +82,7 @@ struct scsi_cmnd {
 
        unsigned char prot_op;
        unsigned char prot_type;
+       unsigned char prot_flags;
 
        unsigned short cmd_len;
        enum dma_data_direction sc_data_direction;
@@ -252,6 +254,14 @@ static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd)
        return scmd->prot_op;
 }
 
+enum scsi_prot_flags {
+       SCSI_PROT_TRANSFER_PI           = 1 << 0,
+       SCSI_PROT_GUARD_CHECK           = 1 << 1,
+       SCSI_PROT_REF_CHECK             = 1 << 2,
+       SCSI_PROT_REF_INCREMENT         = 1 << 3,
+       SCSI_PROT_IP_CHECKSUM           = 1 << 4,
+};
+
 /*
  * The controller usually does not know anything about the target it
  * is communicating with.  However, when DIX is enabled the controller
@@ -280,6 +290,17 @@ static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
        return blk_rq_pos(scmd->request);
 }
 
+static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd)
+{
+       return scmd->device->sector_size;
+}
+
+static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd)
+{
+       return blk_rq_pos(scmd->request) >>
+               (ilog2(scsi_prot_interval(scmd)) - 9) & 0xffffffff;
+}
+
 static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd)
 {
        return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0;
@@ -316,17 +337,12 @@ static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
 static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
 {
        unsigned int xfer_len = scsi_out(scmd)->length;
-       unsigned int prot_op = scsi_get_prot_op(scmd);
-       unsigned int sector_size = scmd->device->sector_size;
+       unsigned int prot_interval = scsi_prot_interval(scmd);
 
-       switch (prot_op) {
-       case SCSI_PROT_NORMAL:
-       case SCSI_PROT_WRITE_STRIP:
-       case SCSI_PROT_READ_INSERT:
-               return xfer_len;
-       }
+       if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
+               xfer_len += (xfer_len >> ilog2(prot_interval)) * 8;
 
-       return xfer_len + (xfer_len >> ilog2(sector_size)) * 8;
+       return xfer_len;
 }
 
 #endif /* _SCSI_SCSI_CMND_H */