at v2.6.18-rc4 5.5 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 159 if (count > sizeof(debug_string) - 1) 160 return -EINVAL; 161 162 if (copy_from_user(debug_string, buffer, count)) 163 return -EFAULT; 164 165 debug_string[count] = '\0'; 166 167 switch ((unsigned long)data) { 168 case 0: 169 acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); 170 break; 171 case 1: 172 acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); 173 break; 174 default: 175 return -EINVAL; 176 } 177 178 return count; 179} 180 181static int __init acpi_debug_init(void) 182{ 183 struct proc_dir_entry *entry; 184 int error = 0; 185 char *name; 186 187 188 if (acpi_disabled) 189 return 0; 190 191 /* 'debug_layer' [R/W] */ 192 name = ACPI_SYSTEM_FILE_DEBUG_LAYER; 193 entry = 194 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 195 acpi_root_dir, acpi_system_read_debug, 196 (void *)0); 197 if (entry) 198 entry->write_proc = acpi_system_write_debug; 199 else 200 goto Error; 201 202 /* 'debug_level' [R/W] */ 203 name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; 204 entry = 205 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, 206 acpi_root_dir, acpi_system_read_debug, 207 (void *)1); 208 if (entry) 209 entry->write_proc = acpi_system_write_debug; 210 else 211 goto Error; 212 213 Done: 214 return error; 215 216 Error: 217 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); 218 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); 219 error = -ENODEV; 220 goto Done; 221} 222 223subsys_initcall(acpi_debug_init);