diff options
Diffstat (limited to 'drivers/acpi/acpica/nsnames.c')
-rw-r--r-- | drivers/acpi/acpica/nsnames.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c new file mode 100644 index 000000000000..b7e301848ba7 --- /dev/null +++ b/drivers/acpi/acpica/nsnames.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: nsnames - Name manipulation and search | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsnames") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_ns_build_external_path | ||
55 | * | ||
56 | * PARAMETERS: Node - NS node whose pathname is needed | ||
57 | * Size - Size of the pathname | ||
58 | * *name_buffer - Where to return the pathname | ||
59 | * | ||
60 | * RETURN: Status | ||
61 | * Places the pathname into the name_buffer, in external format | ||
62 | * (name segments separated by path separators) | ||
63 | * | ||
64 | * DESCRIPTION: Generate a full pathaname | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | acpi_status | ||
68 | acpi_ns_build_external_path(struct acpi_namespace_node *node, | ||
69 | acpi_size size, char *name_buffer) | ||
70 | { | ||
71 | acpi_size index; | ||
72 | struct acpi_namespace_node *parent_node; | ||
73 | |||
74 | ACPI_FUNCTION_ENTRY(); | ||
75 | |||
76 | /* Special case for root */ | ||
77 | |||
78 | index = size - 1; | ||
79 | if (index < ACPI_NAME_SIZE) { | ||
80 | name_buffer[0] = AML_ROOT_PREFIX; | ||
81 | name_buffer[1] = 0; | ||
82 | return (AE_OK); | ||
83 | } | ||
84 | |||
85 | /* Store terminator byte, then build name backwards */ | ||
86 | |||
87 | parent_node = node; | ||
88 | name_buffer[index] = 0; | ||
89 | |||
90 | while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) { | ||
91 | index -= ACPI_NAME_SIZE; | ||
92 | |||
93 | /* Put the name into the buffer */ | ||
94 | |||
95 | ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name); | ||
96 | parent_node = acpi_ns_get_parent_node(parent_node); | ||
97 | |||
98 | /* Prefix name with the path separator */ | ||
99 | |||
100 | index--; | ||
101 | name_buffer[index] = ACPI_PATH_SEPARATOR; | ||
102 | } | ||
103 | |||
104 | /* Overwrite final separator with the root prefix character */ | ||
105 | |||
106 | name_buffer[index] = AML_ROOT_PREFIX; | ||
107 | |||
108 | if (index != 0) { | ||
109 | ACPI_ERROR((AE_INFO, | ||
110 | "Could not construct external pathname; index=%X, size=%X, Path=%s", | ||
111 | (u32) index, (u32) size, &name_buffer[size])); | ||
112 | |||
113 | return (AE_BAD_PARAMETER); | ||
114 | } | ||
115 | |||
116 | return (AE_OK); | ||
117 | } | ||
118 | |||
119 | /******************************************************************************* | ||
120 | * | ||
121 | * FUNCTION: acpi_ns_get_external_pathname | ||
122 | * | ||
123 | * PARAMETERS: Node - Namespace node whose pathname is needed | ||
124 | * | ||
125 | * RETURN: Pointer to storage containing the fully qualified name of | ||
126 | * the node, In external format (name segments separated by path | ||
127 | * separators.) | ||
128 | * | ||
129 | * DESCRIPTION: Used for debug printing in acpi_ns_search_table(). | ||
130 | * | ||
131 | ******************************************************************************/ | ||
132 | |||
133 | char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | ||
134 | { | ||
135 | acpi_status status; | ||
136 | char *name_buffer; | ||
137 | acpi_size size; | ||
138 | |||
139 | ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node); | ||
140 | |||
141 | /* Calculate required buffer size based on depth below root */ | ||
142 | |||
143 | size = acpi_ns_get_pathname_length(node); | ||
144 | if (!size) { | ||
145 | return_PTR(NULL); | ||
146 | } | ||
147 | |||
148 | /* Allocate a buffer to be returned to caller */ | ||
149 | |||
150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); | ||
151 | if (!name_buffer) { | ||
152 | ACPI_ERROR((AE_INFO, "Allocation failure")); | ||
153 | return_PTR(NULL); | ||
154 | } | ||
155 | |||
156 | /* Build the path in the allocated buffer */ | ||
157 | |||
158 | status = acpi_ns_build_external_path(node, size, name_buffer); | ||
159 | if (ACPI_FAILURE(status)) { | ||
160 | ACPI_FREE(name_buffer); | ||
161 | return_PTR(NULL); | ||
162 | } | ||
163 | |||
164 | return_PTR(name_buffer); | ||
165 | } | ||
166 | |||
167 | /******************************************************************************* | ||
168 | * | ||
169 | * FUNCTION: acpi_ns_get_pathname_length | ||
170 | * | ||
171 | * PARAMETERS: Node - Namespace node | ||
172 | * | ||
173 | * RETURN: Length of path, including prefix | ||
174 | * | ||
175 | * DESCRIPTION: Get the length of the pathname string for this node | ||
176 | * | ||
177 | ******************************************************************************/ | ||
178 | |||
179 | acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) | ||
180 | { | ||
181 | acpi_size size; | ||
182 | struct acpi_namespace_node *next_node; | ||
183 | |||
184 | ACPI_FUNCTION_ENTRY(); | ||
185 | |||
186 | /* | ||
187 | * Compute length of pathname as 5 * number of name segments. | ||
188 | * Go back up the parent tree to the root | ||
189 | */ | ||
190 | size = 0; | ||
191 | next_node = node; | ||
192 | |||
193 | while (next_node && (next_node != acpi_gbl_root_node)) { | ||
194 | if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) { | ||
195 | ACPI_ERROR((AE_INFO, | ||
196 | "Invalid Namespace Node (%p) while traversing namespace", | ||
197 | next_node)); | ||
198 | return 0; | ||
199 | } | ||
200 | size += ACPI_PATH_SEGMENT_LENGTH; | ||
201 | next_node = acpi_ns_get_parent_node(next_node); | ||
202 | } | ||
203 | |||
204 | if (!size) { | ||
205 | size = 1; /* Root node case */ | ||
206 | } | ||
207 | |||
208 | return (size + 1); /* +1 for null string terminator */ | ||
209 | } | ||
210 | |||
211 | /******************************************************************************* | ||
212 | * | ||
213 | * FUNCTION: acpi_ns_handle_to_pathname | ||
214 | * | ||
215 | * PARAMETERS: target_handle - Handle of named object whose name is | ||
216 | * to be found | ||
217 | * Buffer - Where the pathname is returned | ||
218 | * | ||
219 | * RETURN: Status, Buffer is filled with pathname if status is AE_OK | ||
220 | * | ||
221 | * DESCRIPTION: Build and return a full namespace pathname | ||
222 | * | ||
223 | ******************************************************************************/ | ||
224 | |||
225 | acpi_status | ||
226 | acpi_ns_handle_to_pathname(acpi_handle target_handle, | ||
227 | struct acpi_buffer * buffer) | ||
228 | { | ||
229 | acpi_status status; | ||
230 | struct acpi_namespace_node *node; | ||
231 | acpi_size required_size; | ||
232 | |||
233 | ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle); | ||
234 | |||
235 | node = acpi_ns_map_handle_to_node(target_handle); | ||
236 | if (!node) { | ||
237 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
238 | } | ||
239 | |||
240 | /* Determine size required for the caller buffer */ | ||
241 | |||
242 | required_size = acpi_ns_get_pathname_length(node); | ||
243 | if (!required_size) { | ||
244 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
245 | } | ||
246 | |||
247 | /* Validate/Allocate/Clear caller buffer */ | ||
248 | |||
249 | status = acpi_ut_initialize_buffer(buffer, required_size); | ||
250 | if (ACPI_FAILURE(status)) { | ||
251 | return_ACPI_STATUS(status); | ||
252 | } | ||
253 | |||
254 | /* Build the path in the caller buffer */ | ||
255 | |||
256 | status = | ||
257 | acpi_ns_build_external_path(node, required_size, buffer->pointer); | ||
258 | if (ACPI_FAILURE(status)) { | ||
259 | return_ACPI_STATUS(status); | ||
260 | } | ||
261 | |||
262 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n", | ||
263 | (char *)buffer->pointer, (u32) required_size)); | ||
264 | return_ACPI_STATUS(AE_OK); | ||
265 | } | ||