diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-04-08 12:31:38 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-04-08 12:31:38 +0200 |
commit | 6912897d7574d780994ac9a531f76c5df1669aeb (patch) | |
tree | 9fe4d0bef6270a1ecf804865dfe3cf5b18a9f24a /drivers/acpi | |
parent | 16b53e7e8542082ac628e9e69f6cdf725a576f81 (diff) | |
parent | f084dbb939070281be7c882db63a4a428c51fcf4 (diff) |
Merge branch 'acpica' into linux-next
* acpica: (22 commits)
ACPI: Set length even for TYPE_END_TAG acpi resource
ACPICA: Update version to 20130214
ACPICA: Object repair: Allow 0-length packages for variable-length packages
ACPICA: Disassembler: Add warnings for unresolved control methods
ACPICA: Return object repair: Add resource template repairs
ACPICA: Return object repair: Add string-to-unicode conversion
ACPICA: Split object conversion functions to a new file
ACPICA: Add mechanism for early object repairs on a per-name basis
ACPICA: Remove trailing comma in enum declarations
ACPICA: Add exception descriptions to exception info table
ACPICA: Add macros to exception code definitions
ACPICA: Regression fix: reinstate safe exit macros
ACPICA: Update for ACPI 5 hardware-reduced feature
ACPICA: Add parens within macros around parameter names
ACPICA: Add macros to access pointer to next object in the descriptor list
ACPICA: Update error/debug messages for fixed events
ACPICA: Fix a long-standing bug in local cache
ACPICA: iASL/Disassembler: Add support for MTMR table
ACPICA: iASL/Disassembler: Add support for VRTC table
ACPICA: Update RASF table definition
...
Diffstat (limited to 'drivers/acpi')
31 files changed, 830 insertions, 400 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index a1b9bf5085a2..5a542c8db942 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o acpi-y += \ nsaccess.o \ nsalloc.o \ + nsconvert.o \ nsdump.o \ nseval.o \ nsinit.o \ diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ecb49927b817..833fbc5be2d6 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -413,10 +413,12 @@ ACPI_EXTERN u8 acpi_gbl_db_output_flags; #ifdef ACPI_DISASSEMBLER -u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE); +ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE); ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; +ACPI_EXTERN u8 acpi_gbl_num_external_methods; +ACPI_EXTERN u32 acpi_gbl_resolved_external_methods; ACPI_EXTERN struct acpi_external_list *acpi_gbl_external_list; ACPI_EXTERN struct acpi_external_file *acpi_gbl_external_file_list; #endif diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 805f419086ab..636658ffc9b1 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -363,6 +363,7 @@ struct acpi_predefined_data { union acpi_operand_object *parent_package; struct acpi_namespace_node *node; u32 flags; + u32 return_btype; u8 node_flags; }; @@ -371,6 +372,20 @@ struct acpi_predefined_data { #define ACPI_OBJECT_REPAIRED 1 #define ACPI_OBJECT_WRAPPED 2 +/* Return object auto-repair info */ + +typedef acpi_status(*acpi_object_converter) (union acpi_operand_object + *original_object, + union acpi_operand_object + **converted_object); + +struct acpi_simple_repair_info { + char name[ACPI_NAME_SIZE]; + u32 unexpected_btypes; + u32 package_index; + acpi_object_converter object_converter; +}; + /* * Bitmapped return value types * Note: the actual data types must be contiguous, a loop in nspredef.c @@ -1037,6 +1052,7 @@ struct acpi_external_list { u16 length; u8 type; u8 flags; + u8 resolved; }; /* Values for Flags field above */ diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index ed7943b9044f..53666bd9193d 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -322,10 +322,12 @@ * where a pointer to an object of type union acpi_operand_object can also * appear. This macro is used to distinguish them. * - * The "Descriptor" field is the first field in both structures. + * The "DescriptorType" field is the second field in both structures. */ +#define ACPI_GET_DESCRIPTOR_PTR(d) (((union acpi_descriptor *)(void *)(d))->common.common_pointer) +#define ACPI_SET_DESCRIPTOR_PTR(d, p) (((union acpi_descriptor *)(void *)(d))->common.common_pointer = (p)) #define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type) -#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t) +#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = (t)) /* * Macros for the master AML opcode table diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 02cd5482ff8b..6475962a7f2d 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -167,6 +167,29 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent); int acpi_ns_compare_names(char *name1, char *name2); /* + * nsconvert - Dynamic object conversion routines + */ +acpi_status +acpi_ns_convert_to_integer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_convert_to_string(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_convert_to_unicode(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_convert_to_resource(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +/* * nsdump - Namespace dump/print utilities */ #ifdef ACPI_FUTURE_USAGE @@ -289,7 +312,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, * predefined methods/objects */ acpi_status -acpi_ns_repair_object(struct acpi_predefined_data *data, +acpi_ns_simple_repair(struct acpi_predefined_data *data, u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr); diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 0082fa0a6139..c01f1a10a9d7 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -483,7 +483,8 @@ acpi_ut_short_divide(u64 in_dividend, /* * utmisc */ -const char *acpi_ut_validate_exception(acpi_status status); +const struct acpi_exception_info *acpi_ut_validate_exception(acpi_status + status); u8 acpi_ut_is_pci_root_bridge(char *id); diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 4d8c992a51d8..99778997c35a 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -178,7 +178,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, if (!op) { ACPI_ERROR((AE_INFO, "Null Op")); - return_VALUE(TRUE); + return_UINT8(TRUE); } /* @@ -210,7 +210,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, "At Method level, result of [%s] not used\n", acpi_ps_get_opcode_name(op->common. aml_opcode))); - return_VALUE(FALSE); + return_UINT8(FALSE); } /* Get info on the parent. The root_op is AML_SCOPE */ @@ -219,7 +219,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode); if (parent_info->class == AML_CLASS_UNKNOWN) { ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op)); - return_VALUE(FALSE); + return_UINT8(FALSE); } /* @@ -307,7 +307,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_name(op->common.parent->common. aml_opcode), op)); - return_VALUE(TRUE); + return_UINT8(TRUE); result_not_used: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, @@ -316,7 +316,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_name(op->common.parent->common. aml_opcode), op)); - return_VALUE(FALSE); + return_UINT8(FALSE); } /******************************************************************************* diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index b8ea0b26cde3..02219ffba8b6 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -257,6 +257,8 @@ u32 acpi_ev_fixed_event_detect(void) * * DESCRIPTION: Clears the status bit for the requested event, calls the * handler that previously registered for the event. + * NOTE: If there is no handler for the event, the event is + * disabled to prevent futher interrupts. * ******************************************************************************/ @@ -271,17 +273,17 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) status_register_id, ACPI_CLEAR_STATUS); /* - * Make sure we've got a handler. If not, report an error. The event is - * disabled to prevent further interrupts. + * Make sure that a handler exists. If not, report an error + * and disable the event to prevent further interrupts. */ - if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { + if (!acpi_gbl_fixed_event_handlers[event].handler) { (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. enable_register_id, ACPI_DISABLE_EVENT); ACPI_ERROR((AE_INFO, - "No installed handler for fixed event [0x%08X]", - event)); + "No installed handler for fixed event - %s (%u), disabling", + acpi_ut_get_event_name(event), event)); return (ACPI_INTERRUPT_NOT_HANDLED); } diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index b9adb9a7ed85..a493b528f8f9 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -707,7 +707,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to clear GPE%02X", gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -724,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to disable GPE%02X", gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } /* @@ -784,7 +784,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, break; } - return_VALUE(ACPI_INTERRUPT_HANDLED); + return_UINT32(ACPI_INTERRUPT_HANDLED); } #endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index f4b43bede015..b905acf7aacd 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -89,7 +89,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) */ interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); - return_VALUE(interrupt_handled); + return_UINT32(interrupt_handled); } /******************************************************************************* @@ -120,7 +120,7 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); - return_VALUE(interrupt_handled); + return_UINT32(interrupt_handled); } /****************************************************************************** diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index ddffd6847914..ca5fba99c33b 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -467,9 +467,9 @@ acpi_install_fixed_event_handler(u32 event, return_ACPI_STATUS(status); } - /* Don't allow two handlers. */ + /* Do not allow multiple handlers */ - if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { + if (acpi_gbl_fixed_event_handlers[event].handler) { status = AE_ALREADY_EXISTS; goto cleanup; } @@ -483,8 +483,9 @@ acpi_install_fixed_event_handler(u32 event, if (ACPI_SUCCESS(status)) status = acpi_enable_event(event, 0); if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X", - event)); + ACPI_WARNING((AE_INFO, + "Could not enable fixed event - %s (%u)", + acpi_ut_get_event_name(event), event)); /* Remove the handler */ @@ -492,7 +493,8 @@ acpi_install_fixed_event_handler(u32 event, acpi_gbl_fixed_event_handlers[event].context = NULL; } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Enabled fixed event %X, Handler=%p\n", event, + "Enabled fixed event %s (%X), Handler=%p\n", + acpi_ut_get_event_name(event), event, handler)); } @@ -544,11 +546,12 @@ acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, - "Could not write to fixed event enable register 0x%X", - event)); + "Could not disable fixed event - %s (%u)", + acpi_ut_get_event_name(event), event)); } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", - event)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Disabled fixed event - %s (%X)\n", + acpi_ut_get_event_name(event), event)); } (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d6e4e42316db..7039606a0ba8 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -74,6 +74,12 @@ acpi_status acpi_enable(void) return_ACPI_STATUS(AE_NO_ACPI_TABLES); } + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* Check current mode */ if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { @@ -126,6 +132,12 @@ acpi_status acpi_disable(void) ACPI_FUNCTION_TRACE(acpi_disable); + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n")); diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index d6eab81f54fb..6b728aef2dca 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -276,7 +276,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, /* Invalid field access type */ ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access)); - return_VALUE(0); + return_UINT32(0); } if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) { @@ -289,7 +289,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, } *return_byte_alignment = byte_alignment; - return_VALUE(bit_length); + return_UINT32(bit_length); } /******************************************************************************* diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index b205cbb4b50c..99dc7b287d55 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -340,7 +340,7 @@ static u32 acpi_ex_digits_needed(u64 value, u32 base) /* u64 is unsigned, so we don't worry about a '-' prefix */ if (value == 0) { - return_VALUE(1); + return_UINT32(1); } current_value = value; @@ -354,7 +354,7 @@ static u32 acpi_ex_digits_needed(u64 value, u32 base) num_digits++; } - return_VALUE(num_digits); + return_UINT32(num_digits); } /******************************************************************************* diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index deb3f61e2bd1..579c3a53ac87 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -66,6 +66,12 @@ acpi_status acpi_hw_set_mode(u32 mode) ACPI_FUNCTION_TRACE(hw_set_mode); + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. @@ -146,23 +152,29 @@ u32 acpi_hw_get_mode(void) ACPI_FUNCTION_TRACE(hw_get_mode); + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_UINT32(ACPI_SYS_MODE_ACPI); + } + /* * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. */ if (!acpi_gbl_FADT.smi_command) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value); if (ACPI_FAILURE(status)) { - return_VALUE(ACPI_SYS_MODE_LEGACY); + return_UINT32(ACPI_SYS_MODE_LEGACY); } if (value) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } else { - return_VALUE(ACPI_SYS_MODE_LEGACY); + return_UINT32(ACPI_SYS_MODE_LEGACY); } } diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c new file mode 100644 index 000000000000..8f79a9d2d50e --- /dev/null +++ b/drivers/acpi/acpica/nsconvert.c @@ -0,0 +1,443 @@ +/****************************************************************************** + * + * Module Name: nsconvert - Object conversions for objects returned by + * predefined methods + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2013, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include "accommon.h" +#include "acnamesp.h" +#include "acinterp.h" +#include "acpredef.h" +#include "amlresrc.h" + +#define _COMPONENT ACPI_NAMESPACE +ACPI_MODULE_NAME("nsconvert") + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_integer + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. + * + ******************************************************************************/ +acpi_status +acpi_ns_convert_to_integer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + acpi_status status; + u64 value = 0; + u32 i; + + switch (original_object->common.type) { + case ACPI_TYPE_STRING: + + /* String-to-Integer conversion */ + + status = acpi_ut_strtoul64(original_object->string.pointer, + ACPI_ANY_BASE, &value); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_TYPE_BUFFER: + + /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ + + if (original_object->buffer.length > 8) { + return (AE_AML_OPERAND_TYPE); + } + + /* Extract each buffer byte to create the integer */ + + for (i = 0; i < original_object->buffer.length; i++) { + value |= + ((u64)original_object->buffer. + pointer[i] << (i * 8)); + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + new_object = acpi_ut_create_integer_object(value); + if (!new_object) { + return (AE_NO_MEMORY); + } + + *return_object = new_object; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_string + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. + * + ******************************************************************************/ + +acpi_status +acpi_ns_convert_to_string(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + acpi_size length; + acpi_status status; + + switch (original_object->common.type) { + case ACPI_TYPE_INTEGER: + /* + * Integer-to-String conversion. Commonly, convert + * an integer of value 0 to a NULL string. The last element of + * _BIF and _BIX packages occasionally need this fix. + */ + if (original_object->integer.value == 0) { + + /* Allocate a new NULL string object */ + + new_object = acpi_ut_create_string_object(0); + if (!new_object) { + return (AE_NO_MEMORY); + } + } else { + status = + acpi_ex_convert_to_string(original_object, + &new_object, + ACPI_IMPLICIT_CONVERT_HEX); + if (ACPI_FAILURE(status)) { + return (status); + } + } + break; + + case ACPI_TYPE_BUFFER: + /* + * Buffer-to-String conversion. Use a to_string + * conversion, no transform performed on the buffer data. The best + * example of this is the _BIF method, where the string data from + * the battery is often (incorrectly) returned as buffer object(s). + */ + length = 0; + while ((length < original_object->buffer.length) && + (original_object->buffer.pointer[length])) { + length++; + } + + /* Allocate a new string object */ + + new_object = acpi_ut_create_string_object(length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* + * Copy the raw buffer data with no transform. String is already NULL + * terminated at Length+1. + */ + ACPI_MEMCPY(new_object->string.pointer, + original_object->buffer.pointer, length); + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *return_object = new_object; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_buffer + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. + * + ******************************************************************************/ + +acpi_status +acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + acpi_status status; + union acpi_operand_object **elements; + u32 *dword_buffer; + u32 count; + u32 i; + + switch (original_object->common.type) { + case ACPI_TYPE_INTEGER: + /* + * Integer-to-Buffer conversion. + * Convert the Integer to a packed-byte buffer. _MAT and other + * objects need this sometimes, if a read has been performed on a + * Field object that is less than or equal to the global integer + * size (32 or 64 bits). + */ + status = + acpi_ex_convert_to_buffer(original_object, &new_object); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_TYPE_STRING: + + /* String-to-Buffer conversion. Simple data copy */ + + new_object = + acpi_ut_create_buffer_object(original_object->string. + length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY(new_object->buffer.pointer, + original_object->string.pointer, + original_object->string.length); + break; + + case ACPI_TYPE_PACKAGE: + /* + * This case is often seen for predefined names that must return a + * Buffer object with multiple DWORD integers within. For example, + * _FDE and _GTM. The Package can be converted to a Buffer. + */ + + /* All elements of the Package must be integers */ + + elements = original_object->package.elements; + count = original_object->package.count; + + for (i = 0; i < count; i++) { + if ((!*elements) || + ((*elements)->common.type != ACPI_TYPE_INTEGER)) { + return (AE_AML_OPERAND_TYPE); + } + elements++; + } + + /* Create the new buffer object to replace the Package */ + + new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* Copy the package elements (integers) to the buffer as DWORDs */ + + elements = original_object->package.elements; + dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer); + + for (i = 0; i < count; i++) { + *dword_buffer = (u32)(*elements)->integer.value; + dword_buffer++; + elements++; + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *return_object = new_object; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_unicode + * + * PARAMETERS: original_object - ASCII String Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a String o |