#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/poll.h>
#include "internal.h"
static BLOCKING_NOTIFIER_HEAD(mce_injector_chain);
static DEFINE_MUTEX(mce_chrdev_read_mutex);
static char mce_helper[128];
static char *mce_helper_argv[2] = …;
static struct mce_log_buffer *mcelog;
static DECLARE_WAIT_QUEUE_HEAD(mce_chrdev_wait);
static int dev_mce_log(struct notifier_block *nb, unsigned long val,
void *data)
{ … }
static struct notifier_block dev_mcelog_nb = …;
static void mce_do_trigger(struct work_struct *work)
{ … }
static DECLARE_WORK(mce_trigger_work, mce_do_trigger);
void mce_work_trigger(void)
{ … }
static ssize_t
show_trigger(struct device *s, struct device_attribute *attr, char *buf)
{ … }
static ssize_t set_trigger(struct device *s, struct device_attribute *attr,
const char *buf, size_t siz)
{ … }
DEVICE_ATTR(…);
static DEFINE_SPINLOCK(mce_chrdev_state_lock);
static int mce_chrdev_open_count;
static int mce_chrdev_open_exclu;
static int mce_chrdev_open(struct inode *inode, struct file *file)
{ … }
static int mce_chrdev_release(struct inode *inode, struct file *file)
{ … }
static int mce_apei_read_done;
static int __mce_read_apei(char __user **ubuf, size_t usize)
{ … }
static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf,
size_t usize, loff_t *off)
{ … }
static __poll_t mce_chrdev_poll(struct file *file, poll_table *wait)
{ … }
static long mce_chrdev_ioctl(struct file *f, unsigned int cmd,
unsigned long arg)
{ … }
void mce_register_injector_chain(struct notifier_block *nb)
{ … }
EXPORT_SYMBOL_GPL(…);
void mce_unregister_injector_chain(struct notifier_block *nb)
{ … }
EXPORT_SYMBOL_GPL(…);
static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
size_t usize, loff_t *off)
{ … }
static const struct file_operations mce_chrdev_ops = …;
static struct miscdevice mce_chrdev_device = …;
static __init int dev_mcelog_init_device(void)
{ … }
device_initcall_sync(dev_mcelog_init_device);