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=-4.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C8B6C43381 for ; Fri, 15 Mar 2019 08:34:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5EB3C21872 for ; Fri, 15 Mar 2019 08:34:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728551AbfCOIee convert rfc822-to-8bit (ORCPT ); Fri, 15 Mar 2019 04:34:34 -0400 Received: from relay12.mail.gandi.net ([217.70.178.232]:42989 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727183AbfCOIee (ORCPT ); Fri, 15 Mar 2019 04:34:34 -0400 Received: from xps13 (aaubervilliers-681-1-80-102.w90-88.abo.wanadoo.fr [90.88.22.102]) (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 78E31200017; Fri, 15 Mar 2019 08:34:30 +0000 (UTC) Date: Fri, 15 Mar 2019 09:34:29 +0100 From: Miquel Raynal To: Masahiro Yamada Cc: Boris Brezillon , Richard Weinberger , Linux Kernel Mailing List , Marek Vasut , linux-mtd , Brian Norris , David Woodhouse Subject: Re: [PATCH v3 2/9] mtd: rawnand: denali: refactor syndrome layout handling for raw access Message-ID: <20190315093429.35137adb@xps13> In-Reply-To: References: <1552380290-19951-1-git-send-email-yamada.masahiro@socionext.com> <1552380290-19951-3-git-send-email-yamada.masahiro@socionext.com> <20190312112811.1af0bb00@xps13> <20190312115425.612bcdf2@xps13> <20190312141327.31c6af3f@xps13> 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 Masahiro, Masahiro Yamada wrote on Thu, 14 Mar 2019 17:24:41 +0900: > Hi Miquel, > > On Tue, Mar 12, 2019 at 10:13 PM Miquel Raynal > wrote: > > > > Hi Masahiro, > > > > Masahiro Yamada wrote on Tue, 12 Mar > > 2019 20:07:27 +0900: > > > > > Hi Miquel, > > > > > > > > > On Tue, Mar 12, 2019 at 7:54 PM Miquel Raynal wrote: > > > > > > > > Hi Masahiro, > > > > > > > > Masahiro Yamada wrote on Tue, 12 Mar > > > > 2019 19:51:21 +0900: > > > > > > > > > On Tue, Mar 12, 2019 at 7:28 PM Miquel Raynal wrote: > > > > > > > > > > > > Hi Masahiro, > > > > > > > > > > > > Masahiro Yamada wrote on Tue, 12 Mar > > > > > > 2019 17:44:43 +0900: > > > > > > > > > > > > > The Denali IP adopts the syndrome page layout (payload and ECC are > > > > > > > interleaved). The *_page_raw() and *_oob() callbacks are complicated > > > > > > > because they must hide the underlying layout used by the hardware, > > > > > > > and always return contiguous in-band and out-of-band data. > > > > > > > > > > > > > > Currently, similar code is duplicated to reorganize the data layout. > > > > > > > For example, denali_read_page_raw() and denali_write_page_raw() look > > > > > > > almost the same. > > > > > > > > > > > > > > The idea for refactoring is to split the code into two parts: > > > > > > > [1] conversion of page layout > > > > > > > [2] what to do at every ECC chunk boundary > > > > > > > > > > > > > > For [1], I wrote denali_raw_payload_op() and denali_raw_oob_op(). > > > > > > > They manipulate data for the Denali controller's specific page layout > > > > > > > of in-band, out-of-band, respectively. > > > > > > > > > > > > > > The difference between write and read is just the operation at > > > > > > > ECC chunk boundaries. For example, denali_read_oob() calls > > > > > > > nand_change_read_column_op(), whereas denali_write_oob() calls > > > > > > > nand_change_write_column_op(). So, I implemented [2] as a callback > > > > > > > passed into [1]. > > > > > > > > > > > > > > Signed-off-by: Masahiro Yamada > > > > > > > --- > > > > > > > > > > > > > > > > > > > [...] > > > > > > > > > > > > > static int denali_read_page_raw(struct nand_chip *chip, uint8_t *buf, > > > > > > > int oob_required, int page) > > > > > > > { > > > > > > > + struct denali_nand_info *denali = to_denali(chip); > > > > > > > struct mtd_info *mtd = nand_to_mtd(chip); > > > > > > > - struct denali_nand_info *denali = mtd_to_denali(mtd); > > > > > > > - int writesize = mtd->writesize; > > > > > > > - int oobsize = mtd->oobsize; > > > > > > > - int ecc_steps = chip->ecc.steps; > > > > > > > - int ecc_size = chip->ecc.size; > > > > > > > - int ecc_bytes = chip->ecc.bytes; > > > > > > > void *tmp_buf = denali->buf; > > > > > > > - int oob_skip = denali->oob_skip_bytes; > > > > > > > - size_t size = writesize + oobsize; > > > > > > > - int ret, i, pos, len; > > > > > > > + size_t size = mtd->writesize + mtd->oobsize; > > > > > > > + int ret; > > > > > > > + > > > > > > > + if (!buf) > > > > > > > + return -EINVAL; > > > > > > > > > > > > > > ret = denali_data_xfer(chip, tmp_buf, size, page, 1, 0); > > > > > > > if (ret) > > > > > > > return ret; > > > > > > > > > > > > > > - /* Arrange the buffer for syndrome payload/ecc layout */ > > > > > > > - if (buf) { > > > > > > > - for (i = 0; i < ecc_steps; i++) { > > > > > > > - pos = i * (ecc_size + ecc_bytes); > > > > > > > - len = ecc_size; > > > > > > > - > > > > > > > - if (pos >= writesize) > > > > > > > - pos += oob_skip; > > > > > > > - else if (pos + len > writesize) > > > > > > > - len = writesize - pos; > > > > > > > - > > > > > > > - memcpy(buf, tmp_buf + pos, len); > > > > > > > - buf += len; > > > > > > > - if (len < ecc_size) { > > > > > > > - len = ecc_size - len; > > > > > > > - memcpy(buf, tmp_buf + writesize + oob_skip, > > > > > > > - len); > > > > > > > - buf += len; > > > > > > > - } > > > > > > > - } > > > > > > > - } > > > > > > > + ret = denali_raw_payload_op(chip, buf, denali_memcpy_in, tmp_buf); > > > > > > > > > > > > Honestly, I still don't like passing denali_memcpy_in/out as parameter. > > > > > > > > > > > > Besides that, once you'll have added helpers to avoid abusing the > > > > > > ternary operator in 4/9, the rest looks fine by me. > > > > > > > > > > > > > > > > > > > > > Do you have any suggestion? > > > > > > > > Maybe register these two helpers at probe as controller specific hooks, > > > > then just pass an in/out boolean to the function? > > > > > > > > > > Sorry, I do not understand. > > > > > > Are you suggesting to do like follows in probe ? > > > > > > denali->change_column_read_raw = denali_memcpy_in; > > > denali->change_column_write_raw = denali_memcpy_out; > > > denali->change_column_read_oob = denali_change_read_column_op; > > > denali->change_column_write_oob = denali_change_write_column_op; > > > > > > > > > All the 4 hooks are always needed > > > regardless of any probed features. > > > > > > > > > The result is just textual replacement > > > denali_* with denali->*. > > > > > > What's the point of copying fixed function addresses > > > to denali structure? > > > > > > > > > > What I don't like is the function pointer as a function parameter. > > This is a usual way to handle callback. > > > You > > can use the functions defined statically if you prefer as long as the > > parameter is just a boolean for instance? > > > > I still do not understand your concern, > but if you ban the use of function pointer, > the following is the best I can do > since there are 4 hooks depending on the > combination of oob/raw, write/read. > > > > if (oob) { > if (write) > return nand_change_write_column_op(chip, offset, buf, > len, false); > else > return nand_change_read_column_op(chip, offset, buf, > len, false); > } > > if (write) > memcpy(denali->buf + offset, buf, len); > else > memcpy(buf, denali->buf + offset, len); > > return 0; No, I meant passing a boolean to denali_raw_payload_op() instead of a function pointer. Then from denali_raw_payload_op(), intead of doing ret = cb(); if (ret) ... doing: if (read) ret = denali_memcpy_in() else ret = denali_memcpy_out() if (ret) ... But nevermind, if this is bothering you too much let's keep the current form, it's fine. > > > BTW, when are .read_page_raw / .write_page_raw used? I'm not sure what is the question here but these hooks are important and allow to test the driver. nandbiterrs use them (although we do not care about the performance in these hooks). > > Currently, I use "whole page access && memcpy" for better performance. > > If those hooks are rarely used, I use > nand_change_write_column_op / nand_change_read_column_op, > which will reduce the if-conditional. Yes you can. We do not care about performance in raw accessors. 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=-4.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAD72C43381 for ; Fri, 15 Mar 2019 08:34:42 +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 7337E218AC for ; Fri, 15 Mar 2019 08:34:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="bKo3uKdJ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7337E218AC 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=iSIe/L3/q6cgX1IL5xp6BmNBqyNOCeiW4/YTiI+Ayiw=; b=bKo3uKdJJez9/G /bmyTLXDpnQIgCNEEnCyC5m4DUhtMSA6wDi2d65WPnQ7dnz5GVLtxz20vNeD+Jky5D/xlpWmfa3kH m4H6MWIkKEzxSBzw4gcAnNrXFOuBEqAvmDca5/Tlmnu13qmXO35VXD/EOKWkqiQr42s0M3puT/e4F SMfbto95dEg9YYGeLJCF9LQRRdNjpu7DKs+4govFrodqO++T3tw3oAjA69bxkNV2gDPNvKwr+yrKl B4ohO3CKW8glqgNVcd4moSL7kTqtsUqJmrq2oz66RSlDR88xCBUgGXqvw17kcqQtc0s8HkeC8gvKz MoJM6dJOqqm2lltuekrw==; 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 1h4iIa-0002C3-Js; Fri, 15 Mar 2019 08:34:40 +0000 Received: from relay12.mail.gandi.net ([217.70.178.232]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1h4iIX-0002BD-Ma for linux-mtd@lists.infradead.org; Fri, 15 Mar 2019 08:34:39 +0000 Received: from xps13 (aaubervilliers-681-1-80-102.w90-88.abo.wanadoo.fr [90.88.22.102]) (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 78E31200017; Fri, 15 Mar 2019 08:34:30 +0000 (UTC) Date: Fri, 15 Mar 2019 09:34:29 +0100 From: Miquel Raynal To: Masahiro Yamada Subject: Re: [PATCH v3 2/9] mtd: rawnand: denali: refactor syndrome layout handling for raw access Message-ID: <20190315093429.35137adb@xps13> In-Reply-To: References: <1552380290-19951-1-git-send-email-yamada.masahiro@socionext.com> <1552380290-19951-3-git-send-email-yamada.masahiro@socionext.com> <20190312112811.1af0bb00@xps13> <20190312115425.612bcdf2@xps13> <20190312141327.31c6af3f@xps13> 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-20190315_013438_042508_51973E95 X-CRM114-Status: GOOD ( 34.41 ) 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: Boris Brezillon , Richard Weinberger , Linux Kernel Mailing List , Marek Vasut , linux-mtd , Brian Norris , David Woodhouse 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 SGkgTWFzYWhpcm8sCgpNYXNhaGlybyBZYW1hZGEgPHlhbWFkYS5tYXNhaGlyb0Bzb2Npb25leHQu Y29tPiB3cm90ZSBvbiBUaHUsIDE0IE1hcgoyMDE5IDE3OjI0OjQxICswOTAwOgoKPiBIaSBNaXF1 ZWwsCj4gCj4gT24gVHVlLCBNYXIgMTIsIDIwMTkgYXQgMTA6MTMgUE0gTWlxdWVsIFJheW5hbAo+ IDxtaXF1ZWwucmF5bmFsQGJvb3RsaW4uY29tPiB3cm90ZToKPiA+Cj4gPiBIaSBNYXNhaGlybywK PiA+Cj4gPiBNYXNhaGlybyBZYW1hZGEgPHlhbWFkYS5tYXNhaGlyb0Bzb2Npb25leHQuY29tPiB3 cm90ZSBvbiBUdWUsIDEyIE1hcgo+ID4gMjAxOSAyMDowNzoyNyArMDkwMDoKPiA+ICAKPiA+ID4g SGkgTWlxdWVsLAo+ID4gPgo+ID4gPgo+ID4gPiBPbiBUdWUsIE1hciAxMiwgMjAxOSBhdCA3OjU0 IFBNIE1pcXVlbCBSYXluYWwgPG1pcXVlbC5yYXluYWxAYm9vdGxpbi5jb20+IHdyb3RlOiAgCj4g PiA+ID4KPiA+ID4gPiBIaSBNYXNhaGlybywKPiA+ID4gPgo+ID4gPiA+IE1hc2FoaXJvIFlhbWFk YSA8eWFtYWRhLm1hc2FoaXJvQHNvY2lvbmV4dC5jb20+IHdyb3RlIG9uIFR1ZSwgMTIgTWFyCj4g PiA+ID4gMjAxOSAxOTo1MToyMSArMDkwMDoKPiA+ID4gPiAgCj4gPiA+ID4gPiBPbiBUdWUsIE1h ciAxMiwgMjAxOSBhdCA3OjI4IFBNIE1pcXVlbCBSYXluYWwgPG1pcXVlbC5yYXluYWxAYm9vdGxp bi5jb20+IHdyb3RlOiAgCj4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+IEhpIE1hc2FoaXJvLAo+ID4g PiA+ID4gPgo+ID4gPiA+ID4gPiBNYXNhaGlybyBZYW1hZGEgPHlhbWFkYS5tYXNhaGlyb0Bzb2Np b25leHQuY29tPiB3cm90ZSBvbiBUdWUsIDEyIE1hcgo+ID4gPiA+ID4gPiAyMDE5IDE3OjQ0OjQz ICswOTAwOgo+ID4gPiA+ID4gPiAgCj4gPiA+ID4gPiA+ID4gVGhlIERlbmFsaSBJUCBhZG9wdHMg dGhlIHN5bmRyb21lIHBhZ2UgbGF5b3V0IChwYXlsb2FkIGFuZCBFQ0MgYXJlCj4gPiA+ID4gPiA+ ID4gaW50ZXJsZWF2ZWQpLiBUaGUgKl9wYWdlX3JhdygpIGFuZCAqX29vYigpIGNhbGxiYWNrcyBh cmUgY29tcGxpY2F0ZWQKPiA+ID4gPiA+ID4gPiBiZWNhdXNlIHRoZXkgbXVzdCBoaWRlIHRoZSB1 bmRlcmx5aW5nIGxheW91dCB1c2VkIGJ5IHRoZSBoYXJkd2FyZSwKPiA+ID4gPiA+ID4gPiBhbmQg YWx3YXlzIHJldHVybiBjb250aWd1b3VzIGluLWJhbmQgYW5kIG91dC1vZi1iYW5kIGRhdGEuCj4g PiA+ID4gPiA+ID4KPiA+ID4gPiA+ID4gPiBDdXJyZW50bHksIHNpbWlsYXIgY29kZSBpcyBkdXBs aWNhdGVkIHRvIHJlb3JnYW5pemUgdGhlIGRhdGEgbGF5b3V0Lgo+ID4gPiA+ID4gPiA+IEZvciBl eGFtcGxlLCBkZW5hbGlfcmVhZF9wYWdlX3JhdygpIGFuZCBkZW5hbGlfd3JpdGVfcGFnZV9yYXco KSBsb29rCj4gPiA+ID4gPiA+ID4gYWxtb3N0IHRoZSBzYW1lLgo+ID4gPiA+ID4gPiA+Cj4gPiA+ ID4gPiA+ID4gVGhlIGlkZWEgZm9yIHJlZmFjdG9yaW5nIGlzIHRvIHNwbGl0IHRoZSBjb2RlIGlu dG8gdHdvIHBhcnRzOgo+ID4gPiA+ID4gPiA+ICAgWzFdIGNvbnZlcnNpb24gb2YgcGFnZSBsYXlv dXQKPiA+ID4gPiA+ID4gPiAgIFsyXSB3aGF0IHRvIGRvIGF0IGV2ZXJ5IEVDQyBjaHVuayBib3Vu ZGFyeQo+ID4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+ID4gRm9yIFsxXSwgSSB3cm90ZSBkZW5hbGlf cmF3X3BheWxvYWRfb3AoKSBhbmQgZGVuYWxpX3Jhd19vb2Jfb3AoKS4KPiA+ID4gPiA+ID4gPiBU aGV5IG1hbmlwdWxhdGUgZGF0YSBmb3IgdGhlIERlbmFsaSBjb250cm9sbGVyJ3Mgc3BlY2lmaWMg cGFnZSBsYXlvdXQKPiA+ID4gPiA+ID4gPiBvZiBpbi1iYW5kLCBvdXQtb2YtYmFuZCwgcmVzcGVj dGl2ZWx5Lgo+ID4gPiA+ID4gPiA+Cj4gPiA+ID4gPiA+ID4gVGhlIGRpZmZlcmVuY2UgYmV0d2Vl biB3cml0ZSBhbmQgcmVhZCBpcyBqdXN0IHRoZSBvcGVyYXRpb24gYXQKPiA+ID4gPiA+ID4gPiBF Q0MgY2h1bmsgYm91bmRhcmllcy4gRm9yIGV4YW1wbGUsIGRlbmFsaV9yZWFkX29vYigpIGNhbGxz Cj4gPiA+ID4gPiA+ID4gbmFuZF9jaGFuZ2VfcmVhZF9jb2x1bW5fb3AoKSwgd2hlcmVhcyBkZW5h bGlfd3JpdGVfb29iKCkgY2FsbHMKPiA+ID4gPiA+ID4gPiBuYW5kX2NoYW5nZV93cml0ZV9jb2x1 bW5fb3AoKS4gU28sIEkgaW1wbGVtZW50ZWQgWzJdIGFzIGEgY2FsbGJhY2sKPiA+ID4gPiA+ID4g PiBwYXNzZWQgaW50byBbMV0uCj4gPiA+ID4gPiA+ID4KPiA+ID4gPiA+ID4gPiBTaWduZWQtb2Zm LWJ5OiBNYXNhaGlybyBZYW1hZGEgPHlhbWFkYS5tYXNhaGlyb0Bzb2Npb25leHQuY29tPgo+ID4g PiA+ID4gPiA+IC0tLQo+ID4gPiA+ID4gPiA+ICAKPiA+ID4gPiA+ID4KPiA+ID4gPiA+ID4gWy4u Ll0KPiA+ID4gPiA+ID4gIAo+ID4gPiA+ID4gPiA+ICBzdGF0aWMgaW50IGRlbmFsaV9yZWFkX3Bh Z2VfcmF3KHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsIHVpbnQ4X3QgKmJ1ZiwKPiA+ID4gPiA+ID4g PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb29iX3JlcXVpcmVkLCBpbnQgcGFn ZSkKPiA+ID4gPiA+ID4gPiAgewo+ID4gPiA+ID4gPiA+ICsgICAgIHN0cnVjdCBkZW5hbGlfbmFu ZF9pbmZvICpkZW5hbGkgPSB0b19kZW5hbGkoY2hpcCk7Cj4gPiA+ID4gPiA+ID4gICAgICAgc3Ry dWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZChjaGlwKTsKPiA+ID4gPiA+ID4gPiAtICAg ICBzdHJ1Y3QgZGVuYWxpX25hbmRfaW5mbyAqZGVuYWxpID0gbXRkX3RvX2RlbmFsaShtdGQpOwo+ ID4gPiA+ID4gPiA+IC0gICAgIGludCB3cml0ZXNpemUgPSBtdGQtPndyaXRlc2l6ZTsKPiA+ID4g PiA+ID4gPiAtICAgICBpbnQgb29ic2l6ZSA9IG10ZC0+b29ic2l6ZTsKPiA+ID4gPiA+ID4gPiAt ICAgICBpbnQgZWNjX3N0ZXBzID0gY2hpcC0+ZWNjLnN0ZXBzOwo+ID4gPiA+ID4gPiA+IC0gICAg IGludCBlY2Nfc2l6ZSA9IGNoaXAtPmVjYy5zaXplOwo+ID4gPiA+ID4gPiA+IC0gICAgIGludCBl Y2NfYnl0ZXMgPSBjaGlwLT5lY2MuYnl0ZXM7Cj4gPiA+ID4gPiA+ID4gICAgICAgdm9pZCAqdG1w X2J1ZiA9IGRlbmFsaS0+YnVmOwo+ID4gPiA+ID4gPiA+IC0gICAgIGludCBvb2Jfc2tpcCA9IGRl bmFsaS0+b29iX3NraXBfYnl0ZXM7Cj4gPiA+ID4gPiA+ID4gLSAgICAgc2l6ZV90IHNpemUgPSB3 cml0ZXNpemUgKyBvb2JzaXplOwo+ID4gPiA+ID4gPiA+IC0gICAgIGludCByZXQsIGksIHBvcywg bGVuOwo+ID4gPiA+ID4gPiA+ICsgICAgIHNpemVfdCBzaXplID0gbXRkLT53cml0ZXNpemUgKyBt dGQtPm9vYnNpemU7Cj4gPiA+ID4gPiA+ID4gKyAgICAgaW50IHJldDsKPiA+ID4gPiA+ID4gPiAr Cj4gPiA+ID4gPiA+ID4gKyAgICAgaWYgKCFidWYpCj4gPiA+ID4gPiA+ID4gKyAgICAgICAgICAg ICByZXR1cm4gLUVJTlZBTDsKPiA+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPiA+ICAgICAgIHJldCA9 IGRlbmFsaV9kYXRhX3hmZXIoY2hpcCwgdG1wX2J1Ziwgc2l6ZSwgcGFnZSwgMSwgMCk7Cj4gPiA+ ID4gPiA+ID4gICAgICAgaWYgKHJldCkKPiA+ID4gPiA+ID4gPiAgICAgICAgICAgICAgIHJldHVy biByZXQ7Cj4gPiA+ID4gPiA+ID4KPiA+ID4gPiA+ID4gPiAtICAgICAvKiBBcnJhbmdlIHRoZSBi dWZmZXIgZm9yIHN5bmRyb21lIHBheWxvYWQvZWNjIGxheW91dCAqLwo+ID4gPiA+ID4gPiA+IC0g ICAgIGlmIChidWYpIHsKPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkg PCBlY2Nfc3RlcHM7IGkrKykgewo+ID4gPiA+ID4gPiA+IC0gICAgICAgICAgICAgICAgICAgICBw b3MgPSBpICogKGVjY19zaXplICsgZWNjX2J5dGVzKTsKPiA+ID4gPiA+ID4gPiAtICAgICAgICAg ICAgICAgICAgICAgbGVuID0gZWNjX3NpemU7Cj4gPiA+ID4gPiA+ID4gLQo+ID4gPiA+ID4gPiA+ IC0gICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IHdyaXRlc2l6ZSkKPiA+ID4gPiA+ID4g PiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MgKz0gb29iX3NraXA7Cj4gPiA+ID4g PiA+ID4gLSAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBvcyArIGxlbiA+IHdyaXRlc2l6 ZSkKPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSB3cml0 ZXNpemUgLSBwb3M7Cj4gPiA+ID4gPiA+ID4gLQo+ID4gPiA+ID4gPiA+IC0gICAgICAgICAgICAg ICAgICAgICBtZW1jcHkoYnVmLCB0bXBfYnVmICsgcG9zLCBsZW4pOwo+ID4gPiA+ID4gPiA+IC0g ICAgICAgICAgICAgICAgICAgICBidWYgKz0gbGVuOwo+ID4gPiA+ID4gPiA+IC0gICAgICAgICAg ICAgICAgICAgICBpZiAobGVuIDwgZWNjX3NpemUpIHsKPiA+ID4gPiA+ID4gPiAtICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBsZW4gPSBlY2Nfc2l6ZSAtIGxlbjsKPiA+ID4gPiA+ID4gPiAt ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoYnVmLCB0bXBfYnVmICsgd3JpdGVz aXplICsgb29iX3NraXAsCj4gPiA+ID4gPiA+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGxlbik7Cj4gPiA+ID4gPiA+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgYnVmICs9IGxlbjsKPiA+ID4gPiA+ID4gPiAtICAgICAgICAgICAgICAgICAgICAgfQo+ID4g PiA+ID4gPiA+IC0gICAgICAgICAgICAgfQo+ID4gPiA+ID4gPiA+IC0gICAgIH0KPiA+ID4gPiA+ ID4gPiArICAgICByZXQgPSBkZW5hbGlfcmF3X3BheWxvYWRfb3AoY2hpcCwgYnVmLCBkZW5hbGlf bWVtY3B5X2luLCB0bXBfYnVmKTsgIAo+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPiBIb25lc3RseSwg SSBzdGlsbCBkb24ndCBsaWtlIHBhc3NpbmcgZGVuYWxpX21lbWNweV9pbi9vdXQgYXMgcGFyYW1l dGVyLgo+ID4gPiA+ID4gPgo+ID4gPiA+ID4gPiBCZXNpZGVzIHRoYXQsIG9uY2UgeW91J2xsIGhh dmUgYWRkZWQgaGVscGVycyB0byBhdm9pZCBhYnVzaW5nIHRoZQo+ID4gPiA+ID4gPiB0ZXJuYXJ5 IG9wZXJhdG9yIGluIDQvOSwgdGhlIHJlc3QgbG9va3MgZmluZSBieSBtZS4KPiA+ID4gPiA+ID4g IAo+ID4gPiA+ID4KPiA+ID4gPiA+Cj4gPiA+ID4gPiBEbyB5b3UgaGF2ZSBhbnkgc3VnZ2VzdGlv bj8gIAo+ID4gPiA+Cj4gPiA+ID4gTWF5YmUgcmVnaXN0ZXIgdGhlc2UgdHdvIGhlbHBlcnMgYXQg cHJvYmUgYXMgY29udHJvbGxlciBzcGVjaWZpYyBob29rcywKPiA+ID4gPiB0aGVuIGp1c3QgcGFz cyBhbiBpbi9vdXQgYm9vbGVhbiB0byB0aGUgZnVuY3Rpb24/Cj4gPiA+ID4gIAo+ID4gPgo+ID4g PiBTb3JyeSwgSSBkbyBub3QgdW5kZXJzdGFuZC4KPiA+ID4KPiA+ID4gQXJlIHlvdSBzdWdnZXN0 aW5nIHRvIGRvIGxpa2UgZm9sbG93cyBpbiBwcm9iZSA/Cj4gPiA+Cj4gPiA+IGRlbmFsaS0+Y2hh bmdlX2NvbHVtbl9yZWFkX3JhdyA9IGRlbmFsaV9tZW1jcHlfaW47Cj4gPiA+IGRlbmFsaS0+Y2hh bmdlX2NvbHVtbl93cml0ZV9yYXcgPSBkZW5hbGlfbWVtY3B5X291dDsKPiA+ID4gZGVuYWxpLT5j aGFuZ2VfY29sdW1uX3JlYWRfb29iID0gZGVuYWxpX2NoYW5nZV9yZWFkX2NvbHVtbl9vcDsKPiA+ ID4gZGVuYWxpLT5jaGFuZ2VfY29sdW1uX3dyaXRlX29vYiA9IGRlbmFsaV9jaGFuZ2Vfd3JpdGVf Y29sdW1uX29wOwo+ID4gPgo+ID4gPgo+ID4gPiBBbGwgdGhlIDQgaG9va3MgYXJlIGFsd2F5cyBu ZWVkZWQKPiA+ID4gcmVnYXJkbGVzcyBvZiBhbnkgcHJvYmVkIGZlYXR1cmVzLgo+ID4gPgo+ID4g Pgo+ID4gPiBUaGUgcmVzdWx0IGlzIGp1c3QgdGV4dHVhbCByZXBsYWNlbWVudAo+ID4gPiBkZW5h bGlfKiB3aXRoIGRlbmFsaS0+Ki4KPiA+ID4KPiA+ID4gV2hhdCdzIHRoZSBwb2ludCBvZiBjb3B5 aW5nIGZpeGVkIGZ1bmN0aW9uIGFkZHJlc3Nlcwo+ID4gPiB0byBkZW5hbGkgc3RydWN0dXJlPwo+ ID4gPgo+ID4gPiAgCj4gPgo+ID4gV2hhdCBJIGRvbid0IGxpa2UgaXMgdGhlIGZ1bmN0aW9uIHBv aW50ZXIgYXMgYSBmdW5jdGlvbiBwYXJhbWV0ZXIuICAKPiAKPiBUaGlzIGlzIGEgdXN1YWwgd2F5 IHRvIGhhbmRsZSBjYWxsYmFjay4KPiAKPiA+IFlvdQo+ID4gY2FuIHVzZSB0aGUgZnVuY3Rpb25z IGRlZmluZWQgc3RhdGljYWxseSBpZiB5b3UgcHJlZmVyIGFzIGxvbmcgYXMgdGhlCj4gPiBwYXJh bWV0ZXIgaXMganVzdCBhIGJvb2xlYW4gZm9yIGluc3RhbmNlPyAgCj4gCj4gCj4gCj4gSSBzdGls bCBkbyBub3QgdW5kZXJzdGFuZCB5b3VyIGNvbmNlcm4sCj4gYnV0IGlmIHlvdSBiYW4gdGhlIHVz ZSBvZiBmdW5jdGlvbiBwb2ludGVyLAo+IHRoZSBmb2xsb3dpbmcgaXMgdGhlIGJlc3QgSSBjYW4g ZG8KPiBzaW5jZSB0aGVyZSBhcmUgNCBob29rcyBkZXBlbmRpbmcgb24gdGhlCj4gY29tYmluYXRp b24gb2Ygb29iL3Jhdywgd3JpdGUvcmVhZC4KPiAKPiAKPiAKPiBpZiAob29iKSB7Cj4gICAgICAg ICBpZiAod3JpdGUpCj4gICAgICAgICAgICAgICAgIHJldHVybiBuYW5kX2NoYW5nZV93cml0ZV9j b2x1bW5fb3AoY2hpcCwgb2Zmc2V0LCBidWYsCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgbGVuLCBmYWxzZSk7Cj4gICAgICAgICBlbHNlCj4gICAg ICAgICAgICAgICAgIHJldHVybiBuYW5kX2NoYW5nZV9yZWFkX2NvbHVtbl9vcChjaGlwLCBvZmZz ZXQsIGJ1ZiwKPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIGxlbiwgZmFsc2UpOwo+IH0KPiAKPiBpZiAod3JpdGUpCj4gICAgICAgICBtZW1jcHkoZGVu YWxpLT5idWYgKyBvZmZzZXQsIGJ1ZiwgbGVuKTsKPiBlbHNlCj4gICAgICAgICBtZW1jcHkoYnVm LCBkZW5hbGktPmJ1ZiArIG9mZnNldCwgbGVuKTsKPiAKPiByZXR1cm4gMDsKCk5vLCBJIG1lYW50 IHBhc3NpbmcgYSBib29sZWFuIHRvIGRlbmFsaV9yYXdfcGF5bG9hZF9vcCgpIGluc3RlYWQgb2Yg YQpmdW5jdGlvbiBwb2ludGVyLiBUaGVuIGZyb20gZGVuYWxpX3Jhd19wYXlsb2FkX29wKCksIGlu dGVhZCBvZiBkb2luZwoKcmV0ID0gY2IoKTsKaWYgKHJldCkKICAgICAgICAuLi4KCmRvaW5nOgoK aWYgKHJlYWQpCiAgICAgICAgcmV0ID0gZGVuYWxpX21lbWNweV9pbigpCmVsc2UKICAgICAgICBy ZXQgPSBkZW5hbGlfbWVtY3B5X291dCgpCgppZiAocmV0KQogICAgICAgIC4uLgoKQnV0IG5ldmVy bWluZCwgaWYgdGhpcyBpcyBib3RoZXJpbmcgeW91IHRvbyBtdWNoIGxldCdzIGtlZXAgdGhlIGN1 cnJlbnQKZm9ybSwgaXQncyBmaW5lLgoKPiAKPiAKPiBCVFcsIHdoZW4gYXJlIC5yZWFkX3BhZ2Vf cmF3IC8gLndyaXRlX3BhZ2VfcmF3IHVzZWQ/CgpJJ20gbm90IHN1cmUgd2hhdCBpcyB0aGUgcXVl c3Rpb24gaGVyZSBidXQgdGhlc2UgaG9va3MgYXJlIGltcG9ydGFudAphbmQgYWxsb3cgdG8gdGVz dCB0aGUgZHJpdmVyLiBuYW5kYml0ZXJycyB1c2UgdGhlbSAoYWx0aG91Z2ggd2UgZG8Kbm90IGNh cmUgYWJvdXQgdGhlIHBlcmZvcm1hbmNlIGluIHRoZXNlIGhvb2tzKS4KCj4gCj4gQ3VycmVudGx5 LCBJIHVzZSAid2hvbGUgcGFnZSBhY2Nlc3MgJiYgbWVtY3B5IiBmb3IgYmV0dGVyIHBlcmZvcm1h bmNlLgo+IAo+IElmIHRob3NlIGhvb2tzIGFyZSByYXJlbHkgdXNlZCwgSSB1c2UKPiBuYW5kX2No YW5nZV93cml0ZV9jb2x1bW5fb3AgLyBuYW5kX2NoYW5nZV9yZWFkX2NvbHVtbl9vcCwKPiB3aGlj aCB3aWxsIHJlZHVjZSB0aGUgaWYtY29uZGl0aW9uYWwuCgpZZXMgeW91IGNhbi4gV2UgZG8gbm90 IGNhcmUgYWJvdXQgcGVyZm9ybWFuY2UgaW4gcmF3IGFjY2Vzc29ycy4KClRoYW5rcywKTWlxdcOo bAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f CkxpbnV4IE1URCBkaXNjdXNzaW9uIG1haWxpbmcgbGlzdApodHRwOi8vbGlzdHMuaW5mcmFkZWFk Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LW10ZC8K