FreeBSD/sys/dev/drm2/ttm/ttm_bo_util.c
/**
 * ttm_buffer_object_transfer
 *
 * @bo: A pointer to a struct ttm_buffer_object.
 * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
 * holding the data of @bo with the old placement.
 *
 * This is a utility function that may be called after an accelerated move
 * has been scheduled. A new buffer object is created as a placeholder for
 * the old data while it's being copied. When that buffer object is idle,
 * it can be destroyed, releasing the space of the old placement.
 * Returns:
 * !0: Failure.
 */
ttm_buffer_object_transfer
@bo: A pointer to a struct ttm_buffer_object.
@new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
holding the data of @bo with the old placement.

This is a utility function that may be called after an accelerated move
has been scheduled. A new buffer object is created as a placeholder for
the old data while it's being copied. When that buffer object is idle,
it can be destroyed, releasing the space of the old placement.
Returns:
!0: Failure.
ttm_buffer_object_transfer @bo : A pointer to a struct ttm_buffer_object . @new_obj : A pointer to a pointer to a newly created ttm_buffer_object holding the data of @bo with the old placement . This is a utility function that may be called after an accelerated move has been scheduled . A new buffer object is created as a placeholder for the old data while it ' s being copied . When that buffer object is idle it can be destroyed releasing the space of the old placement . Returns : !0 : Failure .
static int
ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
    struct ttm_buffer_object **new_obj)
{
	struct ttm_buffer_object *fbo;
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_bo_driver *driver = bdev->driver;
	fbo = malloc(sizeof(*fbo), M_TTM_TRANSF_OBJ, M_WAITOK);
	*fbo = *bo;
	INIT_LIST_HEAD(&fbo->ddestroy);
	INIT_LIST_HEAD(&fbo->lru);
	INIT_LIST_HEAD(&fbo->swap);
	INIT_LIST_HEAD(&fbo->io_reserve_lru);
	fbo->vm_node = NULL;
	atomic_set(&fbo->cpu_writers, 0);
	mtx_lock(&bdev->fence_lock);
	if (bo->sync_obj)
		fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
	else
		fbo->sync_obj = NULL;
	mtx_unlock(&bdev->fence_lock);
	refcount_init(&fbo->list_kref, 1);
	refcount_init(&fbo->kref, 1);
	fbo->destroy = &ttm_transfered_destroy;
	fbo->acc_size = 0;
	*new_obj = fbo;
	return 0;
}
static int ttm_buffer_object_transfer ( struct ttm_buffer_object * bo , struct ttm_buffer_object * * new_obj ) { struct ttm_buffer_object * fbo ; struct ttm_bo_device * bdev = bo -> bdev ; struct ttm_bo_driver * driver = bdev -> driver ; fbo = malloc ( sizeof ( * fbo ) , M_TTM_TRANSF_OBJ , M_WAITOK ) ; * fbo = * bo ; INIT_LIST_HEAD ( & fbo -> ddestroy ) ; INIT_LIST_HEAD ( & fbo -> lru ) ; INIT_LIST_HEAD ( & fbo -> swap ) ; INIT_LIST_HEAD ( & fbo -> io_reserve_lru ) ; fbo -> vm_node = NULL ; atomic_set ( & fbo -> cpu_writers , 0 ) ; mtx_lock ( & bdev -> fence_lock ) ; if ( bo -> sync_obj ) fbo -> sync_obj = driver -> sync_obj_ref ( bo -> sync_obj ) ; else fbo -> sync_obj = NULL ; mtx_unlock ( & bdev -> fence_lock ) ; refcount_init ( & fbo -> list_kref , 1 ) ; refcount_init ( & fbo -> kref , 1 ) ; fbo -> destroy = & ttm_transfered_destroy ; fbo -> acc_size = 0 ; * new_obj = fbo ; return 0 ; }
ttm_buffer_object_transfer
 @bo: A pointer to a struct ttm_buffer_object.
ttm_buffer_object_transfer @bo : A pointer to a struct ttm_buffer_object .
/**
	 * Fix up members that we shouldn't copy directly:
	 * TODO: Explicit member copy would probably be better here.
	 */