linux/drivers/dma/dmatest.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * DMA Engine test module
 *
 * Copyright (C) 2007 Atmel Corporation
 * Copyright (C) 2013 Intel Corporation
 */
#define pr_fmt(fmt)

#include <linux/err.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/freezer.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/sched/task.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/wait.h>

static bool nobounce;
module_param(nobounce, bool, 0644);
MODULE_PARM_DESC();

static unsigned int test_buf_size =;
module_param(test_buf_size, uint, 0644);
MODULE_PARM_DESC();

static char test_device[32];
module_param_string();
MODULE_PARM_DESC();

static unsigned int threads_per_chan =;
module_param(threads_per_chan, uint, 0644);
MODULE_PARM_DESC();

static unsigned int max_channels;
module_param(max_channels, uint, 0644);
MODULE_PARM_DESC();

static unsigned int iterations;
module_param(iterations, uint, 0644);
MODULE_PARM_DESC();

static unsigned int dmatest;
module_param(dmatest, uint, 0644);
MODULE_PARM_DESC();

static unsigned int xor_sources =;
module_param(xor_sources, uint, 0644);
MODULE_PARM_DESC();

static unsigned int pq_sources =;
module_param(pq_sources, uint, 0644);
MODULE_PARM_DESC();

static int timeout =;
module_param(timeout, int, 0644);
MODULE_PARM_DESC();

static bool noverify;
module_param(noverify, bool, 0644);
MODULE_PARM_DESC();

static bool norandom;
module_param(norandom, bool, 0644);
MODULE_PARM_DESC();

static bool verbose;
module_param(verbose, bool, 0644);
MODULE_PARM_DESC();

static int alignment =;
module_param(alignment, int, 0644);
MODULE_PARM_DESC();

static unsigned int transfer_size;
module_param(transfer_size, uint, 0644);
MODULE_PARM_DESC();

static bool polled;
module_param(polled, bool, 0644);
MODULE_PARM_DESC();

/**
 * struct dmatest_params - test parameters.
 * @nobounce:		prevent using swiotlb buffer
 * @buf_size:		size of the memcpy test buffer
 * @channel:		bus ID of the channel to test
 * @device:		bus ID of the DMA Engine to test
 * @threads_per_chan:	number of threads to start per channel
 * @max_channels:	maximum number of channels to use
 * @iterations:		iterations before stopping test
 * @xor_sources:	number of xor source buffers
 * @pq_sources:		number of p+q source buffers
 * @timeout:		transfer timeout in msec, -1 for infinite timeout
 * @noverify:		disable data verification
 * @norandom:		disable random offset setup
 * @alignment:		custom data address alignment taken as 2^alignment
 * @transfer_size:	custom transfer size in bytes
 * @polled:		use polling for completion instead of interrupts
 */
struct dmatest_params {};

/**
 * struct dmatest_info - test information.
 * @params:		test parameters
 * @channels:		channels under test
 * @nr_channels:	number of channels under test
 * @lock:		access protection to the fields of this structure
 * @did_init:		module has been initialized completely
 * @last_error:		test has faced configuration issues
 */
static struct dmatest_info {} test_info =;

static int dmatest_run_set(const char *val, const struct kernel_param *kp);
static int dmatest_run_get(char *val, const struct kernel_param *kp);
static const struct kernel_param_ops run_ops =;
static bool dmatest_run;
module_param_cb();
MODULE_PARM_DESC();

static int dmatest_chan_set(const char *val, const struct kernel_param *kp);
static int dmatest_chan_get(char *val, const struct kernel_param *kp);
static const struct kernel_param_ops multi_chan_ops =;

static char test_channel[20];
static struct kparam_string newchan_kps =;
module_param_cb();
MODULE_PARM_DESC();

static int dmatest_test_list_get(char *val, const struct kernel_param *kp);
static const struct kernel_param_ops test_list_ops =;
module_param_cb();
MODULE_PARM_DESC();

/* Maximum amount of mismatched bytes in buffer to print */
#define MAX_ERROR_COUNT

/*
 * Initialization patterns. All bytes in the source buffer has bit 7
 * set, all bytes in the destination buffer has bit 7 cleared.
 *
 * Bit 6 is set for all bytes which are to be copied by the DMA
 * engine. Bit 5 is set for all bytes which are to be overwritten by
 * the DMA engine.
 *
 * The remaining bits are the inverse of a counter which increments by
 * one for each byte address.
 */
