nsxfeval.c 21.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8
/*******************************************************************************
 *
 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
 *                         ACPI Object evaluation interfaces
 *
 ******************************************************************************/

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

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

#define _COMPONENT          ACPI_NAMESPACE
L
Len Brown 已提交
50
ACPI_MODULE_NAME("nsxfeval")
B
Bob Moore 已提交
51
#ifdef ACPI_FUTURE_USAGE
L
Linus Torvalds 已提交
52 53 54 55 56
/*******************************************************************************
 *
 * FUNCTION:    acpi_evaluate_object_typed
 *
 * PARAMETERS:  Handle              - Object handle (optional)
R
Robert Moore 已提交
57 58
 *              Pathname            - Object pathname (optional)
 *              external_params     - List of parameters to pass to method,
L
Linus Torvalds 已提交
59 60
 *                                    terminated by NULL.  May be NULL
 *                                    if no parameters are being passed.
R
Robert Moore 已提交
61
 *              return_buffer       - Where to put method's return value (if
L
Linus Torvalds 已提交
62 63 64 65 66 67 68 69 70 71 72
 *                                    any).  If NULL, no value is returned.
 *              return_type         - Expected type of return object
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Find and evaluate the given object, passing the given
 *              parameters if necessary.  One of "Handle" or "Pathname" must
 *              be valid (non-null)
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
73 74
acpi_evaluate_object_typed(acpi_handle handle,
			   acpi_string pathname,
L
Len Brown 已提交
75 76
			   struct acpi_object_list *external_params,
			   struct acpi_buffer *return_buffer,
L
Len Brown 已提交
77
			   acpi_object_type return_type)
L
Linus Torvalds 已提交
78
{
L
Len Brown 已提交
79 80
	acpi_status status;
	u8 must_free = FALSE;
L
Linus Torvalds 已提交
81

B
Bob Moore 已提交
82
	ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed);
L
Linus Torvalds 已提交
83 84 85 86

	/* Return buffer must be valid */

	if (!return_buffer) {
L
Len Brown 已提交
87
		return_ACPI_STATUS(AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
88 89 90 91 92 93 94 95
	}

	if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
		must_free = TRUE;
	}

	/* Evaluate the object */

L
Len Brown 已提交
96 97 98 99 100
	status =
	    acpi_evaluate_object(handle, pathname, external_params,
				 return_buffer);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
101 102 103 104 105
	}

	/* Type ANY means "don't care" */

	if (return_type == ACPI_TYPE_ANY) {
L
Len Brown 已提交
106
		return_ACPI_STATUS(AE_OK);
L
Linus Torvalds 已提交
107 108 109
	}

	if (return_buffer->length == 0) {
B
Bob Moore 已提交
110

L
Linus Torvalds 已提交
111 112
		/* Error because caller specifically asked for a return value */

B
Bob Moore 已提交
113
		ACPI_ERROR((AE_INFO, "No return value"));
L
Len Brown 已提交
114
		return_ACPI_STATUS(AE_NULL_OBJECT);
L
Linus Torvalds 已提交
115 116 117 118
	}

	/* Examine the object type returned from evaluate_object */

L
Len Brown 已提交
119 120
	if (((union acpi_object *)return_buffer->pointer)->type == return_type) {
		return_ACPI_STATUS(AE_OK);
L
Linus Torvalds 已提交
121 122 123 124
	}

	/* Return object type does not match requested type */

B
Bob Moore 已提交
125 126 127 128 129
	ACPI_ERROR((AE_INFO,
		    "Incorrect return type [%s] requested [%s]",
		    acpi_ut_get_type_name(((union acpi_object *)return_buffer->
					   pointer)->type),
		    acpi_ut_get_type_name(return_type)));
L
Linus Torvalds 已提交
130 131

	if (must_free) {
B
Bob Moore 已提交
132

L
Linus Torvalds 已提交
133 134
		/* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */

135
		ACPI_FREE(return_buffer->pointer);
L
Linus Torvalds 已提交
136 137 138 139
		return_buffer->pointer = NULL;
	}

	return_buffer->length = 0;
L
Len Brown 已提交
140
	return_ACPI_STATUS(AE_TYPE);
