xf86drm: introduce drmGetDeviceNameFromFd2
authorEmil Velikov <emil.velikov@collabora.com>
Thu, 10 Nov 2016 17:26:50 +0000 (17:26 +0000)
committerEmil Velikov <emil.l.velikov@gmail.com>
Tue, 22 Nov 2016 13:54:23 +0000 (13:54 +0000)
The original version considered only card devices, while this will pick
the device/node name regardless - card, control, renderD, other...

Current implementation is "linux" specific, in such that it relies on
sysfs/uevent file. At the same time this gives us the flexibility to
support any nodes even future ones, as long as they're within DRM_MAJOR.

Shamelessly copied from mesa, latter by: Gary Wong <gtw@gnu.org>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
xf86drm.c
xf86drm.h

index 9b97bbb..ed924a7 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -3303,3 +3303,54 @@ free_locals:
     free(local_devices);
     return ret;
 }
+
+char *drmGetDeviceNameFromFd2(int fd)
+{
+#ifdef __linux__
+    struct stat sbuf;
+    char *device_name = NULL;
+    unsigned int maj, min;
+    FILE *f;
+    char buf[512];
+    static const char match[9] = "\nDEVNAME=";
+    int expected = 1;
+
+
+    if (fstat(fd, &sbuf))
+        return NULL;
+
+    maj = major(sbuf.st_rdev);
+    min = minor(sbuf.st_rdev);
+
+    if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+        return NULL;
+
+    snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/uevent", maj, min);
+    if (!(f = fopen(buf, "r")))
+        return NULL;
+
+    while (expected < sizeof(match)) {
+        int c = getc(f);
+
+        if (c == EOF) {
+            fclose(f);
+            return NULL;
+        } else if (c == match[expected] )
+            expected++;
+        else
+            expected = 0;
+    }
+
+    strcpy(buf, "/dev/");
+    if (fgets(buf + 5, sizeof(buf) - 5, f)) {
+        buf[strcspn(buf, "\n")] = '\0';
+        device_name = strdup(buf);
+    }
+
+    fclose(f);
+    return device_name;
+#else
+#warning "Missing implementation of drmGetDeviceNameFromFd2"
+    return NULL;
+#endif
+}
index 481d882..4da6bd3 100644 (file)
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -753,6 +753,11 @@ typedef struct _drmEventContext {
 extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
 
 extern char *drmGetDeviceNameFromFd(int fd);
+
+/* Improved version of drmGetDeviceNameFromFd which attributes for any type of
+ * device/node - card, control or renderD.
+ */
+extern char *drmGetDeviceNameFromFd2(int fd);
 extern int drmGetNodeTypeFromFd(int fd);
 
 extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);