Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exstorob.c
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * Module Name: exstorob - AML Interpreter object store support, store to object
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2012, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions, and the following disclaimer,
17  * without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  * substantially similar to the "NO WARRANTY" disclaimer below
20  * ("Disclaimer") and any redistribution must be conditioned upon
21  * including a substantially similar Disclaimer requirement for further
22  * binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  * of any contributors may be used to endorse or promote products derived
25  * from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acinterp.h"
48 
49 #define _COMPONENT ACPI_EXECUTER
50 ACPI_MODULE_NAME("exstorob")
51 
52 /*******************************************************************************
53  *
54  * FUNCTION: acpi_ex_store_buffer_to_buffer
55  *
56  * PARAMETERS: source_desc - Source object to copy
57  * target_desc - Destination object of the copy
58  *
59  * RETURN: Status
60  *
61  * DESCRIPTION: Copy a buffer object to another buffer object.
62  *
63  ******************************************************************************/
66  union acpi_operand_object *target_desc)
67 {
68  u32 length;
69  u8 *buffer;
70 
71  ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
72 
73  /* If Source and Target are the same, just return */
74 
75  if (source_desc == target_desc) {
77  }
78 
79  /* We know that source_desc is a buffer by now */
80 
81  buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
82  length = source_desc->buffer.length;
83 
84  /*
85  * If target is a buffer of length zero or is a static buffer,
86  * allocate a new buffer of the proper length
87  */
88  if ((target_desc->buffer.length == 0) ||
89  (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
90  target_desc->buffer.pointer = ACPI_ALLOCATE(length);
91  if (!target_desc->buffer.pointer) {
93  }
94 
95  target_desc->buffer.length = length;
96  }
97 
98  /* Copy source buffer to target buffer */
99 
100  if (length <= target_desc->buffer.length) {
101 
102  /* Clear existing buffer and copy in the new one */
103 
104  ACPI_MEMSET(target_desc->buffer.pointer, 0,
105  target_desc->buffer.length);
106  ACPI_MEMCPY(target_desc->buffer.pointer, buffer, length);
107 
108 #ifdef ACPI_OBSOLETE_BEHAVIOR
109  /*
110  * NOTE: ACPI versions up to 3.0 specified that the buffer must be
111  * truncated if the string is smaller than the buffer. However, "other"
112  * implementations of ACPI never did this and thus became the defacto
113  * standard. ACPI 3.0A changes this behavior such that the buffer
114  * is no longer truncated.
115  */
116 
117  /*
118  * OBSOLETE BEHAVIOR:
119  * If the original source was a string, we must truncate the buffer,
120  * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
121  * copy must not truncate the original buffer.
122  */
123  if (original_src_type == ACPI_TYPE_STRING) {
124 
125  /* Set the new length of the target */
126 
127  target_desc->buffer.length = length;
128  }
129 #endif
130  } else {
131  /* Truncate the source, copy only what will fit */
132 
133  ACPI_MEMCPY(target_desc->buffer.pointer, buffer,
134  target_desc->buffer.length);
135 
137  "Truncating source buffer from %X to %X\n",
138  length, target_desc->buffer.length));
139  }
140 
141  /* Copy flags */
142 
143  target_desc->buffer.flags = source_desc->buffer.flags;
144  target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
146 }
147 
148 /*******************************************************************************
149  *
150  * FUNCTION: acpi_ex_store_string_to_string
151  *
152  * PARAMETERS: source_desc - Source object to copy
153  * target_desc - Destination object of the copy
154  *
155  * RETURN: Status
156  *
157  * DESCRIPTION: Copy a String object to another String object
158  *
159  ******************************************************************************/
160 
163  union acpi_operand_object *target_desc)
164 {
165  u32 length;
166  u8 *buffer;
167 
168  ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
169 
170  /* If Source and Target are the same, just return */
171 
172  if (source_desc == target_desc) {
174  }
175 
176  /* We know that source_desc is a string by now */
177 
178  buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
179  length = source_desc->string.length;
180 
181  /*
182  * Replace existing string value if it will fit and the string
183  * pointer is not a static pointer (part of an ACPI table)
184  */
185  if ((length < target_desc->string.length) &&
186  (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
187  /*
188  * String will fit in existing non-static buffer.
189  * Clear old string and copy in the new one
190  */
191  ACPI_MEMSET(target_desc->string.pointer, 0,
192  (acpi_size) target_desc->string.length + 1);
193  ACPI_MEMCPY(target_desc->string.pointer, buffer, length);
194  } else {
195  /*
196  * Free the current buffer, then allocate a new buffer
197  * large enough to hold the value
198  */
199  if (target_desc->string.pointer &&
200  (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
201 
202  /* Only free if not a pointer into the DSDT */
203 
204  ACPI_FREE(target_desc->string.pointer);
205  }
206 
207  target_desc->string.pointer = ACPI_ALLOCATE_ZEROED((acpi_size)
208  length + 1);
209  if (!target_desc->string.pointer) {
211  }
212 
213  target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
214  ACPI_MEMCPY(target_desc->string.pointer, buffer, length);
215  }
216 
217  /* Set the new target length */
218 
219  target_desc->string.length = length;
221 }