From: "Joshi, Kunal1" <kunal1.joshi@intel.com>
To: "Murthy, Arun R" <arun.r.murthy@intel.com>,
igt-dev@lists.freedesktop.org
Subject: Re: [i-g-t,2/6] lib/igt_connector_helper: Add generic connector helpers
Date: Mon, 9 Mar 2026 16:36:58 +0530 [thread overview]
Message-ID: <d3322c0b-8bd6-4242-8a74-ad5dfacb3909@intel.com> (raw)
In-Reply-To: <d256aedf-2e67-41be-a440-a6e39ad5d18b@intel.com>
Hello Arun,
On 09-03-2026 15:08, Murthy, Arun R wrote:
> On 26-02-2026 02:58, Kunal Joshi wrote:
>> Add a lightweight helper library for DRM connector operations used
>> by USB4 switch and other dock/undock tests:
>>
>> - igt_connector_get_connected(): enumerate connected connectors
>> - igt_connector_get_info(): query name, EDID serial, and MST path
>> - igt_connector_find_by_path(): PATH-based connector lookup (MST)
>> - igt_connector_find_by_name(): name-based connector lookup
>> - igt_connector_reprobe_all(): force reprobe all connectors by
>> iterating each connector to trigger DRM core re-detection
>>
>> These helpers abstract common DRM connector patterns that are needed
>> by multiple test suites for display enumeration and verification.
> The contents of these are already present in lib/igt__kms.c
>
Wasn't able to find similar helper that maybe already present,
Could you please point to those function names?
> Instead of a new file, can these be exported from lib/igt_kms.c ?
It was intentional, since igt_kms is already over 8k lines, want to have
separate lib's grouped by entity,
In this case created connector_helper for having all connector related
helpers at one place.
Thanks and Regards
Kunal Joshi
>
>
> Thanks and Regards,
> Arun R Murthy
> -------------------
>
>>
>> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
>> ---
>> lib/igt_connector_helper.c | 299 +++++++++++++++++++++++++++++++++++++
>> lib/igt_connector_helper.h | 27 ++++
>> lib/meson.build | 1 +
>> 3 files changed, 327 insertions(+)
>> create mode 100644 lib/igt_connector_helper.c
>> create mode 100644 lib/igt_connector_helper.h
>>
>> diff --git a/lib/igt_connector_helper.c b/lib/igt_connector_helper.c
>> new file mode 100644
>> index 000000000..6be849b7a
>> --- /dev/null
>> +++ b/lib/igt_connector_helper.c
>> @@ -0,0 +1,299 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright © 2026 Intel Corporation
>> + */
>> +
>> +/**
>> + * SECTION:igt_connector_helper
>> + * @short_description: Generic connector helper functions for DRM/KMS
>> + * @title: Connector Helper
>> + * @include: igt_connector_helper.h
>> + *
>> + * Helper functions for DRM connector operations including enumeration,
>> + * lookup by name/path, and EDID serial extraction.
>> + */
>> +
>> +#include <string.h>
>> +#include <xf86drm.h>
>> +#include <xf86drmMode.h>
>> +
>> +#include "igt_core.h"
>> +#include "igt_edid.h"
>> +#include "igt_kms.h"
>> +#include "igt_connector_helper.h"
>> +
>> +/**
>> + * igt_connector_get_connected:
>> + * @drm_fd: DRM file descriptor
>> + * @connectors: array to store connector IDs; must be valid if
>> @max_connectors > 0
>> + * @max_connectors: maximum number of connectors to store
>> + *
>> + * Walks all DRM connectors and stores the IDs of those currently
>> connected.
>> + * Scanning stops once @max_connectors IDs have been collected; later
>> + * connectors are not examined.
>> + *
>> + * Returns: number of connector IDs written to @connectors, capped by
>> + * @max_connectors.
>> + */
>> +int igt_connector_get_connected(int drm_fd, uint32_t *connectors,
>> + int max_connectors)
>> +{
>> + drmModeRes *res;
>> + drmModeConnector *conn;
>> + int count = 0;
>> + int i;
>> +
>> + igt_assert(max_connectors >= 0);
>> + if (max_connectors > 0)
>> + igt_assert(connectors);
>> +
>> + res = drmModeGetResources(drm_fd);
>> + if (!res)
>> + return 0;
>> +
>> + for (i = 0; i < res->count_connectors && count < max_connectors;
>> i++) {
>> + conn = drmModeGetConnector(drm_fd, res->connectors[i]);
>> + if (!conn)
>> + continue;
>> +
>> + if (conn->connection == DRM_MODE_CONNECTED)
>> + connectors[count++] = conn->connector_id;
>> +
>> + drmModeFreeConnector(conn);
>> + }
>> +
>> + drmModeFreeResources(res);
>> + return count;
>> +}
>> +
>> +/**
>> + * igt_connector_get_info:
>> + * @drm_fd: DRM file descriptor
>> + * @connector_id: connector ID
>> + * @name: buffer for connector name (mandatory)
>> + * @name_size: size of @name; must be > 0
>> + * @serial: buffer for EDID-derived serial (mandatory)
>> + * @serial_size: size of @serial; must be > 1
>> + * @path: buffer for MST PATH property (optional, may be NULL)
>> + * @path_size: size of @path buffer
>> + *
>> + * Fills connector name, MST PATH, and EDID-derived serial for a
>> connector.
>> + * @name is always filled when the connector is found. @serial is
>> filled from
>> + * the ASCII serial string descriptor (0xFF) if present, else from
>> the 32-bit
>> + * header serial number; left empty if no EDID is available. @path
>> is filled
>> + * only if requested and the PATH property exists.
>> + *
>> + * Success means the connector object was found and @name was filled.
>> + * @serial and @path are best-effort and may still be empty on success.
>> + *
>> + * Returns: true if the connector was found, false otherwise.
>> + */
>> +bool igt_connector_get_info(int drm_fd, uint32_t connector_id,
>> + char *name, size_t name_size,
>> + char *serial, size_t serial_size,
>> + char *path, size_t path_size)
>> +{
>> + drmModeConnector *conn;
>> + drmModePropertyBlobPtr edid_blob = NULL;
>> + uint64_t blob_id = 0;
>> + drmModePropertyPtr prop;
>> + const struct edid *edid;
>> + int i;
>> +
>> + igt_assert(name && name_size > 0);
>> + igt_assert(serial && serial_size > 1);
>> + igt_assert(!path || path_size > 0);
>> +
>> + name[0] = '\0';
>> + serial[0] = '\0';
>> + if (path)
>> + path[0] = '\0';
>> +
>> + conn = drmModeGetConnector(drm_fd, connector_id);
>> + if (!conn)
>> + return false;
>> +
>> + snprintf(name, name_size, "%s-%d",
>> + kmstest_connector_type_str(conn->connector_type),
>> + conn->connector_type_id);
>> +
>> + for (i = 0; i < conn->count_props; i++) {
>> + prop = drmModeGetProperty(drm_fd, conn->props[i]);
>> + if (!prop)
>> + continue;
>> +
>> + if (strcmp(prop->name, "EDID") == 0)
>> + blob_id = conn->prop_values[i];
>> +
>> + drmModeFreeProperty(prop);
>> + if (blob_id)
>> + break;
>> + }
>> +
>> + /* Extract MST PATH if requested */
>> + if (path) {
>> + drmModePropertyBlobPtr path_blob;
>> +
>> + /* PATH blob payload is a NUL-terminated string */
>> + path_blob = kmstest_get_path_blob(drm_fd, connector_id);
>> + if (path_blob) {
>> + snprintf(path, path_size, "%s",
>> + (const char *)path_blob->data);
>> + drmModeFreePropertyBlob(path_blob);
>> + }
>> + }
>> +
>> + drmModeFreeConnector(conn);
>> +
>> + if (blob_id) {
>> + edid_blob = drmModeGetPropertyBlob(drm_fd, blob_id);
>> + if (edid_blob) {
>> + if (edid_blob->length >= sizeof(struct edid)) {
>> + edid = edid_blob->data;
>> + edid_get_any_serial(edid, serial, serial_size);
>> + }
>> + drmModeFreePropertyBlob(edid_blob);
>> + }
>> + }
>> +
>> + return true;
>> +}
>> +
>> +/**
>> + * igt_connector_find_by_path:
>> + * @drm_fd: DRM file descriptor
>> + * @path: MST PATH property value to match
>> + * @connector_id: output for connector ID (filled on success)
>> + *
>> + * Finds the currently connected connector whose PATH property
>> matches @path
>> + * (exact string comparison). PATH is the preferred stable identity
>> for MST
>> + * connectors; connector IDs may change across hotplug events.
>> + *
>> + * Returns: true if a matching connected connector was found.
>> + */
>> +bool igt_connector_find_by_path(int drm_fd, const char *path,
>> + uint32_t *connector_id)
>> +{
>> + drmModeRes *res;
>> + drmModeConnector *conn;
>> + drmModePropertyBlobPtr path_blob;
>> + bool found = false;
>> + int i;
>> +
>> + if (!path || !connector_id)
>> + return false;
>> +
>> + res = drmModeGetResources(drm_fd);
>> + if (!res)
>> + return false;
>> +
>> + for (i = 0; i < res->count_connectors && !found; i++) {
>> + conn = drmModeGetConnector(drm_fd, res->connectors[i]);
>> + if (!conn)
>> + continue;
>> +
>> + if (conn->connection == DRM_MODE_CONNECTED) {
>> + path_blob = kmstest_get_path_blob(drm_fd,
>> + conn->connector_id);
>> + if (path_blob) {
>> + if (strcmp(path_blob->data, path) == 0) {
>> + *connector_id = conn->connector_id;
>> + found = true;
>> + }
>> + drmModeFreePropertyBlob(path_blob);
>> + }
>> + }
>> +
>> + drmModeFreeConnector(conn);
>> + }
>> +
>> + drmModeFreeResources(res);
>> +
>> + if (found)
>> + igt_debug("igt_connector: Found connector %u for path '%s'\n",
>> + *connector_id, path);
>> +
>> + return found;
>> +}
>> +
>> +/**
>> + * igt_connector_find_by_name:
>> + * @drm_fd: DRM file descriptor
>> + * @name: connector name to match (e.g., "DP-6")
>> + * @connector_id: output for connector ID (filled on success)
>> + *
>> + * Name-based lookup helper. Prefer igt_connector_find_by_path()
>> for MST
>> + * connectors, since connector names and IDs may change across
>> hotplug events.
>> + *
>> + * Returns: true if a matching connected connector was found.
>> + */
>> +bool igt_connector_find_by_name(int drm_fd, const char *name,
>> + uint32_t *connector_id)
>> +{
>> + drmModeRes *res;
>> + drmModeConnector *conn;
>> + char conn_name[IGT_CONNECTOR_NAME_MAX];
>> + bool found = false;
>> + int i;
>> +
>> + if (!name || !connector_id)
>> + return false;
>> +
>> + res = drmModeGetResources(drm_fd);
>> + if (!res)
>> + return false;
>> +
>> + for (i = 0; i < res->count_connectors && !found; i++) {
>> + conn = drmModeGetConnector(drm_fd, res->connectors[i]);
>> + if (!conn)
>> + continue;
>> +
>> + snprintf(conn_name, sizeof(conn_name), "%s-%d",
>> + kmstest_connector_type_str(conn->connector_type),
>> + conn->connector_type_id);
>> +
>> + if (strcmp(conn_name, name) == 0 &&
>> + conn->connection == DRM_MODE_CONNECTED) {
>> + *connector_id = conn->connector_id;
>> + found = true;
>> + }
>> +
>> + drmModeFreeConnector(conn);
>> + }
>> +
>> + drmModeFreeResources(res);
>> +
>> + if (found)
>> + igt_debug("igt_connector: Found connector %u for name '%s'\n",
>> + *connector_id, name);
>> +
>> + return found;
>> +}
>> +
>> +/**
>> + * igt_connector_reprobe_all:
>> + * @drm_fd: DRM file descriptor
>> + *
>> + * Issues a GETCONNECTOR ioctl for every connector, requesting fresh
>> state
>> + * from the kernel. This is often sufficient to refresh connector
>> status and
>> + * MST topology visibility after hotplug events, but does not
>> guarantee a
>> + * full hardware reprobe in all driver paths.
>> + */
>> +void igt_connector_reprobe_all(int drm_fd)
>> +{
>> + drmModeRes *res;
>> + drmModeConnector *conn;
>> + int i;
>> +
>> + res = drmModeGetResources(drm_fd);
>> + if (!res)
>> + return;
>> +
>> + for (i = 0; i < res->count_connectors; i++) {
>> + conn = drmModeGetConnector(drm_fd, res->connectors[i]);
>> + if (conn)
>> + drmModeFreeConnector(conn);
>> + }
>> +
>> + drmModeFreeResources(res);
>> +}
>> diff --git a/lib/igt_connector_helper.h b/lib/igt_connector_helper.h
>> new file mode 100644
>> index 000000000..fffb2661b
>> --- /dev/null
>> +++ b/lib/igt_connector_helper.h
>> @@ -0,0 +1,27 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2026 Intel Corporation
>> + */
>> +
>> +#ifndef IGT_CONNECTOR_HELPER_H
>> +#define IGT_CONNECTOR_HELPER_H
>> +
>> +#include <stdbool.h>
>> +#include <stddef.h>
>> +#include <stdint.h>
>> +
>> +#define IGT_CONNECTOR_NAME_MAX 32
>> +
>> +int igt_connector_get_connected(int drm_fd, uint32_t *connectors,
>> + int max_connectors);
>> +bool igt_connector_get_info(int drm_fd, uint32_t connector_id,
>> + char *name, size_t name_size,
>> + char *serial, size_t serial_size,
>> + char *path, size_t path_size);
>> +bool igt_connector_find_by_path(int drm_fd, const char *path,
>> + uint32_t *connector_id);
>> +bool igt_connector_find_by_name(int drm_fd, const char *name,
>> + uint32_t *connector_id);
>> +void igt_connector_reprobe_all(int drm_fd);
>> +
>> +#endif /* IGT_CONNECTOR_HELPER_H */
>> diff --git a/lib/meson.build b/lib/meson.build
>> index ea721ecf7..074b21fdf 100644
>> --- a/lib/meson.build
>> +++ b/lib/meson.build
>> @@ -113,6 +113,7 @@ lib_sources = [
>> 'igt_vmwgfx.c',
>> 'igt_psr.c',
>> 'igt_amd.c',
>> + 'igt_connector_helper.c',
>> 'igt_edid.c',
>> 'igt_eld.c',
>> 'igt_infoframe.c',
next prev parent reply other threads:[~2026-03-09 11:07 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-25 21:28 [PATCH i-g-t 0/6] add test to validate dock/undock and switch Kunal Joshi
2026-02-25 21:28 ` [PATCH i-g-t 1/6] lib/igt_edid: add EDID serial extraction helpers Kunal Joshi
2026-03-09 9:30 ` [i-g-t,1/6] " Murthy, Arun R
2026-03-09 11:02 ` Joshi, Kunal1
2026-03-16 3:03 ` Murthy, Arun R
2026-02-25 21:28 ` [PATCH i-g-t 2/6] lib/igt_connector_helper: Add generic connector helpers Kunal Joshi
2026-03-09 9:38 ` [i-g-t,2/6] " Murthy, Arun R
2026-03-09 11:06 ` Joshi, Kunal1 [this message]
2026-03-16 3:17 ` Murthy, Arun R
2026-02-25 21:28 ` [PATCH i-g-t 3/6] lib/igt_serial: add generic serial communication helper Kunal Joshi
2026-03-16 5:40 ` [i-g-t,3/6] " Murthy, Arun R
2026-02-25 21:28 ` [PATCH i-g-t 4/6] lib/igt_usb4_switch: add helper library for USB4 Switch 3141 Kunal Joshi
2026-03-16 8:45 ` [i-g-t,4/6] " Murthy, Arun R
2026-02-25 21:28 ` [PATCH i-g-t 5/6] tests/kms_feature_discovery: add basic usb4 switch discovery Kunal Joshi
2026-03-09 10:05 ` [i-g-t,5/6] " Murthy, Arun R
2026-02-25 21:28 ` [PATCH i-g-t 6/6] tests/intel/kms_usb4_switch: Add USB4 switch test suite Kunal Joshi
2026-03-09 10:03 ` [i-g-t,6/6] " Murthy, Arun R
2026-03-09 11:14 ` Joshi, Kunal1
2026-03-16 3:38 ` Murthy, Arun R
2026-02-26 2:20 ` ✗ Xe.CI.BAT: failure for add test to validate dock/undock and switch (rev3) Patchwork
2026-02-26 3:04 ` ✓ i915.CI.BAT: success " Patchwork
2026-02-26 6:52 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-02-26 7:45 ` ✗ i915.CI.Full: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d3322c0b-8bd6-4242-8a74-ad5dfacb3909@intel.com \
--to=kunal1.joshi@intel.com \
--cc=arun.r.murthy@intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox