[go: nahoru, domu]

11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                         ACPI Object evaluation interfaces
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
9fbb7a2dc2be493c87399550bdc2ddaa510cdf450Bob Moore * Copyright (C) 2000 - 2014, Intel Corp.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved.
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met:
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    notice, this list of conditions, and the following disclaimer,
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    without modification.
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    substantially similar to the "NO WARRANTY" disclaimer below
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ("Disclaimer") and any redistribution must be conditioned upon
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    including a substantially similar Disclaimer requirement for further
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    binary redistribution.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    of any contributors may be used to endorse or promote products derived
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    from this software without specific prior written permission.
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation.
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
45839e928f5bbb695c31ddc23cf3fae3cf1c9e9f20Lv Zheng#define EXPORT_ACPI_INTERFACES
46839e928f5bbb695c31ddc23cf3fae3cf1c9e9f20Lv Zheng
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h>
48e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "accommon.h"
49e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acnamesp.h"
50e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acinterp.h"
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT          ACPI_NAMESPACE
534be44fcd3bf648b782f4460fd06dfae6c42ded4bLen BrownACPI_MODULE_NAME("nsxfeval")
54bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
55bbc241340681557a16982f4d1840f00963bc05b4Lin Ming/* Local prototypes */
56bbc241340681557a16982f4d1840f00963bc05b4Lin Mingstatic void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
57bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_evaluate_object_typed
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
62ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Object handle (optional)
63ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              pathname            - Object pathname (optional)
6444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *              external_params     - List of parameters to pass to method,
6573a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *                                    terminated by NULL. May be NULL
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    if no parameters are being passed.
6744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *              return_buffer       - Where to put method's return value (if
6873a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *                                    any). If NULL, no value is returned.
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              return_type         - Expected type of return object
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Find and evaluate the given object, passing the given
7473a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *              parameters if necessary. One of "Handle" or "Pathname" must
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              be valid (non-null)
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
78bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
804be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_evaluate_object_typed(acpi_handle handle,
814be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			   acpi_string pathname,
82fd3509436fde38d4c854bf5a6b83d2c779904f8eLen Brown			   struct acpi_object_list *external_params,
83fd3509436fde38d4c854bf5a6b83d2c779904f8eLen Brown			   struct acpi_buffer *return_buffer,
844be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			   acpi_object_type return_type)
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
87bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng	u8 free_buffer_on_error = FALSE;
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
89b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed);
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Return buffer must be valid */
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!return_buffer) {
944be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_BAD_PARAMETER);
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
98bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		free_buffer_on_error = TRUE;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Evaluate the object */
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
103bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng	status = acpi_evaluate_object(handle, pathname,
104bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng				      external_params, return_buffer);
1054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
1064be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(status);
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Type ANY means "don't care" */
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (return_type == ACPI_TYPE_ANY) {
1124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_OK);
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (return_buffer->length == 0) {
11652fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Error because caller specifically asked for a return value */
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
119b8e4d89357fc434618a59c1047cac72641191805Bob Moore		ACPI_ERROR((AE_INFO, "No return value"));
1204be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_NULL_OBJECT);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Examine the object type returned from evaluate_object */
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1254be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (((union acpi_object *)return_buffer->pointer)->type == return_type) {
1264be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_OK);
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Return object type does not match requested type */
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131b8e4d89357fc434618a59c1047cac72641191805Bob Moore	ACPI_ERROR((AE_INFO,
132b8e4d89357fc434618a59c1047cac72641191805Bob Moore		    "Incorrect return type [%s] requested [%s]",
133b8e4d89357fc434618a59c1047cac72641191805Bob Moore		    acpi_ut_get_type_name(((union acpi_object *)return_buffer->
134b8e4d89357fc434618a59c1047cac72641191805Bob Moore					   pointer)->type),
135b8e4d89357fc434618a59c1047cac72641191805Bob Moore		    acpi_ut_get_type_name(return_type)));
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
137bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng	if (free_buffer_on_error) {
138bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		/*
139bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		 * Free a buffer created via ACPI_ALLOCATE_BUFFER.
140bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		 * Note: We use acpi_os_free here because acpi_os_allocate was used
141bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		 * to allocate the buffer. This purposefully bypasses the
142bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		 * (optionally enabled) allocation tracking mechanism since we
143bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		 * only want to track internal allocations.
144bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		 */
145bb3fec146c8561441db058db07b3fbdd7fe7e1dfLv Zheng		acpi_os_free(return_buffer->pointer);
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return_buffer->pointer = NULL;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return_buffer->length = 0;
1504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(AE_TYPE);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1528313524a0d466f451a62709aaedf988d8257b21cBob Moore
1538313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
1542c03d07ad54db03b813bb98c469790c07ca9f5ddLuca Tettamanti
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_evaluate_object
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
159ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  handle              - Object handle (optional)
160ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              pathname            - Object pathname (optional)
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              external_params     - List of parameters to pass to method,
16273a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *                                    terminated by NULL. May be NULL
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    if no parameters are being passed.
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              return_buffer       - Where to put method's return value (if
16573a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *                                    any). If NULL, no value is returned.
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Find and evaluate the given object, passing the given
17073a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *              parameters if necessary. One of "Handle" or "Pathname" must
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              be valid (non-null)
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
1754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_evaluate_object(acpi_handle handle,
1764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		     acpi_string pathname,
1774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		     struct acpi_object_list *external_params,
1784be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		     struct acpi_buffer *return_buffer)
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1804be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
1814119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	struct acpi_evaluate_info *info;
1824be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_size buffer_space_needed;
1834be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u32 i;
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
185b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(acpi_evaluate_object);
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1874119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	/* Allocate and initialize the evaluation information block */
1884119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
1894119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
1904119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	if (!info) {
1914119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		return_ACPI_STATUS(AE_NO_MEMORY);
1924119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	}
1934119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
1944119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	/* Convert and validate the device handle */
1954119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
196f24b664dc44a4ab4df61db2258cea298eeb43a8eBob Moore	info->prefix_node = acpi_ns_validate_handle(handle);
1974119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	if (!info->prefix_node) {
1984119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		status = AE_BAD_PARAMETER;
1994119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		goto cleanup;
2004119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	}
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
20329a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * Get the actual namespace node for the target object.
20429a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * Handles these cases:
20529a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 *
20629a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * 1) Null node, valid pathname from root (absolute path)
20729a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * 2) Node and valid pathname (path relative to Node)
20829a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * 3) Node, Null pathname
20929a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 */
21029a241cc02110b8b2259fd72719b8cadc03909beBob Moore	if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
21129a241cc02110b8b2259fd72719b8cadc03909beBob Moore
21229a241cc02110b8b2259fd72719b8cadc03909beBob Moore		/* The path is fully qualified, just evaluate by name */
21329a241cc02110b8b2259fd72719b8cadc03909beBob Moore
21429a241cc02110b8b2259fd72719b8cadc03909beBob Moore		info->prefix_node = NULL;
21529a241cc02110b8b2259fd72719b8cadc03909beBob Moore	} else if (!handle) {
21629a241cc02110b8b2259fd72719b8cadc03909beBob Moore		/*
21729a241cc02110b8b2259fd72719b8cadc03909beBob Moore		 * A handle is optional iff a fully qualified pathname is specified.
21829a241cc02110b8b2259fd72719b8cadc03909beBob Moore		 * Since we've already handled fully qualified names above, this is
21929a241cc02110b8b2259fd72719b8cadc03909beBob Moore		 * an error.
22029a241cc02110b8b2259fd72719b8cadc03909beBob Moore		 */
22129a241cc02110b8b2259fd72719b8cadc03909beBob Moore		if (!pathname) {
22229a241cc02110b8b2259fd72719b8cadc03909beBob Moore			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
22329a241cc02110b8b2259fd72719b8cadc03909beBob Moore					  "Both Handle and Pathname are NULL"));
22429a241cc02110b8b2259fd72719b8cadc03909beBob Moore		} else {
22529a241cc02110b8b2259fd72719b8cadc03909beBob Moore			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
22629a241cc02110b8b2259fd72719b8cadc03909beBob Moore					  "Null Handle with relative pathname [%s]",
22729a241cc02110b8b2259fd72719b8cadc03909beBob Moore					  pathname));
22829a241cc02110b8b2259fd72719b8cadc03909beBob Moore		}
22929a241cc02110b8b2259fd72719b8cadc03909beBob Moore
23029a241cc02110b8b2259fd72719b8cadc03909beBob Moore		status = AE_BAD_PARAMETER;
23129a241cc02110b8b2259fd72719b8cadc03909beBob Moore		goto cleanup;
23229a241cc02110b8b2259fd72719b8cadc03909beBob Moore	}
23329a241cc02110b8b2259fd72719b8cadc03909beBob Moore
23429a241cc02110b8b2259fd72719b8cadc03909beBob Moore	info->relative_pathname = pathname;
23529a241cc02110b8b2259fd72719b8cadc03909beBob Moore
23629a241cc02110b8b2259fd72719b8cadc03909beBob Moore	/*
23729a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * Convert all external objects passed as arguments to the
23829a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * internal version(s).
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (external_params && external_params->count) {
24129a241cc02110b8b2259fd72719b8cadc03909beBob Moore		info->param_count = (u16)external_params->count;
24229a241cc02110b8b2259fd72719b8cadc03909beBob Moore
24329a241cc02110b8b2259fd72719b8cadc03909beBob Moore		/* Warn on impossible argument count */
24429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
24529a241cc02110b8b2259fd72719b8cadc03909beBob Moore		if (info->param_count > ACPI_METHOD_NUM_ARGS) {
24629a241cc02110b8b2259fd72719b8cadc03909beBob Moore			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
24729a241cc02110b8b2259fd72719b8cadc03909beBob Moore					      ACPI_WARN_ALWAYS,
24829a241cc02110b8b2259fd72719b8cadc03909beBob Moore					      "Excess arguments (%u) - using only %u",
24929a241cc02110b8b2259fd72719b8cadc03909beBob Moore					      info->param_count,
25029a241cc02110b8b2259fd72719b8cadc03909beBob Moore					      ACPI_METHOD_NUM_ARGS));
25129a241cc02110b8b2259fd72719b8cadc03909beBob Moore
25229a241cc02110b8b2259fd72719b8cadc03909beBob Moore			info->param_count = ACPI_METHOD_NUM_ARGS;
25329a241cc02110b8b2259fd72719b8cadc03909beBob Moore		}
25429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Allocate a new parameter block for the internal objects
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Add 1 to count to allow for null terminated internal list
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
25929a241cc02110b8b2259fd72719b8cadc03909beBob Moore		info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info->
26029a241cc02110b8b2259fd72719b8cadc03909beBob Moore							 param_count +
2614119532c95547821dbe72d6916dfa1b2148475b3Bob Moore							 1) * sizeof(void *));
2624119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		if (!info->parameters) {
2634119532c95547821dbe72d6916dfa1b2148475b3Bob Moore			status = AE_NO_MEMORY;
2644119532c95547821dbe72d6916dfa1b2148475b3Bob Moore			goto cleanup;
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2674119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		/* Convert each external object in the list to an internal object */
2684119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
26929a241cc02110b8b2259fd72719b8cadc03909beBob Moore		for (i = 0; i < info->param_count; i++) {
2704be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			status =
2714be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    acpi_ut_copy_eobject_to_iobject(&external_params->
2724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							    pointer[i],
2734119532c95547821dbe72d6916dfa1b2148475b3Bob Moore							    &info->
2744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							    parameters[i]);
2754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			if (ACPI_FAILURE(status)) {
2764119532c95547821dbe72d6916dfa1b2148475b3Bob Moore				goto cleanup;
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
27929a241cc02110b8b2259fd72719b8cadc03909beBob Moore
28029a241cc02110b8b2259fd72719b8cadc03909beBob Moore		info->parameters[info->param_count] = NULL;
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
28329a241cc02110b8b2259fd72719b8cadc03909beBob Moore#if 0
28429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
28629a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * Begin incoming argument count analysis. Check for too few args
28729a241cc02110b8b2259fd72719b8cadc03909beBob Moore	 * and too many args.
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
28952fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
29029a241cc02110b8b2259fd72719b8cadc03909beBob Moore	switch (acpi_ns_get_type(info->node)) {
29129a241cc02110b8b2259fd72719b8cadc03909beBob Moore	case ACPI_TYPE_METHOD:
29229a241cc02110b8b2259fd72719b8cadc03909beBob Moore
29329a241cc02110b8b2259fd72719b8cadc03909beBob Moore		/* Check incoming argument count against the method definition */
29429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
29529a241cc02110b8b2259fd72719b8cadc03909beBob Moore		if (info->obj_desc->method.param_count > info->param_count) {
29629a241cc02110b8b2259fd72719b8cadc03909beBob Moore			ACPI_ERROR((AE_INFO,
29729a241cc02110b8b2259fd72719b8cadc03909beBob Moore				    "Insufficient arguments (%u) - %u are required",
29829a241cc02110b8b2259fd72719b8cadc03909beBob Moore				    info->param_count,
29929a241cc02110b8b2259fd72719b8cadc03909beBob Moore				    info->obj_desc->method.param_count));
30029a241cc02110b8b2259fd72719b8cadc03909beBob Moore
30129a241cc02110b8b2259fd72719b8cadc03909beBob Moore			status = AE_MISSING_ARGUMENTS;
30229a241cc02110b8b2259fd72719b8cadc03909beBob Moore			goto cleanup;
30329a241cc02110b8b2259fd72719b8cadc03909beBob Moore		}
30429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
30529a241cc02110b8b2259fd72719b8cadc03909beBob Moore		else if (info->obj_desc->method.param_count < info->param_count) {
30629a241cc02110b8b2259fd72719b8cadc03909beBob Moore			ACPI_WARNING((AE_INFO,
30729a241cc02110b8b2259fd72719b8cadc03909beBob Moore				      "Excess arguments (%u) - only %u are required",
30829a241cc02110b8b2259fd72719b8cadc03909beBob Moore				      info->param_count,
30929a241cc02110b8b2259fd72719b8cadc03909beBob Moore				      info->obj_desc->method.param_count));
31029a241cc02110b8b2259fd72719b8cadc03909beBob Moore
31129a241cc02110b8b2259fd72719b8cadc03909beBob Moore			/* Just pass the required number of arguments */
31229a241cc02110b8b2259fd72719b8cadc03909beBob Moore
31329a241cc02110b8b2259fd72719b8cadc03909beBob Moore			info->param_count = info->obj_desc->method.param_count;
31429a241cc02110b8b2259fd72719b8cadc03909beBob Moore		}
31552fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
31729a241cc02110b8b2259fd72719b8cadc03909beBob Moore		 * Any incoming external objects to be passed as arguments to the
31829a241cc02110b8b2259fd72719b8cadc03909beBob Moore		 * method must be converted to internal objects
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
32029a241cc02110b8b2259fd72719b8cadc03909beBob Moore		if (info->param_count) {
32129a241cc02110b8b2259fd72719b8cadc03909beBob Moore			/*
32229a241cc02110b8b2259fd72719b8cadc03909beBob Moore			 * Allocate a new parameter block for the internal objects
32329a241cc02110b8b2259fd72719b8cadc03909beBob Moore			 * Add 1 to count to allow for null terminated internal list
32429a241cc02110b8b2259fd72719b8cadc03909beBob Moore			 */
32529a241cc02110b8b2259fd72719b8cadc03909beBob Moore			info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
32629a241cc02110b8b2259fd72719b8cadc03909beBob Moore								 info->
32729a241cc02110b8b2259fd72719b8cadc03909beBob Moore								 param_count +
32829a241cc02110b8b2259fd72719b8cadc03909beBob Moore								 1) *
32929a241cc02110b8b2259fd72719b8cadc03909beBob Moore								sizeof(void *));
33029a241cc02110b8b2259fd72719b8cadc03909beBob Moore			if (!info->parameters) {
33129a241cc02110b8b2259fd72719b8cadc03909beBob Moore				status = AE_NO_MEMORY;
33229a241cc02110b8b2259fd72719b8cadc03909beBob Moore				goto cleanup;
33329a241cc02110b8b2259fd72719b8cadc03909beBob Moore			}
33429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
33529a241cc02110b8b2259fd72719b8cadc03909beBob Moore			/* Convert each external object in the list to an internal object */
33629a241cc02110b8b2259fd72719b8cadc03909beBob Moore
33729a241cc02110b8b2259fd72719b8cadc03909beBob Moore			for (i = 0; i < info->param_count; i++) {
33829a241cc02110b8b2259fd72719b8cadc03909beBob Moore				status =
33929a241cc02110b8b2259fd72719b8cadc03909beBob Moore				    acpi_ut_copy_eobject_to_iobject
34029a241cc02110b8b2259fd72719b8cadc03909beBob Moore				    (&external_params->pointer[i],
34129a241cc02110b8b2259fd72719b8cadc03909beBob Moore				     &info->parameters[i]);
34229a241cc02110b8b2259fd72719b8cadc03909beBob Moore				if (ACPI_FAILURE(status)) {
34329a241cc02110b8b2259fd72719b8cadc03909beBob Moore					goto cleanup;
34429a241cc02110b8b2259fd72719b8cadc03909beBob Moore				}
34529a241cc02110b8b2259fd72719b8cadc03909beBob Moore			}
34629a241cc02110b8b2259fd72719b8cadc03909beBob Moore
34729a241cc02110b8b2259fd72719b8cadc03909beBob Moore			info->parameters[info->param_count] = NULL;
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
34929a241cc02110b8b2259fd72719b8cadc03909beBob Moore		break;
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35129a241cc02110b8b2259fd72719b8cadc03909beBob Moore	default:
35229a241cc02110b8b2259fd72719b8cadc03909beBob Moore
35329a241cc02110b8b2259fd72719b8cadc03909beBob Moore		/* Warn if arguments passed to an object that is not a method */
35452fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
35529a241cc02110b8b2259fd72719b8cadc03909beBob Moore		if (info->param_count) {
35629a241cc02110b8b2259fd72719b8cadc03909beBob Moore			ACPI_WARNING((AE_INFO,
35729a241cc02110b8b2259fd72719b8cadc03909beBob Moore				      "%u arguments were passed to a non-method ACPI object",
35829a241cc02110b8b2259fd72719b8cadc03909beBob Moore				      info->param_count));
35929a241cc02110b8b2259fd72719b8cadc03909beBob Moore		}
36029a241cc02110b8b2259fd72719b8cadc03909beBob Moore		break;
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
36329a241cc02110b8b2259fd72719b8cadc03909beBob Moore#endif
36429a241cc02110b8b2259fd72719b8cadc03909beBob Moore
36529a241cc02110b8b2259fd72719b8cadc03909beBob Moore	/* Now we can evaluate the object */
36629a241cc02110b8b2259fd72719b8cadc03909beBob Moore
36729a241cc02110b8b2259fd72719b8cadc03909beBob Moore	status = acpi_ns_evaluate(info);
36829a241cc02110b8b2259fd72719b8cadc03909beBob Moore
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If we are expecting a return value, and all went well above,
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * copy the return value to an external object.
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (return_buffer) {
3744119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		if (!info->return_object) {
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_buffer->length = 0;
3764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		} else {
3774119532c95547821dbe72d6916dfa1b2148475b3Bob Moore			if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
3784be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    ACPI_DESC_TYPE_NAMED) {
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * If we received a NS Node as a return object, this means that
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * the object we are evaluating has nothing interesting to
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * return (such as a mutex, etc.)  We return an error because
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * these types are essentially unsupported by this interface.
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * We don't check up front because this makes it easier to add
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * support for various types at a later date if necessary.
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = AE_TYPE;
3884119532c95547821dbe72d6916dfa1b2148475b3Bob Moore				info->return_object = NULL;	/* No need to delete a NS Node */
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return_buffer->length = 0;
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			if (ACPI_SUCCESS(status)) {
3934119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
394bbc241340681557a16982f4d1840f00963bc05b4Lin Ming				/* Dereference Index and ref_of references */
395bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
396bbc241340681557a16982f4d1840f00963bc05b4Lin Ming				acpi_ns_resolve_references(info);
397bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
3984119532c95547821dbe72d6916dfa1b2148475b3Bob Moore				/* Get the size of the returned object */
3994119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
4004be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				status =
4014119532c95547821dbe72d6916dfa1b2148475b3Bob Moore				    acpi_ut_get_object_size(info->return_object,
4024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown							    &buffer_space_needed);
4034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				if (ACPI_SUCCESS(status)) {
40452fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					/* Validate/Allocate/Clear caller buffer */
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					status =
4084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					    acpi_ut_initialize_buffer
4094be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					    (return_buffer,
4104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					     buffer_space_needed);
4114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					if (ACPI_FAILURE(status)) {
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						/*
41352fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore						 * Caller's buffer is too small or a new one can't
41452fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore						 * be allocated
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 */
4164be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4174be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  "Needed buffer size %X, %s\n",
4184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  (u32)
4194be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  buffer_space_needed,
4204be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  acpi_format_exception
4214be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown								  (status)));
4224be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					} else {
42352fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore						/* We have enough space for the object, build it */
42452fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
4254be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						status =
4264be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						    acpi_ut_copy_iobject_to_eobject
4274119532c95547821dbe72d6916dfa1b2148475b3Bob Moore						    (info->return_object,
4284be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						     return_buffer);
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4354119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	if (info->return_object) {
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
4374119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		 * Delete the internal return object. NOTE: Interpreter must be
4384119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		 * locked to avoid race condition.
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
4404d2acd9ea539e0f59178b126f6750ccc41eefcddLen Brown		acpi_ex_enter_interpreter();
4414119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
4424d2acd9ea539e0f59178b126f6750ccc41eefcddLen Brown		/* Remove one reference on the return object (should delete it) */
4434119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
4444d2acd9ea539e0f59178b126f6750ccc41eefcddLen Brown		acpi_ut_remove_reference(info->return_object);
4454d2acd9ea539e0f59178b126f6750ccc41eefcddLen Brown		acpi_ex_exit_interpreter();
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44810622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengcleanup:
4494119532c95547821dbe72d6916dfa1b2148475b3Bob Moore
45052fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore	/* Free the input parameter list (if we created one) */
45152fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
4524119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	if (info->parameters) {
45352fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Free the allocated parameter block */
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4564119532c95547821dbe72d6916dfa1b2148475b3Bob Moore		acpi_ut_delete_internal_object_list(info->parameters);
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4594119532c95547821dbe72d6916dfa1b2148475b3Bob Moore	ACPI_FREE(info);
4604be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4638313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_evaluate_object)
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
467bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * FUNCTION:    acpi_ns_resolve_references
468bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
469ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  info                    - Evaluation info block
470bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
471bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * RETURN:      Info->return_object is replaced with the dereferenced object
472bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
473bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * DESCRIPTION: Dereference certain reference objects. Called before an
474bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *              internal return object is converted to an external union acpi_object.
475bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
476bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * Performs an automatic dereference of Index and ref_of reference objects.
477bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * These reference objects are not supported by the union acpi_object, so this is a
478bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * last resort effort to return something useful. Also, provides compatibility
479bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * with other ACPI implementations.
480bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
481bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * NOTE: does not handle references within returned package objects or nested
482bbc241340681557a16982f4d1840f00963bc05b4Lin Ming * references, but this support could be added later if found to be necessary.
483bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
484bbc241340681557a16982f4d1840f00963bc05b4Lin Ming ******************************************************************************/
485bbc241340681557a16982f4d1840f00963bc05b4Lin Mingstatic void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
486bbc241340681557a16982f4d1840f00963bc05b4Lin Ming{
487bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	union acpi_operand_object *obj_desc = NULL;
488bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	struct acpi_namespace_node *node;
489bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
490bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	/* We are interested in reference objects only */
491bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
4923371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore	if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
493bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		return;
494bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	}
495bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
496bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	/*
497bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	 * Two types of references are supported - those created by Index and
498bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	 * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
499bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	 * to an union acpi_object, so it is not dereferenced here. A ddb_handle
500bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
501bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	 * an union acpi_object.
502bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	 */
5031044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	switch (info->return_object->reference.class) {
5041044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_INDEX:
505bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
506bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		obj_desc = *(info->return_object->reference.where);
507bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		break;
508bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
5091044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_REFOF:
510bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
511bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		node = info->return_object->reference.object;
512bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		if (node) {
513bbc241340681557a16982f4d1840f00963bc05b4Lin Ming			obj_desc = node->object;
514bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		}
515bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		break;
516bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
517bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	default:
5181d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
519bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		return;
520bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	}
521bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
522bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	/* Replace the existing reference object */
523bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
524bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	if (obj_desc) {
525bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		acpi_ut_add_reference(obj_desc);
526bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		acpi_ut_remove_reference(info->return_object);
527bbc241340681557a16982f4d1840f00963bc05b4Lin Ming		info->return_object = obj_desc;
528bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	}
529bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
530bbc241340681557a16982f4d1840f00963bc05b4Lin Ming	return;
531bbc241340681557a16982f4d1840f00963bc05b4Lin Ming}
532bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
533bbc241340681557a16982f4d1840f00963bc05b4Lin Ming/*******************************************************************************
534bbc241340681557a16982f4d1840f00963bc05b4Lin Ming *
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_walk_namespace
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
537ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore * PARAMETERS:  type                - acpi_object_type to search for
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              start_object        - Handle in namespace where search begins
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              max_depth           - Depth to which search is to reach
5404ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore *              descending_callback - Called during tree descent
5412263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *                                    when an object of "Type" is found
5424ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore *              ascending_callback  - Called during tree ascent
5432263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *                                    when an object of "Type" is found
544ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              context             - Passed to user function(s) above
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              return_value        - Location where return value of
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    user_function is put if terminated early
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURNS      Return value from the user_function if terminated early.
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Otherwise, returns NULL.
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              starting (and ending) at the object specified by start_handle.
5532263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *              The callback function is called whenever an object that matches
5542263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *              the type parameter is found. If the callback function returns
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              a non-zero value, the search is terminated immediately and this
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              value is returned to the caller.
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              The point of this procedure is to provide a generic namespace
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              walk routine that can be called from multiple places to
5602263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *              provide multiple services; the callback function(s) can be
5612263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *              tailored to each task, whether it is a print function,
5622263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming *              a compare function, etc.
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
565bbc241340681557a16982f4d1840f00963bc05b4Lin Ming
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
5674be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_walk_namespace(acpi_object_type type,
5684be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_handle start_object,
5694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    u32 max_depth,
5704ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore		    acpi_walk_callback descending_callback,
5714ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore		    acpi_walk_callback ascending_callback,
5724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    void *context, void **return_value)
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
576b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(acpi_walk_namespace);
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Parameter validation */
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5802263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming	if ((type > ACPI_TYPE_LOCAL_MAX) ||
5814ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore	    (!max_depth) || (!descending_callback && !ascending_callback)) {
5824be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_BAD_PARAMETER);
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
5868a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * Need to acquire the namespace reader lock to prevent interference
5878a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * with any concurrent table unloads (which causes the deletion of
5888a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * namespace objects). We cannot allow the deletion of a namespace node
5898a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * while the user function is using it. The exception to this are the
5908a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * nodes created and deleted during control method execution -- these
5918a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * nodes are marked as temporary nodes and are ignored by the namespace
5928a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * walk. Thus, control methods can be executed while holding the
5938a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * namespace deletion lock (and the user function can execute control
5948a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * methods.)
5958a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 */
5968a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
5978a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	if (ACPI_FAILURE(status)) {
5987b6afb6782053f9679f5b9f05287f8c700d7d68fLv Zheng		return_ACPI_STATUS(status);
5998a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	}
6008a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore
6018a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	/*
6028a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * Lock the namespace around the walk. The namespace will be
6038a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * unlocked/locked around each call to the user function - since the user
6048a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * function must be allowed to make ACPICA calls itself (for example, it
6058a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	 * will typically execute control methods during device enumeration.)
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
6084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
6098a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore		goto unlock_and_exit;
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
612d53d820741806a5488d0f002b61765deb58371f3Bob Moore	/* Now we can validate the starting node */
613d53d820741806a5488d0f002b61765deb58371f3Bob Moore
614d53d820741806a5488d0f002b61765deb58371f3Bob Moore	if (!acpi_ns_validate_handle(start_object)) {
615d53d820741806a5488d0f002b61765deb58371f3Bob Moore		status = AE_BAD_PARAMETER;
616d53d820741806a5488d0f002b61765deb58371f3Bob Moore		goto unlock_and_exit2;
617d53d820741806a5488d0f002b61765deb58371f3Bob Moore	}
618d53d820741806a5488d0f002b61765deb58371f3Bob Moore
6194be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ns_walk_namespace(type, start_object, max_depth,
6204ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore					ACPI_NS_WALK_UNLOCK,
6214ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore					descending_callback, ascending_callback,
6224ef17507834d19ba4fc24c4c1c61e8f68df356a6Bob Moore					context, return_value);
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
62410622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengunlock_and_exit2:
6254be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
6268a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore
62710622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengunlock_and_exit:
6288a335a2331c72e60c6b3ef09b2dedd3ba00da1b1Bob Moore	(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
6294be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6328313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_walk_namespace)
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ns_get_device_callback
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  Callback from acpi_get_device
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              present devices, or if they specified a HID, it filters based
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              on that.
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic acpi_status
6484be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ns_get_device_callback(acpi_handle obj_handle,
6494be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    u32 nesting_level,
6504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    void *context, void **return_value)
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6524be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_get_devices_info *info = context;
6534be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
6544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *node;
6554be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u32 flags;
65678e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id *hid;
65778e25fef2751434f38c7f711ecbf8762f79f7318Lv Zheng	struct acpi_pnp_device_id_list *cid;
65867a119f990063f5662574f6d6414fe9bc5ece86aBob Moore	u32 i;
65915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	u8 found;
66015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore	int no_match;
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
6634be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
6647b6afb6782053f9679f5b9f05287f8c700d7d68fLv Zheng		return (status);
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
667f24b664dc44a4ab4df61db2258cea298eeb43a8eBob Moore	node = acpi_ns_validate_handle(obj_handle);
6684be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
6694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (status);
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node) {
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (AE_BAD_PARAMETER);
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6775f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	/*
6785f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * First, filter based on the device HID and CID.
6795f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 *
6805f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * 01/2010: For this case where a specific HID is requested, we don't
6815f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * want to run _STA until we have an actual HID match. Thus, we will
6825f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * not unnecessarily execute _STA on devices for which the caller
6835f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * doesn't care about. Previously, _STA was executed unconditionally
6845f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * on all devices found here.
6855f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 *
6865f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * A side-effect of this change is that now we will continue to search
6875f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * for a matching HID even under device trees where the parent device
6885f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * would have returned a _STA that indicates it is not present or
6895f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 * not functioning (thus aborting the search on that branch).
6905f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	 */
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (info->hid != NULL) {
6924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status = acpi_ut_execute_HID(node, &hid);
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (status == AE_NOT_FOUND) {
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return (AE_OK);
6954be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		} else if (ACPI_FAILURE(status)) {
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return (AE_CTRL_DEPTH);
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
69915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		no_match = ACPI_STRCMP(hid->string, info->hid);
70015b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		ACPI_FREE(hid);
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
70215b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore		if (no_match) {
70315b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			/*
70415b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			 * HID does not match, attempt match within the
70515b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			 * list of Compatible IDs (CIDs)
70615b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore			 */
7074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			status = acpi_ut_execute_CID(node, &cid);
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (status == AE_NOT_FOUND) {
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (AE_OK);
7104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			} else if (ACPI_FAILURE(status)) {
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return (AE_CTRL_DEPTH);
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Walk the CID list */
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
716739dcbb90a347a66f25cc0c3ef4eef3d4558f409Lv Zheng			found = FALSE;
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (i = 0; i < cid->count; i++) {
71815b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore				if (ACPI_STRCMP(cid->ids[i].string, info->hid)
71915b8dd53f5ffaf8e2d9095c423f713423f576c0fBob Moore				    == 0) {
7203e8214e5c2bd449b30109d4a098597ab1b7c9fb9Lv Zheng
72175c8044fb38051713000e0d151852f5f9614f77bLv Zheng					/* Found a matching CID */
7223e8214e5c2bd449b30109d4a098597ab1b7c9fb9Lv Zheng
723739dcbb90a347a66f25cc0c3ef4eef3d4558f409Lv Zheng					found = TRUE;
72402f8a8586574350a1f3c2cee79cbc0faf630961dAndrew Patterson					break;
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
727739dcbb90a347a66f25cc0c3ef4eef3d4558f409Lv Zheng
7288313524a0d466f451a62709aaedf988d8257b21cBob Moore			ACPI_FREE(cid);
729739dcbb90a347a66f25cc0c3ef4eef3d4558f409Lv Zheng			if (!found) {
73002f8a8586574350a1f3c2cee79cbc0faf630961dAndrew Patterson				return (AE_OK);
731739dcbb90a347a66f25cc0c3ef4eef3d4558f409Lv Zheng			}
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7355f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	/* Run _STA to determine if device is present */
7365f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming
7375f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	status = acpi_ut_execute_STA(node, &flags);
7385f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	if (ACPI_FAILURE(status)) {
7395f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		return (AE_CTRL_DEPTH);
7405f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	}
7415f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming
7425f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
7435f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	    !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
7445f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		/*
7455f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		 * Don't examine the children of the device only when the
7465f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		 * device is neither present nor functional. See ACPI spec,
7475f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		 * description of _STA for more information.
7485f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		 */
7495f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming		return (AE_CTRL_DEPTH);
7505f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	}
7515f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming
7525f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming	/* We have a valid device, invoke the user function */
7535f8902acf87aa206ee4b3f633104456d82747ca6Lin Ming
7544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = info->user_function(obj_handle, nesting_level, info->context,
7554be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				     return_value);
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (status);
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_get_devices
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  HID                 - HID to search for. Can be NULL.
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              user_function       - Called when a matching object is found
765ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              context             - Passed to user function
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              return_value        - Location where return value of
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    user_function is put if terminated early
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURNS      Return value from the user_function if terminated early.
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Otherwise, returns NULL.
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              starting (and ending) at the object specified by start_handle.
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              The user_function is called whenever an object of type
77573a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *              Device is found. If the user function returns
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              a non-zero value, the search is terminated immediately and this
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              value is returned to the caller.
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              This is a wrapper for walk_namespace, but the callback performs
780549f46044e1e207a2cbfdfb3f9a0d3fd5fd4105eBob Moore *              additional filtering. Please see acpi_ns_get_device_callback.
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
78570b30fb13bf46d7874537f5e2089bcc772559fc4Al Viroacpi_get_devices(const char *HID,
7864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		 acpi_walk_callback user_function,
7874be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		 void *context, void **return_value)
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
7904be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_get_devices_info info;
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
792b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(acpi_get_devices);
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Parameter validation */
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!user_function) {
7974be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_BAD_PARAMETER);
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We're going to call their callback from OUR callback, so we need
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * to know what it is, and their context parameter.
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
80452fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore	info.hid = HID;
8054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	info.context = context;
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info.user_function = user_function;
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Lock the namespace around the walk.
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * The namespace will be unlocked/locked around each call
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * to the user function - since this function
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * must be allowed to make Acpi calls itself.
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8144be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
8154be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
8164be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(status);
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
81952fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
82052fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore					ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
8212263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming					acpi_ns_get_device_callback, NULL,
8222263576cfc6e8f6ab038126c3254404b9fcb1c33Lin Ming					&info, return_value);
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
8254be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8288313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_get_devices)
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_attach_data
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  obj_handle          - Namespace node
835ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              handler             - Handler for this attachment
836ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              data                - Pointer to data to be attached
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
8444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_attach_data(acpi_handle obj_handle,
8454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		 acpi_object_handler handler, void *data)
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8474be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *node;
8484be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Parameter validation */
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8524be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (!obj_handle || !handler || !data) {
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (AE_BAD_PARAMETER);
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
8574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (status);
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Convert and validate the handle */
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
863f24b664dc44a4ab4df61db2258cea298eeb43a8eBob Moore	node = acpi_ns_validate_handle(obj_handle);
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node) {
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_BAD_PARAMETER;
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto unlock_and_exit;
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ns_attach_data(node, handler, data);
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
87110622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengunlock_and_exit:
8724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (status);
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8768313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_attach_data)
8778313524a0d466f451a62709aaedf988d8257b21cBob Moore
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_detach_data
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  obj_handle          - Namespace node handle
883ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              handler             - Handler used in call to acpi_attach_data
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Remove data that was previously attached to a node.
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
8914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler)
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8934be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *node;
8944be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Parameter validation */
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8984be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (!obj_handle || !handler) {
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (AE_BAD_PARAMETER);
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
9034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (status);
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Convert and validate the handle */
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
909f24b664dc44a4ab4df61db2258cea298eeb43a8eBob Moore	node = acpi_ns_validate_handle(obj_handle);
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node) {
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_BAD_PARAMETER;
9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto unlock_and_exit;
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9154be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ns_detach_data(node, handler);
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
91710622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengunlock_and_exit:
9184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (status);
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9228313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_detach_data)
9238313524a0d466f451a62709aaedf988d8257b21cBob Moore
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9267c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki * FUNCTION:    acpi_get_data_full
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  obj_handle          - Namespace node
929ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              handler             - Handler used in call to attach_data
930ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              data                - Where the data is returned
9317c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *              callback            - function to execute before returning
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9357c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki * DESCRIPTION: Retrieve data that was previously attached to a namespace node
9367c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *              and execute a callback before returning.
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
9407c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysockiacpi_get_data_full(acpi_handle obj_handle, acpi_object_handler handler,
9417c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki		   void **data, void (*callback)(void *))
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9434be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *node;
9444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status;
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Parameter validation */
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9484be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (!obj_handle || !handler || !data) {
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (AE_BAD_PARAMETER);
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9524be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
9534be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (status);
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Convert and validate the handle */
9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
959f24b664dc44a4ab4df61db2258cea298eeb43a8eBob Moore	node = acpi_ns_validate_handle(obj_handle);
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!node) {
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_BAD_PARAMETER;
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto unlock_and_exit;
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9654be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ns_get_attached_data(node, handler, data);
9667c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki	if (ACPI_SUCCESS(status) && callback) {
9677c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki		callback(*data);
9687c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki	}
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
97010622bf8ce432e6a53fd3c37163e99e99c9e43eeLv Zhengunlock_and_exit:
9714be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (status);
9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9748313524a0d466f451a62709aaedf988d8257b21cBob Moore
9757c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. WysockiACPI_EXPORT_SYMBOL(acpi_get_data_full)
9767c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki
9777c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki/*******************************************************************************
9787c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *
9797c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki * FUNCTION:    acpi_get_data
9807c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *
9817c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki * PARAMETERS:  obj_handle          - Namespace node
9827c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *              handler             - Handler used in call to attach_data
9837c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *              data                - Where the data is returned
9847c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *
9857c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki * RETURN:      Status
9867c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *
9877c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
9887c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki *
9897c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki ******************************************************************************/
9907c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysockiacpi_status
9917c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysockiacpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data)
9927c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki{
9937c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki	return acpi_get_data_full(obj_handle, handler, data, NULL);
9947c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki}
9957c2e17714e190b2ef857e7e842464fb47ceca146Rafael J. Wysocki
9968313524a0d466f451a62709aaedf988d8257b21cBob MooreACPI_EXPORT_SYMBOL(acpi_get_data)
997