Commit | Line | Data |
---|---|---|
4cd9d6f7 | 1 | #include <linux/slab.h> |
4cd9d6f7 RP |
2 | #include <linux/proc_fs.h> |
3 | #include <asm/setup.h> | |
4 | #include <asm/types.h> | |
5 | #include <asm/page.h> | |
6 | ||
7 | struct buffer { | |
8 | size_t size; | |
f7b0b939 | 9 | char data[]; |
4cd9d6f7 | 10 | }; |
4cd9d6f7 RP |
11 | |
12 | static int | |
13 | read_buffer(char* page, char** start, off_t off, int count, | |
14 | int* eof, void* data) | |
15 | { | |
16 | struct buffer *buffer = (struct buffer *)data; | |
17 | ||
18 | if (off >= buffer->size) { | |
19 | *eof = 1; | |
20 | return 0; | |
21 | } | |
22 | ||
23 | count = min((int) (buffer->size - off), count); | |
24 | ||
25 | memcpy(page, &buffer->data[off], count); | |
26 | ||
27 | return count; | |
28 | } | |
29 | ||
8ff7f2a4 | 30 | #define BOOT_PARAMS_SIZE 1536 |
f7b0b939 | 31 | static char __initdata atags_copy[BOOT_PARAMS_SIZE]; |
4cd9d6f7 RP |
32 | |
33 | void __init save_atags(const struct tag *tags) | |
34 | { | |
f7b0b939 | 35 | memcpy(atags_copy, tags, sizeof(atags_copy)); |
4cd9d6f7 RP |
36 | } |
37 | ||
4cd9d6f7 RP |
38 | static int __init init_atags_procfs(void) |
39 | { | |
f7b0b939 UKK |
40 | /* |
41 | * This cannot go into save_atags() because kmalloc and proc don't work | |
42 | * yet when it is called. | |
43 | */ | |
44 | struct proc_dir_entry *tags_entry; | |
45 | struct tag *tag = (struct tag *)atags_copy; | |
46 | struct buffer *b; | |
47 | size_t size; | |
4cd9d6f7 | 48 | |
f7b0b939 UKK |
49 | if (tag->hdr.tag != ATAG_CORE) { |
50 | printk(KERN_INFO "No ATAGs?"); | |
51 | return -EINVAL; | |
4cd9d6f7 RP |
52 | } |
53 | ||
f7b0b939 | 54 | for (; tag->hdr.size; tag = tag_next(tag)) |
4cd9d6f7 RP |
55 | ; |
56 | ||
f7b0b939 UKK |
57 | /* include the terminating ATAG_NONE */ |
58 | size = (char *)tag - atags_copy + sizeof(struct tag_header); | |
4cd9d6f7 | 59 | |
f7b0b939 UKK |
60 | WARN_ON(tag->hdr.tag != ATAG_NONE); |
61 | ||
62 | b = kmalloc(sizeof(*b) + size, GFP_KERNEL); | |
63 | if (!b) | |
64 | goto nomem; | |
4cd9d6f7 | 65 | |
f7b0b939 UKK |
66 | b->size = size; |
67 | memcpy(b->data, atags_copy, size); | |
68 | ||
69 | tags_entry = create_proc_read_entry("atags", 0400, | |
70 | NULL, read_buffer, b); | |
71 | ||
72 | if (!tags_entry) | |
73 | goto nomem; | |
74 | ||
75 | return 0; | |
76 | ||
77 | nomem: | |
78 | kfree(b); | |
79 | printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); | |
80 | ||
81 | return -ENOMEM; | |
82 | } | |
4cd9d6f7 | 83 | arch_initcall(init_atags_procfs); |