[PATCH libdrm] xf86drm: introduce drmGetDeviceNameFromFd2
Emil Velikov
emil.l.velikov at gmail.com
Thu Nov 10 17:43:05 UTC 2016
From: Emil Velikov <emil.velikov at collabora.com>
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 at gnu.org>
Signed-off-by: Emil Velikov <emil.velikov at collabora.com>
---
There's quite a bit of [subtle chaos] in mesa about this. Sometimes we
explicitly request the render node, sometimes we use an open-coded version
of drmGetDeviceNameFromFd, which due to sheer luck just works.
One could apply some polish here, but I'd choose to keep things as close
to original.
---
xf86drm.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
xf86drm.h | 5 +++++
2 files changed, 56 insertions(+)
diff --git a/xf86drm.c b/xf86drm.c
index 80e2f27..0bca43a 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -3367,3 +3367,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
+}
diff --git a/xf86drm.h b/xf86drm.h
index d1ebc32..4fa395e 100644
--- 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);
--
2.10.2
More information about the dri-devel
mailing list