cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nsxfeval.c (28367B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
      5 *                         ACPI Object evaluation interfaces
      6 *
      7 ******************************************************************************/
      8
      9#define EXPORT_ACPI_INTERFACES
     10
     11#include <acpi/acpi.h>
     12#include "accommon.h"
     13#include "acnamesp.h"
     14#include "acinterp.h"
     15
     16#define _COMPONENT          ACPI_NAMESPACE
     17ACPI_MODULE_NAME("nsxfeval")
     18
     19/* Local prototypes */
     20static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
     21
     22/*******************************************************************************
     23 *
     24 * FUNCTION:    acpi_evaluate_object_typed
     25 *
     26 * PARAMETERS:  handle              - Object handle (optional)
     27 *              pathname            - Object pathname (optional)
     28 *              external_params     - List of parameters to pass to a method,
     29 *                                    terminated by NULL. May be NULL
     30 *                                    if no parameters are being passed.
     31 *              return_buffer       - Where to put the object's return value (if
     32 *                                    any). If NULL, no value is returned.
     33 *              return_type         - Expected type of return object
     34 *
     35 * RETURN:      Status
     36 *
     37 * DESCRIPTION: Find and evaluate the given object, passing the given
     38 *              parameters if necessary. One of "Handle" or "Pathname" must
     39 *              be valid (non-null)
     40 *
     41 ******************************************************************************/
     42
     43acpi_status
     44acpi_evaluate_object_typed(acpi_handle handle,
     45			   acpi_string pathname,
     46			   struct acpi_object_list *external_params,
     47			   struct acpi_buffer *return_buffer,
     48			   acpi_object_type return_type)
     49{
     50	acpi_status status;
     51	u8 free_buffer_on_error = FALSE;
     52	acpi_handle target_handle;
     53	char *full_pathname;
     54
     55	ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed);
     56
     57	/* Return buffer must be valid */
     58
     59	if (!return_buffer) {
     60		return_ACPI_STATUS(AE_BAD_PARAMETER);
     61	}
     62
     63	if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
     64		free_buffer_on_error = TRUE;
     65	}
     66
     67	/* Get a handle here, in order to build an error message if needed */
     68
     69	target_handle = handle;
     70	if (pathname) {
     71		status = acpi_get_handle(handle, pathname, &target_handle);
     72		if (ACPI_FAILURE(status)) {
     73			return_ACPI_STATUS(status);
     74		}
     75	}
     76
     77	full_pathname = acpi_ns_get_external_pathname(target_handle);
     78	if (!full_pathname) {
     79		return_ACPI_STATUS(AE_NO_MEMORY);
     80	}
     81
     82	/* Evaluate the object */
     83
     84	status = acpi_evaluate_object(target_handle, NULL, external_params,
     85				      return_buffer);
     86	if (ACPI_FAILURE(status)) {
     87		goto exit;
     88	}
     89
     90	/* Type ANY means "don't care about return value type" */
     91
     92	if (return_type == ACPI_TYPE_ANY) {
     93		goto exit;
     94	}
     95
     96	if (return_buffer->length == 0) {
     97
     98		/* Error because caller specifically asked for a return value */
     99
    100		ACPI_ERROR((AE_INFO, "%s did not return any object",
    101			    full_pathname));
    102		status = AE_NULL_OBJECT;
    103		goto exit;
    104	}
    105
    106	/* Examine the object type returned from evaluate_object */
    107
    108	if (((union acpi_object *)return_buffer->pointer)->type == return_type) {
    109		goto exit;
    110	}
    111
    112	/* Return object type does not match requested type */
    113
    114	ACPI_ERROR((AE_INFO,
    115		    "Incorrect return type from %s - received [%s], requested [%s]",
    116		    full_pathname,
    117		    acpi_ut_get_type_name(((union acpi_object *)return_buffer->
    118					   pointer)->type),
    119		    acpi_ut_get_type_name(return_type)));
    120
    121	if (free_buffer_on_error) {
    122		/*
    123		 * Free a buffer created via ACPI_ALLOCATE_BUFFER.
    124		 * Note: We use acpi_os_free here because acpi_os_allocate was used
    125		 * to allocate the buffer. This purposefully bypasses the
    126		 * (optionally enabled) allocation tracking mechanism since we
    127		 * only want to track internal allocations.
    128		 */
    129		acpi_os_free(return_buffer->pointer);
    130		return_buffer->pointer = NULL;
    131	}
    132
    133	return_buffer->length = 0;
    134	status = AE_TYPE;
    135
    136exit:
    137	ACPI_FREE(full_pathname);
    138	return_ACPI_STATUS(status);
    139}
    140
    141ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
    142
    143/*******************************************************************************
    144 *
    145 * FUNCTION:    acpi_evaluate_object
    146 *
    147 * PARAMETERS:  handle              - Object handle (optional)
    148 *              pathname            - Object pathname (optional)
    149 *              external_params     - List of parameters to pass to method,
    150 *                                    terminated by NULL. May be NULL
    151 *                                    if no parameters are being passed.
    152 *              return_buffer       - Where to put method's return value (if
    153 *                                    any). If NULL, no value is returned.
    154 *
    155 * RETURN:      Status
    156 *
    157 * DESCRIPTION: Find and evaluate the given object, passing the given
    158 *              parameters if necessary. One of "Handle" or "Pathname" must
    159 *              be valid (non-null)
    160 *
    161 ******************************************************************************/
    162acpi_status
    163acpi_evaluate_object(acpi_handle handle,
    164		     acpi_string pathname,
    165		     struct acpi_object_list *external_params,
    166		     struct acpi_buffer *return_buffer)
    167{
    168	acpi_status status;
    169	struct acpi_evaluate_info *info;
    170	acpi_size buffer_space_needed;
    171	u32 i;
    172
    173	ACPI_FUNCTION_TRACE(acpi_evaluate_object);
    174
    175	/* Allocate and initialize the evaluation information block */
    176
    177	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
    178	if (!info) {
    179		return_ACPI_STATUS(AE_NO_MEMORY);
    180	}
    181
    182	/* Convert and validate the device handle */
    183
    184	info->prefix_node = acpi_ns_validate_handle(handle);
    185	if (!info->prefix_node) {
    186		status = AE_BAD_PARAMETER;
    187		goto cleanup;
    188	}
    189
    190	/*
    191	 * Get the actual namespace node for the target object.
    192	 * Handles these cases:
    193	 *
    194	 * 1) Null node, valid pathname from root (absolute path)
    195	 * 2) Node and valid pathname (path relative to Node)
    196	 * 3) Node, Null pathname
    197	 */
    198	if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
    199
    200		/* The path is fully qualified, just evaluate by name */
    201
    202		info->prefix_node = NULL;
    203	} else if (!handle) {
    204		/*
    205		 * A handle is optional iff a fully qualified pathname is specified.
    206		 * Since we've already handled fully qualified names above, this is
    207		 * an error.
    208		 */
    209		if (!pathname) {
    210			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    211					  "Both Handle and Pathname are NULL"));
    212		} else {
    213			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    214					  "Null Handle with relative pathname [%s]",
    215					  pathname));
    216		}
    217
    218		status = AE_BAD_PARAMETER;
    219		goto cleanup;
    220	}
    221
    222	info->relative_pathname = pathname;
    223
    224	/*
    225	 * Convert all external objects passed as arguments to the
    226	 * internal version(s).
    227	 */
    228	if (external_params && external_params->count) {
    229		info->param_count = (u16)external_params->count;
    230
    231		/* Warn on impossible argument count */
    232
    233		if (info->param_count > ACPI_METHOD_NUM_ARGS) {
    234			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
    235					      ACPI_WARN_ALWAYS,
    236					      "Excess arguments (%u) - using only %u",
    237					      info->param_count,
    238					      ACPI_METHOD_NUM_ARGS));
    239
    240			info->param_count = ACPI_METHOD_NUM_ARGS;
    241		}
    242
    243		/*
    244		 * Allocate a new parameter block for the internal objects
    245		 * Add 1 to count to allow for null terminated internal list
    246		 */
    247		info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)info->
    248							 param_count +
    249							 1) * sizeof(void *));
    250		if (!info->parameters) {
    251			status = AE_NO_MEMORY;
    252			goto cleanup;
    253		}
    254
    255		/* Convert each external object in the list to an internal object */
    256
    257		for (i = 0; i < info->param_count; i++) {
    258			status =
    259			    acpi_ut_copy_eobject_to_iobject(&external_params->
    260							    pointer[i],
    261							    &info->
    262							    parameters[i]);
    263			if (ACPI_FAILURE(status)) {
    264				goto cleanup;
    265			}
    266		}
    267
    268		info->parameters[info->param_count] = NULL;
    269	}
    270
    271#ifdef _FUTURE_FEATURE
    272
    273	/*
    274	 * Begin incoming argument count analysis. Check for too few args
    275	 * and too many args.
    276	 */
    277	switch (acpi_ns_get_type(info->node)) {
    278	case ACPI_TYPE_METHOD:
    279
    280		/* Check incoming argument count against the method definition */
    281
    282		if (info->obj_desc->method.param_count > info->param_count) {
    283			ACPI_ERROR((AE_INFO,
    284				    "Insufficient arguments (%u) - %u are required",
    285				    info->param_count,
    286				    info->obj_desc->method.param_count));
    287
    288			status = AE_MISSING_ARGUMENTS;
    289			goto cleanup;
    290		}
    291
    292		else if (info->obj_desc->method.param_count < info->param_count) {
    293			ACPI_WARNING((AE_INFO,
    294				      "Excess arguments (%u) - only %u are required",
    295				      info->param_count,
    296				      info->obj_desc->method.param_count));
    297
    298			/* Just pass the required number of arguments */
    299
    300			info->param_count = info->obj_desc->method.param_count;
    301		}
    302
    303		/*
    304		 * Any incoming external objects to be passed as arguments to the
    305		 * method must be converted to internal objects
    306		 */
    307		if (info->param_count) {
    308			/*
    309			 * Allocate a new parameter block for the internal objects
    310			 * Add 1 to count to allow for null terminated internal list
    311			 */
    312			info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
    313								 info->
    314								 param_count +
    315								 1) *
    316								sizeof(void *));
    317			if (!info->parameters) {
    318				status = AE_NO_MEMORY;
    319				goto cleanup;
    320			}
    321
    322			/* Convert each external object in the list to an internal object */
    323
    324			for (i = 0; i < info->param_count; i++) {
    325				status =
    326				    acpi_ut_copy_eobject_to_iobject
    327				    (&external_params->pointer[i],
    328				     &info->parameters[i]);
    329				if (ACPI_FAILURE(status)) {
    330					goto cleanup;
    331				}
    332			}
    333
    334			info->parameters[info->param_count] = NULL;
    335		}
    336		break;
    337
    338	default:
    339
    340		/* Warn if arguments passed to an object that is not a method */
    341
    342		if (info->param_count) {
    343			ACPI_WARNING((AE_INFO,
    344				      "%u arguments were passed to a non-method ACPI object",
    345				      info->param_count));
    346		}
    347		break;
    348	}
    349
    350#endif
    351
    352	/* Now we can evaluate the object */
    353
    354	status = acpi_ns_evaluate(info);
    355
    356	/*
    357	 * If we are expecting a return value, and all went well above,
    358	 * copy the return value to an external object.
    359	 */
    360	if (!return_buffer) {
    361		goto cleanup_return_object;
    362	}
    363
    364	if (!info->return_object) {
    365		return_buffer->length = 0;
    366		goto cleanup;
    367	}
    368
    369	if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
    370	    ACPI_DESC_TYPE_NAMED) {
    371		/*
    372		 * If we received a NS Node as a return object, this means that
    373		 * the object we are evaluating has nothing interesting to
    374		 * return (such as a mutex, etc.)  We return an error because
    375		 * these types are essentially unsupported by this interface.
    376		 * We don't check up front because this makes it easier to add
    377		 * support for various types at a later date if necessary.
    378		 */
    379		status = AE_TYPE;
    380		info->return_object = NULL;	/* No need to delete a NS Node */
    381		return_buffer->length = 0;
    382	}
    383
    384	if (ACPI_FAILURE(status)) {
    385		goto cleanup_return_object;
    386	}
    387
    388	/* Dereference Index and ref_of references */
    389
    390	acpi_ns_resolve_references(info);
    391
    392	/* Get the size of the returned object */
    393
    394	status = acpi_ut_get_object_size(info->return_object,
    395					 &buffer_space_needed);
    396	if (ACPI_SUCCESS(status)) {
    397
    398		/* Validate/Allocate/Clear caller buffer */
    399
    400		status = acpi_ut_initialize_buffer(return_buffer,
    401						   buffer_space_needed);
    402		if (ACPI_FAILURE(status)) {
    403			/*
    404			 * Caller's buffer is too small or a new one can't
    405			 * be allocated
    406			 */
    407			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    408					  "Needed buffer size %X, %s\n",
    409					  (u32)buffer_space_needed,
    410					  acpi_format_exception(status)));
    411		} else {
    412			/* We have enough space for the object, build it */
    413
    414			status =
    415			    acpi_ut_copy_iobject_to_eobject(info->return_object,
    416							    return_buffer);
    417		}
    418	}
    419
    420cleanup_return_object:
    421
    422	if (info->return_object) {
    423		/*
    424		 * Delete the internal return object. NOTE: Interpreter must be
    425		 * locked to avoid race condition.
    426		 */
    427		acpi_ex_enter_interpreter();
    428
    429		/* Remove one reference on the return object (should delete it) */
    430
    431		acpi_ut_remove_reference(info->return_object);
    432		acpi_ex_exit_interpreter();
    433	}
    434
    435cleanup:
    436
    437	/* Free the input parameter list (if we created one) */
    438
    439	if (info->parameters) {
    440
    441		/* Free the allocated parameter block */
    442
    443		acpi_ut_delete_internal_object_list(info->parameters);
    444	}
    445
    446	ACPI_FREE(info);
    447	return_ACPI_STATUS(status);
    448}
    449
    450ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
    451
    452/*******************************************************************************
    453 *
    454 * FUNCTION:    acpi_ns_resolve_references
    455 *
    456 * PARAMETERS:  info                    - Evaluation info block
    457 *
    458 * RETURN:      Info->return_object is replaced with the dereferenced object
    459 *
    460 * DESCRIPTION: Dereference certain reference objects. Called before an
    461 *              internal return object is converted to an external union acpi_object.
    462 *
    463 * Performs an automatic dereference of Index and ref_of reference objects.
    464 * These reference objects are not supported by the union acpi_object, so this is a
    465 * last resort effort to return something useful. Also, provides compatibility
    466 * with other ACPI implementations.
    467 *
    468 * NOTE: does not handle references within returned package objects or nested
    469 * references, but this support could be added later if found to be necessary.
    470 *
    471 ******************************************************************************/
    472static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
    473{
    474	union acpi_operand_object *obj_desc = NULL;
    475	struct acpi_namespace_node *node;
    476
    477	/* We are interested in reference objects only */
    478
    479	if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
    480		return;
    481	}
    482
    483	/*
    484	 * Two types of references are supported - those created by Index and
    485	 * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
    486	 * to a union acpi_object, so it is not dereferenced here. A ddb_handle
    487	 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
    488	 * a union acpi_object.
    489	 */
    490	switch (info->return_object->reference.class) {
    491	case ACPI_REFCLASS_INDEX:
    492
    493		obj_desc = *(info->return_object->reference.where);
    494		break;
    495
    496	case ACPI_REFCLASS_REFOF:
    497
    498		node = info->return_object->reference.object;
    499		if (node) {
    500			obj_desc = node->object;
    501		}
    502		break;
    503
    504	default:
    505
    506		return;
    507	}
    508
    509	/* Replace the existing reference object */
    510
    511	if (obj_desc) {
    512		acpi_ut_add_reference(obj_desc);
    513		acpi_ut_remove_reference(info->return_object);
    514		info->return_object = obj_desc;
    515	}
    516
    517	return;
    518}
    519
    520/*******************************************************************************
    521 *
    522 * FUNCTION:    acpi_walk_namespace
    523 *
    524 * PARAMETERS:  type                - acpi_object_type to search for
    525 *              start_object        - Handle in namespace where search begins
    526 *              max_depth           - Depth to which search is to reach
    527 *              descending_callback - Called during tree descent
    528 *                                    when an object of "Type" is found
    529 *              ascending_callback  - Called during tree ascent
    530 *                                    when an object of "Type" is found
    531 *              context             - Passed to user function(s) above
    532 *              return_value        - Location where return value of
    533 *                                    user_function is put if terminated early
    534 *
    535 * RETURNS      Return value from the user_function if terminated early.
    536 *              Otherwise, returns NULL.
    537 *
    538 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
    539 *              starting (and ending) at the object specified by start_handle.
    540 *              The callback function is called whenever an object that matches
    541 *              the type parameter is found. If the callback function returns
    542 *              a non-zero value, the search is terminated immediately and this
    543 *              value is returned to the caller.
    544 *
    545 *              The point of this procedure is to provide a generic namespace
    546 *              walk routine that can be called from multiple places to
    547 *              provide multiple services; the callback function(s) can be
    548 *              tailored to each task, whether it is a print function,
    549 *              a compare function, etc.
    550 *
    551 ******************************************************************************/
    552
    553acpi_status
    554acpi_walk_namespace(acpi_object_type type,
    555		    acpi_handle start_object,
    556		    u32 max_depth,
    557		    acpi_walk_callback descending_callback,
    558		    acpi_walk_callback ascending_callback,
    559		    void *context, void **return_value)
    560{
    561	acpi_status status;
    562
    563	ACPI_FUNCTION_TRACE(acpi_walk_namespace);
    564
    565	/* Parameter validation */
    566
    567	if ((type > ACPI_TYPE_LOCAL_MAX) ||
    568	    (!max_depth) || (!descending_callback && !ascending_callback)) {
    569		return_ACPI_STATUS(AE_BAD_PARAMETER);
    570	}
    571
    572	/*
    573	 * Need to acquire the namespace reader lock to prevent interference
    574	 * with any concurrent table unloads (which causes the deletion of
    575	 * namespace objects). We cannot allow the deletion of a namespace node
    576	 * while the user function is using it. The exception to this are the
    577	 * nodes created and deleted during control method execution -- these
    578	 * nodes are marked as temporary nodes and are ignored by the namespace
    579	 * walk. Thus, control methods can be executed while holding the
    580	 * namespace deletion lock (and the user function can execute control
    581	 * methods.)
    582	 */
    583	status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
    584	if (ACPI_FAILURE(status)) {
    585		return_ACPI_STATUS(status);
    586	}
    587
    588	/*
    589	 * Lock the namespace around the walk. The namespace will be
    590	 * unlocked/locked around each call to the user function - since the user
    591	 * function must be allowed to make ACPICA calls itself (for example, it
    592	 * will typically execute control methods during device enumeration.)
    593	 */
    594	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    595	if (ACPI_FAILURE(status)) {
    596		goto unlock_and_exit;
    597	}
    598
    599	/* Now we can validate the starting node */
    600
    601	if (!acpi_ns_validate_handle(start_object)) {
    602		status = AE_BAD_PARAMETER;
    603		goto unlock_and_exit2;
    604	}
    605
    606	status = acpi_ns_walk_namespace(type, start_object, max_depth,
    607					ACPI_NS_WALK_UNLOCK,
    608					descending_callback, ascending_callback,
    609					context, return_value);
    610
    611unlock_and_exit2:
    612	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    613
    614unlock_and_exit:
    615	(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
    616	return_ACPI_STATUS(status);
    617}
    618
    619ACPI_EXPORT_SYMBOL(acpi_walk_namespace)
    620
    621/*******************************************************************************
    622 *
    623 * FUNCTION:    acpi_ns_get_device_callback
    624 *
    625 * PARAMETERS:  Callback from acpi_get_device
    626 *
    627 * RETURN:      Status
    628 *
    629 * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
    630 *              present devices, or if they specified a HID, it filters based
    631 *              on that.
    632 *
    633 ******************************************************************************/
    634static acpi_status
    635acpi_ns_get_device_callback(acpi_handle obj_handle,
    636			    u32 nesting_level,
    637			    void *context, void **return_value)
    638{
    639	struct acpi_get_devices_info *info = context;
    640	acpi_status status;
    641	struct acpi_namespace_node *node;
    642	u32 flags;
    643	struct acpi_pnp_device_id *hid;
    644	struct acpi_pnp_device_id_list *cid;
    645	u32 i;
    646	u8 found;
    647	int no_match;
    648
    649	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    650	if (ACPI_FAILURE(status)) {
    651		return (status);
    652	}
    653
    654	node = acpi_ns_validate_handle(obj_handle);
    655	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    656	if (ACPI_FAILURE(status)) {
    657		return (status);
    658	}
    659
    660	if (!node) {
    661		return (AE_BAD_PARAMETER);
    662	}
    663
    664	/*
    665	 * First, filter based on the device HID and CID.
    666	 *
    667	 * 01/2010: For this case where a specific HID is requested, we don't
    668	 * want to run _STA until we have an actual HID match. Thus, we will
    669	 * not unnecessarily execute _STA on devices for which the caller
    670	 * doesn't care about. Previously, _STA was executed unconditionally
    671	 * on all devices found here.
    672	 *
    673	 * A side-effect of this change is that now we will continue to search
    674	 * for a matching HID even under device trees where the parent device
    675	 * would have returned a _STA that indicates it is not present or
    676	 * not functioning (thus aborting the search on that branch).
    677	 */
    678	if (info->hid != NULL) {
    679		status = acpi_ut_execute_HID(node, &hid);
    680		if (status == AE_NOT_FOUND) {
    681			return (AE_OK);
    682		} else if (ACPI_FAILURE(status)) {
    683			return (AE_CTRL_DEPTH);
    684		}
    685
    686		no_match = strcmp(hid->string, info->hid);
    687		ACPI_FREE(hid);
    688
    689		if (no_match) {
    690			/*
    691			 * HID does not match, attempt match within the
    692			 * list of Compatible IDs (CIDs)
    693			 */
    694			status = acpi_ut_execute_CID(node, &cid);
    695			if (status == AE_NOT_FOUND) {
    696				return (AE_OK);
    697			} else if (ACPI_FAILURE(status)) {
    698				return (AE_CTRL_DEPTH);
    699			}
    700
    701			/* Walk the CID list */
    702
    703			found = FALSE;
    704			for (i = 0; i < cid->count; i++) {
    705				if (strcmp(cid->ids[i].string, info->hid) == 0) {
    706
    707					/* Found a matching CID */
    708
    709					found = TRUE;
    710					break;
    711				}
    712			}
    713
    714			ACPI_FREE(cid);
    715			if (!found) {
    716				return (AE_OK);
    717			}
    718		}
    719	}
    720
    721	/* Run _STA to determine if device is present */
    722
    723	status = acpi_ut_execute_STA(node, &flags);
    724	if (ACPI_FAILURE(status)) {
    725		return (AE_CTRL_DEPTH);
    726	}
    727
    728	if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
    729	    !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
    730		/*
    731		 * Don't examine the children of the device only when the
    732		 * device is neither present nor functional. See ACPI spec,
    733		 * description of _STA for more information.
    734		 */
    735		return (AE_CTRL_DEPTH);
    736	}
    737
    738	/* We have a valid device, invoke the user function */
    739
    740	status = info->user_function(obj_handle, nesting_level,
    741				     info->context, return_value);
    742	return (status);
    743}
    744
    745/*******************************************************************************
    746 *
    747 * FUNCTION:    acpi_get_devices
    748 *
    749 * PARAMETERS:  HID                 - HID to search for. Can be NULL.
    750 *              user_function       - Called when a matching object is found
    751 *              context             - Passed to user function
    752 *              return_value        - Location where return value of
    753 *                                    user_function is put if terminated early
    754 *
    755 * RETURNS      Return value from the user_function if terminated early.
    756 *              Otherwise, returns NULL.
    757 *
    758 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
    759 *              starting (and ending) at the object specified by start_handle.
    760 *              The user_function is called whenever an object of type
    761 *              Device is found. If the user function returns
    762 *              a non-zero value, the search is terminated immediately and this
    763 *              value is returned to the caller.
    764 *
    765 *              This is a wrapper for walk_namespace, but the callback performs
    766 *              additional filtering. Please see acpi_ns_get_device_callback.
    767 *
    768 ******************************************************************************/
    769
    770acpi_status
    771acpi_get_devices(const char *HID,
    772		 acpi_walk_callback user_function,
    773		 void *context, void **return_value)
    774{
    775	acpi_status status;
    776	struct acpi_get_devices_info info;
    777
    778	ACPI_FUNCTION_TRACE(acpi_get_devices);
    779
    780	/* Parameter validation */
    781
    782	if (!user_function) {
    783		return_ACPI_STATUS(AE_BAD_PARAMETER);
    784	}
    785
    786	/*
    787	 * We're going to call their callback from OUR callback, so we need
    788	 * to know what it is, and their context parameter.
    789	 */
    790	info.hid = HID;
    791	info.context = context;
    792	info.user_function = user_function;
    793
    794	/*
    795	 * Lock the namespace around the walk.
    796	 * The namespace will be unlocked/locked around each call
    797	 * to the user function - since this function
    798	 * must be allowed to make Acpi calls itself.
    799	 */
    800	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    801	if (ACPI_FAILURE(status)) {
    802		return_ACPI_STATUS(status);
    803	}
    804
    805	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
    806					ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
    807					acpi_ns_get_device_callback, NULL,
    808					&info, return_value);
    809
    810	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    811	return_ACPI_STATUS(status);
    812}
    813
    814ACPI_EXPORT_SYMBOL(acpi_get_devices)
    815
    816/*******************************************************************************
    817 *
    818 * FUNCTION:    acpi_attach_data
    819 *
    820 * PARAMETERS:  obj_handle          - Namespace node
    821 *              handler             - Handler for this attachment
    822 *              data                - Pointer to data to be attached
    823 *
    824 * RETURN:      Status
    825 *
    826 * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
    827 *
    828 ******************************************************************************/
    829acpi_status
    830acpi_attach_data(acpi_handle obj_handle,
    831		 acpi_object_handler handler, void *data)
    832{
    833	struct acpi_namespace_node *node;
    834	acpi_status status;
    835
    836	/* Parameter validation */
    837
    838	if (!obj_handle || !handler || !data) {
    839		return (AE_BAD_PARAMETER);
    840	}
    841
    842	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    843	if (ACPI_FAILURE(status)) {
    844		return (status);
    845	}
    846
    847	/* Convert and validate the handle */
    848
    849	node = acpi_ns_validate_handle(obj_handle);
    850	if (!node) {
    851		status = AE_BAD_PARAMETER;
    852		goto unlock_and_exit;
    853	}
    854
    855	status = acpi_ns_attach_data(node, handler, data);
    856
    857unlock_and_exit:
    858	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    859	return (status);
    860}
    861
    862ACPI_EXPORT_SYMBOL(acpi_attach_data)
    863
    864/*******************************************************************************
    865 *
    866 * FUNCTION:    acpi_detach_data
    867 *
    868 * PARAMETERS:  obj_handle          - Namespace node handle
    869 *              handler             - Handler used in call to acpi_attach_data
    870 *
    871 * RETURN:      Status
    872 *
    873 * DESCRIPTION: Remove data that was previously attached to a node.
    874 *
    875 ******************************************************************************/
    876acpi_status
    877acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler)
    878{
    879	struct acpi_namespace_node *node;
    880	acpi_status status;
    881
    882	/* Parameter validation */
    883
    884	if (!obj_handle || !handler) {
    885		return (AE_BAD_PARAMETER);
    886	}
    887
    888	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    889	if (ACPI_FAILURE(status)) {
    890		return (status);
    891	}
    892
    893	/* Convert and validate the handle */
    894
    895	node = acpi_ns_validate_handle(obj_handle);
    896	if (!node) {
    897		status = AE_BAD_PARAMETER;
    898		goto unlock_and_exit;
    899	}
    900
    901	status = acpi_ns_detach_data(node, handler);
    902
    903unlock_and_exit:
    904	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    905	return (status);
    906}
    907
    908ACPI_EXPORT_SYMBOL(acpi_detach_data)
    909
    910/*******************************************************************************
    911 *
    912 * FUNCTION:    acpi_get_data_full
    913 *
    914 * PARAMETERS:  obj_handle          - Namespace node
    915 *              handler             - Handler used in call to attach_data
    916 *              data                - Where the data is returned
    917 *              callback            - function to execute before returning
    918 *
    919 * RETURN:      Status
    920 *
    921 * DESCRIPTION: Retrieve data that was previously attached to a namespace node
    922 *              and execute a callback before returning.
    923 *
    924 ******************************************************************************/
    925acpi_status
    926acpi_get_data_full(acpi_handle obj_handle, acpi_object_handler handler,
    927		   void **data, void (*callback)(void *))
    928{
    929	struct acpi_namespace_node *node;
    930	acpi_status status;
    931
    932	/* Parameter validation */
    933
    934	if (!obj_handle || !handler || !data) {
    935		return (AE_BAD_PARAMETER);
    936	}
    937
    938	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    939	if (ACPI_FAILURE(status)) {
    940		return (status);
    941	}
    942
    943	/* Convert and validate the handle */
    944
    945	node = acpi_ns_validate_handle(obj_handle);
    946	if (!node) {
    947		status = AE_BAD_PARAMETER;
    948		goto unlock_and_exit;
    949	}
    950
    951	status = acpi_ns_get_attached_data(node, handler, data);
    952	if (ACPI_SUCCESS(status) && callback) {
    953		callback(*data);
    954	}
    955
    956unlock_and_exit:
    957	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
    958	return (status);
    959}
    960
    961ACPI_EXPORT_SYMBOL(acpi_get_data_full)
    962
    963/*******************************************************************************
    964 *
    965 * FUNCTION:    acpi_get_data
    966 *
    967 * PARAMETERS:  obj_handle          - Namespace node
    968 *              handler             - Handler used in call to attach_data
    969 *              data                - Where the data is returned
    970 *
    971 * RETURN:      Status
    972 *
    973 * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
    974 *
    975 ******************************************************************************/
    976acpi_status
    977acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data)
    978{
    979	return acpi_get_data_full(obj_handle, handler, data, NULL);
    980}
    981
    982ACPI_EXPORT_SYMBOL(acpi_get_data)