aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser')
-rw-r--r--drivers/acpi/parser/psargs.c358
-rw-r--r--drivers/acpi/parser/psloop.c39
-rw-r--r--drivers/acpi/parser/psopcode.c4
-rw-r--r--drivers/acpi/parser/psparse.c55
-rw-r--r--drivers/acpi/parser/psscope.c2
-rw-r--r--drivers/acpi/parser/pstree.c5
-rw-r--r--drivers/acpi/parser/psutils.c2
-rw-r--r--drivers/acpi/parser/pswalk.c2
-rw-r--r--drivers/acpi/parser/psxface.c144
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
50ACPI_MODULE_NAME("psargs") 51ACPI_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
72static u32 74static u32
73acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) 75acpi_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)
135u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) 126u8 *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)
240acpi_status 228acpi_status
241acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, 229acpi_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
382acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, 384acpi_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 @@
50ACPI_MODULE_NAME("psxface") 50ACPI_MODULE_NAME("psxface")
51 51
52/* Local Prototypes */ 52/* Local Prototypes */
53static void acpi_ps_start_trace(struct acpi_parameter_info *info);
54
55static void acpi_ps_stop_trace(struct acpi_parameter_info *info);
56
53static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); 57static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info);
54 58
55static void 59static 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
78acpi_status
79acpi_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
116static 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
161static 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);