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