diff options
author | Len Brown <len.brown@intel.com> | 2009-01-09 00:13:17 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-09 03:30:47 -0500 |
commit | 95b482a8d31116f3f5c2a5089569393234d06385 (patch) | |
tree | f32aec8673a285a9d188948be97af3034ee06e93 /drivers/acpi/utilities/utcopy.c | |
parent | 6620e0c49f577454b772fb381543d60ae53eb885 (diff) |
ACPICA: create acpica/ directory
also, delete sleep/ and delete ACPI_CFLAGS from Makefile
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/utilities/utcopy.c')
-rw-r--r-- | drivers/acpi/utilities/utcopy.c | 970 |
1 files changed, 0 insertions, 970 deletions
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c deleted file mode 100644 index e6f3002312e5..000000000000 --- a/drivers/acpi/utilities/utcopy.c +++ /dev/null | |||
@@ -1,970 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utcopy - Internal to external object translation utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/accommon.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | |||
48 | |||
49 | #define _COMPONENT ACPI_UTILITIES | ||
50 | ACPI_MODULE_NAME("utcopy") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static acpi_status | ||
54 | acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | ||
55 | union acpi_object *external_object, | ||
56 | u8 * data_space, acpi_size * buffer_space_used); | ||
57 | |||
58 | static acpi_status | ||
59 | acpi_ut_copy_ielement_to_ielement(u8 object_type, | ||
60 | union acpi_operand_object *source_object, | ||
61 | union acpi_generic_state *state, | ||
62 | void *context); | ||
63 | |||
64 | static acpi_status | ||
65 | acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, | ||
66 | u8 * buffer, acpi_size * space_used); | ||
67 | |||
68 | static acpi_status | ||
69 | acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj, | ||
70 | union acpi_operand_object **return_obj); | ||
71 | |||
72 | static acpi_status | ||
73 | acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, | ||
74 | union acpi_operand_object **internal_object); | ||
75 | |||
76 | static acpi_status | ||
77 | acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | ||
78 | union acpi_operand_object *dest_desc); | ||
79 | |||
80 | static acpi_status | ||
81 | acpi_ut_copy_ielement_to_eelement(u8 object_type, | ||
82 | union acpi_operand_object *source_object, | ||
83 | union acpi_generic_state *state, | ||
84 | void *context); | ||
85 | |||
86 | static acpi_status | ||
87 | acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, | ||
88 | union acpi_operand_object *dest_obj, | ||
89 | struct acpi_walk_state *walk_state); | ||
90 | |||
91 | /******************************************************************************* | ||
92 | * | ||
93 | * FUNCTION: acpi_ut_copy_isimple_to_esimple | ||
94 | * | ||
95 | * PARAMETERS: internal_object - Source object to be copied | ||
96 | * external_object - Where to return the copied object | ||
97 | * data_space - Where object data is returned (such as | ||
98 | * buffer and string data) | ||
99 | * buffer_space_used - Length of data_space that was used | ||
100 | * | ||
101 | * RETURN: Status | ||
102 | * | ||
103 | * DESCRIPTION: This function is called to copy a simple internal object to | ||
104 | * an external object. | ||
105 | * | ||
106 | * The data_space buffer is assumed to have sufficient space for | ||
107 | * the object. | ||
108 | * | ||
109 | ******************************************************************************/ | ||
110 | |||
111 | static acpi_status | ||
112 | acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | ||
113 | union acpi_object *external_object, | ||
114 | u8 * data_space, acpi_size * buffer_space_used) | ||
115 | { | ||
116 | acpi_status status = AE_OK; | ||
117 | |||
118 | ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple); | ||
119 | |||
120 | *buffer_space_used = 0; | ||
121 | |||
122 | /* | ||
123 | * Check for NULL object case (could be an uninitialized | ||
124 | * package element) | ||
125 | */ | ||
126 | if (!internal_object) { | ||
127 | return_ACPI_STATUS(AE_OK); | ||
128 | } | ||
129 | |||
130 | /* Always clear the external object */ | ||
131 | |||
132 | ACPI_MEMSET(external_object, 0, sizeof(union acpi_object)); | ||
133 | |||
134 | /* | ||
135 | * In general, the external object will be the same type as | ||
136 | * the internal object | ||
137 | */ | ||
138 | external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); | ||
139 | |||
140 | /* However, only a limited number of external types are supported */ | ||
141 | |||
142 | switch (ACPI_GET_OBJECT_TYPE(internal_object)) { | ||
143 | case ACPI_TYPE_STRING: | ||
144 | |||
145 | external_object->string.pointer = (char *)data_space; | ||
146 | external_object->string.length = internal_object->string.length; | ||
147 | *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) | ||
148 | internal_object-> | ||
149 | string. | ||
150 | length + 1); | ||
151 | |||
152 | ACPI_MEMCPY((void *)data_space, | ||
153 | (void *)internal_object->string.pointer, | ||
154 | (acpi_size) internal_object->string.length + 1); | ||
155 | break; | ||
156 | |||
157 | case ACPI_TYPE_BUFFER: | ||
158 | |||
159 | external_object->buffer.pointer = data_space; | ||
160 | external_object->buffer.length = internal_object->buffer.length; | ||
161 | *buffer_space_used = | ||
162 | ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string. | ||
163 | length); | ||
164 | |||
165 | ACPI_MEMCPY((void *)data_space, | ||
166 | (void *)internal_object->buffer.pointer, | ||
167 | internal_object->buffer.length); | ||
168 | break; | ||
169 | |||
170 | case ACPI_TYPE_INTEGER: | ||
171 | |||
172 | external_object->integer.value = internal_object->integer.value; | ||
173 | break; | ||
174 | |||
175 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
176 | |||
177 | /* This is an object reference. */ | ||
178 | |||
179 | switch (internal_object->reference.class) { | ||
180 | case ACPI_REFCLASS_NAME: | ||
181 | |||
182 | /* | ||
183 | * For namepath, return the object handle ("reference") | ||
184 | * We are referring to the namespace node | ||
185 | */ | ||
186 | external_object->reference.handle = | ||
187 | internal_object->reference.node; | ||
188 | external_object->reference.actual_type = | ||
189 | acpi_ns_get_type(internal_object->reference.node); | ||
190 | break; | ||
191 | |||
192 | default: | ||
193 | |||
194 | /* All other reference types are unsupported */ | ||
195 | |||
196 | return_ACPI_STATUS(AE_TYPE); | ||
197 | } | ||
198 | break; | ||
199 | |||
200 | case ACPI_TYPE_PROCESSOR: | ||
201 | |||
202 | external_object->processor.proc_id = | ||
203 | internal_object->processor.proc_id; | ||
204 | external_object->processor.pblk_address = | ||
205 | internal_object->processor.address; | ||
206 | external_object->processor.pblk_length = | ||
207 | internal_object->processor.length; | ||
208 | break; | ||
209 | |||
210 | case ACPI_TYPE_POWER: | ||
211 | |||
212 | external_object->power_resource.system_level = | ||
213 | internal_object->power_resource.system_level; | ||
214 | |||
215 | external_object->power_resource.resource_order = | ||
216 | internal_object->power_resource.resource_order; | ||
217 | break; | ||
218 | |||
219 | default: | ||
220 | /* | ||
221 | * There is no corresponding external object type | ||
222 | */ | ||
223 | ACPI_ERROR((AE_INFO, | ||
224 | "Unsupported object type, cannot convert to external object: %s", | ||
225 | acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE | ||
226 | (internal_object)))); | ||
227 | |||
228 | return_ACPI_STATUS(AE_SUPPORT); | ||
229 | } | ||
230 | |||
231 | return_ACPI_STATUS(status); | ||
232 | } | ||
233 | |||
234 | /******************************************************************************* | ||
235 | * | ||
236 | * FUNCTION: acpi_ut_copy_ielement_to_eelement | ||
237 | * | ||
238 | * PARAMETERS: acpi_pkg_callback | ||
239 | * | ||
240 | * RETURN: Status | ||
241 | * | ||
242 | * DESCRIPTION: Copy one package element to another package element | ||
243 | * | ||
244 | ******************************************************************************/ | ||
245 | |||
246 | static acpi_status | ||
247 | acpi_ut_copy_ielement_to_eelement(u8 object_type, | ||
248 | union acpi_operand_object *source_object, | ||
249 | union acpi_generic_state *state, | ||
250 | void *context) | ||
251 | { | ||
252 | acpi_status status = AE_OK; | ||
253 | struct acpi_pkg_info *info = (struct acpi_pkg_info *)context; | ||
254 | acpi_size object_space; | ||
255 | u32 this_index; | ||
256 | union acpi_object *target_object; | ||
257 | |||
258 | ACPI_FUNCTION_ENTRY(); | ||
259 | |||
260 | this_index = state->pkg.index; | ||
261 | target_object = (union acpi_object *) | ||
262 | &((union acpi_object *)(state->pkg.dest_object))->package. | ||
263 | elements[this_index]; | ||
264 | |||
265 | switch (object_type) { | ||
266 | case ACPI_COPY_TYPE_SIMPLE: | ||
267 | |||
268 | /* | ||
269 | * This is a simple or null object | ||
270 | */ | ||
271 | status = acpi_ut_copy_isimple_to_esimple(source_object, | ||
272 | target_object, | ||
273 | info->free_space, | ||
274 | &object_space); | ||
275 | if (ACPI_FAILURE(status)) { | ||
276 | return (status); | ||
277 | } | ||
278 | break; | ||
279 | |||
280 | case ACPI_COPY_TYPE_PACKAGE: | ||
281 | |||
282 | /* | ||
283 | * Build the package object | ||
284 | */ | ||
285 | target_object->type = ACPI_TYPE_PACKAGE; | ||
286 | target_object->package.count = source_object->package.count; | ||
287 | target_object->package.elements = | ||
288 | ACPI_CAST_PTR(union acpi_object, info->free_space); | ||
289 | |||
290 | /* | ||
291 | * Pass the new package object back to the package walk routine | ||
292 | */ | ||
293 | state->pkg.this_target_obj = target_object; | ||
294 | |||
295 | /* | ||
296 | * Save space for the array of objects (Package elements) | ||
297 | * update the buffer length counter | ||
298 | */ | ||
299 | object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) | ||
300 | target_object-> | ||
301 | package.count * | ||
302 | sizeof(union | ||
303 | acpi_object)); | ||
304 | break; | ||
305 | |||
306 | default: | ||
307 | return (AE_BAD_PARAMETER); | ||
308 | } | ||
309 | |||
310 | info->free_space += object_space; | ||
311 | info->length += object_space; | ||
312 | return (status); | ||
313 | } | ||
314 | |||
315 | /******************************************************************************* | ||
316 | * | ||
317 | * FUNCTION: acpi_ut_copy_ipackage_to_epackage | ||
318 | * | ||
319 | * PARAMETERS: internal_object - Pointer to the object we are returning | ||
320 | * Buffer - Where the object is returned | ||
321 | * space_used - Where the object length is returned | ||
322 | * | ||
323 | * RETURN: Status | ||
324 | * | ||
325 | * DESCRIPTION: This function is called to place a package object in a user | ||
326 | * buffer. A package object by definition contains other objects. | ||
327 | * | ||
328 | * The buffer is assumed to have sufficient space for the object. | ||
329 | * The caller must have verified the buffer length needed using the | ||
330 | * acpi_ut_get_object_size function before calling this function. | ||
331 | * | ||
332 | ******************************************************************************/ | ||
333 | |||
334 | static acpi_status | ||
335 | acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, | ||
336 | u8 * buffer, acpi_size * space_used) | ||
337 | { | ||
338 | union acpi_object *external_object; | ||
339 | acpi_status status; | ||
340 | struct acpi_pkg_info info; | ||
341 | |||
342 | ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage); | ||
343 | |||
344 | /* | ||
345 | * First package at head of the buffer | ||
346 | */ | ||
347 | external_object = ACPI_CAST_PTR(union acpi_object, buffer); | ||
348 | |||
349 | /* | ||
350 | * Free space begins right after the first package | ||
351 | */ | ||
352 | info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); | ||
353 | info.free_space = | ||
354 | buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); | ||
355 | info.object_space = 0; | ||
356 | info.num_packages = 1; | ||
357 | |||
358 | external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); | ||
359 | external_object->package.count = internal_object->package.count; | ||
360 | external_object->package.elements = ACPI_CAST_PTR(union acpi_object, | ||
361 | info.free_space); | ||
362 | |||
363 | /* | ||
364 | * Leave room for an array of ACPI_OBJECTS in the buffer | ||
365 | * and move the free space past it | ||
366 | */ | ||
367 | info.length += (acpi_size) external_object->package.count * | ||
368 | ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); | ||
369 | info.free_space += external_object->package.count * | ||
370 | ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); | ||
371 | |||
372 | status = acpi_ut_walk_package_tree(internal_object, external_object, | ||
373 | acpi_ut_copy_ielement_to_eelement, | ||
374 | &info); | ||
375 | |||
376 | *space_used = info.length; | ||
377 | return_ACPI_STATUS(status); | ||
378 | } | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_ut_copy_iobject_to_eobject | ||
383 | * | ||
384 | * PARAMETERS: internal_object - The internal object to be converted | ||
385 | * buffer_ptr - Where the object is returned | ||
386 | * | ||
387 | * RETURN: Status | ||
388 | * | ||
389 | * DESCRIPTION: This function is called to build an API object to be returned to | ||
390 | * the caller. | ||
391 | * | ||
392 | ******************************************************************************/ | ||
393 | |||
394 | acpi_status | ||
395 | acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object, | ||
396 | struct acpi_buffer *ret_buffer) | ||
397 | { | ||
398 | acpi_status status; | ||
399 | |||
400 | ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject); | ||
401 | |||
402 | if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) { | ||
403 | /* | ||
404 | * Package object: Copy all subobjects (including | ||
405 | * nested packages) | ||
406 | */ | ||
407 | status = acpi_ut_copy_ipackage_to_epackage(internal_object, | ||
408 | ret_buffer->pointer, | ||
409 | &ret_buffer->length); | ||
410 | } else { | ||
411 | /* | ||
412 | * Build a simple object (no nested objects) | ||
413 | */ | ||
414 | status = acpi_ut_copy_isimple_to_esimple(internal_object, | ||
415 | ACPI_CAST_PTR(union | ||
416 | acpi_object, | ||
417 | ret_buffer-> | ||
418 | pointer), | ||
419 | ACPI_ADD_PTR(u8, | ||
420 | ret_buffer-> | ||
421 | pointer, | ||
422 | ACPI_ROUND_UP_TO_NATIVE_WORD | ||
423 | (sizeof | ||
424 | (union | ||
425 | acpi_object))), | ||
426 | &ret_buffer->length); | ||
427 | /* | ||
428 | * build simple does not include the object size in the length | ||
429 | * so we add it in here | ||
430 | */ | ||
431 | ret_buffer->length += sizeof(union acpi_object); | ||
432 | } | ||
433 | |||
434 | return_ACPI_STATUS(status); | ||
435 | } | ||
436 | |||
437 | /******************************************************************************* | ||
438 | * | ||
439 | * FUNCTION: acpi_ut_copy_esimple_to_isimple | ||
440 | * | ||
441 | * PARAMETERS: external_object - The external object to be converted | ||
442 | * ret_internal_object - Where the internal object is returned | ||
443 | * | ||
444 | * RETURN: Status | ||
445 | * | ||
446 | * DESCRIPTION: This function copies an external object to an internal one. | ||
447 | * NOTE: Pointers can be copied, we don't need to copy data. | ||
448 | * (The pointers have to be valid in our address space no matter | ||
449 | * what we do with them!) | ||
450 | * | ||
451 | ******************************************************************************/ | ||
452 | |||
453 | static acpi_status | ||
454 | acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | ||
455 | union acpi_operand_object **ret_internal_object) | ||
456 | { | ||
457 | union acpi_operand_object *internal_object; | ||
458 | |||
459 | ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple); | ||
460 | |||
461 | /* | ||
462 | * Simple types supported are: String, Buffer, Integer | ||
463 | */ | ||
464 | switch (external_object->type) { | ||
465 | case ACPI_TYPE_STRING: | ||
466 | case ACPI_TYPE_BUFFER: | ||
467 | case ACPI_TYPE_INTEGER: | ||
468 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
469 | |||
470 | internal_object = acpi_ut_create_internal_object((u8) | ||
471 | external_object-> | ||
472 | type); | ||
473 | if (!internal_object) { | ||
474 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
475 | } | ||
476 | break; | ||
477 | |||
478 | case ACPI_TYPE_ANY: /* This is the case for a NULL object */ | ||
479 | |||
480 | *ret_internal_object = NULL; | ||
481 | return_ACPI_STATUS(AE_OK); | ||
482 | |||
483 | default: | ||
484 | /* All other types are not supported */ | ||
485 | |||
486 | ACPI_ERROR((AE_INFO, | ||
487 | "Unsupported object type, cannot convert to internal object: %s", | ||
488 | acpi_ut_get_type_name(external_object->type))); | ||
489 | |||
490 | return_ACPI_STATUS(AE_SUPPORT); | ||
491 | } | ||
492 | |||
493 | /* Must COPY string and buffer contents */ | ||
494 | |||
495 | switch (external_object->type) { | ||
496 | case ACPI_TYPE_STRING: | ||
497 | |||
498 | internal_object->string.pointer = | ||
499 | ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string. | ||
500 | length + 1); | ||
501 | if (!internal_object->string.pointer) { | ||
502 | goto error_exit; | ||
503 | } | ||
504 | |||
505 | ACPI_MEMCPY(internal_object->string.pointer, | ||
506 | external_object->string.pointer, | ||
507 | external_object->string.length); | ||
508 | |||
509 | internal_object->string.length = external_object->string.length; | ||
510 | break; | ||
511 | |||
512 | case ACPI_TYPE_BUFFER: | ||
513 | |||
514 | internal_object->buffer.pointer = | ||
515 | ACPI_ALLOCATE_ZEROED(external_object->buffer.length); | ||
516 | if (!internal_object->buffer.pointer) { | ||
517 | goto error_exit; | ||
518 | } | ||
519 | |||
520 | ACPI_MEMCPY(internal_object->buffer.pointer, | ||
521 | external_object->buffer.pointer, | ||
522 | external_object->buffer.length); | ||
523 | |||
524 | internal_object->buffer.length = external_object->buffer.length; | ||
525 | |||
526 | /* Mark buffer data valid */ | ||
527 | |||
528 | internal_object->buffer.flags |= AOPOBJ_DATA_VALID; | ||
529 | break; | ||
530 | |||
531 | case ACPI_TYPE_INTEGER: | ||
532 | |||
533 | internal_object->integer.value = external_object->integer.value; | ||
534 | break; | ||
535 | |||
536 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
537 | |||
538 | /* TBD: should validate incoming handle */ | ||
539 | |||
540 | internal_object->reference.class = ACPI_REFCLASS_NAME; | ||
541 | internal_object->reference.node = | ||
542 | external_object->reference.handle; | ||
543 | break; | ||
544 | |||
545 | default: | ||
546 | /* Other types can't get here */ | ||
547 | break; | ||
548 | } | ||
549 | |||
550 | *ret_internal_object = internal_object; | ||
551 | return_ACPI_STATUS(AE_OK); | ||
552 | |||
553 | error_exit: | ||
554 | acpi_ut_remove_reference(internal_object); | ||
555 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
556 | } | ||
557 | |||
558 | /******************************************************************************* | ||
559 | * | ||
560 | * FUNCTION: acpi_ut_copy_epackage_to_ipackage | ||
561 | * | ||
562 | * PARAMETERS: external_object - The external object to be converted | ||
563 | * internal_object - Where the internal object is returned | ||
564 | * | ||
565 | * RETURN: Status | ||
566 | * | ||
567 | * DESCRIPTION: Copy an external package object to an internal package. | ||
568 | * Handles nested packages. | ||
569 | * | ||
570 | ******************************************************************************/ | ||
571 | |||
572 | static acpi_status | ||
573 | acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, | ||
574 | union acpi_operand_object **internal_object) | ||
575 | { | ||
576 | acpi_status status = AE_OK; | ||
577 | union acpi_operand_object *package_object; | ||
578 | union acpi_operand_object **package_elements; | ||
579 | u32 i; | ||
580 | |||
581 | ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); | ||
582 | |||
583 | /* Create the package object */ | ||
584 | |||
585 | package_object = | ||
586 | acpi_ut_create_package_object(external_object->package.count); | ||
587 | if (!package_object) { | ||
588 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
589 | } | ||
590 | |||
591 | package_elements = package_object->package.elements; | ||
592 | |||
593 | /* | ||
594 | * Recursive implementation. Probably ok, since nested external packages | ||
595 | * as parameters should be very rare. | ||
596 | */ | ||
597 | for (i = 0; i < external_object->package.count; i++) { | ||
598 | status = | ||
599 | acpi_ut_copy_eobject_to_iobject(&external_object->package. | ||
600 | elements[i], | ||
601 | &package_elements[i]); | ||
602 | if (ACPI_FAILURE(status)) { | ||
603 | |||
604 | /* Truncate package and delete it */ | ||
605 | |||
606 | package_object->package.count = i; | ||
607 | package_elements[i] = NULL; | ||
608 | acpi_ut_remove_reference(package_object); | ||
609 | return_ACPI_STATUS(status); | ||
610 | } | ||
611 | } | ||
612 | |||
613 | /* Mark package data valid */ | ||
614 | |||
615 | package_object->package.flags |= AOPOBJ_DATA_VALID; | ||
616 | |||
617 | *internal_object = package_object; | ||
618 | return_ACPI_STATUS(status); | ||
619 | } | ||
620 | |||
621 | /******************************************************************************* | ||
622 | * | ||
623 | * FUNCTION: acpi_ut_copy_eobject_to_iobject | ||
624 | * | ||
625 | * PARAMETERS: external_object - The external object to be converted | ||
626 | * internal_object - Where the internal object is returned | ||
627 | * | ||
628 | * RETURN: Status - the status of the call | ||
629 | * | ||
630 | * DESCRIPTION: Converts an external object to an internal object. | ||
631 | * | ||
632 | ******************************************************************************/ | ||
633 | |||
634 | acpi_status | ||
635 | acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, | ||
636 | union acpi_operand_object **internal_object) | ||
637 | { | ||
638 | acpi_status status; | ||
639 | |||
640 | ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject); | ||
641 | |||
642 | if (external_object->type == ACPI_TYPE_PACKAGE) { | ||
643 | status = | ||
644 | acpi_ut_copy_epackage_to_ipackage(external_object, | ||
645 | internal_object); | ||
646 | } else { | ||
647 | /* | ||
648 | * Build a simple object (no nested objects) | ||
649 | */ | ||
650 | status = | ||
651 | acpi_ut_copy_esimple_to_isimple(external_object, | ||
652 | internal_object); | ||
653 | } | ||
654 | |||
655 | return_ACPI_STATUS(status); | ||
656 | } | ||
657 | |||
658 | /******************************************************************************* | ||
659 | * | ||
660 | * FUNCTION: acpi_ut_copy_simple_object | ||
661 | * | ||
662 | * PARAMETERS: source_desc - The internal object to be copied | ||
663 | * dest_desc - New target object | ||
664 | * | ||
665 | * RETURN: Status | ||
666 | * | ||
667 | * DESCRIPTION: Simple copy of one internal object to another. Reference count | ||
668 | * of the destination object is preserved. | ||
669 | * | ||
670 | ******************************************************************************/ | ||
671 | |||
672 | static acpi_status | ||
673 | acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | ||
674 | union acpi_operand_object *dest_desc) | ||
675 | { | ||
676 | u16 reference_count; | ||
677 | union acpi_operand_object *next_object; | ||
678 | |||
679 | /* Save fields from destination that we don't want to overwrite */ | ||
680 | |||
681 | reference_count = dest_desc->common.reference_count; | ||
682 | next_object = dest_desc->common.next_object; | ||
683 | |||
684 | /* Copy the entire source object over the destination object */ | ||
685 | |||
686 | ACPI_MEMCPY((char *)dest_desc, (char *)source_desc, | ||
687 | sizeof(union acpi_operand_object)); | ||
688 | |||
689 | /* Restore the saved fields */ | ||
690 | |||
691 | dest_desc->common.reference_count = reference_count; | ||
692 | dest_desc->common.next_object = next_object; | ||
693 | |||
694 | /* New object is not static, regardless of source */ | ||
695 | |||
696 | dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER; | ||
697 | |||
698 | /* Handle the objects with extra data */ | ||
699 | |||
700 | switch (ACPI_GET_OBJECT_TYPE(dest_desc)) { | ||
701 | case ACPI_TYPE_BUFFER: | ||
702 | /* | ||
703 | * Allocate and copy the actual buffer if and only if: | ||
704 | * 1) There is a valid buffer pointer | ||
705 | * 2) The buffer has a length > 0 | ||
706 | */ | ||
707 | if ((source_desc->buffer.pointer) && | ||
708 | (source_desc->buffer.length)) { | ||
709 | dest_desc->buffer.pointer = | ||
710 | ACPI_ALLOCATE(source_desc->buffer.length); | ||
711 | if (!dest_desc->buffer.pointer) { | ||
712 | return (AE_NO_MEMORY); | ||
713 | } | ||
714 | |||
715 | /* Copy the actual buffer data */ | ||
716 | |||
717 | ACPI_MEMCPY(dest_desc->buffer.pointer, | ||
718 | source_desc->buffer.pointer, | ||
719 | source_desc->buffer.length); | ||
720 | } | ||
721 | break; | ||
722 | |||
723 | case ACPI_TYPE_STRING: | ||
724 | /* | ||
725 | * Allocate and copy the actual string if and only if: | ||
726 | * 1) There is a valid string pointer | ||
727 | * (Pointer to a NULL string is allowed) | ||
728 | */ | ||
729 | if (source_desc->string.pointer) { | ||
730 | dest_desc->string.pointer = | ||
731 | ACPI_ALLOCATE((acpi_size) source_desc->string. | ||
732 | length + 1); | ||
733 | if (!dest_desc->string.pointer) { | ||
734 | return (AE_NO_MEMORY); | ||
735 | } | ||
736 | |||
737 | /* Copy the actual string data */ | ||
738 | |||
739 | ACPI_MEMCPY(dest_desc->string.pointer, | ||
740 | source_desc->string.pointer, | ||
741 | (acpi_size) source_desc->string.length + 1); | ||
742 | } | ||
743 | break; | ||
744 | |||
745 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
746 | /* | ||
747 | * We copied the reference object, so we now must add a reference | ||
748 | * to the object pointed to by the reference | ||
749 | * | ||
750 | * DDBHandle reference (from Load/load_table) is a special reference, | ||
751 | * it does not have a Reference.Object, so does not need to | ||
752 | * increase the reference count | ||
753 | */ | ||
754 | if (source_desc->reference.class == ACPI_REFCLASS_TABLE) { | ||
755 | break; | ||
756 | } | ||
757 | |||
758 | acpi_ut_add_reference(source_desc->reference.object); | ||
759 | break; | ||
760 | |||
761 | case ACPI_TYPE_REGION: | ||
762 | /* | ||
763 | * We copied the Region Handler, so we now must add a reference | ||
764 | */ | ||
765 | if (dest_desc->region.handler) { | ||
766 | acpi_ut_add_reference(dest_desc->region.handler); | ||
767 | } | ||
768 | break; | ||
769 | |||
770 | default: | ||
771 | /* Nothing to do for other simple objects */ | ||
772 | break; | ||
773 | } | ||
774 | |||
775 | return (AE_OK); | ||
776 | } | ||
777 | |||
778 | /******************************************************************************* | ||
779 | * | ||
780 | * FUNCTION: acpi_ut_copy_ielement_to_ielement | ||
781 | * | ||
782 | * PARAMETERS: acpi_pkg_callback | ||
783 | * | ||
784 | * RETURN: Status | ||
785 | * | ||
786 | * DESCRIPTION: Copy one package element to another package element | ||
787 | * | ||
788 | ******************************************************************************/ | ||
789 | |||
790 | static acpi_status | ||
791 | acpi_ut_copy_ielement_to_ielement(u8 object_type, | ||
792 | union acpi_operand_object *source_object, | ||
793 | union acpi_generic_state *state, | ||
794 | void *context) | ||
795 | { | ||
796 | acpi_status status = AE_OK; | ||
797 | u32 this_index; | ||
798 | union acpi_operand_object **this_target_ptr; | ||
799 | union acpi_operand_object *target_object; | ||
800 | |||
801 | ACPI_FUNCTION_ENTRY(); | ||
802 | |||
803 | this_index = state->pkg.index; | ||
804 | this_target_ptr = (union acpi_operand_object **) | ||
805 | &state->pkg.dest_object->package.elements[this_index]; | ||
806 | |||
807 | switch (object_type) { | ||
808 | case ACPI_COPY_TYPE_SIMPLE: | ||
809 | |||
810 | /* A null source object indicates a (legal) null package element */ | ||
811 | |||
812 | if (source_object) { | ||
813 | /* | ||
814 | * This is a simple object, just copy it | ||
815 | */ | ||
816 | target_object = | ||
817 | acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE | ||
818 | (source_object)); | ||
819 | if (!target_object) { | ||
820 | return (AE_NO_MEMORY); | ||
821 | } | ||
822 | |||
823 | status = | ||
824 | acpi_ut_copy_simple_object(source_object, | ||
825 | target_object); | ||
826 | if (ACPI_FAILURE(status)) { | ||
827 | goto error_exit; | ||
828 | } | ||
829 | |||
830 | *this_target_ptr = target_object; | ||
831 | } else { | ||
832 | /* Pass through a null element */ | ||
833 | |||
834 | *this_target_ptr = NULL; | ||
835 | } | ||
836 | break; | ||
837 | |||
838 | case ACPI_COPY_TYPE_PACKAGE: | ||
839 | |||
840 | /* | ||
841 | * This object is a package - go down another nesting level | ||
842 | * Create and build the package object | ||
843 | */ | ||
844 | target_object = | ||
845 | acpi_ut_create_package_object(source_object->package.count); | ||
846 | if (!target_object) { | ||
847 | return (AE_NO_MEMORY); | ||
848 | } | ||
849 | |||
850 | target_object->common.flags = source_object->common.flags; | ||
851 | |||
852 | /* Pass the new package object back to the package walk routine */ | ||
853 | |||
854 | state->pkg.this_target_obj = target_object; | ||
855 | |||
856 | /* Store the object pointer in the parent package object */ | ||
857 | |||
858 | *this_target_ptr = target_object; | ||
859 | break; | ||
860 | |||
861 | default: | ||
862 | return (AE_BAD_PARAMETER); | ||
863 | } | ||
864 | |||
865 | return (status); | ||
866 | |||
867 | error_exit: | ||
868 | acpi_ut_remove_reference(target_object); | ||
869 | return (status); | ||
870 | } | ||
871 | |||
872 | /******************************************************************************* | ||
873 | * | ||
874 | * FUNCTION: acpi_ut_copy_ipackage_to_ipackage | ||
875 | * | ||
876 | * PARAMETERS: *source_obj - Pointer to the source package object | ||
877 | * *dest_obj - Where the internal object is returned | ||
878 | * | ||
879 | * RETURN: Status - the status of the call | ||
880 | * | ||
881 | * DESCRIPTION: This function is called to copy an internal package object | ||
882 | * into another internal package object. | ||
883 | * | ||
884 | ******************************************************************************/ | ||
885 | |||
886 | static acpi_status | ||
887 | acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, | ||
888 | union acpi_operand_object *dest_obj, | ||
889 | struct acpi_walk_state *walk_state) | ||
890 | { | ||
891 | acpi_status status = AE_OK; | ||
892 | |||
893 | ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage); | ||
894 | |||
895 | dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj); | ||
896 | dest_obj->common.flags = source_obj->common.flags; | ||
897 | dest_obj->package.count = source_obj->package.count; | ||
898 | |||
899 | /* | ||
900 | * Create the object array and walk the source package tree | ||
901 | */ | ||
902 | dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) | ||
903 | source_obj->package. | ||
904 | count + | ||
905 | 1) * sizeof(void *)); | ||
906 | if (!dest_obj->package.elements) { | ||
907 | ACPI_ERROR((AE_INFO, "Package allocation failure")); | ||
908 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
909 | } | ||
910 | |||
911 | /* | ||
912 | * Copy the package element-by-element by walking the package "tree". | ||
913 | * This handles nested packages of arbitrary depth. | ||
914 | */ | ||
915 | status = acpi_ut_walk_package_tree(source_obj, dest_obj, | ||
916 | acpi_ut_copy_ielement_to_ielement, | ||
917 | walk_state); | ||
918 | if (ACPI_FAILURE(status)) { | ||
919 | |||
920 | /* On failure, delete the destination package object */ | ||
921 | |||
922 | acpi_ut_remove_reference(dest_obj); | ||
923 | } | ||
924 | |||
925 | return_ACPI_STATUS(status); | ||
926 | } | ||
927 | |||
928 | /******************************************************************************* | ||
929 | * | ||
930 | * FUNCTION: acpi_ut_copy_iobject_to_iobject | ||
931 | * | ||
932 | * PARAMETERS: walk_state - Current walk state | ||
933 | * source_desc - The internal object to be copied | ||
934 | * dest_desc - Where the copied object is returned | ||
935 | * | ||
936 | * RETURN: Status | ||
937 | * | ||
938 | * DESCRIPTION: Copy an internal object to a new internal object | ||
939 | * | ||
940 | ******************************************************************************/ | ||
941 | |||
942 | acpi_status | ||
943 | acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, | ||
944 | union acpi_operand_object **dest_desc, | ||
945 | struct acpi_walk_state *walk_state) | ||
946 | { | ||
947 | acpi_status status = AE_OK; | ||
948 | |||
949 | ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject); | ||
950 | |||
951 | /* Create the top level object */ | ||
952 | |||
953 | *dest_desc = | ||
954 | acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc)); | ||
955 | if (!*dest_desc) { | ||
956 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
957 | } | ||
958 | |||
959 | /* Copy the object and possible subobjects */ | ||
960 | |||
961 | if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) { | ||
962 | status = | ||
963 | acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc, | ||
964 | walk_state); | ||
965 | } else { | ||
966 | status = acpi_ut_copy_simple_object(source_desc, *dest_desc); | ||
967 | } | ||
968 | |||
969 | return_ACPI_STATUS(status); | ||
970 | } | ||