aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2014-09-26 19:20:08 -0400
committerJens Axboe <axboe@fb.com>2014-09-30 17:17:35 -0400
commitc611529e7cd3465ec0eada0f44200e8420c38908 (patch)
treec1cbfbd9b3229906ec36c897761d06e1521823bd /include/scsi
parent582940508b5d589229d0232e0eeee8fef0d54809 (diff)
sd: Honor block layer integrity handling flags
A set of flags introduced in the block layer enable better control over how protection information is handled. These flags are useful for both error injection and data recovery purposes. Checking can be enabled and disabled for controller and disk, and the guard tag format is now a per-I/O property. Update sd_protect_op to communicate the relevant information to the low-level device driver via a set of flags in scsi_cmnd. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/scsi_cmnd.h36
1 files changed, 26 insertions, 10 deletions
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 73f349044941..522a5f27f553 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -10,9 +10,10 @@
10#include <scsi/scsi_device.h> 10#include <scsi/scsi_device.h>
11 11
12struct Scsi_Host; 12struct Scsi_Host;
13struct scsi_device;
14struct scsi_driver; 13struct scsi_driver;
15 14
15#include <scsi/scsi_device.h>
16
16/* 17/*
17 * MAX_COMMAND_SIZE is: 18 * MAX_COMMAND_SIZE is:
18 * The longest fixed-length SCSI CDB as per the SCSI standard. 19 * The longest fixed-length SCSI CDB as per the SCSI standard.
@@ -81,6 +82,7 @@ struct scsi_cmnd {
81 82
82 unsigned char prot_op; 83 unsigned char prot_op;
83 unsigned char prot_type; 84 unsigned char prot_type;
85 unsigned char prot_flags;
84 86
85 unsigned short cmd_len; 87 unsigned short cmd_len;
86 enum dma_data_direction sc_data_direction; 88 enum dma_data_direction sc_data_direction;
@@ -252,6 +254,14 @@ static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd)
252 return scmd->prot_op; 254 return scmd->prot_op;
253} 255}
254 256
257enum scsi_prot_flags {
258 SCSI_PROT_TRANSFER_PI = 1 << 0,
259 SCSI_PROT_GUARD_CHECK = 1 << 1,
260 SCSI_PROT_REF_CHECK = 1 << 2,
261 SCSI_PROT_REF_INCREMENT = 1 << 3,
262 SCSI_PROT_IP_CHECKSUM = 1 << 4,
263};
264
255/* 265/*
256 * The controller usually does not know anything about the target it 266 * The controller usually does not know anything about the target it
257 * is communicating with. However, when DIX is enabled the controller 267 * 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)
280 return blk_rq_pos(scmd->request); 290 return blk_rq_pos(scmd->request);
281} 291}
282 292
293static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd)
294{
295 return scmd->device->sector_size;
296}
297
298static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd)
299{
300 return blk_rq_pos(scmd->request) >>
301 (ilog2(scsi_prot_interval(scmd)) - 9) & 0xffffffff;
302}
303
283static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd) 304static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd)
284{ 305{
285 return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0; 306 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)
316static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) 337static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
317{ 338{
318 unsigned int xfer_len = scsi_out(scmd)->length; 339 unsigned int xfer_len = scsi_out(scmd)->length;
319 unsigned int prot_op = scsi_get_prot_op(scmd); 340 unsigned int prot_interval = scsi_prot_interval(scmd);
320 unsigned int sector_size = scmd->device->sector_size;
321 341
322 switch (prot_op) { 342 if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
323 case SCSI_PROT_NORMAL: 343 xfer_len += (xfer_len >> ilog2(prot_interval)) * 8;
324 case SCSI_PROT_WRITE_STRIP:
325 case SCSI_PROT_READ_INSERT:
326 return xfer_len;
327 }
328 344
329 return xfer_len + (xfer_len >> ilog2(sector_size)) * 8; 345 return xfer_len;
330} 346}
331 347
332#endif /* _SCSI_SCSI_CMND_H */ 348#endif /* _SCSI_SCSI_CMND_H */