int ret;
struct vigsp_cmd_create_surface_request *request;
- DRM_DEBUG_DRIVER("width = %u, height = %u, stride = %u, fmt = %d, id = 0x%llX\n",
+ DRM_DEBUG_DRIVER("width = %u, height = %u, stride = %u, fmt = %d, id = %u\n",
width,
height,
stride,
int ret;
struct vigsp_cmd_destroy_surface_request *request;
- DRM_DEBUG_DRIVER("id = 0x%llX\n", id);
+ DRM_DEBUG_DRIVER("id = %u\n", id);
ret = vigs_comm_prepare(comm,
vigsp_cmd_destroy_surface,
int ret;
struct vigsp_cmd_set_root_surface_request *request;
- DRM_DEBUG_DRIVER("id = 0x%llX\n", id);
+ DRM_DEBUG_DRIVER("id = %u, offset = %u\n", id, offset);
ret = vigs_comm_prepare(comm,
vigsp_cmd_set_root_surface,
}
ret = vigs_comm_set_root_surface(vigs_dev->comm,
- vigs_surface_id(vigs_fb->fb_sfc),
+ vigs_fb->fb_sfc->id,
vigs_gem_offset(&vigs_fb->fb_sfc->gem));
if (ret != 0) {
#include "vigs_comm.h"
#include "vigs_fbdev.h"
#include "vigs_execbuffer.h"
+#include "vigs_surface.h"
#include <drm/vigs_drm.h>
int vigs_device_init(struct vigs_device *vigs_dev,
vigs_dev->io_base = pci_resource_start(pci_dev, 2);
vigs_dev->io_size = pci_resource_len(pci_dev, 2);
+ idr_init(&vigs_dev->surface_idr);
+
if (!vigs_dev->vram_base || !vigs_dev->ram_base || !vigs_dev->io_base) {
DRM_ERROR("VRAM, RAM or IO bar not found on device\n");
ret = -ENODEV;
fail2:
drm_rmmap(vigs_dev->drm_dev, vigs_dev->io_map);
fail1:
+ idr_destroy(&vigs_dev->surface_idr);
return ret;
}
vigs_comm_destroy(vigs_dev->comm);
vigs_mman_destroy(vigs_dev->mman);
drm_rmmap(vigs_dev->drm_dev, vigs_dev->io_map);
+ idr_destroy(&vigs_dev->surface_idr);
}
int vigs_device_mmap(struct file *filp, struct vm_area_struct *vma)
return vigs_mman_mmap(vigs_dev->mman, filp, vma);
}
+int vigs_device_add_surface(struct vigs_device *vigs_dev,
+ struct vigs_surface *sfc,
+ vigsp_surface_id* id)
+{
+ int ret, tmp_id = 0;
+
+ do {
+ if (unlikely(idr_pre_get(&vigs_dev->surface_idr, GFP_KERNEL) == 0)) {
+ return -ENOMEM;
+ }
+
+ ret = idr_get_new_above(&vigs_dev->surface_idr, sfc, 1, &tmp_id);
+ } while (ret == -EAGAIN);
+
+ *id = tmp_id;
+
+ return ret;
+}
+
+void vigs_device_remove_surface(struct vigs_device *vigs_dev,
+ vigsp_surface_id sfc_id)
+{
+ idr_remove(&vigs_dev->surface_idr, sfc_id);
+}
+
+int vigs_device_add_surface_unlocked(struct vigs_device *vigs_dev,
+ struct vigs_surface *sfc,
+ vigsp_surface_id* id)
+{
+ int ret;
+
+ mutex_lock(&vigs_dev->drm_dev->struct_mutex);
+ ret = vigs_device_add_surface(vigs_dev, sfc, id);
+ mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
+
+ return ret;
+}
+
+struct vigs_surface
+ *vigs_device_reference_surface_unlocked(struct vigs_device *vigs_dev,
+ vigsp_surface_id sfc_id)
+{
+ struct vigs_surface *sfc;
+
+ mutex_lock(&vigs_dev->drm_dev->struct_mutex);
+
+ sfc = idr_find(&vigs_dev->surface_idr, sfc_id);
+
+ if (sfc) {
+ drm_gem_object_reference(&sfc->gem.base);
+ }
+
+ mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
+
+ return sfc;
+}
+
+void vigs_device_remove_surface_unlocked(struct vigs_device *vigs_dev,
+ vigsp_surface_id sfc_id)
+{
+ mutex_lock(&vigs_dev->drm_dev->struct_mutex);
+ vigs_device_remove_surface(vigs_dev, sfc_id);
+ mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
+}
+
int vigs_device_exec_ioctl(struct drm_device *drm_dev,
void *data,
struct drm_file *file_priv)
#define _VIGS_DEVICE_H_
#include "drmP.h"
+#include "vigs_protocol.h"
struct vigs_mman;
struct vigs_comm;
struct vigs_fbdev;
+struct vigs_surface;
struct vigs_device
{
resource_size_t io_base;
resource_size_t io_size;
+ struct idr surface_idr;
+
/* Map of IO BAR. */
drm_local_map_t *io_map;
int vigs_device_mmap(struct file *filp, struct vm_area_struct *vma);
+/*
+ * Must be called with drm_device::struct_mutex held.
+ * @{
+ */
+int vigs_device_add_surface(struct vigs_device *vigs_dev,
+ struct vigs_surface *sfc,
+ vigsp_surface_id* id);
+
+void vigs_device_remove_surface(struct vigs_device *vigs_dev,
+ vigsp_surface_id sfc_id);
+/*
+ * @}
+ */
+
+int vigs_device_add_surface_unlocked(struct vigs_device *vigs_dev,
+ struct vigs_surface *sfc,
+ vigsp_surface_id* id);
+
+struct vigs_surface
+ *vigs_device_reference_surface_unlocked(struct vigs_device *vigs_dev,
+ vigsp_surface_id sfc_id);
+
+void vigs_device_remove_surface_unlocked(struct vigs_device *vigs_dev,
+ vigsp_surface_id sfc_id);
+
/*
* IOCTLs
* @{
typedef unsigned long long vigsp_u64;
typedef vigsp_u32 vigsp_bool;
-typedef vigsp_u64 vigsp_surface_id;
+typedef vigsp_u32 vigsp_surface_id;
typedef vigsp_u32 vigsp_offset;
typedef vigsp_u32 vigsp_color;
typedef vigsp_u64 vigsp_va;
struct vigs_surface *sfc = vigs_gem_to_vigs_surface(gem);
struct vigs_device *vigs_dev = gem->base.dev->dev_private;
- vigs_comm_destroy_surface(vigs_dev->comm,
- vigs_surface_id(sfc));
+ vigs_comm_destroy_surface(vigs_dev->comm, sfc->id);
+
+ vigs_device_remove_surface(vigs_dev, sfc->id);
vigs_gem_cleanup(&sfc->gem);
}
goto fail1;
}
+ ret = vigs_device_add_surface_unlocked(vigs_dev, *sfc, &(*sfc)->id);
+
+ if (ret != 0) {
+ goto fail2;
+ }
+
ret = vigs_comm_create_surface(vigs_dev->comm,
width,
height,
stride,
format,
- vigs_surface_id(*sfc));
+ (*sfc)->id);
if (ret != 0) {
- goto fail2;
+ goto fail3;
}
return 0;
+fail3:
+ vigs_device_remove_surface_unlocked(vigs_dev, (*sfc)->id);
fail2:
vigs_gem_cleanup(&(*sfc)->gem);
fail1:
if (ret == 0) {
args->handle = handle;
args->mmap_offset = vigs_gem_mmap_offset(&sfc->gem);
- args->id = vigs_surface_id(sfc);
+ args->id = sfc->id;
}
return ret;
args->stride = sfc->stride;
args->format = sfc->format;
args->mmap_offset = vigs_gem_mmap_offset(vigs_gem);
- args->id = vigs_surface_id(sfc);
+ args->id = sfc->id;
drm_gem_object_unreference_unlocked(gem);
u32 height;
u32 stride;
vigsp_surface_format format;
+ vigsp_surface_id id;
};
static inline struct vigs_surface *vigs_gem_to_vigs_surface(struct vigs_gem_object *vigs_gem)
vigsp_surface_format format,
struct vigs_surface **sfc);
-static inline vigsp_surface_id vigs_surface_id(struct vigs_surface *sfc)
-{
- return vigs_gem_mmap_offset(&sfc->gem);
-}
-
/*
* IOCTLs
* @{
uint32_t format;
uint32_t handle;
uint64_t mmap_offset;
- uint64_t id;
+ uint32_t id;
};
struct drm_vigs_create_execbuffer
uint32_t stride;
uint32_t format;
uint64_t mmap_offset;
- uint64_t id;
+ uint32_t id;
};
struct drm_vigs_exec