From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754302AbcC1Odz (ORCPT ); Mon, 28 Mar 2016 10:33:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53280 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753889AbcC1Odt (ORCPT ); Mon, 28 Mar 2016 10:33:49 -0400 From: Lyude To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: arthur.j.runyan@intel.com, =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Jani Nikula , Lyude , David Airlie , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 RESEND 3/5] drm/dp_helper: Retry aux transactions on all errors Date: Mon, 28 Mar 2016 10:33:24 -0400 Message-Id: <1459175606-13875-4-git-send-email-cpaul@redhat.com> In-Reply-To: <1459175606-13875-1-git-send-email-cpaul@redhat.com> References: <1459175606-13875-1-git-send-email-cpaul@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is part of a patch series to migrate all of the workarounds for commonly seen behavior from bad sinks in intel_dp_dpcd_read_wake() to drm's DP helper. We cannot rely on sinks NACKing or deferring when they can't receive transactions, nor can we rely on any other sort of consistent error to know when we should stop retrying. As such, we need to just retry unconditionally on errors. We also make sure here to return the error we encountered during the first transaction, since it's possible that retrying the transaction might return a different error then we had originally. This, along with the previous patch, work around a weird bug with the ThinkPad T560's and it's dock. When resuming the laptop, it appears that there's a short period of time where we're unable to complete any aux transactions, as they all immediately timeout. The only machine I'm able to reproduce this on is the T560 as other production Skylake models seem to be fine. The period during which AUX transactions fail appears to be around 22ms long. AFAIK, the dock for the T560 never actually turns off, the only difference is that it's in SST mode at the start of the resume process, so it's unclear as to why it would need so much time to come back up. There's been a discussion on this issue going on for a while on the intel-gfx mailing list about this that has, in addition to including developers from Intel, also had the correspondence of one of the hardware engineers for Intel: http://www.spinics.net/lists/intel-gfx/msg88831.html http://www.spinics.net/lists/intel-gfx/msg88410.html We've already looked into a couple of possible explanations for the problem: - Calling intel_dp_mst_resume() before right fix. intel_runtime_pm_enable_interrupts(). This was the first fix I tried, and while it worked it definitely wasn't the right fix. This worked because DP aux transactions don't actually require interrupts to work: static uint32_t intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg; uint32_t status; bool done; #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0) if (has_aux_irq) done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, msecs_to_jiffies_timeout(10)); else done = wait_for_atomic(C, 10) == 0; if (!done) DRM_ERROR("dp aux hw did not signal timeout (has irq: %i)!\n", has_aux_irq); #undef C return status; } When there's no interrupts enabled, we end up timing out on the wait_event_timeout() call, which causes us to check the DP status register once to see if the transaction was successful or not. Since this adds a 10ms delay to each aux transaction, it ends up adding a long enough delay to the resume process for aux transactions to become functional again. This gave us the illusion that enabling interrupts had something to do with making things work again, and put me on the wrong track for a while. - Interrupts occurring when we try to perform the aux transactions required to put the dock back into MST mode. This isn't the problem, as the only interrupts I've observed that come during this timeout period are from the snd_hda_intel driver, and disabling that driver doesn't appear to change the behavior at all. - Skylake's PSR block causing issues by performing aux transactions while we try to bring the dock out of MST mode. Disabling PSR through i915's command line options doesn't seem to change the behavior either, nor does preventing the DMC firmware from being loaded. Since this investigation went on for about 2 weeks, we decided it would be better for the time being to just workaround this issue by making sure AUX transactions wait a short period of time before retrying. Signed-off-by: Lyude --- drivers/gpu/drm/drm_dp_helper.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 3b915e2..86656ca 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -178,8 +178,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request, unsigned int offset, void *buffer, size_t size) { struct drm_dp_aux_msg msg; - unsigned int retry; - int err = 0; + unsigned int retry, native_reply; + int err = 0, ret = 0; memset(&msg, 0, sizeof(msg)); msg.address = offset; @@ -194,34 +194,37 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request, * sufficient, bump to 32 which makes Dell 4k monitors happier. */ for (retry = 0; retry < 32; retry++) { - if (err != 0 && err != -ETIMEDOUT) { + if (ret != 0 && ret != -ETIMEDOUT) { usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100); } mutex_lock(&aux->hw_mutex); - err = aux->transfer(aux, &msg); + ret = aux->transfer(aux, &msg); mutex_unlock(&aux->hw_mutex); - if (err < 0) { - if (err == -EBUSY) - continue; - return err; - } - - switch (msg.reply & DP_AUX_NATIVE_REPLY_MASK) { - case DP_AUX_NATIVE_REPLY_ACK: - if (err < size) - return -EPROTO; - return err; + if (ret > 0) { + native_reply = msg.reply & DP_AUX_NATIVE_REPLY_MASK; + if (native_reply == DP_AUX_NATIVE_REPLY_ACK) { + if (ret == size) + return ret; - case DP_AUX_NATIVE_REPLY_NACK: - return -EIO; + ret = -EPROTO; + } else + ret = -EIO; } + + /* + * We want the error we return to be the error we received on + * the first transaction, since we may get a different error the + * next time we retry + */ + if (!err) + err = ret; } DRM_DEBUG_KMS("too many retries, giving up\n"); - return -EIO; + return err; } /** -- 2.5.5 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lyude Subject: [PATCH v4 RESEND 3/5] drm/dp_helper: Retry aux transactions on all errors Date: Mon, 28 Mar 2016 10:33:24 -0400 Message-ID: <1459175606-13875-4-git-send-email-cpaul@redhat.com> References: <1459175606-13875-1-git-send-email-cpaul@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1459175606-13875-1-git-send-email-cpaul@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: arthur.j.runyan@intel.com, open list , Lyude List-Id: dri-devel@lists.freedesktop.org VGhpcyBpcyBwYXJ0IG9mIGEgcGF0Y2ggc2VyaWVzIHRvIG1pZ3JhdGUgYWxsIG9mIHRoZSB3b3Jr YXJvdW5kcyBmb3IKY29tbW9ubHkgc2VlbiBiZWhhdmlvciBmcm9tIGJhZCBzaW5rcyBpbiBpbnRl bF9kcF9kcGNkX3JlYWRfd2FrZSgpIHRvCmRybSdzIERQIGhlbHBlci4KCldlIGNhbm5vdCByZWx5 IG9uIHNpbmtzIE5BQ0tpbmcgb3IgZGVmZXJyaW5nIHdoZW4gdGhleSBjYW4ndCByZWNlaXZlCnRy YW5zYWN0aW9ucywgbm9yIGNhbiB3ZSByZWx5IG9uIGFueSBvdGhlciBzb3J0IG9mIGNvbnNpc3Rl bnQgZXJyb3IgdG8Ka25vdyB3aGVuIHdlIHNob3VsZCBzdG9wIHJldHJ5aW5nLiBBcyBzdWNoLCB3 ZSBuZWVkIHRvIGp1c3QgcmV0cnkKdW5jb25kaXRpb25hbGx5IG9uIGVycm9ycy4gV2UgYWxzbyBt YWtlIHN1cmUgaGVyZSB0byByZXR1cm4gdGhlIGVycm9yIHdlCmVuY291bnRlcmVkIGR1cmluZyB0 aGUgZmlyc3QgdHJhbnNhY3Rpb24sIHNpbmNlIGl0J3MgcG9zc2libGUgdGhhdApyZXRyeWluZyB0 aGUgdHJhbnNhY3Rpb24gbWlnaHQgcmV0dXJuIGEgZGlmZmVyZW50IGVycm9yIHRoZW4gd2UgaGFk Cm9yaWdpbmFsbHkuCgpUaGlzLCBhbG9uZyB3aXRoIHRoZSBwcmV2aW91cyBwYXRjaCwgd29yayBh cm91bmQgYSB3ZWlyZCBidWcgd2l0aCB0aGUKVGhpbmtQYWQgVDU2MCdzIGFuZCBpdCdzIGRvY2su IFdoZW4gcmVzdW1pbmcgdGhlIGxhcHRvcCwgaXQgYXBwZWFycyB0aGF0CnRoZXJlJ3MgYSBzaG9y dCBwZXJpb2Qgb2YgdGltZSB3aGVyZSB3ZSdyZSB1bmFibGUgdG8gY29tcGxldGUgYW55IGF1eAp0 cmFuc2FjdGlvbnMsIGFzIHRoZXkgYWxsIGltbWVkaWF0ZWx5IHRpbWVvdXQuIFRoZSBvbmx5IG1h Y2hpbmUgSSdtIGFibGUKdG8gcmVwcm9kdWNlIHRoaXMgb24gaXMgdGhlIFQ1NjAgYXMgb3RoZXIg cHJvZHVjdGlvbiBTa3lsYWtlIG1vZGVscyBzZWVtCnRvIGJlIGZpbmUuIFRoZSBwZXJpb2QgZHVy aW5nIHdoaWNoIEFVWCB0cmFuc2FjdGlvbnMgZmFpbCBhcHBlYXJzIHRvIGJlCmFyb3VuZCAyMm1z IGxvbmcuIEFGQUlLLCB0aGUgZG9jayBmb3IgdGhlIFQ1NjAgbmV2ZXIgYWN0dWFsbHkgdHVybnMg b2ZmLAp0aGUgb25seSBkaWZmZXJlbmNlIGlzIHRoYXQgaXQncyBpbiBTU1QgbW9kZSBhdCB0aGUg c3RhcnQgb2YgdGhlIHJlc3VtZQpwcm9jZXNzLCBzbyBpdCdzIHVuY2xlYXIgYXMgdG8gd2h5IGl0 IHdvdWxkIG5lZWQgc28gbXVjaCB0aW1lIHRvIGNvbWUKYmFjayB1cC4KClRoZXJlJ3MgYmVlbiBh IGRpc2N1c3Npb24gb24gdGhpcyBpc3N1ZSBnb2luZyBvbiBmb3IgYSB3aGlsZSBvbiB0aGUKaW50 ZWwtZ2Z4IG1haWxpbmcgbGlzdCBhYm91dCB0aGlzIHRoYXQgaGFzLCBpbiBhZGRpdGlvbiB0byBp bmNsdWRpbmcKZGV2ZWxvcGVycyBmcm9tIEludGVsLCBhbHNvIGhhZCB0aGUgY29ycmVzcG9uZGVu Y2Ugb2Ygb25lIG9mIHRoZQpoYXJkd2FyZSBlbmdpbmVlcnMgZm9yIEludGVsOgoKaHR0cDovL3d3 dy5zcGluaWNzLm5ldC9saXN0cy9pbnRlbC1nZngvbXNnODg4MzEuaHRtbApodHRwOi8vd3d3LnNw aW5pY3MubmV0L2xpc3RzL2ludGVsLWdmeC9tc2c4ODQxMC5odG1sCgpXZSd2ZSBhbHJlYWR5IGxv b2tlZCBpbnRvIGEgY291cGxlIG9mIHBvc3NpYmxlIGV4cGxhbmF0aW9ucyBmb3IgdGhlCnByb2Js ZW06CgotIENhbGxpbmcgaW50ZWxfZHBfbXN0X3Jlc3VtZSgpIGJlZm9yZSByaWdodCBmaXguCiAg aW50ZWxfcnVudGltZV9wbV9lbmFibGVfaW50ZXJydXB0cygpLiBUaGlzIHdhcyB0aGUgZmlyc3Qg Zml4IEkgdHJpZWQsCiAgYW5kIHdoaWxlIGl0IHdvcmtlZCBpdCBkZWZpbml0ZWx5IHdhc24ndCB0 aGUgcmlnaHQgZml4LiBUaGlzIHdvcmtlZAogIGJlY2F1c2UgRFAgYXV4IHRyYW5zYWN0aW9ucyBk b24ndCBhY3R1YWxseSByZXF1aXJlIGludGVycnVwdHMgdG8gd29yazoKCglzdGF0aWMgdWludDMy X3QKCWludGVsX2RwX2F1eF93YWl0X2RvbmUoc3RydWN0IGludGVsX2RwICppbnRlbF9kcCwgYm9v bCBoYXNfYXV4X2lycSkKCXsKCQlzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRlbF9kaWdf cG9ydCA9IGRwX3RvX2RpZ19wb3J0KGludGVsX2RwKTsKCQlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2 ID0gaW50ZWxfZGlnX3BvcnQtPmJhc2UuYmFzZS5kZXY7CgkJc3RydWN0IGRybV9pOTE1X3ByaXZh dGUgKmRldl9wcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKCQlpOTE1X3JlZ190IGNoX2N0bCA9IGlu dGVsX2RwLT5hdXhfY2hfY3RsX3JlZzsKCQl1aW50MzJfdCBzdGF0dXM7CgkJYm9vbCBkb25lOwoK CSNkZWZpbmUgQyAoKChzdGF0dXMgPSBJOTE1X1JFQURfTk9UUkFDRShjaF9jdGwpKSAmIERQX0FV WF9DSF9DVExfU0VORF9CVVNZKSA9PSAwKQoJCWlmIChoYXNfYXV4X2lycSkKCQkJZG9uZSA9IHdh aXRfZXZlbnRfdGltZW91dChkZXZfcHJpdi0+Z21idXNfd2FpdF9xdWV1ZSwgQywKCQkJCQkJICBt c2Vjc190b19qaWZmaWVzX3RpbWVvdXQoMTApKTsKCQllbHNlCgkJCWRvbmUgPSB3YWl0X2Zvcl9h dG9taWMoQywgMTApID09IDA7CgkJaWYgKCFkb25lKQoJCQlEUk1fRVJST1IoImRwIGF1eCBodyBk aWQgbm90IHNpZ25hbCB0aW1lb3V0IChoYXMgaXJxOiAlaSkhXG4iLAoJCQkJICBoYXNfYXV4X2ly cSk7CgkjdW5kZWYgQwoKCQlyZXR1cm4gc3RhdHVzOwoJfQoKICBXaGVuIHRoZXJlJ3Mgbm8gaW50 ZXJydXB0cyBlbmFibGVkLCB3ZSBlbmQgdXAgdGltaW5nIG91dCBvbiB0aGUKICB3YWl0X2V2ZW50 X3RpbWVvdXQoKSBjYWxsLCB3aGljaCBjYXVzZXMgdXMgdG8gY2hlY2sgdGhlIERQIHN0YXR1cwog IHJlZ2lzdGVyIG9uY2UgdG8gc2VlIGlmIHRoZSB0cmFuc2FjdGlvbiB3YXMgc3VjY2Vzc2Z1bCBv ciBub3QuIFNpbmNlCiAgdGhpcyBhZGRzIGEgMTBtcyBkZWxheSB0byBlYWNoIGF1eCB0cmFuc2Fj dGlvbiwgaXQgZW5kcyB1cCBhZGRpbmcgYQogIGxvbmcgZW5vdWdoIGRlbGF5IHRvIHRoZSByZXN1 bWUgcHJvY2VzcyBmb3IgYXV4IHRyYW5zYWN0aW9ucyB0byBiZWNvbWUKICBmdW5jdGlvbmFsIGFn YWluLiBUaGlzIGdhdmUgdXMgdGhlIGlsbHVzaW9uIHRoYXQgZW5hYmxpbmcgaW50ZXJydXB0cwog IGhhZCBzb21ldGhpbmcgdG8gZG8gd2l0aCBtYWtpbmcgdGhpbmdzIHdvcmsgYWdhaW4sIGFuZCBw dXQgbWUgb24gdGhlCiAgd3JvbmcgdHJhY2sgZm9yIGEgd2hpbGUuCgotIEludGVycnVwdHMgb2Nj dXJyaW5nIHdoZW4gd2UgdHJ5IHRvIHBlcmZvcm0gdGhlIGF1eCB0cmFuc2FjdGlvbnMKICByZXF1 aXJlZCB0byBwdXQgdGhlIGRvY2sgYmFjayBpbnRvIE1TVCBtb2RlLiBUaGlzIGlzbid0IHRoZSBw cm9ibGVtLAogIGFzIHRoZSBvbmx5IGludGVycnVwdHMgSSd2ZSBvYnNlcnZlZCB0aGF0IGNvbWUg ZHVyaW5nIHRoaXMgdGltZW91dAogIHBlcmlvZCBhcmUgZnJvbSB0aGUgc25kX2hkYV9pbnRlbCBk cml2ZXIsIGFuZCBkaXNhYmxpbmcgdGhhdCBkcml2ZXIKICBkb2Vzbid0IGFwcGVhciB0byBjaGFu Z2UgdGhlIGJlaGF2aW9yIGF0IGFsbC4KCi0gU2t5bGFrZSdzIFBTUiBibG9jayBjYXVzaW5nIGlz c3VlcyBieSBwZXJmb3JtaW5nIGF1eCB0cmFuc2FjdGlvbnMKICB3aGlsZSB3ZSB0cnkgdG8gYnJp bmcgdGhlIGRvY2sgb3V0IG9mIE1TVCBtb2RlLiBEaXNhYmxpbmcgUFNSIHRocm91Z2gKICBpOTE1 J3MgY29tbWFuZCBsaW5lIG9wdGlvbnMgZG9lc24ndCBzZWVtIHRvIGNoYW5nZSB0aGUgYmVoYXZp b3IKICBlaXRoZXIsIG5vciBkb2VzIHByZXZlbnRpbmcgdGhlIERNQyBmaXJtd2FyZSBmcm9tIGJl aW5nIGxvYWRlZC4KClNpbmNlIHRoaXMgaW52ZXN0aWdhdGlvbiB3ZW50IG9uIGZvciBhYm91dCAy IHdlZWtzLCB3ZSBkZWNpZGVkIGl0IHdvdWxkCmJlIGJldHRlciBmb3IgdGhlIHRpbWUgYmVpbmcg dG8ganVzdCB3b3JrYXJvdW5kIHRoaXMgaXNzdWUgYnkgbWFraW5nCnN1cmUgQVVYIHRyYW5zYWN0 aW9ucyB3YWl0IGEgc2hvcnQgcGVyaW9kIG9mIHRpbWUgYmVmb3JlIHJldHJ5aW5nLgoKU2lnbmVk LW9mZi1ieTogTHl1ZGUgPGNwYXVsQHJlZGhhdC5jb20+Ci0tLQogZHJpdmVycy9ncHUvZHJtL2Ry bV9kcF9oZWxwZXIuYyB8IDM5ICsrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0tLS0t LQogMSBmaWxlIGNoYW5nZWQsIDIxIGluc2VydGlvbnMoKyksIDE4IGRlbGV0aW9ucygtKQoKZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fZHBfaGVscGVyLmMgYi9kcml2ZXJzL2dwdS9k cm0vZHJtX2RwX2hlbHBlci5jCmluZGV4IDNiOTE1ZTIuLjg2NjU2Y2EgMTAwNjQ0Ci0tLSBhL2Ry aXZlcnMvZ3B1L2RybS9kcm1fZHBfaGVscGVyLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2RybV9k cF9oZWxwZXIuYwpAQCAtMTc4LDggKzE3OCw4IEBAIHN0YXRpYyBpbnQgZHJtX2RwX2RwY2RfYWNj ZXNzKHN0cnVjdCBkcm1fZHBfYXV4ICphdXgsIHU4IHJlcXVlc3QsCiAJCQkgICAgICB1bnNpZ25l ZCBpbnQgb2Zmc2V0LCB2b2lkICpidWZmZXIsIHNpemVfdCBzaXplKQogewogCXN0cnVjdCBkcm1f ZHBfYXV4X21zZyBtc2c7Ci0JdW5zaWduZWQgaW50IHJldHJ5OwotCWludCBlcnIgPSAwOworCXVu c2lnbmVkIGludCByZXRyeSwgbmF0aXZlX3JlcGx5OworCWludCBlcnIgPSAwLCByZXQgPSAwOwog CiAJbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKIAltc2cuYWRkcmVzcyA9IG9mZnNldDsK QEAgLTE5NCwzNCArMTk0LDM3IEBAIHN0YXRpYyBpbnQgZHJtX2RwX2RwY2RfYWNjZXNzKHN0cnVj dCBkcm1fZHBfYXV4ICphdXgsIHU4IHJlcXVlc3QsCiAJICogc3VmZmljaWVudCwgYnVtcCB0byAz MiB3aGljaCBtYWtlcyBEZWxsIDRrIG1vbml0b3JzIGhhcHBpZXIuCiAJICovCiAJZm9yIChyZXRy eSA9IDA7IHJldHJ5IDwgMzI7IHJldHJ5KyspIHsKLQkJaWYgKGVyciAhPSAwICYmIGVyciAhPSAt RVRJTUVET1VUKSB7CisJCWlmIChyZXQgIT0gMCAmJiByZXQgIT0gLUVUSU1FRE9VVCkgewogCQkJ dXNsZWVwX3JhbmdlKEFVWF9SRVRSWV9JTlRFUlZBTCwKIAkJCQkgICAgIEFVWF9SRVRSWV9JTlRF UlZBTCArIDEwMCk7CiAJCX0KIAogCQltdXRleF9sb2NrKCZhdXgtPmh3X211dGV4KTsKLQkJZXJy ID0gYXV4LT50cmFuc2ZlcihhdXgsICZtc2cpOworCQlyZXQgPSBhdXgtPnRyYW5zZmVyKGF1eCwg Jm1zZyk7CiAJCW11dGV4X3VubG9jaygmYXV4LT5od19tdXRleCk7Ci0JCWlmIChlcnIgPCAwKSB7 Ci0JCQlpZiAoZXJyID09IC1FQlVTWSkKLQkJCQljb250aW51ZTsKIAotCQkJcmV0dXJuIGVycjsK LQkJfQotCi0JCXN3aXRjaCAobXNnLnJlcGx5ICYgRFBfQVVYX05BVElWRV9SRVBMWV9NQVNLKSB7 Ci0JCWNhc2UgRFBfQVVYX05BVElWRV9SRVBMWV9BQ0s6Ci0JCQlpZiAoZXJyIDwgc2l6ZSkKLQkJ CQlyZXR1cm4gLUVQUk9UTzsKLQkJCXJldHVybiBlcnI7CisJCWlmIChyZXQgPiAwKSB7CisJCQlu YXRpdmVfcmVwbHkgPSBtc2cucmVwbHkgJiBEUF9BVVhfTkFUSVZFX1JFUExZX01BU0s7CisJCQlp ZiAobmF0aXZlX3JlcGx5ID09IERQX0FVWF9OQVRJVkVfUkVQTFlfQUNLKSB7CisJCQkJaWYgKHJl dCA9PSBzaXplKQorCQkJCQlyZXR1cm4gcmV0OwogCi0JCWNhc2UgRFBfQVVYX05BVElWRV9SRVBM WV9OQUNLOgotCQkJcmV0dXJuIC1FSU87CisJCQkJcmV0ID0gLUVQUk9UTzsKKwkJCX0gZWxzZQor CQkJCXJldCA9IC1FSU87CiAJCX0KKworCQkvKgorCQkgKiBXZSB3YW50IHRoZSBlcnJvciB3ZSBy ZXR1cm4gdG8gYmUgdGhlIGVycm9yIHdlIHJlY2VpdmVkIG9uCisJCSAqIHRoZSBmaXJzdCB0cmFu c2FjdGlvbiwgc2luY2Ugd2UgbWF5IGdldCBhIGRpZmZlcmVudCBlcnJvciB0aGUKKwkJICogbmV4 dCB0aW1lIHdlIHJldHJ5CisJCSAqLworCQlpZiAoIWVycikKKwkJCWVyciA9IHJldDsKIAl9CiAK IAlEUk1fREVCVUdfS01TKCJ0b28gbWFueSByZXRyaWVzLCBnaXZpbmcgdXBcbiIpOwotCXJldHVy biAtRUlPOworCXJldHVybiBlcnI7CiB9CiAKIC8qKgotLSAKMi41LjUKCl9fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QK ZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9w Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=