xref: /linux/lib/raid/xor/xor_impl.h (revision 440d6635b20037bc9ad46b20817d7b61cef0fc1b)
1e20043b4SChristoph Hellwig /* SPDX-License-Identifier: GPL-2.0 */
2e20043b4SChristoph Hellwig #ifndef _XOR_IMPL_H
3e20043b4SChristoph Hellwig #define _XOR_IMPL_H
4e20043b4SChristoph Hellwig 
5e20043b4SChristoph Hellwig #include <linux/init.h>
6*80dcf0a7SChristoph Hellwig #include <linux/minmax.h>
7e20043b4SChristoph Hellwig 
8e20043b4SChristoph Hellwig struct xor_block_template {
9e20043b4SChristoph Hellwig 	struct xor_block_template *next;
10e20043b4SChristoph Hellwig 	const char *name;
11e20043b4SChristoph Hellwig 	int speed;
12*80dcf0a7SChristoph Hellwig 	void (*xor_gen)(void *dest, void **srcs, unsigned int src_cnt,
13*80dcf0a7SChristoph Hellwig 			unsigned int bytes);
14e20043b4SChristoph Hellwig };
15e20043b4SChristoph Hellwig 
16*80dcf0a7SChristoph Hellwig #define __DO_XOR_BLOCKS(_name, _handle1, _handle2, _handle3, _handle4)	\
17*80dcf0a7SChristoph Hellwig void								\
18*80dcf0a7SChristoph Hellwig xor_gen_##_name(void *dest, void **srcs, unsigned int src_cnt,		\
19*80dcf0a7SChristoph Hellwig 		unsigned int bytes)					\
20*80dcf0a7SChristoph Hellwig {									\
21*80dcf0a7SChristoph Hellwig 	unsigned int src_off = 0;					\
22*80dcf0a7SChristoph Hellwig 									\
23*80dcf0a7SChristoph Hellwig 	while (src_cnt > 0) {						\
24*80dcf0a7SChristoph Hellwig 		unsigned int this_cnt = min(src_cnt, 4);		\
25*80dcf0a7SChristoph Hellwig 									\
26*80dcf0a7SChristoph Hellwig 		if (this_cnt == 1)					\
27*80dcf0a7SChristoph Hellwig 			_handle1(bytes, dest, srcs[src_off]);		\
28*80dcf0a7SChristoph Hellwig 		else if (this_cnt == 2)					\
29*80dcf0a7SChristoph Hellwig 			_handle2(bytes, dest, srcs[src_off],		\
30*80dcf0a7SChristoph Hellwig 				srcs[src_off + 1]);			\
31*80dcf0a7SChristoph Hellwig 		else if (this_cnt == 3)					\
32*80dcf0a7SChristoph Hellwig 			_handle3(bytes, dest, srcs[src_off],		\
33*80dcf0a7SChristoph Hellwig 				srcs[src_off + 1], srcs[src_off + 2]);	\
34*80dcf0a7SChristoph Hellwig 		else							\
35*80dcf0a7SChristoph Hellwig 			_handle4(bytes, dest, srcs[src_off],		\
36*80dcf0a7SChristoph Hellwig 				srcs[src_off + 1], srcs[src_off + 2],	\
37*80dcf0a7SChristoph Hellwig 				srcs[src_off + 3]);			\
38*80dcf0a7SChristoph Hellwig 									\
39*80dcf0a7SChristoph Hellwig 		src_cnt -= this_cnt;					\
40*80dcf0a7SChristoph Hellwig 		src_off += this_cnt;					\
41*80dcf0a7SChristoph Hellwig 	}								\
42*80dcf0a7SChristoph Hellwig }
43*80dcf0a7SChristoph Hellwig 
44*80dcf0a7SChristoph Hellwig #define DO_XOR_BLOCKS(_name, _handle1, _handle2, _handle3, _handle4)	\
45*80dcf0a7SChristoph Hellwig 	static __DO_XOR_BLOCKS(_name, _handle1, _handle2, _handle3, _handle4)
46*80dcf0a7SChristoph Hellwig 
47e20043b4SChristoph Hellwig /* generic implementations */
48e20043b4SChristoph Hellwig extern struct xor_block_template xor_block_8regs;
49e20043b4SChristoph Hellwig extern struct xor_block_template xor_block_32regs;
50e20043b4SChristoph Hellwig extern struct xor_block_template xor_block_8regs_p;
51e20043b4SChristoph Hellwig extern struct xor_block_template xor_block_32regs_p;
52e20043b4SChristoph Hellwig 
53e20043b4SChristoph Hellwig void __init xor_register(struct xor_block_template *tmpl);
54e20043b4SChristoph Hellwig void __init xor_force(struct xor_block_template *tmpl);
55e20043b4SChristoph Hellwig 
56e20043b4SChristoph Hellwig #endif /* _XOR_IMPL_H */
57