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
30 #define _COMPONENT ACPI_NAMESPACE
31 MODULE_NAME ("nsxfobj")
34 /*******************************************************************************
36 * FUNCTION: Acpi_evaluate_object
38 * PARAMETERS: Handle - Object handle (optional)
39 * *Pathname - Object pathname (optional)
40 * **Params - List of parameters to pass to
41 * method, terminated by NULL.
42 * Params itself may be NULL
43 * if no parameters are being
45 * *Return_object - Where to put method's return value (if
46 * any). If NULL, no value is returned.
50 * DESCRIPTION: Find and evaluate the given object, passing the given
51 * parameters if necessary. One of "Handle" or "Pathname" must
54 ******************************************************************************/
57 acpi_evaluate_object (
60 ACPI_OBJECT_LIST
*param_objects
,
61 ACPI_BUFFER
*return_buffer
)
64 ACPI_OPERAND_OBJECT
**param_ptr
= NULL
;
65 ACPI_OPERAND_OBJECT
*return_obj
= NULL
;
66 ACPI_OPERAND_OBJECT
*object_ptr
= NULL
;
67 u32 buffer_space_needed
;
68 u32 user_buffer_length
;
76 * If there are parameters to be passed to the object
77 * (which must be a control method), the external objects
78 * must be converted to internal objects
81 if (param_objects
&& param_objects
->count
) {
83 * Allocate a new parameter block for the internal objects
84 * Add 1 to count to allow for null terminated internal list
87 count
= param_objects
->count
;
88 param_length
= (count
+ 1) * sizeof (void *);
89 object_length
= count
* sizeof (ACPI_OPERAND_OBJECT
);
91 param_ptr
= acpi_cm_callocate (param_length
+ /* Parameter List part */
92 object_length
); /* Actual objects */
94 return (AE_NO_MEMORY
);
97 object_ptr
= (ACPI_OPERAND_OBJECT
*) ((u8
*) param_ptr
+
101 * Init the param array of pointers and NULL terminate
105 for (i
= 0; i
< count
; i
++) {
106 param_ptr
[i
] = &object_ptr
[i
];
107 acpi_cm_init_static_object (&object_ptr
[i
]);
109 param_ptr
[count
] = NULL
;
112 * Convert each external object in the list to an
115 for (i
= 0; i
< count
; i
++) {
116 status
= acpi_cm_copy_eobject_to_iobject (¶m_objects
->pointer
[i
],
119 if (ACPI_FAILURE (status
)) {
120 acpi_cm_delete_internal_object_list (param_ptr
);
129 * 1) Fully qualified pathname
130 * 2) No handle, not fully qualified pathname (error)
135 (acpi_ns_valid_root_prefix (pathname
[0]))) {
137 * The path is fully qualified, just evaluate by name
139 status
= acpi_ns_evaluate_by_name (pathname
, param_ptr
, &return_obj
);
144 * A handle is optional iff a fully qualified pathname
145 * is specified. Since we've already handled fully
146 * qualified names above, this is an error
151 status
= AE_BAD_PARAMETER
;
156 * We get here if we have a handle -- and if we have a
157 * pathname it is relative. The handle will be validated
158 * in the lower procedures
163 * The null pathname case means the handle is for
164 * the actual object to be evaluated
166 status
= acpi_ns_evaluate_by_handle (handle
, param_ptr
, &return_obj
);
171 * Both a Handle and a relative Pathname
173 status
= acpi_ns_evaluate_relative (handle
, pathname
, param_ptr
,
180 * If we are expecting a return value, and all went well above,
181 * copy the return value to an external object.
185 user_buffer_length
= return_buffer
->length
;
186 return_buffer
->length
= 0;
189 if (VALID_DESCRIPTOR_TYPE (return_obj
, ACPI_DESC_TYPE_NAMED
)) {
191 * If we got an Node as a return object,
192 * this means the object we are evaluating
193 * has nothing interesting to return (such
194 * as a mutex, etc.) We return an error
195 * because these types are essentially
196 * unsupported by this interface. We
197 * don't check up front because this makes
198 * it easier to add support for various
199 * types at a later date if necessary.
202 return_obj
= NULL
; /* No need to delete an Node */
205 if (ACPI_SUCCESS (status
)) {
207 * Find out how large a buffer is needed
208 * to contain the returned object
210 status
= acpi_cm_get_object_size (return_obj
,
211 &buffer_space_needed
);
212 if (ACPI_SUCCESS (status
)) {
214 * Check if there is enough room in the
218 if (user_buffer_length
< buffer_space_needed
) {
220 * Caller's buffer is too small, can't
221 * give him partial results fail the call
222 * but return the buffer size needed
225 return_buffer
->length
= buffer_space_needed
;
226 status
= AE_BUFFER_OVERFLOW
;
231 * We have enough space for the object, build it
233 status
= acpi_cm_copy_iobject_to_eobject (return_obj
,
235 return_buffer
->length
= buffer_space_needed
;
243 /* Delete the return and parameter objects */
247 * Delete the internal return object. (Or at least
248 * decrement the reference count by one)
250 acpi_cm_remove_reference (return_obj
);
254 * Free the input parameter list (if we created one),
258 /* Free the allocated parameter block */
260 acpi_cm_delete_internal_object_list (param_ptr
);
267 /*******************************************************************************
269 * FUNCTION: Acpi_get_next_object
271 * PARAMETERS: Type - Type of object to be searched for
272 * Parent - Parent object whose children we are getting
273 * Last_child - Previous child that was found.
274 * The NEXT child will be returned
275 * Ret_handle - Where handle to the next object is placed
279 * DESCRIPTION: Return the next peer object within the namespace. If Handle is
280 * valid, Scope is ignored. Otherwise, the first object within
283 ******************************************************************************/
286 acpi_get_next_object (
287 ACPI_OBJECT_TYPE type
,
290 ACPI_HANDLE
*ret_handle
)
292 ACPI_STATUS status
= AE_OK
;
293 ACPI_NAMESPACE_NODE
*node
;
294 ACPI_NAMESPACE_NODE
*parent_node
= NULL
;
295 ACPI_NAMESPACE_NODE
*child_node
= NULL
;
298 /* Parameter validation */
300 if (type
> ACPI_TYPE_MAX
) {
301 return (AE_BAD_PARAMETER
);
304 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
306 /* If null handle, use the parent */
309 /* Start search at the beginning of the specified scope */
311 parent_node
= acpi_ns_convert_handle_to_entry (parent
);
313 status
= AE_BAD_PARAMETER
;
314 goto unlock_and_exit
;
318 /* Non-null handle, ignore the parent */
321 /* Convert and validate the handle */
323 child_node
= acpi_ns_convert_handle_to_entry (child
);
325 status
= AE_BAD_PARAMETER
;
326 goto unlock_and_exit
;
331 /* Internal function does the real work */
333 node
= acpi_ns_get_next_object ((OBJECT_TYPE_INTERNAL
) type
,
334 parent_node
, child_node
);
336 status
= AE_NOT_FOUND
;
337 goto unlock_and_exit
;
341 *ret_handle
= acpi_ns_convert_entry_to_handle (node
);
347 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
352 /*******************************************************************************
354 * FUNCTION: Acpi_get_type
356 * PARAMETERS: Handle - Handle of object whose type is desired
357 * *Ret_type - Where the type will be placed
361 * DESCRIPTION: This routine returns the type associatd with a particular handle
363 ******************************************************************************/
368 ACPI_OBJECT_TYPE
*ret_type
)
370 ACPI_NAMESPACE_NODE
*node
;
373 /* Parameter Validation */
376 return (AE_BAD_PARAMETER
);
380 * Special case for the predefined Root Node
383 if (handle
== ACPI_ROOT_OBJECT
) {
384 *ret_type
= ACPI_TYPE_ANY
;
388 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
390 /* Convert and validate the handle */
392 node
= acpi_ns_convert_handle_to_entry (handle
);
394 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
395 return (AE_BAD_PARAMETER
);
398 *ret_type
= node
->type
;
401 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
406 /*******************************************************************************
408 * FUNCTION: Acpi_get_parent
410 * PARAMETERS: Handle - Handle of object whose parent is desired
411 * Ret_handle - Where the parent handle will be placed
415 * DESCRIPTION: Returns a handle to the parent of the object represented by
418 ******************************************************************************/
423 ACPI_HANDLE
*ret_handle
)
425 ACPI_NAMESPACE_NODE
*node
;
426 ACPI_STATUS status
= AE_OK
;
429 /* No trace macro, too verbose */
433 return (AE_BAD_PARAMETER
);
436 /* Special case for the predefined Root Node (no parent) */
438 if (handle
== ACPI_ROOT_OBJECT
) {
439 return (AE_NULL_ENTRY
);
443 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
445 /* Convert and validate the handle */
447 node
= acpi_ns_convert_handle_to_entry (handle
);
449 status
= AE_BAD_PARAMETER
;
450 goto unlock_and_exit
;
454 /* Get the parent entry */
457 acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_object (node
));
459 /* Return exeption if parent is null */
461 if (!acpi_ns_get_parent_object (node
)) {
462 status
= AE_NULL_ENTRY
;
468 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
473 /*******************************************************************************
475 * FUNCTION: Acpi_walk_namespace
477 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
478 * Start_object - Handle in namespace where search begins
479 * Max_depth - Depth to which search is to reach
480 * User_function - Called when an object of "Type" is found
481 * Context - Passed to user function
482 * Return_value - Location where return value of
483 * User_function is put if terminated early
485 * RETURNS Return value from the User_function if terminated early.
486 * Otherwise, returns NULL.
488 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
489 * starting (and ending) at the object specified by Start_handle.
490 * The User_function is called whenever an object that matches
491 * the type parameter is found. If the user function returns
492 * a non-zero value, the search is terminated immediately and this
493 * value is returned to the caller.
495 * The point of this procedure is to provide a generic namespace
496 * walk routine that can be called from multiple places to
497 * provide multiple services; the User Function can be tailored
498 * to each task, whether it is a print function, a compare
501 ******************************************************************************/
504 acpi_walk_namespace (
505 ACPI_OBJECT_TYPE type
,
506 ACPI_HANDLE start_object
,
508 WALK_CALLBACK user_function
,
515 /* Parameter validation */
517 if ((type
> ACPI_TYPE_MAX
) ||
520 return (AE_BAD_PARAMETER
);
524 * Lock the namespace around the walk.
525 * The namespace will be unlocked/locked around each call
526 * to the user function - since this function
527 * must be allowed to make Acpi calls itself.
530 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
531 status
= acpi_ns_walk_namespace ((OBJECT_TYPE_INTERNAL
) type
,
532 start_object
, max_depth
,
534 user_function
, context
,
537 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
543 /*******************************************************************************
545 * FUNCTION: Acpi_ns_get_device_callback
547 * PARAMETERS: Callback from Acpi_get_device
551 * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non-
552 * present devices, or if they specified a HID, it filters based
555 ******************************************************************************/
558 acpi_ns_get_device_callback (
559 ACPI_HANDLE obj_handle
,
565 ACPI_NAMESPACE_NODE
*node
;
568 ACPI_GET_DEVICES_INFO
*info
;
573 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
575 node
= acpi_ns_convert_handle_to_entry (obj_handle
);
577 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);
580 return (AE_BAD_PARAMETER
);
584 * Run _STA to determine if device is present
587 status
= acpi_cm_execute_STA (node
, &flags
);
588 if (ACPI_FAILURE (status
)) {
592 if (!(flags
& 0x01)) {
593 /* don't return at the device or children of the device if not there */
595 return (AE_CTRL_DEPTH
);
599 * Filter based on device HID
601 if (info
->hid
!= NULL
) {
602 status
= acpi_cm_execute_HID (node
, &device_id
);
604 if (status
== AE_NOT_FOUND
) {
608 else if (ACPI_FAILURE (status
)) {
612 if (STRNCMP (device_id
.buffer
, info
->hid
, sizeof (device_id
.buffer
)) != 0) {
617 info
->user_function (obj_handle
, nesting_level
, info
->context
, return_value
);
623 /*******************************************************************************
625 * FUNCTION: Acpi_get_devices
627 * PARAMETERS: HID - HID to search for. Can be NULL.
628 * User_function - Called when a matching object is found
629 * Context - Passed to user function
630 * Return_value - Location where return value of
631 * User_function is put if terminated early
633 * RETURNS Return value from the User_function if terminated early.
634 * Otherwise, returns NULL.
636 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
637 * starting (and ending) at the object specified by Start_handle.
638 * The User_function is called whenever an object that matches
639 * the type parameter is found. If the user function returns
640 * a non-zero value, the search is terminated immediately and this
641 * value is returned to the caller.
643 * This is a wrapper for Walk_namespace, but the callback performs
644 * additional filtering. Please see Acpi_get_device_callback.
646 ******************************************************************************/
651 WALK_CALLBACK user_function
,
656 ACPI_GET_DEVICES_INFO info
;
659 /* Parameter validation */
661 if (!user_function
) {
662 return (AE_BAD_PARAMETER
);
666 * We're going to call their callback from OUR callback, so we need
667 * to know what it is, and their context parameter.
669 info
.context
= context
;
670 info
.user_function
= user_function
;
674 * Lock the namespace around the walk.
675 * The namespace will be unlocked/locked around each call
676 * to the user function - since this function
677 * must be allowed to make Acpi calls itself.
680 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE
);
681 status
= acpi_ns_walk_namespace (ACPI_TYPE_DEVICE
,
682 ACPI_ROOT_OBJECT
, ACPI_UINT32_MAX
,
684 acpi_ns_get_device_callback
, &info
,
687 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE
);