[PATCH] ramoops: Add a device file for ramoops buffer access.

From: Bryan Freed
Date: Mon Nov 07 2011 - 19:06:33 EST


Add a /dev/ramoops device file that gives direct access to ramoops buffers.
This interface is cleaner than using /dev/mem to access the buffers because
we no longer need to lseek() or (for ARM) mmap() to an address specified in
the sysfs mem_address file.

Signed-off-by: Bryan Freed <bfreed@xxxxxxxxxxxx>
---
drivers/char/ramoops.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c
index 7c7f42a1f8..eac273a 100644
--- a/drivers/char/ramoops.c
+++ b/drivers/char/ramoops.c
@@ -32,6 +32,9 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/ramoops.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>

#define RAMOOPS_KERNMSG_HDR "===="
#define MIN_MEM_SIZE 4096UL
@@ -65,11 +68,39 @@ static struct ramoops_context {
int dump_oops;
int count;
int max_count;
+ struct miscdevice misc_dev;
} oops_cxt;

static struct platform_device *dummy;
static struct ramoops_platform_data *dummy_data;

+static int ramoops_open(struct inode *inode, struct file *file)
+{
+ file->private_data = &oops_cxt;
+ return 0;
+}
+
+static ssize_t
+ramoops_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+ struct ramoops_context *cxt = file->private_data;
+ void *from = cxt->virt_addr + *ppos;
+
+ if (*ppos + count > cxt->size)
+ count = cxt->size - *ppos;
+ if (copy_to_user(buf, from, count))
+ count = -EFAULT;
+ else
+ *ppos += count;
+
+ return count;
+}
+
+static const struct file_operations ramoops_fops = {
+ .open = ramoops_open,
+ .read = ramoops_read,
+};
+
static void ramoops_do_dump(struct kmsg_dumper *dumper,
enum kmsg_dump_reason reason, const char *s1, unsigned long l1,
const char *s2, unsigned long l2)
@@ -169,15 +200,24 @@ static int __init ramoops_probe(struct platform_device *pdev)
goto fail2;
}

+ cxt->misc_dev.minor = MISC_DYNAMIC_MINOR;
+ cxt->misc_dev.name = "ramoops";
+ cxt->misc_dev.fops = &ramoops_fops;
+ err = misc_register(&cxt->misc_dev);
+ if (err)
+ goto fail1;
+
cxt->dump.dump = ramoops_do_dump;
err = kmsg_dump_register(&cxt->dump);
if (err) {
pr_err("registering kmsg dumper failed\n");
- goto fail1;
+ goto clean_misc;
}

return 0;

+clean_misc:
+ misc_deregister(&cxt->misc_dev);
fail1:
iounmap(cxt->virt_addr);
fail2:
@@ -193,6 +233,7 @@ static int __exit ramoops_remove(struct platform_device *pdev)
if (kmsg_dump_unregister(&cxt->dump) < 0)
pr_warn("could not unregister kmsg_dumper\n");

+ misc_deregister(&cxt->misc_dev);
iounmap(cxt->virt_addr);
release_mem_region(cxt->phys_addr, cxt->size);
return 0;
--
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/