2010-07-15 10:46:15 +08:00
/*
* 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 " ) ;
2010-07-15 10:46:17 +08:00
/* /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. " ) ;
2010-07-15 10:46:15 +08:00
/* /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 ;
}