xf86drm: introduce drmGetDeviceNameFromFd2

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>
main
Emil Velikov 2016-11-10 17:26:50 +00:00 committed by Emil Velikov
parent 7e0bc3bf1c
commit 37d790f7d4
2 changed files with 56 additions and 0 deletions

View File

@ -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
}

View File

@ -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);