ACPICA: Source restructuring: split large files into 8 new files.
Created logical splits for eight new files. Improves modularity and configurability. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
4f84291668
commit
42f8fb75c4
@ -31,6 +31,7 @@ acpi-y += \
|
|||||||
evgpeinit.o \
|
evgpeinit.o \
|
||||||
evgpeutil.o \
|
evgpeutil.o \
|
||||||
evglock.o \
|
evglock.o \
|
||||||
|
evhandler.o \
|
||||||
evmisc.o \
|
evmisc.o \
|
||||||
evregion.o \
|
evregion.o \
|
||||||
evrgnini.o \
|
evrgnini.o \
|
||||||
@ -90,6 +91,7 @@ acpi-y += \
|
|||||||
nsobject.o \
|
nsobject.o \
|
||||||
nsparse.o \
|
nsparse.o \
|
||||||
nspredef.o \
|
nspredef.o \
|
||||||
|
nsprepkg.o \
|
||||||
nsrepair.o \
|
nsrepair.o \
|
||||||
nsrepair2.o \
|
nsrepair2.o \
|
||||||
nssearch.o \
|
nssearch.o \
|
||||||
@ -104,7 +106,9 @@ acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
|
|||||||
acpi-y += \
|
acpi-y += \
|
||||||
psargs.o \
|
psargs.o \
|
||||||
psloop.o \
|
psloop.o \
|
||||||
|
psobject.o \
|
||||||
psopcode.o \
|
psopcode.o \
|
||||||
|
psopinfo.o \
|
||||||
psparse.o \
|
psparse.o \
|
||||||
psscope.o \
|
psscope.o \
|
||||||
pstree.o \
|
pstree.o \
|
||||||
@ -126,7 +130,7 @@ acpi-y += \
|
|||||||
rsutils.o \
|
rsutils.o \
|
||||||
rsxface.o
|
rsxface.o
|
||||||
|
|
||||||
acpi-$(ACPI_FUTURE_USAGE) += rsdump.o
|
acpi-$(ACPI_FUTURE_USAGE) += rsdump.o rsdumpinfo.o
|
||||||
|
|
||||||
acpi-y += \
|
acpi-y += \
|
||||||
tbfadt.o \
|
tbfadt.o \
|
||||||
@ -155,8 +159,10 @@ acpi-y += \
|
|||||||
utmutex.o \
|
utmutex.o \
|
||||||
utobject.o \
|
utobject.o \
|
||||||
utosi.o \
|
utosi.o \
|
||||||
|
utownerid.o \
|
||||||
utresrc.o \
|
utresrc.o \
|
||||||
utstate.o \
|
utstate.o \
|
||||||
|
utstring.o \
|
||||||
utxface.o \
|
utxface.o \
|
||||||
utxfinit.o \
|
utxfinit.o \
|
||||||
utxferror.o \
|
utxferror.o \
|
||||||
|
@ -114,6 +114,21 @@ ACPI_HW_DEPENDENT_RETURN_VOID(void
|
|||||||
acpi_db_generate_gpe(char *gpe_arg,
|
acpi_db_generate_gpe(char *gpe_arg,
|
||||||
char *block_arg))
|
char *block_arg))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dbconvert - miscellaneous conversion routines
|
||||||
|
*/
|
||||||
|
acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value);
|
||||||
|
|
||||||
|
acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_db_convert_to_object(acpi_object_type type,
|
||||||
|
char *string, union acpi_object *object);
|
||||||
|
|
||||||
|
u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info);
|
||||||
|
|
||||||
|
void acpi_db_dump_pld_buffer(union acpi_object *obj_desc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dbmethod - control method commands
|
* dbmethod - control method commands
|
||||||
*/
|
*/
|
||||||
@ -191,6 +206,8 @@ void
|
|||||||
acpi_db_create_execution_threads(char *num_threads_arg,
|
acpi_db_create_execution_threads(char *num_threads_arg,
|
||||||
char *num_loops_arg, char *method_name_arg);
|
char *num_loops_arg, char *method_name_arg);
|
||||||
|
|
||||||
|
void acpi_db_delete_objects(u32 count, union acpi_object *objects);
|
||||||
|
|
||||||
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
|
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
|
||||||
u32 acpi_db_get_cache_info(struct acpi_memory_list *cache);
|
u32 acpi_db_get_cache_info(struct acpi_memory_list *cache);
|
||||||
#endif
|
#endif
|
||||||
|
@ -158,10 +158,23 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||||||
void *context);
|
void *context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* evregion - Address Space handling
|
* evhandler - Address space handling
|
||||||
*/
|
*/
|
||||||
|
u8
|
||||||
|
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
|
||||||
|
acpi_adr_space_type space_id);
|
||||||
|
|
||||||
acpi_status acpi_ev_install_region_handlers(void);
|
acpi_status acpi_ev_install_region_handlers(void);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ev_install_space_handler(struct acpi_namespace_node *node,
|
||||||
|
acpi_adr_space_type space_id,
|
||||||
|
acpi_adr_space_handler handler,
|
||||||
|
acpi_adr_space_setup setup, void *context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* evregion - Operation region support
|
||||||
|
*/
|
||||||
acpi_status acpi_ev_initialize_op_regions(void);
|
acpi_status acpi_ev_initialize_op_regions(void);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
@ -179,12 +192,6 @@ void
|
|||||||
acpi_ev_detach_region(union acpi_operand_object *region_obj,
|
acpi_ev_detach_region(union acpi_operand_object *region_obj,
|
||||||
u8 acpi_ns_is_locked);
|
u8 acpi_ns_is_locked);
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_ev_install_space_handler(struct acpi_namespace_node *node,
|
|
||||||
acpi_adr_space_type space_id,
|
|
||||||
acpi_adr_space_handler handler,
|
|
||||||
acpi_adr_space_setup setup, void *context);
|
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||||
acpi_adr_space_type space_id);
|
acpi_adr_space_type space_id);
|
||||||
|
@ -218,6 +218,18 @@ acpi_ns_check_parameter_count(char *pathname,
|
|||||||
u32 user_param_count,
|
u32 user_param_count,
|
||||||
const union acpi_predefined_info *info);
|
const union acpi_predefined_info *info);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ns_check_object_type(struct acpi_predefined_data *data,
|
||||||
|
union acpi_operand_object **return_object_ptr,
|
||||||
|
u32 expected_btypes, u32 package_index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nsprepkg - Validation of predefined name packages
|
||||||
|
*/
|
||||||
|
acpi_status
|
||||||
|
acpi_ns_check_package(struct acpi_predefined_data *data,
|
||||||
|
union acpi_operand_object **return_object_ptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nsnames - Name and Scope manipulation
|
* nsnames - Name and Scope manipulation
|
||||||
*/
|
*/
|
||||||
|
@ -105,7 +105,28 @@ union acpi_parse_object *acpi_ps_find_name(union acpi_parse_object *scope,
|
|||||||
union acpi_parse_object *acpi_ps_get_parent(union acpi_parse_object *op);
|
union acpi_parse_object *acpi_ps_get_parent(union acpi_parse_object *op);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* psopcode - AML Opcode information
|
* psobject - support for parse object processing
|
||||||
|
*/
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
|
||||||
|
u8 *aml_op_start,
|
||||||
|
union acpi_parse_object *unnamed_op,
|
||||||
|
union acpi_parse_object **op);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_create_op(struct acpi_walk_state *walk_state,
|
||||||
|
u8 *aml_op_start, union acpi_parse_object **new_op);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_complete_op(struct acpi_walk_state *walk_state,
|
||||||
|
union acpi_parse_object **op, acpi_status status);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||||
|
union acpi_parse_object *op, acpi_status status);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* psopinfo - AML Opcode information
|
||||||
*/
|
*/
|
||||||
const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode);
|
const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode);
|
||||||
|
|
||||||
|
@ -347,18 +347,21 @@ extern struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[];
|
|||||||
extern struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[];
|
extern struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rsdump
|
* rsdumpinfo
|
||||||
*/
|
*/
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_irq[];
|
extern struct acpi_rsdump_info acpi_rs_dump_irq[];
|
||||||
|
extern struct acpi_rsdump_info acpi_rs_dump_prt[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_dma[];
|
extern struct acpi_rsdump_info acpi_rs_dump_dma[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_start_dpf[];
|
extern struct acpi_rsdump_info acpi_rs_dump_start_dpf[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_end_dpf[];
|
extern struct acpi_rsdump_info acpi_rs_dump_end_dpf[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_io[];
|
extern struct acpi_rsdump_info acpi_rs_dump_io[];
|
||||||
|
extern struct acpi_rsdump_info acpi_rs_dump_io_flags[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_fixed_io[];
|
extern struct acpi_rsdump_info acpi_rs_dump_fixed_io[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_vendor[];
|
extern struct acpi_rsdump_info acpi_rs_dump_vendor[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_end_tag[];
|
extern struct acpi_rsdump_info acpi_rs_dump_end_tag[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_memory24[];
|
extern struct acpi_rsdump_info acpi_rs_dump_memory24[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_memory32[];
|
extern struct acpi_rsdump_info acpi_rs_dump_memory32[];
|
||||||
|
extern struct acpi_rsdump_info acpi_rs_dump_memory_flags[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[];
|
extern struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_address16[];
|
extern struct acpi_rsdump_info acpi_rs_dump_address16[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_address32[];
|
extern struct acpi_rsdump_info acpi_rs_dump_address32[];
|
||||||
@ -372,6 +375,7 @@ extern struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[];
|
|||||||
extern struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[];
|
extern struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[];
|
extern struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[];
|
||||||
extern struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[];
|
extern struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[];
|
||||||
|
extern struct acpi_rsdump_info acpi_rs_dump_general_flags[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ACRESRC_H__ */
|
#endif /* __ACRESRC_H__ */
|
||||||
|
@ -483,39 +483,17 @@ acpi_ut_short_divide(u64 in_dividend,
|
|||||||
/*
|
/*
|
||||||
* utmisc
|
* utmisc
|
||||||
*/
|
*/
|
||||||
void ut_convert_backslashes(char *pathname);
|
|
||||||
|
|
||||||
const char *acpi_ut_validate_exception(acpi_status status);
|
const char *acpi_ut_validate_exception(acpi_status status);
|
||||||
|
|
||||||
u8 acpi_ut_is_pci_root_bridge(char *id);
|
u8 acpi_ut_is_pci_root_bridge(char *id);
|
||||||
|
|
||||||
u8 acpi_ut_is_aml_table(struct acpi_table_header *table);
|
u8 acpi_ut_is_aml_table(struct acpi_table_header *table);
|
||||||
|
|
||||||
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
|
|
||||||
|
|
||||||
void acpi_ut_release_owner_id(acpi_owner_id * owner_id);
|
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
|
acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
|
||||||
void *target_object,
|
void *target_object,
|
||||||
acpi_pkg_callback walk_callback, void *context);
|
acpi_pkg_callback walk_callback, void *context);
|
||||||
|
|
||||||
void acpi_ut_strupr(char *src_string);
|
|
||||||
|
|
||||||
void acpi_ut_strlwr(char *src_string);
|
|
||||||
|
|
||||||
int acpi_ut_stricmp(char *string1, char *string2);
|
|
||||||
|
|
||||||
void acpi_ut_print_string(char *string, u8 max_length);
|
|
||||||
|
|
||||||
u8 acpi_ut_valid_acpi_name(u32 name);
|
|
||||||
|
|
||||||
void acpi_ut_repair_name(char *name);
|
|
||||||
|
|
||||||
u8 acpi_ut_valid_acpi_char(char character, u32 position);
|
|
||||||
|
|
||||||
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer);
|
|
||||||
|
|
||||||
/* Values for Base above (16=Hex, 10=Decimal) */
|
/* Values for Base above (16=Hex, 10=Decimal) */
|
||||||
|
|
||||||
#define ACPI_ANY_BASE 0
|
#define ACPI_ANY_BASE 0
|
||||||
@ -531,6 +509,13 @@ acpi_ut_display_init_pathname(u8 type,
|
|||||||
char *path);
|
char *path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* utownerid - Support for Table/Method Owner IDs
|
||||||
|
*/
|
||||||
|
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
|
||||||
|
|
||||||
|
void acpi_ut_release_owner_id(acpi_owner_id * owner_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* utresrc
|
* utresrc
|
||||||
*/
|
*/
|
||||||
@ -556,6 +541,27 @@ u8 acpi_ut_get_resource_type(void *aml);
|
|||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag);
|
acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* utstring - String and character utilities
|
||||||
|
*/
|
||||||
|
void acpi_ut_strupr(char *src_string);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
void acpi_ut_print_string(char *string, u8 max_length);
|
||||||
|
|
||||||
|
void ut_convert_backslashes(char *pathname);
|
||||||
|
|
||||||
|
u8 acpi_ut_valid_acpi_name(u32 name);
|
||||||
|
|
||||||
|
u8 acpi_ut_valid_acpi_char(char character, u32 position);
|
||||||
|
|
||||||
|
void acpi_ut_repair_name(char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* utmutex - mutex support
|
* utmutex - mutex support
|
||||||
*/
|
*/
|
||||||
|
529
drivers/acpi/acpica/evhandler.c
Normal file
529
drivers/acpi/acpica/evhandler.c
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: evhandler - Support for Address Space handlers
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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 "acevents.h"
|
||||||
|
#include "acnamesp.h"
|
||||||
|
#include "acinterp.h"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_EVENTS
|
||||||
|
ACPI_MODULE_NAME("evhandler")
|
||||||
|
|
||||||
|
/* Local prototypes */
|
||||||
|
static acpi_status
|
||||||
|
acpi_ev_install_handler(acpi_handle obj_handle,
|
||||||
|
u32 level, void *context, void **return_value);
|
||||||
|
|
||||||
|
/* These are the address spaces that will get default handlers */
|
||||||
|
|
||||||
|
u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
|
||||||
|
ACPI_ADR_SPACE_SYSTEM_MEMORY,
|
||||||
|
ACPI_ADR_SPACE_SYSTEM_IO,
|
||||||
|
ACPI_ADR_SPACE_PCI_CONFIG,
|
||||||
|
ACPI_ADR_SPACE_DATA_TABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ev_install_region_handlers
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Installs the core subsystem default address space handlers.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status acpi_ev_install_region_handlers(void)
|
||||||
|
{
|
||||||
|
acpi_status status;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ev_install_region_handlers);
|
||||||
|
|
||||||
|
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All address spaces (PCI Config, EC, SMBus) are scope dependent and
|
||||||
|
* registration must occur for a specific device.
|
||||||
|
*
|
||||||
|
* In the case of the system memory and IO address spaces there is
|
||||||
|
* currently no device associated with the address space. For these we
|
||||||
|
* use the root.
|
||||||
|
*
|
||||||
|
* We install the default PCI config space handler at the root so that
|
||||||
|
* this space is immediately available even though the we have not
|
||||||
|
* enumerated all the PCI Root Buses yet. This is to conform to the ACPI
|
||||||
|
* specification which states that the PCI config space must be always
|
||||||
|
* available -- even though we are nowhere near ready to find the PCI root
|
||||||
|
* buses at this point.
|
||||||
|
*
|
||||||
|
* NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
|
||||||
|
* has already been installed (via acpi_install_address_space_handler).
|
||||||
|
* Similar for AE_SAME_HANDLER.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
|
||||||
|
status = acpi_ev_install_space_handler(acpi_gbl_root_node,
|
||||||
|
acpi_gbl_default_address_spaces
|
||||||
|
[i],
|
||||||
|
ACPI_DEFAULT_HANDLER,
|
||||||
|
NULL, NULL);
|
||||||
|
switch (status) {
|
||||||
|
case AE_OK:
|
||||||
|
case AE_SAME_HANDLER:
|
||||||
|
case AE_ALREADY_EXISTS:
|
||||||
|
|
||||||
|
/* These exceptions are all OK */
|
||||||
|
|
||||||
|
status = AE_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_and_exit:
|
||||||
|
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ev_has_default_handler
|
||||||
|
*
|
||||||
|
* PARAMETERS: node - Namespace node for the device
|
||||||
|
* space_id - The address space ID
|
||||||
|
*
|
||||||
|
* RETURN: TRUE if default handler is installed, FALSE otherwise
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Check if the default handler is installed for the requested
|
||||||
|
* space ID.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
u8
|
||||||
|
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
|
||||||
|
acpi_adr_space_type space_id)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *obj_desc;
|
||||||
|
union acpi_operand_object *handler_obj;
|
||||||
|
|
||||||
|
/* Must have an existing internal object */
|
||||||
|
|
||||||
|
obj_desc = acpi_ns_get_attached_object(node);
|
||||||
|
if (obj_desc) {
|
||||||
|
handler_obj = obj_desc->device.handler;
|
||||||
|
|
||||||
|
/* Walk the linked list of handlers for this object */
|
||||||
|
|
||||||
|
while (handler_obj) {
|
||||||
|
if (handler_obj->address_space.space_id == space_id) {
|
||||||
|
if (handler_obj->address_space.handler_flags &
|
||||||
|
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler_obj = handler_obj->address_space.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ev_install_handler
|
||||||
|
*
|
||||||
|
* PARAMETERS: walk_namespace callback
|
||||||
|
*
|
||||||
|
* DESCRIPTION: This routine installs an address handler into objects that are
|
||||||
|
* of type Region or Device.
|
||||||
|
*
|
||||||
|
* If the Object is a Device, and the device has a handler of
|
||||||
|
* the same type then the search is terminated in that branch.
|
||||||
|
*
|
||||||
|
* This is because the existing handler is closer in proximity
|
||||||
|
* to any more regions than the one we are trying to install.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static acpi_status
|
||||||
|
acpi_ev_install_handler(acpi_handle obj_handle,
|
||||||
|
u32 level, void *context, void **return_value)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *handler_obj;
|
||||||
|
union acpi_operand_object *next_handler_obj;
|
||||||
|
union acpi_operand_object *obj_desc;
|
||||||
|
struct acpi_namespace_node *node;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_NAME(ev_install_handler);
|
||||||
|
|
||||||
|
handler_obj = (union acpi_operand_object *)context;
|
||||||
|
|
||||||
|
/* Parameter validation */
|
||||||
|
|
||||||
|
if (!handler_obj) {
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert and validate the device handle */
|
||||||
|
|
||||||
|
node = acpi_ns_validate_handle(obj_handle);
|
||||||
|
if (!node) {
|
||||||
|
return (AE_BAD_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only care about regions and objects that are allowed to have
|
||||||
|
* address space handlers
|
||||||
|
*/
|
||||||
|
if ((node->type != ACPI_TYPE_DEVICE) &&
|
||||||
|
(node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for an existing internal object */
|
||||||
|
|
||||||
|
obj_desc = acpi_ns_get_attached_object(node);
|
||||||
|
if (!obj_desc) {
|
||||||
|
|
||||||
|
/* No object, just exit */
|
||||||
|
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Devices are handled different than regions */
|
||||||
|
|
||||||
|
if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
|
||||||
|
|
||||||
|
/* Check if this Device already has a handler for this address space */
|
||||||
|
|
||||||
|
next_handler_obj = obj_desc->device.handler;
|
||||||
|
while (next_handler_obj) {
|
||||||
|
|
||||||
|
/* Found a handler, is it for the same address space? */
|
||||||
|
|
||||||
|
if (next_handler_obj->address_space.space_id ==
|
||||||
|
handler_obj->address_space.space_id) {
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||||
|
"Found handler for region [%s] in device %p(%p) "
|
||||||
|
"handler %p\n",
|
||||||
|
acpi_ut_get_region_name
|
||||||
|
(handler_obj->address_space.
|
||||||
|
space_id), obj_desc,
|
||||||
|
next_handler_obj,
|
||||||
|
handler_obj));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since the object we found it on was a device, then it
|
||||||
|
* means that someone has already installed a handler for
|
||||||
|
* the branch of the namespace from this device on. Just
|
||||||
|
* bail out telling the walk routine to not traverse this
|
||||||
|
* branch. This preserves the scoping rule for handlers.
|
||||||
|
*/
|
||||||
|
return (AE_CTRL_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk the linked list of handlers attached to this device */
|
||||||
|
|
||||||
|
next_handler_obj = next_handler_obj->address_space.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As long as the device didn't have a handler for this space we
|
||||||
|
* don't care about it. We just ignore it and proceed.
|
||||||
|
*/
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Object is a Region */
|
||||||
|
|
||||||
|
if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
|
||||||
|
|
||||||
|
/* This region is for a different address space, just ignore it */
|
||||||
|
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we have a region and it is for the handler's address space type.
|
||||||
|
*
|
||||||
|
* First disconnect region for any previous handler (if any)
|
||||||
|
*/
|
||||||
|
acpi_ev_detach_region(obj_desc, FALSE);
|
||||||
|
|
||||||
|
/* Connect the region to the new handler */
|
||||||
|
|
||||||
|
status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ev_install_space_handler
|
||||||
|
*
|
||||||
|
* PARAMETERS: node - Namespace node for the device
|
||||||
|
* space_id - The address space ID
|
||||||
|
* handler - Address of the handler
|
||||||
|
* setup - Address of the setup function
|
||||||
|
* context - Value passed to the handler on each access
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Install a handler for all op_regions of a given space_id.
|
||||||
|
* Assumes namespace is locked
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ev_install_space_handler(struct acpi_namespace_node * node,
|
||||||
|
acpi_adr_space_type space_id,
|
||||||
|
acpi_adr_space_handler handler,
|
||||||
|
acpi_adr_space_setup setup, void *context)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *obj_desc;
|
||||||
|
union acpi_operand_object *handler_obj;
|
||||||
|
acpi_status status;
|
||||||
|
acpi_object_type type;
|
||||||
|
u8 flags = 0;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ev_install_space_handler);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This registration is valid for only the types below and the root. This
|
||||||
|
* is where the default handlers get placed.
|
||||||
|
*/
|
||||||
|
if ((node->type != ACPI_TYPE_DEVICE) &&
|
||||||
|
(node->type != ACPI_TYPE_PROCESSOR) &&
|
||||||
|
(node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
|
||||||
|
status = AE_BAD_PARAMETER;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler == ACPI_DEFAULT_HANDLER) {
|
||||||
|
flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
|
||||||
|
|
||||||
|
switch (space_id) {
|
||||||
|
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||||
|
handler = acpi_ex_system_memory_space_handler;
|
||||||
|
setup = acpi_ev_system_memory_region_setup;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||||
|
handler = acpi_ex_system_io_space_handler;
|
||||||
|
setup = acpi_ev_io_space_region_setup;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_ADR_SPACE_PCI_CONFIG:
|
||||||
|
handler = acpi_ex_pci_config_space_handler;
|
||||||
|
setup = acpi_ev_pci_config_region_setup;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_ADR_SPACE_CMOS:
|
||||||
|
handler = acpi_ex_cmos_space_handler;
|
||||||
|
setup = acpi_ev_cmos_region_setup;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_ADR_SPACE_PCI_BAR_TARGET:
|
||||||
|
handler = acpi_ex_pci_bar_space_handler;
|
||||||
|
setup = acpi_ev_pci_bar_region_setup;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_ADR_SPACE_DATA_TABLE:
|
||||||
|
handler = acpi_ex_data_table_space_handler;
|
||||||
|
setup = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = AE_BAD_PARAMETER;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the caller hasn't specified a setup routine, use the default */
|
||||||
|
|
||||||
|
if (!setup) {
|
||||||
|
setup = acpi_ev_default_region_setup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for an existing internal object */
|
||||||
|
|
||||||
|
obj_desc = acpi_ns_get_attached_object(node);
|
||||||
|
if (obj_desc) {
|
||||||
|
/*
|
||||||
|
* The attached device object already exists. Make sure the handler
|
||||||
|
* is not already installed.
|
||||||
|
*/
|
||||||
|
handler_obj = obj_desc->device.handler;
|
||||||
|
|
||||||
|
/* Walk the handler list for this device */
|
||||||
|
|
||||||
|
while (handler_obj) {
|
||||||
|
|
||||||
|
/* Same space_id indicates a handler already installed */
|
||||||
|
|
||||||
|
if (handler_obj->address_space.space_id == space_id) {
|
||||||
|
if (handler_obj->address_space.handler ==
|
||||||
|
handler) {
|
||||||
|
/*
|
||||||
|
* It is (relatively) OK to attempt to install the SAME
|
||||||
|
* handler twice. This can easily happen with the
|
||||||
|
* PCI_Config space.
|
||||||
|
*/
|
||||||
|
status = AE_SAME_HANDLER;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
} else {
|
||||||
|
/* A handler is already installed */
|
||||||
|
|
||||||
|
status = AE_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk the linked list of handlers */
|
||||||
|
|
||||||
|
handler_obj = handler_obj->address_space.next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||||
|
"Creating object on Device %p while installing handler\n",
|
||||||
|
node));
|
||||||
|
|
||||||
|
/* obj_desc does not exist, create one */
|
||||||
|
|
||||||
|
if (node->type == ACPI_TYPE_ANY) {
|
||||||
|
type = ACPI_TYPE_DEVICE;
|
||||||
|
} else {
|
||||||
|
type = node->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj_desc = acpi_ut_create_internal_object(type);
|
||||||
|
if (!obj_desc) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init new descriptor */
|
||||||
|
|
||||||
|
obj_desc->common.type = (u8)type;
|
||||||
|
|
||||||
|
/* Attach the new object to the Node */
|
||||||
|
|
||||||
|
status = acpi_ns_attach_object(node, obj_desc, type);
|
||||||
|
|
||||||
|
/* Remove local reference to the object */
|
||||||
|
|
||||||
|
acpi_ut_remove_reference(obj_desc);
|
||||||
|
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||||
|
"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
|
||||||
|
acpi_ut_get_region_name(space_id), space_id,
|
||||||
|
acpi_ut_get_node_name(node), node, obj_desc));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install the handler
|
||||||
|
*
|
||||||
|
* At this point there is no existing handler. Just allocate the object
|
||||||
|
* for the handler and link it into the list.
|
||||||
|
*/
|
||||||
|
handler_obj =
|
||||||
|
acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
|
||||||
|
if (!handler_obj) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init handler obj */
|
||||||
|
|
||||||
|
handler_obj->address_space.space_id = (u8)space_id;
|
||||||
|
handler_obj->address_space.handler_flags = flags;
|
||||||
|
handler_obj->address_space.region_list = NULL;
|
||||||
|
handler_obj->address_space.node = node;
|
||||||
|
handler_obj->address_space.handler = handler;
|
||||||
|
handler_obj->address_space.context = context;
|
||||||
|
handler_obj->address_space.setup = setup;
|
||||||
|
|
||||||
|
/* Install at head of Device.address_space list */
|
||||||
|
|
||||||
|
handler_obj->address_space.next = obj_desc->device.handler;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Device object is the first reference on the handler_obj.
|
||||||
|
* Each region that uses the handler adds a reference.
|
||||||
|
*/
|
||||||
|
obj_desc->device.handler = handler_obj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk the namespace finding all of the regions this
|
||||||
|
* handler will manage.
|
||||||
|
*
|
||||||
|
* Start at the device and search the branch toward
|
||||||
|
* the leaf nodes until either the leaf is encountered or
|
||||||
|
* a device is detected that has an address handler of the
|
||||||
|
* same type.
|
||||||
|
*
|
||||||
|
* In either case, back up and search down the remainder
|
||||||
|
* of the branch
|
||||||
|
*/
|
||||||
|
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
|
||||||
|
ACPI_NS_WALK_UNLOCK,
|
||||||
|
acpi_ev_install_handler, NULL,
|
||||||
|
handler_obj, NULL);
|
||||||
|
|
||||||
|
unlock_and_exit:
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* Module Name: evregion - ACPI address_space (op_region) handler dispatch
|
* Module Name: evregion - Operation Region support
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
@ -50,10 +50,9 @@
|
|||||||
#define _COMPONENT ACPI_EVENTS
|
#define _COMPONENT ACPI_EVENTS
|
||||||
ACPI_MODULE_NAME("evregion")
|
ACPI_MODULE_NAME("evregion")
|
||||||
|
|
||||||
|
extern u8 acpi_gbl_default_address_spaces[];
|
||||||
|
|
||||||
/* Local prototypes */
|
/* Local prototypes */
|
||||||
static u8
|
|
||||||
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
|
|
||||||
acpi_adr_space_type space_id);
|
|
||||||
|
|
||||||
static void acpi_ev_orphan_ec_reg_method(void);
|
static void acpi_ev_orphan_ec_reg_method(void);
|
||||||
|
|
||||||
@ -61,135 +60,6 @@ static acpi_status
|
|||||||
acpi_ev_reg_run(acpi_handle obj_handle,
|
acpi_ev_reg_run(acpi_handle obj_handle,
|
||||||
u32 level, void *context, void **return_value);
|
u32 level, void *context, void **return_value);
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ev_install_handler(acpi_handle obj_handle,
|
|
||||||
u32 level, void *context, void **return_value);
|
|
||||||
|
|
||||||
/* These are the address spaces that will get default handlers */
|
|
||||||
|
|
||||||
#define ACPI_NUM_DEFAULT_SPACES 4
|
|
||||||
|
|
||||||
static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
|
|
||||||
ACPI_ADR_SPACE_SYSTEM_MEMORY,
|
|
||||||
ACPI_ADR_SPACE_SYSTEM_IO,
|
|
||||||
ACPI_ADR_SPACE_PCI_CONFIG,
|
|
||||||
ACPI_ADR_SPACE_DATA_TABLE
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ev_install_region_handlers
|
|
||||||
*
|
|
||||||
* PARAMETERS: None
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Installs the core subsystem default address space handlers.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status acpi_ev_install_region_handlers(void)
|
|
||||||
{
|
|
||||||
acpi_status status;
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_install_region_handlers);
|
|
||||||
|
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* All address spaces (PCI Config, EC, SMBus) are scope dependent and
|
|
||||||
* registration must occur for a specific device.
|
|
||||||
*
|
|
||||||
* In the case of the system memory and IO address spaces there is
|
|
||||||
* currently no device associated with the address space. For these we
|
|
||||||
* use the root.
|
|
||||||
*
|
|
||||||
* We install the default PCI config space handler at the root so that
|
|
||||||
* this space is immediately available even though the we have not
|
|
||||||
* enumerated all the PCI Root Buses yet. This is to conform to the ACPI
|
|
||||||
* specification which states that the PCI config space must be always
|
|
||||||
* available -- even though we are nowhere near ready to find the PCI root
|
|
||||||
* buses at this point.
|
|
||||||
*
|
|
||||||
* NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
|
|
||||||
* has already been installed (via acpi_install_address_space_handler).
|
|
||||||
* Similar for AE_SAME_HANDLER.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
|
|
||||||
status = acpi_ev_install_space_handler(acpi_gbl_root_node,
|
|
||||||
acpi_gbl_default_address_spaces
|
|
||||||
[i],
|
|
||||||
ACPI_DEFAULT_HANDLER,
|
|
||||||
NULL, NULL);
|
|
||||||
switch (status) {
|
|
||||||
case AE_OK:
|
|
||||||
case AE_SAME_HANDLER:
|
|
||||||
case AE_ALREADY_EXISTS:
|
|
||||||
|
|
||||||
/* These exceptions are all OK */
|
|
||||||
|
|
||||||
status = AE_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unlock_and_exit:
|
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ev_has_default_handler
|
|
||||||
*
|
|
||||||
* PARAMETERS: node - Namespace node for the device
|
|
||||||
* space_id - The address space ID
|
|
||||||
*
|
|
||||||
* RETURN: TRUE if default handler is installed, FALSE otherwise
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Check if the default handler is installed for the requested
|
|
||||||
* space ID.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static u8
|
|
||||||
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
|
|
||||||
acpi_adr_space_type space_id)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *obj_desc;
|
|
||||||
union acpi_operand_object *handler_obj;
|
|
||||||
|
|
||||||
/* Must have an existing internal object */
|
|
||||||
|
|
||||||
obj_desc = acpi_ns_get_attached_object(node);
|
|
||||||
if (obj_desc) {
|
|
||||||
handler_obj = obj_desc->device.handler;
|
|
||||||
|
|
||||||
/* Walk the linked list of handlers for this object */
|
|
||||||
|
|
||||||
while (handler_obj) {
|
|
||||||
if (handler_obj->address_space.space_id == space_id) {
|
|
||||||
if (handler_obj->address_space.handler_flags &
|
|
||||||
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handler_obj = handler_obj->address_space.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ev_initialize_op_regions
|
* FUNCTION: acpi_ev_initialize_op_regions
|
||||||
@ -239,91 +109,6 @@ acpi_status acpi_ev_initialize_op_regions(void)
|
|||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ev_execute_reg_method
|
|
||||||
*
|
|
||||||
* PARAMETERS: region_obj - Region object
|
|
||||||
* function - Passed to _REG: On (1) or Off (0)
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Execute _REG method for a region
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status
|
|
||||||
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;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_execute_reg_method);
|
|
||||||
|
|
||||||
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) {
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate and initialize the evaluation information block */
|
|
||||||
|
|
||||||
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
|
|
||||||
if (!info) {
|
|
||||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
info->prefix_node = region_obj2->extra.method_REG;
|
|
||||||
info->pathname = NULL;
|
|
||||||
info->parameters = args;
|
|
||||||
info->flags = ACPI_IGNORE_RETURN_VALUE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The _REG method has two arguments:
|
|
||||||
*
|
|
||||||
* arg0 - Integer:
|
|
||||||
* Operation region space ID Same value as region_obj->Region.space_id
|
|
||||||
*
|
|
||||||
* arg1 - Integer:
|
|
||||||
* connection status 1 for connecting the handler, 0 for disconnecting
|
|
||||||
* the handler (Passed as a parameter)
|
|
||||||
*/
|
|
||||||
args[0] =
|
|
||||||
acpi_ut_create_integer_object((u64) region_obj->region.space_id);
|
|
||||||
if (!args[0]) {
|
|
||||||
status = AE_NO_MEMORY;
|
|
||||||
goto cleanup1;
|
|
||||||
}
|
|
||||||
|
|
||||||
args[1] = acpi_ut_create_integer_object((u64) function);
|
|
||||||
if (!args[1]) {
|
|
||||||
status = AE_NO_MEMORY;
|
|
||||||
goto cleanup2;
|
|
||||||
}
|
|
||||||
|
|
||||||
args[2] = NULL; /* Terminate list */
|
|
||||||
|
|
||||||
/* Execute the method, no return value */
|
|
||||||
|
|
||||||
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
|
|
||||||
(ACPI_TYPE_METHOD, info->prefix_node, NULL));
|
|
||||||
|
|
||||||
status = acpi_ns_evaluate(info);
|
|
||||||
acpi_ut_remove_reference(args[1]);
|
|
||||||
|
|
||||||
cleanup2:
|
|
||||||
acpi_ut_remove_reference(args[0]);
|
|
||||||
|
|
||||||
cleanup1:
|
|
||||||
ACPI_FREE(info);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ev_address_space_dispatch
|
* FUNCTION: acpi_ev_address_space_dispatch
|
||||||
@ -709,351 +494,86 @@ acpi_ev_attach_region(union acpi_operand_object *handler_obj,
|
|||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ev_install_handler
|
* FUNCTION: acpi_ev_execute_reg_method
|
||||||
*
|
*
|
||||||
* PARAMETERS: walk_namespace callback
|
* PARAMETERS: region_obj - Region object
|
||||||
*
|
* function - Passed to _REG: On (1) or Off (0)
|
||||||
* DESCRIPTION: This routine installs an address handler into objects that are
|
|
||||||
* of type Region or Device.
|
|
||||||
*
|
|
||||||
* If the Object is a Device, and the device has a handler of
|
|
||||||
* the same type then the search is terminated in that branch.
|
|
||||||
*
|
|
||||||
* This is because the existing handler is closer in proximity
|
|
||||||
* to any more regions than the one we are trying to install.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ev_install_handler(acpi_handle obj_handle,
|
|
||||||
u32 level, void *context, void **return_value)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *handler_obj;
|
|
||||||
union acpi_operand_object *next_handler_obj;
|
|
||||||
union acpi_operand_object *obj_desc;
|
|
||||||
struct acpi_namespace_node *node;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_NAME(ev_install_handler);
|
|
||||||
|
|
||||||
handler_obj = (union acpi_operand_object *)context;
|
|
||||||
|
|
||||||
/* Parameter validation */
|
|
||||||
|
|
||||||
if (!handler_obj) {
|
|
||||||
return (AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert and validate the device handle */
|
|
||||||
|
|
||||||
node = acpi_ns_validate_handle(obj_handle);
|
|
||||||
if (!node) {
|
|
||||||
return (AE_BAD_PARAMETER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We only care about regions and objects that are allowed to have
|
|
||||||
* address space handlers
|
|
||||||
*/
|
|
||||||
if ((node->type != ACPI_TYPE_DEVICE) &&
|
|
||||||
(node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
|
|
||||||
return (AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for an existing internal object */
|
|
||||||
|
|
||||||
obj_desc = acpi_ns_get_attached_object(node);
|
|
||||||
if (!obj_desc) {
|
|
||||||
|
|
||||||
/* No object, just exit */
|
|
||||||
|
|
||||||
return (AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Devices are handled different than regions */
|
|
||||||
|
|
||||||
if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
|
|
||||||
|
|
||||||
/* Check if this Device already has a handler for this address space */
|
|
||||||
|
|
||||||
next_handler_obj = obj_desc->device.handler;
|
|
||||||
while (next_handler_obj) {
|
|
||||||
|
|
||||||
/* Found a handler, is it for the same address space? */
|
|
||||||
|
|
||||||
if (next_handler_obj->address_space.space_id ==
|
|
||||||
handler_obj->address_space.space_id) {
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
|
||||||
"Found handler for region [%s] in device %p(%p) "
|
|
||||||
"handler %p\n",
|
|
||||||
acpi_ut_get_region_name
|
|
||||||
(handler_obj->address_space.
|
|
||||||
space_id), obj_desc,
|
|
||||||
next_handler_obj,
|
|
||||||
handler_obj));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since the object we found it on was a device, then it
|
|
||||||
* means that someone has already installed a handler for
|
|
||||||
* the branch of the namespace from this device on. Just
|
|
||||||
* bail out telling the walk routine to not traverse this
|
|
||||||
* branch. This preserves the scoping rule for handlers.
|
|
||||||
*/
|
|
||||||
return (AE_CTRL_DEPTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk the linked list of handlers attached to this device */
|
|
||||||
|
|
||||||
next_handler_obj = next_handler_obj->address_space.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* As long as the device didn't have a handler for this space we
|
|
||||||
* don't care about it. We just ignore it and proceed.
|
|
||||||
*/
|
|
||||||
return (AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Object is a Region */
|
|
||||||
|
|
||||||
if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
|
|
||||||
|
|
||||||
/* This region is for a different address space, just ignore it */
|
|
||||||
|
|
||||||
return (AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now we have a region and it is for the handler's address space type.
|
|
||||||
*
|
|
||||||
* First disconnect region for any previous handler (if any)
|
|
||||||
*/
|
|
||||||
acpi_ev_detach_region(obj_desc, FALSE);
|
|
||||||
|
|
||||||
/* Connect the region to the new handler */
|
|
||||||
|
|
||||||
status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ev_install_space_handler
|
|
||||||
*
|
|
||||||
* PARAMETERS: node - Namespace node for the device
|
|
||||||
* space_id - The address space ID
|
|
||||||
* handler - Address of the handler
|
|
||||||
* setup - Address of the setup function
|
|
||||||
* context - Value passed to the handler on each access
|
|
||||||
*
|
*
|
||||||
* RETURN: Status
|
* RETURN: Status
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Install a handler for all op_regions of a given space_id.
|
* DESCRIPTION: Execute _REG method for a region
|
||||||
* Assumes namespace is locked
|
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ev_install_space_handler(struct acpi_namespace_node * node,
|
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
|
||||||
acpi_adr_space_type space_id,
|
|
||||||
acpi_adr_space_handler handler,
|
|
||||||
acpi_adr_space_setup setup, void *context)
|
|
||||||
{
|
{
|
||||||
union acpi_operand_object *obj_desc;
|
struct acpi_evaluate_info *info;
|
||||||
union acpi_operand_object *handler_obj;
|
union acpi_operand_object *args[3];
|
||||||
|
union acpi_operand_object *region_obj2;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
acpi_object_type type;
|
|
||||||
u8 flags = 0;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_install_space_handler);
|
ACPI_FUNCTION_TRACE(ev_execute_reg_method);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate and initialize the evaluation information block */
|
||||||
|
|
||||||
|
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
|
||||||
|
if (!info) {
|
||||||
|
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
info->prefix_node = region_obj2->extra.method_REG;
|
||||||
|
info->pathname = NULL;
|
||||||
|
info->parameters = args;
|
||||||
|
info->flags = ACPI_IGNORE_RETURN_VALUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This registration is valid for only the types below and the root. This
|
* The _REG method has two arguments:
|
||||||
* is where the default handlers get placed.
|
|
||||||
*/
|
|
||||||
if ((node->type != ACPI_TYPE_DEVICE) &&
|
|
||||||
(node->type != ACPI_TYPE_PROCESSOR) &&
|
|
||||||
(node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
|
|
||||||
status = AE_BAD_PARAMETER;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler == ACPI_DEFAULT_HANDLER) {
|
|
||||||
flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
|
|
||||||
|
|
||||||
switch (space_id) {
|
|
||||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
|
||||||
handler = acpi_ex_system_memory_space_handler;
|
|
||||||
setup = acpi_ev_system_memory_region_setup;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
|
||||||
handler = acpi_ex_system_io_space_handler;
|
|
||||||
setup = acpi_ev_io_space_region_setup;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_ADR_SPACE_PCI_CONFIG:
|
|
||||||
handler = acpi_ex_pci_config_space_handler;
|
|
||||||
setup = acpi_ev_pci_config_region_setup;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_ADR_SPACE_CMOS:
|
|
||||||
handler = acpi_ex_cmos_space_handler;
|
|
||||||
setup = acpi_ev_cmos_region_setup;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_ADR_SPACE_PCI_BAR_TARGET:
|
|
||||||
handler = acpi_ex_pci_bar_space_handler;
|
|
||||||
setup = acpi_ev_pci_bar_region_setup;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_ADR_SPACE_DATA_TABLE:
|
|
||||||
handler = acpi_ex_data_table_space_handler;
|
|
||||||
setup = NULL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
status = AE_BAD_PARAMETER;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the caller hasn't specified a setup routine, use the default */
|
|
||||||
|
|
||||||
if (!setup) {
|
|
||||||
setup = acpi_ev_default_region_setup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for an existing internal object */
|
|
||||||
|
|
||||||
obj_desc = acpi_ns_get_attached_object(node);
|
|
||||||
if (obj_desc) {
|
|
||||||
/*
|
|
||||||
* The attached device object already exists. Make sure the handler
|
|
||||||
* is not already installed.
|
|
||||||
*/
|
|
||||||
handler_obj = obj_desc->device.handler;
|
|
||||||
|
|
||||||
/* Walk the handler list for this device */
|
|
||||||
|
|
||||||
while (handler_obj) {
|
|
||||||
|
|
||||||
/* Same space_id indicates a handler already installed */
|
|
||||||
|
|
||||||
if (handler_obj->address_space.space_id == space_id) {
|
|
||||||
if (handler_obj->address_space.handler ==
|
|
||||||
handler) {
|
|
||||||
/*
|
|
||||||
* It is (relatively) OK to attempt to install the SAME
|
|
||||||
* handler twice. This can easily happen with the
|
|
||||||
* PCI_Config space.
|
|
||||||
*/
|
|
||||||
status = AE_SAME_HANDLER;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
} else {
|
|
||||||
/* A handler is already installed */
|
|
||||||
|
|
||||||
status = AE_ALREADY_EXISTS;
|
|
||||||
}
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk the linked list of handlers */
|
|
||||||
|
|
||||||
handler_obj = handler_obj->address_space.next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
|
||||||
"Creating object on Device %p while installing handler\n",
|
|
||||||
node));
|
|
||||||
|
|
||||||
/* obj_desc does not exist, create one */
|
|
||||||
|
|
||||||
if (node->type == ACPI_TYPE_ANY) {
|
|
||||||
type = ACPI_TYPE_DEVICE;
|
|
||||||
} else {
|
|
||||||
type = node->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj_desc = acpi_ut_create_internal_object(type);
|
|
||||||
if (!obj_desc) {
|
|
||||||
status = AE_NO_MEMORY;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init new descriptor */
|
|
||||||
|
|
||||||
obj_desc->common.type = (u8) type;
|
|
||||||
|
|
||||||
/* Attach the new object to the Node */
|
|
||||||
|
|
||||||
status = acpi_ns_attach_object(node, obj_desc, type);
|
|
||||||
|
|
||||||
/* Remove local reference to the object */
|
|
||||||
|
|
||||||
acpi_ut_remove_reference(obj_desc);
|
|
||||||
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
|
||||||
"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
|
|
||||||
acpi_ut_get_region_name(space_id), space_id,
|
|
||||||
acpi_ut_get_node_name(node), node, obj_desc));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install the handler
|
|
||||||
*
|
*
|
||||||
* At this point there is no existing handler. Just allocate the object
|
* arg0 - Integer:
|
||||||
* for the handler and link it into the list.
|
* Operation region space ID Same value as region_obj->Region.space_id
|
||||||
|
*
|
||||||
|
* arg1 - Integer:
|
||||||
|
* connection status 1 for connecting the handler, 0 for disconnecting
|
||||||
|
* the handler (Passed as a parameter)
|
||||||
*/
|
*/
|
||||||
handler_obj =
|
args[0] =
|
||||||
acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
|
acpi_ut_create_integer_object((u64)region_obj->region.space_id);
|
||||||
if (!handler_obj) {
|
if (!args[0]) {
|
||||||
status = AE_NO_MEMORY;
|
status = AE_NO_MEMORY;
|
||||||
goto unlock_and_exit;
|
goto cleanup1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init handler obj */
|
args[1] = acpi_ut_create_integer_object((u64)function);
|
||||||
|
if (!args[1]) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto cleanup2;
|
||||||
|
}
|
||||||
|
|
||||||
handler_obj->address_space.space_id = (u8) space_id;
|
args[2] = NULL; /* Terminate list */
|
||||||
handler_obj->address_space.handler_flags = flags;
|
|
||||||
handler_obj->address_space.region_list = NULL;
|
|
||||||
handler_obj->address_space.node = node;
|
|
||||||
handler_obj->address_space.handler = handler;
|
|
||||||
handler_obj->address_space.context = context;
|
|
||||||
handler_obj->address_space.setup = setup;
|
|
||||||
|
|
||||||
/* Install at head of Device.address_space list */
|
/* Execute the method, no return value */
|
||||||
|
|
||||||
handler_obj->address_space.next = obj_desc->device.handler;
|
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
|
||||||
|
(ACPI_TYPE_METHOD, info->prefix_node, NULL));
|
||||||
|
|
||||||
/*
|
status = acpi_ns_evaluate(info);
|
||||||
* The Device object is the first reference on the handler_obj.
|
acpi_ut_remove_reference(args[1]);
|
||||||
* Each region that uses the handler adds a reference.
|
|
||||||
*/
|
|
||||||
obj_desc->device.handler = handler_obj;
|
|
||||||
|
|
||||||
/*
|
cleanup2:
|
||||||
* Walk the namespace finding all of the regions this
|
acpi_ut_remove_reference(args[0]);
|
||||||
* handler will manage.
|
|
||||||
*
|
|
||||||
* Start at the device and search the branch toward
|
|
||||||
* the leaf nodes until either the leaf is encountered or
|
|
||||||
* a device is detected that has an address handler of the
|
|
||||||
* same type.
|
|
||||||
*
|
|
||||||
* In either case, back up and search down the remainder
|
|
||||||
* of the branch
|
|
||||||
*/
|
|
||||||
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
|
|
||||||
ACPI_NS_WALK_UNLOCK,
|
|
||||||
acpi_ev_install_handler, NULL,
|
|
||||||
handler_obj, NULL);
|
|
||||||
|
|
||||||
unlock_and_exit:
|
cleanup1:
|
||||||
|
ACPI_FREE(info);
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,27 +72,6 @@ ACPI_MODULE_NAME("nspredef")
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/* Local prototypes */
|
/* Local prototypes */
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_package(struct acpi_predefined_data *data,
|
|
||||||
union acpi_operand_object **return_object_ptr);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_package_list(struct acpi_predefined_data *data,
|
|
||||||
const union acpi_predefined_info *package,
|
|
||||||
union acpi_operand_object **elements, u32 count);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_package_elements(struct acpi_predefined_data *data,
|
|
||||||
union acpi_operand_object **elements,
|
|
||||||
u8 type1,
|
|
||||||
u32 count1,
|
|
||||||
u8 type2, u32 count2, u32 start_index);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_object_type(struct acpi_predefined_data *data,
|
|
||||||
union acpi_operand_object **return_object_ptr,
|
|
||||||
u32 expected_btypes, u32 package_index);
|
|
||||||
|
|
||||||
static acpi_status
|
static acpi_status
|
||||||
acpi_ns_check_reference(struct acpi_predefined_data *data,
|
acpi_ns_check_reference(struct acpi_predefined_data *data,
|
||||||
union acpi_operand_object *return_object);
|
union acpi_operand_object *return_object);
|
||||||
@ -405,564 +384,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
|
|||||||
return (NULL); /* Not found */
|
return (NULL); /* Not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ns_check_package
|
|
||||||
*
|
|
||||||
* PARAMETERS: data - Pointer to validation data structure
|
|
||||||
* return_object_ptr - Pointer to the object returned from the
|
|
||||||
* evaluation of a method or object
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Check a returned package object for the correct count and
|
|
||||||
* correct type of all sub-objects.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_package(struct acpi_predefined_data *data,
|
|
||||||
union acpi_operand_object **return_object_ptr)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *return_object = *return_object_ptr;
|
|
||||||
const union acpi_predefined_info *package;
|
|
||||||
union acpi_operand_object **elements;
|
|
||||||
acpi_status status = AE_OK;
|
|
||||||
u32 expected_count;
|
|
||||||
u32 count;
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_NAME(ns_check_package);
|
|
||||||
|
|
||||||
/* The package info for this name is in the next table entry */
|
|
||||||
|
|
||||||
package = data->predefined + 1;
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
|
|
||||||
"%s Validating return Package of Type %X, Count %X\n",
|
|
||||||
data->pathname, package->ret_info.type,
|
|
||||||
return_object->package.count));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For variable-length Packages, we can safely remove all embedded
|
|
||||||
* and trailing NULL package elements
|
|
||||||
*/
|
|
||||||
acpi_ns_remove_null_elements(data, package->ret_info.type,
|
|
||||||
return_object);
|
|
||||||
|
|
||||||
/* Extract package count and elements array */
|
|
||||||
|
|
||||||
elements = return_object->package.elements;
|
|
||||||
count = return_object->package.count;
|
|
||||||
|
|
||||||
/* The package must have at least one element, else invalid */
|
|
||||||
|
|
||||||
if (!count) {
|
|
||||||
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
|
||||||
"Return Package has no elements (empty)"));
|
|
||||||
|
|
||||||
return (AE_AML_OPERAND_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decode the type of the expected package contents
|
|
||||||
*
|
|
||||||
* PTYPE1 packages contain no subpackages
|
|
||||||
* PTYPE2 packages contain sub-packages
|
|
||||||
*/
|
|
||||||
switch (package->ret_info.type) {
|
|
||||||
case ACPI_PTYPE1_FIXED:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The package count is fixed and there are no sub-packages
|
|
||||||
*
|
|
||||||
* If package is too small, exit.
|
|
||||||
* If package is larger than expected, issue warning but continue
|
|
||||||
*/
|
|
||||||
expected_count =
|
|
||||||
package->ret_info.count1 + package->ret_info.count2;
|
|
||||||
if (count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
} else if (count > expected_count) {
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
|
|
||||||
"%s: Return Package is larger than needed - "
|
|
||||||
"found %u, expected %u\n",
|
|
||||||
data->pathname, count,
|
|
||||||
expected_count));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Validate all elements of the returned package */
|
|
||||||
|
|
||||||
status = acpi_ns_check_package_elements(data, elements,
|
|
||||||
package->ret_info.
|
|
||||||
object_type1,
|
|
||||||
package->ret_info.
|
|
||||||
count1,
|
|
||||||
package->ret_info.
|
|
||||||
object_type2,
|
|
||||||
package->ret_info.
|
|
||||||
count2, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE1_VAR:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The package count is variable, there are no sub-packages, and all
|
|
||||||
* elements must be of the same type
|
|
||||||
*/
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
status = acpi_ns_check_object_type(data, elements,
|
|
||||||
package->ret_info.
|
|
||||||
object_type1, i);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
elements++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE1_OPTION:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The package count is variable, there are no sub-packages. There are
|
|
||||||
* a fixed number of required elements, and a variable number of
|
|
||||||
* optional elements.
|
|
||||||
*
|
|
||||||
* Check if package is at least as large as the minimum required
|
|
||||||
*/
|
|
||||||
expected_count = package->ret_info3.count;
|
|
||||||
if (count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Variable number of sub-objects */
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
if (i < package->ret_info3.count) {
|
|
||||||
|
|
||||||
/* These are the required package elements (0, 1, or 2) */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_object_type(data, elements,
|
|
||||||
package->
|
|
||||||
ret_info3.
|
|
||||||
object_type[i],
|
|
||||||
i);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* These are the optional package elements */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_object_type(data, elements,
|
|
||||||
package->
|
|
||||||
ret_info3.
|
|
||||||
tail_object_type,
|
|
||||||
i);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elements++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2_REV_FIXED:
|
|
||||||
|
|
||||||
/* First element is the (Integer) revision */
|
|
||||||
|
|
||||||
status = acpi_ns_check_object_type(data, elements,
|
|
||||||
ACPI_RTYPE_INTEGER, 0);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
elements++;
|
|
||||||
count--;
|
|
||||||
|
|
||||||
/* Examine the sub-packages */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_list(data, package, elements, count);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2_PKG_COUNT:
|
|
||||||
|
|
||||||
/* First element is the (Integer) count of sub-packages to follow */
|
|
||||||
|
|
||||||
status = acpi_ns_check_object_type(data, elements,
|
|
||||||
ACPI_RTYPE_INTEGER, 0);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Count cannot be larger than the parent package length, but allow it
|
|
||||||
* to be smaller. The >= accounts for the Integer above.
|
|
||||||
*/
|
|
||||||
expected_count = (u32) (*elements)->integer.value;
|
|
||||||
if (expected_count >= count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = expected_count;
|
|
||||||
elements++;
|
|
||||||
|
|
||||||
/* Examine the sub-packages */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_list(data, package, elements, count);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2:
|
|
||||||
case ACPI_PTYPE2_FIXED:
|
|
||||||
case ACPI_PTYPE2_MIN:
|
|
||||||
case ACPI_PTYPE2_COUNT:
|
|
||||||
case ACPI_PTYPE2_FIX_VAR:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These types all return a single Package that consists of a
|
|
||||||
* variable number of sub-Packages.
|
|
||||||
*
|
|
||||||
* First, ensure that the first element is a sub-Package. If not,
|
|
||||||
* the BIOS may have incorrectly returned the object as a single
|
|
||||||
* package instead of a Package of Packages (a common error if
|
|
||||||
* there is only one entry). We may be able to repair this by
|
|
||||||
* wrapping the returned Package with a new outer Package.
|
|
||||||
*/
|
|
||||||
if (*elements
|
|
||||||
&& ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
|
|
||||||
|
|
||||||
/* Create the new outer package and populate it */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_wrap_with_package(data, return_object,
|
|
||||||
return_object_ptr);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update locals to point to the new package (of 1 element) */
|
|
||||||
|
|
||||||
return_object = *return_object_ptr;
|
|
||||||
elements = return_object->package.elements;
|
|
||||||
count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Examine the sub-packages */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_list(data, package, elements, count);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
/* Should not get here if predefined info table is correct */
|
|
||||||
|
|
||||||
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
|
||||||
"Invalid internal return type in table entry: %X",
|
|
||||||
package->ret_info.type));
|
|
||||||
|
|
||||||
return (AE_AML_INTERNAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (status);
|
|
||||||
|
|
||||||
package_too_small:
|
|
||||||
|
|
||||||
/* Error exit for the case with an incorrect package count */
|
|
||||||
|
|
||||||
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
|
||||||
"Return Package is too small - found %u elements, expected %u",
|
|
||||||
count, expected_count));
|
|
||||||
|
|
||||||
return (AE_AML_OPERAND_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ns_check_package_list
|
|
||||||
*
|
|
||||||
* PARAMETERS: data - Pointer to validation data structure
|
|
||||||
* package - Pointer to package-specific info for method
|
|
||||||
* elements - Element list of parent package. All elements
|
|
||||||
* of this list should be of type Package.
|
|
||||||
* count - Count of subpackages
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Examine a list of subpackages
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_package_list(struct acpi_predefined_data *data,
|
|
||||||
const union acpi_predefined_info *package,
|
|
||||||
union acpi_operand_object **elements, u32 count)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *sub_package;
|
|
||||||
union acpi_operand_object **sub_elements;
|
|
||||||
acpi_status status;
|
|
||||||
u32 expected_count;
|
|
||||||
u32 i;
|
|
||||||
u32 j;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Validate each sub-Package in the parent Package
|
|
||||||
*
|
|
||||||
* NOTE: assumes list of sub-packages contains no NULL elements.
|
|
||||||
* Any NULL elements should have been removed by earlier call
|
|
||||||
* to acpi_ns_remove_null_elements.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
sub_package = *elements;
|
|
||||||
sub_elements = sub_package->package.elements;
|
|
||||||
data->parent_package = sub_package;
|
|
||||||
|
|
||||||
/* Each sub-object must be of type Package */
|
|
||||||
|
|
||||||
status = acpi_ns_check_object_type(data, &sub_package,
|
|
||||||
ACPI_RTYPE_PACKAGE, i);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Examine the different types of expected sub-packages */
|
|
||||||
|
|
||||||
data->parent_package = sub_package;
|
|
||||||
switch (package->ret_info.type) {
|
|
||||||
case ACPI_PTYPE2:
|
|
||||||
case ACPI_PTYPE2_PKG_COUNT:
|
|
||||||
case ACPI_PTYPE2_REV_FIXED:
|
|
||||||
|
|
||||||
/* Each subpackage has a fixed number of elements */
|
|
||||||
|
|
||||||
expected_count =
|
|
||||||
package->ret_info.count1 + package->ret_info.count2;
|
|
||||||
if (sub_package->package.count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_elements(data, sub_elements,
|
|
||||||
package->ret_info.
|
|
||||||
object_type1,
|
|
||||||
package->ret_info.
|
|
||||||
count1,
|
|
||||||
package->ret_info.
|
|
||||||
object_type2,
|
|
||||||
package->ret_info.
|
|
||||||
count2, 0);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2_FIX_VAR:
|
|
||||||
/*
|
|
||||||
* Each subpackage has a fixed number of elements and an
|
|
||||||
* optional element
|
|
||||||
*/
|
|
||||||
expected_count =
|
|
||||||
package->ret_info.count1 + package->ret_info.count2;
|
|
||||||
if (sub_package->package.count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_elements(data, sub_elements,
|
|
||||||
package->ret_info.
|
|
||||||
object_type1,
|
|
||||||
package->ret_info.
|
|
||||||
count1,
|
|
||||||
package->ret_info.
|
|
||||||
object_type2,
|
|
||||||
sub_package->package.
|
|
||||||
count -
|
|
||||||
package->ret_info.
|
|
||||||
count1, 0);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2_FIXED:
|
|
||||||
|
|
||||||
/* Each sub-package has a fixed length */
|
|
||||||
|
|
||||||
expected_count = package->ret_info2.count;
|
|
||||||
if (sub_package->package.count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the type of each sub-package element */
|
|
||||||
|
|
||||||
for (j = 0; j < expected_count; j++) {
|
|
||||||
status =
|
|
||||||
acpi_ns_check_object_type(data,
|
|
||||||
&sub_elements[j],
|
|
||||||
package->
|
|
||||||
ret_info2.
|
|
||||||
object_type[j],
|
|
||||||
j);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2_MIN:
|
|
||||||
|
|
||||||
/* Each sub-package has a variable but minimum length */
|
|
||||||
|
|
||||||
expected_count = package->ret_info.count1;
|
|
||||||
if (sub_package->package.count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the type of each sub-package element */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_elements(data, sub_elements,
|
|
||||||
package->ret_info.
|
|
||||||
object_type1,
|
|
||||||
sub_package->package.
|
|
||||||
count, 0, 0, 0);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACPI_PTYPE2_COUNT:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First element is the (Integer) count of elements, including
|
|
||||||
* the count field (the ACPI name is num_elements)
|
|
||||||
*/
|
|
||||||
status = acpi_ns_check_object_type(data, sub_elements,
|
|
||||||
ACPI_RTYPE_INTEGER,
|
|
||||||
0);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure package is large enough for the Count and is
|
|
||||||
* is as large as the minimum size
|
|
||||||
*/
|
|
||||||
expected_count = (u32)(*sub_elements)->integer.value;
|
|
||||||
if (sub_package->package.count < expected_count) {
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
if (sub_package->package.count <
|
|
||||||
package->ret_info.count1) {
|
|
||||||
expected_count = package->ret_info.count1;
|
|
||||||
goto package_too_small;
|
|
||||||
}
|
|
||||||
if (expected_count == 0) {
|
|
||||||
/*
|
|
||||||
* Either the num_entries element was originally zero or it was
|
|
||||||
* a NULL element and repaired to an Integer of value zero.
|
|
||||||
* In either case, repair it by setting num_entries to be the
|
|
||||||
* actual size of the subpackage.
|
|
||||||
*/
|
|
||||||
expected_count = sub_package->package.count;
|
|
||||||
(*sub_elements)->integer.value = expected_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the type of each sub-package element */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_check_package_elements(data,
|
|
||||||
(sub_elements + 1),
|
|
||||||
package->ret_info.
|
|
||||||
object_type1,
|
|
||||||
(expected_count - 1),
|
|
||||||
0, 0, 1);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* Should not get here, type was validated by caller */
|
|
||||||
|
|
||||||
return (AE_AML_INTERNAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
elements++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (AE_OK);
|
|
||||||
|
|
||||||
package_too_small:
|
|
||||||
|
|
||||||
/* The sub-package count was smaller than required */
|
|
||||||
|
|
||||||
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
|
||||||
"Return Sub-Package[%u] is too small - found %u elements, expected %u",
|
|
||||||
i, sub_package->package.count, expected_count));
|
|
||||||
|
|
||||||
return (AE_AML_OPERAND_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ns_check_package_elements
|
|
||||||
*
|
|
||||||
* PARAMETERS: data - Pointer to validation data structure
|
|
||||||
* elements - Pointer to the package elements array
|
|
||||||
* type1 - Object type for first group
|
|
||||||
* count1 - Count for first group
|
|
||||||
* type2 - Object type for second group
|
|
||||||
* count2 - Count for second group
|
|
||||||
* start_index - Start of the first group of elements
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Check that all elements of a package are of the correct object
|
|
||||||
* type. Supports up to two groups of different object types.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ns_check_package_elements(struct acpi_predefined_data *data,
|
|
||||||
union acpi_operand_object **elements,
|
|
||||||
u8 type1,
|
|
||||||
u32 count1,
|
|
||||||
u8 type2, u32 count2, u32 start_index)
|
|
||||||
{
|
|
||||||
union acpi_operand_object **this_element = elements;
|
|
||||||
acpi_status status;
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Up to two groups of package elements are supported by the data
|
|
||||||
* structure. All elements in each group must be of the same type.
|
|
||||||
* The second group can have a count of zero.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < count1; i++) {
|
|
||||||
status = acpi_ns_check_object_type(data, this_element,
|
|
||||||
type1, i + start_index);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
this_element++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count2; i++) {
|
|
||||||
status = acpi_ns_check_object_type(data, this_element,
|
|
||||||
type2,
|
|
||||||
(i + count1 + start_index));
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
this_element++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ns_check_object_type
|
* FUNCTION: acpi_ns_check_object_type
|
||||||
@ -982,7 +403,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data,
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static acpi_status
|
acpi_status
|
||||||
acpi_ns_check_object_type(struct acpi_predefined_data *data,
|
acpi_ns_check_object_type(struct acpi_predefined_data *data,
|
||||||
union acpi_operand_object **return_object_ptr,
|
union acpi_operand_object **return_object_ptr,
|
||||||
u32 expected_btypes, u32 package_index)
|
u32 expected_btypes, u32 package_index)
|
||||||
|
621
drivers/acpi/acpica/nsprepkg.c
Normal file
621
drivers/acpi/acpica/nsprepkg.c
Normal file
@ -0,0 +1,621 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: nsprepkg - Validation of package objects for predefined names
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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 "acpredef.h"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_NAMESPACE
|
||||||
|
ACPI_MODULE_NAME("nsprepkg")
|
||||||
|
|
||||||
|
/* Local prototypes */
|
||||||
|
static acpi_status
|
||||||
|
acpi_ns_check_package_list(struct acpi_predefined_data *data,
|
||||||
|
const union acpi_predefined_info *package,
|
||||||
|
union acpi_operand_object **elements, u32 count);
|
||||||
|
|
||||||
|
static acpi_status
|
||||||
|
acpi_ns_check_package_elements(struct acpi_predefined_data *data,
|
||||||
|
union acpi_operand_object **elements,
|
||||||
|
u8 type1,
|
||||||
|
u32 count1,
|
||||||
|
u8 type2, u32 count2, u32 start_index);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ns_check_package
|
||||||
|
*
|
||||||
|
* PARAMETERS: data - Pointer to validation data structure
|
||||||
|
* return_object_ptr - Pointer to the object returned from the
|
||||||
|
* evaluation of a method or object
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Check a returned package object for the correct count and
|
||||||
|
* correct type of all sub-objects.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ns_check_package(struct acpi_predefined_data *data,
|
||||||
|
union acpi_operand_object **return_object_ptr)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *return_object = *return_object_ptr;
|
||||||
|
const union acpi_predefined_info *package;
|
||||||
|
union acpi_operand_object **elements;
|
||||||
|
acpi_status status = AE_OK;
|
||||||
|
u32 expected_count;
|
||||||
|
u32 count;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_NAME(ns_check_package);
|
||||||
|
|
||||||
|
/* The package info for this name is in the next table entry */
|
||||||
|
|
||||||
|
package = data->predefined + 1;
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
|
||||||
|
"%s Validating return Package of Type %X, Count %X\n",
|
||||||
|
data->pathname, package->ret_info.type,
|
||||||
|
return_object->package.count));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For variable-length Packages, we can safely remove all embedded
|
||||||
|
* and trailing NULL package elements
|
||||||
|
*/
|
||||||
|
acpi_ns_remove_null_elements(data, package->ret_info.type,
|
||||||
|
return_object);
|
||||||
|
|
||||||
|
/* Extract package count and elements array */
|
||||||
|
|
||||||
|
elements = return_object->package.elements;
|
||||||
|
count = return_object->package.count;
|
||||||
|
|
||||||
|
/* The package must have at least one element, else invalid */
|
||||||
|
|
||||||
|
if (!count) {
|
||||||
|
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
||||||
|
"Return Package has no elements (empty)"));
|
||||||
|
|
||||||
|
return (AE_AML_OPERAND_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode the type of the expected package contents
|
||||||
|
*
|
||||||
|
* PTYPE1 packages contain no subpackages
|
||||||
|
* PTYPE2 packages contain sub-packages
|
||||||
|
*/
|
||||||
|
switch (package->ret_info.type) {
|
||||||
|
case ACPI_PTYPE1_FIXED:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The package count is fixed and there are no sub-packages
|
||||||
|
*
|
||||||
|
* If package is too small, exit.
|
||||||
|
* If package is larger than expected, issue warning but continue
|
||||||
|
*/
|
||||||
|
expected_count =
|
||||||
|
package->ret_info.count1 + package->ret_info.count2;
|
||||||
|
if (count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
} else if (count > expected_count) {
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
|
||||||
|
"%s: Return Package is larger than needed - "
|
||||||
|
"found %u, expected %u\n",
|
||||||
|
data->pathname, count,
|
||||||
|
expected_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate all elements of the returned package */
|
||||||
|
|
||||||
|
status = acpi_ns_check_package_elements(data, elements,
|
||||||
|
package->ret_info.
|
||||||
|
object_type1,
|
||||||
|
package->ret_info.
|
||||||
|
count1,
|
||||||
|
package->ret_info.
|
||||||
|
object_type2,
|
||||||
|
package->ret_info.
|
||||||
|
count2, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE1_VAR:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The package count is variable, there are no sub-packages, and all
|
||||||
|
* elements must be of the same type
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
status = acpi_ns_check_object_type(data, elements,
|
||||||
|
package->ret_info.
|
||||||
|
object_type1, i);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
elements++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE1_OPTION:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The package count is variable, there are no sub-packages. There are
|
||||||
|
* a fixed number of required elements, and a variable number of
|
||||||
|
* optional elements.
|
||||||
|
*
|
||||||
|
* Check if package is at least as large as the minimum required
|
||||||
|
*/
|
||||||
|
expected_count = package->ret_info3.count;
|
||||||
|
if (count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Variable number of sub-objects */
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (i < package->ret_info3.count) {
|
||||||
|
|
||||||
|
/* These are the required package elements (0, 1, or 2) */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_object_type(data, elements,
|
||||||
|
package->
|
||||||
|
ret_info3.
|
||||||
|
object_type[i],
|
||||||
|
i);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* These are the optional package elements */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_object_type(data, elements,
|
||||||
|
package->
|
||||||
|
ret_info3.
|
||||||
|
tail_object_type,
|
||||||
|
i);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elements++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2_REV_FIXED:
|
||||||
|
|
||||||
|
/* First element is the (Integer) revision */
|
||||||
|
|
||||||
|
status = acpi_ns_check_object_type(data, elements,
|
||||||
|
ACPI_RTYPE_INTEGER, 0);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
elements++;
|
||||||
|
count--;
|
||||||
|
|
||||||
|
/* Examine the sub-packages */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_list(data, package, elements, count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2_PKG_COUNT:
|
||||||
|
|
||||||
|
/* First element is the (Integer) count of sub-packages to follow */
|
||||||
|
|
||||||
|
status = acpi_ns_check_object_type(data, elements,
|
||||||
|
ACPI_RTYPE_INTEGER, 0);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count cannot be larger than the parent package length, but allow it
|
||||||
|
* to be smaller. The >= accounts for the Integer above.
|
||||||
|
*/
|
||||||
|
expected_count = (u32)(*elements)->integer.value;
|
||||||
|
if (expected_count >= count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = expected_count;
|
||||||
|
elements++;
|
||||||
|
|
||||||
|
/* Examine the sub-packages */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_list(data, package, elements, count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2:
|
||||||
|
case ACPI_PTYPE2_FIXED:
|
||||||
|
case ACPI_PTYPE2_MIN:
|
||||||
|
case ACPI_PTYPE2_COUNT:
|
||||||
|
case ACPI_PTYPE2_FIX_VAR:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These types all return a single Package that consists of a
|
||||||
|
* variable number of sub-Packages.
|
||||||
|
*
|
||||||
|
* First, ensure that the first element is a sub-Package. If not,
|
||||||
|
* the BIOS may have incorrectly returned the object as a single
|
||||||
|
* package instead of a Package of Packages (a common error if
|
||||||
|
* there is only one entry). We may be able to repair this by
|
||||||
|
* wrapping the returned Package with a new outer Package.
|
||||||
|
*/
|
||||||
|
if (*elements
|
||||||
|
&& ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
|
||||||
|
|
||||||
|
/* Create the new outer package and populate it */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_wrap_with_package(data, return_object,
|
||||||
|
return_object_ptr);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update locals to point to the new package (of 1 element) */
|
||||||
|
|
||||||
|
return_object = *return_object_ptr;
|
||||||
|
elements = return_object->package.elements;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Examine the sub-packages */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_list(data, package, elements, count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
/* Should not get here if predefined info table is correct */
|
||||||
|
|
||||||
|
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
||||||
|
"Invalid internal return type in table entry: %X",
|
||||||
|
package->ret_info.type));
|
||||||
|
|
||||||
|
return (AE_AML_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
package_too_small:
|
||||||
|
|
||||||
|
/* Error exit for the case with an incorrect package count */
|
||||||
|
|
||||||
|
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
||||||
|
"Return Package is too small - found %u elements, expected %u",
|
||||||
|
count, expected_count));
|
||||||
|
|
||||||
|
return (AE_AML_OPERAND_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ns_check_package_list
|
||||||
|
*
|
||||||
|
* PARAMETERS: data - Pointer to validation data structure
|
||||||
|
* package - Pointer to package-specific info for method
|
||||||
|
* elements - Element list of parent package. All elements
|
||||||
|
* of this list should be of type Package.
|
||||||
|
* count - Count of subpackages
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Examine a list of subpackages
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static acpi_status
|
||||||
|
acpi_ns_check_package_list(struct acpi_predefined_data *data,
|
||||||
|
const union acpi_predefined_info *package,
|
||||||
|
union acpi_operand_object **elements, u32 count)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *sub_package;
|
||||||
|
union acpi_operand_object **sub_elements;
|
||||||
|
acpi_status status;
|
||||||
|
u32 expected_count;
|
||||||
|
u32 i;
|
||||||
|
u32 j;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate each sub-Package in the parent Package
|
||||||
|
*
|
||||||
|
* NOTE: assumes list of sub-packages contains no NULL elements.
|
||||||
|
* Any NULL elements should have been removed by earlier call
|
||||||
|
* to acpi_ns_remove_null_elements.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
sub_package = *elements;
|
||||||
|
sub_elements = sub_package->package.elements;
|
||||||
|
data->parent_package = sub_package;
|
||||||
|
|
||||||
|
/* Each sub-object must be of type Package */
|
||||||
|
|
||||||
|
status = acpi_ns_check_object_type(data, &sub_package,
|
||||||
|
ACPI_RTYPE_PACKAGE, i);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Examine the different types of expected sub-packages */
|
||||||
|
|
||||||
|
data->parent_package = sub_package;
|
||||||
|
switch (package->ret_info.type) {
|
||||||
|
case ACPI_PTYPE2:
|
||||||
|
case ACPI_PTYPE2_PKG_COUNT:
|
||||||
|
case ACPI_PTYPE2_REV_FIXED:
|
||||||
|
|
||||||
|
/* Each subpackage has a fixed number of elements */
|
||||||
|
|
||||||
|
expected_count =
|
||||||
|
package->ret_info.count1 + package->ret_info.count2;
|
||||||
|
if (sub_package->package.count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_elements(data, sub_elements,
|
||||||
|
package->ret_info.
|
||||||
|
object_type1,
|
||||||
|
package->ret_info.
|
||||||
|
count1,
|
||||||
|
package->ret_info.
|
||||||
|
object_type2,
|
||||||
|
package->ret_info.
|
||||||
|
count2, 0);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2_FIX_VAR:
|
||||||
|
/*
|
||||||
|
* Each subpackage has a fixed number of elements and an
|
||||||
|
* optional element
|
||||||
|
*/
|
||||||
|
expected_count =
|
||||||
|
package->ret_info.count1 + package->ret_info.count2;
|
||||||
|
if (sub_package->package.count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_elements(data, sub_elements,
|
||||||
|
package->ret_info.
|
||||||
|
object_type1,
|
||||||
|
package->ret_info.
|
||||||
|
count1,
|
||||||
|
package->ret_info.
|
||||||
|
object_type2,
|
||||||
|
sub_package->package.
|
||||||
|
count -
|
||||||
|
package->ret_info.
|
||||||
|
count1, 0);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2_FIXED:
|
||||||
|
|
||||||
|
/* Each sub-package has a fixed length */
|
||||||
|
|
||||||
|
expected_count = package->ret_info2.count;
|
||||||
|
if (sub_package->package.count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the type of each sub-package element */
|
||||||
|
|
||||||
|
for (j = 0; j < expected_count; j++) {
|
||||||
|
status =
|
||||||
|
acpi_ns_check_object_type(data,
|
||||||
|
&sub_elements[j],
|
||||||
|
package->
|
||||||
|
ret_info2.
|
||||||
|
object_type[j],
|
||||||
|
j);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2_MIN:
|
||||||
|
|
||||||
|
/* Each sub-package has a variable but minimum length */
|
||||||
|
|
||||||
|
expected_count = package->ret_info.count1;
|
||||||
|
if (sub_package->package.count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the type of each sub-package element */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_elements(data, sub_elements,
|
||||||
|
package->ret_info.
|
||||||
|
object_type1,
|
||||||
|
sub_package->package.
|
||||||
|
count, 0, 0, 0);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_PTYPE2_COUNT:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First element is the (Integer) count of elements, including
|
||||||
|
* the count field (the ACPI name is num_elements)
|
||||||
|
*/
|
||||||
|
status = acpi_ns_check_object_type(data, sub_elements,
|
||||||
|
ACPI_RTYPE_INTEGER,
|
||||||
|
0);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure package is large enough for the Count and is
|
||||||
|
* is as large as the minimum size
|
||||||
|
*/
|
||||||
|
expected_count = (u32)(*sub_elements)->integer.value;
|
||||||
|
if (sub_package->package.count < expected_count) {
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
if (sub_package->package.count <
|
||||||
|
package->ret_info.count1) {
|
||||||
|
expected_count = package->ret_info.count1;
|
||||||
|
goto package_too_small;
|
||||||
|
}
|
||||||
|
if (expected_count == 0) {
|
||||||
|
/*
|
||||||
|
* Either the num_entries element was originally zero or it was
|
||||||
|
* a NULL element and repaired to an Integer of value zero.
|
||||||
|
* In either case, repair it by setting num_entries to be the
|
||||||
|
* actual size of the subpackage.
|
||||||
|
*/
|
||||||
|
expected_count = sub_package->package.count;
|
||||||
|
(*sub_elements)->integer.value = expected_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the type of each sub-package element */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ns_check_package_elements(data,
|
||||||
|
(sub_elements + 1),
|
||||||
|
package->ret_info.
|
||||||
|
object_type1,
|
||||||
|
(expected_count - 1),
|
||||||
|
0, 0, 1);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* Should not get here, type was validated by caller */
|
||||||
|
|
||||||
|
return (AE_AML_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
elements++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (AE_OK);
|
||||||
|
|
||||||
|
package_too_small:
|
||||||
|
|
||||||
|
/* The sub-package count was smaller than required */
|
||||||
|
|
||||||
|
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
||||||
|
"Return Sub-Package[%u] is too small - found %u elements, expected %u",
|
||||||
|
i, sub_package->package.count, expected_count));
|
||||||
|
|
||||||
|
return (AE_AML_OPERAND_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ns_check_package_elements
|
||||||
|
*
|
||||||
|
* PARAMETERS: data - Pointer to validation data structure
|
||||||
|
* elements - Pointer to the package elements array
|
||||||
|
* type1 - Object type for first group
|
||||||
|
* count1 - Count for first group
|
||||||
|
* type2 - Object type for second group
|
||||||
|
* count2 - Count for second group
|
||||||
|
* start_index - Start of the first group of elements
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Check that all elements of a package are of the correct object
|
||||||
|
* type. Supports up to two groups of different object types.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static acpi_status
|
||||||
|
acpi_ns_check_package_elements(struct acpi_predefined_data *data,
|
||||||
|
union acpi_operand_object **elements,
|
||||||
|
u8 type1,
|
||||||
|
u32 count1,
|
||||||
|
u8 type2, u32 count2, u32 start_index)
|
||||||
|
{
|
||||||
|
union acpi_operand_object **this_element = elements;
|
||||||
|
acpi_status status;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Up to two groups of package elements are supported by the data
|
||||||
|
* structure. All elements in each group must be of the same type.
|
||||||
|
* The second group can have a count of zero.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count1; i++) {
|
||||||
|
status = acpi_ns_check_object_type(data, this_element,
|
||||||
|
type1, i + start_index);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
this_element++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count2; i++) {
|
||||||
|
status = acpi_ns_check_object_type(data, this_element,
|
||||||
|
type2,
|
||||||
|
(i + count1 + start_index));
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
this_element++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
@ -58,351 +58,15 @@
|
|||||||
#define _COMPONENT ACPI_PARSER
|
#define _COMPONENT ACPI_PARSER
|
||||||
ACPI_MODULE_NAME("psloop")
|
ACPI_MODULE_NAME("psloop")
|
||||||
|
|
||||||
static u32 acpi_gbl_depth = 0;
|
|
||||||
|
|
||||||
/* Local prototypes */
|
/* Local prototypes */
|
||||||
|
|
||||||
static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
|
|
||||||
u8 * aml_op_start,
|
|
||||||
union acpi_parse_object *unnamed_op,
|
|
||||||
union acpi_parse_object **op);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_create_op(struct acpi_walk_state *walk_state,
|
|
||||||
u8 * aml_op_start, union acpi_parse_object **new_op);
|
|
||||||
|
|
||||||
static acpi_status
|
static acpi_status
|
||||||
acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
|
acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
|
||||||
u8 * aml_op_start, union acpi_parse_object *op);
|
u8 * aml_op_start, union acpi_parse_object *op);
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_complete_op(struct acpi_walk_state *walk_state,
|
|
||||||
union acpi_parse_object **op, acpi_status status);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
|
||||||
union acpi_parse_object *op, acpi_status status);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_ps_link_module_code(union acpi_parse_object *parent_op,
|
acpi_ps_link_module_code(union acpi_parse_object *parent_op,
|
||||||
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
|
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_get_aml_opcode
|
|
||||||
*
|
|
||||||
* PARAMETERS: walk_state - Current state
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Extract the next AML opcode from the input stream.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
|
|
||||||
{
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
|
|
||||||
|
|
||||||
walk_state->aml_offset =
|
|
||||||
(u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
|
|
||||||
walk_state->parser_state.aml_start);
|
|
||||||
walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First cut to determine what we have found:
|
|
||||||
* 1) A valid AML opcode
|
|
||||||
* 2) A name string
|
|
||||||
* 3) An unknown/invalid opcode
|
|
||||||
*/
|
|
||||||
walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
|
|
||||||
|
|
||||||
switch (walk_state->op_info->class) {
|
|
||||||
case AML_CLASS_ASCII:
|
|
||||||
case AML_CLASS_PREFIX:
|
|
||||||
/*
|
|
||||||
* Starts with a valid prefix or ASCII char, this is a name
|
|
||||||
* string. Convert the bare name string to a namepath.
|
|
||||||
*/
|
|
||||||
walk_state->opcode = AML_INT_NAMEPATH_OP;
|
|
||||||
walk_state->arg_types = ARGP_NAMESTRING;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AML_CLASS_UNKNOWN:
|
|
||||||
|
|
||||||
/* The opcode is unrecognized. Complain and skip unknown opcodes */
|
|
||||||
|
|
||||||
if (walk_state->pass_number == 2) {
|
|
||||||
ACPI_ERROR((AE_INFO,
|
|
||||||
"Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
|
|
||||||
walk_state->opcode,
|
|
||||||
(u32)(walk_state->aml_offset +
|
|
||||||
sizeof(struct acpi_table_header))));
|
|
||||||
|
|
||||||
ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
|
|
||||||
48);
|
|
||||||
|
|
||||||
#ifdef ACPI_ASL_COMPILER
|
|
||||||
/*
|
|
||||||
* This is executed for the disassembler only. Output goes
|
|
||||||
* to the disassembled ASL output file.
|
|
||||||
*/
|
|
||||||
acpi_os_printf
|
|
||||||
("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
|
|
||||||
walk_state->opcode,
|
|
||||||
(u32)(walk_state->aml_offset +
|
|
||||||
sizeof(struct acpi_table_header)));
|
|
||||||
|
|
||||||
/* Dump the context surrounding the invalid opcode */
|
|
||||||
|
|
||||||
acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
|
|
||||||
aml - 16), 48, DB_BYTE_DISPLAY,
|
|
||||||
(walk_state->aml_offset +
|
|
||||||
sizeof(struct acpi_table_header) -
|
|
||||||
16));
|
|
||||||
acpi_os_printf(" */\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment past one-byte or two-byte opcode */
|
|
||||||
|
|
||||||
walk_state->parser_state.aml++;
|
|
||||||
if (walk_state->opcode > 0xFF) { /* Can only happen if first byte is 0x5B */
|
|
||||||
walk_state->parser_state.aml++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
/* Found opcode info, this is a normal opcode */
|
|
||||||
|
|
||||||
walk_state->parser_state.aml +=
|
|
||||||
acpi_ps_get_opcode_size(walk_state->opcode);
|
|
||||||
walk_state->arg_types = walk_state->op_info->parse_args;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_build_named_op
|
|
||||||
*
|
|
||||||
* PARAMETERS: walk_state - Current state
|
|
||||||
* aml_op_start - Begin of named Op in AML
|
|
||||||
* unnamed_op - Early Op (not a named Op)
|
|
||||||
* op - Returned Op
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Parse a named Op
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
|
|
||||||
u8 * aml_op_start,
|
|
||||||
union acpi_parse_object *unnamed_op,
|
|
||||||
union acpi_parse_object **op)
|
|
||||||
{
|
|
||||||
acpi_status status = AE_OK;
|
|
||||||
union acpi_parse_object *arg = NULL;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
|
|
||||||
|
|
||||||
unnamed_op->common.value.arg = NULL;
|
|
||||||
unnamed_op->common.arg_list_length = 0;
|
|
||||||
unnamed_op->common.aml_opcode = walk_state->opcode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get and append arguments until we find the node that contains
|
|
||||||
* the name (the type ARGP_NAME).
|
|
||||||
*/
|
|
||||||
while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
|
|
||||||
(GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
|
|
||||||
status =
|
|
||||||
acpi_ps_get_next_arg(walk_state,
|
|
||||||
&(walk_state->parser_state),
|
|
||||||
GET_CURRENT_ARG_TYPE(walk_state->
|
|
||||||
arg_types), &arg);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ps_append_arg(unnamed_op, arg);
|
|
||||||
INCREMENT_ARG_LIST(walk_state->arg_types);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure that we found a NAME and didn't run out of arguments
|
|
||||||
*/
|
|
||||||
if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
|
|
||||||
return_ACPI_STATUS(AE_AML_NO_OPERAND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We know that this arg is a name, move to next arg */
|
|
||||||
|
|
||||||
INCREMENT_ARG_LIST(walk_state->arg_types);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the object. This will either insert the object into
|
|
||||||
* the namespace or simply look it up
|
|
||||||
*/
|
|
||||||
walk_state->op = NULL;
|
|
||||||
|
|
||||||
status = walk_state->descending_callback(walk_state, op);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*op) {
|
|
||||||
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = acpi_ps_next_parse_state(walk_state, *op, status);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
if (status == AE_CTRL_PENDING) {
|
|
||||||
return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
|
|
||||||
}
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
|
|
||||||
acpi_gbl_depth++;
|
|
||||||
|
|
||||||
if ((*op)->common.aml_opcode == AML_REGION_OP ||
|
|
||||||
(*op)->common.aml_opcode == AML_DATA_REGION_OP) {
|
|
||||||
/*
|
|
||||||
* Defer final parsing of an operation_region body, because we don't
|
|
||||||
* have enough info in the first pass to parse it correctly (i.e.,
|
|
||||||
* there may be method calls within the term_arg elements of the body.)
|
|
||||||
*
|
|
||||||
* However, we must continue parsing because the opregion is not a
|
|
||||||
* standalone package -- we don't know where the end is at this point.
|
|
||||||
*
|
|
||||||
* (Length is unknown until parse of the body complete)
|
|
||||||
*/
|
|
||||||
(*op)->named.data = aml_op_start;
|
|
||||||
(*op)->named.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_create_op
|
|
||||||
*
|
|
||||||
* PARAMETERS: walk_state - Current state
|
|
||||||
* aml_op_start - Op start in AML
|
|
||||||
* new_op - Returned Op
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Get Op from AML
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_create_op(struct acpi_walk_state *walk_state,
|
|
||||||
u8 * aml_op_start, union acpi_parse_object **new_op)
|
|
||||||
{
|
|
||||||
acpi_status status = AE_OK;
|
|
||||||
union acpi_parse_object *op;
|
|
||||||
union acpi_parse_object *named_op = NULL;
|
|
||||||
union acpi_parse_object *parent_scope;
|
|
||||||
u8 argument_count;
|
|
||||||
const struct acpi_opcode_info *op_info;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
|
|
||||||
|
|
||||||
status = acpi_ps_get_aml_opcode(walk_state);
|
|
||||||
if (status == AE_CTRL_PARSE_CONTINUE) {
|
|
||||||
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create Op structure and append to parent's argument list */
|
|
||||||
|
|
||||||
walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
|
|
||||||
op = acpi_ps_alloc_op(walk_state->opcode);
|
|
||||||
if (!op) {
|
|
||||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walk_state->op_info->flags & AML_NAMED) {
|
|
||||||
status =
|
|
||||||
acpi_ps_build_named_op(walk_state, aml_op_start, op,
|
|
||||||
&named_op);
|
|
||||||
acpi_ps_free_op(op);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
*new_op = named_op;
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not a named opcode, just allocate Op and append to parent */
|
|
||||||
|
|
||||||
if (walk_state->op_info->flags & AML_CREATE) {
|
|
||||||
/*
|
|
||||||
* Backup to beginning of create_XXXfield declaration
|
|
||||||
* body_length is unknown until we parse the body
|
|
||||||
*/
|
|
||||||
op->named.data = aml_op_start;
|
|
||||||
op->named.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walk_state->opcode == AML_BANK_FIELD_OP) {
|
|
||||||
/*
|
|
||||||
* Backup to beginning of bank_field declaration
|
|
||||||
* body_length is unknown until we parse the body
|
|
||||||
*/
|
|
||||||
op->named.data = aml_op_start;
|
|
||||||
op->named.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
|
|
||||||
acpi_ps_append_arg(parent_scope, op);
|
|
||||||
|
|
||||||
if (parent_scope) {
|
|
||||||
op_info =
|
|
||||||
acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
|
|
||||||
if (op_info->flags & AML_HAS_TARGET) {
|
|
||||||
argument_count =
|
|
||||||
acpi_ps_get_argument_count(op_info->type);
|
|
||||||
if (parent_scope->common.arg_list_length >
|
|
||||||
argument_count) {
|
|
||||||
op->common.flags |= ACPI_PARSEOP_TARGET;
|
|
||||||
}
|
|
||||||
} else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
|
|
||||||
op->common.flags |= ACPI_PARSEOP_TARGET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walk_state->descending_callback != NULL) {
|
|
||||||
/*
|
|
||||||
* Find the object. This will either insert the object into
|
|
||||||
* the namespace or simply look it up
|
|
||||||
*/
|
|
||||||
walk_state->op = *new_op = op;
|
|
||||||
|
|
||||||
status = walk_state->descending_callback(walk_state, &op);
|
|
||||||
status = acpi_ps_next_parse_state(walk_state, op, status);
|
|
||||||
if (status == AE_CTRL_PENDING) {
|
|
||||||
status = AE_CTRL_PARSE_PENDING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ps_get_arguments
|
* FUNCTION: acpi_ps_get_arguments
|
||||||
@ -710,288 +374,6 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_complete_op
|
|
||||||
*
|
|
||||||
* PARAMETERS: walk_state - Current state
|
|
||||||
* op - Returned Op
|
|
||||||
* status - Parse status before complete Op
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Complete Op
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_complete_op(struct acpi_walk_state *walk_state,
|
|
||||||
union acpi_parse_object **op, acpi_status status)
|
|
||||||
{
|
|
||||||
acpi_status status2;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finished one argument of the containing scope
|
|
||||||
*/
|
|
||||||
walk_state->parser_state.scope->parse_scope.arg_count--;
|
|
||||||
|
|
||||||
/* Close this Op (will result in parse subtree deletion) */
|
|
||||||
|
|
||||||
status2 = acpi_ps_complete_this_op(walk_state, *op);
|
|
||||||
if (ACPI_FAILURE(status2)) {
|
|
||||||
return_ACPI_STATUS(status2);
|
|
||||||
}
|
|
||||||
|
|
||||||
*op = NULL;
|
|
||||||
|
|
||||||
switch (status) {
|
|
||||||
case AE_OK:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AE_CTRL_TRANSFER:
|
|
||||||
|
|
||||||
/* We are about to transfer to a called method */
|
|
||||||
|
|
||||||
walk_state->prev_op = NULL;
|
|
||||||
walk_state->prev_arg_types = walk_state->arg_types;
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
|
|
||||||
case AE_CTRL_END:
|
|
||||||
|
|
||||||
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
|
|
||||||
if (*op) {
|
|
||||||
walk_state->op = *op;
|
|
||||||
walk_state->op_info =
|
|
||||||
acpi_ps_get_opcode_info((*op)->common.aml_opcode);
|
|
||||||
walk_state->opcode = (*op)->common.aml_opcode;
|
|
||||||
|
|
||||||
status = walk_state->ascending_callback(walk_state);
|
|
||||||
status =
|
|
||||||
acpi_ps_next_parse_state(walk_state, *op, status);
|
|
||||||
|
|
||||||
status2 = acpi_ps_complete_this_op(walk_state, *op);
|
|
||||||
if (ACPI_FAILURE(status2)) {
|
|
||||||
return_ACPI_STATUS(status2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status = AE_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AE_CTRL_BREAK:
|
|
||||||
case AE_CTRL_CONTINUE:
|
|
||||||
|
|
||||||
/* Pop off scopes until we find the While */
|
|
||||||
|
|
||||||
while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
|
|
||||||
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close this iteration of the While loop */
|
|
||||||
|
|
||||||
walk_state->op = *op;
|
|
||||||
walk_state->op_info =
|
|
||||||
acpi_ps_get_opcode_info((*op)->common.aml_opcode);
|
|
||||||
walk_state->opcode = (*op)->common.aml_opcode;
|
|
||||||
|
|
||||||
status = walk_state->ascending_callback(walk_state);
|
|
||||||
status = acpi_ps_next_parse_state(walk_state, *op, status);
|
|
||||||
|
|
||||||
status2 = acpi_ps_complete_this_op(walk_state, *op);
|
|
||||||
if (ACPI_FAILURE(status2)) {
|
|
||||||
return_ACPI_STATUS(status2);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = AE_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AE_CTRL_TERMINATE:
|
|
||||||
|
|
||||||
/* Clean up */
|
|
||||||
do {
|
|
||||||
if (*op) {
|
|
||||||
status2 =
|
|
||||||
acpi_ps_complete_this_op(walk_state, *op);
|
|
||||||
if (ACPI_FAILURE(status2)) {
|
|
||||||
return_ACPI_STATUS(status2);
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ut_delete_generic_state
|
|
||||||
(acpi_ut_pop_generic_state
|
|
||||||
(&walk_state->control_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
|
|
||||||
} while (*op);
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
|
|
||||||
default: /* All other non-AE_OK status */
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (*op) {
|
|
||||||
status2 =
|
|
||||||
acpi_ps_complete_this_op(walk_state, *op);
|
|
||||||
if (ACPI_FAILURE(status2)) {
|
|
||||||
return_ACPI_STATUS(status2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
|
|
||||||
} while (*op);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* TBD: Cleanup parse ops on error
|
|
||||||
*/
|
|
||||||
if (*op == NULL) {
|
|
||||||
acpi_ps_pop_scope(parser_state, op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
walk_state->prev_op = NULL;
|
|
||||||
walk_state->prev_arg_types = walk_state->arg_types;
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This scope complete? */
|
|
||||||
|
|
||||||
if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
|
|
||||||
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
|
|
||||||
} else {
|
|
||||||
*op = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_complete_final_op
|
|
||||||
*
|
|
||||||
* PARAMETERS: walk_state - Current state
|
|
||||||
* op - Current Op
|
|
||||||
* status - Current parse status before complete last
|
|
||||||
* Op
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Complete last Op.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
|
||||||
union acpi_parse_object *op, acpi_status status)
|
|
||||||
{
|
|
||||||
acpi_status status2;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Complete the last Op (if not completed), and clear the scope stack.
|
|
||||||
* It is easily possible to end an AML "package" with an unbounded number
|
|
||||||
* of open scopes (such as when several ASL blocks are closed with
|
|
||||||
* sequential closing braces). We want to terminate each one cleanly.
|
|
||||||
*/
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
|
|
||||||
op));
|
|
||||||
do {
|
|
||||||
if (op) {
|
|
||||||
if (walk_state->ascending_callback != NULL) {
|
|
||||||
walk_state->op = op;
|
|
||||||
walk_state->op_info =
|
|
||||||
acpi_ps_get_opcode_info(op->common.
|
|
||||||
aml_opcode);
|
|
||||||
walk_state->opcode = op->common.aml_opcode;
|
|
||||||
|
|
||||||
status =
|
|
||||||
walk_state->ascending_callback(walk_state);
|
|
||||||
status =
|
|
||||||
acpi_ps_next_parse_state(walk_state, op,
|
|
||||||
status);
|
|
||||||
if (status == AE_CTRL_PENDING) {
|
|
||||||
status =
|
|
||||||
acpi_ps_complete_op(walk_state, &op,
|
|
||||||
AE_OK);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == AE_CTRL_TERMINATE) {
|
|
||||||
status = AE_OK;
|
|
||||||
|
|
||||||
/* Clean up */
|
|
||||||
do {
|
|
||||||
if (op) {
|
|
||||||
status2 =
|
|
||||||
acpi_ps_complete_this_op
|
|
||||||
(walk_state, op);
|
|
||||||
if (ACPI_FAILURE
|
|
||||||
(status2)) {
|
|
||||||
return_ACPI_STATUS
|
|
||||||
(status2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ps_pop_scope(&
|
|
||||||
(walk_state->
|
|
||||||
parser_state),
|
|
||||||
&op,
|
|
||||||
&walk_state->
|
|
||||||
arg_types,
|
|
||||||
&walk_state->
|
|
||||||
arg_count);
|
|
||||||
|
|
||||||
} while (op);
|
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (ACPI_FAILURE(status)) {
|
|
||||||
|
|
||||||
/* First error is most important */
|
|
||||||
|
|
||||||
(void)
|
|
||||||
acpi_ps_complete_this_op(walk_state,
|
|
||||||
op);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status2 = acpi_ps_complete_this_op(walk_state, op);
|
|
||||||
if (ACPI_FAILURE(status2)) {
|
|
||||||
return_ACPI_STATUS(status2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_ps_pop_scope(&(walk_state->parser_state), &op,
|
|
||||||
&walk_state->arg_types,
|
|
||||||
&walk_state->arg_count);
|
|
||||||
|
|
||||||
} while (op);
|
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ps_parse_loop
|
* FUNCTION: acpi_ps_parse_loop
|
||||||
@ -1178,10 +560,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
|
|||||||
walk_state->op_info =
|
walk_state->op_info =
|
||||||
acpi_ps_get_opcode_info(op->common.aml_opcode);
|
acpi_ps_get_opcode_info(op->common.aml_opcode);
|
||||||
if (walk_state->op_info->flags & AML_NAMED) {
|
if (walk_state->op_info->flags & AML_NAMED) {
|
||||||
if (acpi_gbl_depth) {
|
|
||||||
acpi_gbl_depth--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op->common.aml_opcode == AML_REGION_OP ||
|
if (op->common.aml_opcode == AML_REGION_OP ||
|
||||||
op->common.aml_opcode == AML_DATA_REGION_OP) {
|
op->common.aml_opcode == AML_DATA_REGION_OP) {
|
||||||
/*
|
/*
|
||||||
|
647
drivers/acpi/acpica/psobject.c
Normal file
647
drivers/acpi/acpica/psobject.c
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: psobject - Support for parse objects
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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 "acparser.h"
|
||||||
|
#include "amlcode.h"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_PARSER
|
||||||
|
ACPI_MODULE_NAME("psobject")
|
||||||
|
|
||||||
|
/* Local prototypes */
|
||||||
|
static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_get_aml_opcode
|
||||||
|
*
|
||||||
|
* PARAMETERS: walk_state - Current state
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Extract the next AML opcode from the input stream.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
|
||||||
|
{
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
|
||||||
|
|
||||||
|
walk_state->aml_offset =
|
||||||
|
(u32)ACPI_PTR_DIFF(walk_state->parser_state.aml,
|
||||||
|
walk_state->parser_state.aml_start);
|
||||||
|
walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First cut to determine what we have found:
|
||||||
|
* 1) A valid AML opcode
|
||||||
|
* 2) A name string
|
||||||
|
* 3) An unknown/invalid opcode
|
||||||
|
*/
|
||||||
|
walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
|
||||||
|
|
||||||
|
switch (walk_state->op_info->class) {
|
||||||
|
case AML_CLASS_ASCII:
|
||||||
|
case AML_CLASS_PREFIX:
|
||||||
|
/*
|
||||||
|
* Starts with a valid prefix or ASCII char, this is a name
|
||||||
|
* string. Convert the bare name string to a namepath.
|
||||||
|
*/
|
||||||
|
walk_state->opcode = AML_INT_NAMEPATH_OP;
|
||||||
|
walk_state->arg_types = ARGP_NAMESTRING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AML_CLASS_UNKNOWN:
|
||||||
|
|
||||||
|
/* The opcode is unrecognized. Complain and skip unknown opcodes */
|
||||||
|
|
||||||
|
if (walk_state->pass_number == 2) {
|
||||||
|
ACPI_ERROR((AE_INFO,
|
||||||
|
"Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
|
||||||
|
walk_state->opcode,
|
||||||
|
(u32)(walk_state->aml_offset +
|
||||||
|
sizeof(struct acpi_table_header))));
|
||||||
|
|
||||||
|
ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
|
||||||
|
48);
|
||||||
|
|
||||||
|
#ifdef ACPI_ASL_COMPILER
|
||||||
|
/*
|
||||||
|
* This is executed for the disassembler only. Output goes
|
||||||
|
* to the disassembled ASL output file.
|
||||||
|
*/
|
||||||
|
acpi_os_printf
|
||||||
|
("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
|
||||||
|
walk_state->opcode,
|
||||||
|
(u32)(walk_state->aml_offset +
|
||||||
|
sizeof(struct acpi_table_header)));
|
||||||
|
|
||||||
|
/* Dump the context surrounding the invalid opcode */
|
||||||
|
|
||||||
|
acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
|
||||||
|
aml - 16), 48, DB_BYTE_DISPLAY,
|
||||||
|
(walk_state->aml_offset +
|
||||||
|
sizeof(struct acpi_table_header) -
|
||||||
|
16));
|
||||||
|
acpi_os_printf(" */\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment past one-byte or two-byte opcode */
|
||||||
|
|
||||||
|
walk_state->parser_state.aml++;
|
||||||
|
if (walk_state->opcode > 0xFF) { /* Can only happen if first byte is 0x5B */
|
||||||
|
walk_state->parser_state.aml++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
/* Found opcode info, this is a normal opcode */
|
||||||
|
|
||||||
|
walk_state->parser_state.aml +=
|
||||||
|
acpi_ps_get_opcode_size(walk_state->opcode);
|
||||||
|
walk_state->arg_types = walk_state->op_info->parse_args;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_build_named_op
|
||||||
|
*
|
||||||
|
* PARAMETERS: walk_state - Current state
|
||||||
|
* aml_op_start - Begin of named Op in AML
|
||||||
|
* unnamed_op - Early Op (not a named Op)
|
||||||
|
* op - Returned Op
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Parse a named Op
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
|
||||||
|
u8 *aml_op_start,
|
||||||
|
union acpi_parse_object *unnamed_op,
|
||||||
|
union acpi_parse_object **op)
|
||||||
|
{
|
||||||
|
acpi_status status = AE_OK;
|
||||||
|
union acpi_parse_object *arg = NULL;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
|
||||||
|
|
||||||
|
unnamed_op->common.value.arg = NULL;
|
||||||
|
unnamed_op->common.arg_list_length = 0;
|
||||||
|
unnamed_op->common.aml_opcode = walk_state->opcode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get and append arguments until we find the node that contains
|
||||||
|
* the name (the type ARGP_NAME).
|
||||||
|
*/
|
||||||
|
while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
|
||||||
|
(GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
|
||||||
|
status =
|
||||||
|
acpi_ps_get_next_arg(walk_state,
|
||||||
|
&(walk_state->parser_state),
|
||||||
|
GET_CURRENT_ARG_TYPE(walk_state->
|
||||||
|
arg_types), &arg);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_append_arg(unnamed_op, arg);
|
||||||
|
INCREMENT_ARG_LIST(walk_state->arg_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that we found a NAME and didn't run out of arguments
|
||||||
|
*/
|
||||||
|
if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
|
||||||
|
return_ACPI_STATUS(AE_AML_NO_OPERAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We know that this arg is a name, move to next arg */
|
||||||
|
|
||||||
|
INCREMENT_ARG_LIST(walk_state->arg_types);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the object. This will either insert the object into
|
||||||
|
* the namespace or simply look it up
|
||||||
|
*/
|
||||||
|
walk_state->op = NULL;
|
||||||
|
|
||||||
|
status = walk_state->descending_callback(walk_state, op);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*op) {
|
||||||
|
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = acpi_ps_next_parse_state(walk_state, *op, status);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
if (status == AE_CTRL_PENDING) {
|
||||||
|
return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
|
||||||
|
}
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
|
||||||
|
|
||||||
|
if ((*op)->common.aml_opcode == AML_REGION_OP ||
|
||||||
|
(*op)->common.aml_opcode == AML_DATA_REGION_OP) {
|
||||||
|
/*
|
||||||
|
* Defer final parsing of an operation_region body, because we don't
|
||||||
|
* have enough info in the first pass to parse it correctly (i.e.,
|
||||||
|
* there may be method calls within the term_arg elements of the body.)
|
||||||
|
*
|
||||||
|
* However, we must continue parsing because the opregion is not a
|
||||||
|
* standalone package -- we don't know where the end is at this point.
|
||||||
|
*
|
||||||
|
* (Length is unknown until parse of the body complete)
|
||||||
|
*/
|
||||||
|
(*op)->named.data = aml_op_start;
|
||||||
|
(*op)->named.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_create_op
|
||||||
|
*
|
||||||
|
* PARAMETERS: walk_state - Current state
|
||||||
|
* aml_op_start - Op start in AML
|
||||||
|
* new_op - Returned Op
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Get Op from AML
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_create_op(struct acpi_walk_state *walk_state,
|
||||||
|
u8 *aml_op_start, union acpi_parse_object **new_op)
|
||||||
|
{
|
||||||
|
acpi_status status = AE_OK;
|
||||||
|
union acpi_parse_object *op;
|
||||||
|
union acpi_parse_object *named_op = NULL;
|
||||||
|
union acpi_parse_object *parent_scope;
|
||||||
|
u8 argument_count;
|
||||||
|
const struct acpi_opcode_info *op_info;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
|
||||||
|
|
||||||
|
status = acpi_ps_get_aml_opcode(walk_state);
|
||||||
|
if (status == AE_CTRL_PARSE_CONTINUE) {
|
||||||
|
return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create Op structure and append to parent's argument list */
|
||||||
|
|
||||||
|
walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
|
||||||
|
op = acpi_ps_alloc_op(walk_state->opcode);
|
||||||
|
if (!op) {
|
||||||
|
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk_state->op_info->flags & AML_NAMED) {
|
||||||
|
status =
|
||||||
|
acpi_ps_build_named_op(walk_state, aml_op_start, op,
|
||||||
|
&named_op);
|
||||||
|
acpi_ps_free_op(op);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_op = named_op;
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not a named opcode, just allocate Op and append to parent */
|
||||||
|
|
||||||
|
if (walk_state->op_info->flags & AML_CREATE) {
|
||||||
|
/*
|
||||||
|
* Backup to beginning of create_XXXfield declaration
|
||||||
|
* body_length is unknown until we parse the body
|
||||||
|
*/
|
||||||
|
op->named.data = aml_op_start;
|
||||||
|
op->named.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk_state->opcode == AML_BANK_FIELD_OP) {
|
||||||
|
/*
|
||||||
|
* Backup to beginning of bank_field declaration
|
||||||
|
* body_length is unknown until we parse the body
|
||||||
|
*/
|
||||||
|
op->named.data = aml_op_start;
|
||||||
|
op->named.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
|
||||||
|
acpi_ps_append_arg(parent_scope, op);
|
||||||
|
|
||||||
|
if (parent_scope) {
|
||||||
|
op_info =
|
||||||
|
acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
|
||||||
|
if (op_info->flags & AML_HAS_TARGET) {
|
||||||
|
argument_count =
|
||||||
|
acpi_ps_get_argument_count(op_info->type);
|
||||||
|
if (parent_scope->common.arg_list_length >
|
||||||
|
argument_count) {
|
||||||
|
op->common.flags |= ACPI_PARSEOP_TARGET;
|
||||||
|
}
|
||||||
|
} else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
|
||||||
|
op->common.flags |= ACPI_PARSEOP_TARGET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walk_state->descending_callback != NULL) {
|
||||||
|
/*
|
||||||
|
* Find the object. This will either insert the object into
|
||||||
|
* the namespace or simply look it up
|
||||||
|
*/
|
||||||
|
walk_state->op = *new_op = op;
|
||||||
|
|
||||||
|
status = walk_state->descending_callback(walk_state, &op);
|
||||||
|
status = acpi_ps_next_parse_state(walk_state, op, status);
|
||||||
|
if (status == AE_CTRL_PENDING) {
|
||||||
|
status = AE_CTRL_PARSE_PENDING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_complete_op
|
||||||
|
*
|
||||||
|
* PARAMETERS: walk_state - Current state
|
||||||
|
* op - Returned Op
|
||||||
|
* status - Parse status before complete Op
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Complete Op
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_complete_op(struct acpi_walk_state *walk_state,
|
||||||
|
union acpi_parse_object **op, acpi_status status)
|
||||||
|
{
|
||||||
|
acpi_status status2;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finished one argument of the containing scope
|
||||||
|
*/
|
||||||
|
walk_state->parser_state.scope->parse_scope.arg_count--;
|
||||||
|
|
||||||
|
/* Close this Op (will result in parse subtree deletion) */
|
||||||
|
|
||||||
|
status2 = acpi_ps_complete_this_op(walk_state, *op);
|
||||||
|
if (ACPI_FAILURE(status2)) {
|
||||||
|
return_ACPI_STATUS(status2);
|
||||||
|
}
|
||||||
|
|
||||||
|
*op = NULL;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case AE_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AE_CTRL_TRANSFER:
|
||||||
|
|
||||||
|
/* We are about to transfer to a called method */
|
||||||
|
|
||||||
|
walk_state->prev_op = NULL;
|
||||||
|
walk_state->prev_arg_types = walk_state->arg_types;
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
|
||||||
|
case AE_CTRL_END:
|
||||||
|
|
||||||
|
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
|
||||||
|
if (*op) {
|
||||||
|
walk_state->op = *op;
|
||||||
|
walk_state->op_info =
|
||||||
|
acpi_ps_get_opcode_info((*op)->common.aml_opcode);
|
||||||
|
walk_state->opcode = (*op)->common.aml_opcode;
|
||||||
|
|
||||||
|
status = walk_state->ascending_callback(walk_state);
|
||||||
|
status =
|
||||||
|
acpi_ps_next_parse_state(walk_state, *op, status);
|
||||||
|
|
||||||
|
status2 = acpi_ps_complete_this_op(walk_state, *op);
|
||||||
|
if (ACPI_FAILURE(status2)) {
|
||||||
|
return_ACPI_STATUS(status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = AE_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AE_CTRL_BREAK:
|
||||||
|
case AE_CTRL_CONTINUE:
|
||||||
|
|
||||||
|
/* Pop off scopes until we find the While */
|
||||||
|
|
||||||
|
while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
|
||||||
|
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close this iteration of the While loop */
|
||||||
|
|
||||||
|
walk_state->op = *op;
|
||||||
|
walk_state->op_info =
|
||||||
|
acpi_ps_get_opcode_info((*op)->common.aml_opcode);
|
||||||
|
walk_state->opcode = (*op)->common.aml_opcode;
|
||||||
|
|
||||||
|
status = walk_state->ascending_callback(walk_state);
|
||||||
|
status = acpi_ps_next_parse_state(walk_state, *op, status);
|
||||||
|
|
||||||
|
status2 = acpi_ps_complete_this_op(walk_state, *op);
|
||||||
|
if (ACPI_FAILURE(status2)) {
|
||||||
|
return_ACPI_STATUS(status2);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = AE_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AE_CTRL_TERMINATE:
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
do {
|
||||||
|
if (*op) {
|
||||||
|
status2 =
|
||||||
|
acpi_ps_complete_this_op(walk_state, *op);
|
||||||
|
if (ACPI_FAILURE(status2)) {
|
||||||
|
return_ACPI_STATUS(status2);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ut_delete_generic_state
|
||||||
|
(acpi_ut_pop_generic_state
|
||||||
|
(&walk_state->control_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
|
||||||
|
} while (*op);
|
||||||
|
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
|
||||||
|
default: /* All other non-AE_OK status */
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (*op) {
|
||||||
|
status2 =
|
||||||
|
acpi_ps_complete_this_op(walk_state, *op);
|
||||||
|
if (ACPI_FAILURE(status2)) {
|
||||||
|
return_ACPI_STATUS(status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
|
||||||
|
} while (*op);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
* TBD: Cleanup parse ops on error
|
||||||
|
*/
|
||||||
|
if (*op == NULL) {
|
||||||
|
acpi_ps_pop_scope(parser_state, op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
walk_state->prev_op = NULL;
|
||||||
|
walk_state->prev_arg_types = walk_state->arg_types;
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This scope complete? */
|
||||||
|
|
||||||
|
if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
|
||||||
|
acpi_ps_pop_scope(&(walk_state->parser_state), op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
|
||||||
|
} else {
|
||||||
|
*op = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_complete_final_op
|
||||||
|
*
|
||||||
|
* PARAMETERS: walk_state - Current state
|
||||||
|
* op - Current Op
|
||||||
|
* status - Current parse status before complete last
|
||||||
|
* Op
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Complete last Op.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
||||||
|
union acpi_parse_object *op, acpi_status status)
|
||||||
|
{
|
||||||
|
acpi_status status2;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Complete the last Op (if not completed), and clear the scope stack.
|
||||||
|
* It is easily possible to end an AML "package" with an unbounded number
|
||||||
|
* of open scopes (such as when several ASL blocks are closed with
|
||||||
|
* sequential closing braces). We want to terminate each one cleanly.
|
||||||
|
*/
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
|
||||||
|
op));
|
||||||
|
do {
|
||||||
|
if (op) {
|
||||||
|
if (walk_state->ascending_callback != NULL) {
|
||||||
|
walk_state->op = op;
|
||||||
|
walk_state->op_info =
|
||||||
|
acpi_ps_get_opcode_info(op->common.
|
||||||
|
aml_opcode);
|
||||||
|
walk_state->opcode = op->common.aml_opcode;
|
||||||
|
|
||||||
|
status =
|
||||||
|
walk_state->ascending_callback(walk_state);
|
||||||
|
status =
|
||||||
|
acpi_ps_next_parse_state(walk_state, op,
|
||||||
|
status);
|
||||||
|
if (status == AE_CTRL_PENDING) {
|
||||||
|
status =
|
||||||
|
acpi_ps_complete_op(walk_state, &op,
|
||||||
|
AE_OK);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == AE_CTRL_TERMINATE) {
|
||||||
|
status = AE_OK;
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
do {
|
||||||
|
if (op) {
|
||||||
|
status2 =
|
||||||
|
acpi_ps_complete_this_op
|
||||||
|
(walk_state, op);
|
||||||
|
if (ACPI_FAILURE
|
||||||
|
(status2)) {
|
||||||
|
return_ACPI_STATUS
|
||||||
|
(status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_pop_scope(&
|
||||||
|
(walk_state->
|
||||||
|
parser_state),
|
||||||
|
&op,
|
||||||
|
&walk_state->
|
||||||
|
arg_types,
|
||||||
|
&walk_state->
|
||||||
|
arg_count);
|
||||||
|
|
||||||
|
} while (op);
|
||||||
|
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (ACPI_FAILURE(status)) {
|
||||||
|
|
||||||
|
/* First error is most important */
|
||||||
|
|
||||||
|
(void)
|
||||||
|
acpi_ps_complete_this_op(walk_state,
|
||||||
|
op);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status2 = acpi_ps_complete_this_op(walk_state, op);
|
||||||
|
if (ACPI_FAILURE(status2)) {
|
||||||
|
return_ACPI_STATUS(status2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_pop_scope(&(walk_state->parser_state), &op,
|
||||||
|
&walk_state->arg_types,
|
||||||
|
&walk_state->arg_count);
|
||||||
|
|
||||||
|
} while (op);
|
||||||
|
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
@ -43,16 +43,12 @@
|
|||||||
|
|
||||||
#include <acpi/acpi.h>
|
#include <acpi/acpi.h>
|
||||||
#include "accommon.h"
|
#include "accommon.h"
|
||||||
#include "acparser.h"
|
|
||||||
#include "acopcode.h"
|
#include "acopcode.h"
|
||||||
#include "amlcode.h"
|
#include "amlcode.h"
|
||||||
|
|
||||||
#define _COMPONENT ACPI_PARSER
|
#define _COMPONENT ACPI_PARSER
|
||||||
ACPI_MODULE_NAME("psopcode")
|
ACPI_MODULE_NAME("psopcode")
|
||||||
|
|
||||||
static const u8 acpi_gbl_argument_count[] =
|
|
||||||
{ 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* NAME: acpi_gbl_aml_op_info
|
* NAME: acpi_gbl_aml_op_info
|
||||||
@ -63,7 +59,6 @@ static const u8 acpi_gbl_argument_count[] =
|
|||||||
* the operand type.
|
* the operand type.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Summary of opcode types/flags
|
* Summary of opcode types/flags
|
||||||
*
|
*
|
||||||
@ -181,7 +176,6 @@ static const u8 acpi_gbl_argument_count[] =
|
|||||||
AML_CREATE_QWORD_FIELD_OP
|
AML_CREATE_QWORD_FIELD_OP
|
||||||
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Master Opcode information table. A summary of everything we know about each
|
* Master Opcode information table. A summary of everything we know about each
|
||||||
* opcode, all in one place.
|
* opcode, all in one place.
|
||||||
@ -656,169 +650,3 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
|
|||||||
|
|
||||||
/*! [End] no source code translation !*/
|
/*! [End] no source code translation !*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* This table is directly indexed by the opcodes, and returns an
|
|
||||||
* index into the table above
|
|
||||||
*/
|
|
||||||
static const u8 acpi_gbl_short_op_index[256] = {
|
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
|
||||||
/* 8 9 A B C D E F */
|
|
||||||
/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
|
|
||||||
/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
|
|
||||||
/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
|
|
||||||
/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
|
|
||||||
/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
|
||||||
/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
|
||||||
/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
|
||||||
/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
|
|
||||||
/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
|
|
||||||
/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
|
|
||||||
/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
|
|
||||||
/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
|
||||||
/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
|
|
||||||
/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
|
|
||||||
/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
|
|
||||||
/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
|
|
||||||
/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
|
|
||||||
/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This table is indexed by the second opcode of the extended opcode
|
|
||||||
* pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
|
|
||||||
*/
|
|
||||||
static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
|
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
|
||||||
/* 8 9 A B C D E F */
|
|
||||||
/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
|
|
||||||
/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
|
|
||||||
/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
|
||||||
/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
|
||||||
/* 0x88 */ 0x7C,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_get_opcode_info
|
|
||||||
*
|
|
||||||
* PARAMETERS: opcode - The AML opcode
|
|
||||||
*
|
|
||||||
* RETURN: A pointer to the info about the opcode.
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Find AML opcode description based on the opcode.
|
|
||||||
* NOTE: This procedure must ALWAYS return a valid pointer!
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode)
|
|
||||||
{
|
|
||||||
ACPI_FUNCTION_NAME(ps_get_opcode_info);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Detect normal 8-bit opcode or extended 16-bit opcode
|
|
||||||
*/
|
|
||||||
if (!(opcode & 0xFF00)) {
|
|
||||||
|
|
||||||
/* Simple (8-bit) opcode: 0-255, can't index beyond table */
|
|
||||||
|
|
||||||
return (&acpi_gbl_aml_op_info
|
|
||||||
[acpi_gbl_short_op_index[(u8) opcode]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
|
|
||||||
(((u8) opcode) <= MAX_EXTENDED_OPCODE)) {
|
|
||||||
|
|
||||||
/* Valid extended (16-bit) opcode */
|
|
||||||
|
|
||||||
return (&acpi_gbl_aml_op_info
|
|
||||||
[acpi_gbl_long_op_index[(u8) opcode]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unknown AML opcode */
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
||||||
"Unknown AML opcode [%4.4X]\n", opcode));
|
|
||||||
|
|
||||||
return (&acpi_gbl_aml_op_info[_UNK]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_get_opcode_name
|
|
||||||
*
|
|
||||||
* PARAMETERS: opcode - The AML opcode
|
|
||||||
*
|
|
||||||
* RETURN: A pointer to the name of the opcode (ASCII String)
|
|
||||||
* Note: Never returns NULL.
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Translate an opcode into a human-readable string
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
char *acpi_ps_get_opcode_name(u16 opcode)
|
|
||||||
{
|
|
||||||
#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
|
|
||||||
|
|
||||||
const struct acpi_opcode_info *op;
|
|
||||||
|
|
||||||
op = acpi_ps_get_opcode_info(opcode);
|
|
||||||
|
|
||||||
/* Always guaranteed to return a valid pointer */
|
|
||||||
|
|
||||||
return (op->name);
|
|
||||||
|
|
||||||
#else
|
|
||||||
return ("OpcodeName unavailable");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ps_get_argument_count
|
|
||||||
*
|
|
||||||
* PARAMETERS: op_type - Type associated with the AML opcode
|
|
||||||
*
|
|
||||||
* RETURN: Argument count
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Obtain the number of expected arguments for an AML opcode
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
u8 acpi_ps_get_argument_count(u32 op_type)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
|
|
||||||
return (acpi_gbl_argument_count[op_type]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
223
drivers/acpi/acpica/psopinfo.c
Normal file
223
drivers/acpi/acpica/psopinfo.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: psopinfo - AML opcode information functions and dispatch tables
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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 "acparser.h"
|
||||||
|
#include "acopcode.h"
|
||||||
|
#include "amlcode.h"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_PARSER
|
||||||
|
ACPI_MODULE_NAME("psopinfo")
|
||||||
|
|
||||||
|
extern const u8 acpi_gbl_short_op_index[];
|
||||||
|
extern const u8 acpi_gbl_long_op_index[];
|
||||||
|
|
||||||
|
static const u8 acpi_gbl_argument_count[] =
|
||||||
|
{ 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_get_opcode_info
|
||||||
|
*
|
||||||
|
* PARAMETERS: opcode - The AML opcode
|
||||||
|
*
|
||||||
|
* RETURN: A pointer to the info about the opcode.
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Find AML opcode description based on the opcode.
|
||||||
|
* NOTE: This procedure must ALWAYS return a valid pointer!
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode)
|
||||||
|
{
|
||||||
|
ACPI_FUNCTION_NAME(ps_get_opcode_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detect normal 8-bit opcode or extended 16-bit opcode
|
||||||
|
*/
|
||||||
|
if (!(opcode & 0xFF00)) {
|
||||||
|
|
||||||
|
/* Simple (8-bit) opcode: 0-255, can't index beyond table */
|
||||||
|
|
||||||
|
return (&acpi_gbl_aml_op_info
|
||||||
|
[acpi_gbl_short_op_index[(u8)opcode]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
|
||||||
|
(((u8)opcode) <= MAX_EXTENDED_OPCODE)) {
|
||||||
|
|
||||||
|
/* Valid extended (16-bit) opcode */
|
||||||
|
|
||||||
|
return (&acpi_gbl_aml_op_info
|
||||||
|
[acpi_gbl_long_op_index[(u8)opcode]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown AML opcode */
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||||
|
"Unknown AML opcode [%4.4X]\n", opcode));
|
||||||
|
|
||||||
|
return (&acpi_gbl_aml_op_info[_UNK]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_get_opcode_name
|
||||||
|
*
|
||||||
|
* PARAMETERS: opcode - The AML opcode
|
||||||
|
*
|
||||||
|
* RETURN: A pointer to the name of the opcode (ASCII String)
|
||||||
|
* Note: Never returns NULL.
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Translate an opcode into a human-readable string
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
char *acpi_ps_get_opcode_name(u16 opcode)
|
||||||
|
{
|
||||||
|
#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
|
||||||
|
|
||||||
|
const struct acpi_opcode_info *op;
|
||||||
|
|
||||||
|
op = acpi_ps_get_opcode_info(opcode);
|
||||||
|
|
||||||
|
/* Always guaranteed to return a valid pointer */
|
||||||
|
|
||||||
|
return (op->name);
|
||||||
|
|
||||||
|
#else
|
||||||
|
return ("OpcodeName unavailable");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_get_argument_count
|
||||||
|
*
|
||||||
|
* PARAMETERS: op_type - Type associated with the AML opcode
|
||||||
|
*
|
||||||
|
* RETURN: Argument count
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Obtain the number of expected arguments for an AML opcode
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
u8 acpi_ps_get_argument_count(u32 op_type)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
|
||||||
|
return (acpi_gbl_argument_count[op_type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This table is directly indexed by the opcodes It returns
|
||||||
|
* an index into the opcode table (acpi_gbl_aml_op_info)
|
||||||
|
*/
|
||||||
|
const u8 acpi_gbl_short_op_index[256] = {
|
||||||
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
|
/* 8 9 A B C D E F */
|
||||||
|
/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
|
||||||
|
/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
|
||||||
|
/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
|
||||||
|
/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
|
||||||
|
/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
||||||
|
/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
||||||
|
/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
|
||||||
|
/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
|
||||||
|
/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
|
||||||
|
/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
|
||||||
|
/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
|
||||||
|
/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
||||||
|
/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
|
||||||
|
/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
|
||||||
|
/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
|
||||||
|
/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
|
||||||
|
/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
|
||||||
|
/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This table is indexed by the second opcode of the extended opcode
|
||||||
|
* pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
|
||||||
|
*/
|
||||||
|
const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
|
||||||
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
|
/* 8 9 A B C D E F */
|
||||||
|
/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
|
||||||
|
/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
|
||||||
|
/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
|
||||||
|
/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||||
|
/* 0x88 */ 0x7C,
|
||||||
|
};
|
@ -77,419 +77,16 @@ static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
|
|||||||
static void
|
static void
|
||||||
acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
|
acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
|
||||||
|
|
||||||
#define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f)
|
|
||||||
#define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f)
|
|
||||||
#define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info))
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* Resource Descriptor info tables
|
|
||||||
*
|
|
||||||
* Note: The first table entry must be a Title or Literal and must contain
|
|
||||||
* the table length (number of table entries)
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
|
|
||||||
"Descriptor Length", NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
|
|
||||||
acpi_gbl_he_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
|
|
||||||
acpi_gbl_ll_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing",
|
|
||||||
acpi_gbl_shr_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count),
|
|
||||||
"Interrupt Count", NULL},
|
|
||||||
{ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]),
|
|
||||||
"Interrupt List", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed",
|
|
||||||
acpi_gbl_typ_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering",
|
|
||||||
acpi_gbl_bm_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type",
|
|
||||||
acpi_gbl_siz_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List",
|
|
||||||
NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
|
|
||||||
"Start-Dependent-Functions", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
|
|
||||||
"Descriptor Length", NULL},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
|
|
||||||
"Compatibility Priority", acpi_gbl_config_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
|
|
||||||
"Performance/Robustness", acpi_gbl_config_decode}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf),
|
|
||||||
"End-Dependent-Functions", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_io[6] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding",
|
|
||||||
acpi_gbl_io_decode},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length",
|
|
||||||
NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io),
|
|
||||||
"Fixed I/O", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length),
|
|
||||||
"Address Length", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_vendor[3] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor),
|
|
||||||
"Vendor Specific", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL},
|
|
||||||
{ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data",
|
|
||||||
NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "EndTag",
|
|
||||||
NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_memory24[6] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24),
|
|
||||||
"24-Bit Memory Range", NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect),
|
|
||||||
"Write Protect", acpi_gbl_rw_decode},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length),
|
|
||||||
"Address Length", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_memory32[6] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32),
|
|
||||||
"32-Bit Memory Range", NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect),
|
|
||||||
"Write Protect", acpi_gbl_rw_decode},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length),
|
|
||||||
"Address Length", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32),
|
|
||||||
"32-Bit Fixed Memory Range", NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect),
|
|
||||||
"Write Protect", acpi_gbl_rw_decode},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length),
|
|
||||||
"Address Length", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_address16[8] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16),
|
|
||||||
"16-Bit WORD Address Space", NULL},
|
|
||||||
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset),
|
|
||||||
"Translation Offset", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length),
|
|
||||||
"Address Length", NULL},
|
|
||||||
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_address32[8] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32),
|
|
||||||
"32-Bit DWORD Address Space", NULL},
|
|
||||||
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset),
|
|
||||||
"Translation Offset", NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length),
|
|
||||||
"Address Length", NULL},
|
|
||||||
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_address64[8] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64),
|
|
||||||
"64-Bit QWORD Address Space", NULL},
|
|
||||||
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset),
|
|
||||||
"Translation Offset", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length),
|
|
||||||
"Address Length", NULL},
|
|
||||||
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64),
|
|
||||||
"64-Bit Extended Address Space", NULL},
|
|
||||||
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity),
|
|
||||||
"Granularity", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum),
|
|
||||||
"Address Minimum", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum),
|
|
||||||
"Address Maximum", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset),
|
|
||||||
"Translation Offset", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length),
|
|
||||||
"Address Length", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific),
|
|
||||||
"Type-Specific Attribute", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq),
|
|
||||||
"Extended IRQ", NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer),
|
|
||||||
"Type", acpi_gbl_consume_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering),
|
|
||||||
"Triggering", acpi_gbl_he_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity",
|
|
||||||
acpi_gbl_ll_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing",
|
|
||||||
acpi_gbl_shr_decode},
|
|
||||||
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL,
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count),
|
|
||||||
"Interrupt Count", NULL},
|
|
||||||
{ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]),
|
|
||||||
"Interrupt List", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg),
|
|
||||||
"Generic Register", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size),
|
|
||||||
"Access Size", NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_gpio[16] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_gpio), "GPIO", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.revision_id), "RevisionId", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.connection_type),
|
|
||||||
"ConnectionType", acpi_gbl_ct_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.producer_consumer),
|
|
||||||
"ProducerConsumer", acpi_gbl_consume_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.pin_config), "PinConfig",
|
|
||||||
acpi_gbl_ppc_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.sharable), "Sharing",
|
|
||||||
acpi_gbl_shr_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.io_restriction),
|
|
||||||
"IoRestriction", acpi_gbl_ior_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.triggering), "Triggering",
|
|
||||||
acpi_gbl_he_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.polarity), "Polarity",
|
|
||||||
acpi_gbl_ll_decode},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.drive_strength), "DriveStrength",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.debounce_timeout),
|
|
||||||
"DebounceTimeout", NULL},
|
|
||||||
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(gpio.resource_source),
|
|
||||||
"ResourceSource", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.pin_table_length),
|
|
||||||
"PinTableLength", NULL},
|
|
||||||
{ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET(gpio.pin_table), "PinTable", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.vendor_length), "VendorLength",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_SHORTLISTX, ACPI_RSD_OFFSET(gpio.vendor_data), "VendorData",
|
|
||||||
NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_fixed_dma[4] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_dma),
|
|
||||||
"FixedDma", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.request_lines),
|
|
||||||
"RequestLines", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.channels), "Channels",
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_dma.width), "TransferWidth",
|
|
||||||
acpi_gbl_dts_decode},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ACPI_RS_DUMP_COMMON_SERIAL_BUS \
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.revision_id), "RevisionId", NULL}, \
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.type), "Type", acpi_gbl_sbt_decode}, \
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.producer_consumer), "ProducerConsumer", acpi_gbl_consume_decode}, \
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.slave_mode), "SlaveMode", acpi_gbl_sm_decode}, \
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.type_revision_id), "TypeRevisionId", NULL}, \
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET (common_serial_bus.type_data_length), "TypeDataLength", NULL}, \
|
|
||||||
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (common_serial_bus.resource_source), "ResourceSource", NULL}, \
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET (common_serial_bus.vendor_length), "VendorLength", NULL}, \
|
|
||||||
{ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (common_serial_bus.vendor_data), "VendorData", NULL},
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[10] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_common_serial_bus),
|
|
||||||
"Common Serial Bus", NULL},
|
|
||||||
ACPI_RS_DUMP_COMMON_SERIAL_BUS
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[13] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_i2c_serial_bus),
|
|
||||||
"I2C Serial Bus", NULL},
|
|
||||||
ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
|
|
||||||
ACPI_RSD_OFFSET(i2c_serial_bus.
|
|
||||||
access_mode),
|
|
||||||
"AccessMode", acpi_gbl_am_decode},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(i2c_serial_bus.connection_speed),
|
|
||||||
"ConnectionSpeed", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(i2c_serial_bus.slave_address),
|
|
||||||
"SlaveAddress", NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[17] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_spi_serial_bus),
|
|
||||||
"Spi Serial Bus", NULL},
|
|
||||||
ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
|
|
||||||
ACPI_RSD_OFFSET(spi_serial_bus.
|
|
||||||
wire_mode), "WireMode",
|
|
||||||
acpi_gbl_wm_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(spi_serial_bus.device_polarity),
|
|
||||||
"DevicePolarity", acpi_gbl_dp_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.data_bit_length),
|
|
||||||
"DataBitLength", NULL},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_phase),
|
|
||||||
"ClockPhase", acpi_gbl_cph_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_polarity),
|
|
||||||
"ClockPolarity", acpi_gbl_cpo_decode},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(spi_serial_bus.device_selection),
|
|
||||||
"DeviceSelection", NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(spi_serial_bus.connection_speed),
|
|
||||||
"ConnectionSpeed", NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[19] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_uart_serial_bus),
|
|
||||||
"Uart Serial Bus", NULL},
|
|
||||||
ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_2BITFLAG,
|
|
||||||
ACPI_RSD_OFFSET(uart_serial_bus.
|
|
||||||
flow_control),
|
|
||||||
"FlowControl", acpi_gbl_fc_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.stop_bits),
|
|
||||||
"StopBits", acpi_gbl_sb_decode},
|
|
||||||
{ACPI_RSD_3BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.data_bits),
|
|
||||||
"DataBits", acpi_gbl_bpb_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.endian), "Endian",
|
|
||||||
acpi_gbl_ed_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.parity), "Parity",
|
|
||||||
acpi_gbl_pt_decode},
|
|
||||||
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.lines_enabled),
|
|
||||||
"LinesEnabled", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.rx_fifo_size),
|
|
||||||
"RxFifoSize", NULL},
|
|
||||||
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.tx_fifo_size),
|
|
||||||
"TxFifoSize", NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(uart_serial_bus.default_baud_rate),
|
|
||||||
"ConnectionSpeed", NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tables used for common address descriptor flag fields
|
|
||||||
*/
|
|
||||||
static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL,
|
|
||||||
NULL},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer),
|
|
||||||
"Consumer/Producer", acpi_gbl_consume_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode",
|
|
||||||
acpi_gbl_dec_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed),
|
|
||||||
"Min Relocatability", acpi_gbl_min_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed),
|
|
||||||
"Max Relocatability", acpi_gbl_max_decode}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = {
|
|
||||||
{ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags),
|
|
||||||
"Resource Type", (void *)"Memory Range"},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect),
|
|
||||||
"Write Protect", acpi_gbl_rw_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching),
|
|
||||||
"Caching", acpi_gbl_mem_decode},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type),
|
|
||||||
"Range Type", acpi_gbl_mtp_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation),
|
|
||||||
"Translation", acpi_gbl_ttp_decode}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = {
|
|
||||||
{ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags),
|
|
||||||
"Resource Type", (void *)"I/O Range"},
|
|
||||||
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type),
|
|
||||||
"Range Type", acpi_gbl_rng_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation),
|
|
||||||
"Translation", acpi_gbl_ttp_decode},
|
|
||||||
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type),
|
|
||||||
"Translation Type", acpi_gbl_trs_decode}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Table used to dump _PRT contents
|
|
||||||
*/
|
|
||||||
static struct acpi_rsdump_info acpi_rs_dump_prt[5] = {
|
|
||||||
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL},
|
|
||||||
{ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL},
|
|
||||||
{ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL},
|
|
||||||
{ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_rs_dump_descriptor
|
* FUNCTION: acpi_rs_dump_descriptor
|
||||||
*
|
*
|
||||||
* PARAMETERS: Resource
|
* PARAMETERS: resource - Buffer containing the resource
|
||||||
|
* table - Table entry to decode the resource
|
||||||
*
|
*
|
||||||
* RETURN: None
|
* RETURN: None
|
||||||
*
|
*
|
||||||
* DESCRIPTION:
|
* DESCRIPTION: Dump a resource descriptor based on a dump table entry.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
454
drivers/acpi/acpica/rsdumpinfo.c
Normal file
454
drivers/acpi/acpica/rsdumpinfo.c
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: rsdumpinfo - Tables used to display resource descriptors.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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 "acresrc.h"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_RESOURCES
|
||||||
|
ACPI_MODULE_NAME("rsdumpinfo")
|
||||||
|
|
||||||
|
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
|
||||||
|
#define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f)
|
||||||
|
#define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f)
|
||||||
|
#define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info))
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Resource Descriptor info tables
|
||||||
|
*
|
||||||
|
* Note: The first table entry must be a Title or Literal and must contain
|
||||||
|
* the table length (number of table entries)
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
|
||||||
|
"Descriptor Length", NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
|
||||||
|
acpi_gbl_he_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
|
||||||
|
acpi_gbl_ll_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing",
|
||||||
|
acpi_gbl_shr_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count),
|
||||||
|
"Interrupt Count", NULL},
|
||||||
|
{ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]),
|
||||||
|
"Interrupt List", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed",
|
||||||
|
acpi_gbl_typ_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering",
|
||||||
|
acpi_gbl_bm_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type",
|
||||||
|
acpi_gbl_siz_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List",
|
||||||
|
NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
|
||||||
|
"Start-Dependent-Functions", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
|
||||||
|
"Descriptor Length", NULL},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
|
||||||
|
"Compatibility Priority", acpi_gbl_config_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
|
||||||
|
"Performance/Robustness", acpi_gbl_config_decode}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf),
|
||||||
|
"End-Dependent-Functions", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_io[6] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding",
|
||||||
|
acpi_gbl_io_decode},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length",
|
||||||
|
NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io),
|
||||||
|
"Fixed I/O", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length),
|
||||||
|
"Address Length", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_vendor[3] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor),
|
||||||
|
"Vendor Specific", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL},
|
||||||
|
{ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data",
|
||||||
|
NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "EndTag",
|
||||||
|
NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_memory24[6] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24),
|
||||||
|
"24-Bit Memory Range", NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect),
|
||||||
|
"Write Protect", acpi_gbl_rw_decode},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length),
|
||||||
|
"Address Length", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_memory32[6] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32),
|
||||||
|
"32-Bit Memory Range", NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect),
|
||||||
|
"Write Protect", acpi_gbl_rw_decode},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length),
|
||||||
|
"Address Length", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32),
|
||||||
|
"32-Bit Fixed Memory Range", NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect),
|
||||||
|
"Write Protect", acpi_gbl_rw_decode},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length),
|
||||||
|
"Address Length", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_address16[8] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16),
|
||||||
|
"16-Bit WORD Address Space", NULL},
|
||||||
|
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset),
|
||||||
|
"Translation Offset", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length),
|
||||||
|
"Address Length", NULL},
|
||||||
|
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_address32[8] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32),
|
||||||
|
"32-Bit DWORD Address Space", NULL},
|
||||||
|
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset),
|
||||||
|
"Translation Offset", NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length),
|
||||||
|
"Address Length", NULL},
|
||||||
|
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_address64[8] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64),
|
||||||
|
"64-Bit QWORD Address Space", NULL},
|
||||||
|
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset),
|
||||||
|
"Translation Offset", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length),
|
||||||
|
"Address Length", NULL},
|
||||||
|
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64),
|
||||||
|
"64-Bit Extended Address Space", NULL},
|
||||||
|
{ACPI_RSD_ADDRESS, 0, NULL, NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity),
|
||||||
|
"Granularity", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum),
|
||||||
|
"Address Minimum", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum),
|
||||||
|
"Address Maximum", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset),
|
||||||
|
"Translation Offset", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length),
|
||||||
|
"Address Length", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific),
|
||||||
|
"Type-Specific Attribute", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq),
|
||||||
|
"Extended IRQ", NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer),
|
||||||
|
"Type", acpi_gbl_consume_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering),
|
||||||
|
"Triggering", acpi_gbl_he_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity",
|
||||||
|
acpi_gbl_ll_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing",
|
||||||
|
acpi_gbl_shr_decode},
|
||||||
|
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL,
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count),
|
||||||
|
"Interrupt Count", NULL},
|
||||||
|
{ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]),
|
||||||
|
"Interrupt List", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg),
|
||||||
|
"Generic Register", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size),
|
||||||
|
"Access Size", NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_gpio[16] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_gpio), "GPIO", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.revision_id), "RevisionId", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.connection_type),
|
||||||
|
"ConnectionType", acpi_gbl_ct_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.producer_consumer),
|
||||||
|
"ProducerConsumer", acpi_gbl_consume_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.pin_config), "PinConfig",
|
||||||
|
acpi_gbl_ppc_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.sharable), "Sharing",
|
||||||
|
acpi_gbl_shr_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.io_restriction),
|
||||||
|
"IoRestriction", acpi_gbl_ior_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.triggering), "Triggering",
|
||||||
|
acpi_gbl_he_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.polarity), "Polarity",
|
||||||
|
acpi_gbl_ll_decode},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.drive_strength), "DriveStrength",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.debounce_timeout),
|
||||||
|
"DebounceTimeout", NULL},
|
||||||
|
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(gpio.resource_source),
|
||||||
|
"ResourceSource", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.pin_table_length),
|
||||||
|
"PinTableLength", NULL},
|
||||||
|
{ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET(gpio.pin_table), "PinTable", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.vendor_length), "VendorLength",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_SHORTLISTX, ACPI_RSD_OFFSET(gpio.vendor_data), "VendorData",
|
||||||
|
NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_fixed_dma[4] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_dma),
|
||||||
|
"FixedDma", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.request_lines),
|
||||||
|
"RequestLines", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.channels), "Channels",
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_dma.width), "TransferWidth",
|
||||||
|
acpi_gbl_dts_decode},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ACPI_RS_DUMP_COMMON_SERIAL_BUS \
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.revision_id), "RevisionId", NULL}, \
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.type), "Type", acpi_gbl_sbt_decode}, \
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.producer_consumer), "ProducerConsumer", acpi_gbl_consume_decode}, \
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.slave_mode), "SlaveMode", acpi_gbl_sm_decode}, \
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.type_revision_id), "TypeRevisionId", NULL}, \
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET (common_serial_bus.type_data_length), "TypeDataLength", NULL}, \
|
||||||
|
{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (common_serial_bus.resource_source), "ResourceSource", NULL}, \
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET (common_serial_bus.vendor_length), "VendorLength", NULL}, \
|
||||||
|
{ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (common_serial_bus.vendor_data), "VendorData", NULL},
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[10] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_common_serial_bus),
|
||||||
|
"Common Serial Bus", NULL},
|
||||||
|
ACPI_RS_DUMP_COMMON_SERIAL_BUS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[13] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_i2c_serial_bus),
|
||||||
|
"I2C Serial Bus", NULL},
|
||||||
|
ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
|
||||||
|
ACPI_RSD_OFFSET(i2c_serial_bus.
|
||||||
|
access_mode),
|
||||||
|
"AccessMode", acpi_gbl_am_decode},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(i2c_serial_bus.connection_speed),
|
||||||
|
"ConnectionSpeed", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(i2c_serial_bus.slave_address),
|
||||||
|
"SlaveAddress", NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[17] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_spi_serial_bus),
|
||||||
|
"Spi Serial Bus", NULL},
|
||||||
|
ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
|
||||||
|
ACPI_RSD_OFFSET(spi_serial_bus.
|
||||||
|
wire_mode), "WireMode",
|
||||||
|
acpi_gbl_wm_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(spi_serial_bus.device_polarity),
|
||||||
|
"DevicePolarity", acpi_gbl_dp_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.data_bit_length),
|
||||||
|
"DataBitLength", NULL},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_phase),
|
||||||
|
"ClockPhase", acpi_gbl_cph_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_polarity),
|
||||||
|
"ClockPolarity", acpi_gbl_cpo_decode},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(spi_serial_bus.device_selection),
|
||||||
|
"DeviceSelection", NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(spi_serial_bus.connection_speed),
|
||||||
|
"ConnectionSpeed", NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[19] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_uart_serial_bus),
|
||||||
|
"Uart Serial Bus", NULL},
|
||||||
|
ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_2BITFLAG,
|
||||||
|
ACPI_RSD_OFFSET(uart_serial_bus.
|
||||||
|
flow_control),
|
||||||
|
"FlowControl", acpi_gbl_fc_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.stop_bits),
|
||||||
|
"StopBits", acpi_gbl_sb_decode},
|
||||||
|
{ACPI_RSD_3BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.data_bits),
|
||||||
|
"DataBits", acpi_gbl_bpb_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.endian), "Endian",
|
||||||
|
acpi_gbl_ed_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.parity), "Parity",
|
||||||
|
acpi_gbl_pt_decode},
|
||||||
|
{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.lines_enabled),
|
||||||
|
"LinesEnabled", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.rx_fifo_size),
|
||||||
|
"RxFifoSize", NULL},
|
||||||
|
{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.tx_fifo_size),
|
||||||
|
"TxFifoSize", NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(uart_serial_bus.default_baud_rate),
|
||||||
|
"ConnectionSpeed", NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tables used for common address descriptor flag fields
|
||||||
|
*/
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL,
|
||||||
|
NULL},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer),
|
||||||
|
"Consumer/Producer", acpi_gbl_consume_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode",
|
||||||
|
acpi_gbl_dec_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed),
|
||||||
|
"Min Relocatability", acpi_gbl_min_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed),
|
||||||
|
"Max Relocatability", acpi_gbl_max_decode}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = {
|
||||||
|
{ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags),
|
||||||
|
"Resource Type", (void *)"Memory Range"},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect),
|
||||||
|
"Write Protect", acpi_gbl_rw_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching),
|
||||||
|
"Caching", acpi_gbl_mem_decode},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type),
|
||||||
|
"Range Type", acpi_gbl_mtp_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation),
|
||||||
|
"Translation", acpi_gbl_ttp_decode}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = {
|
||||||
|
{ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags),
|
||||||
|
"Resource Type", (void *)"I/O Range"},
|
||||||
|
{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type),
|
||||||
|
"Range Type", acpi_gbl_rng_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation),
|
||||||
|
"Translation", acpi_gbl_ttp_decode},
|
||||||
|
{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type),
|
||||||
|
"Translation Type", acpi_gbl_trs_decode}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table used to dump _PRT contents
|
||||||
|
*/
|
||||||
|
struct acpi_rsdump_info acpi_rs_dump_prt[5] = {
|
||||||
|
{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL},
|
||||||
|
{ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL},
|
||||||
|
{ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL},
|
||||||
|
{ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -48,36 +48,6 @@
|
|||||||
#define _COMPONENT ACPI_UTILITIES
|
#define _COMPONENT ACPI_UTILITIES
|
||||||
ACPI_MODULE_NAME("utmisc")
|
ACPI_MODULE_NAME("utmisc")
|
||||||
|
|
||||||
#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: ut_convert_backslashes
|
|
||||||
*
|
|
||||||
* PARAMETERS: pathname - File pathname string to be converted
|
|
||||||
*
|
|
||||||
* RETURN: Modifies the input Pathname
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
|
|
||||||
* the entire input file pathname string.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
void ut_convert_backslashes(char *pathname)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!pathname) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*pathname) {
|
|
||||||
if (*pathname == '\\') {
|
|
||||||
*pathname = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
pathname++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ut_is_pci_root_bridge
|
* FUNCTION: acpi_ut_is_pci_root_bridge
|
||||||
@ -89,7 +59,6 @@ void ut_convert_backslashes(char *pathname)
|
|||||||
* DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
|
* DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
u8 acpi_ut_is_pci_root_bridge(char *id)
|
u8 acpi_ut_is_pci_root_bridge(char *id)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -134,362 +103,6 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_allocate_owner_id
|
|
||||||
*
|
|
||||||
* PARAMETERS: owner_id - Where the new owner ID is returned
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
|
|
||||||
* track objects created by the table or method, to be deleted
|
|
||||||
* when the method exits or the table is unloaded.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
u32 j;
|
|
||||||
u32 k;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
|
|
||||||
|
|
||||||
/* Guard against multiple allocations of ID to the same location */
|
|
||||||
|
|
||||||
if (*owner_id) {
|
|
||||||
ACPI_ERROR((AE_INFO, "Owner ID [0x%2.2X] already exists",
|
|
||||||
*owner_id));
|
|
||||||
return_ACPI_STATUS(AE_ALREADY_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mutex for the global ID mask */
|
|
||||||
|
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find a free owner ID, cycle through all possible IDs on repeated
|
|
||||||
* allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
|
|
||||||
* to be scanned twice.
|
|
||||||
*/
|
|
||||||
for (i = 0, j = acpi_gbl_last_owner_id_index;
|
|
||||||
i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
|
|
||||||
if (j >= ACPI_NUM_OWNERID_MASKS) {
|
|
||||||
j = 0; /* Wraparound to start of mask array */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
|
|
||||||
if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
|
|
||||||
|
|
||||||
/* There are no free IDs in this mask */
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
|
|
||||||
/*
|
|
||||||
* Found a free ID. The actual ID is the bit index plus one,
|
|
||||||
* making zero an invalid Owner ID. Save this as the last ID
|
|
||||||
* allocated and update the global ID mask.
|
|
||||||
*/
|
|
||||||
acpi_gbl_owner_id_mask[j] |= (1 << k);
|
|
||||||
|
|
||||||
acpi_gbl_last_owner_id_index = (u8)j;
|
|
||||||
acpi_gbl_next_owner_id_offset = (u8)(k + 1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Construct encoded ID from the index and bit position
|
|
||||||
*
|
|
||||||
* Note: Last [j].k (bit 255) is never used and is marked
|
|
||||||
* permanently allocated (prevents +1 overflow)
|
|
||||||
*/
|
|
||||||
*owner_id =
|
|
||||||
(acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
|
|
||||||
"Allocated OwnerId: %2.2X\n",
|
|
||||||
(unsigned int)*owner_id));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_gbl_next_owner_id_offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* All owner_ids have been allocated. This typically should
|
|
||||||
* not happen since the IDs are reused after deallocation. The IDs are
|
|
||||||
* allocated upon table load (one per table) and method execution, and
|
|
||||||
* they are released when a table is unloaded or a method completes
|
|
||||||
* execution.
|
|
||||||
*
|
|
||||||
* If this error happens, there may be very deep nesting of invoked control
|
|
||||||
* methods, or there may be a bug where the IDs are not released.
|
|
||||||
*/
|
|
||||||
status = AE_OWNER_ID_LIMIT;
|
|
||||||
ACPI_ERROR((AE_INFO,
|
|
||||||
"Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
|
|
||||||
|
|
||||||
exit:
|
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_release_owner_id
|
|
||||||
*
|
|
||||||
* PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_ID
|
|
||||||
*
|
|
||||||
* RETURN: None. No error is returned because we are either exiting a
|
|
||||||
* control method or unloading a table. Either way, we would
|
|
||||||
* ignore any error anyway.
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
|
|
||||||
{
|
|
||||||
acpi_owner_id owner_id = *owner_id_ptr;
|
|
||||||
acpi_status status;
|
|
||||||
u32 index;
|
|
||||||
u32 bit;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
|
|
||||||
|
|
||||||
/* Always clear the input owner_id (zero is an invalid ID) */
|
|
||||||
|
|
||||||
*owner_id_ptr = 0;
|
|
||||||
|
|
||||||
/* Zero is not a valid owner_ID */
|
|
||||||
|
|
||||||
if (owner_id == 0) {
|
|
||||||
ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%2.2X", owner_id));
|
|
||||||
return_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mutex for the global ID mask */
|
|
||||||
|
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Normalize the ID to zero */
|
|
||||||
|
|
||||||
owner_id--;
|
|
||||||
|
|
||||||
/* Decode ID to index/offset pair */
|
|
||||||
|
|
||||||
index = ACPI_DIV_32(owner_id);
|
|
||||||
bit = 1 << ACPI_MOD_32(owner_id);
|
|
||||||
|
|
||||||
/* Free the owner ID only if it is valid */
|
|
||||||
|
|
||||||
if (acpi_gbl_owner_id_mask[index] & bit) {
|
|
||||||
acpi_gbl_owner_id_mask[index] ^= bit;
|
|
||||||
} else {
|
|
||||||
ACPI_ERROR((AE_INFO,
|
|
||||||
"Release of non-allocated OwnerId: 0x%2.2X",
|
|
||||||
owner_id + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
|
|
||||||
return_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_strupr (strupr)
|
|
||||||
*
|
|
||||||
* PARAMETERS: src_string - The source string to convert
|
|
||||||
*
|
|
||||||
* RETURN: None
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Convert string to uppercase
|
|
||||||
*
|
|
||||||
* NOTE: This is not a POSIX function, so it appears here, not in utclib.c
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void acpi_ut_strupr(char *src_string)
|
|
||||||
{
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_ENTRY();
|
|
||||||
|
|
||||||
if (!src_string) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk entire string, uppercasing the letters */
|
|
||||||
|
|
||||||
for (string = src_string; *string; string++) {
|
|
||||||
*string = (char)ACPI_TOUPPER(*string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ACPI_ASL_COMPILER
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_strlwr (strlwr)
|
|
||||||
*
|
|
||||||
* PARAMETERS: src_string - The source string to convert
|
|
||||||
*
|
|
||||||
* RETURN: None
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Convert string to lowercase
|
|
||||||
*
|
|
||||||
* NOTE: This is not a POSIX function, so it appears here, not in utclib.c
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void acpi_ut_strlwr(char *src_string)
|
|
||||||
{
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_ENTRY();
|
|
||||||
|
|
||||||
if (!src_string) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk entire string, lowercasing the letters */
|
|
||||||
|
|
||||||
for (string = src_string; *string; string++) {
|
|
||||||
*string = (char)ACPI_TOLOWER(*string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_stricmp
|
|
||||||
*
|
|
||||||
* PARAMETERS: string1 - first string to compare
|
|
||||||
* string2 - second string to compare
|
|
||||||
*
|
|
||||||
* RETURN: int that signifies string relationship. Zero means strings
|
|
||||||
* are equal.
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
|
|
||||||
* strings with no case sensitivity)
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
int acpi_ut_stricmp(char *string1, char *string2)
|
|
||||||
{
|
|
||||||
int c1;
|
|
||||||
int c2;
|
|
||||||
|
|
||||||
do {
|
|
||||||
c1 = tolower((int)*string1);
|
|
||||||
c2 = tolower((int)*string2);
|
|
||||||
|
|
||||||
string1++;
|
|
||||||
string2++;
|
|
||||||
}
|
|
||||||
while ((c1 == c2) && (c1));
|
|
||||||
|
|
||||||
return (c1 - c2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_print_string
|
|
||||||
*
|
|
||||||
* PARAMETERS: string - Null terminated ASCII string
|
|
||||||
* max_length - Maximum output length
|
|
||||||
*
|
|
||||||
* RETURN: None
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
|
|
||||||
* sequences.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void acpi_ut_print_string(char *string, u8 max_length)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
if (!string) {
|
|
||||||
acpi_os_printf("<\"NULL STRING PTR\">");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
acpi_os_printf("\"");
|
|
||||||
for (i = 0; string[i] && (i < max_length); i++) {
|
|
||||||
|
|
||||||
/* Escape sequences */
|
|
||||||
|
|
||||||
switch (string[i]) {
|
|
||||||
case 0x07:
|
|
||||||
acpi_os_printf("\\a"); /* BELL */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x08:
|
|
||||||
acpi_os_printf("\\b"); /* BACKSPACE */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0C:
|
|
||||||
acpi_os_printf("\\f"); /* FORMFEED */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0A:
|
|
||||||
acpi_os_printf("\\n"); /* LINEFEED */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0D:
|
|
||||||
acpi_os_printf("\\r"); /* CARRIAGE RETURN */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x09:
|
|
||||||
acpi_os_printf("\\t"); /* HORIZONTAL TAB */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0B:
|
|
||||||
acpi_os_printf("\\v"); /* VERTICAL TAB */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\'': /* Single Quote */
|
|
||||||
case '\"': /* Double Quote */
|
|
||||||
case '\\': /* Backslash */
|
|
||||||
acpi_os_printf("\\%c", (int)string[i]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
/* Check for printable character or hex escape */
|
|
||||||
|
|
||||||
if (ACPI_IS_PRINT(string[i])) {
|
|
||||||
/* This is a normal character */
|
|
||||||
|
|
||||||
acpi_os_printf("%c", (int)string[i]);
|
|
||||||
} else {
|
|
||||||
/* All others will be Hex escapes */
|
|
||||||
|
|
||||||
acpi_os_printf("\\x%2.2X", (s32) string[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
acpi_os_printf("\"");
|
|
||||||
|
|
||||||
if (i == max_length && string[i]) {
|
|
||||||
acpi_os_printf("...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ut_dword_byte_swap
|
* FUNCTION: acpi_ut_dword_byte_swap
|
||||||
@ -559,379 +172,6 @@ void acpi_ut_set_integer_width(u8 revision)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ACPI_DEBUG_OUTPUT
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_display_init_pathname
|
|
||||||
*
|
|
||||||
* PARAMETERS: type - Object type of the node
|
|
||||||
* obj_handle - Handle whose pathname will be displayed
|
|
||||||
* path - Additional path string to be appended.
|
|
||||||
* (NULL if no extra path)
|
|
||||||
*
|
|
||||||
* RETURN: acpi_status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Display full pathname of an object, DEBUG ONLY
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void
|
|
||||||
acpi_ut_display_init_pathname(u8 type,
|
|
||||||
struct acpi_namespace_node *obj_handle,
|
|
||||||
char *path)
|
|
||||||
{
|
|
||||||
acpi_status status;
|
|
||||||
struct acpi_buffer buffer;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_ENTRY();
|
|
||||||
|
|
||||||
/* Only print the path if the appropriate debug level is enabled */
|
|
||||||
|
|
||||||
if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the full pathname to the node */
|
|
||||||
|
|
||||||
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
|
||||||
status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print what we're doing */
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case ACPI_TYPE_METHOD:
|
|
||||||
acpi_os_printf("Executing ");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
acpi_os_printf("Initializing ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print the object type and pathname */
|
|
||||||
|
|
||||||
acpi_os_printf("%-12s %s",
|
|
||||||
acpi_ut_get_type_name(type), (char *)buffer.pointer);
|
|
||||||
|
|
||||||
/* Extra path is used to append names like _STA, _INI, etc. */
|
|
||||||
|
|
||||||
if (path) {
|
|
||||||
acpi_os_printf(".%s", path);
|
|
||||||
}
|
|
||||||
acpi_os_printf("\n");
|
|
||||||
|
|
||||||
ACPI_FREE(buffer.pointer);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_valid_acpi_char
|
|
||||||
*
|
|
||||||
* PARAMETERS: char - The character to be examined
|
|
||||||
* position - Byte position (0-3)
|
|
||||||
*
|
|
||||||
* RETURN: TRUE if the character is valid, FALSE otherwise
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Check for a valid ACPI character. Must be one of:
|
|
||||||
* 1) Upper case alpha
|
|
||||||
* 2) numeric
|
|
||||||
* 3) underscore
|
|
||||||
*
|
|
||||||
* We allow a '!' as the last character because of the ASF! table
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
u8 acpi_ut_valid_acpi_char(char character, u32 position)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!((character >= 'A' && character <= 'Z') ||
|
|
||||||
(character >= '0' && character <= '9') || (character == '_'))) {
|
|
||||||
|
|
||||||
/* Allow a '!' in the last position */
|
|
||||||
|
|
||||||
if (character == '!' && position == 3) {
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_valid_acpi_name
|
|
||||||
*
|
|
||||||
* PARAMETERS: name - The name to be examined
|
|
||||||
*
|
|
||||||
* RETURN: TRUE if the name is valid, FALSE otherwise
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
|
|
||||||
* 1) Upper case alpha
|
|
||||||
* 2) numeric
|
|
||||||
* 3) underscore
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
u8 acpi_ut_valid_acpi_name(u32 name)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_ENTRY();
|
|
||||||
|
|
||||||
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
|
||||||
if (!acpi_ut_valid_acpi_char
|
|
||||||
((ACPI_CAST_PTR(char, &name))[i], i)) {
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_repair_name
|
|
||||||
*
|
|
||||||
* PARAMETERS: name - The ACPI name to be repaired
|
|
||||||
*
|
|
||||||
* RETURN: Repaired version of the name
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
|
|
||||||
* return the new name. NOTE: the Name parameter must reside in
|
|
||||||
* read/write memory, cannot be a const.
|
|
||||||
*
|
|
||||||
* An ACPI Name must consist of valid ACPI characters. We will repair the name
|
|
||||||
* if necessary because we don't want to abort because of this, but we want
|
|
||||||
* all namespace names to be printable. A warning message is appropriate.
|
|
||||||
*
|
|
||||||
* This issue came up because there are in fact machines that exhibit
|
|
||||||
* this problem, and we want to be able to enable ACPI support for them,
|
|
||||||
* even though there are a few bad names.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void acpi_ut_repair_name(char *name)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
u8 found_bad_char = FALSE;
|
|
||||||
u32 original_name;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_NAME(ut_repair_name);
|
|
||||||
|
|
||||||
ACPI_MOVE_NAME(&original_name, name);
|
|
||||||
|
|
||||||
/* Check each character in the name */
|
|
||||||
|
|
||||||
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
|
||||||
if (acpi_ut_valid_acpi_char(name[i], i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Replace a bad character with something printable, yet technically
|
|
||||||
* still invalid. This prevents any collisions with existing "good"
|
|
||||||
* names in the namespace.
|
|
||||||
*/
|
|
||||||
name[i] = '*';
|
|
||||||
found_bad_char = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_bad_char) {
|
|
||||||
|
|
||||||
/* Report warning only if in strict mode or debug mode */
|
|
||||||
|
|
||||||
if (!acpi_gbl_enable_interpreter_slack) {
|
|
||||||
ACPI_WARNING((AE_INFO,
|
|
||||||
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
|
|
||||||
original_name, name));
|
|
||||||
} else {
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
||||||
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
|
|
||||||
original_name, name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_strtoul64
|
|
||||||
*
|
|
||||||
* PARAMETERS: string - Null terminated string
|
|
||||||
* base - Radix of the string: 16 or ACPI_ANY_BASE;
|
|
||||||
* ACPI_ANY_BASE means 'in behalf of to_integer'
|
|
||||||
* ret_integer - Where the converted integer is returned
|
|
||||||
*
|
|
||||||
* RETURN: Status and Converted value
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Convert a string into an unsigned value. Performs either a
|
|
||||||
* 32-bit or 64-bit conversion, depending on the current mode
|
|
||||||
* of the interpreter.
|
|
||||||
* NOTE: Does not support Octal strings, not needed.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
|
|
||||||
{
|
|
||||||
u32 this_digit = 0;
|
|
||||||
u64 return_value = 0;
|
|
||||||
u64 quotient;
|
|
||||||
u64 dividend;
|
|
||||||
u32 to_integer_op = (base == ACPI_ANY_BASE);
|
|
||||||
u32 mode32 = (acpi_gbl_integer_byte_width == 4);
|
|
||||||
u8 valid_digits = 0;
|
|
||||||
u8 sign_of0x = 0;
|
|
||||||
u8 term = 0;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
|
|
||||||
|
|
||||||
switch (base) {
|
|
||||||
case ACPI_ANY_BASE:
|
|
||||||
case 16:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Invalid Base */
|
|
||||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string) {
|
|
||||||
goto error_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip over any white space in the buffer */
|
|
||||||
|
|
||||||
while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
|
|
||||||
string++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to_integer_op) {
|
|
||||||
/*
|
|
||||||
* Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
|
|
||||||
* We need to determine if it is decimal or hexadecimal.
|
|
||||||
*/
|
|
||||||
if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
|
|
||||||
sign_of0x = 1;
|
|
||||||
base = 16;
|
|
||||||
|
|
||||||
/* Skip over the leading '0x' */
|
|
||||||
string += 2;
|
|
||||||
} else {
|
|
||||||
base = 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Any string left? Check that '0x' is not followed by white space. */
|
|
||||||
|
|
||||||
if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
|
|
||||||
if (to_integer_op) {
|
|
||||||
goto error_exit;
|
|
||||||
} else {
|
|
||||||
goto all_done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform a 32-bit or 64-bit conversion, depending upon the current
|
|
||||||
* execution mode of the interpreter
|
|
||||||
*/
|
|
||||||
dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
|
|
||||||
|
|
||||||
/* Main loop: convert the string to a 32- or 64-bit integer */
|
|
||||||
|
|
||||||
while (*string) {
|
|
||||||
if (ACPI_IS_DIGIT(*string)) {
|
|
||||||
|
|
||||||
/* Convert ASCII 0-9 to Decimal value */
|
|
||||||
|
|
||||||
this_digit = ((u8)*string) - '0';
|
|
||||||
} else if (base == 10) {
|
|
||||||
|
|
||||||
/* Digit is out of range; possible in to_integer case only */
|
|
||||||
|
|
||||||
term = 1;
|
|
||||||
} else {
|
|
||||||
this_digit = (u8)ACPI_TOUPPER(*string);
|
|
||||||
if (ACPI_IS_XDIGIT((char)this_digit)) {
|
|
||||||
|
|
||||||
/* Convert ASCII Hex char to value */
|
|
||||||
|
|
||||||
this_digit = this_digit - 'A' + 10;
|
|
||||||
} else {
|
|
||||||
term = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (term) {
|
|
||||||
if (to_integer_op) {
|
|
||||||
goto error_exit;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if ((valid_digits == 0) && (this_digit == 0)
|
|
||||||
&& !sign_of0x) {
|
|
||||||
|
|
||||||
/* Skip zeros */
|
|
||||||
string++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_digits++;
|
|
||||||
|
|
||||||
if (sign_of0x
|
|
||||||
&& ((valid_digits > 16)
|
|
||||||
|| ((valid_digits > 8) && mode32))) {
|
|
||||||
/*
|
|
||||||
* This is to_integer operation case.
|
|
||||||
* No any restrictions for string-to-integer conversion,
|
|
||||||
* see ACPI spec.
|
|
||||||
*/
|
|
||||||
goto error_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Divide the digit into the correct position */
|
|
||||||
|
|
||||||
(void)acpi_ut_short_divide((dividend - (u64)this_digit),
|
|
||||||
base, "ient, NULL);
|
|
||||||
|
|
||||||
if (return_value > quotient) {
|
|
||||||
if (to_integer_op) {
|
|
||||||
goto error_exit;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return_value *= base;
|
|
||||||
return_value += this_digit;
|
|
||||||
string++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All done, normal exit */
|
|
||||||
|
|
||||||
all_done:
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
|
|
||||||
ACPI_FORMAT_UINT64(return_value)));
|
|
||||||
|
|
||||||
*ret_integer = return_value;
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
|
||||||
|
|
||||||
error_exit:
|
|
||||||
/* Base was set/validated above */
|
|
||||||
|
|
||||||
if (base == 10) {
|
|
||||||
return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
|
|
||||||
} else {
|
|
||||||
return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ut_create_update_state_and_push
|
* FUNCTION: acpi_ut_create_update_state_and_push
|
||||||
@ -1097,3 +337,71 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
|
|||||||
|
|
||||||
return_ACPI_STATUS(AE_AML_INTERNAL);
|
return_ACPI_STATUS(AE_AML_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ACPI_DEBUG_OUTPUT
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_display_init_pathname
|
||||||
|
*
|
||||||
|
* PARAMETERS: type - Object type of the node
|
||||||
|
* obj_handle - Handle whose pathname will be displayed
|
||||||
|
* path - Additional path string to be appended.
|
||||||
|
* (NULL if no extra path)
|
||||||
|
*
|
||||||
|
* RETURN: acpi_status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Display full pathname of an object, DEBUG ONLY
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
acpi_ut_display_init_pathname(u8 type,
|
||||||
|
struct acpi_namespace_node *obj_handle,
|
||||||
|
char *path)
|
||||||
|
{
|
||||||
|
acpi_status status;
|
||||||
|
struct acpi_buffer buffer;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_ENTRY();
|
||||||
|
|
||||||
|
/* Only print the path if the appropriate debug level is enabled */
|
||||||
|
|
||||||
|
if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the full pathname to the node */
|
||||||
|
|
||||||
|
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
||||||
|
status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print what we're doing */
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ACPI_TYPE_METHOD:
|
||||||
|
acpi_os_printf("Executing ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
acpi_os_printf("Initializing ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the object type and pathname */
|
||||||
|
|
||||||
|
acpi_os_printf("%-12s %s",
|
||||||
|
acpi_ut_get_type_name(type), (char *)buffer.pointer);
|
||||||
|
|
||||||
|
/* Extra path is used to append names like _STA, _INI, etc. */
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
acpi_os_printf(".%s", path);
|
||||||
|
}
|
||||||
|
acpi_os_printf("\n");
|
||||||
|
|
||||||
|
ACPI_FREE(buffer.pointer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
218
drivers/acpi/acpica/utownerid.c
Normal file
218
drivers/acpi/acpica/utownerid.c
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: utownerid - Support for Table/Method Owner IDs
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_UTILITIES
|
||||||
|
ACPI_MODULE_NAME("utownerid")
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_allocate_owner_id
|
||||||
|
*
|
||||||
|
* PARAMETERS: owner_id - Where the new owner ID is returned
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
|
||||||
|
* track objects created by the table or method, to be deleted
|
||||||
|
* when the method exits or the table is unloaded.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
u32 j;
|
||||||
|
u32 k;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
|
||||||
|
|
||||||
|
/* Guard against multiple allocations of ID to the same location */
|
||||||
|
|
||||||
|
if (*owner_id) {
|
||||||
|
ACPI_ERROR((AE_INFO, "Owner ID [0x%2.2X] already exists",
|
||||||
|
*owner_id));
|
||||||
|
return_ACPI_STATUS(AE_ALREADY_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mutex for the global ID mask */
|
||||||
|
|
||||||
|
status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a free owner ID, cycle through all possible IDs on repeated
|
||||||
|
* allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
|
||||||
|
* to be scanned twice.
|
||||||
|
*/
|
||||||
|
for (i = 0, j = acpi_gbl_last_owner_id_index;
|
||||||
|
i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
|
||||||
|
if (j >= ACPI_NUM_OWNERID_MASKS) {
|
||||||
|
j = 0; /* Wraparound to start of mask array */
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
|
||||||
|
if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
|
||||||
|
|
||||||
|
/* There are no free IDs in this mask */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
|
||||||
|
/*
|
||||||
|
* Found a free ID. The actual ID is the bit index plus one,
|
||||||
|
* making zero an invalid Owner ID. Save this as the last ID
|
||||||
|
* allocated and update the global ID mask.
|
||||||
|
*/
|
||||||
|
acpi_gbl_owner_id_mask[j] |= (1 << k);
|
||||||
|
|
||||||
|
acpi_gbl_last_owner_id_index = (u8)j;
|
||||||
|
acpi_gbl_next_owner_id_offset = (u8)(k + 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct encoded ID from the index and bit position
|
||||||
|
*
|
||||||
|
* Note: Last [j].k (bit 255) is never used and is marked
|
||||||
|
* permanently allocated (prevents +1 overflow)
|
||||||
|
*/
|
||||||
|
*owner_id =
|
||||||
|
(acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
|
||||||
|
"Allocated OwnerId: %2.2X\n",
|
||||||
|
(unsigned int)*owner_id));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_gbl_next_owner_id_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All owner_ids have been allocated. This typically should
|
||||||
|
* not happen since the IDs are reused after deallocation. The IDs are
|
||||||
|
* allocated upon table load (one per table) and method execution, and
|
||||||
|
* they are released when a table is unloaded or a method completes
|
||||||
|
* execution.
|
||||||
|
*
|
||||||
|
* If this error happens, there may be very deep nesting of invoked control
|
||||||
|
* methods, or there may be a bug where the IDs are not released.
|
||||||
|
*/
|
||||||
|
status = AE_OWNER_ID_LIMIT;
|
||||||
|
ACPI_ERROR((AE_INFO,
|
||||||
|
"Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
|
||||||
|
|
||||||
|
exit:
|
||||||
|
(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_release_owner_id
|
||||||
|
*
|
||||||
|
* PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_ID
|
||||||
|
*
|
||||||
|
* RETURN: None. No error is returned because we are either exiting a
|
||||||
|
* control method or unloading a table. Either way, we would
|
||||||
|
* ignore any error anyway.
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
|
||||||
|
{
|
||||||
|
acpi_owner_id owner_id = *owner_id_ptr;
|
||||||
|
acpi_status status;
|
||||||
|
u32 index;
|
||||||
|
u32 bit;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
|
||||||
|
|
||||||
|
/* Always clear the input owner_id (zero is an invalid ID) */
|
||||||
|
|
||||||
|
*owner_id_ptr = 0;
|
||||||
|
|
||||||
|
/* Zero is not a valid owner_ID */
|
||||||
|
|
||||||
|
if (owner_id == 0) {
|
||||||
|
ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%2.2X", owner_id));
|
||||||
|
return_VOID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mutex for the global ID mask */
|
||||||
|
|
||||||
|
status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_VOID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normalize the ID to zero */
|
||||||
|
|
||||||
|
owner_id--;
|
||||||
|
|
||||||
|
/* Decode ID to index/offset pair */
|
||||||
|
|
||||||
|
index = ACPI_DIV_32(owner_id);
|
||||||
|
bit = 1 << ACPI_MOD_32(owner_id);
|
||||||
|
|
||||||
|
/* Free the owner ID only if it is valid */
|
||||||
|
|
||||||
|
if (acpi_gbl_owner_id_mask[index] & bit) {
|
||||||
|
acpi_gbl_owner_id_mask[index] ^= bit;
|
||||||
|
} else {
|
||||||
|
ACPI_ERROR((AE_INFO,
|
||||||
|
"Release of non-allocated OwnerId: 0x%2.2X",
|
||||||
|
owner_id + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
|
||||||
|
return_VOID;
|
||||||
|
}
|
574
drivers/acpi/acpica/utstring.c
Normal file
574
drivers/acpi/acpica/utstring.c
Normal file
@ -0,0 +1,574 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: utstring - Common functions for strings and characters
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2012, 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"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_UTILITIES
|
||||||
|
ACPI_MODULE_NAME("utstring")
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
|
||||||
|
* version of strtoul.
|
||||||
|
*/
|
||||||
|
#ifdef ACPI_ASL_COMPILER
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_strlwr (strlwr)
|
||||||
|
*
|
||||||
|
* PARAMETERS: src_string - The source string to convert
|
||||||
|
*
|
||||||
|
* RETURN: None
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Convert string to lowercase
|
||||||
|
*
|
||||||
|
* NOTE: This is not a POSIX function, so it appears here, not in utclib.c
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
void acpi_ut_strlwr(char *src_string)
|
||||||
|
{
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_ENTRY();
|
||||||
|
|
||||||
|
if (!src_string) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk entire string, lowercasing the letters */
|
||||||
|
|
||||||
|
for (string = src_string; *string; string++) {
|
||||||
|
*string = (char)ACPI_TOLOWER(*string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_stricmp (stricmp)
|
||||||
|
*
|
||||||
|
* PARAMETERS: string1 - first string to compare
|
||||||
|
* string2 - second string to compare
|
||||||
|
*
|
||||||
|
* RETURN: int that signifies string relationship. Zero means strings
|
||||||
|
* are equal.
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
|
||||||
|
* strings with no case sensitivity)
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
int acpi_ut_stricmp(char *string1, char *string2)
|
||||||
|
{
|
||||||
|
int c1;
|
||||||
|
int c2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c1 = tolower((int)*string1);
|
||||||
|
c2 = tolower((int)*string2);
|
||||||
|
|
||||||
|
string1++;
|
||||||
|
string2++;
|
||||||
|
}
|
||||||
|
while ((c1 == c2) && (c1));
|
||||||
|
|
||||||
|
return (c1 - c2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_strupr (strupr)
|
||||||
|
*
|
||||||
|
* PARAMETERS: src_string - The source string to convert
|
||||||
|
*
|
||||||
|
* RETURN: None
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Convert string to uppercase
|
||||||
|
*
|
||||||
|
* NOTE: This is not a POSIX function, so it appears here, not in utclib.c
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void acpi_ut_strupr(char *src_string)
|
||||||
|
{
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_ENTRY();
|
||||||
|
|
||||||
|
if (!src_string) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk entire string, uppercasing the letters */
|
||||||
|
|
||||||
|
for (string = src_string; *string; string++) {
|
||||||
|
*string = (char)ACPI_TOUPPER(*string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_strtoul64
|
||||||
|
*
|
||||||
|
* PARAMETERS: string - Null terminated string
|
||||||
|
* base - Radix of the string: 16 or ACPI_ANY_BASE;
|
||||||
|
* ACPI_ANY_BASE means 'in behalf of to_integer'
|
||||||
|
* ret_integer - Where the converted integer is returned
|
||||||
|
*
|
||||||
|
* RETURN: Status and Converted value
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Convert a string into an unsigned value. Performs either a
|
||||||
|
* 32-bit or 64-bit conversion, depending on the current mode
|
||||||
|
* of the interpreter.
|
||||||
|
* NOTE: Does not support Octal strings, not needed.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
|
||||||
|
{
|
||||||
|
u32 this_digit = 0;
|
||||||
|
u64 return_value = 0;
|
||||||
|
u64 quotient;
|
||||||
|
u64 dividend;
|
||||||
|
u32 to_integer_op = (base == ACPI_ANY_BASE);
|
||||||
|
u32 mode32 = (acpi_gbl_integer_byte_width == 4);
|
||||||
|
u8 valid_digits = 0;
|
||||||
|
u8 sign_of0x = 0;
|
||||||
|
u8 term = 0;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
|
||||||
|
|
||||||
|
switch (base) {
|
||||||
|
case ACPI_ANY_BASE:
|
||||||
|
case 16:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Invalid Base */
|
||||||
|
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string) {
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip over any white space in the buffer */
|
||||||
|
|
||||||
|
while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
|
||||||
|
string++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_integer_op) {
|
||||||
|
/*
|
||||||
|
* Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
|
||||||
|
* We need to determine if it is decimal or hexadecimal.
|
||||||
|
*/
|
||||||
|
if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
|
||||||
|
sign_of0x = 1;
|
||||||
|
base = 16;
|
||||||
|
|
||||||
|
/* Skip over the leading '0x' */
|
||||||
|
string += 2;
|
||||||
|
} else {
|
||||||
|
base = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Any string left? Check that '0x' is not followed by white space. */
|
||||||
|
|
||||||
|
if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
|
||||||
|
if (to_integer_op) {
|
||||||
|
goto error_exit;
|
||||||
|
} else {
|
||||||
|
goto all_done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform a 32-bit or 64-bit conversion, depending upon the current
|
||||||
|
* execution mode of the interpreter
|
||||||
|
*/
|
||||||
|
dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
|
||||||
|
|
||||||
|
/* Main loop: convert the string to a 32- or 64-bit integer */
|
||||||
|
|
||||||
|
while (*string) {
|
||||||
|
if (ACPI_IS_DIGIT(*string)) {
|
||||||
|
|
||||||
|
/* Convert ASCII 0-9 to Decimal value */
|
||||||
|
|
||||||
|
this_digit = ((u8)*string) - '0';
|
||||||
|
} else if (base == 10) {
|
||||||
|
|
||||||
|
/* Digit is out of range; possible in to_integer case only */
|
||||||
|
|
||||||
|
term = 1;
|
||||||
|
} else {
|
||||||
|
this_digit = (u8)ACPI_TOUPPER(*string);
|
||||||
|
if (ACPI_IS_XDIGIT((char)this_digit)) {
|
||||||
|
|
||||||
|
/* Convert ASCII Hex char to value */
|
||||||
|
|
||||||
|
this_digit = this_digit - 'A' + 10;
|
||||||
|
} else {
|
||||||
|
term = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (term) {
|
||||||
|
if (to_integer_op) {
|
||||||
|
goto error_exit;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if ((valid_digits == 0) && (this_digit == 0)
|
||||||
|
&& !sign_of0x) {
|
||||||
|
|
||||||
|
/* Skip zeros */
|
||||||
|
string++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_digits++;
|
||||||
|
|
||||||
|
if (sign_of0x
|
||||||
|
&& ((valid_digits > 16)
|
||||||
|
|| ((valid_digits > 8) && mode32))) {
|
||||||
|
/*
|
||||||
|
* This is to_integer operation case.
|
||||||
|
* No any restrictions for string-to-integer conversion,
|
||||||
|
* see ACPI spec.
|
||||||
|
*/
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Divide the digit into the correct position */
|
||||||
|
|
||||||
|
(void)acpi_ut_short_divide((dividend - (u64)this_digit),
|
||||||
|
base, "ient, NULL);
|
||||||
|
|
||||||
|
if (return_value > quotient) {
|
||||||
|
if (to_integer_op) {
|
||||||
|
goto error_exit;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return_value *= base;
|
||||||
|
return_value += this_digit;
|
||||||
|
string++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All done, normal exit */
|
||||||
|
|
||||||
|
all_done:
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
|
||||||
|
ACPI_FORMAT_UINT64(return_value)));
|
||||||
|
|
||||||
|
*ret_integer = return_value;
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
|
||||||
|
error_exit:
|
||||||
|
/* Base was set/validated above */
|
||||||
|
|
||||||
|
if (base == 10) {
|
||||||
|
return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
|
||||||
|
} else {
|
||||||
|
return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_print_string
|
||||||
|
*
|
||||||
|
* PARAMETERS: string - Null terminated ASCII string
|
||||||
|
* max_length - Maximum output length
|
||||||
|
*
|
||||||
|
* RETURN: None
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
|
||||||
|
* sequences.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void acpi_ut_print_string(char *string, u8 max_length)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
if (!string) {
|
||||||
|
acpi_os_printf("<\"NULL STRING PTR\">");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_os_printf("\"");
|
||||||
|
for (i = 0; string[i] && (i < max_length); i++) {
|
||||||
|
|
||||||
|
/* Escape sequences */
|
||||||
|
|
||||||
|
switch (string[i]) {
|
||||||
|
case 0x07:
|
||||||
|
acpi_os_printf("\\a"); /* BELL */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x08:
|
||||||
|
acpi_os_printf("\\b"); /* BACKSPACE */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0C:
|
||||||
|
acpi_os_printf("\\f"); /* FORMFEED */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0A:
|
||||||
|
acpi_os_printf("\\n"); /* LINEFEED */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0D:
|
||||||
|
acpi_os_printf("\\r"); /* CARRIAGE RETURN */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x09:
|
||||||
|
acpi_os_printf("\\t"); /* HORIZONTAL TAB */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0B:
|
||||||
|
acpi_os_printf("\\v"); /* VERTICAL TAB */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\'': /* Single Quote */
|
||||||
|
case '\"': /* Double Quote */
|
||||||
|
case '\\': /* Backslash */
|
||||||
|
acpi_os_printf("\\%c", (int)string[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
/* Check for printable character or hex escape */
|
||||||
|
|
||||||
|
if (ACPI_IS_PRINT(string[i])) {
|
||||||
|
/* This is a normal character */
|
||||||
|
|
||||||
|
acpi_os_printf("%c", (int)string[i]);
|
||||||
|
} else {
|
||||||
|
/* All others will be Hex escapes */
|
||||||
|
|
||||||
|
acpi_os_printf("\\x%2.2X", (s32) string[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
acpi_os_printf("\"");
|
||||||
|
|
||||||
|
if (i == max_length && string[i]) {
|
||||||
|
acpi_os_printf("...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_valid_acpi_char
|
||||||
|
*
|
||||||
|
* PARAMETERS: char - The character to be examined
|
||||||
|
* position - Byte position (0-3)
|
||||||
|
*
|
||||||
|
* RETURN: TRUE if the character is valid, FALSE otherwise
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Check for a valid ACPI character. Must be one of:
|
||||||
|
* 1) Upper case alpha
|
||||||
|
* 2) numeric
|
||||||
|
* 3) underscore
|
||||||
|
*
|
||||||
|
* We allow a '!' as the last character because of the ASF! table
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
u8 acpi_ut_valid_acpi_char(char character, u32 position)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!((character >= 'A' && character <= 'Z') ||
|
||||||
|
(character >= '0' && character <= '9') || (character == '_'))) {
|
||||||
|
|
||||||
|
/* Allow a '!' in the last position */
|
||||||
|
|
||||||
|
if (character == '!' && position == 3) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_valid_acpi_name
|
||||||
|
*
|
||||||
|
* PARAMETERS: name - The name to be examined
|
||||||
|
*
|
||||||
|
* RETURN: TRUE if the name is valid, FALSE otherwise
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
|
||||||
|
* 1) Upper case alpha
|
||||||
|
* 2) numeric
|
||||||
|
* 3) underscore
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
u8 acpi_ut_valid_acpi_name(u32 name)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_ENTRY();
|
||||||
|
|
||||||
|
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
||||||
|
if (!acpi_ut_valid_acpi_char
|
||||||
|
((ACPI_CAST_PTR(char, &name))[i], i)) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_repair_name
|
||||||
|
*
|
||||||
|
* PARAMETERS: name - The ACPI name to be repaired
|
||||||
|
*
|
||||||
|
* RETURN: Repaired version of the name
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
|
||||||
|
* return the new name. NOTE: the Name parameter must reside in
|
||||||
|
* read/write memory, cannot be a const.
|
||||||
|
*
|
||||||
|
* An ACPI Name must consist of valid ACPI characters. We will repair the name
|
||||||
|
* if necessary because we don't want to abort because of this, but we want
|
||||||
|
* all namespace names to be printable. A warning message is appropriate.
|
||||||
|
*
|
||||||
|
* This issue came up because there are in fact machines that exhibit
|
||||||
|
* this problem, and we want to be able to enable ACPI support for them,
|
||||||
|
* even though there are a few bad names.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void acpi_ut_repair_name(char *name)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
u8 found_bad_char = FALSE;
|
||||||
|
u32 original_name;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_NAME(ut_repair_name);
|
||||||
|
|
||||||
|
ACPI_MOVE_NAME(&original_name, name);
|
||||||
|
|
||||||
|
/* Check each character in the name */
|
||||||
|
|
||||||
|
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
||||||
|
if (acpi_ut_valid_acpi_char(name[i], i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replace a bad character with something printable, yet technically
|
||||||
|
* still invalid. This prevents any collisions with existing "good"
|
||||||
|
* names in the namespace.
|
||||||
|
*/
|
||||||
|
name[i] = '*';
|
||||||
|
found_bad_char = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_bad_char) {
|
||||||
|
|
||||||
|
/* Report warning only if in strict mode or debug mode */
|
||||||
|
|
||||||
|
if (!acpi_gbl_enable_interpreter_slack) {
|
||||||
|
ACPI_WARNING((AE_INFO,
|
||||||
|
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
|
||||||
|
original_name, name));
|
||||||
|
} else {
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||||
|
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
|
||||||
|
original_name, name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: ut_convert_backslashes
|
||||||
|
*
|
||||||
|
* PARAMETERS: pathname - File pathname string to be converted
|
||||||
|
*
|
||||||
|
* RETURN: Modifies the input Pathname
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
|
||||||
|
* the entire input file pathname string.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void ut_convert_backslashes(char *pathname)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!pathname) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*pathname) {
|
||||||
|
if (*pathname == '\\') {
|
||||||
|
*pathname = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
pathname++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -191,6 +191,7 @@
|
|||||||
/* Maximum space_ids for Operation Regions */
|
/* Maximum space_ids for Operation Regions */
|
||||||
|
|
||||||
#define ACPI_MAX_ADDRESS_SPACE 255
|
#define ACPI_MAX_ADDRESS_SPACE 255
|
||||||
|
#define ACPI_NUM_DEFAULT_SPACES 4
|
||||||
|
|
||||||
/* Array sizes. Used for range checking also */
|
/* Array sizes. Used for range checking also */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user