[igt-dev] [PATCH i-g-t v4 03/10] lib/igt_chamelium: allow EDIDs to be mutated for each port

Simon Ser
2019-06-25T13:14:28Z

This adds the infrastructure necessary to change EDIDs provided to
chamelium_new_edid, without actually doing it yet. This commit just updates the
API to make it possible, documents expectations and updates callers
accordingly. Mutating EDIDs is necessary to add an identifier to them (e.g. by
adding a serial number) and to be able to map Chamelium ports to DRM
connectors.

A new function chamelium_edid_get_raw allows callers to retrieve the exact EDID
used for a particular port.

Signed-off-by: Simon Ser <simon.ser@intel.com>
---
lib/igt_chamelium.c | 30 ++++++++++++++++++++++++++++--
lib/igt_chamelium.h | 2 ++
tests/kms_chamelium.c | 7 +++++--
3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 4a3f64b3585d..9ea483eee717 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -83,6 +83,7 @@

struct chamelium_edid {
int id;
+ struct edid *raw;
struct igt_list link;
};

@@ -530,6 +531,11 @@ void chamelium_schedule_hpd_toggle(struct chamelium *chamelium,
* Uploads and registers a new EDID with the chamelium. The EDID will be
* destroyed automatically when #chamelium_deinit is called.
*
+ * Callers shouldn't assume that the raw EDID they provide is uploaded as-is to
+ * the Chamelium. The EDID may be mutated (e.g. a serial number can be appended
+ * to be able to uniquely identify the EDID). To retrieve the exact EDID that
+ * will be applied to a particular port, use #chamelium_edid_get_raw.
+ *
* Returns: An opaque pointer to the Chamelium EDID
*/
struct chamelium_edid *chamelium_new_edid(struct chamelium *chamelium,
@@ -539,16 +545,18 @@ struct chamelium_edid *chamelium_new_edid(struct chamelium *chamelium,
struct chamelium_edid *chamelium_edid;
int edid_id;
const struct edid *edid = (struct edid *) raw_edid;
+ size_t edid_size = edid_get_size(edid);

res = chamelium_rpc(chamelium, NULL, "CreateEdid", "(6)",
- raw_edid, edid_get_size(edid));
+ raw_edid, edid_size);

xmlrpc_read_int(&chamelium->env, res, &edid_id);
xmlrpc_DECREF(res);

chamelium_edid = calloc(1, sizeof(struct chamelium_edid));
chamelium_edid->id = edid_id;
-
+ chamelium_edid->raw = malloc(edid_size);
+ memcpy(chamelium_edid->raw, raw_edid, edid_size);
igt_list_add(&chamelium_edid->link, &chamelium->edids);

return chamelium_edid;
@@ -560,6 +568,23 @@ static void chamelium_destroy_edid(struct chamelium *chamelium, int edid_id)
edid_id));
}

+/**
+ * chamelium_edid_get_raw: get the raw EDID
+ * @edid: the Chamelium EDID
+ * @port: the Chamelium port
+ *
+ * The EDID provided to #chamelium_new_edid may be mutated for identification
+ * purposes. This function allows to retrieve the exact EDID that will be set
+ * for a given port.
+ *
+ * The returned raw EDID is only valid until the next call to this function.
+ */
+const struct edid *chamelium_edid_get_raw(struct chamelium_edid *edid,
+ struct chamelium_port *port)
+{
+ return edid->raw;
+}
+
/**
* chamelium_port_set_edid:
* @chamelium: The Chamelium instance to use
@@ -1898,6 +1923,7 @@ void chamelium_deinit(struct chamelium *chamelium)
/* Destroy any EDIDs we created to make sure we don't leak them */
igt_list_for_each_safe(pos, tmp, &chamelium->edids, link) {
chamelium_destroy_edid(chamelium, pos->id);
+ free(pos->raw);
free(pos);
}

diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index ce9e9ced75d9..f58e4f1f0c75 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -102,6 +102,8 @@ void chamelium_schedule_hpd_toggle(struct chamelium *chamelium,
bool rising_edge);
struct chamelium_edid *chamelium_new_edid(struct chamelium *chamelium,
const unsigned char *edid);
+const struct edid *chamelium_edid_get_raw(struct chamelium_edid *edid,
+ struct chamelium_port *port);
void chamelium_port_set_edid(struct chamelium *chamelium,
struct chamelium_port *port,
struct chamelium_edid *edid);
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 378024d8fd05..175e5032c973 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -276,9 +276,10 @@ static void
test_edid_read(data_t *data, struct chamelium_port *port, enum test_edid edid)
{
drmModePropertyBlobPtr edid_blob = NULL;
- const unsigned char *raw_edid = get_edid(edid);
drmModeConnector *connector = chamelium_port_get_connector(
data->chamelium, port, false);
+ size_t raw_edid_size;
+ const struct edid *raw_edid;
uint64_t edid_blob_id;

reset_state(data, port);
@@ -295,7 +296,9 @@ test_edid_read(data_t *data, struct chamelium_port *port, enum test_edid edid)
igt_assert(edid_blob = drmModeGetPropertyBlob(data->drm_fd,
edid_blob_id));

- igt_assert(memcmp(raw_edid, edid_blob->data, EDID_LENGTH) == 0);
+ raw_edid = chamelium_edid_get_raw(data->edids[edid], port);
+ raw_edid_size = edid_get_size(raw_edid);
+ igt_assert(memcmp(raw_edid, edid_blob->data, raw_edid_size) == 0);

drmModeFreePropertyBlob(edid_blob);
drmModeFreeConnector(connector);
--
2.22.0