summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xf86drm.c84
-rw-r--r--xf86drm.h3
2 files changed, 87 insertions, 0 deletions
diff --git a/xf86drm.c b/xf86drm.c
index e117bc63..194cd35e 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -40,6 +40,8 @@
#include <string.h>
#include <strings.h>
#include <ctype.h>
+#include <dirent.h>
+#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
@@ -522,6 +524,20 @@ static int drmGetMinorType(int minor)
}
}
+static const char *drmGetMinorName(int type)
+{
+ switch (type) {
+ case DRM_NODE_PRIMARY:
+ return "card";
+ case DRM_NODE_CONTROL:
+ return "controlD";
+ case DRM_NODE_RENDER:
+ return "renderD";
+ default:
+ return NULL;
+ }
+}
+
/**
* Open the device by bus ID.
*
@@ -2736,3 +2752,71 @@ int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
return 0;
}
+static char *drmGetMinorNameForFD(int fd, int type)
+{
+#ifdef __linux__
+ DIR *sysdir;
+ struct dirent *pent, *ent;
+ struct stat sbuf;
+ const char *name = drmGetMinorName(type);
+ int len;
+ char dev_name[64], buf[64];
+ long name_max;
+ int maj, min;
+
+ if (!name)
+ return NULL;
+
+ len = strlen(name);
+
+ 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/device/drm", maj, min);
+
+ sysdir = opendir(buf);
+ if (!sysdir)
+ return NULL;
+
+ name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
+ if (name_max == -1)
+ goto out_close_dir;
+
+ pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
+ if (pent == NULL)
+ goto out_close_dir;
+
+ while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
+ if (strncmp(ent->d_name, name, len) == 0) {
+ free(pent);
+ closedir(sysdir);
+
+ snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
+ ent->d_name);
+ return strdup(dev_name);
+ }
+ }
+
+ free(pent);
+
+out_close_dir:
+ closedir(sysdir);
+#endif
+ return NULL;
+}
+
+char *drmGetPrimaryDeviceNameFromFd(int fd)
+{
+ return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
+}
+
+char *drmGetRenderDeviceNameFromFd(int fd)
+{
+ return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
+}
diff --git a/xf86drm.h b/xf86drm.h
index afd38a10..40c55c92 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -749,6 +749,9 @@ extern int drmGetNodeTypeFromFd(int fd);
extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
+extern char *drmGetPrimaryDeviceNameFromFd(int fd);
+extern char *drmGetRenderDeviceNameFromFd(int fd);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif