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
parent
13b99f2a89
commit
5403cb39c1
68
xf86drm.c
68
xf86drm.c
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue