/* * Copyright (C) 2021-2024 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/os_interface/linux/pci_path.h" #include "shared/source/os_interface/linux/sys_calls.h" #include #include #include namespace NEO { std::optional getPciLinkPath(int deviceFd) { char path[256] = {0}; size_t pathlen = 256; if (SysCalls::getDevicePath(deviceFd, path, pathlen)) { return std::nullopt; } if (SysCalls::access(path, F_OK)) { return std::nullopt; } int readLinkSize = 0; char devicePath[256] = {0}; size_t devicePathLength = 256; readLinkSize = SysCalls::readlink(path, devicePath, devicePathLength); if (readLinkSize == -1) { return std::nullopt; } return std::string(devicePath, static_cast(readLinkSize)); } std::optional getPciPath(int deviceFd) { auto deviceLinkPath = NEO::getPciLinkPath(deviceFd); if (deviceLinkPath == std::nullopt) { return std::nullopt; } auto pciPathPos = deviceLinkPath->find("/drm/render"); if (pciPathPos == std::string::npos) { pciPathPos = deviceLinkPath->find("/drm/card"); } if (pciPathPos == std::string::npos || pciPathPos < 12) { return std::nullopt; } return deviceLinkPath->substr(pciPathPos - 12u, 12u); } std::optional getPciRootPath(int deviceFd) { auto pciLinkPath = NEO::getPciLinkPath(deviceFd); // pciLinkPath = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128/", // Then root path = "/pci0000:37/0000:37:01.0/0000:38:00.0/" if (pciLinkPath == std::nullopt) { return std::nullopt; } auto startPos = pciLinkPath->find("/pci"); if (startPos == std::string::npos) { return std::nullopt; } // Root PCI path is at 2 levels up from drm/renderD128 uint32_t rootPciDepth = 4; auto endPos = std::string::npos; while (rootPciDepth--) { endPos = pciLinkPath->rfind('/', endPos - 1); if (endPos == std::string::npos) { return std::nullopt; } } return pciLinkPath->substr(startPos, endPos - startPos); } } // namespace NEO