Commit | Line | Data |
---|---|---|
fe45e630 CH |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_BLK_INTEGRITY_H | |
3 | #define _LINUX_BLK_INTEGRITY_H | |
4 | ||
5 | #include <linux/blk-mq.h> | |
6 | ||
7 | struct request; | |
8 | ||
9 | enum blk_integrity_flags { | |
10 | BLK_INTEGRITY_VERIFY = 1 << 0, | |
11 | BLK_INTEGRITY_GENERATE = 1 << 1, | |
12 | BLK_INTEGRITY_DEVICE_CAPABLE = 1 << 2, | |
13 | BLK_INTEGRITY_IP_CHECKSUM = 1 << 3, | |
14 | }; | |
15 | ||
16 | struct blk_integrity_iter { | |
17 | void *prot_buf; | |
18 | void *data_buf; | |
19 | sector_t seed; | |
20 | unsigned int data_size; | |
21 | unsigned short interval; | |
c340b990 | 22 | unsigned char tuple_size; |
fe45e630 CH |
23 | const char *disk_name; |
24 | }; | |
25 | ||
26 | typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *); | |
27 | typedef void (integrity_prepare_fn) (struct request *); | |
28 | typedef void (integrity_complete_fn) (struct request *, unsigned int); | |
29 | ||
30 | struct blk_integrity_profile { | |
31 | integrity_processing_fn *generate_fn; | |
32 | integrity_processing_fn *verify_fn; | |
33 | integrity_prepare_fn *prepare_fn; | |
34 | integrity_complete_fn *complete_fn; | |
35 | const char *name; | |
36 | }; | |
37 | ||
38 | #ifdef CONFIG_BLK_DEV_INTEGRITY | |
39 | void blk_integrity_register(struct gendisk *, struct blk_integrity *); | |
40 | void blk_integrity_unregister(struct gendisk *); | |
41 | int blk_integrity_compare(struct gendisk *, struct gendisk *); | |
42 | int blk_rq_map_integrity_sg(struct request_queue *, struct bio *, | |
43 | struct scatterlist *); | |
44 | int blk_rq_count_integrity_sg(struct request_queue *, struct bio *); | |
45 | ||
46 | static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) | |
47 | { | |
48 | struct blk_integrity *bi = &disk->queue->integrity; | |
49 | ||
50 | if (!bi->profile) | |
51 | return NULL; | |
52 | ||
53 | return bi; | |
54 | } | |
55 | ||
56 | static inline struct blk_integrity * | |
57 | bdev_get_integrity(struct block_device *bdev) | |
58 | { | |
59 | return blk_get_integrity(bdev->bd_disk); | |
60 | } | |
61 | ||
62 | static inline bool | |
63 | blk_integrity_queue_supports_integrity(struct request_queue *q) | |
64 | { | |
65 | return q->integrity.profile; | |
66 | } | |
67 | ||
68 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, | |
69 | unsigned int segs) | |
70 | { | |
71 | q->limits.max_integrity_segments = segs; | |
72 | } | |
73 | ||
74 | static inline unsigned short | |
75 | queue_max_integrity_segments(const struct request_queue *q) | |
76 | { | |
77 | return q->limits.max_integrity_segments; | |
78 | } | |
79 | ||
80 | /** | |
81 | * bio_integrity_intervals - Return number of integrity intervals for a bio | |
82 | * @bi: blk_integrity profile for device | |
83 | * @sectors: Size of the bio in 512-byte sectors | |
84 | * | |
85 | * Description: The block layer calculates everything in 512 byte | |
86 | * sectors but integrity metadata is done in terms of the data integrity | |
87 | * interval size of the storage device. Convert the block layer sectors | |
88 | * to the appropriate number of integrity intervals. | |
89 | */ | |
90 | static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi, | |
91 | unsigned int sectors) | |
92 | { | |
93 | return sectors >> (bi->interval_exp - 9); | |
94 | } | |
95 | ||
96 | static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi, | |
97 | unsigned int sectors) | |
98 | { | |
99 | return bio_integrity_intervals(bi, sectors) * bi->tuple_size; | |
100 | } | |
101 | ||
102 | static inline bool blk_integrity_rq(struct request *rq) | |
103 | { | |
104 | return rq->cmd_flags & REQ_INTEGRITY; | |
105 | } | |
106 | ||
107 | /* | |
108 | * Return the first bvec that contains integrity data. Only drivers that are | |
109 | * limited to a single integrity segment should use this helper. | |
110 | */ | |
111 | static inline struct bio_vec *rq_integrity_vec(struct request *rq) | |
112 | { | |
113 | if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1)) | |
114 | return NULL; | |
115 | return rq->bio->bi_integrity->bip_vec; | |
116 | } | |
117 | #else /* CONFIG_BLK_DEV_INTEGRITY */ | |
118 | static inline int blk_rq_count_integrity_sg(struct request_queue *q, | |
119 | struct bio *b) | |
120 | { | |
121 | return 0; | |
122 | } | |
123 | static inline int blk_rq_map_integrity_sg(struct request_queue *q, | |
124 | struct bio *b, | |
125 | struct scatterlist *s) | |
126 | { | |
127 | return 0; | |
128 | } | |
129 | static inline struct blk_integrity *bdev_get_integrity(struct block_device *b) | |
130 | { | |
131 | return NULL; | |
132 | } | |
133 | static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) | |
134 | { | |
135 | return NULL; | |
136 | } | |
137 | static inline bool | |
138 | blk_integrity_queue_supports_integrity(struct request_queue *q) | |
139 | { | |
140 | return false; | |
141 | } | |
142 | static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b) | |
143 | { | |
144 | return 0; | |
145 | } | |
146 | static inline void blk_integrity_register(struct gendisk *d, | |
147 | struct blk_integrity *b) | |
148 | { | |
149 | } | |
150 | static inline void blk_integrity_unregister(struct gendisk *d) | |
151 | { | |
152 | } | |
153 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, | |
154 | unsigned int segs) | |
155 | { | |
156 | } | |
157 | static inline unsigned short | |
158 | queue_max_integrity_segments(const struct request_queue *q) | |
159 | { | |
160 | return 0; | |
161 | } | |
162 | ||
163 | static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi, | |
164 | unsigned int sectors) | |
165 | { | |
166 | return 0; | |
167 | } | |
168 | ||
169 | static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi, | |
170 | unsigned int sectors) | |
171 | { | |
172 | return 0; | |
173 | } | |
174 | static inline int blk_integrity_rq(struct request *rq) | |
175 | { | |
176 | return 0; | |
177 | } | |
178 | ||
179 | static inline struct bio_vec *rq_integrity_vec(struct request *rq) | |
180 | { | |
181 | return NULL; | |
182 | } | |
183 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | |
184 | #endif /* _LINUX_BLK_INTEGRITY_H */ |