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