summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-10 02:34:35 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-03-10 02:37:21 +0000
commitead1a0a0876bd416332122be81f6498b2b5dedfe (patch)
tree68bc766ad85ca8b77fddb02a5ef70b49c7b9a343
parent999a4dd5db1b94dc6edf74a9c094ce4b9ee0524b (diff)
sna: Repeat EDID read if it changes beneath us
If the blob is changed by the kernel between us querying the connector property and the multi-stage retrieval, start the read afresh. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_display.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 573869e3..e85e444c 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3809,30 +3809,33 @@ sna_output_attach_edid(xf86OutputPtr output)
}
blob.data = (uintptr_t)raw;
- if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
- DBG(("%s(%s): failed to read blob, reusing previous\n",
- __FUNCTION__, output->name));
- goto skip_read;
- }
+ do {
+ while (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
+ update_properties(sna, sna_output);
+ if (blob.blob_id == sna_output->prop_values[sna_output->edid_idx]) {
+ DBG(("%s(%s): failed to read blob, reusing previous\n",
+ __FUNCTION__, output->name));
+ goto done;
+ }
+ blob.blob_id = sna_output->prop_values[sna_output->edid_idx];
+ }
- DBG(("%s(%s): retrieving blob id=%d, length=%d\n",
- __FUNCTION__, output->name, blob.blob_id, blob.length));
+ DBG(("%s(%s): retrieving blob id=%d, length=%d\n",
+ __FUNCTION__, output->name, blob.blob_id, blob.length));
- if (blob.length > sna_output->edid_len) {
- raw = realloc(raw, blob.length);
- if (raw == NULL)
+ if (blob.length < 128)
goto done;
- VG(memset(raw, 0, blob.length));
- blob.data = (uintptr_t)raw;
- }
-
- if (blob.length != sna_output->edid_len &&
- drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
- goto done;
+ if (blob.length > sna_output->edid_len) {
+ raw = realloc(raw, blob.length);
+ if (raw == NULL)
+ goto done;
- if (blob.length < 128)
- goto done;
+ VG(memset(raw, 0, blob.length));
+ blob.data = (uintptr_t)raw;
+ }
+ } while (blob.length != sna_output->edid_len &&
+ drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob));
if (blob.length & 127) {
/* Truncated EDID! Make sure no one reads too far */