at v2.6.21 7.4 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 133/* -------------------------------------------------------------------------- 134 FS Interface (/proc) 135 -------------------------------------------------------------------------- */ 136#ifdef CONFIG_ACPI_PROCFS 137#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" 138#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" 139 140static int 141acpi_system_read_debug(char *page, 142 char **start, off_t off, int count, int *eof, void *data) 143{ 144 char *p = page; 145 int size = 0; 146 unsigned int i; 147 148 if (off != 0) 149 goto end; 150 151 p += sprintf(p, "%-25s\tHex SET\n", "Description"); 152 153 switch ((unsigned long)data) { 154 case 0: 155 for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { 156 p += sprintf(p, "%-25s\t0x%08lX [%c]\n", 157 acpi_debug_layers[i].name, 158 acpi_debug_layers[i].value, 159 (acpi_dbg_layer & acpi_debug_layers[i]. 160 value) ? '*' : ' '); 161 } 162 p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", 163 ACPI_ALL_DRIVERS, 164 (acpi_dbg_layer & ACPI_ALL_DRIVERS) == 165 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & 166 ACPI_ALL_DRIVERS) == 167 0 ? ' ' : '-'); 168 p += sprintf(p, 169 "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", 170 acpi_dbg_layer); 171 break; 172 case 1: 173 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { 174 p += sprintf(p, "%-25s\t0x%08lX [%c]\n", 175 acpi_debug_levels[i].name, 176 acpi_debug_levels[i].value, 177 (acpi_dbg_level & acpi_debug_levels[i]. 178 value) ? '*' : ' '); 179 } 180 p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n", 181 acpi_dbg_level); 182 break; 183 default: 184 p += sprintf(p, "Invalid debug option\n"); 185 break; 186 } 187 188 end: 189 size = (p - page); 190 if (size <= off + count) 191 *eof = 1; 192 *start = page + off; 193 size -= off; 194 if (size > count) 195 size = count; 196 if (size < 0) 197 size = 0; 198 199 return size; 200} 201 202static int 203acpi_system_write_debug(struct file *file, 204 const char __user * buffer, 205 unsigned long count, void *data) 206{ 207 char debug_string[12] = { '\0' }; 208 209 210 if (count > sizeof(debug_string) - 1) 211 return -EINVAL; 212 213 if (copy_from_user(debug_string, buffer, count)) 214 return -EFAULT; 215 216 debug_string[count] = '\0'; 217 218 switch ((unsigned long)data) { 219 case 0: 220 acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); 221 break; 222 case 1: 223 acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); 224 break; 225 default: 226 return -EINVAL; 227 } 228 229 return count; 230} 231 232static int __init acpi_debug_init(void) 233{ 234 struct proc_dir_entry *entry; 235 int error = 0; 236 char *name; 237 238 239 if (acpi_disabled) 240 return 0; 241 242 /* 'debug_layer' [R/W] */ 243 name = ACPI_SYSTEM_FILE_DEBUG_LAYER; 244 entry = 245 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 246 acpi_root_dir, acpi_system_read_debug, 247 (void *)0); 248 if (entry) 249 entry->write_proc = acpi_system_write_debug; 250 else 251 goto Error; 252 253 /* 'debug_level' [R/W] */ 254 name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; 255 entry = 256 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 257 acpi_root_dir, acpi_system_read_debug, 258 (void *)1); 259 if (entry) 260 entry->write_proc = acpi_system_write_debug; 261 else 262 goto Error; 263 264 Done: 265 return error; 266 267 Error: 268 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); 269 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); 270 error = -ENODEV; 271 goto Done; 272} 273 274subsys_initcall(acpi_debug_init); 275#endif