debug.c 5.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * debug.c - ACPI debug interface to userspace.
 */

#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <asm/uaccess.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acglobal.h>

#define _COMPONENT		ACPI_SYSTEM_COMPONENT
L
Len Brown 已提交
15
ACPI_MODULE_NAME("debug")
L
Linus Torvalds 已提交
16 17 18 19 20 21
#define ACPI_SYSTEM_FILE_DEBUG_LAYER	"debug_layer"
#define ACPI_SYSTEM_FILE_DEBUG_LEVEL	"debug_level"
#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
#define MODULE_PARAM_PREFIX
L
Len Brown 已提交
22
    module_param(acpi_dbg_layer, uint, 0400);
L
Linus Torvalds 已提交
23 24 25 26 27 28 29 30 31 32 33 34
module_param(acpi_dbg_level, uint, 0400);

struct acpi_dlayer {
	const char *name;
	unsigned long value;
};
struct acpi_dlevel {
	const char *name;
	unsigned long value;
};
#define ACPI_DEBUG_INIT(v)	{ .name = #v, .value = v }

L
Len Brown 已提交
35
static const struct acpi_dlayer acpi_debug_layers[] = {
L
Linus Torvalds 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
	ACPI_DEBUG_INIT(ACPI_UTILITIES),
	ACPI_DEBUG_INIT(ACPI_HARDWARE),
	ACPI_DEBUG_INIT(ACPI_EVENTS),
	ACPI_DEBUG_INIT(ACPI_TABLES),
	ACPI_DEBUG_INIT(ACPI_NAMESPACE),
	ACPI_DEBUG_INIT(ACPI_PARSER),
	ACPI_DEBUG_INIT(ACPI_DISPATCHER),
	ACPI_DEBUG_INIT(ACPI_EXECUTER),
	ACPI_DEBUG_INIT(ACPI_RESOURCES),
	ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
	ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
	ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
	ACPI_DEBUG_INIT(ACPI_COMPILER),
	ACPI_DEBUG_INIT(ACPI_TOOLS),
};

L
Len Brown 已提交
52
static const struct acpi_dlevel acpi_debug_levels[] = {
L
Linus Torvalds 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
	ACPI_DEBUG_INIT(ACPI_LV_ERROR),
	ACPI_DEBUG_INIT(ACPI_LV_WARN),
	ACPI_DEBUG_INIT(ACPI_LV_INIT),
	ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
	ACPI_DEBUG_INIT(ACPI_LV_INFO),

	ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
	ACPI_DEBUG_INIT(ACPI_LV_PARSE),
	ACPI_DEBUG_INIT(ACPI_LV_LOAD),
	ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
	ACPI_DEBUG_INIT(ACPI_LV_EXEC),
	ACPI_DEBUG_INIT(ACPI_LV_NAMES),
	ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
	ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
	ACPI_DEBUG_INIT(ACPI_LV_TABLES),
	ACPI_DEBUG_INIT(ACPI_LV_VALUES),
	ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
	ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
	ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
	ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),

	ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
	ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
	ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),

	ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
	ACPI_DEBUG_INIT(ACPI_LV_THREADS),
	ACPI_DEBUG_INIT(ACPI_LV_IO),
	ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),

	ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
	ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
	ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
L
Len Brown 已提交
86
	ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
L
Linus Torvalds 已提交
87 88 89
};

static int
L
Len Brown 已提交
90 91
acpi_system_read_debug(char *page,
		       char **start, off_t off, int count, int *eof, void *data)
L
Linus Torvalds 已提交
92
{
L
Len Brown 已提交
93 94 95
	char *p = page;
	int size = 0;
	unsigned int i;
L
Linus Torvalds 已提交
96 97 98 99 100 101

	if (off != 0)
		goto end;

	p += sprintf(p, "%-25s\tHex        SET\n", "Description");

L
Len Brown 已提交
102
	switch ((unsigned long)data) {
L
Linus Torvalds 已提交
103 104 105
	case 0:
		for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
			p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
L
Len Brown 已提交
106 107 108 109
				     acpi_debug_layers[i].name,
				     acpi_debug_layers[i].value,
				     (acpi_dbg_layer & acpi_debug_layers[i].
				      value) ? '*' : ' ');
L
Linus Torvalds 已提交
110 111
		}
		p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
