linux/include/linux/raid/pq.h

/* SPDX-License-Identifier: GPL-2.0-or-later */
/* -*- linux-c -*- ------------------------------------------------------- *
 *
 *   Copyright 2003 H. Peter Anvin - All Rights Reserved
 *
 * ----------------------------------------------------------------------- */

#ifndef LINUX_RAID_RAID6_H
#define LINUX_RAID_RAID6_H

#ifdef __KERNEL__

#include <linux/blkdev.h>

extern const char raid6_empty_zero_page[PAGE_SIZE];

#else /* ! __KERNEL__ */
/* Used for testing in user space */

#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>

/* Not standard, but glibc defines it */
#define BITS_PER_LONG

typedef uint8_t  u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

#ifndef PAGE_SIZE
#define PAGE_SIZE
#endif
#ifndef PAGE_SHIFT
#define PAGE_SHIFT
#endif
extern const char raid6_empty_zero_page[PAGE_SIZE];

#define __init
#define __exit
#ifndef __attribute_const__
#define __attribute_const__
#endif
#define noinline

#define preempt_enable
#define preempt_disable
#define cpu_has_feature
#define enable_kernel_altivec
#define disable_kernel_altivec

#undef	EXPORT_SYMBOL
#define EXPORT_SYMBOL
#undef	EXPORT_SYMBOL_GPL
#define EXPORT_SYMBOL_GPL
#define MODULE_LICENSE
#define MODULE_DESCRIPTION
#define subsys_initcall
#define module_exit

#define IS_ENABLED
#define CONFIG_RAID6_PQ_BENCHMARK
#endif /* __KERNEL__ */

/* Routine choices */
struct raid6_calls {};

/* Selected algorithm */
extern struct raid6_calls raid6_call;

/* Various routine sets */
extern const struct raid6_calls raid6_intx1;
extern const struct raid6_calls raid6_intx2;
extern const struct raid6_calls raid6_intx4;
extern const struct raid6_calls raid6_intx8;
extern const struct raid6_calls raid6_mmxx1;
extern const struct raid6_calls raid6_mmxx2;
extern const struct raid6_calls raid6_sse1x1;
extern const struct raid6_calls raid6_sse1x2;
extern const struct raid6_calls raid6_sse2x1;
extern const struct raid6_calls raid6_sse2x2;
extern const struct raid6_calls raid6_sse2x4;
extern const struct raid6_calls raid6_altivec1;
extern const struct raid6_calls raid6_altivec2;
extern const struct raid6_calls raid6_altivec4;
extern const struct raid6_calls raid6_altivec8;
extern const struct raid6_calls raid6_avx2x1;
extern const struct raid6_calls raid6_avx2x2;
extern const struct raid6_calls raid6_avx2x4;
extern const struct raid6_calls raid6_avx512x1;
extern const struct raid6_calls raid6_avx512x2;
extern const struct raid6_calls raid6_avx512x4;
extern const struct raid6_calls raid6_s390vx8;
extern const struct raid6_calls raid6_vpermxor1;
extern const struct raid6_calls raid6_vpermxor2;
extern const struct raid6_calls raid6_vpermxor4;
extern const struct raid6_calls raid6_vpermxor8;
extern const struct raid6_calls raid6_lsx;
extern const struct raid6_calls raid6_lasx;

struct raid6_recov_calls {};

extern const struct raid6_recov_calls raid6_recov_intx1;
extern const struct raid6_recov_calls raid6_recov_ssse3;
extern const struct raid6_recov_calls raid6_recov_avx2;
extern const struct raid6_recov_calls raid6_recov_avx512;
extern const struct raid6_recov_calls raid6_recov_s390xc;
extern const struct raid6_recov_calls raid6_recov_neon;
extern const struct raid6_recov_calls raid6_recov_lsx;
extern const struct raid6_recov_calls raid6_recov_lasx;

extern const struct raid6_calls raid6_neonx1;
extern const struct raid6_calls raid6_neonx2;
extern const struct raid6_calls raid6_neonx4;
extern const struct raid6_calls raid6_neonx8;

/* Algorithm list */
extern const struct raid6_calls * const raid6_algos[];
extern const struct raid6_recov_calls *const raid6_recov_algos[];
int raid6_select_algo(void);

/* Return values from chk_syndrome */
#define RAID6_OK
#define RAID6_P_BAD
#define RAID6_Q_BAD
#define RAID6_PQ_BAD

/* Galois field tables */
extern const u8 raid6_gfmul[256][256] __attribute__((aligned));
extern const u8 raid6_vgfmul[256][32] __attribute__((aligned));
extern const u8 raid6_gfexp[256]      __attribute__((aligned));
extern const u8 raid6_gflog[256]      __attribute__((aligned));
extern const u8 raid6_gfinv[256]      __attribute__((aligned));
extern const u8 raid6_gfexi[256]      __attribute__((aligned));

/* Recovery routines */
extern void (*raid6_2data_recov)(int disks, size_t bytes, int faila, int failb,
		       void **ptrs);
extern void (*raid6_datap_recov)(int disks, size_t bytes, int faila,
			void **ptrs);
void raid6_dual_recov(int disks, size_t bytes, int faila, int failb,
		      void **ptrs);

/* Some definitions to allow code to be compiled for testing in userspace */
#ifndef __KERNEL__

#define jiffies
#define printk
#define pr_err
#define pr_info
#define GFP_KERNEL
#define __get_free_pages
#define free_pages

static inline void cpu_relax(void)
{
	/* Nothing */
}

#undef  HZ
#define HZ
static inline uint32_t raid6_jiffies(void)
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return tv.tv_sec*1000 + tv.tv_usec/1000;
}

#endif /* ! __KERNEL__ */

#endif /* LINUX_RAID_RAID6_H */