1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/module.h>
27#include <linux/types.h>
28#include <linux/miscdevice.h>
29#include <linux/init.h>
30#include <asm/io.h>
31#include <asm/uaccess.h>
32#include <asm/types.h>
33#include <asm/crash-driver.h>
34
35#define CRASH_VERSION "1.1"
36
37
38
39
40
41
42static loff_t
43crash_llseek(struct file * file, loff_t offset, int orig)
44{
45 switch (orig) {
46 case 0:
47 file->f_pos = offset;
48 return file->f_pos;
49 case 1:
50 file->f_pos += offset;
51 return file->f_pos;
52 default:
53 return -EINVAL;
54 }
55}
56
57
58
59
60
61
62static ssize_t
63crash_read(struct file *file, char *buf, size_t count, loff_t *poff)
64{
65 void *vaddr;
66 struct page *page;
67 u64 offset;
68 ssize_t read;
69
70 offset = *poff;
71 if (offset >> PAGE_SHIFT != (offset+count-1) >> PAGE_SHIFT)
72 return -EINVAL;
73
74 vaddr = map_virtual(offset, &page);
75 if (!vaddr)
76 return -EFAULT;
77
78 if (copy_to_user(buf, vaddr, count)) {
79 unmap_virtual(page);
80 return -EFAULT;
81 }
82 unmap_virtual(page);
83
84 read = count;
85 *poff += read;
86 return read;
87}
88
89static int
90crash_open(struct inode * inode, struct file * filp)
91{
92 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
93}
94
95static struct file_operations crash_fops = {
96 .owner = THIS_MODULE,
97 .llseek = crash_llseek,
98 .read = crash_read,
99 .open = crash_open,
100};
101
102static struct miscdevice crash_dev = {
103 MISC_DYNAMIC_MINOR,
104 "crash",
105 &crash_fops
106};
107
108static int __init
109crash_init(void)
110{
111 int ret;
112
113 ret = misc_register(&crash_dev);
114 if (ret) {
115 printk(KERN_ERR
116 "crash memory driver: cannot misc_register (MISC_DYNAMIC_MINOR)\n");
117 goto out;
118 }
119
120 ret = 0;
121 printk(KERN_INFO "crash memory driver: version %s\n", CRASH_VERSION);
122out:
123 return ret;
124}
125
126static void __exit
127crash_cleanup_module(void)
128{
129 misc_deregister(&crash_dev);
130}
131
132module_init(crash_init);
133module_exit(crash_cleanup_module);
134
135MODULE_LICENSE("GPL");
136