diff options
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r-- | drivers/acpi/namespace/Makefile | 14 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsaccess.c | 45 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsalloc.c | 4 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsdump.c | 36 | ||||
-rw-r--r-- | drivers/acpi/namespace/nseval.c | 38 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsinit.c | 271 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsload.c | 177 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsnames.c | 10 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsobject.c | 12 | ||||
-rw-r--r-- | drivers/acpi/namespace/nssearch.c | 18 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsutils.c | 253 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfname.c | 124 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfobj.c | 153 |
13 files changed, 866 insertions, 289 deletions
diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/namespace/Makefile +++ b/drivers/acpi/namespace/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index e04ffe4e9..27c02e22a 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 108 $ + * $Revision: 117 $ * ******************************************************************************/ @@ -87,8 +87,6 @@ acpi_ns_root_initialize (void) IMODE_LOAD_PASS2, NS_NO_UPSEARCH, NULL, &new_node); - if (ACPI_FAILURE (status) || - (!new_node)) /* * Name entered successfully. @@ -122,7 +120,7 @@ acpi_ns_root_initialize (void) case ACPI_TYPE_NUMBER: obj_desc->number.value = - (u32) STRTOUL (init_val->val, NULL, 10); + (ACPI_INTEGER) STRTOUL (init_val->val, NULL, 10); break; @@ -138,11 +136,7 @@ acpi_ns_root_initialize (void) */ obj_desc->string.pointer = acpi_cm_allocate ( (obj_desc->string.length + 1)); - if (!obj_desc->string.pointer) { - REPORT_ERROR ("Initial value string" - "allocation failure"); - acpi_cm_remove_reference (obj_desc); status = AE_NO_MEMORY; goto unlock_and_exit; @@ -190,7 +184,8 @@ acpi_ns_root_initialize (void) default: - REPORT_ERROR ("Unsupported initial type value"); + REPORT_ERROR (("Unsupported initial type value %X\n", + init_val->type)); acpi_cm_remove_reference (obj_desc); obj_desc = NULL; continue; @@ -214,14 +209,14 @@ unlock_and_exit: * * FUNCTION: Acpi_ns_lookup * - * PARAMETERS: Prefix_node - Search scope if name is not fully qualified + * PARAMETERS: Prefix_node - Search scope if name is not fully qualified * Pathname - Search pathname, in internal format * (as represented in the AML stream) * Type - Type associated with name * Interpreter_mode - IMODE_LOAD_PASS2 => add name if not found * Flags - Flags describing the search restrictions * Walk_state - Current state of the walk - * Return_node - Where the Node is placed (if found + * Return_node - Where the Node is placed (if found * or created successfully) * * RETURN: Status @@ -254,6 +249,9 @@ acpi_ns_lookup ( OBJECT_TYPE_INTERNAL type_to_check_for; OBJECT_TYPE_INTERNAL this_search_type; + DEBUG_ONLY_MEMBERS (u32 i) + + if (!return_node) { return (AE_BAD_PARAMETER); } @@ -379,8 +377,7 @@ acpi_ns_lookup ( if (!this_node) { /* Current scope has no parent scope */ - REPORT_ERROR ("Too many parent prefixes (^) - reached root"); - + REPORT_ERROR (("Too many parent prefixes (^) - reached root\n")); return (AE_NOT_FOUND); } @@ -442,7 +439,7 @@ acpi_ns_lookup ( this_search_type = type; } - /* Pluck and ACPI name from the front of the pathname */ + /* Pluck one ACPI name from the front of the pathname */ MOVE_UNALIGNED32_TO_32 (&simple_name, pathname); @@ -467,25 +464,29 @@ acpi_ns_lookup ( * If 1) This is the last segment (Num_segments == 0) * 2) and looking for a specific type * (Not checking for TYPE_ANY) - * 3) which is not a local type (TYPE_DEF_ANY) - * 4) which is not a local type (TYPE_SCOPE) - * 5) which is not a local type (TYPE_INDEX_FIELD_DEFN) - * 6) and type of object is known (not TYPE_ANY) - * 7) and object does not match request + * 3) Which is not an alias + * 4) which is not a local type (TYPE_DEF_ANY) + * 5) which is not a local type (TYPE_SCOPE) + * 6) which is not a local type (TYPE_INDEX_FIELD_DEFN) + * 7) and type of object is known (not TYPE_ANY) + * 8) and object does not match request * * Then we have a type mismatch. Just warn and ignore it. */ if ((num_segments == 0) && (type_to_check_for != ACPI_TYPE_ANY) && + (type_to_check_for != INTERNAL_TYPE_ALIAS) && (type_to_check_for != INTERNAL_TYPE_DEF_ANY) && (type_to_check_for != INTERNAL_TYPE_SCOPE) && (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) && - (this_node->type != ACPI_TYPE_ANY) && - (this_node->type != type_to_check_for)) + (this_node->type != ACPI_TYPE_ANY) && + (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ - REPORT_WARNING ("Type mismatch"); + REPORT_WARNING ( + ("Ns_lookup: %4.4s, type %X, checking for type %X\n", + &simple_name, this_node->type, type_to_check_for)); } /* diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 0b8272724..9f1d5377e 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 41 $ + * $Revision: 43 $ * ******************************************************************************/ @@ -434,7 +434,7 @@ acpi_ns_delete_namespace_subtree ( * ******************************************************************************/ -void +static void acpi_ns_remove_reference ( ACPI_NAMESPACE_NODE *node) { diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c deleted file mode 100644 index 117af81e3..000000000 --- a/drivers/acpi/namespace/nsdump.c +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** - * - * Module Name: nsdump - table dumping routines for debug - * $Revision: 78 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" - - -#define _COMPONENT NAMESPACE - MODULE_NAME ("nsdump") - - diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 2df17e94f..fbba7840c 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -2,7 +2,7 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 76 $ + * $Revision: 79 $ * ******************************************************************************/ @@ -99,7 +99,7 @@ acpi_ns_evaluate_relative ( /* Lookup the name in the namespace */ - scope_info.scope.node = prefix_node->child; + scope_info.scope.node = prefix_node; status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); @@ -432,28 +432,14 @@ acpi_ns_get_object_value ( } /* - * Just copy from the original to the return object + * Just copy from the original to the return object + * + * TBD: [Future] - need a low-level object copy that handles + * the reference count automatically. (Don't want to copy it) */ - switch (node->type) - { - case ACPI_TYPE_PROCESSOR: - obj_desc->processor.proc_id = val_desc->processor.proc_id; - obj_desc->processor.address = val_desc->processor.address; - obj_desc->processor.sys_handler = val_desc->processor.sys_handler; - obj_desc->processor.drv_handler = val_desc->processor.drv_handler; - obj_desc->processor.addr_handler = val_desc->processor.addr_handler; - - break; - - case ACPI_TYPE_POWER: - obj_desc->power_resource.system_level = val_desc->power_resource.system_level; - obj_desc->power_resource.resource_order = val_desc->power_resource.resource_order; - obj_desc->power_resource.sys_handler = val_desc->power_resource.sys_handler; - obj_desc->power_resource.drv_handler = val_desc->power_resource.drv_handler; - - break; - } + MEMCPY (obj_desc, val_desc, sizeof (ACPI_OPERAND_OBJECT)); + obj_desc->common.reference_count = 1; } @@ -483,9 +469,17 @@ acpi_ns_get_object_value ( * NOTE: we can get away with passing in NULL for a walk state * because Obj_desc is guaranteed to not be a reference to either * a method local or a method argument + * + * Even though we do not technically need to use the interpreter + * for this, we must enter it because we could hit an opregion. + * The opregion access code assumes it is in the interpreter. */ + acpi_aml_enter_interpreter(); + status = acpi_aml_resolve_to_value (&obj_desc, NULL); + + acpi_aml_exit_interpreter(); } /* diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c new file mode 100644 index 000000000..ddacd7b8c --- /dev/null +++ b/drivers/acpi/namespace/nsinit.c @@ -0,0 +1,271 @@ +/****************************************************************************** + * + * Module Name: nsinit - namespace initialization + * $Revision: 9 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "acnamesp.h" +#include "acdispat.h" + +#define _COMPONENT NAMESPACE + MODULE_NAME ("nsinit") + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_initialize_objects + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Walk the entire namespace and perform any necessary + * initialization on the objects found therein + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_initialize_objects ( + void) +{ + ACPI_STATUS status; + ACPI_INIT_WALK_INFO info; + + + info.field_count = 0; + info.field_init = 0; + info.op_region_count = 0; + info.op_region_init = 0; + info.object_count = 0; + + + /* Walk entire namespace from the supplied root */ + + status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, acpi_ns_init_one_object, + &info, NULL); + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_ns_initialize_devices + * + * PARAMETERS: None + * + * RETURN: ACPI_STATUS + * + * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. + * This means running _INI on all present devices. + * + * Also: Install PCI config space handler for all PCI root bridges. + * A PCI root bridge is found by searching for devices containing + * a HID with the value EISAID("PNP0A03") + * + *****************************************************************************/ + +ACPI_STATUS +acpi_ns_initialize_devices ( + u32 flags) +{ + ACPI_STATUS status; + ACPI_DEVICE_WALK_INFO info; + + + info.flags = flags; + info.device_count = 0; + info.num_STA = 0; + info.num_INI = 0; + + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + FALSE, acpi_ns_init_one_device, &info, NULL); + + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_init_one_object + * + * PARAMETERS: Obj_handle - Node + * Level - Current nesting level + * Context - Points to a init info struct + * Return_value - Not used + * + * RETURN: Status + * + * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object + * within the namespace. + * + * Currently, the only objects that require initialization are: + * 1) Methods + * 2) Op Regions + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_init_one_object ( + ACPI_HANDLE obj_handle, + u32 level, + void *context, + void **return_value) +{ + OBJECT_TYPE_INTERNAL type; + ACPI_STATUS status; + ACPI_INIT_WALK_INFO *info = (ACPI_INIT_WALK_INFO *) context; + ACPI_NAMESPACE_NODE *node = (ACPI_NAMESPACE_NODE *) obj_handle; + ACPI_OPERAND_OBJECT *obj_desc; + + + info->object_count++; + + + /* And even then, we are only interested in a few object types */ + + type = acpi_ns_get_type (obj_handle); + obj_desc = node->object; + if (!obj_desc) { + return (AE_OK); + } + + switch (type) + { + + case ACPI_TYPE_REGION: + + info->op_region_count++; + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + break; + } + + info->op_region_init++; + status = acpi_ds_get_region_arguments (obj_desc); + + break; + + + case ACPI_TYPE_FIELD_UNIT: + + info->field_count++; + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + break; + } + + info->field_init++; + status = acpi_ds_get_field_unit_arguments (obj_desc); + break; + + default: + break; + } + + /* + * We ignore errors from above, and always return OK, since + * we don't want to abort the walk on a single error. + */ + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_ns_init_one_device + * + * PARAMETERS: The usual "I'm a namespace callback" stuff + * + * RETURN: ACPI_STATUS + * + * DESCRIPTION: This is called once per device soon after ACPI is enabled + * to initialize each device. It determines if the device is + * present, and if so, calls _INI. + * + *****************************************************************************/ + +ACPI_STATUS +acpi_ns_init_one_device ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_NAMESPACE_NODE *node; + u32 flags; + ACPI_DEVICE_WALK_INFO *info = (ACPI_DEVICE_WALK_INFO *) context; + + + info->device_count++; + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + + node = acpi_ns_convert_handle_to_entry (obj_handle); + if (!node) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + /* + * Run _STA to determine if we can run _INI on the device. + */ + + status = acpi_cm_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (status); + } + + info->num_STA++; + + if (!(flags & 0x01)) { + /* don't look at children of a not present device */ + return(AE_CTRL_DEPTH); + } + + /* + * The device is present. Run _INI. + */ + + status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); + if (AE_NOT_FOUND == status) { + /* No _INI means device requires no initialization */ + status = AE_OK; + } + + else if (ACPI_FAILURE (status)) { + return (status); + } + + else { + info->num_INI++; + } + + return (status); +} diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 8faa8ea4f..28a26376d 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 28 $ + * $Revision: 33 $ * *****************************************************************************/ @@ -37,6 +37,123 @@ MODULE_NAME ("nsload") +/****************************************************************************** + * + * FUNCTION: Acpi_load_namespace + * + * PARAMETERS: Display_aml_during_load + * + * RETURN: Status + * + * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. + * (DSDT points to either the BIOS or a buffer.) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_load_namespace ( + void) +{ + ACPI_STATUS status; + + + /* There must be at least a DSDT installed */ + + if (acpi_gbl_DSDT == NULL) { + return (AE_NO_ACPI_TABLES); + } + + + /* + * Load the namespace. The DSDT is required, + * but the SSDT and PSDT tables are optional. + */ + + status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Ignore exceptions from these */ + + acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); + acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_one_parse_pass + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_one_complete_parse ( + u32 pass_number, + ACPI_TABLE_DESC *table_desc) +{ + ACPI_PARSE_DOWNWARDS descending_callback; + ACPI_PARSE_UPWARDS ascending_callback; + ACPI_PARSE_OBJECT *parse_root; + ACPI_STATUS status; + + + switch (pass_number) + { + case 1: + descending_callback = acpi_ds_load1_begin_op; + ascending_callback = acpi_ds_load1_end_op; + break; + + case 2: + descending_callback = acpi_ds_load2_begin_op; + ascending_callback = acpi_ds_load2_end_op; + break; + + case 3: + descending_callback = acpi_ds_exec_begin_op; + ascending_callback = acpi_ds_exec_end_op; + break; + + default: + return (AE_BAD_PARAMETER); + } + + /* Create and init a Root Node */ + + parse_root = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!parse_root) { + return (AE_NO_MEMORY); + } + + ((ACPI_PARSE2_OBJECT *) parse_root)->name = ACPI_ROOT_NAME; + + + /* Pass 1: Parse everything except control method bodies */ + + status = acpi_ps_parse_aml (parse_root, + table_desc->aml_pointer, + table_desc->aml_length, + ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, + NULL, NULL, NULL, + descending_callback, + ascending_callback); + + acpi_ps_delete_parse_tree (parse_root); + + return (status); +} + + /******************************************************************************* * * FUNCTION: Acpi_ns_parse_table @@ -69,32 +186,11 @@ acpi_ns_parse_table ( * performs another complete parse of the AML.. */ - /* Create and init a Root Node */ - - acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!acpi_gbl_parsed_namespace_root) { - return (AE_NO_MEMORY); - } - - ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME; - - - /* Pass 1: Parse everything except control method bodies */ - - status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root, - table_desc->aml_pointer, - table_desc->aml_length, - ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, - NULL, NULL, NULL, - acpi_ds_load1_begin_op, - acpi_ds_load1_end_op); - + status = acpi_ns_one_complete_parse (1, table_desc); if (ACPI_FAILURE (status)) { return (status); } - acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root); - /* * AML Parse, pass 2 @@ -106,34 +202,11 @@ acpi_ns_parse_table ( * parse objects are all cached. */ - /* Create and init a Root Node */ - - acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!acpi_gbl_parsed_namespace_root) { - return (AE_NO_MEMORY); - } - - ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME; - - - /* Pass 2: Resolve forward references */ - - status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root, - table_desc->aml_pointer, - table_desc->aml_length, - ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, - NULL, NULL, NULL, - acpi_ds_load2_begin_op, - acpi_ds_load2_end_op); - + status = acpi_ns_one_complete_parse (2, table_desc); if (ACPI_FAILURE (status)) { return (status); } - acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root); - acpi_gbl_parsed_namespace_root = NULL; - - return (status); } @@ -147,8 +220,7 @@ acpi_ns_parse_table ( * * RETURN: Status * - * DESCRIPTION: Mainline of the AML load/dump subsystem. Sets up the - * input engine, calls handler for outermost object type. + * DESCRIPTION: Load one ACPI table into the namespace * ****************************************************************************/ @@ -248,13 +320,6 @@ acpi_ns_load_table_by_type ( table_desc->table_id = TABLE_ID_DSDT; - /* Initialize the root of the namespace tree */ - - status = acpi_ns_root_initialize (); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - /* Now load the single DSDT */ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index 3c18cf87f..faf8fe56a 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 48 $ + * $Revision: 51 $ * ******************************************************************************/ @@ -86,7 +86,7 @@ acpi_ns_get_table_pathname ( name_buffer = acpi_cm_callocate (size + 1); if (!name_buffer) { - REPORT_ERROR ("Ns_get_table_pathname: allocation failure"); + REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n")); return (NULL); } @@ -170,6 +170,12 @@ acpi_ns_handle_to_pathname ( size += PATH_SEGMENT_LENGTH; } + /* Special case for size still 0 - no parent for "special" nodes */ + + if (!size) { + size = PATH_SEGMENT_LENGTH; + } + /* Set return length to the required path length */ path_length = size + 1; diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index df4c28239..6d41b91ce 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c @@ -2,7 +2,7 @@ * * Module Name: nsobject - Utilities for objects attached to namespace * table entries - * $Revision: 44 $ + * $Revision: 47 $ * ******************************************************************************/ @@ -73,29 +73,28 @@ acpi_ns_attach_object ( if (!acpi_gbl_root_node) { /* Name space not initialized */ - REPORT_ERROR ("Ns_attach_object: Name space not initialized"); + REPORT_ERROR (("Ns_attach_object: Namespace not initialized\n")); return (AE_NO_NAMESPACE); } if (!node) { /* Invalid handle */ - REPORT_ERROR ("Ns_attach_object: Null Named_obj handle"); + REPORT_ERROR (("Ns_attach_object: Null Named_obj handle\n")); return (AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ - REPORT_ERROR ("Ns_attach_object: Null object, but type" - "not ACPI_TYPE_ANY"); + REPORT_ERROR (("Ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n")); return (AE_BAD_PARAMETER); } if (!VALID_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED)) { /* Not a name handle */ - REPORT_ERROR ("Ns_attach_object: Invalid handle"); + REPORT_ERROR (("Ns_attach_object: Invalid handle\n")); return (AE_BAD_PARAMETER); } @@ -355,7 +354,6 @@ acpi_ns_get_attached_object ( if (!handle) { /* handle invalid */ - REPORT_WARNING ("Ns_get_attached_object: Null handle"); return (NULL); } diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index b6abbd782..001f57d9d 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nssearch - Namespace search - * $Revision: 57 $ + * $Revision: 62 $ * ******************************************************************************/ @@ -169,7 +169,7 @@ acpi_ns_search_node ( * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ns_search_parent_tree ( u32 target_name, ACPI_NAMESPACE_NODE *node, @@ -270,7 +270,7 @@ acpi_ns_search_and_enter ( /* Parameter validation */ if (!node || !target_name || !return_node) { - REPORT_ERROR ("Ns_search_and_enter: bad (null)parameter"); + REPORT_ERROR (("Ns_search_and_enter: bad (null) parameter\n")); return (AE_BAD_PARAMETER); } @@ -278,7 +278,7 @@ acpi_ns_search_and_enter ( /* Name must consist of printable characters */ if (!acpi_cm_valid_acpi_name (target_name)) { - REPORT_ERROR ("Ns_search_and_enter: Bad character in ACPI Name"); + REPORT_ERROR (("Ns_search_and_enter: Bad character in ACPI Name\n")); return (AE_BAD_CHARACTER); } @@ -290,6 +290,16 @@ acpi_ns_search_and_enter ( type, return_node); if (status != AE_NOT_FOUND) { /* + * If we found it AND the request specifies that a + * find is an error, return the error + */ + if ((status == AE_OK) && + (flags & NS_ERROR_IF_FOUND)) + { + status = AE_EXIST; + } + + /* * Either found it or there was an error * -- finished either way */ diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 3d5a98a07..593064dbb 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -2,7 +2,7 @@ * * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing * parents and siblings and Scope manipulation - * $Revision: 69 $ + * $Revision: 74 $ * *****************************************************************************/ @@ -93,7 +93,7 @@ acpi_ns_get_type ( { if (!handle) { - REPORT_WARNING ("Ns_get_type: Null handle"); + REPORT_WARNING (("Ns_get_type: Null handle\n")); return (ACPI_TYPE_ANY); } @@ -120,7 +120,7 @@ acpi_ns_local ( if (!acpi_cm_valid_object_type (type)) { /* Type code out of range */ - REPORT_WARNING ("Ns_local: Invalid Object Type"); + REPORT_WARNING (("Ns_local: Invalid Object Type\n")); return (NSP_NORMAL); } @@ -150,9 +150,10 @@ acpi_ns_internalize_name ( { NATIVE_CHAR *result = NULL; NATIVE_CHAR *internal_name; - u32 num_segments; + u32 num_segments = 0; u8 fully_qualified = FALSE; u32 i; + u32 num_carats = 0; if ((!external_name) || @@ -178,6 +179,16 @@ acpi_ns_internalize_name ( external_name++; } + else { + /* + * Handle Carat prefixes + */ + + while (*external_name == '^') { + num_carats++; + external_name++; + } + } /* * Determine the number of ACPI name "segments" by counting @@ -186,17 +197,19 @@ acpi_ns_internalize_name ( * + 1, and zero separators is ok. */ - num_segments = 1; - for (i = 0; external_name[i]; i++) { - if (acpi_ns_valid_path_separator (external_name[i])) { - num_segments++; + if (*external_name) { + num_segments = 1; + for (i = 0; external_name[i]; i++) { + if (acpi_ns_valid_path_separator (external_name[i])) { + num_segments++; + } } } /* We need a segment to store the internal version of the name */ - internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4); + internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4 + num_carats); if (!internal_name) { return (AE_NO_MEMORY); } @@ -206,14 +219,49 @@ acpi_ns_internalize_name ( if (fully_qualified) { internal_name[0] = '\\'; - internal_name[1] = AML_MULTI_NAME_PREFIX_OP; - internal_name[2] = (char) num_segments; - result = &internal_name[3]; + + if (num_segments <= 1) { + result = &internal_name[1]; + } + else if (num_segments == 2) { + internal_name[1] = AML_DUAL_NAME_PREFIX; + result = &internal_name[2]; + } + else { + internal_name[1] = AML_MULTI_NAME_PREFIX_OP; + internal_name[2] = (char) num_segments; + result = &internal_name[3]; + } + } + else { - internal_name[0] = AML_MULTI_NAME_PREFIX_OP; - internal_name[1] = (char) num_segments; - result = &internal_name[2]; + /* + * Not fully qualified. + * Handle Carats first, then append the name segments + */ + + i = 0; + if (num_carats) { + for (i = 0; i < num_carats; i++) { + internal_name[i] = '^'; + } + } + + if (num_segments == 1) { + result = &internal_name[i]; + } + + else if (num_segments == 2) { + internal_name[i] = AML_DUAL_NAME_PREFIX; + result = &internal_name[i+1]; + } + + else { + internal_name[i] = AML_MULTI_NAME_PREFIX_OP; + internal_name[i+1] = (char) num_segments; + result = &internal_name[i+2]; + } } @@ -271,6 +319,157 @@ acpi_ns_internalize_name ( /**************************************************************************** * + * FUNCTION: Acpi_ns_externalize_name + * + * PARAMETERS: *Internal_name - Internal representation of name + * **Converted_name - Where to return the resulting + * external representation of name + * + * RETURN: Status + * + * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) + * to its external form (e.g. "\_PR_.CPU0") + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ns_externalize_name ( + u32 internal_name_length, + char *internal_name, + u32 *converted_name_length, + char **converted_name) +{ + u32 prefix_length = 0; + u32 names_index = 0; + u32 names_count = 0; + u32 i = 0; + u32 j = 0; + + + if (!internal_name_length || + !internal_name || + !converted_name_length || + !converted_name) + { + return (AE_BAD_PARAMETER); + } + + + /* + * Check for a prefix (one '\' | one or more '^'). + */ + switch (internal_name[0]) + { + case '\\': + prefix_length = 1; + break; + + case '^': + for (i = 0; i < internal_name_length; i++) { + if (internal_name[i] != '^') { + prefix_length = i + 1; + } + } + + if (i == internal_name_length) { + prefix_length = i; + } + + break; + } + + /* + * Check for object names. Note that there could be 0-255 of these + * 4-byte elements. + */ + if (prefix_length < internal_name_length) { + switch (internal_name[prefix_length]) + { + + /* <count> 4-byte names */ + + case AML_MULTI_NAME_PREFIX_OP: + names_index = prefix_length + 2; + names_count = (u32) internal_name[prefix_length + 1]; + break; + + + /* two 4-byte names */ + + case AML_DUAL_NAME_PREFIX: + names_index = prefix_length + 1; + names_count = 2; + break; + + + /* Null_name */ + + case 0: + names_index = 0; + names_count = 0; + break; + + + /* one 4-byte name */ + + default: + names_index = prefix_length; + names_count = 1; + break; + } + } + + /* + * Calculate the length of Converted_name, which equals the length + * of the prefix, length of all object names, length of any required + * punctuation ('.') between object names, plus the NULL terminator. + */ + *converted_name_length = prefix_length + (4 * names_count) + + ((names_count > 0) ? (names_count - 1) : 0) + 1; + + /* + * Check to see if we're still in bounds. If not, there's a problem + * with Internal_name (invalid format). + */ + if (*converted_name_length > internal_name_length) { + REPORT_ERROR (("Ns_externalize_name: Invalid internal name\n")); + return (AE_BAD_PATHNAME); + } + + /* + * Build Converted_name... + */ + + (*converted_name) = acpi_cm_callocate (*converted_name_length); + if (!(*converted_name)) { + return (AE_NO_MEMORY); + } + + j = 0; + + for (i = 0; i < prefix_length; i++) { + (*converted_name)[j++] = internal_name[i]; + } + + if (names_count > 0) { + for (i = 0; i < names_count; i++) { + if (i > 0) { + (*converted_name)[j++] = '.'; + } + + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + } + } + + return (AE_OK); +} + + +/**************************************************************************** + * * FUNCTION: Acpi_ns_convert_handle_to_entry * * PARAMETERS: Handle - Handle to be converted to an Node @@ -425,7 +624,7 @@ acpi_ns_opens_scope ( if (!acpi_cm_valid_object_type (type)) { /* type code out of range */ - REPORT_WARNING ("Ns_opens_scope: Invalid Object Type"); + REPORT_WARNING (("Ns_opens_scope: Invalid Object Type\n")); return (NSP_NORMAL); } @@ -464,8 +663,6 @@ acpi_ns_get_node ( NATIVE_CHAR *internal_path = NULL; - scope_info.scope.node = start_node; - /* Ensure that the namespace has been initialized */ if (!acpi_gbl_root_node) { @@ -487,19 +684,9 @@ acpi_ns_get_node ( acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - /* NS_ALL means start from the root */ - - if (NS_ALL == scope_info.scope.node) { - scope_info.scope.node = acpi_gbl_root_node; - } + /* Setup lookup scope (search starting point) */ - else { - scope_info.scope.node = start_node; - if (!scope_info.scope.node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } + scope_info.scope.node = start_node; /* Lookup the name in the namespace */ @@ -510,8 +697,6 @@ acpi_ns_get_node ( -unlock_and_exit: - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); /* Cleanup */ @@ -579,6 +764,10 @@ acpi_ns_get_parent_object ( { + if (!node) { + return (NULL); + } + /* * Walk to the end of this peer list. * The last entry is marked with a flag and the peer diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index dc02c6407..2947f7f06 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -2,7 +2,7 @@ * * Module Name: nsxfname - Public interfaces to the ACPI subsystem * ACPI Namespace oriented interfaces - * $Revision: 64 $ + * $Revision: 73 $ * *****************************************************************************/ @@ -38,60 +38,6 @@ MODULE_NAME ("nsxfname") -/****************************************************************************** - * - * FUNCTION: Acpi_load_namespace - * - * PARAMETERS: Display_aml_during_load - * - * RETURN: Status - * - * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. - * (DSDT points to either the BIOS or a buffer.) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_load_namespace ( - void) -{ - ACPI_STATUS status; - - - /* There must be at least a DSDT installed */ - - if (acpi_gbl_DSDT == NULL) { - return (AE_NO_ACPI_TABLES); - } - - - /* - * Load the namespace. The DSDT is required, - * but the SSDT and PSDT tables are optional. - */ - - status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Ignore exceptions from these */ - - acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); - acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); - - - /* - * Install the default Op_region handlers, ignore the return - * code right now. - */ - - acpi_ev_install_default_address_space_handlers (); - - return (status); -} - - /**************************************************************************** * * FUNCTION: Acpi_get_handle @@ -117,7 +63,7 @@ acpi_get_handle ( ACPI_HANDLE *ret_handle) { ACPI_STATUS status; - ACPI_NAMESPACE_NODE *node; + ACPI_NAMESPACE_NODE *node = NULL; ACPI_NAMESPACE_NODE *prefix_node = NULL; @@ -125,21 +71,21 @@ acpi_get_handle ( return (AE_BAD_PARAMETER); } + /* Convert a parent handle to a prefix node */ + if (parent) { acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - node = acpi_ns_convert_handle_to_entry (parent); - if (!node) { + prefix_node = acpi_ns_convert_handle_to_entry (parent); + if (!prefix_node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - prefix_node = node->child; acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); } /* Special case for root, since we can't search for it */ - /* TBD: [Investigate] Check for both forward and backslash?? */ if (STRCMP (pathname, NS_ROOT_PATH) == 0) { *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node); @@ -147,13 +93,12 @@ acpi_get_handle ( } /* - * Find the Node and convert to the user format + * Find the Node and convert to a handle */ - node = NULL; status = acpi_ns_get_node (pathname, prefix_node, &node); *ret_handle = NULL; - if(ACPI_SUCCESS(status)) { + if (ACPI_SUCCESS (status)) { *ret_handle = acpi_ns_convert_entry_to_handle (node); } @@ -253,42 +198,41 @@ unlock_and_exit: * * RETURN: Status * - * DESCRIPTION: Returns information about an object as gleaned from running - * several standard control methods. + * DESCRIPTION: Returns information about an object as gleaned from the + * namespace node and possibly by running several standard + * control methods (Such as in the case of a device.) * ******************************************************************************/ ACPI_STATUS acpi_get_object_info ( - ACPI_HANDLE device, + ACPI_HANDLE handle, ACPI_DEVICE_INFO *info) { DEVICE_ID hid; DEVICE_ID uid; ACPI_STATUS status; u32 device_status = 0; - u32 address = 0; - ACPI_NAMESPACE_NODE *device_node; + ACPI_INTEGER address = 0; + ACPI_NAMESPACE_NODE *node; /* Parameter validation */ - if (!device || !info) { + if (!handle || !info) { return (AE_BAD_PARAMETER); } acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - device_node = acpi_ns_convert_handle_to_entry (device); - if (!device_node) { + node = acpi_ns_convert_handle_to_entry (handle); + if (!node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - info->type = device_node->type; - info->name = device_node->name; - info->parent = acpi_ns_convert_entry_to_handle ( - acpi_ns_get_parent_object (device_node)); + info->type = node->type; + info->name = node->name; acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); @@ -300,34 +244,30 @@ acpi_get_object_info ( } - /* Get extra info for ACPI devices */ + /* + * Get extra info for ACPI devices only. Run the + * _HID, _UID, _STA, and _ADR methods. Note: none + * of these methods are required, so they may or may + * not be present. The Info->Valid bits are used + * to indicate which methods ran successfully. + */ info->valid = 0; /* Execute the _HID method and save the result */ - status = acpi_cm_execute_HID (device_node, &hid); + status = acpi_cm_execute_HID (node, &hid); if (ACPI_SUCCESS (status)) { - if (hid.type == STRING_PTR_DEVICE_ID) { - STRCPY (info->hardware_id, hid.data.string_ptr); - } - else { - STRCPY (info->hardware_id, hid.data.buffer); - } + STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id)); info->valid |= ACPI_VALID_HID; } /* Execute the _UID method and save the result */ - status = acpi_cm_execute_UID (device_node, &uid); + status = acpi_cm_execute_UID (node, &uid); if (ACPI_SUCCESS (status)) { - if (hid.type == STRING_PTR_DEVICE_ID) { - STRCPY (info->unique_id, uid.data.string_ptr); - } - else { - STRCPY (info->unique_id, uid.data.buffer); - } + STRCPY (info->unique_id, uid.buffer); info->valid |= ACPI_VALID_UID; } @@ -337,7 +277,7 @@ acpi_get_object_info ( * _STA is not always present */ - status = acpi_cm_execute_STA (device_node, &device_status); + status = acpi_cm_execute_STA (node, &device_status); if (ACPI_SUCCESS (status)) { info->current_status = device_status; info->valid |= ACPI_VALID_STA; @@ -349,7 +289,7 @@ acpi_get_object_info ( */ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, - device_node, &address); + node, &address); if (ACPI_SUCCESS (status)) { info->address = address; diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index 9b254ea99..b9f93fdcb 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -2,7 +2,7 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 65 $ + * $Revision: 75 $ * ******************************************************************************/ @@ -28,6 +28,7 @@ #include "acpi.h" #include "acinterp.h" #include "acnamesp.h" +#include "acdispat.h" #define _COMPONENT NAMESPACE @@ -484,6 +485,8 @@ unlock_and_exit: * Max_depth - Depth to which search is to reach * User_function - Called when an object of "Type" is found * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early * * RETURNS Return value from the User_function if terminated early. * Otherwise, returns NULL. @@ -544,3 +547,151 @@ acpi_walk_namespace ( } +/******************************************************************************* + * + * FUNCTION: Acpi_ns_get_device_callback + * + * PARAMETERS: Callback from Acpi_get_device + * + * RETURN: Status + * + * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non- + * present devices, or if they specified a HID, it filters based + * on that. + * + ******************************************************************************/ + +static ACPI_STATUS +acpi_ns_get_device_callback ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_NAMESPACE_NODE *node; + u32 flags; + DEVICE_ID device_id; + ACPI_GET_DEVICES_INFO *info; + + + info = context; + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + + node = acpi_ns_convert_handle_to_entry (obj_handle); + if (!node) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + /* + * Run _STA to determine if device is present + */ + + status = acpi_cm_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (status); + } + + if (!(flags & 0x01)) { + /* don't return at the device or children of the device if not there */ + + return (AE_CTRL_DEPTH); + } + + /* + * Filter based on device HID + */ + if (info->hid != NULL) { + status = acpi_cm_execute_HID (node, &device_id); + + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + + else if (ACPI_FAILURE (status)) { + return (status); + } + + if (STRNCMP (device_id.buffer, info->hid, sizeof (device_id.buffer)) != 0) { + return (AE_OK); + } + } + + info->user_function (obj_handle, nesting_level, info->context, return_value); + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_get_devices + * + * PARAMETERS: HID - HID to search for. Can be NULL. + * User_function - Called when a matching object is found + * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early + * + * RETURNS Return value from the User_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by Start_handle. + * The User_function is called whenever an object that matches + * the type parameter is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * This is a wrapper for Walk_namespace, but the callback performs + * additional filtering. Please see Acpi_get_device_callback. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_get_devices ( + NATIVE_CHAR *HID, + WALK_CALLBACK user_function, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_GET_DEVICES_INFO info; + + + /* Parameter validation */ + + if (!user_function) { + return (AE_BAD_PARAMETER); + } + + /* + * We're going to call their callback from OUR callback, so we need + * to know what it is, and their context parameter. + */ + info.context = context; + info.user_function = user_function; + info.hid = HID; + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + NS_WALK_UNLOCK, + acpi_ns_get_device_callback, &info, + return_value); + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + return (status); +}
\ No newline at end of file |