aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser')
-rw-r--r--drivers/acpi/parser/psargs.c152
-rw-r--r--drivers/acpi/parser/psparse.c35
-rw-r--r--drivers/acpi/parser/psxface.c2
3 files changed, 94 insertions, 95 deletions
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 562d0f822ab1..6eae35febccd 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -62,61 +62,51 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
62 * 62 *
63 * PARAMETERS: parser_state - Current parser state object 63 * PARAMETERS: parser_state - Current parser state object
64 * 64 *
65 * RETURN: Decoded package length. On completion, the AML pointer points 65 * RETURN: Decoded package length. On completion, the AML pointer points
66 * past the length byte or bytes. 66 * past the length byte or bytes.
67 * 67 *
68 * DESCRIPTION: Decode and return a package length field 68 * DESCRIPTION: Decode and return a package length field.
69 * Note: Largest package length is 28 bits, from ACPI specification
69 * 70 *
70 ******************************************************************************/ 71 ******************************************************************************/
71 72
72static u32 73static u32
73acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) 74acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
74{ 75{
75 u32 encoded_length; 76 u8 *aml = parser_state->aml;
76 u32 length = 0; 77 u32 package_length = 0;
78 acpi_native_uint byte_count;
79 u8 byte_zero_mask = 0x3F; /* Default [0:5] */
77 80
78 ACPI_FUNCTION_TRACE("ps_get_next_package_length"); 81 ACPI_FUNCTION_TRACE("ps_get_next_package_length");
79 82
80 encoded_length = (u32) ACPI_GET8(parser_state->aml); 83 /*
81 parser_state->aml++; 84 * Byte 0 bits [6:7] contain the number of additional bytes
82 85 * used to encode the package length, either 0,1,2, or 3
83 switch (encoded_length >> 6) { /* bits 6-7 contain encoding scheme */ 86 */
84 case 0: /* 1-byte encoding (bits 0-5) */ 87 byte_count = (aml[0] >> 6);
85 88 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
104 case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
105 89
106 length = ((ACPI_GET8(parser_state->aml + 2) << 20) | 90 /* Get bytes 3, 2, 1 as needed */
107 (ACPI_GET8(parser_state->aml + 1) << 12) |
108 (ACPI_GET8(parser_state->aml) << 04) |
109 (encoded_length & 0x0F));
110 parser_state->aml += 3;
111 break;
112 91
113 default: 92 while (byte_count) {
93 /*
94 * Final bit positions for the package length bytes:
95 * Byte3->[20:27]
96 * Byte2->[12:19]
97 * Byte1->[04:11]
98 * Byte0->[00:03]
99 */
100 package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
114 101
115 /* Can't get here, only 2 bits / 4 cases */ 102 byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */
116 break; 103 byte_count--;
117 } 104 }
118 105
119 return_UINT32(length); 106 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
107
108 package_length |= (aml[0] & byte_zero_mask);
109 return_UINT32(package_length);
120} 110}
121 111
122/******************************************************************************* 112/*******************************************************************************
@@ -135,16 +125,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) 125u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
136{ 126{
137 u8 *start = parser_state->aml; 127 u8 *start = parser_state->aml;
138 acpi_native_uint length; 128 u32 package_length;
139 129
140 ACPI_FUNCTION_TRACE("ps_get_next_package_end"); 130 ACPI_FUNCTION_TRACE("ps_get_next_package_end");
141 131
142 /* Function below changes parser_state->Aml */ 132 /* Function below updates parser_state->Aml */
143 133
144 length = 134 package_length = acpi_ps_get_next_package_length(parser_state);
145 (acpi_native_uint) acpi_ps_get_next_package_length(parser_state);
146 135
147 return_PTR(start + length); /* end of package */ 136 return_PTR(start + package_length); /* end of package */
148} 137}
149 138
150/******************************************************************************* 139/*******************************************************************************
@@ -169,17 +158,15 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
169 158
170 ACPI_FUNCTION_TRACE("ps_get_next_namestring"); 159 ACPI_FUNCTION_TRACE("ps_get_next_namestring");
171 160
172 /* Handle multiple prefix characters */ 161 /* 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 162
163 while (acpi_ps_is_prefix_char(*end)) {
177 end++; 164 end++;
178 } 165 }
179 166
180 /* Decode the path */ 167 /* Decode the path prefix character */
181 168
182 switch (ACPI_GET8(end)) { 169 switch (*end) {
183 case 0: 170 case 0:
184 171
185 /* null_name */ 172 /* null_name */
@@ -199,9 +186,9 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
199 186
200 case AML_MULTI_NAME_PREFIX_OP: 187 case AML_MULTI_NAME_PREFIX_OP:
201 188
202 /* Multiple name segments, 4 chars each */ 189 /* Multiple name segments, 4 chars each, count in next byte */
203 190
204 end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE); 191 end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
205 break; 192 break;
206 193
207 default: 194 default:
@@ -212,7 +199,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
212 break; 199 break;
213 } 200 }
214 201
215 parser_state->aml = (u8 *) end; 202 parser_state->aml = end;
216 return_PTR((char *)start); 203 return_PTR((char *)start);
217} 204}
218 205
@@ -342,7 +329,6 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
342 ("search_node %p start_node %p return_node %p\n", 329 ("search_node %p start_node %p return_node %p\n",
343 scope_info.scope.node, 330 scope_info.scope.node,
344 parser_state->start_node, node); 331 parser_state->start_node, node);
345
346 } else { 332 } else {
347 /* 333 /*
348 * We got a NOT_FOUND during table load or we encountered 334 * We got a NOT_FOUND during table load or we encountered
@@ -382,59 +368,63 @@ void
382acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, 368acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
383 u32 arg_type, union acpi_parse_object *arg) 369 u32 arg_type, union acpi_parse_object *arg)
384{ 370{
371 u32 length;
372 u16 opcode;
373 u8 *aml = parser_state->aml;
385 374
386 ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); 375 ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type);
387 376
388 switch (arg_type) { 377 switch (arg_type) {
389 case ARGP_BYTEDATA: 378 case ARGP_BYTEDATA:
390 379
391 acpi_ps_init_op(arg, AML_BYTE_OP); 380 /* Get 1 byte from the AML stream */
392 arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml); 381
393 parser_state->aml++; 382 opcode = AML_BYTE_OP;
383 arg->common.value.integer = (acpi_integer) * aml;
384 length = 1;
394 break; 385 break;
395 386
396 case ARGP_WORDDATA: 387 case ARGP_WORDDATA:
397 388
398 acpi_ps_init_op(arg, AML_WORD_OP);
399
400 /* Get 2 bytes from the AML stream */ 389 /* Get 2 bytes from the AML stream */
401 390
402 ACPI_MOVE_16_TO_32(&arg->common.value.integer, 391 opcode = AML_WORD_OP;
403 parser_state->aml); 392 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
404 parser_state->aml += 2; 393 length = 2;
405 break; 394 break;
406 395
407 case ARGP_DWORDDATA: 396 case ARGP_DWORDDATA:
408 397
409 acpi_ps_init_op(arg, AML_DWORD_OP);
410
411 /* Get 4 bytes from the AML stream */ 398 /* Get 4 bytes from the AML stream */
412 399
413 ACPI_MOVE_32_TO_32(&arg->common.value.integer, 400 opcode = AML_DWORD_OP;
414 parser_state->aml); 401 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
415 parser_state->aml += 4; 402 length = 4;
416 break; 403 break;
417 404
418 case ARGP_QWORDDATA: 405 case ARGP_QWORDDATA:
419 406
420 acpi_ps_init_op(arg, AML_QWORD_OP);
421
422 /* Get 8 bytes from the AML stream */ 407 /* Get 8 bytes from the AML stream */
423 408
424 ACPI_MOVE_64_TO_64(&arg->common.value.integer, 409 opcode = AML_QWORD_OP;
425 parser_state->aml); 410 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
426 parser_state->aml += 8; 411 length = 8;
427 break; 412 break;
428 413
429 case ARGP_CHARLIST: 414 case ARGP_CHARLIST:
430 415
431 acpi_ps_init_op(arg, AML_STRING_OP); 416 /* Get a pointer to the string, point past the string */
432 arg->common.value.string = (char *)parser_state->aml; 417
418 opcode = AML_STRING_OP;
419 arg->common.value.string = ACPI_CAST_PTR(char, aml);
433 420
434 while (ACPI_GET8(parser_state->aml) != '\0') { 421 /* Find the null terminator */
435 parser_state->aml++; 422
423 length = 0;
424 while (aml[length]) {
425 length++;
436 } 426 }
437 parser_state->aml++; 427 length++;
438 break; 428 break;
439 429
440 case ARGP_NAME: 430 case ARGP_NAME:
@@ -443,14 +433,16 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
443 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 433 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
444 arg->common.value.name = 434 arg->common.value.name =
445 acpi_ps_get_next_namestring(parser_state); 435 acpi_ps_get_next_namestring(parser_state);
446 break; 436 return_VOID;
447 437
448 default: 438 default:
449 439
450 ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type)); 440 ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type));
451 break; 441 return_VOID;
452 } 442 }
453 443
444 acpi_ps_init_op(arg, opcode);
445 parser_state->aml += length;
454 return_VOID; 446 return_VOID;
455} 447}
456 448
@@ -540,7 +532,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 532 * access_type is first operand, access_attribute is second
541 */ 533 */
542 field->common.value.integer = 534 field->common.value.integer =
543 (ACPI_GET8(parser_state->aml) << 8); 535 (((u32) ACPI_GET8(parser_state->aml) << 8));
544 parser_state->aml++; 536 parser_state->aml++;
545 field->common.value.integer |= ACPI_GET8(parser_state->aml); 537 field->common.value.integer |= ACPI_GET8(parser_state->aml);
546 parser_state->aml++; 538 parser_state->aml++;
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 76d4d640d83c..7cfa7eb0dfc7 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -503,22 +503,23 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
503 } else if (status == AE_CTRL_TERMINATE) { 503 } else if (status == AE_CTRL_TERMINATE) {
504 status = AE_OK; 504 status = AE_OK;
505 } else if ((status != AE_OK) && (walk_state->method_desc)) { 505 } else if ((status != AE_OK) && (walk_state->method_desc)) {
506 ACPI_REPORT_METHOD_ERROR("Method execution failed", 506 /* Either the method parse or actual execution failed */
507 walk_state->method_node, NULL,
508 status);
509 507
510 /* Ensure proper cleanup */ 508 ACPI_REPORT_METHOD_ERROR
511 509 ("Method parse/execution failed",
512 walk_state->parse_flags |= ACPI_PARSE_EXECUTE; 510 walk_state->method_node, NULL, status);
513 511
514 /* Check for possible multi-thread reentrancy problem */ 512 /* Check for possible multi-thread reentrancy problem */
515 513
516 if ((status == AE_ALREADY_EXISTS) && 514 if ((status == AE_ALREADY_EXISTS) &&
517 (!walk_state->method_desc->method.semaphore)) { 515 (!walk_state->method_desc->method.semaphore)) {
518 /* 516 /*
519 * This method is marked not_serialized, but it tried to create 517 * Method tried to create an object twice. The probable cause is
518 * that the method cannot handle reentrancy.
519 *
520 * The method is marked not_serialized, but it tried to create
520 * a named object, causing the second thread entrance to fail. 521 * a named object, causing the second thread entrance to fail.
521 * We will workaround this by marking the method permanently 522 * Workaround this problem by marking the method permanently
522 * as Serialized. 523 * as Serialized.
523 */ 524 */
524 walk_state->method_desc->method.method_flags |= 525 walk_state->method_desc->method.method_flags |=
@@ -536,15 +537,22 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
536 acpi_ds_scope_stack_clear(walk_state); 537 acpi_ds_scope_stack_clear(walk_state);
537 538
538 /* 539 /*
539 * If we just returned from the execution of a control method, 540 * If we just returned from the execution of a control method or if we
540 * there's lots of cleanup to do 541 * encountered an error during the method parse phase, there's lots of
542 * cleanup to do
541 */ 543 */
542 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == 544 if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
543 ACPI_PARSE_EXECUTE) { 545 ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) {
544 if (walk_state->method_desc) { 546 if (walk_state->method_desc) {
545 /* Decrement the thread count on the method parse tree */ 547 /* Decrement the thread count on the method parse tree */
546 548
547 walk_state->method_desc->method.thread_count--; 549 if (walk_state->method_desc->method.
550 thread_count) {
551 walk_state->method_desc->method.
552 thread_count--;
553 } else {
554 ACPI_REPORT_ERROR(("Invalid zero thread count in method\n"));
555 }
548 } 556 }
549 557
550 acpi_ds_terminate_control_method(walk_state); 558 acpi_ds_terminate_control_method(walk_state);
@@ -553,7 +561,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
553 /* Delete this walk state and all linked control states */ 561 /* Delete this walk state and all linked control states */
554 562
555 acpi_ps_cleanup_scope(&walk_state->parser_state); 563 acpi_ps_cleanup_scope(&walk_state->parser_state);
556
557 previous_walk_state = walk_state; 564 previous_walk_state = walk_state;
558 565
559 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 566 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 4c426f4c6af6..14d544d60867 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -87,7 +87,7 @@ acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags)
87 87
88 /* TBDs: Validate name, allow full path or just nameseg */ 88 /* TBDs: Validate name, allow full path or just nameseg */
89 89
90 acpi_gbl_trace_method_name = *(u32 *) name; 90 acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name);
91 acpi_gbl_trace_flags = flags; 91 acpi_gbl_trace_flags = flags;
92 92
93 if (debug_level) { 93 if (debug_level) {