Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_T10_PI_H
0003 #define _LINUX_T10_PI_H
0004 
0005 #include <linux/types.h>
0006 #include <linux/blk-mq.h>
0007 
0008 /*
0009  * A T10 PI-capable target device can be formatted with different
0010  * protection schemes.  Currently 0 through 3 are defined:
0011  *
0012  * Type 0 is regular (unprotected) I/O
0013  *
0014  * Type 1 defines the contents of the guard and reference tags
0015  *
0016  * Type 2 defines the contents of the guard and reference tags and
0017  * uses 32-byte commands to seed the latter
0018  *
0019  * Type 3 defines the contents of the guard tag only
0020  */
0021 enum t10_dif_type {
0022     T10_PI_TYPE0_PROTECTION = 0x0,
0023     T10_PI_TYPE1_PROTECTION = 0x1,
0024     T10_PI_TYPE2_PROTECTION = 0x2,
0025     T10_PI_TYPE3_PROTECTION = 0x3,
0026 };
0027 
0028 /*
0029  * T10 Protection Information tuple.
0030  */
0031 struct t10_pi_tuple {
0032     __be16 guard_tag;   /* Checksum */
0033     __be16 app_tag;     /* Opaque storage */
0034     __be32 ref_tag;     /* Target LBA or indirect LBA */
0035 };
0036 
0037 #define T10_PI_APP_ESCAPE cpu_to_be16(0xffff)
0038 #define T10_PI_REF_ESCAPE cpu_to_be32(0xffffffff)
0039 
0040 static inline u32 t10_pi_ref_tag(struct request *rq)
0041 {
0042     unsigned int shift = ilog2(queue_logical_block_size(rq->q));
0043 
0044 #ifdef CONFIG_BLK_DEV_INTEGRITY
0045     if (rq->q->integrity.interval_exp)
0046         shift = rq->q->integrity.interval_exp;
0047 #endif
0048     return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff;
0049 }
0050 
0051 extern const struct blk_integrity_profile t10_pi_type1_crc;
0052 extern const struct blk_integrity_profile t10_pi_type1_ip;
0053 extern const struct blk_integrity_profile t10_pi_type3_crc;
0054 extern const struct blk_integrity_profile t10_pi_type3_ip;
0055 
0056 struct crc64_pi_tuple {
0057     __be64 guard_tag;
0058     __be16 app_tag;
0059     __u8   ref_tag[6];
0060 };
0061 
0062 /**
0063  * lower_48_bits() - return bits 0-47 of a number
0064  * @n: the number we're accessing
0065  */
0066 static inline u64 lower_48_bits(u64 n)
0067 {
0068     return n & ((1ull << 48) - 1);
0069 }
0070 
0071 static inline u64 ext_pi_ref_tag(struct request *rq)
0072 {
0073     unsigned int shift = ilog2(queue_logical_block_size(rq->q));
0074 
0075 #ifdef CONFIG_BLK_DEV_INTEGRITY
0076     if (rq->q->integrity.interval_exp)
0077         shift = rq->q->integrity.interval_exp;
0078 #endif
0079     return lower_48_bits(blk_rq_pos(rq) >> (shift - SECTOR_SHIFT));
0080 }
0081 
0082 extern const struct blk_integrity_profile ext_pi_type1_crc64;
0083 extern const struct blk_integrity_profile ext_pi_type3_crc64;
0084 
0085 #endif