From 53405da4ad2d99654b0d0034c3d42926a0f9e6f1 Mon Sep 17 00:00:00 2001 From: kankanzh Date: Thu, 30 Dec 2021 23:30:02 +0800 Subject: [PATCH] [Media Common] Reduce library dependency Reduce library dependency and add corresponding implementation --- cmrtlib/linux/hardware/drm_device.h | 119 +++++++++++++++++- .../linux/common/os/i915/include/xf86drm.h | 33 ----- media_driver/linux/common/os/media_srcs.cmake | 3 + .../linux/common/os/mos_interface.cpp | 1 + media_driver/media_top_cmake.cmake | 2 +- 5 files changed, 122 insertions(+), 36 deletions(-) diff --git a/cmrtlib/linux/hardware/drm_device.h b/cmrtlib/linux/hardware/drm_device.h index 8071de9fae..83b240288d 100644 --- a/cmrtlib/linux/hardware/drm_device.h +++ b/cmrtlib/linux/hardware/drm_device.h @@ -53,6 +53,7 @@ #endif #include #include +#include #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -124,7 +125,7 @@ typedef void *drmAddress, **drmAddressPtr; /**< For mapped regions */ #define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) #define __align_mask(value, mask) (((value) + (mask)) & ~(mask)) -#define ALIGN(value, alignment) __align_mask(value, (__typeof__(value))((alignment) - 1)) +#define ALIGN_CEIL(value, alignment) __align_mask(value, (__typeof__(value))((alignment) - 1)) #define DRM_PLATFORM_DEVICE_NAME_LEN 512 typedef struct _drmPciBusInfo { @@ -230,6 +231,21 @@ drm_device_validate_flags(uint32_t flags) return (flags & ~DRM_DEVICE_GET_PCI_REVISION); } +static bool +drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev) +{ + struct stat sbuf; + + for (int i = 0; i < DRM_NODE_MAX; i++) { + if (device->available_nodes & 1 << i) { + if (stat(device->nodes[i], &sbuf) == 0 && + sbuf.st_rdev == find_rdev) + return true; + } + } + return false; +} + static int drmGetMaxNodeName(void) { return sizeof(DRM_DIR_NAME) + @@ -289,7 +305,7 @@ static drmDevicePtr drmDeviceAlloc(unsigned int type, const char *node, unsigned int i; char *ptr; - max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *)); + max_node_length = ALIGN_CEIL(drmGetMaxNodeName(), sizeof(void *)); extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); @@ -1176,6 +1192,105 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices) return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices); } +/** + * Get information about the opened drm device + * + * \param fd file descriptor of the drm device + * \param flags feature/behaviour bitmask + * \param device the address of a drmDevicePtr where the information + * will be allocated in stored + * + * \return zero on success, negative error code otherwise. + * + * \note Unlike drmGetDevice it does not retrieve the pci device revision field + * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set. + */ +int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) +{ + drmDevicePtr local_devices[MAX_DRM_NODES]; + drmDevicePtr d; + DIR *sysdir; + struct dirent *dent; + struct stat sbuf; + int subsystem_type; + int maj, min; + int ret, i, node_count; + dev_t find_rdev; + + if (drm_device_validate_flags(flags)) + return -EINVAL; + + if (fd == -1 || device == NULL) + return -EINVAL; + + if (fstat(fd, &sbuf)) + return -errno; + + find_rdev = sbuf.st_rdev; + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + + if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode)) + return -EINVAL; + + subsystem_type = drmParseSubsystemType(maj, min); + if (subsystem_type < 0) + return subsystem_type; + + sysdir = opendir(DRM_DIR_NAME); + if (!sysdir) + return -errno; + + i = 0; + while ((dent = readdir(sysdir))) { + ret = process_device(&d, dent->d_name, subsystem_type, true, flags); + if (ret) + continue; + + if (i >= MAX_DRM_NODES) { + fprintf(stderr, "More than %d drm nodes detected. " + "Please report a bug - that should not happen.\n" + "Skipping extra nodes\n", MAX_DRM_NODES); + break; + } + local_devices[i] = d; + i++; + } + node_count = i; + + drmFoldDuplicatedDevices(local_devices, node_count); + + *device = NULL; + + for (i = 0; i < node_count; i++) { + if (!local_devices[i]) + continue; + + if (drm_device_has_rdev(local_devices[i], find_rdev)) + *device = local_devices[i]; + else + drmFreeDevice(&local_devices[i]); + } + + closedir(sysdir); + if (*device == NULL) + return -ENODEV; + return 0; +} + +/** + * Get information about the opened drm device + * + * \param fd file descriptor of the drm device + * \param device the address of a drmDevicePtr where the information + * will be allocated in stored + * + * \return zero on success, negative error code otherwise. + */ +int drmGetDevice(int fd, drmDevicePtr *device) +{ + return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device); +} static int32_t GetRendererFileDescriptor(char * drm_node) { diff --git a/media_driver/linux/common/os/i915/include/xf86drm.h b/media_driver/linux/common/os/i915/include/xf86drm.h index 6ff1ba8a00..1a27858a49 100644 --- a/media_driver/linux/common/os/i915/include/xf86drm.h +++ b/media_driver/linux/common/os/i915/include/xf86drm.h @@ -713,39 +713,6 @@ extern char *drmGetRenderDeviceNameFromFd(int fd); #define DRM_BUS_PCI 0 -typedef struct _drmPciBusInfo { - uint16_t domain; - uint8_t bus; - uint8_t dev; - uint8_t func; -} drmPciBusInfo, *drmPciBusInfoPtr; - -typedef struct _drmPciDeviceInfo { - uint16_t vendor_id; - uint16_t device_id; - uint16_t subvendor_id; - uint16_t subdevice_id; - uint8_t revision_id; -} drmPciDeviceInfo, *drmPciDeviceInfoPtr; - -typedef struct _drmDevice { - char **nodes; /* DRM_NODE_MAX sized array */ - int available_nodes; /* DRM_NODE_* bitmask */ - int bustype; - union { - drmPciBusInfoPtr pci; - } businfo; - union { - drmPciDeviceInfoPtr pci; - } deviceinfo; -} drmDevice, *drmDevicePtr; - -extern int drmGetDevice(int fd, drmDevicePtr *device); -extern void drmFreeDevice(drmDevicePtr *device); - -extern int drmGetDevices(drmDevicePtr devices[], int max_devices); -extern void drmFreeDevices(drmDevicePtr devices[], int count); - #if defined(__cplusplus) } #endif diff --git a/media_driver/linux/common/os/media_srcs.cmake b/media_driver/linux/common/os/media_srcs.cmake index e80e326529..df3ccb33a4 100644 --- a/media_driver/linux/common/os/media_srcs.cmake +++ b/media_driver/linux/common/os/media_srcs.cmake @@ -24,6 +24,9 @@ if(ENABLE_PRODUCTION_KMD) media_include_subdirectory(i915_production) endif() +# This is to include drm_device.h in cmrtlib, no cpp file needed. +include_directories(${BS_DIR_MEDIA}/cmrtlib/linux/hardware) + set(TMP_SOURCES_ ${CMAKE_CURRENT_LIST_DIR}/hwinfo_linux.c ${CMAKE_CURRENT_LIST_DIR}/mos_context_specific.cpp diff --git a/media_driver/linux/common/os/mos_interface.cpp b/media_driver/linux/common/os/mos_interface.cpp index ae2567b79c..fd00ae78e8 100644 --- a/media_driver/linux/common/os/mos_interface.cpp +++ b/media_driver/linux/common/os/mos_interface.cpp @@ -34,6 +34,7 @@ #include "mos_os_virtualengine_scalability_specific_next.h" #include "mos_graphicsresource_specific_next.h" #include "mos_bufmgr_priv.h" +#include "drm_device.h" #if (_DEBUG || _RELEASE_INTERNAL) #include //for simulate random OS API failure diff --git a/media_driver/media_top_cmake.cmake b/media_driver/media_top_cmake.cmake index 238d9adae3..fad0bd310d 100755 --- a/media_driver/media_top_cmake.cmake +++ b/media_driver/media_top_cmake.cmake @@ -145,7 +145,7 @@ if (NOT DEFINED INCLUDED_LIBS OR "${INCLUDED_LIBS}" STREQUAL "") endif() target_compile_options( ${LIB_NAME} PUBLIC ${LIBGMM_CFLAGS_OTHER}) - target_link_libraries ( ${LIB_NAME} ${LIBGMM_LIBRARIES} drm) + target_link_libraries ( ${LIB_NAME} ${LIBGMM_LIBRARIES}) include(${MEDIA_EXT_CMAKE}/ext/media_feature_include_ext.cmake OPTIONAL)