1#include <errno.h> 2#include <fcntl.h> 3#include <stdio.h> 4#include <stdint.h> 5#include <string.h> 6#include <unistd.h> 7 8#include <sys/ioctl.h> 9#include <sys/types.h> 10#include <sys/stat.h> 11 12#include <linux/dma-buf.h> 13 14#include <drm/drm.h> 15 16#include "ion.h" 17#include "ionutils.h" 18 19int check_vgem(int fd) 20{ 21 drm_version_t version = { 0 }; 22 char name[5]; 23 int ret; 24 25 version.name_len = 4; 26 version.name = name; 27 28 ret = ioctl(fd, DRM_IOCTL_VERSION, &version); 29 if (ret) 30 return 1; 31 32 return strcmp(name, "vgem"); 33} 34 35int open_vgem(void) 36{ 37 int i, fd; 38 const char *drmstr = "/dev/dri/card"; 39 40 fd = -1; 41 for (i = 0; i < 16; i++) { 42 char name[80]; 43 44 sprintf(name, "%s%u", drmstr, i); 45 46 fd = open(name, O_RDWR); 47 if (fd < 0) 48 continue; 49 50 if (check_vgem(fd)) { 51 close(fd); 52 continue; 53 } else { 54 break; 55 } 56 57 } 58 return fd; 59} 60 61int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle) 62{ 63 struct drm_prime_handle import_handle = { 0 }; 64 int ret; 65 66 import_handle.fd = dma_buf_fd; 67 import_handle.flags = 0; 68 import_handle.handle = 0; 69 70 ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle); 71 if (ret == 0) 72 *handle = import_handle.handle; 73 return ret; 74} 75 76void close_handle(int vgem_fd, uint32_t handle) 77{ 78 struct drm_gem_close close = { 0 }; 79 80 close.handle = handle; 81 ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close); 82} 83 84int main() 85{ 86 int ret, vgem_fd; 87 struct ion_buffer_info info; 88 uint32_t handle = 0; 89 struct dma_buf_sync sync = { 0 }; 90 91 info.heap_type = ION_HEAP_TYPE_SYSTEM; 92 info.heap_size = 4096; 93 info.flag_type = ION_FLAG_CACHED; 94 95 ret = ion_export_buffer_fd(&info); 96 if (ret < 0) { 97 printf("ion buffer alloc failed\n"); 98 return -1; 99 } 100 101 vgem_fd = open_vgem(); 102 if (vgem_fd < 0) { 103 ret = vgem_fd; 104 printf("Failed to open vgem\n"); 105 goto out_ion; 106 } 107 108 ret = import_vgem_fd(vgem_fd, info.buffd, &handle); 109 110 if (ret < 0) { 111 printf("Failed to import buffer\n"); 112 goto out_vgem; 113 } 114 115 sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW; 116 ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); 117 if (ret) 118 printf("sync start failed %d\n", errno); 119 120 memset(info.buffer, 0xff, 4096); 121 122 sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; 123 ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); 124 if (ret) 125 printf("sync end failed %d\n", errno); 126 127 close_handle(vgem_fd, handle); 128 ret = 0; 129 130out_vgem: 131 close(vgem_fd); 132out_ion: 133 ion_close_buffer_fd(&info); 134 printf("done.\n"); 135 return ret; 136} 137