- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / acpi / dispatcher / dsmthdat.c
blobe6913fabf4345a0659d04e58c8bcea20687e53fe
1 /*******************************************************************************
3 * Module Name: dsmthdat - control method arguments and local variables
4 * $Revision: 36 $
6 ******************************************************************************/
8 /*
9 * Copyright (C) 2000 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "acpi.h"
28 #include "acparser.h"
29 #include "acdispat.h"
30 #include "acinterp.h"
31 #include "amlcode.h"
32 #include "acnamesp.h"
35 #define _COMPONENT DISPATCHER
36 MODULE_NAME ("dsmthdat")
39 /*******************************************************************************
41 * FUNCTION: Acpi_ds_method_data_init
43 * PARAMETERS: *Obj_desc
45 * RETURN: Status
47 * DESCRIPTION: Initialize the data structures that hold the method's arguments
48 * and locals. The data struct is an array of NTEs for each.
49 * This allows Ref_of and De_ref_of to work properly for these
50 * special data types.
52 ******************************************************************************/
54 ACPI_STATUS
55 acpi_ds_method_data_init (
56 ACPI_WALK_STATE *walk_state)
58 u32 i;
62 * Walk_state fields are initialized to zero by the
63 * Acpi_cm_callocate().
65 * An Node is assigned to each argument and local so
66 * that Ref_of() can return a pointer to the Node.
69 /* Init the method arguments */
71 for (i = 0; i < MTH_NUM_ARGS; i++) {
72 MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name,
73 NAMEOF_ARG_NTE);
74 walk_state->arguments[i].name |= (i << 24);
75 walk_state->arguments[i].data_type = ACPI_DESC_TYPE_NAMED;
76 walk_state->arguments[i].type = ACPI_TYPE_ANY;
77 walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
80 /* Init the method locals */
82 for (i = 0; i < MTH_NUM_LOCALS; i++) {
83 MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name,
84 NAMEOF_LOCAL_NTE);
86 walk_state->local_variables[i].name |= (i << 24);
87 walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED;
88 walk_state->local_variables[i].type = ACPI_TYPE_ANY;
89 walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
92 return (AE_OK);
96 /*******************************************************************************
98 * FUNCTION: Acpi_ds_method_data_delete_all
100 * PARAMETERS: None
102 * RETURN: Status
104 * DESCRIPTION: Delete method locals and arguments. Arguments are only
105 * deleted if this method was called from another method.
107 ******************************************************************************/
109 ACPI_STATUS
110 acpi_ds_method_data_delete_all (
111 ACPI_WALK_STATE *walk_state)
113 u32 index;
114 ACPI_OPERAND_OBJECT *object;
117 /* Delete the locals */
119 for (index = 0; index < MTH_NUM_LOCALS; index++) {
120 object = walk_state->local_variables[index].object;
121 if (object) {
122 /* Remove first */
124 walk_state->local_variables[index].object = NULL;
126 /* Was given a ref when stored */
128 acpi_cm_remove_reference (object);
133 /* Delete the arguments */
135 for (index = 0; index < MTH_NUM_ARGS; index++) {
136 object = walk_state->arguments[index].object;
137 if (object) {
138 /* Remove first */
140 walk_state->arguments[index].object = NULL;
142 /* Was given a ref when stored */
144 acpi_cm_remove_reference (object);
148 return (AE_OK);
152 /*******************************************************************************
154 * FUNCTION: Acpi_ds_method_data_init_args
156 * PARAMETERS: None
158 * RETURN: Status
160 * DESCRIPTION: Initialize arguments for a method
162 ******************************************************************************/
164 ACPI_STATUS
165 acpi_ds_method_data_init_args (
166 ACPI_OPERAND_OBJECT **params,
167 u32 max_param_count,
168 ACPI_WALK_STATE *walk_state)
170 ACPI_STATUS status;
171 u32 mindex;
172 u32 pindex;
175 if (!params) {
176 return (AE_OK);
179 /* Copy passed parameters into the new method stack frame */
181 for (pindex = mindex = 0;
182 (mindex < MTH_NUM_ARGS) && (pindex < max_param_count);
183 mindex++)
185 if (params[pindex]) {
187 * A valid parameter.
188 * Set the current method argument to the
189 * Params[Pindex++] argument object descriptor
191 status = acpi_ds_method_data_set_value (MTH_TYPE_ARG, mindex,
192 params[pindex], walk_state);
193 if (ACPI_FAILURE (status)) {
194 break;
197 pindex++;
200 else {
201 break;
205 return (AE_OK);
209 /*******************************************************************************
211 * FUNCTION: Acpi_ds_method_data_get_entry
213 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
214 * Index - Which local_var or argument to get
215 * Entry - Pointer to where a pointer to the stack
216 * entry is returned.
218 * RETURN: Status
220 * DESCRIPTION: Get the address of the stack entry given by Type:Index
222 ******************************************************************************/
224 ACPI_STATUS
225 acpi_ds_method_data_get_entry (
226 u32 type,
227 u32 index,
228 ACPI_WALK_STATE *walk_state,
229 ACPI_OPERAND_OBJECT ***entry)
234 * Get the requested object.
235 * The stack "Type" is either a Local_variable or an Argument
238 switch (type)
241 case MTH_TYPE_LOCAL:
243 if (index > MTH_MAX_LOCAL) {
244 return (AE_BAD_PARAMETER);
247 *entry =
248 (ACPI_OPERAND_OBJECT **) &walk_state->local_variables[index].object;
249 break;
252 case MTH_TYPE_ARG:
254 if (index > MTH_MAX_ARG) {
255 return (AE_BAD_PARAMETER);
258 *entry =
259 (ACPI_OPERAND_OBJECT **) &walk_state->arguments[index].object;
260 break;
263 default:
264 return (AE_BAD_PARAMETER);
268 return (AE_OK);
272 /*******************************************************************************
274 * FUNCTION: Acpi_ds_method_data_set_entry
276 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
277 * Index - Which local_var or argument to get
278 * Object - Object to be inserted into the stack entry
280 * RETURN: Status
282 * DESCRIPTION: Insert an object onto the method stack at entry Type:Index.
284 ******************************************************************************/
286 ACPI_STATUS
287 acpi_ds_method_data_set_entry (
288 u32 type,
289 u32 index,
290 ACPI_OPERAND_OBJECT *object,
291 ACPI_WALK_STATE *walk_state)
293 ACPI_STATUS status;
294 ACPI_OPERAND_OBJECT **entry;
297 /* Get a pointer to the stack entry to set */
299 status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
300 if (ACPI_FAILURE (status)) {
301 return (status);
304 /* Increment ref count so object can't be deleted while installed */
306 acpi_cm_add_reference (object);
308 /* Install the object into the stack entry */
310 *entry = object;
312 return (AE_OK);
316 /*******************************************************************************
318 * FUNCTION: Acpi_ds_method_data_get_type
320 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
321 * Index - Which local_var or argument whose type
322 * to get
324 * RETURN: Data type of selected Arg or Local
325 * Used only in Exec_monadic2()/Type_op.
327 ******************************************************************************/
329 OBJECT_TYPE_INTERNAL
330 acpi_ds_method_data_get_type (
331 u32 type,
332 u32 index,
333 ACPI_WALK_STATE *walk_state)
335 ACPI_STATUS status;
336 ACPI_OPERAND_OBJECT **entry;
337 ACPI_OPERAND_OBJECT *object;
340 /* Get a pointer to the requested stack entry */
342 status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
343 if (ACPI_FAILURE (status)) {
344 return ((ACPI_TYPE_NOT_FOUND));
347 /* Get the object from the method stack */
349 object = *entry;
351 /* Get the object type */
353 if (!object) {
354 /* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */
355 return (ACPI_TYPE_ANY);
358 return (object->common.type);
362 /*******************************************************************************
364 * FUNCTION: Acpi_ds_method_data_get_nte
366 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
367 * Index - Which local_var or argument whose type
368 * to get
370 * RETURN: Get the Node associated with a local or arg.
372 ******************************************************************************/
374 ACPI_NAMESPACE_NODE *
375 acpi_ds_method_data_get_nte (
376 u32 type,
377 u32 index,
378 ACPI_WALK_STATE *walk_state)
380 ACPI_NAMESPACE_NODE *node = NULL;
383 switch (type)
386 case MTH_TYPE_LOCAL:
388 if (index > MTH_MAX_LOCAL) {
389 return (node);
392 node = &walk_state->local_variables[index];
393 break;
396 case MTH_TYPE_ARG:
398 if (index > MTH_MAX_ARG) {
399 return (node);
402 node = &walk_state->arguments[index];
403 break;
406 default:
407 break;
411 return (node);
415 /*******************************************************************************
417 * FUNCTION: Acpi_ds_method_data_get_value
419 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
420 * Index - Which local_var or argument to get
421 * *Dest_desc - Descriptor into which selected Arg
422 * or Local value should be copied
424 * RETURN: Status
426 * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
427 * at the current top of the method stack.
428 * Used only in Acpi_aml_resolve_to_value().
430 ******************************************************************************/
432 ACPI_STATUS
433 acpi_ds_method_data_get_value (
434 u32 type,
435 u32 index,
436 ACPI_WALK_STATE *walk_state,
437 ACPI_OPERAND_OBJECT **dest_desc)
439 ACPI_STATUS status;
440 ACPI_OPERAND_OBJECT **entry;
441 ACPI_OPERAND_OBJECT *object;
444 /* Validate the object descriptor */
446 if (!dest_desc) {
447 return (AE_BAD_PARAMETER);
451 /* Get a pointer to the requested method stack entry */
453 status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
454 if (ACPI_FAILURE (status)) {
455 return (status);
458 /* Get the object from the method stack */
460 object = *entry;
463 /* Examine the returned object, it must be valid. */
465 if (!object) {
467 * Index points to uninitialized object stack value.
468 * This means that either 1) The expected argument was
469 * not passed to the method, or 2) A local variable
470 * was referenced by the method (via the ASL)
471 * before it was initialized. Either case is an error.
474 switch (type)
476 case MTH_TYPE_ARG:
477 return (AE_AML_UNINITIALIZED_ARG);
478 break;
480 case MTH_TYPE_LOCAL:
481 return (AE_AML_UNINITIALIZED_LOCAL);
482 break;
488 * Index points to initialized and valid object stack value.
489 * Return an additional reference to the object
492 *dest_desc = object;
493 acpi_cm_add_reference (object);
495 return (AE_OK);
499 /*******************************************************************************
501 * FUNCTION: Acpi_ds_method_data_delete_value
503 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
504 * Index - Which local_var or argument to delete
506 * RETURN: Status
508 * DESCRIPTION: Delete the entry at Type:Index on the method stack. Inserts
509 * a null into the stack slot after the object is deleted.
511 ******************************************************************************/
513 ACPI_STATUS
514 acpi_ds_method_data_delete_value (
515 u32 type,
516 u32 index,
517 ACPI_WALK_STATE *walk_state)
519 ACPI_STATUS status;
520 ACPI_OPERAND_OBJECT **entry;
521 ACPI_OPERAND_OBJECT *object;
524 /* Get a pointer to the requested entry */
526 status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
527 if (ACPI_FAILURE (status)) {
528 return (status);
531 /* Get the current entry in this slot k */
533 object = *entry;
536 * Undefine the Arg or Local by setting its descriptor
537 * pointer to NULL. Locals/Args can contain both
538 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
540 *entry = NULL;
543 if ((object) &&
544 (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)))
547 * There is a valid object in this slot
548 * Decrement the reference count by one to balance the
549 * increment when the object was stored in the slot.
552 acpi_cm_remove_reference (object);
556 return (AE_OK);
560 /*******************************************************************************
562 * FUNCTION: Acpi_ds_method_data_set_value
564 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
565 * Index - Which local_var or argument to set
566 * *Src_desc - Value to be stored
567 * *Dest_desc - Descriptor into which *Src_desc
568 * can be copied, or NULL if one must
569 * be allocated for the purpose. If
570 * provided, this descriptor will be
571 * used for the new value.
573 * RETURN: Status
575 * DESCRIPTION: Store a value in an Arg or Local. The Src_desc is installed
576 * as the new value for the Arg or Local and the reference count
577 * is incremented.
579 ******************************************************************************/
581 ACPI_STATUS
582 acpi_ds_method_data_set_value (
583 u32 type,
584 u32 index,
585 ACPI_OPERAND_OBJECT *src_desc,
586 ACPI_WALK_STATE *walk_state)
588 ACPI_STATUS status;
589 ACPI_OPERAND_OBJECT **entry;
592 /* Parameter validation */
594 if (!src_desc) {
595 return (AE_BAD_PARAMETER);
599 /* Get a pointer to the requested method stack entry */
601 status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
602 if (ACPI_FAILURE (status)) {
603 goto cleanup;
606 if (*entry == src_desc) {
607 goto cleanup;
612 * If there is an object already in this slot, we either
613 * have to delete it, or if this is an argument and there
614 * is an object reference stored there, we have to do
615 * an indirect store!
618 if (*entry) {
620 * Check for an indirect store if an argument
621 * contains an object reference (stored as an Node).
622 * We don't allow this automatic dereferencing for
623 * locals, since a store to a local should overwrite
624 * anything there, including an object reference.
626 * If both Arg0 and Local0 contain Ref_of (Local4):
628 * Store (1, Arg0) - Causes indirect store to local4
629 * Store (1, Local0) - Stores 1 in local0, overwriting
630 * the reference to local4
631 * Store (1, De_refof (Local0)) - Causes indirect store to local4
633 * Weird, but true.
636 if ((type == MTH_TYPE_ARG) &&
637 (VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED)))
639 /* Detach an existing object from the Node */
641 acpi_ns_detach_object ((ACPI_NAMESPACE_NODE *) *entry);
644 * Store this object into the Node
645 * (do the indirect store)
648 status = acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) *entry, src_desc,
649 src_desc->common.type);
650 return (status);
655 * Otherwise, just delete the existing object
656 * before storing the new one
659 acpi_ds_method_data_delete_value (type, index, walk_state);
664 * Install the Obj_stack descriptor (*Src_desc) into
665 * the descriptor for the Arg or Local.
666 * Install the new object in the stack entry
667 * (increments the object reference count by one)
670 status = acpi_ds_method_data_set_entry (type, index, src_desc, walk_state);
671 if (ACPI_FAILURE (status)) {
672 goto cleanup;
675 /* Normal exit */
677 return (AE_OK);
680 /* Error exit */
682 cleanup:
684 return (status);