aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/utilities
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2006-05-26 16:36:00 -0400
committerLen Brown <len.brown@intel.com>2006-06-14 02:44:35 -0400
commit4119532c95547821dbe72d6916dfa1b2148475b3 (patch)
tree564eb8f69924fb7dc72e93526faf1547acac7d30 /drivers/acpi/utilities
parentb8d35192c55fb055792ff0641408eaaec7c88988 (diff)
ACPI: ACPICA 20060526
Restructured, flattened, and simplified the internal interfaces for namespace object evaluation - resulting in smaller code, less CPU stack use, and fewer interfaces. (With assistance from Mikhail Kouzmich) Fixed a problem with the CopyObject operator where the first parameter was not typed correctly for the parser, interpreter, compiler, and disassembler. Caused various errors and unexpected behavior. Fixed a problem where a ShiftLeft or ShiftRight of more than 64 bits produced incorrect results with some C compilers. Since the behavior of C compilers when the shift value is larger than the datatype width is apparently not well defined, the interpreter now detects this condition and simply returns zero as expected in all such cases. (BZ 395) Fixed problem reports (Valery Podrezov) integrated: - Update String-to-Integer conversion to match ACPI 3.0A spec http://bugzilla.kernel.org/show_bug.cgi?id=5329 Allow interpreter to handle nested method declarations http://bugzilla.kernel.org/show_bug.cgi?id=5361 Fixed problem reports (Fiodor Suietov) integrated: - acpi_terminate() doesn't free debug memory allocation list objects (BZ 355) - After Core Subsystem shutdown, acpi_subsystem_status() returns AE_OK (BZ 356) - acpi_os_unmap_memory() for RSDP can be invoked inconsistently (BZ 357) - Resource Manager should return AE_TYPE for non-device objects (BZ 358) - Incomplete cleanup branch in AcpiNsEvaluateRelative (BZ 359) - Use acpi_os_free() instead of ACPI_FREE in acpi_rs_set_srs_method_data (BZ 360) - Incomplete cleanup branch in acpi_ps_parse_aml (BZ 361) - Incomplete cleanup branch in acpi_ds_delete_walk_state (BZ 362) - acpi_get_table_header returns AE_NO_ACPI_TABLES until DSDT is loaded (BZ 365) - Status of the Global Initialization Handler call not used (BZ 366) - Incorrect object parameter to Global Initialization Handler (BZ 367) Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/utilities')
-rw-r--r--drivers/acpi/utilities/utalloc.c51
-rw-r--r--drivers/acpi/utilities/utdelete.c24
-rw-r--r--drivers/acpi/utilities/uteval.c45
-rw-r--r--drivers/acpi/utilities/utinit.c8
-rw-r--r--drivers/acpi/utilities/utmisc.c109
5 files changed, 143 insertions, 94 deletions
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 65a7c2ed9aa1..7940fc1bd69e 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -61,24 +61,6 @@ acpi_status acpi_ut_create_caches(void)
61{ 61{
62 acpi_status status; 62 acpi_status status;
63 63
64#ifdef ACPI_DBG_TRACK_ALLOCATIONS
65
66 /* Memory allocation lists */
67
68 status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
69 if (ACPI_FAILURE(status)) {
70 return (status);
71 }
72
73 status =
74 acpi_ut_create_list("Acpi-Namespace",
75 sizeof(struct acpi_namespace_node),
76 &acpi_gbl_ns_node_list);
77 if (ACPI_FAILURE(status)) {
78 return (status);
79 }
80#endif
81
82 /* Object Caches, for frequently used objects */ 64 /* Object Caches, for frequently used objects */
83 65
84 status = 66 status =
@@ -125,6 +107,24 @@ acpi_status acpi_ut_create_caches(void)
125 return (status); 107 return (status);
126 } 108 }
127 109
110#ifdef ACPI_DBG_TRACK_ALLOCATIONS
111
112 /* Memory allocation lists */
113
114 status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
115 if (ACPI_FAILURE(status)) {
116 return (status);
117 }
118
119 status =
120 acpi_ut_create_list("Acpi-Namespace",
121 sizeof(struct acpi_namespace_node),
122 &acpi_gbl_ns_node_list);
123 if (ACPI_FAILURE(status)) {
124 return (status);
125 }
126#endif
127
128 return (AE_OK); 128 return (AE_OK);
129} 129}
130 130
@@ -158,6 +158,21 @@ acpi_status acpi_ut_delete_caches(void)
158 (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); 158 (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
159 acpi_gbl_ps_node_ext_cache = NULL; 159 acpi_gbl_ps_node_ext_cache = NULL;
160 160
161#ifdef ACPI_DBG_TRACK_ALLOCATIONS
162
163 /* Debug only - display leftover memory allocation, if any */
164
165 acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
166
167 /* Free memory lists */
168
169 acpi_os_free(acpi_gbl_global_list);
170 acpi_gbl_global_list = NULL;
171
172 acpi_os_free(acpi_gbl_ns_node_list);
173 acpi_gbl_ns_node_list = NULL;
174#endif
175
161 return (AE_OK); 176 return (AE_OK);
162} 177}
163 178
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 0bb4b59b2804..67b9f325c6fa 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -319,11 +319,9 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
319 new_count = count; 319 new_count = count;
320 320
321 /* 321 /*
322 * Perform the reference count action 322 * Perform the reference count action (increment, decrement, force delete)
323 * (increment, decrement, or force delete)
324 */ 323 */
325 switch (action) { 324 switch (action) {
326
327 case REF_INCREMENT: 325 case REF_INCREMENT:
328 326
329 new_count++; 327 new_count++;
@@ -360,7 +358,6 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
360 if (new_count == 0) { 358 if (new_count == 0) {
361 acpi_ut_delete_internal_obj(object); 359 acpi_ut_delete_internal_obj(object);
362 } 360 }
363
364 break; 361 break;
365 362
366 case REF_FORCE_DELETE: 363 case REF_FORCE_DELETE:
@@ -385,13 +382,10 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
385 * (A deleted object will have a huge reference count) 382 * (A deleted object will have a huge reference count)
386 */ 383 */
387 if (count > ACPI_MAX_REFERENCE_COUNT) { 384 if (count > ACPI_MAX_REFERENCE_COUNT) {
388
389 ACPI_WARNING((AE_INFO, 385 ACPI_WARNING((AE_INFO,
390 "Large Reference Count (%X) in object %p", 386 "Large Reference Count (%X) in object %p", count,
391 count, object)); 387 object));
392 } 388 }
393
394 return;
395} 389}
396 390
397/******************************************************************************* 391/*******************************************************************************
@@ -417,7 +411,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
417 ******************************************************************************/ 411 ******************************************************************************/
418 412
419acpi_status 413acpi_status
420acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action) 414acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
421{ 415{
422 acpi_status status = AE_OK; 416 acpi_status status = AE_OK;
423 union acpi_generic_state *state_list = NULL; 417 union acpi_generic_state *state_list = NULL;
@@ -521,11 +515,11 @@ acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action)
521 515
522 case ACPI_TYPE_REGION: 516 case ACPI_TYPE_REGION:
523 default: 517 default:
524 break; /* No subobjects */ 518 break; /* No subobjects for all other types */
525 } 519 }
526 520
527 /* 521 /*
528 * Now we can update the count in the main object. This can only 522 * Now we can update the count in the main object. This can only
529 * happen after we update the sub-objects in case this causes the 523 * happen after we update the sub-objects in case this causes the
530 * main object to be deleted. 524 * main object to be deleted.
531 */ 525 */
@@ -606,8 +600,8 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
606 ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object); 600 ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object);
607 601
608 /* 602 /*
609 * Allow a NULL pointer to be passed in, just ignore it. This saves 603 * Allow a NULL pointer to be passed in, just ignore it. This saves
610 * each caller from having to check. Also, ignore NS nodes. 604 * each caller from having to check. Also, ignore NS nodes.
611 * 605 *
612 */ 606 */
613 if (!object || 607 if (!object ||
@@ -627,7 +621,7 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
627 621
628 /* 622 /*
629 * Decrement the reference count, and only actually delete the object 623 * Decrement the reference count, and only actually delete the object
630 * if the reference count becomes 0. (Must also decrement the ref count 624 * if the reference count becomes 0. (Must also decrement the ref count
631 * of all subobjects!) 625 * of all subobjects!)
632 */ 626 */
633 (void)acpi_ut_update_object_reference(object, REF_DECREMENT); 627 (void)acpi_ut_update_object_reference(object, REF_DECREMENT);
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 444d3a502c46..d6d7121583c0 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -181,19 +181,26 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
181 u32 expected_return_btypes, 181 u32 expected_return_btypes,
182 union acpi_operand_object **return_desc) 182 union acpi_operand_object **return_desc)
183{ 183{
184 struct acpi_parameter_info info; 184 struct acpi_evaluate_info *info;
185 acpi_status status; 185 acpi_status status;
186 u32 return_btype; 186 u32 return_btype;
187 187
188 ACPI_FUNCTION_TRACE(ut_evaluate_object); 188 ACPI_FUNCTION_TRACE(ut_evaluate_object);
189 189
190 info.node = prefix_node; 190 /* Allocate the evaluation information block */
191 info.parameters = NULL; 191
192 info.parameter_type = ACPI_PARAM_ARGS; 192 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
193 if (!info) {
194 return_ACPI_STATUS(AE_NO_MEMORY);
195 }
196
197 info->prefix_node = prefix_node;
198 info->pathname = path;
199 info->parameter_type = ACPI_PARAM_ARGS;
193 200
194 /* Evaluate the object/method */ 201 /* Evaluate the object/method */
195 202
196 status = acpi_ns_evaluate_relative(path, &info); 203 status = acpi_ns_evaluate(info);
197 if (ACPI_FAILURE(status)) { 204 if (ACPI_FAILURE(status)) {
198 if (status == AE_NOT_FOUND) { 205 if (status == AE_NOT_FOUND) {
199 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 206 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -205,25 +212,25 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
205 prefix_node, path, status); 212 prefix_node, path, status);
206 } 213 }
207 214
208 return_ACPI_STATUS(status); 215 goto cleanup;
209 } 216 }
210 217
211 /* Did we get a return object? */ 218 /* Did we get a return object? */
212 219
213 if (!info.return_object) { 220 if (!info->return_object) {
214 if (expected_return_btypes) { 221 if (expected_return_btypes) {
215 ACPI_ERROR_METHOD("No object was returned from", 222 ACPI_ERROR_METHOD("No object was returned from",
216 prefix_node, path, AE_NOT_EXIST); 223 prefix_node, path, AE_NOT_EXIST);
217 224
218 return_ACPI_STATUS(AE_NOT_EXIST); 225 status = AE_NOT_EXIST;
219 } 226 }
220 227
221 return_ACPI_STATUS(AE_OK); 228 goto cleanup;
222 } 229 }
223 230
224 /* Map the return object type to the bitmapped type */ 231 /* Map the return object type to the bitmapped type */
225 232
226 switch (ACPI_GET_OBJECT_TYPE(info.return_object)) { 233 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
227 case ACPI_TYPE_INTEGER: 234 case ACPI_TYPE_INTEGER:
228 return_btype = ACPI_BTYPE_INTEGER; 235 return_btype = ACPI_BTYPE_INTEGER;
229 break; 236 break;
@@ -251,8 +258,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
251 * happen frequently if the "implicit return" feature is enabled. 258 * happen frequently if the "implicit return" feature is enabled.
252 * Just delete the return object and return AE_OK. 259 * Just delete the return object and return AE_OK.
253 */ 260 */
254 acpi_ut_remove_reference(info.return_object); 261 acpi_ut_remove_reference(info->return_object);
255 return_ACPI_STATUS(AE_OK); 262 goto cleanup;
256 } 263 }
257 264
258 /* Is the return object one of the expected types? */ 265 /* Is the return object one of the expected types? */
@@ -264,19 +271,23 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
264 ACPI_ERROR((AE_INFO, 271 ACPI_ERROR((AE_INFO,
265 "Type returned from %s was incorrect: %s, expected Btypes: %X", 272 "Type returned from %s was incorrect: %s, expected Btypes: %X",
266 path, 273 path,
267 acpi_ut_get_object_type_name(info.return_object), 274 acpi_ut_get_object_type_name(info->return_object),
268 expected_return_btypes)); 275 expected_return_btypes));
269 276
270 /* On error exit, we must delete the return object */ 277 /* On error exit, we must delete the return object */
271 278
272 acpi_ut_remove_reference(info.return_object); 279 acpi_ut_remove_reference(info->return_object);
273 return_ACPI_STATUS(AE_TYPE); 280 status = AE_TYPE;
281 goto cleanup;
274 } 282 }
275 283
276 /* Object type is OK, return it */ 284 /* Object type is OK, return it */
277 285
278 *return_desc = info.return_object; 286 *return_desc = info->return_object;
279 return_ACPI_STATUS(AE_OK); 287
288 cleanup:
289 ACPI_FREE(info);
290 return_ACPI_STATUS(status);
280} 291}
281 292
282/******************************************************************************* 293/*******************************************************************************
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index c65747d3c880..ff76055eb7d6 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -228,6 +228,7 @@ void acpi_ut_subsystem_shutdown(void)
228 /* Subsystem appears active, go ahead and shut it down */ 228 /* Subsystem appears active, go ahead and shut it down */
229 229
230 acpi_gbl_shutdown = TRUE; 230 acpi_gbl_shutdown = TRUE;
231 acpi_gbl_startup_flags = 0;
231 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); 232 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
232 233
233 /* Close the acpi_event Handling */ 234 /* Close the acpi_event Handling */
@@ -245,12 +246,5 @@ void acpi_ut_subsystem_shutdown(void)
245 /* Purge the local caches */ 246 /* Purge the local caches */
246 247
247 (void)acpi_ut_delete_caches(); 248 (void)acpi_ut_delete_caches();
248
249 /* Debug only - display leftover memory allocation, if any */
250
251#ifdef ACPI_DBG_TRACK_ALLOCATIONS
252 acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
253#endif
254
255 return_VOID; 249 return_VOID;
256} 250}
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 874467117cec..5c75d35ad1cd 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -601,7 +601,8 @@ acpi_name acpi_ut_repair_name(acpi_name name)
601 * FUNCTION: acpi_ut_strtoul64 601 * FUNCTION: acpi_ut_strtoul64
602 * 602 *
603 * PARAMETERS: String - Null terminated string 603 * PARAMETERS: String - Null terminated string
604 * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE 604 * Base - Radix of the string: 16 or ACPI_ANY_BASE;
605 * ACPI_ANY_BASE means 'in behalf of to_integer'
605 * ret_integer - Where the converted integer is returned 606 * ret_integer - Where the converted integer is returned
606 * 607 *
607 * RETURN: Status and Converted value 608 * RETURN: Status and Converted value
@@ -617,16 +618,17 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
617 u32 this_digit = 0; 618 u32 this_digit = 0;
618 acpi_integer return_value = 0; 619 acpi_integer return_value = 0;
619 acpi_integer quotient; 620 acpi_integer quotient;
621 acpi_integer dividend;
622 u32 to_integer_op = (base == ACPI_ANY_BASE);
623 u32 mode32 = (acpi_gbl_integer_byte_width == 4);
624 u8 valid_digits = 0;
625 u8 sign_of0x = 0;
626 u8 term = 0;
620 627
621 ACPI_FUNCTION_TRACE(ut_stroul64); 628 ACPI_FUNCTION_TRACE(ut_stroul64);
622 629
623 if ((!string) || !(*string)) {
624 goto error_exit;
625 }
626
627 switch (base) { 630 switch (base) {
628 case ACPI_ANY_BASE: 631 case ACPI_ANY_BASE:
629 case 10:
630 case 16: 632 case 16:
631 break; 633 break;
632 634
@@ -635,39 +637,45 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
635 return_ACPI_STATUS(AE_BAD_PARAMETER); 637 return_ACPI_STATUS(AE_BAD_PARAMETER);
636 } 638 }
637 639
640 if (!string) {
641 goto error_exit;
642 }
643
638 /* Skip over any white space in the buffer */ 644 /* Skip over any white space in the buffer */
639 645
640 while (ACPI_IS_SPACE(*string) || *string == '\t') { 646 while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
641 string++; 647 string++;
642 } 648 }
643 649
644 /* 650 if (to_integer_op) {
645 * If the input parameter Base is zero, then we need to 651 /*
646 * determine if it is decimal or hexadecimal: 652 * Base equal to ACPI_ANY_BASE means 'to_integer operation case'.
647 */ 653 * We need to determine if it is decimal or hexadecimal.
648 if (base == 0) { 654 */
649 if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { 655 if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
656 sign_of0x = 1;
650 base = 16; 657 base = 16;
658
659 /* Skip over the leading '0x' */
651 string += 2; 660 string += 2;
652 } else { 661 } else {
653 base = 10; 662 base = 10;
654 } 663 }
655 } 664 }
656 665
657 /* 666 /* Any string left? Check that '0x' is not followed by white space. */
658 * For hexadecimal base, skip over the leading 667
659 * 0 or 0x, if they are present. 668 if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
660 */ 669 if (to_integer_op) {
661 if ((base == 16) && 670 goto error_exit;
662 (*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { 671 } else {
663 string += 2; 672 goto all_done;
673 }
664 } 674 }
665 675
666 /* Any string left? */ 676 dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
667 677
668 if (!(*string)) { 678 /* At least one character in the string here */
669 goto error_exit;
670 }
671 679
672 /* Main loop: convert the string to a 64-bit integer */ 680 /* Main loop: convert the string to a 64-bit integer */
673 681
@@ -677,14 +685,12 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
677 /* Convert ASCII 0-9 to Decimal value */ 685 /* Convert ASCII 0-9 to Decimal value */
678 686
679 this_digit = ((u8) * string) - '0'; 687 this_digit = ((u8) * string) - '0';
680 } else { 688 } else if (base == 10) {
681 if (base == 10) {
682 689
683 /* Digit is out of range */ 690 /* Digit is out of range; possible in to_integer case only */
684
685 goto error_exit;
686 }
687 691
692 term = 1;
693 } else {
688 this_digit = (u8) ACPI_TOUPPER(*string); 694 this_digit = (u8) ACPI_TOUPPER(*string);
689 if (ACPI_IS_XDIGIT((char)this_digit)) { 695 if (ACPI_IS_XDIGIT((char)this_digit)) {
690 696
@@ -692,22 +698,49 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
692 698
693 this_digit = this_digit - 'A' + 10; 699 this_digit = this_digit - 'A' + 10;
694 } else { 700 } else {
695 /* 701 term = 1;
696 * We allow non-hex chars, just stop now, same as end-of-string. 702 }
697 * See ACPI spec, string-to-integer conversion. 703 }
698 */ 704
705 if (term) {
706 if (to_integer_op) {
707 goto error_exit;
708 } else {
699 break; 709 break;
700 } 710 }
711 } else if ((valid_digits == 0) && (this_digit == 0)
712 && !sign_of0x) {
713
714 /* Skip zeros */
715 string++;
716 continue;
717 }
718
719 valid_digits++;
720
721 if (sign_of0x
722 && ((valid_digits > 16)
723 || ((valid_digits > 8) && mode32))) {
724 /*
725 * This is to_integer operation case.
726 * No any restrictions for string-to-integer conversion,
727 * see ACPI spec.
728 */
729 goto error_exit;
701 } 730 }
702 731
703 /* Divide the digit into the correct position */ 732 /* Divide the digit into the correct position */
704 733
705 (void) 734 (void)
706 acpi_ut_short_divide((ACPI_INTEGER_MAX - 735 acpi_ut_short_divide((dividend - (acpi_integer) this_digit),
707 (acpi_integer) this_digit), base, 736 base, &quotient, NULL);
708 &quotient, NULL); 737
709 if (return_value > quotient) { 738 if (return_value > quotient) {
710 goto error_exit; 739 if (to_integer_op) {
740 goto error_exit;
741 } else {
742 break;
743 }
711 } 744 }
712 745
713 return_value *= base; 746 return_value *= base;
@@ -717,6 +750,8 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
717 750
718 /* All done, normal exit */ 751 /* All done, normal exit */
719 752
753 all_done:
754
720 *ret_integer = return_value; 755 *ret_integer = return_value;
721 return_ACPI_STATUS(AE_OK); 756 return_ACPI_STATUS(AE_OK);
722 757