at v2.6.26 8.8 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 17#ifdef MODULE_PARAM_PREFIX 18#undef MODULE_PARAM_PREFIX 19#endif 20#define MODULE_PARAM_PREFIX "acpi." 21 22struct acpi_dlayer { 23 const char *name; 24 unsigned long value; 25}; 26struct acpi_dlevel { 27 const char *name; 28 unsigned long value; 29}; 30#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } 31 32static const struct acpi_dlayer acpi_debug_layers[] = { 33 ACPI_DEBUG_INIT(ACPI_UTILITIES), 34 ACPI_DEBUG_INIT(ACPI_HARDWARE), 35 ACPI_DEBUG_INIT(ACPI_EVENTS), 36 ACPI_DEBUG_INIT(ACPI_TABLES), 37 ACPI_DEBUG_INIT(ACPI_NAMESPACE), 38 ACPI_DEBUG_INIT(ACPI_PARSER), 39 ACPI_DEBUG_INIT(ACPI_DISPATCHER), 40 ACPI_DEBUG_INIT(ACPI_EXECUTER), 41 ACPI_DEBUG_INIT(ACPI_RESOURCES), 42 ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), 43 ACPI_DEBUG_INIT(ACPI_OS_SERVICES), 44 ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), 45 ACPI_DEBUG_INIT(ACPI_COMPILER), 46 ACPI_DEBUG_INIT(ACPI_TOOLS), 47}; 48 49static const struct acpi_dlevel acpi_debug_levels[] = { 50 ACPI_DEBUG_INIT(ACPI_LV_ERROR), 51 ACPI_DEBUG_INIT(ACPI_LV_WARN), 52 ACPI_DEBUG_INIT(ACPI_LV_INIT), 53 ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), 54 ACPI_DEBUG_INIT(ACPI_LV_INFO), 55 56 ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), 57 ACPI_DEBUG_INIT(ACPI_LV_PARSE), 58 ACPI_DEBUG_INIT(ACPI_LV_LOAD), 59 ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), 60 ACPI_DEBUG_INIT(ACPI_LV_EXEC), 61 ACPI_DEBUG_INIT(ACPI_LV_NAMES), 62 ACPI_DEBUG_INIT(ACPI_LV_OPREGION), 63 ACPI_DEBUG_INIT(ACPI_LV_BFIELD), 64 ACPI_DEBUG_INIT(ACPI_LV_TABLES), 65 ACPI_DEBUG_INIT(ACPI_LV_VALUES), 66 ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), 67 ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), 68 ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), 69 ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), 70 71 ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), 72 ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), 73 ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), 74 75 ACPI_DEBUG_INIT(ACPI_LV_MUTEX), 76 ACPI_DEBUG_INIT(ACPI_LV_THREADS), 77 ACPI_DEBUG_INIT(ACPI_LV_IO), 78 ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), 79 80 ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), 81 ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), 82 ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), 83 ACPI_DEBUG_INIT(ACPI_LV_EVENTS), 84}; 85 86/* -------------------------------------------------------------------------- 87 FS Interface (/sys) 88 -------------------------------------------------------------------------- */ 89static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { 90 int result = 0; 91 int i; 92 93 result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); 94 95 for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) { 96 result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n", 97 acpi_debug_layers[i].name, 98 acpi_debug_layers[i].value, 99 (acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' '); 100 } 101 result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", 102 ACPI_ALL_DRIVERS, 103 (acpi_dbg_layer & ACPI_ALL_DRIVERS) == 104 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & 105 ACPI_ALL_DRIVERS) == 0 ? ' ' : '-'); 106 result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer); 107 108 return result; 109} 110 111static int param_get_debug_level(char *buffer, struct kernel_param *kp) { 112 int result = 0; 113 int i; 114 115 result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); 116 117 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { 118 result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n", 119 acpi_debug_levels[i].name, 120 acpi_debug_levels[i].value, 121 (acpi_dbg_level & acpi_debug_levels[i]. 122 value) ? '*' : ' '); 123 } 124 result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n", 125 acpi_dbg_level); 126 127 return result; 128} 129 130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); 131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); 132 133static char trace_method_name[6]; 134module_param_string(trace_method_name, trace_method_name, 6, 0644); 135static unsigned int trace_debug_layer; 136module_param(trace_debug_layer, uint, 0644); 137static unsigned int trace_debug_level; 138module_param(trace_debug_level, uint, 0644); 139 140static int param_set_trace_state(const char *val, struct kernel_param *kp) 141{ 142 int result = 0; 143 144 if (!strncmp(val, "enable", strlen("enable") - 1)) { 145 result = acpi_debug_trace(trace_method_name, trace_debug_level, 146 trace_debug_layer, 0); 147 if (result) 148 result = -EBUSY; 149 goto exit; 150 } 151 152 if (!strncmp(val, "disable", strlen("disable") - 1)) { 153 int name = 0; 154 result = acpi_debug_trace((char *)&name, trace_debug_level, 155 trace_debug_layer, 0); 156 if (result) 157 result = -EBUSY; 158 goto exit; 159 } 160 161 if (!strncmp(val, "1", 1)) { 162 result = acpi_debug_trace(trace_method_name, trace_debug_level, 163 trace_debug_layer, 1); 164 if (result) 165 result = -EBUSY; 166 goto exit; 167 } 168 169 result = -EINVAL; 170exit: 171 return result; 172} 173 174static int param_get_trace_state(char *buffer, struct kernel_param *kp) 175{ 176 if (!acpi_gbl_trace_method_name) 177 return sprintf(buffer, "disable"); 178 else { 179 if (acpi_gbl_trace_flags & 1) 180 return sprintf(buffer, "1"); 181 else 182 return sprintf(buffer, "enable"); 183 } 184 return 0; 185} 186 187module_param_call(trace_state, param_set_trace_state, param_get_trace_state, 188 NULL, 0644); 189 190/* -------------------------------------------------------------------------- 191 FS Interface (/proc) 192 -------------------------------------------------------------------------- */ 193#ifdef CONFIG_ACPI_PROCFS 194#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" 195#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" 196 197static int 198acpi_system_read_debug(char *page, 199 char **start, off_t off, int count, int *eof, void *data) 200{ 201 char *p = page; 202 int size = 0; 203 unsigned int i; 204 205 if (off != 0) 206 goto end; 207 208 p += sprintf(p, "%-25s\tHex SET\n", "Description"); 209 210 switch ((unsigned long)data) { 211 case 0: 212 for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { 213 p += sprintf(p, "%-25s\t0x%08lX [%c]\n", 214 acpi_debug_layers[i].name, 215 acpi_debug_layers[i].value, 216 (acpi_dbg_layer & acpi_debug_layers[i]. 217 value) ? '*' : ' '); 218 } 219 p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", 220 ACPI_ALL_DRIVERS, 221 (acpi_dbg_layer & ACPI_ALL_DRIVERS) == 222 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & 223 ACPI_ALL_DRIVERS) == 224 0 ? ' ' : '-'); 225 p += sprintf(p, 226 "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", 227 acpi_dbg_layer); 228 break; 229 case 1: 230 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { 231 p += sprintf(p, "%-25s\t0x%08lX [%c]\n", 232 acpi_debug_levels[i].name, 233 acpi_debug_levels[i].value, 234 (acpi_dbg_level & acpi_debug_levels[i]. 235 value) ? '*' : ' '); 236 } 237 p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n", 238 acpi_dbg_level); 239 break; 240 default: 241 p += sprintf(p, "Invalid debug option\n"); 242 break; 243 } 244 245 end: 246 size = (p - page); 247 if (size <= off + count) 248 *eof = 1; 249 *start = page + off; 250 size -= off; 251 if (size > count) 252 size = count; 253 if (size < 0) 254 size = 0; 255 256 return size; 257} 258 259static int 260acpi_system_write_debug(struct file *file, 261 const char __user * buffer, 262 unsigned long count, void *data) 263{ 264 char debug_string[12] = { '\0' }; 265 266 267 if (count > sizeof(debug_string) - 1) 268 return -EINVAL; 269 270 if (copy_from_user(debug_string, buffer, count)) 271 return -EFAULT; 272 273 debug_string[count] = '\0'; 274 275 switch ((unsigned long)data) { 276 case 0: 277 acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); 278 break; 279 case 1: 280 acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); 281 break; 282 default: 283 return -EINVAL; 284 } 285 286 return count; 287} 288 289static int __init acpi_debug_init(void) 290{ 291 struct proc_dir_entry *entry; 292 int error = 0; 293 char *name; 294 295 296 if (acpi_disabled) 297 return 0; 298 299 /* 'debug_layer' [R/W] */ 300 name = ACPI_SYSTEM_FILE_DEBUG_LAYER; 301 entry = 302 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 303 acpi_root_dir, acpi_system_read_debug, 304 (void *)0); 305 if (entry) 306 entry->write_proc = acpi_system_write_debug; 307 else 308 goto Error; 309 310 /* 'debug_level' [R/W] */ 311 name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; 312 entry = 313 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 314 acpi_root_dir, acpi_system_read_debug, 315 (void *)1); 316 if (entry) 317 entry->write_proc = acpi_system_write_debug; 318 else 319 goto Error; 320 321 Done: 322 return error; 323 324 Error: 325 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); 326 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); 327 error = -ENODEV; 328 goto Done; 329} 330 331subsys_initcall(acpi_debug_init); 332#endif