xf86drm: Reuse sysfs_uevent_get()

Recent patches for USB, platform and host1x bus support introduced the
sysfs_uevent_get() function that provides a generic way of parsing the
sysfs uevent file that is associated with each device in Linux.

Open-coded variants of this still exist in other places, so make those
reuse the new function to remove some code duplication.

Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
main
Thierry Reding 2017-01-18 08:29:23 +01:00
parent 13b99f2a89
commit 5403cb39c1
1 changed files with 19 additions and 49 deletions

View File

@ -2971,33 +2971,22 @@ static int drmParseSubsystemType(int maj, int min)
static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
{ {
#ifdef __linux__ #ifdef __linux__
char path[PATH_MAX + 1]; unsigned int domain, bus, dev, func;
char data[512 + 1]; char path[PATH_MAX + 1], *value;
char *str; int num;
int domain, bus, dev, func;
int fd, ret;
snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/uevent", maj, min); snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
fd = open(path, O_RDONLY);
if (fd < 0)
return -errno;
ret = read(fd, data, sizeof(data)-1); value = sysfs_uevent_get(path, "PCI_SLOT_NAME");
close(fd); if (!value)
if (ret < 0) return -ENOENT;
return -errno;
data[ret] = '\0';
#define TAG "PCI_SLOT_NAME=" num = sscanf(value, "%04x:%02x:%02x.%1u", &domain, &bus, &dev, &func);
str = strstr(data, TAG); free(value);
if (str == NULL)
if (num != 4)
return -EINVAL; return -EINVAL;
if (sscanf(str, TAG "%04x:%02x:%02x.%1u",
&domain, &bus, &dev, &func) != 4)
return -EINVAL;
#undef TAG
info->domain = domain; info->domain = domain;
info->bus = bus; info->bus = bus;
info->dev = dev; info->dev = dev;
@ -4084,13 +4073,8 @@ char *drmGetDeviceNameFromFd2(int fd)
{ {
#ifdef __linux__ #ifdef __linux__
struct stat sbuf; struct stat sbuf;
char *device_name = NULL; char path[PATH_MAX + 1], *value;
unsigned int maj, min; unsigned int maj, min;
FILE *f;
char buf[512];
static const char match[9] = "\nDEVNAME=";
size_t expected = 1;
if (fstat(fd, &sbuf)) if (fstat(fd, &sbuf))
return NULL; return NULL;
@ -4101,30 +4085,16 @@ char *drmGetDeviceNameFromFd2(int fd)
if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
return NULL; return NULL;
snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/uevent", maj, min); snprintf(path, sizeof(path), "/sys/dev/char/%d:%d", maj, min);
if (!(f = fopen(buf, "r")))
value = sysfs_uevent_get(path, "DEVNAME");
if (!value)
return NULL; return NULL;
while (expected < sizeof(match)) { snprintf(path, sizeof(path), "/dev/%s", value);
int c = getc(f); free(value);
if (c == EOF) { return strdup(path);
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 #else
struct stat sbuf; struct stat sbuf;
char node[PATH_MAX + 1]; char node[PATH_MAX + 1];