Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
atags_proc.c
Go to the documentation of this file.
1 #include <linux/slab.h>
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;
9  char data[];
10 };
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 
30 #define BOOT_PARAMS_SIZE 1536
31 static char __initdata atags_copy[BOOT_PARAMS_SIZE];
32 
33 void __init save_atags(const struct tag *tags)
34 {
35  memcpy(atags_copy, tags, sizeof(atags_copy));
36 }
37 
38 static int __init init_atags_procfs(void)
39 {
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;
48 
49  if (tag->hdr.tag != ATAG_CORE) {
50  printk(KERN_INFO "No ATAGs?");
51  return -EINVAL;
52  }
53 
54  for (; tag->hdr.size; tag = tag_next(tag))
55  ;
56 
57  /* include the terminating ATAG_NONE */
58  size = (char *)tag - atags_copy + sizeof(struct tag_header);
59 
60  WARN_ON(tag->hdr.tag != ATAG_NONE);
61 
62  b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
63  if (!b)
64  goto nomem;
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 
77 nomem:
78  kfree(b);
79  printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
80 
81  return -ENOMEM;
82 }
83 arch_initcall(init_atags_procfs);