137 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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;
 | |
| }
 |