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=-15.3 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 8F58DC433B4 for ; Wed, 14 Apr 2021 06:17:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 68097613D0 for ; Wed, 14 Apr 2021 06:17:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349170AbhDNGRk (ORCPT ); Wed, 14 Apr 2021 02:17:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348021AbhDNGRh (ORCPT ); Wed, 14 Apr 2021 02:17:37 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCB1BC061574 for ; Tue, 13 Apr 2021 23:17:13 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id m9so5925254wrx.3 for ; Tue, 13 Apr 2021 23:17:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=eXGdLIcmTSbWyBBFK1pqcTD9BaUOcCFISmVmmzF0eDk=; b=JRkXrDdtDalw3JAElnMt+GKilESNHJvq14HCE3BGKEp5QGk6KVrhZFaN+dK38Hag0N mThCSsRop4mpPnSJvPbeM0E9k+kgo0urUULXIkiaX/lohra9aCdzCICi06tKuFYt6SHF l2F+felNQVgIFdZSS697TKjhMMHkrdQ00yTFow26qOtrC0xgNVIF4Mjv/+sdUhwMNLnA PzdMp7IHwlO/8m3ZIEKndO4iaOUfZEHbwd5/nrQpicThrWBhqao8lrHM6TVWAwA74w6t A/VV9WmE8x31CT3feU6hAV1OQanK7+jdRUvPTEpzHE8HwBNTBWFy1MudQnFZjuagvMQ7 3wjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=eXGdLIcmTSbWyBBFK1pqcTD9BaUOcCFISmVmmzF0eDk=; b=QaBCL+H1pOTs7UgCZ9wc/hMVpM68YVwGD9dwaiSE3WQslYi/Q9kew600f2lXViN1Sy s4FVJvcV1I22Q3gZzJjel4nSnNJNLoq0b9bpTlSajxBb9iUlxaN7/grZmvgLKB0hhc3B DUQD6ZCZHHoI12LPczwl0/l54cmBK46YGbujpoOD1vk3BppQ+whLv7PwJ0R3B2s+AbZY 3WEpWHLWGWD2FTWxm+8+PoxIiU1Jx6HHPe1Y6aZNK311rn1+gfPtNCeO6PpjSQzNMBUI /L7XekkvIwb5RaZRJIqQe2nNNWhBSSF/NpwQxKPo491Jz8VvbSY/qCcFAzlGcZVlP22Z oxlw== X-Gm-Message-State: AOAM532iLWbHWVkL5mo60F15DZZ5GlCcRiKCdGKLARX7xWYITsyDpErW A39CBgskQIa8+KTQ+Xma3hPv2w== X-Google-Smtp-Source: ABdhPJx5rfekNgwKpu7OID5d92R2MShE7MCLx0c/rRfrERFTpgAmBFA7mre1fR8idfoQP0T4gnsoQQ== X-Received: by 2002:a05:6000:1549:: with SMTP id 9mr40984448wry.192.1618381032410; Tue, 13 Apr 2021 23:17:12 -0700 (PDT) Received: from Armstrongs-MacBook-Pro.local ([2a01:e0a:90c:e290:29e7:a4d9:c2b0:1adc]) by smtp.gmail.com with ESMTPSA id l7sm24346898wrb.35.2021.04.13.23.17.10 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 13 Apr 2021 23:17:11 -0700 (PDT) Subject: Re: [PATCH v3 2/3] drm: bridge: add it66121 driver To: Paul Cercueil Cc: a.hajda@samsung.com, Laurent.pinchart@ideasonboard.com, robert.foss@linaro.org, jonas@kwiboo.se, jernej.skrabec@siol.net, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Phong LE References: <20210412154648.3719153-1-narmstrong@baylibre.com> <20210412154648.3719153-3-narmstrong@baylibre.com> From: Neil Armstrong Message-ID: <1d963840-cb96-399b-7f27-ce3eb9ad6083@baylibre.com> Date: Wed, 14 Apr 2021 08:17:09 +0200 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: fr Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Le 13/04/2021 à 22:56, Paul Cercueil a écrit : > Hi Neil, > > I get build failures locally: > > drivers/gpu/drm/bridge/ite-it66121.c: In function ‘it66121_hw_reset’: > drivers/gpu/drm/bridge/ite-it66121.c:242:2: error: implicit declaration of function ‘gpiod_set_value’ [-Werror=implicit-function-declaration] > 242 | gpiod_set_value(ctx->gpio_reset, 1); >     | ^~~~~~~~~~~~~~~ > drivers/gpu/drm/bridge/ite-it66121.c: In function ‘it66121_probe’: > drivers/gpu/drm/bridge/ite-it66121.c:1016:16: error: implicit declaration of function ‘FIELD_GET’; did you mean ‘FOLL_GET’? [-Werror=implicit-function-declaration] > 1016 | revision_id = FIELD_GET(IT66121_REVISION_MASK, device_ids[1]); >     | ^~~~~~~~~ >     | FOLL_GET > > Nothing difficult to fix, but the includes should be added nonetheless. Exact, I got the CI build failures, I'll fix these for v4. Were you able to test on your setup ? The v2 always forced DDR mode, with this v3, I also switch to normal 24input mode, but totally untested. Thanks, Neil > > Cheers, > -Paul > > > Le lun. 12 avril 2021 à 17:46, Neil Armstrong a écrit : >> From: Phong LE >> >> This commit is a simple driver for bridge HMDI it66121. >> The input format is RBG and there is no color conversion. >> Audio, HDCP and CEC are not supported yet. >> >> Signed-off-by: Phong LE >> Signed-off-by: Neil Armstrong >> --- >>  drivers/gpu/drm/bridge/Kconfig       |    8 + >>  drivers/gpu/drm/bridge/Makefile      |    1 + >>  drivers/gpu/drm/bridge/ite-it66121.c | 1081 ++++++++++++++++++++++++++ >>  3 files changed, 1090 insertions(+) >>  create mode 100644 drivers/gpu/drm/bridge/ite-it66121.c >> >> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig >> index e4110d6ca7b3..6915c38fa459 100644 >> --- a/drivers/gpu/drm/bridge/Kconfig >> +++ b/drivers/gpu/drm/bridge/Kconfig >> @@ -74,6 +74,14 @@ config DRM_LONTIUM_LT9611UXC >>        HDMI signals >>        Please say Y if you have such hardware. >> >> +config DRM_ITE_IT66121 >> +    tristate "ITE IT66121 HDMI bridge" >> +    depends on OF >> +    select DRM_KMS_HELPER >> +    select REGMAP_I2C >> +    help >> +      Support for ITE IT66121 HDMI bridge. >> + >>  config DRM_LVDS_CODEC >>      tristate "Transparent LVDS encoders and decoders support" >>      depends on OF >> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile >> index 86e7acc76f8d..4f725753117c 100644 >> --- a/drivers/gpu/drm/bridge/Makefile >> +++ b/drivers/gpu/drm/bridge/Makefile >> @@ -24,6 +24,7 @@ obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o >>  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o >>  obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o >>  obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o >> +obj-$(CONFIG_DRM_ITE_IT66121) += ite-it66121.o >> >>  obj-y += analogix/ >>  obj-y += cadence/ >> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c >> new file mode 100644 >> index 000000000000..73af49b29dfa >> --- /dev/null >> +++ b/drivers/gpu/drm/bridge/ite-it66121.c >> @@ -0,0 +1,1081 @@ >> +// SPDX-License-Identifier: GPL-2.0-only >> +/* >> + * Copyright (C) 2020 BayLibre, SAS >> + * Author: Phong LE >> + * Copyright (C) 2018-2019, Artem Mygaiev >> + * Copyright (C) 2017, Fresco Logic, Incorporated. >> + * >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define IT66121_VENDOR_ID0_REG            0x00 >> +#define IT66121_VENDOR_ID1_REG            0x01 >> +#define IT66121_DEVICE_ID0_REG            0x02 >> +#define IT66121_DEVICE_ID1_REG            0x03 >> + >> +#define IT66121_VENDOR_ID0            0x54 >> +#define IT66121_VENDOR_ID1            0x49 >> +#define IT66121_DEVICE_ID0            0x12 >> +#define IT66121_DEVICE_ID1            0x06 >> +#define IT66121_REVISION_MASK            GENMASK(7, 4) >> +#define IT66121_DEVICE_ID1_MASK            GENMASK(3, 0) >> + >> +#define IT66121_MASTER_SEL_REG            0x10 >> +#define IT66121_MASTER_SEL_HOST            BIT(0) >> + >> +#define IT66121_AFE_DRV_REG            0x61 >> +#define IT66121_AFE_DRV_RST            BIT(4) >> +#define IT66121_AFE_DRV_PWD            BIT(5) >> + >> +#define IT66121_INPUT_MODE_REG            0x70 >> +#define IT66121_INPUT_MODE_RGB            (0 << 6) >> +#define IT66121_INPUT_MODE_YUV422        BIT(6) >> +#define IT66121_INPUT_MODE_YUV444        (2 << 6) >> +#define IT66121_INPUT_MODE_CCIR656        BIT(4) >> +#define IT66121_INPUT_MODE_SYNCEMB        BIT(3) >> +#define IT66121_INPUT_MODE_DDR            BIT(2) >> + >> +#define IT66121_INPUT_CSC_REG            0x72 >> +#define IT66121_INPUT_CSC_ENDITHER        BIT(7) >> +#define IT66121_INPUT_CSC_ENUDFILTER        BIT(6) >> +#define IT66121_INPUT_CSC_DNFREE_GO        BIT(5) >> +#define IT66121_INPUT_CSC_RGB_TO_YUV        0x02 >> +#define IT66121_INPUT_CSC_YUV_TO_RGB        0x03 >> +#define IT66121_INPUT_CSC_NO_CONV        0x00 >> + >> +#define IT66121_AFE_XP_REG            0x62 >> +#define IT66121_AFE_XP_GAINBIT            BIT(7) >> +#define IT66121_AFE_XP_PWDPLL            BIT(6) >> +#define IT66121_AFE_XP_ENI            BIT(5) >> +#define IT66121_AFE_XP_ENO            BIT(4) >> +#define IT66121_AFE_XP_RESETB            BIT(3) >> +#define IT66121_AFE_XP_PWDI            BIT(2) >> + >> +#define IT66121_AFE_IP_REG            0x64 >> +#define IT66121_AFE_IP_GAINBIT            BIT(7) >> +#define IT66121_AFE_IP_PWDPLL            BIT(6) >> +#define IT66121_AFE_IP_CKSEL_05            (0 << 4) >> +#define IT66121_AFE_IP_CKSEL_1            BIT(4) >> +#define IT66121_AFE_IP_CKSEL_2            (2 << 4) >> +#define IT66121_AFE_IP_CKSEL_2OR4        (3 << 4) >> +#define IT66121_AFE_IP_ER0            BIT(3) >> +#define IT66121_AFE_IP_RESETB            BIT(2) >> +#define IT66121_AFE_IP_ENC            BIT(1) >> +#define IT66121_AFE_IP_EC1            BIT(0) >> + >> +#define IT66121_AFE_XP_EC1_REG            0x68 >> +#define IT66121_AFE_XP_EC1_LOWCLK        BIT(4) >> + >> +#define IT66121_SW_RST_REG            0x04 >> +#define IT66121_SW_RST_REF            BIT(5) >> +#define IT66121_SW_RST_AREF            BIT(4) >> +#define IT66121_SW_RST_VID            BIT(3) >> +#define IT66121_SW_RST_AUD            BIT(2) >> +#define IT66121_SW_RST_HDCP            BIT(0) >> + >> +#define IT66121_DDC_COMMAND_REG            0x15 >> +#define IT66121_DDC_COMMAND_BURST_READ        0x0 >> +#define IT66121_DDC_COMMAND_EDID_READ        0x3 >> +#define IT66121_DDC_COMMAND_FIFO_CLR        0x9 >> +#define IT66121_DDC_COMMAND_SCL_PULSE        0xA >> +#define IT66121_DDC_COMMAND_ABORT        0xF >> + >> +#define IT66121_HDCP_REG            0x20 >> +#define IT66121_HDCP_CPDESIRED            BIT(0) >> +#define IT66121_HDCP_EN1P1FEAT            BIT(1) >> + >> +#define IT66121_INT_STATUS1_REG            0x06 >> +#define IT66121_INT_STATUS1_AUD_OVF        BIT(7) >> +#define IT66121_INT_STATUS1_DDC_NOACK        BIT(5) >> +#define IT66121_INT_STATUS1_DDC_FIFOERR        BIT(4) >> +#define IT66121_INT_STATUS1_DDC_BUSHANG        BIT(2) >> +#define IT66121_INT_STATUS1_RX_SENS_STATUS    BIT(1) >> +#define IT66121_INT_STATUS1_HPD_STATUS        BIT(0) >> + >> +#define IT66121_DDC_HEADER_REG            0x11 >> +#define IT66121_DDC_HEADER_HDCP            0x74 >> +#define IT66121_DDC_HEADER_EDID            0xA0 >> + >> +#define IT66121_DDC_OFFSET_REG            0x12 >> +#define IT66121_DDC_BYTE_REG            0x13 >> +#define IT66121_DDC_SEGMENT_REG            0x14 >> +#define IT66121_DDC_RD_FIFO_REG            0x17 >> + >> +#define IT66121_CLK_BANK_REG            0x0F >> +#define IT66121_CLK_BANK_PWROFF_RCLK        BIT(6) >> +#define IT66121_CLK_BANK_PWROFF_ACLK        BIT(5) >> +#define IT66121_CLK_BANK_PWROFF_TXCLK        BIT(4) >> +#define IT66121_CLK_BANK_PWROFF_CRCLK        BIT(3) >> +#define IT66121_CLK_BANK_0            0 >> +#define IT66121_CLK_BANK_1            1 >> + >> +#define IT66121_INT_REG                0x05 >> +#define IT66121_INT_ACTIVE_HIGH            BIT(7) >> +#define IT66121_INT_OPEN_DRAIN            BIT(6) >> +#define IT66121_INT_TX_CLK_OFF            BIT(0) >> + >> +#define IT66121_INT_MASK1_REG            0x09 >> +#define IT66121_INT_MASK1_AUD_OVF        BIT(7) >> +#define IT66121_INT_MASK1_DDC_NOACK        BIT(5) >> +#define IT66121_INT_MASK1_DDC_FIFOERR        BIT(4) >> +#define IT66121_INT_MASK1_DDC_BUSHANG        BIT(2) >> +#define IT66121_INT_MASK1_RX_SENS        BIT(1) >> +#define IT66121_INT_MASK1_HPD            BIT(0) >> + >> +#define IT66121_INT_CLR1_REG            0x0C >> +#define IT66121_INT_CLR1_PKTACP            BIT(7) >> +#define IT66121_INT_CLR1_PKTNULL        BIT(6) >> +#define IT66121_INT_CLR1_PKTGEN            BIT(5) >> +#define IT66121_INT_CLR1_KSVLISTCHK        BIT(4) >> +#define IT66121_INT_CLR1_AUTHDONE        BIT(3) >> +#define IT66121_INT_CLR1_AUTHFAIL        BIT(2) >> +#define IT66121_INT_CLR1_RX_SENS        BIT(1) >> +#define IT66121_INT_CLR1_HPD            BIT(0) >> + >> +#define IT66121_AV_MUTE_REG            0xC1 >> +#define IT66121_AV_MUTE_ON            BIT(0) >> +#define IT66121_AV_MUTE_BLUESCR            BIT(1) >> + >> +#define IT66121_PKT_GEN_CTRL_REG        0xC6 >> +#define IT66121_PKT_GEN_CTRL_ON            BIT(0) >> +#define IT66121_PKT_GEN_CTRL_RPT        BIT(1) >> + >> +#define IT66121_AVIINFO_DB1_REG            0x158 >> +#define IT66121_AVIINFO_DB2_REG            0x159 >> +#define IT66121_AVIINFO_DB3_REG            0x15A >> +#define IT66121_AVIINFO_DB4_REG            0x15B >> +#define IT66121_AVIINFO_DB5_REG            0x15C >> +#define IT66121_AVIINFO_CSUM_REG        0x15D >> +#define IT66121_AVIINFO_DB6_REG            0x15E >> +#define IT66121_AVIINFO_DB7_REG            0x15F >> +#define IT66121_AVIINFO_DB8_REG            0x160 >> +#define IT66121_AVIINFO_DB9_REG            0x161 >> +#define IT66121_AVIINFO_DB10_REG        0x162 >> +#define IT66121_AVIINFO_DB11_REG        0x163 >> +#define IT66121_AVIINFO_DB12_REG        0x164 >> +#define IT66121_AVIINFO_DB13_REG        0x165 >> + >> +#define IT66121_AVI_INFO_PKT_REG        0xCD >> +#define IT66121_AVI_INFO_PKT_ON            BIT(0) >> +#define IT66121_AVI_INFO_PKT_RPT        BIT(1) >> + >> +#define IT66121_HDMI_MODE_REG            0xC0 >> +#define IT66121_HDMI_MODE_HDMI            BIT(0) >> + >> +#define IT66121_SYS_STATUS_REG            0x0E >> +#define IT66121_SYS_STATUS_ACTIVE_IRQ        BIT(7) >> +#define IT66121_SYS_STATUS_HPDETECT        BIT(6) >> +#define IT66121_SYS_STATUS_SENDECTECT        BIT(5) >> +#define IT66121_SYS_STATUS_VID_STABLE        BIT(4) >> +#define IT66121_SYS_STATUS_AUD_CTS_CLR        BIT(1) >> +#define IT66121_SYS_STATUS_CLEAR_IRQ        BIT(0) >> + >> +#define IT66121_DDC_STATUS_REG            0x16 >> +#define IT66121_DDC_STATUS_TX_DONE        BIT(7) >> +#define IT66121_DDC_STATUS_ACTIVE        BIT(6) >> +#define IT66121_DDC_STATUS_NOACK        BIT(5) >> +#define IT66121_DDC_STATUS_WAIT_BUS        BIT(4) >> +#define IT66121_DDC_STATUS_ARBI_LOSE        BIT(3) >> +#define IT66121_DDC_STATUS_FIFO_FULL        BIT(2) >> +#define IT66121_DDC_STATUS_FIFO_EMPTY        BIT(1) >> +#define IT66121_DDC_STATUS_FIFO_VALID        BIT(0) >> + >> +#define IT66121_EDID_SLEEP_US            20000 >> +#define IT66121_EDID_TIMEOUT_US            200000 >> +#define IT66121_EDID_FIFO_SIZE            32 >> +#define IT66121_AFE_CLK_HIGH            80000 /* Khz */ >> + >> +struct it66121_ctx { >> +    struct regmap *regmap; >> +    struct drm_bridge bridge; >> +    struct drm_connector connector; >> +    struct device *dev; >> +    struct gpio_desc *gpio_reset; >> +    struct i2c_client *client; >> +    struct regulator_bulk_data supplies[3]; >> +    u32 bus_width; >> +    struct mutex lock; /* Protects fields below and device registers */ >> +    struct edid *edid; >> +    struct hdmi_avi_infoframe hdmi_avi_infoframe; >> +}; >> + >> +static const struct regmap_range_cfg it66121_regmap_banks[] = { >> +    { >> +        .name = "it66121", >> +        .range_min = 0x00, >> +        .range_max = 0x1FF, >> +        .selector_reg = IT66121_CLK_BANK_REG, >> +        .selector_mask = 0x1, >> +        .selector_shift = 0, >> +        .window_start = 0x00, >> +        .window_len = 0x130, >> +    }, >> +}; >> + >> +static const struct regmap_config it66121_regmap_config = { >> +    .val_bits = 8, >> +    .reg_bits = 8, >> +    .max_register = 0x1FF, >> +    .ranges = it66121_regmap_banks, >> +    .num_ranges = ARRAY_SIZE(it66121_regmap_banks), >> +}; >> + >> +static void it66121_hw_reset(struct it66121_ctx *ctx) >> +{ >> +    gpiod_set_value(ctx->gpio_reset, 1); >> +    msleep(20); >> +    gpiod_set_value(ctx->gpio_reset, 0); >> +} >> + >> +static int ite66121_power_on(struct it66121_ctx *ctx) >> +{ >> +    return regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); >> +} >> + >> +static int ite66121_power_off(struct it66121_ctx *ctx) >> +{ >> +    return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); >> +} >> + >> +static int it66121_preamble_ddc(struct it66121_ctx *ctx) >> +{ >> +    return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, >> +                IT66121_MASTER_SEL_HOST); >> +} >> + >> +static int it66121_fire_afe(struct it66121_ctx *ctx) >> +{ >> +    return regmap_write(ctx->regmap, IT66121_AFE_DRV_REG, 0); >> +} >> + >> +/* TOFIX: Handle YCbCr Input & Output */ >> +static int it66121_configure_input(struct it66121_ctx *ctx) >> +{ >> +    int ret; >> +    u8 mode = IT66121_INPUT_MODE_RGB; >> + >> +    if (ctx->bus_width == 12) >> +        mode |= IT66121_INPUT_MODE_DDR; >> + >> +    ret = regmap_write(ctx->regmap, IT66121_INPUT_MODE_REG, mode); >> +    if (ret) >> +        return ret; >> + >> +    return regmap_write(ctx->regmap, IT66121_INPUT_CSC_REG, IT66121_INPUT_CSC_NO_CONV); >> +} >> + >> +/** >> + * it66121_configure_afe() - Configure the analog front end >> + * @ctx: it66121_ctx object >> + * @mode: mode to configure >> + * >> + * RETURNS: >> + * zero if success, a negative error code otherwise. >> + */ >> +static int it66121_configure_afe(struct it66121_ctx *ctx, >> +                 const struct drm_display_mode *mode) >> +{ >> +    int ret; >> + >> +    ret = regmap_write(ctx->regmap, IT66121_AFE_DRV_REG, >> +               IT66121_AFE_DRV_RST); >> +    if (ret) >> +        return ret; >> + >> +    if (mode->clock > IT66121_AFE_CLK_HIGH) { >> +        ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, >> +                    IT66121_AFE_XP_GAINBIT | >> +                    IT66121_AFE_XP_ENO, >> +                    IT66121_AFE_XP_GAINBIT); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, >> +                    IT66121_AFE_IP_GAINBIT | >> +                    IT66121_AFE_IP_ER0 | >> +                    IT66121_AFE_IP_EC1, >> +                    IT66121_AFE_IP_GAINBIT); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG, >> +                    IT66121_AFE_XP_EC1_LOWCLK, 0x80); >> +        if (ret) >> +            return ret; >> +    } else { >> +        ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, >> +                    IT66121_AFE_XP_GAINBIT | >> +                    IT66121_AFE_XP_ENO, >> +                    IT66121_AFE_XP_ENO); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, >> +                    IT66121_AFE_IP_GAINBIT | >> +                    IT66121_AFE_IP_ER0 | >> +                    IT66121_AFE_IP_EC1, IT66121_AFE_IP_ER0 | >> +                    IT66121_AFE_IP_EC1); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG, >> +                    IT66121_AFE_XP_EC1_LOWCLK, >> +                    IT66121_AFE_XP_EC1_LOWCLK); >> +        if (ret) >> +            return ret; >> +    } >> + >> +    /* Clear reset flags */ >> +    ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, >> +                IT66121_SW_RST_REF | IT66121_SW_RST_VID, >> +                ~(IT66121_SW_RST_REF | IT66121_SW_RST_VID) & >> +                0xFF); >> +    if (ret) >> +        return ret; >> + >> +    return it66121_fire_afe(ctx); >> +} >> + >> +static inline int it66121_wait_ddc_ready(struct it66121_ctx *ctx) >> +{ >> +    int ret, val; >> +    u32 busy = IT66121_DDC_STATUS_NOACK | IT66121_DDC_STATUS_WAIT_BUS | >> +           IT66121_DDC_STATUS_ARBI_LOSE; >> + >> +    ret = regmap_read_poll_timeout(ctx->regmap, IT66121_DDC_STATUS_REG, val, true, >> +                       IT66121_EDID_SLEEP_US, IT66121_EDID_TIMEOUT_US); >> +    if (ret) >> +        return ret; >> + >> +    if (val & busy) >> +        return -EAGAIN; >> + >> +    return 0; >> +} >> + >> +static int it66121_clear_ddc_fifo(struct it66121_ctx *ctx) >> +{ >> +    int ret; >> + >> +    ret = it66121_preamble_ddc(ctx); >> +    if (ret) >> +        return ret; >> + >> +    return regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, >> +                IT66121_DDC_COMMAND_FIFO_CLR); >> +} >> + >> +static int it66121_abort_ddc_ops(struct it66121_ctx *ctx) >> +{ >> +    int ret; >> +    unsigned int swreset, cpdesire; >> + >> +    ret = regmap_read(ctx->regmap, IT66121_SW_RST_REG, &swreset); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_read(ctx->regmap, IT66121_HDCP_REG, &cpdesire); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write(ctx->regmap, IT66121_HDCP_REG, >> +               cpdesire & (~IT66121_HDCP_CPDESIRED & 0xFF)); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write(ctx->regmap, IT66121_SW_RST_REG, >> +               (swreset | IT66121_SW_RST_HDCP)); >> +    if (ret) >> +        return ret; >> + >> +    ret = it66121_preamble_ddc(ctx); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, >> +               IT66121_DDC_COMMAND_ABORT); >> +    if (ret) >> +        return ret; >> + >> +    return it66121_wait_ddc_ready(ctx); >> +} >> + >> +static int it66121_get_edid_block(void *context, u8 *buf, >> +                  unsigned int block, size_t len) >> +{ >> +    struct it66121_ctx *ctx = context; >> +    unsigned int val; >> +    int remain = len; >> +    int offset = 0; >> +    int ret, cnt; >> + >> +    offset = (block % 2) * len; >> +    block = block / 2; >> + >> +    ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); >> +    if (ret) >> +        return ret; >> + >> +    if (val & IT66121_INT_STATUS1_DDC_BUSHANG) { >> +        ret = it66121_abort_ddc_ops(ctx); >> +        if (ret) >> +            return ret; >> +    } >> + >> +    ret = it66121_clear_ddc_fifo(ctx); >> +    if (ret) >> +        return ret; >> + >> +    while (remain > 0) { >> +        cnt = (remain > IT66121_EDID_FIFO_SIZE) ? >> +                IT66121_EDID_FIFO_SIZE : remain; >> +        ret = it66121_preamble_ddc(ctx); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, >> +                   IT66121_DDC_COMMAND_FIFO_CLR); >> +        if (ret) >> +            return ret; >> + >> +        ret = it66121_wait_ddc_ready(ctx); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); >> +        if (ret) >> +            return ret; >> + >> +        if (val & IT66121_INT_STATUS1_DDC_BUSHANG) { >> +            ret = it66121_abort_ddc_ops(ctx); >> +            if (ret) >> +                return ret; >> +        } >> + >> +        ret = it66121_preamble_ddc(ctx); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG, >> +                   IT66121_DDC_HEADER_EDID); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write(ctx->regmap, IT66121_DDC_OFFSET_REG, offset); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write(ctx->regmap, IT66121_DDC_BYTE_REG, cnt); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write(ctx->regmap, IT66121_DDC_SEGMENT_REG, block); >> +        if (ret) >> +            return ret; >> + >> +        ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, >> +                   IT66121_DDC_COMMAND_EDID_READ); >> +        if (ret) >> +            return ret; >> + >> +        offset += cnt; >> +        remain -= cnt; >> + >> +        /* Per programming manual, sleep here before emptying the FIFO */ >> +        msleep(20); >> + >> +        ret = it66121_wait_ddc_ready(ctx); >> +        if (ret) >> +            return ret; >> + >> +        do { >> +            ret = regmap_read(ctx->regmap, IT66121_DDC_RD_FIFO_REG, &val); >> +            if (ret) >> +                return ret; >> +            *(buf++) = val; >> +            cnt--; >> +        } while (cnt > 0); >> +    } >> + >> +    return 0; >> +} >> + >> +static int it66121_connector_get_modes(struct drm_connector *connector) >> +{ >> +    int ret, num_modes = 0; >> +    struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, >> +            connector); >> + >> +    if (ctx->edid) >> +        return drm_add_edid_modes(connector, ctx->edid); >> + >> +    mutex_lock(&ctx->lock); >> + >> +    ctx->edid = drm_do_get_edid(connector, it66121_get_edid_block, ctx); >> +    if (!ctx->edid) { >> +        DRM_ERROR("Failed to read EDID\n"); >> +        goto unlock; >> +    } >> + >> +    ret = drm_connector_update_edid_property(connector, ctx->edid); >> +    if (ret) { >> +        DRM_ERROR("Failed to update EDID property: %d\n", ret); >> +        goto unlock; >> +    } >> + >> +    num_modes = drm_add_edid_modes(connector, ctx->edid); >> + >> +unlock: >> +    mutex_unlock(&ctx->lock); >> + >> +    return num_modes; >> +} >> + >> +static bool it66121_is_hpd_detect(struct it66121_ctx *ctx) >> +{ >> +    int val; >> + >> +    if (regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val)) >> +        return false; >> + >> +    return val & IT66121_SYS_STATUS_HPDETECT; >> +} >> + >> +static int it66121_connector_detect_ctx(struct drm_connector *connector, >> +                    struct drm_modeset_acquire_ctx *c, >> +                    bool force) >> +{ >> +    struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, >> +            connector); >> + >> +    return it66121_is_hpd_detect(ctx) ? connector_status_connected >> +                      : connector_status_disconnected; >> +} >> + >> +static enum drm_mode_status it66121_mode_valid(struct it66121_ctx *ctx, >> +                           const struct drm_display_mode *mode) >> +{ >> +    unsigned long max_clock; >> + >> +    max_clock = (ctx->bus_width == 12) ? 74250 : 148500; >> + >> +    if (mode->clock > max_clock) >> +        return MODE_CLOCK_HIGH; >> + >> +    if (mode->clock < 25000) >> +        return MODE_CLOCK_LOW; >> + >> +    return MODE_OK; >> +} >> + >> +static enum drm_mode_status it66121_connector_mode_valid(struct drm_connector *connector, >> +                             struct drm_display_mode *mode) >> +{ >> +    struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, >> +            connector); >> + >> +    return it66121_mode_valid(ctx, mode); >> +} >> + >> +static struct drm_connector_helper_funcs it66121_connector_helper_funcs = { >> +    .get_modes = it66121_connector_get_modes, >> +    .detect_ctx = it66121_connector_detect_ctx, >> +    .mode_valid = it66121_connector_mode_valid, >> +}; >> + >> +static const struct drm_connector_funcs it66121_connector_funcs = { >> +    .reset = drm_atomic_helper_connector_reset, >> +    .fill_modes = drm_helper_probe_single_connector_modes, >> +    .destroy = drm_connector_cleanup, >> +    .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, >> +    .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, >> +}; >> + >> +static int it66121_bridge_attach(struct drm_bridge *bridge, >> +                 enum drm_bridge_attach_flags flags) >> +{ >> +    int ret; >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, >> +            bridge); >> + >> +    if (!bridge->encoder) { >> +        DRM_ERROR("Parent encoder object not found"); >> +        return -ENODEV; >> +    } >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, >> +                IT66121_CLK_BANK_PWROFF_RCLK, 0); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_INT_REG, >> +                IT66121_INT_TX_CLK_OFF, 0); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AFE_DRV_REG, >> +                IT66121_AFE_DRV_PWD, 0); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, >> +                IT66121_AFE_XP_PWDI | IT66121_AFE_XP_PWDPLL, 0); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, >> +                IT66121_AFE_IP_PWDPLL, 0); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AFE_DRV_REG, >> +                IT66121_AFE_DRV_RST, 0); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, >> +                IT66121_AFE_XP_RESETB, IT66121_AFE_XP_RESETB); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, >> +                IT66121_AFE_IP_RESETB, IT66121_AFE_IP_RESETB); >> +    if (ret) >> +        return ret; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, >> +                IT66121_SW_RST_REF, >> +                IT66121_SW_RST_REF); >> +    if (ret) >> +        return ret; >> + >> +    /* Per programming manual, sleep here for bridge to settle */ >> +    msleep(50); >> + >> +    /* Start interrupts */ >> +    ret = regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG, >> +                IT66121_INT_MASK1_DDC_NOACK | >> +                IT66121_INT_MASK1_HPD | >> +                IT66121_INT_MASK1_DDC_FIFOERR | >> +                IT66121_INT_MASK1_DDC_BUSHANG, >> +                ~(IT66121_INT_MASK1_DDC_NOACK | >> +                IT66121_INT_MASK1_HPD | >> +                IT66121_INT_MASK1_DDC_FIFOERR | >> +                IT66121_INT_MASK1_DDC_BUSHANG) & 0xFF); >> +    if (ret) >> +        return ret; >> + >> +    if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) >> +        return 0; >> + >> +    ret = drm_connector_init(bridge->dev, &ctx->connector, >> +                 &it66121_connector_funcs, >> +                 DRM_MODE_CONNECTOR_HDMIA); >> +    if (ret) >> +        return ret; >> + >> +    ctx->connector.polled = DRM_CONNECTOR_POLL_HPD; >> +    drm_connector_helper_add(&ctx->connector, >> +                 &it66121_connector_helper_funcs); >> + >> +    ret = drm_connector_attach_encoder(&ctx->connector, bridge->encoder); >> +    if (ret) >> +        return ret; >> + >> +    return drm_connector_register(&ctx->connector); >> +} >> + >> +static int it66121_set_mute(struct it66121_ctx *ctx, bool mute) >> +{ >> +    int ret; >> +    unsigned int val = 0; >> + >> +    if (mute) >> +        val = IT66121_AV_MUTE_ON; >> + >> +    ret = regmap_write_bits(ctx->regmap, IT66121_AV_MUTE_REG, IT66121_AV_MUTE_ON, val); >> +    if (ret) >> +        return ret; >> + >> +    return regmap_write(ctx->regmap, IT66121_PKT_GEN_CTRL_REG, >> +                IT66121_PKT_GEN_CTRL_ON | IT66121_PKT_GEN_CTRL_RPT); >> +} >> + >> +#define MAX_OUTPUT_SEL_FORMATS    1 >> + >> +static u32 *it66121_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, >> +                              struct drm_bridge_state *bridge_state, >> +                              struct drm_crtc_state *crtc_state, >> +                              struct drm_connector_state *conn_state, >> +                              unsigned int *num_output_fmts) >> +{ >> +    u32 *output_fmts; >> + >> +    output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts), >> +                  GFP_KERNEL); >> +    if (!output_fmts) >> +        return NULL; >> + >> +    /* TOFIX handle more than MEDIA_BUS_FMT_RGB888_1X24 as output format */ >> +    output_fmts[0] =  MEDIA_BUS_FMT_RGB888_1X24; >> +    *num_output_fmts = 1; >> + >> +    return output_fmts; >> +} >> + >> +#define MAX_INPUT_SEL_FORMATS    1 >> + >> +static u32 *it66121_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, >> +                             struct drm_bridge_state *bridge_state, >> +                             struct drm_crtc_state *crtc_state, >> +                             struct drm_connector_state *conn_state, >> +                             u32 output_fmt, >> +                             unsigned int *num_input_fmts) >> +{ >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> +    u32 *input_fmts; >> + >> +    *num_input_fmts = 0; >> + >> +    input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), >> +                 GFP_KERNEL); >> +    if (!input_fmts) >> +        return NULL; >> + >> +    if (ctx->bus_width == 12) >> +        /* IT66121FN Datasheet specifies Little-Endian ordering */ >> +        input_fmts[0] = MEDIA_BUS_FMT_RGB888_2X12_LE; >> +    else >> +        /* TOFIX support more input bus formats in 24bit width */ >> +        input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; >> +    *num_input_fmts = 1; >> + >> +    return input_fmts; >> +} >> + >> +static void it66121_bridge_enable(struct drm_bridge *bridge) >> +{ >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> + >> +    it66121_set_mute(ctx, false); >> +} >> + >> +static void it66121_bridge_disable(struct drm_bridge *bridge) >> +{ >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> + >> +    it66121_set_mute(ctx, true); >> +} >> + >> +static >> +void it66121_bridge_mode_set(struct drm_bridge *bridge, >> +                 const struct drm_display_mode *mode, >> +                 const struct drm_display_mode *adjusted_mode) >> +{ >> +    int ret, i; >> +    u8 buf[HDMI_INFOFRAME_SIZE(AVI)]; >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> +    const u16 aviinfo_reg[HDMI_AVI_INFOFRAME_SIZE] = { >> +        IT66121_AVIINFO_DB1_REG, >> +        IT66121_AVIINFO_DB2_REG, >> +        IT66121_AVIINFO_DB3_REG, >> +        IT66121_AVIINFO_DB4_REG, >> +        IT66121_AVIINFO_DB5_REG, >> +        IT66121_AVIINFO_DB6_REG, >> +        IT66121_AVIINFO_DB7_REG, >> +        IT66121_AVIINFO_DB8_REG, >> +        IT66121_AVIINFO_DB9_REG, >> +        IT66121_AVIINFO_DB10_REG, >> +        IT66121_AVIINFO_DB11_REG, >> +        IT66121_AVIINFO_DB12_REG, >> +        IT66121_AVIINFO_DB13_REG >> +    }; >> + >> +    mutex_lock(&ctx->lock); >> + >> +    hdmi_avi_infoframe_init(&ctx->hdmi_avi_infoframe); >> + >> +    ret = drm_hdmi_avi_infoframe_from_display_mode(&ctx->hdmi_avi_infoframe, &ctx->connector, >> +                               adjusted_mode); >> +    if (ret) { >> +        DRM_ERROR("Failed to setup AVI infoframe: %d\n", ret); >> +        goto unlock; >> +    } >> + >> +    ret = hdmi_avi_infoframe_pack(&ctx->hdmi_avi_infoframe, buf, sizeof(buf)); >> +    if (ret < 0) { >> +        DRM_ERROR("Failed to pack infoframe: %d\n", ret); >> +        goto unlock; >> +    } >> + >> +    /* Write new AVI infoframe packet */ >> +    for (i = 0; i < HDMI_AVI_INFOFRAME_SIZE; i++) { >> +        if (regmap_write(ctx->regmap, aviinfo_reg[i], buf[i + HDMI_INFOFRAME_HEADER_SIZE])) >> +            goto unlock; >> +    } >> +    if (regmap_write(ctx->regmap, IT66121_AVIINFO_CSUM_REG, buf[3])) >> +        goto unlock; >> + >> +    /* Enable AVI infoframe */ >> +    if (regmap_write(ctx->regmap, IT66121_AVI_INFO_PKT_REG, >> +             IT66121_AVI_INFO_PKT_ON | IT66121_AVI_INFO_PKT_RPT)) >> +        goto unlock; >> + >> +    /* Set TX mode to HDMI */ >> +    if (regmap_write(ctx->regmap, IT66121_HDMI_MODE_REG, IT66121_HDMI_MODE_HDMI)) >> +        goto unlock; >> + >> +    if (regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, >> +                  IT66121_CLK_BANK_PWROFF_TXCLK, IT66121_CLK_BANK_PWROFF_TXCLK)) >> +        goto unlock; >> + >> +    if (it66121_configure_input(ctx)) >> +        goto unlock; >> + >> +    if (it66121_configure_afe(ctx, adjusted_mode)) >> +        goto unlock; >> + >> +    regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, IT66121_CLK_BANK_PWROFF_TXCLK, 0); >> + >> +unlock: >> +    mutex_unlock(&ctx->lock); >> +} >> + >> +static enum drm_mode_status it66121_bridge_mode_valid(struct drm_bridge *bridge, >> +                              const struct drm_display_info *info, >> +                              const struct drm_display_mode *mode) >> +{ >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> + >> +    return it66121_mode_valid(ctx, mode); >> +} >> + >> +static enum drm_connector_status it66121_bridge_detect(struct drm_bridge *bridge) >> +{ >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> + >> +    return it66121_is_hpd_detect(ctx) ? connector_status_connected >> +                      : connector_status_disconnected; >> +} >> + >> +static struct edid *it66121_bridge_get_edid(struct drm_bridge *bridge, >> +                        struct drm_connector *connector) >> +{ >> +    struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge); >> +    struct edid *edid; >> + >> +    mutex_lock(&ctx->lock); >> +    edid = drm_do_get_edid(connector, it66121_get_edid_block, ctx); >> +    mutex_unlock(&ctx->lock); >> + >> +    return edid; >> +} >> + >> +static const struct drm_bridge_funcs it66121_bridge_funcs = { >> +    .attach = it66121_bridge_attach, >> +    .enable = it66121_bridge_enable, >> +    .disable = it66121_bridge_disable, >> +    .mode_set = it66121_bridge_mode_set, >> +    .mode_valid = it66121_bridge_mode_valid, >> +    .detect = it66121_bridge_detect, >> +    .get_edid = it66121_bridge_get_edid, >> +    .atomic_get_output_bus_fmts = it66121_bridge_atomic_get_output_bus_fmts, >> +    .atomic_get_input_bus_fmts = it66121_bridge_atomic_get_input_bus_fmts, >> +}; >> + >> +static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) >> +{ >> +    int ret; >> +    unsigned int val; >> +    struct it66121_ctx *ctx = dev_id; >> +    struct device *dev = ctx->dev; >> +    bool event = false; >> + >> +    mutex_lock(&ctx->lock); >> + >> +    ret = regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val); >> +    if (ret) >> +        goto unlock; >> + >> +    if (!(val & IT66121_SYS_STATUS_ACTIVE_IRQ)) >> +        goto unlock; >> + >> +    ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); >> +    if (ret) { >> +        dev_err(dev, "Cannot read STATUS1_REG %d\n", ret); >> +    } else { >> +        if (val & IT66121_INT_STATUS1_DDC_FIFOERR) >> +            it66121_clear_ddc_fifo(ctx); >> +        if (val & (IT66121_INT_STATUS1_DDC_BUSHANG | >> +               IT66121_INT_STATUS1_DDC_NOACK)) >> +            it66121_abort_ddc_ops(ctx); >> +        if (val & IT66121_INT_STATUS1_HPD_STATUS) { >> +            regmap_write_bits(ctx->regmap, IT66121_INT_CLR1_REG, >> +                      IT66121_INT_CLR1_HPD, IT66121_INT_CLR1_HPD); >> + >> +            if (!it66121_is_hpd_detect(ctx)) { >> +                kfree(ctx->edid); >> +                ctx->edid = NULL; >> +            } >> + >> +            event = true; >> +        } >> +    } >> + >> +    regmap_write_bits(ctx->regmap, IT66121_SYS_STATUS_REG, >> +              IT66121_SYS_STATUS_CLEAR_IRQ, >> +              IT66121_SYS_STATUS_CLEAR_IRQ); >> + >> +unlock: >> +    mutex_unlock(&ctx->lock); >> + >> +    if (event) >> +        drm_helper_hpd_irq_event(ctx->bridge.dev); >> + >> +    return IRQ_HANDLED; >> +} >> + >> +static int it66121_probe(struct i2c_client *client, >> +             const struct i2c_device_id *id) >> +{ >> +    u32 vendor_ids[2], device_ids[2], revision_id; >> +    struct device_node *ep; >> +    int ret; >> +    struct it66121_ctx *ctx; >> +    struct device *dev = &client->dev; >> + >> +    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { >> +        dev_err(dev, "I2C check functionality failed.\n"); >> +        return -ENXIO; >> +    } >> + >> +    ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); >> +    if (!ep) >> +        return -EINVAL; >> + >> +    ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); >> +    if (!ctx) >> +        return -ENOMEM; >> + >> +    ctx->dev = dev; >> +    ctx->client = client; >> + >> +    of_property_read_u32(ep, "bus-width", &ctx->bus_width); >> +    of_node_put(ep); >> + >> +    if (ctx->bus_width != 12 && ctx->bus_width != 24) >> +        return -EINVAL; >> + >> +    i2c_set_clientdata(client, ctx); >> +    mutex_init(&ctx->lock); >> + >> +    ctx->supplies[0].supply = "vcn33"; >> +    ctx->supplies[1].supply = "vcn18"; >> +    ctx->supplies[2].supply = "vrf12"; >> +    ret = devm_regulator_bulk_get(ctx->dev, 3, ctx->supplies); >> +    if (ret) { >> +        dev_err(ctx->dev, "regulator_bulk failed\n"); >> +        return ret; >> +    } >> + >> +    ret = ite66121_power_on(ctx); >> +    if (ret) >> +        return ret; >> + >> +    it66121_hw_reset(ctx); >> + >> +    ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config); >> +    if (IS_ERR(ctx->regmap)) { >> +        ite66121_power_off(ctx); >> +        return PTR_ERR(ctx); >> +    } >> + >> +    regmap_read(ctx->regmap, IT66121_VENDOR_ID0_REG, &vendor_ids[0]); >> +    regmap_read(ctx->regmap, IT66121_VENDOR_ID1_REG, &vendor_ids[1]); >> +    regmap_read(ctx->regmap, IT66121_DEVICE_ID0_REG, &device_ids[0]); >> +    regmap_read(ctx->regmap, IT66121_DEVICE_ID1_REG, &device_ids[1]); >> + >> +    /* Revision is shared with DEVICE_ID1 */ >> +    revision_id = FIELD_GET(IT66121_REVISION_MASK, device_ids[1]); >> +    device_ids[1] &= IT66121_DEVICE_ID1_MASK; >> + >> +    if (vendor_ids[0] != IT66121_VENDOR_ID0 || vendor_ids[1] != IT66121_VENDOR_ID1 || >> +        device_ids[0] != IT66121_DEVICE_ID0 || device_ids[1] != IT66121_DEVICE_ID1) { >> +        ite66121_power_off(ctx); >> +        return -ENODEV; >> +    } >> + >> +    ctx->bridge.funcs = &it66121_bridge_funcs; >> +    ctx->bridge.of_node = dev->of_node; >> + >> +    ret = devm_request_threaded_irq(dev, client->irq, NULL,    it66121_irq_threaded_handler, >> +                    IRQF_SHARED | IRQF_ONESHOT, dev_name(dev), ctx); >> +    if (ret < 0) { >> +        dev_err(dev, "Failed to request irq %d:%d\n", client->irq, ret); >> +        ite66121_power_off(ctx); >> +        return ret; >> +    } >> + >> +    drm_bridge_add(&ctx->bridge); >> + >> +    dev_info(ctx->dev, "IT66121 revision %d probed\n", revision_id); >> + >> +    return 0; >> +} >> + >> +static int it66121_remove(struct i2c_client *client) >> +{ >> +    struct it66121_ctx *ctx = i2c_get_clientdata(client); >> + >> +    ite66121_power_off(ctx); >> +    drm_bridge_remove(&ctx->bridge); >> +    kfree(ctx->edid); >> +    mutex_destroy(&ctx->lock); >> + >> +    return 0; >> +} >> + >> +static const struct of_device_id it66121_dt_match[] = { >> +    { .compatible = "ite,it66121" }, >> +    { } >> +}; >> +MODULE_DEVICE_TABLE(of, it66121_dt_match); >> + >> +static const struct i2c_device_id it66121_id[] = { >> +    { "it66121", 0 }, >> +    { } >> +}; >> +MODULE_DEVICE_TABLE(i2c, it66121_id); >> + >> +static struct i2c_driver it66121_driver = { >> +    .driver = { >> +        .name    = "it66121", >> +        .of_match_table = it66121_dt_match, >> +    }, >> +    .probe = it66121_probe, >> +    .remove = it66121_remove, >> +    .id_table = it66121_id, >> +}; >> + >> +module_i2c_driver(it66121_driver); >> + >> +MODULE_AUTHOR("Phong LE"); >> +MODULE_DESCRIPTION("IT66121 HDMI transmitter driver"); >> +MODULE_LICENSE("GPL v2"); >> -- >> 2.25.1 >> > > 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=-15.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 9C845C433ED for ; Wed, 14 Apr 2021 06:17:15 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 560D6611C9 for ; Wed, 14 Apr 2021 06:17:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 560D6611C9 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BDC376E44B; Wed, 14 Apr 2021 06:17:14 +0000 (UTC) Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by gabe.freedesktop.org (Postfix) with ESMTPS id E42636E44B for ; Wed, 14 Apr 2021 06:17:13 +0000 (UTC) Received: by mail-wr1-x42b.google.com with SMTP id w4so14921563wrt.5 for ; Tue, 13 Apr 2021 23:17:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=eXGdLIcmTSbWyBBFK1pqcTD9BaUOcCFISmVmmzF0eDk=; b=JRkXrDdtDalw3JAElnMt+GKilESNHJvq14HCE3BGKEp5QGk6KVrhZFaN+dK38Hag0N mThCSsRop4mpPnSJvPbeM0E9k+kgo0urUULXIkiaX/lohra9aCdzCICi06tKuFYt6SHF l2F+felNQVgIFdZSS697TKjhMMHkrdQ00yTFow26qOtrC0xgNVIF4Mjv/+sdUhwMNLnA PzdMp7IHwlO/8m3ZIEKndO4iaOUfZEHbwd5/nrQpicThrWBhqao8lrHM6TVWAwA74w6t A/VV9WmE8x31CT3feU6hAV1OQanK7+jdRUvPTEpzHE8HwBNTBWFy1MudQnFZjuagvMQ7 3wjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=eXGdLIcmTSbWyBBFK1pqcTD9BaUOcCFISmVmmzF0eDk=; b=JU8YXKY5QMgofCYyr1Nwk3cFAyBlwXGfcN24zHOYhGDXHGElrYiw+R5EAYmuSSS4h3 1m6CqxRjwwDxFKoxZNqu5avraXFDqfw7hPXHrm5OOv3FDgsuFUu25wgNHZCaNunVCB5T YPVRcaPhVrZr7M3fKrah+juNE/jHKTyRekyMt7reJskfbfZ+NjCH3CnOLh0WUVMHCSWo SVv8xW0bV4dq695dW9qU4caNHJwffTUx5m4sPC2kZZGNS0sQxPCcu0CXz+ip+a3XMmrG ZwSX3dLbVb4uJ2VayAT71rNkQxcdCPpHOQQBidum486ve4/rbfvv5XXQbjfn4/OupfZX Znmw== X-Gm-Message-State: AOAM533NKJj1OnVhLyvaptMDAXguKqO/BS1yMt2r+BTIIKChtryU0qOY IPqiq3fGHbbPAzxKuJ6BXaxG3A== X-Google-Smtp-Source: ABdhPJx5rfekNgwKpu7OID5d92R2MShE7MCLx0c/rRfrERFTpgAmBFA7mre1fR8idfoQP0T4gnsoQQ== X-Received: by 2002:a05:6000:1549:: with SMTP id 9mr40984448wry.192.1618381032410; Tue, 13 Apr 2021 23:17:12 -0700 (PDT) Received: from Armstrongs-MacBook-Pro.local ([2a01:e0a:90c:e290:29e7:a4d9:c2b0:1adc]) by smtp.gmail.com with ESMTPSA id l7sm24346898wrb.35.2021.04.13.23.17.10 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 13 Apr 2021 23:17:11 -0700 (PDT) Subject: Re: [PATCH v3 2/3] drm: bridge: add it66121 driver To: Paul Cercueil References: <20210412154648.3719153-1-narmstrong@baylibre.com> <20210412154648.3719153-3-narmstrong@baylibre.com> From: Neil Armstrong Message-ID: <1d963840-cb96-399b-7f27-ce3eb9ad6083@baylibre.com> Date: Wed, 14 Apr 2021 08:17:09 +0200 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: Content-Language: fr X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jernej.skrabec@siol.net, jonas@kwiboo.se, robert.foss@linaro.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Phong LE , a.hajda@samsung.com, Laurent.pinchart@ideasonboard.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" SGksCgpMZSAxMy8wNC8yMDIxIMOgIDIyOjU2LCBQYXVsIENlcmN1ZWlsIGEgw6ljcml0wqA6Cj4g SGkgTmVpbCwKPiAKPiBJIGdldCBidWlsZCBmYWlsdXJlcyBsb2NhbGx5Ogo+IAo+IGRyaXZlcnMv Z3B1L2RybS9icmlkZ2UvaXRlLWl0NjYxMjEuYzogSW4gZnVuY3Rpb24g4oCYaXQ2NjEyMV9od19y ZXNldOKAmToKPiBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2l0ZS1pdDY2MTIxLmM6MjQyOjI6IGVy cm9yOiBpbXBsaWNpdCBkZWNsYXJhdGlvbiBvZiBmdW5jdGlvbiDigJhncGlvZF9zZXRfdmFsdWXi gJkgWy1XZXJyb3I9aW1wbGljaXQtZnVuY3Rpb24tZGVjbGFyYXRpb25dCj4gMjQyIHwgZ3Bpb2Rf c2V0X3ZhbHVlKGN0eC0+Z3Bpb19yZXNldCwgMSk7Cj4gwqDCoMKgIHwgXn5+fn5+fn5+fn5+fn5+ Cj4gZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9pdGUtaXQ2NjEyMS5jOiBJbiBmdW5jdGlvbiDigJhp dDY2MTIxX3Byb2Jl4oCZOgo+IGRyaXZlcnMvZ3B1L2RybS9icmlkZ2UvaXRlLWl0NjYxMjEuYzox MDE2OjE2OiBlcnJvcjogaW1wbGljaXQgZGVjbGFyYXRpb24gb2YgZnVuY3Rpb24g4oCYRklFTERf R0VU4oCZOyBkaWQgeW91IG1lYW4g4oCYRk9MTF9HRVTigJk/IFstV2Vycm9yPWltcGxpY2l0LWZ1 bmN0aW9uLWRlY2xhcmF0aW9uXQo+IDEwMTYgfCByZXZpc2lvbl9pZCA9IEZJRUxEX0dFVChJVDY2 MTIxX1JFVklTSU9OX01BU0ssIGRldmljZV9pZHNbMV0pOwo+IMKgwqDCoCB8IF5+fn5+fn5+fgo+ IMKgwqDCoCB8IEZPTExfR0VUCj4gCj4gTm90aGluZyBkaWZmaWN1bHQgdG8gZml4LCBidXQgdGhl IGluY2x1ZGVzIHNob3VsZCBiZSBhZGRlZCBub25ldGhlbGVzcy4KCkV4YWN0LCBJIGdvdCB0aGUg Q0kgYnVpbGQgZmFpbHVyZXMsIEknbGwgZml4IHRoZXNlIGZvciB2NC4KCldlcmUgeW91IGFibGUg dG8gdGVzdCBvbiB5b3VyIHNldHVwID8KVGhlIHYyIGFsd2F5cyBmb3JjZWQgRERSIG1vZGUsIHdp dGggdGhpcyB2MywgSSBhbHNvIHN3aXRjaCB0byBub3JtYWwgMjRpbnB1dCBtb2RlLCBidXQgdG90 YWxseSB1bnRlc3RlZC4KClRoYW5rcywKTmVpbAoKPiAKPiBDaGVlcnMsCj4gLVBhdWwKPiAKPiAK PiBMZSBsdW4uIDEyIGF2cmlsIDIwMjEgw6AgMTc6NDYsIE5laWwgQXJtc3Ryb25nIDxuYXJtc3Ry b25nQGJheWxpYnJlLmNvbT4gYSDDqWNyaXQgOgo+PiBGcm9tOiBQaG9uZyBMRSA8cGxlQGJheWxp YnJlLmNvbT4KPj4KPj4gVGhpcyBjb21taXQgaXMgYSBzaW1wbGUgZHJpdmVyIGZvciBicmlkZ2Ug SE1ESSBpdDY2MTIxLgo+PiBUaGUgaW5wdXQgZm9ybWF0IGlzIFJCRyBhbmQgdGhlcmUgaXMgbm8g Y29sb3IgY29udmVyc2lvbi4KPj4gQXVkaW8sIEhEQ1AgYW5kIENFQyBhcmUgbm90IHN1cHBvcnRl ZCB5ZXQuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IFBob25nIExFIDxwbGVAYmF5bGlicmUuY29tPgo+ PiBTaWduZWQtb2ZmLWJ5OiBOZWlsIEFybXN0cm9uZyA8bmFybXN0cm9uZ0BiYXlsaWJyZS5jb20+ Cj4+IC0tLQo+PiDCoGRyaXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZpZ8KgwqDCoMKgwqDCoCB8 wqDCoMKgIDggKwo+PiDCoGRyaXZlcnMvZ3B1L2RybS9icmlkZ2UvTWFrZWZpbGXCoMKgwqDCoMKg IHzCoMKgwqAgMSArCj4+IMKgZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9pdGUtaXQ2NjEyMS5jIHwg MTA4MSArKysrKysrKysrKysrKysrKysrKysrKysrKwo+PiDCoDMgZmlsZXMgY2hhbmdlZCwgMTA5 MCBpbnNlcnRpb25zKCspCj4+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9i cmlkZ2UvaXRlLWl0NjYxMjEuYwo+Pgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2Jy aWRnZS9LY29uZmlnIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29uZmlnCj4+IGluZGV4IGU0 MTEwZDZjYTdiMy4uNjkxNWMzOGZhNDU5IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0v YnJpZGdlL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29uZmlnCj4+ IEBAIC03NCw2ICs3NCwxNCBAQCBjb25maWcgRFJNX0xPTlRJVU1fTFQ5NjExVVhDCj4+IMKgwqDC oMKgwqDCoCBIRE1JIHNpZ25hbHMKPj4gwqDCoMKgwqDCoMKgIFBsZWFzZSBzYXkgWSBpZiB5b3Ug aGF2ZSBzdWNoIGhhcmR3YXJlLgo+Pgo+PiArY29uZmlnIERSTV9JVEVfSVQ2NjEyMQo+PiArwqDC oMKgIHRyaXN0YXRlICJJVEUgSVQ2NjEyMSBIRE1JIGJyaWRnZSIKPj4gK8KgwqDCoCBkZXBlbmRz IG9uIE9GCj4+ICvCoMKgwqAgc2VsZWN0IERSTV9LTVNfSEVMUEVSCj4+ICvCoMKgwqAgc2VsZWN0 IFJFR01BUF9JMkMKPj4gK8KgwqDCoCBoZWxwCj4+ICvCoMKgwqDCoMKgIFN1cHBvcnQgZm9yIElU RSBJVDY2MTIxIEhETUkgYnJpZGdlLgo+PiArCj4+IMKgY29uZmlnIERSTV9MVkRTX0NPREVDCj4+ IMKgwqDCoMKgIHRyaXN0YXRlICJUcmFuc3BhcmVudCBMVkRTIGVuY29kZXJzIGFuZCBkZWNvZGVy cyBzdXBwb3J0Igo+PiDCoMKgwqDCoCBkZXBlbmRzIG9uIE9GCj4+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vYnJpZGdlL01ha2VmaWxlIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9NYWtl ZmlsZQo+PiBpbmRleCA4NmU3YWNjNzZmOGQuLjRmNzI1NzUzMTE3YyAxMDA2NDQKPj4gLS0tIGEv ZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZQo+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0v YnJpZGdlL01ha2VmaWxlCj4+IEBAIC0yNCw2ICsyNCw3IEBAIG9iai0kKENPTkZJR19EUk1fVElf U042NURTSTg2KSArPSB0aS1zbjY1ZHNpODYubwo+PiDCoG9iai0kKENPTkZJR19EUk1fVElfVEZQ NDEwKSArPSB0aS10ZnA0MTAubwo+PiDCoG9iai0kKENPTkZJR19EUk1fVElfVFBEMTJTMDE1KSAr PSB0aS10cGQxMnMwMTUubwo+PiDCoG9iai0kKENPTkZJR19EUk1fTldMX01JUElfRFNJKSArPSBu d2wtZHNpLm8KPj4gK29iai0kKENPTkZJR19EUk1fSVRFX0lUNjYxMjEpICs9IGl0ZS1pdDY2MTIx Lm8KPj4KPj4gwqBvYmoteSArPSBhbmFsb2dpeC8KPj4gwqBvYmoteSArPSBjYWRlbmNlLwo+PiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9pdGUtaXQ2NjEyMS5jIGIvZHJpdmVy cy9ncHUvZHJtL2JyaWRnZS9pdGUtaXQ2NjEyMS5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+ IGluZGV4IDAwMDAwMDAwMDAwMC4uNzNhZjQ5YjI5ZGZhCj4+IC0tLSAvZGV2L251bGwKPj4gKysr IGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9pdGUtaXQ2NjEyMS5jCj4+IEBAIC0wLDAgKzEsMTA4 MSBAQAo+PiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+PiArLyoK Pj4gKyAqIENvcHlyaWdodCAoQykgMjAyMCBCYXlMaWJyZSwgU0FTCj4+ICsgKiBBdXRob3I6IFBo b25nIExFIDxwbGVAYmF5bGlicmUuY29tPgo+PiArICogQ29weXJpZ2h0IChDKSAyMDE4LTIwMTks IEFydGVtIE15Z2FpZXYKPj4gKyAqIENvcHlyaWdodCAoQykgMjAxNywgRnJlc2NvIExvZ2ljLCBJ bmNvcnBvcmF0ZWQuCj4+ICsgKgo+PiArICovCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC9kZXZp Y2UuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pbnRl cnJ1cHQuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4gKyNpbmNsdWRlIDxsaW51 eC9wcm9wZXJ0eS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29mX2dyYXBoLmg+Cj4+ICsjaW5jbHVk ZSA8bGludXgvcGluY3RybC9jb25zdW1lci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5o Pgo+PiArI2luY2x1ZGUgPGxpbnV4L3JlZ3VsYXRvci9jb25zdW1lci5oPgo+PiArCj4+ICsjaW5j bHVkZSA8ZHJtL2RybV9hdG9taWNfaGVscGVyLmg+Cj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9icmlk Z2UuaD4KPj4gKyNpbmNsdWRlIDxkcm0vZHJtX2NydGNfaGVscGVyLmg+Cj4+ICsjaW5jbHVkZSA8 ZHJtL2RybV9lZGlkLmg+Cj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9tb2Rlcy5oPgo+PiArI2luY2x1 ZGUgPGRybS9kcm1fcHJpbnQuaD4KPj4gKyNpbmNsdWRlIDxkcm0vZHJtX3Byb2JlX2hlbHBlci5o Pgo+PiArCj4+ICsjZGVmaW5lIElUNjYxMjFfVkVORE9SX0lEMF9SRUfCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIDB4MDAKPj4gKyNkZWZpbmUgSVQ2NjEyMV9WRU5ET1JfSUQxX1JFR8KgwqDCoMKgwqDC oMKgwqDCoMKgwqAgMHgwMQo+PiArI2RlZmluZSBJVDY2MTIxX0RFVklDRV9JRDBfUkVHwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAweDAyCj4+ICsjZGVmaW5lIElUNjYxMjFfREVWSUNFX0lEMV9SRUfC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MDMKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIxX1ZFTkRP Ul9JRDDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4NTQKPj4gKyNkZWZpbmUgSVQ2NjEyMV9WRU5E T1JfSUQxwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAweDQ5Cj4+ICsjZGVmaW5lIElUNjYxMjFfREVW SUNFX0lEMMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHgxMgo+PiArI2RlZmluZSBJVDY2MTIxX0RF VklDRV9JRDHCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MDYKPj4gKyNkZWZpbmUgSVQ2NjEyMV9S RVZJU0lPTl9NQVNLwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRU5NQVNLKDcsIDQpCj4+ICsjZGVm aW5lIElUNjYxMjFfREVWSUNFX0lEMV9NQVNLwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRU5NQVNL KDMsIDApCj4+ICsKPj4gKyNkZWZpbmUgSVQ2NjEyMV9NQVNURVJfU0VMX1JFR8KgwqDCoMKgwqDC oMKgwqDCoMKgwqAgMHgxMAo+PiArI2RlZmluZSBJVDY2MTIxX01BU1RFUl9TRUxfSE9TVMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgQklUKDApCj4+ICsKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BRkVfRFJW X1JFR8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHg2MQo+PiArI2RlZmluZSBJVDY2MTIxX0FGRV9E UlZfUlNUwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoNCkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9B RkVfRFJWX1BXRMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQklUKDUpCj4+ICsKPj4gKyNkZWZpbmUg SVQ2NjEyMV9JTlBVVF9NT0RFX1JFR8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHg3MAo+PiArI2Rl ZmluZSBJVDY2MTIxX0lOUFVUX01PREVfUkdCwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoMCA8PCA2 KQo+PiArI2RlZmluZSBJVDY2MTIxX0lOUFVUX01PREVfWVVWNDIywqDCoMKgwqDCoMKgwqAgQklU KDYpCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5QVVRfTU9ERV9ZVVY0NDTCoMKgwqDCoMKgwqDCoCAo MiA8PCA2KQo+PiArI2RlZmluZSBJVDY2MTIxX0lOUFVUX01PREVfQ0NJUjY1NsKgwqDCoMKgwqDC oMKgIEJJVCg0KQo+PiArI2RlZmluZSBJVDY2MTIxX0lOUFVUX01PREVfU1lOQ0VNQsKgwqDCoMKg wqDCoMKgIEJJVCgzKQo+PiArI2RlZmluZSBJVDY2MTIxX0lOUFVUX01PREVfRERSwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBCSVQoMikKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIxX0lOUFVUX0NTQ19S RUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4NzIKPj4gKyNkZWZpbmUgSVQ2NjEyMV9JTlBVVF9D U0NfRU5ESVRIRVLCoMKgwqDCoMKgwqDCoCBCSVQoNykKPj4gKyNkZWZpbmUgSVQ2NjEyMV9JTlBV VF9DU0NfRU5VREZJTFRFUsKgwqDCoMKgwqDCoMKgIEJJVCg2KQo+PiArI2RlZmluZSBJVDY2MTIx X0lOUFVUX0NTQ19ETkZSRUVfR0/CoMKgwqDCoMKgwqDCoCBCSVQoNSkKPj4gKyNkZWZpbmUgSVQ2 NjEyMV9JTlBVVF9DU0NfUkdCX1RPX1lVVsKgwqDCoMKgwqDCoMKgIDB4MDIKPj4gKyNkZWZpbmUg SVQ2NjEyMV9JTlBVVF9DU0NfWVVWX1RPX1JHQsKgwqDCoMKgwqDCoMKgIDB4MDMKPj4gKyNkZWZp bmUgSVQ2NjEyMV9JTlBVVF9DU0NfTk9fQ09OVsKgwqDCoMKgwqDCoMKgIDB4MDAKPj4gKwo+PiAr I2RlZmluZSBJVDY2MTIxX0FGRV9YUF9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4NjIKPj4g KyNkZWZpbmUgSVQ2NjEyMV9BRkVfWFBfR0FJTkJJVMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQklU KDcpCj4+ICsjZGVmaW5lIElUNjYxMjFfQUZFX1hQX1BXRFBMTMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgQklUKDYpCj4+ICsjZGVmaW5lIElUNjYxMjFfQUZFX1hQX0VOScKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgQklUKDUpCj4+ICsjZGVmaW5lIElUNjYxMjFfQUZFX1hQX0VOT8KgwqDCoMKgwqDCoMKg wqDCoMKgwqAgQklUKDQpCj4+ICsjZGVmaW5lIElUNjYxMjFfQUZFX1hQX1JFU0VUQsKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgQklUKDMpCj4+ICsjZGVmaW5lIElUNjYxMjFfQUZFX1hQX1BXREnCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgyKQo+PiArCj4+ICsjZGVmaW5lIElUNjYxMjFfQUZFX0lQ X1JFR8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHg2NAo+PiArI2RlZmluZSBJVDY2MTIxX0FGRV9J UF9HQUlOQklUwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoNykKPj4gKyNkZWZpbmUgSVQ2NjEy MV9BRkVfSVBfUFdEUExMwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoNikKPj4gKyNkZWZpbmUg SVQ2NjEyMV9BRkVfSVBfQ0tTRUxfMDXCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgwIDw8IDQpCj4+ ICsjZGVmaW5lIElUNjYxMjFfQUZFX0lQX0NLU0VMXzHCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEJJ VCg0KQo+PiArI2RlZmluZSBJVDY2MTIxX0FGRV9JUF9DS1NFTF8ywqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAoMiA8PCA0KQo+PiArI2RlZmluZSBJVDY2MTIxX0FGRV9JUF9DS1NFTF8yT1I0wqDCoMKg wqDCoMKgwqAgKDMgPDwgNCkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BRkVfSVBfRVIwwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBCSVQoMykKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BRkVfSVBfUkVTRVRCwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMikKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BRkVfSVBfRU5D wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMSkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BRkVfSVBf RUMxwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMCkKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIx X0FGRV9YUF9FQzFfUkVHwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAweDY4Cj4+ICsjZGVmaW5lIElU NjYxMjFfQUZFX1hQX0VDMV9MT1dDTEvCoMKgwqDCoMKgwqDCoCBCSVQoNCkKPj4gKwo+PiArI2Rl ZmluZSBJVDY2MTIxX1NXX1JTVF9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MDQKPj4gKyNk ZWZpbmUgSVQ2NjEyMV9TV19SU1RfUkVGwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoNSkKPj4g KyNkZWZpbmUgSVQ2NjEyMV9TV19SU1RfQVJFRsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQklUKDQp Cj4+ICsjZGVmaW5lIElUNjYxMjFfU1dfUlNUX1ZJRMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQklU KDMpCj4+ICsjZGVmaW5lIElUNjYxMjFfU1dfUlNUX0FVRMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg QklUKDIpCj4+ICsjZGVmaW5lIElUNjYxMjFfU1dfUlNUX0hEQ1DCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIEJJVCgwKQo+PiArCj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX0NPTU1BTkRfUkVHwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAweDE1Cj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX0NPTU1BTkRfQlVS U1RfUkVBRMKgwqDCoMKgwqDCoMKgIDB4MAo+PiArI2RlZmluZSBJVDY2MTIxX0REQ19DT01NQU5E X0VESURfUkVBRMKgwqDCoMKgwqDCoMKgIDB4Mwo+PiArI2RlZmluZSBJVDY2MTIxX0REQ19DT01N QU5EX0ZJRk9fQ0xSwqDCoMKgwqDCoMKgwqAgMHg5Cj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX0NP TU1BTkRfU0NMX1BVTFNFwqDCoMKgwqDCoMKgwqAgMHhBCj4+ICsjZGVmaW5lIElUNjYxMjFfRERD X0NPTU1BTkRfQUJPUlTCoMKgwqDCoMKgwqDCoCAweEYKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIx X0hEQ1BfUkVHwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAweDIwCj4+ICsjZGVmaW5lIElUNjYxMjFf SERDUF9DUERFU0lSRUTCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgwKQo+PiArI2RlZmluZSBJ VDY2MTIxX0hEQ1BfRU4xUDFGRUFUwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMSkKPj4gKwo+ PiArI2RlZmluZSBJVDY2MTIxX0lOVF9TVEFUVVMxX1JFR8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAg MHgwNgo+PiArI2RlZmluZSBJVDY2MTIxX0lOVF9TVEFUVVMxX0FVRF9PVkbCoMKgwqDCoMKgwqDC oCBCSVQoNykKPj4gKyNkZWZpbmUgSVQ2NjEyMV9JTlRfU1RBVFVTMV9ERENfTk9BQ0vCoMKgwqDC oMKgwqDCoCBCSVQoNSkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9JTlRfU1RBVFVTMV9ERENfRklGT0VS UsKgwqDCoMKgwqDCoMKgIEJJVCg0KQo+PiArI2RlZmluZSBJVDY2MTIxX0lOVF9TVEFUVVMxX0RE Q19CVVNIQU5HwqDCoMKgwqDCoMKgwqAgQklUKDIpCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5UX1NU QVRVUzFfUlhfU0VOU19TVEFUVVPCoMKgwqAgQklUKDEpCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5U X1NUQVRVUzFfSFBEX1NUQVRVU8KgwqDCoMKgwqDCoMKgIEJJVCgwKQo+PiArCj4+ICsjZGVmaW5l IElUNjYxMjFfRERDX0hFQURFUl9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MTEKPj4gKyNk ZWZpbmUgSVQ2NjEyMV9ERENfSEVBREVSX0hEQ1DCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4NzQK Pj4gKyNkZWZpbmUgSVQ2NjEyMV9ERENfSEVBREVSX0VESUTCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IDB4QTAKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIxX0REQ19PRkZTRVRfUkVHwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCAweDEyCj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX0JZVEVfUkVHwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAweDEzCj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX1NFR01FTlRfUkVHwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAweDE0Cj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX1JEX0ZJRk9f UkVHwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAweDE3Cj4+ICsKPj4gKyNkZWZpbmUgSVQ2NjEyMV9D TEtfQkFOS19SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MEYKPj4gKyNkZWZpbmUgSVQ2NjEy MV9DTEtfQkFOS19QV1JPRkZfUkNMS8KgwqDCoMKgwqDCoMKgIEJJVCg2KQo+PiArI2RlZmluZSBJ VDY2MTIxX0NMS19CQU5LX1BXUk9GRl9BQ0xLwqDCoMKgwqDCoMKgwqAgQklUKDUpCj4+ICsjZGVm aW5lIElUNjYxMjFfQ0xLX0JBTktfUFdST0ZGX1RYQ0xLwqDCoMKgwqDCoMKgwqAgQklUKDQpCj4+ ICsjZGVmaW5lIElUNjYxMjFfQ0xLX0JBTktfUFdST0ZGX0NSQ0xLwqDCoMKgwqDCoMKgwqAgQklU KDMpCj4+ICsjZGVmaW5lIElUNjYxMjFfQ0xLX0JBTktfMMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg MAo+PiArI2RlZmluZSBJVDY2MTIxX0NMS19CQU5LXzHCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDEK Pj4gKwo+PiArI2RlZmluZSBJVDY2MTIxX0lOVF9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgMHgwNQo+PiArI2RlZmluZSBJVDY2MTIxX0lOVF9BQ1RJVkVfSElHSMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgQklUKDcpCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5UX09QRU5fRFJBSU7CoMKg wqDCoMKgwqDCoMKgwqDCoMKgIEJJVCg2KQo+PiArI2RlZmluZSBJVDY2MTIxX0lOVF9UWF9DTEtf T0ZGwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMCkKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIx X0lOVF9NQVNLMV9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MDkKPj4gKyNkZWZpbmUgSVQ2 NjEyMV9JTlRfTUFTSzFfQVVEX09WRsKgwqDCoMKgwqDCoMKgIEJJVCg3KQo+PiArI2RlZmluZSBJ VDY2MTIxX0lOVF9NQVNLMV9ERENfTk9BQ0vCoMKgwqDCoMKgwqDCoCBCSVQoNSkKPj4gKyNkZWZp bmUgSVQ2NjEyMV9JTlRfTUFTSzFfRERDX0ZJRk9FUlLCoMKgwqDCoMKgwqDCoCBCSVQoNCkKPj4g KyNkZWZpbmUgSVQ2NjEyMV9JTlRfTUFTSzFfRERDX0JVU0hBTkfCoMKgwqDCoMKgwqDCoCBCSVQo MikKPj4gKyNkZWZpbmUgSVQ2NjEyMV9JTlRfTUFTSzFfUlhfU0VOU8KgwqDCoMKgwqDCoMKgIEJJ VCgxKQo+PiArI2RlZmluZSBJVDY2MTIxX0lOVF9NQVNLMV9IUETCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIEJJVCgwKQo+PiArCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5UX0NMUjFfUkVHwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAweDBDCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5UX0NMUjFfUEtUQUNQwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoNykKPj4gKyNkZWZpbmUgSVQ2NjEyMV9JTlRfQ0xSMV9Q S1ROVUxMwqDCoMKgwqDCoMKgwqAgQklUKDYpCj4+ICsjZGVmaW5lIElUNjYxMjFfSU5UX0NMUjFf UEtUR0VOwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoNSkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9J TlRfQ0xSMV9LU1ZMSVNUQ0hLwqDCoMKgwqDCoMKgwqAgQklUKDQpCj4+ICsjZGVmaW5lIElUNjYx MjFfSU5UX0NMUjFfQVVUSERPTkXCoMKgwqDCoMKgwqDCoCBCSVQoMykKPj4gKyNkZWZpbmUgSVQ2 NjEyMV9JTlRfQ0xSMV9BVVRIRkFJTMKgwqDCoMKgwqDCoMKgIEJJVCgyKQo+PiArI2RlZmluZSBJ VDY2MTIxX0lOVF9DTFIxX1JYX1NFTlPCoMKgwqDCoMKgwqDCoCBCSVQoMSkKPj4gKyNkZWZpbmUg SVQ2NjEyMV9JTlRfQ0xSMV9IUETCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgwKQo+PiArCj4+ ICsjZGVmaW5lIElUNjYxMjFfQVZfTVVURV9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4QzEK Pj4gKyNkZWZpbmUgSVQ2NjEyMV9BVl9NVVRFX09OwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQo MCkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BVl9NVVRFX0JMVUVTQ1LCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIEJJVCgxKQo+PiArCj4+ICsjZGVmaW5lIElUNjYxMjFfUEtUX0dFTl9DVFJMX1JFR8KgwqDC oMKgwqDCoMKgIDB4QzYKPj4gKyNkZWZpbmUgSVQ2NjEyMV9QS1RfR0VOX0NUUkxfT07CoMKgwqDC oMKgwqDCoMKgwqDCoMKgIEJJVCgwKQo+PiArI2RlZmluZSBJVDY2MTIxX1BLVF9HRU5fQ1RSTF9S UFTCoMKgwqDCoMKgwqDCoCBCSVQoMSkKPj4gKwo+PiArI2RlZmluZSBJVDY2MTIxX0FWSUlORk9f REIxX1JFR8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHgxNTgKPj4gKyNkZWZpbmUgSVQ2NjEyMV9B VklJTkZPX0RCMl9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MTU5Cj4+ICsjZGVmaW5lIElU NjYxMjFfQVZJSU5GT19EQjNfUkVHwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAweDE1QQo+PiArI2Rl ZmluZSBJVDY2MTIxX0FWSUlORk9fREI0X1JFR8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHgxNUIK Pj4gKyNkZWZpbmUgSVQ2NjEyMV9BVklJTkZPX0RCNV9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IDB4MTVDCj4+ICsjZGVmaW5lIElUNjYxMjFfQVZJSU5GT19DU1VNX1JFR8KgwqDCoMKgwqDCoMKg IDB4MTVECj4+ICsjZGVmaW5lIElUNjYxMjFfQVZJSU5GT19EQjZfUkVHwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCAweDE1RQo+PiArI2RlZmluZSBJVDY2MTIxX0FWSUlORk9fREI3X1JFR8KgwqDCoMKg wqDCoMKgwqDCoMKgwqAgMHgxNUYKPj4gKyNkZWZpbmUgSVQ2NjEyMV9BVklJTkZPX0RCOF9SRUfC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MTYwCj4+ICsjZGVmaW5lIElUNjYxMjFfQVZJSU5GT19E QjlfUkVHwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAweDE2MQo+PiArI2RlZmluZSBJVDY2MTIxX0FW SUlORk9fREIxMF9SRUfCoMKgwqDCoMKgwqDCoCAweDE2Mgo+PiArI2RlZmluZSBJVDY2MTIxX0FW SUlORk9fREIxMV9SRUfCoMKgwqDCoMKgwqDCoCAweDE2Mwo+PiArI2RlZmluZSBJVDY2MTIxX0FW SUlORk9fREIxMl9SRUfCoMKgwqDCoMKgwqDCoCAweDE2NAo+PiArI2RlZmluZSBJVDY2MTIxX0FW SUlORk9fREIxM19SRUfCoMKgwqDCoMKgwqDCoCAweDE2NQo+PiArCj4+ICsjZGVmaW5lIElUNjYx MjFfQVZJX0lORk9fUEtUX1JFR8KgwqDCoMKgwqDCoMKgIDB4Q0QKPj4gKyNkZWZpbmUgSVQ2NjEy MV9BVklfSU5GT19QS1RfT07CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgwKQo+PiArI2RlZmlu ZSBJVDY2MTIxX0FWSV9JTkZPX1BLVF9SUFTCoMKgwqDCoMKgwqDCoCBCSVQoMSkKPj4gKwo+PiAr I2RlZmluZSBJVDY2MTIxX0hETUlfTU9ERV9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4QzAK Pj4gKyNkZWZpbmUgSVQ2NjEyMV9IRE1JX01PREVfSERNScKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg QklUKDApCj4+ICsKPj4gKyNkZWZpbmUgSVQ2NjEyMV9TWVNfU1RBVFVTX1JFR8KgwqDCoMKgwqDC oMKgwqDCoMKgwqAgMHgwRQo+PiArI2RlZmluZSBJVDY2MTIxX1NZU19TVEFUVVNfQUNUSVZFX0lS UcKgwqDCoMKgwqDCoMKgIEJJVCg3KQo+PiArI2RlZmluZSBJVDY2MTIxX1NZU19TVEFUVVNfSFBE RVRFQ1TCoMKgwqDCoMKgwqDCoCBCSVQoNikKPj4gKyNkZWZpbmUgSVQ2NjEyMV9TWVNfU1RBVFVT X1NFTkRFQ1RFQ1TCoMKgwqDCoMKgwqDCoCBCSVQoNSkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9TWVNf U1RBVFVTX1ZJRF9TVEFCTEXCoMKgwqDCoMKgwqDCoCBCSVQoNCkKPj4gKyNkZWZpbmUgSVQ2NjEy MV9TWVNfU1RBVFVTX0FVRF9DVFNfQ0xSwqDCoMKgwqDCoMKgwqAgQklUKDEpCj4+ICsjZGVmaW5l IElUNjYxMjFfU1lTX1NUQVRVU19DTEVBUl9JUlHCoMKgwqDCoMKgwqDCoCBCSVQoMCkKPj4gKwo+ PiArI2RlZmluZSBJVDY2MTIxX0REQ19TVEFUVVNfUkVHwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAw eDE2Cj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX1NUQVRVU19UWF9ET05FwqDCoMKgwqDCoMKgwqAg QklUKDcpCj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX1NUQVRVU19BQ1RJVkXCoMKgwqDCoMKgwqDC oCBCSVQoNikKPj4gKyNkZWZpbmUgSVQ2NjEyMV9ERENfU1RBVFVTX05PQUNLwqDCoMKgwqDCoMKg wqAgQklUKDUpCj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX1NUQVRVU19XQUlUX0JVU8KgwqDCoMKg wqDCoMKgIEJJVCg0KQo+PiArI2RlZmluZSBJVDY2MTIxX0REQ19TVEFUVVNfQVJCSV9MT1NFwqDC oMKgwqDCoMKgwqAgQklUKDMpCj4+ICsjZGVmaW5lIElUNjYxMjFfRERDX1NUQVRVU19GSUZPX0ZV TEzCoMKgwqDCoMKgwqDCoCBCSVQoMikKPj4gKyNkZWZpbmUgSVQ2NjEyMV9ERENfU1RBVFVTX0ZJ Rk9fRU1QVFnCoMKgwqDCoMKgwqDCoCBCSVQoMSkKPj4gKyNkZWZpbmUgSVQ2NjEyMV9ERENfU1RB VFVTX0ZJRk9fVkFMSUTCoMKgwqDCoMKgwqDCoCBCSVQoMCkKPj4gKwo+PiArI2RlZmluZSBJVDY2 MTIxX0VESURfU0xFRVBfVVPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDIwMDAwCj4+ICsjZGVmaW5l IElUNjYxMjFfRURJRF9USU1FT1VUX1VTwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAyMDAwMDAKPj4g KyNkZWZpbmUgSVQ2NjEyMV9FRElEX0ZJRk9fU0laRcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMzIK Pj4gKyNkZWZpbmUgSVQ2NjEyMV9BRkVfQ0xLX0hJR0jCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDgw MDAwIC8qIEtoeiAqLwo+PiArCj4+ICtzdHJ1Y3QgaXQ2NjEyMV9jdHggewo+PiArwqDCoMKgIHN0 cnVjdCByZWdtYXAgKnJlZ21hcDsKPj4gK8KgwqDCoCBzdHJ1Y3QgZHJtX2JyaWRnZSBicmlkZ2U7 Cj4+ICvCoMKgwqAgc3RydWN0IGRybV9jb25uZWN0b3IgY29ubmVjdG9yOwo+PiArwqDCoMKgIHN0 cnVjdCBkZXZpY2UgKmRldjsKPj4gK8KgwqDCoCBzdHJ1Y3QgZ3Bpb19kZXNjICpncGlvX3Jlc2V0 Owo+PiArwqDCoMKgIHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7Cj4+ICvCoMKgwqAgc3RydWN0 IHJlZ3VsYXRvcl9idWxrX2RhdGEgc3VwcGxpZXNbM107Cj4+ICvCoMKgwqAgdTMyIGJ1c193aWR0 aDsKPj4gK8KgwqDCoCBzdHJ1Y3QgbXV0ZXggbG9jazsgLyogUHJvdGVjdHMgZmllbGRzIGJlbG93 IGFuZCBkZXZpY2UgcmVnaXN0ZXJzICovCj4+ICvCoMKgwqAgc3RydWN0IGVkaWQgKmVkaWQ7Cj4+ ICvCoMKgwqAgc3RydWN0IGhkbWlfYXZpX2luZm9mcmFtZSBoZG1pX2F2aV9pbmZvZnJhbWU7Cj4+ ICt9Owo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9yYW5nZV9jZmcgaXQ2NjEy MV9yZWdtYXBfYmFua3NbXSA9IHsKPj4gK8KgwqDCoCB7Cj4+ICvCoMKgwqDCoMKgwqDCoCAubmFt ZSA9ICJpdDY2MTIxIiwKPj4gK8KgwqDCoMKgwqDCoMKgIC5yYW5nZV9taW4gPSAweDAwLAo+PiAr wqDCoMKgwqDCoMKgwqAgLnJhbmdlX21heCA9IDB4MUZGLAo+PiArwqDCoMKgwqDCoMKgwqAgLnNl bGVjdG9yX3JlZyA9IElUNjYxMjFfQ0xLX0JBTktfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqAgLnNl bGVjdG9yX21hc2sgPSAweDEsCj4+ICvCoMKgwqDCoMKgwqDCoCAuc2VsZWN0b3Jfc2hpZnQgPSAw LAo+PiArwqDCoMKgwqDCoMKgwqAgLndpbmRvd19zdGFydCA9IDB4MDAsCj4+ICvCoMKgwqDCoMKg wqDCoCAud2luZG93X2xlbiA9IDB4MTMwLAo+PiArwqDCoMKgIH0sCj4+ICt9Owo+PiArCj4+ICtz dGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9jb25maWcgaXQ2NjEyMV9yZWdtYXBfY29uZmlnID0g ewo+PiArwqDCoMKgIC52YWxfYml0cyA9IDgsCj4+ICvCoMKgwqAgLnJlZ19iaXRzID0gOCwKPj4g K8KgwqDCoCAubWF4X3JlZ2lzdGVyID0gMHgxRkYsCj4+ICvCoMKgwqAgLnJhbmdlcyA9IGl0NjYx MjFfcmVnbWFwX2JhbmtzLAo+PiArwqDCoMKgIC5udW1fcmFuZ2VzID0gQVJSQVlfU0laRShpdDY2 MTIxX3JlZ21hcF9iYW5rcyksCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgdm9pZCBpdDY2MTIxX2h3 X3Jlc2V0KHN0cnVjdCBpdDY2MTIxX2N0eCAqY3R4KQo+PiArewo+PiArwqDCoMKgIGdwaW9kX3Nl dF92YWx1ZShjdHgtPmdwaW9fcmVzZXQsIDEpOwo+PiArwqDCoMKgIG1zbGVlcCgyMCk7Cj4+ICvC oMKgwqAgZ3Bpb2Rfc2V0X3ZhbHVlKGN0eC0+Z3Bpb19yZXNldCwgMCk7Cj4+ICt9Cj4+ICsKPj4g K3N0YXRpYyBpbnQgaXRlNjYxMjFfcG93ZXJfb24oc3RydWN0IGl0NjYxMjFfY3R4ICpjdHgpCj4+ ICt7Cj4+ICvCoMKgwqAgcmV0dXJuIHJlZ3VsYXRvcl9idWxrX2VuYWJsZShBUlJBWV9TSVpFKGN0 eC0+c3VwcGxpZXMpLCBjdHgtPnN1cHBsaWVzKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBp dGU2NjEyMV9wb3dlcl9vZmYoc3RydWN0IGl0NjYxMjFfY3R4ICpjdHgpCj4+ICt7Cj4+ICvCoMKg wqAgcmV0dXJuIHJlZ3VsYXRvcl9idWxrX2Rpc2FibGUoQVJSQVlfU0laRShjdHgtPnN1cHBsaWVz KSwgY3R4LT5zdXBwbGllcyk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaXQ2NjEyMV9wcmVh bWJsZV9kZGMoc3RydWN0IGl0NjYxMjFfY3R4ICpjdHgpCj4+ICt7Cj4+ICvCoMKgwqAgcmV0dXJu IHJlZ21hcF93cml0ZShjdHgtPnJlZ21hcCwgSVQ2NjEyMV9NQVNURVJfU0VMX1JFRywKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX01BU1RFUl9TRUxfSE9TVCk7Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaXQ2NjEyMV9maXJlX2FmZShzdHJ1Y3QgaXQ2NjEyMV9j dHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCByZXR1cm4gcmVnbWFwX3dyaXRlKGN0eC0+cmVnbWFw LCBJVDY2MTIxX0FGRV9EUlZfUkVHLCAwKTsKPj4gK30KPj4gKwo+PiArLyogVE9GSVg6IEhhbmRs ZSBZQ2JDciBJbnB1dCAmIE91dHB1dCAqLwo+PiArc3RhdGljIGludCBpdDY2MTIxX2NvbmZpZ3Vy ZV9pbnB1dChzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBpbnQgcmV0 Owo+PiArwqDCoMKgIHU4IG1vZGUgPSBJVDY2MTIxX0lOUFVUX01PREVfUkdCOwo+PiArCj4+ICvC oMKgwqAgaWYgKGN0eC0+YnVzX3dpZHRoID09IDEyKQo+PiArwqDCoMKgwqDCoMKgwqAgbW9kZSB8 PSBJVDY2MTIxX0lOUFVUX01PREVfRERSOwo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFwX3dy aXRlKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0lOUFVUX01PREVfUkVHLCBtb2RlKTsKPj4gK8KgwqDC oCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKg IHJldHVybiByZWdtYXBfd3JpdGUoY3R4LT5yZWdtYXAsIElUNjYxMjFfSU5QVVRfQ1NDX1JFRywg SVQ2NjEyMV9JTlBVVF9DU0NfTk9fQ09OVik7Cj4+ICt9Cj4+ICsKPj4gKy8qKgo+PiArICogaXQ2 NjEyMV9jb25maWd1cmVfYWZlKCkgLSBDb25maWd1cmUgdGhlIGFuYWxvZyBmcm9udCBlbmQKPj4g KyAqIEBjdHg6IGl0NjYxMjFfY3R4IG9iamVjdAo+PiArICogQG1vZGU6IG1vZGUgdG8gY29uZmln dXJlCj4+ICsgKgo+PiArICogUkVUVVJOUzoKPj4gKyAqIHplcm8gaWYgc3VjY2VzcywgYSBuZWdh dGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KPj4gKyAqLwo+PiArc3RhdGljIGludCBpdDY2MTIx X2NvbmZpZ3VyZV9hZmUoc3RydWN0IGl0NjYxMjFfY3R4ICpjdHgsCj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBjb25zdCBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSkK Pj4gK3sKPj4gK8KgwqDCoCBpbnQgcmV0Owo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFwX3dy aXRlKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0FGRV9EUlZfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FGRV9EUlZfUlNUKTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+ PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKgIGlmIChtb2RlLT5j bG9jayA+IElUNjYxMjFfQUZFX0NMS19ISUdIKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXQgPSBy ZWdtYXBfd3JpdGVfYml0cyhjdHgtPnJlZ21hcCwgSVQ2NjEyMV9BRkVfWFBfUkVHLAo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9BRkVfWFBfR0FJTkJJ VCB8Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FG RV9YUF9FTk8sCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2 MTIxX0FGRV9YUF9HQUlOQklUKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKgIHJl dCA9IHJlZ21hcF93cml0ZV9iaXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0FGRV9JUF9SRUcsCj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FGRV9JUF9H QUlOQklUIHwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYx MjFfQUZFX0lQX0VSMCB8Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBJVDY2MTIxX0FGRV9JUF9FQzEsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBJVDY2MTIxX0FGRV9JUF9HQUlOQklUKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChy ZXQpCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDC oMKgwqDCoMKgIHJldCA9IHJlZ21hcF93cml0ZV9iaXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0FG RV9YUF9FQzFfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg SVQ2NjEyMV9BRkVfWFBfRUMxX0xPV0NMSywgMHg4MCk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAo cmV0KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiArwqDCoMKgIH0g ZWxzZSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXQgPSByZWdtYXBfd3JpdGVfYml0cyhjdHgtPnJl Z21hcCwgSVQ2NjEyMV9BRkVfWFBfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgSVQ2NjEyMV9BRkVfWFBfR0FJTkJJVCB8Cj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FGRV9YUF9FTk8sCj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FGRV9YUF9FTk8pOwo+PiArwqDC oMKgwqDCoMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJl dDsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5y ZWdtYXAsIElUNjYxMjFfQUZFX0lQX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIElUNjYxMjFfQUZFX0lQX0dBSU5CSVQgfAo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9BRkVfSVBfRVIwIHwKPj4gK8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfQUZFX0lQX0VDMSwgSVQ2NjEy MV9BRkVfSVBfRVIwIHwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IElUNjYxMjFfQUZFX0lQX0VDMSk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAocmV0KQo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBy ZXQgPSByZWdtYXBfd3JpdGVfYml0cyhjdHgtPnJlZ21hcCwgSVQ2NjEyMV9BRkVfWFBfRUMxX1JF RywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfQUZF X1hQX0VDMV9MT1dDTEssCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBJVDY2MTIxX0FGRV9YUF9FQzFfTE9XQ0xLKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChyZXQp Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICvCoMKgwqAgfQo+PiAr Cj4+ICvCoMKgwqAgLyogQ2xlYXIgcmVzZXQgZmxhZ3MgKi8KPj4gK8KgwqDCoCByZXQgPSByZWdt YXBfd3JpdGVfYml0cyhjdHgtPnJlZ21hcCwgSVQ2NjEyMV9TV19SU1RfUkVHLAo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfU1dfUlNUX1JFRiB8IElUNjYxMjFfU1df UlNUX1ZJRCwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB+KElUNjYxMjFfU1df UlNUX1JFRiB8IElUNjYxMjFfU1dfUlNUX1ZJRCkgJgo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIDB4RkYpOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoCBy ZXR1cm4gcmV0Owo+PiArCj4+ICvCoMKgwqAgcmV0dXJuIGl0NjYxMjFfZmlyZV9hZmUoY3R4KTsK Pj4gK30KPj4gKwo+PiArc3RhdGljIGlubGluZSBpbnQgaXQ2NjEyMV93YWl0X2RkY19yZWFkeShz dHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBpbnQgcmV0LCB2YWw7Cj4+ ICvCoMKgwqAgdTMyIGJ1c3kgPSBJVDY2MTIxX0REQ19TVEFUVVNfTk9BQ0sgfCBJVDY2MTIxX0RE Q19TVEFUVVNfV0FJVF9CVVMgfAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9ERENf U1RBVFVTX0FSQklfTE9TRTsKPj4gKwo+PiArwqDCoMKgIHJldCA9IHJlZ21hcF9yZWFkX3BvbGxf dGltZW91dChjdHgtPnJlZ21hcCwgSVQ2NjEyMV9ERENfU1RBVFVTX1JFRywgdmFsLCB0cnVlLAo+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9F RElEX1NMRUVQX1VTLCBJVDY2MTIxX0VESURfVElNRU9VVF9VUyk7Cj4+ICvCoMKgwqAgaWYgKHJl dCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoCBpZiAodmFs ICYgYnVzeSkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiAtRUFHQUlOOwo+PiArCj4+ICvCoMKg wqAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaXQ2NjEyMV9jbGVhcl9kZGNf ZmlmbyhzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBpbnQgcmV0Owo+ PiArCj4+ICvCoMKgwqAgcmV0ID0gaXQ2NjEyMV9wcmVhbWJsZV9kZGMoY3R4KTsKPj4gK8KgwqDC oCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKg IHJldHVybiByZWdtYXBfd3JpdGUoY3R4LT5yZWdtYXAsIElUNjYxMjFfRERDX0NPTU1BTkRfUkVH LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfRERDX0NPTU1BTkRf RklGT19DTFIpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGl0NjYxMjFfYWJvcnRfZGRjX29w cyhzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBpbnQgcmV0Owo+PiAr wqDCoMKgIHVuc2lnbmVkIGludCBzd3Jlc2V0LCBjcGRlc2lyZTsKPj4gKwo+PiArwqDCoMKgIHJl dCA9IHJlZ21hcF9yZWFkKGN0eC0+cmVnbWFwLCBJVDY2MTIxX1NXX1JTVF9SRUcsICZzd3Jlc2V0 KTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4g Kwo+PiArwqDCoMKgIHJldCA9IHJlZ21hcF9yZWFkKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0hEQ1Bf UkVHLCAmY3BkZXNpcmUpOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoCBy ZXR1cm4gcmV0Owo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlKGN0eC0+cmVnbWFw LCBJVDY2MTIxX0hEQ1BfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBjcGRl c2lyZSAmICh+SVQ2NjEyMV9IRENQX0NQREVTSVJFRCAmIDB4RkYpKTsKPj4gK8KgwqDCoCBpZiAo cmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKgIHJldCA9 IHJlZ21hcF93cml0ZShjdHgtPnJlZ21hcCwgSVQ2NjEyMV9TV19SU1RfUkVHLAo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoc3dyZXNldCB8IElUNjYxMjFfU1dfUlNUX0hEQ1ApKTsK Pj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+ PiArwqDCoMKgIHJldCA9IGl0NjYxMjFfcHJlYW1ibGVfZGRjKGN0eCk7Cj4+ICvCoMKgwqAgaWYg KHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoCByZXQg PSByZWdtYXBfd3JpdGUoY3R4LT5yZWdtYXAsIElUNjYxMjFfRERDX0NPTU1BTkRfUkVHLAo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0REQ19DT01NQU5EX0FCT1JUKTsK Pj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+ PiArwqDCoMKgIHJldHVybiBpdDY2MTIxX3dhaXRfZGRjX3JlYWR5KGN0eCk7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyBpbnQgaXQ2NjEyMV9nZXRfZWRpZF9ibG9jayh2b2lkICpjb250ZXh0LCB1OCAq YnVmLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1bnNpZ25lZCBpbnQg YmxvY2ssIHNpemVfdCBsZW4pCj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGl0NjYxMjFfY3R4ICpj dHggPSBjb250ZXh0Owo+PiArwqDCoMKgIHVuc2lnbmVkIGludCB2YWw7Cj4+ICvCoMKgwqAgaW50 IHJlbWFpbiA9IGxlbjsKPj4gK8KgwqDCoCBpbnQgb2Zmc2V0ID0gMDsKPj4gK8KgwqDCoCBpbnQg cmV0LCBjbnQ7Cj4+ICsKPj4gK8KgwqDCoCBvZmZzZXQgPSAoYmxvY2sgJSAyKSAqIGxlbjsKPj4g K8KgwqDCoCBibG9jayA9IGJsb2NrIC8gMjsKPj4gKwo+PiArwqDCoMKgIHJldCA9IHJlZ21hcF9y ZWFkKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0lOVF9TVEFUVVMxX1JFRywgJnZhbCk7Cj4+ICvCoMKg wqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDC oCBpZiAodmFsICYgSVQ2NjEyMV9JTlRfU1RBVFVTMV9ERENfQlVTSEFORykgewo+PiArwqDCoMKg wqDCoMKgwqAgcmV0ID0gaXQ2NjEyMV9hYm9ydF9kZGNfb3BzKGN0eCk7Cj4+ICvCoMKgwqDCoMKg wqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiAr wqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIHJldCA9IGl0NjYxMjFfY2xlYXJfZGRjX2ZpZm8oY3R4 KTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4g Kwo+PiArwqDCoMKgIHdoaWxlIChyZW1haW4gPiAwKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBjbnQg PSAocmVtYWluID4gSVQ2NjEyMV9FRElEX0ZJRk9fU0laRSkgPwo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfRURJRF9GSUZPX1NJWkUgOiByZW1haW47Cj4+ICvCoMKg wqDCoMKgwqDCoCByZXQgPSBpdDY2MTIxX3ByZWFtYmxlX2RkYyhjdHgpOwo+PiArwqDCoMKgwqDC oMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4g Kwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlKGN0eC0+cmVnbWFwLCBJVDY2 MTIxX0REQ19DT01NQU5EX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBJVDY2MTIxX0REQ19DT01NQU5EX0ZJRk9fQ0xSKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlm IChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8Kg wqDCoMKgwqDCoMKgIHJldCA9IGl0NjYxMjFfd2FpdF9kZGNfcmVhZHkoY3R4KTsKPj4gK8KgwqDC oMKgwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7 Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKgIHJldCA9IHJlZ21hcF9yZWFkKGN0eC0+cmVnbWFwLCBJ VDY2MTIxX0lOVF9TVEFUVVMxX1JFRywgJnZhbCk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAocmV0 KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiArCj4+ICvCoMKgwqDC oMKgwqDCoCBpZiAodmFsICYgSVQ2NjEyMV9JTlRfU1RBVFVTMV9ERENfQlVTSEFORykgewo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXQgPSBpdDY2MTIxX2Fib3J0X2RkY19vcHMoY3R4KTsK Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiArwqDCoMKgwqDCoMKgwqAgfQo+PiArCj4+ICvC oMKgwqDCoMKgwqDCoCByZXQgPSBpdDY2MTIxX3ByZWFtYmxlX2RkYyhjdHgpOwo+PiArwqDCoMKg wqDCoMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsK Pj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlKGN0eC0+cmVnbWFwLCBJ VDY2MTIxX0REQ19IRUFERVJfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIElUNjYxMjFfRERDX0hFQURFUl9FRElEKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChy ZXQpCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDC oMKgwqDCoMKgIHJldCA9IHJlZ21hcF93cml0ZShjdHgtPnJlZ21hcCwgSVQ2NjEyMV9ERENfT0ZG U0VUX1JFRywgb2Zmc2V0KTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKgIHJldCA9 IHJlZ21hcF93cml0ZShjdHgtPnJlZ21hcCwgSVQ2NjEyMV9ERENfQllURV9SRUcsIGNudCk7Cj4+ ICvCoMKgwqDCoMKgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1 cm4gcmV0Owo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCByZXQgPSByZWdtYXBfd3JpdGUoY3R4LT5y ZWdtYXAsIElUNjYxMjFfRERDX1NFR01FTlRfUkVHLCBibG9jayk7Cj4+ICvCoMKgwqDCoMKgwqDC oCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiArCj4+ ICvCoMKgwqDCoMKgwqDCoCByZXQgPSByZWdtYXBfd3JpdGUoY3R4LT5yZWdtYXAsIElUNjYxMjFf RERDX0NPTU1BTkRfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IElUNjYxMjFfRERDX0NPTU1BTkRfRURJRF9SRUFEKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChy ZXQpCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDC oMKgwqDCoMKgIG9mZnNldCArPSBjbnQ7Cj4+ICvCoMKgwqDCoMKgwqDCoCByZW1haW4gLT0gY250 Owo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCAvKiBQZXIgcHJvZ3JhbW1pbmcgbWFudWFsLCBzbGVl cCBoZXJlIGJlZm9yZSBlbXB0eWluZyB0aGUgRklGTyAqLwo+PiArwqDCoMKgwqDCoMKgwqAgbXNs ZWVwKDIwKTsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0ID0gaXQ2NjEyMV93YWl0X2RkY19y ZWFkeShjdHgpOwo+PiArwqDCoMKgwqDCoMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgZG8gewo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCByZXQgPSByZWdtYXBfcmVhZChjdHgtPnJlZ21hcCwgSVQ2NjEy MV9ERENfUkRfRklGT19SRUcsICZ2YWwpOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpZiAo cmV0KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgICooYnVmKyspID0gdmFsOwo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBjbnQtLTsKPj4gK8KgwqDCoMKgwqDCoMKgIH0gd2hpbGUgKGNudCA+IDApOwo+PiAr wqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg aW50IGl0NjYxMjFfY29ubmVjdG9yX2dldF9tb2RlcyhzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29u bmVjdG9yKQo+PiArewo+PiArwqDCoMKgIGludCByZXQsIG51bV9tb2RlcyA9IDA7Cj4+ICvCoMKg wqAgc3RydWN0IGl0NjYxMjFfY3R4ICpjdHggPSBjb250YWluZXJfb2YoY29ubmVjdG9yLCBzdHJ1 Y3QgaXQ2NjEyMV9jdHgsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvbm5lY3Rvcik7Cj4+ ICsKPj4gK8KgwqDCoCBpZiAoY3R4LT5lZGlkKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIGRy bV9hZGRfZWRpZF9tb2Rlcyhjb25uZWN0b3IsIGN0eC0+ZWRpZCk7Cj4+ICsKPj4gK8KgwqDCoCBt dXRleF9sb2NrKCZjdHgtPmxvY2spOwo+PiArCj4+ICvCoMKgwqAgY3R4LT5lZGlkID0gZHJtX2Rv X2dldF9lZGlkKGNvbm5lY3RvciwgaXQ2NjEyMV9nZXRfZWRpZF9ibG9jaywgY3R4KTsKPj4gK8Kg wqDCoCBpZiAoIWN0eC0+ZWRpZCkgewo+PiArwqDCoMKgwqDCoMKgwqAgRFJNX0VSUk9SKCJGYWls ZWQgdG8gcmVhZCBFRElEXG4iKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8gdW5sb2NrOwo+PiAr wqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIHJldCA9IGRybV9jb25uZWN0b3JfdXBkYXRlX2VkaWRf cHJvcGVydHkoY29ubmVjdG9yLCBjdHgtPmVkaWQpOwo+PiArwqDCoMKgIGlmIChyZXQpIHsKPj4g K8KgwqDCoMKgwqDCoMKgIERSTV9FUlJPUigiRmFpbGVkIHRvIHVwZGF0ZSBFRElEIHByb3BlcnR5 OiAlZFxuIiwgcmV0KTsKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8gdW5sb2NrOwo+PiArwqDCoMKg IH0KPj4gKwo+PiArwqDCoMKgIG51bV9tb2RlcyA9IGRybV9hZGRfZWRpZF9tb2Rlcyhjb25uZWN0 b3IsIGN0eC0+ZWRpZCk7Cj4+ICsKPj4gK3VubG9jazoKPj4gK8KgwqDCoCBtdXRleF91bmxvY2so JmN0eC0+bG9jayk7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gbnVtX21vZGVzOwo+PiArfQo+PiAr Cj4+ICtzdGF0aWMgYm9vbCBpdDY2MTIxX2lzX2hwZF9kZXRlY3Qoc3RydWN0IGl0NjYxMjFfY3R4 ICpjdHgpCj4+ICt7Cj4+ICvCoMKgwqAgaW50IHZhbDsKPj4gKwo+PiArwqDCoMKgIGlmIChyZWdt YXBfcmVhZChjdHgtPnJlZ21hcCwgSVQ2NjEyMV9TWVNfU1RBVFVTX1JFRywgJnZhbCkpCj4+ICvC oMKgwqDCoMKgwqDCoCByZXR1cm4gZmFsc2U7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gdmFsICYg SVQ2NjEyMV9TWVNfU1RBVFVTX0hQREVURUNUOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGl0 NjYxMjFfY29ubmVjdG9yX2RldGVjdF9jdHgoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3Rv ciwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCBkcm1f bW9kZXNldF9hY3F1aXJlX2N0eCAqYywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIGJvb2wgZm9yY2UpCj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGl0NjYxMjFfY3R4 ICpjdHggPSBjb250YWluZXJfb2YoY29ubmVjdG9yLCBzdHJ1Y3QgaXQ2NjEyMV9jdHgsCj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvbm5lY3Rvcik7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4g aXQ2NjEyMV9pc19ocGRfZGV0ZWN0KGN0eCkgPyBjb25uZWN0b3Jfc3RhdHVzX2Nvbm5lY3RlZAo+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDogY29ubmVjdG9y X3N0YXR1c19kaXNjb25uZWN0ZWQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBlbnVtIGRybV9tb2Rl X3N0YXR1cyBpdDY2MTIxX21vZGVfdmFsaWQoc3RydWN0IGl0NjYxMjFfY3R4ICpjdHgsCj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvbnN0 IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlKQo+PiArewo+PiArwqDCoMKgIHVuc2lnbmVk IGxvbmcgbWF4X2Nsb2NrOwo+PiArCj4+ICvCoMKgwqAgbWF4X2Nsb2NrID0gKGN0eC0+YnVzX3dp ZHRoID09IDEyKSA/IDc0MjUwIDogMTQ4NTAwOwo+PiArCj4+ICvCoMKgwqAgaWYgKG1vZGUtPmNs b2NrID4gbWF4X2Nsb2NrKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIE1PREVfQ0xPQ0tfSElH SDsKPj4gKwo+PiArwqDCoMKgIGlmIChtb2RlLT5jbG9jayA8IDI1MDAwKQo+PiArwqDCoMKgwqDC oMKgwqAgcmV0dXJuIE1PREVfQ0xPQ0tfTE9XOwo+PiArCj4+ICvCoMKgwqAgcmV0dXJuIE1PREVf T0s7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBlbnVtIGRybV9tb2RlX3N0YXR1cyBpdDY2MTIxX2Nv bm5lY3Rvcl9tb2RlX3ZhbGlkKHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IsCj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBz dHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaXQ2 NjEyMV9jdHggKmN0eCA9IGNvbnRhaW5lcl9vZihjb25uZWN0b3IsIHN0cnVjdCBpdDY2MTIxX2N0 eCwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29ubmVjdG9yKTsKPj4gKwo+PiArwqDCoMKg IHJldHVybiBpdDY2MTIxX21vZGVfdmFsaWQoY3R4LCBtb2RlKTsKPj4gK30KPj4gKwo+PiArc3Rh dGljIHN0cnVjdCBkcm1fY29ubmVjdG9yX2hlbHBlcl9mdW5jcyBpdDY2MTIxX2Nvbm5lY3Rvcl9o ZWxwZXJfZnVuY3MgPSB7Cj4+ICvCoMKgwqAgLmdldF9tb2RlcyA9IGl0NjYxMjFfY29ubmVjdG9y X2dldF9tb2RlcywKPj4gK8KgwqDCoCAuZGV0ZWN0X2N0eCA9IGl0NjYxMjFfY29ubmVjdG9yX2Rl dGVjdF9jdHgsCj4+ICvCoMKgwqAgLm1vZGVfdmFsaWQgPSBpdDY2MTIxX2Nvbm5lY3Rvcl9tb2Rl X3ZhbGlkLAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fY29ubmVjdG9y X2Z1bmNzIGl0NjYxMjFfY29ubmVjdG9yX2Z1bmNzID0gewo+PiArwqDCoMKgIC5yZXNldCA9IGRy bV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9yZXNldCwKPj4gK8KgwqDCoCAuZmlsbF9tb2RlcyA9 IGRybV9oZWxwZXJfcHJvYmVfc2luZ2xlX2Nvbm5lY3Rvcl9tb2RlcywKPj4gK8KgwqDCoCAuZGVz dHJveSA9IGRybV9jb25uZWN0b3JfY2xlYW51cCwKPj4gK8KgwqDCoCAuYXRvbWljX2R1cGxpY2F0 ZV9zdGF0ZSA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kdXBsaWNhdGVfc3RhdGUsCj4+ ICvCoMKgwqAgLmF0b21pY19kZXN0cm95X3N0YXRlID0gZHJtX2F0b21pY19oZWxwZXJfY29ubmVj dG9yX2Rlc3Ryb3lfc3RhdGUsCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgaW50IGl0NjYxMjFfYnJp ZGdlX2F0dGFjaChzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlLAo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgZW51bSBkcm1fYnJpZGdlX2F0dGFjaF9mbGFncyBmbGFncykKPj4g K3sKPj4gK8KgwqDCoCBpbnQgcmV0Owo+PiArwqDCoMKgIHN0cnVjdCBpdDY2MTIxX2N0eCAqY3R4 ID0gY29udGFpbmVyX29mKGJyaWRnZSwgc3RydWN0IGl0NjYxMjFfY3R4LAo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBicmlkZ2UpOwo+PiArCj4+ICvCoMKgwqAgaWYgKCFicmlkZ2UtPmVuY29k ZXIpIHsKPj4gK8KgwqDCoMKgwqDCoMKgIERSTV9FUlJPUigiUGFyZW50IGVuY29kZXIgb2JqZWN0 IG5vdCBmb3VuZCIpOwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9ERVY7Cj4+ICvCoMKg wqAgfQo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5yZWdtYXAs IElUNjYxMjFfQ0xLX0JBTktfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IElUNjYxMjFfQ0xLX0JBTktfUFdST0ZGX1JDTEssIDApOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFw X3dyaXRlX2JpdHMoY3R4LT5yZWdtYXAsIElUNjYxMjFfSU5UX1JFRywKPj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0lOVF9UWF9DTEtfT0ZGLCAwKTsKPj4gK8KgwqDC oCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKg IHJldCA9IHJlZ21hcF93cml0ZV9iaXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0FGRV9EUlZfUkVH LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfQUZFX0RSVl9QV0Qs IDApOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+ PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5yZWdtYXAsIElUNjYx MjFfQUZFX1hQX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIx X0FGRV9YUF9QV0RJIHwgSVQ2NjEyMV9BRkVfWFBfUFdEUExMLCAwKTsKPj4gK8KgwqDCoCBpZiAo cmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKgIHJldCA9 IHJlZ21hcF93cml0ZV9iaXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0FGRV9JUF9SRUcsCj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9BRkVfSVBfUFdEUExMLCAwKTsK Pj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+ PiArwqDCoMKgIHJldCA9IHJlZ21hcF93cml0ZV9iaXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0FG RV9EUlZfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfQUZF X0RSVl9SU1QsIDApOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1 cm4gcmV0Owo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5yZWdt YXAsIElUNjYxMjFfQUZFX1hQX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBJVDY2MTIxX0FGRV9YUF9SRVNFVEIsIElUNjYxMjFfQUZFX1hQX1JFU0VUQik7Cj4+ICvCoMKg wqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDC oCByZXQgPSByZWdtYXBfd3JpdGVfYml0cyhjdHgtPnJlZ21hcCwgSVQ2NjEyMV9BRkVfSVBfUkVH LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfQUZFX0lQX1JFU0VU QiwgSVQ2NjEyMV9BRkVfSVBfUkVTRVRCKTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKg wqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKgIHJldCA9IHJlZ21hcF93cml0ZV9i aXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX1NXX1JTVF9SRUcsCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9TV19SU1RfUkVGLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIElUNjYxMjFfU1dfUlNUX1JFRik7Cj4+ICvCoMKgwqAgaWYgKHJldCkKPj4g K8KgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoCAvKiBQZXIgcHJvZ3Jh bW1pbmcgbWFudWFsLCBzbGVlcCBoZXJlIGZvciBicmlkZ2UgdG8gc2V0dGxlICovCj4+ICvCoMKg wqAgbXNsZWVwKDUwKTsKPj4gKwo+PiArwqDCoMKgIC8qIFN0YXJ0IGludGVycnVwdHMgKi8KPj4g K8KgwqDCoCByZXQgPSByZWdtYXBfd3JpdGVfYml0cyhjdHgtPnJlZ21hcCwgSVQ2NjEyMV9JTlRf TUFTSzFfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfSU5U X01BU0sxX0REQ19OT0FDSyB8Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2 NjEyMV9JTlRfTUFTSzFfSFBEIHwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJ VDY2MTIxX0lOVF9NQVNLMV9ERENfRklGT0VSUiB8Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgSVQ2NjEyMV9JTlRfTUFTSzFfRERDX0JVU0hBTkcsCj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgfihJVDY2MTIxX0lOVF9NQVNLMV9ERENfTk9BQ0sgfAo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfSU5UX01BU0sxX0hQRCB8Cj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9JTlRfTUFTSzFfRERDX0ZJRk9F UlIgfAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfSU5UX01BU0sx X0REQ19CVVNIQU5HKSAmIDB4RkYpOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKg wqDCoCByZXR1cm4gcmV0Owo+PiArCj4+ICvCoMKgwqAgaWYgKGZsYWdzICYgRFJNX0JSSURHRV9B VFRBQ0hfTk9fQ09OTkVDVE9SKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIDA7Cj4+ICsKPj4g K8KgwqDCoCByZXQgPSBkcm1fY29ubmVjdG9yX2luaXQoYnJpZGdlLT5kZXYsICZjdHgtPmNvbm5l Y3RvciwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICZpdDY2MTIxX2Nvbm5l Y3Rvcl9mdW5jcywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIERSTV9NT0RF X0NPTk5FQ1RPUl9IRE1JQSk7Cj4+ICvCoMKgwqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKg IHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoCBjdHgtPmNvbm5lY3Rvci5wb2xsZWQgPSBEUk1f Q09OTkVDVE9SX1BPTExfSFBEOwo+PiArwqDCoMKgIGRybV9jb25uZWN0b3JfaGVscGVyX2FkZCgm Y3R4LT5jb25uZWN0b3IsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAmaXQ2 NjEyMV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzKTsKPj4gKwo+PiArwqDCoMKgIHJldCA9IGRybV9j b25uZWN0b3JfYXR0YWNoX2VuY29kZXIoJmN0eC0+Y29ubmVjdG9yLCBicmlkZ2UtPmVuY29kZXIp Owo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+PiAr Cj4+ICvCoMKgwqAgcmV0dXJuIGRybV9jb25uZWN0b3JfcmVnaXN0ZXIoJmN0eC0+Y29ubmVjdG9y KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBpdDY2MTIxX3NldF9tdXRlKHN0cnVjdCBpdDY2 MTIxX2N0eCAqY3R4LCBib29sIG11dGUpCj4+ICt7Cj4+ICvCoMKgwqAgaW50IHJldDsKPj4gK8Kg wqDCoCB1bnNpZ25lZCBpbnQgdmFsID0gMDsKPj4gKwo+PiArwqDCoMKgIGlmIChtdXRlKQo+PiAr wqDCoMKgwqDCoMKgwqAgdmFsID0gSVQ2NjEyMV9BVl9NVVRFX09OOwo+PiArCj4+ICvCoMKgwqAg cmV0ID0gcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5yZWdtYXAsIElUNjYxMjFfQVZfTVVURV9SRUcs IElUNjYxMjFfQVZfTVVURV9PTiwgdmFsKTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKg wqDCoMKgwqAgcmV0dXJuIHJldDsKPj4gKwo+PiArwqDCoMKgIHJldHVybiByZWdtYXBfd3JpdGUo Y3R4LT5yZWdtYXAsIElUNjYxMjFfUEtUX0dFTl9DVFJMX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX1BLVF9HRU5fQ1RSTF9PTiB8IElUNjYxMjFfUEtUX0dF Tl9DVFJMX1JQVCk7Cj4+ICt9Cj4+ICsKPj4gKyNkZWZpbmUgTUFYX09VVFBVVF9TRUxfRk9STUFU U8KgwqDCoCAxCj4+ICsKPj4gK3N0YXRpYyB1MzIgKml0NjYxMjFfYnJpZGdlX2F0b21pY19nZXRf b3V0cHV0X2J1c19mbXRzKHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsCj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCBk cm1fYnJpZGdlX3N0YXRlICpicmlkZ2Vfc3RhdGUsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCBkcm1fY3J0Y19zdGF0 ZSAqY3J0Y19zdGF0ZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RydWN0IGRybV9jb25uZWN0b3Jfc3RhdGUgKmNvbm5fc3Rh dGUsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIHVuc2lnbmVkIGludCAqbnVtX291dHB1dF9mbXRzKQo+PiArewo+PiArwqDCoMKg IHUzMiAqb3V0cHV0X2ZtdHM7Cj4+ICsKPj4gK8KgwqDCoCBvdXRwdXRfZm10cyA9IGtjYWxsb2Mo TUFYX09VVFBVVF9TRUxfRk9STUFUUywgc2l6ZW9mKCpvdXRwdXRfZm10cyksCj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEdGUF9LRVJORUwpOwo+PiArwqDCoMKgIGlmICgh b3V0cHV0X2ZtdHMpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gTlVMTDsKPj4gKwo+PiArwqDC oMKgIC8qIFRPRklYIGhhbmRsZSBtb3JlIHRoYW4gTUVESUFfQlVTX0ZNVF9SR0I4ODhfMVgyNCBh cyBvdXRwdXQgZm9ybWF0ICovCj4+ICvCoMKgwqAgb3V0cHV0X2ZtdHNbMF0gPcKgIE1FRElBX0JV U19GTVRfUkdCODg4XzFYMjQ7Cj4+ICvCoMKgwqAgKm51bV9vdXRwdXRfZm10cyA9IDE7Cj4+ICsK Pj4gK8KgwqDCoCByZXR1cm4gb3V0cHV0X2ZtdHM7Cj4+ICt9Cj4+ICsKPj4gKyNkZWZpbmUgTUFY X0lOUFVUX1NFTF9GT1JNQVRTwqDCoMKgIDEKPj4gKwo+PiArc3RhdGljIHUzMiAqaXQ2NjEyMV9i cmlkZ2VfYXRvbWljX2dldF9pbnB1dF9idXNfZm10cyhzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdl LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgc3RydWN0IGRybV9icmlkZ2Vfc3RhdGUgKmJyaWRnZV9zdGF0ZSwKPj4gK8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCBk cm1fY3J0Y19zdGF0ZSAqY3J0Y19zdGF0ZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCBkcm1fY29ubmVjdG9yX3N0YXRl ICpjb25uX3N0YXRlLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgdTMyIG91dHB1dF9mbXQsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1bnNpZ25lZCBpbnQgKm51bV9p bnB1dF9mbXRzKQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBpdDY2MTIxX2N0eCAqY3R4ID0gY29u dGFpbmVyX29mKGJyaWRnZSwgc3RydWN0IGl0NjYxMjFfY3R4LCBicmlkZ2UpOwo+PiArwqDCoMKg IHUzMiAqaW5wdXRfZm10czsKPj4gKwo+PiArwqDCoMKgICpudW1faW5wdXRfZm10cyA9IDA7Cj4+ ICsKPj4gK8KgwqDCoCBpbnB1dF9mbXRzID0ga2NhbGxvYyhNQVhfSU5QVVRfU0VMX0ZPUk1BVFMs IHNpemVvZigqaW5wdXRfZm10cyksCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBHRlBfS0VSTkVMKTsKPj4gK8KgwqDCoCBpZiAoIWlucHV0X2ZtdHMpCj4+ICvCoMKgwqDCoMKg wqDCoCByZXR1cm4gTlVMTDsKPj4gKwo+PiArwqDCoMKgIGlmIChjdHgtPmJ1c193aWR0aCA9PSAx MikKPj4gK8KgwqDCoMKgwqDCoMKgIC8qIElUNjYxMjFGTiBEYXRhc2hlZXQgc3BlY2lmaWVzIExp dHRsZS1FbmRpYW4gb3JkZXJpbmcgKi8KPj4gK8KgwqDCoMKgwqDCoMKgIGlucHV0X2ZtdHNbMF0g PSBNRURJQV9CVVNfRk1UX1JHQjg4OF8yWDEyX0xFOwo+PiArwqDCoMKgIGVsc2UKPj4gK8KgwqDC oMKgwqDCoMKgIC8qIFRPRklYIHN1cHBvcnQgbW9yZSBpbnB1dCBidXMgZm9ybWF0cyBpbiAyNGJp dCB3aWR0aCAqLwo+PiArwqDCoMKgwqDCoMKgwqAgaW5wdXRfZm10c1swXSA9IE1FRElBX0JVU19G TVRfUkdCODg4XzFYMjQ7Cj4+ICvCoMKgwqAgKm51bV9pbnB1dF9mbXRzID0gMTsKPj4gKwo+PiAr wqDCoMKgIHJldHVybiBpbnB1dF9mbXRzOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBpdDY2 MTIxX2JyaWRnZV9lbmFibGUoc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZSkKPj4gK3sKPj4gK8Kg wqDCoCBzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCA9IGNvbnRhaW5lcl9vZihicmlkZ2UsIHN0cnVj dCBpdDY2MTIxX2N0eCwgYnJpZGdlKTsKPj4gKwo+PiArwqDCoMKgIGl0NjYxMjFfc2V0X211dGUo Y3R4LCBmYWxzZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGl0NjYxMjFfYnJpZGdlX2Rp c2FibGUoc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZSkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3Qg aXQ2NjEyMV9jdHggKmN0eCA9IGNvbnRhaW5lcl9vZihicmlkZ2UsIHN0cnVjdCBpdDY2MTIxX2N0 eCwgYnJpZGdlKTsKPj4gKwo+PiArwqDCoMKgIGl0NjYxMjFfc2V0X211dGUoY3R4LCB0cnVlKTsK Pj4gK30KPj4gKwo+PiArc3RhdGljCj4+ICt2b2lkIGl0NjYxMjFfYnJpZGdlX21vZGVfc2V0KHN0 cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBjb25zdCBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSwKPj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICphZGp1 c3RlZF9tb2RlKQo+PiArewo+PiArwqDCoMKgIGludCByZXQsIGk7Cj4+ICvCoMKgwqAgdTggYnVm W0hETUlfSU5GT0ZSQU1FX1NJWkUoQVZJKV07Cj4+ICvCoMKgwqAgc3RydWN0IGl0NjYxMjFfY3R4 ICpjdHggPSBjb250YWluZXJfb2YoYnJpZGdlLCBzdHJ1Y3QgaXQ2NjEyMV9jdHgsIGJyaWRnZSk7 Cj4+ICvCoMKgwqAgY29uc3QgdTE2IGF2aWluZm9fcmVnW0hETUlfQVZJX0lORk9GUkFNRV9TSVpF XSA9IHsKPj4gK8KgwqDCoMKgwqDCoMKgIElUNjYxMjFfQVZJSU5GT19EQjFfUkVHLAo+PiArwqDC oMKgwqDCoMKgwqAgSVQ2NjEyMV9BVklJTkZPX0RCMl9SRUcsCj4+ICvCoMKgwqDCoMKgwqDCoCBJ VDY2MTIxX0FWSUlORk9fREIzX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgIElUNjYxMjFfQVZJSU5G T19EQjRfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9BVklJTkZPX0RCNV9SRUcsCj4+ ICvCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FWSUlORk9fREI2X1JFRywKPj4gK8KgwqDCoMKgwqDC oMKgIElUNjYxMjFfQVZJSU5GT19EQjdfUkVHLAo+PiArwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9B VklJTkZPX0RCOF9SRUcsCj4+ICvCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0FWSUlORk9fREI5X1JF RywKPj4gK8KgwqDCoMKgwqDCoMKgIElUNjYxMjFfQVZJSU5GT19EQjEwX1JFRywKPj4gK8KgwqDC oMKgwqDCoMKgIElUNjYxMjFfQVZJSU5GT19EQjExX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgIElU NjYxMjFfQVZJSU5GT19EQjEyX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgIElUNjYxMjFfQVZJSU5G T19EQjEzX1JFRwo+PiArwqDCoMKgIH07Cj4+ICsKPj4gK8KgwqDCoCBtdXRleF9sb2NrKCZjdHgt PmxvY2spOwo+PiArCj4+ICvCoMKgwqAgaGRtaV9hdmlfaW5mb2ZyYW1lX2luaXQoJmN0eC0+aGRt aV9hdmlfaW5mb2ZyYW1lKTsKPj4gKwo+PiArwqDCoMKgIHJldCA9IGRybV9oZG1pX2F2aV9pbmZv ZnJhbWVfZnJvbV9kaXNwbGF5X21vZGUoJmN0eC0+aGRtaV9hdmlfaW5mb2ZyYW1lLCAmY3R4LT5j b25uZWN0b3IsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgYWRqdXN0ZWRfbW9kZSk7Cj4+ICvCoMKgwqAgaWYgKHJldCkgewo+ PiArwqDCoMKgwqDCoMKgwqAgRFJNX0VSUk9SKCJGYWlsZWQgdG8gc2V0dXAgQVZJIGluZm9mcmFt ZTogJWRcbiIsIHJldCk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIHVubG9jazsKPj4gK8KgwqDC oCB9Cj4+ICsKPj4gK8KgwqDCoCByZXQgPSBoZG1pX2F2aV9pbmZvZnJhbWVfcGFjaygmY3R4LT5o ZG1pX2F2aV9pbmZvZnJhbWUsIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwo+PiArwqDCoMKgIGlmIChyZXQg PCAwKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBEUk1fRVJST1IoIkZhaWxlZCB0byBwYWNrIGluZm9m cmFtZTogJWRcbiIsIHJldCk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIHVubG9jazsKPj4gK8Kg wqDCoCB9Cj4+ICsKPj4gK8KgwqDCoCAvKiBXcml0ZSBuZXcgQVZJIGluZm9mcmFtZSBwYWNrZXQg Ki8KPj4gK8KgwqDCoCBmb3IgKGkgPSAwOyBpIDwgSERNSV9BVklfSU5GT0ZSQU1FX1NJWkU7IGkr Kykgewo+PiArwqDCoMKgwqDCoMKgwqAgaWYgKHJlZ21hcF93cml0ZShjdHgtPnJlZ21hcCwgYXZp aW5mb19yZWdbaV0sIGJ1ZltpICsgSERNSV9JTkZPRlJBTUVfSEVBREVSX1NJWkVdKSkKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqAgZ290byB1bmxvY2s7Cj4+ICvCoMKgwqAgfQo+PiArwqDCoMKg IGlmIChyZWdtYXBfd3JpdGUoY3R4LT5yZWdtYXAsIElUNjYxMjFfQVZJSU5GT19DU1VNX1JFRywg YnVmWzNdKSkKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8gdW5sb2NrOwo+PiArCj4+ICvCoMKgwqAg LyogRW5hYmxlIEFWSSBpbmZvZnJhbWUgKi8KPj4gK8KgwqDCoCBpZiAocmVnbWFwX3dyaXRlKGN0 eC0+cmVnbWFwLCBJVDY2MTIxX0FWSV9JTkZPX1BLVF9SRUcsCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgSVQ2NjEyMV9BVklfSU5GT19QS1RfT04gfCBJVDY2MTIxX0FWSV9JTkZPX1BLVF9S UFQpKQo+PiArwqDCoMKgwqDCoMKgwqAgZ290byB1bmxvY2s7Cj4+ICsKPj4gK8KgwqDCoCAvKiBT ZXQgVFggbW9kZSB0byBIRE1JICovCj4+ICvCoMKgwqAgaWYgKHJlZ21hcF93cml0ZShjdHgtPnJl Z21hcCwgSVQ2NjEyMV9IRE1JX01PREVfUkVHLCBJVDY2MTIxX0hETUlfTU9ERV9IRE1JKSkKPj4g K8KgwqDCoMKgwqDCoMKgIGdvdG8gdW5sb2NrOwo+PiArCj4+ICvCoMKgwqAgaWYgKHJlZ21hcF93 cml0ZV9iaXRzKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0NMS19CQU5LX1JFRywKPj4gK8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2NjEyMV9DTEtfQkFOS19QV1JPRkZfVFhDTEss IElUNjYxMjFfQ0xLX0JBTktfUFdST0ZGX1RYQ0xLKSkKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8g dW5sb2NrOwo+PiArCj4+ICvCoMKgwqAgaWYgKGl0NjYxMjFfY29uZmlndXJlX2lucHV0KGN0eCkp Cj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIHVubG9jazsKPj4gKwo+PiArwqDCoMKgIGlmIChpdDY2 MTIxX2NvbmZpZ3VyZV9hZmUoY3R4LCBhZGp1c3RlZF9tb2RlKSkKPj4gK8KgwqDCoMKgwqDCoMKg IGdvdG8gdW5sb2NrOwo+PiArCj4+ICvCoMKgwqAgcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5yZWdt YXAsIElUNjYxMjFfQ0xLX0JBTktfUkVHLCBJVDY2MTIxX0NMS19CQU5LX1BXUk9GRl9UWENMSywg MCk7Cj4+ICsKPj4gK3VubG9jazoKPj4gK8KgwqDCoCBtdXRleF91bmxvY2soJmN0eC0+bG9jayk7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBlbnVtIGRybV9tb2RlX3N0YXR1cyBpdDY2MTIxX2JyaWRn ZV9tb2RlX3ZhbGlkKHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsCj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvbnN0IHN0cnVj dCBkcm1fZGlzcGxheV9pbmZvICppbmZvLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBjb25zdCBzdHJ1Y3QgZHJtX2Rpc3BsYXlf bW9kZSAqbW9kZSkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCA9IGNv bnRhaW5lcl9vZihicmlkZ2UsIHN0cnVjdCBpdDY2MTIxX2N0eCwgYnJpZGdlKTsKPj4gKwo+PiAr wqDCoMKgIHJldHVybiBpdDY2MTIxX21vZGVfdmFsaWQoY3R4LCBtb2RlKTsKPj4gK30KPj4gKwo+ PiArc3RhdGljIGVudW0gZHJtX2Nvbm5lY3Rvcl9zdGF0dXMgaXQ2NjEyMV9icmlkZ2VfZGV0ZWN0 KHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UpCj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGl0NjYx MjFfY3R4ICpjdHggPSBjb250YWluZXJfb2YoYnJpZGdlLCBzdHJ1Y3QgaXQ2NjEyMV9jdHgsIGJy aWRnZSk7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gaXQ2NjEyMV9pc19ocGRfZGV0ZWN0KGN0eCkg PyBjb25uZWN0b3Jfc3RhdHVzX2Nvbm5lY3RlZAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIDogY29ubmVjdG9yX3N0YXR1c19kaXNjb25uZWN0ZWQ7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZWRpZCAqaXQ2NjEyMV9icmlkZ2VfZ2V0X2VkaWQoc3Ry dWN0IGRybV9icmlkZ2UgKmJyaWRnZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcikKPj4gK3sK Pj4gK8KgwqDCoCBzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCA9IGNvbnRhaW5lcl9vZihicmlkZ2Us IHN0cnVjdCBpdDY2MTIxX2N0eCwgYnJpZGdlKTsKPj4gK8KgwqDCoCBzdHJ1Y3QgZWRpZCAqZWRp ZDsKPj4gKwo+PiArwqDCoMKgIG11dGV4X2xvY2soJmN0eC0+bG9jayk7Cj4+ICvCoMKgwqAgZWRp ZCA9IGRybV9kb19nZXRfZWRpZChjb25uZWN0b3IsIGl0NjYxMjFfZ2V0X2VkaWRfYmxvY2ssIGN0 eCk7Cj4+ICvCoMKgwqAgbXV0ZXhfdW5sb2NrKCZjdHgtPmxvY2spOwo+PiArCj4+ICvCoMKgwqAg cmV0dXJuIGVkaWQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2JyaWRn ZV9mdW5jcyBpdDY2MTIxX2JyaWRnZV9mdW5jcyA9IHsKPj4gK8KgwqDCoCAuYXR0YWNoID0gaXQ2 NjEyMV9icmlkZ2VfYXR0YWNoLAo+PiArwqDCoMKgIC5lbmFibGUgPSBpdDY2MTIxX2JyaWRnZV9l bmFibGUsCj4+ICvCoMKgwqAgLmRpc2FibGUgPSBpdDY2MTIxX2JyaWRnZV9kaXNhYmxlLAo+PiAr wqDCoMKgIC5tb2RlX3NldCA9IGl0NjYxMjFfYnJpZGdlX21vZGVfc2V0LAo+PiArwqDCoMKgIC5t b2RlX3ZhbGlkID0gaXQ2NjEyMV9icmlkZ2VfbW9kZV92YWxpZCwKPj4gK8KgwqDCoCAuZGV0ZWN0 ID0gaXQ2NjEyMV9icmlkZ2VfZGV0ZWN0LAo+PiArwqDCoMKgIC5nZXRfZWRpZCA9IGl0NjYxMjFf YnJpZGdlX2dldF9lZGlkLAo+PiArwqDCoMKgIC5hdG9taWNfZ2V0X291dHB1dF9idXNfZm10cyA9 IGl0NjYxMjFfYnJpZGdlX2F0b21pY19nZXRfb3V0cHV0X2J1c19mbXRzLAo+PiArwqDCoMKgIC5h dG9taWNfZ2V0X2lucHV0X2J1c19mbXRzID0gaXQ2NjEyMV9icmlkZ2VfYXRvbWljX2dldF9pbnB1 dF9idXNfZm10cywKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBpdDY2MTIxX2ly cV90aHJlYWRlZF9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRldl9pZCkKPj4gK3sKPj4gK8KgwqDC oCBpbnQgcmV0Owo+PiArwqDCoMKgIHVuc2lnbmVkIGludCB2YWw7Cj4+ICvCoMKgwqAgc3RydWN0 IGl0NjYxMjFfY3R4ICpjdHggPSBkZXZfaWQ7Cj4+ICvCoMKgwqAgc3RydWN0IGRldmljZSAqZGV2 ID0gY3R4LT5kZXY7Cj4+ICvCoMKgwqAgYm9vbCBldmVudCA9IGZhbHNlOwo+PiArCj4+ICvCoMKg wqAgbXV0ZXhfbG9jaygmY3R4LT5sb2NrKTsKPj4gKwo+PiArwqDCoMKgIHJldCA9IHJlZ21hcF9y ZWFkKGN0eC0+cmVnbWFwLCBJVDY2MTIxX1NZU19TVEFUVVNfUkVHLCAmdmFsKTsKPj4gK8KgwqDC oCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgZ290byB1bmxvY2s7Cj4+ICsKPj4gK8KgwqDC oCBpZiAoISh2YWwgJiBJVDY2MTIxX1NZU19TVEFUVVNfQUNUSVZFX0lSUSkpCj4+ICvCoMKgwqDC oMKgwqDCoCBnb3RvIHVubG9jazsKPj4gKwo+PiArwqDCoMKgIHJldCA9IHJlZ21hcF9yZWFkKGN0 eC0+cmVnbWFwLCBJVDY2MTIxX0lOVF9TVEFUVVMxX1JFRywgJnZhbCk7Cj4+ICvCoMKgwqAgaWYg KHJldCkgewo+PiArwqDCoMKgwqDCoMKgwqAgZGV2X2VycihkZXYsICJDYW5ub3QgcmVhZCBTVEFU VVMxX1JFRyAlZFxuIiwgcmV0KTsKPj4gK8KgwqDCoCB9IGVsc2Ugewo+PiArwqDCoMKgwqDCoMKg wqAgaWYgKHZhbCAmIElUNjYxMjFfSU5UX1NUQVRVUzFfRERDX0ZJRk9FUlIpCj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGl0NjYxMjFfY2xlYXJfZGRjX2ZpZm8oY3R4KTsKPj4gK8KgwqDCoMKg wqDCoMKgIGlmICh2YWwgJiAoSVQ2NjEyMV9JTlRfU1RBVFVTMV9ERENfQlVTSEFORyB8Cj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElUNjYxMjFfSU5UX1NUQVRVUzFfRERDX05PQUNL KSkKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaXQ2NjEyMV9hYm9ydF9kZGNfb3BzKGN0eCk7 Cj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAodmFsICYgSVQ2NjEyMV9JTlRfU1RBVFVTMV9IUERfU1RB VFVTKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJlZ21hcF93cml0ZV9iaXRzKGN0eC0+ cmVnbWFwLCBJVDY2MTIxX0lOVF9DTFIxX1JFRywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIxX0lOVF9DTFIxX0hQRCwgSVQ2NjEyMV9JTlRfQ0xS MV9IUEQpOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmICghaXQ2NjEyMV9pc19o cGRfZGV0ZWN0KGN0eCkpIHsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBrZnJl ZShjdHgtPmVkaWQpOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGN0eC0+ZWRp ZCA9IE5VTEw7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBldmVudCA9IHRydWU7Cj4+ICvCoMKgwqDCoMKgwqDCoCB9Cj4+ICvCoMKg wqAgfQo+PiArCj4+ICvCoMKgwqAgcmVnbWFwX3dyaXRlX2JpdHMoY3R4LT5yZWdtYXAsIElUNjYx MjFfU1lTX1NUQVRVU19SRUcsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJVDY2MTIx X1NZU19TVEFUVVNfQ0xFQVJfSVJRLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVQ2 NjEyMV9TWVNfU1RBVFVTX0NMRUFSX0lSUSk7Cj4+ICsKPj4gK3VubG9jazoKPj4gK8KgwqDCoCBt dXRleF91bmxvY2soJmN0eC0+bG9jayk7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoZXZlbnQpCj4+ICvC oMKgwqDCoMKgwqDCoCBkcm1faGVscGVyX2hwZF9pcnFfZXZlbnQoY3R4LT5icmlkZ2UuZGV2KTsK Pj4gKwo+PiArwqDCoMKgIHJldHVybiBJUlFfSEFORExFRDsKPj4gK30KPj4gKwo+PiArc3RhdGlj IGludCBpdDY2MTIxX3Byb2JlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQsCj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQo+PiArewo+ PiArwqDCoMKgIHUzMiB2ZW5kb3JfaWRzWzJdLCBkZXZpY2VfaWRzWzJdLCByZXZpc2lvbl9pZDsK Pj4gK8KgwqDCoCBzdHJ1Y3QgZGV2aWNlX25vZGUgKmVwOwo+PiArwqDCoMKgIGludCByZXQ7Cj4+ ICvCoMKgwqAgc3RydWN0IGl0NjYxMjFfY3R4ICpjdHg7Cj4+ICvCoMKgwqAgc3RydWN0IGRldmlj ZSAqZGV2ID0gJmNsaWVudC0+ZGV2Owo+PiArCj4+ICvCoMKgwqAgaWYgKCFpMmNfY2hlY2tfZnVu Y3Rpb25hbGl0eShjbGllbnQtPmFkYXB0ZXIsIEkyQ19GVU5DX0kyQykpIHsKPj4gK8KgwqDCoMKg wqDCoMKgIGRldl9lcnIoZGV2LCAiSTJDIGNoZWNrIGZ1bmN0aW9uYWxpdHkgZmFpbGVkLlxuIik7 Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVOWElPOwo+PiArwqDCoMKgIH0KPj4gKwo+PiAr wqDCoMKgIGVwID0gb2ZfZ3JhcGhfZ2V0X2VuZHBvaW50X2J5X3JlZ3MoZGV2LT5vZl9ub2RlLCAw LCAwKTsKPj4gK8KgwqDCoCBpZiAoIWVwKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FSU5W QUw7Cj4+ICsKPj4gK8KgwqDCoCBjdHggPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKmN0eCks IEdGUF9LRVJORUwpOwo+PiArwqDCoMKgIGlmICghY3R4KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0 dXJuIC1FTk9NRU07Cj4+ICsKPj4gK8KgwqDCoCBjdHgtPmRldiA9IGRldjsKPj4gK8KgwqDCoCBj dHgtPmNsaWVudCA9IGNsaWVudDsKPj4gKwo+PiArwqDCoMKgIG9mX3Byb3BlcnR5X3JlYWRfdTMy KGVwLCAiYnVzLXdpZHRoIiwgJmN0eC0+YnVzX3dpZHRoKTsKPj4gK8KgwqDCoCBvZl9ub2RlX3B1 dChlcCk7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoY3R4LT5idXNfd2lkdGggIT0gMTIgJiYgY3R4LT5i dXNfd2lkdGggIT0gMjQpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPj4gKwo+ PiArwqDCoMKgIGkyY19zZXRfY2xpZW50ZGF0YShjbGllbnQsIGN0eCk7Cj4+ICvCoMKgwqAgbXV0 ZXhfaW5pdCgmY3R4LT5sb2NrKTsKPj4gKwo+PiArwqDCoMKgIGN0eC0+c3VwcGxpZXNbMF0uc3Vw cGx5ID0gInZjbjMzIjsKPj4gK8KgwqDCoCBjdHgtPnN1cHBsaWVzWzFdLnN1cHBseSA9ICJ2Y24x OCI7Cj4+ICvCoMKgwqAgY3R4LT5zdXBwbGllc1syXS5zdXBwbHkgPSAidnJmMTIiOwo+PiArwqDC oMKgIHJldCA9IGRldm1fcmVndWxhdG9yX2J1bGtfZ2V0KGN0eC0+ZGV2LCAzLCBjdHgtPnN1cHBs aWVzKTsKPj4gK8KgwqDCoCBpZiAocmV0KSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBkZXZfZXJyKGN0 eC0+ZGV2LCAicmVndWxhdG9yX2J1bGsgZmFpbGVkXG4iKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHJl dHVybiByZXQ7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgcmV0ID0gaXRlNjYxMjFfcG93 ZXJfb24oY3R4KTsKPj4gK8KgwqDCoCBpZiAocmV0KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJu IHJldDsKPj4gKwo+PiArwqDCoMKgIGl0NjYxMjFfaHdfcmVzZXQoY3R4KTsKPj4gKwo+PiArwqDC oMKgIGN0eC0+cmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LCAmaXQ2NjEyMV9y ZWdtYXBfY29uZmlnKTsKPj4gK8KgwqDCoCBpZiAoSVNfRVJSKGN0eC0+cmVnbWFwKSkgewo+PiAr wqDCoMKgwqDCoMKgwqAgaXRlNjYxMjFfcG93ZXJfb2ZmKGN0eCk7Cj4+ICvCoMKgwqDCoMKgwqDC oCByZXR1cm4gUFRSX0VSUihjdHgpOwo+PiArwqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIHJlZ21h cF9yZWFkKGN0eC0+cmVnbWFwLCBJVDY2MTIxX1ZFTkRPUl9JRDBfUkVHLCAmdmVuZG9yX2lkc1sw XSk7Cj4+ICvCoMKgwqAgcmVnbWFwX3JlYWQoY3R4LT5yZWdtYXAsIElUNjYxMjFfVkVORE9SX0lE MV9SRUcsICZ2ZW5kb3JfaWRzWzFdKTsKPj4gK8KgwqDCoCByZWdtYXBfcmVhZChjdHgtPnJlZ21h cCwgSVQ2NjEyMV9ERVZJQ0VfSUQwX1JFRywgJmRldmljZV9pZHNbMF0pOwo+PiArwqDCoMKgIHJl Z21hcF9yZWFkKGN0eC0+cmVnbWFwLCBJVDY2MTIxX0RFVklDRV9JRDFfUkVHLCAmZGV2aWNlX2lk c1sxXSk7Cj4+ICsKPj4gK8KgwqDCoCAvKiBSZXZpc2lvbiBpcyBzaGFyZWQgd2l0aCBERVZJQ0Vf SUQxICovCj4+ICvCoMKgwqAgcmV2aXNpb25faWQgPSBGSUVMRF9HRVQoSVQ2NjEyMV9SRVZJU0lP Tl9NQVNLLCBkZXZpY2VfaWRzWzFdKTsKPj4gK8KgwqDCoCBkZXZpY2VfaWRzWzFdICY9IElUNjYx MjFfREVWSUNFX0lEMV9NQVNLOwo+PiArCj4+ICvCoMKgwqAgaWYgKHZlbmRvcl9pZHNbMF0gIT0g SVQ2NjEyMV9WRU5ET1JfSUQwIHx8IHZlbmRvcl9pZHNbMV0gIT0gSVQ2NjEyMV9WRU5ET1JfSUQx IHx8Cj4+ICvCoMKgwqDCoMKgwqDCoCBkZXZpY2VfaWRzWzBdICE9IElUNjYxMjFfREVWSUNFX0lE MCB8fCBkZXZpY2VfaWRzWzFdICE9IElUNjYxMjFfREVWSUNFX0lEMSkgewo+PiArwqDCoMKgwqDC oMKgwqAgaXRlNjYxMjFfcG93ZXJfb2ZmKGN0eCk7Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4g LUVOT0RFVjsKPj4gK8KgwqDCoCB9Cj4+ICsKPj4gK8KgwqDCoCBjdHgtPmJyaWRnZS5mdW5jcyA9 ICZpdDY2MTIxX2JyaWRnZV9mdW5jczsKPj4gK8KgwqDCoCBjdHgtPmJyaWRnZS5vZl9ub2RlID0g ZGV2LT5vZl9ub2RlOwo+PiArCj4+ICvCoMKgwqAgcmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVhZGVk X2lycShkZXYsIGNsaWVudC0+aXJxLCBOVUxMLMKgwqDCoCBpdDY2MTIxX2lycV90aHJlYWRlZF9o YW5kbGVyLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSVJRRl9T SEFSRUQgfCBJUlFGX09ORVNIT1QsIGRldl9uYW1lKGRldiksIGN0eCk7Cj4+ICvCoMKgwqAgaWYg KHJldCA8IDApIHsKPj4gK8KgwqDCoMKgwqDCoMKgIGRldl9lcnIoZGV2LCAiRmFpbGVkIHRvIHJl cXVlc3QgaXJxICVkOiVkXG4iLCBjbGllbnQtPmlycSwgcmV0KTsKPj4gK8KgwqDCoMKgwqDCoMKg IGl0ZTY2MTIxX3Bvd2VyX29mZihjdHgpOwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsK Pj4gK8KgwqDCoCB9Cj4+ICsKPj4gK8KgwqDCoCBkcm1fYnJpZGdlX2FkZCgmY3R4LT5icmlkZ2Up Owo+PiArCj4+ICvCoMKgwqAgZGV2X2luZm8oY3R4LT5kZXYsICJJVDY2MTIxIHJldmlzaW9uICVk IHByb2JlZFxuIiwgcmV2aXNpb25faWQpOwo+PiArCj4+ICvCoMKgwqAgcmV0dXJuIDA7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaXQ2NjEyMV9yZW1vdmUoc3RydWN0IGkyY19jbGllbnQgKmNs aWVudCkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaXQ2NjEyMV9jdHggKmN0eCA9IGkyY19nZXRf Y2xpZW50ZGF0YShjbGllbnQpOwo+PiArCj4+ICvCoMKgwqAgaXRlNjYxMjFfcG93ZXJfb2ZmKGN0 eCk7Cj4+ICvCoMKgwqAgZHJtX2JyaWRnZV9yZW1vdmUoJmN0eC0+YnJpZGdlKTsKPj4gK8KgwqDC oCBrZnJlZShjdHgtPmVkaWQpOwo+PiArwqDCoMKgIG11dGV4X2Rlc3Ryb3koJmN0eC0+bG9jayk7 Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0 cnVjdCBvZl9kZXZpY2VfaWQgaXQ2NjEyMV9kdF9tYXRjaFtdID0gewo+PiArwqDCoMKgIHsgLmNv bXBhdGlibGUgPSAiaXRlLGl0NjYxMjEiIH0sCj4+ICvCoMKgwqAgeyB9Cj4+ICt9Owo+PiArTU9E VUxFX0RFVklDRV9UQUJMRShvZiwgaXQ2NjEyMV9kdF9tYXRjaCk7Cj4+ICsKPj4gK3N0YXRpYyBj b25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCBpdDY2MTIxX2lkW10gPSB7Cj4+ICvCoMKgwqAgeyAi aXQ2NjEyMSIsIDAgfSwKPj4gK8KgwqDCoCB7IH0KPj4gK307Cj4+ICtNT0RVTEVfREVWSUNFX1RB QkxFKGkyYywgaXQ2NjEyMV9pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBp dDY2MTIxX2RyaXZlciA9IHsKPj4gK8KgwqDCoCAuZHJpdmVyID0gewo+PiArwqDCoMKgwqDCoMKg wqAgLm5hbWXCoMKgwqAgPSAiaXQ2NjEyMSIsCj4+ICvCoMKgwqDCoMKgwqDCoCAub2ZfbWF0Y2hf dGFibGUgPSBpdDY2MTIxX2R0X21hdGNoLAo+PiArwqDCoMKgIH0sCj4+ICvCoMKgwqAgLnByb2Jl ID0gaXQ2NjEyMV9wcm9iZSwKPj4gK8KgwqDCoCAucmVtb3ZlID0gaXQ2NjEyMV9yZW1vdmUsCj4+ ICvCoMKgwqAgLmlkX3RhYmxlID0gaXQ2NjEyMV9pZCwKPj4gK307Cj4+ICsKPj4gK21vZHVsZV9p MmNfZHJpdmVyKGl0NjYxMjFfZHJpdmVyKTsKPj4gKwo+PiArTU9EVUxFX0FVVEhPUigiUGhvbmcg TEUiKTsKPj4gK01PRFVMRV9ERVNDUklQVElPTigiSVQ2NjEyMSBIRE1JIHRyYW5zbWl0dGVyIGRy aXZlciIpOwo+PiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+PiAtLSAKPj4gMi4yNS4xCj4+ Cj4gCj4gCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRy aS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRw czovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=