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=-2.4 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=no 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 7B183C2D0C0 for ; Mon, 23 Dec 2019 08:59:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3211A20715 for ; Mon, 23 Dec 2019 08:59:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="xEt+mPkv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726007AbfLWI7E (ORCPT ); Mon, 23 Dec 2019 03:59:04 -0500 Received: from fllv0016.ext.ti.com ([198.47.19.142]:52888 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725927AbfLWI7E (ORCPT ); Mon, 23 Dec 2019 03:59:04 -0500 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id xBN8wpFi122519; Mon, 23 Dec 2019 02:58:51 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1577091531; bh=V3X161XHepZvvFiG+2ureTT5AB/uev5oOnL93dHeVeY=; h=Subject:To:CC:References:From:Date:In-Reply-To; b=xEt+mPkvNQmKzhkZqRjksBDqlYXmKQdaX7aB2/2GQvKSRQtv1+f93qxalSHoXgQFf J8R56GvQeEeLCvATEfTWxAcXfn8T6JzSDH0nD/JcCyZ+Yky1Ixohz1xMSjl+Ky/BDl LXAD56cVFlTOIvhZvOJpPq7TwXKzfufsoZL2JJKM= Received: from DFLE110.ent.ti.com (dfle110.ent.ti.com [10.64.6.31]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id xBN8wpBg045591 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 23 Dec 2019 02:58:51 -0600 Received: from DFLE103.ent.ti.com (10.64.6.24) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Mon, 23 Dec 2019 02:58:51 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Mon, 23 Dec 2019 02:58:51 -0600 Received: from [192.168.2.6] (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id xBN8wlOi032299; Mon, 23 Dec 2019 02:58:48 -0600 Subject: Re: [PATCH v7 09/12] dmaengine: ti: New driver for K3 UDMA To: Vinod Koul CC: , , , , , , , , , , , , , References: <20191209094332.4047-1-peter.ujfalusi@ti.com> <20191209094332.4047-10-peter.ujfalusi@ti.com> <20191223073425.GV2536@vkoul-mobl> From: Peter Ujfalusi Message-ID: Date: Mon, 23 Dec 2019 10:59:06 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: <20191223073425.GV2536@vkoul-mobl> Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 8bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org On 23/12/2019 9.34, Vinod Koul wrote: > On 09-12-19, 11:43, Peter Ujfalusi wrote: > >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include > > to many of headers, do we need all! I'll try to cut them back. >> +static char *udma_get_dir_text(enum dma_transfer_direction dir) >> +{ >> + switch (dir) { >> + case DMA_DEV_TO_MEM: >> + return "DEV_TO_MEM"; >> + case DMA_MEM_TO_DEV: >> + return "MEM_TO_DEV"; >> + case DMA_MEM_TO_MEM: >> + return "MEM_TO_MEM"; >> + case DMA_DEV_TO_DEV: >> + return "DEV_TO_DEV"; >> + default: >> + break; >> + } >> + >> + return "invalid"; >> +} > > this seems generic which other ppl may need, can we move it to core. dmaengine_get_direction_text() to include/linux/dmaengine.h This way client drivers can use it if they need it? >> +static void udma_reset_uchan(struct udma_chan *uc) >> +{ >> + uc->state = UDMA_CHAN_IS_IDLE; >> + uc->remote_thread_id = -1; >> + uc->dir = DMA_MEM_TO_MEM; >> + uc->pkt_mode = false; >> + uc->ep_type = PSIL_EP_NATIVE; >> + uc->enable_acc32 = 0; >> + uc->enable_burst = 0; >> + uc->channel_tpl = 0; >> + uc->psd_size = 0; >> + uc->metadata_size = 0; >> + uc->hdesc_size = 0; >> + uc->notdpkt = 0; > > rather than do setting zero, why note memset and then set the nonzero > members only? I have lots of other things in udma_chan which can not be memset, vchan struct, tasklet, name (for irq), etc. to use memset, I think I could move parameters under a new struct (udma_chan_params) keeping only the state in udma_chan. >> +static void udma_reset_counters(struct udma_chan *uc) >> +{ >> + u32 val; >> + >> + if (uc->tchan) { >> + val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_BCNT_REG); >> + udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_BCNT_REG, val); > > so you read back from UDMA_TCHAN_RT_BCNT_REG and write same value to > it?? Yes, that's correct. This is how we can reset it. The counter is decremented with the value you have written to the register. >> + >> + val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG); >> + udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG, val); >> + >> + val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PCNT_REG); >> + udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PCNT_REG, val); >> + >> + val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG); >> + udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG, val); >> + } >> + >> + if (uc->rchan) { >> + val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_BCNT_REG); >> + udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_BCNT_REG, val); >> + >> + val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG); >> + udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG, val); >> + >> + val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PCNT_REG); >> + udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PCNT_REG, val); >> + >> + val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG); >> + udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG, val); > > True for all of these, what am I missing :) Decrement on write. > >> +static int udma_start(struct udma_chan *uc) >> +{ >> + struct virt_dma_desc *vd = vchan_next_desc(&uc->vc); >> + >> + if (!vd) { >> + uc->desc = NULL; >> + return -ENOENT; >> + } >> + >> + list_del(&vd->node); >> + >> + uc->desc = to_udma_desc(&vd->tx); >> + >> + /* Channel is already running and does not need reconfiguration */ >> + if (udma_is_chan_running(uc) && !udma_chan_needs_reconfiguration(uc)) { >> + udma_start_desc(uc); >> + goto out; > > How about the case where settings are different than the current one? udma_chan_needs_reconfiguration() is checking that. I only need to reconfigure UDMAP/PDMA if the settings have changed. >> +static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc, >> + size_t tr_size, int tr_count, >> + enum dma_transfer_direction dir) >> +{ >> + struct udma_hwdesc *hwdesc; >> + struct cppi5_desc_hdr_t *tr_desc; >> + struct udma_desc *d; >> + u32 reload_count = 0; >> + u32 ring_id; >> + >> + switch (tr_size) { >> + case 16: >> + case 32: >> + case 64: >> + case 128: >> + break; >> + default: >> + dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size); >> + return NULL; >> + } >> + >> + /* We have only one descriptor containing multiple TRs */ >> + d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_ATOMIC); > > this is invoked from prep_ so should use GFP_NOWAIT, we dont use > GFP_ATOMIC :) Ok. btw: EDMA and sDMA driver is using GFP_ATOMIC :o > >> +static struct udma_desc * >> +udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, >> + unsigned int sglen, enum dma_transfer_direction dir, >> + unsigned long tx_flags, void *context) >> +{ >> + enum dma_slave_buswidth dev_width; >> + struct scatterlist *sgent; >> + struct udma_desc *d; >> + size_t tr_size; >> + struct cppi5_tr_type1_t *tr_req = NULL; >> + unsigned int i; >> + u32 burst; >> + >> + if (dir == DMA_DEV_TO_MEM) { >> + dev_width = uc->cfg.src_addr_width; >> + burst = uc->cfg.src_maxburst; >> + } else if (dir == DMA_MEM_TO_DEV) { >> + dev_width = uc->cfg.dst_addr_width; >> + burst = uc->cfg.dst_maxburst; >> + } else { >> + dev_err(uc->ud->dev, "%s: bad direction?\n", __func__); >> + return NULL; >> + } >> + >> + if (!burst) >> + burst = 1; >> + >> + /* Now allocate and setup the descriptor. */ >> + tr_size = sizeof(struct cppi5_tr_type1_t); >> + d = udma_alloc_tr_desc(uc, tr_size, sglen, dir); >> + if (!d) >> + return NULL; >> + >> + d->sglen = sglen; >> + >> + tr_req = (struct cppi5_tr_type1_t *)d->hwdesc[0].tr_req_base; > > cast away from void *? True, it is not needed. >> +static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d, >> + enum dma_slave_buswidth dev_width, >> + u16 elcnt) >> +{ >> + if (uc->ep_type != PSIL_EP_PDMA_XY) >> + return 0; >> + >> + /* Bus width translates to the element size (ES) */ >> + switch (dev_width) { >> + case DMA_SLAVE_BUSWIDTH_1_BYTE: >> + d->static_tr.elsize = 0; >> + break; >> + case DMA_SLAVE_BUSWIDTH_2_BYTES: >> + d->static_tr.elsize = 1; >> + break; >> + case DMA_SLAVE_BUSWIDTH_3_BYTES: >> + d->static_tr.elsize = 2; >> + break; >> + case DMA_SLAVE_BUSWIDTH_4_BYTES: >> + d->static_tr.elsize = 3; >> + break; >> + case DMA_SLAVE_BUSWIDTH_8_BYTES: >> + d->static_tr.elsize = 4; > > seems like ffs(dev_width) to me? Not really: ffs(DMA_SLAVE_BUSWIDTH_1_BYTE) = 1 ffs(DMA_SLAVE_BUSWIDTH_2_BYTES) = 2 ffs(DMA_SLAVE_BUSWIDTH_3_BYTES) = 1 ffs(DMA_SLAVE_BUSWIDTH_4_BYTES) = 3 ffs(DMA_SLAVE_BUSWIDTH_8_BYTES) = 4 > >> +static struct udma_desc * >> +udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl, >> + unsigned int sglen, enum dma_transfer_direction dir, >> + unsigned long tx_flags, void *context) >> +{ >> + struct scatterlist *sgent; >> + struct cppi5_host_desc_t *h_desc = NULL; >> + struct udma_desc *d; >> + u32 ring_id; >> + unsigned int i; >> + >> + d = kzalloc(sizeof(*d) + sglen * sizeof(d->hwdesc[0]), GFP_ATOMIC); > > GFP_NOWAIT here and few other places Yes, I have fixed them up by this time. > >> +static struct udma_desc * >> +udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr, >> + size_t buf_len, size_t period_len, >> + enum dma_transfer_direction dir, unsigned long flags) >> +{ >> + struct udma_desc *d; >> + u32 ring_id; >> + int i; >> + int periods = buf_len / period_len; >> + >> + if (periods > (K3_UDMA_DEFAULT_RING_SIZE - 1)) >> + return NULL; >> + >> + if (period_len > 0x3FFFFF) > > Magic? I'll add a define to cppi5. It is the packet length limit. > >> +static enum dma_status udma_tx_status(struct dma_chan *chan, >> + dma_cookie_t cookie, >> + struct dma_tx_state *txstate) >> +{ >> + struct udma_chan *uc = to_udma_chan(chan); >> + enum dma_status ret; >> + unsigned long flags; >> + >> + spin_lock_irqsave(&uc->vc.lock, flags); >> + >> + ret = dma_cookie_status(chan, cookie, txstate); >> + >> + if (!udma_is_chan_running(uc)) >> + ret = DMA_COMPLETE; > > Even for paused, not started channel? Not sure what will be return on those cases Hrm, if the channel is not started yet, then I think it should be still DMA_IN_PROGRESS, right? The udma_is_chan_running() can be dropped from here. I did missed the DMA_PAUSED state. - if (!udma_is_chan_running(uc)) - ret = DMA_COMPLETE; + if (ret == DMA_IN_PROGRESS && udma_is_chan_paused(uc)) + ret = DMA_PAUSED; - Péter Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki 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=-2.3 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_SANE_1 autolearn=no 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 4C238C2D0C0 for ; Mon, 23 Dec 2019 08:59:13 +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 E7FC020709 for ; Mon, 23 Dec 2019 08:59:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ZjfV3luo"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=ti.com header.i=@ti.com header.b="xEt+mPkv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E7FC020709 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date: Message-ID:From:References:To:Subject:Reply-To:Content-ID:Content-Description :Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=B4kX8Wsl6q/aGl6BDqm7WWogWHBHZZ2pgmmKa6B47z0=; b=ZjfV3luoFn4oa3 //KB8VfB/HwsOiimepdATp4hYZUAeWQiD/C6avevKunLKiTf8t/xEqBo3XobTUT+V7l/C4fscNAqV deMwavUVqgOfSu0GtWNFJ0TFArGvKWxKE5qdPboDQB/h58Q1TgmtSuPhPEz4ZURfvkDePCEY9piaL xeSTfKz1dFIvJFs7CeE2wHHe/wJ7Gegh0hglmMDpa9tRedWvGH7fHEFtEc14ciT9tfLW5vPcyPsSJ 7MyaCYh0HEpUDqm7m2Vxsw1+yRCZaOfsyrR7r9X95o3knQ8M9xUDw/smHLaMHEI9ikXLWwURcvu2j FhOr6Ym9b2UKzUV5XKYw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ijJYP-0005pE-0j; Mon, 23 Dec 2019 08:59:05 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ijJYL-0005oW-Hl for linux-arm-kernel@lists.infradead.org; Mon, 23 Dec 2019 08:59:03 +0000 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id xBN8wpFi122519; Mon, 23 Dec 2019 02:58:51 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1577091531; bh=V3X161XHepZvvFiG+2ureTT5AB/uev5oOnL93dHeVeY=; h=Subject:To:CC:References:From:Date:In-Reply-To; b=xEt+mPkvNQmKzhkZqRjksBDqlYXmKQdaX7aB2/2GQvKSRQtv1+f93qxalSHoXgQFf J8R56GvQeEeLCvATEfTWxAcXfn8T6JzSDH0nD/JcCyZ+Yky1Ixohz1xMSjl+Ky/BDl LXAD56cVFlTOIvhZvOJpPq7TwXKzfufsoZL2JJKM= Received: from DFLE110.ent.ti.com (dfle110.ent.ti.com [10.64.6.31]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id xBN8wpBg045591 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 23 Dec 2019 02:58:51 -0600 Received: from DFLE103.ent.ti.com (10.64.6.24) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Mon, 23 Dec 2019 02:58:51 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Mon, 23 Dec 2019 02:58:51 -0600 Received: from [192.168.2.6] (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id xBN8wlOi032299; Mon, 23 Dec 2019 02:58:48 -0600 Subject: Re: [PATCH v7 09/12] dmaengine: ti: New driver for K3 UDMA To: Vinod Koul References: <20191209094332.4047-1-peter.ujfalusi@ti.com> <20191209094332.4047-10-peter.ujfalusi@ti.com> <20191223073425.GV2536@vkoul-mobl> From: Peter Ujfalusi Message-ID: Date: Mon, 23 Dec 2019 10:59:06 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: <20191223073425.GV2536@vkoul-mobl> Content-Language: en-US X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191223_005901_668964_7C9C2FF9 X-CRM114-Status: GOOD ( 23.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nm@ti.com, devicetree@vger.kernel.org, grygorii.strashko@ti.com, vigneshr@ti.com, lokeshvutla@ti.com, j-keerthy@ti.com, linux-kernel@vger.kernel.org, t-kristo@ti.com, tony@atomide.com, robh+dt@kernel.org, ssantosh@kernel.org, dmaengine@vger.kernel.org, dan.j.williams@intel.com, linux-arm-kernel@lists.infradead.org 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 CgpPbiAyMy8xMi8yMDE5IDkuMzQsIFZpbm9kIEtvdWwgd3JvdGU6Cj4gT24gMDktMTItMTksIDEx OjQzLCBQZXRlciBVamZhbHVzaSB3cm90ZToKPiAKPj4gKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwu aD4KPj4gKyNpbmNsdWRlIDxsaW51eC9kbWFlbmdpbmUuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9k bWEtbWFwcGluZy5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2RtYXBvb2wuaD4KPj4gKyNpbmNsdWRl IDxsaW51eC9lcnIuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pbml0Lmg+Cj4+ICsjaW5jbHVkZSA8 bGludXgvaW50ZXJydXB0Lmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbGlzdC5oPgo+PiArI2luY2x1 ZGUgPGxpbnV4L21vZHVsZS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5o Pgo+PiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9zcGlubG9j ay5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvb2ZfZG1h Lmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvb2ZfZGV2aWNlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgv b2ZfaXJxLmg+Cj4gCj4gdG8gbWFueSBvZiBoZWFkZXJzLCBkbyB3ZSBuZWVkIGFsbCEKCkknbGwg dHJ5IHRvIGN1dCB0aGVtIGJhY2suCgo+PiArc3RhdGljIGNoYXIgKnVkbWFfZ2V0X2Rpcl90ZXh0 KGVudW0gZG1hX3RyYW5zZmVyX2RpcmVjdGlvbiBkaXIpCj4+ICt7Cj4+ICsJc3dpdGNoIChkaXIp IHsKPj4gKwljYXNlIERNQV9ERVZfVE9fTUVNOgo+PiArCQlyZXR1cm4gIkRFVl9UT19NRU0iOwo+ PiArCWNhc2UgRE1BX01FTV9UT19ERVY6Cj4+ICsJCXJldHVybiAiTUVNX1RPX0RFViI7Cj4+ICsJ Y2FzZSBETUFfTUVNX1RPX01FTToKPj4gKwkJcmV0dXJuICJNRU1fVE9fTUVNIjsKPj4gKwljYXNl IERNQV9ERVZfVE9fREVWOgo+PiArCQlyZXR1cm4gIkRFVl9UT19ERVYiOwo+PiArCWRlZmF1bHQ6 Cj4+ICsJCWJyZWFrOwo+PiArCX0KPj4gKwo+PiArCXJldHVybiAiaW52YWxpZCI7Cj4+ICt9Cj4g Cj4gdGhpcyBzZWVtcyBnZW5lcmljIHdoaWNoIG90aGVyIHBwbCBtYXkgbmVlZCwgY2FuIHdlIG1v dmUgaXQgdG8gY29yZS4KCmRtYWVuZ2luZV9nZXRfZGlyZWN0aW9uX3RleHQoKSB0byBpbmNsdWRl L2xpbnV4L2RtYWVuZ2luZS5oClRoaXMgd2F5IGNsaWVudCBkcml2ZXJzIGNhbiB1c2UgaXQgaWYg dGhleSBuZWVkIGl0PwoKPj4gK3N0YXRpYyB2b2lkIHVkbWFfcmVzZXRfdWNoYW4oc3RydWN0IHVk bWFfY2hhbiAqdWMpCj4+ICt7Cj4+ICsJdWMtPnN0YXRlID0gVURNQV9DSEFOX0lTX0lETEU7Cj4+ ICsJdWMtPnJlbW90ZV90aHJlYWRfaWQgPSAtMTsKPj4gKwl1Yy0+ZGlyID0gRE1BX01FTV9UT19N RU07Cj4+ICsJdWMtPnBrdF9tb2RlID0gZmFsc2U7Cj4+ICsJdWMtPmVwX3R5cGUgPSBQU0lMX0VQ X05BVElWRTsKPj4gKwl1Yy0+ZW5hYmxlX2FjYzMyID0gMDsKPj4gKwl1Yy0+ZW5hYmxlX2J1cnN0 ID0gMDsKPj4gKwl1Yy0+Y2hhbm5lbF90cGwgPSAwOwo+PiArCXVjLT5wc2Rfc2l6ZSA9IDA7Cj4+ ICsJdWMtPm1ldGFkYXRhX3NpemUgPSAwOwo+PiArCXVjLT5oZGVzY19zaXplID0gMDsKPj4gKwl1 Yy0+bm90ZHBrdCA9IDA7Cj4gCj4gcmF0aGVyIHRoYW4gZG8gc2V0dGluZyB6ZXJvLCB3aHkgbm90 ZSBtZW1zZXQgYW5kIHRoZW4gc2V0IHRoZSBub256ZXJvCj4gbWVtYmVycyBvbmx5PwoKSSBoYXZl IGxvdHMgb2Ygb3RoZXIgdGhpbmdzIGluIHVkbWFfY2hhbiB3aGljaCBjYW4gbm90IGJlIG1lbXNl dCwgdmNoYW4Kc3RydWN0LCB0YXNrbGV0LCBuYW1lIChmb3IgaXJxKSwgZXRjLgoKdG8gdXNlIG1l bXNldCwgSSB0aGluayBJIGNvdWxkIG1vdmUgcGFyYW1ldGVycyB1bmRlciBhIG5ldyBzdHJ1Y3QK KHVkbWFfY2hhbl9wYXJhbXMpIGtlZXBpbmcgb25seSB0aGUgc3RhdGUgaW4gdWRtYV9jaGFuLgoK Cj4+ICtzdGF0aWMgdm9pZCB1ZG1hX3Jlc2V0X2NvdW50ZXJzKHN0cnVjdCB1ZG1hX2NoYW4gKnVj KQo+PiArewo+PiArCXUzMiB2YWw7Cj4+ICsKPj4gKwlpZiAodWMtPnRjaGFuKSB7Cj4+ICsJCXZh bCA9IHVkbWFfdGNoYW5ydF9yZWFkKHVjLT50Y2hhbiwgVURNQV9UQ0hBTl9SVF9CQ05UX1JFRyk7 Cj4+ICsJCXVkbWFfdGNoYW5ydF93cml0ZSh1Yy0+dGNoYW4sIFVETUFfVENIQU5fUlRfQkNOVF9S RUcsIHZhbCk7Cj4gCj4gc28geW91IHJlYWQgYmFjayBmcm9tIFVETUFfVENIQU5fUlRfQkNOVF9S RUcgYW5kIHdyaXRlIHNhbWUgdmFsdWUgdG8KPiBpdD8/CgpZZXMsIHRoYXQncyBjb3JyZWN0LiBU aGlzIGlzIGhvdyB3ZSBjYW4gcmVzZXQgaXQuIFRoZSBjb3VudGVyIGlzCmRlY3JlbWVudGVkIHdp dGggdGhlIHZhbHVlIHlvdSBoYXZlIHdyaXR0ZW4gdG8gdGhlIHJlZ2lzdGVyLgoKPj4gKwo+PiAr CQl2YWwgPSB1ZG1hX3RjaGFucnRfcmVhZCh1Yy0+dGNoYW4sIFVETUFfVENIQU5fUlRfU0JDTlRf UkVHKTsKPj4gKwkJdWRtYV90Y2hhbnJ0X3dyaXRlKHVjLT50Y2hhbiwgVURNQV9UQ0hBTl9SVF9T QkNOVF9SRUcsIHZhbCk7Cj4+ICsKPj4gKwkJdmFsID0gdWRtYV90Y2hhbnJ0X3JlYWQodWMtPnRj aGFuLCBVRE1BX1RDSEFOX1JUX1BDTlRfUkVHKTsKPj4gKwkJdWRtYV90Y2hhbnJ0X3dyaXRlKHVj LT50Y2hhbiwgVURNQV9UQ0hBTl9SVF9QQ05UX1JFRywgdmFsKTsKPj4gKwo+PiArCQl2YWwgPSB1 ZG1hX3RjaGFucnRfcmVhZCh1Yy0+dGNoYW4sIFVETUFfVENIQU5fUlRfUEVFUl9CQ05UX1JFRyk7 Cj4+ICsJCXVkbWFfdGNoYW5ydF93cml0ZSh1Yy0+dGNoYW4sIFVETUFfVENIQU5fUlRfUEVFUl9C Q05UX1JFRywgdmFsKTsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAodWMtPnJjaGFuKSB7Cj4+ICsJCXZh bCA9IHVkbWFfcmNoYW5ydF9yZWFkKHVjLT5yY2hhbiwgVURNQV9SQ0hBTl9SVF9CQ05UX1JFRyk7 Cj4+ICsJCXVkbWFfcmNoYW5ydF93cml0ZSh1Yy0+cmNoYW4sIFVETUFfUkNIQU5fUlRfQkNOVF9S RUcsIHZhbCk7Cj4+ICsKPj4gKwkJdmFsID0gdWRtYV9yY2hhbnJ0X3JlYWQodWMtPnJjaGFuLCBV RE1BX1JDSEFOX1JUX1NCQ05UX1JFRyk7Cj4+ICsJCXVkbWFfcmNoYW5ydF93cml0ZSh1Yy0+cmNo YW4sIFVETUFfUkNIQU5fUlRfU0JDTlRfUkVHLCB2YWwpOwo+PiArCj4+ICsJCXZhbCA9IHVkbWFf cmNoYW5ydF9yZWFkKHVjLT5yY2hhbiwgVURNQV9SQ0hBTl9SVF9QQ05UX1JFRyk7Cj4+ICsJCXVk bWFfcmNoYW5ydF93cml0ZSh1Yy0+cmNoYW4sIFVETUFfUkNIQU5fUlRfUENOVF9SRUcsIHZhbCk7 Cj4+ICsKPj4gKwkJdmFsID0gdWRtYV9yY2hhbnJ0X3JlYWQodWMtPnJjaGFuLCBVRE1BX1JDSEFO X1JUX1BFRVJfQkNOVF9SRUcpOwo+PiArCQl1ZG1hX3JjaGFucnRfd3JpdGUodWMtPnJjaGFuLCBV RE1BX1JDSEFOX1JUX1BFRVJfQkNOVF9SRUcsIHZhbCk7Cj4gCj4gVHJ1ZSBmb3IgYWxsIG9mIHRo ZXNlLCB3aGF0IGFtIEkgbWlzc2luZyA6KQoKRGVjcmVtZW50IG9uIHdyaXRlLgoKPiAKPj4gK3N0 YXRpYyBpbnQgdWRtYV9zdGFydChzdHJ1Y3QgdWRtYV9jaGFuICp1YykKPj4gK3sKPj4gKwlzdHJ1 Y3QgdmlydF9kbWFfZGVzYyAqdmQgPSB2Y2hhbl9uZXh0X2Rlc2MoJnVjLT52Yyk7Cj4+ICsKPj4g KwlpZiAoIXZkKSB7Cj4+ICsJCXVjLT5kZXNjID0gTlVMTDsKPj4gKwkJcmV0dXJuIC1FTk9FTlQ7 Cj4+ICsJfQo+PiArCj4+ICsJbGlzdF9kZWwoJnZkLT5ub2RlKTsKPj4gKwo+PiArCXVjLT5kZXNj ID0gdG9fdWRtYV9kZXNjKCZ2ZC0+dHgpOwo+PiArCj4+ICsJLyogQ2hhbm5lbCBpcyBhbHJlYWR5 IHJ1bm5pbmcgYW5kIGRvZXMgbm90IG5lZWQgcmVjb25maWd1cmF0aW9uICovCj4+ICsJaWYgKHVk bWFfaXNfY2hhbl9ydW5uaW5nKHVjKSAmJiAhdWRtYV9jaGFuX25lZWRzX3JlY29uZmlndXJhdGlv bih1YykpIHsKPj4gKwkJdWRtYV9zdGFydF9kZXNjKHVjKTsKPj4gKwkJZ290byBvdXQ7Cj4gCj4g SG93IGFib3V0IHRoZSBjYXNlIHdoZXJlIHNldHRpbmdzIGFyZSBkaWZmZXJlbnQgdGhhbiB0aGUg Y3VycmVudCBvbmU/Cgp1ZG1hX2NoYW5fbmVlZHNfcmVjb25maWd1cmF0aW9uKCkgaXMgY2hlY2tp bmcgdGhhdC4gSSBvbmx5IG5lZWQgdG8KcmVjb25maWd1cmUgVURNQVAvUERNQSBpZiB0aGUgc2V0 dGluZ3MgaGF2ZSBjaGFuZ2VkLgoKPj4gK3N0YXRpYyBzdHJ1Y3QgdWRtYV9kZXNjICp1ZG1hX2Fs bG9jX3RyX2Rlc2Moc3RydWN0IHVkbWFfY2hhbiAqdWMsCj4+ICsJCQkJCSAgICBzaXplX3QgdHJf c2l6ZSwgaW50IHRyX2NvdW50LAo+PiArCQkJCQkgICAgZW51bSBkbWFfdHJhbnNmZXJfZGlyZWN0 aW9uIGRpcikKPj4gK3sKPj4gKwlzdHJ1Y3QgdWRtYV9od2Rlc2MgKmh3ZGVzYzsKPj4gKwlzdHJ1 Y3QgY3BwaTVfZGVzY19oZHJfdCAqdHJfZGVzYzsKPj4gKwlzdHJ1Y3QgdWRtYV9kZXNjICpkOwo+ PiArCXUzMiByZWxvYWRfY291bnQgPSAwOwo+PiArCXUzMiByaW5nX2lkOwo+PiArCj4+ICsJc3dp dGNoICh0cl9zaXplKSB7Cj4+ICsJY2FzZSAxNjoKPj4gKwljYXNlIDMyOgo+PiArCWNhc2UgNjQ6 Cj4+ICsJY2FzZSAxMjg6Cj4+ICsJCWJyZWFrOwo+PiArCWRlZmF1bHQ6Cj4+ICsJCWRldl9lcnIo dWMtPnVkLT5kZXYsICJVbnN1cHBvcnRlZCBUUiBzaXplIG9mICV6dVxuIiwgdHJfc2l6ZSk7Cj4+ ICsJCXJldHVybiBOVUxMOwo+PiArCX0KPj4gKwo+PiArCS8qIFdlIGhhdmUgb25seSBvbmUgZGVz Y3JpcHRvciBjb250YWluaW5nIG11bHRpcGxlIFRScyAqLwo+PiArCWQgPSBremFsbG9jKHNpemVv ZigqZCkgKyBzaXplb2YoZC0+aHdkZXNjWzBdKSwgR0ZQX0FUT01JQyk7Cj4gCj4gdGhpcyBpcyBp bnZva2VkIGZyb20gcHJlcF8gc28gc2hvdWxkIHVzZSBHRlBfTk9XQUlULCB3ZSBkb250IHVzZQo+ IEdGUF9BVE9NSUMgOikKCk9rLiBidHc6IEVETUEgYW5kIHNETUEgZHJpdmVyIGlzIHVzaW5nIEdG UF9BVE9NSUMgOm8KCj4gCj4+ICtzdGF0aWMgc3RydWN0IHVkbWFfZGVzYyAqCj4+ICt1ZG1hX3By ZXBfc2xhdmVfc2dfdHIoc3RydWN0IHVkbWFfY2hhbiAqdWMsIHN0cnVjdCBzY2F0dGVybGlzdCAq c2dsLAo+PiArCQkgICAgICB1bnNpZ25lZCBpbnQgc2dsZW4sIGVudW0gZG1hX3RyYW5zZmVyX2Rp cmVjdGlvbiBkaXIsCj4+ICsJCSAgICAgIHVuc2lnbmVkIGxvbmcgdHhfZmxhZ3MsIHZvaWQgKmNv bnRleHQpCj4+ICt7Cj4+ICsJZW51bSBkbWFfc2xhdmVfYnVzd2lkdGggZGV2X3dpZHRoOwo+PiAr CXN0cnVjdCBzY2F0dGVybGlzdCAqc2dlbnQ7Cj4+ICsJc3RydWN0IHVkbWFfZGVzYyAqZDsKPj4g KwlzaXplX3QgdHJfc2l6ZTsKPj4gKwlzdHJ1Y3QgY3BwaTVfdHJfdHlwZTFfdCAqdHJfcmVxID0g TlVMTDsKPj4gKwl1bnNpZ25lZCBpbnQgaTsKPj4gKwl1MzIgYnVyc3Q7Cj4+ICsKPj4gKwlpZiAo ZGlyID09IERNQV9ERVZfVE9fTUVNKSB7Cj4+ICsJCWRldl93aWR0aCA9IHVjLT5jZmcuc3JjX2Fk ZHJfd2lkdGg7Cj4+ICsJCWJ1cnN0ID0gdWMtPmNmZy5zcmNfbWF4YnVyc3Q7Cj4+ICsJfSBlbHNl IGlmIChkaXIgPT0gRE1BX01FTV9UT19ERVYpIHsKPj4gKwkJZGV2X3dpZHRoID0gdWMtPmNmZy5k c3RfYWRkcl93aWR0aDsKPj4gKwkJYnVyc3QgPSB1Yy0+Y2ZnLmRzdF9tYXhidXJzdDsKPj4gKwl9 IGVsc2Ugewo+PiArCQlkZXZfZXJyKHVjLT51ZC0+ZGV2LCAiJXM6IGJhZCBkaXJlY3Rpb24/XG4i LCBfX2Z1bmNfXyk7Cj4+ICsJCXJldHVybiBOVUxMOwo+PiArCX0KPj4gKwo+PiArCWlmICghYnVy c3QpCj4+ICsJCWJ1cnN0ID0gMTsKPj4gKwo+PiArCS8qIE5vdyBhbGxvY2F0ZSBhbmQgc2V0dXAg dGhlIGRlc2NyaXB0b3IuICovCj4+ICsJdHJfc2l6ZSA9IHNpemVvZihzdHJ1Y3QgY3BwaTVfdHJf dHlwZTFfdCk7Cj4+ICsJZCA9IHVkbWFfYWxsb2NfdHJfZGVzYyh1YywgdHJfc2l6ZSwgc2dsZW4s IGRpcik7Cj4+ICsJaWYgKCFkKQo+PiArCQlyZXR1cm4gTlVMTDsKPj4gKwo+PiArCWQtPnNnbGVu ID0gc2dsZW47Cj4+ICsKPj4gKwl0cl9yZXEgPSAoc3RydWN0IGNwcGk1X3RyX3R5cGUxX3QgKilk LT5od2Rlc2NbMF0udHJfcmVxX2Jhc2U7Cj4gCj4gY2FzdCBhd2F5IGZyb20gdm9pZCAqPwoKVHJ1 ZSwgaXQgaXMgbm90IG5lZWRlZC4KCj4+ICtzdGF0aWMgaW50IHVkbWFfY29uZmlndXJlX3N0YXRp Y3RyKHN0cnVjdCB1ZG1hX2NoYW4gKnVjLCBzdHJ1Y3QgdWRtYV9kZXNjICpkLAo+PiArCQkJCSAg IGVudW0gZG1hX3NsYXZlX2J1c3dpZHRoIGRldl93aWR0aCwKPj4gKwkJCQkgICB1MTYgZWxjbnQp Cj4+ICt7Cj4+ICsJaWYgKHVjLT5lcF90eXBlICE9IFBTSUxfRVBfUERNQV9YWSkKPj4gKwkJcmV0 dXJuIDA7Cj4+ICsKPj4gKwkvKiBCdXMgd2lkdGggdHJhbnNsYXRlcyB0byB0aGUgZWxlbWVudCBz aXplIChFUykgKi8KPj4gKwlzd2l0Y2ggKGRldl93aWR0aCkgewo+PiArCWNhc2UgRE1BX1NMQVZF X0JVU1dJRFRIXzFfQllURToKPj4gKwkJZC0+c3RhdGljX3RyLmVsc2l6ZSA9IDA7Cj4+ICsJCWJy ZWFrOwo+PiArCWNhc2UgRE1BX1NMQVZFX0JVU1dJRFRIXzJfQllURVM6Cj4+ICsJCWQtPnN0YXRp Y190ci5lbHNpemUgPSAxOwo+PiArCQlicmVhazsKPj4gKwljYXNlIERNQV9TTEFWRV9CVVNXSURU SF8zX0JZVEVTOgo+PiArCQlkLT5zdGF0aWNfdHIuZWxzaXplID0gMjsKPj4gKwkJYnJlYWs7Cj4+ ICsJY2FzZSBETUFfU0xBVkVfQlVTV0lEVEhfNF9CWVRFUzoKPj4gKwkJZC0+c3RhdGljX3RyLmVs c2l6ZSA9IDM7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgRE1BX1NMQVZFX0JVU1dJRFRIXzhfQllU RVM6Cj4+ICsJCWQtPnN0YXRpY190ci5lbHNpemUgPSA0Owo+IAo+IHNlZW1zIGxpa2UgZmZzKGRl dl93aWR0aCkgdG8gbWU/CgpOb3QgcmVhbGx5OgpmZnMoRE1BX1NMQVZFX0JVU1dJRFRIXzFfQllU RSkgPSAxCmZmcyhETUFfU0xBVkVfQlVTV0lEVEhfMl9CWVRFUykgPSAyCmZmcyhETUFfU0xBVkVf QlVTV0lEVEhfM19CWVRFUykgPSAxCmZmcyhETUFfU0xBVkVfQlVTV0lEVEhfNF9CWVRFUykgPSAz CmZmcyhETUFfU0xBVkVfQlVTV0lEVEhfOF9CWVRFUykgPSA0Cgo+IAo+PiArc3RhdGljIHN0cnVj dCB1ZG1hX2Rlc2MgKgo+PiArdWRtYV9wcmVwX3NsYXZlX3NnX3BrdChzdHJ1Y3QgdWRtYV9jaGFu ICp1Yywgc3RydWN0IHNjYXR0ZXJsaXN0ICpzZ2wsCj4+ICsJCSAgICAgICB1bnNpZ25lZCBpbnQg c2dsZW4sIGVudW0gZG1hX3RyYW5zZmVyX2RpcmVjdGlvbiBkaXIsCj4+ICsJCSAgICAgICB1bnNp Z25lZCBsb25nIHR4X2ZsYWdzLCB2b2lkICpjb250ZXh0KQo+PiArewo+PiArCXN0cnVjdCBzY2F0 dGVybGlzdCAqc2dlbnQ7Cj4+ICsJc3RydWN0IGNwcGk1X2hvc3RfZGVzY190ICpoX2Rlc2MgPSBO VUxMOwo+PiArCXN0cnVjdCB1ZG1hX2Rlc2MgKmQ7Cj4+ICsJdTMyIHJpbmdfaWQ7Cj4+ICsJdW5z aWduZWQgaW50IGk7Cj4+ICsKPj4gKwlkID0ga3phbGxvYyhzaXplb2YoKmQpICsgc2dsZW4gKiBz aXplb2YoZC0+aHdkZXNjWzBdKSwgR0ZQX0FUT01JQyk7Cj4gCj4gR0ZQX05PV0FJVCBoZXJlIGFu ZCBmZXcgb3RoZXIgcGxhY2VzCgpZZXMsIEkgaGF2ZSBmaXhlZCB0aGVtIHVwIGJ5IHRoaXMgdGlt ZS4KCj4gCj4+ICtzdGF0aWMgc3RydWN0IHVkbWFfZGVzYyAqCj4+ICt1ZG1hX3ByZXBfZG1hX2N5 Y2xpY19wa3Qoc3RydWN0IHVkbWFfY2hhbiAqdWMsIGRtYV9hZGRyX3QgYnVmX2FkZHIsCj4+ICsJ CQkgc2l6ZV90IGJ1Zl9sZW4sIHNpemVfdCBwZXJpb2RfbGVuLAo+PiArCQkJIGVudW0gZG1hX3Ry YW5zZmVyX2RpcmVjdGlvbiBkaXIsIHVuc2lnbmVkIGxvbmcgZmxhZ3MpCj4+ICt7Cj4+ICsJc3Ry dWN0IHVkbWFfZGVzYyAqZDsKPj4gKwl1MzIgcmluZ19pZDsKPj4gKwlpbnQgaTsKPj4gKwlpbnQg cGVyaW9kcyA9IGJ1Zl9sZW4gLyBwZXJpb2RfbGVuOwo+PiArCj4+ICsJaWYgKHBlcmlvZHMgPiAo SzNfVURNQV9ERUZBVUxUX1JJTkdfU0laRSAtIDEpKQo+PiArCQlyZXR1cm4gTlVMTDsKPj4gKwo+ PiArCWlmIChwZXJpb2RfbGVuID4gMHgzRkZGRkYpCj4gCj4gTWFnaWM/CgpJJ2xsIGFkZCBhIGRl ZmluZSB0byBjcHBpNS4gSXQgaXMgdGhlIHBhY2tldCBsZW5ndGggbGltaXQuCgo+IAo+PiArc3Rh dGljIGVudW0gZG1hX3N0YXR1cyB1ZG1hX3R4X3N0YXR1cyhzdHJ1Y3QgZG1hX2NoYW4gKmNoYW4s Cj4+ICsJCQkJICAgICAgZG1hX2Nvb2tpZV90IGNvb2tpZSwKPj4gKwkJCQkgICAgICBzdHJ1Y3Qg ZG1hX3R4X3N0YXRlICp0eHN0YXRlKQo+PiArewo+PiArCXN0cnVjdCB1ZG1hX2NoYW4gKnVjID0g dG9fdWRtYV9jaGFuKGNoYW4pOwo+PiArCWVudW0gZG1hX3N0YXR1cyByZXQ7Cj4+ICsJdW5zaWdu ZWQgbG9uZyBmbGFnczsKPj4gKwo+PiArCXNwaW5fbG9ja19pcnFzYXZlKCZ1Yy0+dmMubG9jaywg ZmxhZ3MpOwo+PiArCj4+ICsJcmV0ID0gZG1hX2Nvb2tpZV9zdGF0dXMoY2hhbiwgY29va2llLCB0 eHN0YXRlKTsKPj4gKwo+PiArCWlmICghdWRtYV9pc19jaGFuX3J1bm5pbmcodWMpKQo+PiArCQly ZXQgPSBETUFfQ09NUExFVEU7Cj4gCj4gRXZlbiBmb3IgcGF1c2VkLCBub3Qgc3RhcnRlZCBjaGFu bmVsPyBOb3Qgc3VyZSB3aGF0IHdpbGwgYmUgcmV0dXJuIG9uIHRob3NlIGNhc2VzCgpIcm0sIGlm IHRoZSBjaGFubmVsIGlzIG5vdCBzdGFydGVkIHlldCwgdGhlbiBJIHRoaW5rIGl0IHNob3VsZCBi ZSBzdGlsbApETUFfSU5fUFJPR1JFU1MsIHJpZ2h0PwpUaGUgdWRtYV9pc19jaGFuX3J1bm5pbmco KSBjYW4gYmUgZHJvcHBlZCBmcm9tIGhlcmUuCkkgZGlkIG1pc3NlZCB0aGUgRE1BX1BBVVNFRCBz dGF0ZS4KCi0JaWYgKCF1ZG1hX2lzX2NoYW5fcnVubmluZyh1YykpCi0JCXJldCA9IERNQV9DT01Q TEVURTsKKwlpZiAocmV0ID09IERNQV9JTl9QUk9HUkVTUyAmJiB1ZG1hX2lzX2NoYW5fcGF1c2Vk KHVjKSkKKwkJcmV0ID0gRE1BX1BBVVNFRDsKCgotIFDDqXRlcgoKVGV4YXMgSW5zdHJ1bWVudHMg RmlubGFuZCBPeSwgUG9ya2thbGFua2F0dSAyMiwgMDAxODAgSGVsc2lua2kuClktdHVubnVzL0J1 c2luZXNzIElEOiAwNjE1NTIxLTQuIEtvdGlwYWlra2EvRG9taWNpbGU6IEhlbHNpbmtpCgpfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2Vy bmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0 cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVs Cg==