aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exmisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/executer/exmisc.c')
-rw-r--r--drivers/acpi/executer/exmisc.c113
1 files changed, 63 insertions, 50 deletions
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index a3f4d72bedc9..48c18d29222a 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore 9 * Copyright (C) 2000 - 2006, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include <acpi/acinterp.h> 46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h> 47#include <acpi/amlcode.h>
48#include <acpi/amlresrc.h>
48 49
49#define _COMPONENT ACPI_EXECUTER 50#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exmisc") 51ACPI_MODULE_NAME("exmisc")
@@ -97,7 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
97 98
98 default: 99 default:
99 100
100 ACPI_REPORT_ERROR(("Unknown Reference opcode in get_reference %X\n", obj_desc->reference.opcode)); 101 ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
102 obj_desc->reference.opcode));
101 return_ACPI_STATUS(AE_AML_INTERNAL); 103 return_ACPI_STATUS(AE_AML_INTERNAL);
102 } 104 }
103 break; 105 break;
@@ -112,7 +114,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
112 114
113 default: 115 default:
114 116
115 ACPI_REPORT_ERROR(("Invalid descriptor type in get_reference: %X\n", ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); 117 ACPI_ERROR((AE_INFO, "Invalid descriptor type %X",
118 ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
116 return_ACPI_STATUS(AE_TYPE); 119 return_ACPI_STATUS(AE_TYPE);
117 } 120 }
118 121
@@ -157,48 +160,65 @@ acpi_ex_concat_template(union acpi_operand_object *operand0,
157 union acpi_operand_object **actual_return_desc, 160 union acpi_operand_object **actual_return_desc,
158 struct acpi_walk_state *walk_state) 161 struct acpi_walk_state *walk_state)
159{ 162{
163 acpi_status status;
160 union acpi_operand_object *return_desc; 164 union acpi_operand_object *return_desc;
161 u8 *new_buf; 165 u8 *new_buf;
162 u8 *end_tag1; 166 u8 *end_tag;
163 u8 *end_tag2; 167 acpi_size length0;
164 acpi_size length1; 168 acpi_size length1;
165 acpi_size length2; 169 acpi_size new_length;
166 170
167 ACPI_FUNCTION_TRACE("ex_concat_template"); 171 ACPI_FUNCTION_TRACE("ex_concat_template");
168 172
169 /* Find the end_tags in each resource template */ 173 /*
174 * Find the end_tag descriptor in each resource template.
175 * Note1: returned pointers point TO the end_tag, not past it.
176 * Note2: zero-length buffers are allowed; treated like one end_tag
177 */
178
179 /* Get the length of the first resource template */
170 180
171 end_tag1 = acpi_ut_get_resource_end_tag(operand0); 181 status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
172 end_tag2 = acpi_ut_get_resource_end_tag(operand1); 182 if (ACPI_FAILURE(status)) {
173 if (!end_tag1 || !end_tag2) { 183 return_ACPI_STATUS(status);
174 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
175 } 184 }
176 185
177 /* Compute the length of each part */ 186 length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
187
188 /* Get the length of the second resource template */
189
190 status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
191 if (ACPI_FAILURE(status)) {
192 return_ACPI_STATUS(status);
193 }
178 194
179 length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer); 195 length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
180 length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2; /* Size of END_TAG */
181 196
182 /* Create a new buffer object for the result */ 197 /* Combine both lengths, minimum size will be 2 for end_tag */
183 198
184 return_desc = acpi_ut_create_buffer_object(length1 + length2); 199 new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
200
201 /* Create a new buffer object for the result (with one end_tag) */
202
203 return_desc = acpi_ut_create_buffer_object(new_length);
185 if (!return_desc) { 204 if (!return_desc) {
186 return_ACPI_STATUS(AE_NO_MEMORY); 205 return_ACPI_STATUS(AE_NO_MEMORY);
187 } 206 }
188 207
189 /* Copy the templates to the new descriptor */ 208 /*
190 209 * Copy the templates to the new buffer, 0 first, then 1 follows. One
210 * end_tag descriptor is copied from Operand1.
211 */
191 new_buf = return_desc->buffer.pointer; 212 new_buf = return_desc->buffer.pointer;
192 ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1); 213 ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0);
193 ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2); 214 ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1);
194 215
195 /* Compute the new checksum */ 216 /* Insert end_tag and set the checksum to zero, means "ignore checksum" */
196 217
197 new_buf[return_desc->buffer.length - 1] = 218 new_buf[new_length - 1] = 0;
198 acpi_ut_generate_checksum(return_desc->buffer.pointer, 219 new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
199 (return_desc->buffer.length - 1));
200 220
201 /* Return the completed template descriptor */ 221 /* Return the completed resource template */
202 222
203 *actual_return_desc = return_desc; 223 *actual_return_desc = return_desc;
204 return_ACPI_STATUS(AE_OK); 224 return_ACPI_STATUS(AE_OK);
@@ -229,7 +249,6 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
229 union acpi_operand_object *return_desc; 249 union acpi_operand_object *return_desc;
230 char *new_buf; 250 char *new_buf;
231 acpi_status status; 251 acpi_status status;
232 acpi_size new_length;
233 252
234 ACPI_FUNCTION_TRACE("ex_do_concatenate"); 253 ACPI_FUNCTION_TRACE("ex_do_concatenate");
235 254
@@ -256,8 +275,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
256 break; 275 break;
257 276
258 default: 277 default:
259 ACPI_REPORT_ERROR(("Concat - invalid obj type: %X\n", 278 ACPI_ERROR((AE_INFO, "Invalid object type: %X",
260 ACPI_GET_OBJECT_TYPE(operand0))); 279 ACPI_GET_OBJECT_TYPE(operand0)));
261 status = AE_AML_INTERNAL; 280 status = AE_AML_INTERNAL;
262 } 281 }
263 282
@@ -296,8 +315,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
296 315
297 /* Copy the first integer, LSB first */ 316 /* Copy the first integer, LSB first */
298 317
299 ACPI_MEMCPY(new_buf, 318 ACPI_MEMCPY(new_buf, &operand0->integer.value,
300 &operand0->integer.value,
301 acpi_gbl_integer_byte_width); 319 acpi_gbl_integer_byte_width);
302 320
303 /* Copy the second integer (LSB first) after the first */ 321 /* Copy the second integer (LSB first) after the first */
@@ -311,14 +329,11 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
311 329
312 /* Result of two Strings is a String */ 330 /* Result of two Strings is a String */
313 331
314 new_length = (acpi_size) operand0->string.length + 332 return_desc = acpi_ut_create_string_object((acpi_size)
315 (acpi_size) local_operand1->string.length; 333 (operand0->string.
316 if (new_length > ACPI_MAX_STRING_CONVERSION) { 334 length +
317 status = AE_AML_STRING_LIMIT; 335 local_operand1->
318 goto cleanup; 336 string.length));
319 }
320
321 return_desc = acpi_ut_create_string_object(new_length);
322 if (!return_desc) { 337 if (!return_desc) {
323 status = AE_NO_MEMORY; 338 status = AE_NO_MEMORY;
324 goto cleanup; 339 goto cleanup;
@@ -338,11 +353,10 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
338 /* Result of two Buffers is a Buffer */ 353 /* Result of two Buffers is a Buffer */
339 354
340 return_desc = acpi_ut_create_buffer_object((acpi_size) 355 return_desc = acpi_ut_create_buffer_object((acpi_size)
341 operand0->buffer. 356 (operand0->buffer.
342 length + 357 length +
343 (acpi_size) 358 local_operand1->
344 local_operand1-> 359 buffer.length));
345 buffer.length);
346 if (!return_desc) { 360 if (!return_desc) {
347 status = AE_NO_MEMORY; 361 status = AE_NO_MEMORY;
348 goto cleanup; 362 goto cleanup;
@@ -352,8 +366,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
352 366
353 /* Concatenate the buffers */ 367 /* Concatenate the buffers */
354 368
355 ACPI_MEMCPY(new_buf, 369 ACPI_MEMCPY(new_buf, operand0->buffer.pointer,
356 operand0->buffer.pointer, operand0->buffer.length); 370 operand0->buffer.length);
357 ACPI_MEMCPY(new_buf + operand0->buffer.length, 371 ACPI_MEMCPY(new_buf + operand0->buffer.length,
358 local_operand1->buffer.pointer, 372 local_operand1->buffer.pointer,
359 local_operand1->buffer.length); 373 local_operand1->buffer.length);
@@ -363,8 +377,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
363 377
364 /* Invalid object type, should not happen here */ 378 /* Invalid object type, should not happen here */
365 379
366 ACPI_REPORT_ERROR(("Concatenate - Invalid object type: %X\n", 380 ACPI_ERROR((AE_INFO, "Invalid object type: %X",
367 ACPI_GET_OBJECT_TYPE(operand0))); 381 ACPI_GET_OBJECT_TYPE(operand0)));
368 status = AE_AML_INTERNAL; 382 status = AE_AML_INTERNAL;
369 goto cleanup; 383 goto cleanup;
370 } 384 }
@@ -625,9 +639,8 @@ acpi_ex_do_logical_op(u16 opcode,
625 639
626 /* Lexicographic compare: compare the data bytes */ 640 /* Lexicographic compare: compare the data bytes */
627 641
628 compare = ACPI_MEMCMP((const char *)operand0->buffer.pointer, 642 compare = ACPI_MEMCMP(operand0->buffer.pointer,
629 (const char *)local_operand1->buffer. 643 local_operand1->buffer.pointer,
630 pointer,
631 (length0 > length1) ? length1 : length0); 644 (length0 > length1) ? length1 : length0);
632 645
633 switch (opcode) { 646 switch (opcode) {