1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _VSTRUCTS_H |
3 | #define _VSTRUCTS_H |
4 | |
5 | #include "util.h" |
6 | |
7 | /* |
8 | * NOTE: we can't differentiate between __le64 and u64 with type_is - this |
9 | * assumes u64 is little endian: |
10 | */ |
11 | #define __vstruct_u64s(_s) \ |
12 | ({ \ |
13 | ( type_is((_s)->u64s, u64) ? le64_to_cpu((__force __le64) (_s)->u64s) \ |
14 | : type_is((_s)->u64s, u32) ? le32_to_cpu((__force __le32) (_s)->u64s) \ |
15 | : type_is((_s)->u64s, u16) ? le16_to_cpu((__force __le16) (_s)->u64s) \ |
16 | : ((__force u8) ((_s)->u64s))); \ |
17 | }) |
18 | |
19 | #define __vstruct_bytes(_type, _u64s) \ |
20 | ({ \ |
21 | BUILD_BUG_ON(offsetof(_type, _data) % sizeof(u64)); \ |
22 | \ |
23 | (size_t) (offsetof(_type, _data) + (_u64s) * sizeof(u64)); \ |
24 | }) |
25 | |
26 | #define vstruct_bytes(_s) \ |
27 | __vstruct_bytes(typeof(*(_s)), __vstruct_u64s(_s)) |
28 | |
29 | #define __vstruct_blocks(_type, _sector_block_bits, _u64s) \ |
30 | (round_up(__vstruct_bytes(_type, _u64s), \ |
31 | 512 << (_sector_block_bits)) >> (9 + (_sector_block_bits))) |
32 | |
33 | #define vstruct_blocks(_s, _sector_block_bits) \ |
34 | __vstruct_blocks(typeof(*(_s)), _sector_block_bits, __vstruct_u64s(_s)) |
35 | |
36 | #define vstruct_blocks_plus(_s, _sector_block_bits, _u64s) \ |
37 | __vstruct_blocks(typeof(*(_s)), _sector_block_bits, \ |
38 | __vstruct_u64s(_s) + (_u64s)) |
39 | |
40 | #define vstruct_sectors(_s, _sector_block_bits) \ |
41 | (round_up(vstruct_bytes(_s), 512 << (_sector_block_bits)) >> 9) |
42 | |
43 | #define vstruct_next(_s) \ |
44 | ((typeof(_s)) ((u64 *) (_s)->_data + __vstruct_u64s(_s))) |
45 | #define vstruct_last(_s) \ |
46 | ((typeof(&(_s)->start[0])) ((u64 *) (_s)->_data + __vstruct_u64s(_s))) |
47 | #define vstruct_end(_s) \ |
48 | ((void *) ((u64 *) (_s)->_data + __vstruct_u64s(_s))) |
49 | |
50 | #define vstruct_for_each(_s, _i) \ |
51 | for (typeof(&(_s)->start[0]) _i = (_s)->start; \ |
52 | _i < vstruct_last(_s); \ |
53 | _i = vstruct_next(_i)) |
54 | |
55 | #define vstruct_for_each_safe(_s, _i) \ |
56 | for (typeof(&(_s)->start[0]) _next, _i = (_s)->start; \ |
57 | _i < vstruct_last(_s) && (_next = vstruct_next(_i), true); \ |
58 | _i = _next) |
59 | |
60 | #define vstruct_idx(_s, _idx) \ |
61 | ((typeof(&(_s)->start[0])) ((_s)->_data + (_idx))) |
62 | |
63 | #endif /* _VSTRUCTS_H */ |
64 | |