Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: nsnames - Name manipulation and search
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, 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 
45
#include "accommon.h"
46
#include "amlcode.h"
47
#include "acnamesp.h"
48
 
49
#define _COMPONENT          ACPI_NAMESPACE
50
ACPI_MODULE_NAME("nsnames")
51
 
52
/*******************************************************************************
53
 *
54
 * FUNCTION:    acpi_ns_get_external_pathname
55
 *
56
 * PARAMETERS:  node            - Namespace node whose pathname is needed
57
 *
58
 * RETURN:      Pointer to storage containing the fully qualified name of
59
 *              the node, In external format (name segments separated by path
60
 *              separators.)
61
 *
62
 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
63
 *              for error and debug statements.
64
 *
65
 ******************************************************************************/
66
char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
67
{
68
	char *name_buffer;
69
 
70
	ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node);
71
 
72
	name_buffer = acpi_ns_get_normalized_pathname(node, FALSE);
73
 
74
	return_PTR(name_buffer);
75
}
76
 
77
/*******************************************************************************
78
 *
79
 * FUNCTION:    acpi_ns_get_pathname_length
80
 *
81
 * PARAMETERS:  node        - Namespace node
82
 *
83
 * RETURN:      Length of path, including prefix
84
 *
85
 * DESCRIPTION: Get the length of the pathname string for this node
86
 *
87
 ******************************************************************************/
88
 
89
acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
90
{
91
	acpi_size size;
92
 
93
	ACPI_FUNCTION_ENTRY();
94
 
95
	size = acpi_ns_build_normalized_path(node, NULL, 0, FALSE);
96
 
97
	return (size);
98
}
99
 
100
/*******************************************************************************
101
 *
102
 * FUNCTION:    acpi_ns_handle_to_pathname
103
 *
104
 * PARAMETERS:  target_handle           - Handle of named object whose name is
105
 *                                        to be found
106
 *              buffer                  - Where the pathname is returned
107
 *              no_trailing             - Remove trailing '_' for each name
108
 *                                        segment
109
 *
110
 * RETURN:      Status, Buffer is filled with pathname if status is AE_OK
111
 *
112
 * DESCRIPTION: Build and return a full namespace pathname
113
 *
114
 ******************************************************************************/
115
 
116
acpi_status
117
acpi_ns_handle_to_pathname(acpi_handle target_handle,
118
			   struct acpi_buffer * buffer, u8 no_trailing)
119
{
120
	acpi_status status;
121
	struct acpi_namespace_node *node;
122
	acpi_size required_size;
123
 
124
	ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle);
125
 
126
	node = acpi_ns_validate_handle(target_handle);
127
	if (!node) {
128
		return_ACPI_STATUS(AE_BAD_PARAMETER);
129
	}
130
 
131
	/* Determine size required for the caller buffer */
132
 
133
	required_size =
134
	    acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
135
	if (!required_size) {
136
		return_ACPI_STATUS(AE_BAD_PARAMETER);
137
	}
138
 
139
	/* Validate/Allocate/Clear caller buffer */
140
 
141
	status = acpi_ut_initialize_buffer(buffer, required_size);
142
	if (ACPI_FAILURE(status)) {
143
		return_ACPI_STATUS(status);
144
	}
145
 
146
	/* Build the path in the caller buffer */
147
 
148
	(void)acpi_ns_build_normalized_path(node, buffer->pointer,
149
					    required_size, no_trailing);
150
	if (ACPI_FAILURE(status)) {
151
		return_ACPI_STATUS(status);
152
	}
153
 
154
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
155
			  (char *)buffer->pointer, (u32) required_size));
156
	return_ACPI_STATUS(AE_OK);
157
}
158
 
159
/*******************************************************************************
160
 *
161
 * FUNCTION:    acpi_ns_build_normalized_path
162
 *
163
 * PARAMETERS:  node        - Namespace node
164
 *              full_path   - Where the path name is returned
165
 *              path_size   - Size of returned path name buffer
166
 *              no_trailing - Remove trailing '_' from each name segment
167
 *
168
 * RETURN:      Return 1 if the AML path is empty, otherwise returning (length
169
 *              of pathname + 1) which means the 'FullPath' contains a trailing
170
 *              null.
171
 *
172
 * DESCRIPTION: Build and return a full namespace pathname.
173
 *              Note that if the size of 'FullPath' isn't large enough to
174
 *              contain the namespace node's path name, the actual required
175
 *              buffer length is returned, and it should be greater than
176
 *              'PathSize'. So callers are able to check the returning value
177
 *              to determine the buffer size of 'FullPath'.
178
 *
179
 ******************************************************************************/
180
 
181
u32
182
acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
183
			      char *full_path, u32 path_size, u8 no_trailing)
184
{
185
	u32 length = 0, i;
186
	char name[ACPI_NAME_SIZE];
187
	u8 do_no_trailing;
188
	char c, *left, *right;
189
	struct acpi_namespace_node *next_node;
190
 
191
	ACPI_FUNCTION_TRACE_PTR(ns_build_normalized_path, node);
192
 
193
#define ACPI_PATH_PUT8(path, size, byte, length)    \
194
	do {                                            \
195
		if ((length) < (size))                      \
196
		{                                           \
197
			(path)[(length)] = (byte);              \
198
		}                                           \
199
		(length)++;                                 \
200
	} while (0)
201
 
202
	/*
203
	 * Make sure the path_size is correct, so that we don't need to
204
	 * validate both full_path and path_size.
205
	 */
206
	if (!full_path) {
207
		path_size = 0;
208
	}
209
 
210
	if (!node) {
211
		goto build_trailing_null;
212
	}
213
 
214
	next_node = node;
215
	while (next_node && next_node != acpi_gbl_root_node) {
216
		if (next_node != node) {
217
			ACPI_PATH_PUT8(full_path, path_size,
218
				       AML_DUAL_NAME_PREFIX, length);
219
		}
220
		ACPI_MOVE_32_TO_32(name, &next_node->name);
221
		do_no_trailing = no_trailing;
222
		for (i = 0; i < 4; i++) {
223
			c = name[4 - i - 1];
224
			if (do_no_trailing && c != '_') {
225
				do_no_trailing = FALSE;
226
			}
227
			if (!do_no_trailing) {
228
				ACPI_PATH_PUT8(full_path, path_size, c, length);
229
			}
230
		}
231
		next_node = next_node->parent;
232
	}
233
	ACPI_PATH_PUT8(full_path, path_size, AML_ROOT_PREFIX, length);
234
 
235
	/* Reverse the path string */
236
 
237
	if (length <= path_size) {
238
		left = full_path;
239
		right = full_path + length - 1;
240
		while (left < right) {
241
			c = *left;
242
			*left++ = *right;
243
			*right-- = c;
244
		}
245
	}
246
 
247
	/* Append the trailing null */
248
 
249
build_trailing_null:
250
	ACPI_PATH_PUT8(full_path, path_size, '\0', length);
251
 
252
#undef ACPI_PATH_PUT8
253
 
254
	return_UINT32(length);
255
}
256
 
257
/*******************************************************************************
258
 *
259
 * FUNCTION:    acpi_ns_get_normalized_pathname
260
 *
261
 * PARAMETERS:  node            - Namespace node whose pathname is needed
262
 *              no_trailing     - Remove trailing '_' from each name segment
263
 *
264
 * RETURN:      Pointer to storage containing the fully qualified name of
265
 *              the node, In external format (name segments separated by path
266
 *              separators.)
267
 *
268
 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
269
 *              for error and debug statements. All trailing '_' will be
270
 *              removed from the full pathname if 'NoTrailing' is specified..
271
 *
272
 ******************************************************************************/
273
 
274
char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
275
				      u8 no_trailing)
276
{
277
	char *name_buffer;
278
	acpi_size size;
279
 
280
	ACPI_FUNCTION_TRACE_PTR(ns_get_normalized_pathname, node);
281
 
282
	/* Calculate required buffer size based on depth below root */
283
 
284
	size = acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
285
	if (!size) {
286
		return_PTR(NULL);
287
	}
288
 
289
	/* Allocate a buffer to be returned to caller */
290
 
291
	name_buffer = ACPI_ALLOCATE_ZEROED(size);
292
	if (!name_buffer) {
293
		ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
294
		return_PTR(NULL);
295
	}
296
 
297
	/* Build the path in the allocated buffer */
298
 
299
	(void)acpi_ns_build_normalized_path(node, name_buffer, size,
300
					    no_trailing);
301
 
302
	return_PTR(name_buffer);
303
}