#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/hw_random.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#define RNG_MODULE_NAME …
#define RNG_BUFFER_SIZE …
static struct hwrng *current_rng;
static int cur_rng_set_by_user;
static struct task_struct *hwrng_fill;
static LIST_HEAD(rng_list);
static DEFINE_MUTEX(rng_mutex);
static DEFINE_MUTEX(reading_mutex);
static int data_avail;
static u8 *rng_buffer, *rng_fillbuf;
static unsigned short current_quality;
static unsigned short default_quality = …;
module_param(current_quality, ushort, 0644);
MODULE_PARM_DESC(…) …;
module_param(default_quality, ushort, 0644);
MODULE_PARM_DESC(…) …;
static void drop_current_rng(void);
static int hwrng_init(struct hwrng *rng);
static int hwrng_fillfn(void *unused);
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
int wait);
static size_t rng_buffer_size(void)
{ … }
static inline void cleanup_rng(struct kref *kref)
{ … }
static int set_current_rng(struct hwrng *rng)
{ … }
static void drop_current_rng(void)
{ … }
static struct hwrng *get_current_rng_nolock(void)
{ … }
static struct hwrng *get_current_rng(void)
{ … }
static void put_rng(struct hwrng *rng)
{ … }
static int hwrng_init(struct hwrng *rng)
{ … }
static int rng_dev_open(struct inode *inode, struct file *filp)
{ … }
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
int wait) { … }
static ssize_t rng_dev_read(struct file *filp, char __user *buf,
size_t size, loff_t *offp)
{ … }
static const struct file_operations rng_chrdev_ops = …;
static const struct attribute_group *rng_dev_groups[];
static struct miscdevice rng_miscdev = …;
static int enable_best_rng(void)
{ … }
static ssize_t rng_current_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static ssize_t rng_current_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t rng_available_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t rng_selected_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t rng_quality_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t rng_quality_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static DEVICE_ATTR_RW(rng_current);
static DEVICE_ATTR_RO(rng_available);
static DEVICE_ATTR_RO(rng_selected);
static DEVICE_ATTR_RW(rng_quality);
static struct attribute *rng_dev_attrs[] = …;
ATTRIBUTE_GROUPS(…);
static int hwrng_fillfn(void *unused)
{ … }
int hwrng_register(struct hwrng *rng)
{ … }
EXPORT_SYMBOL_GPL(…);
void hwrng_unregister(struct hwrng *rng)
{ … }
EXPORT_SYMBOL_GPL(…);
static void devm_hwrng_release(struct device *dev, void *res)
{ … }
static int devm_hwrng_match(struct device *dev, void *res, void *data)
{ … }
int devm_hwrng_register(struct device *dev, struct hwrng *rng)
{ … }
EXPORT_SYMBOL_GPL(…);
void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
{ … }
EXPORT_SYMBOL_GPL(…);
long hwrng_msleep(struct hwrng *rng, unsigned int msecs)
{ … }
EXPORT_SYMBOL_GPL(…);
long hwrng_yield(struct hwrng *rng)
{ … }
EXPORT_SYMBOL_GPL(…);
static int __init hwrng_modinit(void)
{ … }
static void __exit hwrng_modexit(void)
{ … }
fs_initcall(hwrng_modinit);
module_exit(hwrng_modexit);
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;