[PATCH libdrm 2/3] tests/util: Make util_open() use drmDevice
Thierry Reding
thierry.reding at gmail.com
Mon Jan 30 10:29:22 UTC 2017
From: Thierry Reding <treding at nvidia.com>
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 at nvidia.com>
---
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
More information about the dri-devel
mailing list