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