From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751301AbeCHXYd (ORCPT ); Thu, 8 Mar 2018 18:24:33 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:36026 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751182AbeCHXYb (ORCPT ); Thu, 8 Mar 2018 18:24:31 -0500 From: Lyude Paul To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: Manasi Navare , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Gustavo Padovan , Maarten Lankhorst , Sean Paul , David Airlie , linux-kernel@vger.kernel.org Subject: [PATCH 5/6] drm/dp_mst: Add drm_atomic_dp_mst_retrain_topology() Date: Thu, 8 Mar 2018 18:24:19 -0500 Message-Id: <20180308232421.14049-6-lyude@redhat.com> In-Reply-To: <20180308232421.14049-1-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Retraining MST is rather difficult. In order to do it properly while guaranteeing that we'll never run into a spot where we commit a physically impossible configuration, we have to do a lot of checks on atomic commits which affect MST topologies. All of this work is going to need to be repeated for every driver at some point, so let's save ourselves some trouble and just implement these atomic checks as a single helper. Signed-off-by: Lyude Paul Cc: Manasi Navare Cc: Ville Syrjälä --- drivers/gpu/drm/drm_dp_mst_topology.c | 223 ++++++++++++++++++++++++++++++++++ include/drm/drm_dp_mst_helper.h | 2 + 2 files changed, 225 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 0d6604500b29..c4a91b1ba61b 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2167,6 +2167,229 @@ int drm_dp_mst_topology_mgr_lower_link_rate(struct drm_dp_mst_topology_mgr *mgr, } EXPORT_SYMBOL(drm_dp_mst_topology_mgr_lower_link_rate); +static bool drm_atomic_dp_mst_state_only_disables_mstbs(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_branch *mstb) +{ + struct drm_dp_mst_branch *rmstb; + struct drm_dp_mst_port *port; + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int ret; + + list_for_each_entry(port, &mstb->ports, next) { + rmstb = drm_dp_get_validated_mstb_ref(mstb->mgr, port->mstb); + if (rmstb) { + ret = drm_atomic_dp_mst_state_only_disables_mstbs( + state, mgr, rmstb); + drm_dp_put_mst_branch_device(rmstb); + if (!ret) + return false; + } + + connector = port->connector; + if (!connector) + continue; + + conn_state = drm_atomic_get_new_connector_state( + state, connector); + if (!conn_state) + continue; + + crtc = conn_state->crtc; + if (!crtc) + continue; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state) + continue; + + if (drm_atomic_crtc_needs_modeset(crtc_state)) + return false; + } + + return true; +} + +static int drm_atomic_dp_mst_all_mstbs_disabled(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_branch *mstb) +{ + struct drm_dp_mst_branch *rmstb; + struct drm_dp_mst_port *port; + struct drm_connector *connector; + struct drm_connector_state *conn_state; + int ret; + + list_for_each_entry(port, &mstb->ports, next) { + rmstb = drm_dp_get_validated_mstb_ref(mstb->mgr, port->mstb); + if (rmstb) { + ret = drm_atomic_dp_mst_all_mstbs_disabled( + state, mgr, rmstb); + drm_dp_put_mst_branch_device(rmstb); + if (ret <= 0) + return ret; + } + + connector = port->connector; + if (!connector) + continue; + + conn_state = drm_atomic_get_connector_state( + state, connector); + if (IS_ERR(conn_state)) + return PTR_ERR(conn_state); + + if (conn_state->crtc) + return false; + } + + /* No enabled CRTCs found */ + return true; +} + +static int drm_atomic_dp_mst_retrain_mstb(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_branch *mstb, + bool full_modeset) +{ + struct drm_dp_mst_branch *rmstb; + struct drm_dp_mst_port *port; + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int ret; + + list_for_each_entry(port, &mstb->ports, next) { + rmstb = drm_dp_get_validated_mstb_ref(mstb->mgr, port->mstb); + if (rmstb) { + ret = drm_atomic_dp_mst_retrain_mstb( + state, mgr, rmstb, full_modeset); + drm_dp_put_mst_branch_device(rmstb); + if (ret) + return ret; + } + + connector = port->connector; + if (!connector) + continue; + + conn_state = drm_atomic_get_connector_state(state, connector); + if (IS_ERR(conn_state)) + return PTR_ERR(conn_state); + + if (conn_state->link_status != DRM_MODE_LINK_STATUS_GOOD) { + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] link status bad -> good\n", + connector->base.id, connector->name); + conn_state->link_status = DRM_MODE_LINK_STATUS_GOOD; + } + + if (!full_modeset) + continue; + + crtc = conn_state->crtc; + if (!crtc) + continue; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + if (!crtc_state->mode_changed) { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs full modeset\n", + crtc->base.id, crtc->name); + crtc_state->mode_changed = true; + } + } + + return 0; +} + +/** + * drm_atomic_dp_mst_retrain_topology() - prepare a modeset that will retrain + * an MST topology + * @state: The new state that would retrain the topology link + * @mgr: The topology manager to use + * + * After userspace has been signaled that connectors are in need of + * retraining, it's expected that a modeset will be performed for any CRTCs on + * said connectors. Since all of the branch devices in an MST topology share a + * single link, they also share the same link status, lane count, and link + * rate. + * + * Since all of these characteristics are shared, there's only two valid + * solutions when fallback link training parameters need to be applied. The + * first is simply unassigning each mstb connector's CRTC. Since this action + * can only free slots on the VCPI table and not allocate them, this can be + * done without pulling in additional CRTCs on the MST topology. Additionally + * if this action would result in there no longer being any CRTCs assigned to + * mstb connectors, this would be enough to bring the topology back into a + * trained state since there would be nothing left requiring VCPI + * reallocations. + * + * The second solution is to commit new modes to all of the connectors on the + * topology. Since this action would result in VCPI reallocations with a new + * link rate and lane count, a modeset must also be performed on every other + * CRTC driving a branch device on the given topology at the same time. This + * is to ensure that all VCPI allocations are properly recalculated in + * response to the new link rate and lane count, that the new modes will fit + * into the recalculated VCPI table, and that the new atomic state could never + * result in an otherwise physically impossible configuration (e.g. different + * mstbs with CRTCs trained to different link rates/lane counts). + * + * Finally, any atomic commit which would result in going from an + * unrecoverable link state to a properly trained link state must also take + * care of appropriately updating the link status properties of all connectors + * on the topology from bad to good. This function takes care of all of these + * checks in @state for the topology manager @mgr including possibly pulling + * in additional CRTCs into the modeset, and possibly updating the link status + * of each mstb's DRM connector. + * + * This function should be called within the driver's atomic check callbacks + * whenever a modeset happens on an MST connector with it's link status set to + * DRM_MODE_LINK_STATUS_BAD. + * + * RETURNS: + * + * Returns 0 for success, or negative error code for failure. + */ +int drm_atomic_dp_mst_retrain_topology(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr) +{ + struct drm_dp_mst_branch *mstb = + drm_dp_get_validated_mstb_ref(mgr, mgr->mst_primary); + int ret = 0; + bool need_modeset = false; + + if (!mstb) + return 0; + + if (drm_atomic_dp_mst_state_only_disables_mstbs(state, mgr, mstb)) { + ret = drm_atomic_dp_mst_all_mstbs_disabled(state, mgr, mstb); + if (ret < 0) + goto out; + + if (ret) + DRM_DEBUG_ATOMIC("state %p disables all CRTCs on mst mgr %p\n", + state, mgr); + else + goto out; /* valid, but doesn't retrain link */ + } else { + DRM_DEBUG_ATOMIC("state %p requires full modeset for CRTCs on mst mgr %p\n", + state, mgr); + need_modeset = true; + } + + ret = drm_atomic_dp_mst_retrain_mstb(state, mgr, mstb, need_modeset); +out: + drm_dp_put_mst_branch_device(mgr->mst_primary); + return ret; +} +EXPORT_SYMBOL(drm_atomic_dp_mst_retrain_topology); + /** * drm_dp_mst_topology_mgr_set_mst() - Set the MST state for a topology manager * @mgr: manager to set state for diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 6261ec43a2c0..24075eb2dd1b 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -636,5 +636,7 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, int drm_dp_mst_topology_mgr_lower_link_rate(struct drm_dp_mst_topology_mgr *mgr, int dp_link_bw, int dp_link_count); +int drm_atomic_dp_mst_retrain_topology(struct drm_atomic_state *state, + struct drm_dp_mst_topology_mgr *mgr); #endif -- 2.14.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lyude Paul Subject: [PATCH 5/6] drm/dp_mst: Add drm_atomic_dp_mst_retrain_topology() Date: Thu, 8 Mar 2018 18:24:19 -0500 Message-ID: <20180308232421.14049-6-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180308232421.14049-1-lyude@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: David Airlie , linux-kernel@vger.kernel.org, Manasi Navare List-Id: dri-devel@lists.freedesktop.org UmV0cmFpbmluZyBNU1QgaXMgcmF0aGVyIGRpZmZpY3VsdC4gSW4gb3JkZXIgdG8gZG8gaXQgcHJv cGVybHkgd2hpbGUKZ3VhcmFudGVlaW5nIHRoYXQgd2UnbGwgbmV2ZXIgcnVuIGludG8gYSBzcG90 IHdoZXJlIHdlIGNvbW1pdCBhCnBoeXNpY2FsbHkgaW1wb3NzaWJsZSBjb25maWd1cmF0aW9uLCB3 ZSBoYXZlIHRvIGRvIGEgbG90IG9mIGNoZWNrcyBvbgphdG9taWMgY29tbWl0cyB3aGljaCBhZmZl Y3QgTVNUIHRvcG9sb2dpZXMuIEFsbCBvZiB0aGlzIHdvcmsgaXMgZ29pbmcgdG8KbmVlZCB0byBi ZSByZXBlYXRlZCBmb3IgZXZlcnkgZHJpdmVyIGF0IHNvbWUgcG9pbnQsIHNvIGxldCdzIHNhdmUK b3Vyc2VsdmVzIHNvbWUgdHJvdWJsZSBhbmQganVzdCBpbXBsZW1lbnQgdGhlc2UgYXRvbWljIGNo ZWNrcyBhcwphIHNpbmdsZSBoZWxwZXIuCgpTaWduZWQtb2ZmLWJ5OiBMeXVkZSBQYXVsIDxseXVk ZUByZWRoYXQuY29tPgpDYzogTWFuYXNpIE5hdmFyZSA8bWFuYXNpLmQubmF2YXJlQGludGVsLmNv bT4KQ2M6IFZpbGxlIFN5cmrDpGzDpCA8dmlsbGUuc3lyamFsYUBsaW51eC5pbnRlbC5jb20+Ci0t LQogZHJpdmVycy9ncHUvZHJtL2RybV9kcF9tc3RfdG9wb2xvZ3kuYyB8IDIyMyArKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrCiBpbmNsdWRlL2RybS9kcm1fZHBfbXN0X2hlbHBlci5o ICAgICAgIHwgICAyICsKIDIgZmlsZXMgY2hhbmdlZCwgMjI1IGluc2VydGlvbnMoKykKCmRpZmYg LS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2RwX21zdF90b3BvbG9neS5jIGIvZHJpdmVycy9n cHUvZHJtL2RybV9kcF9tc3RfdG9wb2xvZ3kuYwppbmRleCAwZDY2MDQ1MDBiMjkuLmM0YTkxYjFi YTYxYiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2RybV9kcF9tc3RfdG9wb2xvZ3kuYwor KysgYi9kcml2ZXJzL2dwdS9kcm0vZHJtX2RwX21zdF90b3BvbG9neS5jCkBAIC0yMTY3LDYgKzIx NjcsMjI5IEBAIGludCBkcm1fZHBfbXN0X3RvcG9sb2d5X21ncl9sb3dlcl9saW5rX3JhdGUoc3Ry dWN0IGRybV9kcF9tc3RfdG9wb2xvZ3lfbWdyICptZ3IsCiB9CiBFWFBPUlRfU1lNQk9MKGRybV9k cF9tc3RfdG9wb2xvZ3lfbWdyX2xvd2VyX2xpbmtfcmF0ZSk7CiAKK3N0YXRpYyBib29sIGRybV9h dG9taWNfZHBfbXN0X3N0YXRlX29ubHlfZGlzYWJsZXNfbXN0YnMoc3RydWN0IGRybV9hdG9taWNf c3RhdGUgKnN0YXRlLAorCQkJCQkJCXN0cnVjdCBkcm1fZHBfbXN0X3RvcG9sb2d5X21nciAqbWdy LAorCQkJCQkJCXN0cnVjdCBkcm1fZHBfbXN0X2JyYW5jaCAqbXN0YikKK3sKKwlzdHJ1Y3QgZHJt X2RwX21zdF9icmFuY2ggKnJtc3RiOworCXN0cnVjdCBkcm1fZHBfbXN0X3BvcnQgKnBvcnQ7CisJ c3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcjsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9z dGF0ZSAqY29ubl9zdGF0ZTsKKwlzdHJ1Y3QgZHJtX2NydGMgKmNydGM7CisJc3RydWN0IGRybV9j cnRjX3N0YXRlICpjcnRjX3N0YXRlOworCWludCByZXQ7CisKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5 KHBvcnQsICZtc3RiLT5wb3J0cywgbmV4dCkgeworCQlybXN0YiA9IGRybV9kcF9nZXRfdmFsaWRh dGVkX21zdGJfcmVmKG1zdGItPm1nciwgcG9ydC0+bXN0Yik7CisJCWlmIChybXN0YikgeworCQkJ cmV0ID0gZHJtX2F0b21pY19kcF9tc3Rfc3RhdGVfb25seV9kaXNhYmxlc19tc3RicygKKwkJCSAg ICBzdGF0ZSwgbWdyLCBybXN0Yik7CisJCQlkcm1fZHBfcHV0X21zdF9icmFuY2hfZGV2aWNlKHJt c3RiKTsKKwkJCWlmICghcmV0KQorCQkJCXJldHVybiBmYWxzZTsKKwkJfQorCisJCWNvbm5lY3Rv ciA9IHBvcnQtPmNvbm5lY3RvcjsKKwkJaWYgKCFjb25uZWN0b3IpCisJCQljb250aW51ZTsKKwor CQljb25uX3N0YXRlID0gZHJtX2F0b21pY19nZXRfbmV3X2Nvbm5lY3Rvcl9zdGF0ZSgKKwkJICAg IHN0YXRlLCBjb25uZWN0b3IpOworCQlpZiAoIWNvbm5fc3RhdGUpCisJCQljb250aW51ZTsKKwor CQljcnRjID0gY29ubl9zdGF0ZS0+Y3J0YzsKKwkJaWYgKCFjcnRjKQorCQkJY29udGludWU7CisK KwkJY3J0Y19zdGF0ZSA9IGRybV9hdG9taWNfZ2V0X25ld19jcnRjX3N0YXRlKHN0YXRlLCBjcnRj KTsKKwkJaWYgKCFjcnRjX3N0YXRlKQorCQkJY29udGludWU7CisKKwkJaWYgKGRybV9hdG9taWNf Y3J0Y19uZWVkc19tb2Rlc2V0KGNydGNfc3RhdGUpKQorCQkJcmV0dXJuIGZhbHNlOworCX0KKwor CXJldHVybiB0cnVlOworfQorCitzdGF0aWMgaW50IGRybV9hdG9taWNfZHBfbXN0X2FsbF9tc3Ri c19kaXNhYmxlZChzdHJ1Y3QgZHJtX2F0b21pY19zdGF0ZSAqc3RhdGUsCisJCQkJCQlzdHJ1Y3Qg ZHJtX2RwX21zdF90b3BvbG9neV9tZ3IgKm1nciwKKwkJCQkJCXN0cnVjdCBkcm1fZHBfbXN0X2Jy YW5jaCAqbXN0YikKK3sKKwlzdHJ1Y3QgZHJtX2RwX21zdF9icmFuY2ggKnJtc3RiOworCXN0cnVj dCBkcm1fZHBfbXN0X3BvcnQgKnBvcnQ7CisJc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3Rv cjsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0ZSAqY29ubl9zdGF0ZTsKKwlpbnQgcmV0Owor CisJbGlzdF9mb3JfZWFjaF9lbnRyeShwb3J0LCAmbXN0Yi0+cG9ydHMsIG5leHQpIHsKKwkJcm1z dGIgPSBkcm1fZHBfZ2V0X3ZhbGlkYXRlZF9tc3RiX3JlZihtc3RiLT5tZ3IsIHBvcnQtPm1zdGIp OworCQlpZiAocm1zdGIpIHsKKwkJCXJldCA9IGRybV9hdG9taWNfZHBfbXN0X2FsbF9tc3Ric19k aXNhYmxlZCgKKwkJCSAgICBzdGF0ZSwgbWdyLCBybXN0Yik7CisJCQlkcm1fZHBfcHV0X21zdF9i cmFuY2hfZGV2aWNlKHJtc3RiKTsKKwkJCWlmIChyZXQgPD0gMCkKKwkJCQlyZXR1cm4gcmV0Owor CQl9CisKKwkJY29ubmVjdG9yID0gcG9ydC0+Y29ubmVjdG9yOworCQlpZiAoIWNvbm5lY3RvcikK KwkJCWNvbnRpbnVlOworCisJCWNvbm5fc3RhdGUgPSBkcm1fYXRvbWljX2dldF9jb25uZWN0b3Jf c3RhdGUoCisJCSAgICBzdGF0ZSwgY29ubmVjdG9yKTsKKwkJaWYgKElTX0VSUihjb25uX3N0YXRl KSkKKwkJCXJldHVybiBQVFJfRVJSKGNvbm5fc3RhdGUpOworCisJCWlmIChjb25uX3N0YXRlLT5j cnRjKQorCQkJcmV0dXJuIGZhbHNlOworCX0KKworCS8qIE5vIGVuYWJsZWQgQ1JUQ3MgZm91bmQg Ki8KKwlyZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGludCBkcm1fYXRvbWljX2RwX21zdF9yZXRy YWluX21zdGIoc3RydWN0IGRybV9hdG9taWNfc3RhdGUgKnN0YXRlLAorCQkJCQkgIHN0cnVjdCBk cm1fZHBfbXN0X3RvcG9sb2d5X21nciAqbWdyLAorCQkJCQkgIHN0cnVjdCBkcm1fZHBfbXN0X2Jy YW5jaCAqbXN0YiwKKwkJCQkJICBib29sIGZ1bGxfbW9kZXNldCkKK3sKKwlzdHJ1Y3QgZHJtX2Rw X21zdF9icmFuY2ggKnJtc3RiOworCXN0cnVjdCBkcm1fZHBfbXN0X3BvcnQgKnBvcnQ7CisJc3Ry dWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcjsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0 ZSAqY29ubl9zdGF0ZTsKKwlzdHJ1Y3QgZHJtX2NydGMgKmNydGM7CisJc3RydWN0IGRybV9jcnRj X3N0YXRlICpjcnRjX3N0YXRlOworCWludCByZXQ7CisKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KHBv cnQsICZtc3RiLT5wb3J0cywgbmV4dCkgeworCQlybXN0YiA9IGRybV9kcF9nZXRfdmFsaWRhdGVk X21zdGJfcmVmKG1zdGItPm1nciwgcG9ydC0+bXN0Yik7CisJCWlmIChybXN0YikgeworCQkJcmV0 ID0gZHJtX2F0b21pY19kcF9tc3RfcmV0cmFpbl9tc3RiKAorCQkJICAgIHN0YXRlLCBtZ3IsIHJt c3RiLCBmdWxsX21vZGVzZXQpOworCQkJZHJtX2RwX3B1dF9tc3RfYnJhbmNoX2RldmljZShybXN0 Yik7CisJCQlpZiAocmV0KQorCQkJCXJldHVybiByZXQ7CisJCX0KKworCQljb25uZWN0b3IgPSBw b3J0LT5jb25uZWN0b3I7CisJCWlmICghY29ubmVjdG9yKQorCQkJY29udGludWU7CisKKwkJY29u bl9zdGF0ZSA9IGRybV9hdG9taWNfZ2V0X2Nvbm5lY3Rvcl9zdGF0ZShzdGF0ZSwgY29ubmVjdG9y KTsKKwkJaWYgKElTX0VSUihjb25uX3N0YXRlKSkKKwkJCXJldHVybiBQVFJfRVJSKGNvbm5fc3Rh dGUpOworCisJCWlmIChjb25uX3N0YXRlLT5saW5rX3N0YXR1cyAhPSBEUk1fTU9ERV9MSU5LX1NU QVRVU19HT09EKSB7CisJCQlEUk1fREVCVUdfQVRPTUlDKCJbQ09OTkVDVE9SOiVkOiVzXSBsaW5r IHN0YXR1cyBiYWQgLT4gZ29vZFxuIiwKKwkJCQkJIGNvbm5lY3Rvci0+YmFzZS5pZCwgY29ubmVj dG9yLT5uYW1lKTsKKwkJCWNvbm5fc3RhdGUtPmxpbmtfc3RhdHVzID0gRFJNX01PREVfTElOS19T VEFUVVNfR09PRDsKKwkJfQorCisJCWlmICghZnVsbF9tb2Rlc2V0KQorCQkJY29udGludWU7CisK KwkJY3J0YyA9IGNvbm5fc3RhdGUtPmNydGM7CisJCWlmICghY3J0YykKKwkJCWNvbnRpbnVlOwor CisJCWNydGNfc3RhdGUgPSBkcm1fYXRvbWljX2dldF9jcnRjX3N0YXRlKHN0YXRlLCBjcnRjKTsK KwkJaWYgKElTX0VSUihjcnRjX3N0YXRlKSkKKwkJCXJldHVybiBQVFJfRVJSKGNydGNfc3RhdGUp OworCisJCWlmICghY3J0Y19zdGF0ZS0+bW9kZV9jaGFuZ2VkKSB7CisJCQlEUk1fREVCVUdfQVRP TUlDKCJbQ1JUQzolZDolc10gbmVlZHMgZnVsbCBtb2Rlc2V0XG4iLAorCQkJCQkgY3J0Yy0+YmFz ZS5pZCwgY3J0Yy0+bmFtZSk7CisJCQljcnRjX3N0YXRlLT5tb2RlX2NoYW5nZWQgPSB0cnVlOwor CQl9CisJfQorCisJcmV0dXJuIDA7Cit9CisKKy8qKgorICogZHJtX2F0b21pY19kcF9tc3RfcmV0 cmFpbl90b3BvbG9neSgpIC0gcHJlcGFyZSBhIG1vZGVzZXQgdGhhdCB3aWxsIHJldHJhaW4KKyAq IGFuIE1TVCB0b3BvbG9neQorICogQHN0YXRlOiBUaGUgbmV3IHN0YXRlIHRoYXQgd291bGQgcmV0 cmFpbiB0aGUgdG9wb2xvZ3kgbGluaworICogQG1ncjogVGhlIHRvcG9sb2d5IG1hbmFnZXIgdG8g dXNlCisgKgorICogQWZ0ZXIgdXNlcnNwYWNlIGhhcyBiZWVuIHNpZ25hbGVkIHRoYXQgY29ubmVj dG9ycyBhcmUgaW4gbmVlZCBvZgorICogcmV0cmFpbmluZywgaXQncyBleHBlY3RlZCB0aGF0IGEg bW9kZXNldCB3aWxsIGJlIHBlcmZvcm1lZCBmb3IgYW55IENSVENzIG9uCisgKiBzYWlkIGNvbm5l Y3RvcnMuIFNpbmNlIGFsbCBvZiB0aGUgYnJhbmNoIGRldmljZXMgaW4gYW4gTVNUIHRvcG9sb2d5 IHNoYXJlIGEKKyAqIHNpbmdsZSBsaW5rLCB0aGV5IGFsc28gc2hhcmUgdGhlIHNhbWUgbGluayBz dGF0dXMsIGxhbmUgY291bnQsIGFuZCBsaW5rCisgKiByYXRlLgorICoKKyAqIFNpbmNlIGFsbCBv ZiB0aGVzZSBjaGFyYWN0ZXJpc3RpY3MgYXJlIHNoYXJlZCwgdGhlcmUncyBvbmx5IHR3byB2YWxp ZAorICogc29sdXRpb25zIHdoZW4gZmFsbGJhY2sgbGluayB0cmFpbmluZyBwYXJhbWV0ZXJzIG5l ZWQgdG8gYmUgYXBwbGllZC4gVGhlCisgKiBmaXJzdCBpcyBzaW1wbHkgdW5hc3NpZ25pbmcgZWFj aCBtc3RiIGNvbm5lY3RvcidzIENSVEMuIFNpbmNlIHRoaXMgYWN0aW9uCisgKiBjYW4gb25seSBm cmVlIHNsb3RzIG9uIHRoZSBWQ1BJIHRhYmxlIGFuZCBub3QgYWxsb2NhdGUgdGhlbSwgdGhpcyBj YW4gYmUKKyAqIGRvbmUgd2l0aG91dCBwdWxsaW5nIGluIGFkZGl0aW9uYWwgQ1JUQ3Mgb24gdGhl IE1TVCB0b3BvbG9neS4gQWRkaXRpb25hbGx5CisgKiBpZiB0aGlzIGFjdGlvbiB3b3VsZCByZXN1 bHQgaW4gdGhlcmUgbm8gbG9uZ2VyIGJlaW5nIGFueSBDUlRDcyBhc3NpZ25lZCB0bworICogbXN0 YiBjb25uZWN0b3JzLCB0aGlzIHdvdWxkIGJlIGVub3VnaCB0byBicmluZyB0aGUgdG9wb2xvZ3kg YmFjayBpbnRvIGEKKyAqIHRyYWluZWQgc3RhdGUgc2luY2UgdGhlcmUgd291bGQgYmUgbm90aGlu ZyBsZWZ0IHJlcXVpcmluZyBWQ1BJCisgKiByZWFsbG9jYXRpb25zLgorICoKKyAqIFRoZSBzZWNv bmQgc29sdXRpb24gaXMgdG8gY29tbWl0IG5ldyBtb2RlcyB0byBhbGwgb2YgdGhlIGNvbm5lY3Rv cnMgb24gdGhlCisgKiB0b3BvbG9neS4gU2luY2UgdGhpcyBhY3Rpb24gd291bGQgcmVzdWx0IGlu IFZDUEkgcmVhbGxvY2F0aW9ucyB3aXRoIGEgbmV3CisgKiBsaW5rIHJhdGUgYW5kIGxhbmUgY291 bnQsIGEgbW9kZXNldCBtdXN0IGFsc28gYmUgcGVyZm9ybWVkIG9uIGV2ZXJ5IG90aGVyCisgKiBD UlRDIGRyaXZpbmcgYSBicmFuY2ggZGV2aWNlIG9uIHRoZSBnaXZlbiB0b3BvbG9neSBhdCB0aGUg c2FtZSB0aW1lLiBUaGlzCisgKiBpcyB0byBlbnN1cmUgdGhhdCBhbGwgVkNQSSBhbGxvY2F0aW9u cyBhcmUgcHJvcGVybHkgcmVjYWxjdWxhdGVkIGluCisgKiByZXNwb25zZSB0byB0aGUgbmV3IGxp bmsgcmF0ZSBhbmQgbGFuZSBjb3VudCwgdGhhdCB0aGUgbmV3IG1vZGVzIHdpbGwgZml0CisgKiBp bnRvIHRoZSByZWNhbGN1bGF0ZWQgVkNQSSB0YWJsZSwgYW5kIHRoYXQgdGhlIG5ldyBhdG9taWMg c3RhdGUgY291bGQgbmV2ZXIKKyAqIHJlc3VsdCBpbiBhbiBvdGhlcndpc2UgcGh5c2ljYWxseSBp bXBvc3NpYmxlIGNvbmZpZ3VyYXRpb24gKGUuZy4gZGlmZmVyZW50CisgKiBtc3RicyB3aXRoIENS VENzIHRyYWluZWQgdG8gZGlmZmVyZW50IGxpbmsgcmF0ZXMvbGFuZSBjb3VudHMpLgorICoKKyAq IEZpbmFsbHksIGFueSBhdG9taWMgY29tbWl0IHdoaWNoIHdvdWxkIHJlc3VsdCBpbiBnb2luZyBm cm9tIGFuCisgKiB1bnJlY292ZXJhYmxlIGxpbmsgc3RhdGUgdG8gYSBwcm9wZXJseSB0cmFpbmVk IGxpbmsgc3RhdGUgbXVzdCBhbHNvIHRha2UKKyAqIGNhcmUgb2YgYXBwcm9wcmlhdGVseSB1cGRh dGluZyB0aGUgbGluayBzdGF0dXMgcHJvcGVydGllcyBvZiBhbGwgY29ubmVjdG9ycworICogb24g dGhlIHRvcG9sb2d5IGZyb20gYmFkIHRvIGdvb2QuIFRoaXMgZnVuY3Rpb24gdGFrZXMgY2FyZSBv ZiBhbGwgb2YgdGhlc2UKKyAqIGNoZWNrcyBpbiBAc3RhdGUgZm9yIHRoZSB0b3BvbG9neSBtYW5h Z2VyIEBtZ3IgaW5jbHVkaW5nIHBvc3NpYmx5IHB1bGxpbmcKKyAqIGluIGFkZGl0aW9uYWwgQ1JU Q3MgaW50byB0aGUgbW9kZXNldCwgYW5kIHBvc3NpYmx5IHVwZGF0aW5nIHRoZSBsaW5rIHN0YXR1 cworICogb2YgZWFjaCBtc3RiJ3MgRFJNIGNvbm5lY3Rvci4KKyAqCisgKiBUaGlzIGZ1bmN0aW9u IHNob3VsZCBiZSBjYWxsZWQgd2l0aGluIHRoZSBkcml2ZXIncyBhdG9taWMgY2hlY2sgY2FsbGJh Y2tzCisgKiB3aGVuZXZlciBhIG1vZGVzZXQgaGFwcGVucyBvbiBhbiBNU1QgY29ubmVjdG9yIHdp dGggaXQncyBsaW5rIHN0YXR1cyBzZXQgdG8KKyAqIERSTV9NT0RFX0xJTktfU1RBVFVTX0JBRC4K KyAqCisgKiBSRVRVUk5TOgorICoKKyAqIFJldHVybnMgMCBmb3Igc3VjY2Vzcywgb3IgbmVnYXRp dmUgZXJyb3IgY29kZSBmb3IgZmFpbHVyZS4KKyAqLworaW50IGRybV9hdG9taWNfZHBfbXN0X3Jl dHJhaW5fdG9wb2xvZ3koc3RydWN0IGRybV9hdG9taWNfc3RhdGUgKnN0YXRlLAorCQkJCSAgICAg ICBzdHJ1Y3QgZHJtX2RwX21zdF90b3BvbG9neV9tZ3IgKm1ncikKK3sKKwlzdHJ1Y3QgZHJtX2Rw X21zdF9icmFuY2ggKm1zdGIgPQorCQlkcm1fZHBfZ2V0X3ZhbGlkYXRlZF9tc3RiX3JlZihtZ3Is IG1nci0+bXN0X3ByaW1hcnkpOworCWludCByZXQgPSAwOworCWJvb2wgbmVlZF9tb2Rlc2V0ID0g ZmFsc2U7CisKKwlpZiAoIW1zdGIpCisJCXJldHVybiAwOworCisJaWYgKGRybV9hdG9taWNfZHBf bXN0X3N0YXRlX29ubHlfZGlzYWJsZXNfbXN0YnMoc3RhdGUsIG1nciwgbXN0YikpIHsKKwkJcmV0 ID0gZHJtX2F0b21pY19kcF9tc3RfYWxsX21zdGJzX2Rpc2FibGVkKHN0YXRlLCBtZ3IsIG1zdGIp OworCQlpZiAocmV0IDwgMCkKKwkJCWdvdG8gb3V0OworCisJCWlmIChyZXQpCisJCQlEUk1fREVC VUdfQVRPTUlDKCJzdGF0ZSAlcCBkaXNhYmxlcyBhbGwgQ1JUQ3Mgb24gbXN0IG1nciAlcFxuIiwK KwkJCQkJIHN0YXRlLCBtZ3IpOworCQllbHNlCisJCQlnb3RvIG91dDsgLyogdmFsaWQsIGJ1dCBk b2Vzbid0IHJldHJhaW4gbGluayAqLworCX0gZWxzZSB7CisJCURSTV9ERUJVR19BVE9NSUMoInN0 YXRlICVwIHJlcXVpcmVzIGZ1bGwgbW9kZXNldCBmb3IgQ1JUQ3Mgb24gbXN0IG1nciAlcFxuIiwK KwkJCQkgc3RhdGUsIG1ncik7CisJCW5lZWRfbW9kZXNldCA9IHRydWU7CisJfQorCisJcmV0ID0g ZHJtX2F0b21pY19kcF9tc3RfcmV0cmFpbl9tc3RiKHN0YXRlLCBtZ3IsIG1zdGIsIG5lZWRfbW9k ZXNldCk7CitvdXQ6CisJZHJtX2RwX3B1dF9tc3RfYnJhbmNoX2RldmljZShtZ3ItPm1zdF9wcmlt YXJ5KTsKKwlyZXR1cm4gcmV0OworfQorRVhQT1JUX1NZTUJPTChkcm1fYXRvbWljX2RwX21zdF9y ZXRyYWluX3RvcG9sb2d5KTsKKwogLyoqCiAgKiBkcm1fZHBfbXN0X3RvcG9sb2d5X21ncl9zZXRf bXN0KCkgLSBTZXQgdGhlIE1TVCBzdGF0ZSBmb3IgYSB0b3BvbG9neSBtYW5hZ2VyCiAgKiBAbWdy OiBtYW5hZ2VyIHRvIHNldCBzdGF0ZSBmb3IKZGlmZiAtLWdpdCBhL2luY2x1ZGUvZHJtL2RybV9k cF9tc3RfaGVscGVyLmggYi9pbmNsdWRlL2RybS9kcm1fZHBfbXN0X2hlbHBlci5oCmluZGV4IDYy NjFlYzQzYTJjMC4uMjQwNzVlYjJkZDFiIDEwMDY0NAotLS0gYS9pbmNsdWRlL2RybS9kcm1fZHBf bXN0X2hlbHBlci5oCisrKyBiL2luY2x1ZGUvZHJtL2RybV9kcF9tc3RfaGVscGVyLmgKQEAgLTYz Niw1ICs2MzYsNyBAQCBpbnQgZHJtX2RwX3NlbmRfcG93ZXJfdXBkb3duX3BoeShzdHJ1Y3QgZHJt X2RwX21zdF90b3BvbG9neV9tZ3IgKm1nciwKIAogaW50IGRybV9kcF9tc3RfdG9wb2xvZ3lfbWdy X2xvd2VyX2xpbmtfcmF0ZShzdHJ1Y3QgZHJtX2RwX21zdF90b3BvbG9neV9tZ3IgKm1nciwKIAkJ CQkJICAgIGludCBkcF9saW5rX2J3LCBpbnQgZHBfbGlua19jb3VudCk7CitpbnQgZHJtX2F0b21p Y19kcF9tc3RfcmV0cmFpbl90b3BvbG9neShzdHJ1Y3QgZHJtX2F0b21pY19zdGF0ZSAqc3RhdGUs CisJCQkJICAgICAgIHN0cnVjdCBkcm1fZHBfbXN0X3RvcG9sb2d5X21nciAqbWdyKTsKIAogI2Vu ZGlmCi0tIAoyLjE0LjMKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9w Lm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1k ZXZlbAo=