diff options
author | Len Brown <len.brown@intel.com> | 2010-08-14 23:55:57 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-08-14 23:55:57 -0400 |
commit | ecd8ee0955a2f21914c2e2ffff82541211c5bd43 (patch) | |
tree | 3987f3d505482a00e9a1d2c44b340d0b71f66d75 /drivers/acpi/debugfs.c | |
parent | feb29c5175e61d0f1ec2cbcaccdfa55e588780be (diff) | |
parent | c637e4861c7db8165d0f438db3829e7878c96059 (diff) | |
download | op-kernel-dev-ecd8ee0955a2f21914c2e2ffff82541211c5bd43.zip op-kernel-dev-ecd8ee0955a2f21914c2e2ffff82541211c5bd43.tar.gz |
Merge branch 'procfs-cleanup' into release
Diffstat (limited to 'drivers/acpi/debugfs.c')
-rw-r--r-- | drivers/acpi/debugfs.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c new file mode 100644 index 0000000..7de27d4 --- /dev/null +++ b/drivers/acpi/debugfs.c @@ -0,0 +1,93 @@ +/* + * debugfs.c - ACPI debugfs interface to userspace. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/uaccess.h> +#include <linux/debugfs.h> +#include <acpi/acpi_drivers.h> + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME("debugfs"); + + +/* /sys/modules/acpi/parameters/aml_debug_output */ + +module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, + bool, 0644); +MODULE_PARM_DESC(aml_debug_output, + "To enable/disable the ACPI Debug Object output."); + +/* /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; +} |