aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorUwe Kleine-König <Uwe.Kleine-Koenig@digi.com>2008-05-30 04:46:30 -0400
committerUwe Kleine-König <Uwe.Kleine-Koenig@digi.com>2008-05-30 04:46:30 -0400
commite22af66fc85a8b008237970da4d9b6910422536b (patch)
tree4c5a71611b57d0e75af8a4bc3e0c44ec9431ecb3 /arch
parenta4831fbe096a6f4f691fd71b041ce27add54088e (diff)
parentf7b0b939d54b457ba172e088f477af2012aef9b3 (diff)
Merge branch 'atags' into for-rmk
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/atags.c83
1 files changed, 40 insertions, 43 deletions
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
index 64c420805e6f..42a1a1415fa6 100644
--- a/arch/arm/kernel/atags.c
+++ b/arch/arm/kernel/atags.c
@@ -1,5 +1,4 @@
1#include <linux/slab.h> 1#include <linux/slab.h>
2#include <linux/kexec.h>
3#include <linux/proc_fs.h> 2#include <linux/proc_fs.h>
4#include <asm/setup.h> 3#include <asm/setup.h>
5#include <asm/types.h> 4#include <asm/types.h>
@@ -7,9 +6,8 @@
7 6
8struct buffer { 7struct buffer {
9 size_t size; 8 size_t size;
10 char *data; 9 char data[];
11}; 10};
12static struct buffer tags_buffer;
13 11
14static int 12static int
15read_buffer(char* page, char** start, off_t off, int count, 13read_buffer(char* page, char** start, off_t off, int count,
@@ -29,58 +27,57 @@ read_buffer(char* page, char** start, off_t off, int count,
29 return count; 27 return count;
30} 28}
31 29
32 30#define BOOT_PARAMS_SIZE 1536
33static int 31static char __initdata atags_copy[BOOT_PARAMS_SIZE];
34create_proc_entries(void)
35{
36 struct proc_dir_entry* tags_entry;
37
38 tags_entry = create_proc_read_entry("atags", 0400, NULL, read_buffer, &tags_buffer);
39 if (!tags_entry)
40 return -ENOMEM;
41
42 return 0;
43}
44
45
46static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE];
47static char __initdata *atags_copy;
48 32
49void __init save_atags(const struct tag *tags) 33void __init save_atags(const struct tag *tags)
50{ 34{
51 atags_copy = atags_copy_buf; 35 memcpy(atags_copy, tags, sizeof(atags_copy));
52 memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE);
53} 36}
54 37
55
56static int __init init_atags_procfs(void) 38static int __init init_atags_procfs(void)
57{ 39{
58 struct tag *tag; 40 /*
59 int error; 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;
60 48
61 if (!atags_copy) { 49 if (tag->hdr.tag != ATAG_CORE) {
62 printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n"); 50 printk(KERN_INFO "No ATAGs?");
63 return -EIO; 51 return -EINVAL;
64 } 52 }
65 53
66 for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag)) 54 for (; tag->hdr.size; tag = tag_next(tag))
67 ; 55 ;
68 56
69 tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr); 57 /* include the terminating ATAG_NONE */
70 tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL); 58 size = (char *)tag - atags_copy + sizeof(struct tag_header);
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 59
83 return error; 60 WARN_ON(tag->hdr.tag != ATAG_NONE);
84} 61
62 b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
63 if (!b)
64 goto nomem;
85 65
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
77nomem:
78 kfree(b);
79 printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
80
81 return -ENOMEM;
82}
86arch_initcall(init_atags_procfs); 83arch_initcall(init_atags_procfs);