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
29 #define _COMPONENT ACPI_NAMESPACE
30 MODULE_NAME ("nsnames")
33 /*******************************************************************************
35 * FUNCTION: Acpi_ns_get_table_pathname
37 * PARAMETERS: Node - Scope whose name is needed
39 * RETURN: Pointer to storage containing the fully qualified name of
40 * the scope, in Label format (all segments strung together
43 * DESCRIPTION: Used for debug printing in Acpi_ns_search_table().
45 ******************************************************************************/
48 acpi_ns_get_table_pathname (
49 ACPI_NAMESPACE_NODE
*node
)
51 NATIVE_CHAR
*name_buffer
;
54 ACPI_NAMESPACE_NODE
*child_node
;
55 ACPI_NAMESPACE_NODE
*parent_node
;
58 if (!acpi_gbl_root_node
|| !node
) {
60 * If the name space has not been initialized,
61 * this function should not have been called.
66 child_node
= node
->child
;
69 /* Calculate required buffer size based on depth below root */
72 parent_node
= child_node
;
74 parent_node
= acpi_ns_get_parent_object (parent_node
);
76 size
+= ACPI_NAME_SIZE
;
81 /* Allocate a buffer to be returned to caller */
83 name_buffer
= acpi_cm_callocate (size
+ 1);
85 REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n"));
90 /* Store terminator byte, then build name backwards */
92 name_buffer
[size
] = '\0';
93 while ((size
> ACPI_NAME_SIZE
) &&
94 acpi_ns_get_parent_object (child_node
)) {
95 size
-= ACPI_NAME_SIZE
;
96 name
= acpi_ns_find_parent_name (child_node
);
98 /* Put the name into the buffer */
100 MOVE_UNALIGNED32_TO_32 ((name_buffer
+ size
), &name
);
101 child_node
= acpi_ns_get_parent_object (child_node
);
104 name_buffer
[--size
] = AML_ROOT_PREFIX
;
107 return (name_buffer
);
111 /*******************************************************************************
113 * FUNCTION: Acpi_ns_get_pathname_length
115 * PARAMETERS: Node - Namespace node
117 * RETURN: Length of path, including prefix
119 * DESCRIPTION: Get the length of the pathname string for this node
121 ******************************************************************************/
124 acpi_ns_get_pathname_length (
125 ACPI_NAMESPACE_NODE
*node
)
128 ACPI_NAMESPACE_NODE
*next_node
;
131 * Compute length of pathname as 5 * number of name segments.
132 * Go back up the parent tree to the root
134 for (size
= 0, next_node
= node
;
135 acpi_ns_get_parent_object (next_node
);
136 next_node
= acpi_ns_get_parent_object (next_node
)) {
137 size
+= PATH_SEGMENT_LENGTH
;
140 /* Special case for size still 0 - no parent for "special" nodes */
143 size
= PATH_SEGMENT_LENGTH
;
150 /*******************************************************************************
152 * FUNCTION: Acpi_ns_handle_to_pathname
154 * PARAMETERS: Target_handle - Handle of named object whose name is
156 * Buf_size - Size of the buffer provided
157 * User_buffer - Where the pathname is returned
159 * RETURN: Status, Buffer is filled with pathname if status is AE_OK
161 * DESCRIPTION: Build and return a full namespace pathname
163 * MUTEX: Locks Namespace
165 ******************************************************************************/
168 acpi_ns_handle_to_pathname (
169 ACPI_HANDLE target_handle
,
171 NATIVE_CHAR
*user_buffer
)
173 ACPI_STATUS status
= AE_OK
;
174 ACPI_NAMESPACE_NODE
*node
;
181 if (!acpi_gbl_root_node
|| !target_handle
) {
183 * If the name space has not been initialized,
184 * this function should not have been called.
187 return (AE_NO_NAMESPACE
);
190 node
= acpi_ns_convert_handle_to_entry (target_handle
);
192 return (AE_BAD_PARAMETER
);
196 /* Set return length to the required path length */
198 path_length
= acpi_ns_get_pathname_length (node
);
199 size
= path_length
- 1;
201 user_buf_size
= *buf_size
;
202 *buf_size
= path_length
;
204 /* Check if the user buffer is sufficiently large */
206 if (path_length
> user_buf_size
) {
207 status
= AE_BUFFER_OVERFLOW
;
211 /* Store null terminator */
213 user_buffer
[size
] = 0;
214 size
-= ACPI_NAME_SIZE
;
216 /* Put the original ACPI name at the end of the path */
218 MOVE_UNALIGNED32_TO_32 ((user_buffer
+ size
),
221 user_buffer
[--size
] = PATH_SEPARATOR
;
223 /* Build name backwards, putting "." between segments */
225 while ((size
> ACPI_NAME_SIZE
) && node
) {
226 size
-= ACPI_NAME_SIZE
;
227 name
= acpi_ns_find_parent_name (node
);
228 MOVE_UNALIGNED32_TO_32 ((user_buffer
+ size
), &name
);
230 user_buffer
[--size
] = PATH_SEPARATOR
;
231 node
= acpi_ns_get_parent_object (node
);
235 * Overlay the "." preceding the first segment with
239 user_buffer
[size
] = '\\';