diff options
Diffstat (limited to 'drivers/acpi/parser')
-rw-r--r-- | drivers/acpi/parser/psargs.c | 358 | ||||
-rw-r--r-- | drivers/acpi/parser/psloop.c | 39 | ||||
-rw-r--r-- | drivers/acpi/parser/psopcode.c | 4 | ||||
-rw-r--r-- | drivers/acpi/parser/psparse.c | 55 | ||||
-rw-r--r-- | drivers/acpi/parser/psscope.c | 2 | ||||
-rw-r--r-- | drivers/acpi/parser/pstree.c | 5 | ||||
-rw-r--r-- | drivers/acpi/parser/psutils.c | 2 | ||||
-rw-r--r-- | drivers/acpi/parser/pswalk.c | 2 | ||||
-rw-r--r-- | drivers/acpi/parser/psxface.c | 144 |
9 files changed, 390 insertions, 221 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 5858188f94a6..de573be52718 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acparser.h> | 45 | #include <acpi/acparser.h> |
46 | #include <acpi/amlcode.h> | 46 | #include <acpi/amlcode.h> |
47 | #include <acpi/acnamesp.h> | 47 | #include <acpi/acnamesp.h> |
48 | #include <acpi/acdispat.h> | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_PARSER | 50 | #define _COMPONENT ACPI_PARSER |
50 | ACPI_MODULE_NAME("psargs") | 51 | ACPI_MODULE_NAME("psargs") |
@@ -62,61 +63,51 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state | |||
62 | * | 63 | * |
63 | * PARAMETERS: parser_state - Current parser state object | 64 | * PARAMETERS: parser_state - Current parser state object |
64 | * | 65 | * |
65 | * RETURN: Decoded package length. On completion, the AML pointer points | 66 | * RETURN: Decoded package length. On completion, the AML pointer points |
66 | * past the length byte or bytes. | 67 | * past the length byte or bytes. |
67 | * | 68 | * |
68 | * DESCRIPTION: Decode and return a package length field | 69 | * DESCRIPTION: Decode and return a package length field. |
70 | * Note: Largest package length is 28 bits, from ACPI specification | ||
69 | * | 71 | * |
70 | ******************************************************************************/ | 72 | ******************************************************************************/ |
71 | 73 | ||
72 | static u32 | 74 | static u32 |
73 | acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) | 75 | acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) |
74 | { | 76 | { |
75 | u32 encoded_length; | 77 | u8 *aml = parser_state->aml; |
76 | u32 length = 0; | 78 | u32 package_length = 0; |
79 | acpi_native_uint byte_count; | ||
80 | u8 byte_zero_mask = 0x3F; /* Default [0:5] */ | ||
77 | 81 | ||
78 | ACPI_FUNCTION_TRACE("ps_get_next_package_length"); | 82 | ACPI_FUNCTION_TRACE("ps_get_next_package_length"); |
79 | 83 | ||
80 | encoded_length = (u32) ACPI_GET8(parser_state->aml); | 84 | /* |
81 | parser_state->aml++; | 85 | * Byte 0 bits [6:7] contain the number of additional bytes |
82 | 86 | * used to encode the package length, either 0,1,2, or 3 | |
83 | switch (encoded_length >> 6) { /* bits 6-7 contain encoding scheme */ | 87 | */ |
84 | case 0: /* 1-byte encoding (bits 0-5) */ | 88 | byte_count = (aml[0] >> 6); |
85 | 89 | parser_state->aml += (byte_count + 1); | |
86 | length = (encoded_length & 0x3F); | ||
87 | break; | ||
88 | |||
89 | case 1: /* 2-byte encoding (next byte + bits 0-3) */ | ||
90 | |||
91 | length = ((ACPI_GET8(parser_state->aml) << 04) | | ||
92 | (encoded_length & 0x0F)); | ||
93 | parser_state->aml++; | ||
94 | break; | ||
95 | |||
96 | case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */ | ||
97 | |||
98 | length = ((ACPI_GET8(parser_state->aml + 1) << 12) | | ||
99 | (ACPI_GET8(parser_state->aml) << 04) | | ||
100 | (encoded_length & 0x0F)); | ||
101 | parser_state->aml += 2; | ||
102 | break; | ||
103 | 90 | ||
104 | case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ | 91 | /* Get bytes 3, 2, 1 as needed */ |
105 | 92 | ||
106 | length = ((ACPI_GET8(parser_state->aml + 2) << 20) | | 93 | while (byte_count) { |
107 | (ACPI_GET8(parser_state->aml + 1) << 12) | | 94 | /* |
108 | (ACPI_GET8(parser_state->aml) << 04) | | 95 | * Final bit positions for the package length bytes: |
109 | (encoded_length & 0x0F)); | 96 | * Byte3->[20:27] |
110 | parser_state->aml += 3; | 97 | * Byte2->[12:19] |
111 | break; | 98 | * Byte1->[04:11] |
112 | 99 | * Byte0->[00:03] | |
113 | default: | 100 | */ |
101 | package_length |= (aml[byte_count] << ((byte_count << 3) - 4)); | ||
114 | 102 | ||
115 | /* Can't get here, only 2 bits / 4 cases */ | 103 | byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */ |
116 | break; | 104 | byte_count--; |
117 | } | 105 | } |
118 | 106 | ||
119 | return_VALUE(length); | 107 | /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ |
108 | |||
109 | package_length |= (aml[0] & byte_zero_mask); | ||
110 | return_UINT32(package_length); | ||
120 | } | 111 | } |
121 | 112 | ||
122 | /******************************************************************************* | 113 | /******************************************************************************* |
@@ -135,16 +126,15 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) | |||
135 | u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) | 126 | u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) |
136 | { | 127 | { |
137 | u8 *start = parser_state->aml; | 128 | u8 *start = parser_state->aml; |
138 | acpi_native_uint length; | 129 | u32 package_length; |
139 | 130 | ||
140 | ACPI_FUNCTION_TRACE("ps_get_next_package_end"); | 131 | ACPI_FUNCTION_TRACE("ps_get_next_package_end"); |
141 | 132 | ||
142 | /* Function below changes parser_state->Aml */ | 133 | /* Function below updates parser_state->Aml */ |
143 | 134 | ||
144 | length = | 135 | package_length = acpi_ps_get_next_package_length(parser_state); |
145 | (acpi_native_uint) acpi_ps_get_next_package_length(parser_state); | ||
146 | 136 | ||
147 | return_PTR(start + length); /* end of package */ | 137 | return_PTR(start + package_length); /* end of package */ |
148 | } | 138 | } |
149 | 139 | ||
150 | /******************************************************************************* | 140 | /******************************************************************************* |
@@ -169,17 +159,15 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) | |||
169 | 159 | ||
170 | ACPI_FUNCTION_TRACE("ps_get_next_namestring"); | 160 | ACPI_FUNCTION_TRACE("ps_get_next_namestring"); |
171 | 161 | ||
172 | /* Handle multiple prefix characters */ | 162 | /* Point past any namestring prefix characters (backslash or carat) */ |
173 | |||
174 | while (acpi_ps_is_prefix_char(ACPI_GET8(end))) { | ||
175 | /* Include prefix '\\' or '^' */ | ||
176 | 163 | ||
164 | while (acpi_ps_is_prefix_char(*end)) { | ||
177 | end++; | 165 | end++; |
178 | } | 166 | } |
179 | 167 | ||
180 | /* Decode the path */ | 168 | /* Decode the path prefix character */ |
181 | 169 | ||
182 | switch (ACPI_GET8(end)) { | 170 | switch (*end) { |
183 | case 0: | 171 | case 0: |
184 | 172 | ||
185 | /* null_name */ | 173 | /* null_name */ |
@@ -199,9 +187,9 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) | |||
199 | 187 | ||
200 | case AML_MULTI_NAME_PREFIX_OP: | 188 | case AML_MULTI_NAME_PREFIX_OP: |
201 | 189 | ||
202 | /* Multiple name segments, 4 chars each */ | 190 | /* Multiple name segments, 4 chars each, count in next byte */ |
203 | 191 | ||
204 | end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE); | 192 | end += 2 + (*(end + 1) * ACPI_NAME_SIZE); |
205 | break; | 193 | break; |
206 | 194 | ||
207 | default: | 195 | default: |
@@ -212,7 +200,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) | |||
212 | break; | 200 | break; |
213 | } | 201 | } |
214 | 202 | ||
215 | parser_state->aml = (u8 *) end; | 203 | parser_state->aml = end; |
216 | return_PTR((char *)start); | 204 | return_PTR((char *)start); |
217 | } | 205 | } |
218 | 206 | ||
@@ -224,7 +212,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) | |||
224 | * Arg - Where the namepath will be stored | 212 | * Arg - Where the namepath will be stored |
225 | * arg_count - If the namepath points to a control method | 213 | * arg_count - If the namepath points to a control method |
226 | * the method's argument is returned here. | 214 | * the method's argument is returned here. |
227 | * method_call - Whether the namepath can possibly be the | 215 | * possible_method_call - Whether the namepath can possibly be the |
228 | * start of a method call | 216 | * start of a method call |
229 | * | 217 | * |
230 | * RETURN: Status | 218 | * RETURN: Status |
@@ -240,11 +228,11 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) | |||
240 | acpi_status | 228 | acpi_status |
241 | acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | 229 | acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, |
242 | struct acpi_parse_state *parser_state, | 230 | struct acpi_parse_state *parser_state, |
243 | union acpi_parse_object *arg, u8 method_call) | 231 | union acpi_parse_object *arg, u8 possible_method_call) |
244 | { | 232 | { |
245 | char *path; | 233 | char *path; |
246 | union acpi_parse_object *name_op; | 234 | union acpi_parse_object *name_op; |
247 | acpi_status status = AE_OK; | 235 | acpi_status status; |
248 | union acpi_operand_object *method_desc; | 236 | union acpi_operand_object *method_desc; |
249 | struct acpi_namespace_node *node; | 237 | struct acpi_namespace_node *node; |
250 | union acpi_generic_state scope_info; | 238 | union acpi_generic_state scope_info; |
@@ -252,115 +240,129 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
252 | ACPI_FUNCTION_TRACE("ps_get_next_namepath"); | 240 | ACPI_FUNCTION_TRACE("ps_get_next_namepath"); |
253 | 241 | ||
254 | path = acpi_ps_get_next_namestring(parser_state); | 242 | path = acpi_ps_get_next_namestring(parser_state); |
243 | acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); | ||
255 | 244 | ||
256 | /* Null path case is allowed */ | 245 | /* Null path case is allowed, just exit */ |
257 | 246 | ||
258 | if (path) { | 247 | if (!path) { |
259 | /* | 248 | arg->common.value.name = path; |
260 | * Lookup the name in the internal namespace | 249 | return_ACPI_STATUS(AE_OK); |
261 | */ | 250 | } |
262 | scope_info.scope.node = NULL; | ||
263 | node = parser_state->start_node; | ||
264 | if (node) { | ||
265 | scope_info.scope.node = node; | ||
266 | } | ||
267 | 251 | ||
268 | /* | 252 | /* Setup search scope info */ |
269 | * Lookup object. We don't want to add anything new to the namespace | ||
270 | * here, however. So we use MODE_EXECUTE. Allow searching of the | ||
271 | * parent tree, but don't open a new scope -- we just want to lookup the | ||
272 | * object (MUST BE mode EXECUTE to perform upsearch) | ||
273 | */ | ||
274 | status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, | ||
275 | ACPI_IMODE_EXECUTE, | ||
276 | ACPI_NS_SEARCH_PARENT | | ||
277 | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node); | ||
278 | if (ACPI_SUCCESS(status) && method_call) { | ||
279 | if (node->type == ACPI_TYPE_METHOD) { | ||
280 | /* This name is actually a control method invocation */ | ||
281 | |||
282 | method_desc = acpi_ns_get_attached_object(node); | ||
283 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
284 | "Control Method - %p Desc %p Path=%p\n", | ||
285 | node, method_desc, path)); | ||
286 | |||
287 | name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); | ||
288 | if (!name_op) { | ||
289 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
290 | } | ||
291 | 253 | ||
292 | /* Change arg into a METHOD CALL and attach name to it */ | 254 | scope_info.scope.node = NULL; |
255 | node = parser_state->start_node; | ||
256 | if (node) { | ||
257 | scope_info.scope.node = node; | ||
258 | } | ||
293 | 259 | ||
294 | acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); | 260 | /* |
295 | name_op->common.value.name = path; | 261 | * Lookup the name in the internal namespace. We don't want to add |
262 | * anything new to the namespace here, however, so we use MODE_EXECUTE. | ||
263 | * Allow searching of the parent tree, but don't open a new scope - | ||
264 | * we just want to lookup the object (must be mode EXECUTE to perform | ||
265 | * the upsearch) | ||
266 | */ | ||
267 | status = | ||
268 | acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | ||
269 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, | ||
270 | NULL, &node); | ||
296 | 271 | ||
297 | /* Point METHODCALL/NAME to the METHOD Node */ | 272 | /* |
273 | * If this name is a control method invocation, we must | ||
274 | * setup the method call | ||
275 | */ | ||
276 | if (ACPI_SUCCESS(status) && | ||
277 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { | ||
278 | /* This name is actually a control method invocation */ | ||
298 | 279 | ||
299 | name_op->common.node = node; | 280 | method_desc = acpi_ns_get_attached_object(node); |
300 | acpi_ps_append_arg(arg, name_op); | 281 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
282 | "Control Method - %p Desc %p Path=%p\n", node, | ||
283 | method_desc, path)); | ||
301 | 284 | ||
302 | if (!method_desc) { | 285 | name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); |
303 | ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node)); | 286 | if (!name_op) { |
304 | return_ACPI_STATUS(AE_AML_INTERNAL); | 287 | return_ACPI_STATUS(AE_NO_MEMORY); |
305 | } | 288 | } |
306 | 289 | ||
307 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 290 | /* Change Arg into a METHOD CALL and attach name to it */ |
308 | "Control Method - %p Args %X\n", | ||
309 | node, | ||
310 | method_desc->method. | ||
311 | param_count)); | ||
312 | 291 | ||
313 | /* Get the number of arguments to expect */ | 292 | acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); |
293 | name_op->common.value.name = path; | ||
314 | 294 | ||
315 | walk_state->arg_count = | 295 | /* Point METHODCALL/NAME to the METHOD Node */ |
316 | method_desc->method.param_count; | ||
317 | return_ACPI_STATUS(AE_OK); | ||
318 | } | ||
319 | 296 | ||
320 | /* | 297 | name_op->common.node = node; |
321 | * Else this is normal named object reference. | 298 | acpi_ps_append_arg(arg, name_op); |
322 | * Just init the NAMEPATH object with the pathname. | ||
323 | * (See code below) | ||
324 | */ | ||
325 | } | ||
326 | 299 | ||
327 | if (ACPI_FAILURE(status)) { | 300 | if (!method_desc) { |
328 | /* | 301 | ACPI_ERROR((AE_INFO, |
329 | * 1) Any error other than NOT_FOUND is always severe | 302 | "Control Method %p has no attached object", |
330 | * 2) NOT_FOUND is only important if we are executing a method. | 303 | node)); |
331 | * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok. | 304 | return_ACPI_STATUS(AE_AML_INTERNAL); |
332 | */ | ||
333 | if ((((walk_state-> | ||
334 | parse_flags & ACPI_PARSE_MODE_MASK) == | ||
335 | ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND) | ||
336 | && (walk_state->op->common.aml_opcode != | ||
337 | AML_COND_REF_OF_OP)) | ||
338 | || (status != AE_NOT_FOUND)) { | ||
339 | ACPI_REPORT_NSERROR(path, status); | ||
340 | |||
341 | acpi_os_printf | ||
342 | ("search_node %p start_node %p return_node %p\n", | ||
343 | scope_info.scope.node, | ||
344 | parser_state->start_node, node); | ||
345 | |||
346 | } else { | ||
347 | /* | ||
348 | * We got a NOT_FOUND during table load or we encountered | ||
349 | * a cond_ref_of(x) where the target does not exist. | ||
350 | * Either case is ok | ||
351 | */ | ||
352 | status = AE_OK; | ||
353 | } | ||
354 | } | 305 | } |
306 | |||
307 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
308 | "Control Method - %p Args %X\n", | ||
309 | node, method_desc->method.param_count)); | ||
310 | |||
311 | /* Get the number of arguments to expect */ | ||
312 | |||
313 | walk_state->arg_count = method_desc->method.param_count; | ||
314 | return_ACPI_STATUS(AE_OK); | ||
355 | } | 315 | } |
356 | 316 | ||
357 | /* | 317 | /* |
358 | * Regardless of success/failure above, | 318 | * Special handling if the name was not found during the lookup - |
359 | * Just initialize the Op with the pathname. | 319 | * some not_found cases are allowed |
360 | */ | 320 | */ |
361 | acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); | 321 | if (status == AE_NOT_FOUND) { |
362 | arg->common.value.name = path; | 322 | /* 1) not_found is ok during load pass 1/2 (allow forward references) */ |
323 | |||
324 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) != | ||
325 | ACPI_PARSE_EXECUTE) { | ||
326 | status = AE_OK; | ||
327 | } | ||
328 | |||
329 | /* 2) not_found during a cond_ref_of(x) is ok by definition */ | ||
330 | |||
331 | else if (walk_state->op->common.aml_opcode == | ||
332 | AML_COND_REF_OF_OP) { | ||
333 | status = AE_OK; | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | * 3) not_found while building a Package is ok at this point, we | ||
338 | * may flag as an error later if slack mode is not enabled. | ||
339 | * (Some ASL code depends on allowing this behavior) | ||
340 | */ | ||
341 | else if ((arg->common.parent) && | ||
342 | ((arg->common.parent->common.aml_opcode == | ||
343 | AML_PACKAGE_OP) | ||
344 | || (arg->common.parent->common.aml_opcode == | ||
345 | AML_VAR_PACKAGE_OP))) { | ||
346 | status = AE_OK; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /* Final exception check (may have been changed from code above) */ | ||
363 | 351 | ||
352 | if (ACPI_FAILURE(status)) { | ||
353 | ACPI_ERROR_NAMESPACE(path, status); | ||
354 | |||
355 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == | ||
356 | ACPI_PARSE_EXECUTE) { | ||
357 | /* Report a control method execution error */ | ||
358 | |||
359 | status = acpi_ds_method_error(status, walk_state); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | /* Save the namepath */ | ||
364 | |||
365 | arg->common.value.name = path; | ||
364 | return_ACPI_STATUS(status); | 366 | return_ACPI_STATUS(status); |
365 | } | 367 | } |
366 | 368 | ||
@@ -382,59 +384,63 @@ void | |||
382 | acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, | 384 | acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, |
383 | u32 arg_type, union acpi_parse_object *arg) | 385 | u32 arg_type, union acpi_parse_object *arg) |
384 | { | 386 | { |
387 | u32 length; | ||
388 | u16 opcode; | ||
389 | u8 *aml = parser_state->aml; | ||
385 | 390 | ||
386 | ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); | 391 | ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); |
387 | 392 | ||
388 | switch (arg_type) { | 393 | switch (arg_type) { |
389 | case ARGP_BYTEDATA: | 394 | case ARGP_BYTEDATA: |
390 | 395 | ||
391 | acpi_ps_init_op(arg, AML_BYTE_OP); | 396 | /* Get 1 byte from the AML stream */ |
392 | arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml); | 397 | |
393 | parser_state->aml++; | 398 | opcode = AML_BYTE_OP; |
399 | arg->common.value.integer = (acpi_integer) * aml; | ||
400 | length = 1; | ||
394 | break; | 401 | break; |
395 | 402 | ||
396 | case ARGP_WORDDATA: | 403 | case ARGP_WORDDATA: |
397 | 404 | ||
398 | acpi_ps_init_op(arg, AML_WORD_OP); | ||
399 | |||
400 | /* Get 2 bytes from the AML stream */ | 405 | /* Get 2 bytes from the AML stream */ |
401 | 406 | ||
402 | ACPI_MOVE_16_TO_32(&arg->common.value.integer, | 407 | opcode = AML_WORD_OP; |
403 | parser_state->aml); | 408 | ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml); |
404 | parser_state->aml += 2; | 409 | length = 2; |
405 | break; | 410 | break; |
406 | 411 | ||
407 | case ARGP_DWORDDATA: | 412 | case ARGP_DWORDDATA: |
408 | 413 | ||
409 | acpi_ps_init_op(arg, AML_DWORD_OP); | ||
410 | |||
411 | /* Get 4 bytes from the AML stream */ | 414 | /* Get 4 bytes from the AML stream */ |
412 | 415 | ||
413 | ACPI_MOVE_32_TO_32(&arg->common.value.integer, | 416 | opcode = AML_DWORD_OP; |
414 | parser_state->aml); | 417 | ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml); |
415 | parser_state->aml += 4; | 418 | length = 4; |
416 | break; | 419 | break; |
417 | 420 | ||
418 | case ARGP_QWORDDATA: | 421 | case ARGP_QWORDDATA: |
419 | 422 | ||
420 | acpi_ps_init_op(arg, AML_QWORD_OP); | ||
421 | |||
422 | /* Get 8 bytes from the AML stream */ | 423 | /* Get 8 bytes from the AML stream */ |
423 | 424 | ||
424 | ACPI_MOVE_64_TO_64(&arg->common.value.integer, | 425 | opcode = AML_QWORD_OP; |
425 | parser_state->aml); | 426 | ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml); |
426 | parser_state->aml += 8; | 427 | length = 8; |
427 | break; | 428 | break; |
428 | 429 | ||
429 | case ARGP_CHARLIST: | 430 | case ARGP_CHARLIST: |
430 | 431 | ||
431 | acpi_ps_init_op(arg, AML_STRING_OP); | 432 | /* Get a pointer to the string, point past the string */ |
432 | arg->common.value.string = (char *)parser_state->aml; | 433 | |
434 | opcode = AML_STRING_OP; | ||
435 | arg->common.value.string = ACPI_CAST_PTR(char, aml); | ||
433 | 436 | ||
434 | while (ACPI_GET8(parser_state->aml) != '\0') { | 437 | /* Find the null terminator */ |
435 | parser_state->aml++; | 438 | |
439 | length = 0; | ||
440 | while (aml[length]) { | ||
441 | length++; | ||
436 | } | 442 | } |
437 | parser_state->aml++; | 443 | length++; |
438 | break; | 444 | break; |
439 | 445 | ||
440 | case ARGP_NAME: | 446 | case ARGP_NAME: |
@@ -443,14 +449,16 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, | |||
443 | acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); | 449 | acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); |
444 | arg->common.value.name = | 450 | arg->common.value.name = |
445 | acpi_ps_get_next_namestring(parser_state); | 451 | acpi_ps_get_next_namestring(parser_state); |
446 | break; | 452 | return_VOID; |
447 | 453 | ||
448 | default: | 454 | default: |
449 | 455 | ||
450 | ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type)); | 456 | ACPI_ERROR((AE_INFO, "Invalid arg_type %X", arg_type)); |
451 | break; | 457 | return_VOID; |
452 | } | 458 | } |
453 | 459 | ||
460 | acpi_ps_init_op(arg, opcode); | ||
461 | parser_state->aml += length; | ||
454 | return_VOID; | 462 | return_VOID; |
455 | } | 463 | } |
456 | 464 | ||
@@ -540,7 +548,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state | |||
540 | * access_type is first operand, access_attribute is second | 548 | * access_type is first operand, access_attribute is second |
541 | */ | 549 | */ |
542 | field->common.value.integer = | 550 | field->common.value.integer = |
543 | (ACPI_GET8(parser_state->aml) << 8); | 551 | (((u32) ACPI_GET8(parser_state->aml) << 8)); |
544 | parser_state->aml++; | 552 | parser_state->aml++; |
545 | field->common.value.integer |= ACPI_GET8(parser_state->aml); | 553 | field->common.value.integer |= ACPI_GET8(parser_state->aml); |
546 | parser_state->aml++; | 554 | parser_state->aml++; |
@@ -703,7 +711,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, | |||
703 | 711 | ||
704 | default: | 712 | default: |
705 | 713 | ||
706 | ACPI_REPORT_ERROR(("Invalid arg_type: %X\n", arg_type)); | 714 | ACPI_ERROR((AE_INFO, "Invalid arg_type: %X", arg_type)); |
707 | status = AE_AML_OPERAND_TYPE; | 715 | status = AE_AML_OPERAND_TYPE; |
708 | break; | 716 | break; |
709 | } | 717 | } |
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index 088d33999d90..00b072e15d19 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -123,16 +123,12 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
123 | && ((status & AE_CODE_MASK) != | 123 | && ((status & AE_CODE_MASK) != |
124 | AE_CODE_CONTROL)) { | 124 | AE_CODE_CONTROL)) { |
125 | if (status == AE_AML_NO_RETURN_VALUE) { | 125 | if (status == AE_AML_NO_RETURN_VALUE) { |
126 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 126 | ACPI_EXCEPTION((AE_INFO, status, |
127 | "Invoked method did not return a value, %s\n", | 127 | "Invoked method did not return a value")); |
128 | acpi_format_exception | ||
129 | (status))); | ||
130 | 128 | ||
131 | } | 129 | } |
132 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 130 | ACPI_EXCEPTION((AE_INFO, status, |
133 | "get_predicate Failed, %s\n", | 131 | "get_predicate Failed")); |
134 | acpi_format_exception | ||
135 | (status))); | ||
136 | return_ACPI_STATUS(status); | 132 | return_ACPI_STATUS(status); |
137 | } | 133 | } |
138 | 134 | ||
@@ -190,11 +186,11 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
190 | 186 | ||
191 | /* The opcode is unrecognized. Just skip unknown opcodes */ | 187 | /* The opcode is unrecognized. Just skip unknown opcodes */ |
192 | 188 | ||
193 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 189 | ACPI_ERROR((AE_INFO, |
194 | "Found unknown opcode %X at AML address %p offset %X, ignoring\n", | 190 | "Found unknown opcode %X at AML address %p offset %X, ignoring", |
195 | walk_state->opcode, | 191 | walk_state->opcode, |
196 | parser_state->aml, | 192 | parser_state->aml, |
197 | walk_state->aml_offset)); | 193 | walk_state->aml_offset)); |
198 | 194 | ||
199 | ACPI_DUMP_BUFFER(parser_state->aml, 128); | 195 | ACPI_DUMP_BUFFER(parser_state->aml, 128); |
200 | 196 | ||
@@ -281,10 +277,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
281 | walk_state->descending_callback(walk_state, | 277 | walk_state->descending_callback(walk_state, |
282 | &op); | 278 | &op); |
283 | if (ACPI_FAILURE(status)) { | 279 | if (ACPI_FAILURE(status)) { |
284 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 280 | ACPI_EXCEPTION((AE_INFO, status, |
285 | "During name lookup/catalog, %s\n", | 281 | "During name lookup/catalog")); |
286 | acpi_format_exception | ||
287 | (status))); | ||
288 | goto close_this_op; | 282 | goto close_this_op; |
289 | } | 283 | } |
290 | 284 | ||
@@ -704,6 +698,15 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
704 | acpi_ps_pop_scope(parser_state, &op, | 698 | acpi_ps_pop_scope(parser_state, &op, |
705 | &walk_state->arg_types, | 699 | &walk_state->arg_types, |
706 | &walk_state->arg_count); | 700 | &walk_state->arg_count); |
701 | |||
702 | if (op->common.aml_opcode != AML_WHILE_OP) { | ||
703 | status2 = | ||
704 | acpi_ds_result_stack_pop | ||
705 | (walk_state); | ||
706 | if (ACPI_FAILURE(status2)) { | ||
707 | return_ACPI_STATUS(status2); | ||
708 | } | ||
709 | } | ||
707 | } | 710 | } |
708 | 711 | ||
709 | /* Close this iteration of the While loop */ | 712 | /* Close this iteration of the While loop */ |
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 229ae86afe8b..11d6351ab8b2 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -747,7 +747,7 @@ const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) | |||
747 | 747 | ||
748 | /* Unknown AML opcode */ | 748 | /* Unknown AML opcode */ |
749 | 749 | ||
750 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 750 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
751 | "Unknown AML opcode [%4.4X]\n", opcode)); | 751 | "Unknown AML opcode [%4.4X]\n", opcode)); |
752 | 752 | ||
753 | return (&acpi_gbl_aml_op_info[_UNK]); | 753 | return (&acpi_gbl_aml_op_info[_UNK]); |
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 76d4d640d83c..a9f3229f4106 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -333,7 +333,6 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, | |||
333 | 333 | ||
334 | switch (callback_status) { | 334 | switch (callback_status) { |
335 | case AE_CTRL_TERMINATE: | 335 | case AE_CTRL_TERMINATE: |
336 | |||
337 | /* | 336 | /* |
338 | * A control method was terminated via a RETURN statement. | 337 | * A control method was terminated via a RETURN statement. |
339 | * The walk of this method is complete. | 338 | * The walk of this method is complete. |
@@ -346,13 +345,19 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, | |||
346 | 345 | ||
347 | parser_state->aml = walk_state->aml_last_while; | 346 | parser_state->aml = walk_state->aml_last_while; |
348 | walk_state->control_state->common.value = FALSE; | 347 | walk_state->control_state->common.value = FALSE; |
349 | status = AE_CTRL_BREAK; | 348 | status = acpi_ds_result_stack_pop(walk_state); |
349 | if (ACPI_SUCCESS(status)) { | ||
350 | status = AE_CTRL_BREAK; | ||
351 | } | ||
350 | break; | 352 | break; |
351 | 353 | ||
352 | case AE_CTRL_CONTINUE: | 354 | case AE_CTRL_CONTINUE: |
353 | 355 | ||
354 | parser_state->aml = walk_state->aml_last_while; | 356 | parser_state->aml = walk_state->aml_last_while; |
355 | status = AE_CTRL_CONTINUE; | 357 | status = acpi_ds_result_stack_pop(walk_state); |
358 | if (ACPI_SUCCESS(status)) { | ||
359 | status = AE_CTRL_CONTINUE; | ||
360 | } | ||
356 | break; | 361 | break; |
357 | 362 | ||
358 | case AE_CTRL_PENDING: | 363 | case AE_CTRL_PENDING: |
@@ -369,16 +374,18 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, | |||
369 | #endif | 374 | #endif |
370 | 375 | ||
371 | case AE_CTRL_TRUE: | 376 | case AE_CTRL_TRUE: |
372 | |||
373 | /* | 377 | /* |
374 | * Predicate of an IF was true, and we are at the matching ELSE. | 378 | * Predicate of an IF was true, and we are at the matching ELSE. |
375 | * Just close out this package | 379 | * Just close out this package |
376 | */ | 380 | */ |
377 | parser_state->aml = acpi_ps_get_next_package_end(parser_state); | 381 | parser_state->aml = acpi_ps_get_next_package_end(parser_state); |
382 | status = acpi_ds_result_stack_pop(walk_state); | ||
383 | if (ACPI_SUCCESS(status)) { | ||
384 | status = AE_CTRL_PENDING; | ||
385 | } | ||
378 | break; | 386 | break; |
379 | 387 | ||
380 | case AE_CTRL_FALSE: | 388 | case AE_CTRL_FALSE: |
381 | |||
382 | /* | 389 | /* |
383 | * Either an IF/WHILE Predicate was false or we encountered a BREAK | 390 | * Either an IF/WHILE Predicate was false or we encountered a BREAK |
384 | * opcode. In both cases, we do not execute the rest of the | 391 | * opcode. In both cases, we do not execute the rest of the |
@@ -503,22 +510,23 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
503 | } else if (status == AE_CTRL_TERMINATE) { | 510 | } else if (status == AE_CTRL_TERMINATE) { |
504 | status = AE_OK; | 511 | status = AE_OK; |
505 | } else if ((status != AE_OK) && (walk_state->method_desc)) { | 512 | } else if ((status != AE_OK) && (walk_state->method_desc)) { |
506 | ACPI_REPORT_METHOD_ERROR("Method execution failed", | 513 | /* Either the method parse or actual execution failed */ |
507 | walk_state->method_node, NULL, | ||
508 | status); | ||
509 | |||
510 | /* Ensure proper cleanup */ | ||
511 | 514 | ||
512 | walk_state->parse_flags |= ACPI_PARSE_EXECUTE; | 515 | ACPI_ERROR_METHOD("Method parse/execution failed", |
516 | walk_state->method_node, NULL, | ||
517 | status); | ||
513 | 518 | ||
514 | /* Check for possible multi-thread reentrancy problem */ | 519 | /* Check for possible multi-thread reentrancy problem */ |
515 | 520 | ||
516 | if ((status == AE_ALREADY_EXISTS) && | 521 | if ((status == AE_ALREADY_EXISTS) && |
517 | (!walk_state->method_desc->method.semaphore)) { | 522 | (!walk_state->method_desc->method.semaphore)) { |
518 | /* | 523 | /* |
519 | * This method is marked not_serialized, but it tried to create | 524 | * Method tried to create an object twice. The probable cause is |
525 | * that the method cannot handle reentrancy. | ||
526 | * | ||
527 | * The method is marked not_serialized, but it tried to create | ||
520 | * a named object, causing the second thread entrance to fail. | 528 | * a named object, causing the second thread entrance to fail. |
521 | * We will workaround this by marking the method permanently | 529 | * Workaround this problem by marking the method permanently |
522 | * as Serialized. | 530 | * as Serialized. |
523 | */ | 531 | */ |
524 | walk_state->method_desc->method.method_flags |= | 532 | walk_state->method_desc->method.method_flags |= |
@@ -536,15 +544,23 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
536 | acpi_ds_scope_stack_clear(walk_state); | 544 | acpi_ds_scope_stack_clear(walk_state); |
537 | 545 | ||
538 | /* | 546 | /* |
539 | * If we just returned from the execution of a control method, | 547 | * If we just returned from the execution of a control method or if we |
540 | * there's lots of cleanup to do | 548 | * encountered an error during the method parse phase, there's lots of |
549 | * cleanup to do | ||
541 | */ | 550 | */ |
542 | if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == | 551 | if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == |
543 | ACPI_PARSE_EXECUTE) { | 552 | ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) { |
544 | if (walk_state->method_desc) { | 553 | if (walk_state->method_desc) { |
545 | /* Decrement the thread count on the method parse tree */ | 554 | /* Decrement the thread count on the method parse tree */ |
546 | 555 | ||
547 | walk_state->method_desc->method.thread_count--; | 556 | if (walk_state->method_desc->method. |
557 | thread_count) { | ||
558 | walk_state->method_desc->method. | ||
559 | thread_count--; | ||
560 | } else { | ||
561 | ACPI_ERROR((AE_INFO, | ||
562 | "Invalid zero thread count in method")); | ||
563 | } | ||
548 | } | 564 | } |
549 | 565 | ||
550 | acpi_ds_terminate_control_method(walk_state); | 566 | acpi_ds_terminate_control_method(walk_state); |
@@ -553,7 +569,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
553 | /* Delete this walk state and all linked control states */ | 569 | /* Delete this walk state and all linked control states */ |
554 | 570 | ||
555 | acpi_ps_cleanup_scope(&walk_state->parser_state); | 571 | acpi_ps_cleanup_scope(&walk_state->parser_state); |
556 | |||
557 | previous_walk_state = walk_state; | 572 | previous_walk_state = walk_state; |
558 | 573 | ||
559 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 574 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index 1c953b6f1af1..bc6047caccd9 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index f0e755884eea..dd6f16726fc4 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -132,7 +132,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) | |||
132 | if (op_info->class == AML_CLASS_UNKNOWN) { | 132 | if (op_info->class == AML_CLASS_UNKNOWN) { |
133 | /* Invalid opcode */ | 133 | /* Invalid opcode */ |
134 | 134 | ||
135 | ACPI_REPORT_ERROR(("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", op->common.aml_opcode)); | 135 | ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X", |
136 | op->common.aml_opcode)); | ||
136 | return; | 137 | return; |
137 | } | 138 | } |
138 | 139 | ||
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index 2075efbb4324..3e07cb9cb748 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index 08f2321b6ded..06f05bfd7612 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 4dcbd443160e..2dd48cbb7c02 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -50,6 +50,10 @@ | |||
50 | ACPI_MODULE_NAME("psxface") | 50 | ACPI_MODULE_NAME("psxface") |
51 | 51 | ||
52 | /* Local Prototypes */ | 52 | /* Local Prototypes */ |
53 | static void acpi_ps_start_trace(struct acpi_parameter_info *info); | ||
54 | |||
55 | static void acpi_ps_stop_trace(struct acpi_parameter_info *info); | ||
56 | |||
53 | static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); | 57 | static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); |
54 | 58 | ||
55 | static void | 59 | static void |
@@ -57,6 +61,136 @@ acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action); | |||
57 | 61 | ||
58 | /******************************************************************************* | 62 | /******************************************************************************* |
59 | * | 63 | * |
64 | * FUNCTION: acpi_debug_trace | ||
65 | * | ||
66 | * PARAMETERS: method_name - Valid ACPI name string | ||
67 | * debug_level - Optional level mask. 0 to use default | ||
68 | * debug_layer - Optional layer mask. 0 to use default | ||
69 | * Flags - bit 1: one shot(1) or persistent(0) | ||
70 | * | ||
71 | * RETURN: Status | ||
72 | * | ||
73 | * DESCRIPTION: External interface to enable debug tracing during control | ||
74 | * method execution | ||
75 | * | ||
76 | ******************************************************************************/ | ||
77 | |||
78 | acpi_status | ||
79 | acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) | ||
80 | { | ||
81 | acpi_status status; | ||
82 | |||
83 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
84 | if (ACPI_FAILURE(status)) { | ||
85 | return (status); | ||
86 | } | ||
87 | |||
88 | /* TBDs: Validate name, allow full path or just nameseg */ | ||
89 | |||
90 | acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name); | ||
91 | acpi_gbl_trace_flags = flags; | ||
92 | |||
93 | if (debug_level) { | ||
94 | acpi_gbl_trace_dbg_level = debug_level; | ||
95 | } | ||
96 | if (debug_layer) { | ||
97 | acpi_gbl_trace_dbg_layer = debug_layer; | ||
98 | } | ||
99 | |||
100 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
101 | return (AE_OK); | ||
102 | } | ||
103 | |||
104 | /******************************************************************************* | ||
105 | * | ||
106 | * FUNCTION: acpi_ps_start_trace | ||
107 | * | ||
108 | * PARAMETERS: Info - Method info struct | ||
109 | * | ||
110 | * RETURN: None | ||
111 | * | ||
112 | * DESCRIPTION: Start control method execution trace | ||
113 | * | ||
114 | ******************************************************************************/ | ||
115 | |||
116 | static void acpi_ps_start_trace(struct acpi_parameter_info *info) | ||
117 | { | ||
118 | acpi_status status; | ||
119 | |||
120 | ACPI_FUNCTION_ENTRY(); | ||
121 | |||
122 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
123 | if (ACPI_FAILURE(status)) { | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | if ((!acpi_gbl_trace_method_name) || | ||
128 | (acpi_gbl_trace_method_name != info->node->name.integer)) { | ||
129 | goto exit; | ||
130 | } | ||
131 | |||
132 | acpi_gbl_original_dbg_level = acpi_dbg_level; | ||
133 | acpi_gbl_original_dbg_layer = acpi_dbg_layer; | ||
134 | |||
135 | acpi_dbg_level = 0x00FFFFFF; | ||
136 | acpi_dbg_layer = ACPI_UINT32_MAX; | ||
137 | |||
138 | if (acpi_gbl_trace_dbg_level) { | ||
139 | acpi_dbg_level = acpi_gbl_trace_dbg_level; | ||
140 | } | ||
141 | if (acpi_gbl_trace_dbg_layer) { | ||
142 | acpi_dbg_layer = acpi_gbl_trace_dbg_layer; | ||
143 | } | ||
144 | |||
145 | exit: | ||
146 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
147 | } | ||
148 | |||
149 | /******************************************************************************* | ||
150 | * | ||
151 | * FUNCTION: acpi_ps_stop_trace | ||
152 | * | ||
153 | * PARAMETERS: Info - Method info struct | ||
154 | * | ||
155 | * RETURN: None | ||
156 | * | ||
157 | * DESCRIPTION: Stop control method execution trace | ||
158 | * | ||
159 | ******************************************************************************/ | ||
160 | |||
161 | static void acpi_ps_stop_trace(struct acpi_parameter_info *info) | ||
162 | { | ||
163 | acpi_status status; | ||
164 | |||
165 | ACPI_FUNCTION_ENTRY(); | ||
166 | |||
167 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
168 | if (ACPI_FAILURE(status)) { | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | if ((!acpi_gbl_trace_method_name) || | ||
173 | (acpi_gbl_trace_method_name != info->node->name.integer)) { | ||
174 | goto exit; | ||
175 | } | ||
176 | |||
177 | /* Disable further tracing if type is one-shot */ | ||
178 | |||
179 | if (acpi_gbl_trace_flags & 1) { | ||
180 | acpi_gbl_trace_method_name = 0; | ||
181 | acpi_gbl_trace_dbg_level = 0; | ||
182 | acpi_gbl_trace_dbg_layer = 0; | ||
183 | } | ||
184 | |||
185 | acpi_dbg_level = acpi_gbl_original_dbg_level; | ||
186 | acpi_dbg_layer = acpi_gbl_original_dbg_layer; | ||
187 | |||
188 | exit: | ||
189 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
190 | } | ||
191 | |||
192 | /******************************************************************************* | ||
193 | * | ||
60 | * FUNCTION: acpi_ps_execute_method | 194 | * FUNCTION: acpi_ps_execute_method |
61 | * | 195 | * |
62 | * PARAMETERS: Info - Method info block, contains: | 196 | * PARAMETERS: Info - Method info block, contains: |
@@ -104,6 +238,10 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
104 | */ | 238 | */ |
105 | acpi_ps_update_parameter_list(info, REF_INCREMENT); | 239 | acpi_ps_update_parameter_list(info, REF_INCREMENT); |
106 | 240 | ||
241 | /* Begin tracing if requested */ | ||
242 | |||
243 | acpi_ps_start_trace(info); | ||
244 | |||
107 | /* | 245 | /* |
108 | * 1) Perform the first pass parse of the method to enter any | 246 | * 1) Perform the first pass parse of the method to enter any |
109 | * named objects that it creates into the namespace | 247 | * named objects that it creates into the namespace |
@@ -129,6 +267,10 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
129 | status = acpi_ps_execute_pass(info); | 267 | status = acpi_ps_execute_pass(info); |
130 | 268 | ||
131 | cleanup: | 269 | cleanup: |
270 | /* End optional tracing */ | ||
271 | |||
272 | acpi_ps_stop_trace(info); | ||
273 | |||
132 | /* Take away the extra reference that we gave the parameters above */ | 274 | /* Take away the extra reference that we gave the parameters above */ |
133 | 275 | ||
134 | acpi_ps_update_parameter_list(info, REF_DECREMENT); | 276 | acpi_ps_update_parameter_list(info, REF_DECREMENT); |