/* SPDX-License-Identifier: GPL-2.0+ */ #include <linux/seq_file.h> #define SP_MAX_INPUT_BUF 8192 #define SP_MAX_PATH_LEN 4096 #define sp_debug_print( \ format, \ arg...) // printk(KERN_ERR "[%s/%d] " format, __func__, __LINE__, ##arg) /* * add_simple_proc_file creates a simple procfile: * path relative to '/proc/': e.g. '{subdir/}my_proc_file' * kernel_input: function, which takes two arguments: * - char *buffer: contains data, which was received via proc file, copied from userspace * - void *private: pointer to private data, which was setup here via add_simple_proc_file * kernel_output: function, which takes two arguments, creates data, which is sent to userspace via proc_file * - struct seq_file *seq: you should pass this to seq_printf in your output kernel_output function * - void *private: pointer to private data, which was setup here via add_simple_proc_file * kernel_output might be called several times, though userspace performs only one read * you can improve this behavior by setting simple_proc_file_setup_expected_output_size */ int add_simple_proc_file(const char *path, int (*kernel_input)(char *send, void *private), void (*kernel_output)(struct seq_file *pseq, void *private), void *priv_data); /* * removes simple procfile, which was created by add_simple_proc_file(): */ void remove_simple_proc_file(const char *path); /* * in case your kernel_output function writes more than PAGESIZE, * your kernel_output function will be called several times. On every call, output * buffer size will be doubled, till everything fits in * If you want to improve this behavior you can setup output buffers size for the first * call of your output function */ void simple_proc_file_setup_expected_output_size(const char *path, size_t expected_output_size); /* * this struct is used in add_simple_proc_file_array and remove_simple_proc_file_array */ struct simple_proc_file { const char *path; int (*kernel_input)(char *send, void *prvate); void (*kernel_output)(struct seq_file *pseq, void *private); void *priv_data; int enabled; }; /* * in case you want to (un-)register a NULL terminated struct simple_proc_file array[] * you can use these functions for batch processing */ int add_simple_proc_file_array(struct simple_proc_file *array); void remove_simple_proc_file_array(struct simple_proc_file *array);