| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <stdint.h> |
| #include <string.h> |
| #include <unistd.h> |
| |
| #include <sys/ioctl.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| |
| #include <linux/dma-buf.h> |
| |
| #include <drm/drm.h> |
| |
| #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; |
| } |