diff options
author | Bob Moore <robert.moore@intel.com> | 2013-01-11 13:08:51 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-11 13:08:51 +0100 |
commit | 42f8fb75c43cc67f06424f991009b3af674f93eb (patch) | |
tree | 01821d5eca5f97d474bee62e7f92fe481adb31b8 | |
parent | 4f8429166818dd615891990040ce13373893ee9a (diff) |
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>
-rw-r--r-- | drivers/acpi/acpica/Makefile | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/acdebug.h | 17 | ||||
-rw-r--r-- | drivers/acpi/acpica/acevents.h | 21 | ||||
-rw-r--r-- | drivers/acpi/acpica/acnamesp.h | 12 | ||||
-rw-r--r-- | drivers/acpi/acpica/acparser.h | 23 | ||||
-rw-r--r-- | drivers/acpi/acpica/acresrc.h | 6 | ||||
-rw-r--r-- | drivers/acpi/acpica/acutils.h | 50 | ||||
-rw-r--r-- | drivers/acpi/acpica/evhandler.c | 529 | ||||
-rw-r--r-- | drivers/acpi/acpica/evregion.c | 582 | ||||
-rw-r--r-- | drivers/acpi/acpica/nspredef.c | 581 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsprepkg.c | 621 | ||||
-rw-r--r-- | drivers/acpi/acpica/psloop.c | 622 | ||||
-rw-r--r-- | drivers/acpi/acpica/psobject.c | 647 | ||||
-rw-r--r-- | drivers/acpi/acpica/psopcode.c | 172 | ||||
-rw-r--r-- | drivers/acpi/acpica/psopinfo.c | 223 | ||||
-rw-r--r-- | drivers/acpi/acpica/rsdump.c | 409 | ||||
-rw-r--r-- | drivers/acpi/acpica/rsdumpinfo.c | 454 | ||||
-rw-r--r-- | drivers/acpi/acpica/utmisc.c | 828 | ||||
-rw-r--r-- | drivers/acpi/acpica/utownerid.c | 218 | ||||
-rw-r--r-- | drivers/acpi/acpica/utstring.c | 574 | ||||
-rw-r--r-- | include/acpi/acconfig.h | 1 |
21 files changed, 3495 insertions, 3103 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index bc7a03ded06..a1b9bf5085a 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -31,6 +31,7 @@ acpi-y += \ evgpeinit.o \ evgpeutil.o \ evglock.o \ + evhandler.o \ evmisc.o \ evregion.o \ evrgnini.o \ @@ -90,6 +91,7 @@ acpi-y += \ nsobject.o \ nsparse.o \ nspredef.o \ + nsprepkg.o \ nsrepair.o \ nsrepair2.o \ nssearch.o \ @@ -104,7 +106,9 @@ acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o acpi-y += \ psargs.o \ psloop.o \ + psobject.o \ psopcode.o \ + psopinfo.o \ psparse.o \ psscope.o \ pstree.o \ @@ -126,7 +130,7 @@ acpi-y += \ rsutils.o \ rsxface.o -acpi-$(ACPI_FUTURE_USAGE) += rsdump.o +acpi-$(ACPI_FUTURE_USAGE) += rsdump.o rsdumpinfo.o acpi-y += \ tbfadt.o \ @@ -155,8 +159,10 @@ acpi-y += \ utmutex.o \ utobject.o \ utosi.o \ + utownerid.o \ utresrc.o \ utstate.o \ + utstring.o \ utxface.o \ utxfinit.o \ utxferror.o \ diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 432a318c9ed..c8dea18ccdc 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -115,6 +115,21 @@ ACPI_HW_DEPENDENT_RETURN_VOID(void 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 */ void @@ -191,6 +206,8 @@ void acpi_db_create_execution_threads(char *num_threads_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 u32 acpi_db_get_cache_info(struct acpi_memory_list *cache); #endif diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index e975c672044..35a2cbce467 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -158,10 +158,23 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 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_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 @@ -180,12 +193,6 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, 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_ev_execute_reg_methods(struct acpi_namespace_node *node, acpi_adr_space_type space_id); diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index b826d9c7aa7..bbfcd1b72b3 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -218,6 +218,18 @@ acpi_ns_check_parameter_count(char *pathname, u32 user_param_count, 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 */ diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 24a59056eee..e8f5726a1ab 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -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); /* - * 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); diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index 0347d099349..89bc3aa99ed 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -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[]; /* - * rsdump + * rsdumpinfo */ 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_start_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_flags[]; 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_end_tag[]; 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_memory_flags[]; 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_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_spi_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 /* __ACRESRC_H__ */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 6e51d193c3e..4e952111ca5 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -483,39 +483,17 @@ acpi_ut_short_divide(u64 in_dividend, /* * utmisc */ -void ut_convert_backslashes(char *pathname); - const char *acpi_ut_validate_exception(acpi_status status); u8 acpi_ut_is_pci_root_bridge(char *id); 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_ut_walk_package_tree(union acpi_operand_object *source_object, void *target_object, 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) */ #define ACPI_ANY_BASE 0 @@ -532,6 +510,13 @@ acpi_ut_display_init_pathname(u8 type, #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 */ acpi_status @@ -557,6 +542,27 @@ acpi_status 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 */ acpi_status acpi_ut_mutex_initialize(void); diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c new file mode 100644 index 00000000000..95e52585bb9 --- /dev/null +++ b/drivers/acpi/acpica/evhandler.c @@ -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); +} diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 0cc6a16fedc..d1fa91d0b5b 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -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 ACPI_MODULE_NAME("evregion") +extern u8 acpi_gbl_default_address_spaces[]; + /* 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); @@ -61,135 +60,6 @@ static acpi_status acpi_ev_reg_run(acpi_handle obj_handle, 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: |