18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <dirent.h>
48c2ecf20Sopenharmony_ci#include <errno.h>
58c2ecf20Sopenharmony_ci#include <fcntl.h>
68c2ecf20Sopenharmony_ci#include <stdio.h>
78c2ecf20Sopenharmony_ci#include <stdlib.h>
88c2ecf20Sopenharmony_ci#include <stdint.h>
98c2ecf20Sopenharmony_ci#include <string.h>
108c2ecf20Sopenharmony_ci#include <unistd.h>
118c2ecf20Sopenharmony_ci#include <sys/ioctl.h>
128c2ecf20Sopenharmony_ci#include <sys/mman.h>
138c2ecf20Sopenharmony_ci#include <sys/types.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/dma-buf.h>
168c2ecf20Sopenharmony_ci#include <drm/drm.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "../../../../include/uapi/linux/dma-heap.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define DEVPATH "/dev/dma_heap"
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic int check_vgem(int fd)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	drm_version_t version = { 0 };
258c2ecf20Sopenharmony_ci	char name[5];
268c2ecf20Sopenharmony_ci	int ret;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	version.name_len = 4;
298c2ecf20Sopenharmony_ci	version.name = name;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
328c2ecf20Sopenharmony_ci	if (ret)
338c2ecf20Sopenharmony_ci		return 0;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	return !strcmp(name, "vgem");
368c2ecf20Sopenharmony_ci}
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic int open_vgem(void)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	int i, fd;
418c2ecf20Sopenharmony_ci	const char *drmstr = "/dev/dri/card";
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	fd = -1;
448c2ecf20Sopenharmony_ci	for (i = 0; i < 16; i++) {
458c2ecf20Sopenharmony_ci		char name[80];
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci		snprintf(name, 80, "%s%u", drmstr, i);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci		fd = open(name, O_RDWR);
508c2ecf20Sopenharmony_ci		if (fd < 0)
518c2ecf20Sopenharmony_ci			continue;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci		if (!check_vgem(fd)) {
548c2ecf20Sopenharmony_ci			close(fd);
558c2ecf20Sopenharmony_ci			fd = -1;
568c2ecf20Sopenharmony_ci			continue;
578c2ecf20Sopenharmony_ci		} else {
588c2ecf20Sopenharmony_ci			break;
598c2ecf20Sopenharmony_ci		}
608c2ecf20Sopenharmony_ci	}
618c2ecf20Sopenharmony_ci	return fd;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	struct drm_prime_handle import_handle = {
678c2ecf20Sopenharmony_ci		.fd = dma_buf_fd,
688c2ecf20Sopenharmony_ci		.flags = 0,
698c2ecf20Sopenharmony_ci		.handle = 0,
708c2ecf20Sopenharmony_ci	 };
718c2ecf20Sopenharmony_ci	int ret;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
748c2ecf20Sopenharmony_ci	if (ret == 0)
758c2ecf20Sopenharmony_ci		*handle = import_handle.handle;
768c2ecf20Sopenharmony_ci	return ret;
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic void close_handle(int vgem_fd, uint32_t handle)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct drm_gem_close close = {
828c2ecf20Sopenharmony_ci		.handle = handle,
838c2ecf20Sopenharmony_ci	};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistatic int dmabuf_heap_open(char *name)
898c2ecf20Sopenharmony_ci{
908c2ecf20Sopenharmony_ci	int ret, fd;
918c2ecf20Sopenharmony_ci	char buf[256];
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	ret = snprintf(buf, 256, "%s/%s", DEVPATH, name);
948c2ecf20Sopenharmony_ci	if (ret < 0) {
958c2ecf20Sopenharmony_ci		printf("snprintf failed!\n");
968c2ecf20Sopenharmony_ci		return ret;
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	fd = open(buf, O_RDWR);
1008c2ecf20Sopenharmony_ci	if (fd < 0)
1018c2ecf20Sopenharmony_ci		printf("open %s failed!\n", buf);
1028c2ecf20Sopenharmony_ci	return fd;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic int dmabuf_heap_alloc_fdflags(int fd, size_t len, unsigned int fd_flags,
1068c2ecf20Sopenharmony_ci				     unsigned int heap_flags, int *dmabuf_fd)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	struct dma_heap_allocation_data data = {
1098c2ecf20Sopenharmony_ci		.len = len,
1108c2ecf20Sopenharmony_ci		.fd = 0,
1118c2ecf20Sopenharmony_ci		.fd_flags = fd_flags,
1128c2ecf20Sopenharmony_ci		.heap_flags = heap_flags,
1138c2ecf20Sopenharmony_ci	};
1148c2ecf20Sopenharmony_ci	int ret;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	if (!dmabuf_fd)
1178c2ecf20Sopenharmony_ci		return -EINVAL;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data);
1208c2ecf20Sopenharmony_ci	if (ret < 0)
1218c2ecf20Sopenharmony_ci		return ret;
1228c2ecf20Sopenharmony_ci	*dmabuf_fd = (int)data.fd;
1238c2ecf20Sopenharmony_ci	return ret;
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic int dmabuf_heap_alloc(int fd, size_t len, unsigned int flags,
1278c2ecf20Sopenharmony_ci			     int *dmabuf_fd)
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci	return dmabuf_heap_alloc_fdflags(fd, len, O_RDWR | O_CLOEXEC, flags,
1308c2ecf20Sopenharmony_ci					 dmabuf_fd);
1318c2ecf20Sopenharmony_ci}
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistatic void dmabuf_sync(int fd, int start_stop)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	struct dma_buf_sync sync = {
1368c2ecf20Sopenharmony_ci		.flags = start_stop | DMA_BUF_SYNC_RW,
1378c2ecf20Sopenharmony_ci	};
1388c2ecf20Sopenharmony_ci	int ret;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
1418c2ecf20Sopenharmony_ci	if (ret)
1428c2ecf20Sopenharmony_ci		printf("sync failed %d\n", errno);
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci#define ONE_MEG (1024 * 1024)
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistatic int test_alloc_and_import(char *heap_name)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	int heap_fd = -1, dmabuf_fd = -1, importer_fd = -1;
1508c2ecf20Sopenharmony_ci	uint32_t handle = 0;
1518c2ecf20Sopenharmony_ci	void *p = NULL;
1528c2ecf20Sopenharmony_ci	int ret;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	printf("Testing heap: %s\n", heap_name);
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	heap_fd = dmabuf_heap_open(heap_name);
1578c2ecf20Sopenharmony_ci	if (heap_fd < 0)
1588c2ecf20Sopenharmony_ci		return -1;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	printf("Allocating 1 MEG\n");
1618c2ecf20Sopenharmony_ci	ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, &dmabuf_fd);
1628c2ecf20Sopenharmony_ci	if (ret) {
1638c2ecf20Sopenharmony_ci		printf("Allocation Failed!\n");
1648c2ecf20Sopenharmony_ci		ret = -1;
1658c2ecf20Sopenharmony_ci		goto out;
1668c2ecf20Sopenharmony_ci	}
1678c2ecf20Sopenharmony_ci	/* mmap and write a simple pattern */
1688c2ecf20Sopenharmony_ci	p = mmap(NULL,
1698c2ecf20Sopenharmony_ci		 ONE_MEG,
1708c2ecf20Sopenharmony_ci		 PROT_READ | PROT_WRITE,
1718c2ecf20Sopenharmony_ci		 MAP_SHARED,
1728c2ecf20Sopenharmony_ci		 dmabuf_fd,
1738c2ecf20Sopenharmony_ci		 0);
1748c2ecf20Sopenharmony_ci	if (p == MAP_FAILED) {
1758c2ecf20Sopenharmony_ci		printf("mmap() failed: %m\n");
1768c2ecf20Sopenharmony_ci		ret = -1;
1778c2ecf20Sopenharmony_ci		goto out;
1788c2ecf20Sopenharmony_ci	}
1798c2ecf20Sopenharmony_ci	printf("mmap passed\n");
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
1828c2ecf20Sopenharmony_ci	memset(p, 1, ONE_MEG / 2);
1838c2ecf20Sopenharmony_ci	memset((char *)p + ONE_MEG / 2, 0, ONE_MEG / 2);
1848c2ecf20Sopenharmony_ci	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	importer_fd = open_vgem();
1878c2ecf20Sopenharmony_ci	if (importer_fd < 0) {
1888c2ecf20Sopenharmony_ci		ret = importer_fd;
1898c2ecf20Sopenharmony_ci		printf("Failed to open vgem\n");
1908c2ecf20Sopenharmony_ci		goto out;
1918c2ecf20Sopenharmony_ci	}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	ret = import_vgem_fd(importer_fd, dmabuf_fd, &handle);
1948c2ecf20Sopenharmony_ci	if (ret < 0) {
1958c2ecf20Sopenharmony_ci		printf("Failed to import buffer\n");
1968c2ecf20Sopenharmony_ci		goto out;
1978c2ecf20Sopenharmony_ci	}
1988c2ecf20Sopenharmony_ci	printf("import passed\n");
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
2018c2ecf20Sopenharmony_ci	memset(p, 0xff, ONE_MEG);
2028c2ecf20Sopenharmony_ci	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);
2038c2ecf20Sopenharmony_ci	printf("syncs passed\n");
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	close_handle(importer_fd, handle);
2068c2ecf20Sopenharmony_ci	ret = 0;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ciout:
2098c2ecf20Sopenharmony_ci	if (p)
2108c2ecf20Sopenharmony_ci		munmap(p, ONE_MEG);
2118c2ecf20Sopenharmony_ci	if (importer_fd >= 0)
2128c2ecf20Sopenharmony_ci		close(importer_fd);
2138c2ecf20Sopenharmony_ci	if (dmabuf_fd >= 0)
2148c2ecf20Sopenharmony_ci		close(dmabuf_fd);
2158c2ecf20Sopenharmony_ci	if (heap_fd >= 0)
2168c2ecf20Sopenharmony_ci		close(heap_fd);
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	return ret;
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci/* Test the ioctl version compatibility w/ a smaller structure then expected */
2228c2ecf20Sopenharmony_cistatic int dmabuf_heap_alloc_older(int fd, size_t len, unsigned int flags,
2238c2ecf20Sopenharmony_ci				   int *dmabuf_fd)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	int ret;
2268c2ecf20Sopenharmony_ci	unsigned int older_alloc_ioctl;
2278c2ecf20Sopenharmony_ci	struct dma_heap_allocation_data_smaller {
2288c2ecf20Sopenharmony_ci		__u64 len;
2298c2ecf20Sopenharmony_ci		__u32 fd;
2308c2ecf20Sopenharmony_ci		__u32 fd_flags;
2318c2ecf20Sopenharmony_ci	} data = {
2328c2ecf20Sopenharmony_ci		.len = len,
2338c2ecf20Sopenharmony_ci		.fd = 0,
2348c2ecf20Sopenharmony_ci		.fd_flags = O_RDWR | O_CLOEXEC,
2358c2ecf20Sopenharmony_ci	};
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	older_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,
2388c2ecf20Sopenharmony_ci				  struct dma_heap_allocation_data_smaller);
2398c2ecf20Sopenharmony_ci	if (!dmabuf_fd)
2408c2ecf20Sopenharmony_ci		return -EINVAL;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	ret = ioctl(fd, older_alloc_ioctl, &data);
2438c2ecf20Sopenharmony_ci	if (ret < 0)
2448c2ecf20Sopenharmony_ci		return ret;
2458c2ecf20Sopenharmony_ci	*dmabuf_fd = (int)data.fd;
2468c2ecf20Sopenharmony_ci	return ret;
2478c2ecf20Sopenharmony_ci}
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci/* Test the ioctl version compatibility w/ a larger structure then expected */
2508c2ecf20Sopenharmony_cistatic int dmabuf_heap_alloc_newer(int fd, size_t len, unsigned int flags,
2518c2ecf20Sopenharmony_ci				   int *dmabuf_fd)
2528c2ecf20Sopenharmony_ci{
2538c2ecf20Sopenharmony_ci	int ret;
2548c2ecf20Sopenharmony_ci	unsigned int newer_alloc_ioctl;
2558c2ecf20Sopenharmony_ci	struct dma_heap_allocation_data_bigger {
2568c2ecf20Sopenharmony_ci		__u64 len;
2578c2ecf20Sopenharmony_ci		__u32 fd;
2588c2ecf20Sopenharmony_ci		__u32 fd_flags;
2598c2ecf20Sopenharmony_ci		__u64 heap_flags;
2608c2ecf20Sopenharmony_ci		__u64 garbage1;
2618c2ecf20Sopenharmony_ci		__u64 garbage2;
2628c2ecf20Sopenharmony_ci		__u64 garbage3;
2638c2ecf20Sopenharmony_ci	} data = {
2648c2ecf20Sopenharmony_ci		.len = len,
2658c2ecf20Sopenharmony_ci		.fd = 0,
2668c2ecf20Sopenharmony_ci		.fd_flags = O_RDWR | O_CLOEXEC,
2678c2ecf20Sopenharmony_ci		.heap_flags = flags,
2688c2ecf20Sopenharmony_ci		.garbage1 = 0xffffffff,
2698c2ecf20Sopenharmony_ci		.garbage2 = 0x88888888,
2708c2ecf20Sopenharmony_ci		.garbage3 = 0x11111111,
2718c2ecf20Sopenharmony_ci	};
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	newer_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,
2748c2ecf20Sopenharmony_ci				  struct dma_heap_allocation_data_bigger);
2758c2ecf20Sopenharmony_ci	if (!dmabuf_fd)
2768c2ecf20Sopenharmony_ci		return -EINVAL;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	ret = ioctl(fd, newer_alloc_ioctl, &data);
2798c2ecf20Sopenharmony_ci	if (ret < 0)
2808c2ecf20Sopenharmony_ci		return ret;
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	*dmabuf_fd = (int)data.fd;
2838c2ecf20Sopenharmony_ci	return ret;
2848c2ecf20Sopenharmony_ci}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_cistatic int test_alloc_compat(char *heap_name)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	int heap_fd = -1, dmabuf_fd = -1;
2898c2ecf20Sopenharmony_ci	int ret;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	heap_fd = dmabuf_heap_open(heap_name);
2928c2ecf20Sopenharmony_ci	if (heap_fd < 0)
2938c2ecf20Sopenharmony_ci		return -1;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	printf("Testing (theoretical)older alloc compat\n");
2968c2ecf20Sopenharmony_ci	ret = dmabuf_heap_alloc_older(heap_fd, ONE_MEG, 0, &dmabuf_fd);
2978c2ecf20Sopenharmony_ci	if (ret) {
2988c2ecf20Sopenharmony_ci		printf("Older compat allocation failed!\n");
2998c2ecf20Sopenharmony_ci		ret = -1;
3008c2ecf20Sopenharmony_ci		goto out;
3018c2ecf20Sopenharmony_ci	}
3028c2ecf20Sopenharmony_ci	close(dmabuf_fd);
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	printf("Testing (theoretical)newer alloc compat\n");
3058c2ecf20Sopenharmony_ci	ret = dmabuf_heap_alloc_newer(heap_fd, ONE_MEG, 0, &dmabuf_fd);
3068c2ecf20Sopenharmony_ci	if (ret) {
3078c2ecf20Sopenharmony_ci		printf("Newer compat allocation failed!\n");
3088c2ecf20Sopenharmony_ci		ret = -1;
3098c2ecf20Sopenharmony_ci		goto out;
3108c2ecf20Sopenharmony_ci	}
3118c2ecf20Sopenharmony_ci	printf("Ioctl compatibility tests passed\n");
3128c2ecf20Sopenharmony_ciout:
3138c2ecf20Sopenharmony_ci	if (dmabuf_fd >= 0)
3148c2ecf20Sopenharmony_ci		close(dmabuf_fd);
3158c2ecf20Sopenharmony_ci	if (heap_fd >= 0)
3168c2ecf20Sopenharmony_ci		close(heap_fd);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	return ret;
3198c2ecf20Sopenharmony_ci}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_cistatic int test_alloc_errors(char *heap_name)
3228c2ecf20Sopenharmony_ci{
3238c2ecf20Sopenharmony_ci	int heap_fd = -1, dmabuf_fd = -1;
3248c2ecf20Sopenharmony_ci	int ret;
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	heap_fd = dmabuf_heap_open(heap_name);
3278c2ecf20Sopenharmony_ci	if (heap_fd < 0)
3288c2ecf20Sopenharmony_ci		return -1;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	printf("Testing expected error cases\n");
3318c2ecf20Sopenharmony_ci	ret = dmabuf_heap_alloc(0, ONE_MEG, 0x111111, &dmabuf_fd);
3328c2ecf20Sopenharmony_ci	if (!ret) {
3338c2ecf20Sopenharmony_ci		printf("Did not see expected error (invalid fd)!\n");
3348c2ecf20Sopenharmony_ci		ret = -1;
3358c2ecf20Sopenharmony_ci		goto out;
3368c2ecf20Sopenharmony_ci	}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0x111111, &dmabuf_fd);
3398c2ecf20Sopenharmony_ci	if (!ret) {
3408c2ecf20Sopenharmony_ci		printf("Did not see expected error (invalid heap flags)!\n");
3418c2ecf20Sopenharmony_ci		ret = -1;
3428c2ecf20Sopenharmony_ci		goto out;
3438c2ecf20Sopenharmony_ci	}
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	ret = dmabuf_heap_alloc_fdflags(heap_fd, ONE_MEG,
3468c2ecf20Sopenharmony_ci					~(O_RDWR | O_CLOEXEC), 0, &dmabuf_fd);
3478c2ecf20Sopenharmony_ci	if (!ret) {
3488c2ecf20Sopenharmony_ci		printf("Did not see expected error (invalid fd flags)!\n");
3498c2ecf20Sopenharmony_ci		ret = -1;
3508c2ecf20Sopenharmony_ci		goto out;
3518c2ecf20Sopenharmony_ci	}
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	printf("Expected error checking passed\n");
3548c2ecf20Sopenharmony_ci	ret = 0;
3558c2ecf20Sopenharmony_ciout:
3568c2ecf20Sopenharmony_ci	if (dmabuf_fd >= 0)
3578c2ecf20Sopenharmony_ci		close(dmabuf_fd);
3588c2ecf20Sopenharmony_ci	if (heap_fd >= 0)
3598c2ecf20Sopenharmony_ci		close(heap_fd);
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	return ret;
3628c2ecf20Sopenharmony_ci}
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ciint main(void)
3658c2ecf20Sopenharmony_ci{
3668c2ecf20Sopenharmony_ci	DIR *d;
3678c2ecf20Sopenharmony_ci	struct dirent *dir;
3688c2ecf20Sopenharmony_ci	int ret = -1;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	d = opendir(DEVPATH);
3718c2ecf20Sopenharmony_ci	if (!d) {
3728c2ecf20Sopenharmony_ci		printf("No %s directory?\n", DEVPATH);
3738c2ecf20Sopenharmony_ci		return -1;
3748c2ecf20Sopenharmony_ci	}
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	while ((dir = readdir(d)) != NULL) {
3778c2ecf20Sopenharmony_ci		if (!strncmp(dir->d_name, ".", 2))
3788c2ecf20Sopenharmony_ci			continue;
3798c2ecf20Sopenharmony_ci		if (!strncmp(dir->d_name, "..", 3))
3808c2ecf20Sopenharmony_ci			continue;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci		ret = test_alloc_and_import(dir->d_name);
3838c2ecf20Sopenharmony_ci		if (ret)
3848c2ecf20Sopenharmony_ci			break;
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_ci		ret = test_alloc_compat(dir->d_name);
3878c2ecf20Sopenharmony_ci		if (ret)
3888c2ecf20Sopenharmony_ci			break;
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci		ret = test_alloc_errors(dir->d_name);
3918c2ecf20Sopenharmony_ci		if (ret)
3928c2ecf20Sopenharmony_ci			break;
3938c2ecf20Sopenharmony_ci	}
3948c2ecf20Sopenharmony_ci	closedir(d);
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	return ret;
3978c2ecf20Sopenharmony_ci}
398