summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-06-24 11:50:55 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-06-24 11:50:55 +0100
commit0c7cf7a6bb1c91b59ad326198f3364554e3dfeb5 (patch)
tree1abe6f118cea6b23a2c9b6623bdd9507e6ff7603
parent5c8829b30ad3acd2e59dac9ffa2aba8aadcada61 (diff)
intel: Wait for our expected device node to appear
If the path we want to open for the KMS device is not yet available, wait a short while and try again. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80397 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/intel_device.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/src/intel_device.c b/src/intel_device.c
index fcb179bd..22eedb69 100644
--- a/src/intel_device.c
+++ b/src/intel_device.c
@@ -163,6 +163,30 @@ static int __intel_check_device(int fd)
return ret;
}
+static int open_cloexec(const char *path)
+{
+ struct stat st;
+ int loop = 1000;
+ int fd;
+
+ /* No file? Assume the driver is loading slowly */
+ while (stat(path, &st) == -1 && errno == ENOENT && --loop)
+ usleep(50000);
+
+ if (loop != 1000)
+ ErrorF("intel: waited %d ms for '%s' to appear\n",
+ (1000 - loop) * 50, path);
+
+ fd = -1;
+#ifdef O_CLOEXEC
+ fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+#endif
+ if (fd == -1)
+ fd = fd_set_cloexec(open(path, O_RDWR | O_NONBLOCK));
+
+ return fd;
+}
+
#ifdef __linux__
static int __intel_open_device__major_minor(int _major, int _minor)
{
@@ -187,11 +211,7 @@ static int __intel_open_device__major_minor(int _major, int _minor)
if (stat(path, &st) == 0 &&
major(st.st_rdev) == _major &&
minor(st.st_rdev) == _minor) {
-#ifdef O_CLOEXEC
- fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
-#endif
- if (fd == -1)
- fd = fd_set_cloexec(open(path, O_RDWR | O_NONBLOCK));
+ fd = open_cloexec(path);
break;
}
}
@@ -254,11 +274,7 @@ static int __intel_open_device__pci(const struct pci_device *pci)
if (strncmp(de->d_name, "card", 4) == 0) {
sprintf(path + base + 4, "/dev/dri/%s", de->d_name);
-#ifdef O_CLOEXEC
- fd = open(path + base + 4, O_RDWR | O_NONBLOCK | O_CLOEXEC);
-#endif
- if (fd == -1)
- fd = fd_set_cloexec(open(path + base + 4, O_RDWR | O_NONBLOCK));
+ fd = open_cloexec(path + base + 4);
if (fd != -1)
break;
@@ -321,15 +337,8 @@ static int __intel_open_device(const struct pci_device *pci, const char *path)
fd = __intel_open_device__pci(pci);
if (fd == -1)
fd = __intel_open_device__legacy(pci);
- } else {
-#ifdef O_CLOEXEC
- fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
-#else
- fd = -1;
-#endif
- if (fd == -1)
- fd = fd_set_cloexec(open(path, O_RDWR | O_NONBLOCK));
- }
+ } else
+ fd = open_cloexec(path);
return fd;
}