diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_resource.c')
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 73 | 
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec7..2c6ffe0e2c0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -1917,3 +1917,76 @@ err_ref:  	vmw_resource_unreference(&res);  	return ret;  } + + +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args) +{ +	struct vmw_private *dev_priv = vmw_priv(dev); +	struct vmw_master *vmaster = vmw_master(file_priv->master); +	struct vmw_user_dma_buffer *vmw_user_bo; +	struct ttm_buffer_object *tmp; +	int ret; + +	args->pitch = args->width * ((args->bpp + 7) / 8); +	args->size = args->pitch * args->height; + +	vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); +	if (vmw_user_bo == NULL) +		return -ENOMEM; + +	ret = ttm_read_lock(&vmaster->lock, true); +	if (ret != 0) { +		kfree(vmw_user_bo); +		return ret; +	} + +	ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, +			      &vmw_vram_sys_placement, true, +			      &vmw_user_dmabuf_destroy); +	if (ret != 0) +		goto out_no_dmabuf; + +	tmp = ttm_bo_reference(&vmw_user_bo->dma.base); +	ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, +				   &vmw_user_bo->base, +				   false, +				   ttm_buffer_type, +				   &vmw_user_dmabuf_release, NULL); +	if (unlikely(ret != 0)) +		goto out_no_base_object; + +	args->handle = vmw_user_bo->base.hash.key; + +out_no_base_object: +	ttm_bo_unref(&tmp); +out_no_dmabuf: +	ttm_read_unlock(&vmaster->lock); +	return ret; +} + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset) +{ +	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; +	struct vmw_dma_buffer *out_buf; +	int ret; + +	ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); +	if (ret != 0) +		return -EINVAL; + +	*offset = out_buf->base.addr_space_offset; +	vmw_dmabuf_unreference(&out_buf); +	return 0; +} + +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle) +{ +	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, +					 handle, TTM_REF_USAGE); +}  |