Commit | Line | Data |
---|---|---|
4cd9d6f7 RP |
1 | #include <linux/slab.h> |
2 | #include <linux/kexec.h> | |
3 | #include <linux/proc_fs.h> | |
4 | #include <asm/setup.h> | |
5 | #include <asm/types.h> | |
6 | #include <asm/page.h> | |
7 | ||
8 | struct buffer { | |
9 | size_t size; | |
10 | char *data; | |
11 | }; | |
12 | static struct buffer tags_buffer; | |
13 | ||
14 | static int | |
15 | read_buffer(char* page, char** start, off_t off, int count, | |
16 | int* eof, void* data) | |
17 | { | |
18 | struct buffer *buffer = (struct buffer *)data; | |
19 | ||
20 | if (off >= buffer->size) { | |
21 | *eof = 1; | |
22 | return 0; | |
23 | } | |
24 | ||
25 | count = min((int) (buffer->size - off), count); | |
26 | ||
27 | memcpy(page, &buffer->data[off], count); | |
28 | ||
29 | return count; | |
30 | } | |
31 | ||
32 | ||
33 | static int | |
34 | create_proc_entries(void) | |
35 | { | |
36 | struct proc_dir_entry* tags_entry; | |
37 | ||
38 | tags_entry = create_proc_read_entry("atags", 0400, &proc_root, read_buffer, &tags_buffer); | |
39 | if (!tags_entry) | |
40 | return -ENOMEM; | |
41 | ||
42 | return 0; | |
43 | } | |
44 | ||
45 | ||
46 | static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE]; | |
47 | static char __initdata *atags_copy; | |
48 | ||
49 | void __init save_atags(const struct tag *tags) | |
50 | { | |
51 | atags_copy = atags_copy_buf; | |
52 | memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE); | |
53 | } | |
54 | ||
55 | ||
56 | static int __init init_atags_procfs(void) | |
57 | { | |
58 | struct tag *tag; | |
59 | int error; | |
60 | ||
61 | if (!atags_copy) { | |
62 | printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n"); | |
63 | return -EIO; | |
64 | } | |
65 | ||
66 | for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag)) | |
67 | ; | |
68 | ||
69 | tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr); | |
70 | tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL); | |
71 | if (tags_buffer.data == NULL) | |
72 | return -ENOMEM; | |
73 | memcpy(tags_buffer.data, atags_copy, tags_buffer.size); | |
74 | ||
75 | error = create_proc_entries(); | |
76 | if (error) { | |
77 | printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); | |
78 | kfree(tags_buffer.data); | |
79 | tags_buffer.size = 0; | |
80 | tags_buffer.data = NULL; | |
81 | } | |
82 | ||
83 | return error; | |
84 | } | |
85 | ||
86 | arch_initcall(init_atags_procfs); |