162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <dirent.h> 462306a36Sopenharmony_ci#include <errno.h> 562306a36Sopenharmony_ci#include <fcntl.h> 662306a36Sopenharmony_ci#include <stdio.h> 762306a36Sopenharmony_ci#include <stdlib.h> 862306a36Sopenharmony_ci#include <stdint.h> 962306a36Sopenharmony_ci#include <string.h> 1062306a36Sopenharmony_ci#include <unistd.h> 1162306a36Sopenharmony_ci#include <sys/ioctl.h> 1262306a36Sopenharmony_ci#include <sys/mman.h> 1362306a36Sopenharmony_ci#include <sys/types.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/dma-buf.h> 1662306a36Sopenharmony_ci#include <linux/dma-heap.h> 1762306a36Sopenharmony_ci#include <drm/drm.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define DEVPATH "/dev/dma_heap" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic int check_vgem(int fd) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci drm_version_t version = { 0 }; 2462306a36Sopenharmony_ci char name[5]; 2562306a36Sopenharmony_ci int ret; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci version.name_len = 4; 2862306a36Sopenharmony_ci version.name = name; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci ret = ioctl(fd, DRM_IOCTL_VERSION, &version); 3162306a36Sopenharmony_ci if (ret) 3262306a36Sopenharmony_ci return 0; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci return !strcmp(name, "vgem"); 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic int open_vgem(void) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci int i, fd; 4062306a36Sopenharmony_ci const char *drmstr = "/dev/dri/card"; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci fd = -1; 4362306a36Sopenharmony_ci for (i = 0; i < 16; i++) { 4462306a36Sopenharmony_ci char name[80]; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci snprintf(name, 80, "%s%u", drmstr, i); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci fd = open(name, O_RDWR); 4962306a36Sopenharmony_ci if (fd < 0) 5062306a36Sopenharmony_ci continue; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci if (!check_vgem(fd)) { 5362306a36Sopenharmony_ci close(fd); 5462306a36Sopenharmony_ci fd = -1; 5562306a36Sopenharmony_ci continue; 5662306a36Sopenharmony_ci } else { 5762306a36Sopenharmony_ci break; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci return fd; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci struct drm_prime_handle import_handle = { 6662306a36Sopenharmony_ci .fd = dma_buf_fd, 6762306a36Sopenharmony_ci .flags = 0, 6862306a36Sopenharmony_ci .handle = 0, 6962306a36Sopenharmony_ci }; 7062306a36Sopenharmony_ci int ret; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle); 7362306a36Sopenharmony_ci if (ret == 0) 7462306a36Sopenharmony_ci *handle = import_handle.handle; 7562306a36Sopenharmony_ci return ret; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistatic void close_handle(int vgem_fd, uint32_t handle) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci struct drm_gem_close close = { 8162306a36Sopenharmony_ci .handle = handle, 8262306a36Sopenharmony_ci }; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close); 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic int dmabuf_heap_open(char *name) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci int ret, fd; 9062306a36Sopenharmony_ci char buf[256]; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci ret = snprintf(buf, 256, "%s/%s", DEVPATH, name); 9362306a36Sopenharmony_ci if (ret < 0) { 9462306a36Sopenharmony_ci printf("snprintf failed!\n"); 9562306a36Sopenharmony_ci return ret; 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci fd = open(buf, O_RDWR); 9962306a36Sopenharmony_ci if (fd < 0) 10062306a36Sopenharmony_ci printf("open %s failed!\n", buf); 10162306a36Sopenharmony_ci return fd; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic int dmabuf_heap_alloc_fdflags(int fd, size_t len, unsigned int fd_flags, 10562306a36Sopenharmony_ci unsigned int heap_flags, int *dmabuf_fd) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci struct dma_heap_allocation_data data = { 10862306a36Sopenharmony_ci .len = len, 10962306a36Sopenharmony_ci .fd = 0, 11062306a36Sopenharmony_ci .fd_flags = fd_flags, 11162306a36Sopenharmony_ci .heap_flags = heap_flags, 11262306a36Sopenharmony_ci }; 11362306a36Sopenharmony_ci int ret; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (!dmabuf_fd) 11662306a36Sopenharmony_ci return -EINVAL; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data); 11962306a36Sopenharmony_ci if (ret < 0) 12062306a36Sopenharmony_ci return ret; 12162306a36Sopenharmony_ci *dmabuf_fd = (int)data.fd; 12262306a36Sopenharmony_ci return ret; 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic int dmabuf_heap_alloc(int fd, size_t len, unsigned int flags, 12662306a36Sopenharmony_ci int *dmabuf_fd) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci return dmabuf_heap_alloc_fdflags(fd, len, O_RDWR | O_CLOEXEC, flags, 12962306a36Sopenharmony_ci dmabuf_fd); 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic int dmabuf_sync(int fd, int start_stop) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct dma_buf_sync sync = { 13562306a36Sopenharmony_ci .flags = start_stop | DMA_BUF_SYNC_RW, 13662306a36Sopenharmony_ci }; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci return ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci#define ONE_MEG (1024 * 1024) 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic int test_alloc_and_import(char *heap_name) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci int heap_fd = -1, dmabuf_fd = -1, importer_fd = -1; 14662306a36Sopenharmony_ci uint32_t handle = 0; 14762306a36Sopenharmony_ci void *p = NULL; 14862306a36Sopenharmony_ci int ret; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci heap_fd = dmabuf_heap_open(heap_name); 15162306a36Sopenharmony_ci if (heap_fd < 0) 15262306a36Sopenharmony_ci return -1; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci printf(" Testing allocation and importing: "); 15562306a36Sopenharmony_ci ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, &dmabuf_fd); 15662306a36Sopenharmony_ci if (ret) { 15762306a36Sopenharmony_ci printf("FAIL (Allocation Failed!)\n"); 15862306a36Sopenharmony_ci ret = -1; 15962306a36Sopenharmony_ci goto out; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci /* mmap and write a simple pattern */ 16262306a36Sopenharmony_ci p = mmap(NULL, 16362306a36Sopenharmony_ci ONE_MEG, 16462306a36Sopenharmony_ci PROT_READ | PROT_WRITE, 16562306a36Sopenharmony_ci MAP_SHARED, 16662306a36Sopenharmony_ci dmabuf_fd, 16762306a36Sopenharmony_ci 0); 16862306a36Sopenharmony_ci if (p == MAP_FAILED) { 16962306a36Sopenharmony_ci printf("FAIL (mmap() failed)\n"); 17062306a36Sopenharmony_ci ret = -1; 17162306a36Sopenharmony_ci goto out; 17262306a36Sopenharmony_ci } 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START); 17562306a36Sopenharmony_ci memset(p, 1, ONE_MEG / 2); 17662306a36Sopenharmony_ci memset((char *)p + ONE_MEG / 2, 0, ONE_MEG / 2); 17762306a36Sopenharmony_ci dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci importer_fd = open_vgem(); 18062306a36Sopenharmony_ci if (importer_fd < 0) { 18162306a36Sopenharmony_ci ret = importer_fd; 18262306a36Sopenharmony_ci printf("(Could not open vgem - skipping): "); 18362306a36Sopenharmony_ci } else { 18462306a36Sopenharmony_ci ret = import_vgem_fd(importer_fd, dmabuf_fd, &handle); 18562306a36Sopenharmony_ci if (ret < 0) { 18662306a36Sopenharmony_ci printf("FAIL (Failed to import buffer)\n"); 18762306a36Sopenharmony_ci goto out; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci } 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START); 19262306a36Sopenharmony_ci if (ret < 0) { 19362306a36Sopenharmony_ci printf("FAIL (DMA_BUF_SYNC_START failed!)\n"); 19462306a36Sopenharmony_ci goto out; 19562306a36Sopenharmony_ci } 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci memset(p, 0xff, ONE_MEG); 19862306a36Sopenharmony_ci ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END); 19962306a36Sopenharmony_ci if (ret < 0) { 20062306a36Sopenharmony_ci printf("FAIL (DMA_BUF_SYNC_END failed!)\n"); 20162306a36Sopenharmony_ci goto out; 20262306a36Sopenharmony_ci } 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci close_handle(importer_fd, handle); 20562306a36Sopenharmony_ci ret = 0; 20662306a36Sopenharmony_ci printf(" OK\n"); 20762306a36Sopenharmony_ciout: 20862306a36Sopenharmony_ci if (p) 20962306a36Sopenharmony_ci munmap(p, ONE_MEG); 21062306a36Sopenharmony_ci if (importer_fd >= 0) 21162306a36Sopenharmony_ci close(importer_fd); 21262306a36Sopenharmony_ci if (dmabuf_fd >= 0) 21362306a36Sopenharmony_ci close(dmabuf_fd); 21462306a36Sopenharmony_ci if (heap_fd >= 0) 21562306a36Sopenharmony_ci close(heap_fd); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci return ret; 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic int test_alloc_zeroed(char *heap_name, size_t size) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci int heap_fd = -1, dmabuf_fd[32]; 22362306a36Sopenharmony_ci int i, j, ret; 22462306a36Sopenharmony_ci void *p = NULL; 22562306a36Sopenharmony_ci char *c; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci printf(" Testing alloced %ldk buffers are zeroed: ", size / 1024); 22862306a36Sopenharmony_ci heap_fd = dmabuf_heap_open(heap_name); 22962306a36Sopenharmony_ci if (heap_fd < 0) 23062306a36Sopenharmony_ci return -1; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* Allocate and fill a bunch of buffers */ 23362306a36Sopenharmony_ci for (i = 0; i < 32; i++) { 23462306a36Sopenharmony_ci ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]); 23562306a36Sopenharmony_ci if (ret < 0) { 23662306a36Sopenharmony_ci printf("FAIL (Allocation (%i) failed)\n", i); 23762306a36Sopenharmony_ci goto out; 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci /* mmap and fill with simple pattern */ 24062306a36Sopenharmony_ci p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0); 24162306a36Sopenharmony_ci if (p == MAP_FAILED) { 24262306a36Sopenharmony_ci printf("FAIL (mmap() failed!)\n"); 24362306a36Sopenharmony_ci ret = -1; 24462306a36Sopenharmony_ci goto out; 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START); 24762306a36Sopenharmony_ci memset(p, 0xff, size); 24862306a36Sopenharmony_ci dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END); 24962306a36Sopenharmony_ci munmap(p, size); 25062306a36Sopenharmony_ci } 25162306a36Sopenharmony_ci /* close them all */ 25262306a36Sopenharmony_ci for (i = 0; i < 32; i++) 25362306a36Sopenharmony_ci close(dmabuf_fd[i]); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci /* Allocate and validate all buffers are zeroed */ 25662306a36Sopenharmony_ci for (i = 0; i < 32; i++) { 25762306a36Sopenharmony_ci ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]); 25862306a36Sopenharmony_ci if (ret < 0) { 25962306a36Sopenharmony_ci printf("FAIL (Allocation (%i) failed)\n", i); 26062306a36Sopenharmony_ci goto out; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* mmap and validate everything is zero */ 26462306a36Sopenharmony_ci p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0); 26562306a36Sopenharmony_ci if (p == MAP_FAILED) { 26662306a36Sopenharmony_ci printf("FAIL (mmap() failed!)\n"); 26762306a36Sopenharmony_ci ret = -1; 26862306a36Sopenharmony_ci goto out; 26962306a36Sopenharmony_ci } 27062306a36Sopenharmony_ci dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START); 27162306a36Sopenharmony_ci c = (char *)p; 27262306a36Sopenharmony_ci for (j = 0; j < size; j++) { 27362306a36Sopenharmony_ci if (c[j] != 0) { 27462306a36Sopenharmony_ci printf("FAIL (Allocated buffer not zeroed @ %i)\n", j); 27562306a36Sopenharmony_ci break; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END); 27962306a36Sopenharmony_ci munmap(p, size); 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci /* close them all */ 28262306a36Sopenharmony_ci for (i = 0; i < 32; i++) 28362306a36Sopenharmony_ci close(dmabuf_fd[i]); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci close(heap_fd); 28662306a36Sopenharmony_ci printf("OK\n"); 28762306a36Sopenharmony_ci return 0; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ciout: 29062306a36Sopenharmony_ci while (i > 0) { 29162306a36Sopenharmony_ci close(dmabuf_fd[i]); 29262306a36Sopenharmony_ci i--; 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci close(heap_fd); 29562306a36Sopenharmony_ci return ret; 29662306a36Sopenharmony_ci} 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci/* Test the ioctl version compatibility w/ a smaller structure then expected */ 29962306a36Sopenharmony_cistatic int dmabuf_heap_alloc_older(int fd, size_t len, unsigned int flags, 30062306a36Sopenharmony_ci int *dmabuf_fd) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci int ret; 30362306a36Sopenharmony_ci unsigned int older_alloc_ioctl; 30462306a36Sopenharmony_ci struct dma_heap_allocation_data_smaller { 30562306a36Sopenharmony_ci __u64 len; 30662306a36Sopenharmony_ci __u32 fd; 30762306a36Sopenharmony_ci __u32 fd_flags; 30862306a36Sopenharmony_ci } data = { 30962306a36Sopenharmony_ci .len = len, 31062306a36Sopenharmony_ci .fd = 0, 31162306a36Sopenharmony_ci .fd_flags = O_RDWR | O_CLOEXEC, 31262306a36Sopenharmony_ci }; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci older_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0, 31562306a36Sopenharmony_ci struct dma_heap_allocation_data_smaller); 31662306a36Sopenharmony_ci if (!dmabuf_fd) 31762306a36Sopenharmony_ci return -EINVAL; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci ret = ioctl(fd, older_alloc_ioctl, &data); 32062306a36Sopenharmony_ci if (ret < 0) 32162306a36Sopenharmony_ci return ret; 32262306a36Sopenharmony_ci *dmabuf_fd = (int)data.fd; 32362306a36Sopenharmony_ci return ret; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci/* Test the ioctl version compatibility w/ a larger structure then expected */ 32762306a36Sopenharmony_cistatic int dmabuf_heap_alloc_newer(int fd, size_t len, unsigned int flags, 32862306a36Sopenharmony_ci int *dmabuf_fd) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci int ret; 33162306a36Sopenharmony_ci unsigned int newer_alloc_ioctl; 33262306a36Sopenharmony_ci struct dma_heap_allocation_data_bigger { 33362306a36Sopenharmony_ci __u64 len; 33462306a36Sopenharmony_ci __u32 fd; 33562306a36Sopenharmony_ci __u32 fd_flags; 33662306a36Sopenharmony_ci __u64 heap_flags; 33762306a36Sopenharmony_ci __u64 garbage1; 33862306a36Sopenharmony_ci __u64 garbage2; 33962306a36Sopenharmony_ci __u64 garbage3; 34062306a36Sopenharmony_ci } data = { 34162306a36Sopenharmony_ci .len = len, 34262306a36Sopenharmony_ci .fd = 0, 34362306a36Sopenharmony_ci .fd_flags = O_RDWR | O_CLOEXEC, 34462306a36Sopenharmony_ci .heap_flags = flags, 34562306a36Sopenharmony_ci .garbage1 = 0xffffffff, 34662306a36Sopenharmony_ci .garbage2 = 0x88888888, 34762306a36Sopenharmony_ci .garbage3 = 0x11111111, 34862306a36Sopenharmony_ci }; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci newer_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0, 35162306a36Sopenharmony_ci struct dma_heap_allocation_data_bigger); 35262306a36Sopenharmony_ci if (!dmabuf_fd) 35362306a36Sopenharmony_ci return -EINVAL; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci ret = ioctl(fd, newer_alloc_ioctl, &data); 35662306a36Sopenharmony_ci if (ret < 0) 35762306a36Sopenharmony_ci return ret; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci *dmabuf_fd = (int)data.fd; 36062306a36Sopenharmony_ci return ret; 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_cistatic int test_alloc_compat(char *heap_name) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci int heap_fd = -1, dmabuf_fd = -1; 36662306a36Sopenharmony_ci int ret; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci heap_fd = dmabuf_heap_open(heap_name); 36962306a36Sopenharmony_ci if (heap_fd < 0) 37062306a36Sopenharmony_ci return -1; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci printf(" Testing (theoretical)older alloc compat: "); 37362306a36Sopenharmony_ci ret = dmabuf_heap_alloc_older(heap_fd, ONE_MEG, 0, &dmabuf_fd); 37462306a36Sopenharmony_ci if (ret) { 37562306a36Sopenharmony_ci printf("FAIL (Older compat allocation failed!)\n"); 37662306a36Sopenharmony_ci ret = -1; 37762306a36Sopenharmony_ci goto out; 37862306a36Sopenharmony_ci } 37962306a36Sopenharmony_ci close(dmabuf_fd); 38062306a36Sopenharmony_ci printf("OK\n"); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci printf(" Testing (theoretical)newer alloc compat: "); 38362306a36Sopenharmony_ci ret = dmabuf_heap_alloc_newer(heap_fd, ONE_MEG, 0, &dmabuf_fd); 38462306a36Sopenharmony_ci if (ret) { 38562306a36Sopenharmony_ci printf("FAIL (Newer compat allocation failed!)\n"); 38662306a36Sopenharmony_ci ret = -1; 38762306a36Sopenharmony_ci goto out; 38862306a36Sopenharmony_ci } 38962306a36Sopenharmony_ci printf("OK\n"); 39062306a36Sopenharmony_ciout: 39162306a36Sopenharmony_ci if (dmabuf_fd >= 0) 39262306a36Sopenharmony_ci close(dmabuf_fd); 39362306a36Sopenharmony_ci if (heap_fd >= 0) 39462306a36Sopenharmony_ci close(heap_fd); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci return ret; 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_cistatic int test_alloc_errors(char *heap_name) 40062306a36Sopenharmony_ci{ 40162306a36Sopenharmony_ci int heap_fd = -1, dmabuf_fd = -1; 40262306a36Sopenharmony_ci int ret; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci heap_fd = dmabuf_heap_open(heap_name); 40562306a36Sopenharmony_ci if (heap_fd < 0) 40662306a36Sopenharmony_ci return -1; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci printf(" Testing expected error cases: "); 40962306a36Sopenharmony_ci ret = dmabuf_heap_alloc(0, ONE_MEG, 0x111111, &dmabuf_fd); 41062306a36Sopenharmony_ci if (!ret) { 41162306a36Sopenharmony_ci printf("FAIL (Did not see expected error (invalid fd)!)\n"); 41262306a36Sopenharmony_ci ret = -1; 41362306a36Sopenharmony_ci goto out; 41462306a36Sopenharmony_ci } 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0x111111, &dmabuf_fd); 41762306a36Sopenharmony_ci if (!ret) { 41862306a36Sopenharmony_ci printf("FAIL (Did not see expected error (invalid heap flags)!)\n"); 41962306a36Sopenharmony_ci ret = -1; 42062306a36Sopenharmony_ci goto out; 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci ret = dmabuf_heap_alloc_fdflags(heap_fd, ONE_MEG, 42462306a36Sopenharmony_ci ~(O_RDWR | O_CLOEXEC), 0, &dmabuf_fd); 42562306a36Sopenharmony_ci if (!ret) { 42662306a36Sopenharmony_ci printf("FAIL (Did not see expected error (invalid fd flags)!)\n"); 42762306a36Sopenharmony_ci ret = -1; 42862306a36Sopenharmony_ci goto out; 42962306a36Sopenharmony_ci } 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci printf("OK\n"); 43262306a36Sopenharmony_ci ret = 0; 43362306a36Sopenharmony_ciout: 43462306a36Sopenharmony_ci if (dmabuf_fd >= 0) 43562306a36Sopenharmony_ci close(dmabuf_fd); 43662306a36Sopenharmony_ci if (heap_fd >= 0) 43762306a36Sopenharmony_ci close(heap_fd); 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci return ret; 44062306a36Sopenharmony_ci} 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ciint main(void) 44362306a36Sopenharmony_ci{ 44462306a36Sopenharmony_ci DIR *d; 44562306a36Sopenharmony_ci struct dirent *dir; 44662306a36Sopenharmony_ci int ret = -1; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci d = opendir(DEVPATH); 44962306a36Sopenharmony_ci if (!d) { 45062306a36Sopenharmony_ci printf("No %s directory?\n", DEVPATH); 45162306a36Sopenharmony_ci return -1; 45262306a36Sopenharmony_ci } 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci while ((dir = readdir(d)) != NULL) { 45562306a36Sopenharmony_ci if (!strncmp(dir->d_name, ".", 2)) 45662306a36Sopenharmony_ci continue; 45762306a36Sopenharmony_ci if (!strncmp(dir->d_name, "..", 3)) 45862306a36Sopenharmony_ci continue; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci printf("Testing heap: %s\n", dir->d_name); 46162306a36Sopenharmony_ci printf("=======================================\n"); 46262306a36Sopenharmony_ci ret = test_alloc_and_import(dir->d_name); 46362306a36Sopenharmony_ci if (ret) 46462306a36Sopenharmony_ci break; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci ret = test_alloc_zeroed(dir->d_name, 4 * 1024); 46762306a36Sopenharmony_ci if (ret) 46862306a36Sopenharmony_ci break; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci ret = test_alloc_zeroed(dir->d_name, ONE_MEG); 47162306a36Sopenharmony_ci if (ret) 47262306a36Sopenharmony_ci break; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci ret = test_alloc_compat(dir->d_name); 47562306a36Sopenharmony_ci if (ret) 47662306a36Sopenharmony_ci break; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci ret = test_alloc_errors(dir->d_name); 47962306a36Sopenharmony_ci if (ret) 48062306a36Sopenharmony_ci break; 48162306a36Sopenharmony_ci } 48262306a36Sopenharmony_ci closedir(d); 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci return ret; 48562306a36Sopenharmony_ci} 486