diff --git a/xf86drm.c b/xf86drm.c index 220aaa16..e48b9c99 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -229,7 +229,7 @@ drmHashEntry *drmGetEntry(int fd) * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is * domain, b is bus, d is device, f is function. */ -static int drmMatchBusID(const char *id1, const char *id2) +static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok) { /* First, check if the IDs are exactly the same */ if (strcasecmp(id1, id2) == 0) @@ -257,6 +257,13 @@ static int drmMatchBusID(const char *id1, const char *id2) return 0; } + /* If domains aren't properly supported by the kernel interface, + * just ignore them, which sucks less than picking a totally random + * card with "open by name" + */ + if (!pci_domain_ok) + o1 = o2 = 0; + if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2)) return 0; else @@ -482,7 +489,7 @@ int drmAvailable(void) */ static int drmOpenByBusid(const char *busid) { - int i; + int i, pci_domain_ok = 1; int fd; const char *buf; drmSetVersion sv; @@ -492,14 +499,27 @@ static int drmOpenByBusid(const char *busid) fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); 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 + */ sv.drm_di_major = 1; - sv.drm_di_minor = 1; + sv.drm_di_minor = 4; sv.drm_dd_major = -1; /* Don't care */ sv.drm_dd_minor = -1; /* Don't care */ - drmSetInterfaceVersion(fd, &sv); + if (drmSetInterfaceVersion(fd, &sv)) { +#ifndef __alpha__ + pci_domain_ok = 0; +#endif + sv.drm_di_major = 1; + 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); + } buf = drmGetBusid(fd); drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); - if (buf && drmMatchBusID(buf, busid)) { + if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) { drmFreeBusid(buf); return fd; }