From: Thierry Reding <treding@xxxxxxxxxx> The util_open() helper is used in a couple of test programs to open an appropriate device. It takes a device path and a module name, both are optional, as parameters. If a device path is specified, it will try to open the given device. Otherwise it will try all available devices. If only a specific subset is desired, the module parameter can be used as a filter. The function will use it to open only devices whose kernel driver matches the given module name. Instead of relying on the legacy drmOpen() function to do this, convert util_open() to use the new drmDevice helpers. This gets it functionally much closer to what other DRM/KMS users, such as the X.Org Server or a Wayland server, do. Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> --- tests/util/kms.c | 167 +++++++++++++++++++++++++++++++++++++++++-------------- tests/util/kms.h | 43 ++++++++++++++ 2 files changed, 168 insertions(+), 42 deletions(-) diff --git a/tests/util/kms.c b/tests/util/kms.c index d866398237bb..c5d35ab616d1 100644 --- a/tests/util/kms.c +++ b/tests/util/kms.c @@ -42,15 +42,18 @@ #endif #include <errno.h> +#include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "xf86drm.h" #include "xf86drmMode.h" #include "common.h" +#include "kms.h" struct type_name { unsigned int type; @@ -125,58 +128,138 @@ const char *util_lookup_connector_type_name(unsigned int type) ARRAY_SIZE(connector_type_names)); } -static const char * const modules[] = { - "i915", - "amdgpu", - "radeon", - "nouveau", - "vmwgfx", - "omapdrm", - "exynos", - "tilcdc", - "msm", - "sti", - "tegra", - "imx-drm", - "rockchip", - "atmel-hlcdc", - "fsl-dcu-drm", - "vc4", - "virtio_gpu", - "mediatek", - "meson", -}; +char *util_get_driver(int fd) +{ + drmVersionPtr version; + char *driver; -int util_open(const char *device, const char *module) + version = drmGetVersion(fd); + if (!version) + return NULL; + + driver = strdup(version->name); + + drmFreeVersion(version); + + return driver; +} + +int util_get_devices(drmDevicePtr **devicesp, uint32_t flags) +{ + drmDevicePtr *devices; + unsigned int count; + int err; + + err = drmGetDevices2(flags, NULL, 0); + if (err < 0) + return err; + + /* + * If the caller hasn't specified a return pointer for the new devices + * array, all of the below is pointless, so simply return the number of + * devices available. + */ + if (!devicesp) + return err; + + count = err; + + devices = calloc(count, sizeof(*devices)); + if (!devices) + return -ENOMEM; + + err = drmGetDevices2(flags, devices, count); + if (err < 0) { + free(devices); + return err; + } + + if (devicesp) + *devicesp = devices; + else + free(devices); + + return count; +} + +void util_free_devices(drmDevicePtr *devices, unsigned int count) +{ + drmFreeDevices(devices, count); + free(devices); +} + +int util_open_with_module(const char *device, const char *module) { - int fd; + int fd, err = 0; + + if (module) + printf("trying to open `%s' with `%s'...", device, module); + else + printf("trying to open `%s'...", device); + + fd = open(device, O_RDWR); + if (fd < 0) { + err = -errno; + goto out; + } if (module) { - fd = drmOpen(module, device); - if (fd < 0) { - fprintf(stderr, "failed to open device '%s': %s\n", - module, strerror(errno)); - return -errno; + char *driver = util_get_driver(fd); + if (!driver) { + err = -EINVAL; + goto close; } - } else { - unsigned int i; - for (i = 0; i < ARRAY_SIZE(modules); i++) { - printf("trying to open device '%s'...", modules[i]); + if (strcmp(module, driver) != 0) + err = -EINVAL; + + free(driver); + + if (err < 0) + goto close; + } + + printf("done\n"); + return fd; + +close: + close(fd); +out: + printf("failed\n"); + return err; +} - fd = drmOpen(modules[i], device); - if (fd < 0) { - printf("failed\n"); - } else { - printf("done\n"); +int util_open(const char *device, const char *module) +{ + int fd, err; + + if (!device) { + drmDevicePtr *devices, dev; + unsigned int count, i, j; + const char *node; + + err = util_get_devices(&devices, 0); + if (err < 0) + return err; + + count = err; + + util_for_each_device(dev, i, devices, count) { + node = util_device_get_node(dev, DRM_NODE_PRIMARY); + if (!node) + continue; + + fd = util_open_with_module(node, module); + if (fd >= 0) break; - } } - if (fd < 0) { - fprintf(stderr, "no device found\n"); - return -ENODEV; - } + util_free_devices(devices, count); + + if (i == count) + fd = -ENOENT; + } else { + fd = util_open_with_module(device, module); } return fd; diff --git a/tests/util/kms.h b/tests/util/kms.h index dde2ed2c5636..b7b5b4747950 100644 --- a/tests/util/kms.h +++ b/tests/util/kms.h @@ -30,6 +30,49 @@ const char *util_lookup_encoder_type_name(unsigned int type); const char *util_lookup_connector_status_name(unsigned int type); const char *util_lookup_connector_type_name(unsigned int type); +char *util_get_driver(int fd); + +int util_get_devices(drmDevicePtr **devicesp, uint32_t flags); +void util_free_devices(drmDevicePtr *devices, unsigned int count); + +static inline drmDevicePtr util_get_device(drmDevicePtr *devices, + unsigned int count, + unsigned int index) +{ + if (index >= count) + return NULL; + + return devices[index]; +} + +#define util_for_each_device(device, index, devices, count) \ + for (device = util_get_device(devices, count, (index) = 0); \ + (index) < (count); \ + device = util_get_device(devices, count, ++(index))) + +static inline char *util_device_get_node(drmDevicePtr device, + unsigned int type) +{ + if (type >= DRM_NODE_MAX) + return NULL; + + return device->nodes[type]; +} + +#define for_each_if(condition) \ + if (!(condition)) { \ + } else + +#define util_device_for_each_node(node, type, device) \ + for (node = util_device_get_node(device, (type) = 0); \ + (type) < DRM_NODE_MAX; \ + node = util_device_get_node(device, ++(type))) + +#define util_device_for_each_available_node(node, type, device) \ + util_device_for_each_node(node, type, device) \ + for_each_if ((device)->available_nodes & (1 << (type))) + +int util_open_with_module(const char *device, const char *module); int util_open(const char *device, const char *module); #endif /* UTIL_KMS_H */ -- 2.11.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel