Commit d1e7ffe5 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPICA: Namespace: Add function to directly return normalized full path

ACPICA commit 6e0229bb156d71675f2e07dc7960adb7ec0a60ea

This patch adds functions to return normalized full path instead of
"external path". The external path contains trailing "_" for each
name segment while the normalized full path doesn't contain the
trailing "_".

Currently this function is used by the method tracing users to specify a
none trailing "_" attached name path. Lv Zheng.

Note that we need to validate and switch all Linux kernel acpi_get_name()
users to use the new name type before removing the old name type from
ACPICA.

Link: https://github.com/acpica/acpica/commit/6e0229bbSigned-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Reviewed-by: default avatarRuiyi Zhang <ruiyi_zhang@hotmail.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 07b9c912
......@@ -272,17 +272,20 @@ acpi_ns_check_package(struct acpi_evaluate_info *info,
*/
u32 acpi_ns_opens_scope(acpi_object_type type);
acpi_status
acpi_ns_build_external_path(struct acpi_namespace_node *node,
acpi_size size, char *name_buffer);
char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node);
u32
acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
char *full_path, u32 path_size, u8 no_trailing);
char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
u8 no_trailing);
char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state);
acpi_status
acpi_ns_handle_to_pathname(acpi_handle target_handle,
struct acpi_buffer *buffer);
struct acpi_buffer *buffer, u8 no_trailing);
u8
acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for);
......
......@@ -995,9 +995,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
if (obj_desc->reference.class == ACPI_REFCLASS_NAME) {
acpi_os_printf(" %p ", obj_desc->reference.node);
status =
acpi_ns_handle_to_pathname(obj_desc->reference.node,
&ret_buf);
status = acpi_ns_handle_to_pathname(obj_desc->reference.node,
&ret_buf, FALSE);
if (ACPI_FAILURE(status)) {
acpi_os_printf(" Could not convert name to pathname\n");
} else {
......
......@@ -49,73 +49,6 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsnames")
/*******************************************************************************
*
* FUNCTION: acpi_ns_build_external_path
*
* PARAMETERS: node - NS node whose pathname is needed
* size - Size of the pathname
* *name_buffer - Where to return the pathname
*
* RETURN: Status
* Places the pathname into the name_buffer, in external format
* (name segments separated by path separators)
*
* DESCRIPTION: Generate a full pathaname
*
******************************************************************************/
acpi_status
acpi_ns_build_external_path(struct acpi_namespace_node *node,
acpi_size size, char *name_buffer)
{
acpi_size index;
struct acpi_namespace_node *parent_node;
ACPI_FUNCTION_ENTRY();
/* Special case for root */
index = size - 1;
if (index < ACPI_NAME_SIZE) {
name_buffer[0] = AML_ROOT_PREFIX;
name_buffer[1] = 0;
return (AE_OK);
}
/* Store terminator byte, then build name backwards */
parent_node = node;
name_buffer[index] = 0;
while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) {
index -= ACPI_NAME_SIZE;
/* Put the name into the buffer */
ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name);
parent_node = parent_node->parent;
/* Prefix name with the path separator */
index--;
name_buffer[index] = ACPI_PATH_SEPARATOR;
}
/* Overwrite final separator with the root prefix character */
name_buffer[index] = AML_ROOT_PREFIX;
if (index != 0) {
ACPI_ERROR((AE_INFO,
"Could not construct external pathname; index=%u, size=%u, Path=%s",
(u32)index, (u32)size, &name_buffer[size]));
return (AE_BAD_PARAMETER);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_external_pathname
......@@ -130,37 +63,13 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
* for error and debug statements.
*
******************************************************************************/
char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
{
acpi_status status;
char *name_buffer;
acpi_size size;
ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node);
/* Calculate required buffer size based on depth below root */
size = acpi_ns_get_pathname_length(node);
if (!size) {
return_PTR(NULL);
}
/* Allocate a buffer to be returned to caller */
name_buffer = ACPI_ALLOCATE_ZEROED(size);
if (!name_buffer) {
ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
return_PTR(NULL);
}
/* Build the path in the allocated buffer */
status = acpi_ns_build_external_path(node, size, name_buffer);
if (ACPI_FAILURE(status)) {
ACPI_FREE(name_buffer);
return_PTR(NULL);
}
name_buffer = acpi_ns_get_normalized_pathname(node, FALSE);
return_PTR(name_buffer);
}
......@@ -180,33 +89,12 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
{
acpi_size size;
struct acpi_namespace_node *next_node;
ACPI_FUNCTION_ENTRY();
/*
* Compute length of pathname as 5 * number of name segments.
* Go back up the parent tree to the root
*/
size = 0;
next_node = node;
size = acpi_ns_build_normalized_path(node, NULL, 0, FALSE);
while (next_node && (next_node != acpi_gbl_root_node)) {
if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) {
ACPI_ERROR((AE_INFO,
"Invalid Namespace Node (%p) while traversing namespace",
next_node));
return (0);
}
size += ACPI_PATH_SEGMENT_LENGTH;
next_node = next_node->parent;
}
if (!size) {
size = 1; /* Root node case */
}
return (size + 1); /* +1 for null string terminator */
return (size);
}
/*******************************************************************************
......@@ -216,6 +104,8 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
* PARAMETERS: target_handle - Handle of named object whose name is
* to be found
* buffer - Where the pathname is returned
* no_trailing - Remove trailing '_' for each name
* segment
*
* RETURN: Status, Buffer is filled with pathname if status is AE_OK
*
......@@ -225,7 +115,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
acpi_status
acpi_ns_handle_to_pathname(acpi_handle target_handle,
struct acpi_buffer * buffer)
struct acpi_buffer * buffer, u8 no_trailing)
{
acpi_status status;
struct acpi_namespace_node *node;
......@@ -240,7 +130,8 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
/* Determine size required for the caller buffer */
required_size = acpi_ns_get_pathname_length(node);
required_size =
acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
if (!required_size) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
......@@ -254,8 +145,8 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
/* Build the path in the caller buffer */
status =
acpi_ns_build_external_path(node, required_size, buffer->pointer);
(void)acpi_ns_build_normalized_path(node, buffer->pointer,
required_size, no_trailing);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
......@@ -264,3 +155,149 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
(char *)buffer->pointer, (u32) required_size));
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ns_build_normalized_path
*
* PARAMETERS: node - Namespace node
* full_path - Where the path name is returned
* path_size - Size of returned path name buffer
* no_trailing - Remove trailing '_' from each name segment
*
* RETURN: Return 1 if the AML path is empty, otherwise returning (length
* of pathname + 1) which means the 'FullPath' contains a trailing
* null.
*
* DESCRIPTION: Build and return a full namespace pathname.
* Note that if the size of 'FullPath' isn't large enough to
* contain the namespace node's path name, the actual required
* buffer length is returned, and it should be greater than
* 'PathSize'. So callers are able to check the returning value
* to determine the buffer size of 'FullPath'.
*
******************************************************************************/
u32
acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
char *full_path, u32 path_size, u8 no_trailing)
{
u32 length = 0, i;
char name[ACPI_NAME_SIZE];
u8 do_no_trailing;
char c, *left, *right;
struct acpi_namespace_node *next_node;
ACPI_FUNCTION_TRACE_PTR(ns_build_normalized_path, node);
#define ACPI_PATH_PUT8(path, size, byte, length) \
do { \
if ((length) < (size)) \
{ \
(path)[(length)] = (byte); \
} \
(length)++; \
} while (0)
/*
* Make sure the path_size is correct, so that we don't need to
* validate both full_path and path_size.
*/
if (!full_path) {
path_size = 0;
}
if (!node) {
goto build_trailing_null;
}
next_node = node;
while (next_node && next_node != acpi_gbl_root_node) {
if (next_node != node) {
ACPI_PATH_PUT8(full_path, path_size,
AML_DUAL_NAME_PREFIX, length);
}
ACPI_MOVE_32_TO_32(name, &next_node->name);
do_no_trailing = no_trailing;
for (i = 0; i < 4; i++) {
c = name[4 - i - 1];
if (do_no_trailing && c != '_') {
do_no_trailing = FALSE;
}
if (!do_no_trailing) {
ACPI_PATH_PUT8(full_path, path_size, c, length);
}
}
next_node = next_node->parent;
}
ACPI_PATH_PUT8(full_path, path_size, AML_ROOT_PREFIX, length);
/* Reverse the path string */
if (length <= path_size) {
left = full_path;
right = full_path + length - 1;
while (left < right) {
c = *left;
*left++ = *right;
*right-- = c;
}
}
/* Append the trailing null */
build_trailing_null:
ACPI_PATH_PUT8(full_path, path_size, '\0', length);
#undef ACPI_PATH_PUT8
return_UINT32(length);
}
/*******************************************************************************
*
* FUNCTION: acpi_ns_get_normalized_pathname
*
* PARAMETERS: node - Namespace node whose pathname is needed
* no_trailing - Remove trailing '_' from each name segment
*
* RETURN: Pointer to storage containing the fully qualified name of
* the node, In external format (name segments separated by path
* separators.)
*
* DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
* for error and debug statements. All trailing '_' will be
* removed from the full pathname if 'NoTrailing' is specified..
*
******************************************************************************/
char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
u8 no_trailing)
{
char *name_buffer;
acpi_size size;
ACPI_FUNCTION_TRACE_PTR(ns_get_normalized_pathname, node);
/* Calculate required buffer size based on depth below root */
size = acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
if (!size) {
return_PTR(NULL);
}
/* Allocate a buffer to be returned to caller */
name_buffer = ACPI_ALLOCATE_ZEROED(size);
if (!name_buffer) {
ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
return_PTR(NULL);
}
/* Build the path in the allocated buffer */
(void)acpi_ns_build_normalized_path(node, name_buffer, size,
no_trailing);
return_PTR(name_buffer);
}
......@@ -83,7 +83,7 @@ acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
status = acpi_ns_handle_to_pathname(node, &buffer);
status = acpi_ns_handle_to_pathname(node, &buffer, FALSE);
if (ACPI_SUCCESS(status)) {
if (message) {
acpi_os_printf("%s ", message);
......
......@@ -172,11 +172,15 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
return (status);
}
if (name_type == ACPI_FULL_PATHNAME) {
if (name_type == ACPI_FULL_PATHNAME ||
name_type == ACPI_FULL_PATHNAME_NO_TRAILING) {
/* Get the full pathname (From the namespace root) */
status = acpi_ns_handle_to_pathname(handle, buffer);
status = acpi_ns_handle_to_pathname(handle, buffer,
name_type ==
ACPI_FULL_PATHNAME ? FALSE :
TRUE);
return (status);
}
......
......@@ -348,7 +348,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
status =
acpi_ns_handle_to_pathname((acpi_handle)
node,
&path_buffer);
&path_buffer,
FALSE);
/* +1 to include null terminator */
......
......@@ -376,7 +376,7 @@ acpi_ut_display_init_pathname(u8 type,
/* Get the full pathname to the node */
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
status = acpi_ns_handle_to_pathname(obj_handle, &buffer, FALSE);
if (ACPI_FAILURE(status)) {
return;
}
......
......@@ -985,7 +985,8 @@ struct acpi_buffer {
*/
#define ACPI_FULL_PATHNAME 0
#define ACPI_SINGLE_NAME 1
#define ACPI_NAME_TYPE_MAX 1
#define ACPI_FULL_PATHNAME_NO_TRAILING 2
#define ACPI_NAME_TYPE_MAX 2
/*
* Predefined Namespace items
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment