nsxfname.c 10.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8
/******************************************************************************
 *
 * Module Name: nsxfname - Public interfaces to the ACPI subsystem
 *                         ACPI Namespace oriented interfaces
 *
 *****************************************************************************/

/*
L
Len Brown 已提交
9
 * Copyright (C) 2000 - 2008, Intel Corp.
L
Linus Torvalds 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <acpi/acpi.h>
#include <acpi/acnamesp.h>

#define _COMPONENT          ACPI_NAMESPACE
L
Len Brown 已提交
49
ACPI_MODULE_NAME("nsxfname")
L
Linus Torvalds 已提交
50 51 52 53 54 55

/******************************************************************************
 *
 * FUNCTION:    acpi_get_handle
 *
 * PARAMETERS:  Parent          - Object to search under (search scope).
R
Robert Moore 已提交
56 57 58
 *              Pathname        - Pointer to an asciiz string containing the
 *                                name
 *              ret_handle      - Where the return handle is returned
L
Linus Torvalds 已提交
59 60 61 62 63 64 65 66 67 68
 *
 * RETURN:      Status
 *
 * DESCRIPTION: This routine will search for a caller specified name in the
 *              name space.  The caller can restrict the search region by
 *              specifying a non NULL parent.  The parent value is itself a
 *              namespace handle.
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
69 70
acpi_get_handle(acpi_handle parent,
		acpi_string pathname, acpi_handle * ret_handle)
L
Linus Torvalds 已提交
71
{
L
Len Brown 已提交
72 73 74
	acpi_status status;
	struct acpi_namespace_node *node = NULL;
	struct acpi_namespace_node *prefix_node = NULL;
L
Linus Torvalds 已提交
75

L
Len Brown 已提交
76
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
77 78 79 80 81 82 83 84 85 86

	/* Parameter Validation */

	if (!ret_handle || !pathname) {
		return (AE_BAD_PARAMETER);
	}

	/* Convert a parent handle to a prefix node */

	if (parent) {
L
Len Brown 已提交
87
		prefix_node = acpi_ns_map_handle_to_node(parent);
L
Linus Torvalds 已提交
88 89 90
		if (!prefix_node) {
			return (AE_BAD_PARAMETER);
		}
91 92 93 94 95 96 97 98 99 100
	}

	/*
	 * Valid cases are:
	 * 1) Fully qualified pathname
	 * 2) Parent + Relative pathname
	 *
	 * Error for <null Parent + relative path>
	 */
	if (acpi_ns_valid_root_prefix(pathname[0])) {
L
Linus Torvalds 已提交
101

102 103 104 105 106 107 108 109
		/* Pathname is fully qualified (starts with '\') */

		/* Special case for root-only, since we can't search for it */

		if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) {
			*ret_handle =
			    acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
			return (AE_OK);
L
Linus Torvalds 已提交
110
		}
111
	} else if (!prefix_node) {
L
Linus Torvalds 已提交
112

113
		/* Relative path with null prefix is disallowed */
L
Linus Torvalds 已提交
114

115
		return (AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
116 117
	}

118
	/* Find the Node and convert to a handle */
L
Linus Torvalds 已提交
119

120 121
	status =
	    acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
L
Len Brown 已提交
122 123
	if (ACPI_SUCCESS(status)) {
		*ret_handle = acpi_ns_convert_entry_to_handle(node);
L
Linus Torvalds 已提交
124 125 126 127 128
	}

	return (status);
}

B
Bob Moore 已提交
129
ACPI_EXPORT_SYMBOL(acpi_get_handle)
L
Linus Torvalds 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

/******************************************************************************
 *
 * FUNCTION:    acpi_get_name
 *
 * PARAMETERS:  Handle          - Handle to be converted to a pathname
 *              name_type       - Full pathname or single segment
 *              Buffer          - Buffer for returned path
 *
 * RETURN:      Pointer to a string containing the fully qualified Name.
 *
 * DESCRIPTION: This routine returns the fully qualified name associated with
 *              the Handle parameter.  This and the acpi_pathname_to_handle are
 *              complementary functions.
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
147
acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
L
Linus Torvalds 已提交
148
{
L
Len Brown 已提交
149 150
	acpi_status status;
	struct acpi_namespace_node *node;
L
Linus Torvalds 已提交
151 152 153 154 155 156 157

	/* Parameter validation */

	if (name_type > ACPI_NAME_TYPE_MAX) {
		return (AE_BAD_PARAMETER);
	}

L
Len Brown 已提交
158 159
	status = acpi_ut_validate_buffer(buffer);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
160 161 162 163
		return (status);
	}

	if (name_type == ACPI_FULL_PATHNAME) {
B
Bob Moore 已提交
164

L
Linus Torvalds 已提交
165 166
		/* Get the full pathname (From the namespace root) */

L
Len Brown 已提交
167
		status = acpi_ns_handle_to_pathname(handle, buffer);
L
Linus Torvalds 已提交
168 169 170 171 172 173 174
		return (status);
	}

	/*
	 * Wants the single segment ACPI name.
	 * Validate handle and convert to a namespace Node
	 */
L
Len Brown 已提交
175 176
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
177 178 179
		return (status);
	}

L
Len Brown 已提交
180
	node = acpi_ns_map_handle_to_node(handle);
L
Linus Torvalds 已提交
181 182 183 184 185 186 187
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

	/* Validate/Allocate/Clear caller buffer */

L
Len Brown 已提交
188 189
	status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
190 191 192 193 194
		goto unlock_and_exit;
	}

	/* Just copy the ACPI name from the Node and zero terminate it */

L
Len Brown 已提交
195 196 197
	ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node),
		     ACPI_NAME_SIZE);
	((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
L
Linus Torvalds 已提交
198 199
	status = AE_OK;

L
Len Brown 已提交
200
      unlock_and_exit:
L
Linus Torvalds 已提交
201

L
Len Brown 已提交
202
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
L
Linus Torvalds 已提交
203 204 205
	return (status);
}

B
Bob Moore 已提交
206
ACPI_EXPORT_SYMBOL(acpi_get_name)
L
Linus Torvalds 已提交
207 208 209 210 211 212

/******************************************************************************
 *
 * FUNCTION:    acpi_get_object_info
 *
 * PARAMETERS:  Handle          - Object Handle
R
Robert Moore 已提交
213
 *              Buffer          - Where the info is returned
L
Linus Torvalds 已提交
214 215 216 217 218 219 220 221 222
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Returns information about an object as gleaned from the
 *              namespace node and possibly by running several standard
 *              control methods (Such as in the case of a device.)
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
223
acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
L
Linus Torvalds 已提交
224
{
L
Len Brown 已提交
225 226 227 228
	acpi_status status;
	struct acpi_namespace_node *node;
	struct acpi_device_info *info;
	struct acpi_device_info *return_info;
L
Linus Torvalds 已提交
229
	struct acpi_compatible_id_list *cid_list = NULL;
L
Len Brown 已提交
230
	acpi_size size;
L
Linus Torvalds 已提交
231 232 233 234 235 236 237

	/* Parameter validation */

	if (!handle || !buffer) {
		return (AE_BAD_PARAMETER);
	}

L
Len Brown 已提交
238 239
	status = acpi_ut_validate_buffer(buffer);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
240 241 242
		return (status);
	}

B
Bob Moore 已提交
243
	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info));
L
Linus Torvalds 已提交
244 245 246 247
	if (!info) {
		return (AE_NO_MEMORY);
	}

L
Len Brown 已提交
248 249
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
250 251 252
		goto cleanup;
	}

L
Len Brown 已提交
253
	node = acpi_ns_map_handle_to_node(handle);
L
Linus Torvalds 已提交
254
	if (!node) {
L
Len Brown 已提交
255
		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
256
		status = AE_BAD_PARAMETER;
L
Linus Torvalds 已提交
257 258 259 260 261
		goto cleanup;
	}

	/* Init return structure */

L
Len Brown 已提交
262
	size = sizeof(struct acpi_device_info);
L
Linus Torvalds 已提交
263

L
Len Brown 已提交
264 265
	info->type = node->type;
	info->name = node->name.integer;
L
Linus Torvalds 已提交
266 267
	info->valid = 0;

268 269 270 271
	if (node->type == ACPI_TYPE_METHOD) {
		info->param_count = node->object->method.param_count;
	}

L
Len Brown 已提交
272 273
	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
		goto cleanup;
	}

	/* If not a device, we are all done */

	if (info->type == ACPI_TYPE_DEVICE) {
		/*
		 * Get extra info for ACPI Devices objects only:
		 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
		 *
		 * Note: none of these methods are required, so they may or may
		 * not be present for this device.  The Info->Valid bitfield is used
		 * to indicate which methods were found and ran successfully.
		 */

		/* Execute the Device._HID method */

L
Len Brown 已提交
291 292
		status = acpi_ut_execute_HID(node, &info->hardware_id);
		if (ACPI_SUCCESS(status)) {
L
Linus Torvalds 已提交
293 294 295 296 297
			info->valid |= ACPI_VALID_HID;
		}

		/* Execute the Device._UID method */

L
Len Brown 已提交
298 299
		status = acpi_ut_execute_UID(node, &info->unique_id);
		if (ACPI_SUCCESS(status)) {
L
Linus Torvalds 已提交
300 301 302 303 304
			info->valid |= ACPI_VALID_UID;
		}

		/* Execute the Device._CID method */

L
Len Brown 已提交
305 306
		status = acpi_ut_execute_CID(node, &cid_list);
		if (ACPI_SUCCESS(status)) {
B
Bob Moore 已提交
307
			size += cid_list->size;
L
Linus Torvalds 已提交
308 309 310 311 312
			info->valid |= ACPI_VALID_CID;
		}

		/* Execute the Device._STA method */

L
Len Brown 已提交
313 314
		status = acpi_ut_execute_STA(node, &info->current_status);
		if (ACPI_SUCCESS(status)) {
L
Linus Torvalds 已提交
315 316 317 318 319
			info->valid |= ACPI_VALID_STA;
		}

		/* Execute the Device._ADR method */

L
Len Brown 已提交
320 321 322
		status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
							 &info->address);
		if (ACPI_SUCCESS(status)) {
L
Linus Torvalds 已提交
323 324 325 326 327
			info->valid |= ACPI_VALID_ADR;
		}

		/* Execute the Device._sx_d methods */

L
Len Brown 已提交
328 329
		status = acpi_ut_execute_sxds(node, info->highest_dstates);
		if (ACPI_SUCCESS(status)) {
L
Linus Torvalds 已提交
330 331 332 333 334 335
			info->valid |= ACPI_VALID_SXDS;
		}
	}

	/* Validate/Allocate/Clear caller buffer */

L
Len Brown 已提交
336 337
	status = acpi_ut_initialize_buffer(buffer, size);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
338 339 340 341 342 343
		goto cleanup;
	}

	/* Populate the return buffer */

	return_info = buffer->pointer;
L
Len Brown 已提交
344
	ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info));
L
Linus Torvalds 已提交
345 346

	if (cid_list) {
L
Len Brown 已提交
347 348
		ACPI_MEMCPY(&return_info->compatibility_id, cid_list,
			    cid_list->size);
L
Linus Torvalds 已提交
349 350
	}

L
Len Brown 已提交
351
      cleanup:
B
Bob Moore 已提交
352
	ACPI_FREE(info);
L
Linus Torvalds 已提交
353
	if (cid_list) {
B
Bob Moore 已提交
354
		ACPI_FREE(cid_list);
L
Linus Torvalds 已提交
355 356 357 358
	}
	return (status);
}

B
Bob Moore 已提交
359
ACPI_EXPORT_SYMBOL(acpi_get_object_info)