Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
 1/*
 2 * Based on arch/arm/kernel/atags_proc.c
 3 */
 4
 5#include <linux/fs.h>
 6#include <linux/init.h>
 7#include <linux/printk.h>
 8#include <linux/proc_fs.h>
 9#include <linux/slab.h>
10#include <linux/string.h>
11
12#include <asm/bootinfo.h>
13#include <asm/byteorder.h>
14
15
16static char bootinfo_tmp[1536] __initdata;
17
18static void *bootinfo_copy;
19static size_t bootinfo_size;
20
21static ssize_t bootinfo_read(struct file *file, char __user *buf,
22			  size_t count, loff_t *ppos)
23{
24	return simple_read_from_buffer(buf, count, ppos, bootinfo_copy,
25				       bootinfo_size);
26}
27
28static const struct file_operations bootinfo_fops = {
29	.read = bootinfo_read,
30	.llseek = default_llseek,
31};
32
33void __init save_bootinfo(const struct bi_record *bi)
34{
35	const void *start = bi;
36	size_t size = sizeof(bi->tag);
37
38	while (be16_to_cpu(bi->tag) != BI_LAST) {
39		uint16_t n = be16_to_cpu(bi->size);
40		size += n;
41		bi = (struct bi_record *)((unsigned long)bi + n);
42	}
43
44	if (size > sizeof(bootinfo_tmp)) {
45		pr_err("Cannot save %zu bytes of bootinfo\n", size);
46		return;
47	}
48
49	pr_info("Saving %zu bytes of bootinfo\n", size);
50	memcpy(bootinfo_tmp, start, size);
51	bootinfo_size = size;
52}
53
54static int __init init_bootinfo_procfs(void)
55{
56	/*
57	 * This cannot go into save_bootinfo() because kmalloc and proc don't
58	 * work yet when it is called.
59	 */
60	struct proc_dir_entry *pde;
61
62	if (!bootinfo_size)
63		return -EINVAL;
64
65	bootinfo_copy = kmemdup(bootinfo_tmp, bootinfo_size, GFP_KERNEL);
66	if (!bootinfo_copy)
67		return -ENOMEM;
68
69	pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_fops, NULL);
70	if (!pde) {
71		kfree(bootinfo_copy);
72		return -ENOMEM;
73	}
74
75	return 0;
76}
77
78arch_initcall(init_bootinfo_procfs);