L
Linus Torvalds 已提交
141
}
B
Bob Moore 已提交
142 143

ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
L
Len Brown 已提交
144
#endif				/*  ACPI_FUTURE_USAGE  */
L
Linus Torvalds 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/*******************************************************************************
 *
 * FUNCTION:    acpi_evaluate_object
 *
 * PARAMETERS:  Handle              - Object handle (optional)
 *              Pathname            - Object pathname (optional)
 *              external_params     - List of parameters to pass to method,
 *                                    terminated by NULL.  May be NULL
 *                                    if no parameters are being passed.
 *              return_buffer       - Where to put method's return value (if
 *                                    any).  If NULL, no value is returned.
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Find and evaluate the given object, passing the given
 *              parameters if necessary.  One of "Handle" or "Pathname" must
 *              be valid (non-null)
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
165 166 167 168
acpi_evaluate_object(acpi_handle handle,
		     acpi_string pathname,
		     struct acpi_object_list *external_params,
		     struct acpi_buffer *return_buffer)
L
Linus Torvalds 已提交
169
{
L
Len Brown 已提交
170
	acpi_status status;
B
Bob Moore 已提交
171
	struct acpi_evaluate_info *info;
L
Len Brown 已提交
172 173
	acpi_size buffer_space_needed;
	u32 i;
L
Linus Torvalds 已提交
174

B
Bob Moore 已提交
175
	ACPI_FUNCTION_TRACE(acpi_evaluate_object);
L
Linus Torvalds 已提交
176

B
Bob Moore 已提交
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
	/* Allocate and initialize the evaluation information block */

	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
	if (!info) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	info->pathname = pathname;
	info->parameter_type = ACPI_PARAM_ARGS;

	/* Convert and validate the device handle */

	info->prefix_node = acpi_ns_map_handle_to_node(handle);
	if (!info->prefix_node) {
		status = AE_BAD_PARAMETER;
		goto cleanup;
	}
L
Linus Torvalds 已提交
194 195

	/*
B
Bob Moore 已提交
196 197
	 * If there are parameters to be passed to a control method, the external
	 * objects must all be converted to internal objects
L
Linus Torvalds 已提交
198 199 200 201 202 203
	 */
	if (external_params && external_params->count) {
		/*
		 * Allocate a new parameter block for the internal objects
		 * Add 1 to count to allow for null terminated internal list
		 */
B
Bob Moore 已提交
204 205 206 207 208 209 210
		info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
							 external_params->
							 count +
							 1) * sizeof(void *));
		if (!info->parameters) {
			status = AE_NO_MEMORY;
			goto cleanup;
L
Linus Torvalds 已提交
211 212
		}

B
Bob Moore 已提交
213 214
		/* Convert each external object in the list to an internal object */

L
Linus Torvalds 已提交
215
		for (i = 0; i < external_params->count; i++) {
L
Len Brown 已提交
216 217 218
			status =
			    acpi_ut_copy_eobject_to_iobject(&external_params->
							    pointer[i],
B
Bob Moore 已提交
219
							    &info->
L
Len Brown 已提交
220 221
							    parameters[i]);
			if (ACPI_FAILURE(status)) {
B
Bob Moore 已提交
222
				goto cleanup;
L
Linus Torvalds 已提交
223 224
			}
		}
B
Bob Moore 已提交
225
		info->parameters[external_params->count] = NULL;
L
Linus Torvalds 已提交
226 227 228 229 230 231 232 233
	}

	/*
	 * Three major cases:
	 * 1) Fully qualified pathname
	 * 2) No handle, not fully qualified pathname (error)
	 * 3) Valid handle
	 */
L
Len Brown 已提交
234
	if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) {
B
Bob Moore 已提交
235 236 237

		/* The path is fully qualified, just evaluate by name */

B
Bob Moore 已提交
238 239
		info->prefix_node = NULL;
		status = acpi_ns_evaluate(info);
L
Len Brown 已提交
240
	} else if (!handle) {
L
Linus Torvalds 已提交
241
		/*
B
Bob Moore 已提交
242 243 244
		 * A handle is optional iff a fully qualified pathname is specified.
		 * Since we've already handled fully qualified names above, this is
		 * an error
L
Linus Torvalds 已提交
245 246
		 */
		if (!pathname) {
B
Bob Moore 已提交
247 248
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
					  "Both Handle and Pathname are NULL"));
L
Len Brown 已提交
249
		} else {
B
Bob Moore 已提交
250 251 252
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
					  "Null Handle with relative pathname [%s]",
					  pathname));
