#include "cairoint.h"
#include "cairo-drm-private.h"
#include "cairo-drm-ioctl-private.h"
#include "cairo-error-private.h"
#include <sys/ioctl.h>
#include <errno.h>
#define ERR_DEBUG(x) x
struct drm_gem_close {
uint32_t handle;
uint32_t pad;
};
struct drm_gem_flink {
uint32_t handle;
uint32_t name;
};
struct drm_gem_open {
uint32_t name;
uint32_t handle;
uint64_t size;
};
#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
cairo_status_t
_cairo_drm_bo_open_for_name (const cairo_drm_device_t *dev,
cairo_drm_bo_t *bo,
uint32_t name)
{
struct drm_gem_open open;
int ret;
open.name = name;
open.handle = 0;
open.size = 0;
do {
ret = ioctl (dev->fd, DRM_IOCTL_GEM_OPEN, &open);
} while (ret == -1 && errno == EINTR);
if (ret == -1) {
ERR_DEBUG((fprintf (stderr, "Failed to open bo for name %d: %s\n",
name, strerror (errno))));
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
bo->name = name;
bo->size = open.size;
bo->handle = open.handle;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_drm_bo_flink (const cairo_drm_device_t *dev,
cairo_drm_bo_t *bo)
{
struct drm_gem_flink flink;
int ret;
memset (&flink, 0, sizeof (flink));
flink.handle = bo->handle;
ret = ioctl (dev->fd, DRM_IOCTL_GEM_FLINK, &flink);
if (ret == -1) {
ERR_DEBUG((fprintf (stderr, "Failed to flink bo: %s\n",
strerror (errno))));
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
bo->name = flink.name;
return CAIRO_STATUS_SUCCESS;
}
void
_cairo_drm_bo_close (const cairo_drm_device_t *dev,
cairo_drm_bo_t *bo)
{
struct drm_gem_close close;
int ret;
close.handle = bo->handle;
do {
ret = ioctl (dev->fd, DRM_IOCTL_GEM_CLOSE, &close);
} while (ret == -1 && errno == EINTR);
}