11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: exstore - AML Interpreter object store support
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
877848130e53b06c22fe37a7b6acbb82bb3e9bfbaBob Moore * Copyright (C) 2000 - 2012, Intel Corp.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met:
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    notice, this list of conditions, and the following disclaimer,
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    without modification.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    substantially similar to the "NO WARRANTY" disclaimer below
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ("Disclaimer") and any redistribution must be conditioned upon
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    including a substantially similar Disclaimer requirement for further
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    binary redistribution.
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    of any contributors may be used to endorse or promote products derived
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    from this software without specific prior written permission.
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation.
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES.
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h>
45e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "accommon.h"
46e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acdispat.h"
47e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acinterp.h"
48e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "amlcode.h"
49e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acnamesp.h"
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT          ACPI_EXECUTER
524be44fcd3bf648b782f4460fd06dfae6c42ded4bLen BrownACPI_MODULE_NAME("exstore")
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore/* Local prototypes */
5544f6c01242da4e162f28d8e1216a8c7a91174605Robert Moorestatic acpi_status
564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			      union acpi_operand_object *dest_desc,
584be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			      struct acpi_walk_state *walk_state);
5944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore
6044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore/*******************************************************************************
6144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ex_store
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  *source_desc        - Value to be stored
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              *dest_desc          - Where to store it.  Must be an NS node
660211a9c8508b2183e0e539509aad60414f1c3813Frederik Schwarzer *                                    or a union acpi_operand_object of type
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    Reference;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              walk_state          - Current walk state
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Store the value described by source_desc into the location
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              described by dest_desc. Called by various interpreter
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              functions to store the result of an operation into
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              the destination operand -- not just simply the actual "Store"
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              ASL operator.
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
814be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ex_store(union acpi_operand_object *source_desc,
824be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	      union acpi_operand_object *dest_desc,
834be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	      struct acpi_walk_state *walk_state)
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
854be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status = AE_OK;
864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *ref_desc = dest_desc;
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
88b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Validate parameters */
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!source_desc || !dest_desc) {
93b8e4d89357fc434618a59c1047cac72641191805Bob Moore		ACPI_ERROR((AE_INFO, "Null parameter"));
944be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_AML_NO_OPERAND);
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* dest_desc can be either a namespace node or an ACPI object */
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
994be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Dest is a namespace node,
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Storing an object into a Named node.
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1044be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status = acpi_ex_store_object_to_node(source_desc,
1054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						      (struct
1064be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						       acpi_namespace_node *)
1074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						      dest_desc, walk_state,
1084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						      ACPI_IMPLICIT_CONVERSION);
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(status);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Destination object must be a Reference or a Constant object */
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1153371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore	switch (dest_desc->common.type) {
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_LOCAL_REFERENCE:
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_INTEGER:
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Allow stores to Constants -- a Noop as per ACPI spec */
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
1244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			return_ACPI_STATUS(AE_OK);
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*lint -fallthrough */
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Destination is not a Reference object */
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
133b8e4d89357fc434618a59c1047cac72641191805Bob Moore		ACPI_ERROR((AE_INFO,
134b8e4d89357fc434618a59c1047cac72641191805Bob Moore			    "Target is not a Reference or Constant object - %s [%p]",
135b8e4d89357fc434618a59c1047cac72641191805Bob Moore			    acpi_ut_get_object_type_name(dest_desc),
136b8e4d89357fc434618a59c1047cac72641191805Bob Moore			    dest_desc));
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1384be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1421044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	 * Examine the Reference class. These cases are handled:
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 1) Store to Name (Change the object associated with a name)
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 2) Store to an indexed area of a Buffer or Package
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 3) Store to a Method Local or Arg
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 4) Store to the debug object
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1491044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	switch (ref_desc->reference.class) {
1501044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_REFOF:
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Storing an object into a Name "container" */
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status = acpi_ex_store_object_to_node(source_desc,
1554be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						      ref_desc->reference.
1564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						      object, walk_state,
1574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						      ACPI_IMPLICIT_CONVERSION);
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1601044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_INDEX:
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Storing to an Index (pointer into a packager or buffer) */
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1644be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status =
1654be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ex_store_object_to_index(source_desc, ref_desc,
1664be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						  walk_state);
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1691044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_LOCAL:
1701044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_ARG:
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Store to a method local/arg  */
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status =
1751044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore		    acpi_ds_store_object_to_local(ref_desc->reference.class,
1761044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore						  ref_desc->reference.value,
1774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						  source_desc, walk_state);
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1801044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore	case ACPI_REFCLASS_DEBUG:
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Storing to the Debug object causes the value stored to be
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * displayed and otherwise has no effect -- see ACPI Specification
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
1874be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  "**** Write to Debug Object: Object %p %s ****:\n\n",
1884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  source_desc,
1894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  acpi_ut_get_object_type_name(source_desc)));
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1914cdf1a562bfb5852954aadbe8515557b8acc8168Lin Ming		ACPI_DEBUG_OBJECT(source_desc, 0, 0);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
196f6a22b0bc417042e83117f52ab1a03696af185abBob Moore		ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
1971044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore			    ref_desc->reference.class));
19823d3e055beb12db2a3b91dfeee474c4d5ecc13b9Bob Moore		ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_AML_INTERNAL;
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2044be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ex_store_object_to_index
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  *source_desc            - Value to be stored
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              *dest_desc              - Named object to receive the value
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              walk_state              - Current walk state
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Store the object to indexed Buffer or Package element
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moorestatic acpi_status
2224be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
2234be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			      union acpi_operand_object *index_desc,
2244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			      struct acpi_walk_state *walk_state)
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2264be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status = AE_OK;
2274be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *obj_desc;
2284be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *new_desc;
2294be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u8 value = 0;
2304be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u32 i;
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
232b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ex_store_object_to_index);
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Destination must be a reference pointer, and
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * must point to either a buffer or a package
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (index_desc->reference.target_type) {
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_PACKAGE:
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Storing to a package element. Copy the object and replace
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * any existing object with the new object. No implicit
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * conversion is performed.
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The object at *(index_desc->Reference.Where) is the
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * element within the package that is to be modified.
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The parent package object is at index_desc->Reference.Object
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		obj_desc = *(index_desc->reference.where);
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2513371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
2523371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore		    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
253bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming
254bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			/* This is a DDBHandle, just add a reference to it */
255bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming
256bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			acpi_ut_add_reference(source_desc);
257bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			new_desc = source_desc;
258bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming		} else {
259bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			/* Normal object, copy it */
260bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming
261bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			status =
262bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			    acpi_ut_copy_iobject_to_iobject(source_desc,
263bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming							    &new_desc,
264bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming							    walk_state);
265bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			if (ACPI_FAILURE(status)) {
266bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				return_ACPI_STATUS(status);
267bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			}
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (obj_desc) {
27152fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Decrement reference count by the ref count of the parent package */
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			for (i = 0; i < ((union acpi_operand_object *)
2754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					 index_desc->reference.object)->common.
2764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     reference_count; i++) {
2774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				acpi_ut_remove_reference(obj_desc);
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*(index_desc->reference.where) = new_desc;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
28344f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		/* Increment ref count by the ref count of the parent package-1 */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2854be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		for (i = 1; i < ((union acpi_operand_object *)
2864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				 index_desc->reference.object)->common.
2874be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		     reference_count; i++) {
2884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			acpi_ut_add_reference(new_desc);
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_BUFFER_FIELD:
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Store into a Buffer or String (not actually a real buffer_field)
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * at a location defined by an Index.
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The first 8-bit element of the source object is written to the
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * 8-bit Buffer location defined by the Index destination object,
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * according to the ACPI 2.0 specification.
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Make sure the target is a Buffer or String. An error should
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * not happen here, since the reference_object was constructed
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * by the INDEX_OP code.
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		obj_desc = index_desc->reference.object;
3103371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore		if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
3113371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore		    (obj_desc->common.type != ACPI_TYPE_STRING)) {
3124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The assignment of the individual elements will be slightly
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * different for each source type.
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
3193371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore		switch (source_desc->common.type) {
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case ACPI_TYPE_INTEGER:
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Use the least-significant byte of the integer */
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			value = (u8) (source_desc->integer.value);
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case ACPI_TYPE_BUFFER:
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case ACPI_TYPE_STRING:
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Note: Takes advantage of common string/buffer fields */
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			value = source_desc->buffer.pointer[0];
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* All other types are invalid */
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
339b8e4d89357fc434618a59c1047cac72641191805Bob Moore			ACPI_ERROR((AE_INFO,
340b8e4d89357fc434618a59c1047cac72641191805Bob Moore				    "Source must be Integer/Buffer/String type, not %s",
341b8e4d89357fc434618a59c1047cac72641191805Bob Moore				    acpi_ut_get_object_type_name(source_desc)));
3424be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Store the source value into the target buffer byte */
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3471044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore		obj_desc->buffer.pointer[index_desc->reference.value] = value;
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
351b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore		ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField"));
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_AML_OPERAND_TYPE;
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ex_store_object_to_node
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  source_desc             - Value to be stored
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Node                    - Named object to receive the value
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              walk_state              - Current walk state
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              implicit_conversion     - Perform implicit conversion (yes/no)
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Store the object to the named object.
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              The Assignment of an object to a named object is handled here
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              The value passed in will replace the current value (if any)
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              with the input value.
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              When storing into an object the data is converted to the
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              target object type then stored in the object.  This means
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              that the target object type (for an initialized target) will
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              not be changed by a store operation.
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Assumes parameters are already validated.
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
3864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
3874be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     struct acpi_namespace_node *node,
3884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     struct acpi_walk_state *walk_state,
3894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			     u8 implicit_conversion)
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status = AE_OK;
3924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *target_desc;
3934be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *new_desc;
3944be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_object_type target_type;
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
396b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
39844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore	/* Get current type of the node, and object attached to Node */
39944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore
4004be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	target_type = acpi_ns_get_type(node);
4014be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	target_desc = acpi_ns_get_attached_object(node);
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
4044be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  source_desc,
4054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  acpi_ut_get_object_type_name(source_desc), node,
4064be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  acpi_ut_get_type_name(target_type)));
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Resolve the source object to an actual value
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * (If it is a reference object)
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
4134be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	if (ACPI_FAILURE(status)) {
4144be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_ACPI_STATUS(status);
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If no implicit conversion, drop into the default case below */
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
419a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming	if ((!implicit_conversion) ||
420a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming	    ((walk_state->opcode == AML_COPY_OP) &&
421a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming	     (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) &&
422a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming	     (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) &&
423a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming	     (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) {
424a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming		/*
425a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming		 * Force execution of default (no implicit conversion). Note:
426a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming		 * copy_object does not perform an implicit conversion, as per the ACPI
427a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming		 * spec -- except in case of region/bank/index fields -- because these
428a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming		 * objects must retain their original type permanently.
429a3df4dadd446c0d7195f2bbe86dd5174426d8090Lin Ming		 */
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		target_type = ACPI_TYPE_ANY;
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
43344f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore	/* Do the actual store operation */
43444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (target_type) {
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_BUFFER_FIELD:
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_LOCAL_REGION_FIELD:
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_LOCAL_BANK_FIELD:
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_LOCAL_INDEX_FIELD:
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		/* For fields, copy the source data to the target field. */
44244f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore
4434be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status = acpi_ex_write_data_to_field(source_desc, target_desc,
4444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						     &walk_state->result_obj);
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_INTEGER:
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_STRING:
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ACPI_TYPE_BUFFER:
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * These target types are all of type Integer/String/Buffer, and
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * therefore support implicit conversion before the store.
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Copy and/or convert the source object to a new target object
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
4574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status =
4584be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ex_store_object_to_object(source_desc, target_desc,
4594be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						   &new_desc, walk_state);
4604be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		if (ACPI_FAILURE(status)) {
4614be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			return_ACPI_STATUS(status);
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (new_desc != target_desc) {
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Store the new new_desc as the new value of the Name, and set
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * the Name's type to that of the value being stored in it.
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * source_desc reference count is incremented by attach_object.
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 *
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Note: This may change the type of the node if an explicit store
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * has been performed such that the node/object type has been
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * changed.
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
4744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			status =
4754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    acpi_ns_attach_object(node, new_desc,
4764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						  new_desc->common.type);
4774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown
4784be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
4794be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					  "Store %s into %s via Convert/Attach\n",
4804be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					  acpi_ut_get_object_type_name
4814be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					  (source_desc),
4824be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					  acpi_ut_get_object_type_name
4834be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					  (new_desc)));
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
4904be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
4914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  acpi_ut_get_object_type_name(source_desc),
4924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				  source_desc, node));
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* No conversions for all other types.  Just attach the source object */
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4964be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		status = acpi_ns_attach_object(node, source_desc,
4973371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore					       source_desc->common.type);
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5014be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
503