tbm_module: check the bufmgr_func symbol at tbm_module_bufmgr_get_capabilities
[platform/core/uifw/libtbm.git] / src / tbm_sync.c
index 9ebca2e..d4bcd66 100644 (file)
@@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <errno.h>
 #include <sys/ioctl.h>
 #include <linux/types.h>
+#include <poll.h>
 
 /* IOCTLs for timeline file object. */
 #define TIMELINE_IOC_MAGIC                     'W'
@@ -47,12 +48,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define TIMELINE_IOC_INC                       _IOW(TIMELINE_IOC_MAGIC, 1, __u32)
 
 /* IOCTLs for fence file object. */
-#define FENCE_IOC_MAGIC                '>'
-#define FENCE_IOC_WAIT         _IOW(FENCE_IOC_MAGIC, 0, __s32)
-#define FENCE_IOC_MERGE                _IOWR(FENCE_IOC_MAGIC, 1, struct sync_merge_data)
+#define FENCE_IOC_MAGIC                                '>'
+#define FENCE_IOC_MERGE                                _IOWR(FENCE_IOC_MAGIC, 3, struct sync_merge_data)
+
+#define FENCE_IOC_LEGACY_WAIT          _IOW(FENCE_IOC_MAGIC, 0, __s32)
+#define FENCE_IOC_LEGACY_MERGE         _IOWR(FENCE_IOC_MAGIC, 1, struct sync_legacy_merge_data)
+
+/* Path to the sync device legacy file. */
+#define SYNC_DEVICE_PATH_LEGACY        "/dev/sw_sync"
 
 /* Path to the sync device file. */
-#define SYNC_DEVICE_PATH       "/dev/sw_sync"
+#define SYNC_DEVICE_PATH       "/sys/kernel/debug/sync/sw_sync"
 
 /* Argument data structure for the timeline.create_fence ioctl. */
 struct create_fence_data {
@@ -63,6 +69,15 @@ struct create_fence_data {
 
 /* Argument data structure for the fence.merge ioctl. */
 struct sync_merge_data {
+       char    name[32];       /* Name of the new fence object (IN) */
+       __s32   fd2;            /* fence to merged with the fence (IN) */
+       __s32   fence;          /* File descriptor for the new fence (OUT) */
+       __u32   flags;          /* merge_data flags (IN) */
+       __u32   pad;            /* padding for 64-bit alignment, should always be zero */
+};
+
+/* Argument data structure for the legacy fence.merge ioctl. */
+struct sync_legacy_merge_data {
        __s32   fd2;            /* fence to merged with the fence (IN) */
        char    name[32];       /* Name of the new fence object (IN) */
        __s32   fence;          /* File descriptor for the new fence (OUT) */
@@ -70,6 +85,7 @@ struct sync_merge_data {
 
 #define ERRNO_BUF_SIZE 256
 
+/* LCOV_EXCL_START */
 static inline void
 _log_errno()
 {
@@ -78,10 +94,10 @@ _log_errno()
        char    buf[ERRNO_BUF_SIZE];
 
        if (strerror_r(errnum, buf, ERRNO_BUF_SIZE) == 0) {
-               TBM_LOG_E("errno : %d(%s)\n", errnum, buf);
+               TBM_ERR("errno : %d(%s)\n", errnum, buf);
                return;
        } else {
-               TBM_LOG_E("errno : %d()\n", errnum);
+               TBM_ERR("errno : %d()\n", errnum);
                return;
        }
 }
@@ -110,6 +126,9 @@ tbm_sync_timeline_create(void)
 {
        tbm_fd timeline = open(SYNC_DEVICE_PATH, O_RDWR | O_CLOEXEC);
 
+       if (timeline < 0)
+               timeline = open(SYNC_DEVICE_PATH_LEGACY, O_RDWR | O_CLOEXEC);
+
        if (timeline == -1)
                _log_errno();
 
@@ -147,23 +166,29 @@ tbm_sync_fence_create(tbm_fd timeline, const char *name, unsigned int value)
 int
 tbm_sync_fence_wait(tbm_fd fence, int timeout)
 {
-       __s32   arg = timeout;
-       int             ret;
-
-       /* Retry while ioctl() ended up with interrupt. */
-       do {
-               ret = ioctl(fence, FENCE_IOC_WAIT, &arg);
-       } while (ret == -1 && errno == EINTR);
+       struct pollfd fds;
+       int ret;
 
-       /* ioctl() was successful. */
-       if (ret == 0)
-               return 1;
+       fds.fd = fence;
+       fds.events = POLLIN;
 
-       /* ioctl() ended up with timeout. */
-       if (errno == ETIME)
-               return -1;
+       do {
+               ret = poll(&fds, 1, timeout);
+               if (ret > 0) {
+                       if (fds.revents & (POLLERR | POLLNVAL)) {
+                               errno = EINVAL;
+                               _log_errno();
+                               return 0;
+                       }
+
+                       return 1;
+               } else if (ret == 0) {
+                       errno = ETIME;
+                       _log_errno();
+                       return 0;
+               }
+       } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
 
-       /* ioctl() failed for some reason. */
        _log_errno();
        return 0;
 }
@@ -172,13 +197,26 @@ tbm_fd
 tbm_sync_fence_merge(const char *name, tbm_fd fence1, tbm_fd fence2)
 {
        struct sync_merge_data data = { .fd2 = fence2 };
+       int ret;
 
        _copy_string(data.name, name, 32);
 
-       if (ioctl(fence1, FENCE_IOC_MERGE, &data) == -1) {
+       ret = ioctl(fence1, FENCE_IOC_MERGE, &data);
+       if (ret < 0 && errno == ENOTTY) {
+               struct sync_legacy_merge_data legacy_data = {. fd2 = fence2 };
+
+               _copy_string(legacy_data.name, name, 32);
+
+               ret = ioctl(fence1, FENCE_IOC_LEGACY_MERGE, &legacy_data);
+               if (ret < 0) {
+                       _log_errno();
+                       return -1;
+               }
+       } else if (ret < 0) {
                _log_errno();
                return -1;
        }
 
        return data.fence;
 }
+/* LCOV_EXCL_STOP */