195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2fe97d287SBob Moore /******************************************************************************* 3fe97d287SBob Moore * 472a29355SBob Moore * Module Name: utstrsuppt - Support functions for string-to-integer conversion 5fe97d287SBob Moore * 6fe97d287SBob Moore ******************************************************************************/ 7fe97d287SBob Moore 8fe97d287SBob Moore #include <acpi/acpi.h> 9fe97d287SBob Moore #include "accommon.h" 10fe97d287SBob Moore 11fe97d287SBob Moore #define _COMPONENT ACPI_UTILITIES 12fe97d287SBob Moore ACPI_MODULE_NAME("utstrsuppt") 13fe97d287SBob Moore 14fe97d287SBob Moore /* Local prototypes */ 15fe97d287SBob Moore static acpi_status 16fe97d287SBob Moore acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit); 17fe97d287SBob Moore 18fe97d287SBob Moore static acpi_status 19db53f7f0SBob Moore acpi_ut_strtoul_multiply64(u64 multiplicand, u32 base, u64 *out_product); 20fe97d287SBob Moore 21db53f7f0SBob Moore static acpi_status acpi_ut_strtoul_add64(u64 addend1, u32 digit, u64 *out_sum); 22fe97d287SBob Moore 23fe97d287SBob Moore /******************************************************************************* 24fe97d287SBob Moore * 25fe97d287SBob Moore * FUNCTION: acpi_ut_convert_octal_string 26fe97d287SBob Moore * 27fe97d287SBob Moore * PARAMETERS: string - Null terminated input string 28fe97d287SBob Moore * return_value_ptr - Where the converted value is returned 29fe97d287SBob Moore * 30fe97d287SBob Moore * RETURN: Status and 64-bit converted integer 31fe97d287SBob Moore * 32fe97d287SBob Moore * DESCRIPTION: Performs a base 8 conversion of the input string to an 33fe97d287SBob Moore * integer value, either 32 or 64 bits. 34fe97d287SBob Moore * 35fe97d287SBob Moore * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777 36fe97d287SBob Moore * Maximum 32-bit unsigned octal value is 037777777777 37fe97d287SBob Moore * 38fe97d287SBob Moore ******************************************************************************/ 39fe97d287SBob Moore 40fe97d287SBob Moore acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value_ptr) 41fe97d287SBob Moore { 42fe97d287SBob Moore u64 accumulated_value = 0; 43fe97d287SBob Moore acpi_status status = AE_OK; 44fe97d287SBob Moore 45fe97d287SBob Moore /* Convert each ASCII byte in the input string */ 46fe97d287SBob Moore 47fe97d287SBob Moore while (*string) { 48ef3efb43SBob Moore /* 49ef3efb43SBob Moore * Character must be ASCII 0-7, otherwise: 50ef3efb43SBob Moore * 1) Runtime: terminate with no error, per the ACPI spec 51ef3efb43SBob Moore * 2) Compiler: return an error 52ef3efb43SBob Moore */ 53fe97d287SBob Moore if (!(ACPI_IS_OCTAL_DIGIT(*string))) { 54ef3efb43SBob Moore #ifdef ACPI_ASL_COMPILER 55ef3efb43SBob Moore status = AE_BAD_OCTAL_CONSTANT; 56ef3efb43SBob Moore #endif 57fe97d287SBob Moore break; 58fe97d287SBob Moore } 59fe97d287SBob Moore 60fe97d287SBob Moore /* Convert and insert this octal digit into the accumulator */ 61fe97d287SBob Moore 62fe97d287SBob Moore status = acpi_ut_insert_digit(&accumulated_value, 8, *string); 63fe97d287SBob Moore if (ACPI_FAILURE(status)) { 64fe97d287SBob Moore status = AE_OCTAL_OVERFLOW; 65fe97d287SBob Moore break; 66fe97d287SBob Moore } 67fe97d287SBob Moore 68fe97d287SBob Moore string++; 69fe97d287SBob Moore } 70fe97d287SBob Moore 71fe97d287SBob Moore /* Always return the value that has been accumulated */ 72fe97d287SBob Moore 73fe97d287SBob Moore *return_value_ptr = accumulated_value; 74fe97d287SBob Moore return (status); 75fe97d287SBob Moore } 76fe97d287SBob Moore 77fe97d287SBob Moore /******************************************************************************* 78fe97d287SBob Moore * 79fe97d287SBob Moore * FUNCTION: acpi_ut_convert_decimal_string 80fe97d287SBob Moore * 81fe97d287SBob Moore * PARAMETERS: string - Null terminated input string 82fe97d287SBob Moore * return_value_ptr - Where the converted value is returned 83fe97d287SBob Moore * 84fe97d287SBob Moore * RETURN: Status and 64-bit converted integer 85fe97d287SBob Moore * 86fe97d287SBob Moore * DESCRIPTION: Performs a base 10 conversion of the input string to an 87fe97d287SBob Moore * integer value, either 32 or 64 bits. 88fe97d287SBob Moore * 89fe97d287SBob Moore * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615 90fe97d287SBob Moore * Maximum 32-bit unsigned decimal value is 4294967295 91fe97d287SBob Moore * 92fe97d287SBob Moore ******************************************************************************/ 93fe97d287SBob Moore 94fe97d287SBob Moore acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr) 95fe97d287SBob Moore { 96fe97d287SBob Moore u64 accumulated_value = 0; 97fe97d287SBob Moore acpi_status status = AE_OK; 98fe97d287SBob Moore 99fe97d287SBob Moore /* Convert each ASCII byte in the input string */ 100fe97d287SBob Moore 101fe97d287SBob Moore while (*string) { 102ef3efb43SBob Moore /* 103ef3efb43SBob Moore * Character must be ASCII 0-9, otherwise: 104ef3efb43SBob Moore * 1) Runtime: terminate with no error, per the ACPI spec 105ef3efb43SBob Moore * 2) Compiler: return an error 106ef3efb43SBob Moore */ 107*c01df543SBob Moore if (!isdigit((int)*string)) { 108ef3efb43SBob Moore #ifdef ACPI_ASL_COMPILER 109ef3efb43SBob Moore status = AE_BAD_DECIMAL_CONSTANT; 110ef3efb43SBob Moore #endif 111fe97d287SBob Moore break; 112fe97d287SBob Moore } 113fe97d287SBob Moore 114fe97d287SBob Moore /* Convert and insert this decimal digit into the accumulator */ 115fe97d287SBob Moore 116fe97d287SBob Moore status = acpi_ut_insert_digit(&accumulated_value, 10, *string); 117fe97d287SBob Moore if (ACPI_FAILURE(status)) { 118fe97d287SBob Moore status = AE_DECIMAL_OVERFLOW; 119fe97d287SBob Moore break; 120fe97d287SBob Moore } 121fe97d287SBob Moore 122fe97d287SBob Moore string++; 123fe97d287SBob Moore } 124fe97d287SBob Moore 125fe97d287SBob Moore /* Always return the value that has been accumulated */ 126fe97d287SBob Moore 127fe97d287SBob Moore *return_value_ptr = accumulated_value; 128fe97d287SBob Moore return (status); 129fe97d287SBob Moore } 130fe97d287SBob Moore 131fe97d287SBob Moore /******************************************************************************* 132fe97d287SBob Moore * 133fe97d287SBob Moore * FUNCTION: acpi_ut_convert_hex_string 134fe97d287SBob Moore * 135fe97d287SBob Moore * PARAMETERS: string - Null terminated input string 136fe97d287SBob Moore * return_value_ptr - Where the converted value is returned 137fe97d287SBob Moore * 138fe97d287SBob Moore * RETURN: Status and 64-bit converted integer 139fe97d287SBob Moore * 140fe97d287SBob Moore * DESCRIPTION: Performs a base 16 conversion of the input string to an 141fe97d287SBob Moore * integer value, either 32 or 64 bits. 142fe97d287SBob Moore * 143fe97d287SBob Moore * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF 144fe97d287SBob Moore * Maximum 32-bit unsigned hex value is 0xFFFFFFFF 145fe97d287SBob Moore * 146fe97d287SBob Moore ******************************************************************************/ 147fe97d287SBob Moore 148fe97d287SBob Moore acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr) 149fe97d287SBob Moore { 150fe97d287SBob Moore u64 accumulated_value = 0; 151fe97d287SBob Moore acpi_status status = AE_OK; 152fe97d287SBob Moore 153fe97d287SBob Moore /* Convert each ASCII byte in the input string */ 154fe97d287SBob Moore 155fe97d287SBob Moore while (*string) { 156ef3efb43SBob Moore /* 157ef3efb43SBob Moore * Character must be ASCII A-F, a-f, or 0-9, otherwise: 158ef3efb43SBob Moore * 1) Runtime: terminate with no error, per the ACPI spec 159ef3efb43SBob Moore * 2) Compiler: return an error 160ef3efb43SBob Moore */ 161*c01df543SBob Moore if (!isxdigit((int)*string)) { 162ef3efb43SBob Moore #ifdef ACPI_ASL_COMPILER 163ef3efb43SBob Moore status = AE_BAD_HEX_CONSTANT; 164ef3efb43SBob Moore #endif 165fe97d287SBob Moore break; 166fe97d287SBob Moore } 167fe97d287SBob Moore 168fe97d287SBob Moore /* Convert and insert this hex digit into the accumulator */ 169fe97d287SBob Moore 170fe97d287SBob Moore status = acpi_ut_insert_digit(&accumulated_value, 16, *string); 171fe97d287SBob Moore if (ACPI_FAILURE(status)) { 172fe97d287SBob Moore status = AE_HEX_OVERFLOW; 173fe97d287SBob Moore break; 174fe97d287SBob Moore } 175fe97d287SBob Moore 176fe97d287SBob Moore string++; 177fe97d287SBob Moore } 178fe97d287SBob Moore 179fe97d287SBob Moore /* Always return the value that has been accumulated */ 180fe97d287SBob Moore 181fe97d287SBob Moore *return_value_ptr = accumulated_value; 182fe97d287SBob Moore return (status); 183fe97d287SBob Moore } 184fe97d287SBob Moore 185fe97d287SBob Moore /******************************************************************************* 186fe97d287SBob Moore * 187fe97d287SBob Moore * FUNCTION: acpi_ut_remove_leading_zeros 188fe97d287SBob Moore * 189fe97d287SBob Moore * PARAMETERS: string - Pointer to input ASCII string 190fe97d287SBob Moore * 19172a29355SBob Moore * RETURN: Next character after any leading zeros. This character may be 19272a29355SBob Moore * used by the caller to detect end-of-string. 193fe97d287SBob Moore * 19472a29355SBob Moore * DESCRIPTION: Remove any leading zeros in the input string. Return the 19572a29355SBob Moore * next character after the final ASCII zero to enable the caller 19672a29355SBob Moore * to check for the end of the string (NULL terminator). 197fe97d287SBob Moore * 198fe97d287SBob Moore ******************************************************************************/ 199fe97d287SBob Moore 200fe97d287SBob Moore char acpi_ut_remove_leading_zeros(char **string) 201fe97d287SBob Moore { 202fe97d287SBob Moore 203fe97d287SBob Moore while (**string == ACPI_ASCII_ZERO) { 204fe97d287SBob Moore *string += 1; 205fe97d287SBob Moore } 206fe97d287SBob Moore 207fe97d287SBob Moore return (**string); 208fe97d287SBob Moore } 209fe97d287SBob Moore 210fe97d287SBob Moore /******************************************************************************* 211fe97d287SBob Moore * 212c2e56e54SBob Moore * FUNCTION: acpi_ut_remove_whitespace 213c2e56e54SBob Moore * 214c2e56e54SBob Moore * PARAMETERS: string - Pointer to input ASCII string 215c2e56e54SBob Moore * 216c2e56e54SBob Moore * RETURN: Next character after any whitespace. This character may be 217c2e56e54SBob Moore * used by the caller to detect end-of-string. 218c2e56e54SBob Moore * 219c2e56e54SBob Moore * DESCRIPTION: Remove any leading whitespace in the input string. Return the 220c2e56e54SBob Moore * next character after the final ASCII zero to enable the caller 221c2e56e54SBob Moore * to check for the end of the string (NULL terminator). 222c2e56e54SBob Moore * 223c2e56e54SBob Moore ******************************************************************************/ 224c2e56e54SBob Moore 225c2e56e54SBob Moore char acpi_ut_remove_whitespace(char **string) 226c2e56e54SBob Moore { 227c2e56e54SBob Moore 228c2e56e54SBob Moore while (isspace((u8)**string)) { 229c2e56e54SBob Moore *string += 1; 230c2e56e54SBob Moore } 231c2e56e54SBob Moore 232c2e56e54SBob Moore return (**string); 233c2e56e54SBob Moore } 234c2e56e54SBob Moore 235c2e56e54SBob Moore /******************************************************************************* 236c2e56e54SBob Moore * 237fe97d287SBob Moore * FUNCTION: acpi_ut_detect_hex_prefix 238fe97d287SBob Moore * 239fe97d287SBob Moore * PARAMETERS: string - Pointer to input ASCII string 240fe97d287SBob Moore * 24172a29355SBob Moore * RETURN: TRUE if a "0x" prefix was found at the start of the string 242fe97d287SBob Moore * 24372a29355SBob Moore * DESCRIPTION: Detect and remove a hex "0x" prefix 244fe97d287SBob Moore * 245fe97d287SBob Moore ******************************************************************************/ 246fe97d287SBob Moore 247fe97d287SBob Moore u8 acpi_ut_detect_hex_prefix(char **string) 248fe97d287SBob Moore { 249089b2becSErik Schmauss char *initial_position = *string; 250fe97d287SBob Moore 251089b2becSErik Schmauss acpi_ut_remove_hex_prefix(string); 252089b2becSErik Schmauss if (*string != initial_position) { 253089b2becSErik Schmauss return (TRUE); /* String is past leading 0x */ 254fe97d287SBob Moore } 255fe97d287SBob Moore 256fe97d287SBob Moore return (FALSE); /* Not a hex string */ 257fe97d287SBob Moore } 258fe97d287SBob Moore 259fe97d287SBob Moore /******************************************************************************* 260fe97d287SBob Moore * 261089b2becSErik Schmauss * FUNCTION: acpi_ut_remove_hex_prefix 262089b2becSErik Schmauss * 263089b2becSErik Schmauss * PARAMETERS: string - Pointer to input ASCII string 264089b2becSErik Schmauss * 265089b2becSErik Schmauss * RETURN: none 266089b2becSErik Schmauss * 267089b2becSErik Schmauss * DESCRIPTION: Remove a hex "0x" prefix 268089b2becSErik Schmauss * 269089b2becSErik Schmauss ******************************************************************************/ 270089b2becSErik Schmauss 271089b2becSErik Schmauss void acpi_ut_remove_hex_prefix(char **string) 272089b2becSErik Schmauss { 273089b2becSErik Schmauss if ((**string == ACPI_ASCII_ZERO) && 274089b2becSErik Schmauss (tolower((int)*(*string + 1)) == 'x')) { 275089b2becSErik Schmauss *string += 2; /* Go past the leading 0x */ 276089b2becSErik Schmauss } 277089b2becSErik Schmauss } 278089b2becSErik Schmauss 279089b2becSErik Schmauss /******************************************************************************* 280089b2becSErik Schmauss * 281fe97d287SBob Moore * FUNCTION: acpi_ut_detect_octal_prefix 282fe97d287SBob Moore * 283fe97d287SBob Moore * PARAMETERS: string - Pointer to input ASCII string 284fe97d287SBob Moore * 28572a29355SBob Moore * RETURN: True if an octal "0" prefix was found at the start of the 28672a29355SBob Moore * string 287fe97d287SBob Moore * 288fe97d287SBob Moore * DESCRIPTION: Detect and remove an octal prefix (zero) 289fe97d287SBob Moore * 290fe97d287SBob Moore ******************************************************************************/ 291fe97d287SBob Moore 292fe97d287SBob Moore u8 acpi_ut_detect_octal_prefix(char **string) 293fe97d287SBob Moore { 294fe97d287SBob Moore 295fe97d287SBob Moore if (**string == ACPI_ASCII_ZERO) { 296fe97d287SBob Moore *string += 1; /* Go past the leading 0 */ 297fe97d287SBob Moore return (TRUE); 298fe97d287SBob Moore } 299fe97d287SBob Moore 300fe97d287SBob Moore return (FALSE); /* Not an octal string */ 301fe97d287SBob Moore } 302fe97d287SBob Moore 303fe97d287SBob Moore /******************************************************************************* 304fe97d287SBob Moore * 305fe97d287SBob Moore * FUNCTION: acpi_ut_insert_digit 306fe97d287SBob Moore * 307fe97d287SBob Moore * PARAMETERS: accumulated_value - Current value of the integer value 30872a29355SBob Moore * accumulator. The new value is 309fe97d287SBob Moore * returned here. 31072a29355SBob Moore * base - Radix, either 8/10/16 311fe97d287SBob Moore * ascii_digit - ASCII single digit to be inserted 312fe97d287SBob Moore * 31372a29355SBob Moore * RETURN: Status and result of the convert/insert operation. The only 31472a29355SBob Moore * possible returned exception code is numeric overflow of 31572a29355SBob Moore * either the multiply or add conversion operations. 316fe97d287SBob Moore * 317fe97d287SBob Moore * DESCRIPTION: Generic conversion and insertion function for all bases: 318fe97d287SBob Moore * 31972a29355SBob Moore * 1) Multiply the current accumulated/converted value by the 320fe97d287SBob Moore * base in order to make room for the new character. 321fe97d287SBob Moore * 32272a29355SBob Moore * 2) Convert the new character to binary and add it to the 32372a29355SBob Moore * current accumulated value. 324fe97d287SBob Moore * 325fe97d287SBob Moore * Note: The only possible exception indicates an integer 326fe97d287SBob Moore * overflow (AE_NUMERIC_OVERFLOW) 327fe97d287SBob Moore * 328fe97d287SBob Moore ******************************************************************************/ 329fe97d287SBob Moore 330fe97d287SBob Moore static acpi_status 331fe97d287SBob Moore acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit) 332fe97d287SBob Moore { 333fe97d287SBob Moore acpi_status status; 334fe97d287SBob Moore u64 product; 335fe97d287SBob Moore 336fe97d287SBob Moore /* Make room in the accumulated value for the incoming digit */ 337fe97d287SBob Moore 338fe97d287SBob Moore status = acpi_ut_strtoul_multiply64(*accumulated_value, base, &product); 339fe97d287SBob Moore if (ACPI_FAILURE(status)) { 340fe97d287SBob Moore return (status); 341fe97d287SBob Moore } 342fe97d287SBob Moore 34372a29355SBob Moore /* Add in the new digit, and store the sum to the accumulated value */ 344fe97d287SBob Moore 345fe97d287SBob Moore status = 346fe97d287SBob Moore acpi_ut_strtoul_add64(product, 347fe97d287SBob Moore acpi_ut_ascii_char_to_hex(ascii_digit), 348fe97d287SBob Moore accumulated_value); 349fe97d287SBob Moore 35072a29355SBob Moore return (status); 351fe97d287SBob Moore } 352fe97d287SBob Moore 353fe97d287SBob Moore /******************************************************************************* 354fe97d287SBob Moore * 355fe97d287SBob Moore * FUNCTION: acpi_ut_strtoul_multiply64 356fe97d287SBob Moore * 357fe97d287SBob Moore * PARAMETERS: multiplicand - Current accumulated converted integer 358db53f7f0SBob Moore * base - Base/Radix 359fe97d287SBob Moore * out_product - Where the product is returned 360fe97d287SBob Moore * 361fe97d287SBob Moore * RETURN: Status and 64-bit product 362fe97d287SBob Moore * 363fe97d287SBob Moore * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as 364fe97d287SBob Moore * well as 32-bit overflow if necessary (if the current global 365fe97d287SBob Moore * integer width is 32). 366fe97d287SBob Moore * 367fe97d287SBob Moore ******************************************************************************/ 368fe97d287SBob Moore 369fe97d287SBob Moore static acpi_status 370db53f7f0SBob Moore acpi_ut_strtoul_multiply64(u64 multiplicand, u32 base, u64 *out_product) 371fe97d287SBob Moore { 3724b688b1cSRafael J. Wysocki u64 product; 373db53f7f0SBob Moore u64 quotient; 374fe97d287SBob Moore 375fe97d287SBob Moore /* Exit if either operand is zero */ 376fe97d287SBob Moore 377fe97d287SBob Moore *out_product = 0; 378db53f7f0SBob Moore if (!multiplicand || !base) { 379fe97d287SBob Moore return (AE_OK); 380fe97d287SBob Moore } 381fe97d287SBob Moore 382db53f7f0SBob Moore /* 383db53f7f0SBob Moore * Check for 64-bit overflow before the actual multiplication. 384db53f7f0SBob Moore * 385db53f7f0SBob Moore * Notes: 64-bit division is often not supported on 32-bit platforms 386db53f7f0SBob Moore * (it requires a library function), Therefore ACPICA has a local 387db53f7f0SBob Moore * 64-bit divide function. Also, Multiplier is currently only used 388db53f7f0SBob Moore * as the radix (8/10/16), to the 64/32 divide will always work. 389db53f7f0SBob Moore */ 390db53f7f0SBob Moore acpi_ut_short_divide(ACPI_UINT64_MAX, base, "ient, NULL); 391db53f7f0SBob Moore if (multiplicand > quotient) { 392fe97d287SBob Moore return (AE_NUMERIC_OVERFLOW); 393fe97d287SBob Moore } 394fe97d287SBob Moore 3954b688b1cSRafael J. Wysocki product = multiplicand * base; 396fe97d287SBob Moore 397fe97d287SBob Moore /* Check for 32-bit overflow if necessary */ 398fe97d287SBob Moore 3994b688b1cSRafael J. Wysocki if ((acpi_gbl_integer_bit_width == 32) && (product > ACPI_UINT32_MAX)) { 400fe97d287SBob Moore return (AE_NUMERIC_OVERFLOW); 401fe97d287SBob Moore } 402fe97d287SBob Moore 4034b688b1cSRafael J. Wysocki *out_product = product; 404fe97d287SBob Moore return (AE_OK); 405fe97d287SBob Moore } 406fe97d287SBob Moore 407fe97d287SBob Moore /******************************************************************************* 408fe97d287SBob Moore * 409fe97d287SBob Moore * FUNCTION: acpi_ut_strtoul_add64 410fe97d287SBob Moore * 411fe97d287SBob Moore * PARAMETERS: addend1 - Current accumulated converted integer 412db53f7f0SBob Moore * digit - New hex value/char 413fe97d287SBob Moore * out_sum - Where sum is returned (Accumulator) 414fe97d287SBob Moore * 415fe97d287SBob Moore * RETURN: Status and 64-bit sum 416fe97d287SBob Moore * 417fe97d287SBob Moore * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as 418fe97d287SBob Moore * well as 32-bit overflow if necessary (if the current global 419fe97d287SBob Moore * integer width is 32). 420fe97d287SBob Moore * 421fe97d287SBob Moore ******************************************************************************/ 422fe97d287SBob Moore 423db53f7f0SBob Moore static acpi_status acpi_ut_strtoul_add64(u64 addend1, u32 digit, u64 *out_sum) 424fe97d287SBob Moore { 425fe97d287SBob Moore u64 sum; 426fe97d287SBob Moore 427fe97d287SBob Moore /* Check for 64-bit overflow before the actual addition */ 428fe97d287SBob Moore 429db53f7f0SBob Moore if ((addend1 > 0) && (digit > (ACPI_UINT64_MAX - addend1))) { 430fe97d287SBob Moore return (AE_NUMERIC_OVERFLOW); 431fe97d287SBob Moore } 432fe97d287SBob Moore 433db53f7f0SBob Moore sum = addend1 + digit; 434fe97d287SBob Moore 435fe97d287SBob Moore /* Check for 32-bit overflow if necessary */ 436fe97d287SBob Moore 437fe97d287SBob Moore if ((acpi_gbl_integer_bit_width == 32) && (sum > ACPI_UINT32_MAX)) { 438fe97d287SBob Moore return (AE_NUMERIC_OVERFLOW); 439fe97d287SBob Moore } 440fe97d287SBob Moore 441fe97d287SBob Moore *out_sum = sum; 442fe97d287SBob Moore return (AE_OK); 443fe97d287SBob Moore } 444