xtest:sdp: support old ION API if new API fails
Implement the old ION API using ion0_ or ION0_ as prefix.
Routine allocate_ion_buffer() attempts to allocate using the new
API. If the 1st request (query heap types) fails, try the old API.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey 4.9/4.12)
Tested-by: Etienne Carriere <etienne.carriere@linaro.org> (Qemus 4.9/4.12)
diff --git a/host/xtest/include/uapi/linux/ion_old.h b/host/xtest/include/uapi/linux/ion_old.h
new file mode 100644
index 0000000..a26fb22
--- /dev/null
+++ b/host/xtest/include/uapi/linux/ion_old.h
@@ -0,0 +1,145 @@
+/*
+ * drivers/staging/android/uapi/ion.h (This is the ION Uapi prior kernel 4.12)
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_ION_OLD_H
+#define _UAPI_LINUX_ION_OLD_H
+
+/* All ION resources are prefixed ION0_ to ditinguish from companion new API */
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+typedef int ion0_user_handle_t;
+
+/**
+ * struct ion0_allocation_data - metadata passed from userspace for allocations
+ * @len: size of the allocation
+ * @align: required alignment of the allocation
+ * @heap_id_mask: mask of heap ids to allocate from
+ * @flags: flags passed to heap
+ * @handle: pointer that will be populated with a cookie to use to
+ * refer to this allocation
+ *
+ * Provided by userspace as an argument to the ioctl
+ */
+struct ion0_allocation_data {
+ size_t len;
+ size_t align;
+ unsigned int heap_id_mask;
+ unsigned int flags;
+ ion0_user_handle_t handle;
+};
+
+/**
+ * struct ion0_fd_data - metadata passed to/from userspace for a handle/fd pair
+ * @handle: a handle
+ * @fd: a file descriptor representing that handle
+ *
+ * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
+ * the handle returned from ion alloc, and the kernel returns the file
+ * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace
+ * provides the file descriptor and the kernel returns the handle.
+ */
+struct ion0_fd_data {
+ ion0_user_handle_t handle;
+ int fd;
+};
+
+/**
+ * struct ion0_handle_data - a handle passed to/from the kernel
+ * @handle: a handle
+ */
+struct ion0_handle_data {
+ ion0_user_handle_t handle;
+};
+
+/**
+ * struct ion0_custom_data - metadata passed to/from userspace for a custom ioctl
+ * @cmd: the custom ioctl function to call
+ * @arg: additional data to pass to the custom ioctl, typically a user
+ * pointer to a predefined structure
+ *
+ * This works just like the regular cmd and arg fields of an ioctl.
+ */
+struct ion0_custom_data {
+ unsigned int cmd;
+ unsigned long arg;
+};
+
+/**
+ * DOC: ION_IOC_ALLOC - allocate memory
+ *
+ * Takes an ion_allocation_data struct and returns it with the handle field
+ * populated with the opaque handle for the allocation.
+ */
+#define ION0_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
+ struct ion0_allocation_data)
+/**
+ * DOC: ION_IOC_FREE - free memory
+ *
+ * Takes an ion_handle_data struct and frees the handle.
+ */
+#define ION0_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion0_handle_data)
+
+/**
+ * DOC: ION_IOC_MAP - get a file descriptor to mmap
+ *
+ * Takes an ion0_fd_data struct with the handle field populated with a valid
+ * opaque handle. Returns the struct with the fd field set to a file
+ * descriptor open in the current address space. This file descriptor
+ * can then be used as an argument to mmap.
+ */
+#define ION0_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion0_fd_data)
+
+/**
+ * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
+ *
+ * Takes an ion_fd_data struct with the handle field populated with a valid
+ * opaque handle. Returns the struct with the fd field set to a file
+ * descriptor open in the current address space. This file descriptor
+ * can then be passed to another process. The corresponding opaque handle can
+ * be retrieved via ION_IOC_IMPORT.
+ */
+#define ION0_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion0_fd_data)
+
+/**
+ * DOC: ION_IOC_IMPORT - imports a shared file descriptor
+ *
+ * Takes an ion0_fd_data struct with the fd field populated with a valid file
+ * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle
+ * filed set to the corresponding opaque handle.
+ */
+#define ION0_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion0_fd_data)
+
+/**
+ * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory
+ *
+ * Deprecated in favor of using the dma_buf api's correctly (syncing
+ * will happen automatically when the buffer is mapped to a device).
+ * If necessary should be used after touching a cached buffer from the cpu,
+ * this will make the buffer in memory coherent.
+ */
+#define ION0_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion0_fd_data)
+
+/**
+ * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl
+ *
+ * Takes the argument of the architecture specific ioctl to call and
+ * passes appropriate userdata for that ioctl
+ */
+#define ION0_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion0_custom_data)
+
+#endif /* _UAPI_LINUX_ION_OLD_H */
diff --git a/host/xtest/sdp_basic.c b/host/xtest/sdp_basic.c
index 84de4b1..7510ee1 100644
--- a/host/xtest/sdp_basic.c
+++ b/host/xtest/sdp_basic.c
@@ -41,6 +41,8 @@
#include "sdp_basic.h"
#include "xtest_test.h"
+#include "include/uapi/linux/ion_old.h"
+
/*
* SDP basic test setup overview.
*
@@ -76,6 +78,37 @@
TEEC_Session sess;
};
+/*
+ * Old ION API to allocate and export a buffer
+ */
+static int allocate_ion_buffer_old_api(size_t size, int heap_type_id, int ion)
+{
+ struct ion0_allocation_data alloc_data;
+ struct ion0_handle_data hdl_data;
+ struct ion0_fd_data fd_data;
+ int fd = -1;
+
+ alloc_data.len = size;
+ alloc_data.align = 0;
+ alloc_data.flags = 0;
+ alloc_data.heap_id_mask = 1 << heap_type_id;
+ if (ioctl(ion, ION0_IOC_ALLOC, &alloc_data) == -1) {
+ fprintf(stderr, "Error: old ION allocate API failed\n");
+ return fd;
+ }
+
+ fd_data.handle = alloc_data.handle;
+ if (ioctl(ion, ION0_IOC_SHARE, &fd_data) != -1)
+ fd = fd_data.fd;
+ else
+ fprintf(stderr, "Error: old ION share API failed\n");
+
+ hdl_data.handle = alloc_data.handle;
+ (void)ioctl(ion, ION0_IOC_FREE, &hdl_data);
+
+ return fd;
+}
+
int allocate_ion_buffer(size_t size, int heap_type_id, int verbosity)
{
struct ion_heap_query query_data;
@@ -106,7 +139,8 @@
query_data.heaps = (__u64)(unsigned long)&heap_data;
if (ioctl(ion, ION_IOC_HEAP_QUERY, &query_data) < 0) {
- fprintf(stderr, "Error: failed to query heaps data\n");
+ fprintf(stderr, "Info: can't query heaps data, try old API\n");
+ fd = allocate_ion_buffer_old_api(size, heap_type_id, ion);
goto out;
}