.open = vmw_driver_open,
.preclose = vmw_preclose,
.postclose = vmw_postclose,
+
+ .dumb_create = vmw_dumb_create,
+ .dumb_map_offset = vmw_dumb_map_offset,
+ .dumb_destroy = vmw_dumb_destroy,
+
.fops = &vmwgfx_driver_fops,
.name = VMWGFX_DRIVER_NAME,
.desc = VMWGFX_DRIVER_DESC,
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int vmw_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args);
+
+int vmw_dumb_map_offset(struct drm_file *file_priv,
+ struct drm_device *dev, uint32_t handle,
+ uint64_t *offset);
+int vmw_dumb_destroy(struct drm_file *file_priv,
+ struct drm_device *dev,
+ uint32_t handle);
/**
* Overlay control - vmwgfx_overlay.c
*/
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);
+}