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 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 7A4ECC04A6B for ; Sun, 12 May 2019 13:19:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 420D92146F for ; Sun, 12 May 2019 13:19:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726728AbfELNTA convert rfc822-to-8bit (ORCPT ); Sun, 12 May 2019 09:19:00 -0400 Received: from relay2-d.mail.gandi.net ([217.70.183.194]:39501 "EHLO relay2-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726415AbfELNTA (ORCPT ); Sun, 12 May 2019 09:19:00 -0400 X-Originating-IP: 109.190.253.16 Received: from xps13 (unknown [109.190.253.16]) (Authenticated sender: miquel.raynal@bootlin.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id DC27B40003; Sun, 12 May 2019 13:18:47 +0000 (UTC) Date: Sun, 12 May 2019 15:18:36 +0200 From: Miquel Raynal To: Mason Yang Cc: broonie@kernel.org, marek.vasut@gmail.com, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, bbrezillon@kernel.org, dwmw2@infradead.org, lee.jones@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, computersforpeace@gmail.com, paul.burton@mips.com, stefan@agner.ch, christophe.kerello@st.com, liang.yang@amlogic.com, geert@linux-m68k.org, devicetree@vger.kernel.org, marcel.ziswiler@toradex.com, linux-mtd@lists.infradead.org, richard@nod.at, juliensu@mxic.com.tw, zhengxunli@mxic.com.tw Subject: Re: [PATCH v3 2/4] mtd: rawnand: Add Macronix MX25F0A NAND controller Message-ID: <20190512151820.4f2dd9da@xps13> In-Reply-To: <1555320234-15802-3-git-send-email-masonccyang@mxic.com.tw> References: <1555320234-15802-1-git-send-email-masonccyang@mxic.com.tw> <1555320234-15802-3-git-send-email-masonccyang@mxic.com.tw> 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 Mason, Mason Yang wrote on Mon, 15 Apr 2019 17:23:52 +0800: > Add a driver for Macronix MX25F0A NAND controller. > > Signed-off-by: Mason Yang > --- > drivers/mtd/nand/raw/Kconfig | 6 + > drivers/mtd/nand/raw/Makefile | 1 + > drivers/mtd/nand/raw/mxic_nand.c | 294 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 301 insertions(+) > create mode 100644 drivers/mtd/nand/raw/mxic_nand.c > > diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig > index e604625..e0329cc 100644 > --- a/drivers/mtd/nand/raw/Kconfig > +++ b/drivers/mtd/nand/raw/Kconfig > @@ -522,6 +522,12 @@ config MTD_NAND_QCOM > Enables support for NAND flash chips on SoCs containing the EBI2 NAND > controller. This controller is found on IPQ806x SoC. > > +config MTD_NAND_MXIC > + tristate "Macronix MX25F0A NAND controller" > + depends on HAS_IOMEM > + help > + This selects the Macronix MX25F0A NAND controller driver. > + > config MTD_NAND_MTK > tristate "Support for NAND controller on MTK SoCs" > depends on ARCH_MEDIATEK || COMPILE_TEST > diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile > index 5a5a72f..c8a6790 100644 > --- a/drivers/mtd/nand/raw/Makefile > +++ b/drivers/mtd/nand/raw/Makefile > @@ -54,6 +54,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o > obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o > obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ > obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o > +obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o > obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o > obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o > obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o > diff --git a/drivers/mtd/nand/raw/mxic_nand.c b/drivers/mtd/nand/raw/mxic_nand.c > new file mode 100644 > index 0000000..689fae2 > --- /dev/null > +++ b/drivers/mtd/nand/raw/mxic_nand.c > @@ -0,0 +1,294 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// > +// Copyright (C) 2019 Macronix International Co., Ltd. > +// > +// Authors: > +// Mason Yang > +// zhengxunli This is not a valid name. Also if he appears here I suppose he should be credited in the module_authors() macro too. > +// As a personal taste, I prefer when the header uses /* */ and only the SPDX tag uses //. > + > +#include > +#include > +#include > + > +#include "internals.h" > + > +struct mxic_nand_ctlr { > + struct mx25f0a_mfd *mfd; > + struct nand_controller base; > + struct nand_chip nand; Even if this controller only supports one CS (and then, one chip), please have a clear separation between the NAND controller and the NAND chip by having one structure for the NAND chips and one structure for the NAND controller. > +}; > + > +static void mxic_host_init(struct mxic_nand_ctlr *mxic) Please choose a constant prefix for all functions, right now there is: mxic_ mxic_nand_ mx25f0a_nand_ I think mxic_nand_ or mx25f0a_nand_ is wise. > +{ > + writel(DATA_STROB_EDO_EN, mxic->mfd->regs + DATA_STROB); > + writel(INT_STS_ALL, mxic->mfd->regs + INT_STS_EN); > + writel(0x0, mxic->mfd->regs + ONFI_DIN_CNT(0)); > + writel(HC_CFG_NIO(8) | HC_CFG_SLV_ACT(0) | HC_CFG_IDLE_SIO_LVL(1) | > + HC_CFG_TYPE(1, HC_CFG_TYPE_RAW_NAND) | HC_CFG_MAN_CS_EN, > + mxic->mfd->regs + HC_CFG); > + writel(0x0, mxic->mfd->regs + HC_EN); > +} > + > +static int mxic_nand_wait_ready(struct nand_chip *chip) > +{ > + struct mxic_nand_ctlr *mxic = nand_get_controller_data(chip); > + u32 sts; > + > + return readl_poll_timeout(mxic->mfd->regs + INT_STS, sts, > + sts & INT_RDY_PIN, 0, USEC_PER_SEC); > +} > + > +static void mxic_nand_select_chip(struct nand_chip *chip, int chipnr) _select_target() is preferred now > +{ > + struct mxic_nand_ctlr *mxic = nand_get_controller_data(chip); > + > + switch (chipnr) { > + case 0: > + case 1: > + writel(HC_EN_BIT, mxic->mfd->regs + HC_EN); > + writel(HC_CFG_MAN_CS_ASSERT | readl(mxic->mfd->regs + HC_CFG), > + mxic->mfd->regs + HC_CFG); In both case I would prefer a: reg = readl(...); reg &= ~xxx; reg |= yyy; writel(reg, ...); Much easier to read. > + break; > + > + case -1: > + writel(~HC_CFG_MAN_CS_ASSERT & readl(mxic->mfd->regs + HC_CFG), > + mxic->mfd->regs + HC_CFG); > + writel(0, mxic->mfd->regs + HC_EN); > + break; > + > + default: Error? > + break; > + } > +} > + > +static int mxic_nand_data_xfer(struct mxic_nand_ctlr *mxic, const void *txbuf, > + void *rxbuf, unsigned int len) > +{ There is not so much code shared, why not separating this function for rx and tx cases? > + unsigned int pos = 0; > + > + while (pos < len) { > + unsigned int nbytes = len - pos; > + u32 data = 0xffffffff; > + u32 sts; > + int ret; > + > + if (nbytes > 4) > + nbytes = 4; > + > + if (txbuf) > + memcpy(&data, txbuf + pos, nbytes); > + > + ret = readl_poll_timeout(mxic->mfd->regs + INT_STS, sts, > + sts & INT_TX_EMPTY, 0, USEC_PER_SEC); Using USEC_PER_SEC for a delay is weird > + if (ret) > + return ret; > + > + writel(data, mxic->mfd->regs + TXD(nbytes % 4)); > + > + if (rxbuf) { > + ret = readl_poll_timeout(mxic->mfd->regs + INT_STS, sts, > + sts & INT_TX_EMPTY, 0, > + USEC_PER_SEC); > + if (ret) > + return ret; > + > + ret = readl_poll_timeout(mxic->mfd->regs + INT_STS, sts, > + sts & INT_RX_NOT_EMPTY, 0, > + USEC_PER_SEC); > + if (ret) > + return ret; > + > + data = readl(mxic->mfd->regs + RXD); > + data >>= (8 * (4 - nbytes)); What is this? Are you trying to handle some endianness issue? > + memcpy(rxbuf + pos, &data, nbytes); > + WARN_ON(readl(mxic->mfd->regs + INT_STS) & > + INT_RX_NOT_EMPTY); > + } else { > + readl(mxic->mfd->regs + RXD); > + } > + WARN_ON(readl(mxic->mfd->regs + INT_STS) & INT_RX_NOT_EMPTY); > + > + pos += nbytes; > + } > + > + return 0; > +} > + > +static int mxic_nand_exec_op(struct nand_chip *chip, > + const struct nand_operation *op, bool check_only) > +{ > + struct mxic_nand_ctlr *mxic = nand_get_controller_data(chip); > + const struct nand_op_instr *instr = NULL; > + int i, len = 0, ret = 0; > + unsigned int op_id; > + unsigned char cmdcnt = 0, addr_cnt = 0, cmd_addr[8] = {0}; > + > + for (op_id = 0; op_id < op->ninstrs; op_id++) { > + instr = &op->instrs[op_id]; > + > + switch (instr->type) { > + case NAND_OP_CMD_INSTR: > + cmd_addr[len++] = instr->ctx.cmd.opcode; > + cmdcnt++; > + break; > + > + case NAND_OP_ADDR_INSTR: > + for (i = 0; i < instr->ctx.addr.naddrs; i++) > + cmd_addr[len++] = instr->ctx.addr.addrs[i]; > + addr_cnt = i; > + break; > + > + case NAND_OP_DATA_IN_INSTR: > + break; > + > + case NAND_OP_DATA_OUT_INSTR: > + writel(instr->ctx.data.len, > + mxic->mfd->regs + ONFI_DIN_CNT(0)); > + break; > + > + case NAND_OP_WAITRDY_INSTR: > + break; > + } > + } > + > + if (op_id == 5 && instr->type == NAND_OP_WAITRDY_INSTR) { > + /* > + * In case cmd-addr-data-cmd-wait in a sequence, > + * separate the 2'nd command, i.e,. nand_prog_page_op() > + */ I think this is the kind of limitation that could be described very easily with a nand_op_parser structure and used by nand_op_parser_exec_op() (see marvell_nand.c). > + writel(OP_CMD_BUSW(OP_BUSW_8) | OP_ADDR_BUSW(OP_BUSW_8) | > + OP_DATA_BUSW(OP_BUSW_8) | OP_DUMMY_CYC(0x3F) | > + OP_ADDR_BYTES(addr_cnt) | > + OP_CMD_BYTES(1), mxic->mfd->regs + SS_CTRL(0)); > + writel(0, mxic->mfd->regs + HC_EN); > + writel(HC_EN_BIT, mxic->mfd->regs + HC_EN); > + > + mxic_nand_data_xfer(mxic, cmd_addr, NULL, len - 1); > + > + mxic_nand_data_xfer(mxic, instr->ctx.data.buf.out, NULL, > + instr->ctx.data.len); > + > + writel(0, mxic->mfd->regs + HC_EN); > + writel(HC_EN_BIT, mxic->mfd->regs + HC_EN); > + mxic_nand_data_xfer(mxic, &cmd_addr[--len], NULL, 1); > + ret = mxic_nand_wait_ready(chip); > + if (ret) > + goto err_out; > + return ret; > + } > + > + if (len) { > + writel(OP_CMD_BUSW(OP_BUSW_8) | OP_ADDR_BUSW(OP_BUSW_8) | > + OP_DATA_BUSW(OP_BUSW_8) | OP_DUMMY_CYC(0x3F) | > + OP_ADDR_BYTES(addr_cnt) | > + OP_CMD_BYTES(cmdcnt > 0 ? cmdcnt : 0), > + mxic->mfd->regs + SS_CTRL(0)); > + writel(0, mxic->mfd->regs + HC_EN); > + writel(HC_EN_BIT, mxic->mfd->regs + HC_EN); > + > + mxic_nand_data_xfer(mxic, cmd_addr, NULL, len); > + } > + > + for (op_id = 0; op_id < op->ninstrs; op_id++) { > + instr = &op->instrs[op_id]; > + > + switch (instr->type) { > + case NAND_OP_CMD_INSTR: > + case NAND_OP_ADDR_INSTR: > + break; > + > + case NAND_OP_DATA_IN_INSTR: > + writel(0x0, mxic->mfd->regs + ONFI_DIN_CNT(0)); > + writel(readl(mxic->mfd->regs + SS_CTRL(0)) | OP_READ, > + mxic->mfd->regs + SS_CTRL(0)); > + mxic_nand_data_xfer(mxic, NULL, instr->ctx.data.buf.in, > + instr->ctx.data.len); > + break; > + > + case NAND_OP_DATA_OUT_INSTR: > + mxic_nand_data_xfer(mxic, instr->ctx.data.buf.out, NULL, > + instr->ctx.data.len); > + break; > + > + case NAND_OP_WAITRDY_INSTR: > + ret = mxic_nand_wait_ready(chip); > + if (ret) > + goto err_out; > + break; > + } > + } > + > +err_out: > + return ret; Ditto, please return directly if there is nothing in the error path. > +} > + > +static const struct nand_controller_ops mxic_nand_controller_ops = { > + .exec_op = mxic_nand_exec_op, > +}; > + > +static int mx25f0a_nand_probe(struct platform_device *pdev) > +{ > + struct mtd_info *mtd; > + struct mx25f0a_mfd *mfd = dev_get_drvdata(pdev->dev.parent); > + struct mxic_nand_ctlr *mxic; > + struct nand_chip *nand_chip; > + int err; > + > + mxic = devm_kzalloc(&pdev->dev, sizeof(struct mxic_nand_ctlr), > + GFP_KERNEL); mxic for a NAND controller structure is probably not a name meaningful enough. > + if (!mxic) > + return -ENOMEM; > + > + nand_chip = &mxic->nand; > + mtd = nand_to_mtd(nand_chip); > + mtd->dev.parent = pdev->dev.parent; > + nand_chip->ecc.priv = NULL; > + nand_set_flash_node(nand_chip, pdev->dev.parent->of_node); > + nand_chip->priv = mxic; > + > + mxic->mfd = mfd; > + > + nand_chip->legacy.select_chip = mxic_nand_select_chip; Please don't implement legacy interfaces. You can check in marvell_nand.c how this is handled now: b25251414f6e mtd: rawnand: marvell: Stop implementing ->select_chip() > + mxic->base.ops = &mxic_nand_controller_ops; > + nand_controller_init(&mxic->base); > + nand_chip->controller = &mxic->base; > + > + mxic_host_init(mxic); > + > + err = nand_scan(nand_chip, 1); > + if (err) > + goto fail; You can return directly as there is nothing to clean in the error path. > + > + err = mtd_device_register(mtd, NULL, 0); > + if (err) > + goto fail; Ditto > + > + platform_set_drvdata(pdev, mxic); > + > + return 0; > +fail: > + return err; > +} > + > +static int mx25f0a_nand_remove(struct platform_device *pdev) > +{ > + struct mxic_nand_ctlr *mxic = platform_get_drvdata(pdev); > + > + nand_release(&mxic->nand); > + > + return 0; > +} > + > +static struct platform_driver mx25f0a_nand_driver = { > + .probe = mx25f0a_nand_probe, Please don't align '=' on tabs. > + .remove = mx25f0a_nand_remove, > + .driver = { > + .name = "mxic-nand-ctlr", > + }, > +}; > +module_platform_driver(mx25f0a_nand_driver); mx25f0a_nand_controller_driver would be better > + > +MODULE_AUTHOR("Mason Yang "); > +MODULE_DESCRIPTION("MX25F0A RAW NAND controller driver"); > +MODULE_LICENSE("GPL v2"); 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=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS 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 62824C04A6B for ; Sun, 12 May 2019 13:19:11 +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 2E8082173B for ; Sun, 12 May 2019 13:19:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ZaAJct7i" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2E8082173B 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-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id: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=l0BiTp/A31Bh+dwTyuksEj7YH9+emCR73rXTID+vVZM=; b=ZaAJct7iEyQShL yNbpMgqZ3tRh8JT6QgddyUfcyKfXm8hlfMMmWVTTwxu2i8veVrQF9J0QsJPeTozLEfJxGmbWL2Mgb TYteog+AeU3a5vRNLW5jPH7zQxVmLFDvCfiqxvwwYWCPtjcO+tsyqqk2u5hZe+bq2aSvXwqjD2Zst 9XtAcRpWMLHIO88rungS7JM99LqaMeSxYs3+w9Lf0tp3mhPsfQL3YO7pCQV9/mTiMCxJad488HbXk VQBJcVlhiOGAqUzXGe0zrLSv5nE8naNHiRQVNHqnF1reJreEiLyBXzzxGvfLNZo0Z15WsWAIldzOC wSg09eEtYpuqoGEeE6Sw==; 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 1hPoNf-0006iH-3w; Sun, 12 May 2019 13:19:07 +0000 Received: from relay2-d.mail.gandi.net ([217.70.183.194]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hPoNb-0006hT-Lp for linux-mtd@lists.infradead.org; Sun, 12 May 2019 13:19:06 +0000 X-Originating-IP: 109.190.253.16 Received: from xps13 (unknown [109.190.253.16]) (Authenticated sender: miquel.raynal@bootlin.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id DC27B40003; Sun, 12 May 2019 13:18:47 +0000 (UTC) Date: Sun, 12 May 2019 15:18:36 +0200 From: Miquel Raynal To: Mason Yang Subject: Re: [PATCH v3 2/4] mtd: rawnand: Add Macronix MX25F0A NAND controller Message-ID: <20190512151820.4f2dd9da@xps13> In-Reply-To: <1555320234-15802-3-git-send-email-masonccyang@mxic.com.tw> References: <1555320234-15802-1-git-send-email-masonccyang@mxic.com.tw> <1555320234-15802-3-git-send-email-masonccyang@mxic.com.tw> 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-20190512_061904_019326_44AC2879 X-CRM114-Status: GOOD ( 27.22 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, christophe.kerello@st.com, juliensu@mxic.com.tw, bbrezillon@kernel.org, marcel.ziswiler@toradex.com, lee.jones@linaro.org, linux-kernel@vger.kernel.org, robh+dt@kernel.org, linux-spi@vger.kernel.org, marek.vasut@gmail.com, paul.burton@mips.com, broonie@kernel.org, geert@linux-m68k.org, stefan@agner.ch, linux-mtd@lists.infradead.org, richard@nod.at, liang.yang@amlogic.com, computersforpeace@gmail.com, dwmw2@infradead.org, zhengxunli@mxic.com.tw Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGkgTWFzb24sCgpNYXNvbiBZYW5nIDxtYXNvbmNjeWFuZ0BteGljLmNvbS50dz4gd3JvdGUgb24g TW9uLCAxNSBBcHIgMjAxOSAxNzoyMzo1MgorMDgwMDoKCj4gQWRkIGEgZHJpdmVyIGZvciBNYWNy b25peCBNWDI1RjBBIE5BTkQgY29udHJvbGxlci4KPiAKPiBTaWduZWQtb2ZmLWJ5OiBNYXNvbiBZ YW5nIDxtYXNvbmNjeWFuZ0BteGljLmNvbS50dz4KPiAtLS0KPiAgZHJpdmVycy9tdGQvbmFuZC9y YXcvS2NvbmZpZyAgICAgfCAgIDYgKwo+ICBkcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZSAg ICB8ICAgMSArCj4gIGRyaXZlcnMvbXRkL25hbmQvcmF3L214aWNfbmFuZC5jIHwgMjk0ICsrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ICAzIGZpbGVzIGNoYW5nZWQsIDMw MSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL210ZC9uYW5kL3Jh dy9teGljX25hbmQuYwo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29u ZmlnIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+IGluZGV4IGU2MDQ2MjUuLmUwMzI5 Y2MgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+ICsrKyBiL2Ry aXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcKPiBAQCAtNTIyLDYgKzUyMiwxMiBAQCBjb25maWcg TVREX05BTkRfUUNPTQo+ICAJICBFbmFibGVzIHN1cHBvcnQgZm9yIE5BTkQgZmxhc2ggY2hpcHMg b24gU29DcyBjb250YWluaW5nIHRoZSBFQkkyIE5BTkQKPiAgCSAgY29udHJvbGxlci4gVGhpcyBj b250cm9sbGVyIGlzIGZvdW5kIG9uIElQUTgwNnggU29DLgo+ICAKPiArY29uZmlnIE1URF9OQU5E X01YSUMKPiArCXRyaXN0YXRlICJNYWNyb25peCBNWDI1RjBBIE5BTkQgY29udHJvbGxlciIKPiAr CWRlcGVuZHMgb24gSEFTX0lPTUVNCj4gKwloZWxwCj4gKwkgIFRoaXMgc2VsZWN0cyB0aGUgTWFj cm9uaXggTVgyNUYwQSBOQU5EIGNvbnRyb2xsZXIgZHJpdmVyLgo+ICsKPiAgY29uZmlnIE1URF9O QU5EX01USwo+ICAJdHJpc3RhdGUgIlN1cHBvcnQgZm9yIE5BTkQgY29udHJvbGxlciBvbiBNVEsg U29DcyIKPiAgCWRlcGVuZHMgb24gQVJDSF9NRURJQVRFSyB8fCBDT01QSUxFX1RFU1QKPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvTWFrZWZpbGUgYi9kcml2ZXJzL210ZC9uYW5k L3Jhdy9NYWtlZmlsZQo+IGluZGV4IDVhNWE3MmYuLmM4YTY3OTAgMTAwNjQ0Cj4gLS0tIGEvZHJp dmVycy9tdGQvbmFuZC9yYXcvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9N YWtlZmlsZQo+IEBAIC01NCw2ICs1NCw3IEBAIG9iai0kKENPTkZJR19NVERfTkFORF9TVU5YSSkJ CSs9IHN1bnhpX25hbmQubwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfSElTSTUwNCkJICAgICAg ICArPSBoaXNpNTA0X25hbmQubwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfQlJDTU5BTkQpCQkr PSBicmNtbmFuZC8KPiAgb2JqLSQoQ09ORklHX01URF9OQU5EX1FDT00pCQkrPSBxY29tX25hbmRj Lm8KPiArb2JqLSQoQ09ORklHX01URF9OQU5EX01YSUMpCQkrPSBteGljX25hbmQubwo+ICBvYmot JChDT05GSUdfTVREX05BTkRfTVRLKQkJKz0gbXRrX2VjYy5vIG10a19uYW5kLm8KPiAgb2JqLSQo Q09ORklHX01URF9OQU5EX1RFR1JBKQkJKz0gdGVncmFfbmFuZC5vCj4gIG9iai0kKENPTkZJR19N VERfTkFORF9TVE0zMl9GTUMyKQkrPSBzdG0zMl9mbWMyX25hbmQubwo+IGRpZmYgLS1naXQgYS9k cml2ZXJzL210ZC9uYW5kL3Jhdy9teGljX25hbmQuYyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L214 aWNfbmFuZC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwLi42ODlmYWUy Cj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L214aWNfbmFuZC5j Cj4gQEAgLTAsMCArMSwyOTQgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjAKPiArLy8KPiArLy8gQ29weXJpZ2h0IChDKSAyMDE5IE1hY3Jvbml4IEludGVybmF0aW9uYWwg Q28uLCBMdGQuCj4gKy8vCj4gKy8vIEF1dGhvcnM6Cj4gKy8vCU1hc29uIFlhbmcgPG1hc29uY2N5 YW5nQG14aWMuY29tLnR3Pgo+ICsvLwl6aGVuZ3h1bmxpIDx6aGVuZ3h1bmxpQG14aWMuY29tLnR3 PgoKVGhpcyBpcyBub3QgYSB2YWxpZCBuYW1lLgoKQWxzbyBpZiBoZSBhcHBlYXJzIGhlcmUgSSBz dXBwb3NlIGhlIHNob3VsZCBiZSBjcmVkaXRlZCBpbiB0aGUKbW9kdWxlX2F1dGhvcnMoKSBtYWNy byB0b28uCgo+ICsvLwoKQXMgYSBwZXJzb25hbCB0YXN0ZSwgSSBwcmVmZXIgd2hlbiB0aGUgaGVh ZGVyIHVzZXMgLyogKi8gYW5kIG9ubHkgdGhlClNQRFggdGFnIHVzZXMgLy8uCgo+ICsKPiArI2lu Y2x1ZGUgPGxpbnV4L21mZC9teGljLW14MjVmMGEuaD4KPiArI2luY2x1ZGUgPGxpbnV4L210ZC9y YXduYW5kLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tdGQvbmFuZF9lY2MuaD4KPiArCj4gKyNpbmNs dWRlICJpbnRlcm5hbHMuaCIKPiArCj4gK3N0cnVjdCBteGljX25hbmRfY3RsciB7Cj4gKwlzdHJ1 Y3QgbXgyNWYwYV9tZmQgKm1mZDsKPiArCXN0cnVjdCBuYW5kX2NvbnRyb2xsZXIgYmFzZTsKPiAr CXN0cnVjdCBuYW5kX2NoaXAgbmFuZDsKCkV2ZW4gaWYgdGhpcyBjb250cm9sbGVyIG9ubHkgc3Vw cG9ydHMgb25lIENTIChhbmQgdGhlbiwgb25lIGNoaXApLApwbGVhc2UgaGF2ZSBhIGNsZWFyIHNl cGFyYXRpb24gYmV0d2VlbiB0aGUgTkFORCBjb250cm9sbGVyIGFuZCB0aGUgTkFORApjaGlwIGJ5 IGhhdmluZyBvbmUgc3RydWN0dXJlIGZvciB0aGUgTkFORCBjaGlwcyBhbmQgb25lIHN0cnVjdHVy ZSBmb3IKdGhlIE5BTkQgY29udHJvbGxlci4KCj4gK307Cj4gKwo+ICtzdGF0aWMgdm9pZCBteGlj X2hvc3RfaW5pdChzdHJ1Y3QgbXhpY19uYW5kX2N0bHIgKm14aWMpCgpQbGVhc2UgY2hvb3NlIGEg Y29uc3RhbnQgcHJlZml4IGZvciBhbGwgZnVuY3Rpb25zLCByaWdodCBub3cgdGhlcmUgaXM6Cm14 aWNfCm14aWNfbmFuZF8KbXgyNWYwYV9uYW5kXwoKSSB0aGluayBteGljX25hbmRfIG9yIG14MjVm MGFfbmFuZF8gaXMgd2lzZS4KCj4gK3sKPiArCXdyaXRlbChEQVRBX1NUUk9CX0VET19FTiwgbXhp Yy0+bWZkLT5yZWdzICsgREFUQV9TVFJPQik7Cj4gKwl3cml0ZWwoSU5UX1NUU19BTEwsIG14aWMt Pm1mZC0+cmVncyArIElOVF9TVFNfRU4pOwo+ICsJd3JpdGVsKDB4MCwgbXhpYy0+bWZkLT5yZWdz ICsgT05GSV9ESU5fQ05UKDApKTsKPiArCXdyaXRlbChIQ19DRkdfTklPKDgpIHwgSENfQ0ZHX1NM Vl9BQ1QoMCkgfCBIQ19DRkdfSURMRV9TSU9fTFZMKDEpIHwKPiArCSAgICAgICBIQ19DRkdfVFlQ RSgxLCBIQ19DRkdfVFlQRV9SQVdfTkFORCkgfCBIQ19DRkdfTUFOX0NTX0VOLAo+ICsJICAgICAg IG14aWMtPm1mZC0+cmVncyArIEhDX0NGRyk7Cj4gKwl3cml0ZWwoMHgwLCBteGljLT5tZmQtPnJl Z3MgKyBIQ19FTik7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgIG14aWNfbmFuZF93YWl0X3JlYWR5 KHN0cnVjdCBuYW5kX2NoaXAgKmNoaXApCj4gK3sKPiArCXN0cnVjdCBteGljX25hbmRfY3RsciAq bXhpYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShjaGlwKTsKPiArCXUzMiBzdHM7Cj4gKwo+ ICsJcmV0dXJuIHJlYWRsX3BvbGxfdGltZW91dChteGljLT5tZmQtPnJlZ3MgKyBJTlRfU1RTLCBz dHMsCj4gKwkJCQkgIHN0cyAmIElOVF9SRFlfUElOLCAwLCBVU0VDX1BFUl9TRUMpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCBteGljX25hbmRfc2VsZWN0X2NoaXAoc3RydWN0IG5hbmRfY2hpcCAq Y2hpcCwgaW50IGNoaXBucikKCl9zZWxlY3RfdGFyZ2V0KCkgaXMgcHJlZmVycmVkIG5vdwoKPiAr ewo+ICsJc3RydWN0IG14aWNfbmFuZF9jdGxyICpteGljID0gbmFuZF9nZXRfY29udHJvbGxlcl9k YXRhKGNoaXApOwo+ICsKPiArCXN3aXRjaCAoY2hpcG5yKSB7Cj4gKwljYXNlIDA6Cj4gKwljYXNl IDE6Cj4gKwkJd3JpdGVsKEhDX0VOX0JJVCwgbXhpYy0+bWZkLT5yZWdzICsgSENfRU4pOwo+ICsJ CXdyaXRlbChIQ19DRkdfTUFOX0NTX0FTU0VSVCB8IHJlYWRsKG14aWMtPm1mZC0+cmVncyArIEhD X0NGRyksCj4gKwkJICAgICAgIG14aWMtPm1mZC0+cmVncyArIEhDX0NGRyk7CgpJbiBib3RoIGNh c2UgSSB3b3VsZCBwcmVmZXIgYToKCiAgICAgICAgcmVnID0gcmVhZGwoLi4uKTsKICAgICAgICBy ZWcgJj0gfnh4eDsKCXJlZyB8PSB5eXk7Cgl3cml0ZWwocmVnLCAuLi4pOwoKTXVjaCBlYXNpZXIg dG8gcmVhZC4KCj4gKwkJYnJlYWs7Cj4gKwo+ICsJY2FzZSAtMToKPiArCQl3cml0ZWwofkhDX0NG R19NQU5fQ1NfQVNTRVJUICYgcmVhZGwobXhpYy0+bWZkLT5yZWdzICsgSENfQ0ZHKSwKPiArCQkg ICAgICAgbXhpYy0+bWZkLT5yZWdzICsgSENfQ0ZHKTsKPiArCQl3cml0ZWwoMCwgbXhpYy0+bWZk LT5yZWdzICsgSENfRU4pOwo+ICsJCWJyZWFrOwo+ICsKPiArCWRlZmF1bHQ6CgpFcnJvcj8KCj4g KwkJYnJlYWs7Cj4gKwl9Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXhpY19uYW5kX2RhdGFfeGZl cihzdHJ1Y3QgbXhpY19uYW5kX2N0bHIgKm14aWMsIGNvbnN0IHZvaWQgKnR4YnVmLAo+ICsJCQkg ICAgICAgdm9pZCAqcnhidWYsIHVuc2lnbmVkIGludCBsZW4pCj4gK3sKClRoZXJlIGlzIG5vdCBz byBtdWNoIGNvZGUgc2hhcmVkLCB3aHkgbm90IHNlcGFyYXRpbmcgdGhpcyBmdW5jdGlvbiBmb3IK cnggYW5kIHR4IGNhc2VzPwoKPiArCXVuc2lnbmVkIGludCBwb3MgPSAwOwo+ICsKPiArCXdoaWxl IChwb3MgPCBsZW4pIHsKPiArCQl1bnNpZ25lZCBpbnQgbmJ5dGVzID0gbGVuIC0gcG9zOwo+ICsJ CXUzMiBkYXRhID0gMHhmZmZmZmZmZjsKPiArCQl1MzIgc3RzOwo+ICsJCWludCByZXQ7Cj4gKwo+ ICsJCWlmIChuYnl0ZXMgPiA0KQo+ICsJCQluYnl0ZXMgPSA0Owo+ICsKPiArCQlpZiAodHhidWYp Cj4gKwkJCW1lbWNweSgmZGF0YSwgdHhidWYgKyBwb3MsIG5ieXRlcyk7Cj4gKwo+ICsJCXJldCA9 IHJlYWRsX3BvbGxfdGltZW91dChteGljLT5tZmQtPnJlZ3MgKyBJTlRfU1RTLCBzdHMsCj4gKwkJ CQkJIHN0cyAmIElOVF9UWF9FTVBUWSwgMCwgVVNFQ19QRVJfU0VDKTsKClVzaW5nIFVTRUNfUEVS X1NFQyBmb3IgYSBkZWxheSBpcyB3ZWlyZAoKPiArCQlpZiAocmV0KQo+ICsJCQlyZXR1cm4gcmV0 Owo+ICsKPiArCQl3cml0ZWwoZGF0YSwgbXhpYy0+bWZkLT5yZWdzICsgVFhEKG5ieXRlcyAlIDQp KTsKPiArCj4gKwkJaWYgKHJ4YnVmKSB7Cj4gKwkJCXJldCA9IHJlYWRsX3BvbGxfdGltZW91dCht eGljLT5tZmQtPnJlZ3MgKyBJTlRfU1RTLCBzdHMsCj4gKwkJCQkJCSBzdHMgJiBJTlRfVFhfRU1Q VFksIDAsCj4gKwkJCQkJCSBVU0VDX1BFUl9TRUMpOwo+ICsJCQlpZiAocmV0KQo+ICsJCQkJcmV0 dXJuIHJldDsKPiArCj4gKwkJCXJldCA9IHJlYWRsX3BvbGxfdGltZW91dChteGljLT5tZmQtPnJl Z3MgKyBJTlRfU1RTLCBzdHMsCj4gKwkJCQkJCSBzdHMgJiBJTlRfUlhfTk9UX0VNUFRZLCAwLAo+ ICsJCQkJCQkgVVNFQ19QRVJfU0VDKTsKPiArCQkJaWYgKHJldCkKPiArCQkJCXJldHVybiByZXQ7 Cj4gKwo+ICsJCQlkYXRhID0gcmVhZGwobXhpYy0+bWZkLT5yZWdzICsgUlhEKTsKPiArCQkJZGF0 YSA+Pj0gKDggKiAoNCAtIG5ieXRlcykpOwoKV2hhdCBpcyB0aGlzPyBBcmUgeW91IHRyeWluZyB0 byBoYW5kbGUgc29tZSBlbmRpYW5uZXNzIGlzc3VlPwoKPiArCQkJbWVtY3B5KHJ4YnVmICsgcG9z LCAmZGF0YSwgbmJ5dGVzKTsKPiArCQkJV0FSTl9PTihyZWFkbChteGljLT5tZmQtPnJlZ3MgKyBJ TlRfU1RTKSAmCj4gKwkJCQlJTlRfUlhfTk9UX0VNUFRZKTsKPiArCQl9IGVsc2Ugewo+ICsJCQly ZWFkbChteGljLT5tZmQtPnJlZ3MgKyBSWEQpOwo+ICsJCX0KPiArCQlXQVJOX09OKHJlYWRsKG14 aWMtPm1mZC0+cmVncyArIElOVF9TVFMpICYgSU5UX1JYX05PVF9FTVBUWSk7Cj4gKwo+ICsJCXBv cyArPSBuYnl0ZXM7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBp bnQgbXhpY19uYW5kX2V4ZWNfb3Aoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwKPiArCQkJICAgICBj b25zdCBzdHJ1Y3QgbmFuZF9vcGVyYXRpb24gKm9wLCBib29sIGNoZWNrX29ubHkpCj4gK3sKPiAr CXN0cnVjdCBteGljX25hbmRfY3RsciAqbXhpYyA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0YShj aGlwKTsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX29wX2luc3RyICppbnN0ciA9IE5VTEw7Cj4gKwlp bnQgaSwgbGVuID0gMCwgcmV0ID0gMDsKPiArCXVuc2lnbmVkIGludCBvcF9pZDsKPiArCXVuc2ln bmVkIGNoYXIgY21kY250ID0gMCwgYWRkcl9jbnQgPSAwLCBjbWRfYWRkcls4XSA9IHswfTsKPiAr Cj4gKwlmb3IgKG9wX2lkID0gMDsgb3BfaWQgPCBvcC0+bmluc3Ryczsgb3BfaWQrKykgewo+ICsJ CWluc3RyID0gJm9wLT5pbnN0cnNbb3BfaWRdOwo+ICsKPiArCQlzd2l0Y2ggKGluc3RyLT50eXBl KSB7Cj4gKwkJY2FzZSBOQU5EX09QX0NNRF9JTlNUUjoKPiArCQkJY21kX2FkZHJbbGVuKytdID0g aW5zdHItPmN0eC5jbWQub3Bjb2RlOwo+ICsJCQljbWRjbnQrKzsKPiArCQkJYnJlYWs7Cj4gKwo+ ICsJCWNhc2UgTkFORF9PUF9BRERSX0lOU1RSOgo+ICsJCQlmb3IgKGkgPSAwOyBpIDwgaW5zdHIt PmN0eC5hZGRyLm5hZGRyczsgaSsrKQo+ICsJCQkJY21kX2FkZHJbbGVuKytdID0gaW5zdHItPmN0 eC5hZGRyLmFkZHJzW2ldOwo+ICsJCQlhZGRyX2NudCA9IGk7Cj4gKwkJCWJyZWFrOwo+ICsKPiAr CQljYXNlIE5BTkRfT1BfREFUQV9JTl9JTlNUUjoKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNhc2Ug TkFORF9PUF9EQVRBX09VVF9JTlNUUjoKPiArCQkJd3JpdGVsKGluc3RyLT5jdHguZGF0YS5sZW4s Cj4gKwkJCSAgICAgICBteGljLT5tZmQtPnJlZ3MgKyBPTkZJX0RJTl9DTlQoMCkpOwo+ICsJCQli cmVhazsKPiArCj4gKwkJY2FzZSBOQU5EX09QX1dBSVRSRFlfSU5TVFI6Cj4gKwkJCWJyZWFrOwo+ ICsJCX0KPiArCX0KPiArCj4gKwlpZiAob3BfaWQgPT0gNSAmJiBpbnN0ci0+dHlwZSA9PSBOQU5E X09QX1dBSVRSRFlfSU5TVFIpIHsKPiArCQkvKgo+ICsJCSAqIEluIGNhc2UgY21kLWFkZHItZGF0 YS1jbWQtd2FpdCBpbiBhIHNlcXVlbmNlLAo+ICsJCSAqIHNlcGFyYXRlIHRoZSAyJ25kIGNvbW1h bmQsIGkuZSwuIG5hbmRfcHJvZ19wYWdlX29wKCkKPiArCQkgKi8KCkkgdGhpbmsgdGhpcyBpcyB0 aGUga2luZCBvZiBsaW1pdGF0aW9uIHRoYXQgY291bGQgYmUgZGVzY3JpYmVkIHZlcnkKZWFzaWx5 IHdpdGggYSBuYW5kX29wX3BhcnNlciBzdHJ1Y3R1cmUgYW5kIHVzZWQgYnkKbmFuZF9vcF9wYXJz ZXJfZXhlY19vcCgpIChzZWUgbWFydmVsbF9uYW5kLmMpLgoKPiArCQl3cml0ZWwoT1BfQ01EX0JV U1coT1BfQlVTV184KSB8IE9QX0FERFJfQlVTVyhPUF9CVVNXXzgpIHwKPiArCQkgICAgICAgT1Bf REFUQV9CVVNXKE9QX0JVU1dfOCkgfCBPUF9EVU1NWV9DWUMoMHgzRikgfAo+ICsJCSAgICAgICBP UF9BRERSX0JZVEVTKGFkZHJfY250KSB8Cj4gKwkJICAgICAgIE9QX0NNRF9CWVRFUygxKSwgbXhp Yy0+bWZkLT5yZWdzICsgU1NfQ1RSTCgwKSk7Cj4gKwkJd3JpdGVsKDAsIG14aWMtPm1mZC0+cmVn cyArIEhDX0VOKTsKPiArCQl3cml0ZWwoSENfRU5fQklULCBteGljLT5tZmQtPnJlZ3MgKyBIQ19F Tik7Cj4gKwo+ICsJCW14aWNfbmFuZF9kYXRhX3hmZXIobXhpYywgY21kX2FkZHIsIE5VTEwsIGxl biAtIDEpOwo+ICsKPiArCQlteGljX25hbmRfZGF0YV94ZmVyKG14aWMsIGluc3RyLT5jdHguZGF0 YS5idWYub3V0LCBOVUxMLAo+ICsJCQkJICAgIGluc3RyLT5jdHguZGF0YS5sZW4pOwo+ICsKPiAr CQl3cml0ZWwoMCwgbXhpYy0+bWZkLT5yZWdzICsgSENfRU4pOwo+ICsJCXdyaXRlbChIQ19FTl9C SVQsIG14aWMtPm1mZC0+cmVncyArIEhDX0VOKTsKPiArCQlteGljX25hbmRfZGF0YV94ZmVyKG14 aWMsICZjbWRfYWRkclstLWxlbl0sIE5VTEwsIDEpOwo+ICsJCXJldCA9IG14aWNfbmFuZF93YWl0 X3JlYWR5KGNoaXApOwo+ICsJCWlmIChyZXQpCj4gKwkJCWdvdG8gZXJyX291dDsKPiArCQlyZXR1 cm4gcmV0Owo+ICsJfQo+ICsKPiArCWlmIChsZW4pIHsKPiArCQl3cml0ZWwoT1BfQ01EX0JVU1co T1BfQlVTV184KSB8IE9QX0FERFJfQlVTVyhPUF9CVVNXXzgpIHwKPiArCQkgICAgICAgT1BfREFU QV9CVVNXKE9QX0JVU1dfOCkgfCBPUF9EVU1NWV9DWUMoMHgzRikgfAo+ICsJCSAgICAgICBPUF9B RERSX0JZVEVTKGFkZHJfY250KSB8Cj4gKwkJICAgICAgIE9QX0NNRF9CWVRFUyhjbWRjbnQgPiAw ID8gY21kY250IDogMCksCj4gKwkJICAgICAgIG14aWMtPm1mZC0+cmVncyArIFNTX0NUUkwoMCkp Owo+ICsJCXdyaXRlbCgwLCBteGljLT5tZmQtPnJlZ3MgKyBIQ19FTik7Cj4gKwkJd3JpdGVsKEhD X0VOX0JJVCwgbXhpYy0+bWZkLT5yZWdzICsgSENfRU4pOwo+ICsKPiArCQlteGljX25hbmRfZGF0 YV94ZmVyKG14aWMsIGNtZF9hZGRyLCBOVUxMLCBsZW4pOwo+ICsJfQo+ICsKPiArCWZvciAob3Bf aWQgPSAwOyBvcF9pZCA8IG9wLT5uaW5zdHJzOyBvcF9pZCsrKSB7Cj4gKwkJaW5zdHIgPSAmb3At Pmluc3Ryc1tvcF9pZF07Cj4gKwo+ICsJCXN3aXRjaCAoaW5zdHItPnR5cGUpIHsKPiArCQljYXNl IE5BTkRfT1BfQ01EX0lOU1RSOgo+ICsJCWNhc2UgTkFORF9PUF9BRERSX0lOU1RSOgo+ICsJCQli cmVhazsKPiArCj4gKwkJY2FzZSBOQU5EX09QX0RBVEFfSU5fSU5TVFI6Cj4gKwkJCXdyaXRlbCgw eDAsIG14aWMtPm1mZC0+cmVncyArIE9ORklfRElOX0NOVCgwKSk7Cj4gKwkJCXdyaXRlbChyZWFk bChteGljLT5tZmQtPnJlZ3MgKyBTU19DVFJMKDApKSB8IE9QX1JFQUQsCj4gKwkJCSAgICAgICBt eGljLT5tZmQtPnJlZ3MgKyBTU19DVFJMKDApKTsKPiArCQkJbXhpY19uYW5kX2RhdGFfeGZlciht eGljLCBOVUxMLCBpbnN0ci0+Y3R4LmRhdGEuYnVmLmluLAo+ICsJCQkJCSAgICBpbnN0ci0+Y3R4 LmRhdGEubGVuKTsKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNhc2UgTkFORF9PUF9EQVRBX09VVF9J TlNUUjoKPiArCQkJbXhpY19uYW5kX2RhdGFfeGZlcihteGljLCBpbnN0ci0+Y3R4LmRhdGEuYnVm Lm91dCwgTlVMTCwKPiArCQkJCQkgICAgaW5zdHItPmN0eC5kYXRhLmxlbik7Cj4gKwkJCWJyZWFr Owo+ICsKPiArCQljYXNlIE5BTkRfT1BfV0FJVFJEWV9JTlNUUjoKPiArCQkJcmV0ID0gbXhpY19u YW5kX3dhaXRfcmVhZHkoY2hpcCk7Cj4gKwkJCWlmIChyZXQpCj4gKwkJCQlnb3RvIGVycl9vdXQ7 Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCX0KPiArCj4gK2Vycl9vdXQ6Cj4gKwlyZXR1cm4gcmV0 OwoKRGl0dG8sIHBsZWFzZSByZXR1cm4gZGlyZWN0bHkgaWYgdGhlcmUgaXMgbm90aGluZyBpbiB0 aGUgZXJyb3IgcGF0aC4KCj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgbmFuZF9jb250 cm9sbGVyX29wcyBteGljX25hbmRfY29udHJvbGxlcl9vcHMgPSB7Cj4gKwkuZXhlY19vcCA9IG14 aWNfbmFuZF9leGVjX29wLAo+ICt9Owo+ICsKPiArc3RhdGljIGludCBteDI1ZjBhX25hbmRfcHJv YmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IG10ZF9pbmZv ICptdGQ7Cj4gKwlzdHJ1Y3QgbXgyNWYwYV9tZmQgKm1mZCA9IGRldl9nZXRfZHJ2ZGF0YShwZGV2 LT5kZXYucGFyZW50KTsKPiArCXN0cnVjdCBteGljX25hbmRfY3RsciAqbXhpYzsKPiArCXN0cnVj dCBuYW5kX2NoaXAgKm5hbmRfY2hpcDsKPiArCWludCBlcnI7Cj4gKwo+ICsJbXhpYyA9IGRldm1f a3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2Yoc3RydWN0IG14aWNfbmFuZF9jdGxyKSwKPiArCQkJ ICAgIEdGUF9LRVJORUwpOwoKbXhpYyBmb3IgYSBOQU5EIGNvbnRyb2xsZXIgc3RydWN0dXJlIGlz IHByb2JhYmx5IG5vdCBhIG5hbWUgbWVhbmluZ2Z1bAplbm91Z2guCgo+ICsJaWYgKCFteGljKQo+ ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCW5hbmRfY2hpcCA9ICZteGljLT5uYW5kOwo+ICsJ bXRkID0gbmFuZF90b19tdGQobmFuZF9jaGlwKTsKPiArCW10ZC0+ZGV2LnBhcmVudCA9IHBkZXYt PmRldi5wYXJlbnQ7Cj4gKwluYW5kX2NoaXAtPmVjYy5wcml2ID0gTlVMTDsKPiArCW5hbmRfc2V0 X2ZsYXNoX25vZGUobmFuZF9jaGlwLCBwZGV2LT5kZXYucGFyZW50LT5vZl9ub2RlKTsKPiArCW5h bmRfY2hpcC0+cHJpdiA9IG14aWM7Cj4gKwo+ICsJbXhpYy0+bWZkID0gbWZkOwo+ICsKPiArCW5h bmRfY2hpcC0+bGVnYWN5LnNlbGVjdF9jaGlwID0gbXhpY19uYW5kX3NlbGVjdF9jaGlwOwoKUGxl YXNlIGRvbid0IGltcGxlbWVudCBsZWdhY3kgaW50ZXJmYWNlcy4gWW91IGNhbiBjaGVjayBpbgpt YXJ2ZWxsX25hbmQuYyBob3cgdGhpcyBpcyBoYW5kbGVkIG5vdzoKCmIyNTI1MTQxNGY2ZSBtdGQ6 IHJhd25hbmQ6IG1hcnZlbGw6IFN0b3AgaW1wbGVtZW50aW5nIC0+c2VsZWN0X2NoaXAoKQoKPiAr CW14aWMtPmJhc2Uub3BzID0gJm14aWNfbmFuZF9jb250cm9sbGVyX29wczsKPiArCW5hbmRfY29u dHJvbGxlcl9pbml0KCZteGljLT5iYXNlKTsKPiArCW5hbmRfY2hpcC0+Y29udHJvbGxlciA9ICZt eGljLT5iYXNlOwo+ICsKPiArCW14aWNfaG9zdF9pbml0KG14aWMpOwo+ICsKPiArCWVyciA9IG5h bmRfc2NhbihuYW5kX2NoaXAsIDEpOwo+ICsJaWYgKGVycikKPiArCQlnb3RvIGZhaWw7CgpZb3Ug Y2FuIHJldHVybiBkaXJlY3RseSBhcyB0aGVyZSBpcyBub3RoaW5nIHRvIGNsZWFuIGluIHRoZSBl cnJvciBwYXRoLgoKPiArCj4gKwllcnIgPSBtdGRfZGV2aWNlX3JlZ2lzdGVyKG10ZCwgTlVMTCwg MCk7Cj4gKwlpZiAoZXJyKQo+ICsJCWdvdG8gZmFpbDsKCkRpdHRvCgo+ICsKPiArCXBsYXRmb3Jt X3NldF9kcnZkYXRhKHBkZXYsIG14aWMpOwo+ICsKPiArCXJldHVybiAwOwo+ICtmYWlsOgo+ICsJ cmV0dXJuIGVycjsKPiArfQo+ICsKPiArc3RhdGljIGludCBteDI1ZjBhX25hbmRfcmVtb3ZlKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBteGljX25hbmRfY3Rs ciAqbXhpYyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ICsKPiArCW5hbmRfcmVsZWFz ZSgmbXhpYy0+bmFuZCk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBzdHJ1 Y3QgcGxhdGZvcm1fZHJpdmVyIG14MjVmMGFfbmFuZF9kcml2ZXIgPSB7Cj4gKwkucHJvYmUJCT0g bXgyNWYwYV9uYW5kX3Byb2JlLAoKUGxlYXNlIGRvbid0IGFsaWduICc9JyBvbiB0YWJzLgoKPiAr CS5yZW1vdmUJCT0gbXgyNWYwYV9uYW5kX3JlbW92ZSwKPiArCS5kcml2ZXIJCT0gewo+ICsJCS5u YW1lCT0gIm14aWMtbmFuZC1jdGxyIiwKPiArCX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9k cml2ZXIobXgyNWYwYV9uYW5kX2RyaXZlcik7CgpteDI1ZjBhX25hbmRfY29udHJvbGxlcl9kcml2 ZXIgd291bGQgYmUgYmV0dGVyCgo+ICsKPiArTU9EVUxFX0FVVEhPUigiTWFzb24gWWFuZyA8bWFz b25jY3lhbmdAbXhpYy5jb20udHc+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiTVgyNUYwQSBS QVcgTkFORCBjb250cm9sbGVyIGRyaXZlciIpOwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7 CgpUaGFua3MsCk1pcXXDqGwKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fXwpMaW51eCBNVEQgZGlzY3Vzc2lvbiBtYWlsaW5nIGxpc3QKaHR0cDov L2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1tdGQvCg==