diff options
Diffstat (limited to 'drivers/acpi/acpica/nsutils.c')
| -rw-r--r-- | drivers/acpi/acpica/nsutils.c | 151 | 
1 files changed, 65 insertions, 86 deletions
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index a7d6ad9c111..4a5e3f5c0ff 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -6,7 +6,7 @@   *****************************************************************************/  /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp.   * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without @@ -46,14 +46,11 @@  #include "accommon.h"  #include "acnamesp.h"  #include "amlcode.h" -#include "actables.h"  #define _COMPONENT          ACPI_NAMESPACE  ACPI_MODULE_NAME("nsutils")  /* Local prototypes */ -static u8 acpi_ns_valid_path_separator(char sep); -  #ifdef ACPI_OBSOLETE_FUNCTIONS  acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);  #endif @@ -62,8 +59,8 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);   *   * FUNCTION:    acpi_ns_print_node_pathname   * - * PARAMETERS:  Node            - Object - *              Message         - Prefix message + * PARAMETERS:  node            - Object + *              message         - Prefix message   *   * DESCRIPTION: Print an object's full namespace pathname   *              Manages allocation/freeing of a pathname buffer @@ -99,45 +96,9 @@ acpi_ns_print_node_pathname(struct acpi_namespace_node *node,  /*******************************************************************************   * - * FUNCTION:    acpi_ns_valid_root_prefix - * - * PARAMETERS:  Prefix          - Character to be checked - * - * RETURN:      TRUE if a valid prefix - * - * DESCRIPTION: Check if a character is a valid ACPI Root prefix - * - ******************************************************************************/ - -u8 acpi_ns_valid_root_prefix(char prefix) -{ - -	return ((u8) (prefix == '\\')); -} - -/******************************************************************************* - * - * FUNCTION:    acpi_ns_valid_path_separator - * - * PARAMETERS:  Sep         - Character to be checked - * - * RETURN:      TRUE if a valid path separator - * - * DESCRIPTION: Check if a character is a valid ACPI path separator - * - ******************************************************************************/ - -static u8 acpi_ns_valid_path_separator(char sep) -{ - -	return ((u8) (sep == '.')); -} - -/******************************************************************************* - *   * FUNCTION:    acpi_ns_get_type   * - * PARAMETERS:  Node        - Parent Node to be examined + * PARAMETERS:  node        - Parent Node to be examined   *   * RETURN:      Type field from Node whose handle is passed   * @@ -151,17 +112,17 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)  	if (!node) {  		ACPI_WARNING((AE_INFO, "Null Node parameter")); -		return_UINT32(ACPI_TYPE_ANY); +		return_UINT8(ACPI_TYPE_ANY);  	} -	return_UINT32((acpi_object_type) node->type); +	return_UINT8(node->type);  }  /*******************************************************************************   *   * FUNCTION:    acpi_ns_local   * - * PARAMETERS:  Type        - A namespace object type + * PARAMETERS:  type        - A namespace object type   *   * RETURN:      LOCAL if names must be found locally in objects of the   *              passed type, 0 if enclosing scopes should be searched @@ -182,14 +143,14 @@ u32 acpi_ns_local(acpi_object_type type)  		return_UINT32(ACPI_NS_NORMAL);  	} -	return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); +	return_UINT32(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);  }  /*******************************************************************************   *   * FUNCTION:    acpi_ns_get_internal_name_length   * - * PARAMETERS:  Info            - Info struct initialized with the + * PARAMETERS:  info            - Info struct initialized with the   *                                external name pointer.   *   * RETURN:      None @@ -218,19 +179,19 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)  	 *  	 * strlen() + 1 covers the first name_seg, which has no path separator  	 */ -	if (acpi_ns_valid_root_prefix(*next_external_char)) { +	if (ACPI_IS_ROOT_PREFIX(*next_external_char)) {  		info->fully_qualified = TRUE;  		next_external_char++;  		/* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */ -		while (acpi_ns_valid_root_prefix(*next_external_char)) { +		while (ACPI_IS_ROOT_PREFIX(*next_external_char)) {  			next_external_char++;  		}  	} else {  		/* Handle Carat prefixes */ -		while (*next_external_char == '^') { +		while (ACPI_IS_PARENT_PREFIX(*next_external_char)) {  			info->num_carats++;  			next_external_char++;  		} @@ -244,7 +205,7 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)  	if (*next_external_char) {  		info->num_segments = 1;  		for (i = 0; next_external_char[i]; i++) { -			if (acpi_ns_valid_path_separator(next_external_char[i])) { +			if (ACPI_IS_PATH_SEPARATOR(next_external_char[i])) {  				info->num_segments++;  			}  		} @@ -260,7 +221,7 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)   *   * FUNCTION:    acpi_ns_build_internal_name   * - * PARAMETERS:  Info            - Info struct fully initialized + * PARAMETERS:  info            - Info struct fully initialized   *   * RETURN:      Status   * @@ -282,7 +243,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)  	/* Setup the correct prefixes, counts, and pointers */  	if (info->fully_qualified) { -		internal_name[0] = '\\'; +		internal_name[0] = AML_ROOT_PREFIX;  		if (num_segments <= 1) {  			result = &internal_name[1]; @@ -302,7 +263,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)  		i = 0;  		if (info->num_carats) {  			for (i = 0; i < info->num_carats; i++) { -				internal_name[i] = '^'; +				internal_name[i] = AML_PARENT_PREFIX;  			}  		} @@ -322,7 +283,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)  	for (; num_segments; num_segments--) {  		for (i = 0; i < ACPI_NAME_SIZE; i++) { -			if (acpi_ns_valid_path_separator(*external_name) || +			if (ACPI_IS_PATH_SEPARATOR(*external_name) ||  			    (*external_name == 0)) {  				/* Pad the segment with underscore(s) if segment is short */ @@ -339,9 +300,9 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)  		/* Now we must have a path separator, or the pathname is bad */ -		if (!acpi_ns_valid_path_separator(*external_name) && +		if (!ACPI_IS_PATH_SEPARATOR(*external_name) &&  		    (*external_name != 0)) { -			return_ACPI_STATUS(AE_BAD_PARAMETER); +			return_ACPI_STATUS(AE_BAD_PATHNAME);  		}  		/* Move on the next segment */ @@ -371,7 +332,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)   * FUNCTION:    acpi_ns_internalize_name   *   * PARAMETERS:  *external_name          - External representation of name - *              **Converted Name        - Where to return the resulting + *              **Converted name        - Where to return the resulting   *                                        internal represention of the name   *   * RETURN:      Status @@ -457,13 +418,15 @@ acpi_ns_externalize_name(u32 internal_name_length,  	/* Check for a prefix (one '\' | one or more '^') */  	switch (internal_name[0]) { -	case '\\': +	case AML_ROOT_PREFIX: +  		prefix_length = 1;  		break; -	case '^': +	case AML_PARENT_PREFIX: +  		for (i = 0; i < internal_name_length; i++) { -			if (internal_name[i] == '^') { +			if (ACPI_IS_PARENT_PREFIX(internal_name[i])) {  				prefix_length = i + 1;  			} else {  				break; @@ -477,6 +440,7 @@ acpi_ns_externalize_name(u32 internal_name_length,  		break;  	default: +  		break;  	} @@ -530,7 +494,7 @@ acpi_ns_externalize_name(u32 internal_name_length,  	    ((num_segments > 0) ? (num_segments - 1) : 0) + 1;  	/* -	 * Check to see if we're still in bounds.  If not, there's a problem +	 * Check to see if we're still in bounds. If not, there's a problem  	 * with internal_name (invalid format).  	 */  	if (required_length > internal_name_length) { @@ -557,10 +521,14 @@ acpi_ns_externalize_name(u32 internal_name_length,  				(*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++]; +			/* Copy and validate the 4-char name segment */ + +			ACPI_MOVE_NAME(&(*converted_name)[j], +				       &internal_name[names_index]); +			acpi_ut_repair_name(&(*converted_name)[j]); + +			j += ACPI_NAME_SIZE; +			names_index += ACPI_NAME_SIZE;  		}  	} @@ -575,7 +543,7 @@ acpi_ns_externalize_name(u32 internal_name_length,   *   * FUNCTION:    acpi_ns_validate_handle   * - * PARAMETERS:  Handle          - Handle to be validated and typecast to a + * PARAMETERS:  handle          - Handle to be validated and typecast to a   *                                namespace node.   *   * RETURN:      A pointer to a namespace node @@ -625,24 +593,26 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle)  void acpi_ns_terminate(void)  { -	union acpi_operand_object *obj_desc; +	acpi_status status;  	ACPI_FUNCTION_TRACE(ns_terminate);  	/* -	 * 1) Free the entire namespace -- all nodes and objects -	 * -	 * Delete all object descriptors attached to namepsace nodes +	 * Free the entire namespace -- all nodes and all objects +	 * attached to the nodes  	 */  	acpi_ns_delete_namespace_subtree(acpi_gbl_root_node); -	/* Detach any objects attached to the root */ +	/* Delete any objects attached to the root node */ -	obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node); -	if (obj_desc) { -		acpi_ns_detach_object(acpi_gbl_root_node); +	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); +	if (ACPI_FAILURE(status)) { +		return_VOID;  	} +	acpi_ns_delete_node(acpi_gbl_root_node); +	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); +  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));  	return_VOID;  } @@ -651,7 +621,7 @@ void acpi_ns_terminate(void)   *   * FUNCTION:    acpi_ns_opens_scope   * - * PARAMETERS:  Type        - A valid namespace type + * PARAMETERS:  type        - A valid namespace type   *   * RETURN:      NEWSCOPE if the passed type "opens a name scope" according   *              to the ACPI specification, else 0 @@ -660,36 +630,36 @@ void acpi_ns_terminate(void)  u32 acpi_ns_opens_scope(acpi_object_type type)  { -	ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type)); +	ACPI_FUNCTION_ENTRY(); -	if (!acpi_ut_valid_object_type(type)) { +	if (type > ACPI_TYPE_LOCAL_MAX) {  		/* type code out of range  */  		ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type)); -		return_UINT32(ACPI_NS_NORMAL); +		return (ACPI_NS_NORMAL);  	} -	return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); +	return (((u32)acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);  }  /*******************************************************************************   *   * FUNCTION:    acpi_ns_get_node   * - * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The + * PARAMETERS:  *pathname   - Name to be found, in external (ASL) format. The   *                            \ (backslash) and ^ (carat) prefixes, and the   *                            . (period) to separate segments are supported.   *              prefix_node  - Root of subtree to be searched, or NS_ALL for the - *                            root of the name space.  If Name is fully + *                            root of the name space. If Name is fully   *                            qualified (first s8 is '\'), the passed value   *                            of Scope will not be accessed. - *              Flags       - Used to indicate whether to perform upsearch or + *              flags       - Used to indicate whether to perform upsearch or   *                            not.   *              return_node - Where the Node is returned   *   * DESCRIPTION: Look up a name relative to a given scope and return the - *              corresponding Node.  NOTE: Scope can be null. + *              corresponding Node. NOTE: Scope can be null.   *   * MUTEX:       Locks namespace   * @@ -706,6 +676,8 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,  	ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); +	/* Simplest case is a null pathname */ +  	if (!pathname) {  		*return_node = prefix_node;  		if (!prefix_node) { @@ -714,6 +686,13 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,  		return_ACPI_STATUS(AE_OK);  	} +	/* Quick check for a reference to the root */ + +	if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) { +		*return_node = acpi_gbl_root_node; +		return_ACPI_STATUS(AE_OK); +	} +  	/* Convert path to internal representation */  	status = acpi_ns_internalize_name(pathname, &internal_path); @@ -745,7 +724,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,  	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); -      cleanup: +cleanup:  	ACPI_FREE(internal_path);  	return_ACPI_STATUS(status);  }  | 
