/******************************************************************************* * * FUNCTION: acpi_ut_copy_isimple_to_esimple * * PARAMETERS: internal_object - Source object to be copied * external_object - Where to return the copied object * data_space - Where object data is returned (such as * buffer and string data) * buffer_space_used - Length of data_space that was used * * RETURN: Status * * DESCRIPTION: This function is called to copy a simple internal object to * an external object. * * The data_space buffer is assumed to have sufficient space for * the object. *
******************************************************************************/
static acpi_status
acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, union acpi_object *external_object,
u8 *data_space, acpi_size *buffer_space_used)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
*buffer_space_used = 0;
/* * Check for NULL object case (could be an uninitialized * package element)
*/ if (!internal_object) {
return_ACPI_STATUS(AE_OK);
}
switch (internal_object->reference.class) { case ACPI_REFCLASS_NAME: /* * For namepath, return the object handle ("reference") * We are referring to the namespace node
*/
external_object->reference.handle =
internal_object->reference.node;
external_object->reference.actual_type =
acpi_ns_get_type(internal_object->reference.node); break;
default: /* * There is no corresponding external object type
*/
ACPI_ERROR((AE_INFO, "Unsupported object type, cannot convert to external object: %s",
acpi_ut_get_type_name(internal_object->common.
type)));
return_ACPI_STATUS(AE_SUPPORT);
}
return_ACPI_STATUS(status);
}
/******************************************************************************* * * FUNCTION: acpi_ut_copy_ielement_to_eelement * * PARAMETERS: acpi_pkg_callback * * RETURN: Status * * DESCRIPTION: Copy one package element to another package element *
******************************************************************************/
static acpi_status
acpi_ut_copy_ielement_to_eelement(u8 object_type, union acpi_operand_object *source_object, union acpi_generic_state *state, void *context)
{
acpi_status status = AE_OK; struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
acpi_size object_space;
u32 this_index; union acpi_object *target_object;
switch (object_type) { case ACPI_COPY_TYPE_SIMPLE: /* * This is a simple or null object
*/
status = acpi_ut_copy_isimple_to_esimple(source_object,
target_object,
info->free_space,
&object_space); if (ACPI_FAILURE(status)) { return (status);
} break;
case ACPI_COPY_TYPE_PACKAGE: /* * Build the package object
*/
target_object->type = ACPI_TYPE_PACKAGE;
target_object->package.count = source_object->package.count;
target_object->package.elements =
ACPI_CAST_PTR(union acpi_object, info->free_space);
/* * Pass the new package object back to the package walk routine
*/
state->pkg.this_target_obj = target_object;
/* * Save space for the array of objects (Package elements) * update the buffer length counter
*/
object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
target_object->
package.count * sizeof(union
acpi_object)); break;
/******************************************************************************* * * FUNCTION: acpi_ut_copy_ipackage_to_epackage * * PARAMETERS: internal_object - Pointer to the object we are returning * buffer - Where the object is returned * space_used - Where the object length is returned * * RETURN: Status * * DESCRIPTION: This function is called to place a package object in a user * buffer. A package object by definition contains other objects. * * The buffer is assumed to have sufficient space for the object. * The caller must have verified the buffer length needed using * the acpi_ut_get_object_size function before calling this function. *
******************************************************************************/
/* * Leave room for an array of ACPI_OBJECTS in the buffer * and move the free space past it
*/
info.length += (acpi_size)external_object->package.count *
ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
info.free_space += external_object->package.count *
ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
status = acpi_ut_walk_package_tree(internal_object, external_object,
acpi_ut_copy_ielement_to_eelement,
&info);
/******************************************************************************* * * FUNCTION: acpi_ut_copy_iobject_to_eobject * * PARAMETERS: internal_object - The internal object to be converted * ret_buffer - Where the object is returned * * RETURN: Status * * DESCRIPTION: This function is called to build an API object to be returned * to the caller. *
******************************************************************************/
if (internal_object->common.type == ACPI_TYPE_PACKAGE) { /* * Package object: Copy all subobjects (including * nested packages)
*/
status = acpi_ut_copy_ipackage_to_epackage(internal_object,
ret_buffer->pointer,
&ret_buffer->length);
} else { /* * Build a simple object (no nested objects)
*/
status = acpi_ut_copy_isimple_to_esimple(internal_object,
ACPI_CAST_PTR(union
acpi_object,
ret_buffer->
pointer),
ACPI_ADD_PTR(u8,
ret_buffer->
pointer,
ACPI_ROUND_UP_TO_NATIVE_WORD
(sizeof
(union
acpi_object))),
&ret_buffer->length); /* * build simple does not include the object size in the length * so we add it in here
*/
ret_buffer->length += sizeof(union acpi_object);
}
return_ACPI_STATUS(status);
}
/******************************************************************************* * * FUNCTION: acpi_ut_copy_esimple_to_isimple * * PARAMETERS: external_object - The external object to be converted * ret_internal_object - Where the internal object is returned * * RETURN: Status * * DESCRIPTION: This function copies an external object to an internal one. * NOTE: Pointers can be copied, we don't need to copy data. * (The pointers have to be valid in our address space no matter * what we do with them!) *
******************************************************************************/
static acpi_status
acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, union acpi_operand_object **ret_internal_object)
{ union acpi_operand_object *internal_object;
ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
/* * Simple types supported are: String, Buffer, Integer
*/ switch (external_object->type) { case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: case ACPI_TYPE_INTEGER: case ACPI_TYPE_LOCAL_REFERENCE:
/******************************************************************************* * * FUNCTION: acpi_ut_copy_epackage_to_ipackage * * PARAMETERS: external_object - The external object to be converted * internal_object - Where the internal object is returned * * RETURN: Status * * DESCRIPTION: Copy an external package object to an internal package. * Handles nested packages. *
******************************************************************************/
static acpi_status
acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, union acpi_operand_object **internal_object)
{
acpi_status status = AE_OK; union acpi_operand_object *package_object; union acpi_operand_object **package_elements;
u32 i;
/* * Recursive implementation. Probably ok, since nested external * packages as parameters should be very rare.
*/ for (i = 0; i < external_object->package.count; i++) {
status =
acpi_ut_copy_eobject_to_iobject(&external_object->package.
elements[i],
&package_elements[i]); if (ACPI_FAILURE(status)) {
/******************************************************************************* * * FUNCTION: acpi_ut_copy_eobject_to_iobject * * PARAMETERS: external_object - The external object to be converted * internal_object - Where the internal object is returned * * RETURN: Status * * DESCRIPTION: Converts an external object to an internal object. *
******************************************************************************/
acpi_status
acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, union acpi_operand_object **internal_object)
{
acpi_status status;
ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
if (external_object->type == ACPI_TYPE_PACKAGE) {
status =
acpi_ut_copy_epackage_to_ipackage(external_object,
internal_object);
} else { /* * Build a simple object (no nested objects)
*/
status = acpi_ut_copy_esimple_to_isimple(external_object,
internal_object);
}
return_ACPI_STATUS(status);
}
/******************************************************************************* * * FUNCTION: acpi_ut_copy_simple_object * * PARAMETERS: source_desc - The internal object to be copied * dest_desc - New target object * * RETURN: Status * * DESCRIPTION: Simple copy of one internal object to another. Reference count * of the destination object is preserved. *
******************************************************************************/
static acpi_status
acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, union acpi_operand_object *dest_desc)
{
u16 reference_count; union acpi_operand_object *next_object;
acpi_status status;
acpi_size copy_size;
/* Save fields from destination that we don't want to overwrite */
/* * Copy the entire source object over the destination object. * Note: Source can be either an operand object or namespace node.
*/
copy_size = sizeof(union acpi_operand_object); if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
copy_size = sizeof(struct acpi_namespace_node);
}
switch (dest_desc->common.type) { case ACPI_TYPE_BUFFER: /* * Allocate and copy the actual buffer if and only if: * 1) There is a valid buffer pointer * 2) The buffer has a length > 0
*/ if ((source_desc->buffer.pointer) &&
(source_desc->buffer.length)) {
dest_desc->buffer.pointer =
ACPI_ALLOCATE(source_desc->buffer.length); if (!dest_desc->buffer.pointer) { return (AE_NO_MEMORY);
}
case ACPI_TYPE_STRING: /* * Allocate and copy the actual string if and only if: * 1) There is a valid string pointer * (Pointer to a NULL string is allowed)
*/ if (source_desc->string.pointer) {
dest_desc->string.pointer =
ACPI_ALLOCATE((acpi_size)source_desc->string.
length + 1); if (!dest_desc->string.pointer) { return (AE_NO_MEMORY);
}
case ACPI_TYPE_LOCAL_REFERENCE: /* * We copied the reference object, so we now must add a reference * to the object pointed to by the reference * * DDBHandle reference (from Load/load_table) is a special reference, * it does not have a Reference.Object, so does not need to * increase the reference count
*/ if (source_desc->reference.class == ACPI_REFCLASS_TABLE) { break;
}
case ACPI_TYPE_REGION: /* * We copied the Region Handler, so we now must add a reference
*/ if (dest_desc->region.handler) {
acpi_ut_add_reference(dest_desc->region.handler);
} break;
/* * For Mutex and Event objects, we cannot simply copy the underlying * OS object. We must create a new one.
*/ case ACPI_TYPE_MUTEX:
status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex); if (ACPI_FAILURE(status)) { return (status);
} break;
case ACPI_TYPE_EVENT:
status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
&dest_desc->event.
os_semaphore); if (ACPI_FAILURE(status)) { return (status);
} break;
default:
/* Nothing to do for other simple objects */
break;
}
return (AE_OK);
}
/******************************************************************************* * * FUNCTION: acpi_ut_copy_ielement_to_ielement * * PARAMETERS: acpi_pkg_callback * * RETURN: Status * * DESCRIPTION: Copy one package element to another package element *
******************************************************************************/
static acpi_status
acpi_ut_copy_ielement_to_ielement(u8 object_type, union acpi_operand_object *source_object, union acpi_generic_state *state, void *context)
{
acpi_status status = AE_OK;
u32 this_index; union acpi_operand_object **this_target_ptr; union acpi_operand_object *target_object;
switch (object_type) { case ACPI_COPY_TYPE_SIMPLE:
/* A null source object indicates a (legal) null package element */
if (source_object) { /* * 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_ut_copy_simple_object(source_object,
target_object); if (ACPI_FAILURE(status)) { goto error_exit;
}
*this_target_ptr = target_object;
} else { /* Pass through a null element */
*this_target_ptr = NULL;
} break;
case ACPI_COPY_TYPE_PACKAGE: /* * This object is a package - go down another nesting level * Create and build the package object
*/
target_object =
acpi_ut_create_package_object(source_object->package.count); if (!target_object) { return (AE_NO_MEMORY);
}
/******************************************************************************* * * FUNCTION: acpi_ut_copy_ipackage_to_ipackage * * PARAMETERS: source_obj - Pointer to the source package object * dest_obj - Where the internal object is returned * walk_state - Current Walk state descriptor * * RETURN: Status * * DESCRIPTION: This function is called to copy an internal package object * into another internal package object. *
******************************************************************************/
static acpi_status
acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, union acpi_operand_object *dest_obj, struct acpi_walk_state *walk_state)
{
acpi_status status = AE_OK;
/* * Create the object array and walk the source package tree
*/
dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
source_obj->package.
count +
1) * sizeof(void *)); if (!dest_obj->package.elements) {
ACPI_ERROR((AE_INFO, "Package allocation failure"));
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* * Copy the package element-by-element by walking the package "tree". * This handles nested packages of arbitrary depth.
*/
status = acpi_ut_walk_package_tree(source_obj, dest_obj,
acpi_ut_copy_ielement_to_ielement,
walk_state);
return_ACPI_STATUS(status);
}
/******************************************************************************* * * FUNCTION: acpi_ut_copy_iobject_to_iobject * * PARAMETERS: source_desc - The internal object to be copied * dest_desc - Where the copied object is returned * walk_state - Current walk state * * RETURN: Status * * DESCRIPTION: Copy an internal object to a new internal object *
******************************************************************************/
acpi_status
acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, union acpi_operand_object **dest_desc, struct acpi_walk_state *walk_state)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
/* Create the top level object */
*dest_desc = acpi_ut_create_internal_object(source_desc->common.type); if (!*dest_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the object and possible subobjects */
if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
walk_state);
} else {
status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
}
/* Delete the allocated object if copy failed */
if (ACPI_FAILURE(status)) {
acpi_ut_remove_reference(*dest_desc);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.