1 /*******************************************************************************
3 * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
4 * ACPI Object oriented interfaces
7 ******************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #define _COMPONENT ACPI_NAMESPACE
35 MODULE_NAME ("nsxfobj")
38 /*******************************************************************************
40 * FUNCTION: Acpi_evaluate_object
42 * PARAMETERS: Handle - Object handle (optional)
43 * *Pathname - Object pathname (optional)
44 * **Params - List of parameters to pass to
45 * method, terminated by NULL.
46 * Params itself may be NULL
47 * if no parameters are being
49 * *Return_object - Where to put method's return value (if
50 * any). If NULL, no value is returned.
54 * DESCRIPTION: Find and evaluate the given object, passing the given
55 * parameters if necessary. One of "Handle" or "Pathname" must
58 ******************************************************************************/
61 acpi_evaluate_object (
64 ACPI_OBJECT_LIST
*param_objects
,
65 ACPI_BUFFER
*return_buffer
)
68 ACPI_OPERAND_OBJECT
**param_ptr
= NULL
;
69 ACPI_OPERAND_OBJECT
*return_obj
= NULL
;
70 ACPI_OPERAND_OBJECT
*object_ptr
= NULL
;
71 u32 buffer_space_needed
;
72 u32 user_buffer_length
;
80 * If there are parameters to be passed to the object
81 * (which must be a control method), the external objects
82 * must be converted to internal objects
85 if (param_objects
&& param_objects
->count
) {
87 * Allocate a new parameter block for the internal objects
88 * Add 1 to count to allow for null terminated internal list
91 count
= param_objects
->count
;
92 param_length
= (count
+ 1) * sizeof (void *);
93 object_length
= count
* sizeof (ACPI_OPERAND_OBJECT
);
95 param_ptr
= acpi_cm_callocate (param_length
+ /* Parameter List part */
96 object_length
); /* Actual objects */
98 return (AE_NO_MEMORY
);
101 object_ptr
= (ACPI_OPERAND_OBJECT
*) ((u8
*) param_ptr
+
105 * Init the param array of pointers and NULL terminate
109 for (i
= 0; i
< count
; i
++) {
110 param_ptr
[i
] = &object_ptr
[i
];
111 acpi_cm_init_static_object (&object_ptr
[i
]);
113 param_ptr
[count
] = NULL
;
116 * Convert each external object in the list to an
119 for (i
= 0; i
< count
; i
++) {
120 status
= acpi_cm_copy_eobject_to_iobject (¶m_objects
->pointer
[i
],
123 if (ACPI_FAILURE (status
)) {
124 acpi_cm_delete_internal_object_list (param_ptr
);
133 * 1) Fully qualified pathname
134 * 2) No handle, not fully qualified pathname (error)
139 (acpi_ns_valid_root_prefix (pathname
[0]))) {
141 * The path is fully qualified, just evaluate by name
143 status
= acpi_ns_evaluate_by_name (pathname
, param_ptr
, &return_obj
);
148 * A handle is optional iff a fully qualified pathname
149 * is specified. Since we've already handled fully
150 * qualified names above, this is an error
155 status
= AE_BAD_PARAMETER
;
160 * We get here if we have a handle -- and if we have a
161 * pathname it is relative. The handle will be validated
162 * in the lower procedures
167 * The null pathname case means the handle is for
168 * the actual object to be evaluated
170 status
= acpi_ns_evaluate_by_handle (handle
, param_ptr
, &return_obj
);
175 * Both a Handle and a relative Pathname
177 status
= acpi_ns_evaluate_relative (handle
, pathname
, param_ptr
,
184 * If we are expecting a return value, and all went well above,
185 * copy the return value to an external object.
189 user_buffer_length
= return_buffer
->length
;
190 return_buffer
->length
= 0;
193 if (VALID_DESCRIPTOR_TYPE (return_obj
, ACPI_DESC_TYPE_NAMED
)) {
195 * If we got an Node as a return object,
196 * this means the object we are evaluating
197 * has nothing interesting to return (such
198 * as a mutex, etc.) We return an error
199 * because these types are essentially
200 * unsupported by this interface. We
201 * don't check up front because this makes
202 * it easier to add support for various
203 * types at a later date if necessary.
206 return_obj
= NULL
; /* No need to delete an Node */
209 if (ACPI_SUCCESS (status
)) {
211 * Find out how large a buffer is needed
212 * to contain the returned object
214 status
= acpi_cm_get_object_size (return_obj
,
215 &buffer_space_needed
);
216 if (ACPI_SUCCESS (status
)) {
218 * Check if there is enough room in the
222 if (user_buffer_length
< buffer_space_needed
) {
224 * Caller's buffer is too small, can't
225 * give him partial results fail the call
226 * but return the buffer size needed
229 return_buffer
->length
= buffer_space_needed
;
230 status
= AE_BUFFER_OVERFLOW
;
235 * We have enough space for the object, build it
237 status
= acpi_cm_copy_iobject_to_eobject (return_obj
,
239 return_buffer
->length
= buffer_space_needed
;
247 /* Delete the return and parameter objects */
251 * Delete the internal return object. (Or at least
252 * decrement the reference count by one)
254 acpi_cm_remove_reference (return_obj
);
258 * Free the input parameter list (if we created one),
262 /* Free the allocated parameter block */
264 acpi_cm_delete_internal_object_list (param_ptr
);
271 /*******************************************************************************
273 * FUNCTION: Acpi_get_next_object
275 * PARAMETERS: Type - Type of object to be searched for
276 * Parent - Parent object whose children we are getting
277 * Last_child - Previous child that was found.
278 * The NEXT child will be returned
279 * Ret_handle - Where handle to the next object is placed
283 * DESCRIPTION: Return the next peer object within the namespace. If Handle is
284 * valid, Scope is ignored. Otherwise, the first object within
287 ******************************************************************************/
290 acpi_get_next_object (
291 ACPI_OBJECT_TYPE type
,
294 ACPI_HANDLE
*ret_handle
)
296 ACPI_STATUS status
= AE_OK
;
297 ACPI_NAMESPACE_NODE
*node
;
298 ACPI_NAMESPACE_NODE
*parent_node
= NULL
;
299 ACPI_NAMESPACE_NODE
*child_node
= NULL
;
302 /* Parameter validation */
304 if (type
> ACPI_TYPE_MAX
) {
305 return (AE_BAD_PARAMETER
);
308 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
310 /* If null handle, use the parent */
313 /* Start search at the beginning of the specified scope */
315 parent_node
= acpi_ns_convert_handle_to_entry (parent
);
317 status
= AE_BAD_PARAMETER
;
318 goto unlock_and_exit
;
322 /* Non-null handle, ignore the parent */
325 /* Convert and validate the handle */
327 child_node
= acpi_ns_convert_handle_to_entry (child
);
329 status
= AE_BAD_PARAMETER
;
330 goto unlock_and_exit
;
335 /* Internal function does the real work */
337 node
= acpi_ns_get_next_object ((OBJECT_TYPE_INTERNAL
) type
,
338 parent_node
, child_node
);
340 status
= AE_NOT_FOUND
;
341 goto unlock_and_exit
;
345 *ret_handle
= acpi_ns_convert_entry_to_handle (node
);
351 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
356 /*******************************************************************************
358 * FUNCTION: Acpi_get_type
360 * PARAMETERS: Handle - Handle of object whose type is desired
361 * *Ret_type - Where the type will be placed
365 * DESCRIPTION: This routine returns the type associatd with a particular handle
367 ******************************************************************************/
372 ACPI_OBJECT_TYPE
*ret_type
)
374 ACPI_NAMESPACE_NODE
*node
;
377 /* Parameter Validation */
380 return (AE_BAD_PARAMETER
);
384 * Special case for the predefined Root Node
387 if (handle
== ACPI_ROOT_OBJECT
) {
388 *ret_type
= ACPI_TYPE_ANY
;
392 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
394 /* Convert and validate the handle */
396 node
= acpi_ns_convert_handle_to_entry (handle
);
398 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
399 return (AE_BAD_PARAMETER
);
402 *ret_type
= node
->type
;
405 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
410 /*******************************************************************************
412 * FUNCTION: Acpi_get_parent
414 * PARAMETERS: Handle - Handle of object whose parent is desired
415 * Ret_handle - Where the parent handle will be placed
419 * DESCRIPTION: Returns a handle to the parent of the object represented by
422 ******************************************************************************/
427 ACPI_HANDLE
*ret_handle
)
429 ACPI_NAMESPACE_NODE
*node
;
430 ACPI_STATUS status
= AE_OK
;
433 /* No trace macro, too verbose */
437 return (AE_BAD_PARAMETER
);
440 /* Special case for the predefined Root Node (no parent) */
442 if (handle
== ACPI_ROOT_OBJECT
) {
443 return (AE_NULL_ENTRY
);
447 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
449 /* Convert and validate the handle */
451 node
= acpi_ns_convert_handle_to_entry (handle
);
453 status
= AE_BAD_PARAMETER
;
454 goto unlock_and_exit
;
458 /* Get the parent entry */
461 acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_object (node
));
463 /* Return exeption if parent is null */
465 if (!acpi_ns_get_parent_object (node
)) {
466 status
= AE_NULL_ENTRY
;
472 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
477 /*******************************************************************************
479 * FUNCTION: Acpi_walk_namespace
481 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
482 * Start_object - Handle in namespace where search begins
483 * Max_depth - Depth to which search is to reach
484 * User_function - Called when an object of "Type" is found
485 * Context - Passed to user function
486 * Return_value - Location where return value of
487 * User_function is put if terminated early
489 * RETURNS Return value from the User_function if terminated early.
490 * Otherwise, returns NULL.
492 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
493 * starting (and ending) at the object specified by Start_handle.
494 * The User_function is called whenever an object that matches
495 * the type parameter is found. If the user function returns
496 * a non-zero value, the search is terminated immediately and this
497 * value is returned to the caller.
499 * The point of this procedure is to provide a generic namespace
500 * walk routine that can be called from multiple places to
501 * provide multiple services; the User Function can be tailored
502 * to each task, whether it is a print function, a compare
505 ******************************************************************************/
508 acpi_walk_namespace (
509 ACPI_OBJECT_TYPE type
,
510 ACPI_HANDLE start_object
,
512 WALK_CALLBACK user_function
,
519 /* Parameter validation */
521 if ((type
> ACPI_TYPE_MAX
) ||
524 return (AE_BAD_PARAMETER
);
528 * Lock the namespace around the walk.
529 * The namespace will be unlocked/locked around each call
530 * to the user function - since this function
531 * must be allowed to make Acpi calls itself.
534 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
535 status
= acpi_ns_walk_namespace ((OBJECT_TYPE_INTERNAL
) type
,
536 start_object
, max_depth
,
538 user_function
, context
,
541 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
547 /*******************************************************************************
549 * FUNCTION: Acpi_ns_get_device_callback
551 * PARAMETERS: Callback from Acpi_get_device
555 * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non-
556 * present devices, or if they specified a HID, it filters based
559 ******************************************************************************/
562 acpi_ns_get_device_callback (
563 ACPI_HANDLE obj_handle
,
569 ACPI_NAMESPACE_NODE
*node
;
572 ACPI_GET_DEVICES_INFO
*info
;
577 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
579 node
= acpi_ns_convert_handle_to_entry (obj_handle
);
581 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
584 return (AE_BAD_PARAMETER
);
588 * Run _STA to determine if device is present
591 status
= acpi_cm_execute_STA (node
, &flags
);
592 if (ACPI_FAILURE (status
)) {
596 if (!(flags
& 0x01)) {
597 /* don't return at the device or children of the device if not there */
599 return (AE_CTRL_DEPTH
);
603 * Filter based on device HID
605 if (info
->hid
!= NULL
) {
606 status
= acpi_cm_execute_HID (node
, &device_id
);
608 if (status
== AE_NOT_FOUND
) {
612 else if (ACPI_FAILURE (status
)) {
616 if (STRNCMP (device_id
.buffer
, info
->hid
, sizeof (device_id
.buffer
)) != 0) {
621 info
->user_function (obj_handle
, nesting_level
, info
->context
, return_value
);
627 /*******************************************************************************
629 * FUNCTION: Acpi_get_devices
631 * PARAMETERS: HID - HID to search for. Can be NULL.
632 * User_function - Called when a matching object is found
633 * Context - Passed to user function
634 * Return_value - Location where return value of
635 * User_function is put if terminated early
637 * RETURNS Return value from the User_function if terminated early.
638 * Otherwise, returns NULL.
640 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
641 * starting (and ending) at the object specified by Start_handle.
642 * The User_function is called whenever an object that matches
643 * the type parameter is found. If the user function returns
644 * a non-zero value, the search is terminated immediately and this
645 * value is returned to the caller.
647 * This is a wrapper for Walk_namespace, but the callback performs
648 * additional filtering. Please see Acpi_get_device_callback.
650 ******************************************************************************/
655 WALK_CALLBACK user_function
,
660 ACPI_GET_DEVICES_INFO info
;
663 /* Parameter validation */
665 if (!user_function
) {
666 return (AE_BAD_PARAMETER
);
670 * We're going to call their callback from OUR callback, so we need
671 * to know what it is, and their context parameter.
673 info
.context
= context
;
674 info
.user_function
= user_function
;
678 * Lock the namespace around the walk.
679 * The namespace will be unlocked/locked around each call
680 * to the user function - since this function
681 * must be allowed to make Acpi calls itself.
684 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
685 status
= acpi_ns_walk_namespace (ACPI_TYPE_DEVICE
,
686 ACPI_ROOT_OBJECT
, ACPI_UINT32_MAX
,
688 acpi_ns_get_device_callback
, &info
,
691 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);