You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-4.7/acpi6.1' into libnvdimm-for-next
This commit is contained in:
@@ -43,6 +43,7 @@ acpi-y += \
|
||||
evxfregn.o
|
||||
|
||||
acpi-y += \
|
||||
exconcat.o \
|
||||
exconfig.o \
|
||||
exconvrt.o \
|
||||
excreate.o \
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */
|
||||
|
||||
struct acpi_db_command_info {
|
||||
char *name; /* Command Name */
|
||||
const char *name; /* Command Name */
|
||||
u8 min_args; /* Minimum arguments required */
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ struct acpi_db_command_help {
|
||||
};
|
||||
|
||||
struct acpi_db_argument_info {
|
||||
char *name; /* Argument Name */
|
||||
const char *name; /* Argument Name */
|
||||
};
|
||||
|
||||
struct acpi_db_execute_walk {
|
||||
|
||||
@@ -198,8 +198,6 @@ void
|
||||
acpi_ev_detach_region(union acpi_operand_object *region_obj,
|
||||
u8 acpi_ns_is_locked);
|
||||
|
||||
void acpi_ev_associate_reg_method(union acpi_operand_object *region_obj);
|
||||
|
||||
void
|
||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||
acpi_adr_space_type space_id, u32 function);
|
||||
|
||||
@@ -187,6 +187,8 @@ extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
|
||||
extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS];
|
||||
extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS];
|
||||
extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
|
||||
extern const char acpi_gbl_lower_hex_digits[];
|
||||
extern const char acpi_gbl_upper_hex_digits[];
|
||||
extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
|
||||
|
||||
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
|
||||
@@ -361,6 +363,15 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects);
|
||||
|
||||
#endif /* ACPI_DEBUGGER */
|
||||
|
||||
#if defined (ACPI_DISASSEMBLER) || defined (ACPI_ASL_COMPILER)
|
||||
|
||||
ACPI_GLOBAL(const char, *acpi_gbl_pld_panel_list[]);
|
||||
ACPI_GLOBAL(const char, *acpi_gbl_pld_vertical_position_list[]);
|
||||
ACPI_GLOBAL(const char, *acpi_gbl_pld_horizontal_position_list[]);
|
||||
ACPI_GLOBAL(const char, *acpi_gbl_pld_shape_list[]);
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Application globals
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
typedef const struct acpi_exdump_info {
|
||||
u8 opcode;
|
||||
u8 offset;
|
||||
char *name;
|
||||
const char *name;
|
||||
|
||||
} acpi_exdump_info;
|
||||
|
||||
|
||||
@@ -1096,6 +1096,7 @@ struct acpi_external_list {
|
||||
#define ACPI_EXT_ORIGIN_FROM_FILE 0x02 /* External came from a file */
|
||||
#define ACPI_EXT_INTERNAL_PATH_ALLOCATED 0x04 /* Deallocate internal path on completion */
|
||||
#define ACPI_EXT_EXTERNAL_EMITTED 0x08 /* External() statement has been emitted */
|
||||
#define ACPI_EXT_ORIGIN_FROM_OPCODE 0x10 /* External came from a External() opcode */
|
||||
|
||||
struct acpi_external_file {
|
||||
char *path;
|
||||
|
||||
@@ -260,6 +260,10 @@
|
||||
|
||||
#define ACPI_IS_MISALIGNED(value) (((acpi_size) value) & (sizeof(acpi_size)-1))
|
||||
|
||||
/* Generic (power-of-two) rounding */
|
||||
|
||||
#define ACPI_IS_POWER_OF_TWO(a) (((a) & ((a) - 1)) == 0)
|
||||
|
||||
/*
|
||||
* Bitmask creation
|
||||
* Bit positions start at zero.
|
||||
@@ -283,10 +287,10 @@
|
||||
/* Generic bitfield macros and masks */
|
||||
|
||||
#define ACPI_GET_BITS(source_ptr, position, mask) \
|
||||
((*source_ptr >> position) & mask)
|
||||
((*(source_ptr) >> (position)) & (mask))
|
||||
|
||||
#define ACPI_SET_BITS(target_ptr, position, mask, value) \
|
||||
(*target_ptr |= ((value & mask) << position))
|
||||
(*(target_ptr) |= (((value) & (mask)) << (position)))
|
||||
|
||||
#define ACPI_1BIT_MASK 0x00000001
|
||||
#define ACPI_2BIT_MASK 0x00000003
|
||||
|
||||
@@ -206,9 +206,10 @@ void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth);
|
||||
void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level);
|
||||
|
||||
void
|
||||
acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component);
|
||||
acpi_ns_dump_pathname(acpi_handle handle,
|
||||
const char *msg, u32 level, u32 component);
|
||||
|
||||
void acpi_ns_print_pathname(u32 num_segments, char *pathname);
|
||||
void acpi_ns_print_pathname(u32 num_segments, const char *pathname);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_dump_one_object(acpi_handle obj_handle,
|
||||
|
||||
@@ -139,7 +139,7 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||
*/
|
||||
const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode);
|
||||
|
||||
char *acpi_ps_get_opcode_name(u16 opcode);
|
||||
const char *acpi_ps_get_opcode_name(u16 opcode);
|
||||
|
||||
u8 acpi_ps_get_argument_count(u32 op_type);
|
||||
|
||||
|
||||
@@ -523,6 +523,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
|
||||
METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (4 Int) */
|
||||
PACKAGE_INFO(ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0),
|
||||
|
||||
{{"_FIT", METHOD_0ARGS,
|
||||
METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, /* ACPI 6.0 */
|
||||
|
||||
{{"_FIX", METHOD_0ARGS,
|
||||
METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints) */
|
||||
PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0),
|
||||
@@ -1053,6 +1056,12 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
|
||||
METHOD_RETURNS(ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING |
|
||||
ACPI_RTYPE_BUFFER)}},
|
||||
|
||||
{{"_WPC", METHOD_0ARGS,
|
||||
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* ACPI 6.1 */
|
||||
|
||||
{{"_WPP", METHOD_0ARGS,
|
||||
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* ACPI 6.1 */
|
||||
|
||||
PACKAGE_INFO(0, 0, 0, 0, 0, 0) /* Table terminator */
|
||||
};
|
||||
#else
|
||||
|
||||
@@ -124,7 +124,7 @@ typedef enum {
|
||||
typedef const struct acpi_rsdump_info {
|
||||
u8 opcode;
|
||||
u8 offset;
|
||||
char *name;
|
||||
const char *name;
|
||||
const char **pointer;
|
||||
|
||||
} acpi_rsdump_info;
|
||||
@@ -209,7 +209,7 @@ acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
|
||||
|
||||
acpi_status
|
||||
acpi_rs_get_method_data(acpi_handle handle,
|
||||
char *path, struct acpi_buffer *ret_buffer);
|
||||
const char *path, struct acpi_buffer *ret_buffer);
|
||||
|
||||
acpi_status
|
||||
acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
|
||||
|
||||
@@ -184,7 +184,7 @@ struct acpi_evaluate_info {
|
||||
/* The first 3 elements are passed by the caller to acpi_ns_evaluate */
|
||||
|
||||
struct acpi_namespace_node *prefix_node; /* Input: starting node */
|
||||
char *relative_pathname; /* Input: path relative to prefix_node */
|
||||
const char *relative_pathname; /* Input: path relative to prefix_node */
|
||||
union acpi_operand_object **parameters; /* Input: argument list */
|
||||
|
||||
struct acpi_namespace_node *node; /* Resolved node (prefix_node:relative_pathname) */
|
||||
|
||||
@@ -175,7 +175,14 @@ void acpi_ut_strlwr(char *src_string);
|
||||
|
||||
int acpi_ut_stricmp(char *string1, char *string2);
|
||||
|
||||
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer);
|
||||
acpi_status
|
||||
acpi_ut_strtoul64(char *string,
|
||||
u32 base, u32 max_integer_byte_width, u64 *ret_integer);
|
||||
|
||||
/* Values for max_integer_byte_width above */
|
||||
|
||||
#define ACPI_MAX32_BYTE_WIDTH 4
|
||||
#define ACPI_MAX64_BYTE_WIDTH 8
|
||||
|
||||
/*
|
||||
* utglobal - Global data structures and procedures
|
||||
@@ -266,7 +273,8 @@ acpi_ut_trace(u32 line_number,
|
||||
void
|
||||
acpi_ut_trace_ptr(u32 line_number,
|
||||
const char *function_name,
|
||||
const char *module_name, u32 component_id, void *pointer);
|
||||
const char *module_name,
|
||||
u32 component_id, const void *pointer);
|
||||
|
||||
void
|
||||
acpi_ut_trace_u32(u32 line_number,
|
||||
@@ -276,7 +284,8 @@ acpi_ut_trace_u32(u32 line_number,
|
||||
void
|
||||
acpi_ut_trace_str(u32 line_number,
|
||||
const char *function_name,
|
||||
const char *module_name, u32 component_id, char *string);
|
||||
const char *module_name,
|
||||
u32 component_id, const char *string);
|
||||
|
||||
void
|
||||
acpi_ut_exit(u32 line_number,
|
||||
@@ -335,12 +344,12 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list);
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
||||
char *path,
|
||||
const char *path,
|
||||
u32 expected_return_btypes,
|
||||
union acpi_operand_object **return_desc);
|
||||
|
||||
acpi_status
|
||||
acpi_ut_evaluate_numeric_object(char *object_name,
|
||||
acpi_ut_evaluate_numeric_object(const char *object_name,
|
||||
struct acpi_namespace_node *device_node,
|
||||
u64 *value);
|
||||
|
||||
@@ -526,7 +535,7 @@ void acpi_ut_set_integer_width(u8 revision);
|
||||
void
|
||||
acpi_ut_display_init_pathname(u8 type,
|
||||
struct acpi_namespace_node *obj_handle,
|
||||
char *path);
|
||||
const char *path);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -628,7 +637,7 @@ void acpi_ut_dump_allocation_info(void);
|
||||
void acpi_ut_dump_allocations(u32 component, const char *module);
|
||||
|
||||
acpi_status
|
||||
acpi_ut_create_list(char *list_name,
|
||||
acpi_ut_create_list(const char *list_name,
|
||||
u16 object_size, struct acpi_memory_list **return_cache);
|
||||
|
||||
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
|
||||
|
||||
@@ -277,7 +277,9 @@ acpi_db_convert_to_object(acpi_object_type type,
|
||||
default:
|
||||
|
||||
object->type = ACPI_TYPE_INTEGER;
|
||||
status = acpi_ut_strtoul64(string, 16, &object->integer.value);
|
||||
status =
|
||||
acpi_ut_strtoul64(string, 16, acpi_gbl_integer_byte_width,
|
||||
&object->integer.value);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,12 +57,12 @@ static u32 acpi_db_get_line(char *input_buffer);
|
||||
|
||||
static u32 acpi_db_match_command(char *user_command);
|
||||
|
||||
static void acpi_db_display_command_info(char *command, u8 display_all);
|
||||
static void acpi_db_display_command_info(const char *command, u8 display_all);
|
||||
|
||||
static void acpi_db_display_help(char *command);
|
||||
|
||||
static u8
|
||||
acpi_db_match_command_help(char *command,
|
||||
acpi_db_match_command_help(const char *command,
|
||||
const struct acpi_db_command_help *help);
|
||||
|
||||
/*
|
||||
@@ -348,7 +348,7 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
|
||||
******************************************************************************/
|
||||
|
||||
static u8
|
||||
acpi_db_match_command_help(char *command,
|
||||
acpi_db_match_command_help(const char *command,
|
||||
const struct acpi_db_command_help *help)
|
||||
{
|
||||
char *invocation = help->invocation;
|
||||
@@ -402,7 +402,7 @@ acpi_db_match_command_help(char *command,
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_db_display_command_info(char *command, u8 display_all)
|
||||
static void acpi_db_display_command_info(const char *command, u8 display_all)
|
||||
{
|
||||
const struct acpi_db_command_help *next;
|
||||
u8 matched;
|
||||
@@ -656,8 +656,9 @@ static u32 acpi_db_match_command(char *user_command)
|
||||
}
|
||||
|
||||
for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) {
|
||||
if (strstr(acpi_gbl_db_commands[i].name, user_command) ==
|
||||
acpi_gbl_db_commands[i].name) {
|
||||
if (strstr
|
||||
(ACPI_CAST_PTR(char, acpi_gbl_db_commands[i].name),
|
||||
user_command) == acpi_gbl_db_commands[i].name) {
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,8 +56,6 @@ acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);
|
||||
void acpi_db_dump_buffer(u32 address);
|
||||
#endif
|
||||
|
||||
static char *gbl_hex_to_ascii = "0123456789ABCDEF";
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_db_match_argument
|
||||
@@ -82,8 +80,9 @@ acpi_db_match_argument(char *user_argument,
|
||||
}
|
||||
|
||||
for (i = 0; arguments[i].name; i++) {
|
||||
if (strstr(arguments[i].name, user_argument) ==
|
||||
arguments[i].name) {
|
||||
if (strstr(ACPI_CAST_PTR(char, arguments[i].name),
|
||||
ACPI_CAST_PTR(char,
|
||||
user_argument)) == arguments[i].name) {
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
@@ -339,7 +338,7 @@ void acpi_db_uint32_to_hex_string(u32 value, char *buffer)
|
||||
buffer[8] = '\0';
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
buffer[i] = gbl_hex_to_ascii[value & 0x0F];
|
||||
buffer[i] = acpi_gbl_upper_hex_digits[value & 0x0F];
|
||||
value = value >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,52 +524,6 @@ acpi_ev_attach_region(union acpi_operand_object *handler_obj,
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_associate_reg_method
|
||||
*
|
||||
* PARAMETERS: region_obj - Region object
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Find and associate _REG method to a region
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void acpi_ev_associate_reg_method(union acpi_operand_object *region_obj)
|
||||
{
|
||||
acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
|
||||
struct acpi_namespace_node *method_node;
|
||||
struct acpi_namespace_node *node;
|
||||
union acpi_operand_object *region_obj2;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_associate_reg_method);
|
||||
|
||||
region_obj2 = acpi_ns_get_secondary_object(region_obj);
|
||||
if (!region_obj2) {
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
node = region_obj->region.node->parent;
|
||||
|
||||
/* Find any "_REG" method associated with this region definition */
|
||||
|
||||
status =
|
||||
acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
|
||||
&method_node);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
/*
|
||||
* The _REG method is optional and there can be only one per region
|
||||
* definition. This will be executed when the handler is attached
|
||||
* or removed
|
||||
*/
|
||||
region_obj2->extra.method_REG = method_node;
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_execute_reg_method
|
||||
@@ -589,18 +543,42 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
|
||||
struct acpi_evaluate_info *info;
|
||||
union acpi_operand_object *args[3];
|
||||
union acpi_operand_object *region_obj2;
|
||||
const acpi_name *reg_name_ptr =
|
||||
ACPI_CAST_PTR(acpi_name, METHOD_NAME__REG);
|
||||
struct acpi_namespace_node *method_node;
|
||||
struct acpi_namespace_node *node;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_execute_reg_method);
|
||||
|
||||
if (!acpi_gbl_namespace_initialized ||
|
||||
region_obj->region.handler == NULL) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
region_obj2 = acpi_ns_get_secondary_object(region_obj);
|
||||
if (!region_obj2) {
|
||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
if (region_obj2->extra.method_REG == NULL ||
|
||||
region_obj->region.handler == NULL ||
|
||||
!acpi_gbl_namespace_initialized) {
|
||||
/*
|
||||
* Find any "_REG" method associated with this region definition.
|
||||
* The method should always be updated as this function may be
|
||||
* invoked after a namespace change.
|
||||
*/
|
||||
node = region_obj->region.node->parent;
|
||||
status =
|
||||
acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
|
||||
&method_node);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
/*
|
||||
* The _REG method is optional and there can be only one per
|
||||
* region definition. This will be executed when the handler is
|
||||
* attached or removed.
|
||||
*/
|
||||
region_obj2->extra.method_REG = method_node;
|
||||
}
|
||||
if (region_obj2->extra.method_REG == NULL) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -518,7 +518,6 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
acpi_ev_associate_reg_method(region_obj);
|
||||
region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
|
||||
|
||||
node = region_obj->region.node->parent;
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: exconcat - Concatenate-type AML operators
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, 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 "acinterp.h"
|
||||
#include "amlresrc.h"
|
||||
|
||||
#define _COMPONENT ACPI_EXECUTER
|
||||
ACPI_MODULE_NAME("exconcat")
|
||||
|
||||
/* Local Prototypes */
|
||||
static acpi_status
|
||||
acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
|
||||
union acpi_operand_object **result_desc);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ex_do_concatenate
|
||||
*
|
||||
* PARAMETERS: operand0 - First source object
|
||||
* operand1 - Second source object
|
||||
* actual_return_desc - Where to place the return object
|
||||
* walk_state - Current walk state
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Concatenate two objects with the ACPI-defined conversion
|
||||
* rules as necessary.
|
||||
* NOTE:
|
||||
* Per the ACPI spec (up to 6.1), Concatenate only supports Integer,
|
||||
* String, and Buffer objects. However, we support all objects here
|
||||
* as an extension. This improves the usefulness of both Concatenate
|
||||
* and the Printf/Fprintf macros. The extension returns a string
|
||||
* describing the object type for the other objects.
|
||||
* 02/2016.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ex_do_concatenate(union acpi_operand_object *operand0,
|
||||
union acpi_operand_object *operand1,
|
||||
union acpi_operand_object **actual_return_desc,
|
||||
struct acpi_walk_state *walk_state)
|
||||
{
|
||||
union acpi_operand_object *local_operand0 = operand0;
|
||||
union acpi_operand_object *local_operand1 = operand1;
|
||||
union acpi_operand_object *temp_operand1 = NULL;
|
||||
union acpi_operand_object *return_desc;
|
||||
char *buffer;
|
||||
acpi_object_type operand0_type;
|
||||
acpi_object_type operand1_type;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ex_do_concatenate);
|
||||
|
||||
/* Operand 0 preprocessing */
|
||||
|
||||
switch (operand0->common.type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
operand0_type = operand0->common.type;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* For all other types, get the "object type" string */
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_object_type_string(operand0,
|
||||
&local_operand0);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
operand0_type = ACPI_TYPE_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Operand 1 preprocessing */
|
||||
|
||||
switch (operand1->common.type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
operand1_type = operand1->common.type;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* For all other types, get the "object type" string */
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_object_type_string(operand1,
|
||||
&local_operand1);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
operand1_type = ACPI_TYPE_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the second operand if necessary. The first operand (0)
|
||||
* determines the type of the second operand (1) (See the Data Types
|
||||
* section of the ACPI specification). Both object types are
|
||||
* guaranteed to be either Integer/String/Buffer by the operand
|
||||
* resolution mechanism.
|
||||
*/
|
||||
switch (operand0_type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_integer(local_operand1, &temp_operand1,
|
||||
16);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_buffer(local_operand1, &temp_operand1);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
switch (operand1_type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/* Other types have already been converted to string */
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_string(local_operand1,
|
||||
&temp_operand1,
|
||||
ACPI_IMPLICIT_CONVERT_HEX);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_OK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
|
||||
operand0->common.type));
|
||||
status = AE_AML_INTERNAL;
|
||||
}
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Take care with any newly created operand objects */
|
||||
|
||||
if ((local_operand1 != operand1) && (local_operand1 != temp_operand1)) {
|
||||
acpi_ut_remove_reference(local_operand1);
|
||||
}
|
||||
|
||||
local_operand1 = temp_operand1;
|
||||
|
||||
/*
|
||||
* Both operands are now known to be the same object type
|
||||
* (Both are Integer, String, or Buffer), and we can now perform
|
||||
* the concatenation.
|
||||
*
|
||||
* There are three cases to handle, as per the ACPI spec:
|
||||
*
|
||||
* 1) Two Integers concatenated to produce a new Buffer
|
||||
* 2) Two Strings concatenated to produce a new String
|
||||
* 3) Two Buffers concatenated to produce a new Buffer
|
||||
*/
|
||||
switch (operand0_type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
/* Result of two Integers is a Buffer */
|
||||
/* Need enough buffer space for two integers */
|
||||
|
||||
return_desc = acpi_ut_create_buffer_object((acpi_size)
|
||||
ACPI_MUL_2
|
||||
(acpi_gbl_integer_byte_width));
|
||||
if (!return_desc) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buffer = (char *)return_desc->buffer.pointer;
|
||||
|
||||
/* Copy the first integer, LSB first */
|
||||
|
||||
memcpy(buffer, &operand0->integer.value,
|
||||
acpi_gbl_integer_byte_width);
|
||||
|
||||
/* Copy the second integer (LSB first) after the first */
|
||||
|
||||
memcpy(buffer + acpi_gbl_integer_byte_width,
|
||||
&local_operand1->integer.value,
|
||||
acpi_gbl_integer_byte_width);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
/* Result of two Strings is a String */
|
||||
|
||||
return_desc = acpi_ut_create_string_object(((acpi_size)
|
||||
local_operand0->
|
||||
string.length +
|
||||
local_operand1->
|
||||
string.length));
|
||||
if (!return_desc) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buffer = return_desc->string.pointer;
|
||||
|
||||
/* Concatenate the strings */
|
||||
|
||||
strcpy(buffer, local_operand0->string.pointer);
|
||||
strcat(buffer, local_operand1->string.pointer);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/* Result of two Buffers is a Buffer */
|
||||
|
||||
return_desc = acpi_ut_create_buffer_object(((acpi_size)
|
||||
operand0->buffer.
|
||||
length +
|
||||
local_operand1->
|
||||
buffer.length));
|
||||
if (!return_desc) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buffer = (char *)return_desc->buffer.pointer;
|
||||
|
||||
/* Concatenate the buffers */
|
||||
|
||||
memcpy(buffer, operand0->buffer.pointer,
|
||||
operand0->buffer.length);
|
||||
memcpy(buffer + operand0->buffer.length,
|
||||
local_operand1->buffer.pointer,
|
||||
local_operand1->buffer.length);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Invalid object type, should not happen here */
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
|
||||
operand0->common.type));
|
||||
status = AE_AML_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*actual_return_desc = return_desc;
|
||||
|
||||
cleanup:
|
||||
if (local_operand0 != operand0) {
|
||||
acpi_ut_remove_reference(local_operand0);
|
||||
}
|
||||
|
||||
if (local_operand1 != operand1) {
|
||||
acpi_ut_remove_reference(local_operand1);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ex_convert_to_object_type_string
|
||||
*
|
||||
* PARAMETERS: obj_desc - Object to be converted
|
||||
* return_desc - Where to place the return object
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Convert an object of arbitrary type to a string object that
|
||||
* contains the namestring for the object. Used for the
|
||||
* concatenate operator.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
|
||||
union acpi_operand_object **result_desc)
|
||||
{
|
||||
union acpi_operand_object *return_desc;
|
||||
const char *type_string;
|
||||
|
||||
type_string = acpi_ut_get_type_name(obj_desc->common.type);
|
||||
|
||||
return_desc = acpi_ut_create_string_object(((acpi_size) strlen(type_string) + 9)); /* 9 For "[ Object]" */
|
||||
if (!return_desc) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
strcpy(return_desc->string.pointer, "[");
|
||||
strcat(return_desc->string.pointer, type_string);
|
||||
strcat(return_desc->string.pointer, " Object]");
|
||||
|
||||
*result_desc = return_desc;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ex_concat_template
|
||||
*
|
||||
* PARAMETERS: operand0 - First source object
|
||||
* operand1 - Second source object
|
||||
* actual_return_desc - Where to place the return object
|
||||
* walk_state - Current walk state
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Concatenate two resource templates
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ex_concat_template(union acpi_operand_object *operand0,
|
||||
union acpi_operand_object *operand1,
|
||||
union acpi_operand_object **actual_return_desc,
|
||||
struct acpi_walk_state * walk_state)
|
||||
{
|
||||
acpi_status status;
|
||||
union acpi_operand_object *return_desc;
|
||||
u8 *new_buf;
|
||||
u8 *end_tag;
|
||||
acpi_size length0;
|
||||
acpi_size length1;
|
||||
acpi_size new_length;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ex_concat_template);
|
||||
|
||||
/*
|
||||
* Find the end_tag descriptor in each resource template.
|
||||
* Note1: returned pointers point TO the end_tag, not past it.
|
||||
* Note2: zero-length buffers are allowed; treated like one end_tag
|
||||
*/
|
||||
|
||||
/* Get the length of the first resource template */
|
||||
|
||||
status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
|
||||
|
||||
/* Get the length of the second resource template */
|
||||
|
||||
status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
|
||||
|
||||
/* Combine both lengths, minimum size will be 2 for end_tag */
|
||||
|
||||
new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
|
||||
|
||||
/* Create a new buffer object for the result (with one end_tag) */
|
||||
|
||||
return_desc = acpi_ut_create_buffer_object(new_length);
|
||||
if (!return_desc) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the templates to the new buffer, 0 first, then 1 follows. One
|
||||
* end_tag descriptor is copied from Operand1.
|
||||
*/
|
||||
new_buf = return_desc->buffer.pointer;
|
||||
memcpy(new_buf, operand0->buffer.pointer, length0);
|
||||
memcpy(new_buf + length0, operand1->buffer.pointer, length1);
|
||||
|
||||
/* Insert end_tag and set the checksum to zero, means "ignore checksum" */
|
||||
|
||||
new_buf[new_length - 1] = 0;
|
||||
new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
|
||||
|
||||
/* Return the completed resource template */
|
||||
|
||||
*actual_return_desc = return_desc;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
@@ -118,7 +118,9 @@ acpi_ex_add_table(u32 table_index,
|
||||
/* Execute any module-level code that was found in the table */
|
||||
|
||||
acpi_ex_exit_interpreter();
|
||||
if (acpi_gbl_group_module_level_code) {
|
||||
acpi_ns_exec_module_code_list();
|
||||
}
|
||||
acpi_ex_enter_interpreter();
|
||||
|
||||
/*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user