diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-03-10 02:34:35 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-03-10 02:37:21 +0000 |
commit | ead1a0a0876bd416332122be81f6498b2b5dedfe (patch) | |
tree | 68bc766ad85ca8b77fddb02a5ef70b49c7b9a343 | |
parent | 999a4dd5db1b94dc6edf74a9c094ce4b9ee0524b (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.c | 41 |
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 */ |