L
Linus Torvalds 已提交
253 254 255
		}

		status = AE_BAD_PARAMETER;
L
Len Brown 已提交
256
	} else {
B
Bob Moore 已提交
257
		/* We have a namespace a node and a possible relative path */
B
Bob Moore 已提交
258

B
Bob Moore 已提交
259
		status = acpi_ns_evaluate(info);
L
Linus Torvalds 已提交
260 261 262 263 264 265 266
	}

	/*
	 * If we are expecting a return value, and all went well above,
	 * copy the return value to an external object.
	 */
	if (return_buffer) {
B
Bob Moore 已提交
267
		if (!info->return_object) {
L
Linus Torvalds 已提交
268
			return_buffer->length = 0;
L
Len Brown 已提交
269
		} else {
B
Bob Moore 已提交
270
			if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
L
Len Brown 已提交
271
			    ACPI_DESC_TYPE_NAMED) {
L
Linus Torvalds 已提交
272 273 274 275 276 277 278 279 280
				/*
				 * If we received a NS Node as a return object, this means that
				 * the object we are evaluating has nothing interesting to
				 * return (such as a mutex, etc.)  We return an error because
				 * these types are essentially unsupported by this interface.
				 * We don't check up front because this makes it easier to add
				 * support for various types at a later date if necessary.
				 */
				status = AE_TYPE;
B
Bob Moore 已提交
281
				info->return_object = NULL;	/* No need to delete a NS Node */
L
Linus Torvalds 已提交
282 283 284
				return_buffer->length = 0;
			}

L
Len Brown 已提交
285
			if (ACPI_SUCCESS(status)) {
B
Bob Moore 已提交
286 287 288

				/* Get the size of the returned object */

L
Len Brown 已提交
289
				status =
B
Bob Moore 已提交
290
				    acpi_ut_get_object_size(info->return_object,
L
Len Brown 已提交
291 292
							    &buffer_space_needed);
				if (ACPI_SUCCESS(status)) {
B
Bob Moore 已提交
293

L
Linus Torvalds 已提交
294 295
					/* Validate/Allocate/Clear caller buffer */

L
Len Brown 已提交
296 297 298 299 300
					status =
					    acpi_ut_initialize_buffer
					    (return_buffer,
					     buffer_space_needed);
					if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
301
						/*
B
Bob Moore 已提交
302 303
						 * Caller's buffer is too small or a new one can't
						 * be allocated
L
Linus Torvalds 已提交
304
						 */
L
Len Brown 已提交
305 306 307 308 309 310 311
						ACPI_DEBUG_PRINT((ACPI_DB_INFO,
								  "Needed buffer size %X, %s\n",
								  (u32)
								  buffer_space_needed,
								  acpi_format_exception
								  (status)));
					} else {
B
Bob Moore 已提交
312 313
						/* We have enough space for the object, build it */

L
Len Brown 已提交
314 315
						status =
						    acpi_ut_copy_iobject_to_eobject
B
Bob Moore 已提交
316
						    (info->return_object,
L
Len Brown 已提交
317
						     return_buffer);
L
Linus Torvalds 已提交
318 319 320 321 322 323
					}
				}
			}
		}
	}

B
Bob Moore 已提交
324
	if (info->return_object) {
L
Linus Torvalds 已提交
325
		/*
B
Bob Moore 已提交
326 327
		 * Delete the internal return object. NOTE: Interpreter must be
		 * locked to avoid race condition.
L
Linus Torvalds 已提交
328
		 */
329
		acpi_ex_enter_interpreter();
B
Bob Moore 已提交
330

331
		/* Remove one reference on the return object (should delete it) */
B
Bob Moore 已提交
332

333 334
		acpi_ut_remove_reference(info->return_object);
		acpi_ex_exit_interpreter();
L
Linus Torvalds 已提交
335 336
	}

B
Bob Moore 已提交
337 338
      cleanup:

B
Bob Moore 已提交
339 340
	/* Free the input parameter list (if we created one) */

B
Bob Moore 已提交
341
	if (info->parameters) {
B
Bob Moore 已提交
342

L
Linus Torvalds 已提交
343 344
		/* Free the allocated parameter block */

B
Bob Moore 已提交
345
		acpi_ut_delete_internal_object_list(info->parameters);
L
Linus Torvalds 已提交
346 347
	}

B
Bob Moore 已提交
348
	ACPI_FREE(info);
