#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/pci.h>
#include <linux/ktime.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/sizes.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/random.h>
#include <linux/ntb.h>
#define DRIVER_NAME …
#define DRIVER_VERSION …
MODULE_LICENSE(…) …;
MODULE_VERSION(…);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
#define MAX_THREADS_CNT …
#define DEF_THREADS_CNT …
#define MAX_CHUNK_SIZE …
#define MAX_CHUNK_ORDER …
#define DMA_TRIES …
#define DMA_MDELAY …
#define MSG_TRIES …
#define MSG_UDELAY_LOW …
#define MSG_UDELAY_HIGH …
#define PERF_BUF_LEN …
static unsigned long max_mw_size;
module_param(max_mw_size, ulong, 0644);
MODULE_PARM_DESC(…) …;
static unsigned char chunk_order = …;
module_param(chunk_order, byte, 0644);
MODULE_PARM_DESC(…) …;
static unsigned char total_order = …;
module_param(total_order, byte, 0644);
MODULE_PARM_DESC(…) …;
static bool use_dma;
module_param(use_dma, bool, 0644);
MODULE_PARM_DESC(…) …;
enum perf_cmd { … };
struct perf_ctx;
struct perf_peer { … };
#define to_peer_service(__work) …
struct perf_thread { … };
#define to_thread_work(__work) …
struct perf_ctx { … };
#define PERF_SPAD_CNT(_pcnt) …
#define PERF_SPAD_CMD(_gidx) …
#define PERF_SPAD_LDATA(_gidx) …
#define PERF_SPAD_HDATA(_gidx) …
#define PERF_SPAD_NOTIFY(_gidx) …
#define PERF_MSG_CNT …
#define PERF_MSG_CMD …
#define PERF_MSG_LDATA …
#define PERF_MSG_HDATA …
static struct dentry *perf_dbgfs_topdir;
static struct workqueue_struct *perf_wq __read_mostly;
static void perf_terminate_test(struct perf_ctx *perf);
static inline bool perf_link_is_up(struct perf_peer *peer)
{ … }
static int perf_spad_cmd_send(struct perf_peer *peer, enum perf_cmd cmd,
u64 data)
{ … }
static int perf_spad_cmd_recv(struct perf_ctx *perf, int *pidx,
enum perf_cmd *cmd, u64 *data)
{ … }
static int perf_msg_cmd_send(struct perf_peer *peer, enum perf_cmd cmd,
u64 data)
{ … }
static int perf_msg_cmd_recv(struct perf_ctx *perf, int *pidx,
enum perf_cmd *cmd, u64 *data)
{ … }
static int perf_cmd_send(struct perf_peer *peer, enum perf_cmd cmd, u64 data)
{ … }
static int perf_cmd_exec(struct perf_peer *peer, enum perf_cmd cmd)
{ … }
static int perf_cmd_recv(struct perf_ctx *perf)
{ … }
static void perf_link_event(void *ctx)
{ … }
static void perf_db_event(void *ctx, int vec)
{ … }
static void perf_msg_event(void *ctx)
{ … }
static const struct ntb_ctx_ops perf_ops = …;
static void perf_free_outbuf(struct perf_peer *peer)
{ … }
static int perf_setup_outbuf(struct perf_peer *peer)
{ … }
static void perf_free_inbuf(struct perf_peer *peer)
{ … }
static int perf_setup_inbuf(struct perf_peer *peer)
{ … }
static void perf_service_work(struct work_struct *work)
{ … }
static int perf_init_service(struct perf_ctx *perf)
{ … }
static int perf_enable_service(struct perf_ctx *perf)
{ … }
static void perf_disable_service(struct perf_ctx *perf)
{ … }
static void perf_dma_copy_callback(void *data)
{ … }
static int perf_copy_chunk(struct perf_thread *pthr,
void __iomem *dst, void *src, size_t len)
{ … }
static bool perf_dma_filter(struct dma_chan *chan, void *data)
{ … }
static int perf_init_test(struct perf_thread *pthr)
{ … }
static int perf_run_test(struct perf_thread *pthr)
{ … }
static int perf_sync_test(struct perf_thread *pthr)
{ … }
static void perf_clear_test(struct perf_thread *pthr)
{ … }
static void perf_thread_work(struct work_struct *work)
{ … }
static int perf_set_tcnt(struct perf_ctx *perf, u8 tcnt)
{ … }
static void perf_terminate_test(struct perf_ctx *perf)
{ … }
static int perf_submit_test(struct perf_peer *peer)
{ … }
static int perf_read_stats(struct perf_ctx *perf, char *buf,
size_t size, ssize_t *pos)
{ … }
static void perf_init_threads(struct perf_ctx *perf)
{ … }
static void perf_clear_threads(struct perf_ctx *perf)
{ … }
static ssize_t perf_dbgfs_read_info(struct file *filep, char __user *ubuf,
size_t size, loff_t *offp)
{ … }
static const struct file_operations perf_dbgfs_info = …;
static ssize_t perf_dbgfs_read_run(struct file *filep, char __user *ubuf,
size_t size, loff_t *offp)
{ … }
static ssize_t perf_dbgfs_write_run(struct file *filep, const char __user *ubuf,
size_t size, loff_t *offp)
{ … }
static const struct file_operations perf_dbgfs_run = …;
static ssize_t perf_dbgfs_read_tcnt(struct file *filep, char __user *ubuf,
size_t size, loff_t *offp)
{ … }
static ssize_t perf_dbgfs_write_tcnt(struct file *filep,
const char __user *ubuf,
size_t size, loff_t *offp)
{ … }
static const struct file_operations perf_dbgfs_tcnt = …;
static void perf_setup_dbgfs(struct perf_ctx *perf)
{ … }
static void perf_clear_dbgfs(struct perf_ctx *perf)
{ … }
static struct perf_ctx *perf_create_data(struct ntb_dev *ntb)
{ … }
static int perf_setup_peer_mw(struct perf_peer *peer)
{ … }
static int perf_init_peers(struct perf_ctx *perf)
{ … }
static int perf_probe(struct ntb_client *client, struct ntb_dev *ntb)
{ … }
static void perf_remove(struct ntb_client *client, struct ntb_dev *ntb)
{ … }
static struct ntb_client perf_client = …;
static int __init perf_init(void)
{ … }
module_init(…) …;
static void __exit perf_exit(void)
{ … }
module_exit(perf_exit);