OSDN Git Service

libdrm: drmNodeIsDRM: Add FreeBSD variant
[android-x86/external-libdrm.git] / xf86drm.c
index b7d5865..63ba1ed 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
 #endif
 #include <math.h>
 
+#if defined(__FreeBSD__)
+#include <sys/param.h>
+#endif
+
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 /* Not all systems have MAP_FAILED defined */
@@ -2777,6 +2781,16 @@ static bool drmNodeIsDRM(int maj, int min)
     snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm",
              maj, min);
     return stat(path, &sbuf) == 0;
+#elif __FreeBSD__
+    char name[SPECNAMELEN];
+
+    if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name)))
+      return 0;
+    /* Handle drm/ and dri/ as both are present in different FreeBSD version
+     * FreeBSD on amd64/i386/powerpc external kernel modules create node in
+     * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
+     * only device nodes in /dev/dri/ */
+    return (!strncmp(name, "drm/", 4) || !strncmp(name, "dri/", 4));
 #else
     return maj == DRM_MAJOR;
 #endif
@@ -2964,10 +2978,10 @@ sysfs_uevent_get(const char *path, const char *fmt, ...)
 /* Little white lie to avoid major rework of the existing code */
 #define DRM_BUS_VIRTIO 0x10
 
-static int drmParseSubsystemType(int maj, int min)
-{
 #ifdef __linux__
-    char path[PATH_MAX + 1];
+static int get_subsystem_type(const char *device_path)
+{
+    char path[PATH_MAX + 1] = "";
     char link[PATH_MAX + 1] = "";
     char *name;
     struct {
@@ -2982,8 +2996,8 @@ static int drmParseSubsystemType(int maj, int min)
         { "/virtio", DRM_BUS_VIRTIO },
     };
 
-    snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem",
-             maj, min);
+    strncpy(path, device_path, PATH_MAX);
+    strncat(path, "/subsystem", PATH_MAX);
 
     if (readlink(path, link, PATH_MAX) < 0)
         return -errno;
@@ -2998,6 +3012,27 @@ static int drmParseSubsystemType(int maj, int min)
     }
 
     return -EINVAL;
+}
+#endif
+
+static int drmParseSubsystemType(int maj, int min)
+{
+#ifdef __linux__
+    char path[PATH_MAX + 1] = "";
+    char real_path[PATH_MAX + 1] = "";
+    int subsystem_type;
+
+    snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+    if (!realpath(path, real_path))
+        return -errno;
+    snprintf(path, sizeof(path), "%s", real_path);
+
+    subsystem_type = get_subsystem_type(path);
+    if (subsystem_type == DRM_BUS_VIRTIO) {
+        strncat(path, "/..", PATH_MAX);
+        subsystem_type = get_subsystem_type(path);
+    }
+    return subsystem_type;
 #elif defined(__OpenBSD__) || defined(__DragonFly__)
     return DRM_BUS_PCI;
 #else
@@ -3699,7 +3734,6 @@ process_device(drmDevicePtr *device, const char *d_name,
 
     switch (subsystem_type) {
     case DRM_BUS_PCI:
-    case DRM_BUS_VIRTIO:
         return drmProcessPciDevice(device, node, node_type, maj, min,
                                    fetch_deviceinfo, flags);
     case DRM_BUS_USB:
@@ -4252,6 +4286,21 @@ drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
     return 0;
 }
 
+drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+                               uint32_t handle_count, uint32_t flags)
+{
+    struct drm_syncobj_timeline_array args;
+
+    memclear(args);
+    args.handles = (uintptr_t)handles;
+    args.points = (uintptr_t)points;
+    args.count_handles = handle_count;
+    args.flags = flags;
+
+    return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+}
+
+
 drm_public int drmSyncobjTransfer(int fd,
                                  uint32_t dst_handle, uint64_t dst_point,
                                  uint32_t src_handle, uint64_t src_point,