#define PATTERN_SRC
#define PATTERN_DST
#define PATTERN_COPY
#define PATTERN_OVERWRITE
#define PATTERN_COUNT_MASK
#define PATTERN_MEMSET_IDX

/* Fixed point arithmetic ops */
#define FIXPT_SHIFT
#define FIXPNT_MASK
#define FIXPT_TO_INT(a)
#define INT_TO_FIXPT(a)
#define FIXPT_GET_FRAC(a)

/* poor man's completion - we want to use wait_event_freezable() on it */
struct dmatest_done {};

struct dmatest_data {};

struct dmatest_thread {};

struct dmatest_chan {};

static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
static bool wait;

static bool is_threaded_test_run(struct dmatest_info *info)
{}

static bool is_threaded_test_pending(struct dmatest_info *info)
{}

static int dmatest_wait_get(char *val, const struct kernel_param *kp)
{}

static const struct kernel_param_ops wait_ops =;
module_param_cb();
MODULE_PARM_DESC();

static bool dmatest_match_channel(struct dmatest_params *params,
		struct dma_chan *chan)
{}

static bool dmatest_match_device(struct dmatest_params *params,
		struct dma_device *device)
{}

static unsigned long dmatest_random(void)
{}

static inline u8 gen_inv_idx(u8 index, bool is_memset)
{}

static inline u8 gen_src_value(u8 index, bool is_memset)
{}

static inline u8 gen_dst_value(u8 index, bool is_memset)
{}

static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len,
		unsigned int buf_size, bool is_memset)
{}

static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
		unsigned int buf_size, bool is_memset)
{}

static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
		unsigned int counter, bool is_srcbuf, bool is_memset)
{}

static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
		unsigned int end, unsigned int counter, u8 pattern,
		bool is_srcbuf, bool is_memset)
{}


static void dmatest_callback(void *arg)
{}

static unsigned int min_odd(unsigned int x, unsigned int y)
{}

static void result(const char *err, unsigned int n, unsigned int src_off,
		   unsigned int dst_off, unsigned int len, unsigned long data)
{}

static void dbg_result(const char *err, unsigned int n, unsigned int src_off,
		       unsigned int dst_off, unsigned int len,
		       unsigned long data)
{}

#define verbose_result(err, n, src_off, dst_off, len, data)

static unsigned long long dmatest_persec(s64 runtime, unsigned int val)
{}

static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len)
{}

static void __dmatest_free_test_data(struct dmatest_data *d, unsigned int cnt)
{}

static void dmatest_free_test_data(struct dmatest_data *d)
{}

static int dmatest_alloc_test_data(struct dmatest_data *d,
		unsigned int buf_size, u8 align)
{}

/*
 * This function repeatedly tests DMA transfers of various lengths and
 * offsets for a given operation type until it is told to exit by
 * kthread_stop(). There may be multiple threads running this function
 * in parallel for a single channel, and there may be multiple channels
 * being tested in parallel.
 *
 * Before each test, the source and destination buffer is initialized
 * with a known pattern. This pattern is different depending on
 * whether it's in an area which is supposed to be copied or
 * overwritten, and different in the source and destination buffers.
 * So if the DMA engine doesn't copy exactly what we tell it to copy,
 * we'll notice.
 */
static int dmatest_func(void *data)
{}

static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
{}

static int dmatest_add_threads(struct dmatest_info *info,
		struct dmatest_chan *dtc, enum dma_transaction_type type)
{}

static int dmatest_add_channel(struct dmatest_info *info,
		struct dma_chan *chan)
{}

static bool filter(struct dma_chan *chan, void *param)
{}

static void request_channels(struct dmatest_info *info,
			     enum dma_transaction_type type)
{}

static void add_threaded_test(struct dmatest_info *info)
{}

static void run_pending_tests(struct dmatest_info *info)
{}

static void stop_threaded_test(struct dmatest_info *info)
{}

static void start_threaded_tests(struct dmatest_info *info)
{}

static int dmatest_run_get(char *val, const struct kernel_param *kp)
{}

static int dmatest_run_set(const char *val, const struct kernel_param *kp)
{}

static int dmatest_chan_set(const char *val, const struct kernel_param *kp)
{}

static int dmatest_chan_get(char *val, const struct kernel_param *kp)
{}

static int dmatest_test_list_get(char *val, const struct kernel_param *kp)
{}

static int __init dmatest_init(void)
{}
/* when compiled-in wait for drivers to load first */
late_initcall(dmatest_init);

static void __exit dmatest_exit(void)
{}
module_exit(dmatest_exit);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();