1a8779927SJohn Stultz // SPDX-License-Identifier: GPL-2.0
2a8779927SJohn Stultz 
3a8779927SJohn Stultz #include <dirent.h>
4a8779927SJohn Stultz #include <errno.h>
5a8779927SJohn Stultz #include <fcntl.h>
6a8779927SJohn Stultz #include <stdio.h>
7a8779927SJohn Stultz #include <stdlib.h>
8a8779927SJohn Stultz #include <stdint.h>
9a8779927SJohn Stultz #include <string.h>
10a8779927SJohn Stultz #include <unistd.h>
11a8779927SJohn Stultz #include <sys/ioctl.h>
12a8779927SJohn Stultz #include <sys/mman.h>
13a8779927SJohn Stultz #include <sys/types.h>
14a8779927SJohn Stultz 
15a8779927SJohn Stultz #include <linux/dma-buf.h>
16*f80f09b5SMathieu Desnoyers #include <linux/dma-heap.h>
17a8779927SJohn Stultz #include <drm/drm.h>
18a8779927SJohn Stultz 
19a8779927SJohn Stultz #define DEVPATH "/dev/dma_heap"
20a8779927SJohn Stultz 
check_vgem(int fd)21a8779927SJohn Stultz static int check_vgem(int fd)
22a8779927SJohn Stultz {
23a8779927SJohn Stultz 	drm_version_t version = { 0 };
24a8779927SJohn Stultz 	char name[5];
25a8779927SJohn Stultz 	int ret;
26a8779927SJohn Stultz 
27a8779927SJohn Stultz 	version.name_len = 4;
28a8779927SJohn Stultz 	version.name = name;
29a8779927SJohn Stultz 
30a8779927SJohn Stultz 	ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
31a8779927SJohn Stultz 	if (ret)
32a8779927SJohn Stultz 		return 0;
33a8779927SJohn Stultz 
34a8779927SJohn Stultz 	return !strcmp(name, "vgem");
35a8779927SJohn Stultz }
36a8779927SJohn Stultz 
open_vgem(void)37a8779927SJohn Stultz static int open_vgem(void)
38a8779927SJohn Stultz {
39a8779927SJohn Stultz 	int i, fd;
40a8779927SJohn Stultz 	const char *drmstr = "/dev/dri/card";
41a8779927SJohn Stultz 
42a8779927SJohn Stultz 	fd = -1;
43a8779927SJohn Stultz 	for (i = 0; i < 16; i++) {
44a8779927SJohn Stultz 		char name[80];
45a8779927SJohn Stultz 
46a8779927SJohn Stultz 		snprintf(name, 80, "%s%u", drmstr, i);
47a8779927SJohn Stultz 
48a8779927SJohn Stultz 		fd = open(name, O_RDWR);
49a8779927SJohn Stultz 		if (fd < 0)
50a8779927SJohn Stultz 			continue;
51a8779927SJohn Stultz 
52a8779927SJohn Stultz 		if (!check_vgem(fd)) {
53a8779927SJohn Stultz 			close(fd);
54a8779927SJohn Stultz 			fd = -1;
55a8779927SJohn Stultz 			continue;
56a8779927SJohn Stultz 		} else {
57a8779927SJohn Stultz 			break;
58a8779927SJohn Stultz 		}
59a8779927SJohn Stultz 	}
60a8779927SJohn Stultz 	return fd;
61a8779927SJohn Stultz }
62a8779927SJohn Stultz 
import_vgem_fd(int vgem_fd,int dma_buf_fd,uint32_t * handle)63a8779927SJohn Stultz static int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
64a8779927SJohn Stultz {
65a8779927SJohn Stultz 	struct drm_prime_handle import_handle = {
66a8779927SJohn Stultz 		.fd = dma_buf_fd,
67a8779927SJohn Stultz 		.flags = 0,
68a8779927SJohn Stultz 		.handle = 0,
69a8779927SJohn Stultz 	 };
70a8779927SJohn Stultz 	int ret;
71a8779927SJohn Stultz 
72a8779927SJohn Stultz 	ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
73a8779927SJohn Stultz 	if (ret == 0)
74a8779927SJohn Stultz 		*handle = import_handle.handle;
75a8779927SJohn Stultz 	return ret;
76a8779927SJohn Stultz }
77a8779927SJohn Stultz 
close_handle(int vgem_fd,uint32_t handle)78a8779927SJohn Stultz static void close_handle(int vgem_fd, uint32_t handle)
79a8779927SJohn Stultz {
80a8779927SJohn Stultz 	struct drm_gem_close close = {
81a8779927SJohn Stultz 		.handle = handle,
82a8779927SJohn Stultz 	};
83a8779927SJohn Stultz 
84a8779927SJohn Stultz 	ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
85a8779927SJohn Stultz }
86a8779927SJohn Stultz 
dmabuf_heap_open(char * name)87a8779927SJohn Stultz static int dmabuf_heap_open(char *name)
88a8779927SJohn Stultz {
89a8779927SJohn Stultz 	int ret, fd;
90a8779927SJohn Stultz 	char buf[256];
91a8779927SJohn Stultz 
92a8779927SJohn Stultz 	ret = snprintf(buf, 256, "%s/%s", DEVPATH, name);
93a8779927SJohn Stultz 	if (ret < 0) {
94a8779927SJohn Stultz 		printf("snprintf failed!\n");
95a8779927SJohn Stultz 		return ret;
96a8779927SJohn Stultz 	}
97a8779927SJohn Stultz 
98a8779927SJohn Stultz 	fd = open(buf, O_RDWR);
99a8779927SJohn Stultz 	if (fd < 0)
100a8779927SJohn Stultz 		printf("open %s failed!\n", buf);
101a8779927SJohn Stultz 	return fd;
102a8779927SJohn Stultz }
103a8779927SJohn Stultz 
dmabuf_heap_alloc_fdflags(int fd,size_t len,unsigned int fd_flags,unsigned int heap_flags,int * dmabuf_fd)104a8779927SJohn Stultz static int dmabuf_heap_alloc_fdflags(int fd, size_t len, unsigned int fd_flags,
105a8779927SJohn Stultz 				     unsigned int heap_flags, int *dmabuf_fd)
106a8779927SJohn Stultz {
107a8779927SJohn Stultz 	struct dma_heap_allocation_data data = {
108a8779927SJohn Stultz 		.len = len,
109a8779927SJohn Stultz 		.fd = 0,
110a8779927SJohn Stultz 		.fd_flags = fd_flags,
111a8779927SJohn Stultz 		.heap_flags = heap_flags,
112a8779927SJohn Stultz 	};
113a8779927SJohn Stultz 	int ret;
114a8779927SJohn Stultz 
115a8779927SJohn Stultz 	if (!dmabuf_fd)
116a8779927SJohn Stultz 		return -EINVAL;
117a8779927SJohn Stultz 
118b3b43465SAndrew F. Davis 	ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data);
119a8779927SJohn Stultz 	if (ret < 0)
120a8779927SJohn Stultz 		return ret;
121a8779927SJohn Stultz 	*dmabuf_fd = (int)data.fd;
122a8779927SJohn Stultz 	return ret;
123a8779927SJohn Stultz }
124a8779927SJohn Stultz 
dmabuf_heap_alloc(int fd,size_t len,unsigned int flags,int * dmabuf_fd)125a8779927SJohn Stultz static int dmabuf_heap_alloc(int fd, size_t len, unsigned int flags,
126a8779927SJohn Stultz 			     int *dmabuf_fd)
127a8779927SJohn Stultz {
128a8779927SJohn Stultz 	return dmabuf_heap_alloc_fdflags(fd, len, O_RDWR | O_CLOEXEC, flags,
129a8779927SJohn Stultz 					 dmabuf_fd);
130a8779927SJohn Stultz }
131a8779927SJohn Stultz 
dmabuf_sync(int fd,int start_stop)13250c65a83SJohn Stultz static int dmabuf_sync(int fd, int start_stop)
133a8779927SJohn Stultz {
134a8779927SJohn Stultz 	struct dma_buf_sync sync = {
135a8779927SJohn Stultz 		.flags = start_stop | DMA_BUF_SYNC_RW,
136a8779927SJohn Stultz 	};
137a8779927SJohn Stultz 
13850c65a83SJohn Stultz 	return ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
139a8779927SJohn Stultz }
140a8779927SJohn Stultz 
141a8779927SJohn Stultz #define ONE_MEG (1024 * 1024)
142a8779927SJohn Stultz 
test_alloc_and_import(char * heap_name)143a8779927SJohn Stultz static int test_alloc_and_import(char *heap_name)
144a8779927SJohn Stultz {
145a8779927SJohn Stultz 	int heap_fd = -1, dmabuf_fd = -1, importer_fd = -1;
146a8779927SJohn Stultz 	uint32_t handle = 0;
147a8779927SJohn Stultz 	void *p = NULL;
148a8779927SJohn Stultz 	int ret;
149a8779927SJohn Stultz 
150a8779927SJohn Stultz 	heap_fd = dmabuf_heap_open(heap_name);
151a8779927SJohn Stultz 	if (heap_fd < 0)
152a8779927SJohn Stultz 		return -1;
153a8779927SJohn Stultz 
15406fc1aaeSJohn Stultz 	printf("  Testing allocation and importing:  ");
155a8779927SJohn Stultz 	ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, &dmabuf_fd);
156a8779927SJohn Stultz 	if (ret) {
15706fc1aaeSJohn Stultz 		printf("FAIL (Allocation Failed!)\n");
158a8779927SJohn Stultz 		ret = -1;
159a8779927SJohn Stultz 		goto out;
160a8779927SJohn Stultz 	}
161a8779927SJohn Stultz 	/* mmap and write a simple pattern */
162a8779927SJohn Stultz 	p = mmap(NULL,
163a8779927SJohn Stultz 		 ONE_MEG,
164a8779927SJohn Stultz 		 PROT_READ | PROT_WRITE,
165a8779927SJohn Stultz 		 MAP_SHARED,
166a8779927SJohn Stultz 		 dmabuf_fd,
167a8779927SJohn Stultz 		 0);
168a8779927SJohn Stultz 	if (p == MAP_FAILED) {
16906fc1aaeSJohn Stultz 		printf("FAIL (mmap() failed)\n");
170a8779927SJohn Stultz 		ret = -1;
171a8779927SJohn Stultz 		goto out;
172a8779927SJohn Stultz 	}
173a8779927SJohn Stultz 
174a8779927SJohn Stultz 	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
175a8779927SJohn Stultz 	memset(p, 1, ONE_MEG / 2);
176a8779927SJohn Stultz 	memset((char *)p + ONE_MEG / 2, 0, ONE_MEG / 2);
177a8779927SJohn Stultz 	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);
178a8779927SJohn Stultz 
179a8779927SJohn Stultz 	importer_fd = open_vgem();
180a8779927SJohn Stultz 	if (importer_fd < 0) {
181a8779927SJohn Stultz 		ret = importer_fd;
18206fc1aaeSJohn Stultz 		printf("(Could not open vgem - skipping):  ");
1831b50e10eSJohn Stultz 	} else {
184a8779927SJohn Stultz 		ret = import_vgem_fd(importer_fd, dmabuf_fd, &handle);
185a8779927SJohn Stultz 		if (ret < 0) {
18606fc1aaeSJohn Stultz 			printf("FAIL (Failed to import buffer)\n");
187a8779927SJohn Stultz 			goto out;
188a8779927SJohn Stultz 		}
1891b50e10eSJohn Stultz 	}
190a8779927SJohn Stultz 
19150c65a83SJohn Stultz 	ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
19250c65a83SJohn Stultz 	if (ret < 0) {
19306fc1aaeSJohn Stultz 		printf("FAIL (DMA_BUF_SYNC_START failed!)\n");
19450c65a83SJohn Stultz 		goto out;
19550c65a83SJohn Stultz 	}
19650c65a83SJohn Stultz 
197a8779927SJohn Stultz 	memset(p, 0xff, ONE_MEG);
19850c65a83SJohn Stultz 	ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);
19950c65a83SJohn Stultz 	if (ret < 0) {
20006fc1aaeSJohn Stultz 		printf("FAIL (DMA_BUF_SYNC_END failed!)\n");
20150c65a83SJohn Stultz 		goto out;
20250c65a83SJohn Stultz 	}
203a8779927SJohn Stultz 
204a8779927SJohn Stultz 	close_handle(importer_fd, handle);
205a8779927SJohn Stultz 	ret = 0;
20606fc1aaeSJohn Stultz 	printf(" OK\n");
207a8779927SJohn Stultz out:
208a8779927SJohn Stultz 	if (p)
209a8779927SJohn Stultz 		munmap(p, ONE_MEG);
210a8779927SJohn Stultz 	if (importer_fd >= 0)
211a8779927SJohn Stultz 		close(importer_fd);
212a8779927SJohn Stultz 	if (dmabuf_fd >= 0)
213a8779927SJohn Stultz 		close(dmabuf_fd);
214a8779927SJohn Stultz 	if (heap_fd >= 0)
215a8779927SJohn Stultz 		close(heap_fd);
216a8779927SJohn Stultz 
217a8779927SJohn Stultz 	return ret;
218a8779927SJohn Stultz }
219a8779927SJohn Stultz 
test_alloc_zeroed(char * heap_name,size_t size)2201d317c1cSJohn Stultz static int test_alloc_zeroed(char *heap_name, size_t size)
2211d317c1cSJohn Stultz {
2221d317c1cSJohn Stultz 	int heap_fd = -1, dmabuf_fd[32];
2231d317c1cSJohn Stultz 	int i, j, ret;
2241d317c1cSJohn Stultz 	void *p = NULL;
2251d317c1cSJohn Stultz 	char *c;
2261d317c1cSJohn Stultz 
2271d317c1cSJohn Stultz 	printf("  Testing alloced %ldk buffers are zeroed:  ", size / 1024);
2281d317c1cSJohn Stultz 	heap_fd = dmabuf_heap_open(heap_name);
2291d317c1cSJohn Stultz 	if (heap_fd < 0)
2301d317c1cSJohn Stultz 		return -1;
2311d317c1cSJohn Stultz 
2321d317c1cSJohn Stultz 	/* Allocate and fill a bunch of buffers */
2331d317c1cSJohn Stultz 	for (i = 0; i < 32; i++) {
2341d317c1cSJohn Stultz 		ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]);
2351d317c1cSJohn Stultz 		if (ret < 0) {
2361d317c1cSJohn Stultz 			printf("FAIL (Allocation (%i) failed)\n", i);
2371d317c1cSJohn Stultz 			goto out;
2381d317c1cSJohn Stultz 		}
2391d317c1cSJohn Stultz 		/* mmap and fill with simple pattern */
2401d317c1cSJohn Stultz 		p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0);
2411d317c1cSJohn Stultz 		if (p == MAP_FAILED) {
2421d317c1cSJohn Stultz 			printf("FAIL (mmap() failed!)\n");
2431d317c1cSJohn Stultz 			ret = -1;
2441d317c1cSJohn Stultz 			goto out;
2451d317c1cSJohn Stultz 		}
2461d317c1cSJohn Stultz 		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START);
2471d317c1cSJohn Stultz 		memset(p, 0xff, size);
2481d317c1cSJohn Stultz 		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
2491d317c1cSJohn Stultz 		munmap(p, size);
2501d317c1cSJohn Stultz 	}
2511d317c1cSJohn Stultz 	/* close them all */
2521d317c1cSJohn Stultz 	for (i = 0; i < 32; i++)
2531d317c1cSJohn Stultz 		close(dmabuf_fd[i]);
2541d317c1cSJohn Stultz 
2551d317c1cSJohn Stultz 	/* Allocate and validate all buffers are zeroed */
2561d317c1cSJohn Stultz 	for (i = 0; i < 32; i++) {
2571d317c1cSJohn Stultz 		ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]);
2581d317c1cSJohn Stultz 		if (ret < 0) {
2591d317c1cSJohn Stultz 			printf("FAIL (Allocation (%i) failed)\n", i);
2601d317c1cSJohn Stultz 			goto out;
2611d317c1cSJohn Stultz 		}
2621d317c1cSJohn Stultz 
2631d317c1cSJohn Stultz 		/* mmap and validate everything is zero */
2641d317c1cSJohn Stultz 		p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0);
2651d317c1cSJohn Stultz 		if (p == MAP_FAILED) {
2661d317c1cSJohn Stultz 			printf("FAIL (mmap() failed!)\n");
2671d317c1cSJohn Stultz 			ret = -1;
2681d317c1cSJohn Stultz 			goto out;
2691d317c1cSJohn Stultz 		}
2701d317c1cSJohn Stultz 		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START);
2711d317c1cSJohn Stultz 		c = (char *)p;
2721d317c1cSJohn Stultz 		for (j = 0; j < size; j++) {
2731d317c1cSJohn Stultz 			if (c[j] != 0) {
2741d317c1cSJohn Stultz 				printf("FAIL (Allocated buffer not zeroed @ %i)\n", j);
2751d317c1cSJohn Stultz 				break;
2761d317c1cSJohn Stultz 			}
2771d317c1cSJohn Stultz 		}
2781d317c1cSJohn Stultz 		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
2791d317c1cSJohn Stultz 		munmap(p, size);
2801d317c1cSJohn Stultz 	}
2811d317c1cSJohn Stultz 	/* close them all */
2821d317c1cSJohn Stultz 	for (i = 0; i < 32; i++)
2831d317c1cSJohn Stultz 		close(dmabuf_fd[i]);
2841d317c1cSJohn Stultz 
2851d317c1cSJohn Stultz 	close(heap_fd);
2861d317c1cSJohn Stultz 	printf("OK\n");
2871d317c1cSJohn Stultz 	return 0;
2881d317c1cSJohn Stultz 
2891d317c1cSJohn Stultz out:
2901d317c1cSJohn Stultz 	while (i > 0) {
2911d317c1cSJohn Stultz 		close(dmabuf_fd[i]);
2921d317c1cSJohn Stultz 		i--;
2931d317c1cSJohn Stultz 	}
2941d317c1cSJohn Stultz 	close(heap_fd);
2951d317c1cSJohn Stultz 	return ret;
2961d317c1cSJohn Stultz }
2971d317c1cSJohn Stultz 
298a8779927SJohn Stultz /* Test the ioctl version compatibility w/ a smaller structure then expected */
dmabuf_heap_alloc_older(int fd,size_t len,unsigned int flags,int * dmabuf_fd)299a8779927SJohn Stultz static int dmabuf_heap_alloc_older(int fd, size_t len, unsigned int flags,
300a8779927SJohn Stultz 				   int *dmabuf_fd)
301a8779927SJohn Stultz {
302a8779927SJohn Stultz 	int ret;
303a8779927SJohn Stultz 	unsigned int older_alloc_ioctl;
304a8779927SJohn Stultz 	struct dma_heap_allocation_data_smaller {
305a8779927SJohn Stultz 		__u64 len;
306a8779927SJohn Stultz 		__u32 fd;
307a8779927SJohn Stultz 		__u32 fd_flags;
308a8779927SJohn Stultz 	} data = {
309a8779927SJohn Stultz 		.len = len,
310a8779927SJohn Stultz 		.fd = 0,
311a8779927SJohn Stultz 		.fd_flags = O_RDWR | O_CLOEXEC,
312a8779927SJohn Stultz 	};
313a8779927SJohn Stultz 
314a8779927SJohn Stultz 	older_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,
315a8779927SJohn Stultz 				  struct dma_heap_allocation_data_smaller);
316a8779927SJohn Stultz 	if (!dmabuf_fd)
317a8779927SJohn Stultz 		return -EINVAL;
318a8779927SJohn Stultz 
319a8779927SJohn Stultz 	ret = ioctl(fd, older_alloc_ioctl, &data);
320a8779927SJohn Stultz 	if (ret < 0)
321a8779927SJohn Stultz 		return ret;
322a8779927SJohn Stultz 	*dmabuf_fd = (int)data.fd;
323a8779927SJohn Stultz 	return ret;
324a8779927SJohn Stultz }
325a8779927SJohn Stultz 
326a8779927SJohn Stultz /* Test the ioctl version compatibility w/ a larger structure then expected */
dmabuf_heap_alloc_newer(int fd,size_t len,unsigned int flags,int * dmabuf_fd)327a8779927SJohn Stultz static int dmabuf_heap_alloc_newer(int fd, size_t len, unsigned int flags,
328a8779927SJohn Stultz 				   int *dmabuf_fd)
329a8779927SJohn Stultz {
330a8779927SJohn Stultz 	int ret;
331a8779927SJohn Stultz 	unsigned int newer_alloc_ioctl;
332a8779927SJohn Stultz 	struct dma_heap_allocation_data_bigger {
333a8779927SJohn Stultz 		__u64 len;
334a8779927SJohn Stultz 		__u32 fd;
335a8779927SJohn Stultz 		__u32 fd_flags;
336a8779927SJohn Stultz 		__u64 heap_flags;
337a8779927SJohn Stultz 		__u64 garbage1;
338a8779927SJohn Stultz 		__u64 garbage2;
339a8779927SJohn Stultz 		__u64 garbage3;
340a8779927SJohn Stultz 	} data = {
341a8779927SJohn Stultz 		.len = len,
342a8779927SJohn Stultz 		.fd = 0,
343a8779927SJohn Stultz 		.fd_flags = O_RDWR | O_CLOEXEC,
344a8779927SJohn Stultz 		.heap_flags = flags,
345a8779927SJohn Stultz 		.garbage1 = 0xffffffff,
346a8779927SJohn Stultz 		.garbage2 = 0x88888888,
347a8779927SJohn Stultz 		.garbage3 = 0x11111111,
348a8779927SJohn Stultz 	};
349a8779927SJohn Stultz 
350a8779927SJohn Stultz 	newer_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,
351a8779927SJohn Stultz 				  struct dma_heap_allocation_data_bigger);
352a8779927SJohn Stultz 	if (!dmabuf_fd)
353a8779927SJohn Stultz 		return -EINVAL;
354a8779927SJohn Stultz 
355a8779927SJohn Stultz 	ret = ioctl(fd, newer_alloc_ioctl, &data);
356a8779927SJohn Stultz 	if (ret < 0)
357a8779927SJohn Stultz 		return ret;
358a8779927SJohn Stultz 
359a8779927SJohn Stultz 	*dmabuf_fd = (int)data.fd;
360a8779927SJohn Stultz 	return ret;
361a8779927SJohn Stultz }
362a8779927SJohn Stultz 
test_alloc_compat(char * heap_name)363a8779927SJohn Stultz static int test_alloc_compat(char *heap_name)
364a8779927SJohn Stultz {
365a8779927SJohn Stultz 	int heap_fd = -1, dmabuf_fd = -1;
366a8779927SJohn Stultz 	int ret;
367a8779927SJohn Stultz 
368a8779927SJohn Stultz 	heap_fd = dmabuf_heap_open(heap_name);
369a8779927SJohn Stultz 	if (heap_fd < 0)
370a8779927SJohn Stultz 		return -1;
371a8779927SJohn Stultz 
37206fc1aaeSJohn Stultz 	printf("  Testing (theoretical)older alloc compat:  ");
373a8779927SJohn Stultz 	ret = dmabuf_heap_alloc_older(heap_fd, ONE_MEG, 0, &dmabuf_fd);
374a8779927SJohn Stultz 	if (ret) {
37506fc1aaeSJohn Stultz 		printf("FAIL (Older compat allocation failed!)\n");
376a8779927SJohn Stultz 		ret = -1;
377a8779927SJohn Stultz 		goto out;
378a8779927SJohn Stultz 	}
379a8779927SJohn Stultz 	close(dmabuf_fd);
38006fc1aaeSJohn Stultz 	printf("OK\n");
381a8779927SJohn Stultz 
38206fc1aaeSJohn Stultz 	printf("  Testing (theoretical)newer alloc compat:  ");
383a8779927SJohn Stultz 	ret = dmabuf_heap_alloc_newer(heap_fd, ONE_MEG, 0, &dmabuf_fd);
384a8779927SJohn Stultz 	if (ret) {
38506fc1aaeSJohn Stultz 		printf("FAIL (Newer compat allocation failed!)\n");
386a8779927SJohn Stultz 		ret = -1;
387a8779927SJohn Stultz 		goto out;
388a8779927SJohn Stultz 	}
38906fc1aaeSJohn Stultz 	printf("OK\n");
390a8779927SJohn Stultz out:
391a8779927SJohn Stultz 	if (dmabuf_fd >= 0)
392a8779927SJohn Stultz 		close(dmabuf_fd);
393a8779927SJohn Stultz 	if (heap_fd >= 0)
394a8779927SJohn Stultz 		close(heap_fd);
395a8779927SJohn Stultz 
396a8779927SJohn Stultz 	return ret;
397a8779927SJohn Stultz }
398a8779927SJohn Stultz 
test_alloc_errors(char * heap_name)399a8779927SJohn Stultz static int test_alloc_errors(char *heap_name)
400a8779927SJohn Stultz {
401a8779927SJohn Stultz 	int heap_fd = -1, dmabuf_fd = -1;
402a8779927SJohn Stultz 	int ret;
403a8779927SJohn Stultz 
404a8779927SJohn Stultz 	heap_fd = dmabuf_heap_open(heap_name);
405a8779927SJohn Stultz 	if (heap_fd < 0)
406a8779927SJohn Stultz 		return -1;
407a8779927SJohn Stultz 
40806fc1aaeSJohn Stultz 	printf("  Testing expected error cases:  ");
409a8779927SJohn Stultz 	ret = dmabuf_heap_alloc(0, ONE_MEG, 0x111111, &dmabuf_fd);
410a8779927SJohn Stultz 	if (!ret) {
41106fc1aaeSJohn Stultz 		printf("FAIL (Did not see expected error (invalid fd)!)\n");
412a8779927SJohn Stultz 		ret = -1;
413a8779927SJohn Stultz 		goto out;
414a8779927SJohn Stultz 	}
415a8779927SJohn Stultz 
416a8779927SJohn Stultz 	ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0x111111, &dmabuf_fd);
417a8779927SJohn Stultz 	if (!ret) {
41806fc1aaeSJohn Stultz 		printf("FAIL (Did not see expected error (invalid heap flags)!)\n");
419a8779927SJohn Stultz 		ret = -1;
420a8779927SJohn Stultz 		goto out;
421a8779927SJohn Stultz 	}
422a8779927SJohn Stultz 
423a8779927SJohn Stultz 	ret = dmabuf_heap_alloc_fdflags(heap_fd, ONE_MEG,
424a8779927SJohn Stultz 					~(O_RDWR | O_CLOEXEC), 0, &dmabuf_fd);
425a8779927SJohn Stultz 	if (!ret) {
42606fc1aaeSJohn Stultz 		printf("FAIL (Did not see expected error (invalid fd flags)!)\n");
427a8779927SJohn Stultz 		ret = -1;
428a8779927SJohn Stultz 		goto out;
429a8779927SJohn Stultz 	}
430a8779927SJohn Stultz 
43106fc1aaeSJohn Stultz 	printf("OK\n");
4324bb9d46dSJohn Stultz 	ret = 0;
433a8779927SJohn Stultz out:
434a8779927SJohn Stultz 	if (dmabuf_fd >= 0)
435a8779927SJohn Stultz 		close(dmabuf_fd);
436a8779927SJohn Stultz 	if (heap_fd >= 0)
437a8779927SJohn Stultz 		close(heap_fd);
438a8779927SJohn Stultz 
439a8779927SJohn Stultz 	return ret;
440a8779927SJohn Stultz }
441a8779927SJohn Stultz 
main(void)442a8779927SJohn Stultz int main(void)
443a8779927SJohn Stultz {
444a8779927SJohn Stultz 	DIR *d;
445a8779927SJohn Stultz 	struct dirent *dir;
446a8779927SJohn Stultz 	int ret = -1;
447a8779927SJohn Stultz 
448a8779927SJohn Stultz 	d = opendir(DEVPATH);
449a8779927SJohn Stultz 	if (!d) {
450a8779927SJohn Stultz 		printf("No %s directory?\n", DEVPATH);
451a8779927SJohn Stultz 		return -1;
452a8779927SJohn Stultz 	}
453a8779927SJohn Stultz 
454a8779927SJohn Stultz 	while ((dir = readdir(d)) != NULL) {
455a8779927SJohn Stultz 		if (!strncmp(dir->d_name, ".", 2))
456a8779927SJohn Stultz 			continue;
457a8779927SJohn Stultz 		if (!strncmp(dir->d_name, "..", 3))
458a8779927SJohn Stultz 			continue;
459a8779927SJohn Stultz 
46006fc1aaeSJohn Stultz 		printf("Testing heap: %s\n", dir->d_name);
46106fc1aaeSJohn Stultz 		printf("=======================================\n");
462a8779927SJohn Stultz 		ret = test_alloc_and_import(dir->d_name);
463a8779927SJohn Stultz 		if (ret)
464a8779927SJohn Stultz 			break;
465a8779927SJohn Stultz 
4661d317c1cSJohn Stultz 		ret = test_alloc_zeroed(dir->d_name, 4 * 1024);
4671d317c1cSJohn Stultz 		if (ret)
4681d317c1cSJohn Stultz 			break;
4691d317c1cSJohn Stultz 
4701d317c1cSJohn Stultz 		ret = test_alloc_zeroed(dir->d_name, ONE_MEG);
4711d317c1cSJohn Stultz 		if (ret)
4721d317c1cSJohn Stultz 			break;
4731d317c1cSJohn Stultz 
474a8779927SJohn Stultz 		ret = test_alloc_compat(dir->d_name);
475a8779927SJohn Stultz 		if (ret)
476a8779927SJohn Stultz 			break;
477a8779927SJohn Stultz 
478a8779927SJohn Stultz 		ret = test_alloc_errors(dir->d_name);
479a8779927SJohn Stultz 		if (ret)
480a8779927SJohn Stultz 			break;
481a8779927SJohn Stultz 	}
482a8779927SJohn Stultz 	closedir(d);
483a8779927SJohn Stultz 
484a8779927SJohn Stultz 	return ret;
485a8779927SJohn Stultz }
486