From a25ee9200eef07377e1703697afbb5d81f89e500 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:15 +0800 Subject: ACPI: introduce drivers/acpi/debugfs.c Introduce drivers/acpi/debugfs.c. Code for ACPI debugfs I/F, i.e. /sys/kernel/debug/acpi/custom_method, is moved to this file. And make ACPI debugfs always built in, even if CONFIG_ACPI_DEBUG is cleared. BTW:this adds about 400bytes code to ACPI, when CONFIG_ACPI_DEBUG is cleared. [uaccess.h build fix from Andrew Morton ] Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/debugfs.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 drivers/acpi/debugfs.c (limited to 'drivers/acpi/debugfs.c') diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c new file mode 100644 index 000000000000..abfcf9f6e766 --- /dev/null +++ b/drivers/acpi/debugfs.c @@ -0,0 +1,85 @@ +/* + * debugfs.c - ACPI debugfs interface to userspace. + */ + +#include +#include +#include +#include +#include +#include + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME("debugfs"); + +/* /sys/kernel/debug/acpi/custom_method */ + +static ssize_t cm_write(struct file *file, const char __user * user_buf, + size_t count, loff_t *ppos) +{ + static char *buf; + static int uncopied_bytes; + struct acpi_table_header table; + acpi_status status; + + if (!(*ppos)) { + /* parse the table header to get the table length */ + if (count <= sizeof(struct acpi_table_header)) + return -EINVAL; + if (copy_from_user(&table, user_buf, + sizeof(struct acpi_table_header))) + return -EFAULT; + uncopied_bytes = table.length; + buf = kzalloc(uncopied_bytes, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } + + if (uncopied_bytes < count) { + kfree(buf); + return -EINVAL; + } + + if (copy_from_user(buf + (*ppos), user_buf, count)) { + kfree(buf); + return -EFAULT; + } + + uncopied_bytes -= count; + *ppos += count; + + if (!uncopied_bytes) { + status = acpi_install_method(buf); + kfree(buf); + if (ACPI_FAILURE(status)) + return -EINVAL; + add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); + } + + return count; +} + +static const struct file_operations cm_fops = { + .write = cm_write, +}; + +int __init acpi_debugfs_init(void) +{ + struct dentry *acpi_dir, *cm_dentry; + + acpi_dir = debugfs_create_dir("acpi", NULL); + if (!acpi_dir) + goto err; + + cm_dentry = debugfs_create_file("custom_method", S_IWUGO, + acpi_dir, NULL, &cm_fops); + if (!cm_dentry) + goto err; + + return 0; + +err: + if (acpi_dir) + debugfs_remove(acpi_dir); + return -EINVAL; +} -- cgit v1.2.3