utcopy.c

来自「linux 内核源代码」· C语言 代码 · 共 926 行 · 第 1/2 页

C
926
字号
		}		break;	default:		/* All other types are not supported */		return_ACPI_STATUS(AE_SUPPORT);	}	/* Must COPY string and buffer contents */	switch (external_object->type) {	case ACPI_TYPE_STRING:		internal_object->string.pointer =		    ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.					 length + 1);		if (!internal_object->string.pointer) {			goto error_exit;		}		ACPI_MEMCPY(internal_object->string.pointer,			    external_object->string.pointer,			    external_object->string.length);		internal_object->string.length = external_object->string.length;		break;	case ACPI_TYPE_BUFFER:		internal_object->buffer.pointer =		    ACPI_ALLOCATE_ZEROED(external_object->buffer.length);		if (!internal_object->buffer.pointer) {			goto error_exit;		}		ACPI_MEMCPY(internal_object->buffer.pointer,			    external_object->buffer.pointer,			    external_object->buffer.length);		internal_object->buffer.length = external_object->buffer.length;		break;	case ACPI_TYPE_INTEGER:		internal_object->integer.value = external_object->integer.value;		break;	default:		/* Other types can't get here */		break;	}	*ret_internal_object = internal_object;	return_ACPI_STATUS(AE_OK);      error_exit:	acpi_ut_remove_reference(internal_object);	return_ACPI_STATUS(AE_NO_MEMORY);}/******************************************************************************* * * 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_statusacpi_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;	acpi_native_uint i;	ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);	/* Create the package object */	package_object =	    acpi_ut_create_package_object(external_object->package.count);	if (!package_object) {		return_ACPI_STATUS(AE_NO_MEMORY);	}	package_elements = package_object->package.elements;	/*	 * 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)) {			/* Truncate package and delete it */			package_object->package.count = i;			package_elements[i] = NULL;			acpi_ut_remove_reference(package_object);			return_ACPI_STATUS(status);		}	}	*internal_object = package_object;	return_ACPI_STATUS(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              - the status of the call * * DESCRIPTION: Converts an external object to an internal object. * ******************************************************************************/acpi_statusacpi_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_statusacpi_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;	/* Save fields from destination that we don't want to overwrite */	reference_count = dest_desc->common.reference_count;	next_object = dest_desc->common.next_object;	/* Copy the entire source object over the destination object */	ACPI_MEMCPY((char *)dest_desc, (char *)source_desc,		    sizeof(union acpi_operand_object));	/* Restore the saved fields */	dest_desc->common.reference_count = reference_count;	dest_desc->common.next_object = next_object;	/* New object is not static, regardless of source */	dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;	/* Handle the objects with extra data */	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {	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);			}			/* Copy the actual buffer data */			ACPI_MEMCPY(dest_desc->buffer.pointer,				    source_desc->buffer.pointer,				    source_desc->buffer.length);		}		break;	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);			}			/* Copy the actual string data */			ACPI_MEMCPY(dest_desc->string.pointer,				    source_desc->string.pointer,				    (acpi_size) source_desc->string.length + 1);		}		break;	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		 */		acpi_ut_add_reference(source_desc->reference.object);		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;	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_statusacpi_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;	ACPI_FUNCTION_ENTRY();	this_index = state->pkg.index;	this_target_ptr = (union acpi_operand_object **)	    &state->pkg.dest_object->package.elements[this_index];	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(ACPI_GET_OBJECT_TYPE							   (source_object));			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);		}		target_object->common.flags = source_object->common.flags;		/* 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);      error_exit:	acpi_ut_remove_reference(target_object);	return (status);}/******************************************************************************* * * FUNCTION:    acpi_ut_copy_ipackage_to_ipackage * * PARAMETERS:  *source_obj     - Pointer to the source package object *              *dest_obj       - Where the internal object is returned * * RETURN:      Status          - the status of the call * * DESCRIPTION: This function is called to copy an internal package object *              into another internal package object. * ******************************************************************************/static acpi_statusacpi_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;	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);	dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);	dest_obj->common.flags = source_obj->common.flags;	dest_obj->package.count = source_obj->package.count;	/*	 * 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);	if (ACPI_FAILURE(status)) {		/* On failure, delete the destination package object */		acpi_ut_remove_reference(dest_obj);	}	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ut_copy_iobject_to_iobject * * PARAMETERS:  walk_state          - Current walk state *              source_desc         - The internal object to be copied *              dest_desc           - Where the copied object is returned * * RETURN:      Status * * DESCRIPTION: Copy an internal object to a new internal object * ******************************************************************************/acpi_statusacpi_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(ACPI_GET_OBJECT_TYPE(source_desc));	if (!*dest_desc) {		return_ACPI_STATUS(AE_NO_MEMORY);	}	/* Copy the object and possible subobjects */	if (ACPI_GET_OBJECT_TYPE(source_desc) == 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);	}	return_ACPI_STATUS(status);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?