aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/utilities/utmisc.c
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/utmisc.c
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/utmisc.c')
-rw-r--r--drivers/acpi/utilities/utmisc.c109
1 files changed, 72 insertions, 37 deletions
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 874467117ce..5c75d35ad1c 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