L
Len Brown 已提交
349
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
350 351
}

B
Bob Moore 已提交
352
ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
L
Linus Torvalds 已提交
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383

/*******************************************************************************
 *
 * FUNCTION:    acpi_walk_namespace
 *
 * PARAMETERS:  Type                - acpi_object_type to search for
 *              start_object        - Handle in namespace where search begins
 *              max_depth           - Depth to which search is to reach
 *              user_function       - Called when an object of "Type" is found
 *              Context             - Passed to user function
 *              return_value        - Location where return value of
 *                                    user_function is put if terminated early
 *
 * RETURNS      Return value from the user_function if terminated early.
 *              Otherwise, returns NULL.
 *
 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
 *              starting (and ending) at the object specified by start_handle.
 *              The user_function is called whenever an object that matches
 *              the type parameter is found.  If the user function returns
 *              a non-zero value, the search is terminated immediately and this
 *              value is returned to the caller.
 *
 *              The point of this procedure is to provide a generic namespace
 *              walk routine that can be called from multiple places to
 *              provide multiple services;  the User Function can be tailored
 *              to each task, whether it is a print function, a compare
 *              function, etc.
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
384 385 386 387 388
acpi_walk_namespace(acpi_object_type type,
		    acpi_handle start_object,
		    u32 max_depth,
		    acpi_walk_callback user_function,
		    void *context, void **return_value)
L
Linus Torvalds 已提交
389
{
L
Len Brown 已提交
390
	acpi_status status;
L
Linus Torvalds 已提交
391

B
Bob Moore 已提交
392
	ACPI_FUNCTION_TRACE(acpi_walk_namespace);
L
Linus Torvalds 已提交
393 394 395

	/* Parameter validation */

B
Bob Moore 已提交
396
	if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) {
L
Len Brown 已提交
397
		return_ACPI_STATUS(AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
398 399 400 401 402 403 404 405
	}

	/*
	 * Lock the namespace around the walk.
	 * The namespace will be unlocked/locked around each call
	 * to the user function - since this function
	 * must be allowed to make Acpi calls itself.
	 */
L
Len Brown 已提交
406 407 408
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
409 410
	}

L
Len Brown 已提交
411 412 413
	status = acpi_ns_walk_namespace(type, start_object, max_depth,
					ACPI_NS_WALK_UNLOCK,
					user_function, context, return_value);
L
Linus Torvalds 已提交
414

L
Len Brown 已提交
415 416
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
417 418
}

B
Bob Moore 已提交
419
ACPI_EXPORT_SYMBOL(acpi_walk_namespace)
L
Linus Torvalds 已提交
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434

/*******************************************************************************
 *
 * FUNCTION:    acpi_ns_get_device_callback
 *
 * PARAMETERS:  Callback from acpi_get_device
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
 *              present devices, or if they specified a HID, it filters based
 *              on that.
 *
 ******************************************************************************/
static acpi_status
L
Len Brown 已提交
435 436 437
acpi_ns_get_device_callback(acpi_handle obj_handle,
			    u32 nesting_level,
			    void *context, void **return_value)
L
Linus Torvalds 已提交
438
{
L
Len Brown 已提交
439 440 441 442
	struct acpi_get_devices_info *info = context;
	acpi_status status;
	struct acpi_namespace_node *node;
	u32 flags;
443
	struct acpica_device_id hid;
L
Linus Torvalds 已提交
444
	struct acpi_compatible_id_list *cid;
L
Len Brown 已提交
445
	acpi_native_uint i;
446
	int found;
L
Linus Torvalds 已提交
447

L
Len Brown 已提交
448 449
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
450 451 452
		return (status);
	}

L
Len Brown 已提交
453 454 455
	node = acpi_ns_map_handle_to_node(obj_handle);
	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
456 457 458 459 460 461 462 463 464
		return (status);
	}

	if (!node) {
		return (AE_BAD_PARAMETER);
	}

	/* Run _STA to determine if device is present */

L
Len Brown 已提交
465 466
	status = acpi_ut_execute_STA(node, &flags);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
467 468 469
		return (AE_CTRL_DEPTH);
	}

B
Bob Moore 已提交
470
	if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
B
Bob Moore 已提交
471

B
Bob Moore 已提交
472
		/* Don't examine children of the device if not present */
