acpi_status acpi_ex_store_object_to_index ( union acpi_operand_object *source_desc, union acpi_operand_object *index_desc, struct acpi_walk_state *walk_state) { acpi_status status = AE_OK; union acpi_operand_object *obj_desc; union acpi_operand_object *new_desc; u8 value = 0; u32 i; ACPI_FUNCTION_TRACE ("ex_store_object_to_index"); /* * Destination must be a reference pointer, and * must point to either a buffer or a package */ switch (index_desc->reference.target_type) { case ACPI_TYPE_PACKAGE: /* * Storing to a package element is not simple. The source must be * evaluated and converted to the type of the destination and then the * source is copied into the destination - we can't just point to the * source object. */ /* * The object at *(index_desc->Reference.Where) is the * element within the package that is to be modified. * The parent package object is at index_desc->Reference.Object */ obj_desc = *(index_desc->reference.where); /* Do the conversion/store */ status = acpi_ex_store_object_to_object (source_desc, obj_desc, &new_desc, walk_state); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not store object to indexed package element\n")); return_ACPI_STATUS (status); } /* * If a new object was created, we must install it as the new * package element */ if (new_desc != obj_desc) { acpi_ut_remove_reference (obj_desc); *(index_desc->reference.where) = new_desc; /* If same as the original source, add a reference */ if (new_desc == source_desc) { acpi_ut_add_reference (new_desc); } /* Increment reference count by the ref count of the parent package -1 */ for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) { acpi_ut_add_reference (new_desc); } } break; case ACPI_TYPE_BUFFER_FIELD: /* * Store into a Buffer (not actually a real buffer_field) at a * location defined by an Index. * * The first 8-bit element of the source object is written to the * 8-bit Buffer location defined by the Index destination object, * according to the ACPI 2.0 specification. */ /* * Make sure the target is a Buffer */ obj_desc = index_desc->reference.object; if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) { return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* * The assignment of the individual elements will be slightly * different for each source type. */ switch (ACPI_GET_OBJECT_TYPE (source_desc)) { case ACPI_TYPE_INTEGER: /* Use the least-significant byte of the integer */ value = (u8) (source_desc->integer.value); break; case ACPI_TYPE_BUFFER: value = source_desc->buffer.pointer[0]; break; case ACPI_TYPE_STRING: value = (u8) source_desc->string.pointer[0]; break; default: /* All other types are invalid */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Source must be Integer/Buffer/String type, not %s\n", acpi_ut_get_object_type_name (source_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Store the source value into the target buffer byte */ obj_desc->buffer.pointer[index_desc->reference.offset] = value; break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Target is not a Package or buffer_field\n")); status = AE_AML_OPERAND_TYPE; break; } return_ACPI_STATUS (status); }
acpi_status acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, struct acpi_namespace_node *node, struct acpi_walk_state *walk_state, u8 implicit_conversion) { acpi_status status = AE_OK; union acpi_operand_object *target_desc; union acpi_operand_object *new_desc; acpi_object_type target_type; ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc); /* Get current type of the node, and object attached to Node */ target_type = acpi_ns_get_type(node); target_desc = acpi_ns_get_attached_object(node); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", source_desc, acpi_ut_get_object_type_name(source_desc), node, acpi_ut_get_type_name(target_type))); /* * Resolve the source object to an actual value * (If it is a reference object) */ status = acpi_ex_resolve_object(&source_desc, target_type, walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* If no implicit conversion, drop into the default case below */ if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { /* Force execution of default (no implicit conversion) */ target_type = ACPI_TYPE_ANY; } /* Do the actual store operation */ switch (target_type) { case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: /* For fields, copy the source data to the target field. */ status = acpi_ex_write_data_to_field(source_desc, target_desc, &walk_state->result_obj); break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These target types are all of type Integer/String/Buffer, and * therefore support implicit conversion before the store. * * Copy and/or convert the source object to a new target object */ status = acpi_ex_store_object_to_object(source_desc, target_desc, &new_desc, walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (new_desc != target_desc) { /* * Store the new new_desc as the new value of the Name, and set * the Name's type to that of the value being stored in it. * source_desc reference count is incremented by attach_object. * * Note: This may change the type of the node if an explicit store * has been performed such that the node/object type has been * changed. */ status = acpi_ns_attach_object(node, new_desc, new_desc->common.type); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Store %s into %s via Convert/Attach\n", acpi_ut_get_object_type_name (source_desc), acpi_ut_get_object_type_name (new_desc))); } break; default: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %s (%p) directly into node (%p) with no implicit conversion\n", acpi_ut_get_object_type_name(source_desc), source_desc, node)); /* No conversions for all other types. Just attach the source object */ status = acpi_ns_attach_object(node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc)); break; } return_ACPI_STATUS(status); }
acpi_status acpi_ut_copy_ielement_to_ielement ( u8 object_type, acpi_operand_object *source_object, acpi_generic_state *state, void *context) { acpi_status status = AE_OK; u32 this_index; acpi_operand_object **this_target_ptr; acpi_operand_object *target_object; FUNCTION_ENTRY (); this_index = state->pkg.index; this_target_ptr = (acpi_operand_object **) &state->pkg.dest_object->package.elements[this_index]; switch (object_type) { case 0: /* * This is a simple object, just copy it */ target_object = acpi_ut_create_internal_object (source_object->common.type); if (!target_object) { return (AE_NO_MEMORY); } status = acpi_ex_store_object_to_object (source_object, target_object, (acpi_walk_state *) context); if (ACPI_FAILURE (status)) { return (status); } *this_target_ptr = target_object; break; case 1: /* * This object is a package - go down another nesting level * Create and build the package object */ target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE); if (!target_object) { /* TBD: must delete package created up to this point */ return (AE_NO_MEMORY); } target_object->package.count = source_object->package.count; /* * Pass the new package object back to the package walk routine */ state->pkg.this_target_obj = target_object; /* * Store the object pointer in the parent package object */ *this_target_ptr = target_object; break; default: return (AE_BAD_PARAMETER); } return (status); }