On 10.11.2016 18:43, Emil Velikov wrote:
From: Emil Velikov <emil.velikov@xxxxxxxxxxxxx> 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@xxxxxxx> Signed-off-by: Emil Velikov <emil.velikov@xxxxxxxxxxxxx>
Makes sense to me. Reviewed-by: Nicolai Hähnle <nicolai.haehnle@xxxxxxx>
--- 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);
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel