drm: Branch 'master' - 10 commits
[email protected] (GitLab Mirror) Tue, 24 Jul 2018 15:32:39 +0000 (UTC)
| Newsgroups | gmane.comp.video.dri.patches |
|---|---|
| Message-ID | <[email protected]> |
tests/Makefile.am | 9 + tests/drmdevice.c | 86 +++++++------- xf86drm.c | 315 +++++++++++++++++++++++------------------------------- 3 files changed, 188 insertions(+), 222 deletions(-) New commits: commit 68bd236aa417048238dc28464540a85ceb88963e Author: Emil Velikov <[email protected]> Date: Mon Jun 25 18:31:35 2018 +0100 drmdevice: print the correct host1x information While fairly close, the host1x and platform are two separate things. Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/tests/drmdevice.c b/tests/drmdevice.c index 049df3cf..cdf6e8de 100644 --- a/tests/drmdevice.c +++ b/tests/drmdevice.c @@ -85,13 +85,13 @@ print_device_info(drmDevicePtr device, int i, bool print_revision) compatible++; } } else if (device->bustype == DRM_BUS_HOST1X) { - char **compatible = device->deviceinfo.platform->compatible; + char **compatible = device->deviceinfo.host1x->compatible; printf("| +-> host1x\n"); printf("| +-> fullname\t%s\n", device->businfo.host1x->fullname); printf("+-> deviceinfo\n"); - printf(" +-> platform\n"); + printf(" +-> host1x\n"); printf(" +-> compatible\n"); while (*compatible) { commit 8a3a8c15e2917fe0e3006ac5305a9df15970a56a Author: Emil Velikov <[email protected]> Date: Mon Jun 25 18:29:35 2018 +0100 drmdevice: convert the tabbed output into a tree Making the output a little bit easier to parse by human beings. v2: Add extra whitespace (Eric) Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> (v1) Reviewed-by: Robert Foss <[email protected]> (v1) Reviewed-by: Eric Engestrom <[email protected]> (v1) diff --git a/tests/drmdevice.c b/tests/drmdevice.c index 0d75836f..049df3cf 100644 --- a/tests/drmdevice.c +++ b/tests/drmdevice.c @@ -36,67 +36,66 @@ static void print_device_info(drmDevicePtr device, int i, bool print_revision) { printf("device[%i]\n", i); - printf("\tavailable_nodes %04x\n", device->available_nodes); - printf("\tnodes\n"); + printf("+-> available_nodes %#04x\n", device->available_nodes); + printf("+-> nodes\n"); for (int j = 0; j < DRM_NODE_MAX; j++) if (device->available_nodes & 1 << j) - printf("\t\tnodes[%d] %s\n", j, device->nodes[j]); + printf("| +-> nodes[%d] %s\n", j, device->nodes[j]); - printf("\tbustype %04x\n", device->bustype); - printf("\tbusinfo\n"); + printf("+-> bustype %04x\n", device->bustype); if (device->bustype == DRM_BUS_PCI) { - printf("\t\tpci\n"); - printf("\t\t\tdomain\t%04x\n",device->businfo.pci->domain); - printf("\t\t\tbus\t%02x\n", device->businfo.pci->bus); - printf("\t\t\tdev\t%02x\n", device->businfo.pci->dev); - printf("\t\t\tfunc\t%1u\n", device->businfo.pci->func); - - printf("\tdeviceinfo\n"); - printf("\t\tpci\n"); - printf("\t\t\tvendor_id\t%04x\n", device->deviceinfo.pci->vendor_id); - printf("\t\t\tdevice_id\t%04x\n", device->deviceinfo.pci->device_id); - printf("\t\t\tsubvendor_id\t%04x\n", device->deviceinfo.pci->subvendor_id); - printf("\t\t\tsubdevice_id\t%04x\n", device->deviceinfo.pci->subdevice_id); + printf("| +-> pci\n"); + printf("| +-> domain %04x\n",device->businfo.pci->domain); + printf("| +-> bus %02x\n", device->businfo.pci->bus); + printf("| +-> dev %02x\n", device->businfo.pci->dev); + printf("| +-> func %1u\n", device->businfo.pci->func); + + printf("+-> deviceinfo\n"); + printf(" +-> pci\n"); + printf(" +-> vendor_id %04x\n", device->deviceinfo.pci->vendor_id); + printf(" +-> device_id %04x\n", device->deviceinfo.pci->device_id); + printf(" +-> subvendor_id %04x\n", device->deviceinfo.pci->subvendor_id); + printf(" +-> subdevice_id %04x\n", device->deviceinfo.pci->subdevice_id); if (print_revision) - printf("\t\t\trevision_id\t%02x\n", device->deviceinfo.pci->revision_id); + printf(" +-> revision_id %02x\n", device->deviceinfo.pci->revision_id); else - printf("\t\t\trevision_id\tIGNORED\n"); + printf(" +-> revision_id IGNORED\n"); } else if (device->bustype == DRM_BUS_USB) { - printf("\t\tusb\n"); - printf("\t\t\tbus\t%03u\n", device->businfo.usb->bus); - printf("\t\t\tdev\t%03u\n", device->businfo.usb->dev); - - printf("\tdeviceinfo\n"); - printf("\t\tusb\n"); - printf("\t\t\tvendor\t%04x\n", device->deviceinfo.usb->vendor); - printf("\t\t\tproduct\t%04x\n", device->deviceinfo.usb->product); + printf("| +-> usb\n"); + printf("| +-> bus %03u\n", device->businfo.usb->bus); + printf("| +-> dev %03u\n", device->businfo.usb->dev); + + printf("+-> deviceinfo\n"); + printf(" +-> usb\n"); + printf(" +-> vendor %04x\n", device->deviceinfo.usb->vendor); + printf(" +-> product %04x\n", device->deviceinfo.usb->product); } else if (device->bustype == DRM_BUS_PLATFORM) { char **compatible = device->deviceinfo.platform->compatible; - printf("\t\tplatform\n"); - printf("\t\t\tfullname\t%s\n", device->businfo.platform->fullname); + printf("| +-> platform\n"); + printf("| +-> fullname\t%s\n", device->businfo.platform->fullname); - printf("\tdeviceinfo\n"); - printf("\t\tplatform\n"); - printf("\t\t\tcompatible\n"); + printf("+-> deviceinfo\n"); + printf(" +-> platform\n"); + printf(" +-> compatible\n"); while (*compatible) { - printf("\t\t\t\t%s\n", *compatible); + printf(" %s\n", *compatible); compatible++; } } else if (device->bustype == DRM_BUS_HOST1X) { char **compatible = device->deviceinfo.platform->compatible; - printf("\t\thost1x\n"); - printf("\t\t\tfullname\t%s\n", device->businfo.host1x->fullname); + printf("| +-> host1x\n"); + printf("| +-> fullname\t%s\n", device->businfo.host1x->fullname); - printf("\tdeviceinfo\n"); - printf("\t\tplatform\n"); - printf("\t\t\tcompatible\n"); + printf("+-> deviceinfo\n"); + printf(" +-> platform\n"); + printf(" +-> compatible\n"); while (*compatible) { - printf("\t\t\t\t%s\n", *compatible); + printf(" %s\n", *compatible); compatible++; } } else { commit 33b035722b8fb30509d893597f1891c00e5c80f9 Author: Emil Velikov <[email protected]> Date: Mon Jun 25 18:07:49 2018 +0100 tests/drmdevice: add a couple of printf headers Add a few printf statements, which should make the output easier to parse. Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/tests/drmdevice.c b/tests/drmdevice.c index 9dd5098a..0d75836f 100644 --- a/tests/drmdevice.c +++ b/tests/drmdevice.c @@ -112,12 +112,15 @@ main(void) drmDevicePtr device; int fd, ret, max_devices; + printf("--- Checking the number of DRM device available ---\n"); max_devices = drmGetDevices2(0, NULL, 0); if (max_devices <= 0) { printf("drmGetDevices2() has returned %d\n", max_devices); return -1; } + printf("--- Devices reported %d ---\n", max_devices); + devices = calloc(max_devices, sizeof(drmDevicePtr)); if (devices == NULL) { @@ -125,6 +128,7 @@ main(void) return -1; } + printf("--- Retrieving devices information (PCI device revision is ignored) ---\n"); ret = drmGetDevices2(0, devices, max_devices); if (ret < 0) { printf("drmGetDevices2() returned an error %d\n", ret); @@ -137,13 +141,14 @@ main(void) for (int j = 0; j < DRM_NODE_MAX; j++) { if (devices[i]->available_nodes & 1 << j) { - printf("Opening device %d node %s\n", i, devices[i]->nodes[j]); + printf("--- Opening device node %s ---\n", devices[i]->nodes[j]); fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC, 0); if (fd < 0) { printf("Failed - %s (%d)\n", strerror(errno), errno); continue; } + printf("--- Retrieving device info, for node %s ---\n", devices[i]->nodes[j]); if (drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, &device) == 0) { print_device_info(device, i, true); drmFreeDevice(&device); commit c64dc00fd96740d2846be1f43956151d75c441eb Author: Emil Velikov <[email protected]> Date: Mon Jun 25 17:45:23 2018 +0100 tests/drmdevices: install alongside other utilities It's mildly useful program, to ship it when the user wants the "tests" installed. Obviously the "tests" in the name is a misnomer. Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/tests/Makefile.am b/tests/Makefile.am index 0355a925..b72c24f9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -43,5 +43,10 @@ TESTS = \ random check_PROGRAMS = \ - $(TESTS) \ - drmdevice + $(TESTS) + +if HAVE_INSTALL_TESTS +bin_PROGRAMS = drmdevice +else +check_PROGRAMS += drmdevice +endif commit 3988580e4c0f4b3647a0c6af138a3825453fe6e0 Author: Emil Velikov <[email protected]> Date: Tue May 15 17:37:49 2018 +0100 xf86drm: Add drmDevice support for virtio_gpu The GPU almost exclusively lives on the PCI bus, so we expose it as a normal PCI one. This allows all existing drmDevice users to work without any changes. One could wonder why a separate typeset is not introduced, alike say host1x. Unlike host1x the PCI/platform distinction for virtio provides no extra information. Plus if needed we can add the separate set at a later stage. Here are a few 'features' that virtio seems to be missing: - provides extra information on top the plaform devices - supports a range of GPU devices - is considered hardware description (DT) Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/xf86drm.c b/xf86drm.c index 51e00d23..1e621e99 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2954,6 +2954,9 @@ sysfs_uevent_get(const char *path, const char *fmt, ...) } #endif +/* Little white lie to avoid major rework of the existing code */ +#define DRM_BUS_VIRTIO 0x10 + static int drmParseSubsystemType(int maj, int min) { #ifdef __linux__ @@ -2983,6 +2986,9 @@ static int drmParseSubsystemType(int maj, int min) if (strncmp(name, "/host1x", 7) == 0) return DRM_BUS_HOST1X; + if (strncmp(name, "/virtio", 7) == 0) + return DRM_BUS_VIRTIO; + return -EINVAL; #elif defined(__OpenBSD__) return DRM_BUS_PCI; @@ -2995,12 +3001,16 @@ static int drmParseSubsystemType(int maj, int min) static char * get_real_pci_path(int maj, int min, char *real_path) { - char path[PATH_MAX + 1]; + char path[PATH_MAX + 1], *term; snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); if (!realpath(path, real_path)) return NULL; + term = strrchr(real_path, '/'); + if (term && strncmp(term, "/virtio", 7) == 0) + *term = 0; + return real_path; } @@ -3724,6 +3734,7 @@ process_device(drmDevicePtr *device, const char *d_name, switch (subsystem_type) { case DRM_BUS_PCI: + case DRM_BUS_VIRTIO: return drmProcessPciDevice(device, node, node_type, maj, min, fetch_deviceinfo, flags); case DRM_BUS_USB: commit a02900133b32dd4a7d6da4966f455ab337e80dfc Author: Emil Velikov <[email protected]> Date: Tue May 15 17:29:44 2018 +0100 xf86drm: introduce a get_real_pci_path() helper Introduce a helper which gets the real sysfs path for the given pci device. In other words, instead opening the /sys/dev/char/*/device symlink, we opt for the actual /sys/devices/pci*/*/ It folds three (nearly identical) snprintf's and paves the way of adding extra devices (see next patch) a piece of pie. v2: use a caller (on stack) provided real_path (Eric) Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> (v1) Reviewed-by: Robert Foss <[email protected]> (v1) Reviewed-by: Eric Engestrom <[email protected]> (v1) diff --git a/xf86drm.c b/xf86drm.c index 02da3e1f..51e00d23 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2992,16 +2992,29 @@ static int drmParseSubsystemType(int maj, int min) #endif } +static char * +get_real_pci_path(int maj, int min, char *real_path) +{ + char path[PATH_MAX + 1]; + + snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); + if (!realpath(path, real_path)) + return NULL; + + return real_path; +} + static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) { #ifdef __linux__ unsigned int domain, bus, dev, func; - char path[PATH_MAX + 1], *value; + char real_path[PATH_MAX + 1], *value; int num; - snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); + if (get_real_pci_path(maj, min, real_path) == NULL) + return -ENOENT; - value = sysfs_uevent_get(path, "PCI_SLOT_NAME"); + value = sysfs_uevent_get(real_path, "PCI_SLOT_NAME"); if (!value) return -ENOENT; @@ -3114,14 +3127,16 @@ static int parse_separate_sysfs_files(int maj, int min, "subsystem_vendor", "subsystem_device", }; - char path[PATH_MAX + 1]; + char path[PATH_MAX + 1], real_path[PATH_MAX + 1]; unsigned int data[ARRAY_SIZE(attrs)]; FILE *fp; int ret; + if (get_real_pci_path(maj, min, real_path) == NULL) + return -ENOENT; + for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) { - snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min, - attrs[i]); + snprintf(path, PATH_MAX, "%s/%s", real_path, attrs[i]); fp = fopen(path, "r"); if (!fp) return -errno; @@ -3145,11 +3160,14 @@ static int parse_separate_sysfs_files(int maj, int min, static int parse_config_sysfs_file(int maj, int min, drmPciDeviceInfoPtr device) { - char path[PATH_MAX + 1]; + char path[PATH_MAX + 1], real_path[PATH_MAX + 1]; unsigned char config[64]; int fd, ret; - snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/config", maj, min); + if (get_real_pci_path(maj, min, real_path) == NULL) + return -ENOENT; + + snprintf(path, PATH_MAX, "%s/config", real_path); fd = open(path, O_RDONLY); if (fd < 0) return -errno; commit 95b262f01975d7522cea67d5f5647e45a0152cf5 Author: Emil Velikov <[email protected]> Date: Tue May 15 16:32:10 2018 +0100 xf86drm: Allocate drmDevicePtr's on stack Currently we dynamically allocate 16 pointers and reallocate more as needed. Instead, allocate the maximum number (256) on stack - the number is small enough and is unlikely to change in the foreseeable future. This allows us to simplify the error handling and even shed a few bytes off the final binary. v2: - add a define & description behind the magic 256 - report error to strerr and skip when over 256 device nodes Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> (v1) Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> (v1) diff --git a/xf86drm.c b/xf86drm.c index 114cf855..02da3e1f 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -3766,6 +3766,13 @@ drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev) return false; } +/* + * The kernel drm core has a number of places that assume maximum of + * 3x64 devices nodes. That's 64 for each of primary, control and + * render nodes. Rounded it up to 256 for simplicity. + */ +#define MAX_DRM_NODES 256 + /** * Get information about the opened drm device * @@ -3846,7 +3853,7 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) return 0; #else - drmDevicePtr *local_devices; + drmDevicePtr local_devices[MAX_DRM_NODES]; drmDevicePtr d; DIR *sysdir; struct dirent *dent; @@ -3854,7 +3861,6 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) int subsystem_type; int maj, min; int ret, i, node_count; - int max_count = 16; dev_t find_rdev; if (drm_device_validate_flags(flags)) @@ -3877,15 +3883,9 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) if (subsystem_type < 0) return subsystem_type; - local_devices = calloc(max_count, sizeof(drmDevicePtr)); - if (local_devices == NULL) - return -ENOMEM; - sysdir = opendir(DRM_DIR_NAME); - if (!sysdir) { - ret = -errno; - goto free_locals; - } + if (!sysdir) + return -errno; i = 0; while ((dent = readdir(sysdir))) { @@ -3893,16 +3893,12 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) if (ret) continue; - if (i >= max_count) { - drmDevicePtr *temp; - - max_count += 16; - temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); - if (!temp) - goto free_devices; - local_devices = temp; + if (i >= MAX_DRM_NODES) { + fprintf(stderr, "More than %d drm nodes detected. " + "Please report a bug - that should not happen.\n" + "Skipping extra nodes\n", MAX_DRM_NODES); + break; } - local_devices[i] = d; i++; } @@ -3921,18 +3917,9 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) } closedir(sysdir); - free(local_devices); if (*device == NULL) return -ENODEV; return 0; - -free_devices: - drmFreeDevices(local_devices, i); - closedir(sysdir); - -free_locals: - free(local_devices); - return ret; #endif } @@ -3968,25 +3955,18 @@ int drmGetDevice(int fd, drmDevicePtr *device) */ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) { - drmDevicePtr *local_devices; + drmDevicePtr local_devices[MAX_DRM_NODES]; drmDevicePtr device; DIR *sysdir; struct dirent *dent; int ret, i, node_count, device_count; - int max_count = 16; if (drm_device_validate_flags(flags)) return -EINVAL; - local_devices = calloc(max_count, sizeof(drmDevicePtr)); - if (local_devices == NULL) - return -ENOMEM; - sysdir = opendir(DRM_DIR_NAME); - if (!sysdir) { - ret = -errno; - goto free_locals; - } + if (!sysdir) + return -errno; i = 0; while ((dent = readdir(sysdir))) { @@ -3994,16 +3974,12 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) if (ret) continue; - if (i >= max_count) { - drmDevicePtr *temp; - - max_count += 16; - temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); - if (!temp) - goto free_devices; - local_devices = temp; + if (i >= MAX_DRM_NODES) { + fprintf(stderr, "More than %d drm nodes detected. " + "Please report a bug - that should not happen.\n" + "Skipping extra nodes\n", MAX_DRM_NODES); + break; } - local_devices[i] = device; i++; } @@ -4025,16 +4001,7 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) } closedir(sysdir); - free(local_devices); return device_count; - -free_devices: - drmFreeDevices(local_devices, i); - closedir(sysdir); - -free_locals: - free(local_devices); - return ret; } /** commit f808fee90dba88d7bb1f2e8091377e4878ad5a4a Author: Emil Velikov <[email protected]> Date: Tue May 15 15:02:52 2018 +0100 xf86drm: Fold drmDevice processing into process_device() helper Don't duplicate the nearly identical code across the two call sites. It improves legibility and the diff stat seems nice. Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/xf86drm.c b/xf86drm.c index cbc0a408..114cf855 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -3676,6 +3676,52 @@ free_device: return ret; } +static int +process_device(drmDevicePtr *device, const char *d_name, + int req_subsystem_type, + bool fetch_deviceinfo, uint32_t flags) +{ + struct stat sbuf; + char node[PATH_MAX + 1]; + int node_type, subsystem_type; + unsigned int maj, min; + + node_type = drmGetNodeType(d_name); + if (node_type < 0) + return -1; + + snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, d_name); + if (stat(node, &sbuf)) + return -1; + + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) + return -1; + + subsystem_type = drmParseSubsystemType(maj, min); + if (req_subsystem_type != -1 && req_subsystem_type != subsystem_type) + return -1; + + switch (subsystem_type) { + case DRM_BUS_PCI: + return drmProcessPciDevice(device, node, node_type, maj, min, + fetch_deviceinfo, flags); + case DRM_BUS_USB: + return drmProcessUsbDevice(device, node, node_type, maj, min, + fetch_deviceinfo, flags); + case DRM_BUS_PLATFORM: + return drmProcessPlatformDevice(device, node, node_type, maj, min, + fetch_deviceinfo, flags); + case DRM_BUS_HOST1X: + return drmProcessHost1xDevice(device, node, node_type, maj, min, + fetch_deviceinfo, flags); + default: + return -1; + } +} + /* Consider devices located on the same bus as duplicate and fold the respective * entries into a single one. * @@ -3805,8 +3851,7 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) DIR *sysdir; struct dirent *dent; struct stat sbuf; - char node[PATH_MAX + 1]; - int node_type, subsystem_type; + int subsystem_type; int maj, min; int ret, i, node_count; int max_count = 16; @@ -3844,55 +3889,9 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) i = 0; while ((dent = readdir(sysdir))) { - node_type = drmGetNodeType(dent->d_name); - if (node_type < 0) - continue; - - snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); - if (stat(node, &sbuf)) - continue; - - maj = major(sbuf.st_rdev); - min = minor(sbuf.st_rdev); - - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) - continue; - - if (drmParseSubsystemType(maj, min) != subsystem_type) - continue; - - switch (subsystem_type) { - case DRM_BUS_PCI: - ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags); - if (ret) - continue; - - break; - - case DRM_BUS_USB: - ret = drmProcessUsbDevice(&d, node, node_type, maj, min, true, flags); - if (ret) - continue; - - break; - - case DRM_BUS_PLATFORM: - ret = drmProcessPlatformDevice(&d, node, node_type, maj, min, true, flags); - if (ret) - continue; - - break; - - case DRM_BUS_HOST1X: - ret = drmProcessHost1xDevice(&d, node, node_type, maj, min, true, flags); - if (ret) - continue; - - break; - - default: + ret = process_device(&d, dent->d_name, subsystem_type, true, flags); + if (ret) continue; - } if (i >= max_count) { drmDevicePtr *temp; @@ -3973,10 +3972,6 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) drmDevicePtr device; DIR *sysdir; struct dirent *dent; - struct stat sbuf; - char node[PATH_MAX + 1]; - int node_type, subsystem_type; - int maj, min; int ret, i, node_count, device_count; int max_count = 16; @@ -3995,61 +3990,9 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) i = 0; while ((dent = readdir(sysdir))) { - node_type = drmGetNodeType(dent->d_name); - if (node_type < 0) - continue; - - snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); - if (stat(node, &sbuf)) - continue; - - maj = major(sbuf.st_rdev); - min = minor(sbuf.st_rdev); - - if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) - continue; - - subsystem_type = drmParseSubsystemType(maj, min); - - if (subsystem_type < 0) - continue; - - switch (subsystem_type) { - case DRM_BUS_PCI: - ret = drmProcessPciDevice(&device, node, node_type, - maj, min, devices != NULL, flags); - if (ret) - continue; - - break; - - case DRM_BUS_USB: - ret = drmProcessUsbDevice(&device, node, node_type, maj, min, - devices != NULL, flags); - if (ret) - continue; - - break; - - case DRM_BUS_PLATFORM: - ret = drmProcessPlatformDevice(&device, node, node_type, maj, min, - devices != NULL, flags); - if (ret) - continue; - - break; - - case DRM_BUS_HOST1X: - ret = drmProcessHost1xDevice(&device, node, node_type, maj, min, - devices != NULL, flags); - if (ret) - continue; - - break; - - default: + ret = process_device(&device, dent->d_name, -1, devices != NULL, flags); + if (ret) continue; - } if (i >= max_count) { drmDevicePtr *temp; commit 56e72d3f2e6d6929433574aaf9fbb422f54d8646 Author: Emil Velikov <[email protected]> Date: Thu Jun 21 16:06:35 2018 +0100 xf86drm: introduce drm_device_has_rdev() helper Currently we match the opened drmDevice fd with each drmDevice we process. Move that after all the devices are processed and folded, via the drm_device_has_rdev(). This makes the code easier to follow and allows us to unify the massive process loop across drmGetDevice2 and drmGetDevices2. That in itself is coming with a later commit. Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/xf86drm.c b/xf86drm.c index e1bbbe99..cbc0a408 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -3705,6 +3705,21 @@ drm_device_validate_flags(uint32_t flags) return (flags & ~DRM_DEVICE_GET_PCI_REVISION); } +static bool +drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev) +{ + struct stat sbuf; + + for (int i = 0; i < DRM_NODE_MAX; i++) { + if (device->available_nodes & 1 << i) { + if (stat(device->nodes[i], &sbuf) == 0 && + sbuf.st_rdev == find_rdev) + return true; + } + } + return false; +} + /** * Get information about the opened drm device * @@ -3889,21 +3904,22 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) local_devices = temp; } - /* store target at local_devices[0] for ease to use below */ - if (find_rdev == sbuf.st_rdev && i) { - local_devices[i] = local_devices[0]; - local_devices[0] = d; - } - else - local_devices[i] = d; + local_devices[i] = d; i++; } node_count = i; drmFoldDuplicatedDevices(local_devices, node_count); - *device = local_devices[0]; - drmFreeDevices(&local_devices[1], node_count - 1); + for (i = 0; i < node_count; i++) { + if (!local_devices[i]) + continue; + + if (drm_device_has_rdev(local_devices[i], find_rdev)) + *device = local_devices[i]; + else + drmFreeDevice(&local_devices[i]); + } closedir(sysdir); free(local_devices); commit 7f52a0ebf7d8f5edbe7382454b7c5d03bb0bb7dc Author: Emil Velikov <[email protected]> Date: Tue May 15 16:43:58 2018 +0100 xf86drm: drmGetDevice2: error out if the fd has unknown subsys Currently one can open() any /dev node. If it's unknown drmParseSubsystemType() will return an error. Track that and bail as needed. Signed-off-by: Emil Velikov <[email protected]> Tested-by: Robert Foss <[email protected]> Reviewed-by: Robert Foss <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> diff --git a/xf86drm.c b/xf86drm.c index 87c216cf..e1bbbe99 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -3814,6 +3814,8 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) return -EINVAL; subsystem_type = drmParseSubsystemType(maj, min); + if (subsystem_type < 0) + return subsystem_type; local_devices = calloc(max_count, sizeof(drmDevicePtr)); if (local_devices == NULL) ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot --