All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@gmail.com>
To: dri-devel@lists.freedesktop.org
Subject: [PATCH libdrm 2/3] tests/util: Make util_open() use drmDevice
Date: Mon, 30 Jan 2017 11:29:22 +0100	[thread overview]
Message-ID: <20170130102923.1991-2-thierry.reding@gmail.com> (raw)
In-Reply-To: <20170130102923.1991-1-thierry.reding@gmail.com>

From: Thierry Reding <treding@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@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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2017-01-30 10:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-30 10:29 [PATCH libdrm 1/3] tests/util: Reindent using editorconfig settings Thierry Reding
2017-01-30 10:29 ` Thierry Reding [this message]
2017-02-01 12:47   ` [PATCH libdrm 2/3] tests/util: Make util_open() use drmDevice Emil Velikov
2017-02-01 15:59     ` Thierry Reding
2017-01-30 10:29 ` [PATCH libdrm 3/3] tests/util: Add some API documentation Thierry Reding
2017-01-30 10:32 ` [PATCH libdrm 1/3] tests/util: Reindent using editorconfig settings Thierry Reding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170130102923.1991-2-thierry.reding@gmail.com \
    --to=thierry.reding@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.