diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a4c186486caf23abe8c700d1a8b5027073f07025..798429a5d373ed07caa07691cb3857aa98ada5ad 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -915,6 +915,27 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, /* Unload any bytes sent back from the other side */ recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); + + /* + * By BSpec: "Message sizes of 0 or >20 are not allowed." + * We have no idea of what happened so we return -EBUSY so + * drm layer takes care for the necessary retries. + */ + if (recv_bytes == 0 || recv_bytes > 20) { + DRM_DEBUG_KMS("Forbidden recv_bytes = %d on aux transaction\n", + recv_bytes); + /* + * FIXME: This patch was created on top of a series that + * organize the retries at drm level. There EBUSY should + * also take care for 1ms wait before retrying. + * That aux retries re-org is still needed and after that is + * merged we remove this sleep from here. + */ + usleep_range(1000, 1500); + ret = -EBUSY; + goto out; + } + if (recv_bytes > recv_size) recv_bytes = recv_size;