L
Linus Torvalds 已提交
473 474 475 476 477 478 479

		return (AE_CTRL_DEPTH);
	}

	/* Filter based on device HID & CID */

	if (info->hid != NULL) {
L
Len Brown 已提交
480
		status = acpi_ut_execute_HID(node, &hid);
L
Linus Torvalds 已提交
481 482
		if (status == AE_NOT_FOUND) {
			return (AE_OK);
L
Len Brown 已提交
483
		} else if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
484 485 486
			return (AE_CTRL_DEPTH);
		}

L
Len Brown 已提交
487
		if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) {
B
Bob Moore 已提交
488

L
Linus Torvalds 已提交
489 490
			/* Get the list of Compatible IDs */

L
Len Brown 已提交
491
			status = acpi_ut_execute_CID(node, &cid);
L
Linus Torvalds 已提交
492 493
			if (status == AE_NOT_FOUND) {
				return (AE_OK);
L
Len Brown 已提交
494
			} else if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
495 496 497 498 499
				return (AE_CTRL_DEPTH);
			}

			/* Walk the CID list */

500
			found = 0;
L
Linus Torvalds 已提交
501
			for (i = 0; i < cid->count; i++) {
L
Len Brown 已提交
502 503
				if (ACPI_STRNCMP(cid->id[i].value, info->hid,
						 sizeof(struct
504
							acpi_compatible_id)) ==
L
Len Brown 已提交
505
				    0) {
506 507
					found = 1;
					break;
L
Linus Torvalds 已提交
508 509
				}
			}
B
Bob Moore 已提交
510
			ACPI_FREE(cid);
511 512
			if (!found)
				return (AE_OK);
L
Linus Torvalds 已提交
513 514 515
		}
	}

L
Len Brown 已提交
516 517
	status = info->user_function(obj_handle, nesting_level, info->context,
				     return_value);
L
Linus Torvalds 已提交
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_get_devices
 *
 * PARAMETERS:  HID                 - HID to search for. Can be NULL.
 *              user_function       - Called when a matching object is found
 *              Context             - Passed to user function
 *              return_value        - Location where return value of
 *                                    user_function is put if terminated early
 *
 * RETURNS      Return value from the user_function if terminated early.
 *              Otherwise, returns NULL.
 *
 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
 *              starting (and ending) at the object specified by start_handle.
 *              The user_function is called whenever an object of type
 *              Device is found.  If the user function returns
 *              a non-zero value, the search is terminated immediately and this
 *              value is returned to the caller.
 *
 *              This is a wrapper for walk_namespace, but the callback performs
 *              additional filtering. Please see acpi_get_device_callback.
 *
 ******************************************************************************/

acpi_status
547
acpi_get_devices(const char *HID,
L
Len Brown 已提交
548 549
		 acpi_walk_callback user_function,
		 void *context, void **return_value)
L
Linus Torvalds 已提交
550
{
L
Len Brown 已提交
551 552
	acpi_status status;
	struct acpi_get_devices_info info;
L
Linus Torvalds 已提交
553

B
Bob Moore 已提交
554
	ACPI_FUNCTION_TRACE(acpi_get_devices);
L
Linus Torvalds 已提交
555 556 557 558

	/* Parameter validation */

	if (!user_function) {
L
Len Brown 已提交
559
		return_ACPI_STATUS(AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
560 561 562 563 564 565
	}

	/*
	 * We're going to call their callback from OUR callback, so we need
	 * to know what it is, and their context parameter.
	 */
B
Bob Moore 已提交
566
	info.hid = HID;
L
Len Brown 已提交
567
	info.context = context;
L
Linus Torvalds 已提交
568 569 570 571 572 573 574 575
	info.user_function = user_function;

	/*
	 * Lock the namespace around the walk.
	 * The namespace will be unlocked/locked around each call
	 * to the user function - since this function
	 * must be allowed to make Acpi calls itself.
	 */
L
Len Brown 已提交
576 577 578
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
579 580
	}

B
Bob Moore 已提交
581 582
	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
					ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
L
Len Brown 已提交
583 584
					acpi_ns_get_device_callback, &info,
					return_value);
L
Linus Torvalds 已提交
585

L
Len Brown 已提交
586 587
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
588 589
}

B
Bob Moore 已提交
590
ACPI_EXPORT_SYMBOL(acpi_get_devices)
L
Linus Torvalds 已提交
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605

