From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57488C3A5A2 for ; Tue, 3 Sep 2019 20:48:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1B61F21897 for ; Tue, 3 Sep 2019 20:48:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727422AbfICUsJ (ORCPT ); Tue, 3 Sep 2019 16:48:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42172 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727175AbfICUsI (ORCPT ); Tue, 3 Sep 2019 16:48:08 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D371118F351C; Tue, 3 Sep 2019 20:48:07 +0000 (UTC) Received: from malachite.bss.redhat.com (dhcp-10-20-1-34.bss.redhat.com [10.20.1.34]) by smtp.corp.redhat.com (Postfix) with ESMTP id 73C9F1001B07; Tue, 3 Sep 2019 20:48:05 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org, amd-gfx@lists.freedesktop.org Cc: Juston Li , Imre Deak , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Harry Wentland , Daniel Vetter , Maarten Lankhorst , Maxime Ripard , Sean Paul , David Airlie , Daniel Vetter , Thomas Hellstrom , Alexandru Gheorghe , Deepak Rawat , linux-kernel@vger.kernel.org Subject: [PATCH v2 07/27] drm/dp_mst: Add sideband down request tracing + selftests Date: Tue, 3 Sep 2019 16:45:45 -0400 Message-Id: <20190903204645.25487-8-lyude@redhat.com> In-Reply-To: <20190903204645.25487-1-lyude@redhat.com> References: <20190903204645.25487-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.63]); Tue, 03 Sep 2019 20:48:08 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Unfortunately the DP MST helpers do not have much in the way of debugging utilities. So, let's add some! This adds basic debugging output for down sideband requests that we send from the driver, so that we can actually discern what's happening when sideband requests timeout. Since there wasn't really a good way of testing that any of this worked, I ended up writing simple selftests that lightly test sideband message encoding and decoding as well. Enjoy! Changes since v1: * Clean up DO_TEST() and sideband_msg_req_encode_decode() - danvet * Get rid of pr_fmt(), just define a prefix string instead and use drm_printf() * Check highest bit of VCPI in drm_dp_decode_sideband_req() - danvet * Make the switch case order between drm_dp_decode_sideband_req() and drm_dp_encode_sideband_req() the same - danvet * Only check DRM_UT_DP - danvet * Clean up sideband_msg_req_equal() from selftests a bit, and add comments explaining why we can't just use memcmp - danvet Cc: Juston Li Cc: Imre Deak Cc: Ville Syrjälä Cc: Harry Wentland Reviewed-by: Daniel Vetter Signed-off-by: Lyude Paul --- drivers/gpu/drm/drm_dp_mst_topology.c | 309 +++++++++++++++++- .../gpu/drm/drm_dp_mst_topology_internal.h | 24 ++ .../gpu/drm/selftests/drm_modeset_selftests.h | 1 + .../drm/selftests/test-drm_dp_mst_helper.c | 204 ++++++++++++ .../drm/selftests/test-drm_modeset_common.h | 1 + include/drm/drm_dp_mst_helper.h | 2 +- 6 files changed, 536 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/drm_dp_mst_topology_internal.h diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 1c862749cb63..f5f1d8b50fb6 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -37,6 +37,7 @@ #include #include "drm_crtc_helper_internal.h" +#include "drm_dp_mst_topology_internal.h" /** * DOC: dp mst helper @@ -73,6 +74,8 @@ static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux); static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux); static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr); +#define DBG_PREFIX "[dp_mst]" + #define DP_STR(x) [DP_ ## x] = #x static const char *drm_dp_mst_req_type_str(u8 req_type) @@ -129,6 +132,43 @@ static const char *drm_dp_mst_nak_reason_str(u8 nak_reason) } #undef DP_STR +#define DP_STR(x) [DRM_DP_SIDEBAND_TX_ ## x] = #x + +static const char *drm_dp_mst_sideband_tx_state_str(int state) +{ + static const char * const sideband_reason_str[] = { + DP_STR(QUEUED), + DP_STR(START_SEND), + DP_STR(SENT), + DP_STR(RX), + DP_STR(TIMEOUT), + }; + + if (state >= ARRAY_SIZE(sideband_reason_str) || + !sideband_reason_str[state]) + return "unknown"; + + return sideband_reason_str[state]; +} + +static int +drm_dp_mst_rad_to_str(const u8 rad[8], u8 lct, char *out, size_t len) +{ + int i; + u8 unpacked_rad[16]; + + for (i = 0; i < lct; i++) { + if (i % 2) + unpacked_rad[i] = rad[i / 2] >> 4; + else + unpacked_rad[i] = rad[i / 2] & BIT_MASK(4); + } + + /* TODO: Eventually add something to printk so we can format the rad + * like this: 1.2.3 + */ + return snprintf(out, len, "%*phC", lct, unpacked_rad); +} /* sideband msg handling */ static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t num_nibbles) @@ -261,8 +301,9 @@ static bool drm_dp_decode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr, return true; } -static void drm_dp_encode_sideband_req(struct drm_dp_sideband_msg_req_body *req, - struct drm_dp_sideband_msg_tx *raw) +void +drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req, + struct drm_dp_sideband_msg_tx *raw) { int idx = 0; int i; @@ -363,6 +404,251 @@ static void drm_dp_encode_sideband_req(struct drm_dp_sideband_msg_req_body *req, } raw->cur_len = idx; } +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_encode_sideband_req); + +/* Decode a sideband request we've encoded, mainly used for debugging */ +int +drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw, + struct drm_dp_sideband_msg_req_body *req) +{ + const u8 *buf = raw->msg; + int i, idx = 0; + + req->req_type = buf[idx++] & 0x7f; + switch (req->req_type) { + case DP_ENUM_PATH_RESOURCES: + case DP_POWER_DOWN_PHY: + case DP_POWER_UP_PHY: + req->u.port_num.port_number = (buf[idx] >> 4) & 0xf; + break; + case DP_ALLOCATE_PAYLOAD: + { + struct drm_dp_allocate_payload *a = + &req->u.allocate_payload; + + a->number_sdp_streams = buf[idx] & 0xf; + a->port_number = (buf[idx] >> 4) & 0xf; + + WARN_ON(buf[++idx] & 0x80); + a->vcpi = buf[idx] & 0x7f; + + a->pbn = buf[++idx] << 8; + a->pbn |= buf[++idx]; + + idx++; + for (i = 0; i < a->number_sdp_streams; i++) { + a->sdp_stream_sink[i] = + (buf[idx + (i / 2)] >> ((i % 2) ? 0 : 4)) & 0xf; + } + } + break; + case DP_QUERY_PAYLOAD: + req->u.query_payload.port_number = (buf[idx] >> 4) & 0xf; + WARN_ON(buf[++idx] & 0x80); + req->u.query_payload.vcpi = buf[idx] & 0x7f; + break; + case DP_REMOTE_DPCD_READ: + { + struct drm_dp_remote_dpcd_read *r = &req->u.dpcd_read; + + r->port_number = (buf[idx] >> 4) & 0xf; + + r->dpcd_address = (buf[idx] << 16) & 0xf0000; + r->dpcd_address |= (buf[++idx] << 8) & 0xff00; + r->dpcd_address |= buf[++idx] & 0xff; + + r->num_bytes = buf[++idx]; + } + break; + case DP_REMOTE_DPCD_WRITE: + { + struct drm_dp_remote_dpcd_write *w = + &req->u.dpcd_write; + + w->port_number = (buf[idx] >> 4) & 0xf; + + w->dpcd_address = (buf[idx] << 16) & 0xf0000; + w->dpcd_address |= (buf[++idx] << 8) & 0xff00; + w->dpcd_address |= buf[++idx] & 0xff; + + w->num_bytes = buf[++idx]; + + w->bytes = kmemdup(&buf[++idx], w->num_bytes, + GFP_KERNEL); + if (!w->bytes) + return -ENOMEM; + } + break; + case DP_REMOTE_I2C_READ: + { + struct drm_dp_remote_i2c_read *r = &req->u.i2c_read; + struct drm_dp_remote_i2c_read_tx *tx; + bool failed = false; + + r->num_transactions = buf[idx] & 0x3; + r->port_number = (buf[idx] >> 4) & 0xf; + for (i = 0; i < r->num_transactions; i++) { + tx = &r->transactions[i]; + + tx->i2c_dev_id = buf[++idx] & 0x7f; + tx->num_bytes = buf[++idx]; + tx->bytes = kmemdup(&buf[++idx], + tx->num_bytes, + GFP_KERNEL); + if (!tx->bytes) { + failed = true; + break; + } + idx += tx->num_bytes; + tx->no_stop_bit = (buf[idx] >> 5) & 0x1; + tx->i2c_transaction_delay = buf[idx] & 0xf; + } + + if (failed) { + for (i = 0; i < r->num_transactions; i++) + kfree(tx->bytes); + return -ENOMEM; + } + + r->read_i2c_device_id = buf[++idx] & 0x7f; + r->num_bytes_read = buf[++idx]; + } + break; + case DP_REMOTE_I2C_WRITE: + { + struct drm_dp_remote_i2c_write *w = &req->u.i2c_write; + + w->port_number = (buf[idx] >> 4) & 0xf; + w->write_i2c_device_id = buf[++idx] & 0x7f; + w->num_bytes = buf[++idx]; + w->bytes = kmemdup(&buf[++idx], w->num_bytes, + GFP_KERNEL); + if (!w->bytes) + return -ENOMEM; + } + break; + } + + return 0; +} +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_decode_sideband_req); + +void +drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req, + int indent, struct drm_printer *printer) +{ + int i; + +#define P(f, ...) drm_printf_indent(printer, indent, f, ##__VA_ARGS__) + if (req->req_type == DP_LINK_ADDRESS) { + /* No contents to print */ + P("type=%s\n", drm_dp_mst_req_type_str(req->req_type)); + return; + } + + P("type=%s contents:\n", drm_dp_mst_req_type_str(req->req_type)); + indent++; + + switch (req->req_type) { + case DP_ENUM_PATH_RESOURCES: + case DP_POWER_DOWN_PHY: + case DP_POWER_UP_PHY: + P("port=%d\n", req->u.port_num.port_number); + break; + case DP_ALLOCATE_PAYLOAD: + P("port=%d vcpi=%d pbn=%d sdp_streams=%d %*ph\n", + req->u.allocate_payload.port_number, + req->u.allocate_payload.vcpi, req->u.allocate_payload.pbn, + req->u.allocate_payload.number_sdp_streams, + req->u.allocate_payload.number_sdp_streams, + req->u.allocate_payload.sdp_stream_sink); + break; + case DP_QUERY_PAYLOAD: + P("port=%d vcpi=%d\n", + req->u.query_payload.port_number, + req->u.query_payload.vcpi); + break; + case DP_REMOTE_DPCD_READ: + P("port=%d dpcd_addr=%05x len=%d\n", + req->u.dpcd_read.port_number, req->u.dpcd_read.dpcd_address, + req->u.dpcd_read.num_bytes); + break; + case DP_REMOTE_DPCD_WRITE: + P("port=%d addr=%05x len=%d: %*ph\n", + req->u.dpcd_write.port_number, + req->u.dpcd_write.dpcd_address, + req->u.dpcd_write.num_bytes, req->u.dpcd_write.num_bytes, + req->u.dpcd_write.bytes); + break; + case DP_REMOTE_I2C_READ: + P("port=%d num_tx=%d id=%d size=%d:\n", + req->u.i2c_read.port_number, + req->u.i2c_read.num_transactions, + req->u.i2c_read.read_i2c_device_id, + req->u.i2c_read.num_bytes_read); + + indent++; + for (i = 0; i < req->u.i2c_read.num_transactions; i++) { + const struct drm_dp_remote_i2c_read_tx *rtx = + &req->u.i2c_read.transactions[i]; + + P("%d: id=%03d size=%03d no_stop_bit=%d tx_delay=%03d: %*ph\n", + i, rtx->i2c_dev_id, rtx->num_bytes, + rtx->no_stop_bit, rtx->i2c_transaction_delay, + rtx->num_bytes, rtx->bytes); + } + break; + case DP_REMOTE_I2C_WRITE: + P("port=%d id=%d size=%d: %*ph\n", + req->u.i2c_write.port_number, + req->u.i2c_write.write_i2c_device_id, + req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes, + req->u.i2c_write.bytes); + break; + default: + P("???\n"); + break; + } +#undef P +} +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_dump_sideband_msg_req_body); + +static inline void +drm_dp_mst_dump_sideband_msg_tx(struct drm_printer *p, + const struct drm_dp_sideband_msg_tx *txmsg) +{ + struct drm_dp_sideband_msg_req_body req; + char buf[64]; + int ret; + int i; + + drm_dp_mst_rad_to_str(txmsg->dst->rad, txmsg->dst->lct, buf, + sizeof(buf)); + drm_printf(p, "txmsg cur_offset=%x cur_len=%x seqno=%x state=%s path_msg=%d dst=%s\n", + txmsg->cur_offset, txmsg->cur_len, txmsg->seqno, + drm_dp_mst_sideband_tx_state_str(txmsg->state), + txmsg->path_msg, buf); + + ret = drm_dp_decode_sideband_req(txmsg, &req); + if (ret) { + drm_printf(p, "\n", ret); + return; + } + drm_dp_dump_sideband_msg_req_body(&req, 1, p); + + switch (req.req_type) { + case DP_REMOTE_DPCD_WRITE: + kfree(req.u.dpcd_write.bytes); + break; + case DP_REMOTE_I2C_READ: + for (i = 0; i < req.u.i2c_read.num_transactions; i++) + kfree(req.u.i2c_read.transactions[i].bytes); + break; + case DP_REMOTE_I2C_WRITE: + kfree(req.u.i2c_write.bytes); + break; + } +} static void drm_dp_crc_sideband_chunk_req(u8 *msg, u8 len) { @@ -894,6 +1180,11 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb, } } out: + if (unlikely(ret == -EIO && drm_debug & DRM_UT_DP)) { + struct drm_printer p = drm_debug_printer(DBG_PREFIX); + + drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); + } mutex_unlock(&mgr->qlock); return ret; @@ -2013,8 +2304,11 @@ static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr, idx += tosend + 1; ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx); - if (ret) { - DRM_DEBUG_KMS("sideband msg failed to send\n"); + if (unlikely(ret && drm_debug & DRM_UT_DP)) { + struct drm_printer p = drm_debug_printer(DBG_PREFIX); + + drm_printf(&p, "sideband msg failed to send\n"); + drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); return ret; } @@ -2076,6 +2370,13 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, { mutex_lock(&mgr->qlock); list_add_tail(&txmsg->next, &mgr->tx_msg_downq); + + if (unlikely(drm_debug & DRM_UT_DP)) { + struct drm_printer p = drm_debug_printer(DBG_PREFIX); + + drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); + } + if (list_is_singular(&mgr->tx_msg_downq)) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); diff --git a/drivers/gpu/drm/drm_dp_mst_topology_internal.h b/drivers/gpu/drm/drm_dp_mst_topology_internal.h new file mode 100644 index 000000000000..eeda9a61c657 --- /dev/null +++ b/drivers/gpu/drm/drm_dp_mst_topology_internal.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Declarations for DP MST related functions which are only used in selftests + * + * Copyright © 2018 Red Hat + * Authors: + * Lyude Paul + */ + +#ifndef _DRM_DP_MST_HELPER_INTERNAL_H_ +#define _DRM_DP_MST_HELPER_INTERNAL_H_ + +#include + +void +drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req, + struct drm_dp_sideband_msg_tx *raw); +int drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw, + struct drm_dp_sideband_msg_req_body *req); +void +drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req, + int indent, struct drm_printer *printer); + +#endif /* !_DRM_DP_MST_HELPER_INTERNAL_H_ */ diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index dec3ee3ec96f..1898de0b4a4d 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -33,3 +33,4 @@ selftest(damage_iter_damage_one_outside, igt_damage_iter_damage_one_outside) selftest(damage_iter_damage_src_moved, igt_damage_iter_damage_src_moved) selftest(damage_iter_damage_not_visible, igt_damage_iter_damage_not_visible) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) +selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c index 9baa5171988d..af2b2de65316 100644 --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c @@ -3,9 +3,12 @@ * Test cases for for the DRM DP MST helpers */ +#define PREFIX_STR "[drm_dp_mst_helper]" + #include #include +#include "../drm_dp_mst_topology_internal.h" #include "test-drm_modeset_common.h" int igt_dp_mst_calc_pbn_mode(void *ignored) @@ -32,3 +35,204 @@ int igt_dp_mst_calc_pbn_mode(void *ignored) return 0; } + +static bool +sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in, + const struct drm_dp_sideband_msg_req_body *out) +{ + const struct drm_dp_remote_i2c_read_tx *txin, *txout; + int i; + + if (in->req_type != out->req_type) + return false; + + switch (in->req_type) { + /* + * Compare struct members manually for request types which can't be + * compared simply using memcmp(). This is because said request types + * contain pointers to other allocated structs + */ + case DP_REMOTE_I2C_READ: +#define IN in->u.i2c_read +#define OUT out->u.i2c_read + if (IN.num_bytes_read != OUT.num_bytes_read || + IN.num_transactions != OUT.num_transactions || + IN.port_number != OUT.port_number || + IN.read_i2c_device_id != OUT.read_i2c_device_id) + return false; + + for (i = 0; i < IN.num_transactions; i++) { + txin = &IN.transactions[i]; + txout = &OUT.transactions[i]; + + if (txin->i2c_dev_id != txout->i2c_dev_id || + txin->no_stop_bit != txout->no_stop_bit || + txin->num_bytes != txout->num_bytes || + txin->i2c_transaction_delay != + txout->i2c_transaction_delay) + return false; + + if (memcmp(txin->bytes, txout->bytes, + txin->num_bytes) != 0) + return false; + } + break; +#undef IN +#undef OUT + + case DP_REMOTE_DPCD_WRITE: +#define IN in->u.dpcd_write +#define OUT out->u.dpcd_write + if (IN.dpcd_address != OUT.dpcd_address || + IN.num_bytes != OUT.num_bytes || + IN.port_number != OUT.port_number) + return false; + + return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0; +#undef IN +#undef OUT + + case DP_REMOTE_I2C_WRITE: +#define IN in->u.i2c_write +#define OUT out->u.i2c_write + if (IN.port_number != OUT.port_number || + IN.write_i2c_device_id != OUT.write_i2c_device_id || + IN.num_bytes != OUT.num_bytes) + return false; + + return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0; +#undef IN +#undef OUT + + default: + return memcmp(in, out, sizeof(*in)) == 0; + } + + return true; +} + +static bool +sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in) +{ + struct drm_dp_sideband_msg_req_body out = {0}; + struct drm_printer p = drm_err_printer(PREFIX_STR); + struct drm_dp_sideband_msg_tx txmsg; + int i, ret; + + drm_dp_encode_sideband_req(in, &txmsg); + ret = drm_dp_decode_sideband_req(&txmsg, &out); + if (ret < 0) { + drm_printf(&p, "Failed to decode sideband request: %d\n", + ret); + return false; + } + + if (!sideband_msg_req_equal(in, &out)) { + drm_printf(&p, "Encode/decode failed, expected:\n"); + drm_dp_dump_sideband_msg_req_body(in, 1, &p); + drm_printf(&p, "Got:\n"); + drm_dp_dump_sideband_msg_req_body(&out, 1, &p); + return false; + } + + switch (in->req_type) { + case DP_REMOTE_DPCD_WRITE: + kfree(out.u.dpcd_write.bytes); + break; + case DP_REMOTE_I2C_READ: + for (i = 0; i < out.u.i2c_read.num_transactions; i++) + kfree(out.u.i2c_read.transactions[i].bytes); + break; + case DP_REMOTE_I2C_WRITE: + kfree(out.u.i2c_write.bytes); + break; + } + + /* Clear everything but the req_type for the input */ + memset(&in->u, 0, sizeof(in->u)); + + return true; +} + +int igt_dp_mst_sideband_msg_req_decode(void *unused) +{ + struct drm_dp_sideband_msg_req_body in = { 0 }; + u8 data[] = { 0xff, 0x0, 0xdd }; + int i; + +#define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in)) + + in.req_type = DP_ENUM_PATH_RESOURCES; + in.u.port_num.port_number = 5; + DO_TEST(); + + in.req_type = DP_POWER_UP_PHY; + in.u.port_num.port_number = 5; + DO_TEST(); + + in.req_type = DP_POWER_DOWN_PHY; + in.u.port_num.port_number = 5; + DO_TEST(); + + in.req_type = DP_ALLOCATE_PAYLOAD; + in.u.allocate_payload.number_sdp_streams = 3; + for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++) + in.u.allocate_payload.sdp_stream_sink[i] = i + 1; + DO_TEST(); + in.u.allocate_payload.port_number = 0xf; + DO_TEST(); + in.u.allocate_payload.vcpi = 0x7f; + DO_TEST(); + in.u.allocate_payload.pbn = U16_MAX; + DO_TEST(); + + in.req_type = DP_QUERY_PAYLOAD; + in.u.query_payload.port_number = 0xf; + DO_TEST(); + in.u.query_payload.vcpi = 0x7f; + DO_TEST(); + + in.req_type = DP_REMOTE_DPCD_READ; + in.u.dpcd_read.port_number = 0xf; + DO_TEST(); + in.u.dpcd_read.dpcd_address = 0xfedcb; + DO_TEST(); + in.u.dpcd_read.num_bytes = U8_MAX; + DO_TEST(); + + in.req_type = DP_REMOTE_DPCD_WRITE; + in.u.dpcd_write.port_number = 0xf; + DO_TEST(); + in.u.dpcd_write.dpcd_address = 0xfedcb; + DO_TEST(); + in.u.dpcd_write.num_bytes = ARRAY_SIZE(data); + in.u.dpcd_write.bytes = data; + DO_TEST(); + + in.req_type = DP_REMOTE_I2C_READ; + in.u.i2c_read.port_number = 0xf; + DO_TEST(); + in.u.i2c_read.read_i2c_device_id = 0x7f; + DO_TEST(); + in.u.i2c_read.num_transactions = 3; + in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3; + for (i = 0; i < in.u.i2c_read.num_transactions; i++) { + in.u.i2c_read.transactions[i].bytes = data; + in.u.i2c_read.transactions[i].num_bytes = ARRAY_SIZE(data); + in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i; + in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i; + } + DO_TEST(); + + in.req_type = DP_REMOTE_I2C_WRITE; + in.u.i2c_write.port_number = 0xf; + DO_TEST(); + in.u.i2c_write.write_i2c_device_id = 0x7f; + DO_TEST(); + in.u.i2c_write.num_bytes = ARRAY_SIZE(data); + in.u.i2c_write.bytes = data; + DO_TEST(); + +#undef DO_TEST + return 0; +} diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 590bda35a683..0fcb8bbc6a1b 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -40,5 +40,6 @@ int igt_damage_iter_damage_one_outside(void *ignored); int igt_damage_iter_damage_src_moved(void *ignored); int igt_damage_iter_damage_not_visible(void *ignored); int igt_dp_mst_calc_pbn_mode(void *ignored); +int igt_dp_mst_sideband_msg_req_decode(void *ignored); #endif diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 4a4507fe928d..5423a8adda78 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -293,7 +293,7 @@ struct drm_dp_remote_dpcd_write { struct drm_dp_remote_i2c_read { u8 num_transactions; u8 port_number; - struct { + struct drm_dp_remote_i2c_read_tx { u8 i2c_dev_id; u8 num_bytes; u8 *bytes; -- 2.21.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lyude Paul Subject: [PATCH v2 07/27] drm/dp_mst: Add sideband down request tracing + selftests Date: Tue, 3 Sep 2019 16:45:45 -0400 Message-ID: <20190903204645.25487-8-lyude@redhat.com> References: <20190903204645.25487-1-lyude@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20190903204645.25487-1-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: nouveau-bounces-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Sender: "Nouveau" To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Cc: Sean Paul , Thomas Hellstrom , David Airlie , Imre Deak , Alexandru Gheorghe , Maarten Lankhorst , linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Maxime Ripard , Juston Li , Daniel Vetter , Deepak Rawat , Harry Wentland , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= List-Id: nouveau.vger.kernel.org VW5mb3J0dW5hdGVseSB0aGUgRFAgTVNUIGhlbHBlcnMgZG8gbm90IGhhdmUgbXVjaCBpbiB0aGUg d2F5IG9mCmRlYnVnZ2luZyB1dGlsaXRpZXMuIFNvLCBsZXQncyBhZGQgc29tZSEKClRoaXMgYWRk cyBiYXNpYyBkZWJ1Z2dpbmcgb3V0cHV0IGZvciBkb3duIHNpZGViYW5kIHJlcXVlc3RzIHRoYXQg d2Ugc2VuZApmcm9tIHRoZSBkcml2ZXIsIHNvIHRoYXQgd2UgY2FuIGFjdHVhbGx5IGRpc2Nlcm4g d2hhdCdzIGhhcHBlbmluZyB3aGVuCnNpZGViYW5kIHJlcXVlc3RzIHRpbWVvdXQuCgpTaW5jZSB0 aGVyZSB3YXNuJ3QgcmVhbGx5IGEgZ29vZCB3YXkgb2YgdGVzdGluZyB0aGF0IGFueSBvZiB0aGlz IHdvcmtlZCwKSSBlbmRlZCB1cCB3cml0aW5nIHNpbXBsZSBzZWxmdGVzdHMgdGhhdCBsaWdodGx5 IHRlc3Qgc2lkZWJhbmQgbWVzc2FnZQplbmNvZGluZyBhbmQgZGVjb2RpbmcgYXMgd2VsbC4gRW5q b3khCgpDaGFuZ2VzIHNpbmNlIHYxOgoqIENsZWFuIHVwIERPX1RFU1QoKSBhbmQgc2lkZWJhbmRf bXNnX3JlcV9lbmNvZGVfZGVjb2RlKCkgLSBkYW52ZXQKKiBHZXQgcmlkIG9mIHByX2ZtdCgpLCBq dXN0IGRlZmluZSBhIHByZWZpeCBzdHJpbmcgaW5zdGVhZCBhbmQgdXNlCiAgZHJtX3ByaW50Zigp CiogQ2hlY2sgaGlnaGVzdCBiaXQgb2YgVkNQSSBpbiBkcm1fZHBfZGVjb2RlX3NpZGViYW5kX3Jl cSgpIC0gZGFudmV0CiogTWFrZSB0aGUgc3dpdGNoIGNhc2Ugb3JkZXIgYmV0d2VlbiBkcm1fZHBf ZGVjb2RlX3NpZGViYW5kX3JlcSgpIGFuZAogIGRybV9kcF9lbmNvZGVfc2lkZWJhbmRfcmVxKCkg dGhlIHNhbWUgLSBkYW52ZXQKKiBPbmx5IGNoZWNrIERSTV9VVF9EUCAtIGRhbnZldAoqIENsZWFu IHVwIHNpZGViYW5kX21zZ19yZXFfZXF1YWwoKSBmcm9tIHNlbGZ0ZXN0cyBhIGJpdCwgYW5kIGFk ZAogIGNvbW1lbnRzIGV4cGxhaW5pbmcgd2h5IHdlIGNhbid0IGp1c3QgdXNlIG1lbWNtcCAtIGRh bnZldAoKQ2M6IEp1c3RvbiBMaSA8anVzdG9uLmxpQGludGVsLmNvbT4KQ2M6IEltcmUgRGVhayA8 aW1yZS5kZWFrQGludGVsLmNvbT4KQ2M6IFZpbGxlIFN5cmrDpGzDpCA8dmlsbGUuc3lyamFsYUBs aW51eC5pbnRlbC5jb20+CkNjOiBIYXJyeSBXZW50bGFuZCA8aHdlbnRsYW5AYW1kLmNvbT4KUmV2 aWV3ZWQtYnk6IERhbmllbCBWZXR0ZXIgPGRhbmllbC52ZXR0ZXJAZmZ3bGwuY2g+ClNpZ25lZC1v ZmYtYnk6IEx5dWRlIFBhdWwgPGx5dWRlQHJlZGhhdC5jb20+Ci0tLQogZHJpdmVycy9ncHUvZHJt L2RybV9kcF9tc3RfdG9wb2xvZ3kuYyAgICAgICAgIHwgMzA5ICsrKysrKysrKysrKysrKysrLQog Li4uL2dwdS9kcm0vZHJtX2RwX21zdF90b3BvbG9neV9pbnRlcm5hbC5oICAgIHwgIDI0ICsrCiAu Li4vZ3B1L2RybS9zZWxmdGVzdHMvZHJtX21vZGVzZXRfc2VsZnRlc3RzLmggfCAgIDEgKwogLi4u L2RybS9zZWxmdGVzdHMvdGVzdC1kcm1fZHBfbXN0X2hlbHBlci5jICAgIHwgMjA0ICsrKysrKysr KysrKwogLi4uL2RybS9zZWxmdGVzdHMvdGVzdC1kcm1fbW9kZXNldF9jb21tb24uaCAgIHwgICAx ICsKIGluY2x1ZGUvZHJtL2RybV9kcF9tc3RfaGVscGVyLmggICAgICAgICAgICAgICB8ICAgMiAr LQogNiBmaWxlcyBjaGFuZ2VkLCA1MzYgaW5zZXJ0aW9ucygrKSwgNSBkZWxldGlvbnMoLSkKIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vZHJtX2RwX21zdF90b3BvbG9neV9pbnRl cm5hbC5oCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2RybV9kcF9tc3RfdG9wb2xvZ3ku YyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fZHBfbXN0X3RvcG9sb2d5LmMKaW5kZXggMWM4NjI3NDlj YjYzLi5mNWYxZDhiNTBmYjYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fZHBfbXN0 X3RvcG9sb2d5LmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2RybV9kcF9tc3RfdG9wb2xvZ3kuYwpA QCAtMzcsNiArMzcsNyBAQAogI2luY2x1ZGUgPGRybS9kcm1fcHJvYmVfaGVscGVyLmg+CiAKICNp bmNsdWRlICJkcm1fY3J0Y19oZWxwZXJfaW50ZXJuYWwuaCIKKyNpbmNsdWRlICJkcm1fZHBfbXN0 X3RvcG9sb2d5X2ludGVybmFsLmgiCiAKIC8qKgogICogRE9DOiBkcCBtc3QgaGVscGVyCkBAIC03 Myw2ICs3NCw4IEBAIHN0YXRpYyBpbnQgZHJtX2RwX21zdF9yZWdpc3Rlcl9pMmNfYnVzKHN0cnVj dCBkcm1fZHBfYXV4ICphdXgpOwogc3RhdGljIHZvaWQgZHJtX2RwX21zdF91bnJlZ2lzdGVyX2ky Y19idXMoc3RydWN0IGRybV9kcF9hdXggKmF1eCk7CiBzdGF0aWMgdm9pZCBkcm1fZHBfbXN0X2tp Y2tfdHgoc3RydWN0IGRybV9kcF9tc3RfdG9wb2xvZ3lfbWdyICptZ3IpOwogCisjZGVmaW5lIERC R19QUkVGSVggIltkcF9tc3RdIgorCiAjZGVmaW5lIERQX1NUUih4KSBbRFBfICMjIHhdID0gI3gK IAogc3RhdGljIGNvbnN0IGNoYXIgKmRybV9kcF9tc3RfcmVxX3R5cGVfc3RyKHU4IHJlcV90eXBl KQpAQCAtMTI5LDYgKzEzMiw0MyBAQCBzdGF0aWMgY29uc3QgY2hhciAqZHJtX2RwX21zdF9uYWtf cmVhc29uX3N0cih1OCBuYWtfcmVhc29uKQogfQogCiAjdW5kZWYgRFBfU1RSCisjZGVmaW5lIERQ X1NUUih4KSBbRFJNX0RQX1NJREVCQU5EX1RYXyAjIyB4XSA9ICN4CisKK3N0YXRpYyBjb25zdCBj aGFyICpkcm1fZHBfbXN0X3NpZGViYW5kX3R4X3N0YXRlX3N0cihpbnQgc3RhdGUpCit7CisJc3Rh dGljIGNvbnN0IGNoYXIgKiBjb25zdCBzaWRlYmFuZF9yZWFzb25fc3RyW10gPSB7CisJCURQX1NU UihRVUVVRUQpLAorCQlEUF9TVFIoU1RBUlRfU0VORCksCisJCURQX1NUUihTRU5UKSwKKwkJRFBf U1RSKFJYKSwKKwkJRFBfU1RSKFRJTUVPVVQpLAorCX07CisKKwlpZiAoc3RhdGUgPj0gQVJSQVlf U0laRShzaWRlYmFuZF9yZWFzb25fc3RyKSB8fAorCSAgICAhc2lkZWJhbmRfcmVhc29uX3N0cltz dGF0ZV0pCisJCXJldHVybiAidW5rbm93biI7CisKKwlyZXR1cm4gc2lkZWJhbmRfcmVhc29uX3N0 cltzdGF0ZV07Cit9CisKK3N0YXRpYyBpbnQKK2RybV9kcF9tc3RfcmFkX3RvX3N0cihjb25zdCB1 OCByYWRbOF0sIHU4IGxjdCwgY2hhciAqb3V0LCBzaXplX3QgbGVuKQoreworCWludCBpOworCXU4 IHVucGFja2VkX3JhZFsxNl07CisKKwlmb3IgKGkgPSAwOyBpIDwgbGN0OyBpKyspIHsKKwkJaWYg KGkgJSAyKQorCQkJdW5wYWNrZWRfcmFkW2ldID0gcmFkW2kgLyAyXSA+PiA0OworCQllbHNlCisJ CQl1bnBhY2tlZF9yYWRbaV0gPSByYWRbaSAvIDJdICYgQklUX01BU0soNCk7CisJfQorCisJLyog VE9ETzogRXZlbnR1YWxseSBhZGQgc29tZXRoaW5nIHRvIHByaW50ayBzbyB3ZSBjYW4gZm9ybWF0 IHRoZSByYWQKKwkgKiBsaWtlIHRoaXM6IDEuMi4zCisJICovCisJcmV0dXJuIHNucHJpbnRmKG91 dCwgbGVuLCAiJSpwaEMiLCBsY3QsIHVucGFja2VkX3JhZCk7Cit9CiAKIC8qIHNpZGViYW5kIG1z ZyBoYW5kbGluZyAqLwogc3RhdGljIHU4IGRybV9kcF9tc2dfaGVhZGVyX2NyYzQoY29uc3QgdWlu dDhfdCAqZGF0YSwgc2l6ZV90IG51bV9uaWJibGVzKQpAQCAtMjYxLDggKzMwMSw5IEBAIHN0YXRp YyBib29sIGRybV9kcF9kZWNvZGVfc2lkZWJhbmRfbXNnX2hkcihzdHJ1Y3QgZHJtX2RwX3NpZGVi YW5kX21zZ19oZHIgKmhkciwKIAlyZXR1cm4gdHJ1ZTsKIH0KIAotc3RhdGljIHZvaWQgZHJtX2Rw X2VuY29kZV9zaWRlYmFuZF9yZXEoc3RydWN0IGRybV9kcF9zaWRlYmFuZF9tc2dfcmVxX2JvZHkg KnJlcSwKLQkJCQkgICAgICAgc3RydWN0IGRybV9kcF9zaWRlYmFuZF9tc2dfdHggKnJhdykKK3Zv aWQKK2RybV9kcF9lbmNvZGVfc2lkZWJhbmRfcmVxKGNvbnN0IHN0cnVjdCBkcm1fZHBfc2lkZWJh bmRfbXNnX3JlcV9ib2R5ICpyZXEsCisJCQkgICBzdHJ1Y3QgZHJtX2RwX3NpZGViYW5kX21zZ190 eCAqcmF3KQogewogCWludCBpZHggPSAwOwogCWludCBpOwpAQCAtMzYzLDYgKzQwNCwyNTEgQEAg c3RhdGljIHZvaWQgZHJtX2RwX2VuY29kZV9zaWRlYmFuZF9yZXEoc3RydWN0IGRybV9kcF9zaWRl YmFuZF9tc2dfcmVxX2JvZHkgKnJlcSwKIAl9CiAJcmF3LT5jdXJfbGVuID0gaWR4OwogfQorRVhQ T1JUX1NZTUJPTF9GT1JfVEVTVFNfT05MWShkcm1fZHBfZW5jb2RlX3NpZGViYW5kX3JlcSk7CisK Ky8qIERlY29kZSBhIHNpZGViYW5kIHJlcXVlc3Qgd2UndmUgZW5jb2RlZCwgbWFpbmx5IHVzZWQg Zm9yIGRlYnVnZ2luZyAqLworaW50Citkcm1fZHBfZGVjb2RlX3NpZGViYW5kX3JlcShjb25zdCBz dHJ1Y3QgZHJtX2RwX3NpZGViYW5kX21zZ190eCAqcmF3LAorCQkJICAgc3RydWN0IGRybV9kcF9z aWRlYmFuZF9tc2dfcmVxX2JvZHkgKnJlcSkKK3sKKwljb25zdCB1OCAqYnVmID0gcmF3LT5tc2c7 CisJaW50IGksIGlkeCA9IDA7CisKKwlyZXEtPnJlcV90eXBlID0gYnVmW2lkeCsrXSAmIDB4N2Y7 CisJc3dpdGNoIChyZXEtPnJlcV90eXBlKSB7CisJY2FzZSBEUF9FTlVNX1BBVEhfUkVTT1VSQ0VT OgorCWNhc2UgRFBfUE9XRVJfRE9XTl9QSFk6CisJY2FzZSBEUF9QT1dFUl9VUF9QSFk6CisJCXJl cS0+dS5wb3J0X251bS5wb3J0X251bWJlciA9IChidWZbaWR4XSA+PiA0KSAmIDB4ZjsKKwkJYnJl YWs7CisJY2FzZSBEUF9BTExPQ0FURV9QQVlMT0FEOgorCQl7CisJCQlzdHJ1Y3QgZHJtX2RwX2Fs bG9jYXRlX3BheWxvYWQgKmEgPQorCQkJCSZyZXEtPnUuYWxsb2NhdGVfcGF5bG9hZDsKKworCQkJ YS0+bnVtYmVyX3NkcF9zdHJlYW1zID0gYnVmW2lkeF0gJiAweGY7CisJCQlhLT5wb3J0X251bWJl ciA9IChidWZbaWR4XSA+PiA0KSAmIDB4ZjsKKworCQkJV0FSTl9PTihidWZbKytpZHhdICYgMHg4 MCk7CisJCQlhLT52Y3BpID0gYnVmW2lkeF0gJiAweDdmOworCisJCQlhLT5wYm4gPSBidWZbKytp ZHhdIDw8IDg7CisJCQlhLT5wYm4gfD0gYnVmWysraWR4XTsKKworCQkJaWR4Kys7CisJCQlmb3Ig KGkgPSAwOyBpIDwgYS0+bnVtYmVyX3NkcF9zdHJlYW1zOyBpKyspIHsKKwkJCQlhLT5zZHBfc3Ry ZWFtX3NpbmtbaV0gPQorCQkJCQkoYnVmW2lkeCArIChpIC8gMildID4+ICgoaSAlIDIpID8gMCA6 IDQpKSAmIDB4ZjsKKwkJCX0KKwkJfQorCQlicmVhazsKKwljYXNlIERQX1FVRVJZX1BBWUxPQUQ6 CisJCXJlcS0+dS5xdWVyeV9wYXlsb2FkLnBvcnRfbnVtYmVyID0gKGJ1ZltpZHhdID4+IDQpICYg MHhmOworCQlXQVJOX09OKGJ1ZlsrK2lkeF0gJiAweDgwKTsKKwkJcmVxLT51LnF1ZXJ5X3BheWxv YWQudmNwaSA9IGJ1ZltpZHhdICYgMHg3ZjsKKwkJYnJlYWs7CisJY2FzZSBEUF9SRU1PVEVfRFBD RF9SRUFEOgorCQl7CisJCQlzdHJ1Y3QgZHJtX2RwX3JlbW90ZV9kcGNkX3JlYWQgKnIgPSAmcmVx LT51LmRwY2RfcmVhZDsKKworCQkJci0+cG9ydF9udW1iZXIgPSAoYnVmW2lkeF0gPj4gNCkgJiAw eGY7CisKKwkJCXItPmRwY2RfYWRkcmVzcyA9IChidWZbaWR4XSA8PCAxNikgJiAweGYwMDAwOwor CQkJci0+ZHBjZF9hZGRyZXNzIHw9IChidWZbKytpZHhdIDw8IDgpICYgMHhmZjAwOworCQkJci0+ ZHBjZF9hZGRyZXNzIHw9IGJ1ZlsrK2lkeF0gJiAweGZmOworCisJCQlyLT5udW1fYnl0ZXMgPSBi dWZbKytpZHhdOworCQl9CisJCWJyZWFrOworCWNhc2UgRFBfUkVNT1RFX0RQQ0RfV1JJVEU6CisJ CXsKKwkJCXN0cnVjdCBkcm1fZHBfcmVtb3RlX2RwY2Rfd3JpdGUgKncgPQorCQkJCSZyZXEtPnUu ZHBjZF93cml0ZTsKKworCQkJdy0+cG9ydF9udW1iZXIgPSAoYnVmW2lkeF0gPj4gNCkgJiAweGY7 CisKKwkJCXctPmRwY2RfYWRkcmVzcyA9IChidWZbaWR4XSA8PCAxNikgJiAweGYwMDAwOworCQkJ dy0+ZHBjZF9hZGRyZXNzIHw9IChidWZbKytpZHhdIDw8IDgpICYgMHhmZjAwOworCQkJdy0+ZHBj ZF9hZGRyZXNzIHw9IGJ1ZlsrK2lkeF0gJiAweGZmOworCisJCQl3LT5udW1fYnl0ZXMgPSBidWZb KytpZHhdOworCisJCQl3LT5ieXRlcyA9IGttZW1kdXAoJmJ1ZlsrK2lkeF0sIHctPm51bV9ieXRl cywKKwkJCQkJICAgR0ZQX0tFUk5FTCk7CisJCQlpZiAoIXctPmJ5dGVzKQorCQkJCXJldHVybiAt RU5PTUVNOworCQl9CisJCWJyZWFrOworCWNhc2UgRFBfUkVNT1RFX0kyQ19SRUFEOgorCQl7CisJ CQlzdHJ1Y3QgZHJtX2RwX3JlbW90ZV9pMmNfcmVhZCAqciA9ICZyZXEtPnUuaTJjX3JlYWQ7CisJ CQlzdHJ1Y3QgZHJtX2RwX3JlbW90ZV9pMmNfcmVhZF90eCAqdHg7CisJCQlib29sIGZhaWxlZCA9 IGZhbHNlOworCisJCQlyLT5udW1fdHJhbnNhY3Rpb25zID0gYnVmW2lkeF0gJiAweDM7CisJCQly LT5wb3J0X251bWJlciA9IChidWZbaWR4XSA+PiA0KSAmIDB4ZjsKKwkJCWZvciAoaSA9IDA7IGkg PCByLT5udW1fdHJhbnNhY3Rpb25zOyBpKyspIHsKKwkJCQl0eCA9ICZyLT50cmFuc2FjdGlvbnNb aV07CisKKwkJCQl0eC0+aTJjX2Rldl9pZCA9IGJ1ZlsrK2lkeF0gJiAweDdmOworCQkJCXR4LT5u dW1fYnl0ZXMgPSBidWZbKytpZHhdOworCQkJCXR4LT5ieXRlcyA9IGttZW1kdXAoJmJ1ZlsrK2lk eF0sCisJCQkJCQkgICAgdHgtPm51bV9ieXRlcywKKwkJCQkJCSAgICBHRlBfS0VSTkVMKTsKKwkJ CQlpZiAoIXR4LT5ieXRlcykgeworCQkJCQlmYWlsZWQgPSB0cnVlOworCQkJCQlicmVhazsKKwkJ CQl9CisJCQkJaWR4ICs9IHR4LT5udW1fYnl0ZXM7CisJCQkJdHgtPm5vX3N0b3BfYml0ID0gKGJ1 ZltpZHhdID4+IDUpICYgMHgxOworCQkJCXR4LT5pMmNfdHJhbnNhY3Rpb25fZGVsYXkgPSBidWZb aWR4XSAmIDB4ZjsKKwkJCX0KKworCQkJaWYgKGZhaWxlZCkgeworCQkJCWZvciAoaSA9IDA7IGkg PCByLT5udW1fdHJhbnNhY3Rpb25zOyBpKyspCisJCQkJCWtmcmVlKHR4LT5ieXRlcyk7CisJCQkJ cmV0dXJuIC1FTk9NRU07CisJCQl9CisKKwkJCXItPnJlYWRfaTJjX2RldmljZV9pZCA9IGJ1Zlsr K2lkeF0gJiAweDdmOworCQkJci0+bnVtX2J5dGVzX3JlYWQgPSBidWZbKytpZHhdOworCQl9CisJ CWJyZWFrOworCWNhc2UgRFBfUkVNT1RFX0kyQ19XUklURToKKwkJeworCQkJc3RydWN0IGRybV9k cF9yZW1vdGVfaTJjX3dyaXRlICp3ID0gJnJlcS0+dS5pMmNfd3JpdGU7CisKKwkJCXctPnBvcnRf bnVtYmVyID0gKGJ1ZltpZHhdID4+IDQpICYgMHhmOworCQkJdy0+d3JpdGVfaTJjX2RldmljZV9p ZCA9IGJ1ZlsrK2lkeF0gJiAweDdmOworCQkJdy0+bnVtX2J5dGVzID0gYnVmWysraWR4XTsKKwkJ CXctPmJ5dGVzID0ga21lbWR1cCgmYnVmWysraWR4XSwgdy0+bnVtX2J5dGVzLAorCQkJCQkgICBH RlBfS0VSTkVMKTsKKwkJCWlmICghdy0+Ynl0ZXMpCisJCQkJcmV0dXJuIC1FTk9NRU07CisJCX0K KwkJYnJlYWs7CisJfQorCisJcmV0dXJuIDA7Cit9CitFWFBPUlRfU1lNQk9MX0ZPUl9URVNUU19P TkxZKGRybV9kcF9kZWNvZGVfc2lkZWJhbmRfcmVxKTsKKwordm9pZAorZHJtX2RwX2R1bXBfc2lk ZWJhbmRfbXNnX3JlcV9ib2R5KGNvbnN0IHN0cnVjdCBkcm1fZHBfc2lkZWJhbmRfbXNnX3JlcV9i b2R5ICpyZXEsCisJCQkJICBpbnQgaW5kZW50LCBzdHJ1Y3QgZHJtX3ByaW50ZXIgKnByaW50ZXIp Cit7CisJaW50IGk7CisKKyNkZWZpbmUgUChmLCAuLi4pIGRybV9wcmludGZfaW5kZW50KHByaW50 ZXIsIGluZGVudCwgZiwgIyNfX1ZBX0FSR1NfXykKKwlpZiAocmVxLT5yZXFfdHlwZSA9PSBEUF9M SU5LX0FERFJFU1MpIHsKKwkJLyogTm8gY29udGVudHMgdG8gcHJpbnQgKi8KKwkJUCgidHlwZT0l c1xuIiwgZHJtX2RwX21zdF9yZXFfdHlwZV9zdHIocmVxLT5yZXFfdHlwZSkpOworCQlyZXR1cm47 CisJfQorCisJUCgidHlwZT0lcyBjb250ZW50czpcbiIsIGRybV9kcF9tc3RfcmVxX3R5cGVfc3Ry KHJlcS0+cmVxX3R5cGUpKTsKKwlpbmRlbnQrKzsKKworCXN3aXRjaCAocmVxLT5yZXFfdHlwZSkg eworCWNhc2UgRFBfRU5VTV9QQVRIX1JFU09VUkNFUzoKKwljYXNlIERQX1BPV0VSX0RPV05fUEhZ OgorCWNhc2UgRFBfUE9XRVJfVVBfUEhZOgorCQlQKCJwb3J0PSVkXG4iLCByZXEtPnUucG9ydF9u dW0ucG9ydF9udW1iZXIpOworCQlicmVhazsKKwljYXNlIERQX0FMTE9DQVRFX1BBWUxPQUQ6CisJ CVAoInBvcnQ9JWQgdmNwaT0lZCBwYm49JWQgc2RwX3N0cmVhbXM9JWQgJSpwaFxuIiwKKwkJICBy ZXEtPnUuYWxsb2NhdGVfcGF5bG9hZC5wb3J0X251bWJlciwKKwkJICByZXEtPnUuYWxsb2NhdGVf cGF5bG9hZC52Y3BpLCByZXEtPnUuYWxsb2NhdGVfcGF5bG9hZC5wYm4sCisJCSAgcmVxLT51LmFs bG9jYXRlX3BheWxvYWQubnVtYmVyX3NkcF9zdHJlYW1zLAorCQkgIHJlcS0+dS5hbGxvY2F0ZV9w YXlsb2FkLm51bWJlcl9zZHBfc3RyZWFtcywKKwkJICByZXEtPnUuYWxsb2NhdGVfcGF5bG9hZC5z ZHBfc3RyZWFtX3NpbmspOworCQlicmVhazsKKwljYXNlIERQX1FVRVJZX1BBWUxPQUQ6CisJCVAo InBvcnQ9JWQgdmNwaT0lZFxuIiwKKwkJICByZXEtPnUucXVlcnlfcGF5bG9hZC5wb3J0X251bWJl ciwKKwkJICByZXEtPnUucXVlcnlfcGF5bG9hZC52Y3BpKTsKKwkJYnJlYWs7CisJY2FzZSBEUF9S RU1PVEVfRFBDRF9SRUFEOgorCQlQKCJwb3J0PSVkIGRwY2RfYWRkcj0lMDV4IGxlbj0lZFxuIiwK KwkJICByZXEtPnUuZHBjZF9yZWFkLnBvcnRfbnVtYmVyLCByZXEtPnUuZHBjZF9yZWFkLmRwY2Rf YWRkcmVzcywKKwkJICByZXEtPnUuZHBjZF9yZWFkLm51bV9ieXRlcyk7CisJCWJyZWFrOworCWNh c2UgRFBfUkVNT1RFX0RQQ0RfV1JJVEU6CisJCVAoInBvcnQ9JWQgYWRkcj0lMDV4IGxlbj0lZDog JSpwaFxuIiwKKwkJICByZXEtPnUuZHBjZF93cml0ZS5wb3J0X251bWJlciwKKwkJICByZXEtPnUu ZHBjZF93cml0ZS5kcGNkX2FkZHJlc3MsCisJCSAgcmVxLT51LmRwY2Rfd3JpdGUubnVtX2J5dGVz LCByZXEtPnUuZHBjZF93cml0ZS5udW1fYnl0ZXMsCisJCSAgcmVxLT51LmRwY2Rfd3JpdGUuYnl0 ZXMpOworCQlicmVhazsKKwljYXNlIERQX1JFTU9URV9JMkNfUkVBRDoKKwkJUCgicG9ydD0lZCBu dW1fdHg9JWQgaWQ9JWQgc2l6ZT0lZDpcbiIsCisJCSAgcmVxLT51LmkyY19yZWFkLnBvcnRfbnVt YmVyLAorCQkgIHJlcS0+dS5pMmNfcmVhZC5udW1fdHJhbnNhY3Rpb25zLAorCQkgIHJlcS0+dS5p MmNfcmVhZC5yZWFkX2kyY19kZXZpY2VfaWQsCisJCSAgcmVxLT51LmkyY19yZWFkLm51bV9ieXRl c19yZWFkKTsKKworCQlpbmRlbnQrKzsKKwkJZm9yIChpID0gMDsgaSA8IHJlcS0+dS5pMmNfcmVh ZC5udW1fdHJhbnNhY3Rpb25zOyBpKyspIHsKKwkJCWNvbnN0IHN0cnVjdCBkcm1fZHBfcmVtb3Rl X2kyY19yZWFkX3R4ICpydHggPQorCQkJCSZyZXEtPnUuaTJjX3JlYWQudHJhbnNhY3Rpb25zW2ld OworCisJCQlQKCIlZDogaWQ9JTAzZCBzaXplPSUwM2Qgbm9fc3RvcF9iaXQ9JWQgdHhfZGVsYXk9 JTAzZDogJSpwaFxuIiwKKwkJCSAgaSwgcnR4LT5pMmNfZGV2X2lkLCBydHgtPm51bV9ieXRlcywK KwkJCSAgcnR4LT5ub19zdG9wX2JpdCwgcnR4LT5pMmNfdHJhbnNhY3Rpb25fZGVsYXksCisJCQkg IHJ0eC0+bnVtX2J5dGVzLCBydHgtPmJ5dGVzKTsKKwkJfQorCQlicmVhazsKKwljYXNlIERQX1JF TU9URV9JMkNfV1JJVEU6CisJCVAoInBvcnQ9JWQgaWQ9JWQgc2l6ZT0lZDogJSpwaFxuIiwKKwkJ ICByZXEtPnUuaTJjX3dyaXRlLnBvcnRfbnVtYmVyLAorCQkgIHJlcS0+dS5pMmNfd3JpdGUud3Jp dGVfaTJjX2RldmljZV9pZCwKKwkJICByZXEtPnUuaTJjX3dyaXRlLm51bV9ieXRlcywgcmVxLT51 LmkyY193cml0ZS5udW1fYnl0ZXMsCisJCSAgcmVxLT51LmkyY193cml0ZS5ieXRlcyk7CisJCWJy ZWFrOworCWRlZmF1bHQ6CisJCVAoIj8/P1xuIik7CisJCWJyZWFrOworCX0KKyN1bmRlZiBQCit9 CitFWFBPUlRfU1lNQk9MX0ZPUl9URVNUU19PTkxZKGRybV9kcF9kdW1wX3NpZGViYW5kX21zZ19y ZXFfYm9keSk7CisKK3N0YXRpYyBpbmxpbmUgdm9pZAorZHJtX2RwX21zdF9kdW1wX3NpZGViYW5k X21zZ190eChzdHJ1Y3QgZHJtX3ByaW50ZXIgKnAsCisJCQkJY29uc3Qgc3RydWN0IGRybV9kcF9z aWRlYmFuZF9tc2dfdHggKnR4bXNnKQoreworCXN0cnVjdCBkcm1fZHBfc2lkZWJhbmRfbXNnX3Jl cV9ib2R5IHJlcTsKKwljaGFyIGJ1Zls2NF07CisJaW50IHJldDsKKwlpbnQgaTsKKworCWRybV9k cF9tc3RfcmFkX3RvX3N0cih0eG1zZy0+ZHN0LT5yYWQsIHR4bXNnLT5kc3QtPmxjdCwgYnVmLAor CQkJICAgICAgc2l6ZW9mKGJ1ZikpOworCWRybV9wcmludGYocCwgInR4bXNnIGN1cl9vZmZzZXQ9 JXggY3VyX2xlbj0leCBzZXFubz0leCBzdGF0ZT0lcyBwYXRoX21zZz0lZCBkc3Q9JXNcbiIsCisJ CSAgIHR4bXNnLT5jdXJfb2Zmc2V0LCB0eG1zZy0+Y3VyX2xlbiwgdHhtc2ctPnNlcW5vLAorCQkg ICBkcm1fZHBfbXN0X3NpZGViYW5kX3R4X3N0YXRlX3N0cih0eG1zZy0+c3RhdGUpLAorCQkgICB0 eG1zZy0+cGF0aF9tc2csIGJ1Zik7CisKKwlyZXQgPSBkcm1fZHBfZGVjb2RlX3NpZGViYW5kX3Jl cSh0eG1zZywgJnJlcSk7CisJaWYgKHJldCkgeworCQlkcm1fcHJpbnRmKHAsICI8ZmFpbGVkIHRv IGRlY29kZSBzaWRlYmFuZCByZXE6ICVkPlxuIiwgcmV0KTsKKwkJcmV0dXJuOworCX0KKwlkcm1f ZHBfZHVtcF9zaWRlYmFuZF9tc2dfcmVxX2JvZHkoJnJlcSwgMSwgcCk7CisKKwlzd2l0Y2ggKHJl cS5yZXFfdHlwZSkgeworCWNhc2UgRFBfUkVNT1RFX0RQQ0RfV1JJVEU6CisJCWtmcmVlKHJlcS51 LmRwY2Rfd3JpdGUuYnl0ZXMpOworCQlicmVhazsKKwljYXNlIERQX1JFTU9URV9JMkNfUkVBRDoK KwkJZm9yIChpID0gMDsgaSA8IHJlcS51LmkyY19yZWFkLm51bV90cmFuc2FjdGlvbnM7IGkrKykK KwkJCWtmcmVlKHJlcS51LmkyY19yZWFkLnRyYW5zYWN0aW9uc1tpXS5ieXRlcyk7CisJCWJyZWFr OworCWNhc2UgRFBfUkVNT1RFX0kyQ19XUklURToKKwkJa2ZyZWUocmVxLnUuaTJjX3dyaXRlLmJ5 dGVzKTsKKwkJYnJlYWs7CisJfQorfQogCiBzdGF0aWMgdm9pZCBkcm1fZHBfY3JjX3NpZGViYW5k X2NodW5rX3JlcSh1OCAqbXNnLCB1OCBsZW4pCiB7CkBAIC04OTQsNiArMTE4MCwxMSBAQCBzdGF0 aWMgaW50IGRybV9kcF9tc3Rfd2FpdF90eF9yZXBseShzdHJ1Y3QgZHJtX2RwX21zdF9icmFuY2gg Km1zdGIsCiAJCX0KIAl9CiBvdXQ6CisJaWYgKHVubGlrZWx5KHJldCA9PSAtRUlPICYmIGRybV9k ZWJ1ZyAmIERSTV9VVF9EUCkpIHsKKwkJc3RydWN0IGRybV9wcmludGVyIHAgPSBkcm1fZGVidWdf cHJpbnRlcihEQkdfUFJFRklYKTsKKworCQlkcm1fZHBfbXN0X2R1bXBfc2lkZWJhbmRfbXNnX3R4 KCZwLCB0eG1zZyk7CisJfQogCW11dGV4X3VubG9jaygmbWdyLT5xbG9jayk7CiAKIAlyZXR1cm4g cmV0OwpAQCAtMjAxMyw4ICsyMzA0LDExIEBAIHN0YXRpYyBpbnQgcHJvY2Vzc19zaW5nbGVfdHhf cWxvY2soc3RydWN0IGRybV9kcF9tc3RfdG9wb2xvZ3lfbWdyICptZ3IsCiAJaWR4ICs9IHRvc2Vu ZCArIDE7CiAKIAlyZXQgPSBkcm1fZHBfc2VuZF9zaWRlYmFuZF9tc2cobWdyLCB1cCwgY2h1bmss IGlkeCk7Ci0JaWYgKHJldCkgewotCQlEUk1fREVCVUdfS01TKCJzaWRlYmFuZCBtc2cgZmFpbGVk IHRvIHNlbmRcbiIpOworCWlmICh1bmxpa2VseShyZXQgJiYgZHJtX2RlYnVnICYgRFJNX1VUX0RQ KSkgeworCQlzdHJ1Y3QgZHJtX3ByaW50ZXIgcCA9IGRybV9kZWJ1Z19wcmludGVyKERCR19QUkVG SVgpOworCisJCWRybV9wcmludGYoJnAsICJzaWRlYmFuZCBtc2cgZmFpbGVkIHRvIHNlbmRcbiIp OworCQlkcm1fZHBfbXN0X2R1bXBfc2lkZWJhbmRfbXNnX3R4KCZwLCB0eG1zZyk7CiAJCXJldHVy biByZXQ7CiAJfQogCkBAIC0yMDc2LDYgKzIzNzAsMTMgQEAgc3RhdGljIHZvaWQgZHJtX2RwX3F1 ZXVlX2Rvd25fdHgoc3RydWN0IGRybV9kcF9tc3RfdG9wb2xvZ3lfbWdyICptZ3IsCiB7CiAJbXV0 ZXhfbG9jaygmbWdyLT5xbG9jayk7CiAJbGlzdF9hZGRfdGFpbCgmdHhtc2ctPm5leHQsICZtZ3It PnR4X21zZ19kb3ducSk7CisKKwlpZiAodW5saWtlbHkoZHJtX2RlYnVnICYgRFJNX1VUX0RQKSkg eworCQlzdHJ1Y3QgZHJtX3ByaW50ZXIgcCA9IGRybV9kZWJ1Z19wcmludGVyKERCR19QUkVGSVgp OworCisJCWRybV9kcF9tc3RfZHVtcF9zaWRlYmFuZF9tc2dfdHgoJnAsIHR4bXNnKTsKKwl9CisK IAlpZiAobGlzdF9pc19zaW5ndWxhcigmbWdyLT50eF9tc2dfZG93bnEpKQogCQlwcm9jZXNzX3Np bmdsZV9kb3duX3R4X3Fsb2NrKG1ncik7CiAJbXV0ZXhfdW5sb2NrKCZtZ3ItPnFsb2NrKTsKZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fZHBfbXN0X3RvcG9sb2d5X2ludGVybmFsLmgg Yi9kcml2ZXJzL2dwdS9kcm0vZHJtX2RwX21zdF90b3BvbG9neV9pbnRlcm5hbC5oCm5ldyBmaWxl IG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uZWVkYTlhNjFjNjU3Ci0tLSAvZGV2L251 bGwKKysrIGIvZHJpdmVycy9ncHUvZHJtL2RybV9kcF9tc3RfdG9wb2xvZ3lfaW50ZXJuYWwuaApA QCAtMCwwICsxLDI0IEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5 CisgKgorICogRGVjbGFyYXRpb25zIGZvciBEUCBNU1QgcmVsYXRlZCBmdW5jdGlvbnMgd2hpY2gg YXJlIG9ubHkgdXNlZCBpbiBzZWxmdGVzdHMKKyAqCisgKiBDb3B5cmlnaHQgwqkgMjAxOCBSZWQg SGF0CisgKiBBdXRob3JzOgorICogICAgIEx5dWRlIFBhdWwgPGx5dWRlQHJlZGhhdC5jb20+Cisg Ki8KKworI2lmbmRlZiBfRFJNX0RQX01TVF9IRUxQRVJfSU5URVJOQUxfSF8KKyNkZWZpbmUgX0RS TV9EUF9NU1RfSEVMUEVSX0lOVEVSTkFMX0hfCisKKyNpbmNsdWRlIDxkcm0vZHJtX2RwX21zdF9o ZWxwZXIuaD4KKwordm9pZAorZHJtX2RwX2VuY29kZV9zaWRlYmFuZF9yZXEoY29uc3Qgc3RydWN0 IGRybV9kcF9zaWRlYmFuZF9tc2dfcmVxX2JvZHkgKnJlcSwKKwkJCSAgIHN0cnVjdCBkcm1fZHBf c2lkZWJhbmRfbXNnX3R4ICpyYXcpOworaW50IGRybV9kcF9kZWNvZGVfc2lkZWJhbmRfcmVxKGNv bnN0IHN0cnVjdCBkcm1fZHBfc2lkZWJhbmRfbXNnX3R4ICpyYXcsCisJCQkgICAgICAgc3RydWN0 IGRybV9kcF9zaWRlYmFuZF9tc2dfcmVxX2JvZHkgKnJlcSk7Cit2b2lkCitkcm1fZHBfZHVtcF9z aWRlYmFuZF9tc2dfcmVxX2JvZHkoY29uc3Qgc3RydWN0IGRybV9kcF9zaWRlYmFuZF9tc2dfcmVx X2JvZHkgKnJlcSwKKwkJCQkgIGludCBpbmRlbnQsIHN0cnVjdCBkcm1fcHJpbnRlciAqcHJpbnRl cik7CisKKyNlbmRpZiAvKiAhX0RSTV9EUF9NU1RfSEVMUEVSX0lOVEVSTkFMX0hfICovCmRpZmYg LS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vc2VsZnRlc3RzL2RybV9tb2Rlc2V0X3NlbGZ0ZXN0cy5o IGIvZHJpdmVycy9ncHUvZHJtL3NlbGZ0ZXN0cy9kcm1fbW9kZXNldF9zZWxmdGVzdHMuaAppbmRl eCBkZWMzZWUzZWM5NmYuLjE4OThkZTBiNGE0ZCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJt L3NlbGZ0ZXN0cy9kcm1fbW9kZXNldF9zZWxmdGVzdHMuaAorKysgYi9kcml2ZXJzL2dwdS9kcm0v c2VsZnRlc3RzL2RybV9tb2Rlc2V0X3NlbGZ0ZXN0cy5oCkBAIC0zMywzICszMyw0IEBAIHNlbGZ0 ZXN0KGRhbWFnZV9pdGVyX2RhbWFnZV9vbmVfb3V0c2lkZSwgaWd0X2RhbWFnZV9pdGVyX2RhbWFn ZV9vbmVfb3V0c2lkZSkKIHNlbGZ0ZXN0KGRhbWFnZV9pdGVyX2RhbWFnZV9zcmNfbW92ZWQsIGln dF9kYW1hZ2VfaXRlcl9kYW1hZ2Vfc3JjX21vdmVkKQogc2VsZnRlc3QoZGFtYWdlX2l0ZXJfZGFt YWdlX25vdF92aXNpYmxlLCBpZ3RfZGFtYWdlX2l0ZXJfZGFtYWdlX25vdF92aXNpYmxlKQogc2Vs ZnRlc3QoZHBfbXN0X2NhbGNfcGJuX21vZGUsIGlndF9kcF9tc3RfY2FsY19wYm5fbW9kZSkKK3Nl bGZ0ZXN0KGRwX21zdF9zaWRlYmFuZF9tc2dfcmVxX2RlY29kZSwgaWd0X2RwX21zdF9zaWRlYmFu ZF9tc2dfcmVxX2RlY29kZSkKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9zZWxmdGVzdHMv dGVzdC1kcm1fZHBfbXN0X2hlbHBlci5jIGIvZHJpdmVycy9ncHUvZHJtL3NlbGZ0ZXN0cy90ZXN0 LWRybV9kcF9tc3RfaGVscGVyLmMKaW5kZXggOWJhYTUxNzE5ODhkLi5hZjJiMmRlNjUzMTYgMTAw NjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9zZWxmdGVzdHMvdGVzdC1kcm1fZHBfbXN0X2hlbHBl ci5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9zZWxmdGVzdHMvdGVzdC1kcm1fZHBfbXN0X2hlbHBl ci5jCkBAIC0zLDkgKzMsMTIgQEAKICAqIFRlc3QgY2FzZXMgZm9yIGZvciB0aGUgRFJNIERQIE1T VCBoZWxwZXJzCiAgKi8KIAorI2RlZmluZSBQUkVGSVhfU1RSICJbZHJtX2RwX21zdF9oZWxwZXJd IgorCiAjaW5jbHVkZSA8ZHJtL2RybV9kcF9tc3RfaGVscGVyLmg+CiAjaW5jbHVkZSA8ZHJtL2Ry bV9wcmludC5oPgogCisjaW5jbHVkZSAiLi4vZHJtX2RwX21zdF90b3BvbG9neV9pbnRlcm5hbC5o IgogI2luY2x1ZGUgInRlc3QtZHJtX21vZGVzZXRfY29tbW9uLmgiCiAKIGludCBpZ3RfZHBfbXN0 X2NhbGNfcGJuX21vZGUodm9pZCAqaWdub3JlZCkKQEAgLTMyLDMgKzM1LDIwNCBAQCBpbnQgaWd0 X2RwX21zdF9jYWxjX3Bibl9tb2RlKHZvaWQgKmlnbm9yZWQpCiAKIAlyZXR1cm4gMDsKIH0KKwor c3RhdGljIGJvb2wKK3NpZGViYW5kX21zZ19yZXFfZXF1YWwoY29uc3Qgc3RydWN0IGRybV9kcF9z aWRlYmFuZF9tc2dfcmVxX2JvZHkgKmluLAorCQkgICAgICAgY29uc3Qgc3RydWN0IGRybV9kcF9z aWRlYmFuZF9tc2dfcmVxX2JvZHkgKm91dCkKK3sKKwljb25zdCBzdHJ1Y3QgZHJtX2RwX3JlbW90 ZV9pMmNfcmVhZF90eCAqdHhpbiwgKnR4b3V0OworCWludCBpOworCisJaWYgKGluLT5yZXFfdHlw ZSAhPSBvdXQtPnJlcV90eXBlKQorCQlyZXR1cm4gZmFsc2U7CisKKwlzd2l0Y2ggKGluLT5yZXFf dHlwZSkgeworCS8qCisJICogQ29tcGFyZSBzdHJ1Y3QgbWVtYmVycyBtYW51YWxseSBmb3IgcmVx dWVzdCB0eXBlcyB3aGljaCBjYW4ndCBiZQorCSAqIGNvbXBhcmVkIHNpbXBseSB1c2luZyBtZW1j bXAoKS4gVGhpcyBpcyBiZWNhdXNlIHNhaWQgcmVxdWVzdCB0eXBlcworCSAqIGNvbnRhaW4gcG9p bnRlcnMgdG8gb3RoZXIgYWxsb2NhdGVkIHN0cnVjdHMKKwkgKi8KKwljYXNlIERQX1JFTU9URV9J MkNfUkVBRDoKKyNkZWZpbmUgSU4gaW4tPnUuaTJjX3JlYWQKKyNkZWZpbmUgT1VUIG91dC0+dS5p MmNfcmVhZAorCQlpZiAoSU4ubnVtX2J5dGVzX3JlYWQgIT0gT1VULm51bV9ieXRlc19yZWFkIHx8 CisJCSAgICBJTi5udW1fdHJhbnNhY3Rpb25zICE9IE9VVC5udW1fdHJhbnNhY3Rpb25zIHx8CisJ CSAgICBJTi5wb3J0X251bWJlciAhPSBPVVQucG9ydF9udW1iZXIgfHwKKwkJICAgIElOLnJlYWRf aTJjX2RldmljZV9pZCAhPSBPVVQucmVhZF9pMmNfZGV2aWNlX2lkKQorCQkJcmV0dXJuIGZhbHNl OworCisJCWZvciAoaSA9IDA7IGkgPCBJTi5udW1fdHJhbnNhY3Rpb25zOyBpKyspIHsKKwkJCXR4 aW4gPSAmSU4udHJhbnNhY3Rpb25zW2ldOworCQkJdHhvdXQgPSAmT1VULnRyYW5zYWN0aW9uc1tp XTsKKworCQkJaWYgKHR4aW4tPmkyY19kZXZfaWQgIT0gdHhvdXQtPmkyY19kZXZfaWQgfHwKKwkJ CSAgICB0eGluLT5ub19zdG9wX2JpdCAhPSB0eG91dC0+bm9fc3RvcF9iaXQgfHwKKwkJCSAgICB0 eGluLT5udW1fYnl0ZXMgIT0gdHhvdXQtPm51bV9ieXRlcyB8fAorCQkJICAgIHR4aW4tPmkyY190 cmFuc2FjdGlvbl9kZWxheSAhPQorCQkJICAgIHR4b3V0LT5pMmNfdHJhbnNhY3Rpb25fZGVsYXkp CisJCQkJcmV0dXJuIGZhbHNlOworCisJCQlpZiAobWVtY21wKHR4aW4tPmJ5dGVzLCB0eG91dC0+ Ynl0ZXMsCisJCQkJICAgdHhpbi0+bnVtX2J5dGVzKSAhPSAwKQorCQkJCXJldHVybiBmYWxzZTsK KwkJfQorCQlicmVhazsKKyN1bmRlZiBJTgorI3VuZGVmIE9VVAorCisJY2FzZSBEUF9SRU1PVEVf RFBDRF9XUklURToKKyNkZWZpbmUgSU4gaW4tPnUuZHBjZF93cml0ZQorI2RlZmluZSBPVVQgb3V0 LT51LmRwY2Rfd3JpdGUKKwkJaWYgKElOLmRwY2RfYWRkcmVzcyAhPSBPVVQuZHBjZF9hZGRyZXNz IHx8CisJCSAgICBJTi5udW1fYnl0ZXMgIT0gT1VULm51bV9ieXRlcyB8fAorCQkgICAgSU4ucG9y dF9udW1iZXIgIT0gT1VULnBvcnRfbnVtYmVyKQorCQkJcmV0dXJuIGZhbHNlOworCisJCXJldHVy biBtZW1jbXAoSU4uYnl0ZXMsIE9VVC5ieXRlcywgSU4ubnVtX2J5dGVzKSA9PSAwOworI3VuZGVm IElOCisjdW5kZWYgT1VUCisKKwljYXNlIERQX1JFTU9URV9JMkNfV1JJVEU6CisjZGVmaW5lIElO IGluLT51LmkyY193cml0ZQorI2RlZmluZSBPVVQgb3V0LT51LmkyY193cml0ZQorCQlpZiAoSU4u cG9ydF9udW1iZXIgIT0gT1VULnBvcnRfbnVtYmVyIHx8CisJCSAgICBJTi53cml0ZV9pMmNfZGV2 aWNlX2lkICE9IE9VVC53cml0ZV9pMmNfZGV2aWNlX2lkIHx8CisJCSAgICBJTi5udW1fYnl0ZXMg IT0gT1VULm51bV9ieXRlcykKKwkJCXJldHVybiBmYWxzZTsKKworCQlyZXR1cm4gbWVtY21wKElO LmJ5dGVzLCBPVVQuYnl0ZXMsIElOLm51bV9ieXRlcykgPT0gMDsKKyN1bmRlZiBJTgorI3VuZGVm IE9VVAorCisJZGVmYXVsdDoKKwkJcmV0dXJuIG1lbWNtcChpbiwgb3V0LCBzaXplb2YoKmluKSkg PT0gMDsKKwl9CisKKwlyZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGJvb2wKK3NpZGViYW5kX21z Z19yZXFfZW5jb2RlX2RlY29kZShzdHJ1Y3QgZHJtX2RwX3NpZGViYW5kX21zZ19yZXFfYm9keSAq aW4pCit7CisJc3RydWN0IGRybV9kcF9zaWRlYmFuZF9tc2dfcmVxX2JvZHkgb3V0ID0gezB9Owor CXN0cnVjdCBkcm1fcHJpbnRlciBwID0gZHJtX2Vycl9wcmludGVyKFBSRUZJWF9TVFIpOworCXN0 cnVjdCBkcm1fZHBfc2lkZWJhbmRfbXNnX3R4IHR4bXNnOworCWludCBpLCByZXQ7CisKKwlkcm1f ZHBfZW5jb2RlX3NpZGViYW5kX3JlcShpbiwgJnR4bXNnKTsKKwlyZXQgPSBkcm1fZHBfZGVjb2Rl X3NpZGViYW5kX3JlcSgmdHhtc2csICZvdXQpOworCWlmIChyZXQgPCAwKSB7CisJCWRybV9wcmlu dGYoJnAsICJGYWlsZWQgdG8gZGVjb2RlIHNpZGViYW5kIHJlcXVlc3Q6ICVkXG4iLAorCQkJICAg cmV0KTsKKwkJcmV0dXJuIGZhbHNlOworCX0KKworCWlmICghc2lkZWJhbmRfbXNnX3JlcV9lcXVh bChpbiwgJm91dCkpIHsKKwkJZHJtX3ByaW50ZigmcCwgIkVuY29kZS9kZWNvZGUgZmFpbGVkLCBl eHBlY3RlZDpcbiIpOworCQlkcm1fZHBfZHVtcF9zaWRlYmFuZF9tc2dfcmVxX2JvZHkoaW4sIDEs ICZwKTsKKwkJZHJtX3ByaW50ZigmcCwgIkdvdDpcbiIpOworCQlkcm1fZHBfZHVtcF9zaWRlYmFu ZF9tc2dfcmVxX2JvZHkoJm91dCwgMSwgJnApOworCQlyZXR1cm4gZmFsc2U7CisJfQorCisJc3dp dGNoIChpbi0+cmVxX3R5cGUpIHsKKwljYXNlIERQX1JFTU9URV9EUENEX1dSSVRFOgorCQlrZnJl ZShvdXQudS5kcGNkX3dyaXRlLmJ5dGVzKTsKKwkJYnJlYWs7CisJY2FzZSBEUF9SRU1PVEVfSTJD X1JFQUQ6CisJCWZvciAoaSA9IDA7IGkgPCBvdXQudS5pMmNfcmVhZC5udW1fdHJhbnNhY3Rpb25z OyBpKyspCisJCQlrZnJlZShvdXQudS5pMmNfcmVhZC50cmFuc2FjdGlvbnNbaV0uYnl0ZXMpOwor CQlicmVhazsKKwljYXNlIERQX1JFTU9URV9JMkNfV1JJVEU6CisJCWtmcmVlKG91dC51LmkyY193 cml0ZS5ieXRlcyk7CisJCWJyZWFrOworCX0KKworCS8qIENsZWFyIGV2ZXJ5dGhpbmcgYnV0IHRo ZSByZXFfdHlwZSBmb3IgdGhlIGlucHV0ICovCisJbWVtc2V0KCZpbi0+dSwgMCwgc2l6ZW9mKGlu LT51KSk7CisKKwlyZXR1cm4gdHJ1ZTsKK30KKworaW50IGlndF9kcF9tc3Rfc2lkZWJhbmRfbXNn X3JlcV9kZWNvZGUodm9pZCAqdW51c2VkKQoreworCXN0cnVjdCBkcm1fZHBfc2lkZWJhbmRfbXNn X3JlcV9ib2R5IGluID0geyAwIH07CisJdTggZGF0YVtdID0geyAweGZmLCAweDAsIDB4ZGQgfTsK KwlpbnQgaTsKKworI2RlZmluZSBET19URVNUKCkgRkFJTF9PTighc2lkZWJhbmRfbXNnX3JlcV9l bmNvZGVfZGVjb2RlKCZpbikpCisKKwlpbi5yZXFfdHlwZSA9IERQX0VOVU1fUEFUSF9SRVNPVVJD RVM7CisJaW4udS5wb3J0X251bS5wb3J0X251bWJlciA9IDU7CisJRE9fVEVTVCgpOworCisJaW4u cmVxX3R5cGUgPSBEUF9QT1dFUl9VUF9QSFk7CisJaW4udS5wb3J0X251bS5wb3J0X251bWJlciA9 IDU7CisJRE9fVEVTVCgpOworCisJaW4ucmVxX3R5cGUgPSBEUF9QT1dFUl9ET1dOX1BIWTsKKwlp bi51LnBvcnRfbnVtLnBvcnRfbnVtYmVyID0gNTsKKwlET19URVNUKCk7CisKKwlpbi5yZXFfdHlw ZSA9IERQX0FMTE9DQVRFX1BBWUxPQUQ7CisJaW4udS5hbGxvY2F0ZV9wYXlsb2FkLm51bWJlcl9z ZHBfc3RyZWFtcyA9IDM7CisJZm9yIChpID0gMDsgaSA8IGluLnUuYWxsb2NhdGVfcGF5bG9hZC5u dW1iZXJfc2RwX3N0cmVhbXM7IGkrKykKKwkJaW4udS5hbGxvY2F0ZV9wYXlsb2FkLnNkcF9zdHJl YW1fc2lua1tpXSA9IGkgKyAxOworCURPX1RFU1QoKTsKKwlpbi51LmFsbG9jYXRlX3BheWxvYWQu cG9ydF9udW1iZXIgPSAweGY7CisJRE9fVEVTVCgpOworCWluLnUuYWxsb2NhdGVfcGF5bG9hZC52 Y3BpID0gMHg3ZjsKKwlET19URVNUKCk7CisJaW4udS5hbGxvY2F0ZV9wYXlsb2FkLnBibiA9IFUx Nl9NQVg7CisJRE9fVEVTVCgpOworCisJaW4ucmVxX3R5cGUgPSBEUF9RVUVSWV9QQVlMT0FEOwor CWluLnUucXVlcnlfcGF5bG9hZC5wb3J0X251bWJlciA9IDB4ZjsKKwlET19URVNUKCk7CisJaW4u dS5xdWVyeV9wYXlsb2FkLnZjcGkgPSAweDdmOworCURPX1RFU1QoKTsKKworCWluLnJlcV90eXBl ID0gRFBfUkVNT1RFX0RQQ0RfUkVBRDsKKwlpbi51LmRwY2RfcmVhZC5wb3J0X251bWJlciA9IDB4 ZjsKKwlET19URVNUKCk7CisJaW4udS5kcGNkX3JlYWQuZHBjZF9hZGRyZXNzID0gMHhmZWRjYjsK KwlET19URVNUKCk7CisJaW4udS5kcGNkX3JlYWQubnVtX2J5dGVzID0gVThfTUFYOworCURPX1RF U1QoKTsKKworCWluLnJlcV90eXBlID0gRFBfUkVNT1RFX0RQQ0RfV1JJVEU7CisJaW4udS5kcGNk X3dyaXRlLnBvcnRfbnVtYmVyID0gMHhmOworCURPX1RFU1QoKTsKKwlpbi51LmRwY2Rfd3JpdGUu ZHBjZF9hZGRyZXNzID0gMHhmZWRjYjsKKwlET19URVNUKCk7CisJaW4udS5kcGNkX3dyaXRlLm51 bV9ieXRlcyA9IEFSUkFZX1NJWkUoZGF0YSk7CisJaW4udS5kcGNkX3dyaXRlLmJ5dGVzID0gZGF0 YTsKKwlET19URVNUKCk7CisKKwlpbi5yZXFfdHlwZSA9IERQX1JFTU9URV9JMkNfUkVBRDsKKwlp bi51LmkyY19yZWFkLnBvcnRfbnVtYmVyID0gMHhmOworCURPX1RFU1QoKTsKKwlpbi51LmkyY19y ZWFkLnJlYWRfaTJjX2RldmljZV9pZCA9IDB4N2Y7CisJRE9fVEVTVCgpOworCWluLnUuaTJjX3Jl YWQubnVtX3RyYW5zYWN0aW9ucyA9IDM7CisJaW4udS5pMmNfcmVhZC5udW1fYnl0ZXNfcmVhZCA9 IEFSUkFZX1NJWkUoZGF0YSkgKiAzOworCWZvciAoaSA9IDA7IGkgPCBpbi51LmkyY19yZWFkLm51 bV90cmFuc2FjdGlvbnM7IGkrKykgeworCQlpbi51LmkyY19yZWFkLnRyYW5zYWN0aW9uc1tpXS5i eXRlcyA9IGRhdGE7CisJCWluLnUuaTJjX3JlYWQudHJhbnNhY3Rpb25zW2ldLm51bV9ieXRlcyA9 IEFSUkFZX1NJWkUoZGF0YSk7CisJCWluLnUuaTJjX3JlYWQudHJhbnNhY3Rpb25zW2ldLmkyY19k ZXZfaWQgPSAweDdmICYgfmk7CisJCWluLnUuaTJjX3JlYWQudHJhbnNhY3Rpb25zW2ldLmkyY190 cmFuc2FjdGlvbl9kZWxheSA9IDB4ZiAmIH5pOworCX0KKwlET19URVNUKCk7CisKKwlpbi5yZXFf dHlwZSA9IERQX1JFTU9URV9JMkNfV1JJVEU7CisJaW4udS5pMmNfd3JpdGUucG9ydF9udW1iZXIg PSAweGY7CisJRE9fVEVTVCgpOworCWluLnUuaTJjX3dyaXRlLndyaXRlX2kyY19kZXZpY2VfaWQg PSAweDdmOworCURPX1RFU1QoKTsKKwlpbi51LmkyY193cml0ZS5udW1fYnl0ZXMgPSBBUlJBWV9T SVpFKGRhdGEpOworCWluLnUuaTJjX3dyaXRlLmJ5dGVzID0gZGF0YTsKKwlET19URVNUKCk7CisK KyN1bmRlZiBET19URVNUCisJcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9k cm0vc2VsZnRlc3RzL3Rlc3QtZHJtX21vZGVzZXRfY29tbW9uLmggYi9kcml2ZXJzL2dwdS9kcm0v c2VsZnRlc3RzL3Rlc3QtZHJtX21vZGVzZXRfY29tbW9uLmgKaW5kZXggNTkwYmRhMzVhNjgzLi4w ZmNiOGJiYzZhMWIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9zZWxmdGVzdHMvdGVzdC1k cm1fbW9kZXNldF9jb21tb24uaAorKysgYi9kcml2ZXJzL2dwdS9kcm0vc2VsZnRlc3RzL3Rlc3Qt ZHJtX21vZGVzZXRfY29tbW9uLmgKQEAgLTQwLDUgKzQwLDYgQEAgaW50IGlndF9kYW1hZ2VfaXRl cl9kYW1hZ2Vfb25lX291dHNpZGUodm9pZCAqaWdub3JlZCk7CiBpbnQgaWd0X2RhbWFnZV9pdGVy X2RhbWFnZV9zcmNfbW92ZWQodm9pZCAqaWdub3JlZCk7CiBpbnQgaWd0X2RhbWFnZV9pdGVyX2Rh bWFnZV9ub3RfdmlzaWJsZSh2b2lkICppZ25vcmVkKTsKIGludCBpZ3RfZHBfbXN0X2NhbGNfcGJu X21vZGUodm9pZCAqaWdub3JlZCk7CitpbnQgaWd0X2RwX21zdF9zaWRlYmFuZF9tc2dfcmVxX2Rl Y29kZSh2b2lkICppZ25vcmVkKTsKIAogI2VuZGlmCmRpZmYgLS1naXQgYS9pbmNsdWRlL2RybS9k cm1fZHBfbXN0X2hlbHBlci5oIGIvaW5jbHVkZS9kcm0vZHJtX2RwX21zdF9oZWxwZXIuaAppbmRl eCA0YTQ1MDdmZTkyOGQuLjU0MjNhOGFkZGE3OCAxMDA2NDQKLS0tIGEvaW5jbHVkZS9kcm0vZHJt X2RwX21zdF9oZWxwZXIuaAorKysgYi9pbmNsdWRlL2RybS9kcm1fZHBfbXN0X2hlbHBlci5oCkBA IC0yOTMsNyArMjkzLDcgQEAgc3RydWN0IGRybV9kcF9yZW1vdGVfZHBjZF93cml0ZSB7CiBzdHJ1 Y3QgZHJtX2RwX3JlbW90ZV9pMmNfcmVhZCB7CiAJdTggbnVtX3RyYW5zYWN0aW9uczsKIAl1OCBw b3J0X251bWJlcjsKLQlzdHJ1Y3QgeworCXN0cnVjdCBkcm1fZHBfcmVtb3RlX2kyY19yZWFkX3R4 IHsKIAkJdTggaTJjX2Rldl9pZDsKIAkJdTggbnVtX2J5dGVzOwogCQl1OCAqYnl0ZXM7Ci0tIAoy LjIxLjAKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCk5v dXZlYXUgbWFpbGluZyBsaXN0Ck5vdXZlYXVAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vbm91dmVhdQ==