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=-13.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=unavailable 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 2A921C3F68F for ; Sun, 12 Jan 2020 17:26:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E845B2084D for ; Sun, 12 Jan 2020 17:26:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sJ/bBz+I" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733087AbgALR0d (ORCPT ); Sun, 12 Jan 2020 12:26:33 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:45372 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728512AbgALR0d (ORCPT ); Sun, 12 Jan 2020 12:26:33 -0500 Received: by mail-wr1-f65.google.com with SMTP id j42so6291355wrj.12; Sun, 12 Jan 2020 09:26:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=xVRZT7YHVPE3GbyttbmSvMk99hkpTLXEzonadfBniK0=; b=sJ/bBz+I6AX+VbqaGHYqU8oVcVl/3fSB0h+kVMFnrusHsAraBxY0dWeSBp/G6dF6VS KC3iiITMz4jGvTyFgMdWFv/IKS0nvXQGjasscb3dfzY5UDXLcJ8F43s9WRibK76KLk2I c4tCo4dpuJ0itfQSWTdmYgfgkTHkMqoI1jEQJmcC6AYjiCK5vcexTiLyYWe+2oaf1D7X n1xemEpadN4Z3XRFXs7Ysx4/EzdtgFKlHMLMD3Jwv7S28I230Ek2qNGbLPva3NdGiWEt zyqdsLAx3UCcNjPnhi4d1sx3JnxiT305p4d9Q7DL03PDA9H5c2Tr5gIytdsAZv2wKxVJ WQqw== 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=xVRZT7YHVPE3GbyttbmSvMk99hkpTLXEzonadfBniK0=; b=tJcq8MAegMe+lz2qur8n4FYPPvisOxiXO+1K7KLGCWNr+EGjQaQO2278KnxR196Yfw 0JPzPOG87NtfjstkHrtJYQAYbuuXmgsoSYI1sg2K9gk2AsuIHOkVCkGf4sP6RHAwyPQO 4yWOtyAmzdCcPHyXnA3Qv408npE2vqlEzpfOHweqTIBpEzaZnGjH8+wJDbf2xdCigaxl fBmAPFkmFEGtjBXowmP7SSqeUOCWr9+w7zGbxjIllLf5Kfdl7BmWzY6fFpccv0pOMcuE qJOrEpTE97a56hgS4m+Ky8UxteLGS+/HuuDMKXYncsS/UFg3To5yZctfazcHkI5HqZx0 dMxg== X-Gm-Message-State: APjAAAWKKtJmr9I6xNd4SGTqOpvIXbwRlKzAQU3hf/bI/WFwYjZOslZx C5iuLwJA4jTOf78pbEPlXOzOz9ko X-Google-Smtp-Source: APXvYqyNJb2sZ+BEdl8Qe/N/WrvcZaNsBPjLBsFGSsIaeCCg3xu/NTbmYXVL2WXphD8eiIaYdsHO/Q== X-Received: by 2002:adf:fbc9:: with SMTP id d9mr14694899wrs.20.1578849984608; Sun, 12 Jan 2020 09:26:24 -0800 (PST) Received: from [192.168.2.1] (ip51ccf9cd.speed.planet.nl. [81.204.249.205]) by smtp.gmail.com with ESMTPSA id 4sm10505338wmg.22.2020.01.12.09.26.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 12 Jan 2020 09:26:23 -0800 (PST) Subject: Re: [RFC PATCH v1 02/10] mtd: nand: raw: add rockchip nand controller driver To: Miquel Raynal Cc: richard@nod.at, vigneshr@ti.com, robh+dt@kernel.org, mark.rutland@arm.com, heiko@sntech.de, linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org References: <20200108205338.11369-1-jbx6244@gmail.com> <20200108205338.11369-3-jbx6244@gmail.com> <20200110120534.1b4026b0@xps13> From: Johan Jonker Message-ID: <7a477af0-1448-4f26-4004-9331978e824c@gmail.com> Date: Sun, 12 Jan 2020 18:26:20 +0100 User-Agent: Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Thunderbird/68.3.0 MIME-Version: 1.0 In-Reply-To: <20200110120534.1b4026b0@xps13> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Miquel, Thank you for your detailed and useful review. Without manufacturer support I must scrape my information from all over the internet, together with slow interpretation of Rockchip drivers. So please have some patience with my updates and new versions. Below are some comments and questions in random order. ///////////////////////////// To prevent guessing games could you confirm the following names: driver file name: rockchip-nand-controller.c document file name: rockchip-nand-controller.yaml compatible: "rockchip,nandc-v6" compatible: "rockchip,nandc-v9" ///////////////////////////// My incomplete sort list for controller versions. Can someone with access to the RV1108 TRM (manual) report the details for the Nandc Version Register and whether it is compatible. Thanks. Added version 7 for RK3228A/RK3228B. Can someone with insider info confirm if this works or not. RK3066/PX2 NANDC_NANDC_VER 0x0160 W 0x56363030 Nandc Version Register RK3188 NANDC_NANDC_VER 0x0160 W 0x56363030 Nandc Version Register PX3 NANDC_NANDC_VER 0x0160 W 0x56363030 Nandc Version Register RK312X NANDC_NANDC_VER 0x0160 W 0x56363232 Nandc Version Register RK3288 NANDC_NANDC_VER 0x0160 W 0x56363232 Nandc Version Register RK3368/PX5 NANDC_NANDC_VER 0x0160 W 0x56363232 Nandc Version Register RK3228A/RK3228B NANDC_NANDC_VER 0x0160 W 0x00000701 Nandc Version Register RK3308 NANDC_NANDC_VER 0x0160 W 0x00000801 Nandc Version Register RK3326/PX30 NANDC_NANDC_VER 0x0080 W 0x56393030 Nandc Version Register RK3328 NO NANDC RK3399 NO NANDC RV1108 unknown ///////////////////////////// My debug kernel.log with 1 partition in dts. Jan 1 00:02:27 mk808 kernel: [ 147.051587] rockchip-nandc 10500000.nand-controller: get clk_nandc failed Jan 1 00:02:27 mk808 kernel: [ 147.052402] nand: device found, Manufacturer ID: 0xad, Chip ID: 0xde Jan 1 00:02:27 mk808 kernel: [ 147.052945] nand: Hynix H27UCG8T2ATR-BC 64G 3.3V 8-bit Jan 1 00:02:27 mk808 kernel: [ 147.053388] nand: 8192 MiB, MLC, erase size: 2048 KiB, page size: 8192, OOB size: 640 Jan 1 00:02:27 mk808 kernel: [ 147.054050] rockchip-nandc 10500000.nand-controller: nand->numchips = 1 Jan 1 00:02:27 mk808 kernel: [ 147.054740] rockchip-nandc 10500000.nand-controller: nand->chipsize = 8589934592 Jan 1 00:02:27 mk808 kernel: [ 147.055380] rockchip-nandc 10500000.nand-controller: nand->pagemask = fffff Jan 1 00:02:27 mk808 kernel: [ 147.055994] rockchip-nandc 10500000.nand-controller: nand->badblockpos = 0 Jan 1 00:02:27 mk808 kernel: [ 147.056591] rockchip-nandc 10500000.nand-controller: nand->chip_shift = 33 Jan 1 00:02:27 mk808 kernel: [ 147.057174] rockchip-nandc 10500000.nand-controller: nand->page_shift = 13 Jan 1 00:02:27 mk808 kernel: [ 147.057751] rockchip-nandc 10500000.nand-controller: nand->phys_erase_shift = 21 Jan 1 00:02:27 mk808 kernel: [ 147.058366] rockchip-nandc 10500000.nand-controller: nand->ecc.mode = 3 Jan 1 00:02:27 mk808 kernel: [ 147.058920] rockchip-nandc 10500000.nand-controller: nand->ecc.steps = 8 Jan 1 00:02:27 mk808 kernel: [ 147.059481] rockchip-nandc 10500000.nand-controller: nand->ecc.bytes = 70 Jan 1 00:02:27 mk808 kernel: [ 147.060049] rockchip-nandc 10500000.nand-controller: nand->ecc.total = 0 Jan 1 00:02:27 mk808 kernel: [ 147.060607] rockchip-nandc 10500000.nand-controller: nand->ecc.prepad = 4 Jan 1 00:02:27 mk808 kernel: [ 147.061175] rockchip-nandc 10500000.nand-controller: nand->ecc.size = 1024 Jan 1 00:02:27 mk808 kernel: [ 147.061748] rockchip-nandc 10500000.nand-controller: nand->ecc.strength = 40 Jan 1 00:02:27 mk808 kernel: [ 147.062341] rockchip-nandc 10500000.nand-controller: mtd->ooblayout = 91ce9ce2 Jan 1 00:02:27 mk808 kernel: [ 147.062943] rockchip-nandc 10500000.nand-controller: mtd->flags = 00000000 Jan 1 00:02:27 mk808 kernel: [ 147.063518] rockchip-nandc 10500000.nand-controller: mtd->size = 8589934592 Jan 1 00:02:27 mk808 kernel: [ 147.064098] rockchip-nandc 10500000.nand-controller: mtd->erasesize = 2097152 Jan 1 00:02:27 mk808 kernel: [ 147.064815] rockchip-nandc 10500000.nand-controller: mtd->writesize = 8192 Jan 1 00:02:27 mk808 kernel: [ 147.065413] rockchip-nandc 10500000.nand-controller: mtd->oobsize = 640 Jan 1 00:02:27 mk808 kernel: [ 147.068985] 1 fixed-partitions partitions found on MTD device 10500000.nand-controller.0 Jan 1 00:02:27 mk808 kernel: [ 147.069190] Creating 1 MTD partitions on "10500000.nand-controller.0": Jan 1 00:02:27 mk808 kernel: [ 147.072375] 0x000000000000-0x000000400000 : "parameter" Jan 1 00:02:27 mk808 kernel: [ 147.075649] rockchip-nandc 10500000.nand-controller: R:0x00ff cs:0 Jan 1 00:02:27 mk808 kernel: [ 147.079423] rockchip-nandc 10500000.nand-controller: R:0x01ff cs:0 Despite nand->options = NAND_SKIP_BBTSCAN. What is the reason for these 2 rk_nandc_hw_syndrome_ecc_read_page() commands at page R:0x00ff and R:0x01ff right after creating partitions. When enabled BBTSCAN MTD starts to store at all kind of places. Can you state there page address logic, ie. Would that damage the excisting Rockchip layout? ///////////////////////////// No bad block support Based on: drivers: mtd: nand: rockchip nandc add bad block detect api https://github.com/rockchip-linux/u-boot/commit/ 7aec704a4e9d9322f1102bcf61ee5c3cf6ec794d rockchip: drivers: mtd: nand: modify the bad block detection process https://github.com/rockchip-linux/u-boot/commit/ d6d708d1a329a6369143e8dd34cf4e2c81d5d92f BCH | oob size ------------------------ 16: bytes: 28 + 4 = 32 24: bytes: 42 + 4 = 46 40: bytes: 70 + 4 = 74 60: bytes: 106 + 4 = 110 The data layout that is written by an internal Rockchip nandc dma is: 1024 bytes data + 32 obb + 1024 data + 32 obb ... The MTD system however tries to detect bad block flags located at: 2048, 4096, 8192... The system checks for bad blocks and looks at the wrong bad block marker location. Yifeng Zhao proposes to add a bad block detecting strategy by doing a read with rk_nandc_hw_syndrome_ecc_read_page() first, if failure then assume it's still raw unwritten NAND and test bytes are at the position MTD normaly would check for right from the factory. When this function is used on a FTL controlled NAND it creates an awful lot of errors in the kernel log, because it uses the BB marker for dirty tag tricks for there data storage. So what is good for a raw empty NAND without FTL does not work for the majority of Rockchip devices I think. Please advise for other options. static uint8_t rk_nand_read_byte(struct nand_chip *nand) { uint8_t ret; rk_nand_read_buf(nand, &ret, 1); return ret; } static int rk_nand_block_bad(struct nand_chip *nand, loff_t ofs) { struct mtd_info *mtd = nand_to_mtd(nand); int page, res = 0; u16 bad = 0xff; u8 *buf = nand_get_data_buf(nand); int chipnr = (int)(ofs >> nand->chip_shift); page = (int)(ofs >> nand->page_shift) & nand->pagemask; rk_nand_select_chip(nand, chipnr); if (rk_nand_hw_syndrome_ecc_read_page(nand, buf, false, page) == -1) { /* first page of a block*/ nand_read_page_op(nand, page, nand->badblockpos, NULL, 0); bad = rk_nand_read_byte(nand); if (bad != 0xFF) res = 1; /* second page of a block*/ nand_read_page_op(nand, page + 1, nand->badblockpos, NULL, 0); bad = rk_nand_read_byte(nand); if (bad != 0xFF) res = 1; /* last page of a block */ page += ((mtd->erasesize - mtd->writesize) >> nand->chip_shift); page--; nand_read_page_op(nand, page, nand->badblockpos, NULL, 0); bad = rk_nand_read_byte(nand); if (bad != 0xFF) res = 1; } rk_nand_select_chip(nand, -1); return res; } This also requires a patch for nand_bbt.c As I try to get to get some shape in the rest of this driver, I have left it out for version 1 and as I wait for our respons first. drivers/mtd/nand/nand_bbt.c @@ -487,8 +487,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, int ret; BUG_ON(bd->options & NAND_BBT_NO_OOB); ret = scan_block_fast(mtd, bd, from, buf, numpages); if (this->block_bad) ret = this->block_bad(mtd, from); else ret = scan_block_fast(mtd, bd, from, buf, numpages); ///////////////////////////// Data structures/Partitions The majority of Rockchip devices use a closed source FTL driver, so when we want to read or write we must deal with it. Example MTD string: mtdparts=rk29xxnand: 0x00002000@0x00002000(misc), 0x00008000@0x00004000(kernel), 0x00008000@0x0000C000(boot), 0x00008000@0x00014000(recovery), 0x000C0000@0x0001C000(backup), 0x00040000@0x000DC000(cache), 0x00300000@0x0011C000(userdata), 0x00002000@0x0041C000(kpanic), 0x00200000@0x0041E000(system), -@0x0063E000(user)" When Rockchip mentions a string like this it has nothing to do with the real position on NAND. FTL write where wants, so reading there is not useful. All sizes have to be multiplied by 512 and casted to (u64)! All partitions need to contain at least 2 erase blocks. One for normal use and one spare. -------------------- FlashSavePhyInfo RawIdbData -------------------- ... FTL data ... -------------------- Map blocks: + L2pMapInfo + VendorBlkInfo Sys info: + sys_save_data Vendor partition: + sys_ext_data 0 + ect_tbl_info 64 + vendor 256 + ? + BootConfig 512 + 0 + DrmKeyInfo 512 + 1 + Vendor0Info 512 + 2 + Vendor1Info 512 + 3 + sys 512 + ? + public key 520 -------------------- Bad Block Map Tbl(not compatible with MTD) -------------------- reserved: last NAND block - n -------------------- >From the above diagram only RawIdbData has to be located in the first erase block. Boot ROM searches for the tag ID_IDRW = 0xFCDC8C3B. Only the first 4 sections (4*1024) of a page are used. When writing multiple pages extra spaces in the data for between the sections are required. Older cpu's (RK3066) might need extra RC4 coding. FTL uses that RawIdbData area unfortunately also to save struct FlashSavePhyInfo. For a bare basic application only RawIdbData is needed. For users that might consider MTD as a option to do something on a Rockchip NAND see the source code below to get an indication of what is needed for a useful setup to just read and write a bootloader alone. Writing of any user partition is not even included. Having a basic MTD driver is just not enough. Please advise if such a overhead can interface with MTD? Have fun! ///////////////////////////// On 1/10/20 12:05 PM, Miquel Raynal wrote: > Hi Johan, > > Johan Jonker wrote on Wed, 8 Jan 2020 21:53:30 > +0100: > >> From: Yifeng Zhao >> > > Can you change the title to "mtd: rawnand: rockchip: Add NAND > controller driver" > >> Add basic Rockchip nand controller driver. >> >> Compatible with hardware version 6 and 9. >> V6:16, 24, 40, 60 per 1024B BCH/ECC. >> V9:16, 40, 60, 70 per 1024B BCH/ECC. >> 8 bit asynchronous flash interface support. >> Supports up to 2 identical nandc nodes. >> Max 4 nand chips per controller. >> Able to select a different hardware ecc setup >> for the loader blocks. >> No bad block support. > > Thank you very much for this series, as the bad blocks support is > absolutely fundamental, I wonder what is the issue here? > >> >> Signed-off-by: Yifeng Zhao >> Signed-off-by: Johan Jonker >> --- >> drivers/mtd/nand/raw/Kconfig | 8 + >> drivers/mtd/nand/raw/Makefile | 1 + >> drivers/mtd/nand/raw/rockchip_nandc.c | 1224 +++++++++++++++++++++++++++++++++ >> 3 files changed, 1233 insertions(+) >> create mode 100644 drivers/mtd/nand/raw/rockchip_nandc.c >> >> diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig >> index 74fb91ade..68dc9a36d 100644 >> --- a/drivers/mtd/nand/raw/Kconfig >> +++ b/drivers/mtd/nand/raw/Kconfig >> @@ -457,6 +457,14 @@ config MTD_NAND_CADENCE >> Enable the driver for NAND flash on platforms using a Cadence NAND >> controller. >> >> +config MTD_NAND_ROCKCHIP >> + tristate "Rockchip raw NAND controller driver" >> + depends on ARCH_ROCKCHIP || COMPILE_TEST >> + depends on HAS_IOMEM >> + help >> + Enables support for the Rockchip raw NAND controller driver. >> + This controller is found on rk3066, rk3188, rk3288 and more. > > Can you write an exhaustive list if you know it? Or at least the > families? It is quite challenging when you are not in the Rockchip > world to know what SoC is similar to another random SoC. See above. > >> + >> comment "Misc" >> >> config MTD_SM_COMMON >> diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile >> index 2d136b158..3063fe74a 100644 >> --- a/drivers/mtd/nand/raw/Makefile >> +++ b/drivers/mtd/nand/raw/Makefile >> @@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o >> obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o >> obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o >> obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o >> +obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip_nandc.o > > A driver named rockchip-nand-controller.c would be nice! > >> >> nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o >> nand-objs += nand_onfi.o >> diff --git a/drivers/mtd/nand/raw/rockchip_nandc.c b/drivers/mtd/nand/raw/rockchip_nandc.c >> new file mode 100644 >> index 000000000..018308e58 >> --- /dev/null >> +++ b/drivers/mtd/nand/raw/rockchip_nandc.c >> @@ -0,0 +1,1224 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Based on: >> + * https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/mtd/nand/ >> + * rockchip_nand_v6.c >> + * https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/mtd/nand/ >> + * rockchip_nand_v9.c > > I'm not sure the entire link is relevant, I would simple mention the > Rockchip official Github repository and work from Yifeng. > >> + * Copyright (c) 2016-2019 Yifeng Zhao yifeng.zhao@rock-chips.com >> + * >> + * Update/restyle for linux-next. >> + * Add exec_op function. > > You can drop these two lines too. This is more a "commit description" > thing. > >> + * Combine driver for nandc version 6 and 9. > > Support NAND controller versions 6 and 9 found on SoCs ... > >> + * Copyright (c) 2020 Johan Jonker jbx6244@gmail.com >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#define NANDC_ID_V600 0x56363030 >> +#define NANDC_ID_V622 0x56363232 >> +#define NANDC_ID_V701 0x701 >> +#define NANDC_ID_V800 0x56383030 >> +#define NANDC_ID_V801 0x801 >> +#define NANDC_ID_V900 0x56393030 > > I would prefer prefixing everything RK_NANDC_ or RK_ Will change define list above and below to RK_NANDC_ It takes more space though. Already difficult to stay below 80 char/line. > >> + >> +#define NANDC_IDBResBlkNum 16 >> +#define NANDC_IDBEccBits 24 >> +#define NANDC_IDBStartAddr 0 >> + >> +#define NANDC_V6_ECC_16 0x00000000 >> +#define NANDC_V6_ECC_24 0x00000010 >> +#define NANDC_V6_ECC_40 0x00040000 >> +#define NANDC_V6_ECC_60 0x00040010 >> + >> +#define NANDC_V9_ECC_16 0x02000001 >> +#define NANDC_V9_ECC_40 0x04000001 >> +#define NANDC_V9_ECC_60 0x06000001 >> +#define NANDC_V9_ECC_70 0x00000001 >> + >> +#define NANDC_NUM_BANKS 4 >> +#define NANDC_DEF_TIMEOUT 10000 >> + >> +#define NANDC_REG_DATA 0x00 >> +#define NANDC_REG_ADDR 0x04 >> +#define NANDC_REG_CMD 0x08 >> + >> +/* register offset nandc version 6 */ >> +#define NANDC_REG_V6_FMCTL 0x00 >> +#define NANDC_REG_V6_FMWAIT 0x04 >> +#define NANDC_REG_V6_FLCTL 0x08 >> +#define NANDC_REG_V6_BCHCTL 0x0c >> +#define NANDC_REG_V6_DMA_CFG 0x10 >> +#define NANDC_REG_V6_DMA_BUF0 0x14 >> +#define NANDC_REG_V6_DMA_BUF1 0x18 >> +#define NANDC_REG_V6_DMA_ST 0x1C >> +#define NANDC_REG_V6_BCHST 0x20 >> +#define NANDC_REG_V6_RANDMZ 0x150 >> +#define NANDC_REG_V6_VER 0x160 >> +#define NANDC_REG_V6_INTEN 0x16C >> +#define NANDC_REG_V6_INTCLR 0x170 >> +#define NANDC_REG_V6_INTST 0x174 >> +#define NANDC_REG_V6_SPARE0 0x200 >> +#define NANDC_REG_V6_SPARE1 0x230 >> + >> +/* register offset nandc version 9 */ >> +#define NANDC_REG_V9_FMCTL 0x00 >> +#define NANDC_REG_V9_FMWAIT 0x04 >> +#define NANDC_REG_V9_FLCTL 0x10 >> +#define NANDC_REG_V9_BCHCTL 0x20 >> +#define NANDC_REG_V9_DMA_CFG 0x30 >> +#define NANDC_REG_V9_DMA_BUF0 0x34 >> +#define NANDC_REG_V9_DMA_BUF1 0x38 >> +#define NANDC_REG_V9_DMA_ST 0x40 >> +#define NANDC_REG_V9_VER 0x80 >> +#define NANDC_REG_V9_INTEN 0x120 >> +#define NANDC_REG_V9_INTCLR 0x124 >> +#define NANDC_REG_V9_INTST 0x128 >> +#define NANDC_REG_V9_BCHST 0x150 >> +#define NANDC_REG_V9_SPARE0 0x200 >> +#define NANDC_REG_V9_SPARE1 0x204 >> +#define NANDC_REG_V9_RANDMZ 0x208 >> + >> +/* register offset nandc common */ >> +#define NANDC_REG_BANK0 0x800 >> +#define NANDC_REG_SRAM0 0x1000 >> + >> +/* FMCTL */ >> +#define NANDC_V6_FM_WP BIT(8) >> +#define NANDC_V6_FM_CE_SEL_M 0xFF >> +#define NANDC_V6_FM_CE_SEL(x) (1 << (x)) >> +#define NANDC_V6_FM_FREADY BIT(9) >> + >> +#define NANDC_V9_FM_WP BIT(8) >> +#define NANDC_V9_FM_CE_SEL_M 0xFF >> +#define NANDC_V9_FM_CE_SEL(x) (1 << (x)) >> +#define NANDC_V9_RDY BIT(9) >> + >> +/* FLCTL */ >> +#define NANDC_V6_FL_RST BIT(0) >> +#define NANDC_V6_FL_DIR(x) ((x) ? BIT(1) : 0) >> +#define NANDC_V6_FL_XFER_START BIT(2) >> +#define NANDC_V6_FL_XFER_EN BIT(3) >> +#define NANDC_V6_FL_ST_BUF_S 0x4 >> +#define NANDC_V6_FL_XFER_COUNT BIT(5) >> +#define NANDC_V6_FL_ACORRECT BIT(10) >> +#define NANDC_V6_FL_XFER_READY BIT(20) >> +#define NANDC_V6_FL_PAGE_NUM(x) ((x) << 22) >> +#define NANDC_V6_FL_ASYNC_TOG_MIX BIT(29) >> + >> +#define NANDC_V9_FL_RST BIT(0) >> +#define NANDC_V9_FL_DIR(x) ((x) ? BIT(1) : 0) >> +#define NANDC_V9_FL_XFER_START BIT(2) >> +#define NANDC_V9_FL_XFER_EN BIT(3) >> +#define NANDC_V9_FL_ST_BUF_S 0x4 >> +#define NANDC_V9_FL_XFER_COUNT BIT(5) >> +#define NANDC_V9_FL_ACORRECT BIT(10) >> +#define NANDC_V9_FL_XFER_READY BIT(20) >> +#define NANDC_V9_FL_PAGE_NUM(x) ((x) << 22) >> +#define NANDC_V9_FL_ASYNC_TOG_MIX BIT(29) >> + >> +/* BCHCTL */ >> +#define NAND_V6_BCH_REGION_S 0x5 >> +#define NAND_V6_BCH_REGION_M 0x7 >> + >> +#define NAND_V9_BCH_MODE_S 25 >> +#define NAND_V9_BCH_MODE_M 0x7 >> + >> +/* BCHST */ >> +#define NANDC_V6_BCH0_ST_ERR BIT(2) >> +#define NANDC_V6_BCH1_ST_ERR BIT(15) >> +#define NANDC_V6_ECC_ERR_CNT0(x) ((((x & (0x1F << 3)) >> 3) \ >> + | ((x & (1 << 27)) >> 22)) & 0x3F) >> +#define NANDC_V6_ECC_ERR_CNT1(x) ((((x & (0x1F << 16)) >> 16) \ >> + | ((x & (1 << 29)) >> 24)) & 0x3F) >> + >> +#define NANDC_V9_BCH0_ST_ERR BIT(2) >> +#define NANDC_V9_BCH1_ST_ERR BIT(18) >> +#define NANDC_V9_ECC_ERR_CNT0(x) (((x) & (0x7F << 3)) >> 3) >> +#define NANDC_V9_ECC_ERR_CNT1(x) (((x) & (0x7F << 19)) >> 19) >> + >> +/* DMA_CFG */ >> +#define NANDC_V6_DMA_CFG_WR_ST BIT(0) >> +#define NANDC_V6_DMA_CFG_WR(x) ((!x) ? BIT(1) : 0) >> +#define NANDC_V6_DMA_CFG_BUS_MODE BIT(2) >> + >> +#define NANDC_V6_DMA_CFG_HSIZE_8 0 >> +#define NANDC_V6_DMA_CFG_HSIZE_16 (1 << 3) >> +#define NANDC_V6_DMA_CFG_HSIZE_32 (2 << 3) >> + >> +#define NANDC_V6_DMA_CFG_BURST_1 0 >> +#define NANDC_V6_DMA_CFG_BURST_4 (3 << 6) >> +#define NANDC_V6_DMA_CFG_BURST_8 (5 << 6) >> +#define NANDC_V6_DMA_CFG_BURST_16 (7 << 6) >> + >> +#define NANDC_V6_DMA_CFG_INCR_NUM(x) ((x) << 9) >> + >> +#define NANDC_V9_DMA_CFG_WR_ST BIT(0) >> +#define NANDC_V9_DMA_CFG_WR(x) ((!x) ? BIT(1) : 0) >> +#define NANDC_V9_DMA_CFG_BUS_MODE BIT(2) >> + >> +#define NANDC_V9_DMA_CFG_HSIZE_8 0 >> +#define NANDC_V9_DMA_CFG_HSIZE_16 (1 << 3) >> +#define NANDC_V9_DMA_CFG_HSIZE_32 (2 << 3) >> + >> +#define NANDC_V9_DMA_CFG_BURST_1 0 >> +#define NANDC_V9_DMA_CFG_BURST_4 (3 << 6) >> +#define NANDC_V9_DMA_CFG_BURST_8 (5 << 6) >> +#define NANDC_V9_DMA_CFG_BURST_16 (7 << 6) >> + >> +#define NANDC_V9_DMA_CFG_INCR_NUM(x) ((x) << 9) >> + >> +/* INTEN */ >> +#define NANDC_V6_INT_DMA BIT(0) >> + >> +#define NANDC_V9_INT_DMA BIT(0) >> + >> +enum rk_nandc_version { >> + VERSION_6 = 6, >> + VERSION_9 = 9, >> +}; >> + >> +struct rk_nandc_data { >> + enum rk_nandc_version version; > > If you make a distinction between both version, maybe you can add more > parameters here and do > > foo = data->param > > instead of > > if (data->version == 6) > foo = this; > else > foo = that; > TODO v2 >> +}; >> + >> +struct rk_nand_controller { >> + void __iomem *regs; >> + int irq; >> + struct clk *hclk; >> + struct clk *clk; >> + struct list_head chips; >> + struct completion complete; >> + struct nand_controller controller; >> + int banks[NANDC_NUM_BANKS]; > >> + bool bootromblocks; >> + int ecc_mode; >> + uint32_t ecc_strength; >> + int max_ecc_strength; > > I have not read yet the entire driver but I believe the above 4 > parameters should probably be moved in rk_nand_chip, right? Anything > that is NAND chip related should not be in the controller structure. It > depends if you can change ECC requirements on the fly or not. Short answer: The reason that it is the most convenience place to have them for now. With one pointer from nand_get_controller_data() I have all data available. struct rk_nand_controller *ctrl = nand_get_controller_data(nand); The ECC is now sort of fixed to 24 and 40 for legacy reasons. The older rk3066 bootrom apparently only works for ecc 24. See info based on older work by Paweł Jarosz for Uboot. I'm not too familiar with all inner working of MTD, so please advise. Can the users get access to struct rk_nand_chip? Would you like to give users control over what ecc to use? What program can we use for that? Can't use dd then any more. How do we regain ecc control if we really have to for example rk3066? Or remove that bootrom check and always set ECC with every rk_nandc_hw_syndrome_ecc_read_page and rk_nandc_hw_syndrome_ecc_write_page with whatever passed along? > >> + uint32_t *oob_buf; >> + uint32_t *page_buf; >> + int selected_bank; >> + enum rk_nandc_version version; >> +}; >> + >> +struct rk_nand_chip { >> + struct nand_chip nand; >> + struct list_head chip_list; >> +}; >> + >> +static struct rk_nand_controller g_nandc_info[2]; > > I don't like this idea so much. I prefer a dynamic allocation in the > probe. > >> +static int g_id_counter; > > Don't know what this is yet, but it is probably a bad idea :) > Maybe not interesting for MTD, but RK3288 has 2 identical NANDC's. The currect FTL setup only works with nandc0. To reuse the probe function for other things then MTD it needs to be aware of alias order. Will remove it for version 2. >> + >> +static void rk_nandc_init(struct rk_nand_controller *ctrl) >> +{ >> + if (ctrl->version == VERSION_9) { >> + writel(0, ctrl->regs + NANDC_REG_V9_RANDMZ); >> + writel(0, ctrl->regs + NANDC_REG_V9_DMA_CFG); >> + writel(NANDC_V9_FM_WP, ctrl->regs + NANDC_REG_V9_FMCTL); >> + writel(NANDC_V9_FL_RST, ctrl->regs + NANDC_REG_V9_FLCTL); >> + writel(0x1081, ctrl->regs + NANDC_REG_V9_FMWAIT); >> + } else { >> + writel(0, ctrl->regs + NANDC_REG_V6_RANDMZ); >> + writel(0, ctrl->regs + NANDC_REG_V6_DMA_CFG); >> + writel(NANDC_V6_FM_WP, ctrl->regs + NANDC_REG_V6_FMCTL); >> + writel(NANDC_V6_FL_RST, ctrl->regs + NANDC_REG_V6_FLCTL); >> + writel(0x1081, ctrl->regs + NANDC_REG_V6_FMWAIT); >> + } > > My above comment about the platform data would make a lot of sense here! > >> +} >> + >> +static irqreturn_t rk_nandc_interrupt(int irq, void *dev_id) >> +{ >> + struct rk_nand_controller *ctrl = dev_id; >> + >> + if (ctrl->version == VERSION_9) { >> + uint32_t st = readl(ctrl->regs + NANDC_REG_V9_INTST); >> + uint32_t ien = readl(ctrl->regs + NANDC_REG_V9_INTEN); >> + >> + if (!(ien & st)) >> + return IRQ_NONE; >> + >> + if ((ien & st) == ien) >> + complete(&ctrl->complete); >> + >> + writel(st, ctrl->regs + NANDC_REG_V9_INTCLR); >> + writel(~st & ien, ctrl->regs + NANDC_REG_V9_INTEN); >> + } else { >> + uint32_t st = readl(ctrl->regs + NANDC_REG_V6_INTST); >> + uint32_t ien = readl(ctrl->regs + NANDC_REG_V6_INTEN); >> + >> + if (!(ien & st)) >> + return IRQ_NONE; >> + >> + if ((ien & st) == ien) >> + complete(&ctrl->complete); >> + >> + writel(st, ctrl->regs + NANDC_REG_V6_INTCLR); >> + writel(~st & ien, ctrl->regs + NANDC_REG_V6_INTEN); >> + } > > Same comment! > >> + >> + return IRQ_HANDLED; >> +} >> + >> +static void rk_nandc_select_chip(struct nand_chip *nand, int chipnr) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + uint32_t reg; >> + int banknr; >> + >> + /* The register offset and bit positions for > > should be: > > /* > * The register... > > Please run checkpatch.pl --strict on this file, this kind of mistake > would have been detected. > When you think that you got rid of all warnings there's always an extra option for more... Thanks for that advice. >> + * NANDC_REG_V6_FMCTL and NANDC_REG_V9_FMCTL >> + * are identical. >> + */ >> + reg = readl(ctrl->regs + NANDC_REG_V6_FMCTL); >> + reg &= ~NANDC_V6_FM_CE_SEL_M; >> + >> + if (chipnr == -1) { >> + banknr = -1; >> + } else { >> + banknr = ctrl->banks[chipnr]; >> + >> + reg |= NANDC_V6_FM_CE_SEL(banknr); >> + } >> + writel(reg, ctrl->regs + NANDC_REG_V6_FMCTL); > > Maybe you can spare this writel by returning early if banknr == > ctrl->selected_bank. > >> + >> + ctrl->selected_bank = banknr; >> +} >> + >> +static int rk_nandc_hw_ecc_setup(struct nand_chip *nand, >> + uint32_t strength) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + uint32_t reg; >> + >> + nand->ecc.strength = strength; Should I add this comment below? /* HW ECC always request ECC bytes for 1024 bytes blocks */ >> + nand->ecc.bytes = DIV_ROUND_UP(nand->ecc.strength * 14, 8); > > What do 14 and 8 mean? fls - find last (most-significant) bit set int fls(unsigned int x) { int r = 32; if (!x) return 0; if (!(x & 0xffff0000u)) { x <<= 16; r -= 16; } if (!(x & 0xff000000u)) { x <<= 8; r -= 8; } if (!(x & 0xf0000000u)) { x <<= 4; r -= 4; } if (!(x & 0xc0000000u)) { x <<= 2; r -= 2; } if (!(x & 0x80000000u)) { x <<= 1; r -= 1; } return r; } nand->ecc.bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); formule is used to translate strength in bit/1024 BCH/ECC to MTD ECC bytes for 1024 bytes blocks in nand->ecc.bytes 14 is replacement for fls(8 * 1024) 8 bits in a byte > >> + /* HW ECC only works with an even number of ECC bytes */ >> + nand->ecc.bytes = ALIGN(nand->ecc.bytes, 2); >> + >> + if (ctrl->version == VERSION_9) { >> + switch (nand->ecc.strength) { >> + case 70: >> + reg = NANDC_V9_ECC_70; >> + break; >> + case 60: >> + reg = NANDC_V9_ECC_60; >> + break; >> + case 40: >> + reg = NANDC_V9_ECC_40; >> + break; >> + case 16: >> + reg = NANDC_V9_ECC_16; >> + break; >> + default: >> + return -EINVAL; >> + } >> + writel(reg, ctrl->regs + NANDC_REG_V9_BCHCTL); >> + } else { >> + switch (nand->ecc.strength) { >> + case 60: >> + reg = NANDC_V6_ECC_60; >> + break; >> + case 40: >> + reg = NANDC_V6_ECC_40; >> + break; >> + case 24: >> + reg = NANDC_V6_ECC_24; >> + break; >> + case 16: >> + reg = NANDC_V6_ECC_16; >> + break; >> + default: >> + return -EINVAL; >> + } >> + writel(reg, ctrl->regs + NANDC_REG_V6_BCHCTL); >> + } >> + >> + return 0; >> +} >> + >> +static void rk_nandc_xfer_start(struct rk_nand_controller *ctrl, >> + uint8_t dir, uint8_t n_KB, >> + dma_addr_t dma_data, dma_addr_t dma_oob) >> +{ >> + uint32_t reg; >> + >> + if (ctrl->version == VERSION_9) { >> + reg = NANDC_V9_DMA_CFG_WR_ST | >> + NANDC_V9_DMA_CFG_WR(dir) | >> + NANDC_V9_DMA_CFG_BUS_MODE | >> + NANDC_V9_DMA_CFG_HSIZE_32 | >> + NANDC_V9_DMA_CFG_BURST_16 | >> + NANDC_V9_DMA_CFG_INCR_NUM(16); >> + writel(reg, ctrl->regs + NANDC_REG_V9_DMA_CFG); >> + writel((uint32_t)dma_data, ctrl->regs + NANDC_REG_V9_DMA_BUF0); >> + writel((uint32_t)dma_oob, ctrl->regs + NANDC_REG_V9_DMA_BUF1); > > I'm pretty sure most of these writel could be turned into > writel_relaxed. writel() -- write to the little-endian hardware register with compiler memory barrier, writel_relaxed -- as above, without barrier, __raw_writel() -- as above (writel_relaxed()) without endianess conversion (CPU ordering will be used). Architecture-dependent. I don't know. > > Also I am not a big fan of these casts, maybe you should change > dma_data and dma_oob types (be careful: you enabled COMPILE_TEST in > Kconfig, you must support 32-bit and 64-bit pointers, please try to > compile this driver with different toolchains). Driver is used for both ARM as arm64. These registers are 32 bit. Please advise what happens when writel gets dma_addr_t and dma_data as 64 bit. Don't have the hardware to find out. > >> + >> + reg = NANDC_V9_FL_DIR(dir) | >> + NANDC_V9_FL_XFER_EN | >> + NANDC_V9_FL_XFER_COUNT | >> + NANDC_V9_FL_ACORRECT | >> + NANDC_V9_FL_PAGE_NUM(n_KB) | >> + NANDC_V9_FL_ASYNC_TOG_MIX; >> + writel(reg, ctrl->regs + NANDC_REG_V9_FLCTL); >> + reg |= NANDC_V9_FL_XFER_START; >> + writel(reg, ctrl->regs + NANDC_REG_V9_FLCTL); >> + } else { >> + reg = readl(ctrl->regs + NANDC_REG_V6_BCHCTL); >> + reg = (reg & (~(NAND_V6_BCH_REGION_M << >> + NAND_V6_BCH_REGION_S))) | >> + (ctrl->selected_bank << NAND_V6_BCH_REGION_S); >> + writel(reg, ctrl->regs + NANDC_REG_V6_BCHCTL); >> + >> + reg = NANDC_V6_DMA_CFG_WR_ST | >> + NANDC_V6_DMA_CFG_WR(dir) | >> + NANDC_V6_DMA_CFG_BUS_MODE | >> + NANDC_V6_DMA_CFG_HSIZE_32 | >> + NANDC_V6_DMA_CFG_BURST_16 | >> + NANDC_V6_DMA_CFG_INCR_NUM(16); >> + writel(reg, ctrl->regs + NANDC_REG_V6_DMA_CFG); >> + writel(dma_data, ctrl->regs + NANDC_REG_V6_DMA_BUF0); >> + writel(dma_oob, ctrl->regs + NANDC_REG_V6_DMA_BUF1); Same here. >> + >> + reg = NANDC_V6_FL_DIR(dir) | >> + NANDC_V6_FL_XFER_EN | >> + NANDC_V6_FL_XFER_COUNT | >> + NANDC_V6_FL_ACORRECT | >> + NANDC_V6_FL_PAGE_NUM(n_KB) | >> + NANDC_V6_FL_ASYNC_TOG_MIX; >> + writel(reg, ctrl->regs + NANDC_REG_V6_FLCTL); >> + reg |= NANDC_V6_FL_XFER_START; >> + writel(reg, ctrl->regs + NANDC_REG_V6_FLCTL); >> + } >> +} >> + >> +static int rk_nandc_wait_for_xfer_done(struct rk_nand_controller *ctrl) >> +{ >> + uint32_t reg; >> + int ret; >> + >> + if (ctrl->version == VERSION_9) { >> + void __iomem *ptr = ctrl->regs + NANDC_REG_V9_FLCTL; >> + >> + ret = readl_poll_timeout_atomic(ptr, reg, >> + reg & NANDC_V9_FL_XFER_READY, >> + 1, NANDC_DEF_TIMEOUT); >> + } else { >> + void __iomem *ptr = ctrl->regs + NANDC_REG_V6_FLCTL; >> + >> + ret = readl_poll_timeout_atomic(ptr, reg, >> + reg & NANDC_V6_FL_XFER_READY, >> + 1, NANDC_DEF_TIMEOUT); >> + } > > Space > >> + if (ret) >> + pr_err("timeout reg=%x\n", reg); >> + >> + return ret; >> +} >> + >> +static unsigned long rk_nandc_dma_map_single(struct device *dev, >> + void *ptr, int size, int dir) > > Unaligned parameters To restyle I use: astyle -T8 --max-code-length=80 --style=linux rockchip_nandc.c Please advise for a better solution. > >> +{ >> +#ifdef CONFIG_ARM64 >> + __dma_map_area((void *)ptr, size, dir); >> + return ((unsigned long)virt_to_phys((void *)ptr)); >> +#else >> + return dma_map_single(dev, (void *)ptr, size, dir); >> +#endif > > Please try to remove these #ifdefs, I don't know why would you need the > former block? This driver is used both for ARM as arm64. Original from Rockchip: arm64 doesn't have dma_map_single() as I remember. Don't know what to use instead. Please advise. > >> +} >> + >> +static void rk_nandc_dma_unmap_single(struct device *dev, >> + unsigned long ptr, int size, int dir) >> +{ >> +#ifdef CONFIG_ARM64 >> + __dma_unmap_area(phys_to_virt(ptr), size, dir); >> +#else >> + dma_unmap_single(dev, (dma_addr_t)ptr, size, dir); >> +#endif > > Same > >> +} >> + >> +static int rk_nandc_hw_syndrome_ecc_read_page(struct nand_chip *nand, >> + uint8_t *buf, >> + int oob_required, int page) > > Unaligned parameters (please check all of them). Again blame astyle ... After correcting it manually a few time I just left it as it is. > >> +{ >> + struct mtd_info *mtd = nand_to_mtd(nand); >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + struct nand_ecc_ctrl *ecc = &nand->ecc; >> + int max_bitflips = 0; >> + dma_addr_t dma_data, dma_oob; >> + int ret, i; >> + int bch_st; >> + int dma_oob_size = ecc->steps * 128; >> + int pages_per_blk = mtd->erasesize / mtd->writesize; >> + >> + rk_nandc_select_chip(nand, ctrl->selected_bank); >> + >> + if ((page < pages_per_blk * NANDC_IDBResBlkNum) && > > Camel case is usually not welcome Any suggestions for a beter replace for NANDC_IDBResBlkNum are welcome. > >> + ctrl->bootromblocks) > > This would probably deserve a helper > >> + rk_nandc_hw_ecc_setup(nand, NANDC_IDBEccBits); >> + >> + nand_read_page_op(nand, page, 0, NULL, 0); >> + >> + dma_data = rk_nandc_dma_map_single(mtd->dev.parent, >> + ctrl->page_buf, mtd->writesize, >> + DMA_FROM_DEVICE); >> + dma_oob = rk_nandc_dma_map_single(mtd->dev.parent, >> + ctrl->oob_buf, dma_oob_size, >> + DMA_FROM_DEVICE); >> + >> + init_completion(&ctrl->complete); > > One init_completion is needed (in the probe, probably) then please use > reinit_completion(). Must study this later. > >> + if (ctrl->version == VERSION_9) >> + writel(NANDC_V9_INT_DMA, ctrl->regs + NANDC_REG_V9_INTEN); >> + else >> + writel(NANDC_V6_INT_DMA, ctrl->regs + NANDC_REG_V6_INTEN); >> + rk_nandc_xfer_start(ctrl, 0, ecc->steps, dma_data, dma_oob); >> + wait_for_completion_timeout(&ctrl->complete, msecs_to_jiffies(5)); >> + rk_nandc_wait_for_xfer_done(ctrl); > > Yous should check the return status of almost all the functions here. Please advise what ERROR code should be returned here that is compatible with MTD. > >> + rk_nandc_dma_unmap_single(mtd->dev.parent, dma_data, mtd->writesize, >> + DMA_FROM_DEVICE); >> + rk_nandc_dma_unmap_single(mtd->dev.parent, dma_oob, dma_oob_size, >> + DMA_FROM_DEVICE); >> + >> + memcpy(buf, ctrl->page_buf, mtd->writesize); >> + >> + if (oob_required) { >> + uint8_t *oob; >> + uint32_t tmp; > > Please use u8, u16 and u32 types. Should this be changed for the entire source? > >> + >> + for (i = 0; i < ecc->steps; i++) { >> + oob = nand->oob_poi + >> + i * (ecc->bytes + nand->ecc.prepad); >> + if (ctrl->version == VERSION_9) { >> + tmp = ctrl->oob_buf[i]; >> + } else { >> + uint8_t oob_step = (ctrl->ecc_mode <= 24) ? >> + 64 : 128; >> + tmp = ctrl->oob_buf[i * oob_step / 4]; >> + } >> + *oob++ = (uint8_t)tmp; >> + *oob++ = (uint8_t)(tmp >> 8); >> + *oob++ = (uint8_t)(tmp >> 16); >> + *oob++ = (uint8_t)(tmp >> 24); >> + } >> + } >> + >> + if (ctrl->version == VERSION_9) { >> + for (i = 0; i < ecc->steps / 2; i++) { >> + bch_st = readl(ctrl->regs + NANDC_REG_V9_BCHST + i * 4); >> + if (bch_st & NANDC_V9_BCH0_ST_ERR || >> + bch_st & NANDC_V9_BCH1_ST_ERR) { >> + mtd->ecc_stats.failed++; >> + max_bitflips = -1; >> + } else { >> + ret = NANDC_V9_ECC_ERR_CNT0(bch_st); >> + mtd->ecc_stats.corrected += ret; >> + max_bitflips = max_t(unsigned int, >> + max_bitflips, ret); >> + >> + ret = NANDC_V9_ECC_ERR_CNT1(bch_st); >> + mtd->ecc_stats.corrected += ret; >> + max_bitflips = max_t(unsigned int, >> + max_bitflips, ret); >> + } >> + } >> + } else { >> + for (i = 0; i < ecc->steps / 2; i++) { >> + bch_st = readl(ctrl->regs + NANDC_REG_V6_BCHST + i * 4); >> + if (bch_st & NANDC_V6_BCH0_ST_ERR || >> + bch_st & NANDC_V6_BCH1_ST_ERR) { >> + mtd->ecc_stats.failed++; >> + max_bitflips = -1; > > Why not using ret = $(real error) instead of using max_bitflips here? > > Then: > > if (ret) { > dev_err(); Do you really want to litter the kernel log with each time you hit a bad block, in case you use this function in a search bad block loop? Don't thinks so ... Please advise. > return ret; > } > > return max_bitflips; rk_nandc_hw_syndrome_ecc_read_page() is used in a bad block search strategy. I think max_bitflips = -1 was chosen as a saver value to return. Please advise what number range MTD interprets as max_bitflips or as fault. Also consider some uncontrolled status return value, it would be better if we are in control of what goes return. > >> + } else { >> + ret = NANDC_V6_ECC_ERR_CNT0(bch_st); >> + mtd->ecc_stats.corrected += ret; >> + max_bitflips = max_t(unsigned int, >> + max_bitflips, ret); >> + >> + ret = NANDC_V6_ECC_ERR_CNT1(bch_st); >> + mtd->ecc_stats.corrected += ret; >> + max_bitflips = max_t(unsigned int, >> + max_bitflips, ret); >> + } >> + } >> + } >> + >> + if (max_bitflips == -1) { >> + dev_err(mtd->dev.parent, >> + "read_page %x %x %x %x %x %p %x\n", >> + page, >> + max_bitflips, >> + bch_st, >> + ((uint32_t *)buf)[0], >> + ((uint32_t *)buf)[1], >> + buf, >> + (uint32_t)dma_data); > > This is not very informative, please write a real error message. Avoid > putting too much debug information, people will troubleshoot themselves > if needed. OK, agree. > >> + } >> + >> + if (ctrl->bootromblocks) >> + rk_nandc_hw_ecc_setup(nand, ctrl->ecc_mode); >> + > > You don't use the same condition as above. Why ? Maybe the helper would > help. A few less conditions to check. It won't do damage in case ecc is same before and after. Will make conditions equal. > >> + return max_bitflips; >> +} >> + >> +static int rk_nandc_hw_syndrome_ecc_write_page(struct nand_chip *nand, >> + const uint8_t *buf, >> + int oob_required, >> + int page) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(nand); >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + struct nand_ecc_ctrl *ecc = &nand->ecc; >> + dma_addr_t dma_data, dma_oob; >> + int i; >> + int dma_oob_size = ecc->steps * 128; >> + int pages_per_blk = mtd->erasesize / mtd->writesize; >> + >> + rk_nandc_select_chip(nand, ctrl->selected_bank); >> + >> + if ((page < pages_per_blk * NANDC_IDBResBlkNum) && >> + ctrl->bootromblocks) >> + rk_nandc_hw_ecc_setup(nand, NANDC_IDBEccBits); >> + >> + nand_prog_page_begin_op(nand, page, 0, NULL, 0); >> + >> + for (i = 0; i < ecc->steps; i++) { >> + uint32_t tmp; >> + >> + if (oob_required) { >> + uint8_t *oob; >> + >> + oob = nand->oob_poi + >> + i * (ecc->bytes + nand->ecc.prepad); >> + tmp = oob[0] | >> + (oob[1] << 8) | >> + (oob[2] << 16) | >> + (oob[3] << 24); >> + } else { >> + /* The first NANDC_IDBResBlkNum blocks are >> + * for the stored loader. The first 32 bits >> + * of oob must contain a sort of link to >> + * the next page address in that same block >> + * for the Bootrom. >> + * Depending on what FTL from Rockchip is used, >> + * the first 2 pages in the NANDC_IDBResBlkNum blocks >> + * are reserved for FlashPhyInfo. >> + * Raw IDB data then starts at page 2 or higher. > > I would separate the function to read/write the loader than the usual > read/write helpers to avoid any confusion on why you do these tricks. > > Maybe not the whole function, but at least the data/oob placement? > (This is really a suggestion) > >> + */ >> + if (!i && >> + page < pages_per_blk * NANDC_IDBResBlkNum && >> + page >= NANDC_IDBStartAddr) >> + tmp = (page & (pages_per_blk - 1)) * 4; >> + else >> + tmp = 0xFFFFFFFF; >> + } >> + if (ctrl->version == VERSION_9) { >> + ctrl->oob_buf[i] = tmp; >> + } else { >> + uint8_t oob_step = (ctrl->ecc_mode <= 24) ? >> + 64 : 128; >> + ctrl->oob_buf[i * oob_step / 4] = tmp; >> + } >> + } >> + >> + memcpy(ctrl->page_buf, buf, mtd->writesize); >> + dma_data = rk_nandc_dma_map_single(mtd->dev.parent, >> + ctrl->page_buf, mtd->writesize, >> + DMA_TO_DEVICE); >> + dma_oob = rk_nandc_dma_map_single(mtd->dev.parent, >> + ctrl->oob_buf, dma_oob_size, >> + DMA_TO_DEVICE); >> + init_completion(&ctrl->complete); >> + if (ctrl->version == VERSION_9) >> + writel(NANDC_V9_INT_DMA, ctrl->regs + NANDC_REG_V9_INTEN); >> + else >> + writel(NANDC_V6_INT_DMA, ctrl->regs + NANDC_REG_V6_INTEN); >> + rk_nandc_xfer_start(ctrl, 1, ecc->steps, dma_data, dma_oob); >> + wait_for_completion_timeout(&ctrl->complete, msecs_to_jiffies(10)); >> + rk_nandc_wait_for_xfer_done(ctrl); >> + rk_nandc_dma_unmap_single(mtd->dev.parent, dma_data, mtd->writesize, >> + DMA_TO_DEVICE); >> + rk_nandc_dma_unmap_single(mtd->dev.parent, dma_oob, dma_oob_size, >> + DMA_TO_DEVICE); >> + >> + if (ctrl->bootromblocks) >> + rk_nandc_hw_ecc_setup(nand, ctrl->ecc_mode); >> + >> + return nand_prog_page_end_op(nand); >> +} >> + >> +static int rk_nandc_hw_ecc_read_oob(struct nand_chip *nand, int page) >> +{ >> + uint8_t *buf = nand_get_data_buf(nand); >> + >> + return nand->ecc.read_page(nand, buf, true, page); >> +} >> + >> +static int rk_nandc_hw_ecc_write_oob(struct nand_chip *nand, int page) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(nand); >> + int ret; >> + uint8_t *buf = nand_get_data_buf(nand); >> + >> + memset(buf, 0xFF, mtd->writesize); >> + ret = nand->ecc.write_page(nand, buf, true, page); >> + if (ret) >> + return ret; >> + >> + return nand_prog_page_end_op(nand); >> +} >> + >> +static void rk_nandc_read_buf(struct nand_chip *nand, uint8_t *buf, int len) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + int offs = 0; >> + void __iomem *bank_base = ctrl->regs + NANDC_REG_BANK0 + >> + ctrl->selected_bank * 0x100; > > 0x100: Maybe a define OK, agree. > >> + >> + for (offs = 0; offs < len; offs++) >> + buf[offs] = readb(bank_base); >> +} >> + >> +static void rk_nandc_write_buf(struct nand_chip *nand, >> + const uint8_t *buf, int len) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + int offs = 0; >> + void __iomem *bank_base = ctrl->regs + NANDC_REG_BANK0 + >> + ctrl->selected_bank * 0x100; >> + >> + for (offs = 0; offs < len; offs++) >> + writeb(buf[offs], bank_base); >> +} >> + >> +static void rk_nandc_write_cmd(struct nand_chip *nand, uint8_t cmd) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + >> + void __iomem *bank_base = ctrl->regs + NANDC_REG_BANK0 + >> + ctrl->selected_bank * 0x100 + >> + NANDC_REG_CMD; > > You might want to write an helper to calculate bank_base, to avoid > repeating these lines. Even with a separate define or helper function I still have to supply my reg, selected_bank and offset. It doesn't make things cleaner pumping date to and from a helper or neither doesn't it shorten my source with a define. Tend to keep it as it is for now. If you agree of course. > >> + >> + writeb(cmd, bank_base); >> +} >> + >> +static void rk_nandc_write_addr(struct nand_chip *nand, uint8_t addr) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + >> + void __iomem *bank_base = ctrl->regs + NANDC_REG_BANK0 + >> + ctrl->selected_bank * 0x100 + >> + NANDC_REG_ADDR; >> + >> + writeb(addr, bank_base); >> +} >> + >> +static int rk_nandc_dev_ready(struct nand_chip *nand) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + >> + if (readl(ctrl->regs + NANDC_REG_V6_FMCTL) & NANDC_V6_FM_FREADY) >> + return 1; >> + >> + return 0; >> +} >> + >> +static int rk_nandc_ooblayout_ecc(struct mtd_info *mtd, int section, >> + struct mtd_oob_region *oobregion) >> +{ >> + struct nand_chip *nand = mtd_to_nand(mtd); >> + >> + if (section >= nand->ecc.steps) >> + return -ERANGE; >> + >> + oobregion->offset = (nand->ecc.bytes + nand->ecc.prepad) * section + >> + nand->ecc.prepad; >> + oobregion->length = nand->ecc.steps * nand->ecc.bytes; >> + >> + return 0; >> +} >> + >> +static int rk_nandc_ooblayout_free(struct mtd_info *mtd, int section, >> + struct mtd_oob_region *oobregion) >> +{ >> + struct nand_chip *nand = mtd_to_nand(mtd); >> + >> + if (section >= nand->ecc.steps) >> + return -ERANGE; >> + >> + oobregion->offset = (nand->ecc.bytes + nand->ecc.prepad) * section; >> + oobregion->length = nand->ecc.steps * nand->ecc.prepad; >> + >> + return 0; >> +} >> + >> +static const struct mtd_ooblayout_ops rk_nandc_oob_ops = { >> + .ecc = rk_nandc_ooblayout_ecc, >> + .free = rk_nandc_ooblayout_free, >> +}; >> + >> +static void rk_nandc_free_buffer(struct nand_chip *nand) >> +{ >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + >> + kfree(ctrl->page_buf); >> + kfree(ctrl->oob_buf); >> +} >> + >> +static int rk_nandc_buffer_init(struct nand_chip *nand) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(nand); >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + >> + ctrl->page_buf = kmalloc(mtd->writesize, GFP_KERNEL | GFP_DMA); > > device managed allocations (devm_...) would be nice devm_kzalloc() needs an extra struct device. Does MTD safe-gard the correct order to detach from struct rk_nand_controller without rk_nandc_free_buffer()? > >> + if (!ctrl->page_buf) >> + return -ENOMEM; >> + >> + ctrl->oob_buf = kmalloc(nand->ecc.steps * 128, GFP_KERNEL | GFP_DMA); >> + if (!ctrl->oob_buf) { >> + kfree(ctrl->page_buf); >> + return -ENOMEM; >> + } >> + >> + return 0; >> +} >> + >> +static int rk_nandc_hw_ecc_ctrl_init(struct nand_chip *nand) >> +{ >> + uint8_t strengths_v6[] = {60, 40, 24, 16}; >> + uint8_t strengths_v9[] = {70, 60, 40, 16}; >> + struct mtd_info *mtd = nand_to_mtd(nand); >> + struct rk_nand_controller *ctrl = nand_get_controller_data(nand); >> + int max_strength; >> + uint32_t i, ver; >> + >> + if (nand->options & NAND_IS_BOOT_MEDIUM) >> + ctrl->bootromblocks = true; >> + else >> + ctrl->bootromblocks = false; >> + >> + nand->ecc.prepad = 4; >> + nand->ecc.steps = mtd->writesize / nand->ecc.size; >> + >> + max_strength = ((mtd->oobsize / nand->ecc.steps) - 4) * 8 / 14; >> + if (ctrl->version == VERSION_9) { >> + ctrl->max_ecc_strength = 70; >> + ver = readl(ctrl->regs + NANDC_REG_V9_VER); >> + if (ver != NANDC_ID_V900) >> + dev_err(mtd->dev.parent, >> + "unsupported nandc version %x\n", ver); >> + >> + if (max_strength > ctrl->max_ecc_strength) >> + max_strength = ctrl->max_ecc_strength; >> + >> + for (i = 0; i < ARRAY_SIZE(strengths_v9); i++) { >> + if (max_strength >= strengths_v9[i]) >> + break; >> + } >> + >> + if (i >= ARRAY_SIZE(strengths_v9)) { >> + dev_err(mtd->dev.parent, >> + "unsupported strength\n"); >> + return -ENOTSUPP; >> + } >> + >> + ctrl->ecc_mode = strengths_v9[i]; >> + } else { >> + ctrl->max_ecc_strength = 60; >> + >> + ver = readl(ctrl->regs + NANDC_REG_V6_VER); >> + if (ver == NANDC_ID_V801) >> + ctrl->max_ecc_strength = 16; >> + else if (ver == NANDC_ID_V600 || >> + ver == NANDC_ID_V622 || >> + ver == NANDC_ID_V701 || Added version 7 for RK3228A/RK3228B. Can someone with insider info confirm if this works or not. >> + ver == NANDC_ID_V800) >> + ctrl->max_ecc_strength = 60; >> + else >> + dev_err(mtd->dev.parent, >> + "unsupported nandc version %x\n", ver); >> + >> + if (max_strength > ctrl->max_ecc_strength) >> + max_strength = ctrl->max_ecc_strength; >> + >> + for (i = 0; i < ARRAY_SIZE(strengths_v6); i++) { >> + if (max_strength >= strengths_v6[i]) >> + break; >> + } >> + >> + if (i >= ARRAY_SIZE(strengths_v6)) { >> + dev_err(mtd->dev.parent, >> + "unsupported strength\n"); >> + return -ENOTSUPP; >> + } >> + >> + ctrl->ecc_mode = strengths_v6[i]; >> + } >> + rk_nandc_hw_ecc_setup(nand, ctrl->ecc_mode); >> + >> + mtd_set_ooblayout(mtd, &rk_nandc_oob_ops); >> + >> + if (mtd->oobsize < ((nand->ecc.bytes + nand->ecc.prepad) * >> + nand->ecc.steps)) { >> + return -EINVAL; >> + } >> + >> + return 0; >> +} >> + >> +static void rk_nandc_detach_chip(struct nand_chip *nand) >> +{ >> + switch (nand->ecc.mode) { >> + case NAND_ECC_HW_SYNDROME: >> + rk_nandc_free_buffer(nand); >> + break; >> + default: >> + break; >> + } >> +} >> + >> +static int rk_nandc_attach_chip(struct nand_chip *nand) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(nand); >> + int ret; >> + >> + switch (nand->ecc.mode) { >> + case NAND_ECC_HW_SYNDROME: >> + ret = rk_nandc_hw_ecc_ctrl_init(nand); >> + if (ret) >> + return ret; >> + ret = rk_nandc_buffer_init(nand); >> + if (ret) >> + return -ENOMEM; >> + nand->ecc.read_page = rk_nandc_hw_syndrome_ecc_read_page; >> + nand->ecc.write_page = rk_nandc_hw_syndrome_ecc_write_page; >> + nand->ecc.read_oob = rk_nandc_hw_ecc_read_oob; >> + nand->ecc.write_oob = rk_nandc_hw_ecc_write_oob; >> + break; >> + case NAND_ECC_HW: > > I would either refuse ECC_HW or put it besides HW_SYNDROME. Is there a fundamental difference in handling ECC_HW and HW_SYNDROME from the MTD point of view? Other then a indication how it's done on the driver side? Will drop it. > >> + case NAND_ECC_NONE: >> + case NAND_ECC_SOFT: > > Have you tested with SW BCH? Short answer: No Just copied it from the original. Please advise a tool to do a test between the individual ecc read options. Or do I have to write the tool my self with mtd-utils? > >> + break; >> + default: >> + return -EINVAL; >> + } >> + >> + return 0; >> +} >> + >> +static int rk_nandc_exec_op(struct nand_chip *nand, >> + const struct nand_operation *op, >> + bool check_only) >> +{ >> + int i; >> + unsigned int op_id; >> + const struct nand_op_instr *instr = NULL; >> + >> + rk_nandc_select_chip(nand, op->cs); >> + >> + if (check_only) >> + return 0; >> + >> + for (op_id = 0; op_id < op->ninstrs; op_id++) { >> + instr = &op->instrs[op_id]; >> + >> + switch (instr->type) { >> + case NAND_OP_CMD_INSTR: >> + rk_nandc_write_cmd(nand, instr->ctx.cmd.opcode); >> + break; >> + case NAND_OP_ADDR_INSTR: >> + for (i = 0; i < instr->ctx.addr.naddrs; i++) >> + rk_nandc_write_addr(nand, >> + instr->ctx.addr.addrs[i]); >> + break; >> + case NAND_OP_DATA_IN_INSTR: >> + rk_nandc_read_buf(nand, instr->ctx.data.buf.in, >> + instr->ctx.data.len); >> + break; >> + case NAND_OP_DATA_OUT_INSTR: >> + rk_nandc_write_buf(nand, instr->ctx.data.buf.out, >> + instr->ctx.data.len); >> + break; >> + case NAND_OP_WAITRDY_INSTR: >> + rk_nandc_dev_ready(nand); >> + break; >> + } >> + } >> + >> + return 0; >> +} >> + >> +static const struct nand_controller_ops rk_nand_controller_ops = { >> + .attach_chip = rk_nandc_attach_chip, >> + .detach_chip = rk_nandc_detach_chip, >> + .exec_op = rk_nandc_exec_op, >> +}; >> + >> +static int rk_nandc_chip_init(struct device *dev, >> + struct rk_nand_controller *ctrl, >> + struct device_node *np, unsigned int chipnr) >> +{ >> + struct rk_nand_chip *node; >> + struct nand_chip *nand; >> + struct mtd_info *mtd; >> + const __be32 *reg; >> + int ret; >> + >> + reg = of_get_property(np, "reg", NULL); >> + if (!reg) >> + return -EINVAL; >> + >> + ctrl->banks[chipnr] = be32_to_cpu(*reg); >> + >> + if (ctrl->banks[chipnr] < 0) >> + return -EINVAL; >> + >> + node = devm_kzalloc(dev, sizeof(*node), GFP_KERNEL); >> + if (!node) >> + return -ENOMEM; >> + >> + nand = &node->nand; >> + >> + nand_set_flash_node(nand, np); >> + nand_set_controller_data(nand, ctrl); >> + >> + nand->controller = &ctrl->controller; >> + nand->controller->ops = &rk_nand_controller_ops; >> + >> + nand->ecc.mode = NAND_ECC_HW_SYNDROME; >> + nand->ecc.size = 1024; >> + nand->ecc.strength = 40; >> + >> + nand->options = NAND_SKIP_BBTSCAN | NAND_NO_SUBPAGE_WRITE; >> + >> + mtd = nand_to_mtd(nand); >> + mtd->dev.parent = dev; >> + mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), >> + ctrl->banks[chipnr]); >> + >> + ret = nand_scan(nand, 1); > > Why 1 here? TODO for version 2. A little misunderstanding on how for_each_child_of_node works. All chips should be scanned. ///// Derive chipnr Example from sunxi_nand.c if (!of_get_property(np, "reg", &nsels)) return -EINVAL; nsels /= sizeof(u32); if (!nsels) { dev_err(dev, "invalid reg property size\n"); return -EINVAL; } ///// >From rk_nandc_chips_init() for_each_child_of_node(np, nand_np) { ret = rk_nandc_chip_init(dev, ctrl, nand_np, i); Why does sunxi_nand.c need this extra for_each_child_of_node? > >> + if (ret) >> + return ret; >> + >> + ret = mtd_device_register(mtd, NULL, 0); >> + if (ret) { >> + dev_err(dev, "mtd device register failed: %d\n", ret); >> + nand_release(nand); >> + return ret; >> + } >> + >> + list_add_tail(&node->chip_list, &ctrl->chips); >> + >> + return 0; >> +} >> + >> +static int rk_nandc_cleanup_chips(struct rk_nand_controller *ctrl) >> +{ >> + struct rk_nand_chip *node; >> + struct mtd_info *mtd; >> + int ret; >> + >> + while (!list_empty(&ctrl->chips)) { >> + node = list_first_entry(&ctrl->chips, struct rk_nand_chip, >> + chip_list); >> + mtd = nand_to_mtd(&node->nand); >> + ret = mtd_device_unregister(mtd); >> + if (ret) >> + return ret; >> + >> + rk_nandc_free_buffer(&node->nand); >> + nand_cleanup(&node->nand); >> + list_del(&node->chip_list); >> + } >> + >> + return 0; >> +} >> + >> +static int rk_nandc_chips_init(struct device *dev, >> + struct rk_nand_controller *ctrl) >> +{ >> + struct device_node *np = dev->of_node; >> + struct device_node *nand_np; >> + int nchips = of_get_child_count(np); >> + int i = 0; >> + int ret; >> + >> + if (nchips > NANDC_NUM_BANKS) { >> + dev_err(dev, "too many NAND chips: %d (max = 4)\n", nchips); >> + return -EINVAL; >> + } >> + >> + for_each_child_of_node(np, nand_np) { >> + ret = rk_nandc_chip_init(dev, ctrl, nand_np, i); >> + if (ret) { >> + rk_nandc_cleanup_chips(ctrl); >> + of_node_put(nand_np); >> + return ret; >> + } >> + i++; >> + } >> + >> + return 0; >> +} >> + >> +static int rk_nandc_probe(struct platform_device *pdev) >> +{ >> + const struct rk_nandc_data *data; >> + struct device *dev = &pdev->dev; >> + struct device_node *node; >> + int id; >> + int ret; >> + >> + data = of_device_get_match_data(&pdev->dev); >> + if (!data) >> + return -ENODEV; >> + >> + node = pdev->dev.of_node; >> + >> + id = of_alias_get_id(node, "nandc"); >> + if (id < 0) >> + id = g_id_counter; >> + if ((id >= ARRAY_SIZE(g_nandc_info) || g_nandc_info[id].regs)) { >> + dev_err( >> + &pdev->dev, >> + "failed to get id for nandc node '%pOFn'\n", >> + node); >> + of_node_put(node); >> + return -ENODEV; >> + } >> + ++g_id_counter; See comments above about Rk3288. Keeping track node alias for nandc0. To remove or not? >> + >> + g_nandc_info[id].version = data->version; >> + >> + g_nandc_info[id].regs = devm_platform_ioremap_resource(pdev, 0); >> + if (IS_ERR(g_nandc_info[id].regs)) { >> + dev_err(dev, "ioremap failed\n"); >> + return PTR_ERR(g_nandc_info[id].regs); >> + } >> + >> + g_nandc_info[id].irq = platform_get_irq(pdev, 0); >> + if (g_nandc_info[id].irq < 0) { >> + dev_err(dev, "get irq failed\n"); >> + return g_nandc_info[id].irq; >> + } >> + >> + g_nandc_info[id].hclk = devm_clk_get(dev, "hclk_nandc"); >> + if (IS_ERR(g_nandc_info[id].hclk)) { >> + dev_err(dev, "get hclk_nandc failed\n"); >> + return PTR_ERR(g_nandc_info[id].hclk); >> + } >> + >> + ret = clk_prepare_enable(g_nandc_info[id].hclk); >> + if (ret) >> + return ret; >> + >> + g_nandc_info[id].clk = devm_clk_get(dev, "clk_nandc"); >> + if (!(IS_ERR(g_nandc_info[id].clk))) { >> + clk_set_rate(g_nandc_info[id].clk, 150 * 1000 * 1000); >> + >> + ret = clk_prepare_enable(g_nandc_info[id].clk); >> + if (ret) >> + goto err_disable_hclk; >> + } else >> + dev_err(dev, "get clk_nandc failed\n"); >> + >> + if (g_nandc_info[id].version == VERSION_9) >> + writel(0, g_nandc_info[id].regs + NANDC_REG_V9_INTEN); >> + else >> + writel(0, g_nandc_info[id].regs + NANDC_REG_V6_INTEN); >> + ret = devm_request_irq(dev, g_nandc_info[id].irq, rk_nandc_interrupt, >> + 0, "nandc", &g_nandc_info[id]); >> + if (ret) >> + goto err_disable_clk; >> + >> + nand_controller_init(&g_nandc_info[id].controller); >> + INIT_LIST_HEAD(&g_nandc_info[id].chips); >> + >> + rk_nandc_init(&g_nandc_info[id]); >> + >> + ret = rk_nandc_chips_init(dev, &g_nandc_info[id]); >> + if (ret) { >> + dev_err(dev, "init nand chips failed\n"); >> + goto err_disable_clk; >> + } >> + >> + platform_set_drvdata(pdev, &g_nandc_info[id]); >> + >> + return 0; >> + >> +err_disable_clk: >> + clk_disable_unprepare(g_nandc_info[id].clk); >> +err_disable_hclk: >> + clk_disable_unprepare(g_nandc_info[id].hclk); >> + >> + return ret; >> +} >> + >> +static int rk_nandc_remove(struct platform_device *pdev) >> +{ >> + struct rk_nand_controller *ctrl = platform_get_drvdata(pdev); >> + int ret; >> + >> + ret = rk_nandc_cleanup_chips(ctrl); >> + if (ret) >> + return ret; >> + >> + clk_disable_unprepare(ctrl->clk); >> + clk_disable_unprepare(ctrl->hclk); >> + platform_set_drvdata(pdev, NULL); >> + >> + return 0; >> +} >> + >> +static void rk_nandc_shutdown(struct platform_device *pdev) >> +{ >> + struct rk_nand_controller *ctrl = platform_get_drvdata(pdev); >> + int ret; >> + >> + ret = rk_nandc_cleanup_chips(ctrl); >> + if (ret) >> + return; >> + >> + clk_disable_unprepare(ctrl->clk); >> + clk_disable_unprepare(ctrl->hclk); >> + platform_set_drvdata(pdev, NULL); >> +} >> + >> +static const struct rk_nandc_data rk_nandc_v6_data = { >> + .version = VERSION_6, >> +}; >> + >> +static const struct rk_nandc_data rk_nandc_v9_data = { >> + .version = VERSION_9, >> +}; >> + >> +static const struct of_device_id of_rk_nandc_match[] = { >> + { >> + .compatible = "rockchip,nandc-v6", >> + .data = &rk_nandc_v6_data, >> + }, >> + { >> + .compatible = "rockchip,nandc-v9", >> + .data = &rk_nandc_v9_data, >> + }, Again to prevent guessing games please advise if "rockchip,nandc-v6" and "rockchip,nandc-v9" are correct or state the desired compatible strings. >> + { /* sentinel */ }, >> +}; >> + >> +static struct platform_driver rk_nandc_driver = { >> + .probe = rk_nandc_probe, >> + .remove = rk_nandc_remove, >> + .shutdown = rk_nandc_shutdown, >> + .driver = { >> + .name = "rockchip-nandc", >> + .of_match_table = of_rk_nandc_match, >> + }, >> +}; >> + > > Move this empty line... > >> +module_platform_driver(rk_nandc_driver); > > ...Here > >> +MODULE_LICENSE("GPL v2"); > > Thanks, > Miquèl > ////////////////////////////////// // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2019, Johan Jonker * * Based on: * https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/rk_nand/rk_ftl_arm_v7.S * https://raw.githubusercontent.com/rockchip-linux/kernel/develop-4.4/drivers/rk_nand/rk_ftl_arm_v7.S * Copyright (c) 2016-2018, Fuzhou Rockchip Electronics Co., Ltd * SPDX-License-Identifier: GPL-2.0+ * * https://github.com/rockchip-linux/u-boot/blob/next-dev/drivers/rknand/rk_ftl_arm_v7.S * https://raw.githubusercontent.com/rockchip-linux/u-boot/next-dev/drivers/rknand/rk_ftl_arm_v7.S * Copyright (c) 2016-2018, Fuzhou Rockchip Electronics Co., Ltd * SPDX-License-Identifier: GPL-2.0+ * * https://github.com/rockchip-linux/rkdeveloptool/blob/master/crc.cpp * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd * SPDX-License-Identifier: GPL-2.0+ */ enum NAND_TAG { ID_IDBT = 0xEFF0, ID_VNDR = 0xF086, ID_SBFX = 0xF095, ID_SYSB = 0xF0A4, ID_L2PM = 0xF0C2, ID_BBTB = 0xF0D1, ID_BBTF = 0xF0E0, ID_RGMP = 0xFAF5, ID_XXXW = 0xFFFF, ID_SBTG = 0x12345678, ID_CHCK = 0x12348765, ID_BTCE = 0x42544345, ID_FTLS = 0x46544C53, ID_HASH = 0x47C6A7E6, ID_NAND = 0x4E414E44, ID_VPCT = 0x50000056, ID_IDRW = 0xFCDC8C3B, ID_XXXD = 0xFFFFFFFF, }; struct __attribute__((aligned(4))) tagFlashSaveInfo { uint32_t Id; uint32_t Size; uint32_t JSHash; uint16_t gNandMaxDie; uint16_t gNandIDBResBlkNum; uint64_t IDByte[8]; uint16_t DieCsIndex[8]; uint64_t DieAddrs[8]; uint32_t gNandParaInfo[8]; uint32_t gNandOptPara[8]; uint8_t gReadRetryInfo[852]; uint32_t gFlashToggleModeEn; }; struct __attribute__((aligned(2))) tagNandOptPara { uint8_t res1[8]; uint8_t StartDpCmd; uint8_t EndDpCmd; uint8_t DpFirstCmd; uint8_t DpSecondCmd; uint8_t res6; uint8_t cmd2; uint8_t cmd1; uint8_t max; uint8_t option; uint8_t res11[15]; }; struct __attribute__((aligned(2))) tagNandParaInfo { uint8_t id_bytes; uint8_t nand_id[6]; uint8_t vendor; uint8_t die_per_chip; uint8_t sec_per_page; uint16_t page_per_blk; uint8_t cell; uint8_t plane_per_die; uint16_t blk_per_plane; uint16_t operation_opt; uint8_t lsb_mode; uint8_t read_retry_mode; uint8_t ecc_bits; uint8_t access_freq; uint8_t opt_mode; uint8_t die_gap; uint8_t bad_block_mode; uint8_t multi_plane_mode; uint8_t slc_mode; uint8_t reserved[5]; }; struct __attribute__((aligned(4))) tagNandPhyInfo { uint32_t chip_id; uint32_t vendor; uint16_t nand_type; uint16_t die_num; uint16_t planes_per_die; uint16_t blk_per_plane; uint16_t page_per_blk; uint16_t page_per_slc_blk; uint16_t sec_per_page; uint16_t block_size; uint16_t sector_size; uint16_t reserved_blks; }; struct tagReadRetryInfo { uint8_t retryMode; uint8_t size; uint8_t max; uint8_t res3; uint8_t addr[8]; uint8_t offset1[8]; uint8_t buf[832]; }; uint8_t gNandIDataBuf[2048]; struct tagNandParaInfo *gpNandParaInfo; struct tagNandOptPara gNandOptPara; struct tagNandPhyInfo gNandPhyInfo; struct tagReadRetryInfo gReadRetryInfo; uint16_t mlcPageToSlcPageTbl[512]; uint16_t slcPageToMlcPageTbl[256]; uint32_t *gFlashPageBuffer0; uint32_t *gFlashPageBuffer1; void P_RC4(uint8_t *buf, uint32_t size) { uint8_t key[16] = { 0x7C, 0x4E, 0x03, 0x04, 0x55, 0x05, 0x09, 0x07, 0x2D, 0x2C, 0x7B, 0x38, 0x17, 0x0D, 0x17, 0x11, }; uint8_t S[256], K[256], temp; uint32_t i, j, t, x; j = 0; for (i = 0; i < 256; i++) { S[i] = (uint8_t)i; j &= 0x0f; K[i] = key[j]; j++; } j = 0; for (i = 0; i < 256; i++) { j = (j + S[i] + K[i]) % 256; temp = S[i]; S[i] = S[j]; S[j] = temp; } i = j = 0; for (x = 0; x < size; x++) { i = (i+1) % 256; j = (j + S[i]) % 256; temp = S[i]; S[i] = S[j]; S[j] = temp; t = (S[i] + (S[j] % 256)) % 256; buf[x] = buf[x] ^ S[t]; } } uint32_t js_hash(uint8_t *buf, uint32_t size) { uint32_t hash; uint8_t *p_max; uint32_t tmp; hash = ID_HASH; p_max = &buf[size]; while (buf != p_max) { tmp = *buf++; hash ^= (hash >> 2) + 32 * hash + tmp; } return hash; } void BuildFlashLsbPageTable(uint32_t lsb_mode, uint16_t size) { uint32_t counter1; uint32_t counter2; uint32_t counter3; uint32_t counter4; uint32_t counter5; uint32_t counter6; uint32_t counter7; uint32_t counter8; uint16_t offset1; uint16_t offset2; uint32_t offset3; uint16_t offset4; uint16_t *p_table1; uint16_t *p_table2; uint16_t *p_table3; uint16_t tmp1; uint16_t tmp2; uint16_t tmp3; uint32_t tmp4; uint16_t tmp5; uint32_t tmp6; if (lsb_mode) { switch (lsb_mode) { case 1u: counter2 = 0; do { tmp1 = counter2; if (counter2 > 3) { if (counter2 & 1) offset1 = 3; else offset1 = 2; tmp1 = 2 * counter2 - offset1; } slcPageToMlcPageTbl[counter2++] = tmp1; } while (counter2 != 256); break; case 2u: counter3 = 0; do { tmp2 = counter3; if (counter3 > 1) tmp2 = 2 * counter3 - 1; slcPageToMlcPageTbl[counter3++] = tmp2; } while (counter3 != 256); break; case 3u: counter4 = 0; do { tmp3 = counter4; if (counter4 > 5) { if (counter4 & 1) offset2 = 5; else offset2 = 4; tmp3 = 2 * counter4 - offset2; } slcPageToMlcPageTbl[counter4++] = tmp3; } while (counter4 != 256); break; default: counter5 = 0; switch (lsb_mode) { case 4u: slcPageToMlcPageTbl[0] = 0; slcPageToMlcPageTbl[1] = 1; slcPageToMlcPageTbl[2] = 2; slcPageToMlcPageTbl[3] = 3; slcPageToMlcPageTbl[5] = 5; slcPageToMlcPageTbl[6] = 7; counter6 = 8; slcPageToMlcPageTbl[4] = 4; slcPageToMlcPageTbl[7] = 8; p_table1 = &slcPageToMlcPageTbl[7]; do { if (counter6 & 1) offset3 = 7; else offset3 = 6; tmp4 = 2 * counter6 - offset3; counter6 = (uint16_t)(counter6 + 1); p_table1[1] = tmp4; ++p_table1; } while (counter6 != 256); break; case 5u: do { slcPageToMlcPageTbl[counter5] = counter5; ++counter5; } while (counter5 != 16); p_table2 = &slcPageToMlcPageTbl[15]; do { p_table2[1] = counter5; ++p_table2; counter5 = (uint16_t)(counter5 + 2); } while (counter5 != 496); break; case 6u: counter7 = 0; do { tmp5 = counter7; if (counter7 > 5) { if (counter7 & 1) offset4 = 12; else offset4 = 10; tmp5 = counter5 - offset4; } slcPageToMlcPageTbl[counter7++] = tmp5; counter5 = (uint16_t)(counter5 + 3); } while (counter7 != 256); break; case 9u: slcPageToMlcPageTbl[0] = 0; slcPageToMlcPageTbl[1] = 1; slcPageToMlcPageTbl[2] = 2; p_table3 = &slcPageToMlcPageTbl[2]; counter8 = 3; do { p_table3[1] = counter8; ++p_table3; counter8 = (uint16_t)(counter8 + 2); } while (counter8 != 509); break; } break; } } else { do { slcPageToMlcPageTbl[lsb_mode] = lsb_mode; ++lsb_mode; } while (lsb_mode != 256); } ftl_memset(mlcPageToSlcPageTbl, 0xFFu, 1024u); counter1 = 0; while (size > (uint16_t)counter1) { tmp6 = slcPageToMlcPageTbl[counter1++]; mlcPageToSlcPageTbl[tmp6] = tmp6; } } int FlashEraseBlock(uint32_t cs, uint32_t page_addr, uint32_t slc_mode) { uint8_t status; NandcWaitFlashReady(cs); NandcFlashCs(cs); FlashEraseCmd(cs, page_addr, slc_mode); NandcWaitFlashReady(cs); status = FlashReadStatus(cs); NandcFlashDeCs(cs); return status & 1; } int FlashProgPageRaw(uint32_t cs, uint32_t page_addr, uint32_t *p_data, uint16_t *p_spare) { uint8_t sec_per_page; uint8_t status; sec_per_page = gNandParaInfo.sec_per_page; if (!cs && gBlockPageAlignSize * gNandIDBResBlkNum > page_addr) { sec_per_page = 4; } NandcWaitFlashReady(cs); NandcFlashCs(cs); FlashProgFirstCmd(cs, page_addr); NandcXferData(cs, 1u, sec_per_page, p_data, p_spare); FlashProgSecondCmd(cs); NandcWaitFlashReady(cs); status = FlashReadStatus(cs); NandcFlashDeCs(cs); return status & 1; } uint32_t FlashReadRawPage(uint32_t cs, uint32_t page_addr, uint32_t *p_data, uint16_t *p_spare) { uint32_t sec_per_page; uint32_t status; sec_per_page = gNandParaInfo.sec_per_page; if (!cs && gBlockPageAlignSize * gNandIDBResBlkNum > page_addr) { sec_per_page = 4; } NandcWaitFlashReady(cs); NandcFlashCs(cs); FlashReadCmd(cs, page_addr); NandcWaitFlashReady(cs); status = NandcXferData(cs, 0, sec_per_page, p_data, p_spare); NandcFlashDeCs(cs); return status; } void FlashBlockAlignInit(uint32_t page_per_blk) { uint32_t align_size; if (page_per_blk > 256) { align_size = 512; label_3: gBlockPageAlignSize = align_size; return; } if (page_per_blk > 128) { align_size = 256; goto label_3; } gBlockPageAlignSize = page_per_blk; } uint32_t FlashLoadPhyInfo(void) { struct tagFlashSaveInfo *info; uint32_t align_size; uint32_t bch_counter; uint32_t counter; uint32_t page_addr; uint32_t status; uint8_t bch[4]; page_addr = 0; counter = 4; bch[0] = 60; bch[1] = 40; bch[2] = 24; bch[3] = 16; status = NAND_STS_ERROR; align_size = gBlockPageAlignSize; gNandFlashInfoBlockAddr = 0; gpFlashSaveInfo = (struct tagFlashSaveInfo *)gFlashPageBuffer0; flash_enter_slc_mode(0); while (1) { bch_counter = 0; while (1) { FlashBchSel(bch[bch_counter]); if (FlashReadRawPage( 0, page_addr, gFlashPageBuffer0, 0) != NAND_STS_ERROR || FlashReadRawPage( 0, page_addr + 1, gFlashPageBuffer0, 0) != NAND_STS_ERROR) { break; } if (++bch_counter == 4) goto label_6; } info = gpFlashSaveInfo; if (gpFlashSaveInfo->Id == ID_NAND) { if (!status) { gNandFlashIdbBlockAddr = page_addr / gBlockPageAlignSize + 1; break; } if ( info->JSHash == js_hash( (uint8_t *)&gpFlashSaveInfo->gNandMaxDie, 2036u)) { ftl_memcpy( &gNandParaInfo, info->gNandParaInfo, 32u); ftl_memcpy( &gNandOptPara, gpFlashSaveInfo->gNandOptPara, 32u); ftl_memcpy( &gReadRetryInfo, gpFlashSaveInfo->gReadRetryInfo, 852u); FlashBlockAlignInit(gNandParaInfo.page_per_blk); gFlashToggleModeEn = gpFlashSaveInfo->gFlashToggleModeEn; gNandFlashInfoBlockAddr = page_addr; if (page_addr / gBlockPageAlignSize + 1 > 1) gNandFlashIdbBlockAddr = page_addr / gBlockPageAlignSize + 1; else gNandFlashIdbBlockAddr = 2; status = NAND_STS_OK; gNandIDBResBlkNumSaveInFlash = gpFlashSaveInfo->gNandIDBResBlkNum; } else { status = NAND_STS_ERROR; } } label_6: --counter; page_addr += align_size; if (counter) continue; break; } flash_exit_slc_mode(0); return status; } void FlashSavePhyInfo(void) { uint32_t counter1; uint32_t counter2; uint32_t done; uint32_t hash; uint32_t status; gpFlashSaveInfo = (struct tagFlashSaveInfo *)gFlashPageBuffer0; FlashBchSel(gNandFlashIDBEccBits); ftl_memset(gFlashPageBuffer0, 0, 2048u); gpFlashSaveInfo->Id = ID_NAND; gpFlashSaveInfo->gNandMaxDie = gNandMaxDie; gpFlashSaveInfo->gNandIDBResBlkNum = gNandIDBResBlkNum; gpFlashSaveInfo->gFlashToggleModeEn = gFlashToggleModeEn; ftl_memcpy(gpFlashSaveInfo->IDByte, IDByte, 32u); ftl_memcpy(gpFlashSaveInfo->DieCsIndex, DieCsIndex, 8u); ftl_memcpy(gpFlashSaveInfo->DieAddrs, DieAddrs, 32u); ftl_memcpy( gpFlashSaveInfo->gNandParaInfo, &gNandParaInfo, 32u); ftl_memcpy(gpFlashSaveInfo->gNandOptPara, &gNandOptPara, 32u); ftl_memcpy( gpFlashSaveInfo->gReadRetryInfo, &gReadRetryInfo, 852u); gpFlashSaveInfo->JSHash = js_hash( (uint8_t *) &gpFlashSaveInfo->gNandMaxDie, 2036u); gpFlashSaveInfo->Size = 1592; done = 0; counter1 = 0; gpFlashSaveInfo = (struct tagFlashSaveInfo *)gFlashPageBuffer1; flash_enter_slc_mode(0); do { FlashEraseBlock(0, gBlockPageAlignSize * counter1, 0); FlashProgPageRaw( 0, gBlockPageAlignSize * counter1, gFlashPageBuffer0, 0); FlashProgPageRaw( 0, gBlockPageAlignSize * counter1 + 1, gFlashPageBuffer0, 0); status = FlashReadRawPage( 0, gBlockPageAlignSize * counter1, gFlashPageBuffer1, 0); counter2 = counter1 + 1; if (status != NAND_STS_ERROR && gpFlashSaveInfo->Id == ID_NAND) { hash = js_hash( (uint8_t *) &gpFlashSaveInfo->gNandMaxDie, 2036u); counter2 = counter1 + 1; if (gpFlashSaveInfo->JSHash == hash) { gNandFlashIdbBlockAddr = counter1 + 1; gNandFlashInfoBlockAddr = counter1 * gBlockPageAlignSize; if (done == 1) break; done = 1; } } counter1 = counter2; } while (counter2 != 4); flash_exit_slc_mode(0); } int FlashReadIdbDataRaw(uint8_t *p_buf) { uint32_t bch_counter; uint32_t ecc_bits; uint32_t ecc_bits2; uint32_t page_counter; int status; uint8_t bch[4]; bch[0] = 60; bch[1] = 40; bch[2] = 24; bch[3] = 16; ecc_bits2 = gNandFlashEccBits; if (idb_flash_slc_mode) flash_enter_slc_mode(0); status = NAND_STS_ERROR; page_counter = 2; ftl_memset(p_buf, 0, 2048u); while (1) { if (page_counter < gNandIDBResBlkNum) { bch_counter = 0; while (1) { ecc_bits = bch[bch_counter]; FlashBchSel(ecc_bits); if ( FlashReadRawPage( 0, gBlockPageAlignSize * page_counter, gFlashPageBuffer0, 0) != NAND_STS_ERROR) break; if (++bch_counter == 4) goto label_11; } if (*gFlashPageBuffer0 == ID_IDRW) { FTL_INFO("ECC:%d\n", ecc_bits); ftl_memcpy( p_buf, gFlashPageBuffer0, 2048u); gNandIDBResBlkNum = gFlashPageBuffer0[128]; if (page_counter >= gNandFlashIdbBlockAddr) { status = NAND_STS_OK; break; } gNandFlashIdbBlockAddr = page_counter; status = NAND_STS_OK; FlashSavePhyInfo(); } label_11: ++page_counter; continue; } break; } FlashBchSel(ecc_bits2); if (idb_flash_slc_mode) flash_exit_slc_mode(0); return status; } void FlashPageProgMsbFFData(uint32_t cs, uint32_t page_addr, uint32_t count) { uint32_t retry_mode; uint32_t shift; uint32_t tmp; if (!gFlashSlcMode || !idb_flash_slc_mode) { retry_mode = gpNandParaInfo->read_retry_mode; shift = (uint8_t)(retry_mode - 5); if (shift > 30) { if (retry_mode != 68) return; } else if (!((0x4000400Fu >> shift) & 1)) { return; } while (gpNandParaInfo->page_per_blk > count && mlcPageToSlcPageTbl[count] == 0xFFFF) { if (retry_mode == 8) tmp = 0; else tmp = 0xFFu; ftl_memset(gFlashPageBuffer1, tmp, 32768u); FlashProgPageRaw( cs, count + page_addr, gFlashPageBuffer1, (uint16_t *)gFlashPageBuffer1); count = (uint16_t)(count + 1); } } } void IdBlockReadData(uint32_t index, uint32_t count, uint32_t *buf) { uint32_t counter; uint16_t counter_add; uint32_t ecc_bits; uint32_t min_sector; uint32_t page; uint32_t sector; uint32_t sector2; uint16_t size; uint32_t start_offset; size = gpNandParaInfo->sec_per_page * (uint16_t)gBlockPageAlignSize; FTL_INFO( "IdBlockReadData %x %x\n", index, count); counter = 0; sector2 = index % size; min_sector = index - index % size; start_offset = (gpNandParaInfo->sec_per_page * (index % size) >> 2) & 3; while (counter < count) { counter_add = 4 - start_offset; page = slcPageToMlcPageTbl[((counter + sector2) >> 2) & 0xFFFF]; if (gFlashSlcMode && g_nandc_version_data == NAND_VERSION_V800) page = ((counter + sector2) >> 2) & 0xFFFF; ecc_bits = gNandFlashEccBits; sector = start_offset + min_sector + gpNandParaInfo->sec_per_page * page; FlashBchSel(gNandFlashIDBEccBits); flash_boot_enter_slc_mode(0); FlashReadPage( 0, sector / gpNandParaInfo->sec_per_page, gFlashPageBuffer1, 0); flash_boot_exit_slc_mode(0); FlashBchSel(ecc_bits); memcpy(&buf[128 * counter], gFlashPageBuffer1, 2048u); start_offset = 0; counter = (uint16_t)(counter_add + counter); } FTL_INFO( "IdBlockReadData %x %x ret= %x\n", index, count, 0); } void IDBlockWriteData(uint32_t index, uint32_t count, uint32_t *buf) { uint32_t counter; uint32_t ecc_bits; uint32_t min_sector; uint32_t page; uint32_t page1; uint32_t page2; uint32_t sector2; uint16_t size; uint32_t spare[32]; size = gpNandParaInfo->sec_per_page * (uint16_t)gBlockPageAlignSize; FTL_INFO( "IDBlockWriteData %x %x\n", index, count); flash_boot_enter_slc_mode(0); FlashEraseBlock(0, index / gNandPhyInfo.sec_per_page, 0); flash_boot_exit_slc_mode(0); counter = 0; sector2 = index % size; min_sector = index - index % size; while (counter < count) { page = ((counter + sector2) >> 2) & 0xFFFF; if (page) { page1 = slcPageToMlcPageTbl[page + 1]; if (gFlashSlcMode && g_nandc_version_data == NAND_VERSION_V800) page1 = (uint16_t) (((counter + sector2) >> 2) + 1); spare[0] = 4 * (page1 - 1); spare[1] = 0; } page2 = slcPageToMlcPageTbl[page]; if (gFlashSlcMode && g_nandc_version_data == NAND_VERSION_V800) page2 = ((counter + sector2) >> 2) & 0xFFFF; ecc_bits = gNandFlashEccBits; FlashBchSel(gNandFlashIDBEccBits); flash_boot_enter_slc_mode(0); FlashProgPageRaw( 0, (min_sector + gpNandParaInfo->sec_per_page * page2) / gpNandParaInfo->sec_per_page, &buf[128 * counter], (uint16_t *)spare); flash_boot_exit_slc_mode(0); FlashBchSel(ecc_bits); FlashPageProgMsbFFData( 0, min_sector / gpNandParaInfo->sec_per_page, (uint16_t)(page2 + 1)); counter = (uint16_t)(counter + 4); } FTL_INFO( "IDBlockWriteData %x %x ret= %x\n", index, count, 0); } int write_idblock(uint32_t size, uint32_t *buf, uint32_t *p_data) { uint32_t count; uint32_t counter; uint32_t counter2; uint32_t index; uint32_t max_size; uint32_t offset; uint32_t offset2; uint32_t page_addr; uint32_t *p_read; uint32_t *p_write; uint32_t r; uint32_t w; uint16_t size2; uint32_t status; uint32_t write_counter; size2 = gpNandParaInfo->sec_per_page * (uint16_t)gBlockPageAlignSize; p_read = (uint32_t *)kmalloc_order_trace(256000, 208, 6); if (p_read) { index = (size + 511) >> 9; if (index <= 255) memcpy(&buf[128 * index], buf, 256 - index); count = index + 128; rknand_print_hex("idblk:", p_data, 4, 5); if (count >= 256) count = 256; counter = 0; FTL_INFO( "idb reverse %x %x\n", buf[128], gNandIDBResBlkNum); write_counter = 0; p_write = buf; if (buf[128] > gNandIDBResBlkNum) buf[128] = gNandIDBResBlkNum; FTL_INFO( "write_idblock total_sec %x %x\n", count, size); max_size = count << 7; do { page_addr = *p_data; ++p_data; if (page_addr < gNandPhyInfo.reserved_blks && page_addr >= gNandFlashIdbBlockAddr) { ftl_memset(p_read, 0, 512); IDBlockWriteData( *(p_data - 1) * size2, count, p_write); IdBlockReadData( *(p_data - 1) * size2, count, p_read); counter2 = 0; offset = 0; while (1) { r = p_read[counter2]; w = p_write[counter2]; ++counter2; if (r != w) break; ++offset; if (offset == max_size) goto label_1; } offset2 = offset & 0xFFFFFF00; FTL_INFO( "write and check error:" "%d idb=%x,offset=%x,r=%x,w=%x\n", write_counter, *(p_data - 1), offset, r, w); rknand_print_hex( "write", &p_write[offset2], 4, 256); rknand_print_hex( "read", &p_read[offset2], 4, 256); ftl_memset(p_read, 0, 512); IDBlockWriteData( *(p_data - 1) * size2, 4u, p_read); FTL_INFO("write_idblock error\n"); if (offset < max_size) goto label_0; label_1: ++counter; } label_0: ++write_counter; } while (write_counter != 5); ftl_free(p_read); if (counter) status = 0; else status = -1; } else { status = -1; } return status; } void write_loader_lba(uint32_t index, uint32_t count, uint32_t *buf) { uint32_t counter1; uint32_t counter2; uint32_t lba1; uint32_t lba2; uint32_t size; uint32_t tmp; uint32_t block[130]; if (index == 64 && *buf == ID_IDRW) { idb_write_enable = 1; idb_buf = ftl_malloc(256000); ftl_memset( idb_buf, 0, 256000); idb_last_lba = index; } FTL_INFO("wl_lba %p %x %x %x\n", idb_buf, *buf, index, count); if (idb_write_enable) { if (index - 64 >= 500) { if (index >= 564) { lba1 = idb_last_lba - 64; if (idb_last_lba - 64 >= 500) lba1 = 500; if (gpNandParaInfo->sec_per_page == 4) { counter1 = 0; do { tmp = 2 * counter1; if (lba1 <= 256) tmp = counter1; block[counter1++] = tmp; } while (counter1 != 5); } else { block[0] = 2; block[1] = 3; block[2] = 4; block[3] = 5; block[4] = 6; } counter2 = 63872; do { if (idb_buf[counter2]) { size = 4 * (counter2 + 128); goto label_28; } --counter2; } while (counter2 != 4096); size = lba1 << 9; label_28: write_idblock( size, idb_buf, block); idb_write_enable = 0; ftl_free(idb_buf); idb_buf = 0; goto label_14; } } else { lba2 = 564 - index; if (564 - index >= count) lba2 = count; ftl_memcpy( (void *) (idb_buf + ((index - 64) << 9)), buf, lba2 << 9); } if (idb_last_lba != index) { idb_write_enable = 0; if (idb_buf) ftl_free(idb_buf); idb_buf = 0; } label_14: idb_last_lba = index + count; } } #define GetIdblockDataNoRc4(p, s) P_RC4(p, s) int FtlGetIdBlockSysData(void *p_buf, int index) { if (index > 3) return -1; ftl_memcpy(p_buf, &gNandIDataBuf[index * 512], 512); if (index == 1) return 0; GetIdblockDataNoRc4(p_buf, 512); return 0; } int FtlGetChipSectorInfo(void *p_buf) { return FtlGetIdBlockSysData(p_buf, 2); } int FtlGetSNSectorInfo(void *p_buf) { return FtlGetIdBlockSysData(p_buf, 3); } /* init */ gFlashPageBuffer0 = (uint32_t *) ftl_malloc(32768u); gFlashPageBuffer1 = (uint32_t *) ftl_malloc(32768u); gBlockPageAlignSize = 128; /* more init */ if (FlashLoadPhyInfo()) { /* sort out your mess here */ FlashSavePhyInfo(); } /* more init */ gFlashSlcMode = gpNandParaInfo->slc_mode; gNandRandomizer = (gpNandParaInfo->operation_opt >> 7) & 1; gMultiPageReadEn = (gpNandParaInfo->operation_opt >> 3) & 1; gMultiPageProgEn = (gpNandParaInfo->operation_opt >> 4) & 1; gFlashInterfaceMode = (gpNandParaInfo->operation_opt >> 8) & 7; BuildFlashLsbPageTable( gpNandParaInfo->lsb_mode, (uint32_t)gpNandParaInfo->page_per_blk / (uint32_t)gpNandParaInfo->cell); FlashReadIdbDataRaw(gNandIDataBuf); gNandIDBResBlkNum = 16; gNandPhyInfo.nand_type = gpNandParaInfo->cell; gNandPhyInfo.vendor = gpNandParaInfo->vendor; gNandPhyInfo.chip_id = *(uint32_t *)IDByte; gNandPhyInfo.die_num = gNandMaxDie; gNandPhyInfo.page_per_blk = gpNandParaInfo->page_per_blk; gNandPhyInfo.blk_per_plane = gpNandParaInfo->blk_per_plane; gNandPhyInfo.planes_per_die = gpNandParaInfo->plane_per_die; gNandPhyInfo.page_per_slc_blk = (uint32_t)gpNandParaInfo->page_per_blk / (uint32_t)gpNandParaInfo->cell; gNandPhyInfo.sector_size = 512; gNandPhyInfo.sec_per_page = gpNandParaInfo->sec_per_page; gNandPhyInfo.reserved_blks = 16; gNandPhyInfo.block_size = gpNandParaInfo->page_per_blk * gpNandParaInfo->sec_per_page; 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=-13.0 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=unavailable 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 30A7CC33CA2 for ; Sun, 12 Jan 2020 17:27:24 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 E13D92084D for ; Sun, 12 Jan 2020 17:27:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="IOCbaI2x"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sJ/bBz+I" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E13D92084D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date: Message-ID:From:References:To:Subject:Reply-To:Content-ID:Content-Description :Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=aaES9iiRzgC8XMd+f8zWQdE520/h7DjQzloFniHJANc=; b=IOCbaI2xW3Od68 QbICywarrzjkXOlZKpPofJRVDAqBd8sPPs5JAVjRHLGrxYTfo9COmqb0IVrXNK+zC/QeTOnYPjpns WDmUB8JDnua2oo3uQg6WSLguxLvw5+Uz5XOQ+/yobCj6Mbuz7Ep5TqFvWK4gRZOOmNqEQXZrAoeFu u3BsNMfz3DFQ/x0hxR1kyJYtrZEU+F+2cQhhwpm1erm5nbUumIw7/xxQDxsuvTPlKYLJu5WBodrXo rRV3T8rxDWqzYJUYusjYf0TwATXLHGZUDrSDXb26DjE+RTClq5HHnK+1GyS/Z95l69UfWBOfwxcnj fZmhOuVkM6v8QW9qdC4w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iqh0x-0001eP-8b; Sun, 12 Jan 2020 17:27:03 +0000 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iqh0O-00012Z-1Q; Sun, 12 Jan 2020 17:26:34 +0000 Received: by mail-wr1-x443.google.com with SMTP id t2so6357065wrr.1; Sun, 12 Jan 2020 09:26:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=xVRZT7YHVPE3GbyttbmSvMk99hkpTLXEzonadfBniK0=; b=sJ/bBz+I6AX+VbqaGHYqU8oVcVl/3fSB0h+kVMFnrusHsAraBxY0dWeSBp/G6dF6VS KC3iiITMz4jGvTyFgMdWFv/IKS0nvXQGjasscb3dfzY5UDXLcJ8F43s9WRibK76KLk2I c4tCo4dpuJ0itfQSWTdmYgfgkTHkMqoI1jEQJmcC6AYjiCK5vcexTiLyYWe+2oaf1D7X n1xemEpadN4Z3XRFXs7Ysx4/EzdtgFKlHMLMD3Jwv7S28I230Ek2qNGbLPva3NdGiWEt zyqdsLAx3UCcNjPnhi4d1sx3JnxiT305p4d9Q7DL03PDA9H5c2Tr5gIytdsAZv2wKxVJ WQqw== 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=xVRZT7YHVPE3GbyttbmSvMk99hkpTLXEzonadfBniK0=; b=eC/NEVAWvs4lV9HAT3WospQ6KFzAVv+qE1fKqpbKTdvm6BDwrj3ub1NQvwdkK83FaZ 5YkqoTo6EIBtgwFY0OfkiFToG4G3GBdOEiQPu9Cxa7WKp4PIWQ9sizLju4dUn8XF0JSp nNHypsiZ4wMsoPVUyMSOe8uiAitcuvgO8F0tWLpIx5g2Qln1/PcdocomXnjp6ZfDMIq9 MpPRtNCYZVoEOHc5C5PbH+SYIDvBK3H4RGDBB0OG5SvlwKc+fypHigxZQVs4EbEeXTpb dFBvo8tEabDJzj+Z9Pbi9Z8FFxc+qeojoA6bDa/6B6Aratq4rxT6Qgr+o0i+3OHiX0HM qArw== X-Gm-Message-State: APjAAAWamXYH6P6qB17VZd0N1nZ4//804SI9Zcil3HfHsP72dabxRr+k A6+MIsbjQbWMOVp/ReII1d0= X-Google-Smtp-Source: APXvYqyNJb2sZ+BEdl8Qe/N/WrvcZaNsBPjLBsFGSsIaeCCg3xu/NTbmYXVL2WXphD8eiIaYdsHO/Q== X-Received: by 2002:adf:fbc9:: with SMTP id d9mr14694899wrs.20.1578849984608; Sun, 12 Jan 2020 09:26:24 -0800 (PST) Received: from [192.168.2.1] (ip51ccf9cd.speed.planet.nl. [81.204.249.205]) by smtp.gmail.com with ESMTPSA id 4sm10505338wmg.22.2020.01.12.09.26.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 12 Jan 2020 09:26:23 -0800 (PST) Subject: Re: [RFC PATCH v1 02/10] mtd: nand: raw: add rockchip nand controller driver To: Miquel Raynal References: <20200108205338.11369-1-jbx6244@gmail.com> <20200108205338.11369-3-jbx6244@gmail.com> <20200110120534.1b4026b0@xps13> From: Johan Jonker Message-ID: <7a477af0-1448-4f26-4004-9331978e824c@gmail.com> Date: Sun, 12 Jan 2020 18:26:20 +0100 User-Agent: Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Thunderbird/68.3.0 MIME-Version: 1.0 In-Reply-To: <20200110120534.1b4026b0@xps13> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200112_092628_298994_4C76E6BF X-CRM114-Status: GOOD ( 32.18 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, vigneshr@ti.com, richard@nod.at, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, robh+dt@kernel.org, linux-mtd@lists.infradead.org, linux-arm-kernel@lists.infradead.org, heiko@sntech.de Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGkgTWlxdWVsLAoKVGhhbmsgeW91IGZvciB5b3VyIGRldGFpbGVkIGFuZCB1c2VmdWwgcmV2aWV3 LgoKV2l0aG91dCBtYW51ZmFjdHVyZXIgc3VwcG9ydCBJIG11c3Qgc2NyYXBlIG15IGluZm9ybWF0 aW9uCmZyb20gYWxsIG92ZXIgdGhlIGludGVybmV0LCB0b2dldGhlciB3aXRoIHNsb3cgaW50ZXJw cmV0YXRpb24gb2YKUm9ja2NoaXAgZHJpdmVycy4KU28gcGxlYXNlIGhhdmUgc29tZSBwYXRpZW5j ZSB3aXRoIG15IHVwZGF0ZXMgYW5kIG5ldyB2ZXJzaW9ucy4KCkJlbG93IGFyZSBzb21lIGNvbW1l bnRzIGFuZCBxdWVzdGlvbnMgaW4gcmFuZG9tIG9yZGVyLgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8KClRvIHByZXZlbnQgZ3Vlc3NpbmcgZ2FtZXMgY291bGQgeW91IGNvbmZpcm0gdGhl IGZvbGxvd2luZyBuYW1lczoKCmRyaXZlciBmaWxlIG5hbWU6ICAgcm9ja2NoaXAtbmFuZC1jb250 cm9sbGVyLmMKZG9jdW1lbnQgZmlsZSBuYW1lOiByb2NrY2hpcC1uYW5kLWNvbnRyb2xsZXIueWFt bAoKY29tcGF0aWJsZTogInJvY2tjaGlwLG5hbmRjLXY2Igpjb21wYXRpYmxlOiAicm9ja2NoaXAs bmFuZGMtdjkiCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKTXkgaW5jb21wbGV0ZSBz b3J0IGxpc3QgZm9yIGNvbnRyb2xsZXIgdmVyc2lvbnMuCgpDYW4gc29tZW9uZSB3aXRoIGFjY2Vz cyB0byB0aGUgUlYxMTA4IFRSTSAobWFudWFsKSByZXBvcnQgdGhlIGRldGFpbHMKZm9yIHRoZSBO YW5kYyBWZXJzaW9uIFJlZ2lzdGVyIGFuZCB3aGV0aGVyIGl0IGlzIGNvbXBhdGlibGUuIFRoYW5r cy4KCkFkZGVkIHZlcnNpb24gNyBmb3IgUkszMjI4QS9SSzMyMjhCLiBDYW4gc29tZW9uZSB3aXRo IGluc2lkZXIgaW5mbyBjb25maXJtCmlmIHRoaXMgd29ya3Mgb3Igbm90LgoKUkszMDY2L1BYMgpO QU5EQ19OQU5EQ19WRVIgMHgwMTYwIFcgMHg1NjM2MzAzMCBOYW5kYyBWZXJzaW9uIFJlZ2lzdGVy CgpSSzMxODgKTkFORENfTkFORENfVkVSIDB4MDE2MCBXIDB4NTYzNjMwMzAgTmFuZGMgVmVyc2lv biBSZWdpc3RlcgoKUFgzCk5BTkRDX05BTkRDX1ZFUiAweDAxNjAgVyAweDU2MzYzMDMwIE5hbmRj IFZlcnNpb24gUmVnaXN0ZXIKClJLMzEyWApOQU5EQ19OQU5EQ19WRVIgMHgwMTYwIFcgMHg1NjM2 MzIzMiBOYW5kYyBWZXJzaW9uIFJlZ2lzdGVyCgpSSzMyODgKTkFORENfTkFORENfVkVSIDB4MDE2 MCBXIDB4NTYzNjMyMzIgTmFuZGMgVmVyc2lvbiBSZWdpc3RlcgoKUkszMzY4L1BYNQpOQU5EQ19O QU5EQ19WRVIgMHgwMTYwIFcgMHg1NjM2MzIzMiBOYW5kYyBWZXJzaW9uIFJlZ2lzdGVyCgpSSzMy MjhBL1JLMzIyOEIKTkFORENfTkFORENfVkVSIDB4MDE2MCBXIDB4MDAwMDA3MDEgTmFuZGMgVmVy c2lvbiBSZWdpc3RlcgoKUkszMzA4Ck5BTkRDX05BTkRDX1ZFUiAweDAxNjAgVyAweDAwMDAwODAx IE5hbmRjIFZlcnNpb24gUmVnaXN0ZXIKClJLMzMyNi9QWDMwCk5BTkRDX05BTkRDX1ZFUiAweDAw ODAgVyAweDU2MzkzMDMwIE5hbmRjIFZlcnNpb24gUmVnaXN0ZXIKClJLMzMyOApOTyBOQU5EQwoK UkszMzk5Ck5PIE5BTkRDCgpSVjExMDgKdW5rbm93bgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8KCk15IGRlYnVnIGtlcm5lbC5sb2cgd2l0aCAxIHBhcnRpdGlvbiBpbiBkdHMuCgpKYW4g IDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDUxNTg3XSByb2NrY2hpcC1uYW5kYwox MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IGdldCBjbGtfbmFuZGMgZmFpbGVkCkphbiAgMSAwMDow MjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTI0MDJdIG5hbmQ6IGRldmljZSBmb3VuZCwKTWFu dWZhY3R1cmVyIElEOiAweGFkLCBDaGlwIElEOiAweGRlCkphbiAgMSAwMDowMjoyNyBtazgwOCBr ZXJuZWw6IFsgIDE0Ny4wNTI5NDVdIG5hbmQ6IEh5bml4IEgyN1VDRzhUMkFUUi1CQwo2NEcgMy4z ViA4LWJpdApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDUzMzg4XSBuYW5k OiA4MTkyIE1pQiwgTUxDLCBlcmFzZQpzaXplOiAyMDQ4IEtpQiwgcGFnZSBzaXplOiA4MTkyLCBP T0Igc2l6ZTogNjQwCkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTQwNTBd IHJvY2tjaGlwLW5hbmRjCjEwNTAwMDAwLm5hbmQtY29udHJvbGxlcjogbmFuZC0+bnVtY2hpcHMg PSAxCkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTQ3NDBdIHJvY2tjaGlw LW5hbmRjCjEwNTAwMDAwLm5hbmQtY29udHJvbGxlcjogbmFuZC0+Y2hpcHNpemUgPSA4NTg5OTM0 NTkyCkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTUzODBdIHJvY2tjaGlw LW5hbmRjCjEwNTAwMDAwLm5hbmQtY29udHJvbGxlcjogbmFuZC0+cGFnZW1hc2sgPSAgICBmZmZm ZgpKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDU1OTk0XSByb2NrY2hpcC1u YW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmJhZGJsb2NrcG9zID0gMApKYW4g IDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDU2NTkxXSByb2NrY2hpcC1uYW5kYwox MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmNoaXBfc2hpZnQgPSAzMwpKYW4gIDEgMDA6 MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDU3MTc0XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAw MC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPnBhZ2Vfc2hpZnQgPSAxMwpKYW4gIDEgMDA6MDI6Mjcg bWs4MDgga2VybmVsOiBbICAxNDcuMDU3NzUxXSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXI6IG5hbmQtPnBoeXNfZXJhc2Vfc2hpZnQgPSAyMQpKYW4gIDEgMDA6MDI6Mjcg bWs4MDgga2VybmVsOiBbICAxNDcuMDU4MzY2XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXI6IG5hbmQtPmVjYy5tb2RlID0gMwpKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2Vy bmVsOiBbICAxNDcuMDU4OTIwXSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xs ZXI6IG5hbmQtPmVjYy5zdGVwcyA9IDgKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDogWyAg MTQ3LjA1OTQ4MV0gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9sbGVyOiBuYW5k LT5lY2MuYnl0ZXMgPSA3MApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYw MDQ5XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmVjYy50 b3RhbCA9IDAKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDogWyAgMTQ3LjA2MDYwN10gcm9j a2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9sbGVyOiBuYW5kLT5lY2MucHJlcGFkID0g NApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYxMTc1XSByb2NrY2hpcC1u YW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmVjYy5zaXplID0gMTAyNApKYW4g IDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYxNzQ4XSByb2NrY2hpcC1uYW5kYwox MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmVjYy5zdHJlbmd0aCA9IDQwCkphbiAgMSAw MDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNjIzNDFdIHJvY2tjaGlwLW5hbmRjCjEwNTAw MDAwLm5hbmQtY29udHJvbGxlcjogbXRkLT5vb2JsYXlvdXQgPSA5MWNlOWNlMgpKYW4gIDEgMDA6 MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYyOTQzXSByb2NrY2hpcC1uYW5kYwoxMDUwMDAw MC5uYW5kLWNvbnRyb2xsZXI6IG10ZC0+ZmxhZ3MgPSAwMDAwMDAwMApKYW4gIDEgMDA6MDI6Mjcg bWs4MDgga2VybmVsOiBbICAxNDcuMDYzNTE4XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXI6IG10ZC0+c2l6ZSA9IDg1ODk5MzQ1OTIKSmFuICAxIDAwOjAyOjI3IG1rODA4 IGtlcm5lbDogWyAgMTQ3LjA2NDA5OF0gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250 cm9sbGVyOiBtdGQtPmVyYXNlc2l6ZSA9IDIwOTcxNTIKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtl cm5lbDogWyAgMTQ3LjA2NDgxNV0gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9s bGVyOiBtdGQtPndyaXRlc2l6ZSA9IDgxOTIKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDog WyAgMTQ3LjA2NTQxM10gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9sbGVyOiBt dGQtPm9vYnNpemUgPSA2NDAKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDogWyAgMTQ3LjA2 ODk4NV0gMSBmaXhlZC1wYXJ0aXRpb25zCnBhcnRpdGlvbnMgZm91bmQgb24gTVREIGRldmljZSAx MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXIuMApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBb ICAxNDcuMDY5MTkwXSBDcmVhdGluZyAxIE1URCBwYXJ0aXRpb25zCm9uICIxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXIuMCI6CkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNzIz NzVdCjB4MDAwMDAwMDAwMDAwLTB4MDAwMDAwNDAwMDAwIDogInBhcmFtZXRlciIKCgpKYW4gIDEg MDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDc1NjQ5XSByb2NrY2hpcC1uYW5kYwoxMDUw MDAwMC5uYW5kLWNvbnRyb2xsZXI6IFI6MHgwMGZmIGNzOjAKSmFuICAxIDAwOjAyOjI3IG1rODA4 IGtlcm5lbDogWyAgMTQ3LjA3OTQyM10gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250 cm9sbGVyOiBSOjB4MDFmZiBjczowCgoKRGVzcGl0ZSBuYW5kLT5vcHRpb25zID0gTkFORF9TS0lQ X0JCVFNDQU4uCgpXaGF0IGlzIHRoZSByZWFzb24gZm9yIHRoZXNlIDIgcmtfbmFuZGNfaHdfc3lu ZHJvbWVfZWNjX3JlYWRfcGFnZSgpIGNvbW1hbmRzCmF0IHBhZ2UgUjoweDAwZmYgYW5kIFI6MHgw MWZmIHJpZ2h0IGFmdGVyIGNyZWF0aW5nIHBhcnRpdGlvbnMuCgpXaGVuIGVuYWJsZWQgQkJUU0NB TiBNVEQgc3RhcnRzIHRvIHN0b3JlIGF0IGFsbCBraW5kIG9mIHBsYWNlcy4gQ2FuIHlvdQpzdGF0 ZQp0aGVyZSBwYWdlIGFkZHJlc3MgbG9naWMsIGllLiBXb3VsZCB0aGF0IGRhbWFnZSB0aGUgZXhj aXN0aW5nIFJvY2tjaGlwCmxheW91dD8KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpO byBiYWQgYmxvY2sgc3VwcG9ydAoKQmFzZWQgb246CmRyaXZlcnM6IG10ZDogbmFuZDogcm9ja2No aXAgbmFuZGMgYWRkIGJhZCBibG9jayBkZXRlY3QgYXBpCmh0dHBzOi8vZ2l0aHViLmNvbS9yb2Nr Y2hpcC1saW51eC91LWJvb3QvY29tbWl0Lwo3YWVjNzA0YTRlOWQ5MzIyZjExMDJiY2Y2MWVlNWMz Y2Y2ZWM3OTRkCgpyb2NrY2hpcDogZHJpdmVyczogbXRkOiBuYW5kOiBtb2RpZnkgdGhlIGJhZCBi bG9jayBkZXRlY3Rpb24gcHJvY2VzcwpodHRwczovL2dpdGh1Yi5jb20vcm9ja2NoaXAtbGludXgv dS1ib290L2NvbW1pdC8KZDZkNzA4ZDFhMzI5YTYzNjkxNDNlOGRkMzRjZjRlMmM4MWQ1ZDkyZgoK QkNIICAgICAgfCAgICAgIG9vYiBzaXplCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoxNjogYnl0 ZXM6IDI4ICsgNCA9IDMyCjI0OiBieXRlczogNDIgKyA0ID0gNDYKNDA6IGJ5dGVzOiA3MCArIDQg PSA3NAo2MDogYnl0ZXM6IDEwNiArIDQgPSAxMTAKClRoZSBkYXRhIGxheW91dCB0aGF0IGlzIHdy aXR0ZW4gYnkgYW4gaW50ZXJuYWwgUm9ja2NoaXAgbmFuZGMgZG1hIGlzOgogICAgMTAyNCBieXRl cyBkYXRhICsgMzIgb2JiICsgMTAyNCBkYXRhICsgMzIgb2JiIC4uLgoKVGhlIE1URCBzeXN0ZW0g aG93ZXZlciB0cmllcyB0byBkZXRlY3QgYmFkIGJsb2NrIGZsYWdzIGxvY2F0ZWQgYXQ6CiAgICAy MDQ4LCA0MDk2LCA4MTkyLi4uCgpUaGUgc3lzdGVtIGNoZWNrcyBmb3IgYmFkIGJsb2NrcyBhbmQg bG9va3MgYXQgdGhlIHdyb25nIGJhZCBibG9jayBtYXJrZXIKbG9jYXRpb24uCllpZmVuZyBaaGFv IHByb3Bvc2VzIHRvIGFkZCBhIGJhZCBibG9jayBkZXRlY3Rpbmcgc3RyYXRlZ3kgYnkgZG9pbmcK YSByZWFkIHdpdGggcmtfbmFuZGNfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZSgpIGZpcnN0LApp ZiBmYWlsdXJlIHRoZW4gYXNzdW1lIGl0J3Mgc3RpbGwgcmF3IHVud3JpdHRlbiBOQU5EIGFuZCB0 ZXN0IGJ5dGVzIGFyZQphdCB0aGUgcG9zaXRpb24gTVREIG5vcm1hbHkgd291bGQgY2hlY2sgZm9y IHJpZ2h0IGZyb20gdGhlIGZhY3RvcnkuCldoZW4gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIG9uIGEg RlRMIGNvbnRyb2xsZWQgTkFORCBpdCBjcmVhdGVzCmFuIGF3ZnVsIGxvdCBvZiBlcnJvcnMgaW4g dGhlIGtlcm5lbCBsb2csIGJlY2F1c2UgaXQgdXNlcyB0aGUgQkIgbWFya2VyCmZvciBkaXJ0eSB0 YWcgdHJpY2tzIGZvciB0aGVyZSBkYXRhIHN0b3JhZ2UuClNvIHdoYXQgaXMgZ29vZCBmb3IgYSBy YXcgZW1wdHkgTkFORCB3aXRob3V0IEZUTApkb2VzIG5vdCB3b3JrIGZvciB0aGUgbWFqb3JpdHkg b2YgUm9ja2NoaXAgZGV2aWNlcyBJIHRoaW5rLgoKUGxlYXNlIGFkdmlzZSBmb3Igb3RoZXIgb3B0 aW9ucy4KCnN0YXRpYyB1aW50OF90IHJrX25hbmRfcmVhZF9ieXRlKHN0cnVjdCBuYW5kX2NoaXAg Km5hbmQpCnsKCXVpbnQ4X3QgcmV0OwoKCXJrX25hbmRfcmVhZF9idWYobmFuZCwgJnJldCwgMSk7 CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBya19uYW5kX2Jsb2NrX2JhZChzdHJ1Y3QgbmFu ZF9jaGlwICpuYW5kLCBsb2ZmX3Qgb2ZzKQp7CglzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRf dG9fbXRkKG5hbmQpOwoJaW50IHBhZ2UsIHJlcyA9IDA7Cgl1MTYgYmFkID0gMHhmZjsKCXU4ICpi dWYgPSBuYW5kX2dldF9kYXRhX2J1ZihuYW5kKTsKCWludCBjaGlwbnIgPSAoaW50KShvZnMgPj4g bmFuZC0+Y2hpcF9zaGlmdCk7CgoJcGFnZSA9IChpbnQpKG9mcyA+PiBuYW5kLT5wYWdlX3NoaWZ0 KSAmIG5hbmQtPnBhZ2VtYXNrOwoJcmtfbmFuZF9zZWxlY3RfY2hpcChuYW5kLCBjaGlwbnIpOwoJ aWYgKHJrX25hbmRfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZShuYW5kLCBidWYsIGZhbHNlLCBw YWdlKSA9PSAtMSkgewoJCS8qIGZpcnN0IHBhZ2Ugb2YgYSBibG9jayovCgkJbmFuZF9yZWFkX3Bh Z2Vfb3AobmFuZCwgcGFnZSwgbmFuZC0+YmFkYmxvY2twb3MsIE5VTEwsIDApOwoJCWJhZCA9IHJr X25hbmRfcmVhZF9ieXRlKG5hbmQpOwoJCWlmIChiYWQgIT0gMHhGRikKCQkJcmVzID0gMTsKCQkv KiBzZWNvbmQgcGFnZSBvZiBhIGJsb2NrKi8KCQluYW5kX3JlYWRfcGFnZV9vcChuYW5kLCBwYWdl ICsgMSwgbmFuZC0+YmFkYmxvY2twb3MsIE5VTEwsIDApOwoJCWJhZCA9IHJrX25hbmRfcmVhZF9i eXRlKG5hbmQpOwoJCWlmIChiYWQgIT0gMHhGRikKCQkJcmVzID0gMTsKCQkvKiBsYXN0IHBhZ2Ug b2YgYSBibG9jayAqLwoJCXBhZ2UgKz0gKChtdGQtPmVyYXNlc2l6ZSAtIG10ZC0+d3JpdGVzaXpl KSA+PiBuYW5kLT5jaGlwX3NoaWZ0KTsKCQlwYWdlLS07CgkJbmFuZF9yZWFkX3BhZ2Vfb3AobmFu ZCwgcGFnZSwgbmFuZC0+YmFkYmxvY2twb3MsIE5VTEwsIDApOwoJCWJhZCA9IHJrX25hbmRfcmVh ZF9ieXRlKG5hbmQpOwoJCWlmIChiYWQgIT0gMHhGRikKCQkJcmVzID0gMTsKCX0KCXJrX25hbmRf c2VsZWN0X2NoaXAobmFuZCwgLTEpOwoJcmV0dXJuIHJlczsKfQoKVGhpcyBhbHNvIHJlcXVpcmVz IGEgcGF0Y2ggZm9yIG5hbmRfYmJ0LmMKQXMgSSB0cnkgdG8gZ2V0IHRvIGdldCBzb21lIHNoYXBl IGluIHRoZSByZXN0IG9mIHRoaXMgZHJpdmVyLApJIGhhdmUgbGVmdCBpdCBvdXQgZm9yIHZlcnNp b24gMSBhbmQgYXMgSSB3YWl0IGZvciBvdXIgcmVzcG9ucyBmaXJzdC4KCmRyaXZlcnMvbXRkL25h bmQvbmFuZF9iYnQuYwpAQCAtNDg3LDggKzQ4NywxMCBAQCBzdGF0aWMgaW50IGNyZWF0ZV9iYnQo c3RydWN0IG10ZF9pbmZvICptdGQsIHVpbnQ4X3QKKmJ1ZiwKCQlpbnQgcmV0OwoKCQlCVUdfT04o YmQtPm9wdGlvbnMgJiBOQU5EX0JCVF9OT19PT0IpOwoKCQlyZXQgPSBzY2FuX2Jsb2NrX2Zhc3Qo bXRkLCBiZCwgZnJvbSwgYnVmLCBudW1wYWdlcyk7CgkJaWYgKHRoaXMtPmJsb2NrX2JhZCkKCQkJ cmV0ID0gdGhpcy0+YmxvY2tfYmFkKG10ZCwgZnJvbSk7CgkJZWxzZQoJCQlyZXQgPSBzY2FuX2Js b2NrX2Zhc3QobXRkLCBiZCwgZnJvbSwgYnVmLCBudW1wYWdlcyk7CgovLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLwoKRGF0YSBzdHJ1Y3R1cmVzL1BhcnRpdGlvbnMKClRoZSBtYWpvcml0eSBv ZiBSb2NrY2hpcCBkZXZpY2VzIHVzZSBhIGNsb3NlZCBzb3VyY2UgRlRMIGRyaXZlciwKc28gd2hl biB3ZSB3YW50IHRvIHJlYWQgb3Igd3JpdGUgd2UgbXVzdCBkZWFsIHdpdGggaXQuCgpFeGFtcGxl IE1URCBzdHJpbmc6Cm10ZHBhcnRzPXJrMjl4eG5hbmQ6CjB4MDAwMDIwMDBAMHgwMDAwMjAwMCht aXNjKSwKMHgwMDAwODAwMEAweDAwMDA0MDAwKGtlcm5lbCksCjB4MDAwMDgwMDBAMHgwMDAwQzAw MChib290KSwKMHgwMDAwODAwMEAweDAwMDE0MDAwKHJlY292ZXJ5KSwKMHgwMDBDMDAwMEAweDAw MDFDMDAwKGJhY2t1cCksCjB4MDAwNDAwMDBAMHgwMDBEQzAwMChjYWNoZSksCjB4MDAzMDAwMDBA MHgwMDExQzAwMCh1c2VyZGF0YSksCjB4MDAwMDIwMDBAMHgwMDQxQzAwMChrcGFuaWMpLAoweDAw MjAwMDAwQDB4MDA0MUUwMDAoc3lzdGVtKSwKLUAweDAwNjNFMDAwKHVzZXIpIgoKV2hlbiBSb2Nr Y2hpcCBtZW50aW9ucyBhIHN0cmluZyBsaWtlIHRoaXMgaXQgaGFzIG5vdGhpbmcgdG8gZG8Kd2l0 aCB0aGUgcmVhbCBwb3NpdGlvbiBvbiBOQU5ELiBGVEwgd3JpdGUgd2hlcmUgd2FudHMsCnNvIHJl YWRpbmcgdGhlcmUgaXMgbm90IHVzZWZ1bC4KQWxsIHNpemVzIGhhdmUgdG8gYmUgbXVsdGlwbGll ZCBieSA1MTIgYW5kIGNhc3RlZCB0byAodTY0KSEKQWxsIHBhcnRpdGlvbnMgbmVlZCB0byBjb250 YWluIGF0IGxlYXN0IDIgZXJhc2UgYmxvY2tzLgpPbmUgZm9yIG5vcm1hbCB1c2UgYW5kIG9uZSBz cGFyZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tCkZsYXNoU2F2ZVBoeUluZm8KUmF3SWRiRGF0YQot LS0tLS0tLS0tLS0tLS0tLS0tLQouLi4KRlRMIGRhdGEKLi4uCi0tLS0tLS0tLS0tLS0tLS0tLS0t Ck1hcCBibG9ja3M6CisgTDJwTWFwSW5mbworIFZlbmRvckJsa0luZm8KClN5cyBpbmZvOgorIHN5 c19zYXZlX2RhdGEKClZlbmRvciBwYXJ0aXRpb246Cisgc3lzX2V4dF9kYXRhICAgIDAKKyBlY3Rf dGJsX2luZm8gICA2NAorIHZlbmRvciAgICAgICAgMjU2ICsgPworIEJvb3RDb25maWcgICAgNTEy ICsgMAorIERybUtleUluZm8gICAgNTEyICsgMQorIFZlbmRvcjBJbmZvICAgNTEyICsgMgorIFZl bmRvcjFJbmZvICAgNTEyICsgMworIHN5cyAgICAgICAgICAgNTEyICsgPworIHB1YmxpYyBrZXkg ICAgNTIwCi0tLS0tLS0tLS0tLS0tLS0tLS0tCkJhZCBCbG9jayBNYXAgVGJsKG5vdCBjb21wYXRp YmxlIHdpdGggTVREKQotLS0tLS0tLS0tLS0tLS0tLS0tLQpyZXNlcnZlZDogbGFzdCBOQU5EIGJs b2NrIC0gbgotLS0tLS0tLS0tLS0tLS0tLS0tLQoKRnJvbSB0aGUgYWJvdmUgZGlhZ3JhbSBvbmx5 IFJhd0lkYkRhdGEgaGFzIHRvIGJlIGxvY2F0ZWQgaW4gdGhlIGZpcnN0CmVyYXNlIGJsb2NrLgpC b290IFJPTSBzZWFyY2hlcyBmb3IgdGhlIHRhZyBJRF9JRFJXID0gMHhGQ0RDOEMzQi4KT25seSB0 aGUgZmlyc3QgNCBzZWN0aW9ucyAoNCoxMDI0KSBvZiBhIHBhZ2UgYXJlIHVzZWQuCldoZW4gd3Jp dGluZyBtdWx0aXBsZSBwYWdlcyBleHRyYSBzcGFjZXMgaW4gdGhlIGRhdGEKZm9yIGJldHdlZW4g dGhlIHNlY3Rpb25zIGFyZSByZXF1aXJlZC4KT2xkZXIgY3B1J3MgKFJLMzA2NikgbWlnaHQgbmVl ZCBleHRyYSBSQzQgY29kaW5nLgoKRlRMIHVzZXMgdGhhdCBSYXdJZGJEYXRhIGFyZWEgdW5mb3J0 dW5hdGVseSBhbHNvIHRvIHNhdmUgc3RydWN0CkZsYXNoU2F2ZVBoeUluZm8uCkZvciBhIGJhcmUg YmFzaWMgYXBwbGljYXRpb24gb25seSBSYXdJZGJEYXRhIGlzIG5lZWRlZC4KCkZvciB1c2VycyB0 aGF0IG1pZ2h0IGNvbnNpZGVyIE1URCBhcyBhIG9wdGlvbiB0byBkbyBzb21ldGhpbmcgb24gYQpS b2NrY2hpcCBOQU5ECnNlZSB0aGUgc291cmNlIGNvZGUgYmVsb3cgdG8gZ2V0IGFuIGluZGljYXRp b24gb2Ygd2hhdCBpcyBuZWVkZWQgZm9yIGEKdXNlZnVsCnNldHVwIHRvIGp1c3QgcmVhZCBhbmQg d3JpdGUgYSBib290bG9hZGVyIGFsb25lLiBXcml0aW5nIG9mIGFueSB1c2VyCnBhcnRpdGlvbgpp cyBub3QgZXZlbiBpbmNsdWRlZC4KSGF2aW5nIGEgYmFzaWMgTVREIGRyaXZlciBpcyBqdXN0IG5v dCBlbm91Z2guClBsZWFzZSBhZHZpc2UgaWYgc3VjaCBhIG92ZXJoZWFkIGNhbiBpbnRlcmZhY2Ug d2l0aCBNVEQ/CkhhdmUgZnVuIQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCk9uIDEv MTAvMjAgMTI6MDUgUE0sIE1pcXVlbCBSYXluYWwgd3JvdGU6Cj4gSGkgSm9oYW4sCj4KPiBKb2hh biBKb25rZXIgPGpieDYyNDRAZ21haWwuY29tPiB3cm90ZSBvbiBXZWQsICA4IEphbiAyMDIwIDIx OjUzOjMwCj4gKzAxMDA6Cj4KPj4gRnJvbTogWWlmZW5nIFpoYW8gPHp5ZkByb2NrLWNoaXBzLmNv bT4KPj4KPgo+IENhbiB5b3UgY2hhbmdlIHRoZSB0aXRsZSB0byAibXRkOiByYXduYW5kOiByb2Nr Y2hpcDogQWRkIE5BTkQKPiBjb250cm9sbGVyIGRyaXZlciIKPgo+PiBBZGQgYmFzaWMgUm9ja2No aXAgbmFuZCBjb250cm9sbGVyIGRyaXZlci4KPj4KPj4gQ29tcGF0aWJsZSB3aXRoIGhhcmR3YXJl IHZlcnNpb24gNiBhbmQgOS4KPj4gVjY6MTYsIDI0LCA0MCwgNjAgcGVyIDEwMjRCIEJDSC9FQ0Mu Cj4+IFY5OjE2LCA0MCwgNjAsIDcwIHBlciAxMDI0QiBCQ0gvRUNDLgo+PiA4IGJpdCBhc3luY2hy b25vdXMgZmxhc2ggaW50ZXJmYWNlIHN1cHBvcnQuCj4+IFN1cHBvcnRzIHVwIHRvIDIgaWRlbnRp Y2FsIG5hbmRjIG5vZGVzLgo+PiBNYXggNCBuYW5kIGNoaXBzIHBlciBjb250cm9sbGVyLgo+PiBB YmxlIHRvIHNlbGVjdCBhIGRpZmZlcmVudCBoYXJkd2FyZSBlY2Mgc2V0dXAKPj4gZm9yIHRoZSBs b2FkZXIgYmxvY2tzLgo+PiBObyBiYWQgYmxvY2sgc3VwcG9ydC4KPgo+IFRoYW5rIHlvdSB2ZXJ5 IG11Y2ggZm9yIHRoaXMgc2VyaWVzLCBhcyB0aGUgYmFkIGJsb2NrcyBzdXBwb3J0IGlzCj4gYWJz b2x1dGVseSBmdW5kYW1lbnRhbCwgSSB3b25kZXIgd2hhdCBpcyB0aGUgaXNzdWUgaGVyZT8KPgo+ Pgo+PiBTaWduZWQtb2ZmLWJ5OiBZaWZlbmcgWmhhbyA8enlmQHJvY2stY2hpcHMuY29tPgo+PiBT aWduZWQtb2ZmLWJ5OiBKb2hhbiBKb25rZXIgPGpieDYyNDRAZ21haWwuY29tPgo+PiAtLS0KPj4g IGRyaXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcgICAgICAgICAgfCAgICA4ICsKPj4gIGRyaXZl cnMvbXRkL25hbmQvcmF3L01ha2VmaWxlICAgICAgICAgfCAgICAxICsKPj4gIGRyaXZlcnMvbXRk L25hbmQvcmF3L3JvY2tjaGlwX25hbmRjLmMgfCAxMjI0CisrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKwo+PiAgMyBmaWxlcyBjaGFuZ2VkLCAxMjMzIGluc2VydGlvbnMoKykKPj4gIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL210ZC9uYW5kL3Jhdy9yb2NrY2hpcF9uYW5kYy5jCj4+ Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnIGIvZHJpdmVycy9t dGQvbmFuZC9yYXcvS2NvbmZpZwo+PiBpbmRleCA3NGZiOTFhZGUuLjY4ZGM5YTM2ZCAxMDA2NDQK Pj4gLS0tIGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+PiArKysgYi9kcml2ZXJzL210 ZC9uYW5kL3Jhdy9LY29uZmlnCj4+IEBAIC00NTcsNiArNDU3LDE0IEBAIGNvbmZpZyBNVERfTkFO RF9DQURFTkNFCj4+ICAJICBFbmFibGUgdGhlIGRyaXZlciBmb3IgTkFORCBmbGFzaCBvbiBwbGF0 Zm9ybXMgdXNpbmcgYSBDYWRlbmNlIE5BTkQKPj4gIAkgIGNvbnRyb2xsZXIuCj4+Cj4+ICtjb25m aWcgTVREX05BTkRfUk9DS0NISVAKPj4gKwl0cmlzdGF0ZSAiUm9ja2NoaXAgcmF3IE5BTkQgY29u dHJvbGxlciBkcml2ZXIiCj4+ICsJZGVwZW5kcyBvbiBBUkNIX1JPQ0tDSElQIHx8IENPTVBJTEVf VEVTVAo+PiArCWRlcGVuZHMgb24gSEFTX0lPTUVNCj4+ICsJaGVscAo+PiArCSAgRW5hYmxlcyBz dXBwb3J0IGZvciB0aGUgUm9ja2NoaXAgcmF3IE5BTkQgY29udHJvbGxlciBkcml2ZXIuCj4+ICsJ ICBUaGlzIGNvbnRyb2xsZXIgaXMgZm91bmQgb24gcmszMDY2LCByazMxODgsIHJrMzI4OCBhbmQg bW9yZS4KPgo+IENhbiB5b3Ugd3JpdGUgYW4gZXhoYXVzdGl2ZSBsaXN0IGlmIHlvdSBrbm93IGl0 PyBPciBhdCBsZWFzdCB0aGUKPiBmYW1pbGllcz8gSXQgaXMgcXVpdGUgY2hhbGxlbmdpbmcgd2hl biB5b3UgYXJlIG5vdCBpbiB0aGUgUm9ja2NoaXAKPiB3b3JsZCB0byBrbm93IHdoYXQgU29DIGlz IHNpbWlsYXIgdG8gYW5vdGhlciByYW5kb20gU29DLgoKU2VlIGFib3ZlLgoKPgo+PiArCj4+ICBj b21tZW50ICJNaXNjIgo+Pgo+PiAgY29uZmlnIE1URF9TTV9DT01NT04KPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCmIvZHJpdmVycy9tdGQvbmFuZC9yYXcvTWFr ZWZpbGUKPj4gaW5kZXggMmQxMzZiMTU4Li4zMDYzZmU3NGEgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZl cnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L01h a2VmaWxlCj4+IEBAIC01OCw2ICs1OCw3IEBAIG9iai0kKENPTkZJR19NVERfTkFORF9URUdSQSkJ CSs9IHRlZ3JhX25hbmQubwo+PiAgb2JqLSQoQ09ORklHX01URF9OQU5EX1NUTTMyX0ZNQzIpCSs9 IHN0bTMyX2ZtYzJfbmFuZC5vCj4+ICBvYmotJChDT05GSUdfTVREX05BTkRfTUVTT04pCQkrPSBt ZXNvbl9uYW5kLm8KPj4gIG9iai0kKENPTkZJR19NVERfTkFORF9DQURFTkNFKQkJKz0gY2FkZW5j ZS1uYW5kLWNvbnRyb2xsZXIubwo+PiArb2JqLSQoQ09ORklHX01URF9OQU5EX1JPQ0tDSElQKQkJ Kz0gcm9ja2NoaXBfbmFuZGMubwo+Cj4gQSBkcml2ZXIgbmFtZWQgcm9ja2NoaXAtbmFuZC1jb250 cm9sbGVyLmMgd291bGQgYmUgbmljZSEKPgo+Pgo+PiAgbmFuZC1vYmpzIDo9IG5hbmRfYmFzZS5v IG5hbmRfbGVnYWN5Lm8gbmFuZF9iYnQubyBuYW5kX3RpbWluZ3MubwpuYW5kX2lkcy5vCj4+ICBu YW5kLW9ianMgKz0gbmFuZF9vbmZpLm8KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQv cmF3L3JvY2tjaGlwX25hbmRjLmMKYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9yb2NrY2hpcF9uYW5k Yy5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMC4uMDE4MzA4ZTU4 Cj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvcm9ja2NoaXBf bmFuZGMuYwo+PiBAQCAtMCwwICsxLDEyMjQgQEAKPj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wCj4+ICsvKgo+PiArICogQmFzZWQgb246Cj4+ICsgKgpodHRwczovL2dpdGh1 Yi5jb20vcm9ja2NoaXAtbGludXgva2VybmVsL2Jsb2IvZGV2ZWxvcC00LjQvZHJpdmVycy9tdGQv bmFuZC8KPj4gKyAqICAgICAgICAgcm9ja2NoaXBfbmFuZF92Ni5jCj4+ICsgKgpodHRwczovL2dp dGh1Yi5jb20vcm9ja2NoaXAtbGludXgva2VybmVsL2Jsb2IvZGV2ZWxvcC00LjQvZHJpdmVycy9t dGQvbmFuZC8KPj4gKyAqICAgICAgICAgcm9ja2NoaXBfbmFuZF92OS5jCj4KPiBJJ20gbm90IHN1 cmUgdGhlIGVudGlyZSBsaW5rIGlzIHJlbGV2YW50LCBJIHdvdWxkIHNpbXBsZSBtZW50aW9uIHRo ZQo+IFJvY2tjaGlwIG9mZmljaWFsIEdpdGh1YiByZXBvc2l0b3J5IGFuZCB3b3JrIGZyb20gWWlm ZW5nLgo+Cj4+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOSBZaWZlbmcgWmhhbyB5aWZlbmcu emhhb0Byb2NrLWNoaXBzLmNvbQo+PiArICoKPj4gKyAqIFVwZGF0ZS9yZXN0eWxlIGZvciBsaW51 eC1uZXh0Lgo+PiArICogQWRkIGV4ZWNfb3AgZnVuY3Rpb24uCj4KPiBZb3UgY2FuIGRyb3AgdGhl c2UgdHdvIGxpbmVzIHRvby4gVGhpcyBpcyBtb3JlIGEgImNvbW1pdCBkZXNjcmlwdGlvbiIKPiB0 aGluZy4KPgo+PiArICogQ29tYmluZSBkcml2ZXIgZm9yIG5hbmRjIHZlcnNpb24gNiBhbmQgOS4K Pgo+ICAgICAgIFN1cHBvcnQgTkFORCBjb250cm9sbGVyIHZlcnNpb25zIDYgYW5kIDkgZm91bmQg b24gU29DcyAuLi4KPgo+PiArICogQ29weXJpZ2h0IChjKSAyMDIwIEpvaGFuIEpvbmtlciBqYng2 MjQ0QGdtYWlsLmNvbQo+PiArICovCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPj4g KyNpbmNsdWRlIDxsaW51eC9kbWEtbWFwcGluZy5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2ludGVy cnVwdC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4 L21vZHVsZS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPgo+PiArI2luY2x1ZGUg PGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgvbXRkL3Jh d25hbmQuaD4KPj4gKwo+PiArI2RlZmluZSBOQU5EQ19JRF9WNjAwCQkJMHg1NjM2MzAzMAo+PiAr I2RlZmluZSBOQU5EQ19JRF9WNjIyCQkJMHg1NjM2MzIzMgo+PiArI2RlZmluZSBOQU5EQ19JRF9W NzAxCQkJMHg3MDEKPj4gKyNkZWZpbmUgTkFORENfSURfVjgwMAkJCTB4NTYzODMwMzAKPj4gKyNk ZWZpbmUgTkFORENfSURfVjgwMQkJCTB4ODAxCj4+ICsjZGVmaW5lIE5BTkRDX0lEX1Y5MDAJCQkw eDU2MzkzMDMwCj4KCj4gSSB3b3VsZCBwcmVmZXIgcHJlZml4aW5nIGV2ZXJ5dGhpbmcgUktfTkFO RENfIG9yIFJLXwoKV2lsbCBjaGFuZ2UgZGVmaW5lIGxpc3QgYWJvdmUgYW5kIGJlbG93IHRvIFJL X05BTkRDXwpJdCB0YWtlcyBtb3JlIHNwYWNlIHRob3VnaC4gQWxyZWFkeSBkaWZmaWN1bHQgdG8g c3RheSBiZWxvdyA4MCBjaGFyL2xpbmUuCgo+Cj4+ICsKPj4gKyNkZWZpbmUgTkFORENfSURCUmVz QmxrTnVtCQkxNgo+PiArI2RlZmluZSBOQU5EQ19JREJFY2NCaXRzCQkyNAo+PiArI2RlZmluZSBO QU5EQ19JREJTdGFydEFkZHIJCTAKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WNl9FQ0NfMTYJCQkw eDAwMDAwMDAwCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0VDQ18yNAkJCTB4MDAwMDAwMTAKPj4gKyNk ZWZpbmUgTkFORENfVjZfRUNDXzQwCQkJMHgwMDA0MDAwMAo+PiArI2RlZmluZSBOQU5EQ19WNl9F Q0NfNjAJCQkweDAwMDQwMDEwCj4+ICsKPj4gKyNkZWZpbmUgTkFORENfVjlfRUNDXzE2CQkJMHgw MjAwMDAwMQo+PiArI2RlZmluZSBOQU5EQ19WOV9FQ0NfNDAJCQkweDA0MDAwMDAxCj4+ICsjZGVm aW5lIE5BTkRDX1Y5X0VDQ182MAkJCTB4MDYwMDAwMDEKPj4gKyNkZWZpbmUgTkFORENfVjlfRUND XzcwCQkJMHgwMDAwMDAwMQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX05VTV9CQU5LUwkJCTQKPj4g KyNkZWZpbmUgTkFORENfREVGX1RJTUVPVVQJCTEwMDAwCj4+ICsKPj4gKyNkZWZpbmUgTkFORENf UkVHX0RBVEEJCQkweDAwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19BRERSCQkJMHgwNAo+PiArI2Rl ZmluZSBOQU5EQ19SRUdfQ01ECQkJMHgwOAo+PiArCj4+ICsvKiByZWdpc3RlciBvZmZzZXQgbmFu ZGMgdmVyc2lvbiA2ICovCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WNl9GTUNUTAkJMHgwMAo+PiAr I2RlZmluZSBOQU5EQ19SRUdfVjZfRk1XQUlUCQkweDA0Cj4+ICsjZGVmaW5lIE5BTkRDX1JFR19W Nl9GTENUTAkJMHgwOAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfQkNIQ1RMCQkweDBjCj4+ICsj ZGVmaW5lIE5BTkRDX1JFR19WNl9ETUFfQ0ZHCQkweDEwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19W Nl9ETUFfQlVGMAkJMHgxNAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfRE1BX0JVRjEJCTB4MTgK Pj4gKyNkZWZpbmUgTkFORENfUkVHX1Y2X0RNQV9TVAkJMHgxQwo+PiArI2RlZmluZSBOQU5EQ19S RUdfVjZfQkNIU1QJCTB4MjAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y2X1JBTkRNWgkJMHgxNTAK Pj4gKyNkZWZpbmUgTkFORENfUkVHX1Y2X1ZFUgkJMHgxNjAKPj4gKyNkZWZpbmUgTkFORENfUkVH X1Y2X0lOVEVOCQkweDE2Qwo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfSU5UQ0xSCQkweDE3MAo+ PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfSU5UU1QJCTB4MTc0Cj4+ICsjZGVmaW5lIE5BTkRDX1JF R19WNl9TUEFSRTAJCTB4MjAwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WNl9TUEFSRTEJCTB4MjMw Cj4+ICsKPj4gKy8qIHJlZ2lzdGVyIG9mZnNldCBuYW5kYyB2ZXJzaW9uIDkgKi8KPj4gKyNkZWZp bmUgTkFORENfUkVHX1Y5X0ZNQ1RMCQkweDAwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WOV9GTVdB SVQJCTB4MDQKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X0ZMQ1RMCQkweDEwCj4+ICsjZGVmaW5l IE5BTkRDX1JFR19WOV9CQ0hDVEwJCTB4MjAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X0RNQV9D RkcJCTB4MzAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X0RNQV9CVUYwCQkweDM0Cj4+ICsjZGVm aW5lIE5BTkRDX1JFR19WOV9ETUFfQlVGMQkJMHgzOAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjlf RE1BX1NUCQkweDQwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WOV9WRVIJCTB4ODAKPj4gKyNkZWZp bmUgTkFORENfUkVHX1Y5X0lOVEVOCQkweDEyMAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjlfSU5U Q0xSCQkweDEyNAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjlfSU5UU1QJCTB4MTI4Cj4+ICsjZGVm aW5lIE5BTkRDX1JFR19WOV9CQ0hTVAkJMHgxNTAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X1NQ QVJFMAkJMHgyMDAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X1NQQVJFMQkJMHgyMDQKPj4gKyNk ZWZpbmUgTkFORENfUkVHX1Y5X1JBTkRNWgkJMHgyMDgKPj4gKwo+PiArLyogcmVnaXN0ZXIgb2Zm c2V0IG5hbmRjIGNvbW1vbiAqLwo+PiArI2RlZmluZSBOQU5EQ19SRUdfQkFOSzAJCQkweDgwMAo+ PiArI2RlZmluZSBOQU5EQ19SRUdfU1JBTTAJCQkweDEwMDAKPj4gKwo+PiArLyogRk1DVEwgKi8K Pj4gKyNkZWZpbmUgTkFORENfVjZfRk1fV1AJCQlCSVQoOCkKPj4gKyNkZWZpbmUgTkFORENfVjZf Rk1fQ0VfU0VMX00JCTB4RkYKPj4gKyNkZWZpbmUgTkFORENfVjZfRk1fQ0VfU0VMKHgpCQkoMSA8 PCAoeCkpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0ZNX0ZSRUFEWQkJQklUKDkpCj4+ICsKPj4gKyNk ZWZpbmUgTkFORENfVjlfRk1fV1AJCQlCSVQoOCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRk1fQ0Vf U0VMX00JCTB4RkYKPj4gKyNkZWZpbmUgTkFORENfVjlfRk1fQ0VfU0VMKHgpCQkoMSA8PCAoeCkp Cj4+ICsjZGVmaW5lIE5BTkRDX1Y5X1JEWQkJCUJJVCg5KQo+PiArCj4+ICsvKiBGTENUTCAqLwo+ PiArI2RlZmluZSBOQU5EQ19WNl9GTF9SU1QJCQlCSVQoMCkKPj4gKyNkZWZpbmUgTkFORENfVjZf RkxfRElSKHgpCQkoKHgpID8gQklUKDEpIDogMCkKPj4gKyNkZWZpbmUgTkFORENfVjZfRkxfWEZF Ul9TVEFSVAkJQklUKDIpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0ZMX1hGRVJfRU4JCUJJVCgzKQo+ PiArI2RlZmluZSBOQU5EQ19WNl9GTF9TVF9CVUZfUwkJMHg0Cj4+ICsjZGVmaW5lIE5BTkRDX1Y2 X0ZMX1hGRVJfQ09VTlQJCUJJVCg1KQo+PiArI2RlZmluZSBOQU5EQ19WNl9GTF9BQ09SUkVDVAkJ QklUKDEwKQo+PiArI2RlZmluZSBOQU5EQ19WNl9GTF9YRkVSX1JFQURZCQlCSVQoMjApCj4+ICsj ZGVmaW5lIE5BTkRDX1Y2X0ZMX1BBR0VfTlVNKHgpCQkoKHgpIDw8IDIyKQo+PiArI2RlZmluZSBO QU5EQ19WNl9GTF9BU1lOQ19UT0dfTUlYCUJJVCgyOSkKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19W OV9GTF9SU1QJCQlCSVQoMCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRkxfRElSKHgpCQkoKHgpID8g QklUKDEpIDogMCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRkxfWEZFUl9TVEFSVAkJQklUKDIpCj4+ ICsjZGVmaW5lIE5BTkRDX1Y5X0ZMX1hGRVJfRU4JCUJJVCgzKQo+PiArI2RlZmluZSBOQU5EQ19W OV9GTF9TVF9CVUZfUwkJMHg0Cj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0ZMX1hGRVJfQ09VTlQJCUJJ VCg1KQo+PiArI2RlZmluZSBOQU5EQ19WOV9GTF9BQ09SUkVDVAkJQklUKDEwKQo+PiArI2RlZmlu ZSBOQU5EQ19WOV9GTF9YRkVSX1JFQURZCQlCSVQoMjApCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0ZM X1BBR0VfTlVNKHgpCQkoKHgpIDw8IDIyKQo+PiArI2RlZmluZSBOQU5EQ19WOV9GTF9BU1lOQ19U T0dfTUlYCUJJVCgyOSkKPj4gKwo+PiArLyogQkNIQ1RMICovCj4+ICsjZGVmaW5lIE5BTkRfVjZf QkNIX1JFR0lPTl9TCQkweDUKPj4gKyNkZWZpbmUgTkFORF9WNl9CQ0hfUkVHSU9OX00JCTB4Nwo+ PiArCj4+ICsjZGVmaW5lIE5BTkRfVjlfQkNIX01PREVfUwkJMjUKPj4gKyNkZWZpbmUgTkFORF9W OV9CQ0hfTU9ERV9NCQkweDcKPj4gKwo+PiArLyogQkNIU1QgKi8KPj4gKyNkZWZpbmUgTkFORENf VjZfQkNIMF9TVF9FUlIJCUJJVCgyKQo+PiArI2RlZmluZSBOQU5EQ19WNl9CQ0gxX1NUX0VSUgkJ QklUKDE1KQo+PiArI2RlZmluZSBOQU5EQ19WNl9FQ0NfRVJSX0NOVDAoeCkJKCgoKHggJiAoMHgx RiA8PCAzKSkgPj4gMykgXAo+PiArCQkJCQl8ICgoeCAmICgxIDw8IDI3KSkgPj4gMjIpKSAmIDB4 M0YpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0VDQ19FUlJfQ05UMSh4KQkoKCgoeCAmICgweDFGIDw8 IDE2KSkgPj4gMTYpIFwKPj4gKwkJCQkJfCAoKHggJiAoMSA8PCAyOSkpID4+IDI0KSkgJiAweDNG KQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0JDSDBfU1RfRVJSCQlCSVQoMikKPj4gKyNkZWZp bmUgTkFORENfVjlfQkNIMV9TVF9FUlIJCUJJVCgxOCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRUND X0VSUl9DTlQwKHgpCSgoKHgpICYgKDB4N0YgPDwgMykpID4+IDMpCj4+ICsjZGVmaW5lIE5BTkRD X1Y5X0VDQ19FUlJfQ05UMSh4KQkoKCh4KSAmICgweDdGIDw8IDE5KSkgPj4gMTkpCj4+ICsKPj4g Ky8qIERNQV9DRkcgKi8KPj4gKyNkZWZpbmUgTkFORENfVjZfRE1BX0NGR19XUl9TVAkJQklUKDAp Cj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0RNQV9DRkdfV1IoeCkJCSgoIXgpID8gQklUKDEpIDogMCkK Pj4gKyNkZWZpbmUgTkFORENfVjZfRE1BX0NGR19CVVNfTU9ERQlCSVQoMikKPj4gKwo+PiArI2Rl ZmluZSBOQU5EQ19WNl9ETUFfQ0ZHX0hTSVpFXzgJMAo+PiArI2RlZmluZSBOQU5EQ19WNl9ETUFf Q0ZHX0hTSVpFXzE2CSgxIDw8IDMpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0RNQV9DRkdfSFNJWkVf MzIJKDIgPDwgMykKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WNl9ETUFfQ0ZHX0JVUlNUXzEJMAo+ PiArI2RlZmluZSBOQU5EQ19WNl9ETUFfQ0ZHX0JVUlNUXzQJKDMgPDwgNikKPj4gKyNkZWZpbmUg TkFORENfVjZfRE1BX0NGR19CVVJTVF84CSg1IDw8IDYpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0RN QV9DRkdfQlVSU1RfMTYJKDcgPDwgNikKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WNl9ETUFfQ0ZH X0lOQ1JfTlVNKHgpCSgoeCkgPDwgOSkKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WOV9ETUFfQ0ZH X1dSX1NUCQlCSVQoMCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRE1BX0NGR19XUih4KQkJKCgheCkg PyBCSVQoMSkgOiAwKQo+PiArI2RlZmluZSBOQU5EQ19WOV9ETUFfQ0ZHX0JVU19NT0RFCUJJVCgy KQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0RNQV9DRkdfSFNJWkVfOAkwCj4+ICsjZGVmaW5l IE5BTkRDX1Y5X0RNQV9DRkdfSFNJWkVfMTYJKDEgPDwgMykKPj4gKyNkZWZpbmUgTkFORENfVjlf RE1BX0NGR19IU0laRV8zMgkoMiA8PCAzKQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0RNQV9D RkdfQlVSU1RfMQkwCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0RNQV9DRkdfQlVSU1RfNAkoMyA8PCA2 KQo+PiArI2RlZmluZSBOQU5EQ19WOV9ETUFfQ0ZHX0JVUlNUXzgJKDUgPDwgNikKPj4gKyNkZWZp bmUgTkFORENfVjlfRE1BX0NGR19CVVJTVF8xNgkoNyA8PCA2KQo+PiArCj4+ICsjZGVmaW5lIE5B TkRDX1Y5X0RNQV9DRkdfSU5DUl9OVU0oeCkJKCh4KSA8PCA5KQo+PiArCj4+ICsvKiBJTlRFTiAq Lwo+PiArI2RlZmluZSBOQU5EQ19WNl9JTlRfRE1BCQlCSVQoMCkKPj4gKwo+PiArI2RlZmluZSBO QU5EQ19WOV9JTlRfRE1BCQlCSVQoMCkKPj4gKwo+PiArZW51bSBya19uYW5kY192ZXJzaW9uIHsK Pj4gKwlWRVJTSU9OXzYgPSA2LAo+PiArCVZFUlNJT05fOSA9IDksCj4+ICt9Owo+PiArCj4+ICtz dHJ1Y3QgcmtfbmFuZGNfZGF0YSB7Cj4+ICsJZW51bSBya19uYW5kY192ZXJzaW9uIHZlcnNpb247 Cj4KCj4gSWYgeW91IG1ha2UgYSBkaXN0aW5jdGlvbiBiZXR3ZWVuIGJvdGggdmVyc2lvbiwgbWF5 YmUgeW91IGNhbiBhZGQgbW9yZQo+IHBhcmFtZXRlcnMgaGVyZSBhbmQgZG8KPgo+IAlmb28gPSBk YXRhLT5wYXJhbQo+Cj4gaW5zdGVhZCBvZgo+Cj4gCWlmIChkYXRhLT52ZXJzaW9uID09IDYpCj4g CQlmb28gPSB0aGlzOwo+IAllbHNlCj4gCQlmb28gPSB0aGF0Owo+CgpUT0RPIHYyCgo+PiArfTsK Cgo+PiArCj4+ICtzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyIHsKPj4gKwl2b2lkIF9faW9tZW0g KnJlZ3M7Cj4+ICsJaW50IGlycTsKPj4gKwlzdHJ1Y3QgY2xrICpoY2xrOwo+PiArCXN0cnVjdCBj bGsgKmNsazsKPj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIGNoaXBzOwo+PiArCXN0cnVjdCBjb21wbGV0 aW9uIGNvbXBsZXRlOwo+PiArCXN0cnVjdCBuYW5kX2NvbnRyb2xsZXIgY29udHJvbGxlcjsKPj4g KwlpbnQgYmFua3NbTkFORENfTlVNX0JBTktTXTsKPgo+PiArCWJvb2wgYm9vdHJvbWJsb2NrczsK Pj4gKwlpbnQgZWNjX21vZGU7Cj4+ICsJdWludDMyX3QgZWNjX3N0cmVuZ3RoOwo+PiArCWludCBt YXhfZWNjX3N0cmVuZ3RoOwo+Cgo+IEkgaGF2ZSBub3QgcmVhZCB5ZXQgdGhlIGVudGlyZSBkcml2 ZXIgYnV0IEkgYmVsaWV2ZSB0aGUgYWJvdmUgNAo+IHBhcmFtZXRlcnMgc2hvdWxkIHByb2JhYmx5 IGJlIG1vdmVkIGluIHJrX25hbmRfY2hpcCwgcmlnaHQ/IEFueXRoaW5nCj4gdGhhdCBpcyBOQU5E IGNoaXAgcmVsYXRlZCBzaG91bGQgbm90IGJlIGluIHRoZSBjb250cm9sbGVyIHN0cnVjdHVyZS4g SXQKPiBkZXBlbmRzIGlmIHlvdSBjYW4gY2hhbmdlIEVDQyByZXF1aXJlbWVudHMgb24gdGhlIGZs eSBvciBub3QuCgpTaG9ydCBhbnN3ZXI6ClRoZSByZWFzb24gdGhhdCBpdCBpcyB0aGUgbW9zdCBj b252ZW5pZW5jZSBwbGFjZSB0byBoYXZlIHRoZW0gZm9yIG5vdy4KV2l0aCBvbmUgcG9pbnRlciBm cm9tIG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YSgpIEkgaGF2ZSBhbGwgZGF0YSBhdmFpbGFibGUu CgpzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF9nZXRfY29udHJvbGxlcl9k YXRhKG5hbmQpOwoKVGhlIEVDQyBpcyBub3cgc29ydCBvZiBmaXhlZCB0byAyNCBhbmQgNDAgZm9y IGxlZ2FjeSByZWFzb25zLgpUaGUgb2xkZXIgcmszMDY2IGJvb3Ryb20gYXBwYXJlbnRseSBvbmx5 IHdvcmtzIGZvciBlY2MgMjQuClNlZSBpbmZvIGJhc2VkIG9uIG9sZGVyIHdvcmsgYnkgUGF3ZcWC IEphcm9zeiBmb3IgVWJvb3QuCgpJJ20gbm90IHRvbyBmYW1pbGlhciB3aXRoIGFsbCBpbm5lciB3 b3JraW5nIG9mIE1URCwgc28gcGxlYXNlIGFkdmlzZS4KQ2FuIHRoZSB1c2VycyBnZXQgYWNjZXNz IHRvIHN0cnVjdCBya19uYW5kX2NoaXA/CldvdWxkIHlvdSBsaWtlIHRvIGdpdmUgdXNlcnMgY29u dHJvbCBvdmVyIHdoYXQgZWNjIHRvIHVzZT8KV2hhdCBwcm9ncmFtIGNhbiB3ZSB1c2UgZm9yIHRo YXQ/IENhbid0IHVzZSBkZCB0aGVuIGFueSBtb3JlLgpIb3cgZG8gd2UgcmVnYWluIGVjYyBjb250 cm9sIGlmIHdlIHJlYWxseSBoYXZlIHRvIGZvciBleGFtcGxlIHJrMzA2Nj8KT3IgcmVtb3ZlIHRo YXQgYm9vdHJvbSBjaGVjayBhbmQgYWx3YXlzIHNldCBFQ0Mgd2l0aCBldmVyeQpya19uYW5kY19o d19zeW5kcm9tZV9lY2NfcmVhZF9wYWdlIGFuZCBya19uYW5kY19od19zeW5kcm9tZV9lY2Nfd3Jp dGVfcGFnZQp3aXRoIHdoYXRldmVyIHBhc3NlZCBhbG9uZz8KCj4KPj4gKwl1aW50MzJfdCAqb29i X2J1ZjsKPj4gKwl1aW50MzJfdCAqcGFnZV9idWY7Cj4+ICsJaW50IHNlbGVjdGVkX2Jhbms7Cj4+ ICsJZW51bSBya19uYW5kY192ZXJzaW9uIHZlcnNpb247Cj4+ICt9Owo+PiArCj4+ICtzdHJ1Y3Qg cmtfbmFuZF9jaGlwIHsKPj4gKwlzdHJ1Y3QgbmFuZF9jaGlwIG5hbmQ7Cj4+ICsJc3RydWN0IGxp c3RfaGVhZCBjaGlwX2xpc3Q7Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHJrX25hbmRf Y29udHJvbGxlciBnX25hbmRjX2luZm9bMl07Cj4KPiBJIGRvbid0IGxpa2UgdGhpcyBpZGVhIHNv IG11Y2guIEkgcHJlZmVyIGEgZHluYW1pYyBhbGxvY2F0aW9uIGluIHRoZQo+IHByb2JlLgo+Cj4+ ICtzdGF0aWMgaW50IGdfaWRfY291bnRlcjsKPgo+IERvbid0IGtub3cgd2hhdCB0aGlzIGlzIHll dCwgYnV0IGl0IGlzIHByb2JhYmx5IGEgYmFkIGlkZWEgOikKPgoKTWF5YmUgbm90IGludGVyZXN0 aW5nIGZvciBNVEQsIGJ1dCBSSzMyODggaGFzIDIgaWRlbnRpY2FsIE5BTkRDJ3MuClRoZSBjdXJy ZWN0IEZUTCBzZXR1cCBvbmx5IHdvcmtzIHdpdGggbmFuZGMwLgpUbyByZXVzZSB0aGUgcHJvYmUg ZnVuY3Rpb24gZm9yIG90aGVyIHRoaW5ncyB0aGVuIE1URAppdCBuZWVkcyB0byBiZSBhd2FyZSBv ZiBhbGlhcyBvcmRlci4KV2lsbCByZW1vdmUgaXQgZm9yIHZlcnNpb24gMi4KCj4+ICsKPj4gK3N0 YXRpYyB2b2lkIHJrX25hbmRjX2luaXQoc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCkK Pj4gK3sKPj4gKwlpZiAoY3RybC0+dmVyc2lvbiA9PSBWRVJTSU9OXzkpIHsKPj4gKwkJd3JpdGVs KDAsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfUkFORE1aKTsKPj4gKwkJd3JpdGVsKDAsIGN0 cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfRE1BX0NGRyk7Cj4+ICsJCXdyaXRlbChOQU5EQ19WOV9G TV9XUCwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WOV9GTUNUTCk7Cj4+ICsJCXdyaXRlbChOQU5E Q19WOV9GTF9SU1QsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfRkxDVEwpOwo+PiArCQl3cml0 ZWwoMHgxMDgxLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0ZNV0FJVCk7Cj4+ICsJfSBlbHNl IHsKPj4gKwkJd3JpdGVsKDAsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfUkFORE1aKTsKPj4g KwkJd3JpdGVsKDAsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRE1BX0NGRyk7Cj4+ICsJCXdy aXRlbChOQU5EQ19WNl9GTV9XUCwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WNl9GTUNUTCk7Cj4+ ICsJCXdyaXRlbChOQU5EQ19WNl9GTF9SU1QsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRkxD VEwpOwo+PiArCQl3cml0ZWwoMHgxMDgxLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0ZNV0FJ VCk7Cj4+ICsJfQo+Cj4gTXkgYWJvdmUgY29tbWVudCBhYm91dCB0aGUgcGxhdGZvcm0gZGF0YSB3 b3VsZCBtYWtlIGEgbG90IG9mIHNlbnNlIGhlcmUhCj4KPj4gK30KPj4gKwo+PiArc3RhdGljIGly cXJldHVybl90IHJrX25hbmRjX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQpCj4+ICt7 Cj4+ICsJc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCA9IGRldl9pZDsKPj4gKwo+PiAr CWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiArCQl1aW50MzJfdCBzdCA9IHJl YWRsKGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfSU5UU1QpOwo+PiArCQl1aW50MzJfdCBpZW4g PSByZWFkbChjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0lOVEVOKTsKPj4gKwo+PiArCQlpZiAo IShpZW4gJiBzdCkpCj4+ICsJCQlyZXR1cm4gSVJRX05PTkU7Cj4+ICsKPj4gKwkJaWYgKChpZW4g JiBzdCkgPT0gaWVuKQo+PiArCQkJY29tcGxldGUoJmN0cmwtPmNvbXBsZXRlKTsKPj4gKwo+PiAr CQl3cml0ZWwoc3QsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfSU5UQ0xSKTsKPj4gKwkJd3Jp dGVsKH5zdCAmIGllbiwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WOV9JTlRFTik7Cj4+ICsJfSBl bHNlIHsKPj4gKwkJdWludDMyX3Qgc3QgPSByZWFkbChjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2 X0lOVFNUKTsKPj4gKwkJdWludDMyX3QgaWVuID0gcmVhZGwoY3RybC0+cmVncyArIE5BTkRDX1JF R19WNl9JTlRFTik7Cj4+ICsKPj4gKwkJaWYgKCEoaWVuICYgc3QpKQo+PiArCQkJcmV0dXJuIElS UV9OT05FOwo+PiArCj4+ICsJCWlmICgoaWVuICYgc3QpID09IGllbikKPj4gKwkJCWNvbXBsZXRl KCZjdHJsLT5jb21wbGV0ZSk7Cj4+ICsKPj4gKwkJd3JpdGVsKHN0LCBjdHJsLT5yZWdzICsgTkFO RENfUkVHX1Y2X0lOVENMUik7Cj4+ICsJCXdyaXRlbCh+c3QgJiBpZW4sIGN0cmwtPnJlZ3MgKyBO QU5EQ19SRUdfVjZfSU5URU4pOwo+PiArCX0KPgo+IFNhbWUgY29tbWVudCEKPgo+PiArCj4+ICsJ cmV0dXJuIElSUV9IQU5ETEVEOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBya19uYW5kY19z ZWxlY3RfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBpbnQgY2hpcG5yKQo+PiArewo+PiAr CXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9jb250cm9sbGVyX2Rh dGEobmFuZCk7Cj4+ICsJdWludDMyX3QgcmVnOwo+PiArCWludCBiYW5rbnI7Cj4+ICsKPj4gKwkv KiBUaGUgcmVnaXN0ZXIgb2Zmc2V0IGFuZCBiaXQgcG9zaXRpb25zIGZvcgo+Cj4gc2hvdWxkIGJl Ogo+Cj4gCS8qCj4gCSAqIFRoZSByZWdpc3Rlci4uLgo+Cgo+IFBsZWFzZSBydW4gY2hlY2twYXRj aC5wbCAtLXN0cmljdCBvbiB0aGlzIGZpbGUsIHRoaXMga2luZCBvZiBtaXN0YWtlCj4gd291bGQg aGF2ZSBiZWVuIGRldGVjdGVkLgo+CgpXaGVuIHlvdSB0aGluayB0aGF0IHlvdSBnb3QgcmlkIG9m IGFsbCB3YXJuaW5ncyB0aGVyZSdzIGFsd2F5cwphbiBleHRyYSBvcHRpb24gZm9yIG1vcmUuLi4K VGhhbmtzIGZvciB0aGF0IGFkdmljZS4KCj4+ICsJICogTkFORENfUkVHX1Y2X0ZNQ1RMIGFuZCBO QU5EQ19SRUdfVjlfRk1DVEwKPj4gKwkgKiBhcmUgaWRlbnRpY2FsLgo+PiArCSAqLwo+PiArCXJl ZyA9IHJlYWRsKGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRk1DVEwpOwo+PiArCXJlZyAmPSB+ TkFORENfVjZfRk1fQ0VfU0VMX007Cj4+ICsKPj4gKwlpZiAoY2hpcG5yID09IC0xKSB7Cj4+ICsJ CWJhbmtuciA9IC0xOwo+PiArCX0gZWxzZSB7Cj4+ICsJCWJhbmtuciA9IGN0cmwtPmJhbmtzW2No aXBucl07Cj4+ICsKPj4gKwkJcmVnIHw9IE5BTkRDX1Y2X0ZNX0NFX1NFTChiYW5rbnIpOwo+PiAr CX0KPj4gKwl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0ZNQ1RMKTsKPgo+ IE1heWJlIHlvdSBjYW4gc3BhcmUgdGhpcyB3cml0ZWwgYnkgcmV0dXJuaW5nIGVhcmx5IGlmIGJh bmtuciA9PQo+IGN0cmwtPnNlbGVjdGVkX2JhbmsuCj4KPj4gKwo+PiArCWN0cmwtPnNlbGVjdGVk X2JhbmsgPSBiYW5rbnI7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfaHdfZWNj X3NldHVwKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsCj4+ICsJCQkJIHVpbnQzMl90IHN0cmVuZ3Ro KQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9j b250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsJdWludDMyX3QgcmVnOwo+PiArCj4+ICsJbmFuZC0+ ZWNjLnN0cmVuZ3RoID0gc3RyZW5ndGg7CgpTaG91bGQgSSBhZGQgdGhpcyBjb21tZW50IGJlbG93 PwoKLyogSFcgRUNDIGFsd2F5cyByZXF1ZXN0IEVDQyBieXRlcyBmb3IgMTAyNCBieXRlcyBibG9j a3MgKi8KCj4+ICsJbmFuZC0+ZWNjLmJ5dGVzID0gRElWX1JPVU5EX1VQKG5hbmQtPmVjYy5zdHJl bmd0aCAqIDE0LCA4KTsKPgoKPiBXaGF0IGRvIDE0IGFuZCA4IG1lYW4/CgpmbHMgLSBmaW5kIGxh c3QgKG1vc3Qtc2lnbmlmaWNhbnQpIGJpdCBzZXQKCmludCBmbHModW5zaWduZWQgaW50IHgpCnsK CWludCByID0gMzI7CgoJaWYgKCF4KQoJCXJldHVybiAwOwoJaWYgKCEoeCAmIDB4ZmZmZjAwMDB1 KSkgewoJCXggPDw9IDE2OwoJCXIgLT0gMTY7Cgl9CglpZiAoISh4ICYgMHhmZjAwMDAwMHUpKSB7 CgkJeCA8PD0gODsKCQlyIC09IDg7Cgl9CglpZiAoISh4ICYgMHhmMDAwMDAwMHUpKSB7CgkJeCA8 PD0gNDsKCQlyIC09IDQ7Cgl9CglpZiAoISh4ICYgMHhjMDAwMDAwMHUpKSB7CgkJeCA8PD0gMjsK CQlyIC09IDI7Cgl9CglpZiAoISh4ICYgMHg4MDAwMDAwMHUpKSB7CgkJeCA8PD0gMTsKCQlyIC09 IDE7Cgl9CglyZXR1cm4gcjsKfQoKCW5hbmQtPmVjYy5ieXRlcyA9IERJVl9ST1VORF9VUChlY2Mt PnN0cmVuZ3RoICogZmxzKDggKiAxMDI0KSwgOCk7Cgpmb3JtdWxlIGlzIHVzZWQgdG8gdHJhbnNs YXRlIHN0cmVuZ3RoIGluIGJpdC8xMDI0IEJDSC9FQ0MKdG8gTVREIEVDQyBieXRlcyBmb3IgMTAy NCBieXRlcyBibG9ja3MgaW4gbmFuZC0+ZWNjLmJ5dGVzCgoxNCBpcyByZXBsYWNlbWVudCBmb3Ig ZmxzKDggKiAxMDI0KQo4IGJpdHMgaW4gYSBieXRlCgo+Cj4+ICsJLyogSFcgRUNDIG9ubHkgd29y a3Mgd2l0aCBhbiBldmVuIG51bWJlciBvZiBFQ0MgYnl0ZXMgKi8KPj4gKwluYW5kLT5lY2MuYnl0 ZXMgPSBBTElHTihuYW5kLT5lY2MuYnl0ZXMsIDIpOwo+PiArCj4+ICsJaWYgKGN0cmwtPnZlcnNp b24gPT0gVkVSU0lPTl85KSB7Cj4+ICsJCXN3aXRjaCAobmFuZC0+ZWNjLnN0cmVuZ3RoKSB7Cj4+ ICsJCWNhc2UgNzA6Cj4+ICsJCQlyZWcgPSBOQU5EQ19WOV9FQ0NfNzA7Cj4+ICsJCQlicmVhazsK Pj4gKwkJY2FzZSA2MDoKPj4gKwkJCXJlZyA9IE5BTkRDX1Y5X0VDQ182MDsKPj4gKwkJCWJyZWFr Owo+PiArCQljYXNlIDQwOgo+PiArCQkJcmVnID0gTkFORENfVjlfRUNDXzQwOwo+PiArCQkJYnJl YWs7Cj4+ICsJCWNhc2UgMTY6Cj4+ICsJCQlyZWcgPSBOQU5EQ19WOV9FQ0NfMTY7Cj4+ICsJCQli cmVhazsKPj4gKwkJZGVmYXVsdDoKPj4gKwkJCXJldHVybiAtRUlOVkFMOwo+PiArCQl9Cj4+ICsJ CXdyaXRlbChyZWcsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfQkNIQ1RMKTsKPj4gKwl9IGVs c2Ugewo+PiArCQlzd2l0Y2ggKG5hbmQtPmVjYy5zdHJlbmd0aCkgewo+PiArCQljYXNlIDYwOgo+ PiArCQkJcmVnID0gTkFORENfVjZfRUNDXzYwOwo+PiArCQkJYnJlYWs7Cj4+ICsJCWNhc2UgNDA6 Cj4+ICsJCQlyZWcgPSBOQU5EQ19WNl9FQ0NfNDA7Cj4+ICsJCQlicmVhazsKPj4gKwkJY2FzZSAy NDoKPj4gKwkJCXJlZyA9IE5BTkRDX1Y2X0VDQ18yNDsKPj4gKwkJCWJyZWFrOwo+PiArCQljYXNl IDE2Ogo+PiArCQkJcmVnID0gTkFORENfVjZfRUNDXzE2Owo+PiArCQkJYnJlYWs7Cj4+ICsJCWRl ZmF1bHQ6Cj4+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwkJfQo+PiArCQl3cml0ZWwocmVnLCBj dHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0JDSENUTCk7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJu IDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJrX25hbmRjX3hmZXJfc3RhcnQoc3RydWN0 IHJrX25hbmRfY29udHJvbGxlciAqY3RybCwKPj4gKwkJCQl1aW50OF90IGRpciwgdWludDhfdCBu X0tCLAo+PiArCQkJCWRtYV9hZGRyX3QgZG1hX2RhdGEsIGRtYV9hZGRyX3QgZG1hX29vYikKPj4g K3sKPj4gKwl1aW50MzJfdCByZWc7Cj4+ICsKPj4gKwlpZiAoY3RybC0+dmVyc2lvbiA9PSBWRVJT SU9OXzkpIHsKPj4gKwkJcmVnID0gTkFORENfVjlfRE1BX0NGR19XUl9TVCB8Cj4+ICsJCSAgICAg IE5BTkRDX1Y5X0RNQV9DRkdfV1IoZGlyKSB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0RNQV9DRkdf QlVTX01PREUgfAo+PiArCQkgICAgICBOQU5EQ19WOV9ETUFfQ0ZHX0hTSVpFXzMyIHwKPj4gKwkJ ICAgICAgTkFORENfVjlfRE1BX0NGR19CVVJTVF8xNiB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0RN QV9DRkdfSU5DUl9OVU0oMTYpOwo+PiArCQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENf UkVHX1Y5X0RNQV9DRkcpOwo+PiArCQl3cml0ZWwoKHVpbnQzMl90KWRtYV9kYXRhLCBjdHJsLT5y ZWdzICsgTkFORENfUkVHX1Y5X0RNQV9CVUYwKTsKPj4gKwkJd3JpdGVsKCh1aW50MzJfdClkbWFf b29iLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0RNQV9CVUYxKTsKPgo+IEknbSBwcmV0dHkg c3VyZSBtb3N0IG9mIHRoZXNlIHdyaXRlbCBjb3VsZCBiZSB0dXJuZWQgaW50bwo+IHdyaXRlbF9y ZWxheGVkLgoKd3JpdGVsKCkgICAgICAgLS0gd3JpdGUgdG8gdGhlIGxpdHRsZS1lbmRpYW4gaGFy ZHdhcmUgcmVnaXN0ZXIgd2l0aApjb21waWxlciBtZW1vcnkgYmFycmllciwKd3JpdGVsX3JlbGF4 ZWQgLS0gYXMgYWJvdmUsIHdpdGhvdXQgYmFycmllciwKX19yYXdfd3JpdGVsKCkgLS0gYXMgYWJv dmUgKHdyaXRlbF9yZWxheGVkKCkpIHdpdGhvdXQgZW5kaWFuZXNzCmNvbnZlcnNpb24gKENQVSBv cmRlcmluZyB3aWxsIGJlIHVzZWQpLgpBcmNoaXRlY3R1cmUtZGVwZW5kZW50LgpJIGRvbid0IGtu b3cuCgo+Cj4gQWxzbyBJIGFtIG5vdCBhIGJpZyBmYW4gb2YgdGhlc2UgY2FzdHMsIG1heWJlIHlv dSBzaG91bGQgY2hhbmdlCj4gZG1hX2RhdGEgYW5kIGRtYV9vb2IgdHlwZXMgKGJlIGNhcmVmdWw6 IHlvdSBlbmFibGVkIENPTVBJTEVfVEVTVCBpbgo+IEtjb25maWcsIHlvdSBtdXN0IHN1cHBvcnQg MzItYml0IGFuZCA2NC1iaXQgcG9pbnRlcnMsIHBsZWFzZSB0cnkgdG8KPiBjb21waWxlIHRoaXMg ZHJpdmVyIHdpdGggZGlmZmVyZW50IHRvb2xjaGFpbnMpLgoKRHJpdmVyIGlzIHVzZWQgZm9yIGJv dGggQVJNIGFzIGFybTY0LgpUaGVzZSByZWdpc3RlcnMgYXJlIDMyIGJpdC4gUGxlYXNlIGFkdmlz ZSB3aGF0IGhhcHBlbnMKd2hlbiB3cml0ZWwgZ2V0cyBkbWFfYWRkcl90IGFuZCBkbWFfZGF0YSBh cyA2NCBiaXQuCkRvbid0IGhhdmUgdGhlIGhhcmR3YXJlIHRvIGZpbmQgb3V0LgoKPgo+PiArCj4+ ICsJCXJlZyA9IE5BTkRDX1Y5X0ZMX0RJUihkaXIpIHwKPj4gKwkJICAgICAgTkFORENfVjlfRkxf WEZFUl9FTiB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0ZMX1hGRVJfQ09VTlQgfAo+PiArCQkgICAg ICBOQU5EQ19WOV9GTF9BQ09SUkVDVCB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0ZMX1BBR0VfTlVN KG5fS0IpIHwKPj4gKwkJICAgICAgTkFORENfVjlfRkxfQVNZTkNfVE9HX01JWDsKPj4gKwkJd3Jp dGVsKHJlZywgY3RybC0+cmVncyArIE5BTkRDX1JFR19WOV9GTENUTCk7Cj4+ICsJCXJlZyB8PSBO QU5EQ19WOV9GTF9YRkVSX1NUQVJUOwo+PiArCQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFO RENfUkVHX1Y5X0ZMQ1RMKTsKPj4gKwl9IGVsc2Ugewo+PiArCQlyZWcgPSByZWFkbChjdHJsLT5y ZWdzICsgTkFORENfUkVHX1Y2X0JDSENUTCk7Cj4+ICsJCXJlZyA9IChyZWcgJiAofihOQU5EX1Y2 X0JDSF9SRUdJT05fTSA8PAo+PiArCQkJCU5BTkRfVjZfQkNIX1JFR0lPTl9TKSkpIHwKPj4gKwkJ ICAgICAgKGN0cmwtPnNlbGVjdGVkX2JhbmsgPDwgTkFORF9WNl9CQ0hfUkVHSU9OX1MpOwo+PiAr CQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0JDSENUTCk7Cj4+ICsKPj4g KwkJcmVnID0gTkFORENfVjZfRE1BX0NGR19XUl9TVCB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y2X0RN QV9DRkdfV1IoZGlyKSB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y2X0RNQV9DRkdfQlVTX01PREUgfAo+ PiArCQkgICAgICBOQU5EQ19WNl9ETUFfQ0ZHX0hTSVpFXzMyIHwKPj4gKwkJICAgICAgTkFORENf VjZfRE1BX0NGR19CVVJTVF8xNiB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y2X0RNQV9DRkdfSU5DUl9O VU0oMTYpOwo+PiArCQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0RNQV9D RkcpOwo+PiArCQl3cml0ZWwoZG1hX2RhdGEsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRE1B X0JVRjApOwo+PiArCQl3cml0ZWwoZG1hX29vYiwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WNl9E TUFfQlVGMSk7CgpTYW1lIGhlcmUuCgo+PiArCj4+ICsJCXJlZyA9IE5BTkRDX1Y2X0ZMX0RJUihk aXIpIHwKPj4gKwkJICAgICAgTkFORENfVjZfRkxfWEZFUl9FTiB8Cj4+ICsJCSAgICAgIE5BTkRD X1Y2X0ZMX1hGRVJfQ09VTlQgfAo+PiArCQkgICAgICBOQU5EQ19WNl9GTF9BQ09SUkVDVCB8Cj4+ ICsJCSAgICAgIE5BTkRDX1Y2X0ZMX1BBR0VfTlVNKG5fS0IpIHwKPj4gKwkJICAgICAgTkFORENf VjZfRkxfQVNZTkNfVE9HX01JWDsKPj4gKwkJd3JpdGVsKHJlZywgY3RybC0+cmVncyArIE5BTkRD X1JFR19WNl9GTENUTCk7Cj4+ICsJCXJlZyB8PSBOQU5EQ19WNl9GTF9YRkVSX1NUQVJUOwo+PiAr CQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0ZMQ1RMKTsKPj4gKwl9Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfd2FpdF9mb3JfeGZlcl9kb25lKHN0cnVj dCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwpCj4+ICt7Cj4+ICsJdWludDMyX3QgcmVnOwo+PiAr CWludCByZXQ7Cj4+ICsKPj4gKwlpZiAoY3RybC0+dmVyc2lvbiA9PSBWRVJTSU9OXzkpIHsKPj4g KwkJdm9pZCBfX2lvbWVtICpwdHIgPSBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0ZMQ1RMOwo+ PiArCj4+ICsJCXJldCA9IHJlYWRsX3BvbGxfdGltZW91dF9hdG9taWMocHRyLCByZWcsCj4+ICsJ CQkJCQlyZWcgJiBOQU5EQ19WOV9GTF9YRkVSX1JFQURZLAo+PiArCQkJCQkJMSwgTkFORENfREVG X1RJTUVPVVQpOwo+PiArCX0gZWxzZSB7Cj4+ICsJCXZvaWQgX19pb21lbSAqcHRyID0gY3RybC0+ cmVncyArIE5BTkRDX1JFR19WNl9GTENUTDsKPj4gKwo+PiArCQlyZXQgPSByZWFkbF9wb2xsX3Rp bWVvdXRfYXRvbWljKHB0ciwgcmVnLAo+PiArCQkJCQkJcmVnICYgTkFORENfVjZfRkxfWEZFUl9S RUFEWSwKPj4gKwkJCQkJCTEsIE5BTkRDX0RFRl9USU1FT1VUKTsKPj4gKwl9Cj4KPiBTcGFjZQo+ Cj4+ICsJaWYgKHJldCkKPj4gKwkJcHJfZXJyKCJ0aW1lb3V0IHJlZz0leFxuIiwgcmVnKTsKPj4g Kwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB1bnNpZ25lZCBsb25nIHJr X25hbmRjX2RtYV9tYXBfc2luZ2xlKHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKwkJdm9pZCAqcHRy LCBpbnQgc2l6ZSwgaW50IGRpcikKPgoKPiBVbmFsaWduZWQgcGFyYW1ldGVycwoKVG8gcmVzdHls ZSBJIHVzZToKYXN0eWxlIC1UOCAtLW1heC1jb2RlLWxlbmd0aD04MCAtLXN0eWxlPWxpbnV4IHJv Y2tjaGlwX25hbmRjLmMKClBsZWFzZSBhZHZpc2UgZm9yIGEgYmV0dGVyIHNvbHV0aW9uLgoKPgo+ PiArewo+PiArI2lmZGVmIENPTkZJR19BUk02NAo+PiArCV9fZG1hX21hcF9hcmVhKCh2b2lkICop cHRyLCBzaXplLCBkaXIpOwo+PiArCXJldHVybiAoKHVuc2lnbmVkIGxvbmcpdmlydF90b19waHlz KCh2b2lkICopcHRyKSk7Cj4+ICsjZWxzZQo+PiArCXJldHVybiBkbWFfbWFwX3NpbmdsZShkZXYs ICh2b2lkICopcHRyLCBzaXplLCBkaXIpOwo+PiArI2VuZGlmCj4KCj4gUGxlYXNlIHRyeSB0byBy ZW1vdmUgdGhlc2UgI2lmZGVmcywgSSBkb24ndCBrbm93IHdoeSB3b3VsZCB5b3UgbmVlZCB0aGUK PiBmb3JtZXIgYmxvY2s/CgpUaGlzIGRyaXZlciBpcyB1c2VkIGJvdGggZm9yIEFSTSBhcyBhcm02 NC4KT3JpZ2luYWwgZnJvbSBSb2NrY2hpcDogYXJtNjQgZG9lc24ndCBoYXZlIGRtYV9tYXBfc2lu Z2xlKCkgYXMgSSByZW1lbWJlci4KRG9uJ3Qga25vdyB3aGF0IHRvIHVzZSBpbnN0ZWFkLgpQbGVh c2UgYWR2aXNlLgoKPgo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBya19uYW5kY19kbWFfdW5t YXBfc2luZ2xlKHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKwkJCQkgICAgICB1bnNpZ25lZCBsb25n IHB0ciwgaW50IHNpemUsIGludCBkaXIpCj4+ICt7Cj4+ICsjaWZkZWYgQ09ORklHX0FSTTY0Cj4+ ICsJX19kbWFfdW5tYXBfYXJlYShwaHlzX3RvX3ZpcnQocHRyKSwgc2l6ZSwgZGlyKTsKPj4gKyNl bHNlCj4+ICsJZG1hX3VubWFwX3NpbmdsZShkZXYsIChkbWFfYWRkcl90KXB0ciwgc2l6ZSwgZGly KTsKPj4gKyNlbmRpZgo+Cj4gU2FtZQo+Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFu ZGNfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZShzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLAo+PiAr CQl1aW50OF90ICpidWYsCj4+ICsJCWludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+Cgo+IFVu YWxpZ25lZCBwYXJhbWV0ZXJzIChwbGVhc2UgY2hlY2sgYWxsIG9mIHRoZW0pLgoKQWdhaW4gYmxh bWUgYXN0eWxlIC4uLgpBZnRlciBjb3JyZWN0aW5nIGl0IG1hbnVhbGx5IGEgZmV3IHRpbWUgSSBq dXN0IGxlZnQgaXQgYXMgaXQgaXMuCgo+Cj4+ICt7Cj4+ICsJc3RydWN0IG10ZF9pbmZvICptdGQg PSBuYW5kX3RvX210ZChuYW5kKTsKPj4gKwlzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJs ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKG5hbmQpOwo+PiArCXN0cnVjdCBuYW5kX2VjY19j dHJsICplY2MgPSAmbmFuZC0+ZWNjOwo+PiArCWludCBtYXhfYml0ZmxpcHMgPSAwOwo+PiArCWRt YV9hZGRyX3QgZG1hX2RhdGEsIGRtYV9vb2I7Cj4+ICsJaW50IHJldCwgaTsKPj4gKwlpbnQgYmNo X3N0Owo+PiArCWludCBkbWFfb29iX3NpemUgPSBlY2MtPnN0ZXBzICogMTI4Owo+PiArCWludCBw YWdlc19wZXJfYmxrID0gbXRkLT5lcmFzZXNpemUgLyBtdGQtPndyaXRlc2l6ZTsKPj4gKwo+PiAr CXJrX25hbmRjX3NlbGVjdF9jaGlwKG5hbmQsIGN0cmwtPnNlbGVjdGVkX2JhbmspOwo+PiArCj4+ ICsJaWYgKChwYWdlIDwgcGFnZXNfcGVyX2JsayAqIE5BTkRDX0lEQlJlc0Jsa051bSkgJiYKPgoK PiBDYW1lbCBjYXNlIGlzIHVzdWFsbHkgbm90IHdlbGNvbWUKCkFueSBzdWdnZXN0aW9ucyBmb3Ig YSBiZXRlciByZXBsYWNlIGZvciBOQU5EQ19JREJSZXNCbGtOdW0gYXJlIHdlbGNvbWUuCgo+Cj4+ ICsJICAgIGN0cmwtPmJvb3Ryb21ibG9ja3MpCj4KPiBUaGlzIHdvdWxkIHByb2JhYmx5IGRlc2Vy dmUgYSBoZWxwZXIKPgo+PiArCQlya19uYW5kY19od19lY2Nfc2V0dXAobmFuZCwgTkFORENfSURC RWNjQml0cyk7Cj4+ICsKPj4gKwluYW5kX3JlYWRfcGFnZV9vcChuYW5kLCBwYWdlLCAwLCBOVUxM LCAwKTsKPj4gKwo+PiArCWRtYV9kYXRhID0gcmtfbmFuZGNfZG1hX21hcF9zaW5nbGUobXRkLT5k ZXYucGFyZW50LAo+PiArCQkJCQkgICBjdHJsLT5wYWdlX2J1ZiwgbXRkLT53cml0ZXNpemUsCj4+ ICsJCQkJCSAgIERNQV9GUk9NX0RFVklDRSk7Cj4+ICsJZG1hX29vYiA9IHJrX25hbmRjX2RtYV9t YXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwKPj4gKwkJCQkJICBjdHJsLT5vb2JfYnVmLCBkbWFf b29iX3NpemUsCj4+ICsJCQkJCSAgRE1BX0ZST01fREVWSUNFKTsKPj4gKwo+PiArCWluaXRfY29t cGxldGlvbigmY3RybC0+Y29tcGxldGUpOwo+Cgo+IE9uZSBpbml0X2NvbXBsZXRpb24gaXMgbmVl ZGVkIChpbiB0aGUgcHJvYmUsIHByb2JhYmx5KSB0aGVuIHBsZWFzZSB1c2UKPiByZWluaXRfY29t cGxldGlvbigpLgoKTXVzdCBzdHVkeSB0aGlzIGxhdGVyLgoKPgo+PiArCWlmIChjdHJsLT52ZXJz aW9uID09IFZFUlNJT05fOSkKPj4gKwkJd3JpdGVsKE5BTkRDX1Y5X0lOVF9ETUEsIGN0cmwtPnJl Z3MgKyBOQU5EQ19SRUdfVjlfSU5URU4pOwo+PiArCWVsc2UKPj4gKwkJd3JpdGVsKE5BTkRDX1Y2 X0lOVF9ETUEsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfSU5URU4pOwo+PiArCXJrX25hbmRj X3hmZXJfc3RhcnQoY3RybCwgMCwgZWNjLT5zdGVwcywgZG1hX2RhdGEsIGRtYV9vb2IpOwoKPj4g Kwl3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJmN0cmwtPmNvbXBsZXRlLCBtc2Vjc190b19q aWZmaWVzKDUpKTsKPj4gKwlya19uYW5kY193YWl0X2Zvcl94ZmVyX2RvbmUoY3RybCk7Cj4KPiBZ b3VzIHNob3VsZCBjaGVjayB0aGUgcmV0dXJuIHN0YXR1cyBvZiBhbG1vc3QgYWxsIHRoZSBmdW5j dGlvbnMgaGVyZS4KClBsZWFzZSBhZHZpc2Ugd2hhdCBFUlJPUiBjb2RlIHNob3VsZCBiZSByZXR1 cm5lZCBoZXJlCnRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIE1URC4KCj4KPj4gKwlya19uYW5kY19k bWFfdW5tYXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwgZG1hX2RhdGEsIG10ZC0+d3JpdGVzaXpl LAo+PiArCQkJCSAgRE1BX0ZST01fREVWSUNFKTsKPj4gKwlya19uYW5kY19kbWFfdW5tYXBfc2lu Z2xlKG10ZC0+ZGV2LnBhcmVudCwgZG1hX29vYiwgZG1hX29vYl9zaXplLAo+PiArCQkJCSAgRE1B X0ZST01fREVWSUNFKTsKPj4gKwo+PiArCW1lbWNweShidWYsIGN0cmwtPnBhZ2VfYnVmLCBtdGQt PndyaXRlc2l6ZSk7Cj4+ICsKPj4gKwlpZiAob29iX3JlcXVpcmVkKSB7Cj4+ICsJCXVpbnQ4X3Qg Km9vYjsKPj4gKwkJdWludDMyX3QgdG1wOwo+Cgo+IFBsZWFzZSB1c2UgdTgsIHUxNiBhbmQgdTMy IHR5cGVzLgoKU2hvdWxkIHRoaXMgYmUgY2hhbmdlZCBmb3IgdGhlIGVudGlyZSBzb3VyY2U/Cgo+ Cj4+ICsKPj4gKwkJZm9yIChpID0gMDsgaSA8IGVjYy0+c3RlcHM7IGkrKykgewo+PiArCQkJb29i ID0gbmFuZC0+b29iX3BvaSArCj4+ICsJCQkgICAgICBpICogKGVjYy0+Ynl0ZXMgKyBuYW5kLT5l Y2MucHJlcGFkKTsKPj4gKwkJCWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiAr CQkJCXRtcCA9IGN0cmwtPm9vYl9idWZbaV07Cj4+ICsJCQl9IGVsc2Ugewo+PiArCQkJCXVpbnQ4 X3Qgb29iX3N0ZXAgPSAoY3RybC0+ZWNjX21vZGUgPD0gMjQpID8KPj4gKwkJCQkJCSAgIDY0IDog MTI4Owo+PiArCQkJCXRtcCA9IGN0cmwtPm9vYl9idWZbaSAqIG9vYl9zdGVwIC8gNF07Cj4+ICsJ CQl9Cj4+ICsJCQkqb29iKysgPSAodWludDhfdCl0bXA7Cj4+ICsJCQkqb29iKysgPSAodWludDhf dCkodG1wID4+IDgpOwo+PiArCQkJKm9vYisrID0gKHVpbnQ4X3QpKHRtcCA+PiAxNik7Cj4+ICsJ CQkqb29iKysgPSAodWludDhfdCkodG1wID4+IDI0KTsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiAr CWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiArCQlmb3IgKGkgPSAwOyBpIDwg ZWNjLT5zdGVwcyAvIDI7IGkrKykgewo+PiArCQkJYmNoX3N0ID0gcmVhZGwoY3RybC0+cmVncyAr IE5BTkRDX1JFR19WOV9CQ0hTVCArIGkgKiA0KTsKPj4gKwkJCWlmIChiY2hfc3QgJiBOQU5EQ19W OV9CQ0gwX1NUX0VSUiB8fAo+PiArCQkJICAgIGJjaF9zdCAmIE5BTkRDX1Y5X0JDSDFfU1RfRVJS KSB7Cj4+ICsJCQkJbXRkLT5lY2Nfc3RhdHMuZmFpbGVkKys7Cj4+ICsJCQkJbWF4X2JpdGZsaXBz ID0gLTE7Cj4+ICsJCQl9IGVsc2Ugewo+PiArCQkJCXJldCA9IE5BTkRDX1Y5X0VDQ19FUlJfQ05U MChiY2hfc3QpOwo+PiArCQkJCW10ZC0+ZWNjX3N0YXRzLmNvcnJlY3RlZCArPSByZXQ7Cj4+ICsJ CQkJbWF4X2JpdGZsaXBzID0gbWF4X3QodW5zaWduZWQgaW50LAo+PiArCQkJCQkJICAgICBtYXhf Yml0ZmxpcHMsIHJldCk7Cj4+ICsKPj4gKwkJCQlyZXQgPSBOQU5EQ19WOV9FQ0NfRVJSX0NOVDEo YmNoX3N0KTsKPj4gKwkJCQltdGQtPmVjY19zdGF0cy5jb3JyZWN0ZWQgKz0gcmV0Owo+PiArCQkJ CW1heF9iaXRmbGlwcyA9IG1heF90KHVuc2lnbmVkIGludCwKPj4gKwkJCQkJCSAgICAgbWF4X2Jp dGZsaXBzLCByZXQpOwo+PiArCQkJfQo+PiArCQl9Cj4+ICsJfSBlbHNlIHsKPj4gKwkJZm9yIChp ID0gMDsgaSA8IGVjYy0+c3RlcHMgLyAyOyBpKyspIHsKPj4gKwkJCWJjaF9zdCA9IHJlYWRsKGN0 cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfQkNIU1QgKyBpICogNCk7Cj4+ICsJCQlpZiAoYmNoX3N0 ICYgTkFORENfVjZfQkNIMF9TVF9FUlIgfHwKPj4gKwkJCSAgICBiY2hfc3QgJiBOQU5EQ19WNl9C Q0gxX1NUX0VSUikgewo+PiArCQkJCW10ZC0+ZWNjX3N0YXRzLmZhaWxlZCsrOwo+PiArCQkJCW1h eF9iaXRmbGlwcyA9IC0xOwo+Cgo+IFdoeSBub3QgdXNpbmcgcmV0ID0gJChyZWFsIGVycm9yKSBp bnN0ZWFkIG9mIHVzaW5nIG1heF9iaXRmbGlwcyBoZXJlPwo+Cj4gVGhlbjoKPgo+IAlpZiAocmV0 KSB7Cgo+IAkJZGV2X2VycigpOwoKRG8geW91IHJlYWxseSB3YW50IHRvIGxpdHRlciB0aGUga2Vy bmVsIGxvZyB3aXRoIGVhY2ggdGltZSB5b3UgaGl0IGEgYmFkCmJsb2NrLAppbiBjYXNlIHlvdSB1 c2UgdGhpcyBmdW5jdGlvbiBpbiBhIHNlYXJjaCBiYWQgYmxvY2sgbG9vcD8KRG9uJ3QgdGhpbmtz IHNvIC4uLgpQbGVhc2UgYWR2aXNlLgoKPiAJCXJldHVybiByZXQ7Cj4gCX0KPgo+IAlyZXR1cm4g bWF4X2JpdGZsaXBzOwoKcmtfbmFuZGNfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZSgpIGlzIHVz ZWQgaW4gYSBiYWQgYmxvY2sgc2VhcmNoIHN0cmF0ZWd5LgpJIHRoaW5rIG1heF9iaXRmbGlwcyA9 IC0xIHdhcyBjaG9zZW4gYXMgYSBzYXZlciB2YWx1ZSB0byByZXR1cm4uClBsZWFzZSBhZHZpc2Ug d2hhdCBudW1iZXIgcmFuZ2UgTVREIGludGVycHJldHMgYXMgbWF4X2JpdGZsaXBzIG9yIGFzIGZh dWx0LgpBbHNvIGNvbnNpZGVyIHNvbWUgdW5jb250cm9sbGVkIHN0YXR1cyByZXR1cm4gdmFsdWUs IGl0IHdvdWxkIGJlIGJldHRlcgppZiB3ZQphcmUgaW4gY29udHJvbCBvZiB3aGF0IGdvZXMgcmV0 dXJuLgoKPgo+PiArCQkJfSBlbHNlIHsKPj4gKwkJCQlyZXQgPSBOQU5EQ19WNl9FQ0NfRVJSX0NO VDAoYmNoX3N0KTsKPj4gKwkJCQltdGQtPmVjY19zdGF0cy5jb3JyZWN0ZWQgKz0gcmV0Owo+PiAr CQkJCW1heF9iaXRmbGlwcyA9IG1heF90KHVuc2lnbmVkIGludCwKPj4gKwkJCQkJCSAgICAgbWF4 X2JpdGZsaXBzLCByZXQpOwo+PiArCj4+ICsJCQkJcmV0ID0gTkFORENfVjZfRUNDX0VSUl9DTlQx KGJjaF9zdCk7Cj4+ICsJCQkJbXRkLT5lY2Nfc3RhdHMuY29ycmVjdGVkICs9IHJldDsKPj4gKwkJ CQltYXhfYml0ZmxpcHMgPSBtYXhfdCh1bnNpZ25lZCBpbnQsCj4+ICsJCQkJCQkgICAgIG1heF9i aXRmbGlwcywgcmV0KTsKPj4gKwkJCX0KPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCWlmIChtYXhf Yml0ZmxpcHMgPT0gLTEpIHsKPj4gKwkJZGV2X2VycihtdGQtPmRldi5wYXJlbnQsCj4+ICsJCQki cmVhZF9wYWdlICV4ICV4ICV4ICV4ICV4ICVwICV4XG4iLAo+PiArCQkJcGFnZSwKPj4gKwkJCW1h eF9iaXRmbGlwcywKPj4gKwkJCWJjaF9zdCwKPj4gKwkJCSgodWludDMyX3QgKilidWYpWzBdLAo+ PiArCQkJKCh1aW50MzJfdCAqKWJ1ZilbMV0sCj4+ICsJCQlidWYsCj4+ICsJCQkodWludDMyX3Qp ZG1hX2RhdGEpOwo+Cgo+IFRoaXMgaXMgbm90IHZlcnkgaW5mb3JtYXRpdmUsIHBsZWFzZSB3cml0 ZSBhIHJlYWwgZXJyb3IgbWVzc2FnZS4gQXZvaWQKPiBwdXR0aW5nIHRvbyBtdWNoIGRlYnVnIGlu Zm9ybWF0aW9uLCBwZW9wbGUgd2lsbCB0cm91Ymxlc2hvb3QgdGhlbXNlbHZlcwo+IGlmIG5lZWRl ZC4KCk9LLCBhZ3JlZS4KCj4KPj4gKwl9Cj4+ICsKPj4gKwlpZiAoY3RybC0+Ym9vdHJvbWJsb2Nr cykKPj4gKwkJcmtfbmFuZGNfaHdfZWNjX3NldHVwKG5hbmQsIGN0cmwtPmVjY19tb2RlKTsKPj4g Kwo+Cgo+IFlvdSBkb24ndCB1c2UgdGhlIHNhbWUgY29uZGl0aW9uIGFzIGFib3ZlLiBXaHkgPyBN YXliZSB0aGUgaGVscGVyIHdvdWxkCj4gaGVscC4KCkEgZmV3IGxlc3MgY29uZGl0aW9ucyB0byBj aGVjay4gSXQgd29uJ3QgZG8gZGFtYWdlIGluIGNhc2UgZWNjIGlzCnNhbWUgYmVmb3JlIGFuZCBh ZnRlci4gV2lsbCBtYWtlIGNvbmRpdGlvbnMgZXF1YWwuCgo+Cj4+ICsJcmV0dXJuIG1heF9iaXRm bGlwczsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBya19uYW5kY19od19zeW5kcm9tZV9lY2Nf d3JpdGVfcGFnZShzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLAo+PiArCQljb25zdCB1aW50OF90ICpi dWYsCj4+ICsJCWludCBvb2JfcmVxdWlyZWQsCj4+ICsJCWludCBwYWdlKQo+PiArewo+PiArCXN0 cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4+ICsJc3RydWN0IHJrX25h bmRfY29udHJvbGxlciAqY3RybCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPj4g KwlzdHJ1Y3QgbmFuZF9lY2NfY3RybCAqZWNjID0gJm5hbmQtPmVjYzsKPj4gKwlkbWFfYWRkcl90 IGRtYV9kYXRhLCBkbWFfb29iOwo+PiArCWludCBpOwo+PiArCWludCBkbWFfb29iX3NpemUgPSBl Y2MtPnN0ZXBzICogMTI4Owo+PiArCWludCBwYWdlc19wZXJfYmxrID0gbXRkLT5lcmFzZXNpemUg LyBtdGQtPndyaXRlc2l6ZTsKPj4gKwo+PiArCXJrX25hbmRjX3NlbGVjdF9jaGlwKG5hbmQsIGN0 cmwtPnNlbGVjdGVkX2JhbmspOwo+PiArCj4+ICsJaWYgKChwYWdlIDwgcGFnZXNfcGVyX2JsayAq IE5BTkRDX0lEQlJlc0Jsa051bSkgJiYKPj4gKwkgICAgY3RybC0+Ym9vdHJvbWJsb2NrcykKPj4g KwkJcmtfbmFuZGNfaHdfZWNjX3NldHVwKG5hbmQsIE5BTkRDX0lEQkVjY0JpdHMpOwo+PiArCj4+ ICsJbmFuZF9wcm9nX3BhZ2VfYmVnaW5fb3AobmFuZCwgcGFnZSwgMCwgTlVMTCwgMCk7Cj4+ICsK Pj4gKwlmb3IgKGkgPSAwOyBpIDwgZWNjLT5zdGVwczsgaSsrKSB7Cj4+ICsJCXVpbnQzMl90IHRt cDsKPj4gKwo+PiArCQlpZiAob29iX3JlcXVpcmVkKSB7Cj4+ICsJCQl1aW50OF90ICpvb2I7Cj4+ ICsKPj4gKwkJCW9vYiA9IG5hbmQtPm9vYl9wb2kgKwo+PiArCQkJICAgICAgaSAqIChlY2MtPmJ5 dGVzICsgbmFuZC0+ZWNjLnByZXBhZCk7Cj4+ICsJCQl0bXAgPSBvb2JbMF0gfAo+PiArCQkJICAg ICAgKG9vYlsxXSA8PCA4KSB8Cj4+ICsJCQkgICAgICAob29iWzJdIDw8IDE2KSB8Cj4+ICsJCQkg ICAgICAob29iWzNdIDw8IDI0KTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCS8qIFRoZSBmaXJzdCBO QU5EQ19JREJSZXNCbGtOdW0gYmxvY2tzIGFyZQo+PiArCQkJICogZm9yIHRoZSBzdG9yZWQgbG9h ZGVyLiBUaGUgZmlyc3QgMzIgYml0cwo+PiArCQkJICogb2Ygb29iIG11c3QgY29udGFpbiBhIHNv cnQgb2YgbGluayB0bwo+PiArCQkJICogdGhlIG5leHQgcGFnZSBhZGRyZXNzIGluIHRoYXQgc2Ft ZSBibG9jawo+PiArCQkJICogZm9yIHRoZSBCb290cm9tLgo+PiArCQkJICogRGVwZW5kaW5nIG9u IHdoYXQgRlRMIGZyb20gUm9ja2NoaXAgaXMgdXNlZCwKPj4gKwkJCSAqIHRoZSBmaXJzdCAyIHBh Z2VzIGluIHRoZSBOQU5EQ19JREJSZXNCbGtOdW0gYmxvY2tzCj4+ICsJCQkgKiBhcmUgcmVzZXJ2 ZWQgZm9yIEZsYXNoUGh5SW5mby4KPj4gKwkJCSAqIFJhdyBJREIgZGF0YSB0aGVuIHN0YXJ0cyBh dCBwYWdlIDIgb3IgaGlnaGVyLgo+Cj4gSSB3b3VsZCBzZXBhcmF0ZSB0aGUgZnVuY3Rpb24gdG8g cmVhZC93cml0ZSB0aGUgbG9hZGVyIHRoYW4gdGhlIHVzdWFsCj4gcmVhZC93cml0ZSBoZWxwZXJz IHRvIGF2b2lkIGFueSBjb25mdXNpb24gb24gd2h5IHlvdSBkbyB0aGVzZSB0cmlja3MuCj4KPiBN YXliZSBub3QgdGhlIHdob2xlIGZ1bmN0aW9uLCBidXQgYXQgbGVhc3QgdGhlIGRhdGEvb29iIHBs YWNlbWVudD8KPiAoVGhpcyBpcyByZWFsbHkgYSBzdWdnZXN0aW9uKQo+Cj4+ICsJCQkgKi8KPj4g KwkJCWlmICghaSAmJgo+PiArCQkJICAgIHBhZ2UgPCBwYWdlc19wZXJfYmxrICogTkFORENfSURC UmVzQmxrTnVtICYmCj4+ICsJCQkgICAgcGFnZSA+PSBOQU5EQ19JREJTdGFydEFkZHIpCj4+ICsJ CQkJdG1wID0gKHBhZ2UgJiAocGFnZXNfcGVyX2JsayAtIDEpKSAqIDQ7Cj4+ICsJCQllbHNlCj4+ ICsJCQkJdG1wID0gMHhGRkZGRkZGRjsKPj4gKwkJfQo+PiArCQlpZiAoY3RybC0+dmVyc2lvbiA9 PSBWRVJTSU9OXzkpIHsKPj4gKwkJCWN0cmwtPm9vYl9idWZbaV0gPSB0bXA7Cj4+ICsJCX0gZWxz ZSB7Cj4+ICsJCQl1aW50OF90IG9vYl9zdGVwID0gKGN0cmwtPmVjY19tb2RlIDw9IDI0KSA/Cj4+ ICsJCQkJCSAgIDY0IDogMTI4Owo+PiArCQkJY3RybC0+b29iX2J1ZltpICogb29iX3N0ZXAgLyA0 XSA9IHRtcDsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCW1lbWNweShjdHJsLT5wYWdlX2J1Ziwg YnVmLCBtdGQtPndyaXRlc2l6ZSk7Cj4+ICsJZG1hX2RhdGEgPSBya19uYW5kY19kbWFfbWFwX3Np bmdsZShtdGQtPmRldi5wYXJlbnQsCj4+ICsJCQkJCSAgIGN0cmwtPnBhZ2VfYnVmLCBtdGQtPndy aXRlc2l6ZSwKPj4gKwkJCQkJICAgRE1BX1RPX0RFVklDRSk7Cj4+ICsJZG1hX29vYiA9IHJrX25h bmRjX2RtYV9tYXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwKPj4gKwkJCQkJICBjdHJsLT5vb2Jf YnVmLCBkbWFfb29iX3NpemUsCj4+ICsJCQkJCSAgRE1BX1RPX0RFVklDRSk7Cj4+ICsJaW5pdF9j b21wbGV0aW9uKCZjdHJsLT5jb21wbGV0ZSk7Cj4+ICsJaWYgKGN0cmwtPnZlcnNpb24gPT0gVkVS U0lPTl85KQo+PiArCQl3cml0ZWwoTkFORENfVjlfSU5UX0RNQSwgY3RybC0+cmVncyArIE5BTkRD X1JFR19WOV9JTlRFTik7Cj4+ICsJZWxzZQo+PiArCQl3cml0ZWwoTkFORENfVjZfSU5UX0RNQSwg Y3RybC0+cmVncyArIE5BTkRDX1JFR19WNl9JTlRFTik7Cj4+ICsJcmtfbmFuZGNfeGZlcl9zdGFy dChjdHJsLCAxLCBlY2MtPnN0ZXBzLCBkbWFfZGF0YSwgZG1hX29vYik7Cj4+ICsJd2FpdF9mb3Jf Y29tcGxldGlvbl90aW1lb3V0KCZjdHJsLT5jb21wbGV0ZSwgbXNlY3NfdG9famlmZmllcygxMCkp Owo+PiArCXJrX25hbmRjX3dhaXRfZm9yX3hmZXJfZG9uZShjdHJsKTsKPj4gKwlya19uYW5kY19k bWFfdW5tYXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwgZG1hX2RhdGEsIG10ZC0+d3JpdGVzaXpl LAo+PiArCQkJCSAgRE1BX1RPX0RFVklDRSk7Cj4+ICsJcmtfbmFuZGNfZG1hX3VubWFwX3Npbmds ZShtdGQtPmRldi5wYXJlbnQsIGRtYV9vb2IsIGRtYV9vb2Jfc2l6ZSwKPj4gKwkJCQkgIERNQV9U T19ERVZJQ0UpOwo+PiArCj4+ICsJaWYgKGN0cmwtPmJvb3Ryb21ibG9ja3MpCj4+ICsJCXJrX25h bmRjX2h3X2VjY19zZXR1cChuYW5kLCBjdHJsLT5lY2NfbW9kZSk7Cj4+ICsKPj4gKwlyZXR1cm4g bmFuZF9wcm9nX3BhZ2VfZW5kX29wKG5hbmQpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJr X25hbmRjX2h3X2VjY19yZWFkX29vYihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBpbnQgcGFnZSkK Pj4gK3sKPj4gKwl1aW50OF90ICpidWYgPSBuYW5kX2dldF9kYXRhX2J1ZihuYW5kKTsKPj4gKwo+ PiArCXJldHVybiBuYW5kLT5lY2MucmVhZF9wYWdlKG5hbmQsIGJ1ZiwgdHJ1ZSwgcGFnZSk7Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfaHdfZWNjX3dyaXRlX29vYihzdHJ1Y3Qg bmFuZF9jaGlwICpuYW5kLCBpbnQgcGFnZSkKPj4gK3sKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10 ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+PiArCWludCByZXQ7Cj4+ICsJdWludDhfdCAqYnVmID0g bmFuZF9nZXRfZGF0YV9idWYobmFuZCk7Cj4+ICsKPj4gKwltZW1zZXQoYnVmLCAweEZGLCBtdGQt PndyaXRlc2l6ZSk7Cj4+ICsJcmV0ID0gbmFuZC0+ZWNjLndyaXRlX3BhZ2UobmFuZCwgYnVmLCB0 cnVlLCBwYWdlKTsKPj4gKwlpZiAocmV0KQo+PiArCQlyZXR1cm4gcmV0Owo+PiArCj4+ICsJcmV0 dXJuIG5hbmRfcHJvZ19wYWdlX2VuZF9vcChuYW5kKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZv aWQgcmtfbmFuZGNfcmVhZF9idWYoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgdWludDhfdCAqYnVm LAppbnQgbGVuKQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBu YW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsJaW50IG9mZnMgPSAwOwo+PiArCXZv aWQgX19pb21lbSAqYmFua19iYXNlID0gY3RybC0+cmVncyArIE5BTkRDX1JFR19CQU5LMCArCj4+ ICsJCQkJICBjdHJsLT5zZWxlY3RlZF9iYW5rICogMHgxMDA7Cj4KCj4gMHgxMDA6IE1heWJlIGEg ZGVmaW5lCgpPSywgYWdyZWUuCgo+Cj4+ICsKPj4gKwlmb3IgKG9mZnMgPSAwOyBvZmZzIDwgbGVu OyBvZmZzKyspCj4+ICsJCWJ1ZltvZmZzXSA9IHJlYWRiKGJhbmtfYmFzZSk7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyB2b2lkIHJrX25hbmRjX3dyaXRlX2J1ZihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k LAo+PiArCQkJICAgICAgIGNvbnN0IHVpbnQ4X3QgKmJ1ZiwgaW50IGxlbikKPj4gK3sKPj4gKwlz dHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRh KG5hbmQpOwo+PiArCWludCBvZmZzID0gMDsKPj4gKwl2b2lkIF9faW9tZW0gKmJhbmtfYmFzZSA9 IGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfQkFOSzAgKwo+PiArCQkJCSAgY3RybC0+c2VsZWN0ZWRf YmFuayAqIDB4MTAwOwo+PiArCj4+ICsJZm9yIChvZmZzID0gMDsgb2ZmcyA8IGxlbjsgb2Zmcysr KQo+PiArCQl3cml0ZWIoYnVmW29mZnNdLCBiYW5rX2Jhc2UpOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgdm9pZCBya19uYW5kY193cml0ZV9jbWQoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgdWludDhf dCBjbWQpCj4+ICt7Cj4+ICsJc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCA9IG5hbmRf Z2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPj4gKwo+PiArCXZvaWQgX19pb21lbSAqYmFua19i YXNlID0gY3RybC0+cmVncyArIE5BTkRDX1JFR19CQU5LMCArCj4+ICsJCQkJICBjdHJsLT5zZWxl Y3RlZF9iYW5rICogMHgxMDAgKwo+PiArCQkJCSAgTkFORENfUkVHX0NNRDsKPgoKPiBZb3UgbWln aHQgd2FudCB0byB3cml0ZSBhbiBoZWxwZXIgdG8gY2FsY3VsYXRlIGJhbmtfYmFzZSwgdG8gYXZv aWQKPiByZXBlYXRpbmcgdGhlc2UgbGluZXMuCgpFdmVuIHdpdGggYSBzZXBhcmF0ZSBkZWZpbmUg b3IgaGVscGVyIGZ1bmN0aW9uIEkgc3RpbGwgaGF2ZSB0byBzdXBwbHkKbXkgcmVnLCBzZWxlY3Rl ZF9iYW5rIGFuZCBvZmZzZXQuIEl0IGRvZXNuJ3QgbWFrZSB0aGluZ3MgY2xlYW5lciBwdW1waW5n CmRhdGUKdG8gYW5kIGZyb20gYSBoZWxwZXIgb3IgbmVpdGhlciBkb2Vzbid0IGl0IHNob3J0ZW4g bXkgc291cmNlIHdpdGggYSBkZWZpbmUuClRlbmQgdG8ga2VlcCBpdCBhcyBpdCBpcyBmb3Igbm93 LiBJZiB5b3UgYWdyZWUgb2YgY291cnNlLgoKPgo+PiArCj4+ICsJd3JpdGViKGNtZCwgYmFua19i YXNlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgcmtfbmFuZGNfd3JpdGVfYWRkcihzdHJ1 Y3QgbmFuZF9jaGlwICpuYW5kLCB1aW50OF90IGFkZHIpCj4+ICt7Cj4+ICsJc3RydWN0IHJrX25h bmRfY29udHJvbGxlciAqY3RybCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPj4g Kwo+PiArCXZvaWQgX19pb21lbSAqYmFua19iYXNlID0gY3RybC0+cmVncyArIE5BTkRDX1JFR19C QU5LMCArCj4+ICsJCQkJICBjdHJsLT5zZWxlY3RlZF9iYW5rICogMHgxMDAgKwo+PiArCQkJCSAg TkFORENfUkVHX0FERFI7Cj4+ICsKPj4gKwl3cml0ZWIoYWRkciwgYmFua19iYXNlKTsKPj4gK30K Pj4gKwo+PiArc3RhdGljIGludCBya19uYW5kY19kZXZfcmVhZHkoc3RydWN0IG5hbmRfY2hpcCAq bmFuZCkKPj4gK3sKPj4gKwlzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF9n ZXRfY29udHJvbGxlcl9kYXRhKG5hbmQpOwo+PiArCj4+ICsJaWYgKHJlYWRsKGN0cmwtPnJlZ3Mg KyBOQU5EQ19SRUdfVjZfRk1DVEwpICYgTkFORENfVjZfRk1fRlJFQURZKQo+PiArCQlyZXR1cm4g MTsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJrX25hbmRj X29vYmxheW91dF9lY2Moc3RydWN0IG10ZF9pbmZvICptdGQsIGludCBzZWN0aW9uLAo+PiArCQkJ CSAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2JyZWdpb24pCj4+ICt7Cj4+ICsJc3RydWN0IG5h bmRfY2hpcCAqbmFuZCA9IG10ZF90b19uYW5kKG10ZCk7Cj4+ICsKPj4gKwlpZiAoc2VjdGlvbiA+ PSBuYW5kLT5lY2Muc3RlcHMpCj4+ICsJCXJldHVybiAtRVJBTkdFOwo+PiArCj4+ICsJb29icmVn aW9uLT5vZmZzZXQgPSAobmFuZC0+ZWNjLmJ5dGVzICsgbmFuZC0+ZWNjLnByZXBhZCkgKiBzZWN0 aW9uICsKPj4gKwkJCSAgICBuYW5kLT5lY2MucHJlcGFkOwo+PiArCW9vYnJlZ2lvbi0+bGVuZ3Ro ID0gbmFuZC0+ZWNjLnN0ZXBzICogbmFuZC0+ZWNjLmJ5dGVzOwo+PiArCj4+ICsJcmV0dXJuIDA7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfb29ibGF5b3V0X2ZyZWUoc3RydWN0 IG10ZF9pbmZvICptdGQsIGludCBzZWN0aW9uLAo+PiArCQkJCSAgIHN0cnVjdCBtdGRfb29iX3Jl Z2lvbiAqb29icmVnaW9uKQo+PiArewo+PiArCXN0cnVjdCBuYW5kX2NoaXAgKm5hbmQgPSBtdGRf dG9fbmFuZChtdGQpOwo+PiArCj4+ICsJaWYgKHNlY3Rpb24gPj0gbmFuZC0+ZWNjLnN0ZXBzKQo+ PiArCQlyZXR1cm4gLUVSQU5HRTsKPj4gKwo+PiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0gKG5hbmQt PmVjYy5ieXRlcyArIG5hbmQtPmVjYy5wcmVwYWQpICogc2VjdGlvbjsKPj4gKwlvb2JyZWdpb24t Pmxlbmd0aCA9IG5hbmQtPmVjYy5zdGVwcyAqIG5hbmQtPmVjYy5wcmVwYWQ7Cj4+ICsKPj4gKwly ZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBtdGRfb29ibGF5b3V0 X29wcyBya19uYW5kY19vb2Jfb3BzID0gewo+PiArCS5lY2MgPSBya19uYW5kY19vb2JsYXlvdXRf ZWNjLAo+PiArCS5mcmVlID0gcmtfbmFuZGNfb29ibGF5b3V0X2ZyZWUsCj4+ICt9Owo+PiArCj4+ ICtzdGF0aWMgdm9pZCBya19uYW5kY19mcmVlX2J1ZmZlcihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k KQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9j b250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsKPj4gKwlrZnJlZShjdHJsLT5wYWdlX2J1Zik7Cj4+ ICsJa2ZyZWUoY3RybC0+b29iX2J1Zik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFu ZGNfYnVmZmVyX2luaXQoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCkKPj4gK3sKPj4gKwlzdHJ1Y3Qg bXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+PiArCXN0cnVjdCBya19uYW5kX2Nv bnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsKPj4g KwljdHJsLT5wYWdlX2J1ZiA9IGttYWxsb2MobXRkLT53cml0ZXNpemUsIEdGUF9LRVJORUwgfCBH RlBfRE1BKTsKPgoKPiBkZXZpY2UgbWFuYWdlZCBhbGxvY2F0aW9ucyAoZGV2bV8uLi4pIHdvdWxk IGJlIG5pY2UKCmRldm1fa3phbGxvYygpIG5lZWRzIGFuIGV4dHJhIHN0cnVjdCBkZXZpY2UuCkRv ZXMgTVREIHNhZmUtZ2FyZCB0aGUgY29ycmVjdCBvcmRlciB0byBkZXRhY2ggZnJvbSBzdHJ1Y3QK cmtfbmFuZF9jb250cm9sbGVyCndpdGhvdXQgcmtfbmFuZGNfZnJlZV9idWZmZXIoKT8KCj4KPj4g KwlpZiAoIWN0cmwtPnBhZ2VfYnVmKQo+PiArCQlyZXR1cm4gLUVOT01FTTsKPj4gKwo+PiArCWN0 cmwtPm9vYl9idWYgPSBrbWFsbG9jKG5hbmQtPmVjYy5zdGVwcyAqIDEyOCwgR0ZQX0tFUk5FTCB8 IEdGUF9ETUEpOwo+PiArCWlmICghY3RybC0+b29iX2J1Zikgewo+PiArCQlrZnJlZShjdHJsLT5w YWdlX2J1Zik7Cj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCX0KPj4gKwo+PiArCXJldHVybiAw Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJrX25hbmRjX2h3X2VjY19jdHJsX2luaXQoc3Ry dWN0IG5hbmRfY2hpcCAqbmFuZCkKPj4gK3sKPj4gKwl1aW50OF90IHN0cmVuZ3Roc192NltdID0g ezYwLCA0MCwgMjQsIDE2fTsKPj4gKwl1aW50OF90IHN0cmVuZ3Roc192OVtdID0gezcwLCA2MCwg NDAsIDE2fTsKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+ PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9jb250cm9sbGVy X2RhdGEobmFuZCk7Cj4+ICsJaW50IG1heF9zdHJlbmd0aDsKPj4gKwl1aW50MzJfdCBpLCB2ZXI7 Cj4+ICsKPj4gKwlpZiAobmFuZC0+b3B0aW9ucyAmIE5BTkRfSVNfQk9PVF9NRURJVU0pCj4+ICsJ CWN0cmwtPmJvb3Ryb21ibG9ja3MgPSB0cnVlOwo+PiArCWVsc2UKPj4gKwkJY3RybC0+Ym9vdHJv bWJsb2NrcyA9IGZhbHNlOwo+PiArCj4+ICsJbmFuZC0+ZWNjLnByZXBhZCA9IDQ7Cj4+ICsJbmFu ZC0+ZWNjLnN0ZXBzID0gbXRkLT53cml0ZXNpemUgLyBuYW5kLT5lY2Muc2l6ZTsKPj4gKwo+PiAr CW1heF9zdHJlbmd0aCA9ICgobXRkLT5vb2JzaXplIC8gbmFuZC0+ZWNjLnN0ZXBzKSAtIDQpICog OCAvIDE0Owo+PiArCWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiArCQljdHJs LT5tYXhfZWNjX3N0cmVuZ3RoID0gNzA7Cj4+ICsJCXZlciA9IHJlYWRsKGN0cmwtPnJlZ3MgKyBO QU5EQ19SRUdfVjlfVkVSKTsKPj4gKwkJaWYgKHZlciAhPSBOQU5EQ19JRF9WOTAwKQo+PiArCQkJ ZGV2X2VycihtdGQtPmRldi5wYXJlbnQsCj4+ICsJCQkJInVuc3VwcG9ydGVkIG5hbmRjIHZlcnNp b24gJXhcbiIsIHZlcik7Cj4+ICsKPj4gKwkJaWYgKG1heF9zdHJlbmd0aCA+IGN0cmwtPm1heF9l Y2Nfc3RyZW5ndGgpCj4+ICsJCQltYXhfc3RyZW5ndGggPSBjdHJsLT5tYXhfZWNjX3N0cmVuZ3Ro Owo+PiArCj4+ICsJCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHN0cmVuZ3Roc192OSk7IGkr Kykgewo+PiArCQkJaWYgKG1heF9zdHJlbmd0aCA+PSBzdHJlbmd0aHNfdjlbaV0pCj4+ICsJCQkJ YnJlYWs7Cj4+ICsJCX0KPj4gKwo+PiArCQlpZiAoaSA+PSBBUlJBWV9TSVpFKHN0cmVuZ3Roc192 OSkpIHsKPj4gKwkJCWRldl9lcnIobXRkLT5kZXYucGFyZW50LAo+PiArCQkJCSJ1bnN1cHBvcnRl ZCBzdHJlbmd0aFxuIik7Cj4+ICsJCQlyZXR1cm4gLUVOT1RTVVBQOwo+PiArCQl9Cj4+ICsKPj4g KwkJY3RybC0+ZWNjX21vZGUgPSBzdHJlbmd0aHNfdjlbaV07Cj4+ICsJfSBlbHNlIHsKPj4gKwkJ Y3RybC0+bWF4X2VjY19zdHJlbmd0aCA9IDYwOwo+PiArCj4+ICsJCXZlciA9IHJlYWRsKGN0cmwt PnJlZ3MgKyBOQU5EQ19SRUdfVjZfVkVSKTsKPj4gKwkJaWYgKHZlciA9PSBOQU5EQ19JRF9WODAx KQo+PiArCQkJY3RybC0+bWF4X2VjY19zdHJlbmd0aCA9IDE2Owo+PiArCQllbHNlIGlmICh2ZXIg PT0gTkFORENfSURfVjYwMCB8fAo+PiArCQkJIHZlciA9PSBOQU5EQ19JRF9WNjIyIHx8Cgo+PiAr CQkJIHZlciA9PSBOQU5EQ19JRF9WNzAxIHx8CgpBZGRlZCB2ZXJzaW9uIDcgZm9yIFJLMzIyOEEv UkszMjI4Qi4gQ2FuIHNvbWVvbmUgd2l0aCBpbnNpZGVyIGluZm8gY29uZmlybQppZiB0aGlzIHdv cmtzIG9yIG5vdC4KCj4+ICsJCQkgdmVyID09IE5BTkRDX0lEX1Y4MDApCj4+ICsJCQljdHJsLT5t YXhfZWNjX3N0cmVuZ3RoID0gNjA7Cj4+ICsJCWVsc2UKPj4gKwkJCWRldl9lcnIobXRkLT5kZXYu cGFyZW50LAo+PiArCQkJCSJ1bnN1cHBvcnRlZCBuYW5kYyB2ZXJzaW9uICV4XG4iLCB2ZXIpOwo+ PiArCj4+ICsJCWlmIChtYXhfc3RyZW5ndGggPiBjdHJsLT5tYXhfZWNjX3N0cmVuZ3RoKQo+PiAr CQkJbWF4X3N0cmVuZ3RoID0gY3RybC0+bWF4X2VjY19zdHJlbmd0aDsKPj4gKwo+PiArCQlmb3Ig KGkgPSAwOyBpIDwgQVJSQVlfU0laRShzdHJlbmd0aHNfdjYpOyBpKyspIHsKPj4gKwkJCWlmICht YXhfc3RyZW5ndGggPj0gc3RyZW5ndGhzX3Y2W2ldKQo+PiArCQkJCWJyZWFrOwo+PiArCQl9Cj4+ ICsKPj4gKwkJaWYgKGkgPj0gQVJSQVlfU0laRShzdHJlbmd0aHNfdjYpKSB7Cj4+ICsJCQlkZXZf ZXJyKG10ZC0+ZGV2LnBhcmVudCwKPj4gKwkJCQkidW5zdXBwb3J0ZWQgc3RyZW5ndGhcbiIpOwo+ PiArCQkJcmV0dXJuIC1FTk9UU1VQUDsKPj4gKwkJfQo+PiArCj4+ICsJCWN0cmwtPmVjY19tb2Rl ID0gc3RyZW5ndGhzX3Y2W2ldOwo+PiArCX0KPj4gKwlya19uYW5kY19od19lY2Nfc2V0dXAobmFu ZCwgY3RybC0+ZWNjX21vZGUpOwo+PiArCj4+ICsJbXRkX3NldF9vb2JsYXlvdXQobXRkLCAmcmtf bmFuZGNfb29iX29wcyk7Cj4+ICsKPj4gKwlpZiAobXRkLT5vb2JzaXplIDwgKChuYW5kLT5lY2Mu Ynl0ZXMgKyBuYW5kLT5lY2MucHJlcGFkKSAqCj4+ICsJCQkgICAgbmFuZC0+ZWNjLnN0ZXBzKSkg ewo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30K Pj4gKwo+PiArc3RhdGljIHZvaWQgcmtfbmFuZGNfZGV0YWNoX2NoaXAoc3RydWN0IG5hbmRfY2hp cCAqbmFuZCkKPj4gK3sKPj4gKwlzd2l0Y2ggKG5hbmQtPmVjYy5tb2RlKSB7Cj4+ICsJY2FzZSBO QU5EX0VDQ19IV19TWU5EUk9NRToKPj4gKwkJcmtfbmFuZGNfZnJlZV9idWZmZXIobmFuZCk7Cj4+ ICsJCWJyZWFrOwo+PiArCWRlZmF1bHQ6Cj4+ICsJCWJyZWFrOwo+PiArCX0KPj4gK30KPj4gKwo+ PiArc3RhdGljIGludCBya19uYW5kY19hdHRhY2hfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k KQo+PiArewo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4+ ICsJaW50IHJldDsKPj4gKwo+PiArCXN3aXRjaCAobmFuZC0+ZWNjLm1vZGUpIHsKPj4gKwljYXNl IE5BTkRfRUNDX0hXX1NZTkRST01FOgo+PiArCQlyZXQgPSBya19uYW5kY19od19lY2NfY3RybF9p bml0KG5hbmQpOwo+PiArCQlpZiAocmV0KQo+PiArCQkJcmV0dXJuIHJldDsKPj4gKwkJcmV0ID0g cmtfbmFuZGNfYnVmZmVyX2luaXQobmFuZCk7Cj4+ICsJCWlmIChyZXQpCj4+ICsJCQlyZXR1cm4g LUVOT01FTTsKPj4gKwkJbmFuZC0+ZWNjLnJlYWRfcGFnZSA9IHJrX25hbmRjX2h3X3N5bmRyb21l X2VjY19yZWFkX3BhZ2U7Cj4+ICsJCW5hbmQtPmVjYy53cml0ZV9wYWdlID0gcmtfbmFuZGNfaHdf c3luZHJvbWVfZWNjX3dyaXRlX3BhZ2U7Cj4+ICsJCW5hbmQtPmVjYy5yZWFkX29vYiA9IHJrX25h bmRjX2h3X2VjY19yZWFkX29vYjsKPj4gKwkJbmFuZC0+ZWNjLndyaXRlX29vYiA9IHJrX25hbmRj X2h3X2VjY193cml0ZV9vb2I7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgTkFORF9FQ0NfSFc6Cj4K PiBJIHdvdWxkIGVpdGhlciByZWZ1c2UgRUNDX0hXIG9yIHB1dCBpdCBiZXNpZGVzIEhXX1NZTkRS T01FLgoKSXMgdGhlcmUgYSBmdW5kYW1lbnRhbCBkaWZmZXJlbmNlIGluIGhhbmRsaW5nIEVDQ19I VyBhbmQgSFdfU1lORFJPTUUKZnJvbSB0aGUgTVREIHBvaW50IG9mIHZpZXc/IE90aGVyIHRoZW4g YSBpbmRpY2F0aW9uIGhvdyBpdCdzIGRvbmUgb24KdGhlIGRyaXZlciBzaWRlPwpXaWxsIGRyb3Ag aXQuCgo+Cj4+ICsJY2FzZSBOQU5EX0VDQ19OT05FOgo+PiArCWNhc2UgTkFORF9FQ0NfU09GVDoK PgoKPiBIYXZlIHlvdSB0ZXN0ZWQgd2l0aCBTVyBCQ0g/CgpTaG9ydCBhbnN3ZXI6IE5vCkp1c3Qg Y29waWVkIGl0IGZyb20gdGhlIG9yaWdpbmFsLgpQbGVhc2UgYWR2aXNlIGEgdG9vbCB0byBkbyBh IHRlc3QgYmV0d2VlbiB0aGUgaW5kaXZpZHVhbCBlY2MgcmVhZCBvcHRpb25zLgpPciBkbyBJIGhh dmUgdG8gd3JpdGUgdGhlIHRvb2wgbXkgc2VsZiB3aXRoIG10ZC11dGlscz8KCj4KPj4gKwkJYnJl YWs7Cj4+ICsJZGVmYXVsdDoKPj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJ cmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfZXhlY19vcChzdHJ1 Y3QgbmFuZF9jaGlwICpuYW5kLAo+PiArCQkJICAgIGNvbnN0IHN0cnVjdCBuYW5kX29wZXJhdGlv biAqb3AsCj4+ICsJCQkgICAgYm9vbCBjaGVja19vbmx5KQo+PiArewo+PiArCWludCBpOwo+PiAr CXVuc2lnbmVkIGludCBvcF9pZDsKPj4gKwljb25zdCBzdHJ1Y3QgbmFuZF9vcF9pbnN0ciAqaW5z dHIgPSBOVUxMOwo+PiArCj4+ICsJcmtfbmFuZGNfc2VsZWN0X2NoaXAobmFuZCwgb3AtPmNzKTsK Pj4gKwo+PiArCWlmIChjaGVja19vbmx5KQo+PiArCQlyZXR1cm4gMDsKPj4gKwo+PiArCWZvciAo b3BfaWQgPSAwOyBvcF9pZCA8IG9wLT5uaW5zdHJzOyBvcF9pZCsrKSB7Cj4+ICsJCWluc3RyID0g Jm9wLT5pbnN0cnNbb3BfaWRdOwo+PiArCj4+ICsJCXN3aXRjaCAoaW5zdHItPnR5cGUpIHsKPj4g KwkJY2FzZSBOQU5EX09QX0NNRF9JTlNUUjoKPj4gKwkJCXJrX25hbmRjX3dyaXRlX2NtZChuYW5k LCBpbnN0ci0+Y3R4LmNtZC5vcGNvZGUpOwo+PiArCQkJYnJlYWs7Cj4+ICsJCWNhc2UgTkFORF9P UF9BRERSX0lOU1RSOgo+PiArCQkJZm9yIChpID0gMDsgaSA8IGluc3RyLT5jdHguYWRkci5uYWRk cnM7IGkrKykKPj4gKwkJCQlya19uYW5kY193cml0ZV9hZGRyKG5hbmQsCj4+ICsJCQkJCQkgICAg aW5zdHItPmN0eC5hZGRyLmFkZHJzW2ldKTsKPj4gKwkJCWJyZWFrOwo+PiArCQljYXNlIE5BTkRf T1BfREFUQV9JTl9JTlNUUjoKPj4gKwkJCXJrX25hbmRjX3JlYWRfYnVmKG5hbmQsIGluc3RyLT5j dHguZGF0YS5idWYuaW4sCj4+ICsJCQkJCSAgaW5zdHItPmN0eC5kYXRhLmxlbik7Cj4+ICsJCQli cmVhazsKPj4gKwkJY2FzZSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSOgo+PiArCQkJcmtfbmFuZGNf d3JpdGVfYnVmKG5hbmQsIGluc3RyLT5jdHguZGF0YS5idWYub3V0LAo+PiArCQkJCQkgICBpbnN0 ci0+Y3R4LmRhdGEubGVuKTsKPj4gKwkJCWJyZWFrOwo+PiArCQljYXNlIE5BTkRfT1BfV0FJVFJE WV9JTlNUUjoKPj4gKwkJCXJrX25hbmRjX2Rldl9yZWFkeShuYW5kKTsKPj4gKwkJCWJyZWFrOwo+ PiArCQl9Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBj b25zdCBzdHJ1Y3QgbmFuZF9jb250cm9sbGVyX29wcyBya19uYW5kX2NvbnRyb2xsZXJfb3BzID0g ewo+PiArCS5hdHRhY2hfY2hpcCA9IHJrX25hbmRjX2F0dGFjaF9jaGlwLAo+PiArCS5kZXRhY2hf Y2hpcCA9IHJrX25hbmRjX2RldGFjaF9jaGlwLAo+PiArCS5leGVjX29wID0gcmtfbmFuZGNfZXhl Y19vcCwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfY2hpcF9pbml0KHN0cnVj dCBkZXZpY2UgKmRldiwKPj4gKwkJCSAgICAgIHN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0 cmwsCj4+ICsJCQkgICAgICBzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wLCB1bnNpZ25lZCBpbnQgY2hp cG5yKQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NoaXAgKm5vZGU7Cj4+ICsJc3RydWN0IG5h bmRfY2hpcCAqbmFuZDsKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZDsKPj4gKwljb25zdCBfX2Jl MzIgKnJlZzsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJcmVnID0gb2ZfZ2V0X3Byb3BlcnR5KG5w LCAicmVnIiwgTlVMTCk7Cj4+ICsJaWYgKCFyZWcpCj4+ICsJCXJldHVybiAtRUlOVkFMOwo+PiAr Cj4+ICsJY3RybC0+YmFua3NbY2hpcG5yXSA9IGJlMzJfdG9fY3B1KCpyZWcpOwo+PiArCj4+ICsJ aWYgKGN0cmwtPmJhbmtzW2NoaXBucl0gPCAwKQo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwo+ PiArCW5vZGUgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKm5vZGUpLCBHRlBfS0VSTkVMKTsK Pj4gKwlpZiAoIW5vZGUpCj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCj4+ICsJbmFuZCA9ICZu b2RlLT5uYW5kOwo+PiArCj4+ICsJbmFuZF9zZXRfZmxhc2hfbm9kZShuYW5kLCBucCk7Cj4+ICsJ bmFuZF9zZXRfY29udHJvbGxlcl9kYXRhKG5hbmQsIGN0cmwpOwo+PiArCj4+ICsJbmFuZC0+Y29u dHJvbGxlciA9ICZjdHJsLT5jb250cm9sbGVyOwo+PiArCW5hbmQtPmNvbnRyb2xsZXItPm9wcyA9 ICZya19uYW5kX2NvbnRyb2xsZXJfb3BzOwo+PiArCj4+ICsJbmFuZC0+ZWNjLm1vZGUgPSBOQU5E X0VDQ19IV19TWU5EUk9NRTsKPj4gKwluYW5kLT5lY2Muc2l6ZSA9IDEwMjQ7Cj4+ICsJbmFuZC0+ ZWNjLnN0cmVuZ3RoID0gNDA7Cj4+ICsKPj4gKwluYW5kLT5vcHRpb25zID0gTkFORF9TS0lQX0JC VFNDQU4gfCBOQU5EX05PX1NVQlBBR0VfV1JJVEU7Cj4+ICsKPj4gKwltdGQgPSBuYW5kX3RvX210 ZChuYW5kKTsKPj4gKwltdGQtPmRldi5wYXJlbnQgPSBkZXY7Cj4+ICsJbXRkLT5uYW1lID0gZGV2 bV9rYXNwcmludGYoZGV2LCBHRlBfS0VSTkVMLCAiJXMuJWQiLCBkZXZfbmFtZShkZXYpLAo+PiAr CQkJCSAgIGN0cmwtPmJhbmtzW2NoaXBucl0pOwo+PiArCj4+ICsJcmV0ID0gbmFuZF9zY2FuKG5h bmQsIDEpOwo+Cj4gV2h5IDEgaGVyZT8KClRPRE8gZm9yIHZlcnNpb24gMi4KQSBsaXR0bGUgbWlz dW5kZXJzdGFuZGluZyBvbiBob3cgZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZSB3b3Jrcy4KQWxsIGNo aXBzIHNob3VsZCBiZSBzY2FubmVkLgovLy8vLwpEZXJpdmUgY2hpcG5yCkV4YW1wbGUgZnJvbSBz dW54aV9uYW5kLmMKCglpZiAoIW9mX2dldF9wcm9wZXJ0eShucCwgInJlZyIsICZuc2VscykpCgkJ cmV0dXJuIC1FSU5WQUw7CgoJbnNlbHMgLz0gc2l6ZW9mKHUzMik7CglpZiAoIW5zZWxzKSB7CgkJ ZGV2X2VycihkZXYsICJpbnZhbGlkIHJlZyBwcm9wZXJ0eSBzaXplXG4iKTsKCQlyZXR1cm4gLUVJ TlZBTDsKCX0KLy8vLy8KRnJvbSBya19uYW5kY19jaGlwc19pbml0KCkKCglmb3JfZWFjaF9jaGls ZF9vZl9ub2RlKG5wLCBuYW5kX25wKSB7CgkJcmV0ID0gcmtfbmFuZGNfY2hpcF9pbml0KGRldiwg Y3RybCwgbmFuZF9ucCwgaSk7CgpXaHkgZG9lcyBzdW54aV9uYW5kLmMgbmVlZCB0aGlzIGV4dHJh IGZvcl9lYWNoX2NoaWxkX29mX25vZGU/Cgo+Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuIHJl dDsKPj4gKwo+PiArCXJldCA9IG10ZF9kZXZpY2VfcmVnaXN0ZXIobXRkLCBOVUxMLCAwKTsKPj4g KwlpZiAocmV0KSB7Cj4+ICsJCWRldl9lcnIoZGV2LCAibXRkIGRldmljZSByZWdpc3RlciBmYWls ZWQ6ICVkXG4iLCByZXQpOwo+PiArCQluYW5kX3JlbGVhc2UobmFuZCk7Cj4+ICsJCXJldHVybiBy ZXQ7Cj4+ICsJfQo+PiArCj4+ICsJbGlzdF9hZGRfdGFpbCgmbm9kZS0+Y2hpcF9saXN0LCAmY3Ry bC0+Y2hpcHMpOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQg cmtfbmFuZGNfY2xlYW51cF9jaGlwcyhzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsKQo+ PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NoaXAgKm5vZGU7Cj4+ICsJc3RydWN0IG10ZF9pbmZv ICptdGQ7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXdoaWxlICghbGlzdF9lbXB0eSgmY3RybC0+ Y2hpcHMpKSB7Cj4+ICsJCW5vZGUgPSBsaXN0X2ZpcnN0X2VudHJ5KCZjdHJsLT5jaGlwcywgc3Ry dWN0IHJrX25hbmRfY2hpcCwKPj4gKwkJCQkJY2hpcF9saXN0KTsKPj4gKwkJbXRkID0gbmFuZF90 b19tdGQoJm5vZGUtPm5hbmQpOwo+PiArCQlyZXQgPSBtdGRfZGV2aWNlX3VucmVnaXN0ZXIobXRk KTsKPj4gKwkJaWYgKHJldCkKPj4gKwkJCXJldHVybiByZXQ7Cj4+ICsKPj4gKwkJcmtfbmFuZGNf ZnJlZV9idWZmZXIoJm5vZGUtPm5hbmQpOwo+PiArCQluYW5kX2NsZWFudXAoJm5vZGUtPm5hbmQp Owo+PiArCQlsaXN0X2RlbCgmbm9kZS0+Y2hpcF9saXN0KTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1 cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBya19uYW5kY19jaGlwc19pbml0KHN0cnVj dCBkZXZpY2UgKmRldiwKPj4gKwkJCSAgICAgICBzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpj dHJsKQo+PiArewo+PiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBkZXYtPm9mX25vZGU7Cj4+ ICsJc3RydWN0IGRldmljZV9ub2RlICpuYW5kX25wOwo+PiArCWludCBuY2hpcHMgPSBvZl9nZXRf Y2hpbGRfY291bnQobnApOwo+PiArCWludCBpID0gMDsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJ aWYgKG5jaGlwcyA+IE5BTkRDX05VTV9CQU5LUykgewo+PiArCQlkZXZfZXJyKGRldiwgInRvbyBt YW55IE5BTkQgY2hpcHM6ICVkIChtYXggPSA0KVxuIiwgbmNoaXBzKTsKPj4gKwkJcmV0dXJuIC1F SU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShucCwgbmFuZF9u cCkgewo+PiArCQlyZXQgPSBya19uYW5kY19jaGlwX2luaXQoZGV2LCBjdHJsLCBuYW5kX25wLCBp KTsKPj4gKwkJaWYgKHJldCkgewo+PiArCQkJcmtfbmFuZGNfY2xlYW51cF9jaGlwcyhjdHJsKTsK Pj4gKwkJCW9mX25vZGVfcHV0KG5hbmRfbnApOwo+PiArCQkJcmV0dXJuIHJldDsKPj4gKwkJfQo+ PiArCQlpKys7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRp YyBpbnQgcmtfbmFuZGNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sK Pj4gKwljb25zdCBzdHJ1Y3QgcmtfbmFuZGNfZGF0YSAqZGF0YTsKPj4gKwlzdHJ1Y3QgZGV2aWNl ICpkZXYgPSAmcGRldi0+ZGV2Owo+PiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbm9kZTsKPj4gKwlp bnQgaWQ7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCWRhdGEgPSBvZl9kZXZpY2VfZ2V0X21hdGNo X2RhdGEoJnBkZXYtPmRldik7Cj4+ICsJaWYgKCFkYXRhKQo+PiArCQlyZXR1cm4gLUVOT0RFVjsK Pj4gKwoKPj4gKwlub2RlID0gcGRldi0+ZGV2Lm9mX25vZGU7Cj4+ICsKPj4gKwlpZCA9IG9mX2Fs aWFzX2dldF9pZChub2RlLCAibmFuZGMiKTsKPj4gKwlpZiAoaWQgPCAwKQo+PiArCQlpZCA9IGdf aWRfY291bnRlcjsKPj4gKwlpZiAoKGlkID49IEFSUkFZX1NJWkUoZ19uYW5kY19pbmZvKSB8fCBn X25hbmRjX2luZm9baWRdLnJlZ3MpKSB7Cj4+ICsJCWRldl9lcnIoCj4+ICsJCQkmcGRldi0+ZGV2 LAo+PiArCQkJImZhaWxlZCB0byBnZXQgaWQgZm9yIG5hbmRjIG5vZGUgJyVwT0ZuJ1xuIiwKPj4g KwkJCW5vZGUpOwo+PiArCQlvZl9ub2RlX3B1dChub2RlKTsKPj4gKwkJcmV0dXJuIC1FTk9ERVY7 Cj4+ICsJfQo+PiArCSsrZ19pZF9jb3VudGVyOwoKU2VlIGNvbW1lbnRzIGFib3ZlIGFib3V0IFJr MzI4OC4gS2VlcGluZyB0cmFjayBub2RlIGFsaWFzIGZvciBuYW5kYzAuClRvIHJlbW92ZSBvciBu b3Q/Cgo+PiArCj4+ICsJZ19uYW5kY19pbmZvW2lkXS52ZXJzaW9uID0gZGF0YS0+dmVyc2lvbjsK Pj4gKwo+PiArCWdfbmFuZGNfaW5mb1tpZF0ucmVncyA9IGRldm1fcGxhdGZvcm1faW9yZW1hcF9y ZXNvdXJjZShwZGV2LCAwKTsKPj4gKwlpZiAoSVNfRVJSKGdfbmFuZGNfaW5mb1tpZF0ucmVncykp IHsKPj4gKwkJZGV2X2VycihkZXYsICJpb3JlbWFwIGZhaWxlZFxuIik7Cj4+ICsJCXJldHVybiBQ VFJfRVJSKGdfbmFuZGNfaW5mb1tpZF0ucmVncyk7Cj4+ICsJfQo+PiArCj4+ICsJZ19uYW5kY19p bmZvW2lkXS5pcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwo+PiArCWlmIChnX25hbmRj X2luZm9baWRdLmlycSA8IDApIHsKPj4gKwkJZGV2X2VycihkZXYsICJnZXQgaXJxIGZhaWxlZFxu Iik7Cj4+ICsJCXJldHVybiBnX25hbmRjX2luZm9baWRdLmlycTsKPj4gKwl9Cj4+ICsKPj4gKwln X25hbmRjX2luZm9baWRdLmhjbGsgPSBkZXZtX2Nsa19nZXQoZGV2LCAiaGNsa19uYW5kYyIpOwo+ PiArCWlmIChJU19FUlIoZ19uYW5kY19pbmZvW2lkXS5oY2xrKSkgewo+PiArCQlkZXZfZXJyKGRl diwgImdldCBoY2xrX25hbmRjIGZhaWxlZFxuIik7Cj4+ICsJCXJldHVybiBQVFJfRVJSKGdfbmFu ZGNfaW5mb1tpZF0uaGNsayk7Cj4+ICsJfQo+PiArCj4+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5h YmxlKGdfbmFuZGNfaW5mb1tpZF0uaGNsayk7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuIHJl dDsKPj4gKwo+PiArCWdfbmFuZGNfaW5mb1tpZF0uY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgImNs a19uYW5kYyIpOwo+PiArCWlmICghKElTX0VSUihnX25hbmRjX2luZm9baWRdLmNsaykpKSB7Cj4+ ICsJCWNsa19zZXRfcmF0ZShnX25hbmRjX2luZm9baWRdLmNsaywgMTUwICogMTAwMCAqIDEwMDAp Owo+PiArCj4+ICsJCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShnX25hbmRjX2luZm9baWRdLmNs ayk7Cj4+ICsJCWlmIChyZXQpCj4+ICsJCQlnb3RvIGVycl9kaXNhYmxlX2hjbGs7Cj4+ICsJfSBl bHNlCj4+ICsJCWRldl9lcnIoZGV2LCAiZ2V0IGNsa19uYW5kYyBmYWlsZWRcbiIpOwo+PiArCj4+ ICsJaWYgKGdfbmFuZGNfaW5mb1tpZF0udmVyc2lvbiA9PSBWRVJTSU9OXzkpCj4+ICsJCXdyaXRl bCgwLCBnX25hbmRjX2luZm9baWRdLnJlZ3MgKyBOQU5EQ19SRUdfVjlfSU5URU4pOwo+PiArCWVs c2UKPj4gKwkJd3JpdGVsKDAsIGdfbmFuZGNfaW5mb1tpZF0ucmVncyArIE5BTkRDX1JFR19WNl9J TlRFTik7Cj4+ICsJcmV0ID0gZGV2bV9yZXF1ZXN0X2lycShkZXYsIGdfbmFuZGNfaW5mb1tpZF0u aXJxLCBya19uYW5kY19pbnRlcnJ1cHQsCj4+ICsJCQkgICAgICAgMCwgIm5hbmRjIiwgJmdfbmFu ZGNfaW5mb1tpZF0pOwo+PiArCWlmIChyZXQpCj4+ICsJCWdvdG8gZXJyX2Rpc2FibGVfY2xrOwo+ PiArCj4+ICsJbmFuZF9jb250cm9sbGVyX2luaXQoJmdfbmFuZGNfaW5mb1tpZF0uY29udHJvbGxl cik7Cj4+ICsJSU5JVF9MSVNUX0hFQUQoJmdfbmFuZGNfaW5mb1tpZF0uY2hpcHMpOwo+PiArCj4+ ICsJcmtfbmFuZGNfaW5pdCgmZ19uYW5kY19pbmZvW2lkXSk7Cj4+ICsKPj4gKwlyZXQgPSBya19u YW5kY19jaGlwc19pbml0KGRldiwgJmdfbmFuZGNfaW5mb1tpZF0pOwo+PiArCWlmIChyZXQpIHsK Pj4gKwkJZGV2X2VycihkZXYsICJpbml0IG5hbmQgY2hpcHMgZmFpbGVkXG4iKTsKPj4gKwkJZ290 byBlcnJfZGlzYWJsZV9jbGs7Cj4+ICsJfQo+PiArCj4+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEo cGRldiwgJmdfbmFuZGNfaW5mb1tpZF0pOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICsKPj4gK2Vy cl9kaXNhYmxlX2NsazoKPj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUoZ19uYW5kY19pbmZvW2lk XS5jbGspOwo+PiArZXJyX2Rpc2FibGVfaGNsazoKPj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUo Z19uYW5kY19pbmZvW2lkXS5oY2xrKTsKPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4+ICt7Cj4+ICsJc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCA9IHBsYXRmb3Jt X2dldF9kcnZkYXRhKHBkZXYpOwo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwlyZXQgPSBya19uYW5k Y19jbGVhbnVwX2NoaXBzKGN0cmwpOwo+PiArCWlmIChyZXQpCj4+ICsJCXJldHVybiByZXQ7Cj4+ ICsKPj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUoY3RybC0+Y2xrKTsKPj4gKwljbGtfZGlzYWJs ZV91bnByZXBhcmUoY3RybC0+aGNsayk7Cj4+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwg TlVMTCk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgcmtf bmFuZGNfc2h1dGRvd24oc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sKPj4gKwlz dHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRl dik7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXJldCA9IHJrX25hbmRjX2NsZWFudXBfY2hpcHMo Y3RybCk7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuOwo+PiArCj4+ICsJY2xrX2Rpc2FibGVf dW5wcmVwYXJlKGN0cmwtPmNsayk7Cj4+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGN0cmwtPmhj bGspOwo+PiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIE5VTEwpOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJrX25hbmRjX2RhdGEgcmtfbmFuZGNfdjZfZGF0YSA9IHsK Pj4gKwkudmVyc2lvbiA9IFZFUlNJT05fNiwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgcmtfbmFuZGNfZGF0YSBya19uYW5kY192OV9kYXRhID0gewo+PiArCS52ZXJzaW9uID0g VkVSU0lPTl85LAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2Vf aWQgb2ZfcmtfbmFuZGNfbWF0Y2hbXSA9IHsKCgo+PiArCXsKPj4gKwkJLmNvbXBhdGlibGUgPSAi cm9ja2NoaXAsbmFuZGMtdjYiLAo+PiArCQkuZGF0YSA9ICZya19uYW5kY192Nl9kYXRhLAo+PiAr CX0sCj4+ICsJewo+PiArCQkuY29tcGF0aWJsZSA9ICJyb2NrY2hpcCxuYW5kYy12OSIsCj4+ICsJ CS5kYXRhID0gJnJrX25hbmRjX3Y5X2RhdGEsCj4+ICsJfSwKCkFnYWluIHRvIHByZXZlbnQgZ3Vl c3NpbmcgZ2FtZXMgcGxlYXNlIGFkdmlzZQppZiAicm9ja2NoaXAsbmFuZGMtdjYiIGFuZCAicm9j a2NoaXAsbmFuZGMtdjkiIGFyZSBjb3JyZWN0IG9yCnN0YXRlIHRoZSBkZXNpcmVkIGNvbXBhdGli bGUgc3RyaW5ncy4KCj4+ICsJeyAvKiBzZW50aW5lbCAqLyB9LAo+PiArfTsKPj4gKwo+PiArc3Rh dGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgcmtfbmFuZGNfZHJpdmVyID0gewo+PiArCS5wcm9i ZSAgPSBya19uYW5kY19wcm9iZSwKPj4gKwkucmVtb3ZlID0gcmtfbmFuZGNfcmVtb3ZlLAo+PiAr CS5zaHV0ZG93biA9IHJrX25hbmRjX3NodXRkb3duLAo+PiArCS5kcml2ZXIgPSB7Cj4+ICsJCS5u YW1lID0gInJvY2tjaGlwLW5hbmRjIiwKPj4gKwkJLm9mX21hdGNoX3RhYmxlID0gb2ZfcmtfbmFu ZGNfbWF0Y2gsCj4+ICsJfSwKPj4gK307Cj4+ICsKPgo+IE1vdmUgdGhpcyBlbXB0eSBsaW5lLi4u Cj4KPj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIocmtfbmFuZGNfZHJpdmVyKTsKPgo+IC4uLkhl cmUKPgo+PiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+Cj4gVGhhbmtzLAo+IE1pcXXDqGwK PgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovLyBTUERYLUxpY2Vuc2UtSWRl bnRpZmllcjogR1BMLTIuMAovKgogKiBDb3B5cmlnaHQgKGMpIDIwMTksIEpvaGFuIEpvbmtlciA8 amJ4NjI0NEBnbWFpbC5jb20+CiAqCiAqIEJhc2VkIG9uOgogKgpodHRwczovL2dpdGh1Yi5jb20v cm9ja2NoaXAtbGludXgva2VybmVsL2Jsb2IvZGV2ZWxvcC00LjQvZHJpdmVycy9ya19uYW5kL3Jr X2Z0bF9hcm1fdjcuUwogKgpodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcm9ja2No aXAtbGludXgva2VybmVsL2RldmVsb3AtNC40L2RyaXZlcnMvcmtfbmFuZC9ya19mdGxfYXJtX3Y3 LlMKICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTgsIEZ1emhvdSBSb2NrY2hpcCBFbGVjdHJvbmlj cyBDby4sIEx0ZAogKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsKICoKICoKaHR0 cHM6Ly9naXRodWIuY29tL3JvY2tjaGlwLWxpbnV4L3UtYm9vdC9ibG9iL25leHQtZGV2L2RyaXZl cnMvcmtuYW5kL3JrX2Z0bF9hcm1fdjcuUwogKgpodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVu dC5jb20vcm9ja2NoaXAtbGludXgvdS1ib290L25leHQtZGV2L2RyaXZlcnMvcmtuYW5kL3JrX2Z0 bF9hcm1fdjcuUwogKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCwgRnV6aG91IFJvY2tjaGlwIEVs ZWN0cm9uaWNzIENvLiwgTHRkCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wKwog KgogKiBodHRwczovL2dpdGh1Yi5jb20vcm9ja2NoaXAtbGludXgvcmtkZXZlbG9wdG9vbC9ibG9i L21hc3Rlci9jcmMuY3BwCiAqIENvcHlyaWdodCAoYykgMjAxNyBGdXpob3UgUm9ja2NoaXAgRWxl Y3Ryb25pY3MgQ28uLCBMdGQKICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjArCiAq LwoKZW51bSBOQU5EX1RBRyB7CglJRF9JREJUID0gMHhFRkYwLAoJSURfVk5EUiA9IDB4RjA4NiwK CUlEX1NCRlggPSAweEYwOTUsCglJRF9TWVNCID0gMHhGMEE0LAoJSURfTDJQTSA9IDB4RjBDMiwK CUlEX0JCVEIgPSAweEYwRDEsCglJRF9CQlRGID0gMHhGMEUwLAoJSURfUkdNUCA9IDB4RkFGNSwK CUlEX1hYWFcgPSAweEZGRkYsCglJRF9TQlRHID0gMHgxMjM0NTY3OCwKCUlEX0NIQ0sgPSAweDEy MzQ4NzY1LAoJSURfQlRDRSA9IDB4NDI1NDQzNDUsCglJRF9GVExTID0gMHg0NjU0NEM1MywKCUlE X0hBU0ggPSAweDQ3QzZBN0U2LAoJSURfTkFORCA9IDB4NEU0MTRFNDQsCglJRF9WUENUID0gMHg1 MDAwMDA1NiwKCUlEX0lEUlcgPSAweEZDREM4QzNCLAoJSURfWFhYRCA9IDB4RkZGRkZGRkYsCn07 CgpzdHJ1Y3QgX19hdHRyaWJ1dGVfXygoYWxpZ25lZCg0KSkpIHRhZ0ZsYXNoU2F2ZUluZm8gewoJ dWludDMyX3QgSWQ7Cgl1aW50MzJfdCBTaXplOwoJdWludDMyX3QgSlNIYXNoOwoJdWludDE2X3Qg Z05hbmRNYXhEaWU7Cgl1aW50MTZfdCBnTmFuZElEQlJlc0Jsa051bTsKCXVpbnQ2NF90IElEQnl0 ZVs4XTsKCXVpbnQxNl90IERpZUNzSW5kZXhbOF07Cgl1aW50NjRfdCBEaWVBZGRyc1s4XTsKCXVp bnQzMl90IGdOYW5kUGFyYUluZm9bOF07Cgl1aW50MzJfdCBnTmFuZE9wdFBhcmFbOF07Cgl1aW50 OF90IGdSZWFkUmV0cnlJbmZvWzg1Ml07Cgl1aW50MzJfdCBnRmxhc2hUb2dnbGVNb2RlRW47Cn07 CgpzdHJ1Y3QgX19hdHRyaWJ1dGVfXygoYWxpZ25lZCgyKSkpIHRhZ05hbmRPcHRQYXJhIHsKCXVp bnQ4X3QgcmVzMVs4XTsKCXVpbnQ4X3QgU3RhcnREcENtZDsKCXVpbnQ4X3QgRW5kRHBDbWQ7Cgl1 aW50OF90IERwRmlyc3RDbWQ7Cgl1aW50OF90IERwU2Vjb25kQ21kOwoJdWludDhfdCByZXM2OwoJ dWludDhfdCBjbWQyOwoJdWludDhfdCBjbWQxOwoJdWludDhfdCBtYXg7Cgl1aW50OF90IG9wdGlv bjsKCXVpbnQ4X3QgcmVzMTFbMTVdOwp9OwoKc3RydWN0IF9fYXR0cmlidXRlX18oKGFsaWduZWQo MikpKSB0YWdOYW5kUGFyYUluZm8gewoJdWludDhfdCBpZF9ieXRlczsKCXVpbnQ4X3QgbmFuZF9p ZFs2XTsKCXVpbnQ4X3QgdmVuZG9yOwoJdWludDhfdCBkaWVfcGVyX2NoaXA7Cgl1aW50OF90IHNl Y19wZXJfcGFnZTsKCXVpbnQxNl90IHBhZ2VfcGVyX2JsazsKCXVpbnQ4X3QgY2VsbDsKCXVpbnQ4 X3QgcGxhbmVfcGVyX2RpZTsKCXVpbnQxNl90IGJsa19wZXJfcGxhbmU7Cgl1aW50MTZfdCBvcGVy YXRpb25fb3B0OwoJdWludDhfdCBsc2JfbW9kZTsKCXVpbnQ4X3QgcmVhZF9yZXRyeV9tb2RlOwoJ dWludDhfdCBlY2NfYml0czsKCXVpbnQ4X3QgYWNjZXNzX2ZyZXE7Cgl1aW50OF90IG9wdF9tb2Rl OwoJdWludDhfdCBkaWVfZ2FwOwoJdWludDhfdCBiYWRfYmxvY2tfbW9kZTsKCXVpbnQ4X3QgbXVs dGlfcGxhbmVfbW9kZTsKCXVpbnQ4X3Qgc2xjX21vZGU7Cgl1aW50OF90IHJlc2VydmVkWzVdOwp9 OwoKc3RydWN0IF9fYXR0cmlidXRlX18oKGFsaWduZWQoNCkpKSB0YWdOYW5kUGh5SW5mbyB7Cgl1 aW50MzJfdCBjaGlwX2lkOwoJdWludDMyX3QgdmVuZG9yOwoJdWludDE2X3QgbmFuZF90eXBlOwoJ dWludDE2X3QgZGllX251bTsKCXVpbnQxNl90IHBsYW5lc19wZXJfZGllOwoJdWludDE2X3QgYmxr X3Blcl9wbGFuZTsKCXVpbnQxNl90IHBhZ2VfcGVyX2JsazsKCXVpbnQxNl90IHBhZ2VfcGVyX3Ns Y19ibGs7Cgl1aW50MTZfdCBzZWNfcGVyX3BhZ2U7Cgl1aW50MTZfdCBibG9ja19zaXplOwoJdWlu dDE2X3Qgc2VjdG9yX3NpemU7Cgl1aW50MTZfdCByZXNlcnZlZF9ibGtzOwp9OwoKc3RydWN0IHRh Z1JlYWRSZXRyeUluZm8gewoJdWludDhfdCByZXRyeU1vZGU7Cgl1aW50OF90IHNpemU7Cgl1aW50 OF90IG1heDsKCXVpbnQ4X3QgcmVzMzsKCXVpbnQ4X3QgYWRkcls4XTsKCXVpbnQ4X3Qgb2Zmc2V0 MVs4XTsKCXVpbnQ4X3QgYnVmWzgzMl07Cn07Cgp1aW50OF90IGdOYW5kSURhdGFCdWZbMjA0OF07 CnN0cnVjdCB0YWdOYW5kUGFyYUluZm8gKmdwTmFuZFBhcmFJbmZvOwpzdHJ1Y3QgdGFnTmFuZE9w dFBhcmEgZ05hbmRPcHRQYXJhOwpzdHJ1Y3QgdGFnTmFuZFBoeUluZm8gZ05hbmRQaHlJbmZvOwpz dHJ1Y3QgdGFnUmVhZFJldHJ5SW5mbyBnUmVhZFJldHJ5SW5mbzsKCnVpbnQxNl90IG1sY1BhZ2VU b1NsY1BhZ2VUYmxbNTEyXTsKdWludDE2X3Qgc2xjUGFnZVRvTWxjUGFnZVRibFsyNTZdOwoKdWlu dDMyX3QgKmdGbGFzaFBhZ2VCdWZmZXIwOwp1aW50MzJfdCAqZ0ZsYXNoUGFnZUJ1ZmZlcjE7Cgp2 b2lkIFBfUkM0KHVpbnQ4X3QgKmJ1ZiwgdWludDMyX3Qgc2l6ZSkKewoJdWludDhfdCBrZXlbMTZd ID0gewoJCTB4N0MsIDB4NEUsIDB4MDMsIDB4MDQsIDB4NTUsIDB4MDUsIDB4MDksIDB4MDcsCgkJ MHgyRCwgMHgyQywgMHg3QiwgMHgzOCwgMHgxNywgMHgwRCwgMHgxNywgMHgxMSwKCX07Cgl1aW50 OF90IFNbMjU2XSwgS1syNTZdLCB0ZW1wOwoJdWludDMyX3QgaSwgaiwgdCwgeDsKCglqID0gMDsK CWZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCVNbaV0gPSAodWludDhfdClpOwoJCWogJj0g MHgwZjsKCQlLW2ldID0ga2V5W2pdOwoJCWorKzsKCX0KCWogPSAwOwoJZm9yIChpID0gMDsgaSA8 IDI1NjsgaSsrKSB7CgkJaiA9IChqICsgU1tpXSArIEtbaV0pICUgMjU2OwoJCXRlbXAgPSBTW2ld OwoJCVNbaV0gPSBTW2pdOwoJCVNbal0gPSB0ZW1wOwoJfQoJaSA9IGogPSAwOwoJZm9yICh4ID0g MDsgeCA8IHNpemU7IHgrKykgewoJCWkgPSAoaSsxKSAlIDI1NjsKCQlqID0gKGogKyBTW2ldKSAl IDI1NjsKCQl0ZW1wID0gU1tpXTsKCQlTW2ldID0gU1tqXTsKCQlTW2pdID0gdGVtcDsKCQl0ID0g KFNbaV0gKyAoU1tqXSAlIDI1NikpICUgMjU2OwoJCWJ1Zlt4XSA9IGJ1Zlt4XSBeIFNbdF07Cgl9 Cn0KCnVpbnQzMl90IGpzX2hhc2godWludDhfdCAqYnVmLCB1aW50MzJfdCBzaXplKQp7Cgl1aW50 MzJfdCBoYXNoOwoJdWludDhfdCAqcF9tYXg7Cgl1aW50MzJfdCB0bXA7CgoJaGFzaCA9IElEX0hB U0g7CglwX21heCA9ICZidWZbc2l6ZV07Cgl3aGlsZSAoYnVmICE9IHBfbWF4KSB7CgkJdG1wID0g KmJ1ZisrOwoJCWhhc2ggXj0gKGhhc2ggPj4gMikgKyAzMiAqIGhhc2ggKyB0bXA7Cgl9CglyZXR1 cm4gaGFzaDsKfQoKdm9pZCBCdWlsZEZsYXNoTHNiUGFnZVRhYmxlKHVpbnQzMl90IGxzYl9tb2Rl LCB1aW50MTZfdCBzaXplKQp7Cgl1aW50MzJfdCBjb3VudGVyMTsKCXVpbnQzMl90IGNvdW50ZXIy OwoJdWludDMyX3QgY291bnRlcjM7Cgl1aW50MzJfdCBjb3VudGVyNDsKCXVpbnQzMl90IGNvdW50 ZXI1OwoJdWludDMyX3QgY291bnRlcjY7Cgl1aW50MzJfdCBjb3VudGVyNzsKCXVpbnQzMl90IGNv dW50ZXI4OwoJdWludDE2X3Qgb2Zmc2V0MTsKCXVpbnQxNl90IG9mZnNldDI7Cgl1aW50MzJfdCBv ZmZzZXQzOwoJdWludDE2X3Qgb2Zmc2V0NDsKCXVpbnQxNl90ICpwX3RhYmxlMTsKCXVpbnQxNl90 ICpwX3RhYmxlMjsKCXVpbnQxNl90ICpwX3RhYmxlMzsKCXVpbnQxNl90IHRtcDE7Cgl1aW50MTZf dCB0bXAyOwoJdWludDE2X3QgdG1wMzsKCXVpbnQzMl90IHRtcDQ7Cgl1aW50MTZfdCB0bXA1OwoJ dWludDMyX3QgdG1wNjsKCglpZiAobHNiX21vZGUpIHsKCQlzd2l0Y2ggKGxzYl9tb2RlKSB7CgkJ Y2FzZSAxdToKCQkJY291bnRlcjIgPSAwOwoJCQlkbyB7CgkJCQl0bXAxID0gY291bnRlcjI7CgkJ CQlpZiAoY291bnRlcjIgPiAzKSB7CgkJCQkJaWYgKGNvdW50ZXIyICYgMSkKCQkJCQkJb2Zmc2V0 MSA9IDM7CgkJCQkJZWxzZQoJCQkJCQlvZmZzZXQxID0gMjsKCQkJCQl0bXAxID0gMiAqIGNvdW50 ZXIyIC0gb2Zmc2V0MTsKCQkJCX0KCQkJCXNsY1BhZ2VUb01sY1BhZ2VUYmxbY291bnRlcjIrK10g PSB0bXAxOwoJCQl9IHdoaWxlIChjb3VudGVyMiAhPSAyNTYpOwoJCQlicmVhazsKCQljYXNlIDJ1 OgoJCQljb3VudGVyMyA9IDA7CgkJCWRvIHsKCQkJCXRtcDIgPSBjb3VudGVyMzsKCQkJCWlmIChj b3VudGVyMyA+IDEpCgkJCQkJdG1wMiA9IDIgKiBjb3VudGVyMyAtIDE7CgkJCQlzbGNQYWdlVG9N bGNQYWdlVGJsW2NvdW50ZXIzKytdID0gdG1wMjsKCQkJfSB3aGlsZSAoY291bnRlcjMgIT0gMjU2 KTsKCQkJYnJlYWs7CgkJY2FzZSAzdToKCQkJY291bnRlcjQgPSAwOwoJCQlkbyB7CgkJCQl0bXAz ID0gY291bnRlcjQ7CgkJCQlpZiAoY291bnRlcjQgPiA1KSB7CgkJCQkJaWYgKGNvdW50ZXI0ICYg MSkKCQkJCQkJb2Zmc2V0MiA9IDU7CgkJCQkJZWxzZQoJCQkJCQlvZmZzZXQyID0gNDsKCQkJCQl0 bXAzID0gMiAqIGNvdW50ZXI0IC0gb2Zmc2V0MjsKCQkJCX0KCQkJCXNsY1BhZ2VUb01sY1BhZ2VU YmxbY291bnRlcjQrK10gPSB0bXAzOwoJCQl9IHdoaWxlIChjb3VudGVyNCAhPSAyNTYpOwoJCQli cmVhazsKCQlkZWZhdWx0OgoJCQljb3VudGVyNSA9IDA7CgkJCXN3aXRjaCAobHNiX21vZGUpIHsK CQkJY2FzZSA0dToKCQkJCXNsY1BhZ2VUb01sY1BhZ2VUYmxbMF0gPSAwOwoJCQkJc2xjUGFnZVRv TWxjUGFnZVRibFsxXSA9IDE7CgkJCQlzbGNQYWdlVG9NbGNQYWdlVGJsWzJdID0gMjsKCQkJCXNs Y1BhZ2VUb01sY1BhZ2VUYmxbM10gPSAzOwoJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFs1XSA9IDU7 CgkJCQlzbGNQYWdlVG9NbGNQYWdlVGJsWzZdID0gNzsKCQkJCWNvdW50ZXI2ID0gODsKCQkJCXNs Y1BhZ2VUb01sY1BhZ2VUYmxbNF0gPSA0OwoJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFs3XSA9IDg7 CgkJCQlwX3RhYmxlMSA9ICZzbGNQYWdlVG9NbGNQYWdlVGJsWzddOwoJCQkJZG8gewoJCQkJCWlm IChjb3VudGVyNiAmIDEpCgkJCQkJCW9mZnNldDMgPSA3OwoJCQkJCWVsc2UKCQkJCQkJb2Zmc2V0 MyA9IDY7CgkJCQkJdG1wNCA9IDIgKiBjb3VudGVyNiAtIG9mZnNldDM7CgkJCQkJY291bnRlcjYg PSAodWludDE2X3QpKGNvdW50ZXI2ICsgMSk7CgkJCQkJcF90YWJsZTFbMV0gPSB0bXA0OwoJCQkJ CSsrcF90YWJsZTE7CgkJCQl9IHdoaWxlIChjb3VudGVyNiAhPSAyNTYpOwoJCQkJYnJlYWs7CgkJ CWNhc2UgNXU6CgkJCQlkbyB7CgkJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFtjb3VudGVyNV0gPQoJ CQkJCQljb3VudGVyNTsKCQkJCQkrK2NvdW50ZXI1OwoJCQkJfSB3aGlsZSAoY291bnRlcjUgIT0g MTYpOwoJCQkJcF90YWJsZTIgPSAmc2xjUGFnZVRvTWxjUGFnZVRibFsxNV07CgkJCQlkbyB7CgkJ CQkJcF90YWJsZTJbMV0gPSBjb3VudGVyNTsKCQkJCQkrK3BfdGFibGUyOwoJCQkJCWNvdW50ZXI1 ID0gKHVpbnQxNl90KShjb3VudGVyNSArIDIpOwoJCQkJfSB3aGlsZSAoY291bnRlcjUgIT0gNDk2 KTsKCQkJCWJyZWFrOwoJCQljYXNlIDZ1OgoJCQkJY291bnRlcjcgPSAwOwoJCQkJZG8gewoJCQkJ CXRtcDUgPSBjb3VudGVyNzsKCQkJCQlpZiAoY291bnRlcjcgPiA1KSB7CgkJCQkJCWlmIChjb3Vu dGVyNyAmIDEpCgkJCQkJCQlvZmZzZXQ0ID0gMTI7CgkJCQkJCWVsc2UKCQkJCQkJCW9mZnNldDQg PSAxMDsKCQkJCQkJdG1wNSA9IGNvdW50ZXI1IC0gb2Zmc2V0NDsKCQkJCQl9CgkJCQkJc2xjUGFn ZVRvTWxjUGFnZVRibFtjb3VudGVyNysrXSA9IHRtcDU7CgkJCQkJY291bnRlcjUgPSAodWludDE2 X3QpKGNvdW50ZXI1ICsgMyk7CgkJCQl9IHdoaWxlIChjb3VudGVyNyAhPSAyNTYpOwoJCQkJYnJl YWs7CgkJCWNhc2UgOXU6CgkJCQlzbGNQYWdlVG9NbGNQYWdlVGJsWzBdID0gMDsKCQkJCXNsY1Bh Z2VUb01sY1BhZ2VUYmxbMV0gPSAxOwoJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFsyXSA9IDI7CgkJ CQlwX3RhYmxlMyA9ICZzbGNQYWdlVG9NbGNQYWdlVGJsWzJdOwoJCQkJY291bnRlcjggPSAzOwoJ CQkJZG8gewoJCQkJCXBfdGFibGUzWzFdID0gY291bnRlcjg7CgkJCQkJKytwX3RhYmxlMzsKCQkJ CQljb3VudGVyOCA9ICh1aW50MTZfdCkoY291bnRlcjggKyAyKTsKCQkJCX0gd2hpbGUgKGNvdW50 ZXI4ICE9IDUwOSk7CgkJCQlicmVhazsKCQkJfQoJCQlicmVhazsKCQl9Cgl9IGVsc2UgewoJCWRv IHsKCQkJc2xjUGFnZVRvTWxjUGFnZVRibFtsc2JfbW9kZV0gPSBsc2JfbW9kZTsKCQkJKytsc2Jf bW9kZTsKCQl9IHdoaWxlIChsc2JfbW9kZSAhPSAyNTYpOwoJfQoJZnRsX21lbXNldChtbGNQYWdl VG9TbGNQYWdlVGJsLCAweEZGdSwgMTAyNHUpOwoJY291bnRlcjEgPSAwOwoJd2hpbGUgKHNpemUg PiAodWludDE2X3QpY291bnRlcjEpIHsKCQl0bXA2ID0gc2xjUGFnZVRvTWxjUGFnZVRibFtjb3Vu dGVyMSsrXTsKCQltbGNQYWdlVG9TbGNQYWdlVGJsW3RtcDZdID0gdG1wNjsKCX0KfQoKaW50IEZs YXNoRXJhc2VCbG9jayh1aW50MzJfdCBjcywgdWludDMyX3QgcGFnZV9hZGRyLCB1aW50MzJfdCBz bGNfbW9kZSkKewoJdWludDhfdCBzdGF0dXM7CgoJTmFuZGNXYWl0Rmxhc2hSZWFkeShjcyk7CglO YW5kY0ZsYXNoQ3MoY3MpOwoJRmxhc2hFcmFzZUNtZChjcywgcGFnZV9hZGRyLCBzbGNfbW9kZSk7 CglOYW5kY1dhaXRGbGFzaFJlYWR5KGNzKTsKCXN0YXR1cyA9IEZsYXNoUmVhZFN0YXR1cyhjcyk7 CglOYW5kY0ZsYXNoRGVDcyhjcyk7CglyZXR1cm4gc3RhdHVzICYgMTsKfQoKaW50IEZsYXNoUHJv Z1BhZ2VSYXcodWludDMyX3QgY3MsIHVpbnQzMl90IHBhZ2VfYWRkciwgdWludDMyX3QgKnBfZGF0 YSwKCQkgICAgIHVpbnQxNl90ICpwX3NwYXJlKQp7Cgl1aW50OF90IHNlY19wZXJfcGFnZTsKCXVp bnQ4X3Qgc3RhdHVzOwoKCXNlY19wZXJfcGFnZSA9IGdOYW5kUGFyYUluZm8uc2VjX3Blcl9wYWdl OwoJaWYgKCFjcyAmJiBnQmxvY2tQYWdlQWxpZ25TaXplICogZ05hbmRJREJSZXNCbGtOdW0gPiBw YWdlX2FkZHIpIHsKCQlzZWNfcGVyX3BhZ2UgPSA0OwoJfQoJTmFuZGNXYWl0Rmxhc2hSZWFkeShj cyk7CglOYW5kY0ZsYXNoQ3MoY3MpOwoJRmxhc2hQcm9nRmlyc3RDbWQoY3MsIHBhZ2VfYWRkcik7 CglOYW5kY1hmZXJEYXRhKGNzLCAxdSwgc2VjX3Blcl9wYWdlLCBwX2RhdGEsIHBfc3BhcmUpOwoJ Rmxhc2hQcm9nU2Vjb25kQ21kKGNzKTsKCU5hbmRjV2FpdEZsYXNoUmVhZHkoY3MpOwoJc3RhdHVz ID0gRmxhc2hSZWFkU3RhdHVzKGNzKTsKCU5hbmRjRmxhc2hEZUNzKGNzKTsKCXJldHVybiBzdGF0 dXMgJiAxOwp9Cgp1aW50MzJfdCBGbGFzaFJlYWRSYXdQYWdlKHVpbnQzMl90IGNzLCB1aW50MzJf dCBwYWdlX2FkZHIsIHVpbnQzMl90ICpwX2RhdGEsCgkJCSAgdWludDE2X3QgKnBfc3BhcmUpCnsK CXVpbnQzMl90IHNlY19wZXJfcGFnZTsKCXVpbnQzMl90IHN0YXR1czsKCglzZWNfcGVyX3BhZ2Ug PSBnTmFuZFBhcmFJbmZvLnNlY19wZXJfcGFnZTsKCWlmICghY3MgJiYgZ0Jsb2NrUGFnZUFsaWdu U2l6ZSAqIGdOYW5kSURCUmVzQmxrTnVtID4gcGFnZV9hZGRyKSB7CgkJc2VjX3Blcl9wYWdlID0g NDsKCX0KCU5hbmRjV2FpdEZsYXNoUmVhZHkoY3MpOwoJTmFuZGNGbGFzaENzKGNzKTsKCUZsYXNo UmVhZENtZChjcywgcGFnZV9hZGRyKTsKCU5hbmRjV2FpdEZsYXNoUmVhZHkoY3MpOwoJc3RhdHVz ID0gTmFuZGNYZmVyRGF0YShjcywgMCwgc2VjX3Blcl9wYWdlLCBwX2RhdGEsIHBfc3BhcmUpOwoJ TmFuZGNGbGFzaERlQ3MoY3MpOwoJcmV0dXJuIHN0YXR1czsKfQoKdm9pZCBGbGFzaEJsb2NrQWxp Z25Jbml0KHVpbnQzMl90IHBhZ2VfcGVyX2JsaykKewoJdWludDMyX3QgYWxpZ25fc2l6ZTsKCglp ZiAocGFnZV9wZXJfYmxrID4gMjU2KSB7CgkJYWxpZ25fc2l6ZSA9IDUxMjsKbGFiZWxfMzoKCQln QmxvY2tQYWdlQWxpZ25TaXplID0gYWxpZ25fc2l6ZTsKCQlyZXR1cm47Cgl9CglpZiAocGFnZV9w ZXJfYmxrID4gMTI4KSB7CgkJYWxpZ25fc2l6ZSA9IDI1NjsKCQlnb3RvIGxhYmVsXzM7Cgl9Cgln QmxvY2tQYWdlQWxpZ25TaXplID0gcGFnZV9wZXJfYmxrOwp9Cgp1aW50MzJfdCBGbGFzaExvYWRQ aHlJbmZvKHZvaWQpCnsKCXN0cnVjdCB0YWdGbGFzaFNhdmVJbmZvICppbmZvOwoJdWludDMyX3Qg YWxpZ25fc2l6ZTsKCXVpbnQzMl90IGJjaF9jb3VudGVyOwoJdWludDMyX3QgY291bnRlcjsKCXVp bnQzMl90IHBhZ2VfYWRkcjsKCXVpbnQzMl90IHN0YXR1czsKCXVpbnQ4X3QgYmNoWzRdOwoKCXBh Z2VfYWRkciA9IDA7Cgljb3VudGVyID0gNDsKCWJjaFswXSA9IDYwOwoJYmNoWzFdID0gNDA7Cgli Y2hbMl0gPSAyNDsKCWJjaFszXSA9IDE2OwoJc3RhdHVzID0gTkFORF9TVFNfRVJST1I7CglhbGln bl9zaXplID0gZ0Jsb2NrUGFnZUFsaWduU2l6ZTsKCWdOYW5kRmxhc2hJbmZvQmxvY2tBZGRyID0g MDsKCWdwRmxhc2hTYXZlSW5mbyA9IChzdHJ1Y3QgdGFnRmxhc2hTYXZlSW5mbyAqKWdGbGFzaFBh Z2VCdWZmZXIwOwoJZmxhc2hfZW50ZXJfc2xjX21vZGUoMCk7Cgl3aGlsZSAoMSkgewoJCWJjaF9j b3VudGVyID0gMDsKCQl3aGlsZSAoMSkgewoJCQlGbGFzaEJjaFNlbChiY2hbYmNoX2NvdW50ZXJd KTsKCQkJaWYgKEZsYXNoUmVhZFJhd1BhZ2UoCgkJCQkgICAgMCwKCQkJCSAgICBwYWdlX2FkZHIs CgkJCQkgICAgZ0ZsYXNoUGFnZUJ1ZmZlcjAsCgkJCQkgICAgMCkgIT0gTkFORF9TVFNfRVJST1Ig fHwKCQkJICAgIEZsYXNoUmVhZFJhd1BhZ2UoCgkJCQkgICAgMCwKCQkJCSAgICBwYWdlX2FkZHIg KyAxLAoJCQkJICAgIGdGbGFzaFBhZ2VCdWZmZXIwLAoJCQkJICAgIDApICE9IE5BTkRfU1RTX0VS Uk9SKSB7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoKytiY2hfY291bnRlciA9PSA0KQoJCQkJZ290 byBsYWJlbF82OwoJCX0KCQlpbmZvID0gZ3BGbGFzaFNhdmVJbmZvOwoJCWlmIChncEZsYXNoU2F2 ZUluZm8tPklkID09IElEX05BTkQpIHsKCQkJaWYgKCFzdGF0dXMpIHsKCQkJCWdOYW5kRmxhc2hJ ZGJCbG9ja0FkZHIgPQoJCQkJCXBhZ2VfYWRkcgoJCQkJCS8gZ0Jsb2NrUGFnZUFsaWduU2l6ZSAr IDE7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoIGluZm8tPkpTSGFzaCA9PSBqc19oYXNoKAoJCQkJ ICAgICAodWludDhfdCAqKSZncEZsYXNoU2F2ZUluZm8tPmdOYW5kTWF4RGllLAoJCQkJICAgICAy MDM2dSkpIHsKCQkJCWZ0bF9tZW1jcHkoCgkJCQkJJmdOYW5kUGFyYUluZm8sCgkJCQkJaW5mby0+ Z05hbmRQYXJhSW5mbywKCQkJCQkzMnUpOwoJCQkJZnRsX21lbWNweSgKCQkJCQkmZ05hbmRPcHRQ YXJhLAoJCQkJCWdwRmxhc2hTYXZlSW5mby0+Z05hbmRPcHRQYXJhLAoJCQkJCTMydSk7CgkJCQlm dGxfbWVtY3B5KAoJCQkJCSZnUmVhZFJldHJ5SW5mbywKCQkJCQlncEZsYXNoU2F2ZUluZm8tPmdS ZWFkUmV0cnlJbmZvLAoJCQkJCTg1MnUpOwoJCQkJRmxhc2hCbG9ja0FsaWduSW5pdChnTmFuZFBh cmFJbmZvLnBhZ2VfcGVyX2Jsayk7CgkJCQlnRmxhc2hUb2dnbGVNb2RlRW4gPQoJCQkJCWdwRmxh c2hTYXZlSW5mby0+Z0ZsYXNoVG9nZ2xlTW9kZUVuOwoJCQkJZ05hbmRGbGFzaEluZm9CbG9ja0Fk ZHIgPSBwYWdlX2FkZHI7CgkJCQlpZiAocGFnZV9hZGRyIC8gZ0Jsb2NrUGFnZUFsaWduU2l6ZSAr IDEgPiAxKQoJCQkJCWdOYW5kRmxhc2hJZGJCbG9ja0FkZHIgPQoJCQkJCQlwYWdlX2FkZHIKCQkJ CQkJLyBnQmxvY2tQYWdlQWxpZ25TaXplICsgMTsKCQkJCWVsc2UKCQkJCQlnTmFuZEZsYXNoSWRi QmxvY2tBZGRyID0gMjsKCQkJCXN0YXR1cyA9IE5BTkRfU1RTX09LOwoJCQkJZ05hbmRJREJSZXNC bGtOdW1TYXZlSW5GbGFzaCA9CgkJCQkJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZElEQlJlc0Jsa051 bTsKCQkJfSBlbHNlIHsKCQkJCXN0YXR1cyA9IE5BTkRfU1RTX0VSUk9SOwoJCQl9CgkJfQpsYWJl bF82OgoJCS0tY291bnRlcjsKCQlwYWdlX2FkZHIgKz0gYWxpZ25fc2l6ZTsKCQlpZiAoY291bnRl cikKCQkJY29udGludWU7CgkJYnJlYWs7Cgl9CglmbGFzaF9leGl0X3NsY19tb2RlKDApOwoJcmV0 dXJuIHN0YXR1czsKfQoKdm9pZCBGbGFzaFNhdmVQaHlJbmZvKHZvaWQpCnsKCXVpbnQzMl90IGNv dW50ZXIxOwoJdWludDMyX3QgY291bnRlcjI7Cgl1aW50MzJfdCBkb25lOwoJdWludDMyX3QgaGFz aDsKCXVpbnQzMl90IHN0YXR1czsKCglncEZsYXNoU2F2ZUluZm8gPSAoc3RydWN0IHRhZ0ZsYXNo U2F2ZUluZm8gKilnRmxhc2hQYWdlQnVmZmVyMDsKCUZsYXNoQmNoU2VsKGdOYW5kRmxhc2hJREJF Y2NCaXRzKTsKCWZ0bF9tZW1zZXQoZ0ZsYXNoUGFnZUJ1ZmZlcjAsIDAsIDIwNDh1KTsKCWdwRmxh c2hTYXZlSW5mby0+SWQgPSBJRF9OQU5EOwoJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZE1heERpZSA9 IGdOYW5kTWF4RGllOwoJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZElEQlJlc0Jsa051bSA9IGdOYW5k SURCUmVzQmxrTnVtOwoJZ3BGbGFzaFNhdmVJbmZvLT5nRmxhc2hUb2dnbGVNb2RlRW4gPSBnRmxh c2hUb2dnbGVNb2RlRW47CglmdGxfbWVtY3B5KGdwRmxhc2hTYXZlSW5mby0+SURCeXRlLCBJREJ5 dGUsIDMydSk7CglmdGxfbWVtY3B5KGdwRmxhc2hTYXZlSW5mby0+RGllQ3NJbmRleCwgRGllQ3NJ bmRleCwgOHUpOwoJZnRsX21lbWNweShncEZsYXNoU2F2ZUluZm8tPkRpZUFkZHJzLCBEaWVBZGRy cywgMzJ1KTsKCWZ0bF9tZW1jcHkoCgkJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZFBhcmFJbmZvLAoJ CSZnTmFuZFBhcmFJbmZvLAoJCTMydSk7CglmdGxfbWVtY3B5KGdwRmxhc2hTYXZlSW5mby0+Z05h bmRPcHRQYXJhLCAmZ05hbmRPcHRQYXJhLCAzMnUpOwoJZnRsX21lbWNweSgKCQlncEZsYXNoU2F2 ZUluZm8tPmdSZWFkUmV0cnlJbmZvLAoJCSZnUmVhZFJldHJ5SW5mbywKCQk4NTJ1KTsKCWdwRmxh c2hTYXZlSW5mby0+SlNIYXNoID0ganNfaGFzaCgKCQkJCQkgICh1aW50OF90ICopCgkJCQkJICAm Z3BGbGFzaFNhdmVJbmZvLT5nTmFuZE1heERpZSwKCQkJCQkgIDIwMzZ1KTsKCWdwRmxhc2hTYXZl SW5mby0+U2l6ZSA9IDE1OTI7Cglkb25lID0gMDsKCWNvdW50ZXIxID0gMDsKCWdwRmxhc2hTYXZl SW5mbyA9IChzdHJ1Y3QgdGFnRmxhc2hTYXZlSW5mbyAqKWdGbGFzaFBhZ2VCdWZmZXIxOwoJZmxh c2hfZW50ZXJfc2xjX21vZGUoMCk7CglkbyB7CgkJRmxhc2hFcmFzZUJsb2NrKDAsIGdCbG9ja1Bh Z2VBbGlnblNpemUgKiBjb3VudGVyMSwgMCk7CgkJRmxhc2hQcm9nUGFnZVJhdygKCQkJMCwKCQkJ Z0Jsb2NrUGFnZUFsaWduU2l6ZSAqIGNvdW50ZXIxLAoJCQlnRmxhc2hQYWdlQnVmZmVyMCwKCQkJ MCk7CgkJRmxhc2hQcm9nUGFnZVJhdygKCQkJMCwKCQkJZ0Jsb2NrUGFnZUFsaWduU2l6ZSAqIGNv dW50ZXIxICsgMSwKCQkJZ0ZsYXNoUGFnZUJ1ZmZlcjAsCgkJCTApOwoJCXN0YXR1cyA9IEZsYXNo UmVhZFJhd1BhZ2UoCgkJCQkgMCwKCQkJCSBnQmxvY2tQYWdlQWxpZ25TaXplICogY291bnRlcjEs CgkJCQkgZ0ZsYXNoUGFnZUJ1ZmZlcjEsCgkJCQkgMCk7CgkJY291bnRlcjIgPSBjb3VudGVyMSAr IDE7CgkJaWYgKHN0YXR1cyAhPSBOQU5EX1NUU19FUlJPUiAmJgoJCSAgICBncEZsYXNoU2F2ZUlu Zm8tPklkID09IElEX05BTkQpIHsKCQkJaGFzaCA9IGpzX2hhc2goCgkJCQkgICAgICAgKHVpbnQ4 X3QgKikKCQkJCSAgICAgICAmZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZE1heERpZSwKCQkJCSAgICAg ICAyMDM2dSk7CgkJCWNvdW50ZXIyID0gY291bnRlcjEgKyAxOwoJCQlpZiAoZ3BGbGFzaFNhdmVJ bmZvLT5KU0hhc2ggPT0gaGFzaCkgewoJCQkJZ05hbmRGbGFzaElkYkJsb2NrQWRkciA9IGNvdW50 ZXIxICsgMTsKCQkJCWdOYW5kRmxhc2hJbmZvQmxvY2tBZGRyID0gY291bnRlcjEKCQkJCQkJCSAg KiBnQmxvY2tQYWdlQWxpZ25TaXplOwoJCQkJaWYgKGRvbmUgPT0gMSkKCQkJCQlicmVhazsKCQkJ CWRvbmUgPSAxOwoJCQl9CgkJfQoJCWNvdW50ZXIxID0gY291bnRlcjI7Cgl9IHdoaWxlIChjb3Vu dGVyMiAhPSA0KTsKCWZsYXNoX2V4aXRfc2xjX21vZGUoMCk7Cn0KCmludCBGbGFzaFJlYWRJZGJE YXRhUmF3KHVpbnQ4X3QgKnBfYnVmKQp7Cgl1aW50MzJfdCBiY2hfY291bnRlcjsKCXVpbnQzMl90 IGVjY19iaXRzOwoJdWludDMyX3QgZWNjX2JpdHMyOwoJdWludDMyX3QgcGFnZV9jb3VudGVyOwoJ aW50IHN0YXR1czsKCXVpbnQ4X3QgYmNoWzRdOwoKCWJjaFswXSA9IDYwOwoJYmNoWzFdID0gNDA7 CgliY2hbMl0gPSAyNDsKCWJjaFszXSA9IDE2OwoJZWNjX2JpdHMyID0gZ05hbmRGbGFzaEVjY0Jp dHM7CglpZiAoaWRiX2ZsYXNoX3NsY19tb2RlKQoJCWZsYXNoX2VudGVyX3NsY19tb2RlKDApOwoJ c3RhdHVzID0gTkFORF9TVFNfRVJST1I7CglwYWdlX2NvdW50ZXIgPSAyOwoJZnRsX21lbXNldChw X2J1ZiwgMCwgMjA0OHUpOwoJd2hpbGUgKDEpIHsKCQlpZiAocGFnZV9jb3VudGVyIDwgZ05hbmRJ REJSZXNCbGtOdW0pIHsKCQkJYmNoX2NvdW50ZXIgPSAwOwoJCQl3aGlsZSAoMSkgewoJCQkJZWNj X2JpdHMgPSBiY2hbYmNoX2NvdW50ZXJdOwoJCQkJRmxhc2hCY2hTZWwoZWNjX2JpdHMpOwoJCQkJ aWYgKCBGbGFzaFJlYWRSYXdQYWdlKAoJCQkJCSAgICAgMCwKCQkJCQkgICAgIGdCbG9ja1BhZ2VB bGlnblNpemUKCQkJCQkgICAgICogcGFnZV9jb3VudGVyLAoJCQkJCSAgICAgZ0ZsYXNoUGFnZUJ1 ZmZlcjAsCgkJCQkJICAgICAwKSAhPSBOQU5EX1NUU19FUlJPUikKCQkJCQlicmVhazsKCQkJCWlm ICgrK2JjaF9jb3VudGVyID09IDQpCgkJCQkJZ290byBsYWJlbF8xMTsKCQkJfQoJCQlpZiAoKmdG bGFzaFBhZ2VCdWZmZXIwID09IElEX0lEUlcpIHsKCQkJCUZUTF9JTkZPKCJFQ0M6JWRcbiIsIGVj Y19iaXRzKTsKCQkJCWZ0bF9tZW1jcHkoCgkJCQkJcF9idWYsCgkJCQkJZ0ZsYXNoUGFnZUJ1ZmZl cjAsCgkJCQkJMjA0OHUpOwoJCQkJZ05hbmRJREJSZXNCbGtOdW0gPSBnRmxhc2hQYWdlQnVmZmVy MFsxMjhdOwoJCQkJaWYgKHBhZ2VfY291bnRlciA+PSBnTmFuZEZsYXNoSWRiQmxvY2tBZGRyKSB7 CgkJCQkJc3RhdHVzID0gTkFORF9TVFNfT0s7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlnTmFuZEZs YXNoSWRiQmxvY2tBZGRyID0gcGFnZV9jb3VudGVyOwoJCQkJc3RhdHVzID0gTkFORF9TVFNfT0s7 CgkJCQlGbGFzaFNhdmVQaHlJbmZvKCk7CgkJCX0KbGFiZWxfMTE6CgkJCSsrcGFnZV9jb3VudGVy OwoJCQljb250aW51ZTsKCQl9CgkJYnJlYWs7Cgl9CglGbGFzaEJjaFNlbChlY2NfYml0czIpOwoJ aWYgKGlkYl9mbGFzaF9zbGNfbW9kZSkKCQlmbGFzaF9leGl0X3NsY19tb2RlKDApOwoJcmV0dXJu IHN0YXR1czsKfQoKdm9pZCBGbGFzaFBhZ2VQcm9nTXNiRkZEYXRhKHVpbnQzMl90IGNzLCB1aW50 MzJfdCBwYWdlX2FkZHIsIHVpbnQzMl90IGNvdW50KQp7Cgl1aW50MzJfdCByZXRyeV9tb2RlOwoJ dWludDMyX3Qgc2hpZnQ7Cgl1aW50MzJfdCB0bXA7CgoJaWYgKCFnRmxhc2hTbGNNb2RlIHx8ICFp ZGJfZmxhc2hfc2xjX21vZGUpIHsKCQlyZXRyeV9tb2RlID0gZ3BOYW5kUGFyYUluZm8tPnJlYWRf cmV0cnlfbW9kZTsKCQlzaGlmdCA9ICh1aW50OF90KShyZXRyeV9tb2RlIC0gNSk7CgkJaWYgKHNo aWZ0ID4gMzApIHsKCQkJaWYgKHJldHJ5X21vZGUgIT0gNjgpCgkJCQlyZXR1cm47CgkJfSBlbHNl IGlmICghKCgweDQwMDA0MDBGdSA+PiBzaGlmdCkgJiAxKSkgewoJCQlyZXR1cm47CgkJfQoJCXdo aWxlIChncE5hbmRQYXJhSW5mby0+cGFnZV9wZXJfYmxrID4gY291bnQgJiYKCQkgICAgICAgbWxj UGFnZVRvU2xjUGFnZVRibFtjb3VudF0gPT0gMHhGRkZGKSB7CgkJCWlmIChyZXRyeV9tb2RlID09 IDgpCgkJCQl0bXAgPSAwOwoJCQllbHNlCgkJCQl0bXAgPSAweEZGdTsKCQkJZnRsX21lbXNldChn Rmxhc2hQYWdlQnVmZmVyMSwgdG1wLCAzMjc2OHUpOwoJCQlGbGFzaFByb2dQYWdlUmF3KAoJCQkJ Y3MsCgkJCQljb3VudCArIHBhZ2VfYWRkciwKCQkJCWdGbGFzaFBhZ2VCdWZmZXIxLAoJCQkJKHVp bnQxNl90ICopZ0ZsYXNoUGFnZUJ1ZmZlcjEpOwoJCQljb3VudCA9ICh1aW50MTZfdCkoY291bnQg KyAxKTsKCQl9Cgl9Cn0KCnZvaWQgSWRCbG9ja1JlYWREYXRhKHVpbnQzMl90IGluZGV4LCB1aW50 MzJfdCBjb3VudCwgdWludDMyX3QgKmJ1ZikKewoJdWludDMyX3QgY291bnRlcjsKCXVpbnQxNl90 IGNvdW50ZXJfYWRkOwoJdWludDMyX3QgZWNjX2JpdHM7Cgl1aW50MzJfdCBtaW5fc2VjdG9yOwoJ dWludDMyX3QgcGFnZTsKCXVpbnQzMl90IHNlY3RvcjsKCXVpbnQzMl90IHNlY3RvcjI7Cgl1aW50 MTZfdCBzaXplOwoJdWludDMyX3Qgc3RhcnRfb2Zmc2V0OwoKCXNpemUgPSBncE5hbmRQYXJhSW5m by0+c2VjX3Blcl9wYWdlICogKHVpbnQxNl90KWdCbG9ja1BhZ2VBbGlnblNpemU7CglGVExfSU5G TygKCQkiSWRCbG9ja1JlYWREYXRhICV4ICV4XG4iLAoJCWluZGV4LAoJCWNvdW50KTsKCWNvdW50 ZXIgPSAwOwoJc2VjdG9yMiA9IGluZGV4ICUgc2l6ZTsKCW1pbl9zZWN0b3IgPSBpbmRleCAtIGlu ZGV4ICUgc2l6ZTsKCXN0YXJ0X29mZnNldCA9IChncE5hbmRQYXJhSW5mby0+c2VjX3Blcl9wYWdl ICogKGluZGV4ICUgc2l6ZSkgPj4gMikgJiAzOwoJd2hpbGUgKGNvdW50ZXIgPCBjb3VudCkgewoJ CWNvdW50ZXJfYWRkID0gNCAtIHN0YXJ0X29mZnNldDsKCQlwYWdlID0gc2xjUGFnZVRvTWxjUGFn ZVRibFsoKGNvdW50ZXIgKyBzZWN0b3IyKSA+PiAyKSAmIDB4RkZGRl07CgkJaWYgKGdGbGFzaFNs Y01vZGUgJiYKCQkgICAgZ19uYW5kY192ZXJzaW9uX2RhdGEgPT0gTkFORF9WRVJTSU9OX1Y4MDAp CgkJCXBhZ2UgPSAoKGNvdW50ZXIgKyBzZWN0b3IyKSA+PiAyKSAmIDB4RkZGRjsKCQllY2NfYml0 cyA9IGdOYW5kRmxhc2hFY2NCaXRzOwoJCXNlY3RvciA9IHN0YXJ0X29mZnNldCArCgkJCSBtaW5f c2VjdG9yICsKCQkJIGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2UgKiBwYWdlOwoJCUZsYXNo QmNoU2VsKGdOYW5kRmxhc2hJREJFY2NCaXRzKTsKCQlmbGFzaF9ib290X2VudGVyX3NsY19tb2Rl KDApOwoJCUZsYXNoUmVhZFBhZ2UoCgkJCTAsCgkJCXNlY3RvciAvIGdwTmFuZFBhcmFJbmZvLT5z ZWNfcGVyX3BhZ2UsCgkJCWdGbGFzaFBhZ2VCdWZmZXIxLAoJCQkwKTsKCQlmbGFzaF9ib290X2V4 aXRfc2xjX21vZGUoMCk7CgkJRmxhc2hCY2hTZWwoZWNjX2JpdHMpOwoJCW1lbWNweSgmYnVmWzEy OCAqIGNvdW50ZXJdLCBnRmxhc2hQYWdlQnVmZmVyMSwgMjA0OHUpOwoJCXN0YXJ0X29mZnNldCA9 IDA7CgkJY291bnRlciA9ICh1aW50MTZfdCkoY291bnRlcl9hZGQgKyBjb3VudGVyKTsKCX0KCUZU TF9JTkZPKAoJCSJJZEJsb2NrUmVhZERhdGEgJXggJXggcmV0PSAleFxuIiwKCQlpbmRleCwKCQlj b3VudCwKCQkwKTsKfQoKdm9pZCBJREJsb2NrV3JpdGVEYXRhKHVpbnQzMl90IGluZGV4LCB1aW50 MzJfdCBjb3VudCwgdWludDMyX3QgKmJ1ZikKewoJdWludDMyX3QgY291bnRlcjsKCXVpbnQzMl90 IGVjY19iaXRzOwoJdWludDMyX3QgbWluX3NlY3RvcjsKCXVpbnQzMl90IHBhZ2U7Cgl1aW50MzJf dCBwYWdlMTsKCXVpbnQzMl90IHBhZ2UyOwoJdWludDMyX3Qgc2VjdG9yMjsKCXVpbnQxNl90IHNp emU7Cgl1aW50MzJfdCBzcGFyZVszMl07CgoJc2l6ZSA9IGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVy X3BhZ2UgKiAodWludDE2X3QpZ0Jsb2NrUGFnZUFsaWduU2l6ZTsKCUZUTF9JTkZPKAoJCSJJREJs b2NrV3JpdGVEYXRhICV4ICV4XG4iLAoJCWluZGV4LAoJCWNvdW50KTsKCWZsYXNoX2Jvb3RfZW50 ZXJfc2xjX21vZGUoMCk7CglGbGFzaEVyYXNlQmxvY2soMCwgaW5kZXggLyBnTmFuZFBoeUluZm8u c2VjX3Blcl9wYWdlLCAwKTsKCWZsYXNoX2Jvb3RfZXhpdF9zbGNfbW9kZSgwKTsKCWNvdW50ZXIg PSAwOwoJc2VjdG9yMiA9IGluZGV4ICUgc2l6ZTsKCW1pbl9zZWN0b3IgPSBpbmRleCAtIGluZGV4 ICUgc2l6ZTsKCXdoaWxlIChjb3VudGVyIDwgY291bnQpIHsKCQlwYWdlID0gKChjb3VudGVyICsg c2VjdG9yMikgPj4gMikgJiAweEZGRkY7CgkJaWYgKHBhZ2UpIHsKCQkJcGFnZTEgPSBzbGNQYWdl VG9NbGNQYWdlVGJsW3BhZ2UgKyAxXTsKCQkJaWYgKGdGbGFzaFNsY01vZGUgJiYKCQkJICAgIGdf bmFuZGNfdmVyc2lvbl9kYXRhID09IE5BTkRfVkVSU0lPTl9WODAwKQoJCQkJcGFnZTEgPSAodWlu dDE2X3QpCgkJCQkJKCgoY291bnRlciArIHNlY3RvcjIpID4+IDIpICsgMSk7CgkJCXNwYXJlWzBd ID0gNCAqIChwYWdlMSAtIDEpOwoJCQlzcGFyZVsxXSA9IDA7CgkJfQoJCXBhZ2UyID0gc2xjUGFn ZVRvTWxjUGFnZVRibFtwYWdlXTsKCQlpZiAoZ0ZsYXNoU2xjTW9kZSAmJgoJCSAgICBnX25hbmRj X3ZlcnNpb25fZGF0YSA9PSBOQU5EX1ZFUlNJT05fVjgwMCkKCQkJcGFnZTIgPSAoKGNvdW50ZXIg KyBzZWN0b3IyKSA+PiAyKSAmIDB4RkZGRjsKCQllY2NfYml0cyA9IGdOYW5kRmxhc2hFY2NCaXRz OwoJCUZsYXNoQmNoU2VsKGdOYW5kRmxhc2hJREJFY2NCaXRzKTsKCQlmbGFzaF9ib290X2VudGVy X3NsY19tb2RlKDApOwoJCUZsYXNoUHJvZ1BhZ2VSYXcoCgkJCTAsCgkJCShtaW5fc2VjdG9yICsg Z3BOYW5kUGFyYUluZm8tPnNlY19wZXJfcGFnZSAqIHBhZ2UyKQoJCQkvIGdwTmFuZFBhcmFJbmZv LT5zZWNfcGVyX3BhZ2UsCgkJCSZidWZbMTI4ICogY291bnRlcl0sCgkJCSh1aW50MTZfdCAqKXNw YXJlKTsKCQlmbGFzaF9ib290X2V4aXRfc2xjX21vZGUoMCk7CgkJRmxhc2hCY2hTZWwoZWNjX2Jp dHMpOwoJCUZsYXNoUGFnZVByb2dNc2JGRkRhdGEoCgkJCTAsCgkJCW1pbl9zZWN0b3IgLyBncE5h bmRQYXJhSW5mby0+c2VjX3Blcl9wYWdlLAoJCQkodWludDE2X3QpKHBhZ2UyICsgMSkpOwoJCWNv dW50ZXIgPSAodWludDE2X3QpKGNvdW50ZXIgKyA0KTsKCX0KCUZUTF9JTkZPKAoJCSJJREJsb2Nr V3JpdGVEYXRhICV4ICV4IHJldD0gJXhcbiIsCgkJaW5kZXgsCgkJY291bnQsCgkJMCk7Cn0KCmlu dCB3cml0ZV9pZGJsb2NrKHVpbnQzMl90IHNpemUsIHVpbnQzMl90ICpidWYsIHVpbnQzMl90ICpw X2RhdGEpCnsKCXVpbnQzMl90IGNvdW50OwoJdWludDMyX3QgY291bnRlcjsKCXVpbnQzMl90IGNv dW50ZXIyOwoJdWludDMyX3QgaW5kZXg7Cgl1aW50MzJfdCBtYXhfc2l6ZTsKCXVpbnQzMl90IG9m ZnNldDsKCXVpbnQzMl90IG9mZnNldDI7Cgl1aW50MzJfdCBwYWdlX2FkZHI7Cgl1aW50MzJfdCAq cF9yZWFkOwoJdWludDMyX3QgKnBfd3JpdGU7Cgl1aW50MzJfdCByOwoJdWludDMyX3QgdzsKCXVp bnQxNl90IHNpemUyOwoJdWludDMyX3Qgc3RhdHVzOwoJdWludDMyX3Qgd3JpdGVfY291bnRlcjsK CglzaXplMiA9IGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2UgKiAodWludDE2X3QpZ0Jsb2Nr UGFnZUFsaWduU2l6ZTsKCXBfcmVhZCA9ICh1aW50MzJfdCAqKWttYWxsb2Nfb3JkZXJfdHJhY2Uo MjU2MDAwLCAyMDgsIDYpOwoJaWYgKHBfcmVhZCkgewoJCWluZGV4ID0gKHNpemUgKyA1MTEpID4+ IDk7CgkJaWYgKGluZGV4IDw9IDI1NSkKCQkJbWVtY3B5KCZidWZbMTI4ICogaW5kZXhdLCBidWYs IDI1NiAtIGluZGV4KTsKCQljb3VudCA9IGluZGV4ICsgMTI4OwoJCXJrbmFuZF9wcmludF9oZXgo ImlkYmxrOiIsIHBfZGF0YSwgNCwgNSk7CgkJaWYgKGNvdW50ID49IDI1NikKCQkJY291bnQgPSAy NTY7CgkJY291bnRlciA9IDA7CgkJRlRMX0lORk8oCgkJCSJpZGIgcmV2ZXJzZSAleCAleFxuIiwK CQkJYnVmWzEyOF0sCgkJCWdOYW5kSURCUmVzQmxrTnVtKTsKCQl3cml0ZV9jb3VudGVyID0gMDsK CQlwX3dyaXRlID0gYnVmOwoJCWlmIChidWZbMTI4XSA+IGdOYW5kSURCUmVzQmxrTnVtKQoJCQli dWZbMTI4XSA9IGdOYW5kSURCUmVzQmxrTnVtOwoJCUZUTF9JTkZPKAoJCQkid3JpdGVfaWRibG9j ayB0b3RhbF9zZWMgJXggJXhcbiIsCgkJCWNvdW50LAoJCQlzaXplKTsKCQltYXhfc2l6ZSA9IGNv dW50IDw8IDc7CgkJZG8gewoJCQlwYWdlX2FkZHIgPSAqcF9kYXRhOwoJCQkrK3BfZGF0YTsKCQkJ aWYgKHBhZ2VfYWRkciA8IGdOYW5kUGh5SW5mby5yZXNlcnZlZF9ibGtzICYmCgkJCSAgICBwYWdl X2FkZHIgPj0gZ05hbmRGbGFzaElkYkJsb2NrQWRkcikgewoJCQkJZnRsX21lbXNldChwX3JlYWQs IDAsIDUxMik7CgkJCQlJREJsb2NrV3JpdGVEYXRhKAoJCQkJCSoocF9kYXRhIC0gMSkgKiBzaXpl MiwKCQkJCQljb3VudCwKCQkJCQlwX3dyaXRlKTsKCQkJCUlkQmxvY2tSZWFkRGF0YSgKCQkJCQkq KHBfZGF0YSAtIDEpICogc2l6ZTIsCgkJCQkJY291bnQsCgkJCQkJcF9yZWFkKTsKCQkJCWNvdW50 ZXIyID0gMDsKCQkJCW9mZnNldCA9IDA7CgkJCQl3aGlsZSAoMSkgewoJCQkJCXIgPSBwX3JlYWRb Y291bnRlcjJdOwoJCQkJCXcgPSBwX3dyaXRlW2NvdW50ZXIyXTsKCQkJCQkrK2NvdW50ZXIyOwoJ CQkJCWlmIChyICE9IHcpCgkJCQkJCWJyZWFrOwoJCQkJCSsrb2Zmc2V0OwoJCQkJCWlmIChvZmZz ZXQgPT0gbWF4X3NpemUpCgkJCQkJCWdvdG8gbGFiZWxfMTsKCQkJCX0KCQkJCW9mZnNldDIgPSBv ZmZzZXQgJiAweEZGRkZGRjAwOwoJCQkJRlRMX0lORk8oCgkJCQkJIndyaXRlIGFuZCBjaGVjayBl cnJvcjoiCgkJCQkJIiVkIGlkYj0leCxvZmZzZXQ9JXgscj0leCx3PSV4XG4iLAoJCQkJCXdyaXRl X2NvdW50ZXIsCgkJCQkJKihwX2RhdGEgLSAxKSwKCQkJCQlvZmZzZXQsCgkJCQkJciwKCQkJCQl3 KTsKCQkJCXJrbmFuZF9wcmludF9oZXgoCgkJCQkJIndyaXRlIiwKCQkJCQkmcF93cml0ZVtvZmZz ZXQyXSwKCQkJCQk0LAoJCQkJCTI1Nik7CgkJCQlya25hbmRfcHJpbnRfaGV4KAoJCQkJCSJyZWFk IiwKCQkJCQkmcF9yZWFkW29mZnNldDJdLAoJCQkJCTQsCgkJCQkJMjU2KTsKCQkJCWZ0bF9tZW1z ZXQocF9yZWFkLCAwLCA1MTIpOwoJCQkJSURCbG9ja1dyaXRlRGF0YSgKCQkJCQkqKHBfZGF0YSAt IDEpICogc2l6ZTIsCgkJCQkJNHUsCgkJCQkJcF9yZWFkKTsKCQkJCUZUTF9JTkZPKCJ3cml0ZV9p ZGJsb2NrIGVycm9yXG4iKTsKCQkJCWlmIChvZmZzZXQgPCBtYXhfc2l6ZSkKCQkJCQlnb3RvIGxh YmVsXzA7CmxhYmVsXzE6CgkJCQkrK2NvdW50ZXI7CgkJCX0KbGFiZWxfMDoKCQkJKyt3cml0ZV9j b3VudGVyOwoJCX0gd2hpbGUgKHdyaXRlX2NvdW50ZXIgIT0gNSk7CgkJZnRsX2ZyZWUocF9yZWFk KTsKCQlpZiAoY291bnRlcikKCQkJc3RhdHVzID0gMDsKCQllbHNlCgkJCXN0YXR1cyA9IC0xOwoJ fSBlbHNlIHsKCQlzdGF0dXMgPSAtMTsKCX0KCXJldHVybiBzdGF0dXM7Cn0KCnZvaWQgd3JpdGVf bG9hZGVyX2xiYSh1aW50MzJfdCBpbmRleCwgdWludDMyX3QgY291bnQsIHVpbnQzMl90ICpidWYp CnsKCXVpbnQzMl90IGNvdW50ZXIxOwoJdWludDMyX3QgY291bnRlcjI7Cgl1aW50MzJfdCBsYmEx OwoJdWludDMyX3QgbGJhMjsKCXVpbnQzMl90IHNpemU7Cgl1aW50MzJfdCB0bXA7Cgl1aW50MzJf dCBibG9ja1sxMzBdOwoKCWlmIChpbmRleCA9PSA2NCAmJiAqYnVmID09IElEX0lEUlcpIHsKCQlp ZGJfd3JpdGVfZW5hYmxlID0gMTsKCQlpZGJfYnVmID0gZnRsX21hbGxvYygyNTYwMDApOwoJCWZ0 bF9tZW1zZXQoCgkJCWlkYl9idWYsCgkJCTAsCgkJCTI1NjAwMCk7CgkJaWRiX2xhc3RfbGJhID0g aW5kZXg7Cgl9CglGVExfSU5GTygid2xfbGJhICVwICV4ICV4ICV4XG4iLCBpZGJfYnVmLCAqYnVm LCBpbmRleCwgY291bnQpOwoJaWYgKGlkYl93cml0ZV9lbmFibGUpIHsKCQlpZiAoaW5kZXggLSA2 NCA+PSA1MDApIHsKCQkJaWYgKGluZGV4ID49IDU2NCkgewoJCQkJbGJhMSA9IGlkYl9sYXN0X2xi YSAtIDY0OwoJCQkJaWYgKGlkYl9sYXN0X2xiYSAtIDY0ID49IDUwMCkKCQkJCQlsYmExID0gNTAw OwoJCQkJaWYgKGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2UgPT0gNCkgewoJCQkJCWNvdW50 ZXIxID0gMDsKCQkJCQlkbyB7CgkJCQkJCXRtcCA9IDIgKiBjb3VudGVyMTsKCQkJCQkJaWYgKGxi YTEgPD0gMjU2KQoJCQkJCQkJdG1wID0gY291bnRlcjE7CgkJCQkJCWJsb2NrW2NvdW50ZXIxKytd ID0gdG1wOwoJCQkJCX0gd2hpbGUgKGNvdW50ZXIxICE9IDUpOwoJCQkJfSBlbHNlIHsKCQkJCQli bG9ja1swXSA9IDI7CgkJCQkJYmxvY2tbMV0gPSAzOwoJCQkJCWJsb2NrWzJdID0gNDsKCQkJCQli bG9ja1szXSA9IDU7CgkJCQkJYmxvY2tbNF0gPSA2OwoJCQkJfQoJCQkJY291bnRlcjIgPSA2Mzg3 MjsKCQkJCWRvIHsKCQkJCQlpZiAoaWRiX2J1Zltjb3VudGVyMl0pIHsKCQkJCQkJc2l6ZSA9IDQg KiAoY291bnRlcjIgKyAxMjgpOwoJCQkJCQlnb3RvIGxhYmVsXzI4OwoJCQkJCX0KCQkJCQktLWNv dW50ZXIyOwoJCQkJfSB3aGlsZSAoY291bnRlcjIgIT0gNDA5Nik7CgkJCQlzaXplID0gbGJhMSA8 PCA5OwpsYWJlbF8yODoKCQkJCXdyaXRlX2lkYmxvY2soCgkJCQkJc2l6ZSwKCQkJCQlpZGJfYnVm LAoJCQkJCWJsb2NrKTsKCQkJCWlkYl93cml0ZV9lbmFibGUgPSAwOwoJCQkJZnRsX2ZyZWUoaWRi X2J1Zik7CgkJCQlpZGJfYnVmID0gMDsKCQkJCWdvdG8gbGFiZWxfMTQ7CgkJCX0KCQl9IGVsc2Ug ewoJCQlsYmEyID0gNTY0IC0gaW5kZXg7CgkJCWlmICg1NjQgLSBpbmRleCA+PSBjb3VudCkKCQkJ CWxiYTIgPSBjb3VudDsKCQkJZnRsX21lbWNweSgKCQkJCSh2b2lkICopCgkJCQkoaWRiX2J1ZiAr ICgoaW5kZXggLSA2NCkgPDwgOSkpLAoJCQkJYnVmLAoJCQkJbGJhMiA8PCA5KTsKCQl9CgkJaWYg KGlkYl9sYXN0X2xiYSAhPSBpbmRleCkgewoJCQlpZGJfd3JpdGVfZW5hYmxlID0gMDsKCQkJaWYg KGlkYl9idWYpCgkJCQlmdGxfZnJlZShpZGJfYnVmKTsKCQkJaWRiX2J1ZiA9IDA7CgkJfQpsYWJl bF8xNDoKCQlpZGJfbGFzdF9sYmEgPSBpbmRleCArIGNvdW50OwoJfQp9CgojZGVmaW5lIEdldElk YmxvY2tEYXRhTm9SYzQocCwgcykgUF9SQzQocCwgcykKCmludCBGdGxHZXRJZEJsb2NrU3lzRGF0 YSh2b2lkICpwX2J1ZiwgaW50IGluZGV4KQp7CglpZiAoaW5kZXggPiAzKQoJCXJldHVybiAtMTsK CWZ0bF9tZW1jcHkocF9idWYsICZnTmFuZElEYXRhQnVmW2luZGV4ICogNTEyXSwgNTEyKTsKCWlm IChpbmRleCA9PSAxKQoJCXJldHVybiAwOwoJR2V0SWRibG9ja0RhdGFOb1JjNChwX2J1ZiwgNTEy KTsKCXJldHVybiAwOwp9CgppbnQgRnRsR2V0Q2hpcFNlY3RvckluZm8odm9pZCAqcF9idWYpCnsK CXJldHVybiBGdGxHZXRJZEJsb2NrU3lzRGF0YShwX2J1ZiwgMik7Cn0KCmludCBGdGxHZXRTTlNl Y3RvckluZm8odm9pZCAqcF9idWYpCnsKCXJldHVybiBGdGxHZXRJZEJsb2NrU3lzRGF0YShwX2J1 ZiwgMyk7Cn0KCi8qIGluaXQgKi8KCglnRmxhc2hQYWdlQnVmZmVyMCA9CgkJKHVpbnQzMl90ICop CgkJZnRsX21hbGxvYygzMjc2OHUpOwoJZ0ZsYXNoUGFnZUJ1ZmZlcjEgPQoJCSh1aW50MzJfdCAq KQoJCWZ0bF9tYWxsb2MoMzI3Njh1KTsKCglnQmxvY2tQYWdlQWxpZ25TaXplID0gMTI4OwovKiBt b3JlIGluaXQgKi8KCgkJaWYgKEZsYXNoTG9hZFBoeUluZm8oKSkgewoKCQkJLyogc29ydCBvdXQg eW91ciBtZXNzIGhlcmUgKi8KCgkJCUZsYXNoU2F2ZVBoeUluZm8oKTsKCQl9CgovKiBtb3JlIGlu aXQgKi8KCglnRmxhc2hTbGNNb2RlID0gZ3BOYW5kUGFyYUluZm8tPnNsY19tb2RlOwoJZ05hbmRS YW5kb21pemVyID0gKGdwTmFuZFBhcmFJbmZvLT5vcGVyYXRpb25fb3B0ID4+IDcpICYgMTsKCWdN dWx0aVBhZ2VSZWFkRW4gPSAoZ3BOYW5kUGFyYUluZm8tPm9wZXJhdGlvbl9vcHQgPj4gMykgJiAx OwoJZ011bHRpUGFnZVByb2dFbiA9IChncE5hbmRQYXJhSW5mby0+b3BlcmF0aW9uX29wdCA+PiA0 KSAmIDE7CglnRmxhc2hJbnRlcmZhY2VNb2RlID0gKGdwTmFuZFBhcmFJbmZvLT5vcGVyYXRpb25f b3B0ID4+IDgpICYgNzsKCglCdWlsZEZsYXNoTHNiUGFnZVRhYmxlKAoJCWdwTmFuZFBhcmFJbmZv LT5sc2JfbW9kZSwKCQkodWludDMyX3QpZ3BOYW5kUGFyYUluZm8tPnBhZ2VfcGVyX2JsayAvCgkJ KHVpbnQzMl90KWdwTmFuZFBhcmFJbmZvLT5jZWxsKTsKCglGbGFzaFJlYWRJZGJEYXRhUmF3KGdO YW5kSURhdGFCdWYpOwoKCWdOYW5kSURCUmVzQmxrTnVtID0gMTY7CglnTmFuZFBoeUluZm8ubmFu ZF90eXBlID0KCQlncE5hbmRQYXJhSW5mby0+Y2VsbDsKCWdOYW5kUGh5SW5mby52ZW5kb3IgPQoJ CWdwTmFuZFBhcmFJbmZvLT52ZW5kb3I7CglnTmFuZFBoeUluZm8uY2hpcF9pZCA9CgkJKih1aW50 MzJfdCAqKUlEQnl0ZTsKCWdOYW5kUGh5SW5mby5kaWVfbnVtID0KCQlnTmFuZE1heERpZTsKCWdO YW5kUGh5SW5mby5wYWdlX3Blcl9ibGsgPQoJCWdwTmFuZFBhcmFJbmZvLT5wYWdlX3Blcl9ibGs7 CglnTmFuZFBoeUluZm8uYmxrX3Blcl9wbGFuZSA9CgkJZ3BOYW5kUGFyYUluZm8tPmJsa19wZXJf cGxhbmU7CglnTmFuZFBoeUluZm8ucGxhbmVzX3Blcl9kaWUgPQoJCWdwTmFuZFBhcmFJbmZvLT5w bGFuZV9wZXJfZGllOwoJZ05hbmRQaHlJbmZvLnBhZ2VfcGVyX3NsY19ibGsgPQoJCSh1aW50MzJf dClncE5hbmRQYXJhSW5mby0+cGFnZV9wZXJfYmxrIC8KCQkodWludDMyX3QpZ3BOYW5kUGFyYUlu Zm8tPmNlbGw7CglnTmFuZFBoeUluZm8uc2VjdG9yX3NpemUgPQoJCTUxMjsKCWdOYW5kUGh5SW5m by5zZWNfcGVyX3BhZ2UgPQoJCWdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2U7CglnTmFuZFBo eUluZm8ucmVzZXJ2ZWRfYmxrcyA9CgkJMTY7CglnTmFuZFBoeUluZm8uYmxvY2tfc2l6ZSA9CgkJ Z3BOYW5kUGFyYUluZm8tPnBhZ2VfcGVyX2JsayAqCgkJZ3BOYW5kUGFyYUluZm8tPnNlY19wZXJf cGFnZTsKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX18KTGludXggTVREIGRpc2N1c3Npb24gbWFpbGluZyBsaXN0Cmh0dHA6Ly9saXN0cy5pbmZy YWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtbXRkLwo= 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=-13.0 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,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 687A5C33CA7 for ; Sun, 12 Jan 2020 17:26:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 1A5042084D for ; Sun, 12 Jan 2020 17:26:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="p0uJ/F5g"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sJ/bBz+I" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1A5042084D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date: Message-ID:From:References:To:Subject:Reply-To:Content-ID:Content-Description :Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=+wwDBysJ3TjZtENKlWr6BkTC8Jr9CUXGmuHo9QxjQv0=; b=p0uJ/F5g6I8kT+ nhqIRnePCKQGTSlD6n0eammkWqvf3rGrA90nDnyzgO1oKm0QAHbnyfSZJwFT8dW9JUMhfD8LL+qHX ihl4kN5mNVWtCMBPIjHOicI4GKi5UsNWbJR24Zv9QFd4EeAn4ZZJyxWfMrtntZwPWbB10q/KPGRTj HkAqeZjoiPpPIJZIGiTNzknWl/OuFU0gm567golwPespwYmDN6vh7sG4SEh2cq75HWrO5l6Szzrcj F/a90mub2xWlYfNKe5StYqjszaKbE0WplHPxgyGlyit7KmugqOMqtFi8mDl8K+RvvAn1DUbnIUvza 0Z2d8OFavlw51adGmtNQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iqh0X-0001Mn-67; Sun, 12 Jan 2020 17:26:37 +0000 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iqh0O-00012Z-1Q; Sun, 12 Jan 2020 17:26:34 +0000 Received: by mail-wr1-x443.google.com with SMTP id t2so6357065wrr.1; Sun, 12 Jan 2020 09:26:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=xVRZT7YHVPE3GbyttbmSvMk99hkpTLXEzonadfBniK0=; b=sJ/bBz+I6AX+VbqaGHYqU8oVcVl/3fSB0h+kVMFnrusHsAraBxY0dWeSBp/G6dF6VS KC3iiITMz4jGvTyFgMdWFv/IKS0nvXQGjasscb3dfzY5UDXLcJ8F43s9WRibK76KLk2I c4tCo4dpuJ0itfQSWTdmYgfgkTHkMqoI1jEQJmcC6AYjiCK5vcexTiLyYWe+2oaf1D7X n1xemEpadN4Z3XRFXs7Ysx4/EzdtgFKlHMLMD3Jwv7S28I230Ek2qNGbLPva3NdGiWEt zyqdsLAx3UCcNjPnhi4d1sx3JnxiT305p4d9Q7DL03PDA9H5c2Tr5gIytdsAZv2wKxVJ WQqw== 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=xVRZT7YHVPE3GbyttbmSvMk99hkpTLXEzonadfBniK0=; b=eC/NEVAWvs4lV9HAT3WospQ6KFzAVv+qE1fKqpbKTdvm6BDwrj3ub1NQvwdkK83FaZ 5YkqoTo6EIBtgwFY0OfkiFToG4G3GBdOEiQPu9Cxa7WKp4PIWQ9sizLju4dUn8XF0JSp nNHypsiZ4wMsoPVUyMSOe8uiAitcuvgO8F0tWLpIx5g2Qln1/PcdocomXnjp6ZfDMIq9 MpPRtNCYZVoEOHc5C5PbH+SYIDvBK3H4RGDBB0OG5SvlwKc+fypHigxZQVs4EbEeXTpb dFBvo8tEabDJzj+Z9Pbi9Z8FFxc+qeojoA6bDa/6B6Aratq4rxT6Qgr+o0i+3OHiX0HM qArw== X-Gm-Message-State: APjAAAWamXYH6P6qB17VZd0N1nZ4//804SI9Zcil3HfHsP72dabxRr+k A6+MIsbjQbWMOVp/ReII1d0= X-Google-Smtp-Source: APXvYqyNJb2sZ+BEdl8Qe/N/WrvcZaNsBPjLBsFGSsIaeCCg3xu/NTbmYXVL2WXphD8eiIaYdsHO/Q== X-Received: by 2002:adf:fbc9:: with SMTP id d9mr14694899wrs.20.1578849984608; Sun, 12 Jan 2020 09:26:24 -0800 (PST) Received: from [192.168.2.1] (ip51ccf9cd.speed.planet.nl. [81.204.249.205]) by smtp.gmail.com with ESMTPSA id 4sm10505338wmg.22.2020.01.12.09.26.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 12 Jan 2020 09:26:23 -0800 (PST) Subject: Re: [RFC PATCH v1 02/10] mtd: nand: raw: add rockchip nand controller driver To: Miquel Raynal References: <20200108205338.11369-1-jbx6244@gmail.com> <20200108205338.11369-3-jbx6244@gmail.com> <20200110120534.1b4026b0@xps13> From: Johan Jonker Message-ID: <7a477af0-1448-4f26-4004-9331978e824c@gmail.com> Date: Sun, 12 Jan 2020 18:26:20 +0100 User-Agent: Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Thunderbird/68.3.0 MIME-Version: 1.0 In-Reply-To: <20200110120534.1b4026b0@xps13> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200112_092628_298994_4C76E6BF X-CRM114-Status: GOOD ( 32.18 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, vigneshr@ti.com, richard@nod.at, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, robh+dt@kernel.org, linux-mtd@lists.infradead.org, linux-arm-kernel@lists.infradead.org, heiko@sntech.de Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgTWlxdWVsLAoKVGhhbmsgeW91IGZvciB5b3VyIGRldGFpbGVkIGFuZCB1c2VmdWwgcmV2aWV3 LgoKV2l0aG91dCBtYW51ZmFjdHVyZXIgc3VwcG9ydCBJIG11c3Qgc2NyYXBlIG15IGluZm9ybWF0 aW9uCmZyb20gYWxsIG92ZXIgdGhlIGludGVybmV0LCB0b2dldGhlciB3aXRoIHNsb3cgaW50ZXJw cmV0YXRpb24gb2YKUm9ja2NoaXAgZHJpdmVycy4KU28gcGxlYXNlIGhhdmUgc29tZSBwYXRpZW5j ZSB3aXRoIG15IHVwZGF0ZXMgYW5kIG5ldyB2ZXJzaW9ucy4KCkJlbG93IGFyZSBzb21lIGNvbW1l bnRzIGFuZCBxdWVzdGlvbnMgaW4gcmFuZG9tIG9yZGVyLgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8KClRvIHByZXZlbnQgZ3Vlc3NpbmcgZ2FtZXMgY291bGQgeW91IGNvbmZpcm0gdGhl IGZvbGxvd2luZyBuYW1lczoKCmRyaXZlciBmaWxlIG5hbWU6ICAgcm9ja2NoaXAtbmFuZC1jb250 cm9sbGVyLmMKZG9jdW1lbnQgZmlsZSBuYW1lOiByb2NrY2hpcC1uYW5kLWNvbnRyb2xsZXIueWFt bAoKY29tcGF0aWJsZTogInJvY2tjaGlwLG5hbmRjLXY2Igpjb21wYXRpYmxlOiAicm9ja2NoaXAs bmFuZGMtdjkiCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKTXkgaW5jb21wbGV0ZSBz b3J0IGxpc3QgZm9yIGNvbnRyb2xsZXIgdmVyc2lvbnMuCgpDYW4gc29tZW9uZSB3aXRoIGFjY2Vz cyB0byB0aGUgUlYxMTA4IFRSTSAobWFudWFsKSByZXBvcnQgdGhlIGRldGFpbHMKZm9yIHRoZSBO YW5kYyBWZXJzaW9uIFJlZ2lzdGVyIGFuZCB3aGV0aGVyIGl0IGlzIGNvbXBhdGlibGUuIFRoYW5r cy4KCkFkZGVkIHZlcnNpb24gNyBmb3IgUkszMjI4QS9SSzMyMjhCLiBDYW4gc29tZW9uZSB3aXRo IGluc2lkZXIgaW5mbyBjb25maXJtCmlmIHRoaXMgd29ya3Mgb3Igbm90LgoKUkszMDY2L1BYMgpO QU5EQ19OQU5EQ19WRVIgMHgwMTYwIFcgMHg1NjM2MzAzMCBOYW5kYyBWZXJzaW9uIFJlZ2lzdGVy CgpSSzMxODgKTkFORENfTkFORENfVkVSIDB4MDE2MCBXIDB4NTYzNjMwMzAgTmFuZGMgVmVyc2lv biBSZWdpc3RlcgoKUFgzCk5BTkRDX05BTkRDX1ZFUiAweDAxNjAgVyAweDU2MzYzMDMwIE5hbmRj IFZlcnNpb24gUmVnaXN0ZXIKClJLMzEyWApOQU5EQ19OQU5EQ19WRVIgMHgwMTYwIFcgMHg1NjM2 MzIzMiBOYW5kYyBWZXJzaW9uIFJlZ2lzdGVyCgpSSzMyODgKTkFORENfTkFORENfVkVSIDB4MDE2 MCBXIDB4NTYzNjMyMzIgTmFuZGMgVmVyc2lvbiBSZWdpc3RlcgoKUkszMzY4L1BYNQpOQU5EQ19O QU5EQ19WRVIgMHgwMTYwIFcgMHg1NjM2MzIzMiBOYW5kYyBWZXJzaW9uIFJlZ2lzdGVyCgpSSzMy MjhBL1JLMzIyOEIKTkFORENfTkFORENfVkVSIDB4MDE2MCBXIDB4MDAwMDA3MDEgTmFuZGMgVmVy c2lvbiBSZWdpc3RlcgoKUkszMzA4Ck5BTkRDX05BTkRDX1ZFUiAweDAxNjAgVyAweDAwMDAwODAx IE5hbmRjIFZlcnNpb24gUmVnaXN0ZXIKClJLMzMyNi9QWDMwCk5BTkRDX05BTkRDX1ZFUiAweDAw ODAgVyAweDU2MzkzMDMwIE5hbmRjIFZlcnNpb24gUmVnaXN0ZXIKClJLMzMyOApOTyBOQU5EQwoK UkszMzk5Ck5PIE5BTkRDCgpSVjExMDgKdW5rbm93bgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8KCk15IGRlYnVnIGtlcm5lbC5sb2cgd2l0aCAxIHBhcnRpdGlvbiBpbiBkdHMuCgpKYW4g IDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDUxNTg3XSByb2NrY2hpcC1uYW5kYwox MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IGdldCBjbGtfbmFuZGMgZmFpbGVkCkphbiAgMSAwMDow MjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTI0MDJdIG5hbmQ6IGRldmljZSBmb3VuZCwKTWFu dWZhY3R1cmVyIElEOiAweGFkLCBDaGlwIElEOiAweGRlCkphbiAgMSAwMDowMjoyNyBtazgwOCBr ZXJuZWw6IFsgIDE0Ny4wNTI5NDVdIG5hbmQ6IEh5bml4IEgyN1VDRzhUMkFUUi1CQwo2NEcgMy4z ViA4LWJpdApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDUzMzg4XSBuYW5k OiA4MTkyIE1pQiwgTUxDLCBlcmFzZQpzaXplOiAyMDQ4IEtpQiwgcGFnZSBzaXplOiA4MTkyLCBP T0Igc2l6ZTogNjQwCkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTQwNTBd IHJvY2tjaGlwLW5hbmRjCjEwNTAwMDAwLm5hbmQtY29udHJvbGxlcjogbmFuZC0+bnVtY2hpcHMg PSAxCkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTQ3NDBdIHJvY2tjaGlw LW5hbmRjCjEwNTAwMDAwLm5hbmQtY29udHJvbGxlcjogbmFuZC0+Y2hpcHNpemUgPSA4NTg5OTM0 NTkyCkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNTUzODBdIHJvY2tjaGlw LW5hbmRjCjEwNTAwMDAwLm5hbmQtY29udHJvbGxlcjogbmFuZC0+cGFnZW1hc2sgPSAgICBmZmZm ZgpKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDU1OTk0XSByb2NrY2hpcC1u YW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmJhZGJsb2NrcG9zID0gMApKYW4g IDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDU2NTkxXSByb2NrY2hpcC1uYW5kYwox MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmNoaXBfc2hpZnQgPSAzMwpKYW4gIDEgMDA6 MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDU3MTc0XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAw MC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPnBhZ2Vfc2hpZnQgPSAxMwpKYW4gIDEgMDA6MDI6Mjcg bWs4MDgga2VybmVsOiBbICAxNDcuMDU3NzUxXSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXI6IG5hbmQtPnBoeXNfZXJhc2Vfc2hpZnQgPSAyMQpKYW4gIDEgMDA6MDI6Mjcg bWs4MDgga2VybmVsOiBbICAxNDcuMDU4MzY2XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXI6IG5hbmQtPmVjYy5tb2RlID0gMwpKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2Vy bmVsOiBbICAxNDcuMDU4OTIwXSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xs ZXI6IG5hbmQtPmVjYy5zdGVwcyA9IDgKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDogWyAg MTQ3LjA1OTQ4MV0gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9sbGVyOiBuYW5k LT5lY2MuYnl0ZXMgPSA3MApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYw MDQ5XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmVjYy50 b3RhbCA9IDAKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDogWyAgMTQ3LjA2MDYwN10gcm9j a2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9sbGVyOiBuYW5kLT5lY2MucHJlcGFkID0g NApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYxMTc1XSByb2NrY2hpcC1u YW5kYwoxMDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmVjYy5zaXplID0gMTAyNApKYW4g IDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYxNzQ4XSByb2NrY2hpcC1uYW5kYwox MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXI6IG5hbmQtPmVjYy5zdHJlbmd0aCA9IDQwCkphbiAgMSAw MDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNjIzNDFdIHJvY2tjaGlwLW5hbmRjCjEwNTAw MDAwLm5hbmQtY29udHJvbGxlcjogbXRkLT5vb2JsYXlvdXQgPSA5MWNlOWNlMgpKYW4gIDEgMDA6 MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDYyOTQzXSByb2NrY2hpcC1uYW5kYwoxMDUwMDAw MC5uYW5kLWNvbnRyb2xsZXI6IG10ZC0+ZmxhZ3MgPSAwMDAwMDAwMApKYW4gIDEgMDA6MDI6Mjcg bWs4MDgga2VybmVsOiBbICAxNDcuMDYzNTE4XSByb2NrY2hpcC1uYW5kYwoxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXI6IG10ZC0+c2l6ZSA9IDg1ODk5MzQ1OTIKSmFuICAxIDAwOjAyOjI3IG1rODA4 IGtlcm5lbDogWyAgMTQ3LjA2NDA5OF0gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250 cm9sbGVyOiBtdGQtPmVyYXNlc2l6ZSA9IDIwOTcxNTIKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtl cm5lbDogWyAgMTQ3LjA2NDgxNV0gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9s bGVyOiBtdGQtPndyaXRlc2l6ZSA9IDgxOTIKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDog WyAgMTQ3LjA2NTQxM10gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250cm9sbGVyOiBt dGQtPm9vYnNpemUgPSA2NDAKSmFuICAxIDAwOjAyOjI3IG1rODA4IGtlcm5lbDogWyAgMTQ3LjA2 ODk4NV0gMSBmaXhlZC1wYXJ0aXRpb25zCnBhcnRpdGlvbnMgZm91bmQgb24gTVREIGRldmljZSAx MDUwMDAwMC5uYW5kLWNvbnRyb2xsZXIuMApKYW4gIDEgMDA6MDI6MjcgbWs4MDgga2VybmVsOiBb ICAxNDcuMDY5MTkwXSBDcmVhdGluZyAxIE1URCBwYXJ0aXRpb25zCm9uICIxMDUwMDAwMC5uYW5k LWNvbnRyb2xsZXIuMCI6CkphbiAgMSAwMDowMjoyNyBtazgwOCBrZXJuZWw6IFsgIDE0Ny4wNzIz NzVdCjB4MDAwMDAwMDAwMDAwLTB4MDAwMDAwNDAwMDAwIDogInBhcmFtZXRlciIKCgpKYW4gIDEg MDA6MDI6MjcgbWs4MDgga2VybmVsOiBbICAxNDcuMDc1NjQ5XSByb2NrY2hpcC1uYW5kYwoxMDUw MDAwMC5uYW5kLWNvbnRyb2xsZXI6IFI6MHgwMGZmIGNzOjAKSmFuICAxIDAwOjAyOjI3IG1rODA4 IGtlcm5lbDogWyAgMTQ3LjA3OTQyM10gcm9ja2NoaXAtbmFuZGMKMTA1MDAwMDAubmFuZC1jb250 cm9sbGVyOiBSOjB4MDFmZiBjczowCgoKRGVzcGl0ZSBuYW5kLT5vcHRpb25zID0gTkFORF9TS0lQ X0JCVFNDQU4uCgpXaGF0IGlzIHRoZSByZWFzb24gZm9yIHRoZXNlIDIgcmtfbmFuZGNfaHdfc3lu ZHJvbWVfZWNjX3JlYWRfcGFnZSgpIGNvbW1hbmRzCmF0IHBhZ2UgUjoweDAwZmYgYW5kIFI6MHgw MWZmIHJpZ2h0IGFmdGVyIGNyZWF0aW5nIHBhcnRpdGlvbnMuCgpXaGVuIGVuYWJsZWQgQkJUU0NB TiBNVEQgc3RhcnRzIHRvIHN0b3JlIGF0IGFsbCBraW5kIG9mIHBsYWNlcy4gQ2FuIHlvdQpzdGF0 ZQp0aGVyZSBwYWdlIGFkZHJlc3MgbG9naWMsIGllLiBXb3VsZCB0aGF0IGRhbWFnZSB0aGUgZXhj aXN0aW5nIFJvY2tjaGlwCmxheW91dD8KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpO byBiYWQgYmxvY2sgc3VwcG9ydAoKQmFzZWQgb246CmRyaXZlcnM6IG10ZDogbmFuZDogcm9ja2No aXAgbmFuZGMgYWRkIGJhZCBibG9jayBkZXRlY3QgYXBpCmh0dHBzOi8vZ2l0aHViLmNvbS9yb2Nr Y2hpcC1saW51eC91LWJvb3QvY29tbWl0Lwo3YWVjNzA0YTRlOWQ5MzIyZjExMDJiY2Y2MWVlNWMz Y2Y2ZWM3OTRkCgpyb2NrY2hpcDogZHJpdmVyczogbXRkOiBuYW5kOiBtb2RpZnkgdGhlIGJhZCBi bG9jayBkZXRlY3Rpb24gcHJvY2VzcwpodHRwczovL2dpdGh1Yi5jb20vcm9ja2NoaXAtbGludXgv dS1ib290L2NvbW1pdC8KZDZkNzA4ZDFhMzI5YTYzNjkxNDNlOGRkMzRjZjRlMmM4MWQ1ZDkyZgoK QkNIICAgICAgfCAgICAgIG9vYiBzaXplCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoxNjogYnl0 ZXM6IDI4ICsgNCA9IDMyCjI0OiBieXRlczogNDIgKyA0ID0gNDYKNDA6IGJ5dGVzOiA3MCArIDQg PSA3NAo2MDogYnl0ZXM6IDEwNiArIDQgPSAxMTAKClRoZSBkYXRhIGxheW91dCB0aGF0IGlzIHdy aXR0ZW4gYnkgYW4gaW50ZXJuYWwgUm9ja2NoaXAgbmFuZGMgZG1hIGlzOgogICAgMTAyNCBieXRl cyBkYXRhICsgMzIgb2JiICsgMTAyNCBkYXRhICsgMzIgb2JiIC4uLgoKVGhlIE1URCBzeXN0ZW0g aG93ZXZlciB0cmllcyB0byBkZXRlY3QgYmFkIGJsb2NrIGZsYWdzIGxvY2F0ZWQgYXQ6CiAgICAy MDQ4LCA0MDk2LCA4MTkyLi4uCgpUaGUgc3lzdGVtIGNoZWNrcyBmb3IgYmFkIGJsb2NrcyBhbmQg bG9va3MgYXQgdGhlIHdyb25nIGJhZCBibG9jayBtYXJrZXIKbG9jYXRpb24uCllpZmVuZyBaaGFv IHByb3Bvc2VzIHRvIGFkZCBhIGJhZCBibG9jayBkZXRlY3Rpbmcgc3RyYXRlZ3kgYnkgZG9pbmcK YSByZWFkIHdpdGggcmtfbmFuZGNfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZSgpIGZpcnN0LApp ZiBmYWlsdXJlIHRoZW4gYXNzdW1lIGl0J3Mgc3RpbGwgcmF3IHVud3JpdHRlbiBOQU5EIGFuZCB0 ZXN0IGJ5dGVzIGFyZQphdCB0aGUgcG9zaXRpb24gTVREIG5vcm1hbHkgd291bGQgY2hlY2sgZm9y IHJpZ2h0IGZyb20gdGhlIGZhY3RvcnkuCldoZW4gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIG9uIGEg RlRMIGNvbnRyb2xsZWQgTkFORCBpdCBjcmVhdGVzCmFuIGF3ZnVsIGxvdCBvZiBlcnJvcnMgaW4g dGhlIGtlcm5lbCBsb2csIGJlY2F1c2UgaXQgdXNlcyB0aGUgQkIgbWFya2VyCmZvciBkaXJ0eSB0 YWcgdHJpY2tzIGZvciB0aGVyZSBkYXRhIHN0b3JhZ2UuClNvIHdoYXQgaXMgZ29vZCBmb3IgYSBy YXcgZW1wdHkgTkFORCB3aXRob3V0IEZUTApkb2VzIG5vdCB3b3JrIGZvciB0aGUgbWFqb3JpdHkg b2YgUm9ja2NoaXAgZGV2aWNlcyBJIHRoaW5rLgoKUGxlYXNlIGFkdmlzZSBmb3Igb3RoZXIgb3B0 aW9ucy4KCnN0YXRpYyB1aW50OF90IHJrX25hbmRfcmVhZF9ieXRlKHN0cnVjdCBuYW5kX2NoaXAg Km5hbmQpCnsKCXVpbnQ4X3QgcmV0OwoKCXJrX25hbmRfcmVhZF9idWYobmFuZCwgJnJldCwgMSk7 CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBya19uYW5kX2Jsb2NrX2JhZChzdHJ1Y3QgbmFu ZF9jaGlwICpuYW5kLCBsb2ZmX3Qgb2ZzKQp7CglzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRf dG9fbXRkKG5hbmQpOwoJaW50IHBhZ2UsIHJlcyA9IDA7Cgl1MTYgYmFkID0gMHhmZjsKCXU4ICpi dWYgPSBuYW5kX2dldF9kYXRhX2J1ZihuYW5kKTsKCWludCBjaGlwbnIgPSAoaW50KShvZnMgPj4g bmFuZC0+Y2hpcF9zaGlmdCk7CgoJcGFnZSA9IChpbnQpKG9mcyA+PiBuYW5kLT5wYWdlX3NoaWZ0 KSAmIG5hbmQtPnBhZ2VtYXNrOwoJcmtfbmFuZF9zZWxlY3RfY2hpcChuYW5kLCBjaGlwbnIpOwoJ aWYgKHJrX25hbmRfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZShuYW5kLCBidWYsIGZhbHNlLCBw YWdlKSA9PSAtMSkgewoJCS8qIGZpcnN0IHBhZ2Ugb2YgYSBibG9jayovCgkJbmFuZF9yZWFkX3Bh Z2Vfb3AobmFuZCwgcGFnZSwgbmFuZC0+YmFkYmxvY2twb3MsIE5VTEwsIDApOwoJCWJhZCA9IHJr X25hbmRfcmVhZF9ieXRlKG5hbmQpOwoJCWlmIChiYWQgIT0gMHhGRikKCQkJcmVzID0gMTsKCQkv KiBzZWNvbmQgcGFnZSBvZiBhIGJsb2NrKi8KCQluYW5kX3JlYWRfcGFnZV9vcChuYW5kLCBwYWdl ICsgMSwgbmFuZC0+YmFkYmxvY2twb3MsIE5VTEwsIDApOwoJCWJhZCA9IHJrX25hbmRfcmVhZF9i eXRlKG5hbmQpOwoJCWlmIChiYWQgIT0gMHhGRikKCQkJcmVzID0gMTsKCQkvKiBsYXN0IHBhZ2Ug b2YgYSBibG9jayAqLwoJCXBhZ2UgKz0gKChtdGQtPmVyYXNlc2l6ZSAtIG10ZC0+d3JpdGVzaXpl KSA+PiBuYW5kLT5jaGlwX3NoaWZ0KTsKCQlwYWdlLS07CgkJbmFuZF9yZWFkX3BhZ2Vfb3AobmFu ZCwgcGFnZSwgbmFuZC0+YmFkYmxvY2twb3MsIE5VTEwsIDApOwoJCWJhZCA9IHJrX25hbmRfcmVh ZF9ieXRlKG5hbmQpOwoJCWlmIChiYWQgIT0gMHhGRikKCQkJcmVzID0gMTsKCX0KCXJrX25hbmRf c2VsZWN0X2NoaXAobmFuZCwgLTEpOwoJcmV0dXJuIHJlczsKfQoKVGhpcyBhbHNvIHJlcXVpcmVz IGEgcGF0Y2ggZm9yIG5hbmRfYmJ0LmMKQXMgSSB0cnkgdG8gZ2V0IHRvIGdldCBzb21lIHNoYXBl IGluIHRoZSByZXN0IG9mIHRoaXMgZHJpdmVyLApJIGhhdmUgbGVmdCBpdCBvdXQgZm9yIHZlcnNp b24gMSBhbmQgYXMgSSB3YWl0IGZvciBvdXIgcmVzcG9ucyBmaXJzdC4KCmRyaXZlcnMvbXRkL25h bmQvbmFuZF9iYnQuYwpAQCAtNDg3LDggKzQ4NywxMCBAQCBzdGF0aWMgaW50IGNyZWF0ZV9iYnQo c3RydWN0IG10ZF9pbmZvICptdGQsIHVpbnQ4X3QKKmJ1ZiwKCQlpbnQgcmV0OwoKCQlCVUdfT04o YmQtPm9wdGlvbnMgJiBOQU5EX0JCVF9OT19PT0IpOwoKCQlyZXQgPSBzY2FuX2Jsb2NrX2Zhc3Qo bXRkLCBiZCwgZnJvbSwgYnVmLCBudW1wYWdlcyk7CgkJaWYgKHRoaXMtPmJsb2NrX2JhZCkKCQkJ cmV0ID0gdGhpcy0+YmxvY2tfYmFkKG10ZCwgZnJvbSk7CgkJZWxzZQoJCQlyZXQgPSBzY2FuX2Js b2NrX2Zhc3QobXRkLCBiZCwgZnJvbSwgYnVmLCBudW1wYWdlcyk7CgovLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLwoKRGF0YSBzdHJ1Y3R1cmVzL1BhcnRpdGlvbnMKClRoZSBtYWpvcml0eSBv ZiBSb2NrY2hpcCBkZXZpY2VzIHVzZSBhIGNsb3NlZCBzb3VyY2UgRlRMIGRyaXZlciwKc28gd2hl biB3ZSB3YW50IHRvIHJlYWQgb3Igd3JpdGUgd2UgbXVzdCBkZWFsIHdpdGggaXQuCgpFeGFtcGxl IE1URCBzdHJpbmc6Cm10ZHBhcnRzPXJrMjl4eG5hbmQ6CjB4MDAwMDIwMDBAMHgwMDAwMjAwMCht aXNjKSwKMHgwMDAwODAwMEAweDAwMDA0MDAwKGtlcm5lbCksCjB4MDAwMDgwMDBAMHgwMDAwQzAw MChib290KSwKMHgwMDAwODAwMEAweDAwMDE0MDAwKHJlY292ZXJ5KSwKMHgwMDBDMDAwMEAweDAw MDFDMDAwKGJhY2t1cCksCjB4MDAwNDAwMDBAMHgwMDBEQzAwMChjYWNoZSksCjB4MDAzMDAwMDBA MHgwMDExQzAwMCh1c2VyZGF0YSksCjB4MDAwMDIwMDBAMHgwMDQxQzAwMChrcGFuaWMpLAoweDAw MjAwMDAwQDB4MDA0MUUwMDAoc3lzdGVtKSwKLUAweDAwNjNFMDAwKHVzZXIpIgoKV2hlbiBSb2Nr Y2hpcCBtZW50aW9ucyBhIHN0cmluZyBsaWtlIHRoaXMgaXQgaGFzIG5vdGhpbmcgdG8gZG8Kd2l0 aCB0aGUgcmVhbCBwb3NpdGlvbiBvbiBOQU5ELiBGVEwgd3JpdGUgd2hlcmUgd2FudHMsCnNvIHJl YWRpbmcgdGhlcmUgaXMgbm90IHVzZWZ1bC4KQWxsIHNpemVzIGhhdmUgdG8gYmUgbXVsdGlwbGll ZCBieSA1MTIgYW5kIGNhc3RlZCB0byAodTY0KSEKQWxsIHBhcnRpdGlvbnMgbmVlZCB0byBjb250 YWluIGF0IGxlYXN0IDIgZXJhc2UgYmxvY2tzLgpPbmUgZm9yIG5vcm1hbCB1c2UgYW5kIG9uZSBz cGFyZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tCkZsYXNoU2F2ZVBoeUluZm8KUmF3SWRiRGF0YQot LS0tLS0tLS0tLS0tLS0tLS0tLQouLi4KRlRMIGRhdGEKLi4uCi0tLS0tLS0tLS0tLS0tLS0tLS0t Ck1hcCBibG9ja3M6CisgTDJwTWFwSW5mbworIFZlbmRvckJsa0luZm8KClN5cyBpbmZvOgorIHN5 c19zYXZlX2RhdGEKClZlbmRvciBwYXJ0aXRpb246Cisgc3lzX2V4dF9kYXRhICAgIDAKKyBlY3Rf dGJsX2luZm8gICA2NAorIHZlbmRvciAgICAgICAgMjU2ICsgPworIEJvb3RDb25maWcgICAgNTEy ICsgMAorIERybUtleUluZm8gICAgNTEyICsgMQorIFZlbmRvcjBJbmZvICAgNTEyICsgMgorIFZl bmRvcjFJbmZvICAgNTEyICsgMworIHN5cyAgICAgICAgICAgNTEyICsgPworIHB1YmxpYyBrZXkg ICAgNTIwCi0tLS0tLS0tLS0tLS0tLS0tLS0tCkJhZCBCbG9jayBNYXAgVGJsKG5vdCBjb21wYXRp YmxlIHdpdGggTVREKQotLS0tLS0tLS0tLS0tLS0tLS0tLQpyZXNlcnZlZDogbGFzdCBOQU5EIGJs b2NrIC0gbgotLS0tLS0tLS0tLS0tLS0tLS0tLQoKRnJvbSB0aGUgYWJvdmUgZGlhZ3JhbSBvbmx5 IFJhd0lkYkRhdGEgaGFzIHRvIGJlIGxvY2F0ZWQgaW4gdGhlIGZpcnN0CmVyYXNlIGJsb2NrLgpC b290IFJPTSBzZWFyY2hlcyBmb3IgdGhlIHRhZyBJRF9JRFJXID0gMHhGQ0RDOEMzQi4KT25seSB0 aGUgZmlyc3QgNCBzZWN0aW9ucyAoNCoxMDI0KSBvZiBhIHBhZ2UgYXJlIHVzZWQuCldoZW4gd3Jp dGluZyBtdWx0aXBsZSBwYWdlcyBleHRyYSBzcGFjZXMgaW4gdGhlIGRhdGEKZm9yIGJldHdlZW4g dGhlIHNlY3Rpb25zIGFyZSByZXF1aXJlZC4KT2xkZXIgY3B1J3MgKFJLMzA2NikgbWlnaHQgbmVl ZCBleHRyYSBSQzQgY29kaW5nLgoKRlRMIHVzZXMgdGhhdCBSYXdJZGJEYXRhIGFyZWEgdW5mb3J0 dW5hdGVseSBhbHNvIHRvIHNhdmUgc3RydWN0CkZsYXNoU2F2ZVBoeUluZm8uCkZvciBhIGJhcmUg YmFzaWMgYXBwbGljYXRpb24gb25seSBSYXdJZGJEYXRhIGlzIG5lZWRlZC4KCkZvciB1c2VycyB0 aGF0IG1pZ2h0IGNvbnNpZGVyIE1URCBhcyBhIG9wdGlvbiB0byBkbyBzb21ldGhpbmcgb24gYQpS b2NrY2hpcCBOQU5ECnNlZSB0aGUgc291cmNlIGNvZGUgYmVsb3cgdG8gZ2V0IGFuIGluZGljYXRp b24gb2Ygd2hhdCBpcyBuZWVkZWQgZm9yIGEKdXNlZnVsCnNldHVwIHRvIGp1c3QgcmVhZCBhbmQg d3JpdGUgYSBib290bG9hZGVyIGFsb25lLiBXcml0aW5nIG9mIGFueSB1c2VyCnBhcnRpdGlvbgpp cyBub3QgZXZlbiBpbmNsdWRlZC4KSGF2aW5nIGEgYmFzaWMgTVREIGRyaXZlciBpcyBqdXN0IG5v dCBlbm91Z2guClBsZWFzZSBhZHZpc2UgaWYgc3VjaCBhIG92ZXJoZWFkIGNhbiBpbnRlcmZhY2Ug d2l0aCBNVEQ/CkhhdmUgZnVuIQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCk9uIDEv MTAvMjAgMTI6MDUgUE0sIE1pcXVlbCBSYXluYWwgd3JvdGU6Cj4gSGkgSm9oYW4sCj4KPiBKb2hh biBKb25rZXIgPGpieDYyNDRAZ21haWwuY29tPiB3cm90ZSBvbiBXZWQsICA4IEphbiAyMDIwIDIx OjUzOjMwCj4gKzAxMDA6Cj4KPj4gRnJvbTogWWlmZW5nIFpoYW8gPHp5ZkByb2NrLWNoaXBzLmNv bT4KPj4KPgo+IENhbiB5b3UgY2hhbmdlIHRoZSB0aXRsZSB0byAibXRkOiByYXduYW5kOiByb2Nr Y2hpcDogQWRkIE5BTkQKPiBjb250cm9sbGVyIGRyaXZlciIKPgo+PiBBZGQgYmFzaWMgUm9ja2No aXAgbmFuZCBjb250cm9sbGVyIGRyaXZlci4KPj4KPj4gQ29tcGF0aWJsZSB3aXRoIGhhcmR3YXJl IHZlcnNpb24gNiBhbmQgOS4KPj4gVjY6MTYsIDI0LCA0MCwgNjAgcGVyIDEwMjRCIEJDSC9FQ0Mu Cj4+IFY5OjE2LCA0MCwgNjAsIDcwIHBlciAxMDI0QiBCQ0gvRUNDLgo+PiA4IGJpdCBhc3luY2hy b25vdXMgZmxhc2ggaW50ZXJmYWNlIHN1cHBvcnQuCj4+IFN1cHBvcnRzIHVwIHRvIDIgaWRlbnRp Y2FsIG5hbmRjIG5vZGVzLgo+PiBNYXggNCBuYW5kIGNoaXBzIHBlciBjb250cm9sbGVyLgo+PiBB YmxlIHRvIHNlbGVjdCBhIGRpZmZlcmVudCBoYXJkd2FyZSBlY2Mgc2V0dXAKPj4gZm9yIHRoZSBs b2FkZXIgYmxvY2tzLgo+PiBObyBiYWQgYmxvY2sgc3VwcG9ydC4KPgo+IFRoYW5rIHlvdSB2ZXJ5 IG11Y2ggZm9yIHRoaXMgc2VyaWVzLCBhcyB0aGUgYmFkIGJsb2NrcyBzdXBwb3J0IGlzCj4gYWJz b2x1dGVseSBmdW5kYW1lbnRhbCwgSSB3b25kZXIgd2hhdCBpcyB0aGUgaXNzdWUgaGVyZT8KPgo+ Pgo+PiBTaWduZWQtb2ZmLWJ5OiBZaWZlbmcgWmhhbyA8enlmQHJvY2stY2hpcHMuY29tPgo+PiBT aWduZWQtb2ZmLWJ5OiBKb2hhbiBKb25rZXIgPGpieDYyNDRAZ21haWwuY29tPgo+PiAtLS0KPj4g IGRyaXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcgICAgICAgICAgfCAgICA4ICsKPj4gIGRyaXZl cnMvbXRkL25hbmQvcmF3L01ha2VmaWxlICAgICAgICAgfCAgICAxICsKPj4gIGRyaXZlcnMvbXRk L25hbmQvcmF3L3JvY2tjaGlwX25hbmRjLmMgfCAxMjI0CisrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKwo+PiAgMyBmaWxlcyBjaGFuZ2VkLCAxMjMzIGluc2VydGlvbnMoKykKPj4gIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL210ZC9uYW5kL3Jhdy9yb2NrY2hpcF9uYW5kYy5jCj4+ Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnIGIvZHJpdmVycy9t dGQvbmFuZC9yYXcvS2NvbmZpZwo+PiBpbmRleCA3NGZiOTFhZGUuLjY4ZGM5YTM2ZCAxMDA2NDQK Pj4gLS0tIGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+PiArKysgYi9kcml2ZXJzL210 ZC9uYW5kL3Jhdy9LY29uZmlnCj4+IEBAIC00NTcsNiArNDU3LDE0IEBAIGNvbmZpZyBNVERfTkFO RF9DQURFTkNFCj4+ICAJICBFbmFibGUgdGhlIGRyaXZlciBmb3IgTkFORCBmbGFzaCBvbiBwbGF0 Zm9ybXMgdXNpbmcgYSBDYWRlbmNlIE5BTkQKPj4gIAkgIGNvbnRyb2xsZXIuCj4+Cj4+ICtjb25m aWcgTVREX05BTkRfUk9DS0NISVAKPj4gKwl0cmlzdGF0ZSAiUm9ja2NoaXAgcmF3IE5BTkQgY29u dHJvbGxlciBkcml2ZXIiCj4+ICsJZGVwZW5kcyBvbiBBUkNIX1JPQ0tDSElQIHx8IENPTVBJTEVf VEVTVAo+PiArCWRlcGVuZHMgb24gSEFTX0lPTUVNCj4+ICsJaGVscAo+PiArCSAgRW5hYmxlcyBz dXBwb3J0IGZvciB0aGUgUm9ja2NoaXAgcmF3IE5BTkQgY29udHJvbGxlciBkcml2ZXIuCj4+ICsJ ICBUaGlzIGNvbnRyb2xsZXIgaXMgZm91bmQgb24gcmszMDY2LCByazMxODgsIHJrMzI4OCBhbmQg bW9yZS4KPgo+IENhbiB5b3Ugd3JpdGUgYW4gZXhoYXVzdGl2ZSBsaXN0IGlmIHlvdSBrbm93IGl0 PyBPciBhdCBsZWFzdCB0aGUKPiBmYW1pbGllcz8gSXQgaXMgcXVpdGUgY2hhbGxlbmdpbmcgd2hl biB5b3UgYXJlIG5vdCBpbiB0aGUgUm9ja2NoaXAKPiB3b3JsZCB0byBrbm93IHdoYXQgU29DIGlz IHNpbWlsYXIgdG8gYW5vdGhlciByYW5kb20gU29DLgoKU2VlIGFib3ZlLgoKPgo+PiArCj4+ICBj b21tZW50ICJNaXNjIgo+Pgo+PiAgY29uZmlnIE1URF9TTV9DT01NT04KPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCmIvZHJpdmVycy9tdGQvbmFuZC9yYXcvTWFr ZWZpbGUKPj4gaW5kZXggMmQxMzZiMTU4Li4zMDYzZmU3NGEgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZl cnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L01h a2VmaWxlCj4+IEBAIC01OCw2ICs1OCw3IEBAIG9iai0kKENPTkZJR19NVERfTkFORF9URUdSQSkJ CSs9IHRlZ3JhX25hbmQubwo+PiAgb2JqLSQoQ09ORklHX01URF9OQU5EX1NUTTMyX0ZNQzIpCSs9 IHN0bTMyX2ZtYzJfbmFuZC5vCj4+ICBvYmotJChDT05GSUdfTVREX05BTkRfTUVTT04pCQkrPSBt ZXNvbl9uYW5kLm8KPj4gIG9iai0kKENPTkZJR19NVERfTkFORF9DQURFTkNFKQkJKz0gY2FkZW5j ZS1uYW5kLWNvbnRyb2xsZXIubwo+PiArb2JqLSQoQ09ORklHX01URF9OQU5EX1JPQ0tDSElQKQkJ Kz0gcm9ja2NoaXBfbmFuZGMubwo+Cj4gQSBkcml2ZXIgbmFtZWQgcm9ja2NoaXAtbmFuZC1jb250 cm9sbGVyLmMgd291bGQgYmUgbmljZSEKPgo+Pgo+PiAgbmFuZC1vYmpzIDo9IG5hbmRfYmFzZS5v IG5hbmRfbGVnYWN5Lm8gbmFuZF9iYnQubyBuYW5kX3RpbWluZ3MubwpuYW5kX2lkcy5vCj4+ICBu YW5kLW9ianMgKz0gbmFuZF9vbmZpLm8KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQv cmF3L3JvY2tjaGlwX25hbmRjLmMKYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9yb2NrY2hpcF9uYW5k Yy5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMC4uMDE4MzA4ZTU4 Cj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvcm9ja2NoaXBf bmFuZGMuYwo+PiBAQCAtMCwwICsxLDEyMjQgQEAKPj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wCj4+ICsvKgo+PiArICogQmFzZWQgb246Cj4+ICsgKgpodHRwczovL2dpdGh1 Yi5jb20vcm9ja2NoaXAtbGludXgva2VybmVsL2Jsb2IvZGV2ZWxvcC00LjQvZHJpdmVycy9tdGQv bmFuZC8KPj4gKyAqICAgICAgICAgcm9ja2NoaXBfbmFuZF92Ni5jCj4+ICsgKgpodHRwczovL2dp dGh1Yi5jb20vcm9ja2NoaXAtbGludXgva2VybmVsL2Jsb2IvZGV2ZWxvcC00LjQvZHJpdmVycy9t dGQvbmFuZC8KPj4gKyAqICAgICAgICAgcm9ja2NoaXBfbmFuZF92OS5jCj4KPiBJJ20gbm90IHN1 cmUgdGhlIGVudGlyZSBsaW5rIGlzIHJlbGV2YW50LCBJIHdvdWxkIHNpbXBsZSBtZW50aW9uIHRo ZQo+IFJvY2tjaGlwIG9mZmljaWFsIEdpdGh1YiByZXBvc2l0b3J5IGFuZCB3b3JrIGZyb20gWWlm ZW5nLgo+Cj4+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOSBZaWZlbmcgWmhhbyB5aWZlbmcu emhhb0Byb2NrLWNoaXBzLmNvbQo+PiArICoKPj4gKyAqIFVwZGF0ZS9yZXN0eWxlIGZvciBsaW51 eC1uZXh0Lgo+PiArICogQWRkIGV4ZWNfb3AgZnVuY3Rpb24uCj4KPiBZb3UgY2FuIGRyb3AgdGhl c2UgdHdvIGxpbmVzIHRvby4gVGhpcyBpcyBtb3JlIGEgImNvbW1pdCBkZXNjcmlwdGlvbiIKPiB0 aGluZy4KPgo+PiArICogQ29tYmluZSBkcml2ZXIgZm9yIG5hbmRjIHZlcnNpb24gNiBhbmQgOS4K Pgo+ICAgICAgIFN1cHBvcnQgTkFORCBjb250cm9sbGVyIHZlcnNpb25zIDYgYW5kIDkgZm91bmQg b24gU29DcyAuLi4KPgo+PiArICogQ29weXJpZ2h0IChjKSAyMDIwIEpvaGFuIEpvbmtlciBqYng2 MjQ0QGdtYWlsLmNvbQo+PiArICovCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPj4g KyNpbmNsdWRlIDxsaW51eC9kbWEtbWFwcGluZy5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2ludGVy cnVwdC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4 L21vZHVsZS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPgo+PiArI2luY2x1ZGUg PGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgvbXRkL3Jh d25hbmQuaD4KPj4gKwo+PiArI2RlZmluZSBOQU5EQ19JRF9WNjAwCQkJMHg1NjM2MzAzMAo+PiAr I2RlZmluZSBOQU5EQ19JRF9WNjIyCQkJMHg1NjM2MzIzMgo+PiArI2RlZmluZSBOQU5EQ19JRF9W NzAxCQkJMHg3MDEKPj4gKyNkZWZpbmUgTkFORENfSURfVjgwMAkJCTB4NTYzODMwMzAKPj4gKyNk ZWZpbmUgTkFORENfSURfVjgwMQkJCTB4ODAxCj4+ICsjZGVmaW5lIE5BTkRDX0lEX1Y5MDAJCQkw eDU2MzkzMDMwCj4KCj4gSSB3b3VsZCBwcmVmZXIgcHJlZml4aW5nIGV2ZXJ5dGhpbmcgUktfTkFO RENfIG9yIFJLXwoKV2lsbCBjaGFuZ2UgZGVmaW5lIGxpc3QgYWJvdmUgYW5kIGJlbG93IHRvIFJL X05BTkRDXwpJdCB0YWtlcyBtb3JlIHNwYWNlIHRob3VnaC4gQWxyZWFkeSBkaWZmaWN1bHQgdG8g c3RheSBiZWxvdyA4MCBjaGFyL2xpbmUuCgo+Cj4+ICsKPj4gKyNkZWZpbmUgTkFORENfSURCUmVz QmxrTnVtCQkxNgo+PiArI2RlZmluZSBOQU5EQ19JREJFY2NCaXRzCQkyNAo+PiArI2RlZmluZSBO QU5EQ19JREJTdGFydEFkZHIJCTAKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WNl9FQ0NfMTYJCQkw eDAwMDAwMDAwCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0VDQ18yNAkJCTB4MDAwMDAwMTAKPj4gKyNk ZWZpbmUgTkFORENfVjZfRUNDXzQwCQkJMHgwMDA0MDAwMAo+PiArI2RlZmluZSBOQU5EQ19WNl9F Q0NfNjAJCQkweDAwMDQwMDEwCj4+ICsKPj4gKyNkZWZpbmUgTkFORENfVjlfRUNDXzE2CQkJMHgw MjAwMDAwMQo+PiArI2RlZmluZSBOQU5EQ19WOV9FQ0NfNDAJCQkweDA0MDAwMDAxCj4+ICsjZGVm aW5lIE5BTkRDX1Y5X0VDQ182MAkJCTB4MDYwMDAwMDEKPj4gKyNkZWZpbmUgTkFORENfVjlfRUND XzcwCQkJMHgwMDAwMDAwMQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX05VTV9CQU5LUwkJCTQKPj4g KyNkZWZpbmUgTkFORENfREVGX1RJTUVPVVQJCTEwMDAwCj4+ICsKPj4gKyNkZWZpbmUgTkFORENf UkVHX0RBVEEJCQkweDAwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19BRERSCQkJMHgwNAo+PiArI2Rl ZmluZSBOQU5EQ19SRUdfQ01ECQkJMHgwOAo+PiArCj4+ICsvKiByZWdpc3RlciBvZmZzZXQgbmFu ZGMgdmVyc2lvbiA2ICovCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WNl9GTUNUTAkJMHgwMAo+PiAr I2RlZmluZSBOQU5EQ19SRUdfVjZfRk1XQUlUCQkweDA0Cj4+ICsjZGVmaW5lIE5BTkRDX1JFR19W Nl9GTENUTAkJMHgwOAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfQkNIQ1RMCQkweDBjCj4+ICsj ZGVmaW5lIE5BTkRDX1JFR19WNl9ETUFfQ0ZHCQkweDEwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19W Nl9ETUFfQlVGMAkJMHgxNAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfRE1BX0JVRjEJCTB4MTgK Pj4gKyNkZWZpbmUgTkFORENfUkVHX1Y2X0RNQV9TVAkJMHgxQwo+PiArI2RlZmluZSBOQU5EQ19S RUdfVjZfQkNIU1QJCTB4MjAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y2X1JBTkRNWgkJMHgxNTAK Pj4gKyNkZWZpbmUgTkFORENfUkVHX1Y2X1ZFUgkJMHgxNjAKPj4gKyNkZWZpbmUgTkFORENfUkVH X1Y2X0lOVEVOCQkweDE2Qwo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfSU5UQ0xSCQkweDE3MAo+ PiArI2RlZmluZSBOQU5EQ19SRUdfVjZfSU5UU1QJCTB4MTc0Cj4+ICsjZGVmaW5lIE5BTkRDX1JF R19WNl9TUEFSRTAJCTB4MjAwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WNl9TUEFSRTEJCTB4MjMw Cj4+ICsKPj4gKy8qIHJlZ2lzdGVyIG9mZnNldCBuYW5kYyB2ZXJzaW9uIDkgKi8KPj4gKyNkZWZp bmUgTkFORENfUkVHX1Y5X0ZNQ1RMCQkweDAwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WOV9GTVdB SVQJCTB4MDQKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X0ZMQ1RMCQkweDEwCj4+ICsjZGVmaW5l IE5BTkRDX1JFR19WOV9CQ0hDVEwJCTB4MjAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X0RNQV9D RkcJCTB4MzAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X0RNQV9CVUYwCQkweDM0Cj4+ICsjZGVm aW5lIE5BTkRDX1JFR19WOV9ETUFfQlVGMQkJMHgzOAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjlf RE1BX1NUCQkweDQwCj4+ICsjZGVmaW5lIE5BTkRDX1JFR19WOV9WRVIJCTB4ODAKPj4gKyNkZWZp bmUgTkFORENfUkVHX1Y5X0lOVEVOCQkweDEyMAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjlfSU5U Q0xSCQkweDEyNAo+PiArI2RlZmluZSBOQU5EQ19SRUdfVjlfSU5UU1QJCTB4MTI4Cj4+ICsjZGVm aW5lIE5BTkRDX1JFR19WOV9CQ0hTVAkJMHgxNTAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X1NQ QVJFMAkJMHgyMDAKPj4gKyNkZWZpbmUgTkFORENfUkVHX1Y5X1NQQVJFMQkJMHgyMDQKPj4gKyNk ZWZpbmUgTkFORENfUkVHX1Y5X1JBTkRNWgkJMHgyMDgKPj4gKwo+PiArLyogcmVnaXN0ZXIgb2Zm c2V0IG5hbmRjIGNvbW1vbiAqLwo+PiArI2RlZmluZSBOQU5EQ19SRUdfQkFOSzAJCQkweDgwMAo+ PiArI2RlZmluZSBOQU5EQ19SRUdfU1JBTTAJCQkweDEwMDAKPj4gKwo+PiArLyogRk1DVEwgKi8K Pj4gKyNkZWZpbmUgTkFORENfVjZfRk1fV1AJCQlCSVQoOCkKPj4gKyNkZWZpbmUgTkFORENfVjZf Rk1fQ0VfU0VMX00JCTB4RkYKPj4gKyNkZWZpbmUgTkFORENfVjZfRk1fQ0VfU0VMKHgpCQkoMSA8 PCAoeCkpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0ZNX0ZSRUFEWQkJQklUKDkpCj4+ICsKPj4gKyNk ZWZpbmUgTkFORENfVjlfRk1fV1AJCQlCSVQoOCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRk1fQ0Vf U0VMX00JCTB4RkYKPj4gKyNkZWZpbmUgTkFORENfVjlfRk1fQ0VfU0VMKHgpCQkoMSA8PCAoeCkp Cj4+ICsjZGVmaW5lIE5BTkRDX1Y5X1JEWQkJCUJJVCg5KQo+PiArCj4+ICsvKiBGTENUTCAqLwo+ PiArI2RlZmluZSBOQU5EQ19WNl9GTF9SU1QJCQlCSVQoMCkKPj4gKyNkZWZpbmUgTkFORENfVjZf RkxfRElSKHgpCQkoKHgpID8gQklUKDEpIDogMCkKPj4gKyNkZWZpbmUgTkFORENfVjZfRkxfWEZF Ul9TVEFSVAkJQklUKDIpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0ZMX1hGRVJfRU4JCUJJVCgzKQo+ PiArI2RlZmluZSBOQU5EQ19WNl9GTF9TVF9CVUZfUwkJMHg0Cj4+ICsjZGVmaW5lIE5BTkRDX1Y2 X0ZMX1hGRVJfQ09VTlQJCUJJVCg1KQo+PiArI2RlZmluZSBOQU5EQ19WNl9GTF9BQ09SUkVDVAkJ QklUKDEwKQo+PiArI2RlZmluZSBOQU5EQ19WNl9GTF9YRkVSX1JFQURZCQlCSVQoMjApCj4+ICsj ZGVmaW5lIE5BTkRDX1Y2X0ZMX1BBR0VfTlVNKHgpCQkoKHgpIDw8IDIyKQo+PiArI2RlZmluZSBO QU5EQ19WNl9GTF9BU1lOQ19UT0dfTUlYCUJJVCgyOSkKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19W OV9GTF9SU1QJCQlCSVQoMCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRkxfRElSKHgpCQkoKHgpID8g QklUKDEpIDogMCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRkxfWEZFUl9TVEFSVAkJQklUKDIpCj4+ ICsjZGVmaW5lIE5BTkRDX1Y5X0ZMX1hGRVJfRU4JCUJJVCgzKQo+PiArI2RlZmluZSBOQU5EQ19W OV9GTF9TVF9CVUZfUwkJMHg0Cj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0ZMX1hGRVJfQ09VTlQJCUJJ VCg1KQo+PiArI2RlZmluZSBOQU5EQ19WOV9GTF9BQ09SUkVDVAkJQklUKDEwKQo+PiArI2RlZmlu ZSBOQU5EQ19WOV9GTF9YRkVSX1JFQURZCQlCSVQoMjApCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0ZM X1BBR0VfTlVNKHgpCQkoKHgpIDw8IDIyKQo+PiArI2RlZmluZSBOQU5EQ19WOV9GTF9BU1lOQ19U T0dfTUlYCUJJVCgyOSkKPj4gKwo+PiArLyogQkNIQ1RMICovCj4+ICsjZGVmaW5lIE5BTkRfVjZf QkNIX1JFR0lPTl9TCQkweDUKPj4gKyNkZWZpbmUgTkFORF9WNl9CQ0hfUkVHSU9OX00JCTB4Nwo+ PiArCj4+ICsjZGVmaW5lIE5BTkRfVjlfQkNIX01PREVfUwkJMjUKPj4gKyNkZWZpbmUgTkFORF9W OV9CQ0hfTU9ERV9NCQkweDcKPj4gKwo+PiArLyogQkNIU1QgKi8KPj4gKyNkZWZpbmUgTkFORENf VjZfQkNIMF9TVF9FUlIJCUJJVCgyKQo+PiArI2RlZmluZSBOQU5EQ19WNl9CQ0gxX1NUX0VSUgkJ QklUKDE1KQo+PiArI2RlZmluZSBOQU5EQ19WNl9FQ0NfRVJSX0NOVDAoeCkJKCgoKHggJiAoMHgx RiA8PCAzKSkgPj4gMykgXAo+PiArCQkJCQl8ICgoeCAmICgxIDw8IDI3KSkgPj4gMjIpKSAmIDB4 M0YpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0VDQ19FUlJfQ05UMSh4KQkoKCgoeCAmICgweDFGIDw8 IDE2KSkgPj4gMTYpIFwKPj4gKwkJCQkJfCAoKHggJiAoMSA8PCAyOSkpID4+IDI0KSkgJiAweDNG KQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0JDSDBfU1RfRVJSCQlCSVQoMikKPj4gKyNkZWZp bmUgTkFORENfVjlfQkNIMV9TVF9FUlIJCUJJVCgxOCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRUND X0VSUl9DTlQwKHgpCSgoKHgpICYgKDB4N0YgPDwgMykpID4+IDMpCj4+ICsjZGVmaW5lIE5BTkRD X1Y5X0VDQ19FUlJfQ05UMSh4KQkoKCh4KSAmICgweDdGIDw8IDE5KSkgPj4gMTkpCj4+ICsKPj4g Ky8qIERNQV9DRkcgKi8KPj4gKyNkZWZpbmUgTkFORENfVjZfRE1BX0NGR19XUl9TVAkJQklUKDAp Cj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0RNQV9DRkdfV1IoeCkJCSgoIXgpID8gQklUKDEpIDogMCkK Pj4gKyNkZWZpbmUgTkFORENfVjZfRE1BX0NGR19CVVNfTU9ERQlCSVQoMikKPj4gKwo+PiArI2Rl ZmluZSBOQU5EQ19WNl9ETUFfQ0ZHX0hTSVpFXzgJMAo+PiArI2RlZmluZSBOQU5EQ19WNl9ETUFf Q0ZHX0hTSVpFXzE2CSgxIDw8IDMpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0RNQV9DRkdfSFNJWkVf MzIJKDIgPDwgMykKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WNl9ETUFfQ0ZHX0JVUlNUXzEJMAo+ PiArI2RlZmluZSBOQU5EQ19WNl9ETUFfQ0ZHX0JVUlNUXzQJKDMgPDwgNikKPj4gKyNkZWZpbmUg TkFORENfVjZfRE1BX0NGR19CVVJTVF84CSg1IDw8IDYpCj4+ICsjZGVmaW5lIE5BTkRDX1Y2X0RN QV9DRkdfQlVSU1RfMTYJKDcgPDwgNikKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WNl9ETUFfQ0ZH X0lOQ1JfTlVNKHgpCSgoeCkgPDwgOSkKPj4gKwo+PiArI2RlZmluZSBOQU5EQ19WOV9ETUFfQ0ZH X1dSX1NUCQlCSVQoMCkKPj4gKyNkZWZpbmUgTkFORENfVjlfRE1BX0NGR19XUih4KQkJKCgheCkg PyBCSVQoMSkgOiAwKQo+PiArI2RlZmluZSBOQU5EQ19WOV9ETUFfQ0ZHX0JVU19NT0RFCUJJVCgy KQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0RNQV9DRkdfSFNJWkVfOAkwCj4+ICsjZGVmaW5l IE5BTkRDX1Y5X0RNQV9DRkdfSFNJWkVfMTYJKDEgPDwgMykKPj4gKyNkZWZpbmUgTkFORENfVjlf RE1BX0NGR19IU0laRV8zMgkoMiA8PCAzKQo+PiArCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0RNQV9D RkdfQlVSU1RfMQkwCj4+ICsjZGVmaW5lIE5BTkRDX1Y5X0RNQV9DRkdfQlVSU1RfNAkoMyA8PCA2 KQo+PiArI2RlZmluZSBOQU5EQ19WOV9ETUFfQ0ZHX0JVUlNUXzgJKDUgPDwgNikKPj4gKyNkZWZp bmUgTkFORENfVjlfRE1BX0NGR19CVVJTVF8xNgkoNyA8PCA2KQo+PiArCj4+ICsjZGVmaW5lIE5B TkRDX1Y5X0RNQV9DRkdfSU5DUl9OVU0oeCkJKCh4KSA8PCA5KQo+PiArCj4+ICsvKiBJTlRFTiAq Lwo+PiArI2RlZmluZSBOQU5EQ19WNl9JTlRfRE1BCQlCSVQoMCkKPj4gKwo+PiArI2RlZmluZSBO QU5EQ19WOV9JTlRfRE1BCQlCSVQoMCkKPj4gKwo+PiArZW51bSBya19uYW5kY192ZXJzaW9uIHsK Pj4gKwlWRVJTSU9OXzYgPSA2LAo+PiArCVZFUlNJT05fOSA9IDksCj4+ICt9Owo+PiArCj4+ICtz dHJ1Y3QgcmtfbmFuZGNfZGF0YSB7Cj4+ICsJZW51bSBya19uYW5kY192ZXJzaW9uIHZlcnNpb247 Cj4KCj4gSWYgeW91IG1ha2UgYSBkaXN0aW5jdGlvbiBiZXR3ZWVuIGJvdGggdmVyc2lvbiwgbWF5 YmUgeW91IGNhbiBhZGQgbW9yZQo+IHBhcmFtZXRlcnMgaGVyZSBhbmQgZG8KPgo+IAlmb28gPSBk YXRhLT5wYXJhbQo+Cj4gaW5zdGVhZCBvZgo+Cj4gCWlmIChkYXRhLT52ZXJzaW9uID09IDYpCj4g CQlmb28gPSB0aGlzOwo+IAllbHNlCj4gCQlmb28gPSB0aGF0Owo+CgpUT0RPIHYyCgo+PiArfTsK Cgo+PiArCj4+ICtzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyIHsKPj4gKwl2b2lkIF9faW9tZW0g KnJlZ3M7Cj4+ICsJaW50IGlycTsKPj4gKwlzdHJ1Y3QgY2xrICpoY2xrOwo+PiArCXN0cnVjdCBj bGsgKmNsazsKPj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIGNoaXBzOwo+PiArCXN0cnVjdCBjb21wbGV0 aW9uIGNvbXBsZXRlOwo+PiArCXN0cnVjdCBuYW5kX2NvbnRyb2xsZXIgY29udHJvbGxlcjsKPj4g KwlpbnQgYmFua3NbTkFORENfTlVNX0JBTktTXTsKPgo+PiArCWJvb2wgYm9vdHJvbWJsb2NrczsK Pj4gKwlpbnQgZWNjX21vZGU7Cj4+ICsJdWludDMyX3QgZWNjX3N0cmVuZ3RoOwo+PiArCWludCBt YXhfZWNjX3N0cmVuZ3RoOwo+Cgo+IEkgaGF2ZSBub3QgcmVhZCB5ZXQgdGhlIGVudGlyZSBkcml2 ZXIgYnV0IEkgYmVsaWV2ZSB0aGUgYWJvdmUgNAo+IHBhcmFtZXRlcnMgc2hvdWxkIHByb2JhYmx5 IGJlIG1vdmVkIGluIHJrX25hbmRfY2hpcCwgcmlnaHQ/IEFueXRoaW5nCj4gdGhhdCBpcyBOQU5E IGNoaXAgcmVsYXRlZCBzaG91bGQgbm90IGJlIGluIHRoZSBjb250cm9sbGVyIHN0cnVjdHVyZS4g SXQKPiBkZXBlbmRzIGlmIHlvdSBjYW4gY2hhbmdlIEVDQyByZXF1aXJlbWVudHMgb24gdGhlIGZs eSBvciBub3QuCgpTaG9ydCBhbnN3ZXI6ClRoZSByZWFzb24gdGhhdCBpdCBpcyB0aGUgbW9zdCBj b252ZW5pZW5jZSBwbGFjZSB0byBoYXZlIHRoZW0gZm9yIG5vdy4KV2l0aCBvbmUgcG9pbnRlciBm cm9tIG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YSgpIEkgaGF2ZSBhbGwgZGF0YSBhdmFpbGFibGUu CgpzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF9nZXRfY29udHJvbGxlcl9k YXRhKG5hbmQpOwoKVGhlIEVDQyBpcyBub3cgc29ydCBvZiBmaXhlZCB0byAyNCBhbmQgNDAgZm9y IGxlZ2FjeSByZWFzb25zLgpUaGUgb2xkZXIgcmszMDY2IGJvb3Ryb20gYXBwYXJlbnRseSBvbmx5 IHdvcmtzIGZvciBlY2MgMjQuClNlZSBpbmZvIGJhc2VkIG9uIG9sZGVyIHdvcmsgYnkgUGF3ZcWC IEphcm9zeiBmb3IgVWJvb3QuCgpJJ20gbm90IHRvbyBmYW1pbGlhciB3aXRoIGFsbCBpbm5lciB3 b3JraW5nIG9mIE1URCwgc28gcGxlYXNlIGFkdmlzZS4KQ2FuIHRoZSB1c2VycyBnZXQgYWNjZXNz IHRvIHN0cnVjdCBya19uYW5kX2NoaXA/CldvdWxkIHlvdSBsaWtlIHRvIGdpdmUgdXNlcnMgY29u dHJvbCBvdmVyIHdoYXQgZWNjIHRvIHVzZT8KV2hhdCBwcm9ncmFtIGNhbiB3ZSB1c2UgZm9yIHRo YXQ/IENhbid0IHVzZSBkZCB0aGVuIGFueSBtb3JlLgpIb3cgZG8gd2UgcmVnYWluIGVjYyBjb250 cm9sIGlmIHdlIHJlYWxseSBoYXZlIHRvIGZvciBleGFtcGxlIHJrMzA2Nj8KT3IgcmVtb3ZlIHRo YXQgYm9vdHJvbSBjaGVjayBhbmQgYWx3YXlzIHNldCBFQ0Mgd2l0aCBldmVyeQpya19uYW5kY19o d19zeW5kcm9tZV9lY2NfcmVhZF9wYWdlIGFuZCBya19uYW5kY19od19zeW5kcm9tZV9lY2Nfd3Jp dGVfcGFnZQp3aXRoIHdoYXRldmVyIHBhc3NlZCBhbG9uZz8KCj4KPj4gKwl1aW50MzJfdCAqb29i X2J1ZjsKPj4gKwl1aW50MzJfdCAqcGFnZV9idWY7Cj4+ICsJaW50IHNlbGVjdGVkX2Jhbms7Cj4+ ICsJZW51bSBya19uYW5kY192ZXJzaW9uIHZlcnNpb247Cj4+ICt9Owo+PiArCj4+ICtzdHJ1Y3Qg cmtfbmFuZF9jaGlwIHsKPj4gKwlzdHJ1Y3QgbmFuZF9jaGlwIG5hbmQ7Cj4+ICsJc3RydWN0IGxp c3RfaGVhZCBjaGlwX2xpc3Q7Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHJrX25hbmRf Y29udHJvbGxlciBnX25hbmRjX2luZm9bMl07Cj4KPiBJIGRvbid0IGxpa2UgdGhpcyBpZGVhIHNv IG11Y2guIEkgcHJlZmVyIGEgZHluYW1pYyBhbGxvY2F0aW9uIGluIHRoZQo+IHByb2JlLgo+Cj4+ ICtzdGF0aWMgaW50IGdfaWRfY291bnRlcjsKPgo+IERvbid0IGtub3cgd2hhdCB0aGlzIGlzIHll dCwgYnV0IGl0IGlzIHByb2JhYmx5IGEgYmFkIGlkZWEgOikKPgoKTWF5YmUgbm90IGludGVyZXN0 aW5nIGZvciBNVEQsIGJ1dCBSSzMyODggaGFzIDIgaWRlbnRpY2FsIE5BTkRDJ3MuClRoZSBjdXJy ZWN0IEZUTCBzZXR1cCBvbmx5IHdvcmtzIHdpdGggbmFuZGMwLgpUbyByZXVzZSB0aGUgcHJvYmUg ZnVuY3Rpb24gZm9yIG90aGVyIHRoaW5ncyB0aGVuIE1URAppdCBuZWVkcyB0byBiZSBhd2FyZSBv ZiBhbGlhcyBvcmRlci4KV2lsbCByZW1vdmUgaXQgZm9yIHZlcnNpb24gMi4KCj4+ICsKPj4gK3N0 YXRpYyB2b2lkIHJrX25hbmRjX2luaXQoc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCkK Pj4gK3sKPj4gKwlpZiAoY3RybC0+dmVyc2lvbiA9PSBWRVJTSU9OXzkpIHsKPj4gKwkJd3JpdGVs KDAsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfUkFORE1aKTsKPj4gKwkJd3JpdGVsKDAsIGN0 cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfRE1BX0NGRyk7Cj4+ICsJCXdyaXRlbChOQU5EQ19WOV9G TV9XUCwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WOV9GTUNUTCk7Cj4+ICsJCXdyaXRlbChOQU5E Q19WOV9GTF9SU1QsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfRkxDVEwpOwo+PiArCQl3cml0 ZWwoMHgxMDgxLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0ZNV0FJVCk7Cj4+ICsJfSBlbHNl IHsKPj4gKwkJd3JpdGVsKDAsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfUkFORE1aKTsKPj4g KwkJd3JpdGVsKDAsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRE1BX0NGRyk7Cj4+ICsJCXdy aXRlbChOQU5EQ19WNl9GTV9XUCwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WNl9GTUNUTCk7Cj4+ ICsJCXdyaXRlbChOQU5EQ19WNl9GTF9SU1QsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRkxD VEwpOwo+PiArCQl3cml0ZWwoMHgxMDgxLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0ZNV0FJ VCk7Cj4+ICsJfQo+Cj4gTXkgYWJvdmUgY29tbWVudCBhYm91dCB0aGUgcGxhdGZvcm0gZGF0YSB3 b3VsZCBtYWtlIGEgbG90IG9mIHNlbnNlIGhlcmUhCj4KPj4gK30KPj4gKwo+PiArc3RhdGljIGly cXJldHVybl90IHJrX25hbmRjX2ludGVycnVwdChpbnQgaXJxLCB2b2lkICpkZXZfaWQpCj4+ICt7 Cj4+ICsJc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCA9IGRldl9pZDsKPj4gKwo+PiAr CWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiArCQl1aW50MzJfdCBzdCA9IHJl YWRsKGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfSU5UU1QpOwo+PiArCQl1aW50MzJfdCBpZW4g PSByZWFkbChjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0lOVEVOKTsKPj4gKwo+PiArCQlpZiAo IShpZW4gJiBzdCkpCj4+ICsJCQlyZXR1cm4gSVJRX05PTkU7Cj4+ICsKPj4gKwkJaWYgKChpZW4g JiBzdCkgPT0gaWVuKQo+PiArCQkJY29tcGxldGUoJmN0cmwtPmNvbXBsZXRlKTsKPj4gKwo+PiAr CQl3cml0ZWwoc3QsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfSU5UQ0xSKTsKPj4gKwkJd3Jp dGVsKH5zdCAmIGllbiwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WOV9JTlRFTik7Cj4+ICsJfSBl bHNlIHsKPj4gKwkJdWludDMyX3Qgc3QgPSByZWFkbChjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2 X0lOVFNUKTsKPj4gKwkJdWludDMyX3QgaWVuID0gcmVhZGwoY3RybC0+cmVncyArIE5BTkRDX1JF R19WNl9JTlRFTik7Cj4+ICsKPj4gKwkJaWYgKCEoaWVuICYgc3QpKQo+PiArCQkJcmV0dXJuIElS UV9OT05FOwo+PiArCj4+ICsJCWlmICgoaWVuICYgc3QpID09IGllbikKPj4gKwkJCWNvbXBsZXRl KCZjdHJsLT5jb21wbGV0ZSk7Cj4+ICsKPj4gKwkJd3JpdGVsKHN0LCBjdHJsLT5yZWdzICsgTkFO RENfUkVHX1Y2X0lOVENMUik7Cj4+ICsJCXdyaXRlbCh+c3QgJiBpZW4sIGN0cmwtPnJlZ3MgKyBO QU5EQ19SRUdfVjZfSU5URU4pOwo+PiArCX0KPgo+IFNhbWUgY29tbWVudCEKPgo+PiArCj4+ICsJ cmV0dXJuIElSUV9IQU5ETEVEOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBya19uYW5kY19z ZWxlY3RfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBpbnQgY2hpcG5yKQo+PiArewo+PiAr CXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9jb250cm9sbGVyX2Rh dGEobmFuZCk7Cj4+ICsJdWludDMyX3QgcmVnOwo+PiArCWludCBiYW5rbnI7Cj4+ICsKPj4gKwkv KiBUaGUgcmVnaXN0ZXIgb2Zmc2V0IGFuZCBiaXQgcG9zaXRpb25zIGZvcgo+Cj4gc2hvdWxkIGJl Ogo+Cj4gCS8qCj4gCSAqIFRoZSByZWdpc3Rlci4uLgo+Cgo+IFBsZWFzZSBydW4gY2hlY2twYXRj aC5wbCAtLXN0cmljdCBvbiB0aGlzIGZpbGUsIHRoaXMga2luZCBvZiBtaXN0YWtlCj4gd291bGQg aGF2ZSBiZWVuIGRldGVjdGVkLgo+CgpXaGVuIHlvdSB0aGluayB0aGF0IHlvdSBnb3QgcmlkIG9m IGFsbCB3YXJuaW5ncyB0aGVyZSdzIGFsd2F5cwphbiBleHRyYSBvcHRpb24gZm9yIG1vcmUuLi4K VGhhbmtzIGZvciB0aGF0IGFkdmljZS4KCj4+ICsJICogTkFORENfUkVHX1Y2X0ZNQ1RMIGFuZCBO QU5EQ19SRUdfVjlfRk1DVEwKPj4gKwkgKiBhcmUgaWRlbnRpY2FsLgo+PiArCSAqLwo+PiArCXJl ZyA9IHJlYWRsKGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRk1DVEwpOwo+PiArCXJlZyAmPSB+ TkFORENfVjZfRk1fQ0VfU0VMX007Cj4+ICsKPj4gKwlpZiAoY2hpcG5yID09IC0xKSB7Cj4+ICsJ CWJhbmtuciA9IC0xOwo+PiArCX0gZWxzZSB7Cj4+ICsJCWJhbmtuciA9IGN0cmwtPmJhbmtzW2No aXBucl07Cj4+ICsKPj4gKwkJcmVnIHw9IE5BTkRDX1Y2X0ZNX0NFX1NFTChiYW5rbnIpOwo+PiAr CX0KPj4gKwl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0ZNQ1RMKTsKPgo+ IE1heWJlIHlvdSBjYW4gc3BhcmUgdGhpcyB3cml0ZWwgYnkgcmV0dXJuaW5nIGVhcmx5IGlmIGJh bmtuciA9PQo+IGN0cmwtPnNlbGVjdGVkX2JhbmsuCj4KPj4gKwo+PiArCWN0cmwtPnNlbGVjdGVk X2JhbmsgPSBiYW5rbnI7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfaHdfZWNj X3NldHVwKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsCj4+ICsJCQkJIHVpbnQzMl90IHN0cmVuZ3Ro KQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9j b250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsJdWludDMyX3QgcmVnOwo+PiArCj4+ICsJbmFuZC0+ ZWNjLnN0cmVuZ3RoID0gc3RyZW5ndGg7CgpTaG91bGQgSSBhZGQgdGhpcyBjb21tZW50IGJlbG93 PwoKLyogSFcgRUNDIGFsd2F5cyByZXF1ZXN0IEVDQyBieXRlcyBmb3IgMTAyNCBieXRlcyBibG9j a3MgKi8KCj4+ICsJbmFuZC0+ZWNjLmJ5dGVzID0gRElWX1JPVU5EX1VQKG5hbmQtPmVjYy5zdHJl bmd0aCAqIDE0LCA4KTsKPgoKPiBXaGF0IGRvIDE0IGFuZCA4IG1lYW4/CgpmbHMgLSBmaW5kIGxh c3QgKG1vc3Qtc2lnbmlmaWNhbnQpIGJpdCBzZXQKCmludCBmbHModW5zaWduZWQgaW50IHgpCnsK CWludCByID0gMzI7CgoJaWYgKCF4KQoJCXJldHVybiAwOwoJaWYgKCEoeCAmIDB4ZmZmZjAwMDB1 KSkgewoJCXggPDw9IDE2OwoJCXIgLT0gMTY7Cgl9CglpZiAoISh4ICYgMHhmZjAwMDAwMHUpKSB7 CgkJeCA8PD0gODsKCQlyIC09IDg7Cgl9CglpZiAoISh4ICYgMHhmMDAwMDAwMHUpKSB7CgkJeCA8 PD0gNDsKCQlyIC09IDQ7Cgl9CglpZiAoISh4ICYgMHhjMDAwMDAwMHUpKSB7CgkJeCA8PD0gMjsK CQlyIC09IDI7Cgl9CglpZiAoISh4ICYgMHg4MDAwMDAwMHUpKSB7CgkJeCA8PD0gMTsKCQlyIC09 IDE7Cgl9CglyZXR1cm4gcjsKfQoKCW5hbmQtPmVjYy5ieXRlcyA9IERJVl9ST1VORF9VUChlY2Mt PnN0cmVuZ3RoICogZmxzKDggKiAxMDI0KSwgOCk7Cgpmb3JtdWxlIGlzIHVzZWQgdG8gdHJhbnNs YXRlIHN0cmVuZ3RoIGluIGJpdC8xMDI0IEJDSC9FQ0MKdG8gTVREIEVDQyBieXRlcyBmb3IgMTAy NCBieXRlcyBibG9ja3MgaW4gbmFuZC0+ZWNjLmJ5dGVzCgoxNCBpcyByZXBsYWNlbWVudCBmb3Ig ZmxzKDggKiAxMDI0KQo4IGJpdHMgaW4gYSBieXRlCgo+Cj4+ICsJLyogSFcgRUNDIG9ubHkgd29y a3Mgd2l0aCBhbiBldmVuIG51bWJlciBvZiBFQ0MgYnl0ZXMgKi8KPj4gKwluYW5kLT5lY2MuYnl0 ZXMgPSBBTElHTihuYW5kLT5lY2MuYnl0ZXMsIDIpOwo+PiArCj4+ICsJaWYgKGN0cmwtPnZlcnNp b24gPT0gVkVSU0lPTl85KSB7Cj4+ICsJCXN3aXRjaCAobmFuZC0+ZWNjLnN0cmVuZ3RoKSB7Cj4+ ICsJCWNhc2UgNzA6Cj4+ICsJCQlyZWcgPSBOQU5EQ19WOV9FQ0NfNzA7Cj4+ICsJCQlicmVhazsK Pj4gKwkJY2FzZSA2MDoKPj4gKwkJCXJlZyA9IE5BTkRDX1Y5X0VDQ182MDsKPj4gKwkJCWJyZWFr Owo+PiArCQljYXNlIDQwOgo+PiArCQkJcmVnID0gTkFORENfVjlfRUNDXzQwOwo+PiArCQkJYnJl YWs7Cj4+ICsJCWNhc2UgMTY6Cj4+ICsJCQlyZWcgPSBOQU5EQ19WOV9FQ0NfMTY7Cj4+ICsJCQli cmVhazsKPj4gKwkJZGVmYXVsdDoKPj4gKwkJCXJldHVybiAtRUlOVkFMOwo+PiArCQl9Cj4+ICsJ CXdyaXRlbChyZWcsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjlfQkNIQ1RMKTsKPj4gKwl9IGVs c2Ugewo+PiArCQlzd2l0Y2ggKG5hbmQtPmVjYy5zdHJlbmd0aCkgewo+PiArCQljYXNlIDYwOgo+ PiArCQkJcmVnID0gTkFORENfVjZfRUNDXzYwOwo+PiArCQkJYnJlYWs7Cj4+ICsJCWNhc2UgNDA6 Cj4+ICsJCQlyZWcgPSBOQU5EQ19WNl9FQ0NfNDA7Cj4+ICsJCQlicmVhazsKPj4gKwkJY2FzZSAy NDoKPj4gKwkJCXJlZyA9IE5BTkRDX1Y2X0VDQ18yNDsKPj4gKwkJCWJyZWFrOwo+PiArCQljYXNl IDE2Ogo+PiArCQkJcmVnID0gTkFORENfVjZfRUNDXzE2Owo+PiArCQkJYnJlYWs7Cj4+ICsJCWRl ZmF1bHQ6Cj4+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwkJfQo+PiArCQl3cml0ZWwocmVnLCBj dHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0JDSENUTCk7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJu IDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJrX25hbmRjX3hmZXJfc3RhcnQoc3RydWN0 IHJrX25hbmRfY29udHJvbGxlciAqY3RybCwKPj4gKwkJCQl1aW50OF90IGRpciwgdWludDhfdCBu X0tCLAo+PiArCQkJCWRtYV9hZGRyX3QgZG1hX2RhdGEsIGRtYV9hZGRyX3QgZG1hX29vYikKPj4g K3sKPj4gKwl1aW50MzJfdCByZWc7Cj4+ICsKPj4gKwlpZiAoY3RybC0+dmVyc2lvbiA9PSBWRVJT SU9OXzkpIHsKPj4gKwkJcmVnID0gTkFORENfVjlfRE1BX0NGR19XUl9TVCB8Cj4+ICsJCSAgICAg IE5BTkRDX1Y5X0RNQV9DRkdfV1IoZGlyKSB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0RNQV9DRkdf QlVTX01PREUgfAo+PiArCQkgICAgICBOQU5EQ19WOV9ETUFfQ0ZHX0hTSVpFXzMyIHwKPj4gKwkJ ICAgICAgTkFORENfVjlfRE1BX0NGR19CVVJTVF8xNiB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0RN QV9DRkdfSU5DUl9OVU0oMTYpOwo+PiArCQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENf UkVHX1Y5X0RNQV9DRkcpOwo+PiArCQl3cml0ZWwoKHVpbnQzMl90KWRtYV9kYXRhLCBjdHJsLT5y ZWdzICsgTkFORENfUkVHX1Y5X0RNQV9CVUYwKTsKPj4gKwkJd3JpdGVsKCh1aW50MzJfdClkbWFf b29iLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0RNQV9CVUYxKTsKPgo+IEknbSBwcmV0dHkg c3VyZSBtb3N0IG9mIHRoZXNlIHdyaXRlbCBjb3VsZCBiZSB0dXJuZWQgaW50bwo+IHdyaXRlbF9y ZWxheGVkLgoKd3JpdGVsKCkgICAgICAgLS0gd3JpdGUgdG8gdGhlIGxpdHRsZS1lbmRpYW4gaGFy ZHdhcmUgcmVnaXN0ZXIgd2l0aApjb21waWxlciBtZW1vcnkgYmFycmllciwKd3JpdGVsX3JlbGF4 ZWQgLS0gYXMgYWJvdmUsIHdpdGhvdXQgYmFycmllciwKX19yYXdfd3JpdGVsKCkgLS0gYXMgYWJv dmUgKHdyaXRlbF9yZWxheGVkKCkpIHdpdGhvdXQgZW5kaWFuZXNzCmNvbnZlcnNpb24gKENQVSBv cmRlcmluZyB3aWxsIGJlIHVzZWQpLgpBcmNoaXRlY3R1cmUtZGVwZW5kZW50LgpJIGRvbid0IGtu b3cuCgo+Cj4gQWxzbyBJIGFtIG5vdCBhIGJpZyBmYW4gb2YgdGhlc2UgY2FzdHMsIG1heWJlIHlv dSBzaG91bGQgY2hhbmdlCj4gZG1hX2RhdGEgYW5kIGRtYV9vb2IgdHlwZXMgKGJlIGNhcmVmdWw6 IHlvdSBlbmFibGVkIENPTVBJTEVfVEVTVCBpbgo+IEtjb25maWcsIHlvdSBtdXN0IHN1cHBvcnQg MzItYml0IGFuZCA2NC1iaXQgcG9pbnRlcnMsIHBsZWFzZSB0cnkgdG8KPiBjb21waWxlIHRoaXMg ZHJpdmVyIHdpdGggZGlmZmVyZW50IHRvb2xjaGFpbnMpLgoKRHJpdmVyIGlzIHVzZWQgZm9yIGJv dGggQVJNIGFzIGFybTY0LgpUaGVzZSByZWdpc3RlcnMgYXJlIDMyIGJpdC4gUGxlYXNlIGFkdmlz ZSB3aGF0IGhhcHBlbnMKd2hlbiB3cml0ZWwgZ2V0cyBkbWFfYWRkcl90IGFuZCBkbWFfZGF0YSBh cyA2NCBiaXQuCkRvbid0IGhhdmUgdGhlIGhhcmR3YXJlIHRvIGZpbmQgb3V0LgoKPgo+PiArCj4+ ICsJCXJlZyA9IE5BTkRDX1Y5X0ZMX0RJUihkaXIpIHwKPj4gKwkJICAgICAgTkFORENfVjlfRkxf WEZFUl9FTiB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0ZMX1hGRVJfQ09VTlQgfAo+PiArCQkgICAg ICBOQU5EQ19WOV9GTF9BQ09SUkVDVCB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y5X0ZMX1BBR0VfTlVN KG5fS0IpIHwKPj4gKwkJICAgICAgTkFORENfVjlfRkxfQVNZTkNfVE9HX01JWDsKPj4gKwkJd3Jp dGVsKHJlZywgY3RybC0+cmVncyArIE5BTkRDX1JFR19WOV9GTENUTCk7Cj4+ICsJCXJlZyB8PSBO QU5EQ19WOV9GTF9YRkVSX1NUQVJUOwo+PiArCQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFO RENfUkVHX1Y5X0ZMQ1RMKTsKPj4gKwl9IGVsc2Ugewo+PiArCQlyZWcgPSByZWFkbChjdHJsLT5y ZWdzICsgTkFORENfUkVHX1Y2X0JDSENUTCk7Cj4+ICsJCXJlZyA9IChyZWcgJiAofihOQU5EX1Y2 X0JDSF9SRUdJT05fTSA8PAo+PiArCQkJCU5BTkRfVjZfQkNIX1JFR0lPTl9TKSkpIHwKPj4gKwkJ ICAgICAgKGN0cmwtPnNlbGVjdGVkX2JhbmsgPDwgTkFORF9WNl9CQ0hfUkVHSU9OX1MpOwo+PiAr CQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0JDSENUTCk7Cj4+ICsKPj4g KwkJcmVnID0gTkFORENfVjZfRE1BX0NGR19XUl9TVCB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y2X0RN QV9DRkdfV1IoZGlyKSB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y2X0RNQV9DRkdfQlVTX01PREUgfAo+ PiArCQkgICAgICBOQU5EQ19WNl9ETUFfQ0ZHX0hTSVpFXzMyIHwKPj4gKwkJICAgICAgTkFORENf VjZfRE1BX0NGR19CVVJTVF8xNiB8Cj4+ICsJCSAgICAgIE5BTkRDX1Y2X0RNQV9DRkdfSU5DUl9O VU0oMTYpOwo+PiArCQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0RNQV9D RkcpOwo+PiArCQl3cml0ZWwoZG1hX2RhdGEsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfRE1B X0JVRjApOwo+PiArCQl3cml0ZWwoZG1hX29vYiwgY3RybC0+cmVncyArIE5BTkRDX1JFR19WNl9E TUFfQlVGMSk7CgpTYW1lIGhlcmUuCgo+PiArCj4+ICsJCXJlZyA9IE5BTkRDX1Y2X0ZMX0RJUihk aXIpIHwKPj4gKwkJICAgICAgTkFORENfVjZfRkxfWEZFUl9FTiB8Cj4+ICsJCSAgICAgIE5BTkRD X1Y2X0ZMX1hGRVJfQ09VTlQgfAo+PiArCQkgICAgICBOQU5EQ19WNl9GTF9BQ09SUkVDVCB8Cj4+ ICsJCSAgICAgIE5BTkRDX1Y2X0ZMX1BBR0VfTlVNKG5fS0IpIHwKPj4gKwkJICAgICAgTkFORENf VjZfRkxfQVNZTkNfVE9HX01JWDsKPj4gKwkJd3JpdGVsKHJlZywgY3RybC0+cmVncyArIE5BTkRD X1JFR19WNl9GTENUTCk7Cj4+ICsJCXJlZyB8PSBOQU5EQ19WNl9GTF9YRkVSX1NUQVJUOwo+PiAr CQl3cml0ZWwocmVnLCBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y2X0ZMQ1RMKTsKPj4gKwl9Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfd2FpdF9mb3JfeGZlcl9kb25lKHN0cnVj dCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwpCj4+ICt7Cj4+ICsJdWludDMyX3QgcmVnOwo+PiAr CWludCByZXQ7Cj4+ICsKPj4gKwlpZiAoY3RybC0+dmVyc2lvbiA9PSBWRVJTSU9OXzkpIHsKPj4g KwkJdm9pZCBfX2lvbWVtICpwdHIgPSBjdHJsLT5yZWdzICsgTkFORENfUkVHX1Y5X0ZMQ1RMOwo+ PiArCj4+ICsJCXJldCA9IHJlYWRsX3BvbGxfdGltZW91dF9hdG9taWMocHRyLCByZWcsCj4+ICsJ CQkJCQlyZWcgJiBOQU5EQ19WOV9GTF9YRkVSX1JFQURZLAo+PiArCQkJCQkJMSwgTkFORENfREVG X1RJTUVPVVQpOwo+PiArCX0gZWxzZSB7Cj4+ICsJCXZvaWQgX19pb21lbSAqcHRyID0gY3RybC0+ cmVncyArIE5BTkRDX1JFR19WNl9GTENUTDsKPj4gKwo+PiArCQlyZXQgPSByZWFkbF9wb2xsX3Rp bWVvdXRfYXRvbWljKHB0ciwgcmVnLAo+PiArCQkJCQkJcmVnICYgTkFORENfVjZfRkxfWEZFUl9S RUFEWSwKPj4gKwkJCQkJCTEsIE5BTkRDX0RFRl9USU1FT1VUKTsKPj4gKwl9Cj4KPiBTcGFjZQo+ Cj4+ICsJaWYgKHJldCkKPj4gKwkJcHJfZXJyKCJ0aW1lb3V0IHJlZz0leFxuIiwgcmVnKTsKPj4g Kwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB1bnNpZ25lZCBsb25nIHJr X25hbmRjX2RtYV9tYXBfc2luZ2xlKHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKwkJdm9pZCAqcHRy LCBpbnQgc2l6ZSwgaW50IGRpcikKPgoKPiBVbmFsaWduZWQgcGFyYW1ldGVycwoKVG8gcmVzdHls ZSBJIHVzZToKYXN0eWxlIC1UOCAtLW1heC1jb2RlLWxlbmd0aD04MCAtLXN0eWxlPWxpbnV4IHJv Y2tjaGlwX25hbmRjLmMKClBsZWFzZSBhZHZpc2UgZm9yIGEgYmV0dGVyIHNvbHV0aW9uLgoKPgo+ PiArewo+PiArI2lmZGVmIENPTkZJR19BUk02NAo+PiArCV9fZG1hX21hcF9hcmVhKCh2b2lkICop cHRyLCBzaXplLCBkaXIpOwo+PiArCXJldHVybiAoKHVuc2lnbmVkIGxvbmcpdmlydF90b19waHlz KCh2b2lkICopcHRyKSk7Cj4+ICsjZWxzZQo+PiArCXJldHVybiBkbWFfbWFwX3NpbmdsZShkZXYs ICh2b2lkICopcHRyLCBzaXplLCBkaXIpOwo+PiArI2VuZGlmCj4KCj4gUGxlYXNlIHRyeSB0byBy ZW1vdmUgdGhlc2UgI2lmZGVmcywgSSBkb24ndCBrbm93IHdoeSB3b3VsZCB5b3UgbmVlZCB0aGUK PiBmb3JtZXIgYmxvY2s/CgpUaGlzIGRyaXZlciBpcyB1c2VkIGJvdGggZm9yIEFSTSBhcyBhcm02 NC4KT3JpZ2luYWwgZnJvbSBSb2NrY2hpcDogYXJtNjQgZG9lc24ndCBoYXZlIGRtYV9tYXBfc2lu Z2xlKCkgYXMgSSByZW1lbWJlci4KRG9uJ3Qga25vdyB3aGF0IHRvIHVzZSBpbnN0ZWFkLgpQbGVh c2UgYWR2aXNlLgoKPgo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBya19uYW5kY19kbWFfdW5t YXBfc2luZ2xlKHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKwkJCQkgICAgICB1bnNpZ25lZCBsb25n IHB0ciwgaW50IHNpemUsIGludCBkaXIpCj4+ICt7Cj4+ICsjaWZkZWYgQ09ORklHX0FSTTY0Cj4+ ICsJX19kbWFfdW5tYXBfYXJlYShwaHlzX3RvX3ZpcnQocHRyKSwgc2l6ZSwgZGlyKTsKPj4gKyNl bHNlCj4+ICsJZG1hX3VubWFwX3NpbmdsZShkZXYsIChkbWFfYWRkcl90KXB0ciwgc2l6ZSwgZGly KTsKPj4gKyNlbmRpZgo+Cj4gU2FtZQo+Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFu ZGNfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZShzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLAo+PiAr CQl1aW50OF90ICpidWYsCj4+ICsJCWludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+Cgo+IFVu YWxpZ25lZCBwYXJhbWV0ZXJzIChwbGVhc2UgY2hlY2sgYWxsIG9mIHRoZW0pLgoKQWdhaW4gYmxh bWUgYXN0eWxlIC4uLgpBZnRlciBjb3JyZWN0aW5nIGl0IG1hbnVhbGx5IGEgZmV3IHRpbWUgSSBq dXN0IGxlZnQgaXQgYXMgaXQgaXMuCgo+Cj4+ICt7Cj4+ICsJc3RydWN0IG10ZF9pbmZvICptdGQg PSBuYW5kX3RvX210ZChuYW5kKTsKPj4gKwlzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJs ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKG5hbmQpOwo+PiArCXN0cnVjdCBuYW5kX2VjY19j dHJsICplY2MgPSAmbmFuZC0+ZWNjOwo+PiArCWludCBtYXhfYml0ZmxpcHMgPSAwOwo+PiArCWRt YV9hZGRyX3QgZG1hX2RhdGEsIGRtYV9vb2I7Cj4+ICsJaW50IHJldCwgaTsKPj4gKwlpbnQgYmNo X3N0Owo+PiArCWludCBkbWFfb29iX3NpemUgPSBlY2MtPnN0ZXBzICogMTI4Owo+PiArCWludCBw YWdlc19wZXJfYmxrID0gbXRkLT5lcmFzZXNpemUgLyBtdGQtPndyaXRlc2l6ZTsKPj4gKwo+PiAr CXJrX25hbmRjX3NlbGVjdF9jaGlwKG5hbmQsIGN0cmwtPnNlbGVjdGVkX2JhbmspOwo+PiArCj4+ ICsJaWYgKChwYWdlIDwgcGFnZXNfcGVyX2JsayAqIE5BTkRDX0lEQlJlc0Jsa051bSkgJiYKPgoK PiBDYW1lbCBjYXNlIGlzIHVzdWFsbHkgbm90IHdlbGNvbWUKCkFueSBzdWdnZXN0aW9ucyBmb3Ig YSBiZXRlciByZXBsYWNlIGZvciBOQU5EQ19JREJSZXNCbGtOdW0gYXJlIHdlbGNvbWUuCgo+Cj4+ ICsJICAgIGN0cmwtPmJvb3Ryb21ibG9ja3MpCj4KPiBUaGlzIHdvdWxkIHByb2JhYmx5IGRlc2Vy dmUgYSBoZWxwZXIKPgo+PiArCQlya19uYW5kY19od19lY2Nfc2V0dXAobmFuZCwgTkFORENfSURC RWNjQml0cyk7Cj4+ICsKPj4gKwluYW5kX3JlYWRfcGFnZV9vcChuYW5kLCBwYWdlLCAwLCBOVUxM LCAwKTsKPj4gKwo+PiArCWRtYV9kYXRhID0gcmtfbmFuZGNfZG1hX21hcF9zaW5nbGUobXRkLT5k ZXYucGFyZW50LAo+PiArCQkJCQkgICBjdHJsLT5wYWdlX2J1ZiwgbXRkLT53cml0ZXNpemUsCj4+ ICsJCQkJCSAgIERNQV9GUk9NX0RFVklDRSk7Cj4+ICsJZG1hX29vYiA9IHJrX25hbmRjX2RtYV9t YXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwKPj4gKwkJCQkJICBjdHJsLT5vb2JfYnVmLCBkbWFf b29iX3NpemUsCj4+ICsJCQkJCSAgRE1BX0ZST01fREVWSUNFKTsKPj4gKwo+PiArCWluaXRfY29t cGxldGlvbigmY3RybC0+Y29tcGxldGUpOwo+Cgo+IE9uZSBpbml0X2NvbXBsZXRpb24gaXMgbmVl ZGVkIChpbiB0aGUgcHJvYmUsIHByb2JhYmx5KSB0aGVuIHBsZWFzZSB1c2UKPiByZWluaXRfY29t cGxldGlvbigpLgoKTXVzdCBzdHVkeSB0aGlzIGxhdGVyLgoKPgo+PiArCWlmIChjdHJsLT52ZXJz aW9uID09IFZFUlNJT05fOSkKPj4gKwkJd3JpdGVsKE5BTkRDX1Y5X0lOVF9ETUEsIGN0cmwtPnJl Z3MgKyBOQU5EQ19SRUdfVjlfSU5URU4pOwo+PiArCWVsc2UKPj4gKwkJd3JpdGVsKE5BTkRDX1Y2 X0lOVF9ETUEsIGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfSU5URU4pOwo+PiArCXJrX25hbmRj X3hmZXJfc3RhcnQoY3RybCwgMCwgZWNjLT5zdGVwcywgZG1hX2RhdGEsIGRtYV9vb2IpOwoKPj4g Kwl3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJmN0cmwtPmNvbXBsZXRlLCBtc2Vjc190b19q aWZmaWVzKDUpKTsKPj4gKwlya19uYW5kY193YWl0X2Zvcl94ZmVyX2RvbmUoY3RybCk7Cj4KPiBZ b3VzIHNob3VsZCBjaGVjayB0aGUgcmV0dXJuIHN0YXR1cyBvZiBhbG1vc3QgYWxsIHRoZSBmdW5j dGlvbnMgaGVyZS4KClBsZWFzZSBhZHZpc2Ugd2hhdCBFUlJPUiBjb2RlIHNob3VsZCBiZSByZXR1 cm5lZCBoZXJlCnRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIE1URC4KCj4KPj4gKwlya19uYW5kY19k bWFfdW5tYXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwgZG1hX2RhdGEsIG10ZC0+d3JpdGVzaXpl LAo+PiArCQkJCSAgRE1BX0ZST01fREVWSUNFKTsKPj4gKwlya19uYW5kY19kbWFfdW5tYXBfc2lu Z2xlKG10ZC0+ZGV2LnBhcmVudCwgZG1hX29vYiwgZG1hX29vYl9zaXplLAo+PiArCQkJCSAgRE1B X0ZST01fREVWSUNFKTsKPj4gKwo+PiArCW1lbWNweShidWYsIGN0cmwtPnBhZ2VfYnVmLCBtdGQt PndyaXRlc2l6ZSk7Cj4+ICsKPj4gKwlpZiAob29iX3JlcXVpcmVkKSB7Cj4+ICsJCXVpbnQ4X3Qg Km9vYjsKPj4gKwkJdWludDMyX3QgdG1wOwo+Cgo+IFBsZWFzZSB1c2UgdTgsIHUxNiBhbmQgdTMy IHR5cGVzLgoKU2hvdWxkIHRoaXMgYmUgY2hhbmdlZCBmb3IgdGhlIGVudGlyZSBzb3VyY2U/Cgo+ Cj4+ICsKPj4gKwkJZm9yIChpID0gMDsgaSA8IGVjYy0+c3RlcHM7IGkrKykgewo+PiArCQkJb29i ID0gbmFuZC0+b29iX3BvaSArCj4+ICsJCQkgICAgICBpICogKGVjYy0+Ynl0ZXMgKyBuYW5kLT5l Y2MucHJlcGFkKTsKPj4gKwkJCWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiAr CQkJCXRtcCA9IGN0cmwtPm9vYl9idWZbaV07Cj4+ICsJCQl9IGVsc2Ugewo+PiArCQkJCXVpbnQ4 X3Qgb29iX3N0ZXAgPSAoY3RybC0+ZWNjX21vZGUgPD0gMjQpID8KPj4gKwkJCQkJCSAgIDY0IDog MTI4Owo+PiArCQkJCXRtcCA9IGN0cmwtPm9vYl9idWZbaSAqIG9vYl9zdGVwIC8gNF07Cj4+ICsJ CQl9Cj4+ICsJCQkqb29iKysgPSAodWludDhfdCl0bXA7Cj4+ICsJCQkqb29iKysgPSAodWludDhf dCkodG1wID4+IDgpOwo+PiArCQkJKm9vYisrID0gKHVpbnQ4X3QpKHRtcCA+PiAxNik7Cj4+ICsJ CQkqb29iKysgPSAodWludDhfdCkodG1wID4+IDI0KTsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiAr CWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiArCQlmb3IgKGkgPSAwOyBpIDwg ZWNjLT5zdGVwcyAvIDI7IGkrKykgewo+PiArCQkJYmNoX3N0ID0gcmVhZGwoY3RybC0+cmVncyAr IE5BTkRDX1JFR19WOV9CQ0hTVCArIGkgKiA0KTsKPj4gKwkJCWlmIChiY2hfc3QgJiBOQU5EQ19W OV9CQ0gwX1NUX0VSUiB8fAo+PiArCQkJICAgIGJjaF9zdCAmIE5BTkRDX1Y5X0JDSDFfU1RfRVJS KSB7Cj4+ICsJCQkJbXRkLT5lY2Nfc3RhdHMuZmFpbGVkKys7Cj4+ICsJCQkJbWF4X2JpdGZsaXBz ID0gLTE7Cj4+ICsJCQl9IGVsc2Ugewo+PiArCQkJCXJldCA9IE5BTkRDX1Y5X0VDQ19FUlJfQ05U MChiY2hfc3QpOwo+PiArCQkJCW10ZC0+ZWNjX3N0YXRzLmNvcnJlY3RlZCArPSByZXQ7Cj4+ICsJ CQkJbWF4X2JpdGZsaXBzID0gbWF4X3QodW5zaWduZWQgaW50LAo+PiArCQkJCQkJICAgICBtYXhf Yml0ZmxpcHMsIHJldCk7Cj4+ICsKPj4gKwkJCQlyZXQgPSBOQU5EQ19WOV9FQ0NfRVJSX0NOVDEo YmNoX3N0KTsKPj4gKwkJCQltdGQtPmVjY19zdGF0cy5jb3JyZWN0ZWQgKz0gcmV0Owo+PiArCQkJ CW1heF9iaXRmbGlwcyA9IG1heF90KHVuc2lnbmVkIGludCwKPj4gKwkJCQkJCSAgICAgbWF4X2Jp dGZsaXBzLCByZXQpOwo+PiArCQkJfQo+PiArCQl9Cj4+ICsJfSBlbHNlIHsKPj4gKwkJZm9yIChp ID0gMDsgaSA8IGVjYy0+c3RlcHMgLyAyOyBpKyspIHsKPj4gKwkJCWJjaF9zdCA9IHJlYWRsKGN0 cmwtPnJlZ3MgKyBOQU5EQ19SRUdfVjZfQkNIU1QgKyBpICogNCk7Cj4+ICsJCQlpZiAoYmNoX3N0 ICYgTkFORENfVjZfQkNIMF9TVF9FUlIgfHwKPj4gKwkJCSAgICBiY2hfc3QgJiBOQU5EQ19WNl9C Q0gxX1NUX0VSUikgewo+PiArCQkJCW10ZC0+ZWNjX3N0YXRzLmZhaWxlZCsrOwo+PiArCQkJCW1h eF9iaXRmbGlwcyA9IC0xOwo+Cgo+IFdoeSBub3QgdXNpbmcgcmV0ID0gJChyZWFsIGVycm9yKSBp bnN0ZWFkIG9mIHVzaW5nIG1heF9iaXRmbGlwcyBoZXJlPwo+Cj4gVGhlbjoKPgo+IAlpZiAocmV0 KSB7Cgo+IAkJZGV2X2VycigpOwoKRG8geW91IHJlYWxseSB3YW50IHRvIGxpdHRlciB0aGUga2Vy bmVsIGxvZyB3aXRoIGVhY2ggdGltZSB5b3UgaGl0IGEgYmFkCmJsb2NrLAppbiBjYXNlIHlvdSB1 c2UgdGhpcyBmdW5jdGlvbiBpbiBhIHNlYXJjaCBiYWQgYmxvY2sgbG9vcD8KRG9uJ3QgdGhpbmtz IHNvIC4uLgpQbGVhc2UgYWR2aXNlLgoKPiAJCXJldHVybiByZXQ7Cj4gCX0KPgo+IAlyZXR1cm4g bWF4X2JpdGZsaXBzOwoKcmtfbmFuZGNfaHdfc3luZHJvbWVfZWNjX3JlYWRfcGFnZSgpIGlzIHVz ZWQgaW4gYSBiYWQgYmxvY2sgc2VhcmNoIHN0cmF0ZWd5LgpJIHRoaW5rIG1heF9iaXRmbGlwcyA9 IC0xIHdhcyBjaG9zZW4gYXMgYSBzYXZlciB2YWx1ZSB0byByZXR1cm4uClBsZWFzZSBhZHZpc2Ug d2hhdCBudW1iZXIgcmFuZ2UgTVREIGludGVycHJldHMgYXMgbWF4X2JpdGZsaXBzIG9yIGFzIGZh dWx0LgpBbHNvIGNvbnNpZGVyIHNvbWUgdW5jb250cm9sbGVkIHN0YXR1cyByZXR1cm4gdmFsdWUs IGl0IHdvdWxkIGJlIGJldHRlcgppZiB3ZQphcmUgaW4gY29udHJvbCBvZiB3aGF0IGdvZXMgcmV0 dXJuLgoKPgo+PiArCQkJfSBlbHNlIHsKPj4gKwkJCQlyZXQgPSBOQU5EQ19WNl9FQ0NfRVJSX0NO VDAoYmNoX3N0KTsKPj4gKwkJCQltdGQtPmVjY19zdGF0cy5jb3JyZWN0ZWQgKz0gcmV0Owo+PiAr CQkJCW1heF9iaXRmbGlwcyA9IG1heF90KHVuc2lnbmVkIGludCwKPj4gKwkJCQkJCSAgICAgbWF4 X2JpdGZsaXBzLCByZXQpOwo+PiArCj4+ICsJCQkJcmV0ID0gTkFORENfVjZfRUNDX0VSUl9DTlQx KGJjaF9zdCk7Cj4+ICsJCQkJbXRkLT5lY2Nfc3RhdHMuY29ycmVjdGVkICs9IHJldDsKPj4gKwkJ CQltYXhfYml0ZmxpcHMgPSBtYXhfdCh1bnNpZ25lZCBpbnQsCj4+ICsJCQkJCQkgICAgIG1heF9i aXRmbGlwcywgcmV0KTsKPj4gKwkJCX0KPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCWlmIChtYXhf Yml0ZmxpcHMgPT0gLTEpIHsKPj4gKwkJZGV2X2VycihtdGQtPmRldi5wYXJlbnQsCj4+ICsJCQki cmVhZF9wYWdlICV4ICV4ICV4ICV4ICV4ICVwICV4XG4iLAo+PiArCQkJcGFnZSwKPj4gKwkJCW1h eF9iaXRmbGlwcywKPj4gKwkJCWJjaF9zdCwKPj4gKwkJCSgodWludDMyX3QgKilidWYpWzBdLAo+ PiArCQkJKCh1aW50MzJfdCAqKWJ1ZilbMV0sCj4+ICsJCQlidWYsCj4+ICsJCQkodWludDMyX3Qp ZG1hX2RhdGEpOwo+Cgo+IFRoaXMgaXMgbm90IHZlcnkgaW5mb3JtYXRpdmUsIHBsZWFzZSB3cml0 ZSBhIHJlYWwgZXJyb3IgbWVzc2FnZS4gQXZvaWQKPiBwdXR0aW5nIHRvbyBtdWNoIGRlYnVnIGlu Zm9ybWF0aW9uLCBwZW9wbGUgd2lsbCB0cm91Ymxlc2hvb3QgdGhlbXNlbHZlcwo+IGlmIG5lZWRl ZC4KCk9LLCBhZ3JlZS4KCj4KPj4gKwl9Cj4+ICsKPj4gKwlpZiAoY3RybC0+Ym9vdHJvbWJsb2Nr cykKPj4gKwkJcmtfbmFuZGNfaHdfZWNjX3NldHVwKG5hbmQsIGN0cmwtPmVjY19tb2RlKTsKPj4g Kwo+Cgo+IFlvdSBkb24ndCB1c2UgdGhlIHNhbWUgY29uZGl0aW9uIGFzIGFib3ZlLiBXaHkgPyBN YXliZSB0aGUgaGVscGVyIHdvdWxkCj4gaGVscC4KCkEgZmV3IGxlc3MgY29uZGl0aW9ucyB0byBj aGVjay4gSXQgd29uJ3QgZG8gZGFtYWdlIGluIGNhc2UgZWNjIGlzCnNhbWUgYmVmb3JlIGFuZCBh ZnRlci4gV2lsbCBtYWtlIGNvbmRpdGlvbnMgZXF1YWwuCgo+Cj4+ICsJcmV0dXJuIG1heF9iaXRm bGlwczsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBya19uYW5kY19od19zeW5kcm9tZV9lY2Nf d3JpdGVfcGFnZShzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLAo+PiArCQljb25zdCB1aW50OF90ICpi dWYsCj4+ICsJCWludCBvb2JfcmVxdWlyZWQsCj4+ICsJCWludCBwYWdlKQo+PiArewo+PiArCXN0 cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4+ICsJc3RydWN0IHJrX25h bmRfY29udHJvbGxlciAqY3RybCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPj4g KwlzdHJ1Y3QgbmFuZF9lY2NfY3RybCAqZWNjID0gJm5hbmQtPmVjYzsKPj4gKwlkbWFfYWRkcl90 IGRtYV9kYXRhLCBkbWFfb29iOwo+PiArCWludCBpOwo+PiArCWludCBkbWFfb29iX3NpemUgPSBl Y2MtPnN0ZXBzICogMTI4Owo+PiArCWludCBwYWdlc19wZXJfYmxrID0gbXRkLT5lcmFzZXNpemUg LyBtdGQtPndyaXRlc2l6ZTsKPj4gKwo+PiArCXJrX25hbmRjX3NlbGVjdF9jaGlwKG5hbmQsIGN0 cmwtPnNlbGVjdGVkX2JhbmspOwo+PiArCj4+ICsJaWYgKChwYWdlIDwgcGFnZXNfcGVyX2JsayAq IE5BTkRDX0lEQlJlc0Jsa051bSkgJiYKPj4gKwkgICAgY3RybC0+Ym9vdHJvbWJsb2NrcykKPj4g KwkJcmtfbmFuZGNfaHdfZWNjX3NldHVwKG5hbmQsIE5BTkRDX0lEQkVjY0JpdHMpOwo+PiArCj4+ ICsJbmFuZF9wcm9nX3BhZ2VfYmVnaW5fb3AobmFuZCwgcGFnZSwgMCwgTlVMTCwgMCk7Cj4+ICsK Pj4gKwlmb3IgKGkgPSAwOyBpIDwgZWNjLT5zdGVwczsgaSsrKSB7Cj4+ICsJCXVpbnQzMl90IHRt cDsKPj4gKwo+PiArCQlpZiAob29iX3JlcXVpcmVkKSB7Cj4+ICsJCQl1aW50OF90ICpvb2I7Cj4+ ICsKPj4gKwkJCW9vYiA9IG5hbmQtPm9vYl9wb2kgKwo+PiArCQkJICAgICAgaSAqIChlY2MtPmJ5 dGVzICsgbmFuZC0+ZWNjLnByZXBhZCk7Cj4+ICsJCQl0bXAgPSBvb2JbMF0gfAo+PiArCQkJICAg ICAgKG9vYlsxXSA8PCA4KSB8Cj4+ICsJCQkgICAgICAob29iWzJdIDw8IDE2KSB8Cj4+ICsJCQkg ICAgICAob29iWzNdIDw8IDI0KTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCS8qIFRoZSBmaXJzdCBO QU5EQ19JREJSZXNCbGtOdW0gYmxvY2tzIGFyZQo+PiArCQkJICogZm9yIHRoZSBzdG9yZWQgbG9h ZGVyLiBUaGUgZmlyc3QgMzIgYml0cwo+PiArCQkJICogb2Ygb29iIG11c3QgY29udGFpbiBhIHNv cnQgb2YgbGluayB0bwo+PiArCQkJICogdGhlIG5leHQgcGFnZSBhZGRyZXNzIGluIHRoYXQgc2Ft ZSBibG9jawo+PiArCQkJICogZm9yIHRoZSBCb290cm9tLgo+PiArCQkJICogRGVwZW5kaW5nIG9u IHdoYXQgRlRMIGZyb20gUm9ja2NoaXAgaXMgdXNlZCwKPj4gKwkJCSAqIHRoZSBmaXJzdCAyIHBh Z2VzIGluIHRoZSBOQU5EQ19JREJSZXNCbGtOdW0gYmxvY2tzCj4+ICsJCQkgKiBhcmUgcmVzZXJ2 ZWQgZm9yIEZsYXNoUGh5SW5mby4KPj4gKwkJCSAqIFJhdyBJREIgZGF0YSB0aGVuIHN0YXJ0cyBh dCBwYWdlIDIgb3IgaGlnaGVyLgo+Cj4gSSB3b3VsZCBzZXBhcmF0ZSB0aGUgZnVuY3Rpb24gdG8g cmVhZC93cml0ZSB0aGUgbG9hZGVyIHRoYW4gdGhlIHVzdWFsCj4gcmVhZC93cml0ZSBoZWxwZXJz IHRvIGF2b2lkIGFueSBjb25mdXNpb24gb24gd2h5IHlvdSBkbyB0aGVzZSB0cmlja3MuCj4KPiBN YXliZSBub3QgdGhlIHdob2xlIGZ1bmN0aW9uLCBidXQgYXQgbGVhc3QgdGhlIGRhdGEvb29iIHBs YWNlbWVudD8KPiAoVGhpcyBpcyByZWFsbHkgYSBzdWdnZXN0aW9uKQo+Cj4+ICsJCQkgKi8KPj4g KwkJCWlmICghaSAmJgo+PiArCQkJICAgIHBhZ2UgPCBwYWdlc19wZXJfYmxrICogTkFORENfSURC UmVzQmxrTnVtICYmCj4+ICsJCQkgICAgcGFnZSA+PSBOQU5EQ19JREJTdGFydEFkZHIpCj4+ICsJ CQkJdG1wID0gKHBhZ2UgJiAocGFnZXNfcGVyX2JsayAtIDEpKSAqIDQ7Cj4+ICsJCQllbHNlCj4+ ICsJCQkJdG1wID0gMHhGRkZGRkZGRjsKPj4gKwkJfQo+PiArCQlpZiAoY3RybC0+dmVyc2lvbiA9 PSBWRVJTSU9OXzkpIHsKPj4gKwkJCWN0cmwtPm9vYl9idWZbaV0gPSB0bXA7Cj4+ICsJCX0gZWxz ZSB7Cj4+ICsJCQl1aW50OF90IG9vYl9zdGVwID0gKGN0cmwtPmVjY19tb2RlIDw9IDI0KSA/Cj4+ ICsJCQkJCSAgIDY0IDogMTI4Owo+PiArCQkJY3RybC0+b29iX2J1ZltpICogb29iX3N0ZXAgLyA0 XSA9IHRtcDsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCW1lbWNweShjdHJsLT5wYWdlX2J1Ziwg YnVmLCBtdGQtPndyaXRlc2l6ZSk7Cj4+ICsJZG1hX2RhdGEgPSBya19uYW5kY19kbWFfbWFwX3Np bmdsZShtdGQtPmRldi5wYXJlbnQsCj4+ICsJCQkJCSAgIGN0cmwtPnBhZ2VfYnVmLCBtdGQtPndy aXRlc2l6ZSwKPj4gKwkJCQkJICAgRE1BX1RPX0RFVklDRSk7Cj4+ICsJZG1hX29vYiA9IHJrX25h bmRjX2RtYV9tYXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwKPj4gKwkJCQkJICBjdHJsLT5vb2Jf YnVmLCBkbWFfb29iX3NpemUsCj4+ICsJCQkJCSAgRE1BX1RPX0RFVklDRSk7Cj4+ICsJaW5pdF9j b21wbGV0aW9uKCZjdHJsLT5jb21wbGV0ZSk7Cj4+ICsJaWYgKGN0cmwtPnZlcnNpb24gPT0gVkVS U0lPTl85KQo+PiArCQl3cml0ZWwoTkFORENfVjlfSU5UX0RNQSwgY3RybC0+cmVncyArIE5BTkRD X1JFR19WOV9JTlRFTik7Cj4+ICsJZWxzZQo+PiArCQl3cml0ZWwoTkFORENfVjZfSU5UX0RNQSwg Y3RybC0+cmVncyArIE5BTkRDX1JFR19WNl9JTlRFTik7Cj4+ICsJcmtfbmFuZGNfeGZlcl9zdGFy dChjdHJsLCAxLCBlY2MtPnN0ZXBzLCBkbWFfZGF0YSwgZG1hX29vYik7Cj4+ICsJd2FpdF9mb3Jf Y29tcGxldGlvbl90aW1lb3V0KCZjdHJsLT5jb21wbGV0ZSwgbXNlY3NfdG9famlmZmllcygxMCkp Owo+PiArCXJrX25hbmRjX3dhaXRfZm9yX3hmZXJfZG9uZShjdHJsKTsKPj4gKwlya19uYW5kY19k bWFfdW5tYXBfc2luZ2xlKG10ZC0+ZGV2LnBhcmVudCwgZG1hX2RhdGEsIG10ZC0+d3JpdGVzaXpl LAo+PiArCQkJCSAgRE1BX1RPX0RFVklDRSk7Cj4+ICsJcmtfbmFuZGNfZG1hX3VubWFwX3Npbmds ZShtdGQtPmRldi5wYXJlbnQsIGRtYV9vb2IsIGRtYV9vb2Jfc2l6ZSwKPj4gKwkJCQkgIERNQV9U T19ERVZJQ0UpOwo+PiArCj4+ICsJaWYgKGN0cmwtPmJvb3Ryb21ibG9ja3MpCj4+ICsJCXJrX25h bmRjX2h3X2VjY19zZXR1cChuYW5kLCBjdHJsLT5lY2NfbW9kZSk7Cj4+ICsKPj4gKwlyZXR1cm4g bmFuZF9wcm9nX3BhZ2VfZW5kX29wKG5hbmQpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJr X25hbmRjX2h3X2VjY19yZWFkX29vYihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBpbnQgcGFnZSkK Pj4gK3sKPj4gKwl1aW50OF90ICpidWYgPSBuYW5kX2dldF9kYXRhX2J1ZihuYW5kKTsKPj4gKwo+ PiArCXJldHVybiBuYW5kLT5lY2MucmVhZF9wYWdlKG5hbmQsIGJ1ZiwgdHJ1ZSwgcGFnZSk7Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfaHdfZWNjX3dyaXRlX29vYihzdHJ1Y3Qg bmFuZF9jaGlwICpuYW5kLCBpbnQgcGFnZSkKPj4gK3sKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10 ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+PiArCWludCByZXQ7Cj4+ICsJdWludDhfdCAqYnVmID0g bmFuZF9nZXRfZGF0YV9idWYobmFuZCk7Cj4+ICsKPj4gKwltZW1zZXQoYnVmLCAweEZGLCBtdGQt PndyaXRlc2l6ZSk7Cj4+ICsJcmV0ID0gbmFuZC0+ZWNjLndyaXRlX3BhZ2UobmFuZCwgYnVmLCB0 cnVlLCBwYWdlKTsKPj4gKwlpZiAocmV0KQo+PiArCQlyZXR1cm4gcmV0Owo+PiArCj4+ICsJcmV0 dXJuIG5hbmRfcHJvZ19wYWdlX2VuZF9vcChuYW5kKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZv aWQgcmtfbmFuZGNfcmVhZF9idWYoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgdWludDhfdCAqYnVm LAppbnQgbGVuKQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBu YW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsJaW50IG9mZnMgPSAwOwo+PiArCXZv aWQgX19pb21lbSAqYmFua19iYXNlID0gY3RybC0+cmVncyArIE5BTkRDX1JFR19CQU5LMCArCj4+ ICsJCQkJICBjdHJsLT5zZWxlY3RlZF9iYW5rICogMHgxMDA7Cj4KCj4gMHgxMDA6IE1heWJlIGEg ZGVmaW5lCgpPSywgYWdyZWUuCgo+Cj4+ICsKPj4gKwlmb3IgKG9mZnMgPSAwOyBvZmZzIDwgbGVu OyBvZmZzKyspCj4+ICsJCWJ1ZltvZmZzXSA9IHJlYWRiKGJhbmtfYmFzZSk7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyB2b2lkIHJrX25hbmRjX3dyaXRlX2J1ZihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k LAo+PiArCQkJICAgICAgIGNvbnN0IHVpbnQ4X3QgKmJ1ZiwgaW50IGxlbikKPj4gK3sKPj4gKwlz dHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRh KG5hbmQpOwo+PiArCWludCBvZmZzID0gMDsKPj4gKwl2b2lkIF9faW9tZW0gKmJhbmtfYmFzZSA9 IGN0cmwtPnJlZ3MgKyBOQU5EQ19SRUdfQkFOSzAgKwo+PiArCQkJCSAgY3RybC0+c2VsZWN0ZWRf YmFuayAqIDB4MTAwOwo+PiArCj4+ICsJZm9yIChvZmZzID0gMDsgb2ZmcyA8IGxlbjsgb2Zmcysr KQo+PiArCQl3cml0ZWIoYnVmW29mZnNdLCBiYW5rX2Jhc2UpOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgdm9pZCBya19uYW5kY193cml0ZV9jbWQoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgdWludDhf dCBjbWQpCj4+ICt7Cj4+ICsJc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCA9IG5hbmRf Z2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPj4gKwo+PiArCXZvaWQgX19pb21lbSAqYmFua19i YXNlID0gY3RybC0+cmVncyArIE5BTkRDX1JFR19CQU5LMCArCj4+ICsJCQkJICBjdHJsLT5zZWxl Y3RlZF9iYW5rICogMHgxMDAgKwo+PiArCQkJCSAgTkFORENfUkVHX0NNRDsKPgoKPiBZb3UgbWln aHQgd2FudCB0byB3cml0ZSBhbiBoZWxwZXIgdG8gY2FsY3VsYXRlIGJhbmtfYmFzZSwgdG8gYXZv aWQKPiByZXBlYXRpbmcgdGhlc2UgbGluZXMuCgpFdmVuIHdpdGggYSBzZXBhcmF0ZSBkZWZpbmUg b3IgaGVscGVyIGZ1bmN0aW9uIEkgc3RpbGwgaGF2ZSB0byBzdXBwbHkKbXkgcmVnLCBzZWxlY3Rl ZF9iYW5rIGFuZCBvZmZzZXQuIEl0IGRvZXNuJ3QgbWFrZSB0aGluZ3MgY2xlYW5lciBwdW1waW5n CmRhdGUKdG8gYW5kIGZyb20gYSBoZWxwZXIgb3IgbmVpdGhlciBkb2Vzbid0IGl0IHNob3J0ZW4g bXkgc291cmNlIHdpdGggYSBkZWZpbmUuClRlbmQgdG8ga2VlcCBpdCBhcyBpdCBpcyBmb3Igbm93 LiBJZiB5b3UgYWdyZWUgb2YgY291cnNlLgoKPgo+PiArCj4+ICsJd3JpdGViKGNtZCwgYmFua19i YXNlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgcmtfbmFuZGNfd3JpdGVfYWRkcihzdHJ1 Y3QgbmFuZF9jaGlwICpuYW5kLCB1aW50OF90IGFkZHIpCj4+ICt7Cj4+ICsJc3RydWN0IHJrX25h bmRfY29udHJvbGxlciAqY3RybCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPj4g Kwo+PiArCXZvaWQgX19pb21lbSAqYmFua19iYXNlID0gY3RybC0+cmVncyArIE5BTkRDX1JFR19C QU5LMCArCj4+ICsJCQkJICBjdHJsLT5zZWxlY3RlZF9iYW5rICogMHgxMDAgKwo+PiArCQkJCSAg TkFORENfUkVHX0FERFI7Cj4+ICsKPj4gKwl3cml0ZWIoYWRkciwgYmFua19iYXNlKTsKPj4gK30K Pj4gKwo+PiArc3RhdGljIGludCBya19uYW5kY19kZXZfcmVhZHkoc3RydWN0IG5hbmRfY2hpcCAq bmFuZCkKPj4gK3sKPj4gKwlzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF9n ZXRfY29udHJvbGxlcl9kYXRhKG5hbmQpOwo+PiArCj4+ICsJaWYgKHJlYWRsKGN0cmwtPnJlZ3Mg KyBOQU5EQ19SRUdfVjZfRk1DVEwpICYgTkFORENfVjZfRk1fRlJFQURZKQo+PiArCQlyZXR1cm4g MTsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJrX25hbmRj X29vYmxheW91dF9lY2Moc3RydWN0IG10ZF9pbmZvICptdGQsIGludCBzZWN0aW9uLAo+PiArCQkJ CSAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2JyZWdpb24pCj4+ICt7Cj4+ICsJc3RydWN0IG5h bmRfY2hpcCAqbmFuZCA9IG10ZF90b19uYW5kKG10ZCk7Cj4+ICsKPj4gKwlpZiAoc2VjdGlvbiA+ PSBuYW5kLT5lY2Muc3RlcHMpCj4+ICsJCXJldHVybiAtRVJBTkdFOwo+PiArCj4+ICsJb29icmVn aW9uLT5vZmZzZXQgPSAobmFuZC0+ZWNjLmJ5dGVzICsgbmFuZC0+ZWNjLnByZXBhZCkgKiBzZWN0 aW9uICsKPj4gKwkJCSAgICBuYW5kLT5lY2MucHJlcGFkOwo+PiArCW9vYnJlZ2lvbi0+bGVuZ3Ro ID0gbmFuZC0+ZWNjLnN0ZXBzICogbmFuZC0+ZWNjLmJ5dGVzOwo+PiArCj4+ICsJcmV0dXJuIDA7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfb29ibGF5b3V0X2ZyZWUoc3RydWN0 IG10ZF9pbmZvICptdGQsIGludCBzZWN0aW9uLAo+PiArCQkJCSAgIHN0cnVjdCBtdGRfb29iX3Jl Z2lvbiAqb29icmVnaW9uKQo+PiArewo+PiArCXN0cnVjdCBuYW5kX2NoaXAgKm5hbmQgPSBtdGRf dG9fbmFuZChtdGQpOwo+PiArCj4+ICsJaWYgKHNlY3Rpb24gPj0gbmFuZC0+ZWNjLnN0ZXBzKQo+ PiArCQlyZXR1cm4gLUVSQU5HRTsKPj4gKwo+PiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0gKG5hbmQt PmVjYy5ieXRlcyArIG5hbmQtPmVjYy5wcmVwYWQpICogc2VjdGlvbjsKPj4gKwlvb2JyZWdpb24t Pmxlbmd0aCA9IG5hbmQtPmVjYy5zdGVwcyAqIG5hbmQtPmVjYy5wcmVwYWQ7Cj4+ICsKPj4gKwly ZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBtdGRfb29ibGF5b3V0 X29wcyBya19uYW5kY19vb2Jfb3BzID0gewo+PiArCS5lY2MgPSBya19uYW5kY19vb2JsYXlvdXRf ZWNjLAo+PiArCS5mcmVlID0gcmtfbmFuZGNfb29ibGF5b3V0X2ZyZWUsCj4+ICt9Owo+PiArCj4+ ICtzdGF0aWMgdm9pZCBya19uYW5kY19mcmVlX2J1ZmZlcihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k KQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9j b250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsKPj4gKwlrZnJlZShjdHJsLT5wYWdlX2J1Zik7Cj4+ ICsJa2ZyZWUoY3RybC0+b29iX2J1Zik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFu ZGNfYnVmZmVyX2luaXQoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCkKPj4gK3sKPj4gKwlzdHJ1Y3Qg bXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+PiArCXN0cnVjdCBya19uYW5kX2Nv bnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4+ICsKPj4g KwljdHJsLT5wYWdlX2J1ZiA9IGttYWxsb2MobXRkLT53cml0ZXNpemUsIEdGUF9LRVJORUwgfCBH RlBfRE1BKTsKPgoKPiBkZXZpY2UgbWFuYWdlZCBhbGxvY2F0aW9ucyAoZGV2bV8uLi4pIHdvdWxk IGJlIG5pY2UKCmRldm1fa3phbGxvYygpIG5lZWRzIGFuIGV4dHJhIHN0cnVjdCBkZXZpY2UuCkRv ZXMgTVREIHNhZmUtZ2FyZCB0aGUgY29ycmVjdCBvcmRlciB0byBkZXRhY2ggZnJvbSBzdHJ1Y3QK cmtfbmFuZF9jb250cm9sbGVyCndpdGhvdXQgcmtfbmFuZGNfZnJlZV9idWZmZXIoKT8KCj4KPj4g KwlpZiAoIWN0cmwtPnBhZ2VfYnVmKQo+PiArCQlyZXR1cm4gLUVOT01FTTsKPj4gKwo+PiArCWN0 cmwtPm9vYl9idWYgPSBrbWFsbG9jKG5hbmQtPmVjYy5zdGVwcyAqIDEyOCwgR0ZQX0tFUk5FTCB8 IEdGUF9ETUEpOwo+PiArCWlmICghY3RybC0+b29iX2J1Zikgewo+PiArCQlrZnJlZShjdHJsLT5w YWdlX2J1Zik7Cj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCX0KPj4gKwo+PiArCXJldHVybiAw Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJrX25hbmRjX2h3X2VjY19jdHJsX2luaXQoc3Ry dWN0IG5hbmRfY2hpcCAqbmFuZCkKPj4gK3sKPj4gKwl1aW50OF90IHN0cmVuZ3Roc192NltdID0g ezYwLCA0MCwgMjQsIDE2fTsKPj4gKwl1aW50OF90IHN0cmVuZ3Roc192OVtdID0gezcwLCA2MCwg NDAsIDE2fTsKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+ PiArCXN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0cmwgPSBuYW5kX2dldF9jb250cm9sbGVy X2RhdGEobmFuZCk7Cj4+ICsJaW50IG1heF9zdHJlbmd0aDsKPj4gKwl1aW50MzJfdCBpLCB2ZXI7 Cj4+ICsKPj4gKwlpZiAobmFuZC0+b3B0aW9ucyAmIE5BTkRfSVNfQk9PVF9NRURJVU0pCj4+ICsJ CWN0cmwtPmJvb3Ryb21ibG9ja3MgPSB0cnVlOwo+PiArCWVsc2UKPj4gKwkJY3RybC0+Ym9vdHJv bWJsb2NrcyA9IGZhbHNlOwo+PiArCj4+ICsJbmFuZC0+ZWNjLnByZXBhZCA9IDQ7Cj4+ICsJbmFu ZC0+ZWNjLnN0ZXBzID0gbXRkLT53cml0ZXNpemUgLyBuYW5kLT5lY2Muc2l6ZTsKPj4gKwo+PiAr CW1heF9zdHJlbmd0aCA9ICgobXRkLT5vb2JzaXplIC8gbmFuZC0+ZWNjLnN0ZXBzKSAtIDQpICog OCAvIDE0Owo+PiArCWlmIChjdHJsLT52ZXJzaW9uID09IFZFUlNJT05fOSkgewo+PiArCQljdHJs LT5tYXhfZWNjX3N0cmVuZ3RoID0gNzA7Cj4+ICsJCXZlciA9IHJlYWRsKGN0cmwtPnJlZ3MgKyBO QU5EQ19SRUdfVjlfVkVSKTsKPj4gKwkJaWYgKHZlciAhPSBOQU5EQ19JRF9WOTAwKQo+PiArCQkJ ZGV2X2VycihtdGQtPmRldi5wYXJlbnQsCj4+ICsJCQkJInVuc3VwcG9ydGVkIG5hbmRjIHZlcnNp b24gJXhcbiIsIHZlcik7Cj4+ICsKPj4gKwkJaWYgKG1heF9zdHJlbmd0aCA+IGN0cmwtPm1heF9l Y2Nfc3RyZW5ndGgpCj4+ICsJCQltYXhfc3RyZW5ndGggPSBjdHJsLT5tYXhfZWNjX3N0cmVuZ3Ro Owo+PiArCj4+ICsJCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHN0cmVuZ3Roc192OSk7IGkr Kykgewo+PiArCQkJaWYgKG1heF9zdHJlbmd0aCA+PSBzdHJlbmd0aHNfdjlbaV0pCj4+ICsJCQkJ YnJlYWs7Cj4+ICsJCX0KPj4gKwo+PiArCQlpZiAoaSA+PSBBUlJBWV9TSVpFKHN0cmVuZ3Roc192 OSkpIHsKPj4gKwkJCWRldl9lcnIobXRkLT5kZXYucGFyZW50LAo+PiArCQkJCSJ1bnN1cHBvcnRl ZCBzdHJlbmd0aFxuIik7Cj4+ICsJCQlyZXR1cm4gLUVOT1RTVVBQOwo+PiArCQl9Cj4+ICsKPj4g KwkJY3RybC0+ZWNjX21vZGUgPSBzdHJlbmd0aHNfdjlbaV07Cj4+ICsJfSBlbHNlIHsKPj4gKwkJ Y3RybC0+bWF4X2VjY19zdHJlbmd0aCA9IDYwOwo+PiArCj4+ICsJCXZlciA9IHJlYWRsKGN0cmwt PnJlZ3MgKyBOQU5EQ19SRUdfVjZfVkVSKTsKPj4gKwkJaWYgKHZlciA9PSBOQU5EQ19JRF9WODAx KQo+PiArCQkJY3RybC0+bWF4X2VjY19zdHJlbmd0aCA9IDE2Owo+PiArCQllbHNlIGlmICh2ZXIg PT0gTkFORENfSURfVjYwMCB8fAo+PiArCQkJIHZlciA9PSBOQU5EQ19JRF9WNjIyIHx8Cgo+PiAr CQkJIHZlciA9PSBOQU5EQ19JRF9WNzAxIHx8CgpBZGRlZCB2ZXJzaW9uIDcgZm9yIFJLMzIyOEEv UkszMjI4Qi4gQ2FuIHNvbWVvbmUgd2l0aCBpbnNpZGVyIGluZm8gY29uZmlybQppZiB0aGlzIHdv cmtzIG9yIG5vdC4KCj4+ICsJCQkgdmVyID09IE5BTkRDX0lEX1Y4MDApCj4+ICsJCQljdHJsLT5t YXhfZWNjX3N0cmVuZ3RoID0gNjA7Cj4+ICsJCWVsc2UKPj4gKwkJCWRldl9lcnIobXRkLT5kZXYu cGFyZW50LAo+PiArCQkJCSJ1bnN1cHBvcnRlZCBuYW5kYyB2ZXJzaW9uICV4XG4iLCB2ZXIpOwo+ PiArCj4+ICsJCWlmIChtYXhfc3RyZW5ndGggPiBjdHJsLT5tYXhfZWNjX3N0cmVuZ3RoKQo+PiAr CQkJbWF4X3N0cmVuZ3RoID0gY3RybC0+bWF4X2VjY19zdHJlbmd0aDsKPj4gKwo+PiArCQlmb3Ig KGkgPSAwOyBpIDwgQVJSQVlfU0laRShzdHJlbmd0aHNfdjYpOyBpKyspIHsKPj4gKwkJCWlmICht YXhfc3RyZW5ndGggPj0gc3RyZW5ndGhzX3Y2W2ldKQo+PiArCQkJCWJyZWFrOwo+PiArCQl9Cj4+ ICsKPj4gKwkJaWYgKGkgPj0gQVJSQVlfU0laRShzdHJlbmd0aHNfdjYpKSB7Cj4+ICsJCQlkZXZf ZXJyKG10ZC0+ZGV2LnBhcmVudCwKPj4gKwkJCQkidW5zdXBwb3J0ZWQgc3RyZW5ndGhcbiIpOwo+ PiArCQkJcmV0dXJuIC1FTk9UU1VQUDsKPj4gKwkJfQo+PiArCj4+ICsJCWN0cmwtPmVjY19tb2Rl ID0gc3RyZW5ndGhzX3Y2W2ldOwo+PiArCX0KPj4gKwlya19uYW5kY19od19lY2Nfc2V0dXAobmFu ZCwgY3RybC0+ZWNjX21vZGUpOwo+PiArCj4+ICsJbXRkX3NldF9vb2JsYXlvdXQobXRkLCAmcmtf bmFuZGNfb29iX29wcyk7Cj4+ICsKPj4gKwlpZiAobXRkLT5vb2JzaXplIDwgKChuYW5kLT5lY2Mu Ynl0ZXMgKyBuYW5kLT5lY2MucHJlcGFkKSAqCj4+ICsJCQkgICAgbmFuZC0+ZWNjLnN0ZXBzKSkg ewo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30K Pj4gKwo+PiArc3RhdGljIHZvaWQgcmtfbmFuZGNfZGV0YWNoX2NoaXAoc3RydWN0IG5hbmRfY2hp cCAqbmFuZCkKPj4gK3sKPj4gKwlzd2l0Y2ggKG5hbmQtPmVjYy5tb2RlKSB7Cj4+ICsJY2FzZSBO QU5EX0VDQ19IV19TWU5EUk9NRToKPj4gKwkJcmtfbmFuZGNfZnJlZV9idWZmZXIobmFuZCk7Cj4+ ICsJCWJyZWFrOwo+PiArCWRlZmF1bHQ6Cj4+ICsJCWJyZWFrOwo+PiArCX0KPj4gK30KPj4gKwo+ PiArc3RhdGljIGludCBya19uYW5kY19hdHRhY2hfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k KQo+PiArewo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4+ ICsJaW50IHJldDsKPj4gKwo+PiArCXN3aXRjaCAobmFuZC0+ZWNjLm1vZGUpIHsKPj4gKwljYXNl IE5BTkRfRUNDX0hXX1NZTkRST01FOgo+PiArCQlyZXQgPSBya19uYW5kY19od19lY2NfY3RybF9p bml0KG5hbmQpOwo+PiArCQlpZiAocmV0KQo+PiArCQkJcmV0dXJuIHJldDsKPj4gKwkJcmV0ID0g cmtfbmFuZGNfYnVmZmVyX2luaXQobmFuZCk7Cj4+ICsJCWlmIChyZXQpCj4+ICsJCQlyZXR1cm4g LUVOT01FTTsKPj4gKwkJbmFuZC0+ZWNjLnJlYWRfcGFnZSA9IHJrX25hbmRjX2h3X3N5bmRyb21l X2VjY19yZWFkX3BhZ2U7Cj4+ICsJCW5hbmQtPmVjYy53cml0ZV9wYWdlID0gcmtfbmFuZGNfaHdf c3luZHJvbWVfZWNjX3dyaXRlX3BhZ2U7Cj4+ICsJCW5hbmQtPmVjYy5yZWFkX29vYiA9IHJrX25h bmRjX2h3X2VjY19yZWFkX29vYjsKPj4gKwkJbmFuZC0+ZWNjLndyaXRlX29vYiA9IHJrX25hbmRj X2h3X2VjY193cml0ZV9vb2I7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgTkFORF9FQ0NfSFc6Cj4K PiBJIHdvdWxkIGVpdGhlciByZWZ1c2UgRUNDX0hXIG9yIHB1dCBpdCBiZXNpZGVzIEhXX1NZTkRS T01FLgoKSXMgdGhlcmUgYSBmdW5kYW1lbnRhbCBkaWZmZXJlbmNlIGluIGhhbmRsaW5nIEVDQ19I VyBhbmQgSFdfU1lORFJPTUUKZnJvbSB0aGUgTVREIHBvaW50IG9mIHZpZXc/IE90aGVyIHRoZW4g YSBpbmRpY2F0aW9uIGhvdyBpdCdzIGRvbmUgb24KdGhlIGRyaXZlciBzaWRlPwpXaWxsIGRyb3Ag aXQuCgo+Cj4+ICsJY2FzZSBOQU5EX0VDQ19OT05FOgo+PiArCWNhc2UgTkFORF9FQ0NfU09GVDoK PgoKPiBIYXZlIHlvdSB0ZXN0ZWQgd2l0aCBTVyBCQ0g/CgpTaG9ydCBhbnN3ZXI6IE5vCkp1c3Qg Y29waWVkIGl0IGZyb20gdGhlIG9yaWdpbmFsLgpQbGVhc2UgYWR2aXNlIGEgdG9vbCB0byBkbyBh IHRlc3QgYmV0d2VlbiB0aGUgaW5kaXZpZHVhbCBlY2MgcmVhZCBvcHRpb25zLgpPciBkbyBJIGhh dmUgdG8gd3JpdGUgdGhlIHRvb2wgbXkgc2VsZiB3aXRoIG10ZC11dGlscz8KCj4KPj4gKwkJYnJl YWs7Cj4+ICsJZGVmYXVsdDoKPj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJ cmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfZXhlY19vcChzdHJ1 Y3QgbmFuZF9jaGlwICpuYW5kLAo+PiArCQkJICAgIGNvbnN0IHN0cnVjdCBuYW5kX29wZXJhdGlv biAqb3AsCj4+ICsJCQkgICAgYm9vbCBjaGVja19vbmx5KQo+PiArewo+PiArCWludCBpOwo+PiAr CXVuc2lnbmVkIGludCBvcF9pZDsKPj4gKwljb25zdCBzdHJ1Y3QgbmFuZF9vcF9pbnN0ciAqaW5z dHIgPSBOVUxMOwo+PiArCj4+ICsJcmtfbmFuZGNfc2VsZWN0X2NoaXAobmFuZCwgb3AtPmNzKTsK Pj4gKwo+PiArCWlmIChjaGVja19vbmx5KQo+PiArCQlyZXR1cm4gMDsKPj4gKwo+PiArCWZvciAo b3BfaWQgPSAwOyBvcF9pZCA8IG9wLT5uaW5zdHJzOyBvcF9pZCsrKSB7Cj4+ICsJCWluc3RyID0g Jm9wLT5pbnN0cnNbb3BfaWRdOwo+PiArCj4+ICsJCXN3aXRjaCAoaW5zdHItPnR5cGUpIHsKPj4g KwkJY2FzZSBOQU5EX09QX0NNRF9JTlNUUjoKPj4gKwkJCXJrX25hbmRjX3dyaXRlX2NtZChuYW5k LCBpbnN0ci0+Y3R4LmNtZC5vcGNvZGUpOwo+PiArCQkJYnJlYWs7Cj4+ICsJCWNhc2UgTkFORF9P UF9BRERSX0lOU1RSOgo+PiArCQkJZm9yIChpID0gMDsgaSA8IGluc3RyLT5jdHguYWRkci5uYWRk cnM7IGkrKykKPj4gKwkJCQlya19uYW5kY193cml0ZV9hZGRyKG5hbmQsCj4+ICsJCQkJCQkgICAg aW5zdHItPmN0eC5hZGRyLmFkZHJzW2ldKTsKPj4gKwkJCWJyZWFrOwo+PiArCQljYXNlIE5BTkRf T1BfREFUQV9JTl9JTlNUUjoKPj4gKwkJCXJrX25hbmRjX3JlYWRfYnVmKG5hbmQsIGluc3RyLT5j dHguZGF0YS5idWYuaW4sCj4+ICsJCQkJCSAgaW5zdHItPmN0eC5kYXRhLmxlbik7Cj4+ICsJCQli cmVhazsKPj4gKwkJY2FzZSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSOgo+PiArCQkJcmtfbmFuZGNf d3JpdGVfYnVmKG5hbmQsIGluc3RyLT5jdHguZGF0YS5idWYub3V0LAo+PiArCQkJCQkgICBpbnN0 ci0+Y3R4LmRhdGEubGVuKTsKPj4gKwkJCWJyZWFrOwo+PiArCQljYXNlIE5BTkRfT1BfV0FJVFJE WV9JTlNUUjoKPj4gKwkJCXJrX25hbmRjX2Rldl9yZWFkeShuYW5kKTsKPj4gKwkJCWJyZWFrOwo+ PiArCQl9Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBj b25zdCBzdHJ1Y3QgbmFuZF9jb250cm9sbGVyX29wcyBya19uYW5kX2NvbnRyb2xsZXJfb3BzID0g ewo+PiArCS5hdHRhY2hfY2hpcCA9IHJrX25hbmRjX2F0dGFjaF9jaGlwLAo+PiArCS5kZXRhY2hf Y2hpcCA9IHJrX25hbmRjX2RldGFjaF9jaGlwLAo+PiArCS5leGVjX29wID0gcmtfbmFuZGNfZXhl Y19vcCwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfY2hpcF9pbml0KHN0cnVj dCBkZXZpY2UgKmRldiwKPj4gKwkJCSAgICAgIHN0cnVjdCBya19uYW5kX2NvbnRyb2xsZXIgKmN0 cmwsCj4+ICsJCQkgICAgICBzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wLCB1bnNpZ25lZCBpbnQgY2hp cG5yKQo+PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NoaXAgKm5vZGU7Cj4+ICsJc3RydWN0IG5h bmRfY2hpcCAqbmFuZDsKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZDsKPj4gKwljb25zdCBfX2Jl MzIgKnJlZzsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJcmVnID0gb2ZfZ2V0X3Byb3BlcnR5KG5w LCAicmVnIiwgTlVMTCk7Cj4+ICsJaWYgKCFyZWcpCj4+ICsJCXJldHVybiAtRUlOVkFMOwo+PiAr Cj4+ICsJY3RybC0+YmFua3NbY2hpcG5yXSA9IGJlMzJfdG9fY3B1KCpyZWcpOwo+PiArCj4+ICsJ aWYgKGN0cmwtPmJhbmtzW2NoaXBucl0gPCAwKQo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwo+ PiArCW5vZGUgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKm5vZGUpLCBHRlBfS0VSTkVMKTsK Pj4gKwlpZiAoIW5vZGUpCj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCj4+ICsJbmFuZCA9ICZu b2RlLT5uYW5kOwo+PiArCj4+ICsJbmFuZF9zZXRfZmxhc2hfbm9kZShuYW5kLCBucCk7Cj4+ICsJ bmFuZF9zZXRfY29udHJvbGxlcl9kYXRhKG5hbmQsIGN0cmwpOwo+PiArCj4+ICsJbmFuZC0+Y29u dHJvbGxlciA9ICZjdHJsLT5jb250cm9sbGVyOwo+PiArCW5hbmQtPmNvbnRyb2xsZXItPm9wcyA9 ICZya19uYW5kX2NvbnRyb2xsZXJfb3BzOwo+PiArCj4+ICsJbmFuZC0+ZWNjLm1vZGUgPSBOQU5E X0VDQ19IV19TWU5EUk9NRTsKPj4gKwluYW5kLT5lY2Muc2l6ZSA9IDEwMjQ7Cj4+ICsJbmFuZC0+ ZWNjLnN0cmVuZ3RoID0gNDA7Cj4+ICsKPj4gKwluYW5kLT5vcHRpb25zID0gTkFORF9TS0lQX0JC VFNDQU4gfCBOQU5EX05PX1NVQlBBR0VfV1JJVEU7Cj4+ICsKPj4gKwltdGQgPSBuYW5kX3RvX210 ZChuYW5kKTsKPj4gKwltdGQtPmRldi5wYXJlbnQgPSBkZXY7Cj4+ICsJbXRkLT5uYW1lID0gZGV2 bV9rYXNwcmludGYoZGV2LCBHRlBfS0VSTkVMLCAiJXMuJWQiLCBkZXZfbmFtZShkZXYpLAo+PiAr CQkJCSAgIGN0cmwtPmJhbmtzW2NoaXBucl0pOwo+PiArCj4+ICsJcmV0ID0gbmFuZF9zY2FuKG5h bmQsIDEpOwo+Cj4gV2h5IDEgaGVyZT8KClRPRE8gZm9yIHZlcnNpb24gMi4KQSBsaXR0bGUgbWlz dW5kZXJzdGFuZGluZyBvbiBob3cgZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZSB3b3Jrcy4KQWxsIGNo aXBzIHNob3VsZCBiZSBzY2FubmVkLgovLy8vLwpEZXJpdmUgY2hpcG5yCkV4YW1wbGUgZnJvbSBz dW54aV9uYW5kLmMKCglpZiAoIW9mX2dldF9wcm9wZXJ0eShucCwgInJlZyIsICZuc2VscykpCgkJ cmV0dXJuIC1FSU5WQUw7CgoJbnNlbHMgLz0gc2l6ZW9mKHUzMik7CglpZiAoIW5zZWxzKSB7CgkJ ZGV2X2VycihkZXYsICJpbnZhbGlkIHJlZyBwcm9wZXJ0eSBzaXplXG4iKTsKCQlyZXR1cm4gLUVJ TlZBTDsKCX0KLy8vLy8KRnJvbSBya19uYW5kY19jaGlwc19pbml0KCkKCglmb3JfZWFjaF9jaGls ZF9vZl9ub2RlKG5wLCBuYW5kX25wKSB7CgkJcmV0ID0gcmtfbmFuZGNfY2hpcF9pbml0KGRldiwg Y3RybCwgbmFuZF9ucCwgaSk7CgpXaHkgZG9lcyBzdW54aV9uYW5kLmMgbmVlZCB0aGlzIGV4dHJh IGZvcl9lYWNoX2NoaWxkX29mX25vZGU/Cgo+Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuIHJl dDsKPj4gKwo+PiArCXJldCA9IG10ZF9kZXZpY2VfcmVnaXN0ZXIobXRkLCBOVUxMLCAwKTsKPj4g KwlpZiAocmV0KSB7Cj4+ICsJCWRldl9lcnIoZGV2LCAibXRkIGRldmljZSByZWdpc3RlciBmYWls ZWQ6ICVkXG4iLCByZXQpOwo+PiArCQluYW5kX3JlbGVhc2UobmFuZCk7Cj4+ICsJCXJldHVybiBy ZXQ7Cj4+ICsJfQo+PiArCj4+ICsJbGlzdF9hZGRfdGFpbCgmbm9kZS0+Y2hpcF9saXN0LCAmY3Ry bC0+Y2hpcHMpOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQg cmtfbmFuZGNfY2xlYW51cF9jaGlwcyhzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsKQo+ PiArewo+PiArCXN0cnVjdCBya19uYW5kX2NoaXAgKm5vZGU7Cj4+ICsJc3RydWN0IG10ZF9pbmZv ICptdGQ7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXdoaWxlICghbGlzdF9lbXB0eSgmY3RybC0+ Y2hpcHMpKSB7Cj4+ICsJCW5vZGUgPSBsaXN0X2ZpcnN0X2VudHJ5KCZjdHJsLT5jaGlwcywgc3Ry dWN0IHJrX25hbmRfY2hpcCwKPj4gKwkJCQkJY2hpcF9saXN0KTsKPj4gKwkJbXRkID0gbmFuZF90 b19tdGQoJm5vZGUtPm5hbmQpOwo+PiArCQlyZXQgPSBtdGRfZGV2aWNlX3VucmVnaXN0ZXIobXRk KTsKPj4gKwkJaWYgKHJldCkKPj4gKwkJCXJldHVybiByZXQ7Cj4+ICsKPj4gKwkJcmtfbmFuZGNf ZnJlZV9idWZmZXIoJm5vZGUtPm5hbmQpOwo+PiArCQluYW5kX2NsZWFudXAoJm5vZGUtPm5hbmQp Owo+PiArCQlsaXN0X2RlbCgmbm9kZS0+Y2hpcF9saXN0KTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1 cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBya19uYW5kY19jaGlwc19pbml0KHN0cnVj dCBkZXZpY2UgKmRldiwKPj4gKwkJCSAgICAgICBzdHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpj dHJsKQo+PiArewo+PiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBkZXYtPm9mX25vZGU7Cj4+ ICsJc3RydWN0IGRldmljZV9ub2RlICpuYW5kX25wOwo+PiArCWludCBuY2hpcHMgPSBvZl9nZXRf Y2hpbGRfY291bnQobnApOwo+PiArCWludCBpID0gMDsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJ aWYgKG5jaGlwcyA+IE5BTkRDX05VTV9CQU5LUykgewo+PiArCQlkZXZfZXJyKGRldiwgInRvbyBt YW55IE5BTkQgY2hpcHM6ICVkIChtYXggPSA0KVxuIiwgbmNoaXBzKTsKPj4gKwkJcmV0dXJuIC1F SU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShucCwgbmFuZF9u cCkgewo+PiArCQlyZXQgPSBya19uYW5kY19jaGlwX2luaXQoZGV2LCBjdHJsLCBuYW5kX25wLCBp KTsKPj4gKwkJaWYgKHJldCkgewo+PiArCQkJcmtfbmFuZGNfY2xlYW51cF9jaGlwcyhjdHJsKTsK Pj4gKwkJCW9mX25vZGVfcHV0KG5hbmRfbnApOwo+PiArCQkJcmV0dXJuIHJldDsKPj4gKwkJfQo+ PiArCQlpKys7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRp YyBpbnQgcmtfbmFuZGNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sK Pj4gKwljb25zdCBzdHJ1Y3QgcmtfbmFuZGNfZGF0YSAqZGF0YTsKPj4gKwlzdHJ1Y3QgZGV2aWNl ICpkZXYgPSAmcGRldi0+ZGV2Owo+PiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbm9kZTsKPj4gKwlp bnQgaWQ7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCWRhdGEgPSBvZl9kZXZpY2VfZ2V0X21hdGNo X2RhdGEoJnBkZXYtPmRldik7Cj4+ICsJaWYgKCFkYXRhKQo+PiArCQlyZXR1cm4gLUVOT0RFVjsK Pj4gKwoKPj4gKwlub2RlID0gcGRldi0+ZGV2Lm9mX25vZGU7Cj4+ICsKPj4gKwlpZCA9IG9mX2Fs aWFzX2dldF9pZChub2RlLCAibmFuZGMiKTsKPj4gKwlpZiAoaWQgPCAwKQo+PiArCQlpZCA9IGdf aWRfY291bnRlcjsKPj4gKwlpZiAoKGlkID49IEFSUkFZX1NJWkUoZ19uYW5kY19pbmZvKSB8fCBn X25hbmRjX2luZm9baWRdLnJlZ3MpKSB7Cj4+ICsJCWRldl9lcnIoCj4+ICsJCQkmcGRldi0+ZGV2 LAo+PiArCQkJImZhaWxlZCB0byBnZXQgaWQgZm9yIG5hbmRjIG5vZGUgJyVwT0ZuJ1xuIiwKPj4g KwkJCW5vZGUpOwo+PiArCQlvZl9ub2RlX3B1dChub2RlKTsKPj4gKwkJcmV0dXJuIC1FTk9ERVY7 Cj4+ICsJfQo+PiArCSsrZ19pZF9jb3VudGVyOwoKU2VlIGNvbW1lbnRzIGFib3ZlIGFib3V0IFJr MzI4OC4gS2VlcGluZyB0cmFjayBub2RlIGFsaWFzIGZvciBuYW5kYzAuClRvIHJlbW92ZSBvciBu b3Q/Cgo+PiArCj4+ICsJZ19uYW5kY19pbmZvW2lkXS52ZXJzaW9uID0gZGF0YS0+dmVyc2lvbjsK Pj4gKwo+PiArCWdfbmFuZGNfaW5mb1tpZF0ucmVncyA9IGRldm1fcGxhdGZvcm1faW9yZW1hcF9y ZXNvdXJjZShwZGV2LCAwKTsKPj4gKwlpZiAoSVNfRVJSKGdfbmFuZGNfaW5mb1tpZF0ucmVncykp IHsKPj4gKwkJZGV2X2VycihkZXYsICJpb3JlbWFwIGZhaWxlZFxuIik7Cj4+ICsJCXJldHVybiBQ VFJfRVJSKGdfbmFuZGNfaW5mb1tpZF0ucmVncyk7Cj4+ICsJfQo+PiArCj4+ICsJZ19uYW5kY19p bmZvW2lkXS5pcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwo+PiArCWlmIChnX25hbmRj X2luZm9baWRdLmlycSA8IDApIHsKPj4gKwkJZGV2X2VycihkZXYsICJnZXQgaXJxIGZhaWxlZFxu Iik7Cj4+ICsJCXJldHVybiBnX25hbmRjX2luZm9baWRdLmlycTsKPj4gKwl9Cj4+ICsKPj4gKwln X25hbmRjX2luZm9baWRdLmhjbGsgPSBkZXZtX2Nsa19nZXQoZGV2LCAiaGNsa19uYW5kYyIpOwo+ PiArCWlmIChJU19FUlIoZ19uYW5kY19pbmZvW2lkXS5oY2xrKSkgewo+PiArCQlkZXZfZXJyKGRl diwgImdldCBoY2xrX25hbmRjIGZhaWxlZFxuIik7Cj4+ICsJCXJldHVybiBQVFJfRVJSKGdfbmFu ZGNfaW5mb1tpZF0uaGNsayk7Cj4+ICsJfQo+PiArCj4+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5h YmxlKGdfbmFuZGNfaW5mb1tpZF0uaGNsayk7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuIHJl dDsKPj4gKwo+PiArCWdfbmFuZGNfaW5mb1tpZF0uY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgImNs a19uYW5kYyIpOwo+PiArCWlmICghKElTX0VSUihnX25hbmRjX2luZm9baWRdLmNsaykpKSB7Cj4+ ICsJCWNsa19zZXRfcmF0ZShnX25hbmRjX2luZm9baWRdLmNsaywgMTUwICogMTAwMCAqIDEwMDAp Owo+PiArCj4+ICsJCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShnX25hbmRjX2luZm9baWRdLmNs ayk7Cj4+ICsJCWlmIChyZXQpCj4+ICsJCQlnb3RvIGVycl9kaXNhYmxlX2hjbGs7Cj4+ICsJfSBl bHNlCj4+ICsJCWRldl9lcnIoZGV2LCAiZ2V0IGNsa19uYW5kYyBmYWlsZWRcbiIpOwo+PiArCj4+ ICsJaWYgKGdfbmFuZGNfaW5mb1tpZF0udmVyc2lvbiA9PSBWRVJTSU9OXzkpCj4+ICsJCXdyaXRl bCgwLCBnX25hbmRjX2luZm9baWRdLnJlZ3MgKyBOQU5EQ19SRUdfVjlfSU5URU4pOwo+PiArCWVs c2UKPj4gKwkJd3JpdGVsKDAsIGdfbmFuZGNfaW5mb1tpZF0ucmVncyArIE5BTkRDX1JFR19WNl9J TlRFTik7Cj4+ICsJcmV0ID0gZGV2bV9yZXF1ZXN0X2lycShkZXYsIGdfbmFuZGNfaW5mb1tpZF0u aXJxLCBya19uYW5kY19pbnRlcnJ1cHQsCj4+ICsJCQkgICAgICAgMCwgIm5hbmRjIiwgJmdfbmFu ZGNfaW5mb1tpZF0pOwo+PiArCWlmIChyZXQpCj4+ICsJCWdvdG8gZXJyX2Rpc2FibGVfY2xrOwo+ PiArCj4+ICsJbmFuZF9jb250cm9sbGVyX2luaXQoJmdfbmFuZGNfaW5mb1tpZF0uY29udHJvbGxl cik7Cj4+ICsJSU5JVF9MSVNUX0hFQUQoJmdfbmFuZGNfaW5mb1tpZF0uY2hpcHMpOwo+PiArCj4+ ICsJcmtfbmFuZGNfaW5pdCgmZ19uYW5kY19pbmZvW2lkXSk7Cj4+ICsKPj4gKwlyZXQgPSBya19u YW5kY19jaGlwc19pbml0KGRldiwgJmdfbmFuZGNfaW5mb1tpZF0pOwo+PiArCWlmIChyZXQpIHsK Pj4gKwkJZGV2X2VycihkZXYsICJpbml0IG5hbmQgY2hpcHMgZmFpbGVkXG4iKTsKPj4gKwkJZ290 byBlcnJfZGlzYWJsZV9jbGs7Cj4+ICsJfQo+PiArCj4+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEo cGRldiwgJmdfbmFuZGNfaW5mb1tpZF0pOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICsKPj4gK2Vy cl9kaXNhYmxlX2NsazoKPj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUoZ19uYW5kY19pbmZvW2lk XS5jbGspOwo+PiArZXJyX2Rpc2FibGVfaGNsazoKPj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUo Z19uYW5kY19pbmZvW2lkXS5oY2xrKTsKPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyBpbnQgcmtfbmFuZGNfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4+ICt7Cj4+ICsJc3RydWN0IHJrX25hbmRfY29udHJvbGxlciAqY3RybCA9IHBsYXRmb3Jt X2dldF9kcnZkYXRhKHBkZXYpOwo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwlyZXQgPSBya19uYW5k Y19jbGVhbnVwX2NoaXBzKGN0cmwpOwo+PiArCWlmIChyZXQpCj4+ICsJCXJldHVybiByZXQ7Cj4+ ICsKPj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUoY3RybC0+Y2xrKTsKPj4gKwljbGtfZGlzYWJs ZV91bnByZXBhcmUoY3RybC0+aGNsayk7Cj4+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwg TlVMTCk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgcmtf bmFuZGNfc2h1dGRvd24oc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sKPj4gKwlz dHJ1Y3QgcmtfbmFuZF9jb250cm9sbGVyICpjdHJsID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRl dik7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXJldCA9IHJrX25hbmRjX2NsZWFudXBfY2hpcHMo Y3RybCk7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuOwo+PiArCj4+ICsJY2xrX2Rpc2FibGVf dW5wcmVwYXJlKGN0cmwtPmNsayk7Cj4+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGN0cmwtPmhj bGspOwo+PiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIE5VTEwpOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJrX25hbmRjX2RhdGEgcmtfbmFuZGNfdjZfZGF0YSA9IHsK Pj4gKwkudmVyc2lvbiA9IFZFUlNJT05fNiwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgcmtfbmFuZGNfZGF0YSBya19uYW5kY192OV9kYXRhID0gewo+PiArCS52ZXJzaW9uID0g VkVSU0lPTl85LAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2Vf aWQgb2ZfcmtfbmFuZGNfbWF0Y2hbXSA9IHsKCgo+PiArCXsKPj4gKwkJLmNvbXBhdGlibGUgPSAi cm9ja2NoaXAsbmFuZGMtdjYiLAo+PiArCQkuZGF0YSA9ICZya19uYW5kY192Nl9kYXRhLAo+PiAr CX0sCj4+ICsJewo+PiArCQkuY29tcGF0aWJsZSA9ICJyb2NrY2hpcCxuYW5kYy12OSIsCj4+ICsJ CS5kYXRhID0gJnJrX25hbmRjX3Y5X2RhdGEsCj4+ICsJfSwKCkFnYWluIHRvIHByZXZlbnQgZ3Vl c3NpbmcgZ2FtZXMgcGxlYXNlIGFkdmlzZQppZiAicm9ja2NoaXAsbmFuZGMtdjYiIGFuZCAicm9j a2NoaXAsbmFuZGMtdjkiIGFyZSBjb3JyZWN0IG9yCnN0YXRlIHRoZSBkZXNpcmVkIGNvbXBhdGli bGUgc3RyaW5ncy4KCj4+ICsJeyAvKiBzZW50aW5lbCAqLyB9LAo+PiArfTsKPj4gKwo+PiArc3Rh dGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgcmtfbmFuZGNfZHJpdmVyID0gewo+PiArCS5wcm9i ZSAgPSBya19uYW5kY19wcm9iZSwKPj4gKwkucmVtb3ZlID0gcmtfbmFuZGNfcmVtb3ZlLAo+PiAr CS5zaHV0ZG93biA9IHJrX25hbmRjX3NodXRkb3duLAo+PiArCS5kcml2ZXIgPSB7Cj4+ICsJCS5u YW1lID0gInJvY2tjaGlwLW5hbmRjIiwKPj4gKwkJLm9mX21hdGNoX3RhYmxlID0gb2ZfcmtfbmFu ZGNfbWF0Y2gsCj4+ICsJfSwKPj4gK307Cj4+ICsKPgo+IE1vdmUgdGhpcyBlbXB0eSBsaW5lLi4u Cj4KPj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIocmtfbmFuZGNfZHJpdmVyKTsKPgo+IC4uLkhl cmUKPgo+PiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+Cj4gVGhhbmtzLAo+IE1pcXXDqGwK PgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovLyBTUERYLUxpY2Vuc2UtSWRl bnRpZmllcjogR1BMLTIuMAovKgogKiBDb3B5cmlnaHQgKGMpIDIwMTksIEpvaGFuIEpvbmtlciA8 amJ4NjI0NEBnbWFpbC5jb20+CiAqCiAqIEJhc2VkIG9uOgogKgpodHRwczovL2dpdGh1Yi5jb20v cm9ja2NoaXAtbGludXgva2VybmVsL2Jsb2IvZGV2ZWxvcC00LjQvZHJpdmVycy9ya19uYW5kL3Jr X2Z0bF9hcm1fdjcuUwogKgpodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcm9ja2No aXAtbGludXgva2VybmVsL2RldmVsb3AtNC40L2RyaXZlcnMvcmtfbmFuZC9ya19mdGxfYXJtX3Y3 LlMKICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTgsIEZ1emhvdSBSb2NrY2hpcCBFbGVjdHJvbmlj cyBDby4sIEx0ZAogKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsKICoKICoKaHR0 cHM6Ly9naXRodWIuY29tL3JvY2tjaGlwLWxpbnV4L3UtYm9vdC9ibG9iL25leHQtZGV2L2RyaXZl cnMvcmtuYW5kL3JrX2Z0bF9hcm1fdjcuUwogKgpodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVu dC5jb20vcm9ja2NoaXAtbGludXgvdS1ib290L25leHQtZGV2L2RyaXZlcnMvcmtuYW5kL3JrX2Z0 bF9hcm1fdjcuUwogKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCwgRnV6aG91IFJvY2tjaGlwIEVs ZWN0cm9uaWNzIENvLiwgTHRkCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wKwog KgogKiBodHRwczovL2dpdGh1Yi5jb20vcm9ja2NoaXAtbGludXgvcmtkZXZlbG9wdG9vbC9ibG9i L21hc3Rlci9jcmMuY3BwCiAqIENvcHlyaWdodCAoYykgMjAxNyBGdXpob3UgUm9ja2NoaXAgRWxl Y3Ryb25pY3MgQ28uLCBMdGQKICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjArCiAq LwoKZW51bSBOQU5EX1RBRyB7CglJRF9JREJUID0gMHhFRkYwLAoJSURfVk5EUiA9IDB4RjA4NiwK CUlEX1NCRlggPSAweEYwOTUsCglJRF9TWVNCID0gMHhGMEE0LAoJSURfTDJQTSA9IDB4RjBDMiwK CUlEX0JCVEIgPSAweEYwRDEsCglJRF9CQlRGID0gMHhGMEUwLAoJSURfUkdNUCA9IDB4RkFGNSwK CUlEX1hYWFcgPSAweEZGRkYsCglJRF9TQlRHID0gMHgxMjM0NTY3OCwKCUlEX0NIQ0sgPSAweDEy MzQ4NzY1LAoJSURfQlRDRSA9IDB4NDI1NDQzNDUsCglJRF9GVExTID0gMHg0NjU0NEM1MywKCUlE X0hBU0ggPSAweDQ3QzZBN0U2LAoJSURfTkFORCA9IDB4NEU0MTRFNDQsCglJRF9WUENUID0gMHg1 MDAwMDA1NiwKCUlEX0lEUlcgPSAweEZDREM4QzNCLAoJSURfWFhYRCA9IDB4RkZGRkZGRkYsCn07 CgpzdHJ1Y3QgX19hdHRyaWJ1dGVfXygoYWxpZ25lZCg0KSkpIHRhZ0ZsYXNoU2F2ZUluZm8gewoJ dWludDMyX3QgSWQ7Cgl1aW50MzJfdCBTaXplOwoJdWludDMyX3QgSlNIYXNoOwoJdWludDE2X3Qg Z05hbmRNYXhEaWU7Cgl1aW50MTZfdCBnTmFuZElEQlJlc0Jsa051bTsKCXVpbnQ2NF90IElEQnl0 ZVs4XTsKCXVpbnQxNl90IERpZUNzSW5kZXhbOF07Cgl1aW50NjRfdCBEaWVBZGRyc1s4XTsKCXVp bnQzMl90IGdOYW5kUGFyYUluZm9bOF07Cgl1aW50MzJfdCBnTmFuZE9wdFBhcmFbOF07Cgl1aW50 OF90IGdSZWFkUmV0cnlJbmZvWzg1Ml07Cgl1aW50MzJfdCBnRmxhc2hUb2dnbGVNb2RlRW47Cn07 CgpzdHJ1Y3QgX19hdHRyaWJ1dGVfXygoYWxpZ25lZCgyKSkpIHRhZ05hbmRPcHRQYXJhIHsKCXVp bnQ4X3QgcmVzMVs4XTsKCXVpbnQ4X3QgU3RhcnREcENtZDsKCXVpbnQ4X3QgRW5kRHBDbWQ7Cgl1 aW50OF90IERwRmlyc3RDbWQ7Cgl1aW50OF90IERwU2Vjb25kQ21kOwoJdWludDhfdCByZXM2OwoJ dWludDhfdCBjbWQyOwoJdWludDhfdCBjbWQxOwoJdWludDhfdCBtYXg7Cgl1aW50OF90IG9wdGlv bjsKCXVpbnQ4X3QgcmVzMTFbMTVdOwp9OwoKc3RydWN0IF9fYXR0cmlidXRlX18oKGFsaWduZWQo MikpKSB0YWdOYW5kUGFyYUluZm8gewoJdWludDhfdCBpZF9ieXRlczsKCXVpbnQ4X3QgbmFuZF9p ZFs2XTsKCXVpbnQ4X3QgdmVuZG9yOwoJdWludDhfdCBkaWVfcGVyX2NoaXA7Cgl1aW50OF90IHNl Y19wZXJfcGFnZTsKCXVpbnQxNl90IHBhZ2VfcGVyX2JsazsKCXVpbnQ4X3QgY2VsbDsKCXVpbnQ4 X3QgcGxhbmVfcGVyX2RpZTsKCXVpbnQxNl90IGJsa19wZXJfcGxhbmU7Cgl1aW50MTZfdCBvcGVy YXRpb25fb3B0OwoJdWludDhfdCBsc2JfbW9kZTsKCXVpbnQ4X3QgcmVhZF9yZXRyeV9tb2RlOwoJ dWludDhfdCBlY2NfYml0czsKCXVpbnQ4X3QgYWNjZXNzX2ZyZXE7Cgl1aW50OF90IG9wdF9tb2Rl OwoJdWludDhfdCBkaWVfZ2FwOwoJdWludDhfdCBiYWRfYmxvY2tfbW9kZTsKCXVpbnQ4X3QgbXVs dGlfcGxhbmVfbW9kZTsKCXVpbnQ4X3Qgc2xjX21vZGU7Cgl1aW50OF90IHJlc2VydmVkWzVdOwp9 OwoKc3RydWN0IF9fYXR0cmlidXRlX18oKGFsaWduZWQoNCkpKSB0YWdOYW5kUGh5SW5mbyB7Cgl1 aW50MzJfdCBjaGlwX2lkOwoJdWludDMyX3QgdmVuZG9yOwoJdWludDE2X3QgbmFuZF90eXBlOwoJ dWludDE2X3QgZGllX251bTsKCXVpbnQxNl90IHBsYW5lc19wZXJfZGllOwoJdWludDE2X3QgYmxr X3Blcl9wbGFuZTsKCXVpbnQxNl90IHBhZ2VfcGVyX2JsazsKCXVpbnQxNl90IHBhZ2VfcGVyX3Ns Y19ibGs7Cgl1aW50MTZfdCBzZWNfcGVyX3BhZ2U7Cgl1aW50MTZfdCBibG9ja19zaXplOwoJdWlu dDE2X3Qgc2VjdG9yX3NpemU7Cgl1aW50MTZfdCByZXNlcnZlZF9ibGtzOwp9OwoKc3RydWN0IHRh Z1JlYWRSZXRyeUluZm8gewoJdWludDhfdCByZXRyeU1vZGU7Cgl1aW50OF90IHNpemU7Cgl1aW50 OF90IG1heDsKCXVpbnQ4X3QgcmVzMzsKCXVpbnQ4X3QgYWRkcls4XTsKCXVpbnQ4X3Qgb2Zmc2V0 MVs4XTsKCXVpbnQ4X3QgYnVmWzgzMl07Cn07Cgp1aW50OF90IGdOYW5kSURhdGFCdWZbMjA0OF07 CnN0cnVjdCB0YWdOYW5kUGFyYUluZm8gKmdwTmFuZFBhcmFJbmZvOwpzdHJ1Y3QgdGFnTmFuZE9w dFBhcmEgZ05hbmRPcHRQYXJhOwpzdHJ1Y3QgdGFnTmFuZFBoeUluZm8gZ05hbmRQaHlJbmZvOwpz dHJ1Y3QgdGFnUmVhZFJldHJ5SW5mbyBnUmVhZFJldHJ5SW5mbzsKCnVpbnQxNl90IG1sY1BhZ2VU b1NsY1BhZ2VUYmxbNTEyXTsKdWludDE2X3Qgc2xjUGFnZVRvTWxjUGFnZVRibFsyNTZdOwoKdWlu dDMyX3QgKmdGbGFzaFBhZ2VCdWZmZXIwOwp1aW50MzJfdCAqZ0ZsYXNoUGFnZUJ1ZmZlcjE7Cgp2 b2lkIFBfUkM0KHVpbnQ4X3QgKmJ1ZiwgdWludDMyX3Qgc2l6ZSkKewoJdWludDhfdCBrZXlbMTZd ID0gewoJCTB4N0MsIDB4NEUsIDB4MDMsIDB4MDQsIDB4NTUsIDB4MDUsIDB4MDksIDB4MDcsCgkJ MHgyRCwgMHgyQywgMHg3QiwgMHgzOCwgMHgxNywgMHgwRCwgMHgxNywgMHgxMSwKCX07Cgl1aW50 OF90IFNbMjU2XSwgS1syNTZdLCB0ZW1wOwoJdWludDMyX3QgaSwgaiwgdCwgeDsKCglqID0gMDsK CWZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCVNbaV0gPSAodWludDhfdClpOwoJCWogJj0g MHgwZjsKCQlLW2ldID0ga2V5W2pdOwoJCWorKzsKCX0KCWogPSAwOwoJZm9yIChpID0gMDsgaSA8 IDI1NjsgaSsrKSB7CgkJaiA9IChqICsgU1tpXSArIEtbaV0pICUgMjU2OwoJCXRlbXAgPSBTW2ld OwoJCVNbaV0gPSBTW2pdOwoJCVNbal0gPSB0ZW1wOwoJfQoJaSA9IGogPSAwOwoJZm9yICh4ID0g MDsgeCA8IHNpemU7IHgrKykgewoJCWkgPSAoaSsxKSAlIDI1NjsKCQlqID0gKGogKyBTW2ldKSAl IDI1NjsKCQl0ZW1wID0gU1tpXTsKCQlTW2ldID0gU1tqXTsKCQlTW2pdID0gdGVtcDsKCQl0ID0g KFNbaV0gKyAoU1tqXSAlIDI1NikpICUgMjU2OwoJCWJ1Zlt4XSA9IGJ1Zlt4XSBeIFNbdF07Cgl9 Cn0KCnVpbnQzMl90IGpzX2hhc2godWludDhfdCAqYnVmLCB1aW50MzJfdCBzaXplKQp7Cgl1aW50 MzJfdCBoYXNoOwoJdWludDhfdCAqcF9tYXg7Cgl1aW50MzJfdCB0bXA7CgoJaGFzaCA9IElEX0hB U0g7CglwX21heCA9ICZidWZbc2l6ZV07Cgl3aGlsZSAoYnVmICE9IHBfbWF4KSB7CgkJdG1wID0g KmJ1ZisrOwoJCWhhc2ggXj0gKGhhc2ggPj4gMikgKyAzMiAqIGhhc2ggKyB0bXA7Cgl9CglyZXR1 cm4gaGFzaDsKfQoKdm9pZCBCdWlsZEZsYXNoTHNiUGFnZVRhYmxlKHVpbnQzMl90IGxzYl9tb2Rl LCB1aW50MTZfdCBzaXplKQp7Cgl1aW50MzJfdCBjb3VudGVyMTsKCXVpbnQzMl90IGNvdW50ZXIy OwoJdWludDMyX3QgY291bnRlcjM7Cgl1aW50MzJfdCBjb3VudGVyNDsKCXVpbnQzMl90IGNvdW50 ZXI1OwoJdWludDMyX3QgY291bnRlcjY7Cgl1aW50MzJfdCBjb3VudGVyNzsKCXVpbnQzMl90IGNv dW50ZXI4OwoJdWludDE2X3Qgb2Zmc2V0MTsKCXVpbnQxNl90IG9mZnNldDI7Cgl1aW50MzJfdCBv ZmZzZXQzOwoJdWludDE2X3Qgb2Zmc2V0NDsKCXVpbnQxNl90ICpwX3RhYmxlMTsKCXVpbnQxNl90 ICpwX3RhYmxlMjsKCXVpbnQxNl90ICpwX3RhYmxlMzsKCXVpbnQxNl90IHRtcDE7Cgl1aW50MTZf dCB0bXAyOwoJdWludDE2X3QgdG1wMzsKCXVpbnQzMl90IHRtcDQ7Cgl1aW50MTZfdCB0bXA1OwoJ dWludDMyX3QgdG1wNjsKCglpZiAobHNiX21vZGUpIHsKCQlzd2l0Y2ggKGxzYl9tb2RlKSB7CgkJ Y2FzZSAxdToKCQkJY291bnRlcjIgPSAwOwoJCQlkbyB7CgkJCQl0bXAxID0gY291bnRlcjI7CgkJ CQlpZiAoY291bnRlcjIgPiAzKSB7CgkJCQkJaWYgKGNvdW50ZXIyICYgMSkKCQkJCQkJb2Zmc2V0 MSA9IDM7CgkJCQkJZWxzZQoJCQkJCQlvZmZzZXQxID0gMjsKCQkJCQl0bXAxID0gMiAqIGNvdW50 ZXIyIC0gb2Zmc2V0MTsKCQkJCX0KCQkJCXNsY1BhZ2VUb01sY1BhZ2VUYmxbY291bnRlcjIrK10g PSB0bXAxOwoJCQl9IHdoaWxlIChjb3VudGVyMiAhPSAyNTYpOwoJCQlicmVhazsKCQljYXNlIDJ1 OgoJCQljb3VudGVyMyA9IDA7CgkJCWRvIHsKCQkJCXRtcDIgPSBjb3VudGVyMzsKCQkJCWlmIChj b3VudGVyMyA+IDEpCgkJCQkJdG1wMiA9IDIgKiBjb3VudGVyMyAtIDE7CgkJCQlzbGNQYWdlVG9N bGNQYWdlVGJsW2NvdW50ZXIzKytdID0gdG1wMjsKCQkJfSB3aGlsZSAoY291bnRlcjMgIT0gMjU2 KTsKCQkJYnJlYWs7CgkJY2FzZSAzdToKCQkJY291bnRlcjQgPSAwOwoJCQlkbyB7CgkJCQl0bXAz ID0gY291bnRlcjQ7CgkJCQlpZiAoY291bnRlcjQgPiA1KSB7CgkJCQkJaWYgKGNvdW50ZXI0ICYg MSkKCQkJCQkJb2Zmc2V0MiA9IDU7CgkJCQkJZWxzZQoJCQkJCQlvZmZzZXQyID0gNDsKCQkJCQl0 bXAzID0gMiAqIGNvdW50ZXI0IC0gb2Zmc2V0MjsKCQkJCX0KCQkJCXNsY1BhZ2VUb01sY1BhZ2VU YmxbY291bnRlcjQrK10gPSB0bXAzOwoJCQl9IHdoaWxlIChjb3VudGVyNCAhPSAyNTYpOwoJCQli cmVhazsKCQlkZWZhdWx0OgoJCQljb3VudGVyNSA9IDA7CgkJCXN3aXRjaCAobHNiX21vZGUpIHsK CQkJY2FzZSA0dToKCQkJCXNsY1BhZ2VUb01sY1BhZ2VUYmxbMF0gPSAwOwoJCQkJc2xjUGFnZVRv TWxjUGFnZVRibFsxXSA9IDE7CgkJCQlzbGNQYWdlVG9NbGNQYWdlVGJsWzJdID0gMjsKCQkJCXNs Y1BhZ2VUb01sY1BhZ2VUYmxbM10gPSAzOwoJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFs1XSA9IDU7 CgkJCQlzbGNQYWdlVG9NbGNQYWdlVGJsWzZdID0gNzsKCQkJCWNvdW50ZXI2ID0gODsKCQkJCXNs Y1BhZ2VUb01sY1BhZ2VUYmxbNF0gPSA0OwoJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFs3XSA9IDg7 CgkJCQlwX3RhYmxlMSA9ICZzbGNQYWdlVG9NbGNQYWdlVGJsWzddOwoJCQkJZG8gewoJCQkJCWlm IChjb3VudGVyNiAmIDEpCgkJCQkJCW9mZnNldDMgPSA3OwoJCQkJCWVsc2UKCQkJCQkJb2Zmc2V0 MyA9IDY7CgkJCQkJdG1wNCA9IDIgKiBjb3VudGVyNiAtIG9mZnNldDM7CgkJCQkJY291bnRlcjYg PSAodWludDE2X3QpKGNvdW50ZXI2ICsgMSk7CgkJCQkJcF90YWJsZTFbMV0gPSB0bXA0OwoJCQkJ CSsrcF90YWJsZTE7CgkJCQl9IHdoaWxlIChjb3VudGVyNiAhPSAyNTYpOwoJCQkJYnJlYWs7CgkJ CWNhc2UgNXU6CgkJCQlkbyB7CgkJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFtjb3VudGVyNV0gPQoJ CQkJCQljb3VudGVyNTsKCQkJCQkrK2NvdW50ZXI1OwoJCQkJfSB3aGlsZSAoY291bnRlcjUgIT0g MTYpOwoJCQkJcF90YWJsZTIgPSAmc2xjUGFnZVRvTWxjUGFnZVRibFsxNV07CgkJCQlkbyB7CgkJ CQkJcF90YWJsZTJbMV0gPSBjb3VudGVyNTsKCQkJCQkrK3BfdGFibGUyOwoJCQkJCWNvdW50ZXI1 ID0gKHVpbnQxNl90KShjb3VudGVyNSArIDIpOwoJCQkJfSB3aGlsZSAoY291bnRlcjUgIT0gNDk2 KTsKCQkJCWJyZWFrOwoJCQljYXNlIDZ1OgoJCQkJY291bnRlcjcgPSAwOwoJCQkJZG8gewoJCQkJ CXRtcDUgPSBjb3VudGVyNzsKCQkJCQlpZiAoY291bnRlcjcgPiA1KSB7CgkJCQkJCWlmIChjb3Vu dGVyNyAmIDEpCgkJCQkJCQlvZmZzZXQ0ID0gMTI7CgkJCQkJCWVsc2UKCQkJCQkJCW9mZnNldDQg PSAxMDsKCQkJCQkJdG1wNSA9IGNvdW50ZXI1IC0gb2Zmc2V0NDsKCQkJCQl9CgkJCQkJc2xjUGFn ZVRvTWxjUGFnZVRibFtjb3VudGVyNysrXSA9IHRtcDU7CgkJCQkJY291bnRlcjUgPSAodWludDE2 X3QpKGNvdW50ZXI1ICsgMyk7CgkJCQl9IHdoaWxlIChjb3VudGVyNyAhPSAyNTYpOwoJCQkJYnJl YWs7CgkJCWNhc2UgOXU6CgkJCQlzbGNQYWdlVG9NbGNQYWdlVGJsWzBdID0gMDsKCQkJCXNsY1Bh Z2VUb01sY1BhZ2VUYmxbMV0gPSAxOwoJCQkJc2xjUGFnZVRvTWxjUGFnZVRibFsyXSA9IDI7CgkJ CQlwX3RhYmxlMyA9ICZzbGNQYWdlVG9NbGNQYWdlVGJsWzJdOwoJCQkJY291bnRlcjggPSAzOwoJ CQkJZG8gewoJCQkJCXBfdGFibGUzWzFdID0gY291bnRlcjg7CgkJCQkJKytwX3RhYmxlMzsKCQkJ CQljb3VudGVyOCA9ICh1aW50MTZfdCkoY291bnRlcjggKyAyKTsKCQkJCX0gd2hpbGUgKGNvdW50 ZXI4ICE9IDUwOSk7CgkJCQlicmVhazsKCQkJfQoJCQlicmVhazsKCQl9Cgl9IGVsc2UgewoJCWRv IHsKCQkJc2xjUGFnZVRvTWxjUGFnZVRibFtsc2JfbW9kZV0gPSBsc2JfbW9kZTsKCQkJKytsc2Jf bW9kZTsKCQl9IHdoaWxlIChsc2JfbW9kZSAhPSAyNTYpOwoJfQoJZnRsX21lbXNldChtbGNQYWdl VG9TbGNQYWdlVGJsLCAweEZGdSwgMTAyNHUpOwoJY291bnRlcjEgPSAwOwoJd2hpbGUgKHNpemUg PiAodWludDE2X3QpY291bnRlcjEpIHsKCQl0bXA2ID0gc2xjUGFnZVRvTWxjUGFnZVRibFtjb3Vu dGVyMSsrXTsKCQltbGNQYWdlVG9TbGNQYWdlVGJsW3RtcDZdID0gdG1wNjsKCX0KfQoKaW50IEZs YXNoRXJhc2VCbG9jayh1aW50MzJfdCBjcywgdWludDMyX3QgcGFnZV9hZGRyLCB1aW50MzJfdCBz bGNfbW9kZSkKewoJdWludDhfdCBzdGF0dXM7CgoJTmFuZGNXYWl0Rmxhc2hSZWFkeShjcyk7CglO YW5kY0ZsYXNoQ3MoY3MpOwoJRmxhc2hFcmFzZUNtZChjcywgcGFnZV9hZGRyLCBzbGNfbW9kZSk7 CglOYW5kY1dhaXRGbGFzaFJlYWR5KGNzKTsKCXN0YXR1cyA9IEZsYXNoUmVhZFN0YXR1cyhjcyk7 CglOYW5kY0ZsYXNoRGVDcyhjcyk7CglyZXR1cm4gc3RhdHVzICYgMTsKfQoKaW50IEZsYXNoUHJv Z1BhZ2VSYXcodWludDMyX3QgY3MsIHVpbnQzMl90IHBhZ2VfYWRkciwgdWludDMyX3QgKnBfZGF0 YSwKCQkgICAgIHVpbnQxNl90ICpwX3NwYXJlKQp7Cgl1aW50OF90IHNlY19wZXJfcGFnZTsKCXVp bnQ4X3Qgc3RhdHVzOwoKCXNlY19wZXJfcGFnZSA9IGdOYW5kUGFyYUluZm8uc2VjX3Blcl9wYWdl OwoJaWYgKCFjcyAmJiBnQmxvY2tQYWdlQWxpZ25TaXplICogZ05hbmRJREJSZXNCbGtOdW0gPiBw YWdlX2FkZHIpIHsKCQlzZWNfcGVyX3BhZ2UgPSA0OwoJfQoJTmFuZGNXYWl0Rmxhc2hSZWFkeShj cyk7CglOYW5kY0ZsYXNoQ3MoY3MpOwoJRmxhc2hQcm9nRmlyc3RDbWQoY3MsIHBhZ2VfYWRkcik7 CglOYW5kY1hmZXJEYXRhKGNzLCAxdSwgc2VjX3Blcl9wYWdlLCBwX2RhdGEsIHBfc3BhcmUpOwoJ Rmxhc2hQcm9nU2Vjb25kQ21kKGNzKTsKCU5hbmRjV2FpdEZsYXNoUmVhZHkoY3MpOwoJc3RhdHVz ID0gRmxhc2hSZWFkU3RhdHVzKGNzKTsKCU5hbmRjRmxhc2hEZUNzKGNzKTsKCXJldHVybiBzdGF0 dXMgJiAxOwp9Cgp1aW50MzJfdCBGbGFzaFJlYWRSYXdQYWdlKHVpbnQzMl90IGNzLCB1aW50MzJf dCBwYWdlX2FkZHIsIHVpbnQzMl90ICpwX2RhdGEsCgkJCSAgdWludDE2X3QgKnBfc3BhcmUpCnsK CXVpbnQzMl90IHNlY19wZXJfcGFnZTsKCXVpbnQzMl90IHN0YXR1czsKCglzZWNfcGVyX3BhZ2Ug PSBnTmFuZFBhcmFJbmZvLnNlY19wZXJfcGFnZTsKCWlmICghY3MgJiYgZ0Jsb2NrUGFnZUFsaWdu U2l6ZSAqIGdOYW5kSURCUmVzQmxrTnVtID4gcGFnZV9hZGRyKSB7CgkJc2VjX3Blcl9wYWdlID0g NDsKCX0KCU5hbmRjV2FpdEZsYXNoUmVhZHkoY3MpOwoJTmFuZGNGbGFzaENzKGNzKTsKCUZsYXNo UmVhZENtZChjcywgcGFnZV9hZGRyKTsKCU5hbmRjV2FpdEZsYXNoUmVhZHkoY3MpOwoJc3RhdHVz ID0gTmFuZGNYZmVyRGF0YShjcywgMCwgc2VjX3Blcl9wYWdlLCBwX2RhdGEsIHBfc3BhcmUpOwoJ TmFuZGNGbGFzaERlQ3MoY3MpOwoJcmV0dXJuIHN0YXR1czsKfQoKdm9pZCBGbGFzaEJsb2NrQWxp Z25Jbml0KHVpbnQzMl90IHBhZ2VfcGVyX2JsaykKewoJdWludDMyX3QgYWxpZ25fc2l6ZTsKCglp ZiAocGFnZV9wZXJfYmxrID4gMjU2KSB7CgkJYWxpZ25fc2l6ZSA9IDUxMjsKbGFiZWxfMzoKCQln QmxvY2tQYWdlQWxpZ25TaXplID0gYWxpZ25fc2l6ZTsKCQlyZXR1cm47Cgl9CglpZiAocGFnZV9w ZXJfYmxrID4gMTI4KSB7CgkJYWxpZ25fc2l6ZSA9IDI1NjsKCQlnb3RvIGxhYmVsXzM7Cgl9Cgln QmxvY2tQYWdlQWxpZ25TaXplID0gcGFnZV9wZXJfYmxrOwp9Cgp1aW50MzJfdCBGbGFzaExvYWRQ aHlJbmZvKHZvaWQpCnsKCXN0cnVjdCB0YWdGbGFzaFNhdmVJbmZvICppbmZvOwoJdWludDMyX3Qg YWxpZ25fc2l6ZTsKCXVpbnQzMl90IGJjaF9jb3VudGVyOwoJdWludDMyX3QgY291bnRlcjsKCXVp bnQzMl90IHBhZ2VfYWRkcjsKCXVpbnQzMl90IHN0YXR1czsKCXVpbnQ4X3QgYmNoWzRdOwoKCXBh Z2VfYWRkciA9IDA7Cgljb3VudGVyID0gNDsKCWJjaFswXSA9IDYwOwoJYmNoWzFdID0gNDA7Cgli Y2hbMl0gPSAyNDsKCWJjaFszXSA9IDE2OwoJc3RhdHVzID0gTkFORF9TVFNfRVJST1I7CglhbGln bl9zaXplID0gZ0Jsb2NrUGFnZUFsaWduU2l6ZTsKCWdOYW5kRmxhc2hJbmZvQmxvY2tBZGRyID0g MDsKCWdwRmxhc2hTYXZlSW5mbyA9IChzdHJ1Y3QgdGFnRmxhc2hTYXZlSW5mbyAqKWdGbGFzaFBh Z2VCdWZmZXIwOwoJZmxhc2hfZW50ZXJfc2xjX21vZGUoMCk7Cgl3aGlsZSAoMSkgewoJCWJjaF9j b3VudGVyID0gMDsKCQl3aGlsZSAoMSkgewoJCQlGbGFzaEJjaFNlbChiY2hbYmNoX2NvdW50ZXJd KTsKCQkJaWYgKEZsYXNoUmVhZFJhd1BhZ2UoCgkJCQkgICAgMCwKCQkJCSAgICBwYWdlX2FkZHIs CgkJCQkgICAgZ0ZsYXNoUGFnZUJ1ZmZlcjAsCgkJCQkgICAgMCkgIT0gTkFORF9TVFNfRVJST1Ig fHwKCQkJICAgIEZsYXNoUmVhZFJhd1BhZ2UoCgkJCQkgICAgMCwKCQkJCSAgICBwYWdlX2FkZHIg KyAxLAoJCQkJICAgIGdGbGFzaFBhZ2VCdWZmZXIwLAoJCQkJICAgIDApICE9IE5BTkRfU1RTX0VS Uk9SKSB7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoKytiY2hfY291bnRlciA9PSA0KQoJCQkJZ290 byBsYWJlbF82OwoJCX0KCQlpbmZvID0gZ3BGbGFzaFNhdmVJbmZvOwoJCWlmIChncEZsYXNoU2F2 ZUluZm8tPklkID09IElEX05BTkQpIHsKCQkJaWYgKCFzdGF0dXMpIHsKCQkJCWdOYW5kRmxhc2hJ ZGJCbG9ja0FkZHIgPQoJCQkJCXBhZ2VfYWRkcgoJCQkJCS8gZ0Jsb2NrUGFnZUFsaWduU2l6ZSAr IDE7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoIGluZm8tPkpTSGFzaCA9PSBqc19oYXNoKAoJCQkJ ICAgICAodWludDhfdCAqKSZncEZsYXNoU2F2ZUluZm8tPmdOYW5kTWF4RGllLAoJCQkJICAgICAy MDM2dSkpIHsKCQkJCWZ0bF9tZW1jcHkoCgkJCQkJJmdOYW5kUGFyYUluZm8sCgkJCQkJaW5mby0+ Z05hbmRQYXJhSW5mbywKCQkJCQkzMnUpOwoJCQkJZnRsX21lbWNweSgKCQkJCQkmZ05hbmRPcHRQ YXJhLAoJCQkJCWdwRmxhc2hTYXZlSW5mby0+Z05hbmRPcHRQYXJhLAoJCQkJCTMydSk7CgkJCQlm dGxfbWVtY3B5KAoJCQkJCSZnUmVhZFJldHJ5SW5mbywKCQkJCQlncEZsYXNoU2F2ZUluZm8tPmdS ZWFkUmV0cnlJbmZvLAoJCQkJCTg1MnUpOwoJCQkJRmxhc2hCbG9ja0FsaWduSW5pdChnTmFuZFBh cmFJbmZvLnBhZ2VfcGVyX2Jsayk7CgkJCQlnRmxhc2hUb2dnbGVNb2RlRW4gPQoJCQkJCWdwRmxh c2hTYXZlSW5mby0+Z0ZsYXNoVG9nZ2xlTW9kZUVuOwoJCQkJZ05hbmRGbGFzaEluZm9CbG9ja0Fk ZHIgPSBwYWdlX2FkZHI7CgkJCQlpZiAocGFnZV9hZGRyIC8gZ0Jsb2NrUGFnZUFsaWduU2l6ZSAr IDEgPiAxKQoJCQkJCWdOYW5kRmxhc2hJZGJCbG9ja0FkZHIgPQoJCQkJCQlwYWdlX2FkZHIKCQkJ CQkJLyBnQmxvY2tQYWdlQWxpZ25TaXplICsgMTsKCQkJCWVsc2UKCQkJCQlnTmFuZEZsYXNoSWRi QmxvY2tBZGRyID0gMjsKCQkJCXN0YXR1cyA9IE5BTkRfU1RTX09LOwoJCQkJZ05hbmRJREJSZXNC bGtOdW1TYXZlSW5GbGFzaCA9CgkJCQkJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZElEQlJlc0Jsa051 bTsKCQkJfSBlbHNlIHsKCQkJCXN0YXR1cyA9IE5BTkRfU1RTX0VSUk9SOwoJCQl9CgkJfQpsYWJl bF82OgoJCS0tY291bnRlcjsKCQlwYWdlX2FkZHIgKz0gYWxpZ25fc2l6ZTsKCQlpZiAoY291bnRl cikKCQkJY29udGludWU7CgkJYnJlYWs7Cgl9CglmbGFzaF9leGl0X3NsY19tb2RlKDApOwoJcmV0 dXJuIHN0YXR1czsKfQoKdm9pZCBGbGFzaFNhdmVQaHlJbmZvKHZvaWQpCnsKCXVpbnQzMl90IGNv dW50ZXIxOwoJdWludDMyX3QgY291bnRlcjI7Cgl1aW50MzJfdCBkb25lOwoJdWludDMyX3QgaGFz aDsKCXVpbnQzMl90IHN0YXR1czsKCglncEZsYXNoU2F2ZUluZm8gPSAoc3RydWN0IHRhZ0ZsYXNo U2F2ZUluZm8gKilnRmxhc2hQYWdlQnVmZmVyMDsKCUZsYXNoQmNoU2VsKGdOYW5kRmxhc2hJREJF Y2NCaXRzKTsKCWZ0bF9tZW1zZXQoZ0ZsYXNoUGFnZUJ1ZmZlcjAsIDAsIDIwNDh1KTsKCWdwRmxh c2hTYXZlSW5mby0+SWQgPSBJRF9OQU5EOwoJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZE1heERpZSA9 IGdOYW5kTWF4RGllOwoJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZElEQlJlc0Jsa051bSA9IGdOYW5k SURCUmVzQmxrTnVtOwoJZ3BGbGFzaFNhdmVJbmZvLT5nRmxhc2hUb2dnbGVNb2RlRW4gPSBnRmxh c2hUb2dnbGVNb2RlRW47CglmdGxfbWVtY3B5KGdwRmxhc2hTYXZlSW5mby0+SURCeXRlLCBJREJ5 dGUsIDMydSk7CglmdGxfbWVtY3B5KGdwRmxhc2hTYXZlSW5mby0+RGllQ3NJbmRleCwgRGllQ3NJ bmRleCwgOHUpOwoJZnRsX21lbWNweShncEZsYXNoU2F2ZUluZm8tPkRpZUFkZHJzLCBEaWVBZGRy cywgMzJ1KTsKCWZ0bF9tZW1jcHkoCgkJZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZFBhcmFJbmZvLAoJ CSZnTmFuZFBhcmFJbmZvLAoJCTMydSk7CglmdGxfbWVtY3B5KGdwRmxhc2hTYXZlSW5mby0+Z05h bmRPcHRQYXJhLCAmZ05hbmRPcHRQYXJhLCAzMnUpOwoJZnRsX21lbWNweSgKCQlncEZsYXNoU2F2 ZUluZm8tPmdSZWFkUmV0cnlJbmZvLAoJCSZnUmVhZFJldHJ5SW5mbywKCQk4NTJ1KTsKCWdwRmxh c2hTYXZlSW5mby0+SlNIYXNoID0ganNfaGFzaCgKCQkJCQkgICh1aW50OF90ICopCgkJCQkJICAm Z3BGbGFzaFNhdmVJbmZvLT5nTmFuZE1heERpZSwKCQkJCQkgIDIwMzZ1KTsKCWdwRmxhc2hTYXZl SW5mby0+U2l6ZSA9IDE1OTI7Cglkb25lID0gMDsKCWNvdW50ZXIxID0gMDsKCWdwRmxhc2hTYXZl SW5mbyA9IChzdHJ1Y3QgdGFnRmxhc2hTYXZlSW5mbyAqKWdGbGFzaFBhZ2VCdWZmZXIxOwoJZmxh c2hfZW50ZXJfc2xjX21vZGUoMCk7CglkbyB7CgkJRmxhc2hFcmFzZUJsb2NrKDAsIGdCbG9ja1Bh Z2VBbGlnblNpemUgKiBjb3VudGVyMSwgMCk7CgkJRmxhc2hQcm9nUGFnZVJhdygKCQkJMCwKCQkJ Z0Jsb2NrUGFnZUFsaWduU2l6ZSAqIGNvdW50ZXIxLAoJCQlnRmxhc2hQYWdlQnVmZmVyMCwKCQkJ MCk7CgkJRmxhc2hQcm9nUGFnZVJhdygKCQkJMCwKCQkJZ0Jsb2NrUGFnZUFsaWduU2l6ZSAqIGNv dW50ZXIxICsgMSwKCQkJZ0ZsYXNoUGFnZUJ1ZmZlcjAsCgkJCTApOwoJCXN0YXR1cyA9IEZsYXNo UmVhZFJhd1BhZ2UoCgkJCQkgMCwKCQkJCSBnQmxvY2tQYWdlQWxpZ25TaXplICogY291bnRlcjEs CgkJCQkgZ0ZsYXNoUGFnZUJ1ZmZlcjEsCgkJCQkgMCk7CgkJY291bnRlcjIgPSBjb3VudGVyMSAr IDE7CgkJaWYgKHN0YXR1cyAhPSBOQU5EX1NUU19FUlJPUiAmJgoJCSAgICBncEZsYXNoU2F2ZUlu Zm8tPklkID09IElEX05BTkQpIHsKCQkJaGFzaCA9IGpzX2hhc2goCgkJCQkgICAgICAgKHVpbnQ4 X3QgKikKCQkJCSAgICAgICAmZ3BGbGFzaFNhdmVJbmZvLT5nTmFuZE1heERpZSwKCQkJCSAgICAg ICAyMDM2dSk7CgkJCWNvdW50ZXIyID0gY291bnRlcjEgKyAxOwoJCQlpZiAoZ3BGbGFzaFNhdmVJ bmZvLT5KU0hhc2ggPT0gaGFzaCkgewoJCQkJZ05hbmRGbGFzaElkYkJsb2NrQWRkciA9IGNvdW50 ZXIxICsgMTsKCQkJCWdOYW5kRmxhc2hJbmZvQmxvY2tBZGRyID0gY291bnRlcjEKCQkJCQkJCSAg KiBnQmxvY2tQYWdlQWxpZ25TaXplOwoJCQkJaWYgKGRvbmUgPT0gMSkKCQkJCQlicmVhazsKCQkJ CWRvbmUgPSAxOwoJCQl9CgkJfQoJCWNvdW50ZXIxID0gY291bnRlcjI7Cgl9IHdoaWxlIChjb3Vu dGVyMiAhPSA0KTsKCWZsYXNoX2V4aXRfc2xjX21vZGUoMCk7Cn0KCmludCBGbGFzaFJlYWRJZGJE YXRhUmF3KHVpbnQ4X3QgKnBfYnVmKQp7Cgl1aW50MzJfdCBiY2hfY291bnRlcjsKCXVpbnQzMl90 IGVjY19iaXRzOwoJdWludDMyX3QgZWNjX2JpdHMyOwoJdWludDMyX3QgcGFnZV9jb3VudGVyOwoJ aW50IHN0YXR1czsKCXVpbnQ4X3QgYmNoWzRdOwoKCWJjaFswXSA9IDYwOwoJYmNoWzFdID0gNDA7 CgliY2hbMl0gPSAyNDsKCWJjaFszXSA9IDE2OwoJZWNjX2JpdHMyID0gZ05hbmRGbGFzaEVjY0Jp dHM7CglpZiAoaWRiX2ZsYXNoX3NsY19tb2RlKQoJCWZsYXNoX2VudGVyX3NsY19tb2RlKDApOwoJ c3RhdHVzID0gTkFORF9TVFNfRVJST1I7CglwYWdlX2NvdW50ZXIgPSAyOwoJZnRsX21lbXNldChw X2J1ZiwgMCwgMjA0OHUpOwoJd2hpbGUgKDEpIHsKCQlpZiAocGFnZV9jb3VudGVyIDwgZ05hbmRJ REJSZXNCbGtOdW0pIHsKCQkJYmNoX2NvdW50ZXIgPSAwOwoJCQl3aGlsZSAoMSkgewoJCQkJZWNj X2JpdHMgPSBiY2hbYmNoX2NvdW50ZXJdOwoJCQkJRmxhc2hCY2hTZWwoZWNjX2JpdHMpOwoJCQkJ aWYgKCBGbGFzaFJlYWRSYXdQYWdlKAoJCQkJCSAgICAgMCwKCQkJCQkgICAgIGdCbG9ja1BhZ2VB bGlnblNpemUKCQkJCQkgICAgICogcGFnZV9jb3VudGVyLAoJCQkJCSAgICAgZ0ZsYXNoUGFnZUJ1 ZmZlcjAsCgkJCQkJICAgICAwKSAhPSBOQU5EX1NUU19FUlJPUikKCQkJCQlicmVhazsKCQkJCWlm ICgrK2JjaF9jb3VudGVyID09IDQpCgkJCQkJZ290byBsYWJlbF8xMTsKCQkJfQoJCQlpZiAoKmdG bGFzaFBhZ2VCdWZmZXIwID09IElEX0lEUlcpIHsKCQkJCUZUTF9JTkZPKCJFQ0M6JWRcbiIsIGVj Y19iaXRzKTsKCQkJCWZ0bF9tZW1jcHkoCgkJCQkJcF9idWYsCgkJCQkJZ0ZsYXNoUGFnZUJ1ZmZl cjAsCgkJCQkJMjA0OHUpOwoJCQkJZ05hbmRJREJSZXNCbGtOdW0gPSBnRmxhc2hQYWdlQnVmZmVy MFsxMjhdOwoJCQkJaWYgKHBhZ2VfY291bnRlciA+PSBnTmFuZEZsYXNoSWRiQmxvY2tBZGRyKSB7 CgkJCQkJc3RhdHVzID0gTkFORF9TVFNfT0s7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlnTmFuZEZs YXNoSWRiQmxvY2tBZGRyID0gcGFnZV9jb3VudGVyOwoJCQkJc3RhdHVzID0gTkFORF9TVFNfT0s7 CgkJCQlGbGFzaFNhdmVQaHlJbmZvKCk7CgkJCX0KbGFiZWxfMTE6CgkJCSsrcGFnZV9jb3VudGVy OwoJCQljb250aW51ZTsKCQl9CgkJYnJlYWs7Cgl9CglGbGFzaEJjaFNlbChlY2NfYml0czIpOwoJ aWYgKGlkYl9mbGFzaF9zbGNfbW9kZSkKCQlmbGFzaF9leGl0X3NsY19tb2RlKDApOwoJcmV0dXJu IHN0YXR1czsKfQoKdm9pZCBGbGFzaFBhZ2VQcm9nTXNiRkZEYXRhKHVpbnQzMl90IGNzLCB1aW50 MzJfdCBwYWdlX2FkZHIsIHVpbnQzMl90IGNvdW50KQp7Cgl1aW50MzJfdCByZXRyeV9tb2RlOwoJ dWludDMyX3Qgc2hpZnQ7Cgl1aW50MzJfdCB0bXA7CgoJaWYgKCFnRmxhc2hTbGNNb2RlIHx8ICFp ZGJfZmxhc2hfc2xjX21vZGUpIHsKCQlyZXRyeV9tb2RlID0gZ3BOYW5kUGFyYUluZm8tPnJlYWRf cmV0cnlfbW9kZTsKCQlzaGlmdCA9ICh1aW50OF90KShyZXRyeV9tb2RlIC0gNSk7CgkJaWYgKHNo aWZ0ID4gMzApIHsKCQkJaWYgKHJldHJ5X21vZGUgIT0gNjgpCgkJCQlyZXR1cm47CgkJfSBlbHNl IGlmICghKCgweDQwMDA0MDBGdSA+PiBzaGlmdCkgJiAxKSkgewoJCQlyZXR1cm47CgkJfQoJCXdo aWxlIChncE5hbmRQYXJhSW5mby0+cGFnZV9wZXJfYmxrID4gY291bnQgJiYKCQkgICAgICAgbWxj UGFnZVRvU2xjUGFnZVRibFtjb3VudF0gPT0gMHhGRkZGKSB7CgkJCWlmIChyZXRyeV9tb2RlID09 IDgpCgkJCQl0bXAgPSAwOwoJCQllbHNlCgkJCQl0bXAgPSAweEZGdTsKCQkJZnRsX21lbXNldChn Rmxhc2hQYWdlQnVmZmVyMSwgdG1wLCAzMjc2OHUpOwoJCQlGbGFzaFByb2dQYWdlUmF3KAoJCQkJ Y3MsCgkJCQljb3VudCArIHBhZ2VfYWRkciwKCQkJCWdGbGFzaFBhZ2VCdWZmZXIxLAoJCQkJKHVp bnQxNl90ICopZ0ZsYXNoUGFnZUJ1ZmZlcjEpOwoJCQljb3VudCA9ICh1aW50MTZfdCkoY291bnQg KyAxKTsKCQl9Cgl9Cn0KCnZvaWQgSWRCbG9ja1JlYWREYXRhKHVpbnQzMl90IGluZGV4LCB1aW50 MzJfdCBjb3VudCwgdWludDMyX3QgKmJ1ZikKewoJdWludDMyX3QgY291bnRlcjsKCXVpbnQxNl90 IGNvdW50ZXJfYWRkOwoJdWludDMyX3QgZWNjX2JpdHM7Cgl1aW50MzJfdCBtaW5fc2VjdG9yOwoJ dWludDMyX3QgcGFnZTsKCXVpbnQzMl90IHNlY3RvcjsKCXVpbnQzMl90IHNlY3RvcjI7Cgl1aW50 MTZfdCBzaXplOwoJdWludDMyX3Qgc3RhcnRfb2Zmc2V0OwoKCXNpemUgPSBncE5hbmRQYXJhSW5m by0+c2VjX3Blcl9wYWdlICogKHVpbnQxNl90KWdCbG9ja1BhZ2VBbGlnblNpemU7CglGVExfSU5G TygKCQkiSWRCbG9ja1JlYWREYXRhICV4ICV4XG4iLAoJCWluZGV4LAoJCWNvdW50KTsKCWNvdW50 ZXIgPSAwOwoJc2VjdG9yMiA9IGluZGV4ICUgc2l6ZTsKCW1pbl9zZWN0b3IgPSBpbmRleCAtIGlu ZGV4ICUgc2l6ZTsKCXN0YXJ0X29mZnNldCA9IChncE5hbmRQYXJhSW5mby0+c2VjX3Blcl9wYWdl ICogKGluZGV4ICUgc2l6ZSkgPj4gMikgJiAzOwoJd2hpbGUgKGNvdW50ZXIgPCBjb3VudCkgewoJ CWNvdW50ZXJfYWRkID0gNCAtIHN0YXJ0X29mZnNldDsKCQlwYWdlID0gc2xjUGFnZVRvTWxjUGFn ZVRibFsoKGNvdW50ZXIgKyBzZWN0b3IyKSA+PiAyKSAmIDB4RkZGRl07CgkJaWYgKGdGbGFzaFNs Y01vZGUgJiYKCQkgICAgZ19uYW5kY192ZXJzaW9uX2RhdGEgPT0gTkFORF9WRVJTSU9OX1Y4MDAp CgkJCXBhZ2UgPSAoKGNvdW50ZXIgKyBzZWN0b3IyKSA+PiAyKSAmIDB4RkZGRjsKCQllY2NfYml0 cyA9IGdOYW5kRmxhc2hFY2NCaXRzOwoJCXNlY3RvciA9IHN0YXJ0X29mZnNldCArCgkJCSBtaW5f c2VjdG9yICsKCQkJIGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2UgKiBwYWdlOwoJCUZsYXNo QmNoU2VsKGdOYW5kRmxhc2hJREJFY2NCaXRzKTsKCQlmbGFzaF9ib290X2VudGVyX3NsY19tb2Rl KDApOwoJCUZsYXNoUmVhZFBhZ2UoCgkJCTAsCgkJCXNlY3RvciAvIGdwTmFuZFBhcmFJbmZvLT5z ZWNfcGVyX3BhZ2UsCgkJCWdGbGFzaFBhZ2VCdWZmZXIxLAoJCQkwKTsKCQlmbGFzaF9ib290X2V4 aXRfc2xjX21vZGUoMCk7CgkJRmxhc2hCY2hTZWwoZWNjX2JpdHMpOwoJCW1lbWNweSgmYnVmWzEy OCAqIGNvdW50ZXJdLCBnRmxhc2hQYWdlQnVmZmVyMSwgMjA0OHUpOwoJCXN0YXJ0X29mZnNldCA9 IDA7CgkJY291bnRlciA9ICh1aW50MTZfdCkoY291bnRlcl9hZGQgKyBjb3VudGVyKTsKCX0KCUZU TF9JTkZPKAoJCSJJZEJsb2NrUmVhZERhdGEgJXggJXggcmV0PSAleFxuIiwKCQlpbmRleCwKCQlj b3VudCwKCQkwKTsKfQoKdm9pZCBJREJsb2NrV3JpdGVEYXRhKHVpbnQzMl90IGluZGV4LCB1aW50 MzJfdCBjb3VudCwgdWludDMyX3QgKmJ1ZikKewoJdWludDMyX3QgY291bnRlcjsKCXVpbnQzMl90 IGVjY19iaXRzOwoJdWludDMyX3QgbWluX3NlY3RvcjsKCXVpbnQzMl90IHBhZ2U7Cgl1aW50MzJf dCBwYWdlMTsKCXVpbnQzMl90IHBhZ2UyOwoJdWludDMyX3Qgc2VjdG9yMjsKCXVpbnQxNl90IHNp emU7Cgl1aW50MzJfdCBzcGFyZVszMl07CgoJc2l6ZSA9IGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVy X3BhZ2UgKiAodWludDE2X3QpZ0Jsb2NrUGFnZUFsaWduU2l6ZTsKCUZUTF9JTkZPKAoJCSJJREJs b2NrV3JpdGVEYXRhICV4ICV4XG4iLAoJCWluZGV4LAoJCWNvdW50KTsKCWZsYXNoX2Jvb3RfZW50 ZXJfc2xjX21vZGUoMCk7CglGbGFzaEVyYXNlQmxvY2soMCwgaW5kZXggLyBnTmFuZFBoeUluZm8u c2VjX3Blcl9wYWdlLCAwKTsKCWZsYXNoX2Jvb3RfZXhpdF9zbGNfbW9kZSgwKTsKCWNvdW50ZXIg PSAwOwoJc2VjdG9yMiA9IGluZGV4ICUgc2l6ZTsKCW1pbl9zZWN0b3IgPSBpbmRleCAtIGluZGV4 ICUgc2l6ZTsKCXdoaWxlIChjb3VudGVyIDwgY291bnQpIHsKCQlwYWdlID0gKChjb3VudGVyICsg c2VjdG9yMikgPj4gMikgJiAweEZGRkY7CgkJaWYgKHBhZ2UpIHsKCQkJcGFnZTEgPSBzbGNQYWdl VG9NbGNQYWdlVGJsW3BhZ2UgKyAxXTsKCQkJaWYgKGdGbGFzaFNsY01vZGUgJiYKCQkJICAgIGdf bmFuZGNfdmVyc2lvbl9kYXRhID09IE5BTkRfVkVSU0lPTl9WODAwKQoJCQkJcGFnZTEgPSAodWlu dDE2X3QpCgkJCQkJKCgoY291bnRlciArIHNlY3RvcjIpID4+IDIpICsgMSk7CgkJCXNwYXJlWzBd ID0gNCAqIChwYWdlMSAtIDEpOwoJCQlzcGFyZVsxXSA9IDA7CgkJfQoJCXBhZ2UyID0gc2xjUGFn ZVRvTWxjUGFnZVRibFtwYWdlXTsKCQlpZiAoZ0ZsYXNoU2xjTW9kZSAmJgoJCSAgICBnX25hbmRj X3ZlcnNpb25fZGF0YSA9PSBOQU5EX1ZFUlNJT05fVjgwMCkKCQkJcGFnZTIgPSAoKGNvdW50ZXIg KyBzZWN0b3IyKSA+PiAyKSAmIDB4RkZGRjsKCQllY2NfYml0cyA9IGdOYW5kRmxhc2hFY2NCaXRz OwoJCUZsYXNoQmNoU2VsKGdOYW5kRmxhc2hJREJFY2NCaXRzKTsKCQlmbGFzaF9ib290X2VudGVy X3NsY19tb2RlKDApOwoJCUZsYXNoUHJvZ1BhZ2VSYXcoCgkJCTAsCgkJCShtaW5fc2VjdG9yICsg Z3BOYW5kUGFyYUluZm8tPnNlY19wZXJfcGFnZSAqIHBhZ2UyKQoJCQkvIGdwTmFuZFBhcmFJbmZv LT5zZWNfcGVyX3BhZ2UsCgkJCSZidWZbMTI4ICogY291bnRlcl0sCgkJCSh1aW50MTZfdCAqKXNw YXJlKTsKCQlmbGFzaF9ib290X2V4aXRfc2xjX21vZGUoMCk7CgkJRmxhc2hCY2hTZWwoZWNjX2Jp dHMpOwoJCUZsYXNoUGFnZVByb2dNc2JGRkRhdGEoCgkJCTAsCgkJCW1pbl9zZWN0b3IgLyBncE5h bmRQYXJhSW5mby0+c2VjX3Blcl9wYWdlLAoJCQkodWludDE2X3QpKHBhZ2UyICsgMSkpOwoJCWNv dW50ZXIgPSAodWludDE2X3QpKGNvdW50ZXIgKyA0KTsKCX0KCUZUTF9JTkZPKAoJCSJJREJsb2Nr V3JpdGVEYXRhICV4ICV4IHJldD0gJXhcbiIsCgkJaW5kZXgsCgkJY291bnQsCgkJMCk7Cn0KCmlu dCB3cml0ZV9pZGJsb2NrKHVpbnQzMl90IHNpemUsIHVpbnQzMl90ICpidWYsIHVpbnQzMl90ICpw X2RhdGEpCnsKCXVpbnQzMl90IGNvdW50OwoJdWludDMyX3QgY291bnRlcjsKCXVpbnQzMl90IGNv dW50ZXIyOwoJdWludDMyX3QgaW5kZXg7Cgl1aW50MzJfdCBtYXhfc2l6ZTsKCXVpbnQzMl90IG9m ZnNldDsKCXVpbnQzMl90IG9mZnNldDI7Cgl1aW50MzJfdCBwYWdlX2FkZHI7Cgl1aW50MzJfdCAq cF9yZWFkOwoJdWludDMyX3QgKnBfd3JpdGU7Cgl1aW50MzJfdCByOwoJdWludDMyX3QgdzsKCXVp bnQxNl90IHNpemUyOwoJdWludDMyX3Qgc3RhdHVzOwoJdWludDMyX3Qgd3JpdGVfY291bnRlcjsK CglzaXplMiA9IGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2UgKiAodWludDE2X3QpZ0Jsb2Nr UGFnZUFsaWduU2l6ZTsKCXBfcmVhZCA9ICh1aW50MzJfdCAqKWttYWxsb2Nfb3JkZXJfdHJhY2Uo MjU2MDAwLCAyMDgsIDYpOwoJaWYgKHBfcmVhZCkgewoJCWluZGV4ID0gKHNpemUgKyA1MTEpID4+ IDk7CgkJaWYgKGluZGV4IDw9IDI1NSkKCQkJbWVtY3B5KCZidWZbMTI4ICogaW5kZXhdLCBidWYs IDI1NiAtIGluZGV4KTsKCQljb3VudCA9IGluZGV4ICsgMTI4OwoJCXJrbmFuZF9wcmludF9oZXgo ImlkYmxrOiIsIHBfZGF0YSwgNCwgNSk7CgkJaWYgKGNvdW50ID49IDI1NikKCQkJY291bnQgPSAy NTY7CgkJY291bnRlciA9IDA7CgkJRlRMX0lORk8oCgkJCSJpZGIgcmV2ZXJzZSAleCAleFxuIiwK CQkJYnVmWzEyOF0sCgkJCWdOYW5kSURCUmVzQmxrTnVtKTsKCQl3cml0ZV9jb3VudGVyID0gMDsK CQlwX3dyaXRlID0gYnVmOwoJCWlmIChidWZbMTI4XSA+IGdOYW5kSURCUmVzQmxrTnVtKQoJCQli dWZbMTI4XSA9IGdOYW5kSURCUmVzQmxrTnVtOwoJCUZUTF9JTkZPKAoJCQkid3JpdGVfaWRibG9j ayB0b3RhbF9zZWMgJXggJXhcbiIsCgkJCWNvdW50LAoJCQlzaXplKTsKCQltYXhfc2l6ZSA9IGNv dW50IDw8IDc7CgkJZG8gewoJCQlwYWdlX2FkZHIgPSAqcF9kYXRhOwoJCQkrK3BfZGF0YTsKCQkJ aWYgKHBhZ2VfYWRkciA8IGdOYW5kUGh5SW5mby5yZXNlcnZlZF9ibGtzICYmCgkJCSAgICBwYWdl X2FkZHIgPj0gZ05hbmRGbGFzaElkYkJsb2NrQWRkcikgewoJCQkJZnRsX21lbXNldChwX3JlYWQs IDAsIDUxMik7CgkJCQlJREJsb2NrV3JpdGVEYXRhKAoJCQkJCSoocF9kYXRhIC0gMSkgKiBzaXpl MiwKCQkJCQljb3VudCwKCQkJCQlwX3dyaXRlKTsKCQkJCUlkQmxvY2tSZWFkRGF0YSgKCQkJCQkq KHBfZGF0YSAtIDEpICogc2l6ZTIsCgkJCQkJY291bnQsCgkJCQkJcF9yZWFkKTsKCQkJCWNvdW50 ZXIyID0gMDsKCQkJCW9mZnNldCA9IDA7CgkJCQl3aGlsZSAoMSkgewoJCQkJCXIgPSBwX3JlYWRb Y291bnRlcjJdOwoJCQkJCXcgPSBwX3dyaXRlW2NvdW50ZXIyXTsKCQkJCQkrK2NvdW50ZXIyOwoJ CQkJCWlmIChyICE9IHcpCgkJCQkJCWJyZWFrOwoJCQkJCSsrb2Zmc2V0OwoJCQkJCWlmIChvZmZz ZXQgPT0gbWF4X3NpemUpCgkJCQkJCWdvdG8gbGFiZWxfMTsKCQkJCX0KCQkJCW9mZnNldDIgPSBv ZmZzZXQgJiAweEZGRkZGRjAwOwoJCQkJRlRMX0lORk8oCgkJCQkJIndyaXRlIGFuZCBjaGVjayBl cnJvcjoiCgkJCQkJIiVkIGlkYj0leCxvZmZzZXQ9JXgscj0leCx3PSV4XG4iLAoJCQkJCXdyaXRl X2NvdW50ZXIsCgkJCQkJKihwX2RhdGEgLSAxKSwKCQkJCQlvZmZzZXQsCgkJCQkJciwKCQkJCQl3 KTsKCQkJCXJrbmFuZF9wcmludF9oZXgoCgkJCQkJIndyaXRlIiwKCQkJCQkmcF93cml0ZVtvZmZz ZXQyXSwKCQkJCQk0LAoJCQkJCTI1Nik7CgkJCQlya25hbmRfcHJpbnRfaGV4KAoJCQkJCSJyZWFk IiwKCQkJCQkmcF9yZWFkW29mZnNldDJdLAoJCQkJCTQsCgkJCQkJMjU2KTsKCQkJCWZ0bF9tZW1z ZXQocF9yZWFkLCAwLCA1MTIpOwoJCQkJSURCbG9ja1dyaXRlRGF0YSgKCQkJCQkqKHBfZGF0YSAt IDEpICogc2l6ZTIsCgkJCQkJNHUsCgkJCQkJcF9yZWFkKTsKCQkJCUZUTF9JTkZPKCJ3cml0ZV9p ZGJsb2NrIGVycm9yXG4iKTsKCQkJCWlmIChvZmZzZXQgPCBtYXhfc2l6ZSkKCQkJCQlnb3RvIGxh YmVsXzA7CmxhYmVsXzE6CgkJCQkrK2NvdW50ZXI7CgkJCX0KbGFiZWxfMDoKCQkJKyt3cml0ZV9j b3VudGVyOwoJCX0gd2hpbGUgKHdyaXRlX2NvdW50ZXIgIT0gNSk7CgkJZnRsX2ZyZWUocF9yZWFk KTsKCQlpZiAoY291bnRlcikKCQkJc3RhdHVzID0gMDsKCQllbHNlCgkJCXN0YXR1cyA9IC0xOwoJ fSBlbHNlIHsKCQlzdGF0dXMgPSAtMTsKCX0KCXJldHVybiBzdGF0dXM7Cn0KCnZvaWQgd3JpdGVf bG9hZGVyX2xiYSh1aW50MzJfdCBpbmRleCwgdWludDMyX3QgY291bnQsIHVpbnQzMl90ICpidWYp CnsKCXVpbnQzMl90IGNvdW50ZXIxOwoJdWludDMyX3QgY291bnRlcjI7Cgl1aW50MzJfdCBsYmEx OwoJdWludDMyX3QgbGJhMjsKCXVpbnQzMl90IHNpemU7Cgl1aW50MzJfdCB0bXA7Cgl1aW50MzJf dCBibG9ja1sxMzBdOwoKCWlmIChpbmRleCA9PSA2NCAmJiAqYnVmID09IElEX0lEUlcpIHsKCQlp ZGJfd3JpdGVfZW5hYmxlID0gMTsKCQlpZGJfYnVmID0gZnRsX21hbGxvYygyNTYwMDApOwoJCWZ0 bF9tZW1zZXQoCgkJCWlkYl9idWYsCgkJCTAsCgkJCTI1NjAwMCk7CgkJaWRiX2xhc3RfbGJhID0g aW5kZXg7Cgl9CglGVExfSU5GTygid2xfbGJhICVwICV4ICV4ICV4XG4iLCBpZGJfYnVmLCAqYnVm LCBpbmRleCwgY291bnQpOwoJaWYgKGlkYl93cml0ZV9lbmFibGUpIHsKCQlpZiAoaW5kZXggLSA2 NCA+PSA1MDApIHsKCQkJaWYgKGluZGV4ID49IDU2NCkgewoJCQkJbGJhMSA9IGlkYl9sYXN0X2xi YSAtIDY0OwoJCQkJaWYgKGlkYl9sYXN0X2xiYSAtIDY0ID49IDUwMCkKCQkJCQlsYmExID0gNTAw OwoJCQkJaWYgKGdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2UgPT0gNCkgewoJCQkJCWNvdW50 ZXIxID0gMDsKCQkJCQlkbyB7CgkJCQkJCXRtcCA9IDIgKiBjb3VudGVyMTsKCQkJCQkJaWYgKGxi YTEgPD0gMjU2KQoJCQkJCQkJdG1wID0gY291bnRlcjE7CgkJCQkJCWJsb2NrW2NvdW50ZXIxKytd ID0gdG1wOwoJCQkJCX0gd2hpbGUgKGNvdW50ZXIxICE9IDUpOwoJCQkJfSBlbHNlIHsKCQkJCQli bG9ja1swXSA9IDI7CgkJCQkJYmxvY2tbMV0gPSAzOwoJCQkJCWJsb2NrWzJdID0gNDsKCQkJCQli bG9ja1szXSA9IDU7CgkJCQkJYmxvY2tbNF0gPSA2OwoJCQkJfQoJCQkJY291bnRlcjIgPSA2Mzg3 MjsKCQkJCWRvIHsKCQkJCQlpZiAoaWRiX2J1Zltjb3VudGVyMl0pIHsKCQkJCQkJc2l6ZSA9IDQg KiAoY291bnRlcjIgKyAxMjgpOwoJCQkJCQlnb3RvIGxhYmVsXzI4OwoJCQkJCX0KCQkJCQktLWNv dW50ZXIyOwoJCQkJfSB3aGlsZSAoY291bnRlcjIgIT0gNDA5Nik7CgkJCQlzaXplID0gbGJhMSA8 PCA5OwpsYWJlbF8yODoKCQkJCXdyaXRlX2lkYmxvY2soCgkJCQkJc2l6ZSwKCQkJCQlpZGJfYnVm LAoJCQkJCWJsb2NrKTsKCQkJCWlkYl93cml0ZV9lbmFibGUgPSAwOwoJCQkJZnRsX2ZyZWUoaWRi X2J1Zik7CgkJCQlpZGJfYnVmID0gMDsKCQkJCWdvdG8gbGFiZWxfMTQ7CgkJCX0KCQl9IGVsc2Ug ewoJCQlsYmEyID0gNTY0IC0gaW5kZXg7CgkJCWlmICg1NjQgLSBpbmRleCA+PSBjb3VudCkKCQkJ CWxiYTIgPSBjb3VudDsKCQkJZnRsX21lbWNweSgKCQkJCSh2b2lkICopCgkJCQkoaWRiX2J1ZiAr ICgoaW5kZXggLSA2NCkgPDwgOSkpLAoJCQkJYnVmLAoJCQkJbGJhMiA8PCA5KTsKCQl9CgkJaWYg KGlkYl9sYXN0X2xiYSAhPSBpbmRleCkgewoJCQlpZGJfd3JpdGVfZW5hYmxlID0gMDsKCQkJaWYg KGlkYl9idWYpCgkJCQlmdGxfZnJlZShpZGJfYnVmKTsKCQkJaWRiX2J1ZiA9IDA7CgkJfQpsYWJl bF8xNDoKCQlpZGJfbGFzdF9sYmEgPSBpbmRleCArIGNvdW50OwoJfQp9CgojZGVmaW5lIEdldElk YmxvY2tEYXRhTm9SYzQocCwgcykgUF9SQzQocCwgcykKCmludCBGdGxHZXRJZEJsb2NrU3lzRGF0 YSh2b2lkICpwX2J1ZiwgaW50IGluZGV4KQp7CglpZiAoaW5kZXggPiAzKQoJCXJldHVybiAtMTsK CWZ0bF9tZW1jcHkocF9idWYsICZnTmFuZElEYXRhQnVmW2luZGV4ICogNTEyXSwgNTEyKTsKCWlm IChpbmRleCA9PSAxKQoJCXJldHVybiAwOwoJR2V0SWRibG9ja0RhdGFOb1JjNChwX2J1ZiwgNTEy KTsKCXJldHVybiAwOwp9CgppbnQgRnRsR2V0Q2hpcFNlY3RvckluZm8odm9pZCAqcF9idWYpCnsK CXJldHVybiBGdGxHZXRJZEJsb2NrU3lzRGF0YShwX2J1ZiwgMik7Cn0KCmludCBGdGxHZXRTTlNl Y3RvckluZm8odm9pZCAqcF9idWYpCnsKCXJldHVybiBGdGxHZXRJZEJsb2NrU3lzRGF0YShwX2J1 ZiwgMyk7Cn0KCi8qIGluaXQgKi8KCglnRmxhc2hQYWdlQnVmZmVyMCA9CgkJKHVpbnQzMl90ICop CgkJZnRsX21hbGxvYygzMjc2OHUpOwoJZ0ZsYXNoUGFnZUJ1ZmZlcjEgPQoJCSh1aW50MzJfdCAq KQoJCWZ0bF9tYWxsb2MoMzI3Njh1KTsKCglnQmxvY2tQYWdlQWxpZ25TaXplID0gMTI4OwovKiBt b3JlIGluaXQgKi8KCgkJaWYgKEZsYXNoTG9hZFBoeUluZm8oKSkgewoKCQkJLyogc29ydCBvdXQg eW91ciBtZXNzIGhlcmUgKi8KCgkJCUZsYXNoU2F2ZVBoeUluZm8oKTsKCQl9CgovKiBtb3JlIGlu aXQgKi8KCglnRmxhc2hTbGNNb2RlID0gZ3BOYW5kUGFyYUluZm8tPnNsY19tb2RlOwoJZ05hbmRS YW5kb21pemVyID0gKGdwTmFuZFBhcmFJbmZvLT5vcGVyYXRpb25fb3B0ID4+IDcpICYgMTsKCWdN dWx0aVBhZ2VSZWFkRW4gPSAoZ3BOYW5kUGFyYUluZm8tPm9wZXJhdGlvbl9vcHQgPj4gMykgJiAx OwoJZ011bHRpUGFnZVByb2dFbiA9IChncE5hbmRQYXJhSW5mby0+b3BlcmF0aW9uX29wdCA+PiA0 KSAmIDE7CglnRmxhc2hJbnRlcmZhY2VNb2RlID0gKGdwTmFuZFBhcmFJbmZvLT5vcGVyYXRpb25f b3B0ID4+IDgpICYgNzsKCglCdWlsZEZsYXNoTHNiUGFnZVRhYmxlKAoJCWdwTmFuZFBhcmFJbmZv LT5sc2JfbW9kZSwKCQkodWludDMyX3QpZ3BOYW5kUGFyYUluZm8tPnBhZ2VfcGVyX2JsayAvCgkJ KHVpbnQzMl90KWdwTmFuZFBhcmFJbmZvLT5jZWxsKTsKCglGbGFzaFJlYWRJZGJEYXRhUmF3KGdO YW5kSURhdGFCdWYpOwoKCWdOYW5kSURCUmVzQmxrTnVtID0gMTY7CglnTmFuZFBoeUluZm8ubmFu ZF90eXBlID0KCQlncE5hbmRQYXJhSW5mby0+Y2VsbDsKCWdOYW5kUGh5SW5mby52ZW5kb3IgPQoJ CWdwTmFuZFBhcmFJbmZvLT52ZW5kb3I7CglnTmFuZFBoeUluZm8uY2hpcF9pZCA9CgkJKih1aW50 MzJfdCAqKUlEQnl0ZTsKCWdOYW5kUGh5SW5mby5kaWVfbnVtID0KCQlnTmFuZE1heERpZTsKCWdO YW5kUGh5SW5mby5wYWdlX3Blcl9ibGsgPQoJCWdwTmFuZFBhcmFJbmZvLT5wYWdlX3Blcl9ibGs7 CglnTmFuZFBoeUluZm8uYmxrX3Blcl9wbGFuZSA9CgkJZ3BOYW5kUGFyYUluZm8tPmJsa19wZXJf cGxhbmU7CglnTmFuZFBoeUluZm8ucGxhbmVzX3Blcl9kaWUgPQoJCWdwTmFuZFBhcmFJbmZvLT5w bGFuZV9wZXJfZGllOwoJZ05hbmRQaHlJbmZvLnBhZ2VfcGVyX3NsY19ibGsgPQoJCSh1aW50MzJf dClncE5hbmRQYXJhSW5mby0+cGFnZV9wZXJfYmxrIC8KCQkodWludDMyX3QpZ3BOYW5kUGFyYUlu Zm8tPmNlbGw7CglnTmFuZFBoeUluZm8uc2VjdG9yX3NpemUgPQoJCTUxMjsKCWdOYW5kUGh5SW5m by5zZWNfcGVyX3BhZ2UgPQoJCWdwTmFuZFBhcmFJbmZvLT5zZWNfcGVyX3BhZ2U7CglnTmFuZFBo eUluZm8ucmVzZXJ2ZWRfYmxrcyA9CgkJMTY7CglnTmFuZFBoeUluZm8uYmxvY2tfc2l6ZSA9CgkJ Z3BOYW5kUGFyYUluZm8tPnBhZ2VfcGVyX2JsayAqCgkJZ3BOYW5kUGFyYUluZm8tPnNlY19wZXJf cGFnZTsKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwps aW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJh ZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51 eC1hcm0ta2VybmVsCg==