/*******************************************************************************
 *
 * FUNCTION:    acpi_attach_data
 *
 * PARAMETERS:  obj_handle          - Namespace node
 *              Handler             - Handler for this attachment
 *              Data                - Pointer to data to be attached
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
606 607
acpi_attach_data(acpi_handle obj_handle,
		 acpi_object_handler handler, void *data)
L
Linus Torvalds 已提交
608
{
L
Len Brown 已提交
609 610
	struct acpi_namespace_node *node;
	acpi_status status;
L
Linus Torvalds 已提交
611 612 613

	/* Parameter validation */

L
Len Brown 已提交
614
	if (!obj_handle || !handler || !data) {
L
Linus Torvalds 已提交
615 616 617
		return (AE_BAD_PARAMETER);
	}

L
Len Brown 已提交
618 619
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
620 621 622 623 624
		return (status);
	}

	/* Convert and validate the handle */

L
Len Brown 已提交
625
	node = acpi_ns_map_handle_to_node(obj_handle);
L
Linus Torvalds 已提交
626 627 628 629 630
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

L
Len Brown 已提交
631
	status = acpi_ns_attach_data(node, handler, data);
L
Linus Torvalds 已提交
632

L
Len Brown 已提交
633 634
      unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
L
Linus Torvalds 已提交
635 636 637
	return (status);
}

B
Bob Moore 已提交
638 639
ACPI_EXPORT_SYMBOL(acpi_attach_data)

L
Linus Torvalds 已提交
640 641 642 643 644 645 646 647 648 649 650 651 652
/*******************************************************************************
 *
 * FUNCTION:    acpi_detach_data
 *
 * PARAMETERS:  obj_handle          - Namespace node handle
 *              Handler             - Handler used in call to acpi_attach_data
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Remove data that was previously attached to a node.
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
653
acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler)
L
Linus Torvalds 已提交
654
{
L
Len Brown 已提交
655 656
	struct acpi_namespace_node *node;
	acpi_status status;
L
Linus Torvalds 已提交
657 658 659

	/* Parameter validation */

L
Len Brown 已提交
660
	if (!obj_handle || !handler) {
L
Linus Torvalds 已提交
661 662 663
		return (AE_BAD_PARAMETER);
	}

L
Len Brown 已提交
664 665
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
666 667 668 669 670
		return (status);
	}

	/* Convert and validate the handle */

L
Len Brown 已提交
671
	node = acpi_ns_map_handle_to_node(obj_handle);
L
Linus Torvalds 已提交
672 673 674 675 676
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

L
Len Brown 已提交
677
	status = acpi_ns_detach_data(node, handler);
L
Linus Torvalds 已提交
678

L
Len Brown 已提交
679 680
      unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
L
Linus Torvalds 已提交
681 682 683
	return (status);
}

B
Bob Moore 已提交
684 685
ACPI_EXPORT_SYMBOL(acpi_detach_data)

L
Linus Torvalds 已提交
686 687 688 689 690 691 692 693 694 695 696 697 698 699
/*******************************************************************************
 *
 * FUNCTION:    acpi_get_data
 *
 * PARAMETERS:  obj_handle          - Namespace node
 *              Handler             - Handler used in call to attach_data
 *              Data                - Where the data is returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
 *
 ******************************************************************************/
acpi_status
L
Len Brown 已提交
700
acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data)
L
Linus Torvalds 已提交
701
{
L
Len Brown 已提交
702 703
	struct acpi_namespace_node *node;
	acpi_status status;
L
Linus Torvalds 已提交
704 705 706

	/* Parameter validation */

L
Len Brown 已提交
707
	if (!obj_handle || !handler || !data) {
L
Linus Torvalds 已提交
708 709 710
		return (AE_BAD_PARAMETER);
	}

L
Len Brown 已提交
711 712
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
713 714 715 716 717
		return (status);
	}

	/* Convert and validate the handle */

L
Len Brown 已提交
718
	node = acpi_ns_map_handle_to_node(obj_handle);
L
Linus Torvalds 已提交
719 720 721 722 723
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

L
Len Brown 已提交
724
	status = acpi_ns_get_attached_data(node, handler, data);
L
Linus Torvalds 已提交
725

L
Len Brown 已提交
726 727
      unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
L
Linus Torvalds 已提交
728 729
	return (status);
}
B
Bob Moore 已提交
730 731

ACPI_EXPORT_SYMBOL(acpi_get_data)