[PATCH i-g-t v2 16/39] lib/chamelium/v3: Add method to discover Chamelium ports

Louis Chauvet louis.chauvet at bootlin.com
Tue Jul 9 15:34:32 UTC 2024


Since Chamelium v3 ports can change (recently added MST ports, for
example), they need to be discovered to prevent using an incorrect port.

This commit introduces the RPC calls GetSupportedPorts, IsMst, and
GetChildren to list all ports, check if a port is MST-capable, and fetch
the child ports of MST ports, respectively.

Signed-off-by: Louis Chauvet <louis.chauvet at bootlin.com>
---
 lib/chamelium/v3/igt_chamelium.c | 133 +++++++++++++++++++++++++++++++++++++++
 lib/chamelium/v3/igt_chamelium.h |   6 ++
 2 files changed, 139 insertions(+)

diff --git a/lib/chamelium/v3/igt_chamelium.c b/lib/chamelium/v3/igt_chamelium.c
index 7a5a1ff19e4b..c4c75c57fa64 100644
--- a/lib/chamelium/v3/igt_chamelium.c
+++ b/lib/chamelium/v3/igt_chamelium.c
@@ -149,3 +149,136 @@ void chamelium_v3_uninit(struct igt_chamelium_v3 *chamelium)
 	free(chamelium);
 }
 
+/**
+ * __chamelium_rpc - Call a remote function on the chamelium
+ *
+ * @chamelium: Chamelium to call the function on
+ * @method_name: RPC endpoint name
+ * @format_str: RPC parameters description
+ * @...: RPC parameters
+ *
+ * Returns a xmlrpc_value that contains the call result.
+ */
+static xmlrpc_value *__chamelium_rpc(struct igt_chamelium_v3 *chamelium,
+				     const char *method_name,
+				     const char *format_str,
+				     ...)
+{
+	xmlrpc_value *res;
+	va_list va_args;
+
+	if (chamelium->env.fault_occurred) {
+		xmlrpc_env_clean(&chamelium->env);
+		xmlrpc_env_init(&chamelium->env);
+	}
+	va_start(va_args, format_str);
+	xmlrpc_client_call2f_va(&chamelium->env, chamelium->client,
+				chamelium->url, method_name, format_str, &res,
+				va_args);
+	va_end(va_args);
+	igt_assert_f(!chamelium->env.fault_occurred,
+		     "Chamelium RPC call[%s] failed: %s\n", method_name,
+		     chamelium->env.fault_string);
+	return res;
+}
+
+/*
+ * For the RPC calls, please refer to the python code [1] for documentation.
+ *
+ * [1]: https://chromium.googlesource.com/chromiumos/platform/chameleon/+/refs/heads/main/v3/chameleond/v3.py
+ */
+
+/**
+ * chamelium_v3_get_supported_ports - Get the list of ports on the chamelium
+ *
+ * @chamelium: Chamelium to get the ports from
+ * @port_ids: Out pointer for the list of port ids
+ *
+ * Returns the number of element stored in @port_ids. The caller must free this pointer when not
+ * used anymore.
+ */
+int chamelium_v3_get_supported_ports(struct igt_chamelium_v3 *chamelium,
+				     chamelium_v3_port_id **port_ids)
+{
+	xmlrpc_value *res, *res_port;
+	int port_count, i;
+
+	igt_assert(port_ids);
+
+	igt_debug("RPC GetSupportedPorts()\n");
+	res = __chamelium_rpc(chamelium, "GetSupportedPorts", "()");
+
+	port_count = xmlrpc_array_size(&chamelium->env, res);
+	*port_ids = calloc(port_count, sizeof(**port_ids));
+
+	for (i = 0; i < port_count; i++) {
+		xmlrpc_array_read_item(&chamelium->env, res, i, &res_port);
+		xmlrpc_read_int(&chamelium->env, res_port, (int *)&(*port_ids)[i]);
+		xmlrpc_DECREF(res_port);
+	}
+	xmlrpc_DECREF(res);
+
+	return port_count;
+}
+
+/**
+ * chamelium_v3_get_supported_ports - Get the list of children port for a specific port on the
+ *	chamelium
+ *
+ * @chamelium: Chamelium to get the ports from
+ * @port_id: Parent port id to get the children port from
+ * @port_ids: Out pointer for the list of port ids
+ *
+ * MST ports on the chamelium have children ports that can be plugged independently, but are always
+ * connected with a parent connector.
+ *
+ * Returns the number of element stored in @port_ids. The caller must free this pointer when not
+ * used anymore.
+ */
+int chamelium_v3_get_children(struct igt_chamelium_v3 *chamelium, chamelium_v3_port_id port_id,
+			      chamelium_v3_port_id **port_ids)
+{
+	xmlrpc_value *res, *res_port;
+	int port_count, i;
+
+	igt_debug("RPC GetChildren(%d)\n", port_id);
+	res = __chamelium_rpc(chamelium, "GetChildren", "(i)", port_id);
+
+	port_count = xmlrpc_array_size(&chamelium->env, res);
+	*port_ids = calloc(port_count, sizeof(**port_ids));
+
+	for (i = 0; i < port_count; i++) {
+		xmlrpc_array_read_item(&chamelium->env, res, i, &res_port);
+		xmlrpc_read_int(&chamelium->env, res_port, (int *)&(*port_ids)[i]);
+		xmlrpc_DECREF(res_port);
+	}
+	xmlrpc_DECREF(res);
+
+	return port_count;
+}
+
+/**
+ * chamelium_v3_is_mst - Get the MST support for a specific port
+ *
+ * @chamelium: Chamelium to get the ports from
+ * @port_id: Port to get the support from
+ *
+ * Not all ports on the chamelium support MST. This functions allows checking if a specific port
+ * supports MST.
+ *
+ * Returns true if the @port_id supports MST.
+ */
+bool chamelium_v3_is_mst(struct igt_chamelium_v3 *chamelium, chamelium_v3_port_id port_id)
+{
+	xmlrpc_value *res;
+	xmlrpc_bool is_mst;
+
+	igt_debug("RPC IsMst(%d)\n", port_id);
+	res = __chamelium_rpc(chamelium, "IsMst", "(i)", port_id);
+
+	xmlrpc_read_bool(&chamelium->env, res, &is_mst);
+
+	xmlrpc_DECREF(res);
+
+	return is_mst;
+}
diff --git a/lib/chamelium/v3/igt_chamelium.h b/lib/chamelium/v3/igt_chamelium.h
index 759a1f4d59e2..763ab4bc0304 100644
--- a/lib/chamelium/v3/igt_chamelium.h
+++ b/lib/chamelium/v3/igt_chamelium.h
@@ -42,4 +42,10 @@ struct igt_chamelium_v3 *chamelium_v3_init_from_config(void);
 
 void chamelium_v3_uninit(struct igt_chamelium_v3 *chamelium);
 
+int chamelium_v3_get_supported_ports(struct igt_chamelium_v3 *chamelium,
+				     chamelium_v3_port_id **port_ids);
+int chamelium_v3_get_children(struct igt_chamelium_v3 *chamelium, chamelium_v3_port_id port_id,
+			      chamelium_v3_port_id **port_ids);
+bool chamelium_v3_is_mst(struct igt_chamelium_v3 *chamelium, chamelium_v3_port_id port_id);
+
 #endif //V3_IGT_CHAMELIUM_H

-- 
2.44.2



More information about the igt-dev mailing list