libdrm: Fix PCI domain domain support

This works in conjunction with newer kernels. If we succeed in requesting
interface 1.4, the we know the kernel provides proper domain numbers. If
not, ignore the domain number as it's bogus (except on Alpha).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Adam Jackson <ajax@redhat.com>
main
Benjamin Herrenschmidt 2010-08-06 13:55:11 +10:00 committed by Adam Jackson
parent 431f7f00db
commit b04515c5d6
1 changed files with 25 additions and 5 deletions

View File

@ -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 * 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. * 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 */ /* First, check if the IDs are exactly the same */
if (strcasecmp(id1, id2) == 0) if (strcasecmp(id1, id2) == 0)
@ -257,6 +257,13 @@ static int drmMatchBusID(const char *id1, const char *id2)
return 0; 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)) if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
return 0; return 0;
else else
@ -482,7 +489,7 @@ int drmAvailable(void)
*/ */
static int drmOpenByBusid(const char *busid) static int drmOpenByBusid(const char *busid)
{ {
int i; int i, pci_domain_ok = 1;
int fd; int fd;
const char *buf; const char *buf;
drmSetVersion sv; drmSetVersion sv;
@ -492,14 +499,27 @@ static int drmOpenByBusid(const char *busid)
fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
if (fd >= 0) { 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_major = 1;
sv.drm_di_minor = 1; sv.drm_di_minor = 4;
sv.drm_dd_major = -1; /* Don't care */ sv.drm_dd_major = -1; /* Don't care */
sv.drm_dd_minor = -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); buf = drmGetBusid(fd);
drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
if (buf && drmMatchBusID(buf, busid)) { if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
drmFreeBusid(buf); drmFreeBusid(buf);
return fd; return fd;
} }