PageRenderTime 62ms CodeModel.GetById 31ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/acpi/dispatcher/dsmthdat.c

https://bitbucket.org/evzijst/gittest
C | 715 lines | 283 code | 144 blank | 288 comment | 45 complexity | c2905309de96a67d22975a804fb8b76a MD5 | raw file
  1/*******************************************************************************
  2 *
  3 * Module Name: dsmthdat - control method arguments and local variables
  4 *
  5 ******************************************************************************/
  6
  7/*
  8 * Copyright (C) 2000 - 2005, R. Byron Moore
  9 * All rights reserved.
 10 *
 11 * Redistribution and use in source and binary forms, with or without
 12 * modification, are permitted provided that the following conditions
 13 * are met:
 14 * 1. Redistributions of source code must retain the above copyright
 15 *    notice, this list of conditions, and the following disclaimer,
 16 *    without modification.
 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 18 *    substantially similar to the "NO WARRANTY" disclaimer below
 19 *    ("Disclaimer") and any redistribution must be conditioned upon
 20 *    including a substantially similar Disclaimer requirement for further
 21 *    binary redistribution.
 22 * 3. Neither the names of the above-listed copyright holders nor the names
 23 *    of any contributors may be used to endorse or promote products derived
 24 *    from this software without specific prior written permission.
 25 *
 26 * Alternatively, this software may be distributed under the terms of the
 27 * GNU General Public License ("GPL") version 2 as published by the Free
 28 * Software Foundation.
 29 *
 30 * NO WARRANTY
 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 41 * POSSIBILITY OF SUCH DAMAGES.
 42 */
 43
 44
 45#include <acpi/acpi.h>
 46#include <acpi/acdispat.h>
 47#include <acpi/amlcode.h>
 48#include <acpi/acnamesp.h>
 49#include <acpi/acinterp.h>
 50
 51
 52#define _COMPONENT          ACPI_DISPATCHER
 53	 ACPI_MODULE_NAME    ("dsmthdat")
 54
 55
 56/*******************************************************************************
 57 *
 58 * FUNCTION:    acpi_ds_method_data_init
 59 *
 60 * PARAMETERS:  walk_state          - Current walk state object
 61 *
 62 * RETURN:      Status
 63 *
 64 * DESCRIPTION: Initialize the data structures that hold the method's arguments
 65 *              and locals.  The data struct is an array of NTEs for each.
 66 *              This allows ref_of and de_ref_of to work properly for these
 67 *              special data types.
 68 *
 69 * NOTES:       walk_state fields are initialized to zero by the
 70 *              ACPI_MEM_CALLOCATE().
 71 *
 72 *              A pseudo-Namespace Node is assigned to each argument and local
 73 *              so that ref_of() can return a pointer to the Node.
 74 *
 75 ******************************************************************************/
 76
 77void
 78acpi_ds_method_data_init (
 79	struct acpi_walk_state          *walk_state)
 80{
 81	u32                             i;
 82
 83
 84	ACPI_FUNCTION_TRACE ("ds_method_data_init");
 85
 86
 87	/* Init the method arguments */
 88
 89	for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
 90		ACPI_MOVE_32_TO_32 (&walk_state->arguments[i].name,
 91				   NAMEOF_ARG_NTE);
 92		walk_state->arguments[i].name.integer |= (i << 24);
 93		walk_state->arguments[i].descriptor   = ACPI_DESC_TYPE_NAMED;
 94		walk_state->arguments[i].type         = ACPI_TYPE_ANY;
 95		walk_state->arguments[i].flags        = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
 96	}
 97
 98	/* Init the method locals */
 99
