at v2.6.16 5.7 kB view raw
1/* 2 * debug.c - ACPI debug interface to userspace. 3 */ 4 5#include <linux/proc_fs.h> 6#include <linux/init.h> 7#include <linux/module.h> 8#include <linux/kernel.h> 9#include <linux/moduleparam.h> 10#include <asm/uaccess.h> 11#include <acpi/acpi_drivers.h> 12#include <acpi/acglobal.h> 13 14#define _COMPONENT ACPI_SYSTEM_COMPONENT 15ACPI_MODULE_NAME("debug") 16#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" 17#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" 18#ifdef MODULE_PARAM_PREFIX 19#undef MODULE_PARAM_PREFIX 20#endif 21#define MODULE_PARAM_PREFIX 22 module_param(acpi_dbg_layer, uint, 0400); 23module_param(acpi_dbg_level, uint, 0400); 24 25struct acpi_dlayer { 26 const char *name; 27 unsigned long value; 28}; 29struct acpi_dlevel { 30 const char *name; 31 unsigned long value; 32}; 33#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } 34 35static const struct acpi_dlayer acpi_debug_layers[] = { 36 ACPI_DEBUG_INIT(ACPI_UTILITIES), 37 ACPI_DEBUG_INIT(ACPI_HARDWARE), 38 ACPI_DEBUG_INIT(ACPI_EVENTS), 39 ACPI_DEBUG_INIT(ACPI_TABLES), 40 ACPI_DEBUG_INIT(ACPI_NAMESPACE), 41 ACPI_DEBUG_INIT(ACPI_PARSER), 42 ACPI_DEBUG_INIT(ACPI_DISPATCHER), 43 ACPI_DEBUG_INIT(ACPI_EXECUTER), 44 ACPI_DEBUG_INIT(ACPI_RESOURCES), 45 ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), 46 ACPI_DEBUG_INIT(ACPI_OS_SERVICES), 47 ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), 48 ACPI_DEBUG_INIT(ACPI_COMPILER), 49 ACPI_DEBUG_INIT(ACPI_TOOLS), 50}; 51 52static const struct acpi_dlevel acpi_debug_levels[] = { 53 ACPI_DEBUG_INIT(ACPI_LV_ERROR), 54 ACPI_DEBUG_INIT(ACPI_LV_WARN), 55 ACPI_DEBUG_INIT(ACPI_LV_INIT), 56 ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), 57 ACPI_DEBUG_INIT(ACPI_LV_INFO), 58 59 ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), 60 ACPI_DEBUG_INIT(ACPI_LV_PARSE), 61 ACPI_DEBUG_INIT(ACPI_LV_LOAD), 62 ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), 63 ACPI_DEBUG_INIT(ACPI_LV_EXEC), 64 ACPI_DEBUG_INIT(ACPI_LV_NAMES), 65 ACPI_DEBUG_INIT(ACPI_LV_OPREGION), 66 ACPI_DEBUG_INIT(ACPI_LV_BFIELD), 67 ACPI_DEBUG_INIT(ACPI_LV_TABLES), 68 ACPI_DEBUG_INIT(ACPI_LV_VALUES), 69 ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), 70 ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), 71 ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), 72 ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), 73 74 ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), 75 ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), 76 ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), 77 78 ACPI_DEBUG_INIT(ACPI_LV_MUTEX), 79 ACPI_DEBUG_INIT(ACPI_LV_THREADS), 80 ACPI_DEBUG_INIT(ACPI_LV_IO), 81 ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), 82 83 ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), 84 ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), 85 ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), 86 ACPI_DEBUG_INIT(ACPI_LV_EVENTS), 87}; 88 89static int 90acpi_system_read_debug(char *page, 91 char **start, off_t off, int count, int *eof, void *data) 92{ 93 char *p = page; 94 int size = 0; 95 unsigned int i; 96 97 if (off != 0) 98 goto end; 99 100 p += sprintf(p, "%-25s\tHex SET\n", "Description"); 101 102 switch ((unsigned long)data) { 103 case 0: 104 for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { 105 p += sprintf(p, "%-25s\t0x%08lX [%c]\n", 106 acpi_debug_layers[i].name, 107 acpi_debug_layers[i].value, 108 (acpi_dbg_layer & acpi_debug_layers[i]. 109 value) ? '*' : ' '); 110 } 111 p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", 112 ACPI_ALL_DRIVERS, 113 (acpi_dbg_layer & ACPI_ALL_DRIVERS) == 114 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & 115 ACPI_ALL_DRIVERS) == 116 0 ? ' ' : '-'); 117 p += sprintf(p, 118 "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", 119 acpi_dbg_layer); 120 break; 121 case 1: 122 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { 123 p += sprintf(p, "%-25s\t0x%08lX [%c]\n", 124 acpi_debug_levels[i].name, 125 acpi_debug_levels[i].value, 126 (acpi_dbg_level & acpi_debug_levels[i]. 127 value) ? '*' : ' '); 128 } 129 p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n", 130 acpi_dbg_level); 131 break; 132 default: 133 p += sprintf(p, "Invalid debug option\n"); 134 break; 135 } 136 137 end: 138 size = (p - page); 139 if (size <= off + count) 140 *eof = 1; 141 *start = page + off; 142 size -= off; 143 if (size > count) 144 size = count; 145 if (size < 0) 146 size = 0; 147 148 return size; 149} 150 151static int 152acpi_system_write_debug(struct file *file, 153 const char __user * buffer, 154 unsigned long count, void *data) 155{ 156 char debug_string[12] = { '\0' }; 157 158 ACPI_FUNCTION_TRACE("acpi_system_write_debug"); 159 160 if (count > sizeof(debug_string) - 1) 161 return_VALUE(-EINVAL); 162 163 if (copy_from_user(debug_string, buffer, count)) 164 return_VALUE(-EFAULT); 165 166 debug_string[count] = '\0'; 167 168 switch ((unsigned long)data) { 169 case 0: 170 acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); 171 break; 172 case 1: 173 acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); 174 break; 175 default: 176 return_VALUE(-EINVAL); 177 } 178 179 return_VALUE(count); 180} 181 182static int __init acpi_debug_init(void) 183{ 184 struct proc_dir_entry *entry; 185 int error = 0; 186 char *name; 187 188 ACPI_FUNCTION_TRACE("acpi_debug_init"); 189 190 if (acpi_disabled) 191 return_VALUE(0); 192 193 /* 'debug_layer' [R/W] */ 194 name = ACPI_SYSTEM_FILE_DEBUG_LAYER; 195 entry = 196 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 197 acpi_root_dir, acpi_system_read_debug, 198 (void *)0); 199 if (entry) 200 entry->write_proc = acpi_system_write_debug; 201 else 202 goto Error; 203 204 /* 'debug_level' [R/W] */ 205 name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; 206 entry = 207 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 208 acpi_root_dir, acpi_system_read_debug, 209 (void *)1); 210 if (entry) 211 entry->write_proc = acpi_system_write_debug; 212 else 213 goto Error; 214 215 Done: 216 return_VALUE(error); 217 218 Error: 219 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 220 "Unable to create '%s' proc fs entry\n", name)); 221 222 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); 223 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); 224 error = -EFAULT; 225 goto Done; 226} 227 228subsys_initcall(acpi_debug_init);