From 5ce95e92d5ec4e4a53abeb6a0f8f843781a4322e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Jun 2014 16:14:28 +0100 Subject: [PATCH] intel: Wait for the DRM device to load Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80397 Signed-off-by: Chris Wilson --- src/intel_device.c | 97 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/src/intel_device.c b/src/intel_device.c index d9d8df3..431905a 100644 --- a/src/intel_device.c +++ b/src/intel_device.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -162,32 +163,96 @@ static int __intel_check_device(int fd) return ret; } -static int __intel_open_device(const struct pci_device *pci, const char *path) +static int __intel_open_device__pci(const struct pci_device *pci) { +#ifdef __linux__ + char path[256]; + DIR *dir; + struct dirent *de; + int base; int fd; - if (path == NULL) { - char id[20]; - int ret; - - if (pci == NULL) - return -1; + base = sprintf(path, + "/sys/bus/pci/devices/%04x:%02x:%02x.%d/", + pci->domain, pci->bus, pci->dev, pci->func); - snprintf(id, sizeof(id), - "pci:%04x:%02x:%02x.%d", - pci->domain, pci->bus, pci->dev, pci->func); + sprintf(path + base, "drm"); + dir = opendir(path); + if (dir == NULL) { + struct stat st; + int loop = 0; - ret = drmCheckModesettingSupported(id); - if (ret) { + sprintf(path + base, "driver"); + if (stat(path, &st)) { if (xf86LoadKernelModule("i915")) - ret = drmCheckModesettingSupported(id); - if (ret) return -1; - /* Be nice to the user and load fbcon too */ (void)xf86LoadKernelModule("fbcon"); } - fd = fd_set_nonblock(drmOpen(NULL, id)); + sprintf(path + base, "drm"); + while ((dir = opendir(path)) == NULL && loop++ < 100) + usleep(20000); + + ErrorF("waited %d ms for driver to load\n", loop * 20000 / 1000); + + if (dir == NULL) + return -1; + } + + fd = -1; + de = readdir(dir); + while (de) { + if (strncmp(de->d_name, "card", 4) == 0) { + sprintf(path + base + 3, "/%s", de->d_name); +#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)); + break; + } + } + closedir(dir); + + return fd; +#else + return -1; +#endif +} + +static int __intel_open_device__legacy(const struct pci_device *pci) +{ + char id[20]; + int ret; + + snprintf(id, sizeof(id), + "pci:%04x:%02x:%02x.%d", + pci->domain, pci->bus, pci->dev, pci->func); + + ret = drmCheckModesettingSupported(id); + if (ret) { + if (xf86LoadKernelModule("i915")) + ret = drmCheckModesettingSupported(id); + if (ret) + return -1; + /* Be nice to the user and load fbcon too */ + (void)xf86LoadKernelModule("fbcon"); + } + + return fd_set_nonblock(drmOpen(NULL, id)); +} + +static int __intel_open_device(const struct pci_device *pci, const char *path) +{ + int fd; + + if (path == NULL) { + if (pci == NULL) + return -1; + + 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); -- 1.9.1