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
17 ACPI_MODULE_NAME("nsxfeval")
18 
19 /* Local prototypes */
20 static 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 
43 acpi_status
acpi_evaluate_object_typed(acpi_handle handle,acpi_string pathname,struct acpi_object_list * external_params,struct acpi_buffer * return_buffer,acpi_object_type return_type)44 acpi_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 
136 exit:
137 	ACPI_FREE(full_pathname);
138 	return_ACPI_STATUS(status);
139 }
140 
ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)141 ACPI_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  ******************************************************************************/
162 acpi_status
163 acpi_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 
420 cleanup_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 
435 cleanup:
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 
ACPI_EXPORT_SYMBOL(acpi_evaluate_object)450 ACPI_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  ******************************************************************************/
472 static 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 
553 acpi_status
acpi_walk_namespace(acpi_object_type type,acpi_handle start_object,u32 max_depth,acpi_walk_callback descending_callback,acpi_walk_callback ascending_callback,void * context,void ** return_value)554 acpi_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 
611 unlock_and_exit2:
612 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
613 
614 unlock_and_exit:
615 	(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
616 	return_ACPI_STATUS(status);
617 }
618 
ACPI_EXPORT_SYMBOL(acpi_walk_namespace)619 ACPI_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  ******************************************************************************/
634 static acpi_status
635 acpi_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 
770 acpi_status
acpi_get_devices(const char * HID,acpi_walk_callback user_function,void * context,void ** return_value)771 acpi_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 
ACPI_EXPORT_SYMBOL(acpi_get_devices)814 ACPI_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  ******************************************************************************/
829 acpi_status
830 acpi_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 
857 unlock_and_exit:
858 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
859 	return (status);
860 }
861 
ACPI_EXPORT_SYMBOL(acpi_attach_data)862 ACPI_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  ******************************************************************************/
876 acpi_status
877 acpi_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 
903 unlock_and_exit:
904 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
905 	return (status);
906 }
907 
ACPI_EXPORT_SYMBOL(acpi_detach_data)908 ACPI_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  ******************************************************************************/
925 acpi_status
926 acpi_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 
956 unlock_and_exit:
957 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
958 	return (status);
959 }
960 
ACPI_EXPORT_SYMBOL(acpi_get_data_full)961 ACPI_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  ******************************************************************************/
976 acpi_status
977 acpi_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 
982 ACPI_EXPORT_SYMBOL(acpi_get_data)
983