L
Len Brown 已提交
112 113 114 115 116
			     ACPI_ALL_DRIVERS,
			     (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
			     ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
						       ACPI_ALL_DRIVERS) ==
			     0 ? ' ' : '-');
L
Linus Torvalds 已提交
117
		p += sprintf(p,
L
Len Brown 已提交
118 119
			     "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
			     acpi_dbg_layer);
L
Linus Torvalds 已提交
120 121 122 123
		break;
	case 1:
		for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
			p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
L
Len Brown 已提交
124 125 126 127
				     acpi_debug_levels[i].name,
				     acpi_debug_levels[i].value,
				     (acpi_dbg_level & acpi_debug_levels[i].
				      value) ? '*' : ' ');
L
Linus Torvalds 已提交
128 129
		}
		p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n",
L
Len Brown 已提交
130
			     acpi_dbg_level);
L
Linus Torvalds 已提交
131 132 133 134 135
		break;
	default:
		p += sprintf(p, "Invalid debug option\n");
		break;
	}
L
Len Brown 已提交
136 137

      end:
L
Linus Torvalds 已提交
138
	size = (p - page);
L
Len Brown 已提交
139 140
	if (size <= off + count)
		*eof = 1;
L
Linus Torvalds 已提交
141 142
	*start = page + off;
	size -= off;
L
Len Brown 已提交
143 144 145 146
	if (size > count)
		size = count;
	if (size < 0)
		size = 0;
L
Linus Torvalds 已提交
147 148 149 150 151

	return size;
}

static int
L
Len Brown 已提交
152 153 154
acpi_system_write_debug(struct file *file,
			const char __user * buffer,
			unsigned long count, void *data)
L
Linus Torvalds 已提交
155
{
L
Len Brown 已提交
156
	char debug_string[12] = { '\0' };
L
Linus Torvalds 已提交
157 158 159 160 161 162 163 164 165 166 167

	ACPI_FUNCTION_TRACE("acpi_system_write_debug");

	if (count > sizeof(debug_string) - 1)
		return_VALUE(-EINVAL);

	if (copy_from_user(debug_string, buffer, count))
		return_VALUE(-EFAULT);

	debug_string[count] = '\0';

L
Len Brown 已提交
168
	switch ((unsigned long)data) {
L
Linus Torvalds 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
	case 0:
		acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0);
		break;
	case 1:
		acpi_dbg_level = simple_strtoul(debug_string, NULL, 0);
		break;
	default:
		return_VALUE(-EINVAL);
	}

	return_VALUE(count);
}

static int __init acpi_debug_init(void)
{
L
Len Brown 已提交
184
	struct proc_dir_entry *entry;
L
Linus Torvalds 已提交
185
	int error = 0;
L
Len Brown 已提交
186
	char *name;
L
Linus Torvalds 已提交
187 188 189 190 191 192 193 194

	ACPI_FUNCTION_TRACE("acpi_debug_init");

	if (acpi_disabled)
		return_VALUE(0);

	/* 'debug_layer' [R/W] */
	name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
L
Len Brown 已提交
195 196 197 198
	entry =
	    create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
				   acpi_root_dir, acpi_system_read_debug,
				   (void *)0);
L
Linus Torvalds 已提交
199 200 201 202 203 204 205
	if (entry)
		entry->write_proc = acpi_system_write_debug;
	else
		goto Error;

	/* 'debug_level' [R/W] */
	name = ACPI_SYSTEM_FILE_DEBUG_LEVEL;
L
Len Brown 已提交
206 207 208 209 210
	entry =
	    create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
				   acpi_root_dir, acpi_system_read_debug,
				   (void *)1);
	if (entry)
L
Linus Torvalds 已提交
211 212 213 214
		entry->write_proc = acpi_system_write_debug;
	else
		goto Error;

L
Len Brown 已提交
215
      Done:
L
Linus Torvalds 已提交
216 217
	return_VALUE(error);

L
Len Brown 已提交
218
      Error:
L
Linus Torvalds 已提交
219 220
	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir);
	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
221
	error = -ENODEV;
L
Linus Torvalds 已提交
222 223 224 225
	goto Done;
}

subsys_initcall(acpi_debug_init);