- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / acpi / interpreter / amstorob.c
blobf3a098bd2585a62d74b862e54f8463f2c4bd812c
2 /******************************************************************************
4 * Module Name: amstorob - AML Interpreter object store support, store to object
5 * $Revision: 18 $
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 "acparser.h"
30 #include "acdispat.h"
31 #include "acinterp.h"
32 #include "amlcode.h"
33 #include "acnamesp.h"
34 #include "actables.h"
37 #define _COMPONENT INTERPRETER
38 MODULE_NAME ("amstorob")
41 /*******************************************************************************
43 * FUNCTION: Acpi_aml_store_object_to_object
45 * PARAMETERS: *Val_desc - Value to be stored
46 * *Dest_desc - Object to receive the value
48 * RETURN: Status
50 * DESCRIPTION: Store an object to another object.
52 * The Assignment of an object to another (not named) object
53 * is handled here.
54 * The val passed in will replace the current value (if any)
55 * with the input value.
57 * When storing into an object the data is converted to the
58 * target object type then stored in the object. This means
59 * that the target object type (for an initialized target) will
60 * not be changed by a store operation.
62 * This module allows destination types of Number, String,
63 * and Buffer.
65 ******************************************************************************/
67 ACPI_STATUS
68 acpi_aml_store_object_to_object (
69 ACPI_OPERAND_OBJECT *val_desc,
70 ACPI_OPERAND_OBJECT *dest_desc,
71 ACPI_WALK_STATE *walk_state)
73 ACPI_STATUS status = AE_OK;
74 u8 *buffer = NULL;
75 u32 length = 0;
76 OBJECT_TYPE_INTERNAL destination_type = dest_desc->common.type;
80 * Assuming the parameters are valid!!!
82 ACPI_ASSERT((dest_desc) && (val_desc));
85 * First ensure we have a value that can be stored in the target
87 switch (destination_type)
89 /* Type of Name's existing value */
91 case ACPI_TYPE_NUMBER:
94 * These cases all require only number values or values that
95 * can be converted to numbers.
97 * If value is not a Number, try to resolve it to one.
100 if (val_desc->common.type != ACPI_TYPE_NUMBER) {
102 * Initially not a number, convert
104 status = acpi_aml_resolve_to_value (&val_desc, walk_state);
105 if (ACPI_SUCCESS (status) &&
106 (val_desc->common.type != ACPI_TYPE_NUMBER))
109 * Conversion successful but still not a number
111 status = AE_AML_OPERAND_TYPE;
115 break;
117 case ACPI_TYPE_STRING:
118 case ACPI_TYPE_BUFFER:
121 * Storing into a Field in a region or into a buffer or into
122 * a string all is essentially the same.
124 * If value is not a valid type, try to resolve it to one.
127 if ((val_desc->common.type != ACPI_TYPE_NUMBER) &&
128 (val_desc->common.type != ACPI_TYPE_BUFFER) &&
129 (val_desc->common.type != ACPI_TYPE_STRING))
132 * Initially not a valid type, convert
134 status = acpi_aml_resolve_to_value (&val_desc, walk_state);
135 if (ACPI_SUCCESS (status) &&
136 (val_desc->common.type != ACPI_TYPE_NUMBER) &&
137 (val_desc->common.type != ACPI_TYPE_BUFFER) &&
138 (val_desc->common.type != ACPI_TYPE_STRING))
141 * Conversion successful but still not a valid type
143 status = AE_AML_OPERAND_TYPE;
146 break;
149 default:
152 * TBD: [Unhandled] What other combinations must be implemented?
154 status = AE_NOT_IMPLEMENTED;
155 break;
158 /* Exit now if failure above */
160 if (ACPI_FAILURE (status)) {
161 goto clean_up_and_bail_out;
165 * Acpi_everything is ready to execute now, We have
166 * a value we can handle, just perform the update
169 switch (destination_type)
172 case ACPI_TYPE_STRING:
175 * Perform the update
178 switch (val_desc->common.type)
180 case ACPI_TYPE_NUMBER:
181 buffer = (u8 *) &val_desc->number.value;
182 length = sizeof (val_desc->number.value);
183 break;
185 case ACPI_TYPE_BUFFER:
186 buffer = (u8 *) val_desc->buffer.pointer;
187 length = val_desc->buffer.length;
188 break;
190 case ACPI_TYPE_STRING:
191 buffer = (u8 *) val_desc->string.pointer;
192 length = val_desc->string.length;
193 break;
197 * Setting a string value replaces the old string
200 if (length < dest_desc->string.length) {
202 * Zero fill, not willing to do pointer arithmetic for
203 * architecture independence. Just clear the whole thing
205 MEMSET(dest_desc->string.pointer, 0, dest_desc->string.length);
206 MEMCPY(dest_desc->string.pointer, buffer, length);
208 else {
210 * Free the current buffer, then allocate a buffer
211 * large enough to hold the value
213 if ( dest_desc->string.pointer &&
214 !acpi_tb_system_table_pointer (dest_desc->string.pointer))
217 * Only free if not a pointer into the DSDT
220 acpi_cm_free(dest_desc->string.pointer);
223 dest_desc->string.pointer = acpi_cm_allocate (length + 1);
224 dest_desc->string.length = length;
226 if (!dest_desc->string.pointer) {
227 status = AE_NO_MEMORY;
228 goto clean_up_and_bail_out;
231 MEMCPY(dest_desc->string.pointer, buffer, length);
233 break;
236 case ACPI_TYPE_BUFFER:
239 * Perform the update to the buffer
242 switch (val_desc->common.type)
244 case ACPI_TYPE_NUMBER:
245 buffer = (u8 *) &val_desc->number.value;
246 length = sizeof (val_desc->number.value);
247 break;
249 case ACPI_TYPE_BUFFER:
250 buffer = (u8 *) val_desc->buffer.pointer;
251 length = val_desc->buffer.length;
252 break;
254 case ACPI_TYPE_STRING:
255 buffer = (u8 *) val_desc->string.pointer;
256 length = val_desc->string.length;
257 break;
261 * If the buffer is uninitialized,
262 * memory needs to be allocated for the copy.
264 if(0 == dest_desc->buffer.length) {
265 dest_desc->buffer.pointer = acpi_cm_callocate(length);
266 dest_desc->buffer.length = length;
268 if (!dest_desc->buffer.pointer) {
269 status = AE_NO_MEMORY;
270 goto clean_up_and_bail_out;
275 * Buffer is a static allocation,
276 * only place what will fit in the buffer.
278 if (length <= dest_desc->buffer.length) {
280 * Zero fill first, not willing to do pointer arithmetic for
281 * architecture independence. Just clear the whole thing
283 MEMSET(dest_desc->buffer.pointer, 0, dest_desc->buffer.length);
284 MEMCPY(dest_desc->buffer.pointer, buffer, length);
286 else {
288 * truncate, copy only what will fit
290 MEMCPY(dest_desc->buffer.pointer, buffer, dest_desc->buffer.length);
292 break;
294 case ACPI_TYPE_NUMBER:
296 dest_desc->number.value = val_desc->number.value;
298 /* Truncate value if we are executing from a 32-bit ACPI table */
300 acpi_aml_truncate_for32bit_table (dest_desc, walk_state);
301 break;
303 default:
306 * All other types than Alias and the various Fields come here.
307 * Store Val_desc as the new value of the Name, and set
308 * the Name's type to that of the value being stored in it.
309 * Val_desc reference count is incremented by Attach_object.
312 status = AE_NOT_IMPLEMENTED;
313 break;
316 clean_up_and_bail_out:
318 return (status);