aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exoparg3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/executer/exoparg3.c')
-rw-r--r--drivers/acpi/executer/exoparg3.c167
1 files changed, 88 insertions, 79 deletions
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index 23b068adbf58..483365777670 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -42,16 +42,13 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45
46#include <acpi/acpi.h> 45#include <acpi/acpi.h>
47#include <acpi/acinterp.h> 46#include <acpi/acinterp.h>
48#include <acpi/acparser.h> 47#include <acpi/acparser.h>
49#include <acpi/amlcode.h> 48#include <acpi/amlcode.h>
50 49
51
52#define _COMPONENT ACPI_EXECUTER 50#define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exoparg3") 51ACPI_MODULE_NAME("exoparg3")
54
55 52
56/*! 53/*!
57 * Naming convention for AML interpreter execution routines. 54 * Naming convention for AML interpreter execution routines.
@@ -74,8 +71,6 @@
74 * The AcpiExOpcode* functions are called via the Dispatcher component with 71 * The AcpiExOpcode* functions are called via the Dispatcher component with
75 * fully resolved operands. 72 * fully resolved operands.
76!*/ 73!*/
77
78
79/******************************************************************************* 74/*******************************************************************************
80 * 75 *
81 * FUNCTION: acpi_ex_opcode_3A_0T_0R 76 * FUNCTION: acpi_ex_opcode_3A_0T_0R
@@ -87,61 +82,53 @@
87 * DESCRIPTION: Execute Triadic operator (3 operands) 82 * DESCRIPTION: Execute Triadic operator (3 operands)
88 * 83 *
89 ******************************************************************************/ 84 ******************************************************************************/
90 85acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state)
91acpi_status
92acpi_ex_opcode_3A_0T_0R (
93 struct acpi_walk_state *walk_state)
94{ 86{
95 union acpi_operand_object **operand = &walk_state->operands[0]; 87 union acpi_operand_object **operand = &walk_state->operands[0];
96 struct acpi_signal_fatal_info *fatal; 88 struct acpi_signal_fatal_info *fatal;
97 acpi_status status = AE_OK; 89 acpi_status status = AE_OK;
98
99
100 ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R",
101 acpi_ps_get_opcode_name (walk_state->opcode));
102 90
91 ACPI_FUNCTION_TRACE_STR("ex_opcode_3A_0T_0R",
92 acpi_ps_get_opcode_name(walk_state->opcode));
103 93
104 switch (walk_state->opcode) { 94 switch (walk_state->opcode) {
105 case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */ 95 case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
106 96
107 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 97 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
108 "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", 98 "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
109 (u32) operand[0]->integer.value, 99 (u32) operand[0]->integer.value,
110 (u32) operand[1]->integer.value, 100 (u32) operand[1]->integer.value,
111 (u32) operand[2]->integer.value)); 101 (u32) operand[2]->integer.value));
112 102
113 fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info)); 103 fatal =
104 ACPI_MEM_ALLOCATE(sizeof(struct acpi_signal_fatal_info));
114 if (fatal) { 105 if (fatal) {
115 fatal->type = (u32) operand[0]->integer.value; 106 fatal->type = (u32) operand[0]->integer.value;
116 fatal->code = (u32) operand[1]->integer.value; 107 fatal->code = (u32) operand[1]->integer.value;
117 fatal->argument = (u32) operand[2]->integer.value; 108 fatal->argument = (u32) operand[2]->integer.value;
118 } 109 }
119 110
120 /* Always signal the OS! */ 111 /* Always signal the OS! */
121 112
122 status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal); 113 status = acpi_os_signal(ACPI_SIGNAL_FATAL, fatal);
123 114
124 /* Might return while OS is shutting down, just continue */ 115 /* Might return while OS is shutting down, just continue */
125 116
126 ACPI_MEM_FREE (fatal); 117 ACPI_MEM_FREE(fatal);
127 break; 118 break;
128 119
129
130 default: 120 default:
131 121
132 ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", 122 ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
133 walk_state->opcode));
134 status = AE_AML_BAD_OPCODE; 123 status = AE_AML_BAD_OPCODE;
135 goto cleanup; 124 goto cleanup;
136 } 125 }
137 126
127 cleanup:
138 128
139cleanup: 129 return_ACPI_STATUS(status);
140
141 return_ACPI_STATUS (status);
142} 130}
143 131
144
145/******************************************************************************* 132/*******************************************************************************
146 * 133 *
147 * FUNCTION: acpi_ex_opcode_3A_1T_1R 134 * FUNCTION: acpi_ex_opcode_3A_1T_1R
@@ -154,31 +141,28 @@ cleanup:
154 * 141 *
155 ******************************************************************************/ 142 ******************************************************************************/
156 143
157acpi_status 144acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
158acpi_ex_opcode_3A_1T_1R (
159 struct acpi_walk_state *walk_state)
160{ 145{
161 union acpi_operand_object **operand = &walk_state->operands[0]; 146 union acpi_operand_object **operand = &walk_state->operands[0];
162 union acpi_operand_object *return_desc = NULL; 147 union acpi_operand_object *return_desc = NULL;
163 char *buffer; 148 char *buffer = NULL;
164 acpi_status status = AE_OK; 149 acpi_status status = AE_OK;
165 acpi_integer index; 150 acpi_integer index;
166 acpi_size length; 151 acpi_size length;
167
168
169 ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R",
170 acpi_ps_get_opcode_name (walk_state->opcode));
171 152
153 ACPI_FUNCTION_TRACE_STR("ex_opcode_3A_1T_1R",
154 acpi_ps_get_opcode_name(walk_state->opcode));
172 155
173 switch (walk_state->opcode) { 156 switch (walk_state->opcode) {
174 case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */ 157 case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
175 158
176 /* 159 /*
177 * Create the return object. The Source operand is guaranteed to be 160 * Create the return object. The Source operand is guaranteed to be
178 * either a String or a Buffer, so just use its type. 161 * either a String or a Buffer, so just use its type.
179 */ 162 */
180 return_desc = acpi_ut_create_internal_object ( 163 return_desc =
181 ACPI_GET_OBJECT_TYPE (operand[0])); 164 acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
165 (operand[0]));
182 if (!return_desc) { 166 if (!return_desc) {
183 status = AE_NO_MEMORY; 167 status = AE_NO_MEMORY;
184 goto cleanup; 168 goto cleanup;
@@ -193,67 +177,92 @@ acpi_ex_opcode_3A_1T_1R (
193 * If the index is beyond the length of the String/Buffer, or if the 177 * If the index is beyond the length of the String/Buffer, or if the
194 * requested length is zero, return a zero-length String/Buffer 178 * requested length is zero, return a zero-length String/Buffer
195 */ 179 */
196 if ((index < operand[0]->string.length) && 180 if (index >= operand[0]->string.length) {
197 (length > 0)) { 181 length = 0;
198 /* Truncate request if larger than the actual String/Buffer */ 182 }
199 183
200 if ((index + length) > 184 /* Truncate request if larger than the actual String/Buffer */
201 operand[0]->string.length) { 185
202 length = (acpi_size) operand[0]->string.length - 186 else if ((index + length) > operand[0]->string.length) {
203 (acpi_size) index; 187 length = (acpi_size) operand[0]->string.length -
204 } 188 (acpi_size) index;
189 }
190
191 /* Strings always have a sub-pointer, not so for buffers */
192
193 switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
194 case ACPI_TYPE_STRING:
205 195
206 /* Allocate a new buffer for the String/Buffer */ 196 /* Always allocate a new buffer for the String */
207 197
208 buffer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1); 198 buffer = ACPI_MEM_CALLOCATE((acpi_size) length + 1);
209 if (!buffer) { 199 if (!buffer) {
210 status = AE_NO_MEMORY; 200 status = AE_NO_MEMORY;
211 goto cleanup; 201 goto cleanup;
212 } 202 }
203 break;
213 204
214 /* Copy the portion requested */ 205 case ACPI_TYPE_BUFFER:
215 206
216 ACPI_MEMCPY (buffer, operand[0]->string.pointer + index, 207 /* If the requested length is zero, don't allocate a buffer */
217 length);
218 208
219 /* Set the length of the new String/Buffer */ 209 if (length > 0) {
210 /* Allocate a new buffer for the Buffer */
220 211
221 return_desc->string.pointer = buffer; 212 buffer = ACPI_MEM_CALLOCATE(length);
222 return_desc->string.length = (u32) length; 213 if (!buffer) {
214 status = AE_NO_MEMORY;
215 goto cleanup;
216 }
217 }
218 break;
219
220 default: /* Should not happen */
221
222 status = AE_AML_OPERAND_TYPE;
223 goto cleanup;
223 } 224 }
224 225
226 if (length > 0) {
227 /* Copy the portion requested */
228
229 ACPI_MEMCPY(buffer, operand[0]->string.pointer + index,
230 length);
231 }
232
233 /* Set the length of the new String/Buffer */
234
235 return_desc->string.pointer = buffer;
236 return_desc->string.length = (u32) length;
237
225 /* Mark buffer initialized */ 238 /* Mark buffer initialized */
226 239
227 return_desc->buffer.flags |= AOPOBJ_DATA_VALID; 240 return_desc->buffer.flags |= AOPOBJ_DATA_VALID;
228 break; 241 break;
229 242
230
231 default: 243 default:
232 244
233 ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", 245 ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
234 walk_state->opcode));
235 status = AE_AML_BAD_OPCODE; 246 status = AE_AML_BAD_OPCODE;
236 goto cleanup; 247 goto cleanup;
237 } 248 }
238 249
239 /* Store the result in the target */ 250 /* Store the result in the target */
240 251
241 status = acpi_ex_store (return_desc, operand[3], walk_state); 252 status = acpi_ex_store(return_desc, operand[3], walk_state);
242 253
243cleanup: 254 cleanup:
244 255
245 /* Delete return object on error */ 256 /* Delete return object on error */
246 257
247 if (ACPI_FAILURE (status)) { 258 if (ACPI_FAILURE(status) || walk_state->result_obj) {
248 acpi_ut_remove_reference (return_desc); 259 acpi_ut_remove_reference(return_desc);
249 } 260 }
250 261
251 /* Set the return object and exit */ 262 /* Set the return object and exit */
252 263
253 if (!walk_state->result_obj) { 264 else {
254 walk_state->result_obj = return_desc; 265 walk_state->result_obj = return_desc;
255 } 266 }
256 return_ACPI_STATUS (status); 267 return_ACPI_STATUS(status);
257} 268}
258
259