commit cc47270236e07a084da0b302b4b14feaeded867e Author: Bryce Harrington Date: Tue Feb 12 14:24:37 2013 -0800 If EAGAIN returned opening drm, then try, try again. The kernel returns EAGAIN on drm open when the drm device is currently unavailable, such as if it is in use by another process (e.g. plymouth), or hasn't finished initializing (e.g. on a really fast SSD). Check for this error code, and if it's hit then block until it either resolved or some other error returned (and in which case, log the appropriate messages to that effect). Signed-off-by: Bryce Harrington diff --git a/xf86drm.c b/xf86drm.c index 2a74c80..063898f 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -476,6 +476,7 @@ static int drmOpenByBusid(const char *busid) { int i, pci_domain_ok = 1; int fd; + int err = 0; const char *buf; drmSetVersion sv; @@ -485,13 +486,19 @@ static int drmOpenByBusid(const char *busid) drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); if (fd >= 0) { /* We need to try for 1.4 first for proper PCI domain support - * and if that fails, we know the kernel is busted + * and if that fails, we know either the kernel is busted or + * the drm device is otherwise occupied at the moment. */ sv.drm_di_major = 1; sv.drm_di_minor = 4; sv.drm_dd_major = -1; /* Don't care */ sv.drm_dd_minor = -1; /* Don't care */ - if (drmSetInterfaceVersion(fd, &sv)) { + err = drmSetInterfaceVersion(fd, &sv); + while (err == EAGAIN) { + usleep(20); /* Just keep swimming */ + err = drmSetInterfaceVersion(fd, &sv); + } + if (err) { #ifndef __alpha__ pci_domain_ok = 0; #endif @@ -499,8 +506,11 @@ static int drmOpenByBusid(const char *busid) sv.drm_di_minor = 1; sv.drm_dd_major = -1; /* Don't care */ sv.drm_dd_minor = -1; /* Don't care */ - drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n",fd); - drmSetInterfaceVersion(fd, &sv); + drmMsg("drmOpenByBusid: Interface 1.4 failed (%d), trying 1.1\n", err); + err = drmSetInterfaceVersion(fd, &sv); + if (err) { + drmMesg("drmOpenByBusid: Interface 1.1 failed (%d) as well\n", err); + } } buf = drmGetBusid(fd); drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);