#include #include #include #include #include #include #include #include #include #include #include #include "ion.h" #include "ionutils.h" int check_vgem(int fd) { drm_version_t version = { 0 }; char name[5]; int ret; version.name_len = 4; version.name = name; ret = ioctl(fd, DRM_IOCTL_VERSION, &version); if (ret) return 1; return strcmp(name, "vgem"); } int open_vgem(void) { int i, fd; const char *drmstr = "/dev/dri/card"; fd = -1; for (i = 0; i < 16; i++) { char name[80]; sprintf(name, "%s%u", drmstr, i); fd = open(name, O_RDWR); if (fd < 0) continue; if (check_vgem(fd)) { close(fd); continue; } else { break; } } return fd; } int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle) { struct drm_prime_handle import_handle = { 0 }; int ret; import_handle.fd = dma_buf_fd; import_handle.flags = 0; import_handle.handle = 0; ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle); if (ret == 0) *handle = import_handle.handle; return ret; } void close_handle(int vgem_fd, uint32_t handle) { struct drm_gem_close close = { 0 }; close.handle = handle; ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close); } int main() { int ret, vgem_fd; struct ion_buffer_info info; uint32_t handle = 0; struct dma_buf_sync sync = { 0 }; info.heap_type = ION_HEAP_TYPE_SYSTEM; info.heap_size = 4096; info.flag_type = ION_FLAG_CACHED; ret = ion_export_buffer_fd(&info); if (ret < 0) { printf("ion buffer alloc failed\n"); return -1; } vgem_fd = open_vgem(); if (vgem_fd < 0) { ret = vgem_fd; printf("Failed to open vgem\n"); goto out_ion; } ret = import_vgem_fd(vgem_fd, info.buffd, &handle); if (ret < 0) { printf("Failed to import buffer\n"); goto out_vgem; } sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW; ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); if (ret) printf("sync start failed %d\n", errno); memset(info.buffer, 0xff, 4096); sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); if (ret) printf("sync end failed %d\n", errno); close_handle(vgem_fd, handle); ret = 0; out_vgem: close(vgem_fd); out_ion: ion_close_buffer_fd(&info); printf("done.\n"); return ret; }