100	for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
101		ACPI_MOVE_32_TO_32 (&walk_state->local_variables[i].name,
102				   NAMEOF_LOCAL_NTE);
103
104		walk_state->local_variables[i].name.integer |= (i << 24);
105		walk_state->local_variables[i].descriptor  = ACPI_DESC_TYPE_NAMED;
106		walk_state->local_variables[i].type        = ACPI_TYPE_ANY;
107		walk_state->local_variables[i].flags       = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
108	}
109
110	return_VOID;
111}
112
113
114/*******************************************************************************
115 *
116 * FUNCTION:    acpi_ds_method_data_delete_all
117 *
118 * PARAMETERS:  walk_state          - Current walk state object
119 *
120 * RETURN:      None
121 *
122 * DESCRIPTION: Delete method locals and arguments.  Arguments are only
123 *              deleted if this method was called from another method.
124 *
125 ******************************************************************************/
126
127void
128acpi_ds_method_data_delete_all (
129	struct acpi_walk_state          *walk_state)
130{
131	u32                             index;
132
133
134	ACPI_FUNCTION_TRACE ("ds_method_data_delete_all");
135
136
137	/* Detach the locals */
138
139	for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
140		if (walk_state->local_variables[index].object) {
141			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
142					index, walk_state->local_variables[index].object));
143
144			/* Detach object (if present) and remove a reference */
145
146			acpi_ns_detach_object (&walk_state->local_variables[index]);
147		}
148	}
149
150	/* Detach the arguments */
151
152	for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
153		if (walk_state->arguments[index].object) {
154			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
155					index, walk_state->arguments[index].object));
156
157			/* Detach object (if present) and remove a reference */
158
159			acpi_ns_detach_object (&walk_state->arguments[index]);
160		}
161	}
162
163	return_VOID;
164}
165
166
167/*******************************************************************************
168 *
169 * FUNCTION:    acpi_ds_method_data_init_args
170 *
171 * PARAMETERS:  *Params         - Pointer to a parameter list for the method
172 *              max_param_count - The arg count for this method
173 *              walk_state      - Current walk state object
174 *
175 * RETURN:      Status
176 *
177 * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
178 *              of ACPI operand objects, either null terminated or whose length
179 *              is defined by max_param_count.
180 *
181 ******************************************************************************/
182
183acpi_status
184acpi_ds_method_data_init_args (
185	union acpi_operand_object       **params,
186	u32                             max_param_count,
187	struct acpi_walk_state          *walk_state)
188{
189	acpi_status                     status;
190	u32                             index = 0;
191
192
193	ACPI_FUNCTION_TRACE_PTR ("ds_method_data_init_args", params);
194
195
196	if (!params) {
197		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
198		return_ACPI_STATUS (AE_OK);
199	}
200
201	/* Copy passed parameters into the new method stack frame  */
202
203	while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) {
204		/*
205		 * A valid parameter.
206		 * Store the argument in the method/walk descriptor.
207		 * Do not copy the arg in order to implement call by reference
208		 */
209		status = acpi_ds_method_data_set_value (AML_ARG_OP, index, params[index], walk_state);
210		if (ACPI_FAILURE (status)) {
211			return_ACPI_STATUS (status);
212		}
213
214		index++;
215	}
216
217	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", index));
218	return_ACPI_STATUS (AE_OK);
219}
220
221
222/*******************************************************************************
223 *
224 * FUNCTION:    acpi_ds_method_data_get_node
225 *
226 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
227 *              Index               - which local_var or argument whose type
228 *                                      to get
229 *              walk_state          - Current walk state object
230 *
231 * RETURN:      Get the Node associated with a local or arg.
232 *
233 ******************************************************************************/
234
235acpi_status
236acpi_ds_method_data_get_node (
237	u16                             opcode,
238	u32                             index,
239	struct acpi_walk_state          *walk_state,
240	struct acpi_namespace_node      **node)
241{
242	ACPI_FUNCTION_TRACE ("ds_method_data_get_node");
243
244
245	/*
246	 * Method Locals and Arguments are supported
247	 */
248	switch (opcode) {
249	case AML_LOCAL_OP:
250
251		if (index > ACPI_METHOD_MAX_LOCAL) {
252			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
253				index, ACPI_METHOD_MAX_LOCAL));
254			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
255		}
256
257		/* Return a pointer to the pseudo-node */
258
259		*node = &walk_state->local_variables[index];
260		break;
261
262	case AML_ARG_OP:
263
264		if (index > ACPI_METHOD_MAX_ARG) {
265			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
266				index, ACPI_METHOD_MAX_ARG));
267			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
268		}
269
270		/* Return a pointer to the pseudo-node */
271
272		*node = &walk_state->arguments[index];
273		break;
274
275	default:
276		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
277		return_ACPI_STATUS (AE_AML_BAD_OPCODE);
278	}
279
280	return_ACPI_STATUS (AE_OK);
281}
282
283
284/*******************************************************************************
285 *
286 * FUNCTION:    acpi_ds_method_data_set_value
287 *
288 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
289 *              Index               - which local_var or argument to get
290 *              Object              - Object to be inserted into the stack entry
291 *              walk_state          - Current walk state object
292 *
293 * RETURN:      Status
294 *
295 * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
296 *              Note: There is no "implicit conversion" for locals.
297 *
298 ******************************************************************************/
299
300acpi_status
301acpi_ds_method_data_set_value (
302	u16                             opcode,
303	u32                             index,
304	union acpi_operand_object       *object,
305	struct acpi_walk_state          *walk_state)
306{
307	acpi_status                     status;
308	struct acpi_namespace_node      *node;
309
310
311	ACPI_FUNCTION_TRACE ("ds_method_data_set_value");
312
313
314	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
315		"new_obj %p Opcode %X, Refs=%d [%s]\n", object,
316		opcode, object->common.reference_count,
317		acpi_ut_get_type_name (object->common.type)));
318
319	/* Get the namespace node for the arg/local */
320
321	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
322	if (ACPI_FAILURE (status)) {
323		return_ACPI_STATUS (status);
324	}
325
326	/*
327	 * Increment ref count so object can't be deleted while installed.
328	 * NOTE: We do not copy the object in order to preserve the call by
329	 * reference semantics of ACPI Control Method invocation.
330	 * (See ACPI specification 2.0_c)
331	 */
332	acpi_ut_add_reference (object);
333
334	/* Install the object */
335
336	node->object = object;
337	return_ACPI_STATUS (status);
338}
339
340
341/*******************************************************************************
342 *
343 * FUNCTION:    acpi_ds_method_data_get_type
344 *
345 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
346 *              Index               - which local_var or argument whose type
347 *                                      to get
348 *              walk_state          - Current walk state object
349 *
350 * RETURN:      Data type of current value of the selected Arg or Local
351 *
352 ******************************************************************************/
353#ifdef ACPI_FUTURE_USAGE
354acpi_object_type
355acpi_ds_method_data_get_type (
356	u16                             opcode,
357	u32                             index,
358	struct acpi_walk_state          *walk_state)
359{
360	acpi_status                     status;
361	struct acpi_namespace_node      *node;
362	union acpi_operand_object       *object;
363
364
365	ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
366
367
368	/* Get the namespace node for the arg/local */
369
370	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
371	if (ACPI_FAILURE (status)) {
372		return_VALUE ((ACPI_TYPE_NOT_FOUND));
373	}
374
375	/* Get the object */
376
377	object = acpi_ns_get_attached_object (node);
378	if (!object) {
379		/* Uninitialized local/arg, return TYPE_ANY */
380
381		return_VALUE (ACPI_TYPE_ANY);
382	}
383
384	/* Get the object type */
385
386	return_VALUE (ACPI_GET_OBJECT_TYPE (object));
387}
388#endif  /*  ACPI_FUTURE_USAGE  */
389
390
391/*******************************************************************************
392 *
393 * FUNCTION:    acpi_ds_method_data_get_value
394 *
395 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
396 *              Index               - which local_var or argument to get
397 *              walk_state          - Current walk state object
398 *              *dest_desc          - Ptr to Descriptor into which selected Arg
399 *                                    or Local value should be copied
400 *
401 * RETURN:      Status
402 *
403 * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
404 *              at the current top of the method stack.
405 *              Used only in acpi_ex_resolve_to_value().
406 *
407 ******************************************************************************/
408
409acpi_status
410acpi_ds_method_data_get_value (
411	u16                             opcode,
412	u32                             index,
413	struct acpi_walk_state          *walk_state,
414	union acpi_operand_object       **dest_desc)
415{
416	acpi_status                     status;
417	struct acpi_namespace_node      *node;
418	union acpi_operand_object       *object;
419
420
421	ACPI_FUNCTION_TRACE ("ds_method_data_get_value");
422
423
424	/* Validate the object descriptor */
425
426	if (!dest_desc) {
427		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointer\n"));
428		return_ACPI_STATUS (AE_BAD_PARAMETER);
429	}
430
431	/* Get the namespace node for the arg/local */
432
433	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
434	if (ACPI_FAILURE (status)) {
435		return_ACPI_STATUS (status);
436	}
437
438	/* Get the object from the node */
439
440	object = node->object;
441
442	/* Examine the returned object, it must be valid. */
443
444	if (!object) {
445		/*
446		 * Index points to uninitialized object.
447		 * This means that either 1) The expected argument was
448		 * not passed to the method, or 2) A local variable
449		 * was referenced by the method (via the ASL)
450		 * before it was initialized.  Either case is an error.
451		 */
452
453		/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
454
455		if (acpi_gbl_enable_interpreter_slack) {
456			object = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
457			if (!object) {
458				return_ACPI_STATUS (AE_NO_MEMORY);
459			}
460
461			object->integer.value = 0;
462			node->object = object;
463		}
464
465		/* Otherwise, return the error */
466
467		else switch (opcode) {
468		case AML_ARG_OP:
469
470			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
471				index, node));
472
473			return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
474
475		case AML_LOCAL_OP:
476
477			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at node %p\n",
478				index, node));
479
480			return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
481
482		default:
483			ACPI_REPORT_ERROR (("Not Arg/Local opcode: %X\n", opcode));
484			return_ACPI_STATUS (AE_AML_INTERNAL);
485		}
486	}
487
488	/*
489	 * The Index points to an initialized and valid object.
490	 * Return an additional reference to the object
491	 */
492	*dest_desc = object;
493	acpi_ut_add_reference (object);
494
495	return_ACPI_STATUS (AE_OK);
496}
497
498
499/*******************************************************************************
500 *
501 * FUNCTION:    acpi_ds_method_data_delete_value
502 *
503 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
504 *              Index               - which local_var or argument to delete
505 *              walk_state          - Current walk state object
506 *
507 * RETURN:      None
508 *
509 * DESCRIPTION: Delete the entry at Opcode:Index on the method stack.  Inserts
510 *              a null into the stack slot after the object is deleted.
511 *
512 ******************************************************************************/
513
514void
515acpi_ds_method_data_delete_value (
516	u16                             opcode,
517	u32                             index,
518	struct acpi_walk_state          *walk_state)
519{
520	acpi_status                     status;
521	struct acpi_namespace_node      *node;
522	union acpi_operand_object       *object;
523
524
525	ACPI_FUNCTION_TRACE ("ds_method_data_delete_value");
526
527
528	/* Get the namespace node for the arg/local */
529
530	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
531	if (ACPI_FAILURE (status)) {
532		return_VOID;
533	}
534
535	/* Get the associated object */
536
537	object = acpi_ns_get_attached_object (node);
538
539	/*
540	 * Undefine the Arg or Local by setting its descriptor
541	 * pointer to NULL. Locals/Args can contain both
542	 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
543	 */
544	node->object = NULL;
545
546	if ((object) &&
547		(ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_OPERAND)) {
548		/*
549		 * There is a valid object.
550		 * Decrement the reference count by one to balance the
551		 * increment when the object was stored.
552		 */
553		acpi_ut_remove_reference (object);
554	}
555
556	return_VOID;
557}
558
559
560/*******************************************************************************
561 *
562 * FUNCTION:    acpi_ds_store_object_to_local
563 *
564 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
565 *              Index               - which local_var or argument to set
566 *              obj_desc            - Value to be stored
567 *              walk_state          - Current walk state
568 *
569 * RETURN:      Status
570 *
571 * DESCRIPTION: Store a value in an Arg or Local.  The obj_desc is installed
572 *              as the new value for the Arg or Local and the reference count
573 *              for obj_desc is incremented.
574 *
575 ******************************************************************************/
576
577acpi_status
578acpi_ds_store_object_to_local (
579	u16                             opcode,
580	u32                             index,
581	union acpi_operand_object       *obj_desc,
582	struct acpi_walk_state          *walk_state)
583{
584	acpi_status                     status;
585	struct acpi_namespace_node      *node;
586	union acpi_operand_object       *current_obj_desc;
587	union acpi_operand_object       *new_obj_desc;
588
589
590	ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
591	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
592		opcode, index, obj_desc));
593
594	/* Parameter validation */
595
596	if (!obj_desc) {
597		return_ACPI_STATUS (AE_BAD_PARAMETER);
598	}
599
600	/* Get the namespace node for the arg/local */
601
602	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
603	if (ACPI_FAILURE (status)) {
604		return_ACPI_STATUS (status);
605	}
606
607	current_obj_desc = acpi_ns_get_attached_object (node);
608	if (current_obj_desc == obj_desc) {
609		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
610			obj_desc));
611		return_ACPI_STATUS (status);
612	}
613
614	/*
615	 * If the reference count on the object is more than one, we must
616	 * take a copy of the object before we store.  A reference count
617	 * of exactly 1 means that the object was just created during the
618	 * evaluation of an expression, and we can safely use it since it
619	 * is not used anywhere else.
620	 */
621	new_obj_desc = obj_desc;
622	if (obj_desc->common.reference_count > 1) {
623		status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
624		if (ACPI_FAILURE (status)) {
625			return_ACPI_STATUS (status);
626		}
627	}
628
629	/*
630	 * If there is an object already in this slot, we either
631	 * have to delete it, or if this is an argument and there
632	 * is an object reference stored there, we have to do
633	 * an indirect store!
634	 */
635	if (current_obj_desc) {
636		/*
637		 * Check for an indirect store if an argument
638		 * contains an object reference (stored as an Node).
639		 * We don't allow this automatic dereferencing for
640		 * locals, since a store to a local should overwrite
641		 * anything there, including an object reference.
642		 *
643		 * If both Arg0 and Local0 contain ref_of (Local4):
644		 *
645		 * Store (1, Arg0)             - Causes indirect store to local4
646		 * Store (1, Local0)           - Stores 1 in local0, overwriting
647		 *                                  the reference to local4
648		 * Store (1, de_refof (Local0)) - Causes indirect store to local4
649		 *
650		 * Weird, but true.
651		 */
652		if (opcode == AML_ARG_OP) {
653			/*
654			 * Make sure that the object is the correct type.  This may be overkill, but
655			 * it is here because references were NS nodes in the past.  Now they are
656			 * operand objects of type Reference.
657			 */
658			if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
659				ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
660						acpi_ut_get_descriptor_name (current_obj_desc)));
661				return_ACPI_STATUS (AE_AML_INTERNAL);
662			}
663
664			/*
665			 * If we have a valid reference object that came from ref_of(), do the
666			 * indirect store
667			 */
668			if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
669				(current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
670				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
671						"Arg (%p) is an obj_ref(Node), storing in node %p\n",
672						new_obj_desc, current_obj_desc));
673
674				/*
675				 * Store this object to the Node (perform the indirect store)
676				 * NOTE: No implicit conversion is performed, as per the ACPI
677				 * specification rules on storing to Locals/Args.
678				 */
679				status = acpi_ex_store_object_to_node (new_obj_desc,
680						 current_obj_desc->reference.object, walk_state,
681						 ACPI_NO_IMPLICIT_CONVERSION);
682
683				/* Remove local reference if we copied the object above */
684
685				if (new_obj_desc != obj_desc) {
686					acpi_ut_remove_reference (new_obj_desc);
687				}
688				return_ACPI_STATUS (status);
689			}
690		}
691
692		/*
693		 * Delete the existing object
694		 * before storing the new one
695		 */
696		acpi_ds_method_data_delete_value (opcode, index, walk_state);
697	}
698
699	/*
700	 * Install the Obj descriptor (*new_obj_desc) into
701	 * the descriptor for the Arg or Local.
702	 * (increments the object reference count by one)
703	 */
704	status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
705
706	/* Remove local reference if we copied the object above */
707
708	if (new_obj_desc != obj_desc) {
709		acpi_ut_remove_reference (new_obj_desc);
710	}
711
712	return_ACPI_STATUS (status);
713}
714
715