Merge with 2.4.0-test3-pre4.
[linux-2.6/linux-mips.git] / drivers / acpi / namespace / nsxfobj.c
blob09c5e4e3ddc770d5c44f375edcf64ce54e3d23c5
2 /******************************************************************************
4 * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
5 * ACPI Object oriented interfaces
7 *****************************************************************************/
9 /*
10 * Copyright (C) 2000 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
28 #include "acpi.h"
29 #include "interp.h"
30 #include "namesp.h"
33 #define _COMPONENT NAMESPACE
34 MODULE_NAME ("nsxfobj");
37 /****************************************************************************
39 * FUNCTION: Acpi_evaluate_object
41 * PARAMETERS: Handle - Object handle (optional)
42 * *Pathname - Object pathname (optional)
43 * **Params - List of parameters to pass to
44 * method, terminated by NULL.
45 * Params itself may be NULL
46 * if no parameters are being
47 * passed.
48 * *Return_object - Where to put method's return value (if
49 * any). If NULL, no value is returned.
51 * RETURN: Status
53 * DESCRIPTION: Find and evaluate the given object, passing the given
54 * parameters if necessary. One of "Handle" or "Pathname" must
55 * be valid (non-null)
57 ****************************************************************************/
59 ACPI_STATUS
60 acpi_evaluate_object (
61 ACPI_HANDLE handle,
62 ACPI_STRING pathname,
63 ACPI_OBJECT_LIST *param_objects,
64 ACPI_BUFFER *return_buffer)
66 ACPI_STATUS status;
67 ACPI_OBJECT_INTERNAL **param_ptr = NULL;
68 ACPI_OBJECT_INTERNAL *return_obj = NULL;
69 ACPI_OBJECT_INTERNAL *object_ptr = NULL;
70 u32 buffer_space_needed;
71 u32 user_buffer_length;
72 u32 count;
73 u32 i;
74 u32 param_length;
75 u32 object_length;
79 * If there are parameters to be passed to the object
80 * (which must be a control method), the external objects
81 * must be converted to internal objects
84 if (param_objects && param_objects->count) {
86 * Allocate a new parameter block for the internal objects
87 * Add 1 to count to allow for null terminated internal list
88 * TBD: [Restructure] merge into single allocation!
91 count = param_objects->count;
92 param_length = (count + 1) * sizeof (void *);
93 object_length = count * sizeof (ACPI_OBJECT_INTERNAL);
95 param_ptr = acpi_cm_callocate (param_length + /* Parameter List part */
96 object_length); /* Actual objects */
97 if (!param_ptr) {
98 return (AE_NO_MEMORY);
101 object_ptr = (ACPI_OBJECT_INTERNAL *) ((u8 *) param_ptr +
102 param_length);
105 * Init the param array of pointers and NULL terminate
106 * the list
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
117 * internal object
119 for (i = 0; i < count; i++) {
120 status =
121 acpi_cm_build_internal_object (&param_objects->pointer[i],
122 param_ptr[i]);
124 if (ACPI_FAILURE (status)) {
125 acpi_cm_delete_internal_object_list (param_ptr);
126 return (status);
133 * Three major cases:
134 * 1) Fully qualified pathname
135 * 2) No handle, not fully qualified pathname (error)
136 * 3) Valid handle
139 if ((pathname) &&
140 (acpi_ns_valid_root_prefix (pathname[0])))
143 * The path is fully qualified, just evaluate by name
145 status = acpi_ns_evaluate_by_name (pathname, param_ptr, &return_obj);
148 else if (!handle) {
150 * A handle is optional iff a fully qualified pathname
151 * is specified. Since we've already handled fully
152 * qualified names above, this is an error
157 status = AE_BAD_PARAMETER;
160 else {
162 * We get here if we have a handle -- and if we have a
163 * pathname it is relative. The handle will be validated
164 * in the lower procedures
167 if (!pathname) {
169 * The null pathname case means the handle is for
170 * the actual object to be evaluated
172 status = acpi_ns_evaluate_by_handle (handle,
173 param_ptr,
174 &return_obj);
177 else {
179 * Both a Handle and a relative Pathname
181 status = acpi_ns_evaluate_relative (handle, pathname,
182 param_ptr,
183 &return_obj);
189 * If we are expecting a return value, and all went well above,
190 * copy the return value to an external object.
193 if (return_buffer) {
194 user_buffer_length = return_buffer->length;
195 return_buffer->length = 0;
197 if (return_obj) {
198 if (VALID_DESCRIPTOR_TYPE (return_obj,
199 ACPI_DESC_TYPE_NAMED))
202 * If we got an NTE as a return object,
203 * this means the object we are evaluating
204 * has nothing interesting to return (such
205 * as a mutex, etc.) We return an error
206 * because these types are essentially
207 * unsupported by this interface. We
208 * don't check up front because this makes
209 * it easier to add support for various
210 * types at a later date if necessary.
212 status = AE_TYPE;
213 return_obj = NULL; /* No need to delete an NTE */
216 if (ACPI_SUCCESS (status)) {
218 * Find out how large a buffer is needed
219 * to contain the returned object
221 status = acpi_cm_get_object_size (return_obj,
222 &buffer_space_needed);
223 if (ACPI_SUCCESS (status)) {
225 * Check if there is enough room in the
226 * caller's buffer
229 if (user_buffer_length < buffer_space_needed) {
231 * Caller's buffer is too small, can't
232 * give him partial results fail the call
233 * but return the buffer size needed
236 return_buffer->length = buffer_space_needed;
237 status = AE_BUFFER_OVERFLOW;
240 else {
242 * We have enough space for the object, build it
244 status =
245 acpi_cm_build_external_object (return_obj,
246 return_buffer);
247 return_buffer->length = buffer_space_needed;
255 /* Delete the return and parameter objects */
257 if (return_obj) {
259 * Delete the internal return object. (Or at least
260 * decrement the reference count by one)
262 acpi_cm_remove_reference (return_obj);
266 * Free the input parameter list (if we created one),
269 if (param_ptr) {
270 /* Free the allocated parameter block */
272 acpi_cm_delete_internal_object_list (param_ptr);
275 return (status);
279 /****************************************************************************
281 * FUNCTION: Acpi_get_next_object
283 * PARAMETERS: Type - Type of object to be searched for
284 * Parent - Parent object whose children we are getting
285 * Last_child - Previous child that was found.
286 * The NEXT child will be returned
287 * Ret_handle - Where handle to the next object is placed
289 * RETURN: Status
291 * DESCRIPTION: Return the next peer object within the namespace. If Handle is
292 * valid, Scope is ignored. Otherwise, the first object within
293 * Scope is returned.
295 ******************************************************************************/
297 ACPI_STATUS
298 acpi_get_next_object (
299 ACPI_OBJECT_TYPE type,
300 ACPI_HANDLE parent,
301 ACPI_HANDLE child,
302 ACPI_HANDLE *ret_handle)
304 ACPI_STATUS status = AE_OK;
305 ACPI_NAMED_OBJECT *entry;
306 ACPI_NAMED_OBJECT *parent_entry = NULL;
307 ACPI_NAMED_OBJECT *child_entry = NULL;
310 /* Parameter validation */
312 if (type > ACPI_TYPE_MAX) {
313 return AE_BAD_PARAMETER;
316 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
318 /* If null handle, use the parent */
320 if (!child) {
321 /* Start search at the beginning of the specified scope */
323 parent_entry = acpi_ns_convert_handle_to_entry (parent);
324 if (!parent_entry) {
325 status = AE_BAD_PARAMETER;
326 goto unlock_and_exit;
330 /* Non-null handle, ignore the parent */
332 else {
333 /* Convert and validate the handle */
335 child_entry = acpi_ns_convert_handle_to_entry (child);
336 if (!child_entry) {
337 status = AE_BAD_PARAMETER;
338 goto unlock_and_exit;
343 /* Internal function does the real work */
345 entry = acpi_ns_get_next_object ((OBJECT_TYPE_INTERNAL) type,
346 parent_entry, child_entry);
347 if (!entry) {
348 status = AE_NOT_FOUND;
349 goto unlock_and_exit;
352 if (ret_handle) {
353 *ret_handle = acpi_ns_convert_entry_to_handle (entry);
357 unlock_and_exit:
359 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
360 return status;
364 /****************************************************************************
366 * FUNCTION: Acpi_get_type
368 * PARAMETERS: Handle - Handle of object whose type is desired
369 * *Ret_type - Where the type will be placed
371 * RETURN: Status
373 * DESCRIPTION: This routine returns the type associatd with a particular handle
375 ******************************************************************************/
377 ACPI_STATUS
378 acpi_get_type (
379 ACPI_HANDLE handle,
380 ACPI_OBJECT_TYPE *ret_type)
382 ACPI_NAMED_OBJECT *object;
385 /* Parameter Validation */
387 if (!ret_type) {
388 return AE_BAD_PARAMETER;
392 * Special case for the predefined Root Object
393 * (return type ANY)
396 if (handle == ACPI_ROOT_OBJECT) {
397 *ret_type = ACPI_TYPE_ANY;
398 return AE_OK;
401 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
403 /* Convert and validate the handle */
405 object = acpi_ns_convert_handle_to_entry (handle);
406 if (!object) {
407 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
408 return AE_BAD_PARAMETER;
411 *ret_type = object->type;
414 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
415 return AE_OK;
419 /****************************************************************************
421 * FUNCTION: Acpi_get_parent
423 * PARAMETERS: Handle - Handle of object whose parent is desired
424 * Ret_handle - Where the parent handle will be placed
426 * RETURN: Status
428 * DESCRIPTION: Returns a handle to the parent of the object represented by
429 * Handle.
431 ******************************************************************************/
433 ACPI_STATUS
434 acpi_get_parent (
435 ACPI_HANDLE handle,
436 ACPI_HANDLE *ret_handle)
438 ACPI_NAMED_OBJECT *object;
439 ACPI_STATUS status = AE_OK;
442 /* No trace macro, too verbose */
445 if (!ret_handle) {
446 return AE_BAD_PARAMETER;
449 /* Special case for the predefined Root Object (no parent) */
451 if (handle == ACPI_ROOT_OBJECT) {
452 return AE_NULL_ENTRY;
456 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
458 /* Convert and validate the handle */
460 object = acpi_ns_convert_handle_to_entry (handle);
461 if (!object) {
462 status = AE_BAD_PARAMETER;
463 goto unlock_and_exit;
467 /* Get the parent entry */
469 *ret_handle =
470 acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_entry (object));
472 /* Return exeption if parent is null */
474 if (!acpi_ns_get_parent_entry (object)) {
475 status = AE_NULL_ENTRY;
479 unlock_and_exit:
481 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
482 return AE_OK;
486 /******************************************************************************
488 * FUNCTION: Acpi_walk_namespace
490 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
491 * Start_object - Handle in namespace where search begins
492 * Max_depth - Depth to which search is to reach
493 * User_function - Called when an object of "Type" is found
494 * Context - Passed to user function
496 * RETURNS Return value from the User_function if terminated early.
497 * Otherwise, returns NULL.
499 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
500 * starting (and ending) at the object specified by Start_handle.
501 * The User_function is called whenever an object that matches
502 * the type parameter is found. If the user function returns
503 * a non-zero value, the search is terminated immediately and this
504 * value is returned to the caller.
506 * The point of this procedure is to provide a generic namespace
507 * walk routine that can be called from multiple places to
508 * provide multiple services; the User Function can be tailored
509 * to each task, whether it is a print function, a compare
510 * function, etc.
512 ******************************************************************************/
514 ACPI_STATUS
515 acpi_walk_namespace (
516 ACPI_OBJECT_TYPE type,
517 ACPI_HANDLE start_object,
518 u32 max_depth,
519 WALK_CALLBACK user_function,
520 void *context,
521 void **return_value)
523 ACPI_STATUS status;
526 /* Parameter validation */
528 if ((type > ACPI_TYPE_MAX) ||
529 (!max_depth) ||
530 (!user_function))
532 return (AE_BAD_PARAMETER);
536 * Lock the namespace around the walk.
537 * The namespace will be unlocked/locked around each call
538 * to the user function - since this function
539 * must be allowed to make Acpi calls itself.
542 acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
543 status = acpi_ns_walk_namespace ((OBJECT_TYPE_INTERNAL) type,
544 start_object, max_depth,
545 NS_WALK_UNLOCK,
546 user_function, context,
547 return_value);
549 acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
551 return (status);