1 | /* SPDX-License-Identifier: GPL-2.0 */ |
---|---|
2 | #ifndef _LINUX_T10_PI_H |
3 | #define _LINUX_T10_PI_H |
4 | |
5 | #include <linux/types.h> |
6 | #include <linux/blk-mq.h> |
7 | |
8 | /* |
9 | * A T10 PI-capable target device can be formatted with different |
10 | * protection schemes. Currently 0 through 3 are defined: |
11 | * |
12 | * Type 0 is regular (unprotected) I/O |
13 | * |
14 | * Type 1 defines the contents of the guard and reference tags |
15 | * |
16 | * Type 2 defines the contents of the guard and reference tags and |
17 | * uses 32-byte commands to seed the latter |
18 | * |
19 | * Type 3 defines the contents of the guard tag only |
20 | */ |
21 | enum t10_dif_type { |
22 | T10_PI_TYPE0_PROTECTION = 0x0, |
23 | T10_PI_TYPE1_PROTECTION = 0x1, |
24 | T10_PI_TYPE2_PROTECTION = 0x2, |
25 | T10_PI_TYPE3_PROTECTION = 0x3, |
26 | }; |
27 | |
28 | /* |
29 | * T10 Protection Information tuple. |
30 | */ |
31 | struct t10_pi_tuple { |
32 | __be16 guard_tag; /* Checksum */ |
33 | __be16 app_tag; /* Opaque storage */ |
34 | __be32 ref_tag; /* Target LBA or indirect LBA */ |
35 | }; |
36 | |
37 | #define T10_PI_APP_ESCAPE cpu_to_be16(0xffff) |
38 | #define T10_PI_REF_ESCAPE cpu_to_be32(0xffffffff) |
39 | |
40 | static inline u32 t10_pi_ref_tag(struct request *rq) |
41 | { |
42 | unsigned int shift = ilog2(queue_logical_block_size(rq->q)); |
43 | |
44 | #ifdef CONFIG_BLK_DEV_INTEGRITY |
45 | if (rq->q->integrity.interval_exp) |
46 | shift = rq->q->integrity.interval_exp; |
47 | #endif |
48 | return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff; |
49 | } |
50 | |
51 | extern const struct blk_integrity_profile t10_pi_type1_crc; |
52 | extern const struct blk_integrity_profile t10_pi_type1_ip; |
53 | extern const struct blk_integrity_profile t10_pi_type3_crc; |
54 | extern const struct blk_integrity_profile t10_pi_type3_ip; |
55 | |
56 | struct crc64_pi_tuple { |
57 | __be64 guard_tag; |
58 | __be16 app_tag; |
59 | __u8 ref_tag[6]; |
60 | }; |
61 | |
62 | /** |
63 | * lower_48_bits() - return bits 0-47 of a number |
64 | * @n: the number we're accessing |
65 | */ |
66 | static inline u64 lower_48_bits(u64 n) |
67 | { |
68 | return n & ((1ull << 48) - 1); |
69 | } |
70 | |
71 | static inline u64 ext_pi_ref_tag(struct request *rq) |
72 | { |
73 | unsigned int shift = ilog2(queue_logical_block_size(rq->q)); |
74 | |
75 | #ifdef CONFIG_BLK_DEV_INTEGRITY |
76 | if (rq->q->integrity.interval_exp) |
77 | shift = rq->q->integrity.interval_exp; |
78 | #endif |
79 | return lower_48_bits(n: blk_rq_pos(rq) >> (shift - SECTOR_SHIFT)); |
80 | } |
81 | |
82 | extern const struct blk_integrity_profile ext_pi_type1_crc64; |
83 | extern const struct blk_integrity_profile ext_pi_type3_crc64; |
84 | |
85 | #endif |
86 |