#define pr_fmt(fmt) …
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/timekeeping.h>
#include <linux/mtd/mtd.h>
#include <linux/kmsg_dump.h>
#define MTDOOPS_MAX_MTD_SIZE …
static unsigned long record_size = …;
module_param(record_size, ulong, 0400);
MODULE_PARM_DESC(…) …;
static char mtddev[80];
module_param_string(…);
MODULE_PARM_DESC(…) …;
static int dump_oops = …;
module_param(dump_oops, int, 0600);
MODULE_PARM_DESC(…) …;
#define MTDOOPS_KERNMSG_MAGIC_v1 …
#define MTDOOPS_KERNMSG_MAGIC_v2 …
struct mtdoops_hdr { … } __packed;
static struct mtdoops_context { … } oops_cxt;
static void mark_page_used(struct mtdoops_context *cxt, int page)
{ … }
static void mark_page_unused(struct mtdoops_context *cxt, int page)
{ … }
static int page_is_used(struct mtdoops_context *cxt, int page)
{ … }
static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset)
{ … }
static void mtdoops_erase(struct mtdoops_context *cxt)
{ … }
static void mtdoops_workfunc_erase(struct work_struct *work)
{ … }
static void mtdoops_inc_counter(struct mtdoops_context *cxt, int panic)
{ … }
static void mtdoops_write(struct mtdoops_context *cxt, int panic)
{ … }
static void mtdoops_workfunc_write(struct work_struct *work)
{ … }
static void find_next_position(struct mtdoops_context *cxt)
{ … }
static void mtdoops_do_dump(struct kmsg_dumper *dumper,
enum kmsg_dump_reason reason)
{ … }
static void mtdoops_notify_add(struct mtd_info *mtd)
{ … }
static void mtdoops_notify_remove(struct mtd_info *mtd)
{ … }
static struct mtd_notifier mtdoops_notifier = …;
static int __init mtdoops_init(void)
{ … }
static void __exit mtdoops_exit(void)
{ … }
module_init(…) …;
module_exit(mtdoops_exit);
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;