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 Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16D1FECAAD4 for ; Wed, 31 Aug 2022 10:42:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229712AbiHaKmR (ORCPT ); Wed, 31 Aug 2022 06:42:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229529AbiHaKmQ (ORCPT ); Wed, 31 Aug 2022 06:42:16 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13539C874C for ; Wed, 31 Aug 2022 03:42:15 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id w88-20020a17090a6be100b001fbb0f0b013so14554617pjj.5 for ; Wed, 31 Aug 2022 03:42:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc; bh=USnEq7i+EspKoRu1Km1ctJNVzyby3/Boh0en787tgT4=; b=q6KB29F9s7ScEmfBLJsjH0tGFTm+Dpby3tqOLuvcJsY9Gd89u43bMs9rdLGTgfyhDq owgGTWQ4MuUqs5W4XFripHtoulDfMyk+o8ENVwBaV0W2LnKXNuTKCwB4V9mDLFWoqf2t XeWW7/FJUoOnvEVgmaBb08SpxviMjvYHOm6WKvxAkAJf4Mv5aj0BJHOlVmY2aVtRh7zn S459OeLCwwBCSZ2H37gUD5Pug/j09ZSWsLJ0pS7zmaQ/CYt62ijJKH3aT9gPBUK3gxgn swdfTO6Ojrc7mN0T1wAYorB/dtxpiGLaQPyxv+Ht8tqYomSjIyu4tMZZyH3GVkdrS130 PkwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc; bh=USnEq7i+EspKoRu1Km1ctJNVzyby3/Boh0en787tgT4=; b=HEpK8IVQN/I0Cgk1H3XONdINxkwZGZ2/FBtSbs627xVmeVdMnSfEqzJ3/tM966XN0h 9iNg0VR1bkVr38brPjH8e5/SK3cPDzZEOK+YSVjBykKY031gBFm5/81YCIMHnKFEceHr ud2CJqh8XQjzpgioNebxKaiYufrtiIU91IVoKVd1ugNSgc5amSCnpFVP53Jma0XPRnLo 5nKYxgTWjGQL5j4NQ8OxDqG7sgEEaMA4rU9HMqTUCWi67Ye1GgbUy6r07R80ArA0PNr/ Y25NbE37d0AvT7y6aZMwhSTNzEAaXGzTsYoiBUCfgMy2ghi06aVkyfM4m2CeqsnfduGD 7Ybg== X-Gm-Message-State: ACgBeo1pLwsdbXcv7DDDIfB+n5bDzm7/8Em0LhRGXRjzBApAznFI9Zc0 bWQh3Rugkz3MrNT+uTA3FOgf X-Google-Smtp-Source: AA6agR5EnVJ32R2CBH2rd5xmGM0YH2cYKxeyeZZO6OMNvLb+3DwAaaDirtc7RwYZN+HAQy3Q9bl7Yg== X-Received: by 2002:a17:902:e54c:b0:171:4b29:d1e with SMTP id n12-20020a170902e54c00b001714b290d1emr25511345plf.39.1661942534422; Wed, 31 Aug 2022 03:42:14 -0700 (PDT) Received: from thinkpad ([117.217.182.234]) by smtp.gmail.com with ESMTPSA id h188-20020a6253c5000000b0052d46b43006sm10939208pfb.156.2022.08.31.03.42.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Aug 2022 03:42:13 -0700 (PDT) Date: Wed, 31 Aug 2022 16:12:03 +0530 From: Manivannan Sadhasivam To: Frank Li Cc: maz@kernel.org, tglx@linutronix.de, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, kw@linux.com, bhelgaas@google.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org, peng.fan@nxp.com, aisheng.dong@nxp.com, jdmason@kudzu.us, kernel@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, kishon@ti.com, lorenzo.pieralisi@arm.com, ntb@lists.linux.dev, lznuaa@gmail.com Subject: Re: [PATCH v6 4/4] pcie: endpoint: pci-epf-vntb: add endpoint MSI support Message-ID: <20220831104203.GD5076@thinkpad> References: <20220818151127.2449064-1-Frank.Li@nxp.com> <20220818151127.2449064-5-Frank.Li@nxp.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20220818151127.2449064-5-Frank.Li@nxp.com> Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org On Thu, Aug 18, 2022 at 10:11:27AM -0500, Frank Li wrote: > ┌───────┐ ┌──────────┐ > │ │ │ │ > ┌─────────────┐ │ │ │ PCI Host │ > │ MSI │◄┐ │ │ │ │ > │ Controller │ │ │ │ │ │ > └─────────────┘ └─┼───────┼──────────┼─BAR0 │ > │ PCI │ │ BAR1 │ > │ Func │ │ BAR2 │ > │ │ │ BAR3 │ > │ │ │ BAR4 │ > │ ├─────────►│ │ > └───────┘ └──────────┘ > This diagram doesn't say which side is host and which one is endpoint. And not conveying any useful information. > Linux supports endpoint functions. PCI Host write BAR space like write > to memory. The EP side can't know memory changed by the host driver. > I think you just say, that there is no defined way of raising IRQs by host to the endpoint. > PCI Spec has not defined a standard method to do that. Only define MSI(x) > to let EP notified RC status change. > MSI is from EP, right? Throughout the driver you should call it as "doorbell" and not MSI. > The basic idea is to trigger an IRQ when PCI RC writes to a memory > address. That's what MSI controller provided. EP drivers just need to > request a platform MSI interrupt, struct msi_msg *msg will pass down a > memory address and data. EP driver will map such memory address to one of > PCI BAR. Host just writes such an address to trigger EP side irq. > IIUC (by looking at other patches in the series), the memory assigned for BAR region by the PCI host is mapped to the platform interrupt controller in PCI Endpoint. Such that, whenever the PCI host writes to the BAR region, it will trigger an IRQ in the Endpoint. This kind of setup is available in other platforms like Qualcomm where the mapping of a register region available in BAR0 and interrupt controller is done in the hardware itself. So whenever the PCI host writes to that register in BAR0, an IRQ will be delivered to the endpoint. > Add MSI support for pci-epf-vntb. pci-epf-vntb driver query if system > have MSI controller. Setup doorbell address according to struct msi_msg. > > So PCIe host can write this doorbell address to triger EP side's irq. > > If no MSI controller exist, fall back to software polling. > > Signed-off-by: Frank Li > --- > drivers/pci/endpoint/functions/pci-epf-vntb.c | 134 +++++++++++++++--- > 1 file changed, 112 insertions(+), 22 deletions(-) > > diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c > index 1466dd1904175..ad4f7ec8a39fc 100644 > --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c > +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c > @@ -44,6 +44,7 @@ > #include > #include > #include > +#include > > static struct workqueue_struct *kpcintb_workqueue; > > @@ -143,6 +144,8 @@ struct epf_ntb { > void __iomem *vpci_mw_addr[MAX_MW]; > > struct delayed_work cmd_handler; > + > + int msi_virqbase; db_base? > }; > > #define to_epf_ntb(epf_group) container_of((epf_group), struct epf_ntb, group) > @@ -253,7 +256,7 @@ static void epf_ntb_cmd_handler(struct work_struct *work) > > ntb = container_of(work, struct epf_ntb, cmd_handler.work); > > - for (i = 1; i < ntb->db_count; i++) { > + for (i = 1; i < ntb->db_count && !ntb->epf_db_phy; i++) { epf_db_phy is a wierd name. "phy" usually means the PHY controller (Physical layer) in kernel. If you are referring to physicall address of the doorbell, then you could use "phys". > if (readl(ntb->epf_db + i * 4)) { > if (readl(ntb->epf_db + i * 4)) > ntb->db |= 1 << (i - 1); > @@ -454,11 +457,9 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb) > ctrl->num_mws = ntb->num_mws; > ntb->spad_size = spad_size; > > - ctrl->db_entry_size = 4; > - > for (i = 0; i < ntb->db_count; i++) { > ntb->reg->db_data[i] = 1 + i; > - ntb->reg->db_offset[i] = 0; > + ntb->reg->db_offset[i] = 4 * i; > } > > return 0; > @@ -509,6 +510,28 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb) > return 0; > } > > +static int epf_ntb_db_size(struct epf_ntb *ntb) > +{ > + const struct pci_epc_features *epc_features; > + size_t size = 4 * ntb->db_count; > + u32 align; > + > + epc_features = pci_epc_get_features(ntb->epf->epc, > + ntb->epf->func_no, > + ntb->epf->vfunc_no); > + align = epc_features->align; > + > + if (size < 128) > + size = 128; > + > + if (align) > + size = ALIGN(size, align); > + else > + size = roundup_pow_of_two(size); > + > + return size; > +} > + > /** > * epf_ntb_db_bar_init() - Configure Doorbell window BARs > * @ntb: NTB device that facilitates communication between HOST and vHOST > @@ -520,35 +543,33 @@ static int epf_ntb_db_bar_init(struct epf_ntb *ntb) > struct device *dev = &ntb->epf->dev; > int ret; > struct pci_epf_bar *epf_bar; > - void __iomem *mw_addr; > + void __iomem *mw_addr = NULL; > enum pci_barno barno; > - size_t size = 4 * ntb->db_count; > + size_t size; > > epc_features = pci_epc_get_features(ntb->epf->epc, > ntb->epf->func_no, > ntb->epf->vfunc_no); > align = epc_features->align; > - > - if (size < 128) > - size = 128; > - > - if (align) > - size = ALIGN(size, align); > - else > - size = roundup_pow_of_two(size); > + size = epf_ntb_db_size(ntb); > > barno = ntb->epf_ntb_bar[BAR_DB]; > + epf_bar = &ntb->epf->bar[barno]; > > - mw_addr = pci_epf_alloc_space(ntb->epf, size, barno, align, 0); > - if (!mw_addr) { > - dev_err(dev, "Failed to allocate OB address\n"); > - return -ENOMEM; > + if (!ntb->epf_db_phy) { > + mw_addr = pci_epf_alloc_space(ntb->epf, size, barno, align, 0); > + if (!mw_addr) { > + dev_err(dev, "Failed to allocate OB address\n"); Expand OB. > + return -ENOMEM; > + } > + } else { > + epf_bar->phys_addr = ntb->epf_db_phy; > + epf_bar->barno = barno; > + epf_bar->size = size; > } > > ntb->epf_db = mw_addr; > > - epf_bar = &ntb->epf->bar[barno]; > - > ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no, epf_bar); > if (ret) { > dev_err(dev, "Doorbell BAR set failed\n"); > @@ -704,6 +725,74 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb) > return 0; > } > > +static void epf_ntb_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg) > +{ > + struct epf_ntb *ntb = dev_get_drvdata(desc->dev); > + struct epf_ntb_ctrl *reg = ntb->reg; > + int size = epf_ntb_db_size(ntb); > + u64 addr; > + > + addr = msg->address_hi; > + addr <<= 32; > + addr |= msg->address_lo; > + > + reg->db_data[desc->msi_index] = msg->data; > + > + if (desc->msi_index == 0) > + ntb->epf_db_phy = round_down(addr, size); > + > + reg->db_offset[desc->msi_index] = addr - ntb->epf_db_phy; > +} > + > +static irqreturn_t epf_ntb_interrupt_handler(int irq, void *data) > +{ > + struct epf_ntb *ntb = data; > + int index; > + > + index = irq - ntb->msi_virqbase; > + ntb->db |= 1 << (index - 1); > + ntb_db_event(&ntb->ntb, index); > + > + return IRQ_HANDLED; > +} > + > +static void epf_ntb_epc_msi_init(struct epf_ntb *ntb) > +{ > + struct device *dev = &ntb->epf->dev; > + struct irq_domain *domain; > + int virq; > + int ret; > + int i; > + > + domain = dev_get_msi_domain(ntb->epf->epc->dev.parent); > + if (!domain) > + return; > + > + dev_set_msi_domain(dev, domain); > + > + if (platform_msi_domain_alloc_irqs(&ntb->epf->dev, > + ntb->db_count, > + epf_ntb_write_msi_msg)) { > + dev_info(dev, "Can't allocate MSI, fall back to poll mode\n"); > + return; > + } > + > + dev_info(dev, "vntb use MSI as doorbell\n"); > + Why are you using the interrupt controller as the MSI controller? Why not just a plain interrupt controller? > + for (i = 0; i < ntb->db_count; i++) { > + virq = msi_get_virq(dev, i); > + ret = devm_request_irq(dev, virq, > + epf_ntb_interrupt_handler, 0, > + "ntb", ntb); "ntb" as a IRQ name seems quite generic. You might want to prefix it with epf or vntb... Thanks, Mani > + > + if (ret) > + dev_err(dev, "devm_request_irq() failure\n"); > + > + if (!i) > + ntb->msi_virqbase = virq; > + } > +} > + > /** > * epf_ntb_epc_init() - Initialize NTB interface > * @ntb: NTB device that facilitates communication between HOST and vHOST2 > @@ -1299,14 +1388,15 @@ static int epf_ntb_bind(struct pci_epf *epf) > goto err_bar_alloc; > } > > + epf_set_drvdata(epf, ntb); > + epf_ntb_epc_msi_init(ntb); > + > ret = epf_ntb_epc_init(ntb); > if (ret) { > dev_err(dev, "Failed to initialize EPC\n"); > goto err_bar_alloc; > } > > - epf_set_drvdata(epf, ntb); > - > pci_space[0] = (ntb->vntb_pid << 16) | ntb->vntb_vid; > pci_vntb_table[0].vendor = ntb->vntb_vid; > pci_vntb_table[0].device = ntb->vntb_pid; > -- > 2.35.1 > -- மணிவண்ணன் சதாசிவம் From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 41EB4ECAAD4 for ; Wed, 31 Aug 2022 10:43:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc: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=vr0lQr41j2EDFdNRYm/GvZ/j0Ahcmdzk08M0svSO3Bo=; b=s9bWI1E+gwq4eG P3xQPymAqMYmueRSvDcd1OABdFu0PqNXyD46rivW6a2dBwACT1gzIPALEGXmMyFstaDn9C0G347I5 o0WsvASu/cAF7o+6ly/XQvFoF0vwOlolSgbQ4wpycR0X7NsfgD3Eou7sr0mZP9PtYp3yY/Bj0cx19 kaz1bRponGsMhR6M/ABNsUnwQTwiAyoiQgDwyhY3io3Bkl8bz/VWjJBUJ4nKZUsI7/cLqlE+sMD4H dLMZ10d2LK4p5RS2cnuFVAZ3YuCCRjtV0sPM5+7IfJUOe0kBXdr/m3Re8vHXERYae3FTKfsSHHXNm O1QYvaZZTXYd0khBrOoA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oTLAr-005icw-1S; Wed, 31 Aug 2022 10:42:21 +0000 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oTLAo-005ibg-1k for linux-arm-kernel@lists.infradead.org; Wed, 31 Aug 2022 10:42:20 +0000 Received: by mail-pj1-x1036.google.com with SMTP id x1-20020a17090ab00100b001fda21bbc90so10272552pjq.3 for ; Wed, 31 Aug 2022 03:42:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc; bh=USnEq7i+EspKoRu1Km1ctJNVzyby3/Boh0en787tgT4=; b=q6KB29F9s7ScEmfBLJsjH0tGFTm+Dpby3tqOLuvcJsY9Gd89u43bMs9rdLGTgfyhDq owgGTWQ4MuUqs5W4XFripHtoulDfMyk+o8ENVwBaV0W2LnKXNuTKCwB4V9mDLFWoqf2t XeWW7/FJUoOnvEVgmaBb08SpxviMjvYHOm6WKvxAkAJf4Mv5aj0BJHOlVmY2aVtRh7zn S459OeLCwwBCSZ2H37gUD5Pug/j09ZSWsLJ0pS7zmaQ/CYt62ijJKH3aT9gPBUK3gxgn swdfTO6Ojrc7mN0T1wAYorB/dtxpiGLaQPyxv+Ht8tqYomSjIyu4tMZZyH3GVkdrS130 PkwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc; bh=USnEq7i+EspKoRu1Km1ctJNVzyby3/Boh0en787tgT4=; b=HihO9m865LkyWSxmCeXdAldI7dPlgJzQsxU2ZqNdNyN3tUhfC8S8ZoiRLNMe/6Zs/L zjWbWeFhjDQu+Y2no/R5yArooybBgDer6s84pw7B1yTwcvWzgIqY7StI8u+EZc55soOJ rTmR2bFi6a1arei17OWfmxdouNcH0CcL1A3/AHKIrdgzNMoJEn28E210jCVLKxUthdcJ 3Egz5gOY+aJCTjQX2tPWuPEn7niXJkOtS452P/SAbPaPgkB6evni50tmuIcYRPPDnvtf U7gR3guU8YPemAWN0QOe0PmXvM4Y1UE12qycoAZV0nMetyUHk6TCB+/5yfliFF4hmuI1 HjYA== X-Gm-Message-State: ACgBeo2rdYv0iZmdapLPkD2iSlp7H+2MWQU9Xpbb+7rucHJPecJJfqv3 YtPfZO2AXcgTnsKzTZpoGpTQ X-Google-Smtp-Source: AA6agR5EnVJ32R2CBH2rd5xmGM0YH2cYKxeyeZZO6OMNvLb+3DwAaaDirtc7RwYZN+HAQy3Q9bl7Yg== X-Received: by 2002:a17:902:e54c:b0:171:4b29:d1e with SMTP id n12-20020a170902e54c00b001714b290d1emr25511345plf.39.1661942534422; Wed, 31 Aug 2022 03:42:14 -0700 (PDT) Received: from thinkpad ([117.217.182.234]) by smtp.gmail.com with ESMTPSA id h188-20020a6253c5000000b0052d46b43006sm10939208pfb.156.2022.08.31.03.42.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Aug 2022 03:42:13 -0700 (PDT) Date: Wed, 31 Aug 2022 16:12:03 +0530 From: Manivannan Sadhasivam To: Frank Li Cc: maz@kernel.org, tglx@linutronix.de, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, kw@linux.com, bhelgaas@google.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org, peng.fan@nxp.com, aisheng.dong@nxp.com, jdmason@kudzu.us, kernel@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, kishon@ti.com, lorenzo.pieralisi@arm.com, ntb@lists.linux.dev, lznuaa@gmail.com Subject: Re: [PATCH v6 4/4] pcie: endpoint: pci-epf-vntb: add endpoint MSI support Message-ID: <20220831104203.GD5076@thinkpad> References: <20220818151127.2449064-1-Frank.Li@nxp.com> <20220818151127.2449064-5-Frank.Li@nxp.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20220818151127.2449064-5-Frank.Li@nxp.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220831_034218_121031_D323F068 X-CRM114-Status: GOOD ( 42.67 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gVGh1LCBBdWcgMTgsIDIwMjIgYXQgMTA6MTE6MjdBTSAtMDUwMCwgRnJhbmsgTGkgd3JvdGU6 Cj4gICAgICAgICAgICAgICAgICAgICAgICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQICAg ICAgICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkAo+ICAgICAgICAgICAg ICAgICAgICAgICAgIOKUgiAgICAgICDilIIgICAgICAgICAg4pSCICAgICAgICAgIOKUggo+ICAg ICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCAgIOKUgiAg ICAgICDilIIgICAgICAgICAg4pSCIFBDSSBIb3N0IOKUggo+ICAgICAgIOKUgiBNU0kgICAgICAg ICDilILil4TilJAg4pSCICAgICAgIOKUgiAgICAgICAgICDilIIgICAgICAgICAg4pSCCj4gICAg ICAg4pSCIENvbnRyb2xsZXIgIOKUgiDilIIg4pSCICAgICAgIOKUgiAgICAgICAgICDilIIgICAg ICAgICAg4pSCCj4gICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSYIOKUlOKUgOKUvOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUvOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUvOKUgEJBUjAgICAgIOKUggo+ICAgICAgICAgICAgICAgICAgICAgICAg IOKUgiBQQ0kgICDilIIgICAgICAgICAg4pSCIEJBUjEgICAgIOKUggo+ICAgICAgICAgICAgICAg ICAgICAgICAgIOKUgiBGdW5jICDilIIgICAgICAgICAg4pSCIEJBUjIgICAgIOKUggo+ICAgICAg ICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIIgICAgICAgICAg4pSCIEJBUjMgICAgIOKU ggo+ICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilIIgICAgICAgICAg4pSCIEJB UjQgICAgIOKUggo+ICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICDilJzilIDilIDi lIDilIDilIDilIDilIDilIDilIDilrrilIIgICAgICAgICAg4pSCCj4gICAgICAgICAgICAgICAg ICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYICAgICAgICAgIOKUlOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmAo+IAoKVGhpcyBkaWFncmFtIGRvZXNuJ3Qgc2F5IHdo aWNoIHNpZGUgaXMgaG9zdCBhbmQgd2hpY2ggb25lIGlzIGVuZHBvaW50LgpBbmQgbm90IGNvbnZl eWluZyBhbnkgdXNlZnVsIGluZm9ybWF0aW9uLgoKPiBMaW51eCBzdXBwb3J0cyBlbmRwb2ludCBm dW5jdGlvbnMuIFBDSSBIb3N0IHdyaXRlIEJBUjxuPiBzcGFjZSBsaWtlIHdyaXRlCj4gdG8gbWVt b3J5LiBUaGUgRVAgc2lkZSBjYW4ndCBrbm93IG1lbW9yeSBjaGFuZ2VkIGJ5IHRoZSBob3N0IGRy aXZlci4KPiAKCkkgdGhpbmsgeW91IGp1c3Qgc2F5LCB0aGF0IHRoZXJlIGlzIG5vIGRlZmluZWQg d2F5IG9mIHJhaXNpbmcgSVJRcyBieSBob3N0CnRvIHRoZSBlbmRwb2ludC4KCj4gUENJIFNwZWMg aGFzIG5vdCBkZWZpbmVkIGEgc3RhbmRhcmQgbWV0aG9kIHRvIGRvIHRoYXQuIE9ubHkgZGVmaW5l IE1TSSh4KQo+IHRvIGxldCBFUCBub3RpZmllZCBSQyBzdGF0dXMgY2hhbmdlLgo+IAoKTVNJIGlz IGZyb20gRVAsIHJpZ2h0PyBUaHJvdWdob3V0IHRoZSBkcml2ZXIgeW91IHNob3VsZCBjYWxsIGl0 IGFzICJkb29yYmVsbCIKYW5kIG5vdCBNU0kuCgo+IFRoZSBiYXNpYyBpZGVhIGlzIHRvIHRyaWdn ZXIgYW4gSVJRIHdoZW4gUENJIFJDIHdyaXRlcyB0byBhIG1lbW9yeQo+IGFkZHJlc3MuIFRoYXQn cyB3aGF0IE1TSSBjb250cm9sbGVyIHByb3ZpZGVkLiBFUCBkcml2ZXJzIGp1c3QgbmVlZCB0bwo+ IHJlcXVlc3QgYSBwbGF0Zm9ybSBNU0kgaW50ZXJydXB0LCBzdHJ1Y3QgbXNpX21zZyAqbXNnIHdp bGwgcGFzcyBkb3duIGEKPiBtZW1vcnkgYWRkcmVzcyBhbmQgZGF0YS4gRVAgZHJpdmVyIHdpbGwg bWFwIHN1Y2ggbWVtb3J5IGFkZHJlc3MgdG8gb25lIG9mCj4gUENJIEJBUjxuPi4gIEhvc3QganVz dCB3cml0ZXMgc3VjaCBhbiBhZGRyZXNzIHRvIHRyaWdnZXIgRVAgc2lkZSBpcnEuCj4gCgpJSVVD IChieSBsb29raW5nIGF0IG90aGVyIHBhdGNoZXMgaW4gdGhlIHNlcmllcyksIHRoZSBtZW1vcnkg YXNzaWduZWQgZm9yIEJBUgpyZWdpb24gYnkgdGhlIFBDSSBob3N0IGlzIG1hcHBlZCB0byB0aGUg cGxhdGZvcm0gaW50ZXJydXB0IGNvbnRyb2xsZXIgaW4KUENJIEVuZHBvaW50LiBTdWNoIHRoYXQs IHdoZW5ldmVyIHRoZSBQQ0kgaG9zdCB3cml0ZXMgdG8gdGhlIEJBUiByZWdpb24sIGl0CndpbGwg dHJpZ2dlciBhbiBJUlEgaW4gdGhlIEVuZHBvaW50LgoKVGhpcyBraW5kIG9mIHNldHVwIGlzIGF2 YWlsYWJsZSBpbiBvdGhlciBwbGF0Zm9ybXMgbGlrZSBRdWFsY29tbSB3aGVyZSB0aGUKbWFwcGlu ZyBvZiBhIHJlZ2lzdGVyIHJlZ2lvbiBhdmFpbGFibGUgaW4gQkFSMCBhbmQgaW50ZXJydXB0IGNv bnRyb2xsZXIgaXMKZG9uZSBpbiB0aGUgaGFyZHdhcmUgaXRzZWxmLiBTbyB3aGVuZXZlciB0aGUg UENJIGhvc3Qgd3JpdGVzIHRvIHRoYXQgcmVnaXN0ZXIKaW4gQkFSMCwgYW4gSVJRIHdpbGwgYmUg ZGVsaXZlcmVkIHRvIHRoZSBlbmRwb2ludC4KCj4gQWRkIE1TSSBzdXBwb3J0IGZvciBwY2ktZXBm LXZudGIuIHBjaS1lcGYtdm50YiBkcml2ZXIgcXVlcnkgaWYgc3lzdGVtCj4gaGF2ZSBNU0kgY29u dHJvbGxlci4gU2V0dXAgZG9vcmJlbGwgYWRkcmVzcyBhY2NvcmRpbmcgdG8gc3RydWN0IG1zaV9t c2cuCj4gCj4gU28gUENJZSBob3N0IGNhbiB3cml0ZSB0aGlzIGRvb3JiZWxsIGFkZHJlc3MgdG8g dHJpZ2VyIEVQIHNpZGUncyBpcnEuCj4gCj4gSWYgbm8gTVNJIGNvbnRyb2xsZXIgZXhpc3QsIGZh bGwgYmFjayB0byBzb2Z0d2FyZSBwb2xsaW5nLgo+IAo+IFNpZ25lZC1vZmYtYnk6IEZyYW5rIExp IDxGcmFuay5MaUBueHAuY29tPgo+IC0tLQo+ICBkcml2ZXJzL3BjaS9lbmRwb2ludC9mdW5jdGlv bnMvcGNpLWVwZi12bnRiLmMgfCAxMzQgKysrKysrKysrKysrKysrLS0tCj4gIDEgZmlsZSBjaGFu Z2VkLCAxMTIgaW5zZXJ0aW9ucygrKSwgMjIgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvcGNpL2VuZHBvaW50L2Z1bmN0aW9ucy9wY2ktZXBmLXZudGIuYyBiL2RyaXZlcnMv cGNpL2VuZHBvaW50L2Z1bmN0aW9ucy9wY2ktZXBmLXZudGIuYwo+IGluZGV4IDE0NjZkZDE5MDQx NzUuLmFkNGY3ZWM4YTM5ZmMgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9wY2kvZW5kcG9pbnQvZnVu Y3Rpb25zL3BjaS1lcGYtdm50Yi5jCj4gKysrIGIvZHJpdmVycy9wY2kvZW5kcG9pbnQvZnVuY3Rp b25zL3BjaS1lcGYtdm50Yi5jCj4gQEAgLTQ0LDYgKzQ0LDcgQEAKPiAgI2luY2x1ZGUgPGxpbnV4 L3BjaS1lcGMuaD4KPiAgI2luY2x1ZGUgPGxpbnV4L3BjaS1lcGYuaD4KPiAgI2luY2x1ZGUgPGxp bnV4L250Yi5oPgo+ICsjaW5jbHVkZSA8bGludXgvbXNpLmg+Cj4gIAo+ICBzdGF0aWMgc3RydWN0 IHdvcmtxdWV1ZV9zdHJ1Y3QgKmtwY2ludGJfd29ya3F1ZXVlOwo+ICAKPiBAQCAtMTQzLDYgKzE0 NCw4IEBAIHN0cnVjdCBlcGZfbnRiIHsKPiAgCXZvaWQgX19pb21lbSAqdnBjaV9td19hZGRyW01B WF9NV107Cj4gIAo+ICAJc3RydWN0IGRlbGF5ZWRfd29yayBjbWRfaGFuZGxlcjsKPiArCj4gKwlp bnQgbXNpX3ZpcnFiYXNlOwoKZGJfYmFzZT8KCj4gIH07Cj4gIAo+ICAjZGVmaW5lIHRvX2VwZl9u dGIoZXBmX2dyb3VwKSBjb250YWluZXJfb2YoKGVwZl9ncm91cCksIHN0cnVjdCBlcGZfbnRiLCBn cm91cCkKPiBAQCAtMjUzLDcgKzI1Niw3IEBAIHN0YXRpYyB2b2lkIGVwZl9udGJfY21kX2hhbmRs ZXIoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+ICAKPiAgCW50YiA9IGNvbnRhaW5lcl9vZih3 b3JrLCBzdHJ1Y3QgZXBmX250YiwgY21kX2hhbmRsZXIud29yayk7Cj4gIAo+IC0JZm9yIChpID0g MTsgaSA8IG50Yi0+ZGJfY291bnQ7IGkrKykgewo+ICsJZm9yIChpID0gMTsgaSA8IG50Yi0+ZGJf Y291bnQgJiYgIW50Yi0+ZXBmX2RiX3BoeTsgaSsrKSB7CgplcGZfZGJfcGh5IGlzIGEgd2llcmQg bmFtZS4gInBoeSIgdXN1YWxseSBtZWFucyB0aGUgUEhZIGNvbnRyb2xsZXIgKFBoeXNpY2FsCmxh eWVyKSBpbiBrZXJuZWwuIElmIHlvdSBhcmUgcmVmZXJyaW5nIHRvIHBoeXNpY2FsbCBhZGRyZXNz IG9mIHRoZSBkb29yYmVsbCwKdGhlbiB5b3UgY291bGQgdXNlICJwaHlzIi4KCj4gIAkJaWYgKHJl YWRsKG50Yi0+ZXBmX2RiICsgaSAqIDQpKSB7Cj4gIAkJCWlmIChyZWFkbChudGItPmVwZl9kYiAr IGkgKiA0KSkKPiAgCQkJCW50Yi0+ZGIgfD0gMSA8PCAoaSAtIDEpOwo+IEBAIC00NTQsMTEgKzQ1 Nyw5IEBAIHN0YXRpYyBpbnQgZXBmX250Yl9jb25maWdfc3BhZF9iYXJfYWxsb2Moc3RydWN0IGVw Zl9udGIgKm50YikKPiAgCWN0cmwtPm51bV9td3MgPSBudGItPm51bV9td3M7Cj4gIAludGItPnNw YWRfc2l6ZSA9IHNwYWRfc2l6ZTsKPiAgCj4gLQljdHJsLT5kYl9lbnRyeV9zaXplID0gNDsKPiAt Cj4gIAlmb3IgKGkgPSAwOyBpIDwgbnRiLT5kYl9jb3VudDsgaSsrKSB7Cj4gIAkJbnRiLT5yZWct PmRiX2RhdGFbaV0gPSAxICsgaTsKPiAtCQludGItPnJlZy0+ZGJfb2Zmc2V0W2ldID0gMDsKPiAr CQludGItPnJlZy0+ZGJfb2Zmc2V0W2ldID0gNCAqIGk7Cj4gIAl9Cj4gIAo+ICAJcmV0dXJuIDA7 Cj4gQEAgLTUwOSw2ICs1MTAsMjggQEAgc3RhdGljIGludCBlcGZfbnRiX2NvbmZpZ3VyZV9pbnRl cnJ1cHQoc3RydWN0IGVwZl9udGIgKm50YikKPiAgCXJldHVybiAwOwo+ICB9Cj4gIAo+ICtzdGF0 aWMgaW50IGVwZl9udGJfZGJfc2l6ZShzdHJ1Y3QgZXBmX250YiAqbnRiKQo+ICt7Cj4gKwljb25z dCBzdHJ1Y3QgcGNpX2VwY19mZWF0dXJlcyAqZXBjX2ZlYXR1cmVzOwo+ICsJc2l6ZV90IHNpemUg PSA0ICogbnRiLT5kYl9jb3VudDsKPiArCXUzMiBhbGlnbjsKPiArCj4gKwllcGNfZmVhdHVyZXMg PSBwY2lfZXBjX2dldF9mZWF0dXJlcyhudGItPmVwZi0+ZXBjLAo+ICsJCQkJCSAgICBudGItPmVw Zi0+ZnVuY19ubywKPiArCQkJCQkgICAgbnRiLT5lcGYtPnZmdW5jX25vKTsKPiArCWFsaWduID0g ZXBjX2ZlYXR1cmVzLT5hbGlnbjsKPiArCj4gKwlpZiAoc2l6ZSA8IDEyOCkKPiArCQlzaXplID0g MTI4Owo+ICsKPiArCWlmIChhbGlnbikKPiArCQlzaXplID0gQUxJR04oc2l6ZSwgYWxpZ24pOwo+ ICsJZWxzZQo+ICsJCXNpemUgPSByb3VuZHVwX3Bvd19vZl90d28oc2l6ZSk7Cj4gKwo+ICsJcmV0 dXJuIHNpemU7Cj4gK30KPiArCj4gIC8qKgo+ICAgKiBlcGZfbnRiX2RiX2Jhcl9pbml0KCkgLSBD b25maWd1cmUgRG9vcmJlbGwgd2luZG93IEJBUnMKPiAgICogQG50YjogTlRCIGRldmljZSB0aGF0 IGZhY2lsaXRhdGVzIGNvbW11bmljYXRpb24gYmV0d2VlbiBIT1NUIGFuZCB2SE9TVAo+IEBAIC01 MjAsMzUgKzU0MywzMyBAQCBzdGF0aWMgaW50IGVwZl9udGJfZGJfYmFyX2luaXQoc3RydWN0IGVw Zl9udGIgKm50YikKPiAgCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZudGItPmVwZi0+ZGV2Owo+ICAJ aW50IHJldDsKPiAgCXN0cnVjdCBwY2lfZXBmX2JhciAqZXBmX2JhcjsKPiAtCXZvaWQgX19pb21l bSAqbXdfYWRkcjsKPiArCXZvaWQgX19pb21lbSAqbXdfYWRkciA9IE5VTEw7Cj4gIAllbnVtIHBj aV9iYXJubyBiYXJubzsKPiAtCXNpemVfdCBzaXplID0gNCAqIG50Yi0+ZGJfY291bnQ7Cj4gKwlz aXplX3Qgc2l6ZTsKPiAgCj4gIAllcGNfZmVhdHVyZXMgPSBwY2lfZXBjX2dldF9mZWF0dXJlcyhu dGItPmVwZi0+ZXBjLAo+ICAJCQkJCSAgICBudGItPmVwZi0+ZnVuY19ubywKPiAgCQkJCQkgICAg bnRiLT5lcGYtPnZmdW5jX25vKTsKPiAgCWFsaWduID0gZXBjX2ZlYXR1cmVzLT5hbGlnbjsKPiAt Cj4gLQlpZiAoc2l6ZSA8IDEyOCkKPiAtCQlzaXplID0gMTI4Owo+IC0KPiAtCWlmIChhbGlnbikK PiAtCQlzaXplID0gQUxJR04oc2l6ZSwgYWxpZ24pOwo+IC0JZWxzZQo+IC0JCXNpemUgPSByb3Vu ZHVwX3Bvd19vZl90d28oc2l6ZSk7Cj4gKwlzaXplID0gZXBmX250Yl9kYl9zaXplKG50Yik7Cj4g IAo+ICAJYmFybm8gPSBudGItPmVwZl9udGJfYmFyW0JBUl9EQl07Cj4gKwllcGZfYmFyID0gJm50 Yi0+ZXBmLT5iYXJbYmFybm9dOwo+ICAKPiAtCW13X2FkZHIgPSBwY2lfZXBmX2FsbG9jX3NwYWNl KG50Yi0+ZXBmLCBzaXplLCBiYXJubywgYWxpZ24sIDApOwo+IC0JaWYgKCFtd19hZGRyKSB7Cj4g LQkJZGV2X2VycihkZXYsICJGYWlsZWQgdG8gYWxsb2NhdGUgT0IgYWRkcmVzc1xuIik7Cj4gLQkJ cmV0dXJuIC1FTk9NRU07Cj4gKwlpZiAoIW50Yi0+ZXBmX2RiX3BoeSkgewo+ICsJCW13X2FkZHIg PSBwY2lfZXBmX2FsbG9jX3NwYWNlKG50Yi0+ZXBmLCBzaXplLCBiYXJubywgYWxpZ24sIDApOwo+ ICsJCWlmICghbXdfYWRkcikgewo+ICsJCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBhbGxvY2F0 ZSBPQiBhZGRyZXNzXG4iKTsKCkV4cGFuZCBPQi4KCj4gKwkJCXJldHVybiAtRU5PTUVNOwo+ICsJ CX0KPiArCX0gZWxzZSB7Cj4gKwkJZXBmX2Jhci0+cGh5c19hZGRyID0gbnRiLT5lcGZfZGJfcGh5 Owo+ICsJCWVwZl9iYXItPmJhcm5vID0gYmFybm87Cj4gKwkJZXBmX2Jhci0+c2l6ZSA9IHNpemU7 Cj4gIAl9Cj4gIAo+ICAJbnRiLT5lcGZfZGIgPSBtd19hZGRyOwo+ICAKPiAtCWVwZl9iYXIgPSAm bnRiLT5lcGYtPmJhcltiYXJub107Cj4gLQo+ICAJcmV0ID0gcGNpX2VwY19zZXRfYmFyKG50Yi0+ ZXBmLT5lcGMsIG50Yi0+ZXBmLT5mdW5jX25vLCBudGItPmVwZi0+dmZ1bmNfbm8sIGVwZl9iYXIp Owo+ICAJaWYgKHJldCkgewo+ICAJCWRldl9lcnIoZGV2LCAiRG9vcmJlbGwgQkFSIHNldCBmYWls ZWRcbiIpOwo+IEBAIC03MDQsNiArNzI1LDc0IEBAIHN0YXRpYyBpbnQgZXBmX250Yl9pbml0X2Vw Y19iYXIoc3RydWN0IGVwZl9udGIgKm50YikKPiAgCXJldHVybiAwOwo+ICB9Cj4gIAo+ICtzdGF0 aWMgdm9pZCBlcGZfbnRiX3dyaXRlX21zaV9tc2coc3RydWN0IG1zaV9kZXNjICpkZXNjLCBzdHJ1 Y3QgbXNpX21zZyAqbXNnKQo+ICt7Cj4gKwlzdHJ1Y3QgZXBmX250YiAqbnRiID0gZGV2X2dldF9k cnZkYXRhKGRlc2MtPmRldik7Cj4gKwlzdHJ1Y3QgZXBmX250Yl9jdHJsICpyZWcgPSBudGItPnJl ZzsKPiArCWludCBzaXplID0gZXBmX250Yl9kYl9zaXplKG50Yik7Cj4gKwl1NjQgYWRkcjsKPiAr Cj4gKwlhZGRyID0gbXNnLT5hZGRyZXNzX2hpOwo+ICsJYWRkciA8PD0gMzI7Cj4gKwlhZGRyIHw9 IG1zZy0+YWRkcmVzc19sbzsKPiArCj4gKwlyZWctPmRiX2RhdGFbZGVzYy0+bXNpX2luZGV4XSA9 IG1zZy0+ZGF0YTsKPiArCj4gKwlpZiAoZGVzYy0+bXNpX2luZGV4ID09IDApCj4gKwkJbnRiLT5l cGZfZGJfcGh5ID0gcm91bmRfZG93bihhZGRyLCBzaXplKTsKPiArCj4gKwlyZWctPmRiX29mZnNl dFtkZXNjLT5tc2lfaW5kZXhdID0gYWRkciAtIG50Yi0+ZXBmX2RiX3BoeTsKPiArfQo+ICsKPiAr c3RhdGljIGlycXJldHVybl90IGVwZl9udGJfaW50ZXJydXB0X2hhbmRsZXIoaW50IGlycSwgdm9p ZCAqZGF0YSkKPiArewo+ICsJc3RydWN0IGVwZl9udGIgKm50YiA9IGRhdGE7Cj4gKwlpbnQgaW5k ZXg7Cj4gKwo+ICsJaW5kZXggPSBpcnEgLSBudGItPm1zaV92aXJxYmFzZTsKPiArCW50Yi0+ZGIg fD0gMSA8PCAoaW5kZXggLSAxKTsKPiArCW50Yl9kYl9ldmVudCgmbnRiLT5udGIsIGluZGV4KTsK PiArCj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGVwZl9u dGJfZXBjX21zaV9pbml0KHN0cnVjdCBlcGZfbnRiICpudGIpCj4gK3sKPiArCXN0cnVjdCBkZXZp Y2UgKmRldiA9ICZudGItPmVwZi0+ZGV2Owo+ICsJc3RydWN0IGlycV9kb21haW4gKmRvbWFpbjsK PiArCWludCB2aXJxOwo+ICsJaW50IHJldDsKPiArCWludCBpOwo+ICsKPiArCWRvbWFpbiA9IGRl dl9nZXRfbXNpX2RvbWFpbihudGItPmVwZi0+ZXBjLT5kZXYucGFyZW50KTsKPiArCWlmICghZG9t YWluKQo+ICsJCXJldHVybjsKPiArCj4gKwlkZXZfc2V0X21zaV9kb21haW4oZGV2LCBkb21haW4p Owo+ICsKPiArCWlmIChwbGF0Zm9ybV9tc2lfZG9tYWluX2FsbG9jX2lycXMoJm50Yi0+ZXBmLT5k ZXYsCj4gKwkJbnRiLT5kYl9jb3VudCwKPiArCQllcGZfbnRiX3dyaXRlX21zaV9tc2cpKSB7Cj4g KwkJZGV2X2luZm8oZGV2LCAiQ2FuJ3QgYWxsb2NhdGUgTVNJLCBmYWxsIGJhY2sgdG8gcG9sbCBt b2RlXG4iKTsKPiArCQlyZXR1cm47Cj4gKwl9Cj4gKwo+ICsJZGV2X2luZm8oZGV2LCAidm50YiB1 c2UgTVNJIGFzIGRvb3JiZWxsXG4iKTsKPiArCgpXaHkgYXJlIHlvdSB1c2luZyB0aGUgaW50ZXJy dXB0IGNvbnRyb2xsZXIgYXMgdGhlIE1TSSBjb250cm9sbGVyPyBXaHkgbm90IGp1c3QKYSBwbGFp biBpbnRlcnJ1cHQgY29udHJvbGxlcj8KCj4gKwlmb3IgKGkgPSAwOyBpIDwgbnRiLT5kYl9jb3Vu dDsgaSsrKSB7Cj4gKwkJdmlycSA9IG1zaV9nZXRfdmlycShkZXYsIGkpOwo+ICsJCXJldCA9IGRl dm1fcmVxdWVzdF9pcnEoZGV2LCB2aXJxLAo+ICsJCQkgICAgICAgZXBmX250Yl9pbnRlcnJ1cHRf aGFuZGxlciwgMCwKPiArCQkJICAgICAgICJudGIiLCBudGIpOwoKIm50YiIgYXMgYSBJUlEgbmFt ZSBzZWVtcyBxdWl0ZSBnZW5lcmljLiBZb3UgbWlnaHQgd2FudCB0byBwcmVmaXggaXQgd2l0aCBl cGYKb3Igdm50Yi4uLgoKVGhhbmtzLApNYW5pCgo+ICsKPiArCQlpZiAocmV0KQo+ICsJCQlkZXZf ZXJyKGRldiwgImRldm1fcmVxdWVzdF9pcnEoKSBmYWlsdXJlXG4iKTsKPiArCj4gKwkJaWYgKCFp KQo+ICsJCQludGItPm1zaV92aXJxYmFzZSA9IHZpcnE7Cj4gKwl9Cj4gK30KPiArCj4gIC8qKgo+ ICAgKiBlcGZfbnRiX2VwY19pbml0KCkgLSBJbml0aWFsaXplIE5UQiBpbnRlcmZhY2UKPiAgICog QG50YjogTlRCIGRldmljZSB0aGF0IGZhY2lsaXRhdGVzIGNvbW11bmljYXRpb24gYmV0d2VlbiBI T1NUIGFuZCB2SE9TVDIKPiBAQCAtMTI5OSwxNCArMTM4OCwxNSBAQCBzdGF0aWMgaW50IGVwZl9u dGJfYmluZChzdHJ1Y3QgcGNpX2VwZiAqZXBmKQo+ICAJCWdvdG8gZXJyX2Jhcl9hbGxvYzsKPiAg CX0KPiAgCj4gKwllcGZfc2V0X2RydmRhdGEoZXBmLCBudGIpOwo+ICsJZXBmX250Yl9lcGNfbXNp X2luaXQobnRiKTsKPiArCj4gIAlyZXQgPSBlcGZfbnRiX2VwY19pbml0KG50Yik7Cj4gIAlpZiAo cmV0KSB7Cj4gIAkJZGV2X2VycihkZXYsICJGYWlsZWQgdG8gaW5pdGlhbGl6ZSBFUENcbiIpOwo+ ICAJCWdvdG8gZXJyX2Jhcl9hbGxvYzsKPiAgCX0KPiAgCj4gLQllcGZfc2V0X2RydmRhdGEoZXBm LCBudGIpOwo+IC0KPiAgCXBjaV9zcGFjZVswXSA9IChudGItPnZudGJfcGlkIDw8IDE2KSB8IG50 Yi0+dm50Yl92aWQ7Cj4gIAlwY2lfdm50Yl90YWJsZVswXS52ZW5kb3IgPSBudGItPnZudGJfdmlk Owo+ICAJcGNpX3ZudGJfdGFibGVbMF0uZGV2aWNlID0gbnRiLT52bnRiX3BpZDsKPiAtLSAKPiAy LjM1LjEKPiAKCi0tIArgrq7grqPgrr/grrXgrqPgr43grqPgrqngr40g4K6a4K6k4K6+4K6a4K6/ 4K614K6u4K+NCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmlu ZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1hcm0ta2VybmVsCg==