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=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9269C64EB1 for ; Fri, 7 Dec 2018 09:25:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 477F420838 for ; Fri, 7 Dec 2018 09:25:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 477F420838 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726072AbeLGJZO convert rfc822-to-8bit (ORCPT ); Fri, 7 Dec 2018 04:25:14 -0500 Received: from mail.bootlin.com ([62.4.15.54]:47173 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726010AbeLGJZL (ORCPT ); Fri, 7 Dec 2018 04:25:11 -0500 Received: by mail.bootlin.com (Postfix, from userid 110) id 8569320834; Fri, 7 Dec 2018 10:25:07 +0100 (CET) Received: from xps13 (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id EC03720701; Fri, 7 Dec 2018 10:24:56 +0100 (CET) Date: Fri, 7 Dec 2018 10:24:56 +0100 From: Miquel Raynal To: Jianxin Pan Cc: Boris Brezillon , , Liang Yang , Yixun Lan , David Woodhouse , Brian Norris , Marek Vasut , Richard Weinberger , Jerome Brunet , Neil Armstrong , Martin Blumenstingl , Carlo Caione , Kevin Hilman , Rob Herring , Jian Hu , Hanjie Lin , Victor Wan , , , Subject: Re: [PATCH v7 2/2] mtd: rawnand: meson: add support for Amlogic NAND flash controller Message-ID: <20181207102456.1dc67e07@xps13> In-Reply-To: <1542386439-30166-3-git-send-email-jianxin.pan@amlogic.com> References: <1542386439-30166-1-git-send-email-jianxin.pan@amlogic.com> <1542386439-30166-3-git-send-email-jianxin.pan@amlogic.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.1 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Jianxin, Looks good to me overall, a few comments inline. Jianxin Pan wrote on Sat, 17 Nov 2018 00:40:38 +0800: > From: Liang Yang > > Add initial support for the Amlogic NAND flash controller which found > in the Meson-GXBB/GXL/AXG SoCs. > > Signed-off-by: Liang Yang > Signed-off-by: Yixun Lan > Signed-off-by: Jianxin Pan > --- > drivers/mtd/nand/raw/Kconfig | 10 + > drivers/mtd/nand/raw/Makefile | 1 + > drivers/mtd/nand/raw/meson_nand.c | 1417 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 1428 insertions(+) > create mode 100644 drivers/mtd/nand/raw/meson_nand.c > > diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig > index c7efc31..223b041 100644 > --- a/drivers/mtd/nand/raw/Kconfig > +++ b/drivers/mtd/nand/raw/Kconfig > @@ -541,4 +541,14 @@ config MTD_NAND_TEGRA > is supported. Extra OOB bytes when using HW ECC are currently > not supported. > > +config MTD_NAND_MESON > + tristate "Support for NAND controller on Amlogic's Meson SoCs" > + depends on ARCH_MESON || COMPILE_TEST > + depends on COMMON_CLK_AMLOGIC > + select COMMON_CLK_REGMAP_MESON > + select MFD_SYSCON > + help > + Enables support for NAND controller on Amlogic's Meson SoCs. > + This controller is found on Meson GXBB, GXL, AXG SoCs. > + > endif # MTD_NAND > diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile > index 57159b3..a2cc2fe 100644 > --- a/drivers/mtd/nand/raw/Makefile > +++ b/drivers/mtd/nand/raw/Makefile > @@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ > obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o > obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o > obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o > +obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o > > 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/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c > new file mode 100644 > index 0000000..c566636 > --- /dev/null > +++ b/drivers/mtd/nand/raw/meson_nand.c > @@ -0,0 +1,1417 @@ > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) > +/* > + * Amlogic Meson Nand Flash Controller Driver > + * > + * Copyright (c) 2018 Amlogic, inc. > + * Author: Liang Yang > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define NFC_REG_CMD 0x00 > +#define NFC_CMD_DRD (0x8 << 14) > +#define NFC_CMD_IDLE (0xc << 14) > +#define NFC_CMD_DWR (0x4 << 14) > +#define NFC_CMD_CLE (0x5 << 14) > +#define NFC_CMD_ALE (0x6 << 14) > +#define NFC_CMD_ADL ((0 << 16) | (3 << 20)) > +#define NFC_CMD_ADH ((1 << 16) | (3 << 20)) > +#define NFC_CMD_AIL ((2 << 16) | (3 << 20)) > +#define NFC_CMD_AIH ((3 << 16) | (3 << 20)) > +#define NFC_CMD_SEED ((8 << 16) | (3 << 20)) > +#define NFC_CMD_M2N ((0 << 17) | (2 << 20)) > +#define NFC_CMD_N2M ((1 << 17) | (2 << 20)) > +#define NFC_CMD_RB BIT(20) > +#define NFC_CMD_IO6 ((0xb << 10) | (1 << 18)) > +#define NFC_CMD_SCRAMBLER_ENABLE BIT(19) > +#define NFC_CMD_RB_INT BIT(14) > + > +#define NFC_CMD_GET_SIZE(x) (((x) >> 22) & GENMASK(4, 0)) > + > +#define NFC_REG_CFG 0x04 > +#define NFC_REG_DADR 0x08 > +#define NFC_REG_IADR 0x0c > +#define NFC_REG_BUF 0x10 > +#define NFC_REG_INFO 0x14 > +#define NFC_REG_DC 0x18 > +#define NFC_REG_ADR 0x1c > +#define NFC_REG_DL 0x20 > +#define NFC_REG_DH 0x24 > +#define NFC_REG_CADR 0x28 > +#define NFC_REG_SADR 0x2c > +#define NFC_REG_PINS 0x30 > +#define NFC_REG_VER 0x38 > + > +#define NFC_RB_IRQ_EN BIT(21) > +#define NFC_INT_MASK (3 << 20) > + > +#define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \ > + ( \ > + (cmd_dir) | \ > + ((ran) << 19) | \ > + ((bch) << 14) | \ > + ((short_mode) << 13) | \ > + (((page_size) & 0x7f) << 6) | \ > + ((pages) & 0x3f) \ > + ) > + > +#define GENCMDDADDRL(adl, addr) ((adl) | ((addr) & 0xffff)) > +#define GENCMDDADDRH(adh, addr) ((adh) | (((addr) >> 16) & 0xffff)) > +#define GENCMDIADDRL(ail, addr) ((ail) | ((addr) & 0xffff)) > +#define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff)) > + > +#define RB_STA(x) (1 << (26 + (x))) > +#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N) > + > +#define ECC_CHECK_RETURN_FF (-1) > + > +#define NAND_CE0 (0xe << 10) > +#define NAND_CE1 (0xd << 10) > + > +#define DMA_BUSY_TIMEOUT 0x100000 > +#define CMD_FIFO_EMPTY_TIMEOUT 1000 > + > +#define MAX_CE_NUM 2 > + > +/* eMMC clock register, misc control */ > +#define SD_EMMC_CLOCK 0x00 > +#define CLK_ALWAYS_ON BIT(28) > +#define CLK_SELECT_NAND BIT(31) > +#define CLK_DIV_MASK GENMASK(5, 0) > + > +#define NFC_CLK_CYCLE 6 > + > +/* nand flash controller delay 3 ns */ > +#define NFC_DEFAULT_DELAY 3000 > + > +#define MAX_ECC_INDEX 10 > + > +#define MUX_CLK_NUM_PARENTS 2 > + > +#define ROW_ADDER(page, index) (((page) >> (8 * (index))) & 0xff) > +#define MAX_CYCLE_ADDRS 5 > +#define DIRREAD 1 > +#define DIRWRITE 0 > + > +#define ECC_PARITY_BCH8_512B 14 > + > +#define PER_INFO_BYTE 8 > + > +#define ECC_COMPLETE BIT(31) > +#define ECC_ERR_CNT(x) (((x) >> 24) & GENMASK(5, 0)) > +#define ECC_ZERO_CNT(x) (((x) >> 16) & GENMASK(5, 0)) > + > +struct meson_nfc_nand_chip { > + struct list_head node; > + struct nand_chip nand; > + unsigned long clk_rate; > + unsigned long level1_divider; > + u32 bus_timing; > + u32 twb; > + u32 tadl; > + u32 tbers_max; > + > + u32 bch_mode; > + u8 *data_buf; > + __le64 *info_buf; > + u32 nsels; > + u8 sels[0]; > +}; > + > +struct meson_nand_ecc { > + u32 bch; > + u32 strength; > +}; > + > +struct meson_nfc_data { > + const struct nand_ecc_caps *ecc_caps; > +}; > + > +struct meson_nfc_param { > + u32 chip_select; > + u32 rb_select; > +}; > + > +struct nand_rw_cmd { > + u32 cmd0; > + u32 addrs[MAX_CYCLE_ADDRS]; > + u32 cmd1; > +}; > + > +struct nand_timing { > + u32 twb; > + u32 tadl; > + u32 tbers_max; > +}; > + > +struct meson_nfc { > + struct nand_controller controller; > + struct clk *core_clk; > + struct clk *device_clk; > + struct clk *phase_tx; > + struct clk *phase_rx; > + > + unsigned long clk_rate; > + u32 bus_timing; > + > + struct device *dev; > + void __iomem *reg_base; > + struct regmap *reg_clk; > + struct completion completion; > + struct list_head chips; > + const struct meson_nfc_data *data; > + struct meson_nfc_param param; > + struct nand_timing timing; > + union { > + int cmd[32]; > + struct nand_rw_cmd rw; > + } cmdfifo; > + > + dma_addr_t daddr; > + dma_addr_t iaddr; > + > + unsigned long assigned_cs; > +}; > + > +enum { > + NFC_ECC_BCH8_1K = 2, > + NFC_ECC_BCH24_1K, > + NFC_ECC_BCH30_1K, > + NFC_ECC_BCH40_1K, > + NFC_ECC_BCH50_1K, > + NFC_ECC_BCH60_1K, > +}; > + > +#define MESON_ECC_DATA(b, s) { .bch = (b), .strength = (s)} > + > +static int meson_nand_calc_ecc_bytes(int step_size, int strength) > +{ > + int ecc_bytes; > + > + if (step_size == 512 && strength == 8) > + return ECC_PARITY_BCH8_512B; > + > + ecc_bytes = DIV_ROUND_UP(strength * fls(step_size * 8), 8); > + ecc_bytes = ALIGN(ecc_bytes, 2); > + > + return ecc_bytes; > +} > + > +NAND_ECC_CAPS_SINGLE(meson_gxl_ecc_caps, > + meson_nand_calc_ecc_bytes, 1024, 8, 24, 30, 40, 50, 60); > +NAND_ECC_CAPS_SINGLE(meson_axg_ecc_caps, > + meson_nand_calc_ecc_bytes, 1024, 8); > + > +static struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand) > +{ > + return container_of(nand, struct meson_nfc_nand_chip, nand); > +} > + > +static void meson_nfc_select_chip(struct nand_chip *nand, int chip) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + int ret, value; > + > + if (chip < 0 || WARN_ON_ONCE(chip > MAX_CE_NUM)) > + return; > + > + nfc->param.chip_select = meson_chip->sels[chip] ? NAND_CE1 : NAND_CE0; > + nfc->param.rb_select = nfc->param.chip_select; > + nfc->timing.twb = meson_chip->twb; > + nfc->timing.tadl = meson_chip->tadl; > + nfc->timing.tbers_max = meson_chip->tbers_max; > + > + if (chip >= 0) { > + if (nfc->clk_rate != meson_chip->clk_rate) { > + ret = clk_set_rate(nfc->device_clk, > + meson_chip->clk_rate); > + if (ret) { > + dev_err(nfc->dev, "failed to set clock rate\n"); > + return; > + } > + nfc->clk_rate = meson_chip->clk_rate; > + } > + if (nfc->bus_timing != meson_chip->bus_timing) { > + value = (NFC_CLK_CYCLE - 1) > + | (meson_chip->bus_timing << 5); > + writel(value, nfc->reg_base + NFC_REG_CFG); > + writel((1 << 31), nfc->reg_base + NFC_REG_CMD); > + nfc->bus_timing = meson_chip->bus_timing; > + } > + } Don't you have timing registers to set? > +} > + > +static void meson_nfc_cmd_idle(struct meson_nfc *nfc, u32 time) > +{ > + writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff), > + nfc->reg_base + NFC_REG_CMD); > +} > + > +static void meson_nfc_cmd_seed(struct meson_nfc *nfc, u32 seed) > +{ > + writel(NFC_CMD_SEED | (0xc2 + (seed & 0x7fff)), > + nfc->reg_base + NFC_REG_CMD); > +} > + > +static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + u32 bch = meson_chip->bch_mode, cmd; > + int len = mtd->writesize, pagesize, pages; > + int scramble = (nand->options & NAND_NEED_SCRAMBLING) ? 1 : 0; There are quite a few places where you use hardcoded values, I would have preferred preprocessor defines for that. In this case, something link: // naming is just as a reference, use whatever you want +#define CMD_SCRAMBLE BIT(19) [...] +int scramble = nand->options & NAND_NEED_SCRAMBLING) ? CMD_SCRAMBLE : 0; would be better (you can extend to other places as well). > + > + pagesize = nand->ecc.size; > + > + if (raw) { > + len = mtd->writesize + mtd->oobsize; > + cmd = (len & 0x3fff) | (scramble << 19) | DMA_DIR(dir); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + return; > + } > + > + pages = len / nand->ecc.size; > + > + cmd = CMDRWGEN(DMA_DIR(dir), scramble, bch, 0, pagesize, pages); > + > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > +} > + > +static void meson_nfc_drain_cmd(struct meson_nfc *nfc) > +{ > + /* > + * Insert two commands to make sure all valid commands are finished. > + * > + * The Nand flash controller is designed as two stages pipleline - > + * a) fetch and b) excute. > + * There might be cases when the driver see command queue is empty, > + * but the Nand flash controller still has two commands buffered, > + * one is fetched into NFC request queue (ready to run), and another > + * is actively executing. So pushing 2 "IDLE" commands guarantees that > + * the pipeline is emptied. > + */ > + meson_nfc_cmd_idle(nfc, 0); > + meson_nfc_cmd_idle(nfc, 0); > +} > + > +static int meson_nfc_wait_cmd_finish(struct meson_nfc *nfc, > + unsigned int timeout_ms) > +{ > + u32 cmd_size = 0; > + int ret; > + > + /* wait cmd fifo is empty */ > + ret = readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size, > + !NFC_CMD_GET_SIZE(cmd_size), > + 10, timeout_ms * 1000); > + if (ret) > + dev_err(nfc->dev, "wait for empty cmd FIFO time out\n"); > + > + return ret; > +} > + > +static int meson_nfc_wait_dma_finish(struct meson_nfc *nfc) > +{ > + meson_nfc_drain_cmd(nfc); > + > + return meson_nfc_wait_cmd_finish(nfc, DMA_BUSY_TIMEOUT); > +} > + > +static u8 *meson_nfc_oob_ptr(struct nand_chip *nand, int i) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + int len; > + > + len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i; > + > + return meson_chip->data_buf + len; > +} > + > +static u8 *meson_nfc_data_ptr(struct nand_chip *nand, int i) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + int len, temp; > + > + temp = nand->ecc.size + nand->ecc.bytes; > + len = (temp + 2) * i; > + > + return meson_chip->data_buf + len; > +} > + > +static void meson_nfc_get_data_oob(struct nand_chip *nand, > + u8 *buf, u8 *oobbuf) > +{ > + int i, oob_len = 0; > + u8 *dsrc, *osrc; > + > + oob_len = nand->ecc.bytes + 2; > + for (i = 0; i < nand->ecc.steps; i++) { > + if (buf) { > + dsrc = meson_nfc_data_ptr(nand, i); > + memcpy(buf, dsrc, nand->ecc.size); > + buf += nand->ecc.size; > + } > + osrc = meson_nfc_oob_ptr(nand, i); > + memcpy(oobbuf, osrc, oob_len); > + oobbuf += oob_len; > + } > +} > + > +static void meson_nfc_set_data_oob(struct nand_chip *nand, > + const u8 *buf, u8 *oobbuf) > +{ > + int i, oob_len = 0; > + u8 *dsrc, *osrc; > + > + oob_len = nand->ecc.bytes + 2; > + for (i = 0; i < nand->ecc.steps; i++) { > + if (buf) { > + dsrc = meson_nfc_data_ptr(nand, i); > + memcpy(dsrc, buf, nand->ecc.size); > + buf += nand->ecc.size; > + } > + osrc = meson_nfc_oob_ptr(nand, i); > + memcpy(osrc, oobbuf, oob_len); > + oobbuf += oob_len; > + } > +} > + > +static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms) > +{ > + u32 cmd, cfg; > + int ret = 0; > + > + meson_nfc_cmd_idle(nfc, nfc->timing.twb); > + meson_nfc_drain_cmd(nfc); > + meson_nfc_wait_cmd_finish(nfc, CMD_FIFO_EMPTY_TIMEOUT); > + > + cfg = readl(nfc->reg_base + NFC_REG_CFG); > + cfg |= (1 << 21); > + writel(cfg, nfc->reg_base + NFC_REG_CFG); > + > + init_completion(&nfc->completion); > + > + /* use the max erase time as the maximum clock for waiting R/B */ > + cmd = NFC_CMD_RB | NFC_CMD_RB_INT > + | nfc->param.chip_select | nfc->timing.tbers_max; Nit: I think the '|' should be on the previous line. > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + > + ret = wait_for_completion_timeout(&nfc->completion, > + msecs_to_jiffies(timeout_ms)); > + if (ret == 0) > + ret = -1; > + > + return ret; > +} > + > +static void meson_nfc_set_user_byte(struct nand_chip *nand, u8 *oob_buf) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + __le64 *info; > + int i, count; > + > + for (i = 0, count = 0; i < nand->ecc.steps; i++, count += 2) { > + info = &meson_chip->info_buf[i]; > + *info |= oob_buf[count]; > + *info |= oob_buf[count + 1] << 8; > + } > +} > + > +static void meson_nfc_get_user_byte(struct nand_chip *nand, u8 *oob_buf) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + __le64 *info; > + int i, count; > + > + for (i = 0, count = 0; i < nand->ecc.steps; i++, count += 2) { > + info = &meson_chip->info_buf[i]; > + oob_buf[count] = *info; > + oob_buf[count + 1] = *info >> 8; > + } > +} > + > +static int meson_nfc_ecc_correct(struct nand_chip *nand) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + __le64 *info; > + u32 bitflips = 0, i; > + int scramble; > + u8 zero_cnt; > + > + scramble = (nand->options & NAND_NEED_SCRAMBLING) ? 1 : 0; > + > + for (i = 0; i < nand->ecc.steps; i++) { > + info = &meson_chip->info_buf[i]; > + if (ECC_ERR_CNT(*info) == 0x3f) { > + zero_cnt = ECC_ZERO_CNT(*info); > + if (scramble && zero_cnt < nand->ecc.strength) > + return ECC_CHECK_RETURN_FF; This and what you do later with ECC_CHECK_RETURN_FF is pretty unclear to me. > + mtd->ecc_stats.failed++; > + continue; > + } > + mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); > + bitflips = max_t(u32, bitflips, ECC_ERR_CNT(*info)); > + } Are you sure you handle correctly empty pages with bf? > + > + return bitflips; > +} > + > +static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, u8 *databuf, > + int datalen, u8 *infobuf, int infolen, > + enum dma_data_direction dir) > +{ > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + u32 cmd; > + int ret = 0; > + > + nfc->daddr = dma_map_single(nfc->dev, (void *)databuf, datalen, dir); > + ret = dma_mapping_error(nfc->dev, nfc->daddr); > + if (ret) { > + dev_err(nfc->dev, "dma mapping error\n"); > + return ret; > + } > + cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + > + cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + > + if (infobuf) { > + nfc->iaddr = dma_map_single(nfc->dev, infobuf, infolen, dir); > + ret = dma_mapping_error(nfc->dev, nfc->iaddr); > + if (ret) { > + dev_err(nfc->dev, "dma mapping error\n"); > + dma_unmap_single(nfc->dev, > + nfc->daddr, datalen, dir); > + return ret; > + } > + cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + > + cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + } > + > + return ret; > +} > + > +static void meson_nfc_dma_buffer_release(struct nand_chip *nand, > + int infolen, int datalen, > + enum dma_data_direction dir) > +{ > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + > + dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); > + if (infolen) > + dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); > +} > + > +static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) > +{ > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + int ret = 0; > + u32 cmd; > + u8 *info; > + > + info = kzalloc(PER_INFO_BYTE, GFP_KERNEL); > + ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, > + PER_INFO_BYTE, DMA_FROM_DEVICE); > + if (ret) > + return ret; > + > + cmd = NFC_CMD_N2M | (len & 0x3fff); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + > + meson_nfc_drain_cmd(nfc); > + meson_nfc_wait_cmd_finish(nfc, 1000); > + meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); > + kfree(info); > + > + return ret; > +} > + > +static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len) > +{ > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + int ret = 0; > + u32 cmd; > + > + ret = meson_nfc_dma_buffer_setup(nand, buf, len, NULL, > + 0, DMA_TO_DEVICE); > + if (ret) > + return ret; > + > + cmd = NFC_CMD_M2N | (len & 0x3fff); > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + > + meson_nfc_drain_cmd(nfc); > + meson_nfc_wait_cmd_finish(nfc, 1000); > + meson_nfc_dma_buffer_release(nand, len, 0, DMA_TO_DEVICE); > + > + return ret; > +} > + > +static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, > + int page, bool in) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + const struct nand_sdr_timings *sdr = > + nand_get_sdr_timings(&nand->data_interface); > + u32 *addrs = nfc->cmdfifo.rw.addrs; > + u32 cs = nfc->param.chip_select; > + u32 cmd0, cmd_num, row_start; > + int ret = 0, i; > + > + cmd_num = sizeof(struct nand_rw_cmd) / sizeof(int); > + > + cmd0 = in ? NAND_CMD_READ0 : NAND_CMD_SEQIN; > + nfc->cmdfifo.rw.cmd0 = cs | NFC_CMD_CLE | cmd0; > + > + addrs[0] = cs | NFC_CMD_ALE | 0; > + if (mtd->writesize <= 512) { > + cmd_num--; > + row_start = 1; > + } else { > + addrs[1] = cs | NFC_CMD_ALE | 0; > + row_start = 2; > + } > + > + addrs[row_start] = cs | NFC_CMD_ALE | ROW_ADDER(page, 0); > + addrs[row_start + 1] = cs | NFC_CMD_ALE | ROW_ADDER(page, 1); > + > + if (nand->options & NAND_ROW_ADDR_3) > + addrs[row_start + 2] = > + cs | NFC_CMD_ALE | ROW_ADDER(page, 2); > + else > + cmd_num--; > + > + /* subtract cmd1 */ > + cmd_num--; > + > + for (i = 0; i < cmd_num; i++) > + writel_relaxed(nfc->cmdfifo.cmd[i], > + nfc->reg_base + NFC_REG_CMD); > + > + if (in) { > + nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART; > + writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD); > + meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tR_max)); > + } else { > + meson_nfc_cmd_idle(nfc, nfc->timing.tadl); > + } > + > + return ret; > +} > + > +static int meson_nfc_write_page_sub(struct nand_chip *nand, > + int page, int raw) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + const struct nand_sdr_timings *sdr = > + nand_get_sdr_timings(&nand->data_interface); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + int data_len, info_len; > + u32 cmd; > + int ret; > + > + data_len = mtd->writesize + mtd->oobsize; > + info_len = nand->ecc.steps * PER_INFO_BYTE; > + > + ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRWRITE); > + if (ret) > + return ret; > + > + ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, > + data_len, (u8 *)meson_chip->info_buf, > + info_len, DMA_TO_DEVICE); > + if (ret) > + return ret; > + > + meson_nfc_cmd_seed(nfc, page); > + meson_nfc_cmd_access(nand, raw, DIRWRITE); > + cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG; > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tPROG_max)); > + > + meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE); > + > + return ret; > +} > + > +static int meson_nfc_write_page_raw(struct nand_chip *nand, const u8 *buf, > + int oob_required, int page) > +{ > + u8 *oob_buf = nand->oob_poi; > + > + meson_nfc_set_data_oob(nand, buf, oob_buf); > + > + return meson_nfc_write_page_sub(nand, page, 1); > +} > + > +static int meson_nfc_write_page_hwecc(struct nand_chip *nand, > + const u8 *buf, int oob_required, int page) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + u8 *oob_buf = nand->oob_poi; > + > + memcpy(meson_chip->data_buf, buf, mtd->writesize); > + memset(meson_chip->info_buf, 0, nand->ecc.steps * PER_INFO_BYTE); > + meson_nfc_set_user_byte(nand, oob_buf); > + > + return meson_nfc_write_page_sub(nand, page, 0); > +} > + > +static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc, > + struct nand_chip *nand, int raw) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + __le64 *info; > + u32 neccpages; > + int ret; > + > + neccpages = raw ? 1 : nand->ecc.steps; > + info = &meson_chip->info_buf[neccpages - 1]; > + do { > + usleep_range(10, 15); > + /* info is updated by nfc dma engine*/ > + smp_rmb(); > + ret = *info & ECC_COMPLETE; > + } while (!ret); > +} > + > +static int meson_nfc_read_page_sub(struct nand_chip *nand, > + int page, int raw) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + int data_len, info_len; > + int ret; > + > + data_len = mtd->writesize + mtd->oobsize; > + info_len = nand->ecc.steps * PER_INFO_BYTE; > + > + ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRREAD); > + if (ret) > + return ret; > + > + ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, > + data_len, (u8 *)meson_chip->info_buf, > + info_len, DMA_FROM_DEVICE); > + if (ret) > + return ret; > + > + meson_nfc_cmd_seed(nfc, page); > + meson_nfc_cmd_access(nand, raw, DIRREAD); > + ret = meson_nfc_wait_dma_finish(nfc); > + meson_nfc_check_ecc_pages_valid(nfc, nand, raw); > + > + meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_FROM_DEVICE); > + > + return ret; > +} > + > +static int meson_nfc_read_page_raw(struct nand_chip *nand, u8 *buf, > + int oob_required, int page) > +{ > + u8 *oob_buf = nand->oob_poi; > + int ret; > + > + ret = meson_nfc_read_page_sub(nand, page, 1); > + if (ret) > + return ret; > + > + meson_nfc_get_data_oob(nand, buf, oob_buf); > + > + return 0; > +} > + > +static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, > + int oob_required, int page) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + u8 *oob_buf = nand->oob_poi; > + int ret; > + > + ret = meson_nfc_read_page_sub(nand, page, 0); > + if (ret) > + return ret; > + > + meson_nfc_get_user_byte(nand, oob_buf); > + > + ret = meson_nfc_ecc_correct(nand); > + if (ret == ECC_CHECK_RETURN_FF) { > + if (buf) > + memset(buf, 0xff, mtd->writesize); > + > + memset(oob_buf, 0xff, mtd->oobsize); > + return 0; > + } > + > + if (buf && buf != meson_chip->data_buf) > + memcpy(buf, meson_chip->data_buf, mtd->writesize); > + > + return ret; > +} > + > +static int meson_nfc_read_oob_raw(struct nand_chip *nand, int page) > +{ > + return meson_nfc_read_page_raw(nand, NULL, 1, page); > +} > + > +static int meson_nfc_read_oob(struct nand_chip *nand, int page) > +{ > + return meson_nfc_read_page_hwecc(nand, NULL, 1, page); > +} > + > +void * > +meson_nand_op_get_dma_safe_input_buf(const struct nand_op_instr *instr) > +{ > + if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR)) > + return NULL; > + if (virt_addr_valid(instr->ctx.data.buf.in) && > + !object_is_on_stack(instr->ctx.data.buf.in)) > + return instr->ctx.data.buf.in; > + > + return kzalloc(instr->ctx.data.len, GFP_KERNEL); I think allocating memory and using it without ever testing the allocation succeeded is wrong. You do that in many places. I would like to see allocations properly handled. > +} > + > +void > +meson_nand_op_put_dma_safe_input_buf(const struct nand_op_instr *instr, > + void *buf) > +{ > + if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR) || > + WARN_ON(!buf)) > + return; > + if (buf == instr->ctx.data.buf.in) > + return; > + > + memcpy(instr->ctx.data.buf.in, buf, instr->ctx.data.len); > + kfree(buf); > +} > + > +const void * > +meson_nand_op_get_dma_safe_output_buf(const struct nand_op_instr *instr) > +{ > + if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR)) > + return NULL; > + > + if (virt_addr_valid(instr->ctx.data.buf.out) && > + !object_is_on_stack(instr->ctx.data.buf.out)) Can you please create helpers for that? I guess it will help removing these checks once the core will have a DMA-safe approach. > + return instr->ctx.data.buf.out; > + > + return kmemdup(instr->ctx.data.buf.out, > + instr->ctx.data.len, GFP_KERNEL); > +} > + > +void > +meson_nand_op_put_dma_safe_output_buf(const struct nand_op_instr *instr, > + const void *buf) > +{ > + if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR) || > + WARN_ON(!buf)) > + return; > + > + if (buf != instr->ctx.data.buf.out) > + kfree(buf); > +} > + > +static int meson_nfc_exec_op(struct nand_chip *nand, > + const struct nand_operation *op, bool check_only) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + const struct nand_op_instr *instr = NULL; > + void *buf; > + u32 op_id, delay_idle, cmd; > + int i; > + > + for (op_id = 0; op_id < op->ninstrs; op_id++) { > + instr = &op->instrs[op_id]; > + delay_idle = DIV_ROUND_UP(PSEC_TO_NSEC(instr->delay_ns), > + meson_chip->level1_divider * > + NFC_CLK_CYCLE); > + switch (instr->type) { > + case NAND_OP_CMD_INSTR: > + cmd = nfc->param.chip_select | NFC_CMD_CLE; > + cmd |= instr->ctx.cmd.opcode & 0xff; > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + meson_nfc_cmd_idle(nfc, delay_idle); > + break; > + > + case NAND_OP_ADDR_INSTR: > + for (i = 0; i < instr->ctx.addr.naddrs; i++) { > + cmd = nfc->param.chip_select | NFC_CMD_ALE; > + cmd |= instr->ctx.addr.addrs[i] & 0xff; > + writel(cmd, nfc->reg_base + NFC_REG_CMD); > + } > + meson_nfc_cmd_idle(nfc, delay_idle); > + break; > + > + case NAND_OP_DATA_IN_INSTR: > + buf = meson_nand_op_get_dma_safe_input_buf(instr); > + meson_nfc_read_buf(nand, buf, > + instr->ctx.data.len); > + meson_nand_op_put_dma_safe_input_buf(instr, buf); > + break; > + > + case NAND_OP_DATA_OUT_INSTR: > + buf = > + (void *)meson_nand_op_get_dma_safe_output_buf(instr); > + meson_nfc_write_buf(nand, buf, > + instr->ctx.data.len); > + meson_nand_op_put_dma_safe_output_buf(instr, buf); > + break; > + > + case NAND_OP_WAITRDY_INSTR: > + meson_nfc_queue_rb(nfc, instr->ctx.waitrdy.timeout_ms); > + if (instr->delay_ns) > + meson_nfc_cmd_idle(nfc, delay_idle); > + break; > + } > + } > + meson_nfc_wait_cmd_finish(nfc, 1000); > + return 0; > +} > + > +static int meson_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 = 2 + (section * (2 + nand->ecc.bytes)); > + oobregion->length = nand->ecc.bytes; > + > + return 0; > +} > + > +static int meson_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 = section * (2 + nand->ecc.bytes); > + oobregion->length = 2; > + > + return 0; > +} > + > +static const struct mtd_ooblayout_ops meson_ooblayout_ops = { > + .ecc = meson_ooblayout_ecc, > + .free = meson_ooblayout_free, > +}; > + > +static int meson_nfc_clk_init(struct meson_nfc *nfc) > +{ > + int ret; > + > + /* request core clock */ > + nfc->core_clk = devm_clk_get(nfc->dev, "core"); > + if (IS_ERR(nfc->core_clk)) { > + dev_err(nfc->dev, "failed to get core clk\n"); > + return PTR_ERR(nfc->core_clk); > + } > + > + nfc->device_clk = devm_clk_get(nfc->dev, "device"); > + if (IS_ERR(nfc->device_clk)) { > + dev_err(nfc->dev, "failed to get device clk\n"); > + return PTR_ERR(nfc->device_clk); > + } > + > + nfc->phase_tx = devm_clk_get(nfc->dev, "tx"); > + if (IS_ERR(nfc->phase_tx)) { > + dev_err(nfc->dev, "failed to get tx clk\n"); > + return PTR_ERR(nfc->phase_tx); > + } > + > + nfc->phase_rx = devm_clk_get(nfc->dev, "rx"); > + if (IS_ERR(nfc->phase_rx)) { > + dev_err(nfc->dev, "failed to get rx clk\n"); > + return PTR_ERR(nfc->phase_rx); > + } > + > + /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ > + regmap_update_bits(nfc->reg_clk, > + 0, CLK_SELECT_NAND, CLK_SELECT_NAND); > + > + ret = clk_prepare_enable(nfc->core_clk); > + if (ret) { > + dev_err(nfc->dev, "failed to enable core clk\n"); > + return ret; > + } > + > + ret = clk_prepare_enable(nfc->device_clk); > + if (ret) { > + dev_err(nfc->dev, "failed to enable device clk\n"); > + clk_disable_unprepare(nfc->core_clk); > + return ret; > + } > + > + ret = clk_prepare_enable(nfc->phase_tx); > + if (ret) { > + dev_err(nfc->dev, "failed to enable tx clk\n"); > + clk_disable_unprepare(nfc->core_clk); > + clk_disable_unprepare(nfc->device_clk); > + return ret; > + } > + > + ret = clk_prepare_enable(nfc->phase_rx); > + if (ret) { > + dev_err(nfc->dev, "failed to enable rx clk\n"); > + clk_disable_unprepare(nfc->core_clk); > + clk_disable_unprepare(nfc->device_clk); > + clk_disable_unprepare(nfc->phase_tx); This error case is a good candidate to a goto statement. > + return ret; > + } > + > + ret = clk_set_rate(nfc->device_clk, 24000000); > + if (ret) > + return ret; > + > + return 0; > +} > + > +static void meson_nfc_disable_clk(struct meson_nfc *nfc) > +{ > + clk_disable_unprepare(nfc->phase_rx); > + clk_disable_unprepare(nfc->phase_tx); > + clk_disable_unprepare(nfc->device_clk); > + clk_disable_unprepare(nfc->core_clk); > +} > + > +static void meson_nfc_free_buffer(struct nand_chip *nand) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + > + kfree(meson_chip->info_buf); > + kfree(meson_chip->data_buf); > +} > + > +static int meson_chip_buffer_init(struct nand_chip *nand) > +{ > + struct mtd_info *mtd = nand_to_mtd(nand); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + u32 page_bytes, info_bytes, nsectors; > + > + nsectors = mtd->writesize / nand->ecc.size; > + > + page_bytes = mtd->writesize + mtd->oobsize; > + info_bytes = nsectors * PER_INFO_BYTE; > + > + meson_chip->data_buf = kmalloc(page_bytes, GFP_KERNEL); > + if (!meson_chip->data_buf) > + return -ENOMEM; > + > + meson_chip->info_buf = kmalloc(info_bytes, GFP_KERNEL); > + if (!meson_chip->info_buf) { > + kfree(meson_chip->data_buf); > + return -ENOMEM; > + } > + > + return 0; > +} > + > +static > +int meson_nfc_setup_data_interface(struct nand_chip *nand, int csline, > + const struct nand_data_interface *conf) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + const struct nand_sdr_timings *timings; > + u32 div, bt_min, bt_max, tbers_clocks; > + > + timings = nand_get_sdr_timings(conf); > + if (IS_ERR(timings)) > + return -ENOTSUPP; > + > + if (csline == NAND_DATA_IFACE_CHECK_ONLY) > + return 0; > + > + div = DIV_ROUND_UP((timings->tRC_min / 1000), NFC_CLK_CYCLE); > + bt_min = (timings->tREA_max + NFC_DEFAULT_DELAY) / div; > + bt_max = (NFC_DEFAULT_DELAY + timings->tRHOH_min + > + timings->tRC_min / 2) / div; > + > + meson_chip->twb = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tWB_max), > + div * NFC_CLK_CYCLE); > + meson_chip->tadl = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tADL_min), > + div * NFC_CLK_CYCLE); > + tbers_clocks = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tBERS_max), > + div * NFC_CLK_CYCLE); > + meson_chip->tbers_max = ilog2(tbers_clocks); > + if (!is_power_of_2(tbers_clocks)) > + meson_chip->tbers_max++; > + > + bt_min = DIV_ROUND_UP(bt_min, 1000); > + bt_max = DIV_ROUND_UP(bt_max, 1000); > + > + if (bt_max < bt_min) > + return -EINVAL; > + > + meson_chip->level1_divider = div; > + meson_chip->clk_rate = 1000000000 / meson_chip->level1_divider; > + meson_chip->bus_timing = (bt_min + bt_max) / 2 + 1; > + > + return 0; > +} > + > +static int meson_nand_bch_mode(struct nand_chip *nand) > +{ > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + struct meson_nand_ecc meson_ecc[] = { > + MESON_ECC_DATA(NFC_ECC_BCH8_1K, 8), > + MESON_ECC_DATA(NFC_ECC_BCH24_1K, 24), > + MESON_ECC_DATA(NFC_ECC_BCH30_1K, 30), > + MESON_ECC_DATA(NFC_ECC_BCH40_1K, 40), > + MESON_ECC_DATA(NFC_ECC_BCH50_1K, 50), > + MESON_ECC_DATA(NFC_ECC_BCH60_1K, 60), > + }; Maybe this array could be static? > + int i; > + > + if (nand->ecc.strength > 60 || nand->ecc.strength < 8) > + return -EINVAL; > + > + for (i = 0; i < sizeof(meson_ecc); i++) { > + if (meson_ecc[i].strength == nand->ecc.strength) { > + meson_chip->bch_mode = meson_ecc[i].bch; > + return 0; > + } > + } > + > + return -EINVAL; > +} > + > +static int meson_nand_attach_chip(struct nand_chip *nand) > +{ > + struct meson_nfc *nfc = nand_get_controller_data(nand); > + struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); > + struct mtd_info *mtd = nand_to_mtd(nand); > + int nsectors = mtd->writesize / 1024; > + int ret; > + > + if (!mtd->name) { > + mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL, > + "%s:nand%d", > + dev_name(nfc->dev), > + meson_chip->sels[0]); > + if (!mtd->name) > + return -ENOMEM; > + } > + > + if (nand->bbt_options & NAND_BBT_USE_FLASH) > + nand->bbt_options |= NAND_BBT_NO_OOB; > + > + nand->options |= NAND_NO_SUBPAGE_WRITE; > + > + ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, > + mtd->oobsize - 2 * nsectors); > + if (ret) { > + dev_err(nfc->dev, "failed to ecc init\n"); > + return -EINVAL; > + } > + > + ret = meson_nand_bch_mode(nand); > + if (ret) > + return -EINVAL; > + > + nand->ecc.mode = NAND_ECC_HW; > + nand->ecc.write_page_raw = meson_nfc_write_page_raw; > + nand->ecc.write_page = meson_nfc_write_page_hwecc; > + nand->ecc.write_oob_raw = nand_write_oob_std; > + nand->ecc.write_oob = nand_write_oob_std; > + > + nand->ecc.read_page_raw = meson_nfc_read_page_raw; > + nand->ecc.read_page = meson_nfc_read_page_hwecc; > + nand->ecc.read_oob_raw = meson_nfc_read_oob_raw; > + nand->ecc.read_oob = meson_nfc_read_oob; > + > + if (nand->options & NAND_BUSWIDTH_16) { > + dev_err(nfc->dev, "16bits buswidth not supported"); > + return -EINVAL; > + } > + meson_chip_buffer_init(nand); > + if (ret) > + return -ENOMEM; > + > + return ret; > +} > + > +static const struct nand_controller_ops meson_nand_controller_ops = { > + .attach_chip = meson_nand_attach_chip, Don't you need a ->detach_chip hook to free data_buf/info_buf buffers? > +}; > + > +static int > +meson_nfc_nand_chip_init(struct device *dev, > + struct meson_nfc *nfc, struct device_node *np) > +{ > + struct meson_nfc_nand_chip *meson_chip; > + struct nand_chip *nand; > + struct mtd_info *mtd; > + int ret, i; > + u32 tmp, nsels; > + > + if (!of_get_property(np, "reg", &nsels)) > + return -EINVAL; > + > + nsels /= sizeof(u32); > + if (!nsels || nsels > MAX_CE_NUM) { > + dev_err(dev, "invalid reg property size\n"); > + return -EINVAL; > + } > + > + meson_chip = devm_kzalloc(dev, > + sizeof(*meson_chip) + (nsels * sizeof(u8)), > + GFP_KERNEL); > + if (!meson_chip) > + return -ENOMEM; > + > + meson_chip->nsels = nsels; > + > + for (i = 0; i < nsels; i++) { > + ret = of_property_read_u32_index(np, "reg", i, &tmp); > + if (ret) { > + dev_err(dev, "could not retrieve reg property: %d\n", > + ret); > + return ret; > + } > + > + if (test_and_set_bit(tmp, &nfc->assigned_cs)) { > + dev_err(dev, "CS %d already assigned\n", tmp); > + return -EINVAL; > + } > + } > + > + nand = &meson_chip->nand; > + nand->controller = &nfc->controller; > + nand->controller->ops = &meson_nand_controller_ops; > + nand_set_flash_node(nand, np); > + nand_set_controller_data(nand, nfc); > + > + nand->options |= NAND_USE_BOUNCE_BUFFER; > + nand->select_chip = meson_nfc_select_chip; > + nand->exec_op = meson_nfc_exec_op; > + nand->setup_data_interface = meson_nfc_setup_data_interface; > + mtd = nand_to_mtd(nand); > + mtd->owner = THIS_MODULE; > + mtd->dev.parent = dev; > + > + ret = nand_scan(nand, nsels); > + if (ret) > + return ret; > + > + ret = mtd_device_register(mtd, NULL, 0); > + if (ret) { > + dev_err(dev, "failed to register mtd device: %d\n", ret); > + nand_cleanup(nand); > + return ret; > + } > + > + list_add_tail(&meson_chip->node, &nfc->chips); > + > + return 0; > +} > + > +static int meson_nfc_nand_chip_cleanup(struct meson_nfc *nfc) > +{ > + struct meson_nfc_nand_chip *meson_chip; > + struct mtd_info *mtd; > + int ret; > + > + while (!list_empty(&nfc->chips)) { > + meson_chip = list_first_entry(&nfc->chips, > + struct meson_nfc_nand_chip, node); > + mtd = nand_to_mtd(&meson_chip->nand); > + ret = mtd_device_unregister(mtd); > + if (ret) > + return ret; > + > + meson_nfc_free_buffer(&meson_chip->nand); > + nand_cleanup(&meson_chip->nand); > + list_del(&meson_chip->node); > + } > + > + return 0; > +} > + > +static int meson_nfc_nand_chips_init(struct device *dev, > + struct meson_nfc *nfc) > +{ > + struct device_node *np = dev->of_node; > + struct device_node *nand_np; > + int ret; > + > + for_each_child_of_node(np, nand_np) { > + ret = meson_nfc_nand_chip_init(dev, nfc, nand_np); > + if (ret) { > + meson_nfc_nand_chip_cleanup(nfc); > + return ret; > + } > + } > + > + return 0; > +} > + > +static irqreturn_t meson_nfc_irq(int irq, void *id) > +{ > + struct meson_nfc *nfc = id; > + u32 cfg; > + > + cfg = readl(nfc->reg_base + NFC_REG_CFG); > + if (!(cfg & NFC_RB_IRQ_EN)) > + return IRQ_NONE; > + > + cfg &= ~(NFC_RB_IRQ_EN); > + writel(cfg, nfc->reg_base + NFC_REG_CFG); > + > + complete(&nfc->completion); > + return IRQ_HANDLED; > +} > + > +static const struct meson_nfc_data meson_gxl_data = { > + .ecc_caps = &meson_gxl_ecc_caps, > +}; > + > +static const struct meson_nfc_data meson_axg_data = { > + .ecc_caps = &meson_axg_ecc_caps, > +}; > + > +static const struct of_device_id meson_nfc_id_table[] = { > + { > + .compatible = "amlogic,meson-gxl-nfc", > + .data = &meson_gxl_data, > + }, { > + .compatible = "amlogic,meson-axg-nfc", > + .data = &meson_axg_data, > + }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, meson_nfc_id_table); > + > +static int meson_nfc_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct meson_nfc *nfc; > + struct resource *res; > + int ret, irq; > + > + nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); > + if (!nfc) > + return -ENOMEM; > + > + nfc->data = of_device_get_match_data(&pdev->dev); > + if (!nfc->data) > + return -ENODEV; > + > + nand_controller_init(&nfc->controller); > + INIT_LIST_HEAD(&nfc->chips); > + > + nfc->dev = dev; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + nfc->reg_base = devm_ioremap_resource(dev, res); > + if (IS_ERR(nfc->reg_base)) > + return PTR_ERR(nfc->reg_base); > + > + nfc->reg_clk = > + syscon_regmap_lookup_by_phandle(dev->of_node, > + "amlogic,mmc-syscon"); > + if (IS_ERR(nfc->reg_clk)) { > + dev_err(dev, "Failed to lookup clock base\n"); > + return PTR_ERR(nfc->reg_clk); > + } > + > + irq = platform_get_irq(pdev, 0); > + if (irq < 0) { > + dev_err(dev, "no nfi irq resource\n"); > + return -EINVAL; > + } > + > + ret = meson_nfc_clk_init(nfc); > + if (ret) { > + dev_err(dev, "failed to initialize nand clk\n"); > + goto err; Useless goto, a return would be enough. > + } > + > + writel(0, nfc->reg_base + NFC_REG_CFG); > + ret = devm_request_irq(dev, irq, meson_nfc_irq, 0, dev_name(dev), nfc); > + if (ret) { > + dev_err(dev, "failed to request nfi irq\n"); > + ret = -EINVAL; > + goto err_clk; > + } > + > + ret = dma_set_mask(dev, DMA_BIT_MASK(32)); > + if (ret) { > + dev_err(dev, "failed to set dma mask\n"); Nit: I prefer when acronyms are upper case in plain English (DMA, NAND, IRQ, etc). > + goto err_clk; > + } > + > + platform_set_drvdata(pdev, nfc); > + > + ret = meson_nfc_nand_chips_init(dev, nfc); > + if (ret) { > + dev_err(dev, "failed to init nand chips\n"); > + goto err_clk; > + } > + > + return 0; > + > +err_clk: > + meson_nfc_disable_clk(nfc); > +err: This goto can be removed. > + return ret; > +} > + > +static int meson_nfc_remove(struct platform_device *pdev) > +{ > + struct meson_nfc *nfc = platform_get_drvdata(pdev); > + int ret; > + > + ret = meson_nfc_nand_chip_cleanup(nfc); > + if (ret) > + return ret; > + > + meson_nfc_disable_clk(nfc); > + > + platform_set_drvdata(pdev, NULL); > + > + return 0; > +} > + > +static struct platform_driver meson_nfc_driver = { > + .probe = meson_nfc_probe, > + .remove = meson_nfc_remove, > + .driver = { > + .name = "meson-nand", > + .of_match_table = meson_nfc_id_table, > + }, > +}; > +module_platform_driver(meson_nfc_driver); > + > +MODULE_LICENSE("Dual MIT/GPL"); > +MODULE_AUTHOR("Liang Yang "); > +MODULE_DESCRIPTION("Amlogic's Meson NAND Flash Controller driver"); Thanks, Miquèl 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=-7.0 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,T_DKIMWL_WL_HIGH,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63DC8C07E85 for ; Fri, 7 Dec 2018 09:25:31 +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 2B90A20838 for ; Fri, 7 Dec 2018 09:25:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="JidGBXJ5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2B90A20838 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bootlin.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:MIME-Version:References:In-Reply-To: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=GOPRxpa6iHkStGGSgXJDo3QIcYxMNdf/ksU2M29YLqI=; b=JidGBXJ5qzylwK /1hXsr2g4vOKW+eIOE4GU+waqLVyEWzEWZBgdYas0XJA6lGegxHIgIRxNXbDEXGyy7u/9bh2VSF5m /wvpiR7y22flx4oZLvdfq/2OJjaLEaqpruu9VTU+voF+g99Zaq8pURIF5ewUqPVPm8Yr1Vmnt3+UB MhslDkHHywuaU+JA5yWYa2THXXvrOJ4MiFGvYQSk0KT9IUF6MNFnNWUH4/5l5UeRvoazPAhNuNnn+ nGpYVJq10oT/NuLfYvvnmZ3Un9a3shq0JAl0fUl1OeVM0limctj3CiZffrRISc8hQguMqzzhTqkwi kGfMoYzRRvLIhO+cd3LA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCNx-0000BL-Kr; Fri, 07 Dec 2018 09:25:25 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCNr-00006Y-6D; Fri, 07 Dec 2018 09:25:22 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 8569320834; Fri, 7 Dec 2018 10:25:07 +0100 (CET) Received: from xps13 (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id EC03720701; Fri, 7 Dec 2018 10:24:56 +0100 (CET) Date: Fri, 7 Dec 2018 10:24:56 +0100 From: Miquel Raynal To: Jianxin Pan Subject: Re: [PATCH v7 2/2] mtd: rawnand: meson: add support for Amlogic NAND flash controller Message-ID: <20181207102456.1dc67e07@xps13> In-Reply-To: <1542386439-30166-3-git-send-email-jianxin.pan@amlogic.com> References: <1542386439-30166-1-git-send-email-jianxin.pan@amlogic.com> <1542386439-30166-3-git-send-email-jianxin.pan@amlogic.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.1 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012519_652192_E666D93C X-CRM114-Status: GOOD ( 26.17 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Hanjie Lin , Victor Wan , Marek Vasut , Martin Blumenstingl , Richard Weinberger , Neil Armstrong , Yixun Lan , linux-kernel@vger.kernel.org, Boris Brezillon , Jian Hu , Liang Yang , linux-mtd@lists.infradead.org, Kevin Hilman , Carlo Caione , linux-amlogic@lists.infradead.org, Brian Norris , David Woodhouse , linux-arm-kernel@lists.infradead.org, Jerome Brunet 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 SGkgSmlhbnhpbiwKCkxvb2tzIGdvb2QgdG8gbWUgb3ZlcmFsbCwgYSBmZXcgY29tbWVudHMgaW5s aW5lLgoKSmlhbnhpbiBQYW4gPGppYW54aW4ucGFuQGFtbG9naWMuY29tPiB3cm90ZSBvbiBTYXQs IDE3IE5vdiAyMDE4CjAwOjQwOjM4ICswODAwOgoKPiBGcm9tOiBMaWFuZyBZYW5nIDxsaWFuZy55 YW5nQGFtbG9naWMuY29tPgo+IAo+IEFkZCBpbml0aWFsIHN1cHBvcnQgZm9yIHRoZSBBbWxvZ2lj IE5BTkQgZmxhc2ggY29udHJvbGxlciB3aGljaCBmb3VuZAo+IGluIHRoZSBNZXNvbi1HWEJCL0dY TC9BWEcgU29Dcy4KPiAKPiBTaWduZWQtb2ZmLWJ5OiBMaWFuZyBZYW5nIDxsaWFuZy55YW5nQGFt bG9naWMuY29tPgo+IFNpZ25lZC1vZmYtYnk6IFlpeHVuIExhbiA8eWl4dW4ubGFuQGFtbG9naWMu Y29tPgo+IFNpZ25lZC1vZmYtYnk6IEppYW54aW4gUGFuIDxqaWFueGluLnBhbkBhbWxvZ2ljLmNv bT4KPiAtLS0KPiAgZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZyAgICAgIHwgICAxMCArCj4g IGRyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlICAgICB8ICAgIDEgKwo+ICBkcml2ZXJzL210 ZC9uYW5kL3Jhdy9tZXNvbl9uYW5kLmMgfCAxNDE3ICsrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysKPiAgMyBmaWxlcyBjaGFuZ2VkLCAxNDI4IGluc2VydGlvbnMoKykKPiAgY3Jl YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbXRkL25hbmQvcmF3L21lc29uX25hbmQuYwo+IAo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnIGIvZHJpdmVycy9tdGQvbmFu ZC9yYXcvS2NvbmZpZwo+IGluZGV4IGM3ZWZjMzEuLjIyM2IwNDEgMTAwNjQ0Cj4gLS0tIGEvZHJp dmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L0tj b25maWcKPiBAQCAtNTQxLDQgKzU0MSwxNCBAQCBjb25maWcgTVREX05BTkRfVEVHUkEKPiAgCSAg aXMgc3VwcG9ydGVkLiBFeHRyYSBPT0IgYnl0ZXMgd2hlbiB1c2luZyBIVyBFQ0MgYXJlIGN1cnJl bnRseQo+ICAJICBub3Qgc3VwcG9ydGVkLgo+ICAKPiArY29uZmlnIE1URF9OQU5EX01FU09OCj4g Kwl0cmlzdGF0ZSAiU3VwcG9ydCBmb3IgTkFORCBjb250cm9sbGVyIG9uIEFtbG9naWMncyBNZXNv biBTb0NzIgo+ICsJZGVwZW5kcyBvbiBBUkNIX01FU09OIHx8IENPTVBJTEVfVEVTVAo+ICsJZGVw ZW5kcyBvbiBDT01NT05fQ0xLX0FNTE9HSUMKPiArCXNlbGVjdCBDT01NT05fQ0xLX1JFR01BUF9N RVNPTgo+ICsJc2VsZWN0IE1GRF9TWVNDT04KPiArCWhlbHAKPiArCSAgRW5hYmxlcyBzdXBwb3J0 IGZvciBOQU5EIGNvbnRyb2xsZXIgb24gQW1sb2dpYydzIE1lc29uIFNvQ3MuCj4gKwkgIFRoaXMg Y29udHJvbGxlciBpcyBmb3VuZCBvbiBNZXNvbiBHWEJCLCBHWEwsIEFYRyBTb0NzLgo+ICsKPiAg ZW5kaWYgIyBNVERfTkFORAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtl ZmlsZSBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4gaW5kZXggNTcxNTliMy4uYTJj YzJmZSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZQo+ICsrKyBi L2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4gQEAgLTU2LDYgKzU2LDcgQEAgb2JqLSQo Q09ORklHX01URF9OQU5EX0JSQ01OQU5EKQkJKz0gYnJjbW5hbmQvCj4gIG9iai0kKENPTkZJR19N VERfTkFORF9RQ09NKQkJKz0gcWNvbV9uYW5kYy5vCj4gIG9iai0kKENPTkZJR19NVERfTkFORF9N VEspCQkrPSBtdGtfZWNjLm8gbXRrX25hbmQubwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfVEVH UkEpCQkrPSB0ZWdyYV9uYW5kLm8KPiArb2JqLSQoQ09ORklHX01URF9OQU5EX01FU09OKQkJKz0g bWVzb25fbmFuZC5vCj4gIAo+ICBuYW5kLW9ianMgOj0gbmFuZF9iYXNlLm8gbmFuZF9sZWdhY3ku byBuYW5kX2JidC5vIG5hbmRfdGltaW5ncy5vIG5hbmRfaWRzLm8KPiAgbmFuZC1vYmpzICs9IG5h bmRfb25maS5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQvcmF3L21lc29uX25hbmQu YyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L21lc29uX25hbmQuYwo+IG5ldyBmaWxlIG1vZGUgMTAw NjQ0Cj4gaW5kZXggMDAwMDAwMC4uYzU2NjYzNgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2 ZXJzL210ZC9uYW5kL3Jhdy9tZXNvbl9uYW5kLmMKPiBAQCAtMCwwICsxLDE0MTcgQEAKPiArLy8g U1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IChHUEwtMi4wKyBPUiBNSVQpCj4gKy8qCj4gKyAqIEFt bG9naWMgTWVzb24gTmFuZCBGbGFzaCBDb250cm9sbGVyIERyaXZlcgo+ICsgKgo+ICsgKiBDb3B5 cmlnaHQgKGMpIDIwMTggQW1sb2dpYywgaW5jLgo+ICsgKiBBdXRob3I6IExpYW5nIFlhbmcgPGxp YW5nLnlhbmdAYW1sb2dpYy5jb20+Cj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRm b3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9tdGQvcmF3bmFuZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbXRkL210ZC5oPgo+ ICsjaW5jbHVkZSA8bGludXgvbWZkL3N5c2Nvbi5oPgo+ICsjaW5jbHVkZSA8bGludXgvcmVnbWFw Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KPiArI2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4K PiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPgo+ICsKPiArI2RlZmluZSBORkNfUkVHX0NN RAkJMHgwMAo+ICsjZGVmaW5lIE5GQ19DTURfRFJECQkoMHg4IDw8IDE0KQo+ICsjZGVmaW5lIE5G Q19DTURfSURMRQkJKDB4YyA8PCAxNCkKPiArI2RlZmluZSBORkNfQ01EX0RXUgkJKDB4NCA8PCAx NCkKPiArI2RlZmluZSBORkNfQ01EX0NMRQkJKDB4NSA8PCAxNCkKPiArI2RlZmluZSBORkNfQ01E X0FMRQkJKDB4NiA8PCAxNCkKPiArI2RlZmluZSBORkNfQ01EX0FETAkJKCgwIDw8IDE2KSB8ICgz IDw8IDIwKSkKPiArI2RlZmluZSBORkNfQ01EX0FESAkJKCgxIDw8IDE2KSB8ICgzIDw8IDIwKSkK PiArI2RlZmluZSBORkNfQ01EX0FJTAkJKCgyIDw8IDE2KSB8ICgzIDw8IDIwKSkKPiArI2RlZmlu ZSBORkNfQ01EX0FJSAkJKCgzIDw8IDE2KSB8ICgzIDw8IDIwKSkKPiArI2RlZmluZSBORkNfQ01E X1NFRUQJCSgoOCA8PCAxNikgfCAoMyA8PCAyMCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9NMk4JCSgo MCA8PCAxNykgfCAoMiA8PCAyMCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9OMk0JCSgoMSA8PCAxNykg fCAoMiA8PCAyMCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9SQgkJQklUKDIwKQo+ICsjZGVmaW5lIE5G Q19DTURfSU82CQkoKDB4YiA8PCAxMCkgfCAoMSA8PCAxOCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9T Q1JBTUJMRVJfRU5BQkxFCUJJVCgxOSkKPiArI2RlZmluZSBORkNfQ01EX1JCX0lOVAkJQklUKDE0 KQo+ICsKPiArI2RlZmluZSBORkNfQ01EX0dFVF9TSVpFKHgpCSgoKHgpID4+IDIyKSAmIEdFTk1B U0soNCwgMCkpCj4gKwo+ICsjZGVmaW5lIE5GQ19SRUdfQ0ZHCQkweDA0Cj4gKyNkZWZpbmUgTkZD X1JFR19EQURSCQkweDA4Cj4gKyNkZWZpbmUgTkZDX1JFR19JQURSCQkweDBjCj4gKyNkZWZpbmUg TkZDX1JFR19CVUYJCTB4MTAKPiArI2RlZmluZSBORkNfUkVHX0lORk8JCTB4MTQKPiArI2RlZmlu ZSBORkNfUkVHX0RDCQkweDE4Cj4gKyNkZWZpbmUgTkZDX1JFR19BRFIJCTB4MWMKPiArI2RlZmlu ZSBORkNfUkVHX0RMCQkweDIwCj4gKyNkZWZpbmUgTkZDX1JFR19ESAkJMHgyNAo+ICsjZGVmaW5l IE5GQ19SRUdfQ0FEUgkJMHgyOAo+ICsjZGVmaW5lIE5GQ19SRUdfU0FEUgkJMHgyYwo+ICsjZGVm aW5lIE5GQ19SRUdfUElOUwkJMHgzMAo+ICsjZGVmaW5lIE5GQ19SRUdfVkVSCQkweDM4Cj4gKwo+ ICsjZGVmaW5lIE5GQ19SQl9JUlFfRU4JCUJJVCgyMSkKPiArI2RlZmluZSBORkNfSU5UX01BU0sJ CSgzIDw8IDIwKQo+ICsKPiArI2RlZmluZSBDTURSV0dFTihjbWRfZGlyLCByYW4sIGJjaCwgc2hv cnRfbW9kZSwgcGFnZV9zaXplLCBwYWdlcykJXAo+ICsJKAkJCQkJCQkJXAo+ICsJCShjbWRfZGly KQkJCXwJCQlcCj4gKwkJKChyYW4pIDw8IDE5KQkJCXwJCQlcCj4gKwkJKChiY2gpIDw8IDE0KQkJ CXwJCQlcCj4gKwkJKChzaG9ydF9tb2RlKSA8PCAxMykJCXwJCQlcCj4gKwkJKCgocGFnZV9zaXpl KSAmIDB4N2YpIDw8IDYpCXwJCQlcCj4gKwkJKChwYWdlcykgJiAweDNmKQkJCQkJXAo+ICsJKQo+ ICsKPiArI2RlZmluZSBHRU5DTUREQUREUkwoYWRsLCBhZGRyKQkJKChhZGwpIHwgKChhZGRyKSAm IDB4ZmZmZikpCj4gKyNkZWZpbmUgR0VOQ01EREFERFJIKGFkaCwgYWRkcikJCSgoYWRoKSB8ICgo KGFkZHIpID4+IDE2KSAmIDB4ZmZmZikpCj4gKyNkZWZpbmUgR0VOQ01ESUFERFJMKGFpbCwgYWRk cikJCSgoYWlsKSB8ICgoYWRkcikgJiAweGZmZmYpKQo+ICsjZGVmaW5lIEdFTkNNRElBRERSSChh aWgsIGFkZHIpCQkoKGFpaCkgfCAoKChhZGRyKSA+PiAxNikgJiAweGZmZmYpKQo+ICsKPiArI2Rl ZmluZSBSQl9TVEEoeCkJCSgxIDw8ICgyNiArICh4KSkpCj4gKyNkZWZpbmUgRE1BX0RJUihkaXIp CQkoKGRpcikgPyBORkNfQ01EX04yTSA6IE5GQ19DTURfTTJOKQo+ICsKPiArI2RlZmluZSBFQ0Nf Q0hFQ0tfUkVUVVJOX0ZGCSgtMSkKPiArCj4gKyNkZWZpbmUgTkFORF9DRTAJCSgweGUgPDwgMTAp Cj4gKyNkZWZpbmUgTkFORF9DRTEJCSgweGQgPDwgMTApCj4gKwo+ICsjZGVmaW5lIERNQV9CVVNZ X1RJTUVPVVQJMHgxMDAwMDAKPiArI2RlZmluZSBDTURfRklGT19FTVBUWV9USU1FT1VUCTEwMDAK PiArCj4gKyNkZWZpbmUgTUFYX0NFX05VTQkJMgo+ICsKPiArLyogZU1NQyBjbG9jayByZWdpc3Rl ciwgbWlzYyBjb250cm9sICovCj4gKyNkZWZpbmUgU0RfRU1NQ19DTE9DSwkJMHgwMAo+ICsjZGVm aW5lIENMS19BTFdBWVNfT04JCUJJVCgyOCkKPiArI2RlZmluZSBDTEtfU0VMRUNUX05BTkQJCUJJ VCgzMSkKPiArI2RlZmluZSBDTEtfRElWX01BU0sJCUdFTk1BU0soNSwgMCkKPiArCj4gKyNkZWZp bmUgTkZDX0NMS19DWUNMRQkJNgo+ICsKPiArLyogbmFuZCBmbGFzaCBjb250cm9sbGVyIGRlbGF5 IDMgbnMgKi8KPiArI2RlZmluZSBORkNfREVGQVVMVF9ERUxBWQkzMDAwCj4gKwo+ICsjZGVmaW5l IE1BWF9FQ0NfSU5ERVgJCTEwCj4gKwo+ICsjZGVmaW5lIE1VWF9DTEtfTlVNX1BBUkVOVFMJMgo+ ICsKPiArI2RlZmluZSBST1dfQURERVIocGFnZSwgaW5kZXgpCSgoKHBhZ2UpID4+ICg4ICogKGlu ZGV4KSkpICYgMHhmZikKPiArI2RlZmluZSBNQVhfQ1lDTEVfQUREUlMJCTUKPiArI2RlZmluZSBE SVJSRUFECQkJMQo+ICsjZGVmaW5lIERJUldSSVRFCQkwCj4gKwo+ICsjZGVmaW5lIEVDQ19QQVJJ VFlfQkNIOF81MTJCCTE0Cj4gKwo+ICsjZGVmaW5lIFBFUl9JTkZPX0JZVEUJCTgKPiArCj4gKyNk ZWZpbmUgRUNDX0NPTVBMRVRFICAgICAgICAgICAgQklUKDMxKQo+ICsjZGVmaW5lIEVDQ19FUlJf Q05UKHgpCQkoKCh4KSA+PiAyNCkgJiBHRU5NQVNLKDUsIDApKQo+ICsjZGVmaW5lIEVDQ19aRVJP X0NOVCh4KQkJKCgoeCkgPj4gMTYpICYgR0VOTUFTSyg1LCAwKSkKPiArCj4gK3N0cnVjdCBtZXNv bl9uZmNfbmFuZF9jaGlwIHsKPiArCXN0cnVjdCBsaXN0X2hlYWQgbm9kZTsKPiArCXN0cnVjdCBu YW5kX2NoaXAgbmFuZDsKPiArCXVuc2lnbmVkIGxvbmcgY2xrX3JhdGU7Cj4gKwl1bnNpZ25lZCBs b25nIGxldmVsMV9kaXZpZGVyOwo+ICsJdTMyIGJ1c190aW1pbmc7Cj4gKwl1MzIgdHdiOwo+ICsJ dTMyIHRhZGw7Cj4gKwl1MzIgdGJlcnNfbWF4Owo+ICsKPiArCXUzMiBiY2hfbW9kZTsKPiArCXU4 ICpkYXRhX2J1ZjsKPiArCV9fbGU2NCAqaW5mb19idWY7Cj4gKwl1MzIgbnNlbHM7Cj4gKwl1OCBz ZWxzWzBdOwo+ICt9Owo+ICsKPiArc3RydWN0IG1lc29uX25hbmRfZWNjIHsKPiArCXUzMiBiY2g7 Cj4gKwl1MzIgc3RyZW5ndGg7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgbWVzb25fbmZjX2RhdGEgewo+ ICsJY29uc3Qgc3RydWN0IG5hbmRfZWNjX2NhcHMgKmVjY19jYXBzOwo+ICt9Owo+ICsKPiArc3Ry dWN0IG1lc29uX25mY19wYXJhbSB7Cj4gKwl1MzIgY2hpcF9zZWxlY3Q7Cj4gKwl1MzIgcmJfc2Vs ZWN0Owo+ICt9Owo+ICsKPiArc3RydWN0IG5hbmRfcndfY21kIHsKPiArCXUzMiBjbWQwOwo+ICsJ dTMyIGFkZHJzW01BWF9DWUNMRV9BRERSU107Cj4gKwl1MzIgY21kMTsKPiArfTsKPiArCj4gK3N0 cnVjdCBuYW5kX3RpbWluZyB7Cj4gKwl1MzIgdHdiOwo+ICsJdTMyIHRhZGw7Cj4gKwl1MzIgdGJl cnNfbWF4Owo+ICt9Owo+ICsKPiArc3RydWN0IG1lc29uX25mYyB7Cj4gKwlzdHJ1Y3QgbmFuZF9j b250cm9sbGVyIGNvbnRyb2xsZXI7Cj4gKwlzdHJ1Y3QgY2xrICpjb3JlX2NsazsKPiArCXN0cnVj dCBjbGsgKmRldmljZV9jbGs7Cj4gKwlzdHJ1Y3QgY2xrICpwaGFzZV90eDsKPiArCXN0cnVjdCBj bGsgKnBoYXNlX3J4Owo+ICsKPiArCXVuc2lnbmVkIGxvbmcgY2xrX3JhdGU7Cj4gKwl1MzIgYnVz X3RpbWluZzsKPiArCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwl2b2lkIF9faW9tZW0gKnJl Z19iYXNlOwo+ICsJc3RydWN0IHJlZ21hcCAqcmVnX2NsazsKPiArCXN0cnVjdCBjb21wbGV0aW9u IGNvbXBsZXRpb247Cj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIGNoaXBzOwo+ICsJY29uc3Qgc3RydWN0 IG1lc29uX25mY19kYXRhICpkYXRhOwo+ICsJc3RydWN0IG1lc29uX25mY19wYXJhbSBwYXJhbTsK PiArCXN0cnVjdCBuYW5kX3RpbWluZyB0aW1pbmc7Cj4gKwl1bmlvbiB7Cj4gKwkJaW50IGNtZFsz Ml07Cj4gKwkJc3RydWN0IG5hbmRfcndfY21kIHJ3Owo+ICsJfSBjbWRmaWZvOwo+ICsKPiArCWRt YV9hZGRyX3QgZGFkZHI7Cj4gKwlkbWFfYWRkcl90IGlhZGRyOwo+ICsKPiArCXVuc2lnbmVkIGxv bmcgYXNzaWduZWRfY3M7Cj4gK307Cj4gKwo+ICtlbnVtIHsKPiArCU5GQ19FQ0NfQkNIOF8xSwkJ PSAyLAo+ICsJTkZDX0VDQ19CQ0gyNF8xSywKPiArCU5GQ19FQ0NfQkNIMzBfMUssCj4gKwlORkNf RUNDX0JDSDQwXzFLLAo+ICsJTkZDX0VDQ19CQ0g1MF8xSywKPiArCU5GQ19FQ0NfQkNINjBfMUss Cj4gK307Cj4gKwo+ICsjZGVmaW5lIE1FU09OX0VDQ19EQVRBKGIsIHMpCXsgLmJjaCA9IChiKSwJ LnN0cmVuZ3RoID0gKHMpfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uYW5kX2NhbGNfZWNjX2J5 dGVzKGludCBzdGVwX3NpemUsIGludCBzdHJlbmd0aCkKPiArewo+ICsJaW50IGVjY19ieXRlczsK PiArCj4gKwlpZiAoc3RlcF9zaXplID09IDUxMiAmJiBzdHJlbmd0aCA9PSA4KQo+ICsJCXJldHVy biBFQ0NfUEFSSVRZX0JDSDhfNTEyQjsKPiArCj4gKwllY2NfYnl0ZXMgPSBESVZfUk9VTkRfVVAo c3RyZW5ndGggKiBmbHMoc3RlcF9zaXplICogOCksIDgpOwo+ICsJZWNjX2J5dGVzID0gQUxJR04o ZWNjX2J5dGVzLCAyKTsKPiArCj4gKwlyZXR1cm4gZWNjX2J5dGVzOwo+ICt9Cj4gKwo+ICtOQU5E X0VDQ19DQVBTX1NJTkdMRShtZXNvbl9neGxfZWNjX2NhcHMsCj4gKwkJICAgICBtZXNvbl9uYW5k X2NhbGNfZWNjX2J5dGVzLCAxMDI0LCA4LCAyNCwgMzAsIDQwLCA1MCwgNjApOwo+ICtOQU5EX0VD Q19DQVBTX1NJTkdMRShtZXNvbl9heGdfZWNjX2NhcHMsCj4gKwkJICAgICBtZXNvbl9uYW5kX2Nh bGNfZWNjX2J5dGVzLCAxMDI0LCA4KTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgbWVzb25fbmZjX25h bmRfY2hpcCAqdG9fbWVzb25fbmFuZChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kKQo+ICt7Cj4gKwly ZXR1cm4gY29udGFpbmVyX29mKG5hbmQsIHN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwLCBuYW5k KTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbWVzb25fbmZjX3NlbGVjdF9jaGlwKHN0cnVjdCBu YW5kX2NoaXAgKm5hbmQsIGludCBjaGlwKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjX25hbmRf Y2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25f bmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4gKwlpbnQgcmV0LCB2 YWx1ZTsKPiArCj4gKwlpZiAoY2hpcCA8IDAgfHwgV0FSTl9PTl9PTkNFKGNoaXAgPiBNQVhfQ0Vf TlVNKSkKPiArCQlyZXR1cm47Cj4gKwo+ICsJbmZjLT5wYXJhbS5jaGlwX3NlbGVjdCA9IG1lc29u X2NoaXAtPnNlbHNbY2hpcF0gPyBOQU5EX0NFMSA6IE5BTkRfQ0UwOwo+ICsJbmZjLT5wYXJhbS5y Yl9zZWxlY3QgPSBuZmMtPnBhcmFtLmNoaXBfc2VsZWN0Owo+ICsJbmZjLT50aW1pbmcudHdiID0g bWVzb25fY2hpcC0+dHdiOwo+ICsJbmZjLT50aW1pbmcudGFkbCA9IG1lc29uX2NoaXAtPnRhZGw7 Cj4gKwluZmMtPnRpbWluZy50YmVyc19tYXggPSBtZXNvbl9jaGlwLT50YmVyc19tYXg7Cj4gKwo+ ICsJaWYgKGNoaXAgPj0gMCkgewo+ICsJCWlmIChuZmMtPmNsa19yYXRlICE9IG1lc29uX2NoaXAt PmNsa19yYXRlKSB7Cj4gKwkJCXJldCA9IGNsa19zZXRfcmF0ZShuZmMtPmRldmljZV9jbGssCj4g KwkJCQkJICAgbWVzb25fY2hpcC0+Y2xrX3JhdGUpOwo+ICsJCQlpZiAocmV0KSB7Cj4gKwkJCQlk ZXZfZXJyKG5mYy0+ZGV2LCAiZmFpbGVkIHRvIHNldCBjbG9jayByYXRlXG4iKTsKPiArCQkJCXJl dHVybjsKPiArCQkJfQo+ICsJCQluZmMtPmNsa19yYXRlID0gbWVzb25fY2hpcC0+Y2xrX3JhdGU7 Cj4gKwkJfQo+ICsJCWlmIChuZmMtPmJ1c190aW1pbmcgIT0gbWVzb25fY2hpcC0+YnVzX3RpbWlu Zykgewo+ICsJCQl2YWx1ZSA9IChORkNfQ0xLX0NZQ0xFIC0gMSkKPiArCQkJCXwgKG1lc29uX2No aXAtPmJ1c190aW1pbmcgPDwgNSk7Cj4gKwkJCXdyaXRlbCh2YWx1ZSwgbmZjLT5yZWdfYmFzZSAr IE5GQ19SRUdfQ0ZHKTsKPiArCQkJd3JpdGVsKCgxIDw8IDMxKSwgbmZjLT5yZWdfYmFzZSArIE5G Q19SRUdfQ01EKTsKPiArCQkJbmZjLT5idXNfdGltaW5nID0gIG1lc29uX2NoaXAtPmJ1c190aW1p bmc7Cj4gKwkJfQo+ICsJfQoKRG9uJ3QgeW91IGhhdmUgdGltaW5nIHJlZ2lzdGVycyB0byBzZXQ/ Cgo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNvbl9uZmNfY21kX2lkbGUoc3RydWN0IG1lc29u X25mYyAqbmZjLCB1MzIgdGltZSkKPiArewo+ICsJd3JpdGVsKG5mYy0+cGFyYW0uY2hpcF9zZWxl Y3QgfCBORkNfQ01EX0lETEUgfCAodGltZSAmIDB4M2ZmKSwKPiArCSAgICAgICBuZmMtPnJlZ19i YXNlICsgTkZDX1JFR19DTUQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNvbl9uZmNfY21k X3NlZWQoc3RydWN0IG1lc29uX25mYyAqbmZjLCB1MzIgc2VlZCkKPiArewo+ICsJd3JpdGVsKE5G Q19DTURfU0VFRCB8ICgweGMyICsgKHNlZWQgJiAweDdmZmYpKSwKPiArCSAgICAgICBuZmMtPnJl Z19iYXNlICsgTkZDX1JFR19DTUQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNvbl9uZmNf Y21kX2FjY2VzcyhzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBpbnQgcmF3LCBib29sIGRpcikKPiAr ewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZChuYW5kKTsKPiArCXN0cnVj dCBtZXNvbl9uZmMgKm5mYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShtdGRfdG9fbmFuZCht dGQpKTsKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVz b25fbmFuZChuYW5kKTsKPiArCXUzMiBiY2ggPSBtZXNvbl9jaGlwLT5iY2hfbW9kZSwgY21kOwo+ ICsJaW50IGxlbiA9IG10ZC0+d3JpdGVzaXplLCBwYWdlc2l6ZSwgcGFnZXM7Cj4gKwlpbnQgc2Ny YW1ibGUgPSAobmFuZC0+b3B0aW9ucyAmIE5BTkRfTkVFRF9TQ1JBTUJMSU5HKSA/IDEgOiAwOwoK VGhlcmUgYXJlIHF1aXRlIGEgZmV3IHBsYWNlcyB3aGVyZSB5b3UgdXNlIGhhcmRjb2RlZCB2YWx1 ZXMsIEkgd291bGQKaGF2ZSBwcmVmZXJyZWQgcHJlcHJvY2Vzc29yIGRlZmluZXMgZm9yIHRoYXQu IEluIHRoaXMgY2FzZSwgc29tZXRoaW5nCmxpbms6CgoKICAgICAgICAvLyBuYW1pbmcgaXMganVz dCBhcyBhIHJlZmVyZW5jZSwgdXNlIHdoYXRldmVyIHlvdSB3YW50CiAgICAgICAgKyNkZWZpbmUg Q01EX1NDUkFNQkxFIEJJVCgxOSkgCiAgICAgICAgWy4uLl0KICAgICAgICAraW50IHNjcmFtYmxl ID0gbmFuZC0+b3B0aW9ucyAmIE5BTkRfTkVFRF9TQ1JBTUJMSU5HKSA/IENNRF9TQ1JBTUJMRSA6 IDA7Cgp3b3VsZCBiZSBiZXR0ZXIgKHlvdSBjYW4gZXh0ZW5kIHRvIG90aGVyIHBsYWNlcyBhcyB3 ZWxsKS4KCj4gKwo+ICsJcGFnZXNpemUgPSBuYW5kLT5lY2Muc2l6ZTsKPiArCj4gKwlpZiAocmF3 KSB7Cj4gKwkJbGVuID0gbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemU7Cj4gKwkJY21kID0g KGxlbiAmIDB4M2ZmZikgfCAoc2NyYW1ibGUgPDwgMTkpIHwgRE1BX0RJUihkaXIpOwo+ICsJCXdy aXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gKwkJcmV0dXJuOwo+ICsJ fQo+ICsKPiArCXBhZ2VzID0gbGVuIC8gbmFuZC0+ZWNjLnNpemU7Cj4gKwo+ICsJY21kID0gQ01E UldHRU4oRE1BX0RJUihkaXIpLCBzY3JhbWJsZSwgYmNoLCAwLCBwYWdlc2l6ZSwgcGFnZXMpOwo+ ICsKPiArCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gK30KPiAr Cj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19kcmFpbl9jbWQoc3RydWN0IG1lc29uX25mYyAqbmZj KQo+ICt7Cj4gKwkvKgo+ICsJICogSW5zZXJ0IHR3byBjb21tYW5kcyB0byBtYWtlIHN1cmUgYWxs IHZhbGlkIGNvbW1hbmRzIGFyZSBmaW5pc2hlZC4KPiArCSAqCj4gKwkgKiBUaGUgTmFuZCBmbGFz aCBjb250cm9sbGVyIGlzIGRlc2lnbmVkIGFzIHR3byBzdGFnZXMgcGlwbGVsaW5lIC0KPiArCSAq ICBhKSBmZXRjaCBhbmQgYikgZXhjdXRlLgo+ICsJICogVGhlcmUgbWlnaHQgYmUgY2FzZXMgd2hl biB0aGUgZHJpdmVyIHNlZSBjb21tYW5kIHF1ZXVlIGlzIGVtcHR5LAo+ICsJICogYnV0IHRoZSBO YW5kIGZsYXNoIGNvbnRyb2xsZXIgc3RpbGwgaGFzIHR3byBjb21tYW5kcyBidWZmZXJlZCwKPiAr CSAqIG9uZSBpcyBmZXRjaGVkIGludG8gTkZDIHJlcXVlc3QgcXVldWUgKHJlYWR5IHRvIHJ1biks IGFuZCBhbm90aGVyCj4gKwkgKiBpcyBhY3RpdmVseSBleGVjdXRpbmcuIFNvIHB1c2hpbmcgMiAi SURMRSIgY29tbWFuZHMgZ3VhcmFudGVlcyB0aGF0Cj4gKwkgKiB0aGUgcGlwZWxpbmUgaXMgZW1w dGllZC4KPiArCSAqLwo+ICsJbWVzb25fbmZjX2NtZF9pZGxlKG5mYywgMCk7Cj4gKwltZXNvbl9u ZmNfY21kX2lkbGUobmZjLCAwKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfd2Fp dF9jbWRfZmluaXNoKHN0cnVjdCBtZXNvbl9uZmMgKm5mYywKPiArCQkJCSAgICAgdW5zaWduZWQg aW50IHRpbWVvdXRfbXMpCj4gK3sKPiArCXUzMiBjbWRfc2l6ZSA9IDA7Cj4gKwlpbnQgcmV0Owo+ ICsKPiArCS8qIHdhaXQgY21kIGZpZm8gaXMgZW1wdHkgKi8KPiArCXJldCA9IHJlYWRsX3JlbGF4 ZWRfcG9sbF90aW1lb3V0KG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCwgY21kX3NpemUsCj4g KwkJCQkJICFORkNfQ01EX0dFVF9TSVpFKGNtZF9zaXplKSwKPiArCQkJCQkgMTAsIHRpbWVvdXRf bXMgKiAxMDAwKTsKPiArCWlmIChyZXQpCj4gKwkJZGV2X2VycihuZmMtPmRldiwgIndhaXQgZm9y IGVtcHR5IGNtZCBGSUZPIHRpbWUgb3V0XG4iKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW50IG1lc29uX25mY193YWl0X2RtYV9maW5pc2goc3RydWN0IG1lc29uX25m YyAqbmZjKQo+ICt7Cj4gKwltZXNvbl9uZmNfZHJhaW5fY21kKG5mYyk7Cj4gKwo+ICsJcmV0dXJu IG1lc29uX25mY193YWl0X2NtZF9maW5pc2gobmZjLCBETUFfQlVTWV9USU1FT1VUKTsKPiArfQo+ ICsKPiArc3RhdGljIHU4ICptZXNvbl9uZmNfb29iX3B0cihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k LCBpbnQgaSkKPiArewo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAg PSB0b19tZXNvbl9uYW5kKG5hbmQpOwo+ICsJaW50IGxlbjsKPiArCj4gKwlsZW4gPSBuYW5kLT5l Y2Muc2l6ZSAqIChpICsgMSkgKyAobmFuZC0+ZWNjLmJ5dGVzICsgMikgKiBpOwo+ICsKPiArCXJl dHVybiBtZXNvbl9jaGlwLT5kYXRhX2J1ZiArIGxlbjsKPiArfQo+ICsKPiArc3RhdGljIHU4ICpt ZXNvbl9uZmNfZGF0YV9wdHIoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgaW50IGkpCj4gK3sKPiAr CXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVzb25fbmFuZChu YW5kKTsKPiArCWludCBsZW4sIHRlbXA7Cj4gKwo+ICsJdGVtcCA9IG5hbmQtPmVjYy5zaXplICsg bmFuZC0+ZWNjLmJ5dGVzOwo+ICsJbGVuID0gKHRlbXAgKyAyKSAqIGk7Cj4gKwo+ICsJcmV0dXJu IG1lc29uX2NoaXAtPmRhdGFfYnVmICsgbGVuOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNv bl9uZmNfZ2V0X2RhdGFfb29iKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsCj4gKwkJCQkgICB1OCAq YnVmLCB1OCAqb29iYnVmKQo+ICt7Cj4gKwlpbnQgaSwgb29iX2xlbiA9IDA7Cj4gKwl1OCAqZHNy YywgKm9zcmM7Cj4gKwo+ICsJb29iX2xlbiA9IG5hbmQtPmVjYy5ieXRlcyArIDI7Cj4gKwlmb3Ig KGkgPSAwOyBpIDwgbmFuZC0+ZWNjLnN0ZXBzOyBpKyspIHsKPiArCQlpZiAoYnVmKSB7Cj4gKwkJ CWRzcmMgPSBtZXNvbl9uZmNfZGF0YV9wdHIobmFuZCwgaSk7Cj4gKwkJCW1lbWNweShidWYsIGRz cmMsIG5hbmQtPmVjYy5zaXplKTsKPiArCQkJYnVmICs9IG5hbmQtPmVjYy5zaXplOwo+ICsJCX0K PiArCQlvc3JjID0gbWVzb25fbmZjX29vYl9wdHIobmFuZCwgaSk7Cj4gKwkJbWVtY3B5KG9vYmJ1 Ziwgb3NyYywgb29iX2xlbik7Cj4gKwkJb29iYnVmICs9IG9vYl9sZW47Cj4gKwl9Cj4gK30KPiAr Cj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19zZXRfZGF0YV9vb2Ioc3RydWN0IG5hbmRfY2hpcCAq bmFuZCwKPiArCQkJCSAgIGNvbnN0IHU4ICpidWYsIHU4ICpvb2JidWYpCj4gK3sKPiArCWludCBp LCBvb2JfbGVuID0gMDsKPiArCXU4ICpkc3JjLCAqb3NyYzsKPiArCj4gKwlvb2JfbGVuID0gbmFu ZC0+ZWNjLmJ5dGVzICsgMjsKPiArCWZvciAoaSA9IDA7IGkgPCBuYW5kLT5lY2Muc3RlcHM7IGkr Kykgewo+ICsJCWlmIChidWYpIHsKPiArCQkJZHNyYyA9IG1lc29uX25mY19kYXRhX3B0cihuYW5k LCBpKTsKPiArCQkJbWVtY3B5KGRzcmMsIGJ1ZiwgbmFuZC0+ZWNjLnNpemUpOwo+ICsJCQlidWYg Kz0gbmFuZC0+ZWNjLnNpemU7Cj4gKwkJfQo+ICsJCW9zcmMgPSBtZXNvbl9uZmNfb29iX3B0cihu YW5kLCBpKTsKPiArCQltZW1jcHkob3NyYywgb29iYnVmLCBvb2JfbGVuKTsKPiArCQlvb2JidWYg Kz0gb29iX2xlbjsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfcXVldWVf cmIoc3RydWN0IG1lc29uX25mYyAqbmZjLCBpbnQgdGltZW91dF9tcykKPiArewo+ICsJdTMyIGNt ZCwgY2ZnOwo+ICsJaW50IHJldCA9IDA7Cj4gKwo+ICsJbWVzb25fbmZjX2NtZF9pZGxlKG5mYywg bmZjLT50aW1pbmcudHdiKTsKPiArCW1lc29uX25mY19kcmFpbl9jbWQobmZjKTsKPiArCW1lc29u X25mY193YWl0X2NtZF9maW5pc2gobmZjLCBDTURfRklGT19FTVBUWV9USU1FT1VUKTsKPiArCj4g KwljZmcgPSByZWFkbChuZmMtPnJlZ19iYXNlICsgTkZDX1JFR19DRkcpOwo+ICsJY2ZnIHw9ICgx IDw8IDIxKTsKPiArCXdyaXRlbChjZmcsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NGRyk7Cj4g Kwo+ICsJaW5pdF9jb21wbGV0aW9uKCZuZmMtPmNvbXBsZXRpb24pOwo+ICsKPiArCS8qIHVzZSB0 aGUgbWF4IGVyYXNlIHRpbWUgYXMgdGhlIG1heGltdW0gY2xvY2sgZm9yIHdhaXRpbmcgUi9CICov Cj4gKwljbWQgPSBORkNfQ01EX1JCIHwgTkZDX0NNRF9SQl9JTlQKPiArCQl8IG5mYy0+cGFyYW0u Y2hpcF9zZWxlY3QgfCBuZmMtPnRpbWluZy50YmVyc19tYXg7CgpOaXQ6IEkgdGhpbmsgdGhlICd8 JyBzaG91bGQgYmUgb24gdGhlIHByZXZpb3VzIGxpbmUuCgo+ICsJd3JpdGVsKGNtZCwgbmZjLT5y ZWdfYmFzZSArIE5GQ19SRUdfQ01EKTsKPiArCj4gKwlyZXQgPSB3YWl0X2Zvcl9jb21wbGV0aW9u X3RpbWVvdXQoJm5mYy0+Y29tcGxldGlvbiwKPiArCQkJCQkgIG1zZWNzX3RvX2ppZmZpZXModGlt ZW91dF9tcykpOwo+ICsJaWYgKHJldCA9PSAwKQo+ICsJCXJldCA9IC0xOwo+ICsKPiArCXJldHVy biByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19zZXRfdXNlcl9ieXRlKHN0 cnVjdCBuYW5kX2NoaXAgKm5hbmQsIHU4ICpvb2JfYnVmKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25f bmZjX25hbmRfY2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwlfX2xl NjQgKmluZm87Cj4gKwlpbnQgaSwgY291bnQ7Cj4gKwo+ICsJZm9yIChpID0gMCwgY291bnQgPSAw OyBpIDwgbmFuZC0+ZWNjLnN0ZXBzOyBpKyssIGNvdW50ICs9IDIpIHsKPiArCQlpbmZvID0gJm1l c29uX2NoaXAtPmluZm9fYnVmW2ldOwo+ICsJCSppbmZvIHw9IG9vYl9idWZbY291bnRdOwo+ICsJ CSppbmZvIHw9IG9vYl9idWZbY291bnQgKyAxXSA8PCA4Owo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0 aWMgdm9pZCBtZXNvbl9uZmNfZ2V0X3VzZXJfYnl0ZShzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCB1 OCAqb29iX2J1ZikKPiArewo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2No aXAgPSB0b19tZXNvbl9uYW5kKG5hbmQpOwo+ICsJX19sZTY0ICppbmZvOwo+ICsJaW50IGksIGNv dW50Owo+ICsKPiArCWZvciAoaSA9IDAsIGNvdW50ID0gMDsgaSA8IG5hbmQtPmVjYy5zdGVwczsg aSsrLCBjb3VudCArPSAyKSB7Cj4gKwkJaW5mbyA9ICZtZXNvbl9jaGlwLT5pbmZvX2J1ZltpXTsK PiArCQlvb2JfYnVmW2NvdW50XSA9ICppbmZvOwo+ICsJCW9vYl9idWZbY291bnQgKyAxXSA9ICpp bmZvID4+IDg7Cj4gKwl9Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX2VjY19jb3Jy ZWN0KHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQpCj4gK3sKPiArCXN0cnVjdCBtdGRfaW5mbyAqbXRk ID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjX25hbmRfY2hpcCAqbWVz b25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwlfX2xlNjQgKmluZm87Cj4gKwl1MzIg Yml0ZmxpcHMgPSAwLCBpOwo+ICsJaW50IHNjcmFtYmxlOwo+ICsJdTggemVyb19jbnQ7Cj4gKwo+ ICsJc2NyYW1ibGUgPSAobmFuZC0+b3B0aW9ucyAmIE5BTkRfTkVFRF9TQ1JBTUJMSU5HKSA/IDEg OiAwOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBuYW5kLT5lY2Muc3RlcHM7IGkrKykgewo+ICsJ CWluZm8gPSAmbWVzb25fY2hpcC0+aW5mb19idWZbaV07Cj4gKwkJaWYgKEVDQ19FUlJfQ05UKCpp bmZvKSA9PSAweDNmKSB7Cj4gKwkJCXplcm9fY250ID0gRUNDX1pFUk9fQ05UKCppbmZvKTsKPiAr CQkJaWYgKHNjcmFtYmxlICYmIHplcm9fY250IDwgbmFuZC0+ZWNjLnN0cmVuZ3RoKQo+ICsJCQkJ cmV0dXJuIEVDQ19DSEVDS19SRVRVUk5fRkY7CgpUaGlzIGFuZCB3aGF0IHlvdSBkbyBsYXRlciB3 aXRoIEVDQ19DSEVDS19SRVRVUk5fRkYgaXMgcHJldHR5IHVuY2xlYXIKdG8gbWUuCgo+ICsJCQlt dGQtPmVjY19zdGF0cy5mYWlsZWQrKzsKPiArCQkJY29udGludWU7Cj4gKwkJfQo+ICsJCW10ZC0+ ZWNjX3N0YXRzLmNvcnJlY3RlZCArPSBFQ0NfRVJSX0NOVCgqaW5mbyk7Cj4gKwkJYml0ZmxpcHMg PSBtYXhfdCh1MzIsIGJpdGZsaXBzLCBFQ0NfRVJSX0NOVCgqaW5mbykpOwo+ICsJfQoKQXJlIHlv dSBzdXJlIHlvdSBoYW5kbGUgY29ycmVjdGx5IGVtcHR5IHBhZ2VzIHdpdGggYmY/Cgo+ICsKPiAr CXJldHVybiBiaXRmbGlwczsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfZG1hX2J1 ZmZlcl9zZXR1cChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCB1OCAqZGF0YWJ1ZiwKPiArCQkJCSAg ICAgIGludCBkYXRhbGVuLCB1OCAqaW5mb2J1ZiwgaW50IGluZm9sZW4sCj4gKwkJCQkgICAgICBl bnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIpCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmMgKm5m YyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPiArCXUzMiBjbWQ7Cj4gKwlpbnQg cmV0ID0gMDsKPiArCj4gKwluZmMtPmRhZGRyID0gZG1hX21hcF9zaW5nbGUobmZjLT5kZXYsICh2 b2lkICopZGF0YWJ1ZiwgZGF0YWxlbiwgZGlyKTsKPiArCXJldCA9IGRtYV9tYXBwaW5nX2Vycm9y KG5mYy0+ZGV2LCBuZmMtPmRhZGRyKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKG5mYy0+ ZGV2LCAiZG1hIG1hcHBpbmcgZXJyb3JcbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwlj bWQgPSBHRU5DTUREQUREUkwoTkZDX0NNRF9BREwsIG5mYy0+ZGFkZHIpOwo+ICsJd3JpdGVsKGNt ZCwgbmZjLT5yZWdfYmFzZSArIE5GQ19SRUdfQ01EKTsKPiArCj4gKwljbWQgPSBHRU5DTUREQURE UkgoTkZDX0NNRF9BREgsIG5mYy0+ZGFkZHIpOwo+ICsJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFz ZSArIE5GQ19SRUdfQ01EKTsKPiArCj4gKwlpZiAoaW5mb2J1Zikgewo+ICsJCW5mYy0+aWFkZHIg PSBkbWFfbWFwX3NpbmdsZShuZmMtPmRldiwgaW5mb2J1ZiwgaW5mb2xlbiwgZGlyKTsKPiArCQly ZXQgPSBkbWFfbWFwcGluZ19lcnJvcihuZmMtPmRldiwgbmZjLT5pYWRkcik7Cj4gKwkJaWYgKHJl dCkgewo+ICsJCQlkZXZfZXJyKG5mYy0+ZGV2LCAiZG1hIG1hcHBpbmcgZXJyb3JcbiIpOwo+ICsJ CQlkbWFfdW5tYXBfc2luZ2xlKG5mYy0+ZGV2LAo+ICsJCQkJCSBuZmMtPmRhZGRyLCBkYXRhbGVu LCBkaXIpOwo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCX0KPiArCQljbWQgPSBHRU5DTURJQUREUkwo TkZDX0NNRF9BSUwsIG5mYy0+aWFkZHIpOwo+ICsJCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2Ug KyBORkNfUkVHX0NNRCk7Cj4gKwo+ICsJCWNtZCA9IEdFTkNNRElBRERSSChORkNfQ01EX0FJSCwg bmZjLT5pYWRkcik7Cj4gKwkJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFzZSArIE5GQ19SRUdfQ01E KTsKPiArCX0KPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNv bl9uZmNfZG1hX2J1ZmZlcl9yZWxlYXNlKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsCj4gKwkJCQkJ IGludCBpbmZvbGVuLCBpbnQgZGF0YWxlbiwKPiArCQkJCQkgZW51bSBkbWFfZGF0YV9kaXJlY3Rp b24gZGlyKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9s bGVyX2RhdGEobmFuZCk7Cj4gKwo+ICsJZG1hX3VubWFwX3NpbmdsZShuZmMtPmRldiwgbmZjLT5k YWRkciwgZGF0YWxlbiwgZGlyKTsKPiArCWlmIChpbmZvbGVuKQo+ICsJCWRtYV91bm1hcF9zaW5n bGUobmZjLT5kZXYsIG5mYy0+aWFkZHIsIGluZm9sZW4sIGRpcik7Cj4gK30KPiArCj4gK3N0YXRp YyBpbnQgbWVzb25fbmZjX3JlYWRfYnVmKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIHU4ICpidWYs IGludCBsZW4pCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmMgKm5mYyA9IG5hbmRfZ2V0X2NvbnRy b2xsZXJfZGF0YShuYW5kKTsKPiArCWludCByZXQgPSAwOwo+ICsJdTMyIGNtZDsKPiArCXU4ICpp bmZvOwo+ICsKPiArCWluZm8gPSBremFsbG9jKFBFUl9JTkZPX0JZVEUsIEdGUF9LRVJORUwpOwo+ ICsJcmV0ID0gbWVzb25fbmZjX2RtYV9idWZmZXJfc2V0dXAobmFuZCwgYnVmLCBsZW4sIGluZm8s Cj4gKwkJCQkJIFBFUl9JTkZPX0JZVEUsIERNQV9GUk9NX0RFVklDRSk7Cj4gKwlpZiAocmV0KQo+ ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJY21kID0gTkZDX0NNRF9OMk0gfCAobGVuICYgMHgzZmZm KTsKPiArCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gKwo+ICsJ bWVzb25fbmZjX2RyYWluX2NtZChuZmMpOwo+ICsJbWVzb25fbmZjX3dhaXRfY21kX2ZpbmlzaChu ZmMsIDEwMDApOwo+ICsJbWVzb25fbmZjX2RtYV9idWZmZXJfcmVsZWFzZShuYW5kLCBsZW4sIFBF Ul9JTkZPX0JZVEUsIERNQV9GUk9NX0RFVklDRSk7Cj4gKwlrZnJlZShpbmZvKTsKPiArCj4gKwly ZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX25mY193cml0ZV9idWYoc3Ry dWN0IG5hbmRfY2hpcCAqbmFuZCwgdTggKmJ1ZiwgaW50IGxlbikKPiArewo+ICsJc3RydWN0IG1l c29uX25mYyAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKG5hbmQpOwo+ICsJaW50IHJl dCA9IDA7Cj4gKwl1MzIgY21kOwo+ICsKPiArCXJldCA9IG1lc29uX25mY19kbWFfYnVmZmVyX3Nl dHVwKG5hbmQsIGJ1ZiwgbGVuLCBOVUxMLAo+ICsJCQkJCSAwLCBETUFfVE9fREVWSUNFKTsKPiAr CWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwljbWQgPSBORkNfQ01EX00yTiB8IChs ZW4gJiAweDNmZmYpOwo+ICsJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFzZSArIE5GQ19SRUdfQ01E KTsKPiArCj4gKwltZXNvbl9uZmNfZHJhaW5fY21kKG5mYyk7Cj4gKwltZXNvbl9uZmNfd2FpdF9j bWRfZmluaXNoKG5mYywgMTAwMCk7Cj4gKwltZXNvbl9uZmNfZG1hX2J1ZmZlcl9yZWxlYXNlKG5h bmQsIGxlbiwgMCwgRE1BX1RPX0RFVklDRSk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsK PiArc3RhdGljIGludCBtZXNvbl9uZmNfcndfY21kX3ByZXBhcmVfYW5kX2V4ZWN1dGUoc3RydWN0 IG5hbmRfY2hpcCAqbmFuZCwKPiArCQkJCQkJaW50IHBhZ2UsIGJvb2wgaW4pCj4gK3sKPiArCXN0 cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25f bmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4gKwljb25zdCBzdHJ1 Y3QgbmFuZF9zZHJfdGltaW5ncyAqc2RyID0KPiArCQluYW5kX2dldF9zZHJfdGltaW5ncygmbmFu ZC0+ZGF0YV9pbnRlcmZhY2UpOwo+ICsJdTMyICphZGRycyA9IG5mYy0+Y21kZmlmby5ydy5hZGRy czsKPiArCXUzMiBjcyA9IG5mYy0+cGFyYW0uY2hpcF9zZWxlY3Q7Cj4gKwl1MzIgY21kMCwgY21k X251bSwgcm93X3N0YXJ0Owo+ICsJaW50IHJldCA9IDAsIGk7Cj4gKwo+ICsJY21kX251bSA9IHNp emVvZihzdHJ1Y3QgbmFuZF9yd19jbWQpIC8gc2l6ZW9mKGludCk7Cj4gKwo+ICsJY21kMCA9IGlu ID8gTkFORF9DTURfUkVBRDAgOiBOQU5EX0NNRF9TRVFJTjsKPiArCW5mYy0+Y21kZmlmby5ydy5j bWQwID0gY3MgfCBORkNfQ01EX0NMRSB8IGNtZDA7Cj4gKwo+ICsJYWRkcnNbMF0gPSBjcyB8IE5G Q19DTURfQUxFIHwgMDsKPiArCWlmIChtdGQtPndyaXRlc2l6ZSA8PSA1MTIpIHsKPiArCQljbWRf bnVtLS07Cj4gKwkJcm93X3N0YXJ0ID0gMTsKPiArCX0gZWxzZSB7Cj4gKwkJYWRkcnNbMV0gPSBj cyB8IE5GQ19DTURfQUxFIHwgMDsKPiArCQlyb3dfc3RhcnQgPSAyOwo+ICsJfQo+ICsKPiArCWFk ZHJzW3Jvd19zdGFydF0gPSBjcyB8IE5GQ19DTURfQUxFIHwgUk9XX0FEREVSKHBhZ2UsIDApOwo+ ICsJYWRkcnNbcm93X3N0YXJ0ICsgMV0gPSBjcyB8IE5GQ19DTURfQUxFIHwgUk9XX0FEREVSKHBh Z2UsIDEpOwo+ICsKPiArCWlmIChuYW5kLT5vcHRpb25zICYgTkFORF9ST1dfQUREUl8zKQo+ICsJ CWFkZHJzW3Jvd19zdGFydCArIDJdID0KPiArCQkJY3MgfCBORkNfQ01EX0FMRSB8IFJPV19BRERF UihwYWdlLCAyKTsKPiArCWVsc2UKPiArCQljbWRfbnVtLS07Cj4gKwo+ICsJLyogc3VidHJhY3Qg Y21kMSAqLwo+ICsJY21kX251bS0tOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBjbWRfbnVtOyBp KyspCj4gKwkJd3JpdGVsX3JlbGF4ZWQobmZjLT5jbWRmaWZvLmNtZFtpXSwKPiArCQkJICAgICAg IG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gKwo+ICsJaWYgKGluKSB7Cj4gKwkJbmZj LT5jbWRmaWZvLnJ3LmNtZDEgPSBjcyB8IE5GQ19DTURfQ0xFIHwgTkFORF9DTURfUkVBRFNUQVJU Owo+ICsJCXdyaXRlbChuZmMtPmNtZGZpZm8ucncuY21kMSwgbmZjLT5yZWdfYmFzZSArIE5GQ19S RUdfQ01EKTsKPiArCQltZXNvbl9uZmNfcXVldWVfcmIobmZjLCBQU0VDX1RPX01TRUMoc2RyLT50 Ul9tYXgpKTsKPiArCX0gZWxzZSB7Cj4gKwkJbWVzb25fbmZjX2NtZF9pZGxlKG5mYywgbmZjLT50 aW1pbmcudGFkbCk7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGlj IGludCBtZXNvbl9uZmNfd3JpdGVfcGFnZV9zdWIoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwKPiAr CQkJCSAgICBpbnQgcGFnZSwgaW50IHJhdykKPiArewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQg PSBuYW5kX3RvX210ZChuYW5kKTsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX3Nkcl90aW1pbmdzICpz ZHIgPQo+ICsJCW5hbmRfZ2V0X3Nkcl90aW1pbmdzKCZuYW5kLT5kYXRhX2ludGVyZmFjZSk7Cj4g KwlzdHJ1Y3QgbWVzb25fbmZjX25hbmRfY2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQo bmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2Rh dGEobmFuZCk7Cj4gKwlpbnQgZGF0YV9sZW4sIGluZm9fbGVuOwo+ICsJdTMyIGNtZDsKPiArCWlu dCByZXQ7Cj4gKwo+ICsJZGF0YV9sZW4gPSAgbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemU7 Cj4gKwlpbmZvX2xlbiA9IG5hbmQtPmVjYy5zdGVwcyAqIFBFUl9JTkZPX0JZVEU7Cj4gKwo+ICsJ cmV0ID0gbWVzb25fbmZjX3J3X2NtZF9wcmVwYXJlX2FuZF9leGVjdXRlKG5hbmQsIHBhZ2UsIERJ UldSSVRFKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQgPSBtZXNv bl9uZmNfZG1hX2J1ZmZlcl9zZXR1cChuYW5kLCBtZXNvbl9jaGlwLT5kYXRhX2J1ZiwKPiArCQkJ CQkgZGF0YV9sZW4sICh1OCAqKW1lc29uX2NoaXAtPmluZm9fYnVmLAo+ICsJCQkJCSBpbmZvX2xl biwgRE1BX1RPX0RFVklDRSk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJ bWVzb25fbmZjX2NtZF9zZWVkKG5mYywgcGFnZSk7Cj4gKwltZXNvbl9uZmNfY21kX2FjY2Vzcyhu YW5kLCByYXcsIERJUldSSVRFKTsKPiArCWNtZCA9IG5mYy0+cGFyYW0uY2hpcF9zZWxlY3QgfCBO RkNfQ01EX0NMRSB8IE5BTkRfQ01EX1BBR0VQUk9HOwo+ICsJd3JpdGVsKGNtZCwgbmZjLT5yZWdf YmFzZSArIE5GQ19SRUdfQ01EKTsKPiArCW1lc29uX25mY19xdWV1ZV9yYihuZmMsIFBTRUNfVE9f TVNFQyhzZHItPnRQUk9HX21heCkpOwo+ICsKPiArCW1lc29uX25mY19kbWFfYnVmZmVyX3JlbGVh c2UobmFuZCwgZGF0YV9sZW4sIGluZm9fbGVuLCBETUFfVE9fREVWSUNFKTsKPiArCj4gKwlyZXR1 cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX25mY193cml0ZV9wYWdlX3Jhdyhz dHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBjb25zdCB1OCAqYnVmLAo+ICsJCQkJICAgIGludCBvb2Jf cmVxdWlyZWQsIGludCBwYWdlKQo+ICt7Cj4gKwl1OCAqb29iX2J1ZiA9IG5hbmQtPm9vYl9wb2k7 Cj4gKwo+ICsJbWVzb25fbmZjX3NldF9kYXRhX29vYihuYW5kLCBidWYsIG9vYl9idWYpOwo+ICsK PiArCXJldHVybiBtZXNvbl9uZmNfd3JpdGVfcGFnZV9zdWIobmFuZCwgcGFnZSwgMSk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX3dyaXRlX3BhZ2VfaHdlY2Moc3RydWN0IG5hbmRf Y2hpcCAqbmFuZCwKPiArCQkJCSAgICAgIGNvbnN0IHU4ICpidWYsIGludCBvb2JfcmVxdWlyZWQs IGludCBwYWdlKQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5h bmQpOwo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAgPSB0b19tZXNv bl9uYW5kKG5hbmQpOwo+ICsJdTggKm9vYl9idWYgPSBuYW5kLT5vb2JfcG9pOwo+ICsKPiArCW1l bWNweShtZXNvbl9jaGlwLT5kYXRhX2J1ZiwgYnVmLCBtdGQtPndyaXRlc2l6ZSk7Cj4gKwltZW1z ZXQobWVzb25fY2hpcC0+aW5mb19idWYsIDAsIG5hbmQtPmVjYy5zdGVwcyAqIFBFUl9JTkZPX0JZ VEUpOwo+ICsJbWVzb25fbmZjX3NldF91c2VyX2J5dGUobmFuZCwgb29iX2J1Zik7Cj4gKwo+ICsJ cmV0dXJuIG1lc29uX25mY193cml0ZV9wYWdlX3N1YihuYW5kLCBwYWdlLCAwKTsKPiArfQo+ICsK PiArc3RhdGljIHZvaWQgbWVzb25fbmZjX2NoZWNrX2VjY19wYWdlc192YWxpZChzdHJ1Y3QgbWVz b25fbmZjICpuZmMsCj4gKwkJCQkJICAgIHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIGludCByYXcp Cj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVz b25fbmFuZChuYW5kKTsKPiArCV9fbGU2NCAqaW5mbzsKPiArCXUzMiBuZWNjcGFnZXM7Cj4gKwlp bnQgcmV0Owo+ICsKPiArCW5lY2NwYWdlcyA9IHJhdyA/IDEgOiBuYW5kLT5lY2Muc3RlcHM7Cj4g KwlpbmZvID0gJm1lc29uX2NoaXAtPmluZm9fYnVmW25lY2NwYWdlcyAtIDFdOwo+ICsJZG8gewo+ ICsJCXVzbGVlcF9yYW5nZSgxMCwgMTUpOwo+ICsJCS8qIGluZm8gaXMgdXBkYXRlZCBieSBuZmMg ZG1hIGVuZ2luZSovCj4gKwkJc21wX3JtYigpOwo+ICsJCXJldCA9ICppbmZvICYgRUNDX0NPTVBM RVRFOwo+ICsJfSB3aGlsZSAoIXJldCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZj X3JlYWRfcGFnZV9zdWIoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwKPiArCQkJCSAgIGludCBwYWdl LCBpbnQgcmF3KQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5h bmQpOwo+ICsJc3RydWN0IG1lc29uX25mYyAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRh KG5hbmQpOwo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAgPSB0b19t ZXNvbl9uYW5kKG5hbmQpOwo+ICsJaW50IGRhdGFfbGVuLCBpbmZvX2xlbjsKPiArCWludCByZXQ7 Cj4gKwo+ICsJZGF0YV9sZW4gPSAgbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemU7Cj4gKwlp bmZvX2xlbiA9IG5hbmQtPmVjYy5zdGVwcyAqIFBFUl9JTkZPX0JZVEU7Cj4gKwo+ICsJcmV0ID0g bWVzb25fbmZjX3J3X2NtZF9wcmVwYXJlX2FuZF9leGVjdXRlKG5hbmQsIHBhZ2UsIERJUlJFQUQp Owo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldCA9IG1lc29uX25mY19k bWFfYnVmZmVyX3NldHVwKG5hbmQsIG1lc29uX2NoaXAtPmRhdGFfYnVmLAo+ICsJCQkJCSBkYXRh X2xlbiwgKHU4ICopbWVzb25fY2hpcC0+aW5mb19idWYsCj4gKwkJCQkJIGluZm9fbGVuLCBETUFf RlJPTV9ERVZJQ0UpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCW1lc29u X25mY19jbWRfc2VlZChuZmMsIHBhZ2UpOwo+ICsJbWVzb25fbmZjX2NtZF9hY2Nlc3MobmFuZCwg cmF3LCBESVJSRUFEKTsKPiArCXJldCA9IG1lc29uX25mY193YWl0X2RtYV9maW5pc2gobmZjKTsK PiArCW1lc29uX25mY19jaGVja19lY2NfcGFnZXNfdmFsaWQobmZjLCBuYW5kLCByYXcpOwo+ICsK PiArCW1lc29uX25mY19kbWFfYnVmZmVyX3JlbGVhc2UobmFuZCwgZGF0YV9sZW4sIGluZm9fbGVu LCBETUFfRlJPTV9ERVZJQ0UpOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRp YyBpbnQgbWVzb25fbmZjX3JlYWRfcGFnZV9yYXcoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgdTgg KmJ1ZiwKPiArCQkJCSAgIGludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+ICt7Cj4gKwl1OCAq b29iX2J1ZiA9IG5hbmQtPm9vYl9wb2k7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IG1lc29u X25mY19yZWFkX3BhZ2Vfc3ViKG5hbmQsIHBhZ2UsIDEpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1 cm4gcmV0Owo+ICsKPiArCW1lc29uX25mY19nZXRfZGF0YV9vb2IobmFuZCwgYnVmLCBvb2JfYnVm KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfcmVh ZF9wYWdlX2h3ZWNjKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIHU4ICpidWYsCj4gKwkJCQkgICAg IGludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10 ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1l c29uX2NoaXAgPSB0b19tZXNvbl9uYW5kKG5hbmQpOwo+ICsJdTggKm9vYl9idWYgPSBuYW5kLT5v b2JfcG9pOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSBtZXNvbl9uZmNfcmVhZF9wYWdlX3N1 YihuYW5kLCBwYWdlLCAwKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlt ZXNvbl9uZmNfZ2V0X3VzZXJfYnl0ZShuYW5kLCBvb2JfYnVmKTsKPiArCj4gKwlyZXQgPSBtZXNv bl9uZmNfZWNjX2NvcnJlY3QobmFuZCk7Cj4gKwlpZiAocmV0ID09IEVDQ19DSEVDS19SRVRVUk5f RkYpIHsKPiArCQlpZiAoYnVmKQo+ICsJCQltZW1zZXQoYnVmLCAweGZmLCBtdGQtPndyaXRlc2l6 ZSk7Cj4gKwo+ICsJCW1lbXNldChvb2JfYnVmLCAweGZmLCBtdGQtPm9vYnNpemUpOwo+ICsJCXJl dHVybiAwOwo+ICsJfQo+ICsKPiArCWlmIChidWYgJiYgYnVmICE9IG1lc29uX2NoaXAtPmRhdGFf YnVmKQo+ICsJCW1lbWNweShidWYsIG1lc29uX2NoaXAtPmRhdGFfYnVmLCBtdGQtPndyaXRlc2l6 ZSk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNf cmVhZF9vb2JfcmF3KHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIGludCBwYWdlKQo+ICt7Cj4gKwly ZXR1cm4gbWVzb25fbmZjX3JlYWRfcGFnZV9yYXcobmFuZCwgTlVMTCwgMSwgcGFnZSk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX3JlYWRfb29iKHN0cnVjdCBuYW5kX2NoaXAgKm5h bmQsIGludCBwYWdlKQo+ICt7Cj4gKwlyZXR1cm4gbWVzb25fbmZjX3JlYWRfcGFnZV9od2VjYyhu YW5kLCBOVUxMLCAxLCBwYWdlKTsKPiArfQo+ICsKPiArdm9pZCAqCj4gK21lc29uX25hbmRfb3Bf Z2V0X2RtYV9zYWZlX2lucHV0X2J1Zihjb25zdCBzdHJ1Y3QgbmFuZF9vcF9pbnN0ciAqaW5zdHIp Cj4gK3sKPiArCWlmIChXQVJOX09OKGluc3RyLT50eXBlICE9IE5BTkRfT1BfREFUQV9JTl9JTlNU UikpCj4gKwkJcmV0dXJuIE5VTEw7Cj4gKwlpZiAodmlydF9hZGRyX3ZhbGlkKGluc3RyLT5jdHgu ZGF0YS5idWYuaW4pICYmCj4gKwkgICAgIW9iamVjdF9pc19vbl9zdGFjayhpbnN0ci0+Y3R4LmRh dGEuYnVmLmluKSkKPiArCQlyZXR1cm4gaW5zdHItPmN0eC5kYXRhLmJ1Zi5pbjsKPiArCj4gKwly ZXR1cm4ga3phbGxvYyhpbnN0ci0+Y3R4LmRhdGEubGVuLCBHRlBfS0VSTkVMKTsKCkkgdGhpbmsg YWxsb2NhdGluZyBtZW1vcnkgYW5kIHVzaW5nIGl0IHdpdGhvdXQgZXZlciB0ZXN0aW5nIHRoZQph bGxvY2F0aW9uIHN1Y2NlZWRlZCBpcyB3cm9uZy4gWW91IGRvIHRoYXQgaW4gbWFueSBwbGFjZXMu IEkgd291bGQgbGlrZQp0byBzZWUgYWxsb2NhdGlvbnMgcHJvcGVybHkgaGFuZGxlZC4KCj4gK30K PiArCj4gK3ZvaWQKPiArbWVzb25fbmFuZF9vcF9wdXRfZG1hX3NhZmVfaW5wdXRfYnVmKGNvbnN0 IHN0cnVjdCBuYW5kX29wX2luc3RyICppbnN0ciwKPiArCQkJCSAgICAgdm9pZCAqYnVmKQo+ICt7 Cj4gKwlpZiAoV0FSTl9PTihpbnN0ci0+dHlwZSAhPSBOQU5EX09QX0RBVEFfSU5fSU5TVFIpIHx8 Cj4gKwkgICAgV0FSTl9PTighYnVmKSkKPiArCQlyZXR1cm47Cj4gKwlpZiAoYnVmID09IGluc3Ry LT5jdHguZGF0YS5idWYuaW4pCj4gKwkJcmV0dXJuOwo+ICsKPiArCW1lbWNweShpbnN0ci0+Y3R4 LmRhdGEuYnVmLmluLCBidWYsIGluc3RyLT5jdHguZGF0YS5sZW4pOwo+ICsJa2ZyZWUoYnVmKTsK PiArfQo+ICsKPiArY29uc3Qgdm9pZCAqCj4gK21lc29uX25hbmRfb3BfZ2V0X2RtYV9zYWZlX291 dHB1dF9idWYoY29uc3Qgc3RydWN0IG5hbmRfb3BfaW5zdHIgKmluc3RyKQo+ICt7Cj4gKwlpZiAo V0FSTl9PTihpbnN0ci0+dHlwZSAhPSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSKSkKPiArCQlyZXR1 cm4gTlVMTDsKPiArCj4gKwlpZiAodmlydF9hZGRyX3ZhbGlkKGluc3RyLT5jdHguZGF0YS5idWYu b3V0KSAmJgo+ICsJICAgICFvYmplY3RfaXNfb25fc3RhY2soaW5zdHItPmN0eC5kYXRhLmJ1Zi5v dXQpKQoKQ2FuIHlvdSBwbGVhc2UgY3JlYXRlIGhlbHBlcnMgZm9yIHRoYXQ/IEkgZ3Vlc3MgaXQg d2lsbCBoZWxwIHJlbW92aW5nCnRoZXNlIGNoZWNrcyBvbmNlIHRoZSBjb3JlIHdpbGwgaGF2ZSBh IERNQS1zYWZlIGFwcHJvYWNoLgoKPiArCQlyZXR1cm4gaW5zdHItPmN0eC5kYXRhLmJ1Zi5vdXQ7 Cj4gKwo+ICsJcmV0dXJuIGttZW1kdXAoaW5zdHItPmN0eC5kYXRhLmJ1Zi5vdXQsCj4gKwkJICAg ICAgIGluc3RyLT5jdHguZGF0YS5sZW4sIEdGUF9LRVJORUwpOwo+ICt9Cj4gKwo+ICt2b2lkCj4g K21lc29uX25hbmRfb3BfcHV0X2RtYV9zYWZlX291dHB1dF9idWYoY29uc3Qgc3RydWN0IG5hbmRf b3BfaW5zdHIgKmluc3RyLAo+ICsJCQkJICAgICAgY29uc3Qgdm9pZCAqYnVmKQo+ICt7Cj4gKwlp ZiAoV0FSTl9PTihpbnN0ci0+dHlwZSAhPSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSKSB8fAo+ICsJ ICAgIFdBUk5fT04oIWJ1ZikpCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlmIChidWYgIT0gaW5zdHIt PmN0eC5kYXRhLmJ1Zi5vdXQpCj4gKwkJa2ZyZWUoYnVmKTsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBtZXNvbl9uZmNfZXhlY19vcChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLAo+ICsJCQkgICAgIGNv bnN0IHN0cnVjdCBuYW5kX29wZXJhdGlvbiAqb3AsIGJvb2wgY2hlY2tfb25seSkKPiArewo+ICsJ c3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAgPSB0b19tZXNvbl9uYW5kKG5h bmQpOwo+ICsJc3RydWN0IG1lc29uX25mYyAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRh KG5hbmQpOwo+ICsJY29uc3Qgc3RydWN0IG5hbmRfb3BfaW5zdHIgKmluc3RyID0gTlVMTDsKPiAr CXZvaWQgKmJ1ZjsKPiArCXUzMiBvcF9pZCwgZGVsYXlfaWRsZSwgY21kOwo+ICsJaW50IGk7Cj4g Kwo+ICsJZm9yIChvcF9pZCA9IDA7IG9wX2lkIDwgb3AtPm5pbnN0cnM7IG9wX2lkKyspIHsKPiAr CQlpbnN0ciA9ICZvcC0+aW5zdHJzW29wX2lkXTsKPiArCQlkZWxheV9pZGxlID0gRElWX1JPVU5E X1VQKFBTRUNfVE9fTlNFQyhpbnN0ci0+ZGVsYXlfbnMpLAo+ICsJCQkJCSAgbWVzb25fY2hpcC0+ bGV2ZWwxX2RpdmlkZXIgKgo+ICsJCQkJCSAgTkZDX0NMS19DWUNMRSk7Cj4gKwkJc3dpdGNoIChp bnN0ci0+dHlwZSkgewo+ICsJCWNhc2UgTkFORF9PUF9DTURfSU5TVFI6Cj4gKwkJCWNtZCA9IG5m Yy0+cGFyYW0uY2hpcF9zZWxlY3QgfCBORkNfQ01EX0NMRTsKPiArCQkJY21kIHw9IGluc3RyLT5j dHguY21kLm9wY29kZSAmIDB4ZmY7Cj4gKwkJCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBO RkNfUkVHX0NNRCk7Cj4gKwkJCW1lc29uX25mY19jbWRfaWRsZShuZmMsIGRlbGF5X2lkbGUpOwo+ ICsJCQlicmVhazsKPiArCj4gKwkJY2FzZSBOQU5EX09QX0FERFJfSU5TVFI6Cj4gKwkJCWZvciAo aSA9IDA7IGkgPCBpbnN0ci0+Y3R4LmFkZHIubmFkZHJzOyBpKyspIHsKPiArCQkJCWNtZCA9IG5m Yy0+cGFyYW0uY2hpcF9zZWxlY3QgfCBORkNfQ01EX0FMRTsKPiArCQkJCWNtZCB8PSBpbnN0ci0+ Y3R4LmFkZHIuYWRkcnNbaV0gJiAweGZmOwo+ICsJCQkJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFz ZSArIE5GQ19SRUdfQ01EKTsKPiArCQkJfQo+ICsJCQltZXNvbl9uZmNfY21kX2lkbGUobmZjLCBk ZWxheV9pZGxlKTsKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNhc2UgTkFORF9PUF9EQVRBX0lOX0lO U1RSOgo+ICsJCQlidWYgPSBtZXNvbl9uYW5kX29wX2dldF9kbWFfc2FmZV9pbnB1dF9idWYoaW5z dHIpOwo+ICsJCQltZXNvbl9uZmNfcmVhZF9idWYobmFuZCwgYnVmLAo+ICsJCQkJCSAgIGluc3Ry LT5jdHguZGF0YS5sZW4pOwo+ICsJCQltZXNvbl9uYW5kX29wX3B1dF9kbWFfc2FmZV9pbnB1dF9i dWYoaW5zdHIsIGJ1Zik7Cj4gKwkJCWJyZWFrOwo+ICsKPiArCQljYXNlIE5BTkRfT1BfREFUQV9P VVRfSU5TVFI6Cj4gKwkJCWJ1ZiA9Cj4gKwkJCSh2b2lkICopbWVzb25fbmFuZF9vcF9nZXRfZG1h X3NhZmVfb3V0cHV0X2J1ZihpbnN0cik7Cj4gKwkJCW1lc29uX25mY193cml0ZV9idWYobmFuZCwg YnVmLAo+ICsJCQkJCSAgICBpbnN0ci0+Y3R4LmRhdGEubGVuKTsKPiArCQkJbWVzb25fbmFuZF9v cF9wdXRfZG1hX3NhZmVfb3V0cHV0X2J1ZihpbnN0ciwgYnVmKTsKPiArCQkJYnJlYWs7Cj4gKwo+ ICsJCWNhc2UgTkFORF9PUF9XQUlUUkRZX0lOU1RSOgo+ICsJCQltZXNvbl9uZmNfcXVldWVfcmIo bmZjLCBpbnN0ci0+Y3R4LndhaXRyZHkudGltZW91dF9tcyk7Cj4gKwkJCWlmIChpbnN0ci0+ZGVs YXlfbnMpCj4gKwkJCQltZXNvbl9uZmNfY21kX2lkbGUobmZjLCBkZWxheV9pZGxlKTsKPiArCQkJ YnJlYWs7Cj4gKwkJfQo+ICsJfQo+ICsJbWVzb25fbmZjX3dhaXRfY21kX2ZpbmlzaChuZmMsIDEw MDApOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fb29ibGF5b3V0 X2VjYyhzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNlY3Rpb24sCj4gKwkJCSAgICAgICBzdHJ1 Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPiArewo+ICsJc3RydWN0IG5hbmRfY2hpcCAq bmFuZCA9IG10ZF90b19uYW5kKG10ZCk7Cj4gKwo+ICsJaWYgKHNlY3Rpb24gPj0gbmFuZC0+ZWNj LnN0ZXBzKQo+ICsJCXJldHVybiAtRVJBTkdFOwo+ICsKPiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0g IDIgKyAoc2VjdGlvbiAqICgyICsgbmFuZC0+ZWNjLmJ5dGVzKSk7Cj4gKwlvb2JyZWdpb24tPmxl bmd0aCA9IG5hbmQtPmVjYy5ieXRlczsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBtZXNvbl9vb2JsYXlvdXRfZnJlZShzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNl Y3Rpb24sCj4gKwkJCQlzdHJ1Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPiArewo+ICsJ c3RydWN0IG5hbmRfY2hpcCAqbmFuZCA9IG10ZF90b19uYW5kKG10ZCk7Cj4gKwo+ICsJaWYgKHNl Y3Rpb24gPj0gbmFuZC0+ZWNjLnN0ZXBzKQo+ICsJCXJldHVybiAtRVJBTkdFOwo+ICsKPiArCW9v YnJlZ2lvbi0+b2Zmc2V0ID0gc2VjdGlvbiAqICgyICsgbmFuZC0+ZWNjLmJ5dGVzKTsKPiArCW9v YnJlZ2lvbi0+bGVuZ3RoID0gMjsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGlj IGNvbnN0IHN0cnVjdCBtdGRfb29ibGF5b3V0X29wcyBtZXNvbl9vb2JsYXlvdXRfb3BzID0gewo+ ICsJLmVjYyA9IG1lc29uX29vYmxheW91dF9lY2MsCj4gKwkuZnJlZSA9IG1lc29uX29vYmxheW91 dF9mcmVlLAo+ICt9Owo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfY2xrX2luaXQoc3RydWN0 IG1lc29uX25mYyAqbmZjKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCS8qIHJlcXVlc3QgY29y ZSBjbG9jayAqLwo+ICsJbmZjLT5jb3JlX2NsayA9IGRldm1fY2xrX2dldChuZmMtPmRldiwgImNv cmUiKTsKPiArCWlmIChJU19FUlIobmZjLT5jb3JlX2NsaykpIHsKPiArCQlkZXZfZXJyKG5mYy0+ ZGV2LCAiZmFpbGVkIHRvIGdldCBjb3JlIGNsa1xuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIobmZj LT5jb3JlX2Nsayk7Cj4gKwl9Cj4gKwo+ICsJbmZjLT5kZXZpY2VfY2xrID0gZGV2bV9jbGtfZ2V0 KG5mYy0+ZGV2LCAiZGV2aWNlIik7Cj4gKwlpZiAoSVNfRVJSKG5mYy0+ZGV2aWNlX2NsaykpIHsK PiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAiZmFpbGVkIHRvIGdldCBkZXZpY2UgY2xrXG4iKTsKPiAr CQlyZXR1cm4gUFRSX0VSUihuZmMtPmRldmljZV9jbGspOwo+ICsJfQo+ICsKPiArCW5mYy0+cGhh c2VfdHggPSBkZXZtX2Nsa19nZXQobmZjLT5kZXYsICJ0eCIpOwo+ICsJaWYgKElTX0VSUihuZmMt PnBoYXNlX3R4KSkgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICJmYWlsZWQgdG8gZ2V0IHR4IGNs a1xuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIobmZjLT5waGFzZV90eCk7Cj4gKwl9Cj4gKwo+ICsJ bmZjLT5waGFzZV9yeCA9IGRldm1fY2xrX2dldChuZmMtPmRldiwgInJ4Iik7Cj4gKwlpZiAoSVNf RVJSKG5mYy0+cGhhc2VfcngpKSB7Cj4gKwkJZGV2X2VycihuZmMtPmRldiwgImZhaWxlZCB0byBn ZXQgcnggY2xrXG4iKTsKPiArCQlyZXR1cm4gUFRSX0VSUihuZmMtPnBoYXNlX3J4KTsKPiArCX0K PiArCj4gKwkvKiBpbml0IFNEX0VNTUNfQ0xPQ0sgdG8gc2FuZSBkZWZhdWx0cyB3L21pbiBjbG9j ayByYXRlICovCj4gKwlyZWdtYXBfdXBkYXRlX2JpdHMobmZjLT5yZWdfY2xrLAo+ICsJCQkgICAw LCBDTEtfU0VMRUNUX05BTkQsIENMS19TRUxFQ1RfTkFORCk7Cj4gKwo+ICsJcmV0ID0gY2xrX3By ZXBhcmVfZW5hYmxlKG5mYy0+Y29yZV9jbGspOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIo bmZjLT5kZXYsICJmYWlsZWQgdG8gZW5hYmxlIGNvcmUgY2xrXG4iKTsKPiArCQlyZXR1cm4gcmV0 Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShuZmMtPmRldmljZV9jbGsp Owo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICJmYWlsZWQgdG8gZW5hYmxl IGRldmljZSBjbGtcbiIpOwo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShuZmMtPmNvcmVfY2xr KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJs ZShuZmMtPnBoYXNlX3R4KTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSB0eCBjbGtcbiIpOwo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShu ZmMtPmNvcmVfY2xrKTsKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5kZXZpY2VfY2xr KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJs ZShuZmMtPnBoYXNlX3J4KTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSByeCBjbGtcbiIpOwo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShu ZmMtPmNvcmVfY2xrKTsKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5kZXZpY2VfY2xr KTsKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5waGFzZV90eCk7CgpUaGlzIGVycm9y IGNhc2UgaXMgYSBnb29kIGNhbmRpZGF0ZSB0byBhIGdvdG8gc3RhdGVtZW50LgoKPiArCQlyZXR1 cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19zZXRfcmF0ZShuZmMtPmRldmljZV9jbGss IDI0MDAwMDAwKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbWVzb25fbmZjX2Rpc2FibGVfY2xrKHN0cnVjdCBt ZXNvbl9uZmMgKm5mYykKPiArewo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKG5mYy0+cGhhc2Vf cngpOwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKG5mYy0+cGhhc2VfdHgpOwo+ICsJY2xrX2Rp c2FibGVfdW5wcmVwYXJlKG5mYy0+ZGV2aWNlX2Nsayk7Cj4gKwljbGtfZGlzYWJsZV91bnByZXBh cmUobmZjLT5jb3JlX2Nsayk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19mcmVl X2J1ZmZlcihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZj X25hbmRfY2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwo+ICsJa2Zy ZWUobWVzb25fY2hpcC0+aW5mb19idWYpOwo+ICsJa2ZyZWUobWVzb25fY2hpcC0+ZGF0YV9idWYp Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX2NoaXBfYnVmZmVyX2luaXQoc3RydWN0IG5h bmRfY2hpcCAqbmFuZCkKPiArewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210 ZChuYW5kKTsKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9f bWVzb25fbmFuZChuYW5kKTsKPiArCXUzMiBwYWdlX2J5dGVzLCBpbmZvX2J5dGVzLCBuc2VjdG9y czsKPiArCj4gKwluc2VjdG9ycyA9IG10ZC0+d3JpdGVzaXplIC8gbmFuZC0+ZWNjLnNpemU7Cj4g Kwo+ICsJcGFnZV9ieXRlcyA9ICBtdGQtPndyaXRlc2l6ZSArIG10ZC0+b29ic2l6ZTsKPiArCWlu Zm9fYnl0ZXMgPSBuc2VjdG9ycyAqIFBFUl9JTkZPX0JZVEU7Cj4gKwo+ICsJbWVzb25fY2hpcC0+ ZGF0YV9idWYgPSBrbWFsbG9jKHBhZ2VfYnl0ZXMsIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFtZXNv bl9jaGlwLT5kYXRhX2J1ZikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwltZXNvbl9jaGlw LT5pbmZvX2J1ZiA9IGttYWxsb2MoaW5mb19ieXRlcywgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIW1l c29uX2NoaXAtPmluZm9fYnVmKSB7Cj4gKwkJa2ZyZWUobWVzb25fY2hpcC0+ZGF0YV9idWYpOwo+ ICsJCXJldHVybiAtRU5PTUVNOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtz dGF0aWMKPiAraW50IG1lc29uX25mY19zZXR1cF9kYXRhX2ludGVyZmFjZShzdHJ1Y3QgbmFuZF9j aGlwICpuYW5kLCBpbnQgY3NsaW5lLAo+ICsJCQkJICAgY29uc3Qgc3RydWN0IG5hbmRfZGF0YV9p bnRlcmZhY2UgKmNvbmYpCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNv bl9jaGlwID0gdG9fbWVzb25fbmFuZChuYW5kKTsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX3Nkcl90 aW1pbmdzICp0aW1pbmdzOwo+ICsJdTMyIGRpdiwgYnRfbWluLCBidF9tYXgsIHRiZXJzX2Nsb2Nr czsKPiArCj4gKwl0aW1pbmdzID0gbmFuZF9nZXRfc2RyX3RpbWluZ3MoY29uZik7Cj4gKwlpZiAo SVNfRVJSKHRpbWluZ3MpKQo+ICsJCXJldHVybiAtRU5PVFNVUFA7Cj4gKwo+ICsJaWYgKGNzbGlu ZSA9PSBOQU5EX0RBVEFfSUZBQ0VfQ0hFQ0tfT05MWSkKPiArCQlyZXR1cm4gMDsKPiArCj4gKwlk aXYgPSBESVZfUk9VTkRfVVAoKHRpbWluZ3MtPnRSQ19taW4gLyAxMDAwKSwgTkZDX0NMS19DWUNM RSk7Cj4gKwlidF9taW4gPSAodGltaW5ncy0+dFJFQV9tYXggKyBORkNfREVGQVVMVF9ERUxBWSkg LyBkaXY7Cj4gKwlidF9tYXggPSAoTkZDX0RFRkFVTFRfREVMQVkgKyB0aW1pbmdzLT50UkhPSF9t aW4gKwo+ICsJCSAgdGltaW5ncy0+dFJDX21pbiAvIDIpIC8gZGl2Owo+ICsKPiArCW1lc29uX2No aXAtPnR3YiA9IERJVl9ST1VORF9VUChQU0VDX1RPX05TRUModGltaW5ncy0+dFdCX21heCksCj4g KwkJCQkgICAgICAgZGl2ICogTkZDX0NMS19DWUNMRSk7Cj4gKwltZXNvbl9jaGlwLT50YWRsID0g RElWX1JPVU5EX1VQKFBTRUNfVE9fTlNFQyh0aW1pbmdzLT50QURMX21pbiksCj4gKwkJCQkJZGl2 ICogTkZDX0NMS19DWUNMRSk7Cj4gKwl0YmVyc19jbG9ja3MgPSBESVZfUk9VTkRfVVAoUFNFQ19U T19OU0VDKHRpbWluZ3MtPnRCRVJTX21heCksCj4gKwkJCQkgICAgZGl2ICogTkZDX0NMS19DWUNM RSk7Cj4gKwltZXNvbl9jaGlwLT50YmVyc19tYXggPSBpbG9nMih0YmVyc19jbG9ja3MpOwo+ICsJ aWYgKCFpc19wb3dlcl9vZl8yKHRiZXJzX2Nsb2NrcykpCj4gKwkJbWVzb25fY2hpcC0+dGJlcnNf bWF4Kys7Cj4gKwo+ICsJYnRfbWluID0gRElWX1JPVU5EX1VQKGJ0X21pbiwgMTAwMCk7Cj4gKwli dF9tYXggPSBESVZfUk9VTkRfVVAoYnRfbWF4LCAxMDAwKTsKPiArCj4gKwlpZiAoYnRfbWF4IDwg YnRfbWluKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCW1lc29uX2NoaXAtPmxldmVsMV9k aXZpZGVyID0gZGl2Owo+ICsJbWVzb25fY2hpcC0+Y2xrX3JhdGUgPSAxMDAwMDAwMDAwIC8gbWVz b25fY2hpcC0+bGV2ZWwxX2RpdmlkZXI7Cj4gKwltZXNvbl9jaGlwLT5idXNfdGltaW5nID0gKGJ0 X21pbiArIGJ0X21heCkgLyAyICsgMTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBtZXNvbl9uYW5kX2JjaF9tb2RlKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQpCj4gK3sK PiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVzb25fbmFu ZChuYW5kKTsKPiArCXN0cnVjdCBtZXNvbl9uYW5kX2VjYyBtZXNvbl9lY2NbXSA9IHsKPiArCQlN RVNPTl9FQ0NfREFUQShORkNfRUNDX0JDSDhfMUssIDgpLAo+ICsJCU1FU09OX0VDQ19EQVRBKE5G Q19FQ0NfQkNIMjRfMUssIDI0KSwKPiArCQlNRVNPTl9FQ0NfREFUQShORkNfRUNDX0JDSDMwXzFL LCAzMCksCj4gKwkJTUVTT05fRUNDX0RBVEEoTkZDX0VDQ19CQ0g0MF8xSywgNDApLAo+ICsJCU1F U09OX0VDQ19EQVRBKE5GQ19FQ0NfQkNINTBfMUssIDUwKSwKPiArCQlNRVNPTl9FQ0NfREFUQShO RkNfRUNDX0JDSDYwXzFLLCA2MCksCj4gKwl9OwoKTWF5YmUgdGhpcyBhcnJheSBjb3VsZCBiZSBz dGF0aWM/Cgo+ICsJaW50IGk7Cj4gKwo+ICsJaWYgKG5hbmQtPmVjYy5zdHJlbmd0aCA+IDYwIHx8 IG5hbmQtPmVjYy5zdHJlbmd0aCA8IDgpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJZm9y IChpID0gMDsgaSA8IHNpemVvZihtZXNvbl9lY2MpOyBpKyspIHsKPiArCQlpZiAobWVzb25fZWNj W2ldLnN0cmVuZ3RoID09IG5hbmQtPmVjYy5zdHJlbmd0aCkgewo+ICsJCQltZXNvbl9jaGlwLT5i Y2hfbW9kZSA9IG1lc29uX2VjY1tpXS5iY2g7Cj4gKwkJCXJldHVybiAwOwo+ICsJCX0KPiArCX0K PiArCj4gKwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uYW5k X2F0dGFjaF9jaGlwKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQpCj4gK3sKPiArCXN0cnVjdCBtZXNv bl9uZmMgKm5mYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPiArCXN0cnVjdCBt ZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVzb25fbmFuZChuYW5kKTsKPiAr CXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwlpbnQgbnNlY3Rv cnMgPSBtdGQtPndyaXRlc2l6ZSAvIDEwMjQ7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWlmICghbXRk LT5uYW1lKSB7Cj4gKwkJbXRkLT5uYW1lID0gZGV2bV9rYXNwcmludGYobmZjLT5kZXYsIEdGUF9L RVJORUwsCj4gKwkJCQkJICAgIiVzOm5hbmQlZCIsCj4gKwkJCQkJICAgZGV2X25hbWUobmZjLT5k ZXYpLAo+ICsJCQkJCSAgIG1lc29uX2NoaXAtPnNlbHNbMF0pOwo+ICsJCWlmICghbXRkLT5uYW1l KQo+ICsJCQlyZXR1cm4gLUVOT01FTTsKPiArCX0KPiArCj4gKwlpZiAobmFuZC0+YmJ0X29wdGlv bnMgJiBOQU5EX0JCVF9VU0VfRkxBU0gpCj4gKwkJbmFuZC0+YmJ0X29wdGlvbnMgfD0gTkFORF9C QlRfTk9fT09COwo+ICsKPiArCW5hbmQtPm9wdGlvbnMgfD0gTkFORF9OT19TVUJQQUdFX1dSSVRF Owo+ICsKPiArCXJldCA9IG5hbmRfZWNjX2Nob29zZV9jb25mKG5hbmQsIG5mYy0+ZGF0YS0+ZWNj X2NhcHMsCj4gKwkJCQkgICBtdGQtPm9vYnNpemUgLSAyICogbnNlY3RvcnMpOwo+ICsJaWYgKHJl dCkgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICJmYWlsZWQgdG8gZWNjIGluaXRcbiIpOwo+ICsJ CXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCXJldCA9IG1lc29uX25hbmRfYmNoX21vZGUo bmFuZCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCW5hbmQtPmVj Yy5tb2RlID0gTkFORF9FQ0NfSFc7Cj4gKwluYW5kLT5lY2Mud3JpdGVfcGFnZV9yYXcgPSBtZXNv bl9uZmNfd3JpdGVfcGFnZV9yYXc7Cj4gKwluYW5kLT5lY2Mud3JpdGVfcGFnZSA9IG1lc29uX25m Y193cml0ZV9wYWdlX2h3ZWNjOwo+ICsJbmFuZC0+ZWNjLndyaXRlX29vYl9yYXcgPSBuYW5kX3dy aXRlX29vYl9zdGQ7Cj4gKwluYW5kLT5lY2Mud3JpdGVfb29iID0gbmFuZF93cml0ZV9vb2Jfc3Rk Owo+ICsKPiArCW5hbmQtPmVjYy5yZWFkX3BhZ2VfcmF3ID0gbWVzb25fbmZjX3JlYWRfcGFnZV9y YXc7Cj4gKwluYW5kLT5lY2MucmVhZF9wYWdlID0gbWVzb25fbmZjX3JlYWRfcGFnZV9od2VjYzsK PiArCW5hbmQtPmVjYy5yZWFkX29vYl9yYXcgPSBtZXNvbl9uZmNfcmVhZF9vb2JfcmF3Owo+ICsJ bmFuZC0+ZWNjLnJlYWRfb29iID0gbWVzb25fbmZjX3JlYWRfb29iOwo+ICsKPiArCWlmIChuYW5k LT5vcHRpb25zICYgTkFORF9CVVNXSURUSF8xNikgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICIx NmJpdHMgYnVzd2lkdGggbm90IHN1cHBvcnRlZCIpOwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJ fQo+ICsJbWVzb25fY2hpcF9idWZmZXJfaW5pdChuYW5kKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0 dXJuIC1FTk9NRU07Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBuYW5kX2NvbnRyb2xsZXJfb3BzIG1lc29uX25hbmRfY29udHJvbGxlcl9vcHMgPSB7 Cj4gKwkuYXR0YWNoX2NoaXAgPSBtZXNvbl9uYW5kX2F0dGFjaF9jaGlwLAoKRG9uJ3QgeW91IG5l ZWQgYSAtPmRldGFjaF9jaGlwIGhvb2sgdG8gZnJlZSBkYXRhX2J1Zi9pbmZvX2J1ZgpidWZmZXJz PwoKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQKPiArbWVzb25fbmZjX25hbmRfY2hpcF9pbml0KHN0 cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJIHN0cnVjdCBtZXNvbl9uZmMgKm5mYywgc3RydWN0IGRl dmljZV9ub2RlICpucCkKPiArewo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29u X2NoaXA7Cj4gKwlzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kOwo+ICsJc3RydWN0IG10ZF9pbmZvICpt dGQ7Cj4gKwlpbnQgcmV0LCBpOwo+ICsJdTMyIHRtcCwgbnNlbHM7Cj4gKwo+ICsJaWYgKCFvZl9n ZXRfcHJvcGVydHkobnAsICJyZWciLCAmbnNlbHMpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsK PiArCW5zZWxzIC89IHNpemVvZih1MzIpOwo+ICsJaWYgKCFuc2VscyB8fCBuc2VscyA+IE1BWF9D RV9OVU0pIHsKPiArCQlkZXZfZXJyKGRldiwgImludmFsaWQgcmVnIHByb3BlcnR5IHNpemVcbiIp Owo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCW1lc29uX2NoaXAgPSBkZXZtX2t6 YWxsb2MoZGV2LAo+ICsJCQkJICBzaXplb2YoKm1lc29uX2NoaXApICsgKG5zZWxzICogc2l6ZW9m KHU4KSksCj4gKwkJCQkgIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFtZXNvbl9jaGlwKQo+ICsJCXJl dHVybiAtRU5PTUVNOwo+ICsKPiArCW1lc29uX2NoaXAtPm5zZWxzID0gbnNlbHM7Cj4gKwo+ICsJ Zm9yIChpID0gMDsgaSA8IG5zZWxzOyBpKyspIHsKPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFk X3UzMl9pbmRleChucCwgInJlZyIsIGksICZ0bXApOwo+ICsJCWlmIChyZXQpIHsKPiArCQkJZGV2 X2VycihkZXYsICJjb3VsZCBub3QgcmV0cmlldmUgcmVnIHByb3BlcnR5OiAlZFxuIiwKPiArCQkJ CXJldCk7Cj4gKwkJCXJldHVybiByZXQ7Cj4gKwkJfQo+ICsKPiArCQlpZiAodGVzdF9hbmRfc2V0 X2JpdCh0bXAsICZuZmMtPmFzc2lnbmVkX2NzKSkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkNTICVk IGFscmVhZHkgYXNzaWduZWRcbiIsIHRtcCk7Cj4gKwkJCXJldHVybiAtRUlOVkFMOwo+ICsJCX0K PiArCX0KPiArCj4gKwluYW5kID0gJm1lc29uX2NoaXAtPm5hbmQ7Cj4gKwluYW5kLT5jb250cm9s bGVyID0gJm5mYy0+Y29udHJvbGxlcjsKPiArCW5hbmQtPmNvbnRyb2xsZXItPm9wcyA9ICZtZXNv bl9uYW5kX2NvbnRyb2xsZXJfb3BzOwo+ICsJbmFuZF9zZXRfZmxhc2hfbm9kZShuYW5kLCBucCk7 Cj4gKwluYW5kX3NldF9jb250cm9sbGVyX2RhdGEobmFuZCwgbmZjKTsKPiArCj4gKwluYW5kLT5v cHRpb25zIHw9IE5BTkRfVVNFX0JPVU5DRV9CVUZGRVI7Cj4gKwluYW5kLT5zZWxlY3RfY2hpcCA9 IG1lc29uX25mY19zZWxlY3RfY2hpcDsKPiArCW5hbmQtPmV4ZWNfb3AgPSBtZXNvbl9uZmNfZXhl Y19vcDsKPiArCW5hbmQtPnNldHVwX2RhdGFfaW50ZXJmYWNlID0gbWVzb25fbmZjX3NldHVwX2Rh dGFfaW50ZXJmYWNlOwo+ICsJbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwltdGQtPm93bmVy ID0gVEhJU19NT0RVTEU7Cj4gKwltdGQtPmRldi5wYXJlbnQgPSBkZXY7Cj4gKwo+ICsJcmV0ID0g bmFuZF9zY2FuKG5hbmQsIG5zZWxzKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiAr Cj4gKwlyZXQgPSBtdGRfZGV2aWNlX3JlZ2lzdGVyKG10ZCwgTlVMTCwgMCk7Cj4gKwlpZiAocmV0 KSB7Cj4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcmVnaXN0ZXIgbXRkIGRldmljZTogJWRc biIsIHJldCk7Cj4gKwkJbmFuZF9jbGVhbnVwKG5hbmQpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9 Cj4gKwo+ICsJbGlzdF9hZGRfdGFpbCgmbWVzb25fY2hpcC0+bm9kZSwgJm5mYy0+Y2hpcHMpOwo+ ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX25mY19uYW5kX2No aXBfY2xlYW51cChzdHJ1Y3QgbWVzb25fbmZjICpuZmMpCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9u ZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwOwo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQ7Cj4gKwlp bnQgcmV0Owo+ICsKPiArCXdoaWxlICghbGlzdF9lbXB0eSgmbmZjLT5jaGlwcykpIHsKPiArCQlt ZXNvbl9jaGlwID0gbGlzdF9maXJzdF9lbnRyeSgmbmZjLT5jaGlwcywKPiArCQkJCQkgICAgICBz dHJ1Y3QgbWVzb25fbmZjX25hbmRfY2hpcCwgbm9kZSk7Cj4gKwkJbXRkID0gbmFuZF90b19tdGQo Jm1lc29uX2NoaXAtPm5hbmQpOwo+ICsJCXJldCA9IG10ZF9kZXZpY2VfdW5yZWdpc3RlcihtdGQp Owo+ICsJCWlmIChyZXQpCj4gKwkJCXJldHVybiByZXQ7Cj4gKwo+ICsJCW1lc29uX25mY19mcmVl X2J1ZmZlcigmbWVzb25fY2hpcC0+bmFuZCk7Cj4gKwkJbmFuZF9jbGVhbnVwKCZtZXNvbl9jaGlw LT5uYW5kKTsKPiArCQlsaXN0X2RlbCgmbWVzb25fY2hpcC0+bm9kZSk7Cj4gKwl9Cj4gKwo+ICsJ cmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX25hbmRfY2hpcHNfaW5p dChzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gKwkJCQkgICAgIHN0cnVjdCBtZXNvbl9uZmMgKm5mYykK PiArewo+ICsJc3RydWN0IGRldmljZV9ub2RlICpucCA9IGRldi0+b2Zfbm9kZTsKPiArCXN0cnVj dCBkZXZpY2Vfbm9kZSAqbmFuZF9ucDsKPiArCWludCByZXQ7Cj4gKwo+ICsJZm9yX2VhY2hfY2hp bGRfb2Zfbm9kZShucCwgbmFuZF9ucCkgewo+ICsJCXJldCA9IG1lc29uX25mY19uYW5kX2NoaXBf aW5pdChkZXYsIG5mYywgbmFuZF9ucCk7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQltZXNvbl9uZmNf bmFuZF9jaGlwX2NsZWFudXAobmZjKTsKPiArCQkJcmV0dXJuIHJldDsKPiArCQl9Cj4gKwl9Cj4g Kwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBtZXNvbl9uZmNf aXJxKGludCBpcnEsIHZvaWQgKmlkKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmMgPSBp ZDsKPiArCXUzMiBjZmc7Cj4gKwo+ICsJY2ZnID0gcmVhZGwobmZjLT5yZWdfYmFzZSArIE5GQ19S RUdfQ0ZHKTsKPiArCWlmICghKGNmZyAmIE5GQ19SQl9JUlFfRU4pKQo+ICsJCXJldHVybiBJUlFf Tk9ORTsKPiArCj4gKwljZmcgJj0gfihORkNfUkJfSVJRX0VOKTsKPiArCXdyaXRlbChjZmcsIG5m Yy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NGRyk7Cj4gKwo+ICsJY29tcGxldGUoJm5mYy0+Y29tcGxl dGlvbik7Cj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgbWVzb25fbmZjX2RhdGEgbWVzb25fZ3hsX2RhdGEgPSB7Cj4gKwkuZWNjX2NhcHMgPSAm bWVzb25fZ3hsX2VjY19jYXBzLAo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBtZXNv bl9uZmNfZGF0YSBtZXNvbl9heGdfZGF0YSA9IHsKPiArCS5lY2NfY2FwcyA9ICZtZXNvbl9heGdf ZWNjX2NhcHMsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBt ZXNvbl9uZmNfaWRfdGFibGVbXSA9IHsKPiArCXsKPiArCQkuY29tcGF0aWJsZSA9ICJhbWxvZ2lj LG1lc29uLWd4bC1uZmMiLAo+ICsJCS5kYXRhID0gJm1lc29uX2d4bF9kYXRhLAo+ICsJfSwgewo+ ICsJCS5jb21wYXRpYmxlID0gImFtbG9naWMsbWVzb24tYXhnLW5mYyIsCj4gKwkJLmRhdGEgPSAm bWVzb25fYXhnX2RhdGEsCj4gKwl9LAo+ICsJe30KPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJM RShvZiwgbWVzb25fbmZjX2lkX3RhYmxlKTsKPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX3By b2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBkZXZpY2Ug KmRldiA9ICZwZGV2LT5kZXY7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmM7Cj4gKwlzdHJ1Y3Qg cmVzb3VyY2UgKnJlczsKPiArCWludCByZXQsIGlycTsKPiArCj4gKwluZmMgPSBkZXZtX2t6YWxs b2MoZGV2LCBzaXplb2YoKm5mYyksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFuZmMpCj4gKwkJcmV0 dXJuIC1FTk9NRU07Cj4gKwo+ICsJbmZjLT5kYXRhID0gb2ZfZGV2aWNlX2dldF9tYXRjaF9kYXRh KCZwZGV2LT5kZXYpOwo+ICsJaWYgKCFuZmMtPmRhdGEpCj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4g Kwo+ICsJbmFuZF9jb250cm9sbGVyX2luaXQoJm5mYy0+Y29udHJvbGxlcik7Cj4gKwlJTklUX0xJ U1RfSEVBRCgmbmZjLT5jaGlwcyk7Cj4gKwo+ICsJbmZjLT5kZXYgPSBkZXY7Cj4gKwo+ICsJcmVz ID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKPiArCW5m Yy0+cmVnX2Jhc2UgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCByZXMpOwo+ICsJaWYgKElT X0VSUihuZmMtPnJlZ19iYXNlKSkKPiArCQlyZXR1cm4gUFRSX0VSUihuZmMtPnJlZ19iYXNlKTsK PiArCj4gKwluZmMtPnJlZ19jbGsgPQo+ICsJCXN5c2Nvbl9yZWdtYXBfbG9va3VwX2J5X3BoYW5k bGUoZGV2LT5vZl9ub2RlLAo+ICsJCQkJCQkiYW1sb2dpYyxtbWMtc3lzY29uIik7Cj4gKwlpZiAo SVNfRVJSKG5mYy0+cmVnX2NsaykpIHsKPiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBsb29r dXAgY2xvY2sgYmFzZVxuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIobmZjLT5yZWdfY2xrKTsKPiAr CX0KPiArCj4gKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwo+ICsJaWYgKGlycSA8 IDApIHsKPiArCQlkZXZfZXJyKGRldiwgIm5vIG5maSBpcnEgcmVzb3VyY2VcbiIpOwo+ICsJCXJl dHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCXJldCA9IG1lc29uX25mY19jbGtfaW5pdChuZmMp Owo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGluaXRpYWxpemUg bmFuZCBjbGtcbiIpOwo+ICsJCWdvdG8gZXJyOwoKVXNlbGVzcyBnb3RvLCBhIHJldHVybiB3b3Vs ZCBiZSBlbm91Z2guCgo+ICsJfQo+ICsKPiArCXdyaXRlbCgwLCBuZmMtPnJlZ19iYXNlICsgTkZD X1JFR19DRkcpOwo+ICsJcmV0ID0gZGV2bV9yZXF1ZXN0X2lycShkZXYsIGlycSwgbWVzb25fbmZj X2lycSwgMCwgZGV2X25hbWUoZGV2KSwgbmZjKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJy KGRldiwgImZhaWxlZCB0byByZXF1ZXN0IG5maSBpcnFcbiIpOwo+ICsJCXJldCA9IC1FSU5WQUw7 Cj4gKwkJZ290byBlcnJfY2xrOwo+ICsJfQo+ICsKPiArCXJldCA9IGRtYV9zZXRfbWFzayhkZXYs IERNQV9CSVRfTUFTSygzMikpOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFp bGVkIHRvIHNldCBkbWEgbWFza1xuIik7CgpOaXQ6IEkgcHJlZmVyIHdoZW4gYWNyb255bXMgYXJl IHVwcGVyIGNhc2UgaW4gcGxhaW4gRW5nbGlzaCAoRE1BLCBOQU5ELApJUlEsIGV0YykuCgo+ICsJ CWdvdG8gZXJyX2NsazsKPiArCX0KPiArCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBu ZmMpOwo+ICsKPiArCXJldCA9IG1lc29uX25mY19uYW5kX2NoaXBzX2luaXQoZGV2LCBuZmMpOwo+ ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGluaXQgbmFuZCBjaGlw c1xuIik7Cj4gKwkJZ290byBlcnJfY2xrOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICsKPiAr ZXJyX2NsazoKPiArCW1lc29uX25mY19kaXNhYmxlX2NsayhuZmMpOwo+ICtlcnI6CgpUaGlzIGdv dG8gY2FuIGJlIHJlbW92ZWQuCgo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBtZXNvbl9uZmNfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiAr CXN0cnVjdCBtZXNvbl9uZmMgKm5mYyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ICsJ aW50IHJldDsKPiArCj4gKwlyZXQgPSBtZXNvbl9uZmNfbmFuZF9jaGlwX2NsZWFudXAobmZjKTsK PiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwltZXNvbl9uZmNfZGlzYWJsZV9j bGsobmZjKTsKPiArCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKPiArCj4g KwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbWVz b25fbmZjX2RyaXZlciA9IHsKPiArCS5wcm9iZSAgPSBtZXNvbl9uZmNfcHJvYmUsCj4gKwkucmVt b3ZlID0gbWVzb25fbmZjX3JlbW92ZSwKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgID0gIm1l c29uLW5hbmQiLAo+ICsJCS5vZl9tYXRjaF90YWJsZSA9IG1lc29uX25mY19pZF90YWJsZSwKPiAr CX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIobWVzb25fbmZjX2RyaXZlcik7Cj4g Kwo+ICtNT0RVTEVfTElDRU5TRSgiRHVhbCBNSVQvR1BMIik7Cj4gK01PRFVMRV9BVVRIT1IoIkxp YW5nIFlhbmcgPGxpYW5nLnlhbmdAYW1sb2dpYy5jb20+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElP TigiQW1sb2dpYydzIE1lc29uIE5BTkQgRmxhc2ggQ29udHJvbGxlciBkcml2ZXIiKTsKCgoKClRo YW5rcywKTWlxdcOobAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0 cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGlu Zm8vbGludXgtYXJtLWtlcm5lbAo= 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=-7.0 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,T_DKIMWL_WL_HIGH 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 56B65C64EB1 for ; Fri, 7 Dec 2018 09:25:33 +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 2228F20838 for ; Fri, 7 Dec 2018 09:25:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="lybcMY9j" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2228F20838 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-amlogic-bounces+linux-amlogic=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:MIME-Version:References:In-Reply-To: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zl1IasfRL5Fxdw/AMB1kXgTvWOUlwkx/G8QINAGyQ/w=; b=lybcMY9j60hsyT 35yo4+KB52mZuwT99fhqLcY7CrOOK1Ml/cfggaFXbdHjlFmt5jsO3jt0eRtRg+7bWc8Fp+agLOgRk 0eb99OZ/SWmP6sb0YSeZ6KohM1K9pCCbp4SS9lUxy/WaoWZzpGi73ncT6d/19l6pnNGn+/QVflnWC I5IxTd6oEZp1aNmWa7xH9qktXqwj2pMKTk12neGUcfwujaBPs4/mMJBiT1jbUs/5VEtFkXA/Z95ll kDY5W/GWJFSPgwz5RZC/O8P1fhcJbUtk8npMGdTMVv8eNVpXCvo7ChK0zydR09ZlinOk08Hj0POLI pOjSS2M9qtfN2Ln3Q9ZQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCNw-0000Ar-8n; Fri, 07 Dec 2018 09:25:24 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCNr-00006Y-6D; Fri, 07 Dec 2018 09:25:22 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 8569320834; Fri, 7 Dec 2018 10:25:07 +0100 (CET) Received: from xps13 (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id EC03720701; Fri, 7 Dec 2018 10:24:56 +0100 (CET) Date: Fri, 7 Dec 2018 10:24:56 +0100 From: Miquel Raynal To: Jianxin Pan Subject: Re: [PATCH v7 2/2] mtd: rawnand: meson: add support for Amlogic NAND flash controller Message-ID: <20181207102456.1dc67e07@xps13> In-Reply-To: <1542386439-30166-3-git-send-email-jianxin.pan@amlogic.com> References: <1542386439-30166-1-git-send-email-jianxin.pan@amlogic.com> <1542386439-30166-3-git-send-email-jianxin.pan@amlogic.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.1 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012519_652192_E666D93C X-CRM114-Status: GOOD ( 26.17 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Hanjie Lin , Victor Wan , Marek Vasut , Martin Blumenstingl , Richard Weinberger , Neil Armstrong , Yixun Lan , linux-kernel@vger.kernel.org, Boris Brezillon , Jian Hu , Liang Yang , linux-mtd@lists.infradead.org, Kevin Hilman , Carlo Caione , linux-amlogic@lists.infradead.org, Brian Norris , David Woodhouse , linux-arm-kernel@lists.infradead.org, Jerome Brunet Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org SGkgSmlhbnhpbiwKCkxvb2tzIGdvb2QgdG8gbWUgb3ZlcmFsbCwgYSBmZXcgY29tbWVudHMgaW5s aW5lLgoKSmlhbnhpbiBQYW4gPGppYW54aW4ucGFuQGFtbG9naWMuY29tPiB3cm90ZSBvbiBTYXQs IDE3IE5vdiAyMDE4CjAwOjQwOjM4ICswODAwOgoKPiBGcm9tOiBMaWFuZyBZYW5nIDxsaWFuZy55 YW5nQGFtbG9naWMuY29tPgo+IAo+IEFkZCBpbml0aWFsIHN1cHBvcnQgZm9yIHRoZSBBbWxvZ2lj IE5BTkQgZmxhc2ggY29udHJvbGxlciB3aGljaCBmb3VuZAo+IGluIHRoZSBNZXNvbi1HWEJCL0dY TC9BWEcgU29Dcy4KPiAKPiBTaWduZWQtb2ZmLWJ5OiBMaWFuZyBZYW5nIDxsaWFuZy55YW5nQGFt bG9naWMuY29tPgo+IFNpZ25lZC1vZmYtYnk6IFlpeHVuIExhbiA8eWl4dW4ubGFuQGFtbG9naWMu Y29tPgo+IFNpZ25lZC1vZmYtYnk6IEppYW54aW4gUGFuIDxqaWFueGluLnBhbkBhbWxvZ2ljLmNv bT4KPiAtLS0KPiAgZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZyAgICAgIHwgICAxMCArCj4g IGRyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlICAgICB8ICAgIDEgKwo+ICBkcml2ZXJzL210 ZC9uYW5kL3Jhdy9tZXNvbl9uYW5kLmMgfCAxNDE3ICsrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysKPiAgMyBmaWxlcyBjaGFuZ2VkLCAxNDI4IGluc2VydGlvbnMoKykKPiAgY3Jl YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbXRkL25hbmQvcmF3L21lc29uX25hbmQuYwo+IAo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnIGIvZHJpdmVycy9tdGQvbmFu ZC9yYXcvS2NvbmZpZwo+IGluZGV4IGM3ZWZjMzEuLjIyM2IwNDEgMTAwNjQ0Cj4gLS0tIGEvZHJp dmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L0tj b25maWcKPiBAQCAtNTQxLDQgKzU0MSwxNCBAQCBjb25maWcgTVREX05BTkRfVEVHUkEKPiAgCSAg aXMgc3VwcG9ydGVkLiBFeHRyYSBPT0IgYnl0ZXMgd2hlbiB1c2luZyBIVyBFQ0MgYXJlIGN1cnJl bnRseQo+ICAJICBub3Qgc3VwcG9ydGVkLgo+ICAKPiArY29uZmlnIE1URF9OQU5EX01FU09OCj4g Kwl0cmlzdGF0ZSAiU3VwcG9ydCBmb3IgTkFORCBjb250cm9sbGVyIG9uIEFtbG9naWMncyBNZXNv biBTb0NzIgo+ICsJZGVwZW5kcyBvbiBBUkNIX01FU09OIHx8IENPTVBJTEVfVEVTVAo+ICsJZGVw ZW5kcyBvbiBDT01NT05fQ0xLX0FNTE9HSUMKPiArCXNlbGVjdCBDT01NT05fQ0xLX1JFR01BUF9N RVNPTgo+ICsJc2VsZWN0IE1GRF9TWVNDT04KPiArCWhlbHAKPiArCSAgRW5hYmxlcyBzdXBwb3J0 IGZvciBOQU5EIGNvbnRyb2xsZXIgb24gQW1sb2dpYydzIE1lc29uIFNvQ3MuCj4gKwkgIFRoaXMg Y29udHJvbGxlciBpcyBmb3VuZCBvbiBNZXNvbiBHWEJCLCBHWEwsIEFYRyBTb0NzLgo+ICsKPiAg ZW5kaWYgIyBNVERfTkFORAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtl ZmlsZSBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4gaW5kZXggNTcxNTliMy4uYTJj YzJmZSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZQo+ICsrKyBi L2RyaXZlcnMvbXRkL25hbmQvcmF3L01ha2VmaWxlCj4gQEAgLTU2LDYgKzU2LDcgQEAgb2JqLSQo Q09ORklHX01URF9OQU5EX0JSQ01OQU5EKQkJKz0gYnJjbW5hbmQvCj4gIG9iai0kKENPTkZJR19N VERfTkFORF9RQ09NKQkJKz0gcWNvbV9uYW5kYy5vCj4gIG9iai0kKENPTkZJR19NVERfTkFORF9N VEspCQkrPSBtdGtfZWNjLm8gbXRrX25hbmQubwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfVEVH UkEpCQkrPSB0ZWdyYV9uYW5kLm8KPiArb2JqLSQoQ09ORklHX01URF9OQU5EX01FU09OKQkJKz0g bWVzb25fbmFuZC5vCj4gIAo+ICBuYW5kLW9ianMgOj0gbmFuZF9iYXNlLm8gbmFuZF9sZWdhY3ku byBuYW5kX2JidC5vIG5hbmRfdGltaW5ncy5vIG5hbmRfaWRzLm8KPiAgbmFuZC1vYmpzICs9IG5h bmRfb25maS5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQvcmF3L21lc29uX25hbmQu YyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L21lc29uX25hbmQuYwo+IG5ldyBmaWxlIG1vZGUgMTAw NjQ0Cj4gaW5kZXggMDAwMDAwMC4uYzU2NjYzNgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2 ZXJzL210ZC9uYW5kL3Jhdy9tZXNvbl9uYW5kLmMKPiBAQCAtMCwwICsxLDE0MTcgQEAKPiArLy8g U1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IChHUEwtMi4wKyBPUiBNSVQpCj4gKy8qCj4gKyAqIEFt bG9naWMgTWVzb24gTmFuZCBGbGFzaCBDb250cm9sbGVyIERyaXZlcgo+ICsgKgo+ICsgKiBDb3B5 cmlnaHQgKGMpIDIwMTggQW1sb2dpYywgaW5jLgo+ICsgKiBBdXRob3I6IExpYW5nIFlhbmcgPGxp YW5nLnlhbmdAYW1sb2dpYy5jb20+Cj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRm b3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9tdGQvcmF3bmFuZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbXRkL210ZC5oPgo+ ICsjaW5jbHVkZSA8bGludXgvbWZkL3N5c2Nvbi5oPgo+ICsjaW5jbHVkZSA8bGludXgvcmVnbWFw Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KPiArI2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4K PiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPgo+ICsKPiArI2RlZmluZSBORkNfUkVHX0NN RAkJMHgwMAo+ICsjZGVmaW5lIE5GQ19DTURfRFJECQkoMHg4IDw8IDE0KQo+ICsjZGVmaW5lIE5G Q19DTURfSURMRQkJKDB4YyA8PCAxNCkKPiArI2RlZmluZSBORkNfQ01EX0RXUgkJKDB4NCA8PCAx NCkKPiArI2RlZmluZSBORkNfQ01EX0NMRQkJKDB4NSA8PCAxNCkKPiArI2RlZmluZSBORkNfQ01E X0FMRQkJKDB4NiA8PCAxNCkKPiArI2RlZmluZSBORkNfQ01EX0FETAkJKCgwIDw8IDE2KSB8ICgz IDw8IDIwKSkKPiArI2RlZmluZSBORkNfQ01EX0FESAkJKCgxIDw8IDE2KSB8ICgzIDw8IDIwKSkK PiArI2RlZmluZSBORkNfQ01EX0FJTAkJKCgyIDw8IDE2KSB8ICgzIDw8IDIwKSkKPiArI2RlZmlu ZSBORkNfQ01EX0FJSAkJKCgzIDw8IDE2KSB8ICgzIDw8IDIwKSkKPiArI2RlZmluZSBORkNfQ01E X1NFRUQJCSgoOCA8PCAxNikgfCAoMyA8PCAyMCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9NMk4JCSgo MCA8PCAxNykgfCAoMiA8PCAyMCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9OMk0JCSgoMSA8PCAxNykg fCAoMiA8PCAyMCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9SQgkJQklUKDIwKQo+ICsjZGVmaW5lIE5G Q19DTURfSU82CQkoKDB4YiA8PCAxMCkgfCAoMSA8PCAxOCkpCj4gKyNkZWZpbmUgTkZDX0NNRF9T Q1JBTUJMRVJfRU5BQkxFCUJJVCgxOSkKPiArI2RlZmluZSBORkNfQ01EX1JCX0lOVAkJQklUKDE0 KQo+ICsKPiArI2RlZmluZSBORkNfQ01EX0dFVF9TSVpFKHgpCSgoKHgpID4+IDIyKSAmIEdFTk1B U0soNCwgMCkpCj4gKwo+ICsjZGVmaW5lIE5GQ19SRUdfQ0ZHCQkweDA0Cj4gKyNkZWZpbmUgTkZD X1JFR19EQURSCQkweDA4Cj4gKyNkZWZpbmUgTkZDX1JFR19JQURSCQkweDBjCj4gKyNkZWZpbmUg TkZDX1JFR19CVUYJCTB4MTAKPiArI2RlZmluZSBORkNfUkVHX0lORk8JCTB4MTQKPiArI2RlZmlu ZSBORkNfUkVHX0RDCQkweDE4Cj4gKyNkZWZpbmUgTkZDX1JFR19BRFIJCTB4MWMKPiArI2RlZmlu ZSBORkNfUkVHX0RMCQkweDIwCj4gKyNkZWZpbmUgTkZDX1JFR19ESAkJMHgyNAo+ICsjZGVmaW5l IE5GQ19SRUdfQ0FEUgkJMHgyOAo+ICsjZGVmaW5lIE5GQ19SRUdfU0FEUgkJMHgyYwo+ICsjZGVm aW5lIE5GQ19SRUdfUElOUwkJMHgzMAo+ICsjZGVmaW5lIE5GQ19SRUdfVkVSCQkweDM4Cj4gKwo+ ICsjZGVmaW5lIE5GQ19SQl9JUlFfRU4JCUJJVCgyMSkKPiArI2RlZmluZSBORkNfSU5UX01BU0sJ CSgzIDw8IDIwKQo+ICsKPiArI2RlZmluZSBDTURSV0dFTihjbWRfZGlyLCByYW4sIGJjaCwgc2hv cnRfbW9kZSwgcGFnZV9zaXplLCBwYWdlcykJXAo+ICsJKAkJCQkJCQkJXAo+ICsJCShjbWRfZGly KQkJCXwJCQlcCj4gKwkJKChyYW4pIDw8IDE5KQkJCXwJCQlcCj4gKwkJKChiY2gpIDw8IDE0KQkJ CXwJCQlcCj4gKwkJKChzaG9ydF9tb2RlKSA8PCAxMykJCXwJCQlcCj4gKwkJKCgocGFnZV9zaXpl KSAmIDB4N2YpIDw8IDYpCXwJCQlcCj4gKwkJKChwYWdlcykgJiAweDNmKQkJCQkJXAo+ICsJKQo+ ICsKPiArI2RlZmluZSBHRU5DTUREQUREUkwoYWRsLCBhZGRyKQkJKChhZGwpIHwgKChhZGRyKSAm IDB4ZmZmZikpCj4gKyNkZWZpbmUgR0VOQ01EREFERFJIKGFkaCwgYWRkcikJCSgoYWRoKSB8ICgo KGFkZHIpID4+IDE2KSAmIDB4ZmZmZikpCj4gKyNkZWZpbmUgR0VOQ01ESUFERFJMKGFpbCwgYWRk cikJCSgoYWlsKSB8ICgoYWRkcikgJiAweGZmZmYpKQo+ICsjZGVmaW5lIEdFTkNNRElBRERSSChh aWgsIGFkZHIpCQkoKGFpaCkgfCAoKChhZGRyKSA+PiAxNikgJiAweGZmZmYpKQo+ICsKPiArI2Rl ZmluZSBSQl9TVEEoeCkJCSgxIDw8ICgyNiArICh4KSkpCj4gKyNkZWZpbmUgRE1BX0RJUihkaXIp CQkoKGRpcikgPyBORkNfQ01EX04yTSA6IE5GQ19DTURfTTJOKQo+ICsKPiArI2RlZmluZSBFQ0Nf Q0hFQ0tfUkVUVVJOX0ZGCSgtMSkKPiArCj4gKyNkZWZpbmUgTkFORF9DRTAJCSgweGUgPDwgMTAp Cj4gKyNkZWZpbmUgTkFORF9DRTEJCSgweGQgPDwgMTApCj4gKwo+ICsjZGVmaW5lIERNQV9CVVNZ X1RJTUVPVVQJMHgxMDAwMDAKPiArI2RlZmluZSBDTURfRklGT19FTVBUWV9USU1FT1VUCTEwMDAK PiArCj4gKyNkZWZpbmUgTUFYX0NFX05VTQkJMgo+ICsKPiArLyogZU1NQyBjbG9jayByZWdpc3Rl ciwgbWlzYyBjb250cm9sICovCj4gKyNkZWZpbmUgU0RfRU1NQ19DTE9DSwkJMHgwMAo+ICsjZGVm aW5lIENMS19BTFdBWVNfT04JCUJJVCgyOCkKPiArI2RlZmluZSBDTEtfU0VMRUNUX05BTkQJCUJJ VCgzMSkKPiArI2RlZmluZSBDTEtfRElWX01BU0sJCUdFTk1BU0soNSwgMCkKPiArCj4gKyNkZWZp bmUgTkZDX0NMS19DWUNMRQkJNgo+ICsKPiArLyogbmFuZCBmbGFzaCBjb250cm9sbGVyIGRlbGF5 IDMgbnMgKi8KPiArI2RlZmluZSBORkNfREVGQVVMVF9ERUxBWQkzMDAwCj4gKwo+ICsjZGVmaW5l IE1BWF9FQ0NfSU5ERVgJCTEwCj4gKwo+ICsjZGVmaW5lIE1VWF9DTEtfTlVNX1BBUkVOVFMJMgo+ ICsKPiArI2RlZmluZSBST1dfQURERVIocGFnZSwgaW5kZXgpCSgoKHBhZ2UpID4+ICg4ICogKGlu ZGV4KSkpICYgMHhmZikKPiArI2RlZmluZSBNQVhfQ1lDTEVfQUREUlMJCTUKPiArI2RlZmluZSBE SVJSRUFECQkJMQo+ICsjZGVmaW5lIERJUldSSVRFCQkwCj4gKwo+ICsjZGVmaW5lIEVDQ19QQVJJ VFlfQkNIOF81MTJCCTE0Cj4gKwo+ICsjZGVmaW5lIFBFUl9JTkZPX0JZVEUJCTgKPiArCj4gKyNk ZWZpbmUgRUNDX0NPTVBMRVRFICAgICAgICAgICAgQklUKDMxKQo+ICsjZGVmaW5lIEVDQ19FUlJf Q05UKHgpCQkoKCh4KSA+PiAyNCkgJiBHRU5NQVNLKDUsIDApKQo+ICsjZGVmaW5lIEVDQ19aRVJP X0NOVCh4KQkJKCgoeCkgPj4gMTYpICYgR0VOTUFTSyg1LCAwKSkKPiArCj4gK3N0cnVjdCBtZXNv bl9uZmNfbmFuZF9jaGlwIHsKPiArCXN0cnVjdCBsaXN0X2hlYWQgbm9kZTsKPiArCXN0cnVjdCBu YW5kX2NoaXAgbmFuZDsKPiArCXVuc2lnbmVkIGxvbmcgY2xrX3JhdGU7Cj4gKwl1bnNpZ25lZCBs b25nIGxldmVsMV9kaXZpZGVyOwo+ICsJdTMyIGJ1c190aW1pbmc7Cj4gKwl1MzIgdHdiOwo+ICsJ dTMyIHRhZGw7Cj4gKwl1MzIgdGJlcnNfbWF4Owo+ICsKPiArCXUzMiBiY2hfbW9kZTsKPiArCXU4 ICpkYXRhX2J1ZjsKPiArCV9fbGU2NCAqaW5mb19idWY7Cj4gKwl1MzIgbnNlbHM7Cj4gKwl1OCBz ZWxzWzBdOwo+ICt9Owo+ICsKPiArc3RydWN0IG1lc29uX25hbmRfZWNjIHsKPiArCXUzMiBiY2g7 Cj4gKwl1MzIgc3RyZW5ndGg7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgbWVzb25fbmZjX2RhdGEgewo+ ICsJY29uc3Qgc3RydWN0IG5hbmRfZWNjX2NhcHMgKmVjY19jYXBzOwo+ICt9Owo+ICsKPiArc3Ry dWN0IG1lc29uX25mY19wYXJhbSB7Cj4gKwl1MzIgY2hpcF9zZWxlY3Q7Cj4gKwl1MzIgcmJfc2Vs ZWN0Owo+ICt9Owo+ICsKPiArc3RydWN0IG5hbmRfcndfY21kIHsKPiArCXUzMiBjbWQwOwo+ICsJ dTMyIGFkZHJzW01BWF9DWUNMRV9BRERSU107Cj4gKwl1MzIgY21kMTsKPiArfTsKPiArCj4gK3N0 cnVjdCBuYW5kX3RpbWluZyB7Cj4gKwl1MzIgdHdiOwo+ICsJdTMyIHRhZGw7Cj4gKwl1MzIgdGJl cnNfbWF4Owo+ICt9Owo+ICsKPiArc3RydWN0IG1lc29uX25mYyB7Cj4gKwlzdHJ1Y3QgbmFuZF9j b250cm9sbGVyIGNvbnRyb2xsZXI7Cj4gKwlzdHJ1Y3QgY2xrICpjb3JlX2NsazsKPiArCXN0cnVj dCBjbGsgKmRldmljZV9jbGs7Cj4gKwlzdHJ1Y3QgY2xrICpwaGFzZV90eDsKPiArCXN0cnVjdCBj bGsgKnBoYXNlX3J4Owo+ICsKPiArCXVuc2lnbmVkIGxvbmcgY2xrX3JhdGU7Cj4gKwl1MzIgYnVz X3RpbWluZzsKPiArCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwl2b2lkIF9faW9tZW0gKnJl Z19iYXNlOwo+ICsJc3RydWN0IHJlZ21hcCAqcmVnX2NsazsKPiArCXN0cnVjdCBjb21wbGV0aW9u IGNvbXBsZXRpb247Cj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIGNoaXBzOwo+ICsJY29uc3Qgc3RydWN0 IG1lc29uX25mY19kYXRhICpkYXRhOwo+ICsJc3RydWN0IG1lc29uX25mY19wYXJhbSBwYXJhbTsK PiArCXN0cnVjdCBuYW5kX3RpbWluZyB0aW1pbmc7Cj4gKwl1bmlvbiB7Cj4gKwkJaW50IGNtZFsz Ml07Cj4gKwkJc3RydWN0IG5hbmRfcndfY21kIHJ3Owo+ICsJfSBjbWRmaWZvOwo+ICsKPiArCWRt YV9hZGRyX3QgZGFkZHI7Cj4gKwlkbWFfYWRkcl90IGlhZGRyOwo+ICsKPiArCXVuc2lnbmVkIGxv bmcgYXNzaWduZWRfY3M7Cj4gK307Cj4gKwo+ICtlbnVtIHsKPiArCU5GQ19FQ0NfQkNIOF8xSwkJ PSAyLAo+ICsJTkZDX0VDQ19CQ0gyNF8xSywKPiArCU5GQ19FQ0NfQkNIMzBfMUssCj4gKwlORkNf RUNDX0JDSDQwXzFLLAo+ICsJTkZDX0VDQ19CQ0g1MF8xSywKPiArCU5GQ19FQ0NfQkNINjBfMUss Cj4gK307Cj4gKwo+ICsjZGVmaW5lIE1FU09OX0VDQ19EQVRBKGIsIHMpCXsgLmJjaCA9IChiKSwJ LnN0cmVuZ3RoID0gKHMpfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uYW5kX2NhbGNfZWNjX2J5 dGVzKGludCBzdGVwX3NpemUsIGludCBzdHJlbmd0aCkKPiArewo+ICsJaW50IGVjY19ieXRlczsK PiArCj4gKwlpZiAoc3RlcF9zaXplID09IDUxMiAmJiBzdHJlbmd0aCA9PSA4KQo+ICsJCXJldHVy biBFQ0NfUEFSSVRZX0JDSDhfNTEyQjsKPiArCj4gKwllY2NfYnl0ZXMgPSBESVZfUk9VTkRfVVAo c3RyZW5ndGggKiBmbHMoc3RlcF9zaXplICogOCksIDgpOwo+ICsJZWNjX2J5dGVzID0gQUxJR04o ZWNjX2J5dGVzLCAyKTsKPiArCj4gKwlyZXR1cm4gZWNjX2J5dGVzOwo+ICt9Cj4gKwo+ICtOQU5E X0VDQ19DQVBTX1NJTkdMRShtZXNvbl9neGxfZWNjX2NhcHMsCj4gKwkJICAgICBtZXNvbl9uYW5k X2NhbGNfZWNjX2J5dGVzLCAxMDI0LCA4LCAyNCwgMzAsIDQwLCA1MCwgNjApOwo+ICtOQU5EX0VD Q19DQVBTX1NJTkdMRShtZXNvbl9heGdfZWNjX2NhcHMsCj4gKwkJICAgICBtZXNvbl9uYW5kX2Nh bGNfZWNjX2J5dGVzLCAxMDI0LCA4KTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgbWVzb25fbmZjX25h bmRfY2hpcCAqdG9fbWVzb25fbmFuZChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kKQo+ICt7Cj4gKwly ZXR1cm4gY29udGFpbmVyX29mKG5hbmQsIHN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwLCBuYW5k KTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbWVzb25fbmZjX3NlbGVjdF9jaGlwKHN0cnVjdCBu YW5kX2NoaXAgKm5hbmQsIGludCBjaGlwKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjX25hbmRf Y2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25f bmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4gKwlpbnQgcmV0LCB2 YWx1ZTsKPiArCj4gKwlpZiAoY2hpcCA8IDAgfHwgV0FSTl9PTl9PTkNFKGNoaXAgPiBNQVhfQ0Vf TlVNKSkKPiArCQlyZXR1cm47Cj4gKwo+ICsJbmZjLT5wYXJhbS5jaGlwX3NlbGVjdCA9IG1lc29u X2NoaXAtPnNlbHNbY2hpcF0gPyBOQU5EX0NFMSA6IE5BTkRfQ0UwOwo+ICsJbmZjLT5wYXJhbS5y Yl9zZWxlY3QgPSBuZmMtPnBhcmFtLmNoaXBfc2VsZWN0Owo+ICsJbmZjLT50aW1pbmcudHdiID0g bWVzb25fY2hpcC0+dHdiOwo+ICsJbmZjLT50aW1pbmcudGFkbCA9IG1lc29uX2NoaXAtPnRhZGw7 Cj4gKwluZmMtPnRpbWluZy50YmVyc19tYXggPSBtZXNvbl9jaGlwLT50YmVyc19tYXg7Cj4gKwo+ ICsJaWYgKGNoaXAgPj0gMCkgewo+ICsJCWlmIChuZmMtPmNsa19yYXRlICE9IG1lc29uX2NoaXAt PmNsa19yYXRlKSB7Cj4gKwkJCXJldCA9IGNsa19zZXRfcmF0ZShuZmMtPmRldmljZV9jbGssCj4g KwkJCQkJICAgbWVzb25fY2hpcC0+Y2xrX3JhdGUpOwo+ICsJCQlpZiAocmV0KSB7Cj4gKwkJCQlk ZXZfZXJyKG5mYy0+ZGV2LCAiZmFpbGVkIHRvIHNldCBjbG9jayByYXRlXG4iKTsKPiArCQkJCXJl dHVybjsKPiArCQkJfQo+ICsJCQluZmMtPmNsa19yYXRlID0gbWVzb25fY2hpcC0+Y2xrX3JhdGU7 Cj4gKwkJfQo+ICsJCWlmIChuZmMtPmJ1c190aW1pbmcgIT0gbWVzb25fY2hpcC0+YnVzX3RpbWlu Zykgewo+ICsJCQl2YWx1ZSA9IChORkNfQ0xLX0NZQ0xFIC0gMSkKPiArCQkJCXwgKG1lc29uX2No aXAtPmJ1c190aW1pbmcgPDwgNSk7Cj4gKwkJCXdyaXRlbCh2YWx1ZSwgbmZjLT5yZWdfYmFzZSAr IE5GQ19SRUdfQ0ZHKTsKPiArCQkJd3JpdGVsKCgxIDw8IDMxKSwgbmZjLT5yZWdfYmFzZSArIE5G Q19SRUdfQ01EKTsKPiArCQkJbmZjLT5idXNfdGltaW5nID0gIG1lc29uX2NoaXAtPmJ1c190aW1p bmc7Cj4gKwkJfQo+ICsJfQoKRG9uJ3QgeW91IGhhdmUgdGltaW5nIHJlZ2lzdGVycyB0byBzZXQ/ Cgo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNvbl9uZmNfY21kX2lkbGUoc3RydWN0IG1lc29u X25mYyAqbmZjLCB1MzIgdGltZSkKPiArewo+ICsJd3JpdGVsKG5mYy0+cGFyYW0uY2hpcF9zZWxl Y3QgfCBORkNfQ01EX0lETEUgfCAodGltZSAmIDB4M2ZmKSwKPiArCSAgICAgICBuZmMtPnJlZ19i YXNlICsgTkZDX1JFR19DTUQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNvbl9uZmNfY21k X3NlZWQoc3RydWN0IG1lc29uX25mYyAqbmZjLCB1MzIgc2VlZCkKPiArewo+ICsJd3JpdGVsKE5G Q19DTURfU0VFRCB8ICgweGMyICsgKHNlZWQgJiAweDdmZmYpKSwKPiArCSAgICAgICBuZmMtPnJl Z19iYXNlICsgTkZDX1JFR19DTUQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNvbl9uZmNf Y21kX2FjY2VzcyhzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBpbnQgcmF3LCBib29sIGRpcikKPiAr ewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZChuYW5kKTsKPiArCXN0cnVj dCBtZXNvbl9uZmMgKm5mYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShtdGRfdG9fbmFuZCht dGQpKTsKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVz b25fbmFuZChuYW5kKTsKPiArCXUzMiBiY2ggPSBtZXNvbl9jaGlwLT5iY2hfbW9kZSwgY21kOwo+ ICsJaW50IGxlbiA9IG10ZC0+d3JpdGVzaXplLCBwYWdlc2l6ZSwgcGFnZXM7Cj4gKwlpbnQgc2Ny YW1ibGUgPSAobmFuZC0+b3B0aW9ucyAmIE5BTkRfTkVFRF9TQ1JBTUJMSU5HKSA/IDEgOiAwOwoK VGhlcmUgYXJlIHF1aXRlIGEgZmV3IHBsYWNlcyB3aGVyZSB5b3UgdXNlIGhhcmRjb2RlZCB2YWx1 ZXMsIEkgd291bGQKaGF2ZSBwcmVmZXJyZWQgcHJlcHJvY2Vzc29yIGRlZmluZXMgZm9yIHRoYXQu IEluIHRoaXMgY2FzZSwgc29tZXRoaW5nCmxpbms6CgoKICAgICAgICAvLyBuYW1pbmcgaXMganVz dCBhcyBhIHJlZmVyZW5jZSwgdXNlIHdoYXRldmVyIHlvdSB3YW50CiAgICAgICAgKyNkZWZpbmUg Q01EX1NDUkFNQkxFIEJJVCgxOSkgCiAgICAgICAgWy4uLl0KICAgICAgICAraW50IHNjcmFtYmxl ID0gbmFuZC0+b3B0aW9ucyAmIE5BTkRfTkVFRF9TQ1JBTUJMSU5HKSA/IENNRF9TQ1JBTUJMRSA6 IDA7Cgp3b3VsZCBiZSBiZXR0ZXIgKHlvdSBjYW4gZXh0ZW5kIHRvIG90aGVyIHBsYWNlcyBhcyB3 ZWxsKS4KCj4gKwo+ICsJcGFnZXNpemUgPSBuYW5kLT5lY2Muc2l6ZTsKPiArCj4gKwlpZiAocmF3 KSB7Cj4gKwkJbGVuID0gbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemU7Cj4gKwkJY21kID0g KGxlbiAmIDB4M2ZmZikgfCAoc2NyYW1ibGUgPDwgMTkpIHwgRE1BX0RJUihkaXIpOwo+ICsJCXdy aXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gKwkJcmV0dXJuOwo+ICsJ fQo+ICsKPiArCXBhZ2VzID0gbGVuIC8gbmFuZC0+ZWNjLnNpemU7Cj4gKwo+ICsJY21kID0gQ01E UldHRU4oRE1BX0RJUihkaXIpLCBzY3JhbWJsZSwgYmNoLCAwLCBwYWdlc2l6ZSwgcGFnZXMpOwo+ ICsKPiArCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gK30KPiAr Cj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19kcmFpbl9jbWQoc3RydWN0IG1lc29uX25mYyAqbmZj KQo+ICt7Cj4gKwkvKgo+ICsJICogSW5zZXJ0IHR3byBjb21tYW5kcyB0byBtYWtlIHN1cmUgYWxs IHZhbGlkIGNvbW1hbmRzIGFyZSBmaW5pc2hlZC4KPiArCSAqCj4gKwkgKiBUaGUgTmFuZCBmbGFz aCBjb250cm9sbGVyIGlzIGRlc2lnbmVkIGFzIHR3byBzdGFnZXMgcGlwbGVsaW5lIC0KPiArCSAq ICBhKSBmZXRjaCBhbmQgYikgZXhjdXRlLgo+ICsJICogVGhlcmUgbWlnaHQgYmUgY2FzZXMgd2hl biB0aGUgZHJpdmVyIHNlZSBjb21tYW5kIHF1ZXVlIGlzIGVtcHR5LAo+ICsJICogYnV0IHRoZSBO YW5kIGZsYXNoIGNvbnRyb2xsZXIgc3RpbGwgaGFzIHR3byBjb21tYW5kcyBidWZmZXJlZCwKPiAr CSAqIG9uZSBpcyBmZXRjaGVkIGludG8gTkZDIHJlcXVlc3QgcXVldWUgKHJlYWR5IHRvIHJ1biks IGFuZCBhbm90aGVyCj4gKwkgKiBpcyBhY3RpdmVseSBleGVjdXRpbmcuIFNvIHB1c2hpbmcgMiAi SURMRSIgY29tbWFuZHMgZ3VhcmFudGVlcyB0aGF0Cj4gKwkgKiB0aGUgcGlwZWxpbmUgaXMgZW1w dGllZC4KPiArCSAqLwo+ICsJbWVzb25fbmZjX2NtZF9pZGxlKG5mYywgMCk7Cj4gKwltZXNvbl9u ZmNfY21kX2lkbGUobmZjLCAwKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfd2Fp dF9jbWRfZmluaXNoKHN0cnVjdCBtZXNvbl9uZmMgKm5mYywKPiArCQkJCSAgICAgdW5zaWduZWQg aW50IHRpbWVvdXRfbXMpCj4gK3sKPiArCXUzMiBjbWRfc2l6ZSA9IDA7Cj4gKwlpbnQgcmV0Owo+ ICsKPiArCS8qIHdhaXQgY21kIGZpZm8gaXMgZW1wdHkgKi8KPiArCXJldCA9IHJlYWRsX3JlbGF4 ZWRfcG9sbF90aW1lb3V0KG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCwgY21kX3NpemUsCj4g KwkJCQkJICFORkNfQ01EX0dFVF9TSVpFKGNtZF9zaXplKSwKPiArCQkJCQkgMTAsIHRpbWVvdXRf bXMgKiAxMDAwKTsKPiArCWlmIChyZXQpCj4gKwkJZGV2X2VycihuZmMtPmRldiwgIndhaXQgZm9y IGVtcHR5IGNtZCBGSUZPIHRpbWUgb3V0XG4iKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW50IG1lc29uX25mY193YWl0X2RtYV9maW5pc2goc3RydWN0IG1lc29uX25m YyAqbmZjKQo+ICt7Cj4gKwltZXNvbl9uZmNfZHJhaW5fY21kKG5mYyk7Cj4gKwo+ICsJcmV0dXJu IG1lc29uX25mY193YWl0X2NtZF9maW5pc2gobmZjLCBETUFfQlVTWV9USU1FT1VUKTsKPiArfQo+ ICsKPiArc3RhdGljIHU4ICptZXNvbl9uZmNfb29iX3B0cihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5k LCBpbnQgaSkKPiArewo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAg PSB0b19tZXNvbl9uYW5kKG5hbmQpOwo+ICsJaW50IGxlbjsKPiArCj4gKwlsZW4gPSBuYW5kLT5l Y2Muc2l6ZSAqIChpICsgMSkgKyAobmFuZC0+ZWNjLmJ5dGVzICsgMikgKiBpOwo+ICsKPiArCXJl dHVybiBtZXNvbl9jaGlwLT5kYXRhX2J1ZiArIGxlbjsKPiArfQo+ICsKPiArc3RhdGljIHU4ICpt ZXNvbl9uZmNfZGF0YV9wdHIoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgaW50IGkpCj4gK3sKPiAr CXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVzb25fbmFuZChu YW5kKTsKPiArCWludCBsZW4sIHRlbXA7Cj4gKwo+ICsJdGVtcCA9IG5hbmQtPmVjYy5zaXplICsg bmFuZC0+ZWNjLmJ5dGVzOwo+ICsJbGVuID0gKHRlbXAgKyAyKSAqIGk7Cj4gKwo+ICsJcmV0dXJu IG1lc29uX2NoaXAtPmRhdGFfYnVmICsgbGVuOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNv bl9uZmNfZ2V0X2RhdGFfb29iKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsCj4gKwkJCQkgICB1OCAq YnVmLCB1OCAqb29iYnVmKQo+ICt7Cj4gKwlpbnQgaSwgb29iX2xlbiA9IDA7Cj4gKwl1OCAqZHNy YywgKm9zcmM7Cj4gKwo+ICsJb29iX2xlbiA9IG5hbmQtPmVjYy5ieXRlcyArIDI7Cj4gKwlmb3Ig KGkgPSAwOyBpIDwgbmFuZC0+ZWNjLnN0ZXBzOyBpKyspIHsKPiArCQlpZiAoYnVmKSB7Cj4gKwkJ CWRzcmMgPSBtZXNvbl9uZmNfZGF0YV9wdHIobmFuZCwgaSk7Cj4gKwkJCW1lbWNweShidWYsIGRz cmMsIG5hbmQtPmVjYy5zaXplKTsKPiArCQkJYnVmICs9IG5hbmQtPmVjYy5zaXplOwo+ICsJCX0K PiArCQlvc3JjID0gbWVzb25fbmZjX29vYl9wdHIobmFuZCwgaSk7Cj4gKwkJbWVtY3B5KG9vYmJ1 Ziwgb3NyYywgb29iX2xlbik7Cj4gKwkJb29iYnVmICs9IG9vYl9sZW47Cj4gKwl9Cj4gK30KPiAr Cj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19zZXRfZGF0YV9vb2Ioc3RydWN0IG5hbmRfY2hpcCAq bmFuZCwKPiArCQkJCSAgIGNvbnN0IHU4ICpidWYsIHU4ICpvb2JidWYpCj4gK3sKPiArCWludCBp LCBvb2JfbGVuID0gMDsKPiArCXU4ICpkc3JjLCAqb3NyYzsKPiArCj4gKwlvb2JfbGVuID0gbmFu ZC0+ZWNjLmJ5dGVzICsgMjsKPiArCWZvciAoaSA9IDA7IGkgPCBuYW5kLT5lY2Muc3RlcHM7IGkr Kykgewo+ICsJCWlmIChidWYpIHsKPiArCQkJZHNyYyA9IG1lc29uX25mY19kYXRhX3B0cihuYW5k LCBpKTsKPiArCQkJbWVtY3B5KGRzcmMsIGJ1ZiwgbmFuZC0+ZWNjLnNpemUpOwo+ICsJCQlidWYg Kz0gbmFuZC0+ZWNjLnNpemU7Cj4gKwkJfQo+ICsJCW9zcmMgPSBtZXNvbl9uZmNfb29iX3B0cihu YW5kLCBpKTsKPiArCQltZW1jcHkob3NyYywgb29iYnVmLCBvb2JfbGVuKTsKPiArCQlvb2JidWYg Kz0gb29iX2xlbjsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfcXVldWVf cmIoc3RydWN0IG1lc29uX25mYyAqbmZjLCBpbnQgdGltZW91dF9tcykKPiArewo+ICsJdTMyIGNt ZCwgY2ZnOwo+ICsJaW50IHJldCA9IDA7Cj4gKwo+ICsJbWVzb25fbmZjX2NtZF9pZGxlKG5mYywg bmZjLT50aW1pbmcudHdiKTsKPiArCW1lc29uX25mY19kcmFpbl9jbWQobmZjKTsKPiArCW1lc29u X25mY193YWl0X2NtZF9maW5pc2gobmZjLCBDTURfRklGT19FTVBUWV9USU1FT1VUKTsKPiArCj4g KwljZmcgPSByZWFkbChuZmMtPnJlZ19iYXNlICsgTkZDX1JFR19DRkcpOwo+ICsJY2ZnIHw9ICgx IDw8IDIxKTsKPiArCXdyaXRlbChjZmcsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NGRyk7Cj4g Kwo+ICsJaW5pdF9jb21wbGV0aW9uKCZuZmMtPmNvbXBsZXRpb24pOwo+ICsKPiArCS8qIHVzZSB0 aGUgbWF4IGVyYXNlIHRpbWUgYXMgdGhlIG1heGltdW0gY2xvY2sgZm9yIHdhaXRpbmcgUi9CICov Cj4gKwljbWQgPSBORkNfQ01EX1JCIHwgTkZDX0NNRF9SQl9JTlQKPiArCQl8IG5mYy0+cGFyYW0u Y2hpcF9zZWxlY3QgfCBuZmMtPnRpbWluZy50YmVyc19tYXg7CgpOaXQ6IEkgdGhpbmsgdGhlICd8 JyBzaG91bGQgYmUgb24gdGhlIHByZXZpb3VzIGxpbmUuCgo+ICsJd3JpdGVsKGNtZCwgbmZjLT5y ZWdfYmFzZSArIE5GQ19SRUdfQ01EKTsKPiArCj4gKwlyZXQgPSB3YWl0X2Zvcl9jb21wbGV0aW9u X3RpbWVvdXQoJm5mYy0+Y29tcGxldGlvbiwKPiArCQkJCQkgIG1zZWNzX3RvX2ppZmZpZXModGlt ZW91dF9tcykpOwo+ICsJaWYgKHJldCA9PSAwKQo+ICsJCXJldCA9IC0xOwo+ICsKPiArCXJldHVy biByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19zZXRfdXNlcl9ieXRlKHN0 cnVjdCBuYW5kX2NoaXAgKm5hbmQsIHU4ICpvb2JfYnVmKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25f bmZjX25hbmRfY2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwlfX2xl NjQgKmluZm87Cj4gKwlpbnQgaSwgY291bnQ7Cj4gKwo+ICsJZm9yIChpID0gMCwgY291bnQgPSAw OyBpIDwgbmFuZC0+ZWNjLnN0ZXBzOyBpKyssIGNvdW50ICs9IDIpIHsKPiArCQlpbmZvID0gJm1l c29uX2NoaXAtPmluZm9fYnVmW2ldOwo+ICsJCSppbmZvIHw9IG9vYl9idWZbY291bnRdOwo+ICsJ CSppbmZvIHw9IG9vYl9idWZbY291bnQgKyAxXSA8PCA4Owo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0 aWMgdm9pZCBtZXNvbl9uZmNfZ2V0X3VzZXJfYnl0ZShzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCB1 OCAqb29iX2J1ZikKPiArewo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2No aXAgPSB0b19tZXNvbl9uYW5kKG5hbmQpOwo+ICsJX19sZTY0ICppbmZvOwo+ICsJaW50IGksIGNv dW50Owo+ICsKPiArCWZvciAoaSA9IDAsIGNvdW50ID0gMDsgaSA8IG5hbmQtPmVjYy5zdGVwczsg aSsrLCBjb3VudCArPSAyKSB7Cj4gKwkJaW5mbyA9ICZtZXNvbl9jaGlwLT5pbmZvX2J1ZltpXTsK PiArCQlvb2JfYnVmW2NvdW50XSA9ICppbmZvOwo+ICsJCW9vYl9idWZbY291bnQgKyAxXSA9ICpp bmZvID4+IDg7Cj4gKwl9Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX2VjY19jb3Jy ZWN0KHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQpCj4gK3sKPiArCXN0cnVjdCBtdGRfaW5mbyAqbXRk ID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjX25hbmRfY2hpcCAqbWVz b25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwlfX2xlNjQgKmluZm87Cj4gKwl1MzIg Yml0ZmxpcHMgPSAwLCBpOwo+ICsJaW50IHNjcmFtYmxlOwo+ICsJdTggemVyb19jbnQ7Cj4gKwo+ ICsJc2NyYW1ibGUgPSAobmFuZC0+b3B0aW9ucyAmIE5BTkRfTkVFRF9TQ1JBTUJMSU5HKSA/IDEg OiAwOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBuYW5kLT5lY2Muc3RlcHM7IGkrKykgewo+ICsJ CWluZm8gPSAmbWVzb25fY2hpcC0+aW5mb19idWZbaV07Cj4gKwkJaWYgKEVDQ19FUlJfQ05UKCpp bmZvKSA9PSAweDNmKSB7Cj4gKwkJCXplcm9fY250ID0gRUNDX1pFUk9fQ05UKCppbmZvKTsKPiAr CQkJaWYgKHNjcmFtYmxlICYmIHplcm9fY250IDwgbmFuZC0+ZWNjLnN0cmVuZ3RoKQo+ICsJCQkJ cmV0dXJuIEVDQ19DSEVDS19SRVRVUk5fRkY7CgpUaGlzIGFuZCB3aGF0IHlvdSBkbyBsYXRlciB3 aXRoIEVDQ19DSEVDS19SRVRVUk5fRkYgaXMgcHJldHR5IHVuY2xlYXIKdG8gbWUuCgo+ICsJCQlt dGQtPmVjY19zdGF0cy5mYWlsZWQrKzsKPiArCQkJY29udGludWU7Cj4gKwkJfQo+ICsJCW10ZC0+ ZWNjX3N0YXRzLmNvcnJlY3RlZCArPSBFQ0NfRVJSX0NOVCgqaW5mbyk7Cj4gKwkJYml0ZmxpcHMg PSBtYXhfdCh1MzIsIGJpdGZsaXBzLCBFQ0NfRVJSX0NOVCgqaW5mbykpOwo+ICsJfQoKQXJlIHlv dSBzdXJlIHlvdSBoYW5kbGUgY29ycmVjdGx5IGVtcHR5IHBhZ2VzIHdpdGggYmY/Cgo+ICsKPiAr CXJldHVybiBiaXRmbGlwczsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfZG1hX2J1 ZmZlcl9zZXR1cChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCB1OCAqZGF0YWJ1ZiwKPiArCQkJCSAg ICAgIGludCBkYXRhbGVuLCB1OCAqaW5mb2J1ZiwgaW50IGluZm9sZW4sCj4gKwkJCQkgICAgICBl bnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIpCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmMgKm5m YyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPiArCXUzMiBjbWQ7Cj4gKwlpbnQg cmV0ID0gMDsKPiArCj4gKwluZmMtPmRhZGRyID0gZG1hX21hcF9zaW5nbGUobmZjLT5kZXYsICh2 b2lkICopZGF0YWJ1ZiwgZGF0YWxlbiwgZGlyKTsKPiArCXJldCA9IGRtYV9tYXBwaW5nX2Vycm9y KG5mYy0+ZGV2LCBuZmMtPmRhZGRyKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKG5mYy0+ ZGV2LCAiZG1hIG1hcHBpbmcgZXJyb3JcbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwlj bWQgPSBHRU5DTUREQUREUkwoTkZDX0NNRF9BREwsIG5mYy0+ZGFkZHIpOwo+ICsJd3JpdGVsKGNt ZCwgbmZjLT5yZWdfYmFzZSArIE5GQ19SRUdfQ01EKTsKPiArCj4gKwljbWQgPSBHRU5DTUREQURE UkgoTkZDX0NNRF9BREgsIG5mYy0+ZGFkZHIpOwo+ICsJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFz ZSArIE5GQ19SRUdfQ01EKTsKPiArCj4gKwlpZiAoaW5mb2J1Zikgewo+ICsJCW5mYy0+aWFkZHIg PSBkbWFfbWFwX3NpbmdsZShuZmMtPmRldiwgaW5mb2J1ZiwgaW5mb2xlbiwgZGlyKTsKPiArCQly ZXQgPSBkbWFfbWFwcGluZ19lcnJvcihuZmMtPmRldiwgbmZjLT5pYWRkcik7Cj4gKwkJaWYgKHJl dCkgewo+ICsJCQlkZXZfZXJyKG5mYy0+ZGV2LCAiZG1hIG1hcHBpbmcgZXJyb3JcbiIpOwo+ICsJ CQlkbWFfdW5tYXBfc2luZ2xlKG5mYy0+ZGV2LAo+ICsJCQkJCSBuZmMtPmRhZGRyLCBkYXRhbGVu LCBkaXIpOwo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCX0KPiArCQljbWQgPSBHRU5DTURJQUREUkwo TkZDX0NNRF9BSUwsIG5mYy0+aWFkZHIpOwo+ICsJCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2Ug KyBORkNfUkVHX0NNRCk7Cj4gKwo+ICsJCWNtZCA9IEdFTkNNRElBRERSSChORkNfQ01EX0FJSCwg bmZjLT5pYWRkcik7Cj4gKwkJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFzZSArIE5GQ19SRUdfQ01E KTsKPiArCX0KPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtZXNv bl9uZmNfZG1hX2J1ZmZlcl9yZWxlYXNlKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsCj4gKwkJCQkJ IGludCBpbmZvbGVuLCBpbnQgZGF0YWxlbiwKPiArCQkJCQkgZW51bSBkbWFfZGF0YV9kaXJlY3Rp b24gZGlyKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9s bGVyX2RhdGEobmFuZCk7Cj4gKwo+ICsJZG1hX3VubWFwX3NpbmdsZShuZmMtPmRldiwgbmZjLT5k YWRkciwgZGF0YWxlbiwgZGlyKTsKPiArCWlmIChpbmZvbGVuKQo+ICsJCWRtYV91bm1hcF9zaW5n bGUobmZjLT5kZXYsIG5mYy0+aWFkZHIsIGluZm9sZW4sIGRpcik7Cj4gK30KPiArCj4gK3N0YXRp YyBpbnQgbWVzb25fbmZjX3JlYWRfYnVmKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIHU4ICpidWYs IGludCBsZW4pCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmMgKm5mYyA9IG5hbmRfZ2V0X2NvbnRy b2xsZXJfZGF0YShuYW5kKTsKPiArCWludCByZXQgPSAwOwo+ICsJdTMyIGNtZDsKPiArCXU4ICpp bmZvOwo+ICsKPiArCWluZm8gPSBremFsbG9jKFBFUl9JTkZPX0JZVEUsIEdGUF9LRVJORUwpOwo+ ICsJcmV0ID0gbWVzb25fbmZjX2RtYV9idWZmZXJfc2V0dXAobmFuZCwgYnVmLCBsZW4sIGluZm8s Cj4gKwkJCQkJIFBFUl9JTkZPX0JZVEUsIERNQV9GUk9NX0RFVklDRSk7Cj4gKwlpZiAocmV0KQo+ ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJY21kID0gTkZDX0NNRF9OMk0gfCAobGVuICYgMHgzZmZm KTsKPiArCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gKwo+ICsJ bWVzb25fbmZjX2RyYWluX2NtZChuZmMpOwo+ICsJbWVzb25fbmZjX3dhaXRfY21kX2ZpbmlzaChu ZmMsIDEwMDApOwo+ICsJbWVzb25fbmZjX2RtYV9idWZmZXJfcmVsZWFzZShuYW5kLCBsZW4sIFBF Ul9JTkZPX0JZVEUsIERNQV9GUk9NX0RFVklDRSk7Cj4gKwlrZnJlZShpbmZvKTsKPiArCj4gKwly ZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX25mY193cml0ZV9idWYoc3Ry dWN0IG5hbmRfY2hpcCAqbmFuZCwgdTggKmJ1ZiwgaW50IGxlbikKPiArewo+ICsJc3RydWN0IG1l c29uX25mYyAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKG5hbmQpOwo+ICsJaW50IHJl dCA9IDA7Cj4gKwl1MzIgY21kOwo+ICsKPiArCXJldCA9IG1lc29uX25mY19kbWFfYnVmZmVyX3Nl dHVwKG5hbmQsIGJ1ZiwgbGVuLCBOVUxMLAo+ICsJCQkJCSAwLCBETUFfVE9fREVWSUNFKTsKPiAr CWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwljbWQgPSBORkNfQ01EX00yTiB8IChs ZW4gJiAweDNmZmYpOwo+ICsJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFzZSArIE5GQ19SRUdfQ01E KTsKPiArCj4gKwltZXNvbl9uZmNfZHJhaW5fY21kKG5mYyk7Cj4gKwltZXNvbl9uZmNfd2FpdF9j bWRfZmluaXNoKG5mYywgMTAwMCk7Cj4gKwltZXNvbl9uZmNfZG1hX2J1ZmZlcl9yZWxlYXNlKG5h bmQsIGxlbiwgMCwgRE1BX1RPX0RFVklDRSk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsK PiArc3RhdGljIGludCBtZXNvbl9uZmNfcndfY21kX3ByZXBhcmVfYW5kX2V4ZWN1dGUoc3RydWN0 IG5hbmRfY2hpcCAqbmFuZCwKPiArCQkJCQkJaW50IHBhZ2UsIGJvb2wgaW4pCj4gK3sKPiArCXN0 cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25f bmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEobmFuZCk7Cj4gKwljb25zdCBzdHJ1 Y3QgbmFuZF9zZHJfdGltaW5ncyAqc2RyID0KPiArCQluYW5kX2dldF9zZHJfdGltaW5ncygmbmFu ZC0+ZGF0YV9pbnRlcmZhY2UpOwo+ICsJdTMyICphZGRycyA9IG5mYy0+Y21kZmlmby5ydy5hZGRy czsKPiArCXUzMiBjcyA9IG5mYy0+cGFyYW0uY2hpcF9zZWxlY3Q7Cj4gKwl1MzIgY21kMCwgY21k X251bSwgcm93X3N0YXJ0Owo+ICsJaW50IHJldCA9IDAsIGk7Cj4gKwo+ICsJY21kX251bSA9IHNp emVvZihzdHJ1Y3QgbmFuZF9yd19jbWQpIC8gc2l6ZW9mKGludCk7Cj4gKwo+ICsJY21kMCA9IGlu ID8gTkFORF9DTURfUkVBRDAgOiBOQU5EX0NNRF9TRVFJTjsKPiArCW5mYy0+Y21kZmlmby5ydy5j bWQwID0gY3MgfCBORkNfQ01EX0NMRSB8IGNtZDA7Cj4gKwo+ICsJYWRkcnNbMF0gPSBjcyB8IE5G Q19DTURfQUxFIHwgMDsKPiArCWlmIChtdGQtPndyaXRlc2l6ZSA8PSA1MTIpIHsKPiArCQljbWRf bnVtLS07Cj4gKwkJcm93X3N0YXJ0ID0gMTsKPiArCX0gZWxzZSB7Cj4gKwkJYWRkcnNbMV0gPSBj cyB8IE5GQ19DTURfQUxFIHwgMDsKPiArCQlyb3dfc3RhcnQgPSAyOwo+ICsJfQo+ICsKPiArCWFk ZHJzW3Jvd19zdGFydF0gPSBjcyB8IE5GQ19DTURfQUxFIHwgUk9XX0FEREVSKHBhZ2UsIDApOwo+ ICsJYWRkcnNbcm93X3N0YXJ0ICsgMV0gPSBjcyB8IE5GQ19DTURfQUxFIHwgUk9XX0FEREVSKHBh Z2UsIDEpOwo+ICsKPiArCWlmIChuYW5kLT5vcHRpb25zICYgTkFORF9ST1dfQUREUl8zKQo+ICsJ CWFkZHJzW3Jvd19zdGFydCArIDJdID0KPiArCQkJY3MgfCBORkNfQ01EX0FMRSB8IFJPV19BRERF UihwYWdlLCAyKTsKPiArCWVsc2UKPiArCQljbWRfbnVtLS07Cj4gKwo+ICsJLyogc3VidHJhY3Qg Y21kMSAqLwo+ICsJY21kX251bS0tOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBjbWRfbnVtOyBp KyspCj4gKwkJd3JpdGVsX3JlbGF4ZWQobmZjLT5jbWRmaWZvLmNtZFtpXSwKPiArCQkJICAgICAg IG5mYy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NNRCk7Cj4gKwo+ICsJaWYgKGluKSB7Cj4gKwkJbmZj LT5jbWRmaWZvLnJ3LmNtZDEgPSBjcyB8IE5GQ19DTURfQ0xFIHwgTkFORF9DTURfUkVBRFNUQVJU Owo+ICsJCXdyaXRlbChuZmMtPmNtZGZpZm8ucncuY21kMSwgbmZjLT5yZWdfYmFzZSArIE5GQ19S RUdfQ01EKTsKPiArCQltZXNvbl9uZmNfcXVldWVfcmIobmZjLCBQU0VDX1RPX01TRUMoc2RyLT50 Ul9tYXgpKTsKPiArCX0gZWxzZSB7Cj4gKwkJbWVzb25fbmZjX2NtZF9pZGxlKG5mYywgbmZjLT50 aW1pbmcudGFkbCk7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGlj IGludCBtZXNvbl9uZmNfd3JpdGVfcGFnZV9zdWIoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwKPiAr CQkJCSAgICBpbnQgcGFnZSwgaW50IHJhdykKPiArewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQg PSBuYW5kX3RvX210ZChuYW5kKTsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX3Nkcl90aW1pbmdzICpz ZHIgPQo+ICsJCW5hbmRfZ2V0X3Nkcl90aW1pbmdzKCZuYW5kLT5kYXRhX2ludGVyZmFjZSk7Cj4g KwlzdHJ1Y3QgbWVzb25fbmZjX25hbmRfY2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQo bmFuZCk7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmMgPSBuYW5kX2dldF9jb250cm9sbGVyX2Rh dGEobmFuZCk7Cj4gKwlpbnQgZGF0YV9sZW4sIGluZm9fbGVuOwo+ICsJdTMyIGNtZDsKPiArCWlu dCByZXQ7Cj4gKwo+ICsJZGF0YV9sZW4gPSAgbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemU7 Cj4gKwlpbmZvX2xlbiA9IG5hbmQtPmVjYy5zdGVwcyAqIFBFUl9JTkZPX0JZVEU7Cj4gKwo+ICsJ cmV0ID0gbWVzb25fbmZjX3J3X2NtZF9wcmVwYXJlX2FuZF9leGVjdXRlKG5hbmQsIHBhZ2UsIERJ UldSSVRFKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXQgPSBtZXNv bl9uZmNfZG1hX2J1ZmZlcl9zZXR1cChuYW5kLCBtZXNvbl9jaGlwLT5kYXRhX2J1ZiwKPiArCQkJ CQkgZGF0YV9sZW4sICh1OCAqKW1lc29uX2NoaXAtPmluZm9fYnVmLAo+ICsJCQkJCSBpbmZvX2xl biwgRE1BX1RPX0RFVklDRSk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJ bWVzb25fbmZjX2NtZF9zZWVkKG5mYywgcGFnZSk7Cj4gKwltZXNvbl9uZmNfY21kX2FjY2Vzcyhu YW5kLCByYXcsIERJUldSSVRFKTsKPiArCWNtZCA9IG5mYy0+cGFyYW0uY2hpcF9zZWxlY3QgfCBO RkNfQ01EX0NMRSB8IE5BTkRfQ01EX1BBR0VQUk9HOwo+ICsJd3JpdGVsKGNtZCwgbmZjLT5yZWdf YmFzZSArIE5GQ19SRUdfQ01EKTsKPiArCW1lc29uX25mY19xdWV1ZV9yYihuZmMsIFBTRUNfVE9f TVNFQyhzZHItPnRQUk9HX21heCkpOwo+ICsKPiArCW1lc29uX25mY19kbWFfYnVmZmVyX3JlbGVh c2UobmFuZCwgZGF0YV9sZW4sIGluZm9fbGVuLCBETUFfVE9fREVWSUNFKTsKPiArCj4gKwlyZXR1 cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX25mY193cml0ZV9wYWdlX3Jhdyhz dHJ1Y3QgbmFuZF9jaGlwICpuYW5kLCBjb25zdCB1OCAqYnVmLAo+ICsJCQkJICAgIGludCBvb2Jf cmVxdWlyZWQsIGludCBwYWdlKQo+ICt7Cj4gKwl1OCAqb29iX2J1ZiA9IG5hbmQtPm9vYl9wb2k7 Cj4gKwo+ICsJbWVzb25fbmZjX3NldF9kYXRhX29vYihuYW5kLCBidWYsIG9vYl9idWYpOwo+ICsK PiArCXJldHVybiBtZXNvbl9uZmNfd3JpdGVfcGFnZV9zdWIobmFuZCwgcGFnZSwgMSk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX3dyaXRlX3BhZ2VfaHdlY2Moc3RydWN0IG5hbmRf Y2hpcCAqbmFuZCwKPiArCQkJCSAgICAgIGNvbnN0IHU4ICpidWYsIGludCBvb2JfcmVxdWlyZWQs IGludCBwYWdlKQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5h bmQpOwo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAgPSB0b19tZXNv bl9uYW5kKG5hbmQpOwo+ICsJdTggKm9vYl9idWYgPSBuYW5kLT5vb2JfcG9pOwo+ICsKPiArCW1l bWNweShtZXNvbl9jaGlwLT5kYXRhX2J1ZiwgYnVmLCBtdGQtPndyaXRlc2l6ZSk7Cj4gKwltZW1z ZXQobWVzb25fY2hpcC0+aW5mb19idWYsIDAsIG5hbmQtPmVjYy5zdGVwcyAqIFBFUl9JTkZPX0JZ VEUpOwo+ICsJbWVzb25fbmZjX3NldF91c2VyX2J5dGUobmFuZCwgb29iX2J1Zik7Cj4gKwo+ICsJ cmV0dXJuIG1lc29uX25mY193cml0ZV9wYWdlX3N1YihuYW5kLCBwYWdlLCAwKTsKPiArfQo+ICsK PiArc3RhdGljIHZvaWQgbWVzb25fbmZjX2NoZWNrX2VjY19wYWdlc192YWxpZChzdHJ1Y3QgbWVz b25fbmZjICpuZmMsCj4gKwkJCQkJICAgIHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIGludCByYXcp Cj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVz b25fbmFuZChuYW5kKTsKPiArCV9fbGU2NCAqaW5mbzsKPiArCXUzMiBuZWNjcGFnZXM7Cj4gKwlp bnQgcmV0Owo+ICsKPiArCW5lY2NwYWdlcyA9IHJhdyA/IDEgOiBuYW5kLT5lY2Muc3RlcHM7Cj4g KwlpbmZvID0gJm1lc29uX2NoaXAtPmluZm9fYnVmW25lY2NwYWdlcyAtIDFdOwo+ICsJZG8gewo+ ICsJCXVzbGVlcF9yYW5nZSgxMCwgMTUpOwo+ICsJCS8qIGluZm8gaXMgdXBkYXRlZCBieSBuZmMg ZG1hIGVuZ2luZSovCj4gKwkJc21wX3JtYigpOwo+ICsJCXJldCA9ICppbmZvICYgRUNDX0NPTVBM RVRFOwo+ICsJfSB3aGlsZSAoIXJldCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZj X3JlYWRfcGFnZV9zdWIoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwKPiArCQkJCSAgIGludCBwYWdl LCBpbnQgcmF3KQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKG5h bmQpOwo+ICsJc3RydWN0IG1lc29uX25mYyAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRh KG5hbmQpOwo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAgPSB0b19t ZXNvbl9uYW5kKG5hbmQpOwo+ICsJaW50IGRhdGFfbGVuLCBpbmZvX2xlbjsKPiArCWludCByZXQ7 Cj4gKwo+ICsJZGF0YV9sZW4gPSAgbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemU7Cj4gKwlp bmZvX2xlbiA9IG5hbmQtPmVjYy5zdGVwcyAqIFBFUl9JTkZPX0JZVEU7Cj4gKwo+ICsJcmV0ID0g bWVzb25fbmZjX3J3X2NtZF9wcmVwYXJlX2FuZF9leGVjdXRlKG5hbmQsIHBhZ2UsIERJUlJFQUQp Owo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldCA9IG1lc29uX25mY19k bWFfYnVmZmVyX3NldHVwKG5hbmQsIG1lc29uX2NoaXAtPmRhdGFfYnVmLAo+ICsJCQkJCSBkYXRh X2xlbiwgKHU4ICopbWVzb25fY2hpcC0+aW5mb19idWYsCj4gKwkJCQkJIGluZm9fbGVuLCBETUFf RlJPTV9ERVZJQ0UpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCW1lc29u X25mY19jbWRfc2VlZChuZmMsIHBhZ2UpOwo+ICsJbWVzb25fbmZjX2NtZF9hY2Nlc3MobmFuZCwg cmF3LCBESVJSRUFEKTsKPiArCXJldCA9IG1lc29uX25mY193YWl0X2RtYV9maW5pc2gobmZjKTsK PiArCW1lc29uX25mY19jaGVja19lY2NfcGFnZXNfdmFsaWQobmZjLCBuYW5kLCByYXcpOwo+ICsK PiArCW1lc29uX25mY19kbWFfYnVmZmVyX3JlbGVhc2UobmFuZCwgZGF0YV9sZW4sIGluZm9fbGVu LCBETUFfRlJPTV9ERVZJQ0UpOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRp YyBpbnQgbWVzb25fbmZjX3JlYWRfcGFnZV9yYXcoc3RydWN0IG5hbmRfY2hpcCAqbmFuZCwgdTgg KmJ1ZiwKPiArCQkJCSAgIGludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+ICt7Cj4gKwl1OCAq b29iX2J1ZiA9IG5hbmQtPm9vYl9wb2k7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IG1lc29u X25mY19yZWFkX3BhZ2Vfc3ViKG5hbmQsIHBhZ2UsIDEpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1 cm4gcmV0Owo+ICsKPiArCW1lc29uX25mY19nZXRfZGF0YV9vb2IobmFuZCwgYnVmLCBvb2JfYnVm KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfcmVh ZF9wYWdlX2h3ZWNjKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIHU4ICpidWYsCj4gKwkJCQkgICAg IGludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10 ZCA9IG5hbmRfdG9fbXRkKG5hbmQpOwo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1l c29uX2NoaXAgPSB0b19tZXNvbl9uYW5kKG5hbmQpOwo+ICsJdTggKm9vYl9idWYgPSBuYW5kLT5v b2JfcG9pOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSBtZXNvbl9uZmNfcmVhZF9wYWdlX3N1 YihuYW5kLCBwYWdlLCAwKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlt ZXNvbl9uZmNfZ2V0X3VzZXJfYnl0ZShuYW5kLCBvb2JfYnVmKTsKPiArCj4gKwlyZXQgPSBtZXNv bl9uZmNfZWNjX2NvcnJlY3QobmFuZCk7Cj4gKwlpZiAocmV0ID09IEVDQ19DSEVDS19SRVRVUk5f RkYpIHsKPiArCQlpZiAoYnVmKQo+ICsJCQltZW1zZXQoYnVmLCAweGZmLCBtdGQtPndyaXRlc2l6 ZSk7Cj4gKwo+ICsJCW1lbXNldChvb2JfYnVmLCAweGZmLCBtdGQtPm9vYnNpemUpOwo+ICsJCXJl dHVybiAwOwo+ICsJfQo+ICsKPiArCWlmIChidWYgJiYgYnVmICE9IG1lc29uX2NoaXAtPmRhdGFf YnVmKQo+ICsJCW1lbWNweShidWYsIG1lc29uX2NoaXAtPmRhdGFfYnVmLCBtdGQtPndyaXRlc2l6 ZSk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNf cmVhZF9vb2JfcmF3KHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQsIGludCBwYWdlKQo+ICt7Cj4gKwly ZXR1cm4gbWVzb25fbmZjX3JlYWRfcGFnZV9yYXcobmFuZCwgTlVMTCwgMSwgcGFnZSk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX3JlYWRfb29iKHN0cnVjdCBuYW5kX2NoaXAgKm5h bmQsIGludCBwYWdlKQo+ICt7Cj4gKwlyZXR1cm4gbWVzb25fbmZjX3JlYWRfcGFnZV9od2VjYyhu YW5kLCBOVUxMLCAxLCBwYWdlKTsKPiArfQo+ICsKPiArdm9pZCAqCj4gK21lc29uX25hbmRfb3Bf Z2V0X2RtYV9zYWZlX2lucHV0X2J1Zihjb25zdCBzdHJ1Y3QgbmFuZF9vcF9pbnN0ciAqaW5zdHIp Cj4gK3sKPiArCWlmIChXQVJOX09OKGluc3RyLT50eXBlICE9IE5BTkRfT1BfREFUQV9JTl9JTlNU UikpCj4gKwkJcmV0dXJuIE5VTEw7Cj4gKwlpZiAodmlydF9hZGRyX3ZhbGlkKGluc3RyLT5jdHgu ZGF0YS5idWYuaW4pICYmCj4gKwkgICAgIW9iamVjdF9pc19vbl9zdGFjayhpbnN0ci0+Y3R4LmRh dGEuYnVmLmluKSkKPiArCQlyZXR1cm4gaW5zdHItPmN0eC5kYXRhLmJ1Zi5pbjsKPiArCj4gKwly ZXR1cm4ga3phbGxvYyhpbnN0ci0+Y3R4LmRhdGEubGVuLCBHRlBfS0VSTkVMKTsKCkkgdGhpbmsg YWxsb2NhdGluZyBtZW1vcnkgYW5kIHVzaW5nIGl0IHdpdGhvdXQgZXZlciB0ZXN0aW5nIHRoZQph bGxvY2F0aW9uIHN1Y2NlZWRlZCBpcyB3cm9uZy4gWW91IGRvIHRoYXQgaW4gbWFueSBwbGFjZXMu IEkgd291bGQgbGlrZQp0byBzZWUgYWxsb2NhdGlvbnMgcHJvcGVybHkgaGFuZGxlZC4KCj4gK30K PiArCj4gK3ZvaWQKPiArbWVzb25fbmFuZF9vcF9wdXRfZG1hX3NhZmVfaW5wdXRfYnVmKGNvbnN0 IHN0cnVjdCBuYW5kX29wX2luc3RyICppbnN0ciwKPiArCQkJCSAgICAgdm9pZCAqYnVmKQo+ICt7 Cj4gKwlpZiAoV0FSTl9PTihpbnN0ci0+dHlwZSAhPSBOQU5EX09QX0RBVEFfSU5fSU5TVFIpIHx8 Cj4gKwkgICAgV0FSTl9PTighYnVmKSkKPiArCQlyZXR1cm47Cj4gKwlpZiAoYnVmID09IGluc3Ry LT5jdHguZGF0YS5idWYuaW4pCj4gKwkJcmV0dXJuOwo+ICsKPiArCW1lbWNweShpbnN0ci0+Y3R4 LmRhdGEuYnVmLmluLCBidWYsIGluc3RyLT5jdHguZGF0YS5sZW4pOwo+ICsJa2ZyZWUoYnVmKTsK PiArfQo+ICsKPiArY29uc3Qgdm9pZCAqCj4gK21lc29uX25hbmRfb3BfZ2V0X2RtYV9zYWZlX291 dHB1dF9idWYoY29uc3Qgc3RydWN0IG5hbmRfb3BfaW5zdHIgKmluc3RyKQo+ICt7Cj4gKwlpZiAo V0FSTl9PTihpbnN0ci0+dHlwZSAhPSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSKSkKPiArCQlyZXR1 cm4gTlVMTDsKPiArCj4gKwlpZiAodmlydF9hZGRyX3ZhbGlkKGluc3RyLT5jdHguZGF0YS5idWYu b3V0KSAmJgo+ICsJICAgICFvYmplY3RfaXNfb25fc3RhY2soaW5zdHItPmN0eC5kYXRhLmJ1Zi5v dXQpKQoKQ2FuIHlvdSBwbGVhc2UgY3JlYXRlIGhlbHBlcnMgZm9yIHRoYXQ/IEkgZ3Vlc3MgaXQg d2lsbCBoZWxwIHJlbW92aW5nCnRoZXNlIGNoZWNrcyBvbmNlIHRoZSBjb3JlIHdpbGwgaGF2ZSBh IERNQS1zYWZlIGFwcHJvYWNoLgoKPiArCQlyZXR1cm4gaW5zdHItPmN0eC5kYXRhLmJ1Zi5vdXQ7 Cj4gKwo+ICsJcmV0dXJuIGttZW1kdXAoaW5zdHItPmN0eC5kYXRhLmJ1Zi5vdXQsCj4gKwkJICAg ICAgIGluc3RyLT5jdHguZGF0YS5sZW4sIEdGUF9LRVJORUwpOwo+ICt9Cj4gKwo+ICt2b2lkCj4g K21lc29uX25hbmRfb3BfcHV0X2RtYV9zYWZlX291dHB1dF9idWYoY29uc3Qgc3RydWN0IG5hbmRf b3BfaW5zdHIgKmluc3RyLAo+ICsJCQkJICAgICAgY29uc3Qgdm9pZCAqYnVmKQo+ICt7Cj4gKwlp ZiAoV0FSTl9PTihpbnN0ci0+dHlwZSAhPSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSKSB8fAo+ICsJ ICAgIFdBUk5fT04oIWJ1ZikpCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlmIChidWYgIT0gaW5zdHIt PmN0eC5kYXRhLmJ1Zi5vdXQpCj4gKwkJa2ZyZWUoYnVmKTsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBtZXNvbl9uZmNfZXhlY19vcChzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kLAo+ICsJCQkgICAgIGNv bnN0IHN0cnVjdCBuYW5kX29wZXJhdGlvbiAqb3AsIGJvb2wgY2hlY2tfb25seSkKPiArewo+ICsJ c3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29uX2NoaXAgPSB0b19tZXNvbl9uYW5kKG5h bmQpOwo+ICsJc3RydWN0IG1lc29uX25mYyAqbmZjID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRh KG5hbmQpOwo+ICsJY29uc3Qgc3RydWN0IG5hbmRfb3BfaW5zdHIgKmluc3RyID0gTlVMTDsKPiAr CXZvaWQgKmJ1ZjsKPiArCXUzMiBvcF9pZCwgZGVsYXlfaWRsZSwgY21kOwo+ICsJaW50IGk7Cj4g Kwo+ICsJZm9yIChvcF9pZCA9IDA7IG9wX2lkIDwgb3AtPm5pbnN0cnM7IG9wX2lkKyspIHsKPiAr CQlpbnN0ciA9ICZvcC0+aW5zdHJzW29wX2lkXTsKPiArCQlkZWxheV9pZGxlID0gRElWX1JPVU5E X1VQKFBTRUNfVE9fTlNFQyhpbnN0ci0+ZGVsYXlfbnMpLAo+ICsJCQkJCSAgbWVzb25fY2hpcC0+ bGV2ZWwxX2RpdmlkZXIgKgo+ICsJCQkJCSAgTkZDX0NMS19DWUNMRSk7Cj4gKwkJc3dpdGNoIChp bnN0ci0+dHlwZSkgewo+ICsJCWNhc2UgTkFORF9PUF9DTURfSU5TVFI6Cj4gKwkJCWNtZCA9IG5m Yy0+cGFyYW0uY2hpcF9zZWxlY3QgfCBORkNfQ01EX0NMRTsKPiArCQkJY21kIHw9IGluc3RyLT5j dHguY21kLm9wY29kZSAmIDB4ZmY7Cj4gKwkJCXdyaXRlbChjbWQsIG5mYy0+cmVnX2Jhc2UgKyBO RkNfUkVHX0NNRCk7Cj4gKwkJCW1lc29uX25mY19jbWRfaWRsZShuZmMsIGRlbGF5X2lkbGUpOwo+ ICsJCQlicmVhazsKPiArCj4gKwkJY2FzZSBOQU5EX09QX0FERFJfSU5TVFI6Cj4gKwkJCWZvciAo aSA9IDA7IGkgPCBpbnN0ci0+Y3R4LmFkZHIubmFkZHJzOyBpKyspIHsKPiArCQkJCWNtZCA9IG5m Yy0+cGFyYW0uY2hpcF9zZWxlY3QgfCBORkNfQ01EX0FMRTsKPiArCQkJCWNtZCB8PSBpbnN0ci0+ Y3R4LmFkZHIuYWRkcnNbaV0gJiAweGZmOwo+ICsJCQkJd3JpdGVsKGNtZCwgbmZjLT5yZWdfYmFz ZSArIE5GQ19SRUdfQ01EKTsKPiArCQkJfQo+ICsJCQltZXNvbl9uZmNfY21kX2lkbGUobmZjLCBk ZWxheV9pZGxlKTsKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNhc2UgTkFORF9PUF9EQVRBX0lOX0lO U1RSOgo+ICsJCQlidWYgPSBtZXNvbl9uYW5kX29wX2dldF9kbWFfc2FmZV9pbnB1dF9idWYoaW5z dHIpOwo+ICsJCQltZXNvbl9uZmNfcmVhZF9idWYobmFuZCwgYnVmLAo+ICsJCQkJCSAgIGluc3Ry LT5jdHguZGF0YS5sZW4pOwo+ICsJCQltZXNvbl9uYW5kX29wX3B1dF9kbWFfc2FmZV9pbnB1dF9i dWYoaW5zdHIsIGJ1Zik7Cj4gKwkJCWJyZWFrOwo+ICsKPiArCQljYXNlIE5BTkRfT1BfREFUQV9P VVRfSU5TVFI6Cj4gKwkJCWJ1ZiA9Cj4gKwkJCSh2b2lkICopbWVzb25fbmFuZF9vcF9nZXRfZG1h X3NhZmVfb3V0cHV0X2J1ZihpbnN0cik7Cj4gKwkJCW1lc29uX25mY193cml0ZV9idWYobmFuZCwg YnVmLAo+ICsJCQkJCSAgICBpbnN0ci0+Y3R4LmRhdGEubGVuKTsKPiArCQkJbWVzb25fbmFuZF9v cF9wdXRfZG1hX3NhZmVfb3V0cHV0X2J1ZihpbnN0ciwgYnVmKTsKPiArCQkJYnJlYWs7Cj4gKwo+ ICsJCWNhc2UgTkFORF9PUF9XQUlUUkRZX0lOU1RSOgo+ICsJCQltZXNvbl9uZmNfcXVldWVfcmIo bmZjLCBpbnN0ci0+Y3R4LndhaXRyZHkudGltZW91dF9tcyk7Cj4gKwkJCWlmIChpbnN0ci0+ZGVs YXlfbnMpCj4gKwkJCQltZXNvbl9uZmNfY21kX2lkbGUobmZjLCBkZWxheV9pZGxlKTsKPiArCQkJ YnJlYWs7Cj4gKwkJfQo+ICsJfQo+ICsJbWVzb25fbmZjX3dhaXRfY21kX2ZpbmlzaChuZmMsIDEw MDApOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fb29ibGF5b3V0 X2VjYyhzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNlY3Rpb24sCj4gKwkJCSAgICAgICBzdHJ1 Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPiArewo+ICsJc3RydWN0IG5hbmRfY2hpcCAq bmFuZCA9IG10ZF90b19uYW5kKG10ZCk7Cj4gKwo+ICsJaWYgKHNlY3Rpb24gPj0gbmFuZC0+ZWNj LnN0ZXBzKQo+ICsJCXJldHVybiAtRVJBTkdFOwo+ICsKPiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0g IDIgKyAoc2VjdGlvbiAqICgyICsgbmFuZC0+ZWNjLmJ5dGVzKSk7Cj4gKwlvb2JyZWdpb24tPmxl bmd0aCA9IG5hbmQtPmVjYy5ieXRlczsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBtZXNvbl9vb2JsYXlvdXRfZnJlZShzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNl Y3Rpb24sCj4gKwkJCQlzdHJ1Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPiArewo+ICsJ c3RydWN0IG5hbmRfY2hpcCAqbmFuZCA9IG10ZF90b19uYW5kKG10ZCk7Cj4gKwo+ICsJaWYgKHNl Y3Rpb24gPj0gbmFuZC0+ZWNjLnN0ZXBzKQo+ICsJCXJldHVybiAtRVJBTkdFOwo+ICsKPiArCW9v YnJlZ2lvbi0+b2Zmc2V0ID0gc2VjdGlvbiAqICgyICsgbmFuZC0+ZWNjLmJ5dGVzKTsKPiArCW9v YnJlZ2lvbi0+bGVuZ3RoID0gMjsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGlj IGNvbnN0IHN0cnVjdCBtdGRfb29ibGF5b3V0X29wcyBtZXNvbl9vb2JsYXlvdXRfb3BzID0gewo+ ICsJLmVjYyA9IG1lc29uX29vYmxheW91dF9lY2MsCj4gKwkuZnJlZSA9IG1lc29uX29vYmxheW91 dF9mcmVlLAo+ICt9Owo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uZmNfY2xrX2luaXQoc3RydWN0 IG1lc29uX25mYyAqbmZjKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCS8qIHJlcXVlc3QgY29y ZSBjbG9jayAqLwo+ICsJbmZjLT5jb3JlX2NsayA9IGRldm1fY2xrX2dldChuZmMtPmRldiwgImNv cmUiKTsKPiArCWlmIChJU19FUlIobmZjLT5jb3JlX2NsaykpIHsKPiArCQlkZXZfZXJyKG5mYy0+ ZGV2LCAiZmFpbGVkIHRvIGdldCBjb3JlIGNsa1xuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIobmZj LT5jb3JlX2Nsayk7Cj4gKwl9Cj4gKwo+ICsJbmZjLT5kZXZpY2VfY2xrID0gZGV2bV9jbGtfZ2V0 KG5mYy0+ZGV2LCAiZGV2aWNlIik7Cj4gKwlpZiAoSVNfRVJSKG5mYy0+ZGV2aWNlX2NsaykpIHsK PiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAiZmFpbGVkIHRvIGdldCBkZXZpY2UgY2xrXG4iKTsKPiAr CQlyZXR1cm4gUFRSX0VSUihuZmMtPmRldmljZV9jbGspOwo+ICsJfQo+ICsKPiArCW5mYy0+cGhh c2VfdHggPSBkZXZtX2Nsa19nZXQobmZjLT5kZXYsICJ0eCIpOwo+ICsJaWYgKElTX0VSUihuZmMt PnBoYXNlX3R4KSkgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICJmYWlsZWQgdG8gZ2V0IHR4IGNs a1xuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIobmZjLT5waGFzZV90eCk7Cj4gKwl9Cj4gKwo+ICsJ bmZjLT5waGFzZV9yeCA9IGRldm1fY2xrX2dldChuZmMtPmRldiwgInJ4Iik7Cj4gKwlpZiAoSVNf RVJSKG5mYy0+cGhhc2VfcngpKSB7Cj4gKwkJZGV2X2VycihuZmMtPmRldiwgImZhaWxlZCB0byBn ZXQgcnggY2xrXG4iKTsKPiArCQlyZXR1cm4gUFRSX0VSUihuZmMtPnBoYXNlX3J4KTsKPiArCX0K PiArCj4gKwkvKiBpbml0IFNEX0VNTUNfQ0xPQ0sgdG8gc2FuZSBkZWZhdWx0cyB3L21pbiBjbG9j ayByYXRlICovCj4gKwlyZWdtYXBfdXBkYXRlX2JpdHMobmZjLT5yZWdfY2xrLAo+ICsJCQkgICAw LCBDTEtfU0VMRUNUX05BTkQsIENMS19TRUxFQ1RfTkFORCk7Cj4gKwo+ICsJcmV0ID0gY2xrX3By ZXBhcmVfZW5hYmxlKG5mYy0+Y29yZV9jbGspOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIo bmZjLT5kZXYsICJmYWlsZWQgdG8gZW5hYmxlIGNvcmUgY2xrXG4iKTsKPiArCQlyZXR1cm4gcmV0 Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShuZmMtPmRldmljZV9jbGsp Owo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICJmYWlsZWQgdG8gZW5hYmxl IGRldmljZSBjbGtcbiIpOwo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShuZmMtPmNvcmVfY2xr KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJs ZShuZmMtPnBoYXNlX3R4KTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSB0eCBjbGtcbiIpOwo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShu ZmMtPmNvcmVfY2xrKTsKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5kZXZpY2VfY2xr KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJs ZShuZmMtPnBoYXNlX3J4KTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSByeCBjbGtcbiIpOwo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShu ZmMtPmNvcmVfY2xrKTsKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5kZXZpY2VfY2xr KTsKPiArCQljbGtfZGlzYWJsZV91bnByZXBhcmUobmZjLT5waGFzZV90eCk7CgpUaGlzIGVycm9y IGNhc2UgaXMgYSBnb29kIGNhbmRpZGF0ZSB0byBhIGdvdG8gc3RhdGVtZW50LgoKPiArCQlyZXR1 cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldCA9IGNsa19zZXRfcmF0ZShuZmMtPmRldmljZV9jbGss IDI0MDAwMDAwKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbWVzb25fbmZjX2Rpc2FibGVfY2xrKHN0cnVjdCBt ZXNvbl9uZmMgKm5mYykKPiArewo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKG5mYy0+cGhhc2Vf cngpOwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKG5mYy0+cGhhc2VfdHgpOwo+ICsJY2xrX2Rp c2FibGVfdW5wcmVwYXJlKG5mYy0+ZGV2aWNlX2Nsayk7Cj4gKwljbGtfZGlzYWJsZV91bnByZXBh cmUobmZjLT5jb3JlX2Nsayk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG1lc29uX25mY19mcmVl X2J1ZmZlcihzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZj X25hbmRfY2hpcCAqbWVzb25fY2hpcCA9IHRvX21lc29uX25hbmQobmFuZCk7Cj4gKwo+ICsJa2Zy ZWUobWVzb25fY2hpcC0+aW5mb19idWYpOwo+ICsJa2ZyZWUobWVzb25fY2hpcC0+ZGF0YV9idWYp Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX2NoaXBfYnVmZmVyX2luaXQoc3RydWN0IG5h bmRfY2hpcCAqbmFuZCkKPiArewo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210 ZChuYW5kKTsKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9f bWVzb25fbmFuZChuYW5kKTsKPiArCXUzMiBwYWdlX2J5dGVzLCBpbmZvX2J5dGVzLCBuc2VjdG9y czsKPiArCj4gKwluc2VjdG9ycyA9IG10ZC0+d3JpdGVzaXplIC8gbmFuZC0+ZWNjLnNpemU7Cj4g Kwo+ICsJcGFnZV9ieXRlcyA9ICBtdGQtPndyaXRlc2l6ZSArIG10ZC0+b29ic2l6ZTsKPiArCWlu Zm9fYnl0ZXMgPSBuc2VjdG9ycyAqIFBFUl9JTkZPX0JZVEU7Cj4gKwo+ICsJbWVzb25fY2hpcC0+ ZGF0YV9idWYgPSBrbWFsbG9jKHBhZ2VfYnl0ZXMsIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFtZXNv bl9jaGlwLT5kYXRhX2J1ZikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwltZXNvbl9jaGlw LT5pbmZvX2J1ZiA9IGttYWxsb2MoaW5mb19ieXRlcywgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIW1l c29uX2NoaXAtPmluZm9fYnVmKSB7Cj4gKwkJa2ZyZWUobWVzb25fY2hpcC0+ZGF0YV9idWYpOwo+ ICsJCXJldHVybiAtRU5PTUVNOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtz dGF0aWMKPiAraW50IG1lc29uX25mY19zZXR1cF9kYXRhX2ludGVyZmFjZShzdHJ1Y3QgbmFuZF9j aGlwICpuYW5kLCBpbnQgY3NsaW5lLAo+ICsJCQkJICAgY29uc3Qgc3RydWN0IG5hbmRfZGF0YV9p bnRlcmZhY2UgKmNvbmYpCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNv bl9jaGlwID0gdG9fbWVzb25fbmFuZChuYW5kKTsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX3Nkcl90 aW1pbmdzICp0aW1pbmdzOwo+ICsJdTMyIGRpdiwgYnRfbWluLCBidF9tYXgsIHRiZXJzX2Nsb2Nr czsKPiArCj4gKwl0aW1pbmdzID0gbmFuZF9nZXRfc2RyX3RpbWluZ3MoY29uZik7Cj4gKwlpZiAo SVNfRVJSKHRpbWluZ3MpKQo+ICsJCXJldHVybiAtRU5PVFNVUFA7Cj4gKwo+ICsJaWYgKGNzbGlu ZSA9PSBOQU5EX0RBVEFfSUZBQ0VfQ0hFQ0tfT05MWSkKPiArCQlyZXR1cm4gMDsKPiArCj4gKwlk aXYgPSBESVZfUk9VTkRfVVAoKHRpbWluZ3MtPnRSQ19taW4gLyAxMDAwKSwgTkZDX0NMS19DWUNM RSk7Cj4gKwlidF9taW4gPSAodGltaW5ncy0+dFJFQV9tYXggKyBORkNfREVGQVVMVF9ERUxBWSkg LyBkaXY7Cj4gKwlidF9tYXggPSAoTkZDX0RFRkFVTFRfREVMQVkgKyB0aW1pbmdzLT50UkhPSF9t aW4gKwo+ICsJCSAgdGltaW5ncy0+dFJDX21pbiAvIDIpIC8gZGl2Owo+ICsKPiArCW1lc29uX2No aXAtPnR3YiA9IERJVl9ST1VORF9VUChQU0VDX1RPX05TRUModGltaW5ncy0+dFdCX21heCksCj4g KwkJCQkgICAgICAgZGl2ICogTkZDX0NMS19DWUNMRSk7Cj4gKwltZXNvbl9jaGlwLT50YWRsID0g RElWX1JPVU5EX1VQKFBTRUNfVE9fTlNFQyh0aW1pbmdzLT50QURMX21pbiksCj4gKwkJCQkJZGl2 ICogTkZDX0NMS19DWUNMRSk7Cj4gKwl0YmVyc19jbG9ja3MgPSBESVZfUk9VTkRfVVAoUFNFQ19U T19OU0VDKHRpbWluZ3MtPnRCRVJTX21heCksCj4gKwkJCQkgICAgZGl2ICogTkZDX0NMS19DWUNM RSk7Cj4gKwltZXNvbl9jaGlwLT50YmVyc19tYXggPSBpbG9nMih0YmVyc19jbG9ja3MpOwo+ICsJ aWYgKCFpc19wb3dlcl9vZl8yKHRiZXJzX2Nsb2NrcykpCj4gKwkJbWVzb25fY2hpcC0+dGJlcnNf bWF4Kys7Cj4gKwo+ICsJYnRfbWluID0gRElWX1JPVU5EX1VQKGJ0X21pbiwgMTAwMCk7Cj4gKwli dF9tYXggPSBESVZfUk9VTkRfVVAoYnRfbWF4LCAxMDAwKTsKPiArCj4gKwlpZiAoYnRfbWF4IDwg YnRfbWluKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCW1lc29uX2NoaXAtPmxldmVsMV9k aXZpZGVyID0gZGl2Owo+ICsJbWVzb25fY2hpcC0+Y2xrX3JhdGUgPSAxMDAwMDAwMDAwIC8gbWVz b25fY2hpcC0+bGV2ZWwxX2RpdmlkZXI7Cj4gKwltZXNvbl9jaGlwLT5idXNfdGltaW5nID0gKGJ0 X21pbiArIGJ0X21heCkgLyAyICsgMTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBtZXNvbl9uYW5kX2JjaF9tb2RlKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQpCj4gK3sK PiArCXN0cnVjdCBtZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVzb25fbmFu ZChuYW5kKTsKPiArCXN0cnVjdCBtZXNvbl9uYW5kX2VjYyBtZXNvbl9lY2NbXSA9IHsKPiArCQlN RVNPTl9FQ0NfREFUQShORkNfRUNDX0JDSDhfMUssIDgpLAo+ICsJCU1FU09OX0VDQ19EQVRBKE5G Q19FQ0NfQkNIMjRfMUssIDI0KSwKPiArCQlNRVNPTl9FQ0NfREFUQShORkNfRUNDX0JDSDMwXzFL LCAzMCksCj4gKwkJTUVTT05fRUNDX0RBVEEoTkZDX0VDQ19CQ0g0MF8xSywgNDApLAo+ICsJCU1F U09OX0VDQ19EQVRBKE5GQ19FQ0NfQkNINTBfMUssIDUwKSwKPiArCQlNRVNPTl9FQ0NfREFUQShO RkNfRUNDX0JDSDYwXzFLLCA2MCksCj4gKwl9OwoKTWF5YmUgdGhpcyBhcnJheSBjb3VsZCBiZSBz dGF0aWM/Cgo+ICsJaW50IGk7Cj4gKwo+ICsJaWYgKG5hbmQtPmVjYy5zdHJlbmd0aCA+IDYwIHx8 IG5hbmQtPmVjYy5zdHJlbmd0aCA8IDgpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJZm9y IChpID0gMDsgaSA8IHNpemVvZihtZXNvbl9lY2MpOyBpKyspIHsKPiArCQlpZiAobWVzb25fZWNj W2ldLnN0cmVuZ3RoID09IG5hbmQtPmVjYy5zdHJlbmd0aCkgewo+ICsJCQltZXNvbl9jaGlwLT5i Y2hfbW9kZSA9IG1lc29uX2VjY1tpXS5iY2g7Cj4gKwkJCXJldHVybiAwOwo+ICsJCX0KPiArCX0K PiArCj4gKwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtZXNvbl9uYW5k X2F0dGFjaF9jaGlwKHN0cnVjdCBuYW5kX2NoaXAgKm5hbmQpCj4gK3sKPiArCXN0cnVjdCBtZXNv bl9uZmMgKm5mYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShuYW5kKTsKPiArCXN0cnVjdCBt ZXNvbl9uZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwID0gdG9fbWVzb25fbmFuZChuYW5kKTsKPiAr CXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwlpbnQgbnNlY3Rv cnMgPSBtdGQtPndyaXRlc2l6ZSAvIDEwMjQ7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWlmICghbXRk LT5uYW1lKSB7Cj4gKwkJbXRkLT5uYW1lID0gZGV2bV9rYXNwcmludGYobmZjLT5kZXYsIEdGUF9L RVJORUwsCj4gKwkJCQkJICAgIiVzOm5hbmQlZCIsCj4gKwkJCQkJICAgZGV2X25hbWUobmZjLT5k ZXYpLAo+ICsJCQkJCSAgIG1lc29uX2NoaXAtPnNlbHNbMF0pOwo+ICsJCWlmICghbXRkLT5uYW1l KQo+ICsJCQlyZXR1cm4gLUVOT01FTTsKPiArCX0KPiArCj4gKwlpZiAobmFuZC0+YmJ0X29wdGlv bnMgJiBOQU5EX0JCVF9VU0VfRkxBU0gpCj4gKwkJbmFuZC0+YmJ0X29wdGlvbnMgfD0gTkFORF9C QlRfTk9fT09COwo+ICsKPiArCW5hbmQtPm9wdGlvbnMgfD0gTkFORF9OT19TVUJQQUdFX1dSSVRF Owo+ICsKPiArCXJldCA9IG5hbmRfZWNjX2Nob29zZV9jb25mKG5hbmQsIG5mYy0+ZGF0YS0+ZWNj X2NhcHMsCj4gKwkJCQkgICBtdGQtPm9vYnNpemUgLSAyICogbnNlY3RvcnMpOwo+ICsJaWYgKHJl dCkgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICJmYWlsZWQgdG8gZWNjIGluaXRcbiIpOwo+ICsJ CXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCXJldCA9IG1lc29uX25hbmRfYmNoX21vZGUo bmFuZCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCW5hbmQtPmVj Yy5tb2RlID0gTkFORF9FQ0NfSFc7Cj4gKwluYW5kLT5lY2Mud3JpdGVfcGFnZV9yYXcgPSBtZXNv bl9uZmNfd3JpdGVfcGFnZV9yYXc7Cj4gKwluYW5kLT5lY2Mud3JpdGVfcGFnZSA9IG1lc29uX25m Y193cml0ZV9wYWdlX2h3ZWNjOwo+ICsJbmFuZC0+ZWNjLndyaXRlX29vYl9yYXcgPSBuYW5kX3dy aXRlX29vYl9zdGQ7Cj4gKwluYW5kLT5lY2Mud3JpdGVfb29iID0gbmFuZF93cml0ZV9vb2Jfc3Rk Owo+ICsKPiArCW5hbmQtPmVjYy5yZWFkX3BhZ2VfcmF3ID0gbWVzb25fbmZjX3JlYWRfcGFnZV9y YXc7Cj4gKwluYW5kLT5lY2MucmVhZF9wYWdlID0gbWVzb25fbmZjX3JlYWRfcGFnZV9od2VjYzsK PiArCW5hbmQtPmVjYy5yZWFkX29vYl9yYXcgPSBtZXNvbl9uZmNfcmVhZF9vb2JfcmF3Owo+ICsJ bmFuZC0+ZWNjLnJlYWRfb29iID0gbWVzb25fbmZjX3JlYWRfb29iOwo+ICsKPiArCWlmIChuYW5k LT5vcHRpb25zICYgTkFORF9CVVNXSURUSF8xNikgewo+ICsJCWRldl9lcnIobmZjLT5kZXYsICIx NmJpdHMgYnVzd2lkdGggbm90IHN1cHBvcnRlZCIpOwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJ fQo+ICsJbWVzb25fY2hpcF9idWZmZXJfaW5pdChuYW5kKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0 dXJuIC1FTk9NRU07Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBuYW5kX2NvbnRyb2xsZXJfb3BzIG1lc29uX25hbmRfY29udHJvbGxlcl9vcHMgPSB7 Cj4gKwkuYXR0YWNoX2NoaXAgPSBtZXNvbl9uYW5kX2F0dGFjaF9jaGlwLAoKRG9uJ3QgeW91IG5l ZWQgYSAtPmRldGFjaF9jaGlwIGhvb2sgdG8gZnJlZSBkYXRhX2J1Zi9pbmZvX2J1ZgpidWZmZXJz PwoKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQKPiArbWVzb25fbmZjX25hbmRfY2hpcF9pbml0KHN0 cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJIHN0cnVjdCBtZXNvbl9uZmMgKm5mYywgc3RydWN0IGRl dmljZV9ub2RlICpucCkKPiArewo+ICsJc3RydWN0IG1lc29uX25mY19uYW5kX2NoaXAgKm1lc29u X2NoaXA7Cj4gKwlzdHJ1Y3QgbmFuZF9jaGlwICpuYW5kOwo+ICsJc3RydWN0IG10ZF9pbmZvICpt dGQ7Cj4gKwlpbnQgcmV0LCBpOwo+ICsJdTMyIHRtcCwgbnNlbHM7Cj4gKwo+ICsJaWYgKCFvZl9n ZXRfcHJvcGVydHkobnAsICJyZWciLCAmbnNlbHMpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsK PiArCW5zZWxzIC89IHNpemVvZih1MzIpOwo+ICsJaWYgKCFuc2VscyB8fCBuc2VscyA+IE1BWF9D RV9OVU0pIHsKPiArCQlkZXZfZXJyKGRldiwgImludmFsaWQgcmVnIHByb3BlcnR5IHNpemVcbiIp Owo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCW1lc29uX2NoaXAgPSBkZXZtX2t6 YWxsb2MoZGV2LAo+ICsJCQkJICBzaXplb2YoKm1lc29uX2NoaXApICsgKG5zZWxzICogc2l6ZW9m KHU4KSksCj4gKwkJCQkgIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFtZXNvbl9jaGlwKQo+ICsJCXJl dHVybiAtRU5PTUVNOwo+ICsKPiArCW1lc29uX2NoaXAtPm5zZWxzID0gbnNlbHM7Cj4gKwo+ICsJ Zm9yIChpID0gMDsgaSA8IG5zZWxzOyBpKyspIHsKPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFk X3UzMl9pbmRleChucCwgInJlZyIsIGksICZ0bXApOwo+ICsJCWlmIChyZXQpIHsKPiArCQkJZGV2 X2VycihkZXYsICJjb3VsZCBub3QgcmV0cmlldmUgcmVnIHByb3BlcnR5OiAlZFxuIiwKPiArCQkJ CXJldCk7Cj4gKwkJCXJldHVybiByZXQ7Cj4gKwkJfQo+ICsKPiArCQlpZiAodGVzdF9hbmRfc2V0 X2JpdCh0bXAsICZuZmMtPmFzc2lnbmVkX2NzKSkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkNTICVk IGFscmVhZHkgYXNzaWduZWRcbiIsIHRtcCk7Cj4gKwkJCXJldHVybiAtRUlOVkFMOwo+ICsJCX0K PiArCX0KPiArCj4gKwluYW5kID0gJm1lc29uX2NoaXAtPm5hbmQ7Cj4gKwluYW5kLT5jb250cm9s bGVyID0gJm5mYy0+Y29udHJvbGxlcjsKPiArCW5hbmQtPmNvbnRyb2xsZXItPm9wcyA9ICZtZXNv bl9uYW5kX2NvbnRyb2xsZXJfb3BzOwo+ICsJbmFuZF9zZXRfZmxhc2hfbm9kZShuYW5kLCBucCk7 Cj4gKwluYW5kX3NldF9jb250cm9sbGVyX2RhdGEobmFuZCwgbmZjKTsKPiArCj4gKwluYW5kLT5v cHRpb25zIHw9IE5BTkRfVVNFX0JPVU5DRV9CVUZGRVI7Cj4gKwluYW5kLT5zZWxlY3RfY2hpcCA9 IG1lc29uX25mY19zZWxlY3RfY2hpcDsKPiArCW5hbmQtPmV4ZWNfb3AgPSBtZXNvbl9uZmNfZXhl Y19vcDsKPiArCW5hbmQtPnNldHVwX2RhdGFfaW50ZXJmYWNlID0gbWVzb25fbmZjX3NldHVwX2Rh dGFfaW50ZXJmYWNlOwo+ICsJbXRkID0gbmFuZF90b19tdGQobmFuZCk7Cj4gKwltdGQtPm93bmVy ID0gVEhJU19NT0RVTEU7Cj4gKwltdGQtPmRldi5wYXJlbnQgPSBkZXY7Cj4gKwo+ICsJcmV0ID0g bmFuZF9zY2FuKG5hbmQsIG5zZWxzKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiAr Cj4gKwlyZXQgPSBtdGRfZGV2aWNlX3JlZ2lzdGVyKG10ZCwgTlVMTCwgMCk7Cj4gKwlpZiAocmV0 KSB7Cj4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcmVnaXN0ZXIgbXRkIGRldmljZTogJWRc biIsIHJldCk7Cj4gKwkJbmFuZF9jbGVhbnVwKG5hbmQpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9 Cj4gKwo+ICsJbGlzdF9hZGRfdGFpbCgmbWVzb25fY2hpcC0+bm9kZSwgJm5mYy0+Y2hpcHMpOwo+ ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG1lc29uX25mY19uYW5kX2No aXBfY2xlYW51cChzdHJ1Y3QgbWVzb25fbmZjICpuZmMpCj4gK3sKPiArCXN0cnVjdCBtZXNvbl9u ZmNfbmFuZF9jaGlwICptZXNvbl9jaGlwOwo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQ7Cj4gKwlp bnQgcmV0Owo+ICsKPiArCXdoaWxlICghbGlzdF9lbXB0eSgmbmZjLT5jaGlwcykpIHsKPiArCQlt ZXNvbl9jaGlwID0gbGlzdF9maXJzdF9lbnRyeSgmbmZjLT5jaGlwcywKPiArCQkJCQkgICAgICBz dHJ1Y3QgbWVzb25fbmZjX25hbmRfY2hpcCwgbm9kZSk7Cj4gKwkJbXRkID0gbmFuZF90b19tdGQo Jm1lc29uX2NoaXAtPm5hbmQpOwo+ICsJCXJldCA9IG10ZF9kZXZpY2VfdW5yZWdpc3RlcihtdGQp Owo+ICsJCWlmIChyZXQpCj4gKwkJCXJldHVybiByZXQ7Cj4gKwo+ICsJCW1lc29uX25mY19mcmVl X2J1ZmZlcigmbWVzb25fY2hpcC0+bmFuZCk7Cj4gKwkJbmFuZF9jbGVhbnVwKCZtZXNvbl9jaGlw LT5uYW5kKTsKPiArCQlsaXN0X2RlbCgmbWVzb25fY2hpcC0+bm9kZSk7Cj4gKwl9Cj4gKwo+ICsJ cmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX25hbmRfY2hpcHNfaW5p dChzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gKwkJCQkgICAgIHN0cnVjdCBtZXNvbl9uZmMgKm5mYykK PiArewo+ICsJc3RydWN0IGRldmljZV9ub2RlICpucCA9IGRldi0+b2Zfbm9kZTsKPiArCXN0cnVj dCBkZXZpY2Vfbm9kZSAqbmFuZF9ucDsKPiArCWludCByZXQ7Cj4gKwo+ICsJZm9yX2VhY2hfY2hp bGRfb2Zfbm9kZShucCwgbmFuZF9ucCkgewo+ICsJCXJldCA9IG1lc29uX25mY19uYW5kX2NoaXBf aW5pdChkZXYsIG5mYywgbmFuZF9ucCk7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQltZXNvbl9uZmNf bmFuZF9jaGlwX2NsZWFudXAobmZjKTsKPiArCQkJcmV0dXJuIHJldDsKPiArCQl9Cj4gKwl9Cj4g Kwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBtZXNvbl9uZmNf aXJxKGludCBpcnEsIHZvaWQgKmlkKQo+ICt7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmMgPSBp ZDsKPiArCXUzMiBjZmc7Cj4gKwo+ICsJY2ZnID0gcmVhZGwobmZjLT5yZWdfYmFzZSArIE5GQ19S RUdfQ0ZHKTsKPiArCWlmICghKGNmZyAmIE5GQ19SQl9JUlFfRU4pKQo+ICsJCXJldHVybiBJUlFf Tk9ORTsKPiArCj4gKwljZmcgJj0gfihORkNfUkJfSVJRX0VOKTsKPiArCXdyaXRlbChjZmcsIG5m Yy0+cmVnX2Jhc2UgKyBORkNfUkVHX0NGRyk7Cj4gKwo+ICsJY29tcGxldGUoJm5mYy0+Y29tcGxl dGlvbik7Cj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgbWVzb25fbmZjX2RhdGEgbWVzb25fZ3hsX2RhdGEgPSB7Cj4gKwkuZWNjX2NhcHMgPSAm bWVzb25fZ3hsX2VjY19jYXBzLAo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBtZXNv bl9uZmNfZGF0YSBtZXNvbl9heGdfZGF0YSA9IHsKPiArCS5lY2NfY2FwcyA9ICZtZXNvbl9heGdf ZWNjX2NhcHMsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBt ZXNvbl9uZmNfaWRfdGFibGVbXSA9IHsKPiArCXsKPiArCQkuY29tcGF0aWJsZSA9ICJhbWxvZ2lj LG1lc29uLWd4bC1uZmMiLAo+ICsJCS5kYXRhID0gJm1lc29uX2d4bF9kYXRhLAo+ICsJfSwgewo+ ICsJCS5jb21wYXRpYmxlID0gImFtbG9naWMsbWVzb24tYXhnLW5mYyIsCj4gKwkJLmRhdGEgPSAm bWVzb25fYXhnX2RhdGEsCj4gKwl9LAo+ICsJe30KPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJM RShvZiwgbWVzb25fbmZjX2lkX3RhYmxlKTsKPiArCj4gK3N0YXRpYyBpbnQgbWVzb25fbmZjX3By b2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBkZXZpY2Ug KmRldiA9ICZwZGV2LT5kZXY7Cj4gKwlzdHJ1Y3QgbWVzb25fbmZjICpuZmM7Cj4gKwlzdHJ1Y3Qg cmVzb3VyY2UgKnJlczsKPiArCWludCByZXQsIGlycTsKPiArCj4gKwluZmMgPSBkZXZtX2t6YWxs b2MoZGV2LCBzaXplb2YoKm5mYyksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFuZmMpCj4gKwkJcmV0 dXJuIC1FTk9NRU07Cj4gKwo+ICsJbmZjLT5kYXRhID0gb2ZfZGV2aWNlX2dldF9tYXRjaF9kYXRh KCZwZGV2LT5kZXYpOwo+ICsJaWYgKCFuZmMtPmRhdGEpCj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4g Kwo+ICsJbmFuZF9jb250cm9sbGVyX2luaXQoJm5mYy0+Y29udHJvbGxlcik7Cj4gKwlJTklUX0xJ U1RfSEVBRCgmbmZjLT5jaGlwcyk7Cj4gKwo+ICsJbmZjLT5kZXYgPSBkZXY7Cj4gKwo+ICsJcmVz ID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKPiArCW5m Yy0+cmVnX2Jhc2UgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCByZXMpOwo+ICsJaWYgKElT X0VSUihuZmMtPnJlZ19iYXNlKSkKPiArCQlyZXR1cm4gUFRSX0VSUihuZmMtPnJlZ19iYXNlKTsK PiArCj4gKwluZmMtPnJlZ19jbGsgPQo+ICsJCXN5c2Nvbl9yZWdtYXBfbG9va3VwX2J5X3BoYW5k bGUoZGV2LT5vZl9ub2RlLAo+ICsJCQkJCQkiYW1sb2dpYyxtbWMtc3lzY29uIik7Cj4gKwlpZiAo SVNfRVJSKG5mYy0+cmVnX2NsaykpIHsKPiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBsb29r dXAgY2xvY2sgYmFzZVxuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIobmZjLT5yZWdfY2xrKTsKPiAr CX0KPiArCj4gKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwo+ICsJaWYgKGlycSA8 IDApIHsKPiArCQlkZXZfZXJyKGRldiwgIm5vIG5maSBpcnEgcmVzb3VyY2VcbiIpOwo+ICsJCXJl dHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCXJldCA9IG1lc29uX25mY19jbGtfaW5pdChuZmMp Owo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGluaXRpYWxpemUg bmFuZCBjbGtcbiIpOwo+ICsJCWdvdG8gZXJyOwoKVXNlbGVzcyBnb3RvLCBhIHJldHVybiB3b3Vs ZCBiZSBlbm91Z2guCgo+ICsJfQo+ICsKPiArCXdyaXRlbCgwLCBuZmMtPnJlZ19iYXNlICsgTkZD X1JFR19DRkcpOwo+ICsJcmV0ID0gZGV2bV9yZXF1ZXN0X2lycShkZXYsIGlycSwgbWVzb25fbmZj X2lycSwgMCwgZGV2X25hbWUoZGV2KSwgbmZjKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJy KGRldiwgImZhaWxlZCB0byByZXF1ZXN0IG5maSBpcnFcbiIpOwo+ICsJCXJldCA9IC1FSU5WQUw7 Cj4gKwkJZ290byBlcnJfY2xrOwo+ICsJfQo+ICsKPiArCXJldCA9IGRtYV9zZXRfbWFzayhkZXYs IERNQV9CSVRfTUFTSygzMikpOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFp bGVkIHRvIHNldCBkbWEgbWFza1xuIik7CgpOaXQ6IEkgcHJlZmVyIHdoZW4gYWNyb255bXMgYXJl IHVwcGVyIGNhc2UgaW4gcGxhaW4gRW5nbGlzaCAoRE1BLCBOQU5ELApJUlEsIGV0YykuCgo+ICsJ CWdvdG8gZXJyX2NsazsKPiArCX0KPiArCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBu ZmMpOwo+ICsKPiArCXJldCA9IG1lc29uX25mY19uYW5kX2NoaXBzX2luaXQoZGV2LCBuZmMpOwo+ ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGluaXQgbmFuZCBjaGlw c1xuIik7Cj4gKwkJZ290byBlcnJfY2xrOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICsKPiAr ZXJyX2NsazoKPiArCW1lc29uX25mY19kaXNhYmxlX2NsayhuZmMpOwo+ICtlcnI6CgpUaGlzIGdv dG8gY2FuIGJlIHJlbW92ZWQuCgo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBtZXNvbl9uZmNfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiAr CXN0cnVjdCBtZXNvbl9uZmMgKm5mYyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ICsJ aW50IHJldDsKPiArCj4gKwlyZXQgPSBtZXNvbl9uZmNfbmFuZF9jaGlwX2NsZWFudXAobmZjKTsK PiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwltZXNvbl9uZmNfZGlzYWJsZV9j bGsobmZjKTsKPiArCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBOVUxMKTsKPiArCj4g KwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbWVz b25fbmZjX2RyaXZlciA9IHsKPiArCS5wcm9iZSAgPSBtZXNvbl9uZmNfcHJvYmUsCj4gKwkucmVt b3ZlID0gbWVzb25fbmZjX3JlbW92ZSwKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgID0gIm1l c29uLW5hbmQiLAo+ICsJCS5vZl9tYXRjaF90YWJsZSA9IG1lc29uX25mY19pZF90YWJsZSwKPiAr CX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIobWVzb25fbmZjX2RyaXZlcik7Cj4g Kwo+ICtNT0RVTEVfTElDRU5TRSgiRHVhbCBNSVQvR1BMIik7Cj4gK01PRFVMRV9BVVRIT1IoIkxp YW5nIFlhbmcgPGxpYW5nLnlhbmdAYW1sb2dpYy5jb20+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElP TigiQW1sb2dpYydzIE1lc29uIE5BTkQgRmxhc2ggQ29udHJvbGxlciBkcml2ZXIiKTsKCgoKClRo YW5rcywKTWlxdcOobAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX18KbGludXgtYW1sb2dpYyBtYWlsaW5nIGxpc3QKbGludXgtYW1sb2dpY0BsaXN0cy5pbmZy YWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGlu dXgtYW1sb2dpYwo=