freedreno: use drm_mmap/drm_munmap wrappers
[platform/upstream/libdrm.git] / freedreno / freedreno_bo.c
index 8cea4de..dacb34c 100644 (file)
@@ -163,8 +163,8 @@ static struct fd_bo *find_in_bucket(struct fd_device *dev,
 }
 
 
-struct fd_bo * fd_bo_new(struct fd_device *dev,
-               uint32_t size, uint32_t flags)
+drm_public struct fd_bo *
+fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
 {
        struct fd_bo *bo = NULL;
        struct fd_bo_bucket *bucket;
@@ -197,8 +197,8 @@ struct fd_bo * fd_bo_new(struct fd_device *dev,
        return bo;
 }
 
-struct fd_bo *fd_bo_from_handle(struct fd_device *dev,
-               uint32_t handle, uint32_t size)
+drm_public struct fd_bo *
+fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size)
 {
        struct fd_bo *bo = NULL;
 
@@ -209,7 +209,26 @@ struct fd_bo *fd_bo_from_handle(struct fd_device *dev,
        return bo;
 }
 
-struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
+drm_public struct fd_bo *
+fd_bo_from_dmabuf(struct fd_device *dev, int fd)
+{
+       struct drm_prime_handle req = {
+                       .fd = fd,
+       };
+       int ret, size;
+
+       ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
+       if (ret) {
+               return NULL;
+       }
+
+       /* hmm, would be nice if we had a way to figure out the size.. */
+       size = 0;
+
+       return fd_bo_from_handle(dev, req.handle, size);
+}
+
+drm_public struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
 {
        struct drm_gem_open req = {
                        .name = name,
@@ -242,19 +261,24 @@ out_unlock:
        return bo;
 }
 
-struct fd_bo * fd_bo_ref(struct fd_bo *bo)
+drm_public struct fd_bo * fd_bo_ref(struct fd_bo *bo)
 {
        atomic_inc(&bo->refcnt);
        return bo;
 }
 
-void fd_bo_del(struct fd_bo *bo)
+drm_public void fd_bo_del(struct fd_bo *bo)
 {
        struct fd_device *dev = bo->dev;
 
        if (!atomic_dec_and_test(&bo->refcnt))
                return;
 
+       if (bo->fd) {
+               close(bo->fd);
+               bo->fd = 0;
+       }
+
        pthread_mutex_lock(&table_lock);
 
        if (bo->bo_reuse) {
@@ -288,7 +312,7 @@ out:
 static void bo_del(struct fd_bo *bo)
 {
        if (bo->map)
-               munmap(bo->map, bo->size);
+               drm_munmap(bo->map, bo->size);
 
        /* TODO probably bo's in bucket list get removed from
         * handle table??
@@ -307,7 +331,7 @@ static void bo_del(struct fd_bo *bo)
        bo->funcs->destroy(bo);
 }
 
-int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
+drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
 {
        if (!bo->name) {
                struct drm_gem_flink req = {
@@ -330,17 +354,36 @@ int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
        return 0;
 }
 
-uint32_t fd_bo_handle(struct fd_bo *bo)
+drm_public uint32_t fd_bo_handle(struct fd_bo *bo)
 {
        return bo->handle;
 }
 
-uint32_t fd_bo_size(struct fd_bo *bo)
+drm_public int fd_bo_dmabuf(struct fd_bo *bo)
+{
+       if (!bo->fd) {
+               struct drm_prime_handle req = {
+                               .handle = bo->handle,
+                               .flags = DRM_CLOEXEC,
+               };
+               int ret;
+
+               ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
+               if (ret) {
+                       return ret;
+               }
+
+               bo->fd = req.fd;
+       }
+       return dup(bo->fd);
+}
+
+drm_public uint32_t fd_bo_size(struct fd_bo *bo)
 {
        return bo->size;
 }
 
-void * fd_bo_map(struct fd_bo *bo)
+drm_public void * fd_bo_map(struct fd_bo *bo)
 {
        if (!bo->map) {
                uint64_t offset;
@@ -351,7 +394,7 @@ void * fd_bo_map(struct fd_bo *bo)
                        return NULL;
                }
 
-               bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+               bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
                                bo->dev->fd, offset);
                if (bo->map == MAP_FAILED) {
                        ERROR_MSG("mmap failed: %s", strerror(errno));
@@ -362,12 +405,12 @@ void * fd_bo_map(struct fd_bo *bo)
 }
 
 /* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */
-int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
+drm_public int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
 {
        return bo->funcs->cpu_prep(bo, pipe, op);
 }
 
-void fd_bo_cpu_fini(struct fd_bo *bo)
+drm_public void fd_bo_cpu_fini(struct fd_bo *bo)
 {
        bo->funcs->cpu_fini(bo);
 }