From: Emil Velikov <emil.velikov@xxxxxxxxxxxxx> The former has very subtle semantics (see the implementation in libdrm for details) which were required in the UMS days. With drmDevices around, we have enough information to build our heuristics and avoid drmOpen all together. Signed-off-by: Emil Velikov <emil.velikov at collabora.com> --- src/amdgpu_probe.c | 93 +++++++++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/src/amdgpu_probe.c b/src/amdgpu_probe.c index d8d8383..ec132e0 100644 --- a/src/amdgpu_probe.c +++ b/src/amdgpu_probe.c @@ -75,28 +75,24 @@ static void AMDGPUIdentify(int flags) xf86PrintChipsets(AMDGPU_NAME, "Driver for AMD Radeon", AMDGPUAny); } -static char *amdgpu_bus_id(ScrnInfoPtr pScrn, struct pci_device *dev) +static Bool amdgpu_device_matches(const drmDevicePtr device, + const struct pci_device *dev) { - char *busid; - - XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d", - dev->domain, dev->bus, dev->dev, dev->func); - - if (!busid) - xf86DrvMsgVerb(pScrn->scrnIndex, X_ERROR, 0, - "AMDGPU: Failed to generate bus ID string\n"); - - return busid; + return (device->bustype == DRM_BUS_PCI && + device->businfo.pci->domain == dev->domain && + device->businfo.pci->bus == dev->bus && + device->businfo.pci->dev == dev->dev && + device->businfo.pci->func == dev->func); } static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, struct pci_device *pci_dev, struct xf86_platform_device *platform_dev) { + drmDevicePtr *devices; struct pci_device *dev; const char *path; - char *busid; - int fd; + int fd, i, ret; if (platform_dev) { #ifdef ODEV_ATTRIB_FD @@ -121,16 +117,41 @@ static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, else dev = pci_dev; - busid = amdgpu_bus_id(pScrn, dev); - if (!busid) + ret = drmGetDevices2(0, NULL, 0); + if (ret <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] Failed to retrieve number of DRM devices: %d\n", + ret); return -1; + } + + devices = xnfcalloc(sizeof(drmDevicePtr), ret); + + ret = drmGetDevices2(0, devices, ret); + if (fd == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] Failed to retrieve DRM devices information: %d\n", + ret); + free(devices); + return -1; + } + + for (i = 0; i < ret; i++) { + if (amdgpu_device_matches(devices[i], dev) && + devices[i]->available_nodes & (1 << DRM_NODE_PRIMARY)) { + path = devices[i]->nodes[DRM_NODE_PRIMARY]; + fd = open(path, O_RDWR | O_CLOEXEC); + break; + } + } + drmFreeDevices(devices, ret); + free(devices); - fd = drmOpen(NULL, busid); if (fd == -1) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] Failed to open DRM device for %s: %s\n", - busid, strerror(errno)); - free(busid); + "[drm] Failed to open DRM device for " + "pci:%04x:%02x:%02x.%1u\n", + dev->domain, dev->bus, dev->dev, dev->func); return fd; } @@ -140,39 +161,10 @@ void amdgpu_kernel_close_fd(AMDGPUEntPtr pAMDGPUEnt) if (!(pAMDGPUEnt->platform_dev && pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) #endif - drmClose(pAMDGPUEnt->fd); + close(pAMDGPUEnt->fd); pAMDGPUEnt->fd = -1; } -static Bool amdgpu_open_drm_master(ScrnInfoPtr pScrn, AMDGPUEntPtr pAMDGPUEnt, - struct pci_device *pci_dev) -{ - drmSetVersion sv; - int err; - - pAMDGPUEnt->fd = amdgpu_kernel_open_fd(pScrn, pci_dev, NULL); - if (pAMDGPUEnt->fd == -1) - return FALSE; - - /* Check that what we opened was a master or a master-capable FD, - * by setting the version of the interface we'll use to talk to it. - * (see DRIOpenDRMMaster() in DRI1) - */ - sv.drm_di_major = 1; - sv.drm_di_minor = 1; - sv.drm_dd_major = -1; - sv.drm_dd_minor = -1; - err = drmSetInterfaceVersion(pAMDGPUEnt->fd, &sv); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] failed to set drm interface version.\n"); - amdgpu_kernel_close_fd(pAMDGPUEnt); - return FALSE; - } - - return TRUE; -} - static Bool amdgpu_get_scrninfo(int entity_num, struct pci_device *pci_dev) { ScrnInfoPtr pScrn = NULL; @@ -221,7 +213,8 @@ static Bool amdgpu_get_scrninfo(int entity_num, struct pci_device *pci_dev) goto error; pAMDGPUEnt = pPriv->ptr; - if (!amdgpu_open_drm_master(pScrn, pAMDGPUEnt, pci_dev)) + pAMDGPUEnt->fd = amdgpu_kernel_open_fd(pScrn, pci_dev, NULL); + if (pAMDGPUEnt->fd < 0) goto error; pAMDGPUEnt->fd_ref = 1; -- 2.16.0