1 /*******************************************************************************
3 * Module Name: nsnames - Name manipulation and search
6 ******************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #define _COMPONENT ACPI_NAMESPACE
34 MODULE_NAME ("nsnames")
37 /*******************************************************************************
39 * FUNCTION: Acpi_ns_get_table_pathname
41 * PARAMETERS: Node - Scope whose name is needed
43 * RETURN: Pointer to storage containing the fully qualified name of
44 * the scope, in Label format (all segments strung together
47 * DESCRIPTION: Used for debug printing in Acpi_ns_search_table().
49 ******************************************************************************/
52 acpi_ns_get_table_pathname (
53 ACPI_NAMESPACE_NODE *node)
55 NATIVE_CHAR *name_buffer;
58 ACPI_NAMESPACE_NODE *child_node;
59 ACPI_NAMESPACE_NODE *parent_node;
62 if (!acpi_gbl_root_node || !node) {
64 * If the name space has not been initialized,
65 * this function should not have been called.
70 child_node = node->child;
73 /* Calculate required buffer size based on depth below root */
76 parent_node = child_node;
78 parent_node = acpi_ns_get_parent_object (parent_node);
80 size += ACPI_NAME_SIZE;
85 /* Allocate a buffer to be returned to caller */
87 name_buffer = acpi_cm_callocate (size + 1);
89 REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n"));
94 /* Store terminator byte, then build name backwards */
96 name_buffer[size] = '\0';
97 while ((size > ACPI_NAME_SIZE) &&
98 acpi_ns_get_parent_object (child_node)) {
99 size -= ACPI_NAME_SIZE;
100 name = acpi_ns_find_parent_name (child_node);
102 /* Put the name into the buffer */
104 MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name);
105 child_node = acpi_ns_get_parent_object (child_node);
108 name_buffer[--size] = AML_ROOT_PREFIX;
111 return (name_buffer);
115 /*******************************************************************************
117 * FUNCTION: Acpi_ns_get_pathname_length
119 * PARAMETERS: Node - Namespace node
121 * RETURN: Length of path, including prefix
123 * DESCRIPTION: Get the length of the pathname string for this node
125 ******************************************************************************/
128 acpi_ns_get_pathname_length (
129 ACPI_NAMESPACE_NODE *node)
132 ACPI_NAMESPACE_NODE *next_node;
135 * Compute length of pathname as 5 * number of name segments.
136 * Go back up the parent tree to the root
138 for (size = 0, next_node = node;
139 acpi_ns_get_parent_object (next_node);
140 next_node = acpi_ns_get_parent_object (next_node)) {
141 size += PATH_SEGMENT_LENGTH;
144 /* Special case for size still 0 - no parent for "special" nodes */
147 size = PATH_SEGMENT_LENGTH;
154 /*******************************************************************************
156 * FUNCTION: Acpi_ns_handle_to_pathname
158 * PARAMETERS: Target_handle - Handle of named object whose name is
160 * Buf_size - Size of the buffer provided
161 * User_buffer - Where the pathname is returned
163 * RETURN: Status, Buffer is filled with pathname if status is AE_OK
165 * DESCRIPTION: Build and return a full namespace pathname
167 * MUTEX: Locks Namespace
169 ******************************************************************************/
172 acpi_ns_handle_to_pathname (
173 ACPI_HANDLE target_handle,
175 NATIVE_CHAR *user_buffer)
177 ACPI_STATUS status = AE_OK;
178 ACPI_NAMESPACE_NODE *node;
185 if (!acpi_gbl_root_node || !target_handle) {
187 * If the name space has not been initialized,
188 * this function should not have been called.
191 return (AE_NO_NAMESPACE);
194 node = acpi_ns_convert_handle_to_entry (target_handle);
196 return (AE_BAD_PARAMETER);
200 /* Set return length to the required path length */
202 path_length = acpi_ns_get_pathname_length (node);
203 size = path_length - 1;
205 user_buf_size = *buf_size;
206 *buf_size = path_length;
208 /* Check if the user buffer is sufficiently large */
210 if (path_length > user_buf_size) {
211 status = AE_BUFFER_OVERFLOW;
215 /* Store null terminator */
217 user_buffer[size] = 0;
218 size -= ACPI_NAME_SIZE;
220 /* Put the original ACPI name at the end of the path */
222 MOVE_UNALIGNED32_TO_32 ((user_buffer + size),
225 user_buffer[--size] = PATH_SEPARATOR;
227 /* Build name backwards, putting "." between segments */
229 while ((size > ACPI_NAME_SIZE) && node) {
230 size -= ACPI_NAME_SIZE;
231 name = acpi_ns_find_parent_name (node);
232 MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &name);
234 user_buffer[--size] = PATH_SEPARATOR;
235 node = acpi_ns_get_parent_object (node);
239 * Overlay the "." preceding the first segment with
243 user_buffer[size] = '\\';