summaryrefslogtreecommitdiff
path: root/lib/drmtest.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-11-13 10:37:16 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-11-16 11:56:03 +0000
commit3a243cb110462dbec2f9f1e3299e425b39d790c6 (patch)
tree233baee1c89f8e396c4d5ae4f4e00274dcef9784 /lib/drmtest.c
parent504f065fe20c6db0f4419dd3ef990d2a61df37c3 (diff)
lib: Attempt to load the module for a missing device
If we asked to open a particular chipset and we find no matching device, try again after attempting to load its module. Previously we only did this for vgem, which is not automatically probed during boot, but if we want to leave the module unloaded we have to try harder when we need the device. v2: DRIVER_* are already masks (and not shifts). Use a common driver_open for both /dev/dri/cardX and /dev/dri/renderDX. v3: Beware making local variables accidentally static scoped. v4: Beware multiple threads trying and failing to open a device v5: Fixed spelling of render (Petri) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Petri Latvala <petri.latvala@intel.com> Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'lib/drmtest.c')
-rw-r--r--lib/drmtest.c97
1 files changed, 57 insertions, 40 deletions
diff --git a/lib/drmtest.c b/lib/drmtest.c
index e6bdbc35..ef2f772e 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -44,6 +44,7 @@
#include <sys/syscall.h>
#include <sys/utsname.h>
#include <termios.h>
+#include <pthread.h>
#include "drmtest.h"
#include "i915_drm.h"
@@ -235,25 +236,19 @@ static int modprobe(const char *driver)
return igt_kmod_load(driver, "");
}
-/**
- * __drm_open_driver:
- * @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
- *
- * Open the first DRM device we can find, searching up to 16 device nodes
- *
- * Returns:
- * An open DRM fd or -1 on error
- */
-int __drm_open_driver(int chipset)
+static void modprobe_i915(const char *name)
{
- if (chipset & DRIVER_VGEM)
- modprobe("vgem");
+ /* When loading i915, we also want to load snd-hda et al */
+ igt_i915_driver_load(NULL);
+}
+static int __open_device(const char *base, int offset, unsigned int chipset)
+{
for (int i = 0; i < 16; i++) {
char name[80];
int fd;
- sprintf(name, "/dev/dri/card%u", i);
+ sprintf(name, "%s%u", base, i + offset);
fd = open(name, O_RDWR);
if (fd == -1)
continue;
@@ -262,16 +257,13 @@ int __drm_open_driver(int chipset)
has_known_intel_chipset(fd))
return fd;
- if (chipset & DRIVER_VC4 &&
- is_vc4_device(fd))
+ if (chipset & DRIVER_VC4 && is_vc4_device(fd))
return fd;
- if (chipset & DRIVER_VGEM &&
- is_vgem_device(fd))
+ if (chipset & DRIVER_VGEM && is_vgem_device(fd))
return fd;
- if (chipset & DRIVER_VIRTIO &&
- is_virtio_device(fd))
+ if (chipset & DRIVER_VIRTIO && is_virtio_device(fd))
return fd;
if (chipset & DRIVER_AMDGPU && is_amd_device(fd))
@@ -287,33 +279,58 @@ int __drm_open_driver(int chipset)
return -1;
}
-static int __drm_open_driver_render(int chipset)
+static int __open_driver(const char *base, int offset, unsigned int chipset)
{
- char *name;
- int i, fd;
-
- for (i = 128; i < (128 + 16); i++) {
- int ret;
-
- ret = asprintf(&name, "/dev/dri/renderD%u", i);
- igt_assert(ret != -1);
-
- fd = open(name, O_RDWR);
- free(name);
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ static const struct module {
+ unsigned int bit;
+ const char *module;
+ void (*modprobe)(const char *name);
+ } modules[] = {
+ { DRIVER_AMDGPU, "amdgpu" },
+ { DRIVER_INTEL, "i915", modprobe_i915 },
+ { DRIVER_VC4, "vc4" },
+ { DRIVER_VGEM, "vgem" },
+ { DRIVER_VIRTIO, "virtio-gpu" },
+ {}
+ };
+ int fd;
- if (fd == -1)
- continue;
+ fd = __open_device(base, offset, chipset);
+ if (fd != -1)
+ return fd;
- if (!is_i915_device(fd) || !has_known_intel_chipset(fd)) {
- close(fd);
- fd = -1;
- continue;
+ pthread_mutex_lock(&mutex);
+ for (const struct module *m = modules; m->module; m++) {
+ if (chipset & m->bit) {
+ if (m->modprobe)
+ m->modprobe(m->module);
+ else
+ modprobe(m->module);
}
-
- return fd;
}
+ pthread_mutex_unlock(&mutex);
- return fd;
+ return __open_device(base, offset, chipset);
+}
+
+/**
+ * __drm_open_driver:
+ * @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
+ *
+ * Open the first DRM device we can find, searching up to 16 device nodes
+ *
+ * Returns:
+ * An open DRM fd or -1 on error
+ */
+int __drm_open_driver(int chipset)
+{
+ return __open_driver("/dev/dri/card", 0, chipset);
+}
+
+static int __drm_open_driver_render(int chipset)
+{
+ return __open_driver("/dev/dri/renderD", 128, chipset);
}
static int at_exit_drm_fd = -1;