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 4FFB0C04A6B for ; Sun, 12 May 2019 12:25:04 +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 1CFD22146F for ; Sun, 12 May 2019 12:25:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="KkwhMkYC" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1CFD22146F 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=mvij2lAuvVXbnKn8L5ROcpdRhk/c24clu9mU8moMlts=; b=KkwhMkYCgeeEwN DYvjaWSljIy6v0E8f3UGvjk34pMnVQwwUBYgcDwdvCuCqwCV/R+O8u4n0h4oMPDICvR2DBI1SJ0lE bLQWAaTfTn3GeOtk4CXetNM0AJIDJaVWvljewfkUaXe9GDc/F6JO/sqbbvZ9xAVXnDPO644z1oYMA aXk8uIVFqusw857L0kofnshIfrhHLP9flnpiJwSNVYpIhduCGxILNebbj/bdewpzQnw2ljMdq8qGO Gs2xnQVrx1SXHWNFMT/70Q4cHKqj+TnVKytjYbhBM9x1phr8lqymVO4ez+zc6T1GaN8sSNohRdvc7 KxlRi7ptYf4CQZiGMT8g==; 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 1hPnXI-0007jw-Eh; Sun, 12 May 2019 12:25:00 +0000 Received: from relay5-d.mail.gandi.net ([217.70.183.197]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hPnXA-0007jL-Rf for linux-mtd@lists.infradead.org; Sun, 12 May 2019 12:24:55 +0000 X-Originating-IP: 109.190.253.16 Received: from xps13 (unknown [109.190.253.16]) (Authenticated sender: miquel.raynal@bootlin.com) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id F2C131C0004; Sun, 12 May 2019 12:24:38 +0000 (UTC) Date: Sun, 12 May 2019 14:24:26 +0200 From: Miquel Raynal To: Piotr Sroka Subject: Re: [PATCH v2 1/2] mtd: nand: Add Cadence NAND controller driver Message-ID: <20190512142426.11453a6c@xps13> In-Reply-To: <20190321093356.GA19577@global.cadence.com> References: <20190219161406.4340-1-piotrs@cadence.com> <20190219161823.22466-1-piotrs@cadence.com> <20190305190954.6c38d681@xps13> <20190321093356.GA19577@global.cadence.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.1 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190512_052453_228832_5D8388B1 X-CRM114-Status: GOOD ( 41.39 ) 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: Arnd Bergmann , Boris Brezillon , Marcel Ziswiler , Richard Weinberger , linux-kernel@vger.kernel.org, Stefan Agner , Marek Vasut , Paul Burton , Geert Uytterhoeven , linux-mtd@lists.infradead.org, Dmitry Osipenko , 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 SGkgUGlvdHIsCgpTb3JyeSBmb3IgZGUgZGVsYXkuCgpQaW90ciBTcm9rYSA8cGlvdHJzQGNhZGVu Y2UuY29tPiB3cm90ZSBvbiBUaHUsIDIxIE1hciAyMDE5IDA5OjMzOjU4CiswMDAwOgoKPiBUaGUg MDMvMDUvMjAxOSAxOTowOSwgTWlxdWVsIFJheW5hbCB3cm90ZToKPiA+RVhURVJOQUwgTUFJTAo+ ID4KPiA+Cj4gPkhpIFBpb3RyLAo+ID4KPiA+UGlvdHIgU3Jva2EgPHBpb3Ryc0BjYWRlbmNlLmNv bT4gd3JvdGUgb24gVHVlLCAxOSBGZWIgMjAxOSAxNjoxODoyMwo+ID4rMDAwMDoKPiA+ICAKPiA+ PiBUaGlzIHBhdGNoIGFkZHMgZHJpdmVyIGZvciBDYWRlbmNlIEhQTkZDIE5BTkQgY29udHJvbGxl ci4KPiA+Pgo+ID4+IFNpZ25lZC1vZmYtYnk6IFBpb3RyIFNyb2thIDxwaW90cnNAY2FkZW5jZS5j b20+Cj4gPj4gLS0tCj4gPj4gQ2hhbmdlcyBmb3IgdjI6Cj4gPj4gLSBjcmVhdGUgb25lIHVuaXZl cnNhbCB3YWl0IGZ1bmN0aW9uIGZvciBhbGwgZXZlbnRzIGluc3RlYWQgb2Ygb25lCj4gPj4gICBm dW5jdGlvbiBwZXIgZXZlbnQuCj4gPj4gLSBzcGxpdCBvbmUgYmlnIGZ1bmN0aW9uIGV4ZWN1dGlu ZyBuYW5kIG9wZXJhdGlvbnMgdG8gc2VwYXJhdGUKPiA+PiAgIGZ1bmN0aW9ucyBvbmUgcGVyIGVh Y2ggdHlwZSBvZiBvcGVyYXRpb24uCj4gPj4gLSBhZGQgZXJhc2UgYXRvbWljIG9wZXJhdGlvbiB0 byBuYW5kIG9wZXJhdGlvbiBwYXJzZXIKPiA+PiAtIHJlbW92ZSB1bm5lY2Vzc2FyeSBpbmNsdWRl cy4KPiA+PiAtIHJlbW92ZSB1bnVzZWQgcmVnaXN0ZXIgZGVmaW5lcwo+ID4+IC0gYWRkIHN1cHBv cnQgZm9yIG11bHRpcGxlIG5hbmQgY2hpcHMKPiA+PiAtIHJlbW92ZSBhbGwgY29kZSB1c2luZyBs ZWdhY3kgZnVuY3Rpb25zCj4gPj4gLSByZW1vdmUgY2hpcCBkZXBlbmRlbnRzIHBhcmFtZXRlcnMg ZnJvbSBkdHMgYmluZGluZ3MsIHRoZXkgd2VyZQo+ID4+ICAgYXR0YWNoZWQgdG8gdGhlIFNvQyBz cGVjaWZpYyBjb21wYXRpYmxlIGF0IHRoZSBkcml2ZXIgbGV2ZWwKPiA+PiAtIHNpbXBsaWZ5IGlu dGVycnVwdCBoYW5kbGluZwo+ID4+IC0gc2ltcGxpZnkgdGltaW5nIGNhbGN1bGF0aW9ucwo+ID4+ IC0gZml4IGNhbGN1bGF0aW9uIG9mIG1heGltdW0gc3VwcG9ydGVkIGNzIHNpZ25hbHMKPiA+PiAt IHNpbXBsaWZ5IGVjYyBzaXplIGNhbGN1bGF0aW9uCj4gPj4gLSByZW1vdmUgaGVhZGVyIGZpbGUg YW5kIHB1dCB3aG9sZSBjb2RlIHRvIG9uZSBjIGZpbGUKPiA+PiAtLS0KPiA+PiAgZHJpdmVycy9t dGQvbmFuZC9yYXcvS2NvbmZpZyAgICAgICAgICAgICAgICAgICB8ICAgIDggKwo+ID4+ICBkcml2 ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZSAgICAgICAgICAgICAgICAgIHwgICAgMSArCj4gPj4g IGRyaXZlcnMvbXRkL25hbmQvcmF3L2NhZGVuY2UtbmFuZC1jb250cm9sbGVyLmMgfCAzMjg4ICsr KysrKysrKysrKysrKysrKysrKysrKyAgCj4gPgo+ID5UaGlzIGRyaXZlciBpcyB3YXkgdG9vIG1h c3NpdmUsIEkgYW0gcHJldHR5IHN1cmUgaXQgY2FuIHNocmluayBhCj4gPmxpdHRsZSBiaXQgbW9y ZS4KPiA+Wy4uLl0KPiA+ICAKPiBJIHdpbGwgdHJ5IHRvIG1ha2UgaXQgc2hvcmVyIGJ1dCBpdCB3 aWxsIGJlIGRpZnVjdWx0IHRvIGFjaGl2ZS4gSXQgaXMgYmVjYXVzZSAtIHRoZXJlIGFyZSBhIGxv dCBvZiBjYWxjdWxhdGlvbiBuZWVkZWQgZm9yIFBIWSAgICAgIC0gRUNDIGFyZSBpbnRlcmxlYXZl ZCB3aXRoIGRhdGEgKGxpa2Ugb24gbWFydmVsbC1uYW5kIG9yIGdwbWktbmFuZCkuCj4gICAgVGhl cmVmb3JlOiAgICArIFJBVyBtb2RlIGlzIGNvbXBsaWNhdGVkICAgICsgcHJvdGVjdGluZyBCQk0g aW5jcmVhc2VzIG51bWJlciBvZiBsaW5lcyBvZiBzb3VyY2UgY29kZQo+IC0gbmVlZCB0byBzdXBw b3J0IHR3byBETUEgZW5naW5lcyBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgKHNsYXZlKSBXZSB3aWxs IHNlZSBvbiBuZXh0IHBhdGNoIHZlcnNpb24gd2hhdCBpcyB0aGUgcmVzdWx0LiAgICAgIFRoYXQg cGFnZSBsYXlvdXQgbG9va3M6CgpNYXliZSB5b3UgZG9uJ3QgbmVlZCB0byBzdXBwb3J0IGJvdGgg aW50ZXJuYWwgYW5kIGV4dGVybmFsIERNQT8KCkkgYW0gcHJldHR5IHN1cmUgdGhlcmUgYXJlIHJv b21zIGZvciBzaXplIHJlZHVjdGlvbi4KCj4gCj4gICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KPiAgIHwgRGF0YSAxIHwgRUNDIDEgfCAuLi4gfCBEYXRhIE4gIHwg RUNDIE4gfCAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiAK PiAgICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKPiAgICAgICAgIExh c3QgRGF0YSB8IE9PQiBieXRlcyB8IExhc3QgRUNDIHwKPiAgICAgICAgLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLSsKPiAJICAgIC9cIAkgICAgfHwgICAgICAgICBPT0IgYXJlYSBz dGFydGVkCj4gICAgICB1c3VhbHkgdmVuZG9yIHNwZWNpZmllZCBCQk0KPiAKPiBGbGFzaCBPT0Ig YXJlYSBzdGFydHMgc29tZXdoZXJlIGluIGxhc3QgZGF0YSBzZWN0b3IuIEZsYXNoIE9PQiBhcmVh IGNvbnRhaW5zIHBhcnQgb2YgbGFzdCBzZWN0b3IsIG9vYiBkYXRhIChhY2Nlc3NpYmxlIGJ5IGRy aXZlciksIGFuZCBsYXN0IEVDQyBjb2RlICAgPj4gKwo+ID4+ICtzdHJ1Y3QgY2Ruc19uYW5kX2No aXAgewo+ID4+ICsJc3RydWN0IGNhZGVuY2VfbmFuZF90aW1pbmdzIHRpbWluZ3M7Cj4gPj4gKwlz dHJ1Y3QgbmFuZF9jaGlwIGNoaXA7Cj4gPj4gKwl1OCBuc2VsczsKPiA+PiArCXN0cnVjdCBsaXN0 X2hlYWQgbm9kZTsKPiA+PiArCj4gPj4gKwkvKgo+ID4+ICsJICogcGFydCBvZiBvb2IgYXJlYSBv ZiBOQU5GIGZsYXNoIG1lbW9yeSBwYWdlLgo+ID4+ICsJICogVGhpcyBwYXJ0IGlzIGF2YWlsYWJs ZSBmb3IgdXNlciB0byByZWFkIG9yIHdyaXRlLgo+ID4+ICsJICovCj4gPj4gKwl1MzIgYXZhaWxf b29iX3NpemU7Cj4gPj4gKwkvKiBvb2IgYXJlYSBzaXplIG9mIE5BTkYgZmxhc2ggbWVtb3J5IHBh Z2UgKi8KPiA+PiArCXUzMiBvb2Jfc2l6ZTsKPiA+PiArCS8qIG1haW4gYXJlYSBzaXplIG9mIE5B TkYgZmxhc2ggbWVtb3J5IHBhZ2UgKi8KPiA+PiArCXUzMiBtYWluX3NpemU7ICAKPiA+Cj4gPlRo ZXNlIGZpZWxkcyBhcmUgcmVkdW5kYW50IGFuZCBleGlzdCBpbiBtdGRfaW5mby9uYW5kX2NoaXAu Cj4gPiAgCj4gT2sgSSB3aWxsIHVzZSB0aGUgcGFyYW1ldGVycyBmcm9tIG10ZF9pbmZvLgo+ID4+ ICsKPiA+PiArCS8qIHNlY3RvciBzaXplIGZldyBzZWN0b3JzIGFyZSBsb2NhdGVkIG9uIG1haW4g YXJlYSBvZiBORiBtZW1vcnkgcGFnZSAqLwo+ID4+ICsJdTMyIHNlY3Rvcl9zaXplOwo+ID4+ICsJ dTMyIHNlY3Rvcl9jb3VudDsKPiA+PiArCj4gPj4gKwkvKiBvZmZzZXQgb2YgQkJNKi8KPiA+PiAr CXU4IGJibV9vZmZzOwo+ID4+ICsJLyogbnVtYmVyIG9mIGJ5dGVzIHJlc2VydmVkIGZvciBCQk0g Ki8KPiA+PiArCXU4IGJibV9sZW47ICAKPiA+Cj4gPldoeSBkbyB5b3UgYm90aGVyIGF0IHRoZSBj b250cm9sbGVyIGRyaXZlciBsZXZlbCB3aXRoIGJibT8KPiA+ICAKPiBXaGVuIEVDQyBpcyBlbmFi bGVkIHRoZW4gQkJNIGlzIHNvbWV3aGVyZSBpbiBsYXN0IGRhdGEgc2VjdG9yLiBTbyBmb3Igd3Jp dGUgb3BlcmF0aW9uIHJlYWwgQkJNIHdpbGwgYmUgb3ZlcndyaXR0ZW4uIEZvciByZWFkIG9wZXJh dGlvbgo+IGl0IHdpbGwgYmUgcmVhZCBmcm9tIHdyb25nIG9mZnNldC4gVG8gcHJvdGVjdCBCQk0g d2UgdXNlIEhXIGZlYXR1cmUgc2tpcCBieXRlcy4gVG8gYmUgYWJsZSB0byBwcm9wZXJseSBjb25m aWd1cmUgdGhpcyBmZWF0dXJlIHdlIG5lZWQgdG8KPiBrbm93IHdoYXQgaXMgdGhlIG9mZnNldCBv ZiBCQk0uICAgPj4gKwo+ID4+ICtzdGF0aWMgaW50IGNhZGVuY2VfbmFuZF9zZXRfZXJhc2VfZGV0 ZWN0aW9uKHN0cnVjdCBjZG5zX25hbmRfY3RybCAqY2Ruc19jdHJsLAo+ID4+ICsJCQkJCSAgICBi b29sIGVuYWJsZSwKPiA+PiArCQkJCQkgICAgdTggYml0ZmxpcHNfdGhyZXNob2xkKSAgCj4gPgo+ ID5XaGF0IGlzIHRoaXMgZm9yPyAgCj4gRnVjbnRpb25zIGVuYWJsZXMvZGlzYWJsZXMgaGFyZHdh cmUgZGV0ZWN0aW9uIG9mIGVyYXNlZCBkYXRhCj4gcGFnZXMuID4KCk9rLCB0aGUgbmFtZSBpcyBu b3QgdmVyeSBleHBsaWNpdCAsIG1heWJlIHlvdSBjb3VsZCB0ZWxsIHRoaXMgd2l0aCBhCmNvbW1l bnQuCgo+ID4+ICsKPiA+PiArLyogaGFyZHdhcmUgaW5pdGlhbGl6YXRpb24gKi8KPiA+PiArc3Rh dGljIGludCBjYWRlbmNlX25hbmRfaHdfaW5pdChzdHJ1Y3QgY2Ruc19uYW5kX2N0cmwgKmNkbnNf Y3RybCkKPiA+PiArewo+ID4+ICsJaW50IHN0YXR1cyA9IDA7Cj4gPj4gKwl1MzIgcmVnOwo+ID4+ ICsKPiA+PiArCXN0YXR1cyA9IGNhZGVuY2VfbmFuZF93YWl0X2Zvcl92YWx1ZShjZG5zX2N0cmws IENUUkxfU1RBVFVTLAo+ID4+ICsJCQkJCSAgICAgMTAwMDAwMCwKPiA+PiArCQkJCQkgICAgIENU UkxfU1RBVFVTX0lOSVRfQ09NUCwgZmFsc2UpOwo+ID4+ICsJaWYgKHN0YXR1cykKPiA+PiArCQly ZXR1cm4gc3RhdHVzOwo+ID4+ICsKPiA+PiArCXJlZyA9IHJlYWRsKGNkbnNfY3RybC0+cmVnICsg Q1RSTF9WRVJTSU9OKTsKPiA+PiArCj4gPj4gKwlkZXZfaW5mbyhjZG5zX2N0cmwtPmRldiwKPiA+ PiArCQkgIiVzOiBjYWRlbmNlIG5hbmQgY29udHJvbGxlciB2ZXJzaW9uIHJlZyAleFxuIiwKPiA+ PiArCQkgX19mdW5jX18sIHJlZyk7Cj4gPj4gKwo+ID4+ICsJLyogZGlzYWJsZSBjYWNoZSBhbmQg bXVsdGlwbGFuZSAqLwo+ID4+ICsJd3JpdGVsKDAsIGNkbnNfY3RybC0+cmVnICsgTVVMVElQTEFO RV9DRkcpOwo+ID4+ICsJd3JpdGVsKDAsIGNkbnNfY3RybC0+cmVnICsgQ0FDSEVfQ0ZHKTsKPiA+ PiArCj4gPj4gKwkvKiBjbGVhciBhbGwgaW50ZXJydXB0cyAqLwo+ID4+ICsJd3JpdGVsKDB4RkZG RkZGRkYsIGNkbnNfY3RybC0+cmVnICsgSU5UUl9TVEFUVVMpOwo+ID4+ICsKPiA+PiArCWNhZGVu Y2VfbmFuZF9nZXRfY2FwcyhjZG5zX2N0cmwpOwo+ID4+ICsJY2FkZW5jZV9uYW5kX3JlYWRfYmNo X2NmZyhjZG5zX2N0cmwpOyAgCj4gPgo+ID5ObywgeW91IGNhbm5vdCByZWx5IG9uIHRoZSBib290 bG9hZGVyJ3MgY29uZmlndXJhdGlvbi4gQW5kIEkgc3VwcG9zZQo+ID50aGlzIGlzIHdoYXQgdGhl IGZpcnN0IGNhbGwgdG8gcmVhZF9iY2hfY2ZnIGRvZXM/ICAKPiBJIGRvIG5vdCByZWFseSBvbiBi b290IGxvYWRlci4gSnVzdCByZWFkIE5BTkQgZmxhc2gKPiBjb250cm9sbGVyIGNvbmZpZ3VyYXRp b24gZnJvbSByZWFkIG9ubHkgY2FwYWJpbGl0aWVzIHJlZ2lzdGVycy4KCk9rLCBpZiB0aGVzZSBh cmUgUk8gcmVnaXN0ZXJzLCBpdCdzIGZpbmUuIEJ1dCBtYXliZSBkb24ndCBjYWxsIHRoZQpmdW5j dGlvbiAicmVhZCBiY2ggY29uZmlnIiB3aGljaCBzdWdnZXN0IHRoYXQgdGhpcyBpcyBzb21ldGhp bmcgeW91IGNhbgpjaGFuZ2UuCgo+IAo+IAo+ID4+ICsKPiA+PiArI2RlZmluZSBUVF9PT0JfQVJF QQkJMQo+ID4+ICsjZGVmaW5lIFRUX01BSU5fT09CX0FSRUFTCTIKPiA+PiArI2RlZmluZSBUVF9S QVdfUEFHRQkJMwo+ID4+ICsjZGVmaW5lIFRUX0JCTQkJCTQKPiA+PiArI2RlZmluZSBUVF9NQUlO X09PQl9BUkVBX0VYVAk1Cj4gPj4gKwo+ID4+ICsvKiBwcmVwYXJlIHNpemUgb2YgZGF0YSB0byB0 cmFuc2ZlciAqLwo+ID4+ICtzdGF0aWMgaW50Cj4gPj4gK2NhZGVuY2VfbmFuZF9wcmVwYXJlX2Rh dGFfc2l6ZShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLAo+ID4+ICsJCQkgICAgICAgaW50IHRyYW5z ZmVyX3R5cGUpCj4gPj4gK3sKPiA+PiArCXN0cnVjdCBjZG5zX25hbmRfY3RybCAqY2Ruc19jdHJs ID0gdG9fY2Ruc19uYW5kX2N0cmwoY2hpcC0+Y29udHJvbGxlcik7Cj4gPj4gKwlzdHJ1Y3QgY2Ru c19uYW5kX2NoaXAgKmNkbnNfY2hpcCA9IHRvX2NkbnNfbmFuZF9jaGlwKGNoaXApOwo+ID4+ICsJ dTMyIHNlY19zaXplID0gMCwgbGFzdF9zZWNfc2l6ZSwgb2Zmc2V0ID0gMCwgc2VjX2NudCA9IDE7 Cj4gPj4gKwl1MzIgZWNjX3NpemUgPSBjaGlwLT5lY2MuYnl0ZXM7Cj4gPj4gKwl1MzIgZGF0YV9j dHJsX3NpemUgPSAwOwo+ID4+ICsJdTMyIHJlZyA9IDA7Cj4gPj4gKwo+ID4+ICsJaWYgKGNkbnNf Y3RybC0+Y3Vycl90cmFuc190eXBlID09IHRyYW5zZmVyX3R5cGUpCj4gPj4gKwkJcmV0dXJuIDA7 Cj4gPj4gKwo+ID4+ICsJc3dpdGNoICh0cmFuc2Zlcl90eXBlKSB7ICAKPiA+Cj4gPlBsZWFzZSB0 dXJuIHRoZSBjb250cm9sbGVyIGRyaXZlciBhcyBkdW1iIGFzIHBvc3NpYmxlLiBZb3Ugc2hvdWxk IG5vdAo+ID5jYXJlIHdoaWNoIHBhcnQgb2YgdGhlIE9PQiBhcmVhIHlvdSBhcmUgYWNjZXNzaW5n LiAgCj4gSXQgaXMgYSBiaXQgY29uZnVzaW5nIGZvciBtZSBob3cgYWNjZXNzaW5nIE9PQiBzaG91 bGQgYmUgaW1wbGVtZW50ZWQuCj4gSSBrbm93IHRoYXQgcmVhZF9vb2IgZnVuY3Rpb24gaXMgY2Fs bGVkIHRvIGNoZWNrIEJCTSB2YWx1ZSB3aGVuIEJCVCBpcwo+IGluaXRpYWxpemVkLiBJdCBpcyBh bHNvIGEgYml0IGNvbmZ1c2luZyBmb3IgbWUgd2h5IHRoZSByYXcgdmVyc2lvbiBpcwo+IG5vdCB1 c2VkIGZvciB0aGF0IHB1cnBvc2UuICAgIEluIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaWYgeW91 IHdyaXRlIG9vYiBieSB3cml0ZV9wYWdlIGZ1bmN0aW9uIG5leHQKPiByZWFkIG9vYiBieSByZWFk X29vYiBmdW5jdGlvbiB0aGVuIGRhdGEgd2lsbCBiZSB0aGUgc2FtZS4KPiBJZiBJIGltcGxlbWVu dCBkdW1wIGZ1bmN0aW9ucyByZWFkX29vYiBhbmQgd3JpdGVfb29iIHRoZW4KPiAxLiBFQ0MgbXVz dCBiZSBkaXNhYmxlZCBmb3IgdGhlc2UgZnVuY3Rpb25zCj4gMi4gb29iIGRhdGEgYWNjZXNzaW5n IGJ5IHdyaXRlX3BhZ2UvcmVhZF9wYWdlIHdpbGwgYmUgZGlmZmVyZW50Cj4gICAgKGRpZmZlcmVu dCBvZmZzZXRzKSB0aGF0IHRoZSBkYXRhIGFjY2Vzc2luZyBieSByZWFkX29vYi93cml0ZV9vb2IK PiAgICBmdW5jdGlvbnMKCk5vLCBJIGZlYXIgdGhpcyBpcyBub3QgYWNjZXB0YWJsZS4KCj4gSWYg IGFib3ZlIGRlc2NyaWJlZCAiZnVuY3Rpb25hbGl0aWVzIiBhcmUgYWNjZXB0YWJsZSBJIHdpbGwg Y2hhbmdlIGltcGxlbWVudGF0aW9uIG9mIHdyaXRlX29vYiBhbmQgcmVhZF9vb2IgZnVuY3Rpb25z Lgo+IFRoZSB3cml0ZV9wYWdlIGFuZCByZWFkX3BhZ2UgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiB0 aGF0IHdheSBhcyBpdCBpcyBub3cuICAgIExldCBtZSBrbm93IHdoaWNoIHNvbHV0aW9uIGlzIHBy ZWZmZXJlZC4KCklmIHRoaXMgaXMgdG9vIGNvbXBsaWNhdGVkIHRvIGp1c3Qgd3JpdGUgdGhlIG9v Yiwgd2h5IG5vdCBmYWxsYmFjayBvbgpyZWFkL3dyaXRlX3BhZ2UgKHdpdGggb29iX3JlcXVpcmVk IGFuZCBhIGR1bW15IGRhdGEgYnVmZmVyKT8KCj4gCj4gPj4gKwljYXNlIFRUX09PQl9BUkVBOgo+ ID4+ICsJCW9mZnNldCA9IGNkbnNfY2hpcC0+bWFpbl9zaXplIC0gY2Ruc19jaGlwLT5zZWN0b3Jf c2l6ZTsKPiA+PiArCQllY2Nfc2l6ZSA9IGVjY19zaXplICogKG9mZnNldCAvIGNkbnNfY2hpcC0+ c2VjdG9yX3NpemUpOwo+ID4+ICsJCW9mZnNldCA9IG9mZnNldCArIGVjY19zaXplOwo+ID4+ICsJ CXNlY19jbnQgPSAxOwo+ID4+ICsJCWxhc3Rfc2VjX3NpemUgPSBjZG5zX2NoaXAtPnNlY3Rvcl9z aXplCj4gPj4gKwkJCSsgY2Ruc19jaGlwLT5hdmFpbF9vb2Jfc2l6ZTsKPiA+PiArCQlicmVhazsK PiA+PiArCWNhc2UgVFRfTUFJTl9PT0JfQVJFQV9FWFQ6Cj4gPj4gKwkJc2VjX2NudCA9IGNkbnNf Y2hpcC0+c2VjdG9yX2NvdW50Owo+ID4+ICsJCWxhc3Rfc2VjX3NpemUgPSBjZG5zX2NoaXAtPnNl Y3Rvcl9zaXplOwo+ID4+ICsJCXNlY19zaXplID0gY2Ruc19jaGlwLT5zZWN0b3Jfc2l6ZTsKPiA+ PiArCQlkYXRhX2N0cmxfc2l6ZSA9IGNkbnNfY2hpcC0+YXZhaWxfb29iX3NpemU7Cj4gPj4gKwkJ YnJlYWs7Cj4gPj4gKwljYXNlIFRUX01BSU5fT09CX0FSRUFTOgo+ID4+ICsJCXNlY19jbnQgPSBj ZG5zX2NoaXAtPnNlY3Rvcl9jb3VudDsKPiA+PiArCQlsYXN0X3NlY19zaXplID0gY2Ruc19jaGlw LT5zZWN0b3Jfc2l6ZQo+ID4+ICsJCQkrIGNkbnNfY2hpcC0+YXZhaWxfb29iX3NpemU7Cj4gPj4g KwkJc2VjX3NpemUgPSBjZG5zX2NoaXAtPnNlY3Rvcl9zaXplOwo+ID4+ICsJCWJyZWFrOwo+ID4+ ICsJY2FzZSBUVF9SQVdfUEFHRToKPiA+PiArCQlsYXN0X3NlY19zaXplID0gY2Ruc19jaGlwLT5t YWluX3NpemUgKyBjZG5zX2NoaXAtPm9vYl9zaXplOwo+ID4+ICsJCWJyZWFrOwo+ID4+ICsJY2Fz ZSBUVF9CQk06Cj4gPj4gKwkJb2Zmc2V0ID0gY2Ruc19jaGlwLT5tYWluX3NpemUgKyBjZG5zX2No aXAtPmJibV9vZmZzOwo+ID4+ICsJCWxhc3Rfc2VjX3NpemUgPSA4Owo+ID4+ICsJCWJyZWFrOwo+ ID4+ICsJZGVmYXVsdDoKPiA+PiArCQlkZXZfZXJyKGNkbnNfY3RybC0+ZGV2LCAiRGF0YSBzaXpl IHByZXBhcmF0aW9uIGZhaWxlZFxuIik7Cj4gPj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gPj4gKwl9 Cj4gPj4gKwo+ID4+ICsJcmVnID0gMDsKPiA+PiArCXJlZyB8PSBGSUVMRF9QUkVQKFRSQU5fQ0ZH XzBfT0ZGU0VULCBvZmZzZXQpOwo+ID4+ICsJcmVnIHw9IEZJRUxEX1BSRVAoVFJBTl9DRkdfMF9T RUNfQ05ULCBzZWNfY250KTsKPiA+PiArCXdyaXRlbChyZWcsIGNkbnNfY3RybC0+cmVnICsgVFJB Tl9DRkdfMCk7Cj4gPj4gKwo+ID4+ICsJcmVnID0gMDsKPiA+PiArCXJlZyB8PSBGSUVMRF9QUkVQ KFRSQU5fQ0ZHXzFfTEFTVF9TRUNfU0laRSwgbGFzdF9zZWNfc2l6ZSk7Cj4gPj4gKwlyZWcgfD0g RklFTERfUFJFUChUUkFOX0NGR18xX1NFQ1RPUl9TSVpFLCBzZWNfc2l6ZSk7Cj4gPj4gKwl3cml0 ZWwocmVnLCBjZG5zX2N0cmwtPnJlZyArIFRSQU5fQ0ZHXzEpOwo+ID4+ICsKPiA+PiArCXJlZyA9 IHJlYWRsKGNkbnNfY3RybC0+cmVnICsgQ09OVFJPTF9EQVRBX0NUUkwpOwo+ID4+ICsJcmVnICY9 IH5DT05UUk9MX0RBVEFfQ1RSTF9TSVpFOwo+ID4+ICsJcmVnIHw9IEZJRUxEX1BSRVAoQ09OVFJP TF9EQVRBX0NUUkxfU0laRSwgZGF0YV9jdHJsX3NpemUpOwo+ID4+ICsJd3JpdGVsKHJlZywgY2Ru c19jdHJsLT5yZWcgKyBDT05UUk9MX0RBVEFfQ1RSTCk7Cj4gPj4gKwo+ID4+ICsJY2Ruc19jdHJs LT5jdXJyX3RyYW5zX3R5cGUgPSB0cmFuc2Zlcl90eXBlOwo+ID4+ICsKPiA+PiArCXJldHVybiAw Owo+ID4+ICt9Cj4gPj4gKyAgCj4gPgo+ID5bLi4uXQo+ID4gIAo+ID4+ICsKPiA+PiArc3RhdGlj IGludCBjYWRlbmNlX25hbmRfcmVhZF9wYWdlX3JhdyhzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLAo+ ID4+ICsJCQkJICAgICAgdTggKmJ1ZiwgaW50IG9vYl9yZXF1aXJlZCwgaW50IHBhZ2UpCj4gPj4g K3sKPiA+PiArCXN0cnVjdCBjZG5zX25hbmRfY3RybCAqY2Ruc19jdHJsID0gdG9fY2Ruc19uYW5k X2N0cmwoY2hpcC0+Y29udHJvbGxlcik7Cj4gPj4gKwlzdHJ1Y3QgY2Ruc19uYW5kX2NoaXAgKmNk bnNfY2hpcCA9IHRvX2NkbnNfbmFuZF9jaGlwKGNoaXApOwo+ID4+ICsJaW50IG9vYl9za2lwID0g Y2Ruc19jaGlwLT5iYm1fbGVuOyAgCj4gPgo+ID5XaHkgZG8geW91IHNraXAgdGhlIEJCTT8KPiA+ Cj4gPkluIGFueSBvZiB0aGUgcmVhZF9wYWdlL29vYiBoZWxwZXJzIEkgZG9uJ3QgdGhpbmsgdGhp cyBpcyByZWxldmFudCBhdAo+ID5hbGwuICAKPiBJIGRlc2NyaWJlZCB0aGUgcHJvYmxlbSBhdCB0 aGUgYmVnaW5uaWcuIEVDQyBhcmUgaW50ZXJsZWF2ZWQgd2l0aCBkYXRhLgo+IFNvIHJlYWwgcG9z c2l0aW9uIG9mIEJCTSBpcyBzb21ld2VocmUgaW4gbGFzdCBkYXRhIHNlY3Rvci4gV2UgdXNlIHNr aXAKPiBieXRlIGZlYXR1cmUgdG8gc2tpcCB0aGlzIEJCTS4gT25jZSB1c2VkIG5lZWQgdG8gaGFu ZGxlIGluIGVhY2gKPiBmdW5jdGlvbi4gU2tpcCBCQk0gaXMgYWxzbyB1c2VkIGluIGRlbmFsaS1u YW5kCj4gICAgICA+ICAKPiA+PiArCWludCB3cml0ZXNpemUgPSBjZG5zX2NoaXAtPm1haW5fc2l6 ZTsKPiA+PiArCWludCBlY2Nfc3RlcHMgPSBjaGlwLT5lY2Muc3RlcHM7Cj4gPj4gKwlpbnQgZWNj X3NpemUgPSBjaGlwLT5lY2Muc2l6ZTsKPiA+PiArCWludCBlY2NfYnl0ZXMgPSBjaGlwLT5lY2Mu Ynl0ZXM7Cj4gPj4gKwl2b2lkICp0bXBfYnVmID0gY2Ruc19jdHJsLT5idWY7Cj4gPj4gKwlpbnQg aSwgcG9zLCBsZW47Cj4gPj4gKwlpbnQgc3RhdHVzID0gMDsKPiA+PiArCj4gPj4gKwlzdGF0dXMg PSBjYWRlbmNlX25hbmRfc2VsZWN0X3RhcmdldChjaGlwKTsKPiA+PiArCWlmIChzdGF0dXMpCj4g Pj4gKwkJcmV0dXJuIHN0YXR1czsKPiA+PiArCj4gPj4gKwljYWRlbmNlX25hbmRfc2V0X3NraXBf Ynl0ZXNfY29uZihjZG5zX2N0cmwsIDAsIDAsIDApOwo+ID4+ICsKPiA+PiArCWNhZGVuY2VfbmFu ZF9wcmVwYXJlX2RhdGFfc2l6ZShjaGlwLCBUVF9SQVdfUEFHRSk7Cj4gPj4gKwlzdGF0dXMgPSBj YWRlbmNlX25hbmRfY2RtYV90cmFuc2ZlcihjZG5zX2N0cmwsCj4gPj4gKwkJCQkJICAgIGNkbnNf Y2hpcC0+Y3NbY2hpcC0+Y3VyX2NzXSwKPiA+PiArCQkJCQkgICAgcGFnZSwgY2Ruc19jdHJsLT5i dWYsCj4gPj4gKwkJCQkJICAgIE5VTEwsCj4gPj4gKwkJCQkJICAgIGNkbnNfY2hpcC0+bWFpbl9z aXplCj4gPj4gKwkJCQkJICAgICsgY2Ruc19jaGlwLT5vb2Jfc2l6ZSwKPiA+PiArCQkJCQkgICAg MCwgRE1BX0ZST01fREVWSUNFLCBmYWxzZSk7Cj4gPj4gKwo+ID4+ICsJc3dpdGNoIChzdGF0dXMp IHsKPiA+PiArCWNhc2UgU1RBVF9FUkFTRUQ6Cj4gPj4gKwljYXNlIFNUQVRfT0s6Cj4gPj4gKwkJ YnJlYWs7Cj4gPj4gKwlkZWZhdWx0Ogo+ID4+ICsJCWRldl9lcnIoY2Ruc19jdHJsLT5kZXYsICJy ZWFkIHJhdyBwYWdlIGZhaWxlZFxuIik7Cj4gPj4gKwkJcmV0dXJuIC1FSU87Cj4gPj4gKwl9Cj4g Pj4gKwo+ID4+ICsJLyogQXJyYW5nZSB0aGUgYnVmZmVyIGZvciBzeW5kcm9tZSBwYXlsb2FkL2Vj YyBsYXlvdXQgKi8KPiA+PiArCWlmIChidWYpIHsKPiA+PiArCQlmb3IgKGkgPSAwOyBpIDwgZWNj X3N0ZXBzOyBpKyspIHsKPiA+PiArCQkJcG9zID0gaSAqIChlY2Nfc2l6ZSArIGVjY19ieXRlcyk7 Cj4gPj4gKwkJCWxlbiA9IGVjY19zaXplOwo+ID4+ICsKPiA+PiArCQkJaWYgKHBvcyA+PSB3cml0 ZXNpemUpCj4gPj4gKwkJCQlwb3MgKz0gb29iX3NraXA7Cj4gPj4gKwkJCWVsc2UgaWYgKHBvcyAr IGxlbiA+IHdyaXRlc2l6ZSkKPiA+PiArCQkJCWxlbiA9IHdyaXRlc2l6ZSAtIHBvczsKPiA+PiAr Cj4gPj4gKwkJCW1lbWNweShidWYsIHRtcF9idWYgKyBwb3MsIGxlbik7Cj4gPj4gKwkJCWJ1ZiAr PSBsZW47Cj4gPj4gKwkJCWlmIChsZW4gPCBlY2Nfc2l6ZSkgewo+ID4+ICsJCQkJbGVuID0gZWNj X3NpemUgLSBsZW47Cj4gPj4gKwkJCQltZW1jcHkoYnVmLCB0bXBfYnVmICsgd3JpdGVzaXplICsg b29iX3NraXAsCj4gPj4gKwkJCQkgICAgICAgbGVuKTsKPiA+PiArCQkJCWJ1ZiArPSBsZW47Cj4g Pj4gKwkJCX0KPiA+PiArCQl9Cj4gPj4gKwl9Cj4gPj4gKwo+ID4+ICsJaWYgKG9vYl9yZXF1aXJl ZCkgewo+ID4+ICsJCXU4ICpvb2IgPSBjaGlwLT5vb2JfcG9pOwo+ID4+ICsJCXUzMiBvb2JfZGF0 YV9vZmZzZXQgPSAoY2Ruc19jaGlwLT5zZWN0b3JfY291bnQgLSAxKSAqCj4gPj4gKwkJCShjZG5z X2NoaXAtPnNlY3Rvcl9zaXplICsgY2hpcC0+ZWNjLmJ5dGVzKQo+ID4+ICsJCQkrIGNkbnNfY2hp cC0+c2VjdG9yX3NpemUgKyBvb2Jfc2tpcDsKPiA+PiArCj4gPj4gKwkJLyogT09CIGZyZWUgKi8K PiA+PiArCQltZW1jcHkob29iLCB0bXBfYnVmICsgb29iX2RhdGFfb2Zmc2V0LAo+ID4+ICsJCSAg ICAgICBjZG5zX2NoaXAtPmF2YWlsX29vYl9zaXplKTsKPiA+PiArCj4gPj4gKwkJLyogQkJNIGF0 IHRoZSBiZWdpbm5pbmcgb2YgdGhlIE9PQiBhcmVhICovCj4gPj4gKwkJbWVtY3B5KG9vYiwgdG1w X2J1ZiArIHdyaXRlc2l6ZSwgb29iX3NraXApOwo+ID4+ICsKPiA+PiArCQlvb2IgKz0gY2Ruc19j aGlwLT5hdmFpbF9vb2Jfc2l6ZTsKPiA+PiArCj4gPj4gKwkJLyogT09CIEVDQyAqLwo+ID4+ICsJ CWZvciAoaSA9IDA7IGkgPCBlY2Nfc3RlcHM7IGkrKykgewo+ID4+ICsJCQlwb3MgPSBlY2Nfc2l6 ZSArIGkgKiAoZWNjX3NpemUgKyBlY2NfYnl0ZXMpOwo+ID4+ICsJCQlsZW4gPSBlY2NfYnl0ZXM7 Cj4gPj4gKwo+ID4+ICsJCQlpZiAoaSA9PSAoZWNjX3N0ZXBzIC0gMSkpCj4gPj4gKwkJCQlwb3Mg Kz0gY2Ruc19jaGlwLT5hdmFpbF9vb2Jfc2l6ZTsKPiA+PiArCj4gPj4gKwkJCWlmIChwb3MgPj0g d3JpdGVzaXplKQo+ID4+ICsJCQkJcG9zICs9IG9vYl9za2lwOwo+ID4+ICsJCQllbHNlIGlmIChw b3MgKyBsZW4gPiB3cml0ZXNpemUpCj4gPj4gKwkJCQlsZW4gPSB3cml0ZXNpemUgLSBwb3M7Cj4g Pj4gKwo+ID4+ICsJCQltZW1jcHkob29iLCB0bXBfYnVmICsgcG9zLCBsZW4pOwo+ID4+ICsJCQlv b2IgKz0gbGVuOwo+ID4+ICsJCQlpZiAobGVuIDwgZWNjX2J5dGVzKSB7Cj4gPj4gKwkJCQlsZW4g PSBlY2NfYnl0ZXMgLSBsZW47Cj4gPj4gKwkJCQltZW1jcHkob29iLCB0bXBfYnVmICsgd3JpdGVz aXplICsgb29iX3NraXAsCj4gPj4gKwkJCQkgICAgICAgbGVuKTsKPiA+PiArCQkJCW9vYiArPSBs ZW47Cj4gPj4gKwkJCX0KPiA+PiArCQl9Cj4gPj4gKwl9Cj4gPj4gKwo+ID4+ICsJcmV0dXJuIDA7 Cj4gPj4gK30gIAo+IFsgLi4uXQo+ICAgPj4gK30KPiA+PiArCj4gPj4gK3N0YXRpYyBpbnQgY2Fk ZW5jZV9uYW5kX3JlYWRfYnVmKHN0cnVjdCBjZG5zX25hbmRfY3RybCAqY2Ruc19jdHJsLAo+ID4+ ICtzdGF0aWMgaW50IGNhZGVuY2VfbmFuZF93cml0ZV9idWYoc3RydWN0IGNkbnNfbmFuZF9jdHJs ICpjZG5zX2N0cmwsCj4gPj4gK3N0YXRpYyBpbnQgY2FkZW5jZV9uYW5kX2NtZF9vcGNvZGUoc3Ry dWN0IG5hbmRfY2hpcCAqY2hpcCwKPiA+PiArc3RhdGljIGludCBjYWRlbmNlX25hbmRfY21kX2Fk ZHJlc3Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwKPiA+PiArc3RhdGljIGludCBjYWRlbmNlX25h bmRfY21kX2VyYXNlKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsCj4gPj4gK3N0YXRpYyBpbnQgY2Fk ZW5jZV9uYW5kX2NtZF9kYXRhKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsICAKPiA+Cj4gPlRoaXMg bG9va3MgcHJldHR5IGZhbWlsaWFyIHdpdGggdGhlIGxlZ2FjeSBhcHByb2FjaCwgSSB0aGluayB5 b3UganVzdAo+ID5yZW5hbWVkIHNvbWUgZnVuY3Rpb25zIGluc3RlYWQgb2YgdHJ5aW5nIHRvIGZp dCB0aGUgLT5leGVjX29wIGludGVyZmFjZQo+ID5hbmQgdGhlcmUgaXMgcHJvYmFibHkgYSBsb3Qg dG8gZG8gb24gdGhpcyBzaWRlIHRoYXQgd291bGQgcmVkdWNlIHRoZQo+ID5kcml2ZXIgc2l6ZS4g VGhlcmUgYXJlIHBsZW50eSBvZiBvcGVyYXRpb25zIGRvbmUgYnkgZWFjaCBvZiB0aGUgYWJvdmUK PiA+aGVscGVycyB0aGF0IHNob3VsZCBwcm9iYWJseSBmYWN0b3JlZCBvdXQuCj4gPiAgCj4gTm8g SSBoYXZlIG5ldmVyIHVzZWQgbGVnYWN5IGFwcHJvYWNoIGZvciB0aGF0IHBhcnQuCj4gSW4gcHJl dmlvdXMgcGF0Y2ggSSBoYXZlIG9uZSBmdW5jdGlvbiB0byBoYW5sZGUgaXQgYnV0IEJvcmlzIHBv aW50Cj4gdGhhdCBvbmUgZnVuY3Rpb24gY29udGFpbmluZyBzd2l0Y2ggaXMgbm90IGEgZ29vZCBz b2x1dGlvbiBzbyBJIHNwbGl0ZWQKPiB0byBmZXcgZnVuY3Rpb25zLiAgIAoKb2sKCj4+ICsKPiA+ PiArc3RhdGljIGNvbnN0IHN0cnVjdCBuYW5kX29wX3BhcnNlciBjYWRlbmNlX25hbmRfb3BfcGFy c2VyID0gTkFORF9PUF9QQVJTRVIoCj4gPj4gKwlOQU5EX09QX1BBUlNFUl9QQVRURVJOKAo+ID4+ ICsJCWNhZGVuY2VfbmFuZF9jbWRfZXJhc2UsCj4gPj4gKwkJTkFORF9PUF9QQVJTRVJfUEFUX0NN RF9FTEVNKGZhbHNlKSwKPiA+PiArCQlOQU5EX09QX1BBUlNFUl9QQVRfQUREUl9FTEVNKGZhbHNl LCBNQVhfRVJBU0VfQUREUkVTU19DWUMpLAo+ID4+ICsJCU5BTkRfT1BfUEFSU0VSX1BBVF9DTURf RUxFTShmYWxzZSksCj4gPj4gKwkJTkFORF9PUF9QQVJTRVJfUEFUX1dBSVRSRFlfRUxFTShmYWxz ZSkpLAo+ID4+ICsJTkFORF9PUF9QQVJTRVJfUEFUVEVSTigKPiA+PiArCQljYWRlbmNlX25hbmRf Y21kX29wY29kZSwKPiA+PiArCQlOQU5EX09QX1BBUlNFUl9QQVRfQ01EX0VMRU0oZmFsc2UpKSwK PiA+PiArCU5BTkRfT1BfUEFSU0VSX1BBVFRFUk4oCj4gPj4gKwkJY2FkZW5jZV9uYW5kX2NtZF9h ZGRyZXNzLAo+ID4+ICsJCU5BTkRfT1BfUEFSU0VSX1BBVF9BRERSX0VMRU0oZmFsc2UsIE1BWF9B RERSRVNTX0NZQykpLAo+ID4+ICsJTkFORF9PUF9QQVJTRVJfUEFUVEVSTigKPiA+PiArCQljYWRl bmNlX25hbmRfY21kX2RhdGEsCj4gPj4gKwkJTkFORF9PUF9QQVJTRVJfUEFUX0RBVEFfSU5fRUxF TShmYWxzZSwgTUFYX0RBVEFfU0laRSkpLAo+ID4+ICsJTkFORF9PUF9QQVJTRVJfUEFUVEVSTigK PiA+PiArCQljYWRlbmNlX25hbmRfY21kX2RhdGEsCj4gPj4gKwkJTkFORF9PUF9QQVJTRVJfUEFU X0RBVEFfT1VUX0VMRU0oZmFsc2UsIE1BWF9EQVRBX1NJWkUpKSwKPiA+PiArCU5BTkRfT1BfUEFS U0VSX1BBVFRFUk4oCj4gPj4gKwkJY2FkZW5jZV9uYW5kX2NtZF93YWl0cmR5LAo+ID4+ICsJCU5B TkRfT1BfUEFSU0VSX1BBVF9XQUlUUkRZX0VMRU0oZmFsc2UpKQo+ID4+ICsJKTsKPiA+PiArCj4g Pj4gK3N0YXRpYyBpbnQgY2FkZW5jZV9uYW5kX2V4ZWNfb3Aoc3RydWN0IG5hbmRfY2hpcCAqY2hp cCwKPiA+PiArCQkJCWNvbnN0IHN0cnVjdCBuYW5kX29wZXJhdGlvbiAqb3AsCj4gPj4gKwkJCQli b29sIGNoZWNrX29ubHkpCj4gPj4gK3sKPiA+PiArCWludCBzdGF0dXMgPSBjYWRlbmNlX25hbmRf c2VsZWN0X3RhcmdldChjaGlwKTsKPiA+PiArCj4gPj4gKwlpZiAoc3RhdHVzKQo+ID4+ICsJCXJl dHVybiBzdGF0dXM7Cj4gPj4gKwo+ID4+ICsJcmV0dXJuIG5hbmRfb3BfcGFyc2VyX2V4ZWNfb3Ao Y2hpcCwgJmNhZGVuY2VfbmFuZF9vcF9wYXJzZXIsIG9wLAo+ID4+ICsJCQkJICAgICAgY2hlY2tf b25seSk7Cj4gPj4gK30KPiA+PiArCj4gPj4gK3N0YXRpYyBpbnQgY2FkZW5jZV9uYW5kX29vYmxh eW91dF9mcmVlKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBpbnQgc2VjdGlvbiwKPiA+PiArCQkJCSAg ICAgICBzdHJ1Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPiA+PiArewo+ID4+ICsJc3Ry dWN0IG5hbmRfY2hpcCAqY2hpcCA9IG10ZF90b19uYW5kKG10ZCk7Cj4gPj4gKwlzdHJ1Y3QgY2Ru c19uYW5kX2NoaXAgKmNkbnNfY2hpcCA9IHRvX2NkbnNfbmFuZF9jaGlwKGNoaXApOwo+ID4+ICsK PiA+PiArCWlmIChzZWN0aW9uKQo+ID4+ICsJCXJldHVybiAtRVJBTkdFOwo+ID4+ICsKPiA+PiAr CW9vYnJlZ2lvbi0+b2Zmc2V0ID0gY2Ruc19jaGlwLT5iYm1fbGVuOwo+ID4+ICsJb29icmVnaW9u LT5sZW5ndGggPSBjZG5zX2NoaXAtPmF2YWlsX29vYl9zaXplCj4gPj4gKwkJLSBjZG5zX2NoaXAt PmJibV9sZW47Cj4gPj4gKwo+ID4+ICsJcmV0dXJuIDA7Cj4gPj4gK30KPiA+PiArCj4gPj4gK3N0 YXRpYyBpbnQgY2FkZW5jZV9uYW5kX29vYmxheW91dF9lY2Moc3RydWN0IG10ZF9pbmZvICptdGQs IGludCBzZWN0aW9uLAo+ID4+ICsJCQkJICAgICAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2Jy ZWdpb24pCj4gPj4gK3sKPiA+PiArCXN0cnVjdCBuYW5kX2NoaXAgKmNoaXAgPSBtdGRfdG9fbmFu ZChtdGQpOwo+ID4+ICsJc3RydWN0IGNkbnNfbmFuZF9jaGlwICpjZG5zX2NoaXAgPSB0b19jZG5z X25hbmRfY2hpcChjaGlwKTsKPiA+PiArCj4gPj4gKwlpZiAoc2VjdGlvbikKPiA+PiArCQlyZXR1 cm4gLUVSQU5HRTsKPiA+PiArCj4gPj4gKwlvb2JyZWdpb24tPm9mZnNldCA9IGNkbnNfY2hpcC0+ YXZhaWxfb29iX3NpemU7Cj4gPj4gKwlvb2JyZWdpb24tPmxlbmd0aCA9IGNoaXAtPmVjYy50b3Rh bDsKPiA+PiArCj4gPj4gKwlyZXR1cm4gMDsKPiA+PiArfQo+ID4+ICsKPiA+PiArc3RhdGljIGNv bnN0IHN0cnVjdCBtdGRfb29ibGF5b3V0X29wcyBjYWRlbmNlX25hbmRfb29ibGF5b3V0X29wcyA9 IHsKPiA+PiArCS5mcmVlID0gY2FkZW5jZV9uYW5kX29vYmxheW91dF9mcmVlLAo+ID4+ICsJLmVj YyA9IGNhZGVuY2VfbmFuZF9vb2JsYXlvdXRfZWNjLAo+ID4+ICt9Owo+ID4+ICsKPiA+PiArc3Rh dGljIGludCBjYWxjX2N5Y2wodTMyIHRpbWluZywgdTMyIGNsb2NrKQo+ID4+ICt7Cj4gPj4gKwlp ZiAodGltaW5nID09IDAgfHwgY2xvY2sgPT0gMCkKPiA+PiArCQlyZXR1cm4gMDsKPiA+PiArCj4g Pj4gKwlpZiAoKHRpbWluZyAlIGNsb2NrKSA+IDApCj4gPj4gKwkJcmV0dXJuIHRpbWluZyAvIGNs b2NrOwo+ID4+ICsJZWxzZQo+ID4+ICsJCXJldHVybiB0aW1pbmcgLyBjbG9jayAtIDE7Cj4gPj4g K30KPiA+PiArICAKPiBbLi4uXSA+PiArCS8qCj4gPj4gKwkgKiB0aGUgaWRlYSBvZiB0aG9zZSBj YWxjdWxhdGlvbiBpcyB0byBnZXQgdGhlIG9wdGltdW0gdmFsdWUKPiA+PiArCSAqIGZvciB0UlAg YW5kIHRSSCB0aW1pbmdzIGlmIGl0IGlzIE5PVCBwb3NzaWJsZSB0byBzYW1wbGUgZGF0YQo+ID4+ ICsJICogd2l0aCBvcHRpbWFsIHRSUC90Ukggc2V0dGluZ3MgdGhlIHBhcmFtZXRlcnMgd2lsbCBi ZSBleHRlbmRlZAo+ID4+ICsJICovCj4gPj4gKwlpZiAoc2RyLT50UkNfbWluIDw9IGNsa19wZXJp b2QgJiYKPiA+PiArCSAgICBzZHItPnRSUF9taW4gPD0gKGNsa19wZXJpb2QgLyAyKSAmJgo+ID4+ ICsJICAgIHNkci0+dFJFSF9taW4gPD0gKGNsa19wZXJpb2QgLyAyKSkgeyAgCj4gPgo+ID5XaWxs IHRoaXMgc2l0dWF0aW9uIHJlYWxseSBoYXBwZW4/ICAKPiBJIHRoaW5rIHllcyBmb3IgZm9sbHdp bmcgdmFsdWVzIHRyY19taW4gIDIwMDAwIHBzCj4gdHJwX21pbiAgMTAwMDAgcHMKPiB0cmVoX21p biA3MDAwICBwcwo+IGNsa19wZXJpb2QgMjAwMDAgcHMKCk9rLCB5b3UgbWF5IGFkZCBhIGNvbW1l bnQgc3RhdGluZyB0aGF0IHRoaXMgbWF5IGJlIHRoZSBjYXNlIGluIEVETyBtb2RlCjUuCgo+IFsu Li5dCj4gPj4gKwl9Cj4gPj4gKwo+ID4+ICsJaWYgKGNkbnNfY3RybC0+Y2FwczIuaXNfcGh5X3R5 cGVfZGxsKSB7ICAKPiA+Cj4gPklzIHRoZSBlbHNlIHBhcnQgYWxsb3dlZD8KPiA+ICAKPiBmb2xs b3dpbmcgcmVnaXN0ZXIgZG9lcyBub3QgZXhpc3QgaWYgY2FwczIuaXNfcGh5X3R5cGVfZGxsIGlz IDAgPj4gKwkJdTMyIHRwcmVfY250ID0gY2FsY19jeWNsKHRwcmUsIGNsa19wZXJpb2QpOwo+ID4+ ICsJCXUzMiB0Y2Rxc3NfY250ID0gY2FsY19jeWNsKHRjZHFzcyArIGlmX3NrZXcsIGNsa19wZXJp b2QpOwo+ID4+ICsJCXUzMiB0cHN0aF9jbnQgPSBjYWxjX2N5Y2wodHBzdGggKyBpZl9za2V3LCBj bGtfcGVyaW9kKTsKPiA+PiArCj4gPj4gKwkJdTMyIHRycHN0X2NudCA9IGNhbGNfY3ljbCh0cnBz dCArIGlmX3NrZXcsIGNsa19wZXJpb2QpICsgMTsKPiA+PiArCQl1MzIgdHdwc3RfY250ID0gY2Fs Y19jeWNsKHR3cHN0ICsgaWZfc2tldywgY2xrX3BlcmlvZCkgKyAxOwo+ID4+ICsJCXUzMiB0Y3Jl c19jbnQgPSBjYWxjX2N5Y2wodGNyZXMgKyBpZl9za2V3LCBjbGtfcGVyaW9kKSArIDE7Cj4gPj4g KwkJdTMyIHRjZHFzaF9jbnQgPSBjYWxjX2N5Y2wodGNkcXNoICsgaWZfc2tldywgY2xrX3Blcmlv ZCkgKyA1Owo+ID4+ICsKPiA+PiArCQl0Y3JfY250ID0gY2FsY19jeWNsKHRjciArIGlmX3NrZXcs IGNsa19wZXJpb2QpOwo+ID4+ICsJCS8qCj4gPj4gKwkJICogc2tldyBub3QgaW5jbHVkZWQgYmVj YXVzZSB0aGlzIHRpbWluZyBkZWZpbmVzIGR1cmF0aW9uIG9mCj4gPj4gKwkJICogUkUgb3IgRFFT IGJlZm9yZSBkYXRhIHRyYW5zZmVyCj4gPj4gKwkJICovCj4gPj4gKwkJdHBzdGhfY250ID0gdHBz dGhfY250ICsgMTsKPiA+PiArCQlyZWcgPSBGSUVMRF9QUkVQKFRPR0dMRV9USU1JTkdTMF9UUFNU SCwgdHBzdGhfY250KTsKPiA+PiArCQlyZWcgfD0gRklFTERfUFJFUChUT0dHTEVfVElNSU5HUzBf VENEUVNTLCB0Y2Rxc3NfY250KTsKPiA+PiArCQlyZWcgfD0gRklFTERfUFJFUChUT0dHTEVfVElN SU5HUzBfVFBSRSwgdHByZV9jbnQpOwo+ID4+ICsJCXJlZyB8PSBGSUVMRF9QUkVQKFRPR0dMRV9U SU1JTkdTMF9UQ1IsIHRjcl9jbnQpOwo+ID4+ICsJCXQtPnRvZ2dsZV90aW1pbmdzXzAgPSByZWc7 Cj4gPj4gKwkJZGV2X2RiZyhjZG5zX2N0cmwtPmRldiwgIlRPR0dMRV9USU1JTkdTXzBfU0RSXHQl eFxuIiwgcmVnKTsKPiA+PiArCj4gPj4gKwkJLy90b2dnbGVfdGltaW5nc18xIC0gdFJQU1QsdFdQ U1QKPiA+PiArCQlyZWcgPSBGSUVMRF9QUkVQKFRPR0dMRV9USU1JTkdTMV9UQ0RRU0gsIHRjZHFz aF9jbnQpOwo+ID4+ICsJCXJlZyB8PSBGSUVMRF9QUkVQKFRPR0dMRV9USU1JTkdTMV9UQ1JFUywg dGNyZXNfY250KTsKPiA+PiArCQlyZWcgfD0gRklFTERfUFJFUChUT0dHTEVfVElNSU5HUzFfVFJQ U1QsIHRycHN0X2NudCk7Cj4gPj4gKwkJcmVnIHw9IEZJRUxEX1BSRVAoVE9HR0xFX1RJTUlOR1Mx X1RXUFNULCB0d3BzdF9jbnQpOwo+ID4+ICsJCXQtPnRvZ2dsZV90aW1pbmdzXzEgPSByZWc7Cj4g Pj4gKwkJZGV2X2RiZyhjZG5zX2N0cmwtPmRldiwgIlRPR0dMRV9USU1JTkdTXzFfU0RSXHQleFxu IiwgcmVnKTsKPiA+PiArCX0gIAo+IFsuLi5dID4KPiA+VGhpcyBmdW5jdGlvbiBpcyBzbyBjb21w bGljYXRlZCAhISEgSG93IGNhbiB0aGlzIGV2ZW4gd29yaz8gUmVhbGx5LCBpdAo+ID5pcyBoYXJk IHRvIGdldCBpbnRvIHRoZSBjb2RlIGFuZCBmb2xsb3csIEkgYW0gc3VyZSB5b3UgY2FuIGRvCj4g PnNvbWV0aGluZy4gIAo+IFllcyBpdCBpcyBjb21wbGljYXRlZCBidXQgd29ya3MsIEkgd2lsbCB0 cnkgdG8gc2ltcGxpZnkgaXQuLi4gICBbLi4uXQoKWWVzIHBsZWFzZSEKCj4gPj4gKwkJCQkiQ1Mg JWQgYWxyZWFkeSBhc3NpZ25lZFxuIiwgY3MpOwo+ID4+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiA+ PiArCQl9Cj4gPj4gKwo+ID4+ICsJCWNkbnNfY2hpcC0+Y3NbaV0gPSBjczsKPiA+PiArCX0KPiA+ PiArCj4gPj4gKwljaGlwID0gJmNkbnNfY2hpcC0+Y2hpcDsKPiA+PiArCWNoaXAtPmNvbnRyb2xs ZXIgPSAmY2Ruc19jdHJsLT5jb250cm9sbGVyOwo+ID4+ICsJbmFuZF9zZXRfZmxhc2hfbm9kZShj aGlwLCBucCk7Cj4gPj4gKwo+ID4+ICsJbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gPj4gKwlt dGQtPmRldi5wYXJlbnQgPSBjZG5zX2N0cmwtPmRldjsKPiA+PiArCj4gPj4gKwkvKgo+ID4+ICsJ ICogRGVmYXVsdCB0byBIVyBFQ0MgZW5naW5lIG1vZGUuIElmIHRoZSBuYW5kLWVjYy1tb2RlIHBy b3BlcnR5IGlzIGdpdmVuCj4gPj4gKwkgKiBpbiB0aGUgRFQgbm9kZSwgdGhpcyBlbnRyeSB3aWxs IGJlIG92ZXJ3cml0dGVuIGluIG5hbmRfc2Nhbl9pZGVudCgpLgo+ID4+ICsJICovCj4gPj4gKwlj aGlwLT5lY2MubW9kZSA9IE5BTkRfRUNDX0hXOwo+ID4+ICsKPiA+PiArCS8qCj4gPj4gKwkgKiBT YXZlIGEgcmVmZXJlbmNlIHZhbHVlIGZvciB0aW1pbmcgcmVnaXN0ZXJzIGJlZm9yZQo+ID4+ICsJ ICogLT5zZXR1cF9kYXRhX2ludGVyZmFjZSgpIGlzIGNhbGxlZC4KPiA+PiArCSAqLwo+ID4+ICsJ Y2FkZW5jZV9uYW5kX2dldF90aW1pbmdzKGNkbnNfY3RybCwgJmNkbnNfY2hpcC0+dGltaW5ncyk7 ICAKPiA+Cj4gPllvdSBjYW5ub3QgcmVseSBvbiB0aGUgQm9vdGxvYWRlcidzIGNvbmZpZ3VyYXRp b24uIFRoaXMgZHJpdmVyIHNob3VsZAo+ID5kZXJpdmUgaXQuICAKPiBJIGRvIG5vdCByZWxheSBv biB0aGUgQm9vdGxvYWRlcidzIGNvbmZpZ3VyYXRpb24gaW4gYW55IHBhcnQuIEkganVzdAo+IGlu aXQgdGltaW5ncyBzdHJ1Y3R1cmUgYmFzZSBvbiBjdXJyZW50IHZhbHVlcyBvZiByZWdpc3RlcnMg dG8gZG8gbm90Cj4gICBoYXZlIHJ1YmlzaCBpbiB0aW1pbmcgc3RydWN0dXJlLiBWYWx1ZXMgd2ls bCBiZSBjYWxjdWxhdGVkIGJ5IGRyaXZlciB3aGVuCj4gc2V0dXBfZGF0YV9pbnRlcmZhY2UgaXMg Y2FsbGVkLiBJbiBjYXNlIHNldF90aW1pbmdzIGlzIGNhbGxlZCBiZWZvcmUKPiBzZXR1cF9kYXRh X2ludGVyZmFjZQoKRG9lcyB0aGlzIHJlYWxseSBoYXBwZW5zPyBJIGFtIHByZXR0eSBzdXJlIGl0 IGlzIHRha2VuIGNhcmUgb2YgYnkgdGhlCmNvcmUuIEkgZG9uJ3QgdGhpbmsgeW91IHNob3VsZCBy ZWx5IG9uIHdoYXQncyBpbiB0aGUgcmVnaXN0ZXJzIGF0IGJvb3QKdGltZS4KCj4gdGhlbiB3ZSB3 cml0ZSB0aGUgc2FtZSB2YWx1cyB0byB0aW1pbmcgcmVnaXN0ZXJzCj4gd2hpY2ggYXJlIHByZXNl dCBpbiByZWdpc3RyZXMuIFRvIGJlIHNob3J0ZXIgdGltaW5nIHJlZ2lzdGVycyB3aWxsIHN0YXkK PiB1bmNoYW5nZWQuICA+PiArCXJldCA9IG5hbmRfc2NhbihjaGlwLCBjZG5zX2NoaXAtPm5zZWxz KTsKPiA+PiArCWlmIChyZXQpIHsKPiA+PiArCQlkZXZfZXJyKGNkbnNfY3RybC0+ZGV2LCAiY291 bGQgbm90IHNjYW4gdGhlIG5hbmQgY2hpcFxuIik7Cj4gPj4gKwkJcmV0dXJuIHJldDsKPiA+PiAr CX0KPiA+PiArCj4gPj4gKwlyZXQgPSBtdGRfZGV2aWNlX3JlZ2lzdGVyKG10ZCwgTlVMTCwgMCk7 Cj4gPj4gKwlpZiAocmV0KSB7Cj4gPj4gKwkJZGV2X2VycihjZG5zX2N0cmwtPmRldiwKPiA+PiAr CQkJImZhaWxlZCB0byByZWdpc3RlciBtdGQgZGV2aWNlOiAlZFxuIiwgcmV0KTsKPiA+PiArCQlu YW5kX3JlbGVhc2UoY2hpcCk7ICAKPiA+Cj4gPkkgdGhpbmsgeW91IHNob3VsZCBjYWxsIG5hbmRf Y2xlYW51cCBpbnN0ZWFkIG9mIG5hbmRfcmVsZWFzZSBoZXJlIGhhcwo+ID50aGUgbXRkIGRldmlj ZSBpcyBub3QgcmVnaXN0ZXJlZCB5ZXQuCj4gPiAgCj4gPj4gKwkJcmV0dXJuIHJldDsKPiA+PiAr CX0KPiA+PiArCj4gPj4gKwlsaXN0X2FkZF90YWlsKCZjZG5zX2NoaXAtPm5vZGUsICZjZG5zX2N0 cmwtPmNoaXBzKTsKPiA+PiArCj4gPj4gKwlyZXR1cm4gMDsKPiA+PiArfQo+ID4+ICsKPiA+PiAr c3RhdGljIGludCBjYWRlbmNlX25hbmRfY2hpcHNfaW5pdChzdHJ1Y3QgY2Ruc19uYW5kX2N0cmwg KmNkbnNfY3RybCkKPiA+PiArewo+ID4+ICsJc3RydWN0IGRldmljZV9ub2RlICpucCA9IGNkbnNf Y3RybC0+ZGV2LT5vZl9ub2RlOwo+ID4+ICsJc3RydWN0IGRldmljZV9ub2RlICpuYW5kX25wOwo+ ID4+ICsJaW50IG1heF9jcyA9IGNkbnNfY3RybC0+Y2FwczIubWF4X2JhbmtzOwo+ID4+ICsJaW50 IG5jaGlwczsKPiA+PiArCWludCByZXQ7Cj4gPj4gKwo+ID4+ICsJbmNoaXBzID0gb2ZfZ2V0X2No aWxkX2NvdW50KG5wKTsKPiA+PiArCj4gPj4gKwlpZiAobmNoaXBzID4gbWF4X2NzKSB7Cj4gPj4g KwkJZGV2X2VycihjZG5zX2N0cmwtPmRldiwKPiA+PiArCQkJInRvbyBtYW55IE5BTkQgY2hpcHM6 ICVkIChtYXggPSAlZCBDUylcbiIsCj4gPj4gKwkJCW5jaGlwcywgbWF4X2NzKTsKPiA+PiArCQly ZXR1cm4gLUVJTlZBTDsKPiA+PiArCX0KPiA+PiArCj4gPj4gKwlmb3JfZWFjaF9jaGlsZF9vZl9u b2RlKG5wLCBuYW5kX25wKSB7Cj4gPj4gKwkJcmV0ID0gY2FkZW5jZV9uYW5kX2NoaXBfaW5pdChj ZG5zX2N0cmwsIG5hbmRfbnApOwo+ID4+ICsJCWlmIChyZXQpIHsKPiA+PiArCQkJb2Zfbm9kZV9w dXQobmFuZF9ucCk7Cj4gPj4gKwkJCXJldHVybiByZXQ7Cj4gPj4gKwkJfSAgCj4gPgo+ID5JZiBu YW5kX2NoaXBfaW5pdCgpIGZhaWxzIG9uIGFub3RoZXIgY2hpcCB0aGFuIHRoZSBmaXJzdCBvbmUs IHRoZXJlIGlzCj4gPnNvbWUgZ2FyYmFnZSBjb2xsZWN0aW9uIHRvIGRvLgo+ID4gIAo+ID4+ICsJ fQo+ID4+ICsKPiA+PiArCXJldHVybiAwOwo+ID4+ICt9Cj4gPj4gKwo+ID4+ICtzdGF0aWMgaW50 IGNhZGVuY2VfbmFuZF9pbml0KHN0cnVjdCBjZG5zX25hbmRfY3RybCAqY2Ruc19jdHJsKQo+ID4+ ICt7Cj4gPj4gKwlkbWFfY2FwX21hc2tfdCBtYXNrOwo+ID4+ICsJaW50IHJldCA9IDA7Cj4gPj4g Kwo+ID4+ICsJY2Ruc19jdHJsLT5jZG1hX2Rlc2MgPSBkbWFfYWxsb2NfY29oZXJlbnQoY2Ruc19j dHJsLT5kZXYsCj4gPj4gKwkJCQkJCSAgc2l6ZW9mKCpjZG5zX2N0cmwtPmNkbWFfZGVzYyksCj4g Pj4gKwkJCQkJCSAgJmNkbnNfY3RybC0+ZG1hX2NkbWFfZGVzYywKPiA+PiArCQkJCQkJICBHRlBf S0VSTkVMKTsKPiA+PiArCWlmICghY2Ruc19jdHJsLT5kbWFfY2RtYV9kZXNjKQo+ID4+ICsJCXJl dHVybiAtRU5PTUVNOwo+ID4+ICsKPiA+PiArCWNkbnNfY3RybC0+YnVmX3NpemUgPSAxNiAqIDEw MjQ7ICAKPiA+Cj4gPnMvMTAyNC9TWl8xSy8KPiA+ICAKPiA+PiArCWNkbnNfY3RybC0+YnVmID0g a21hbGxvYyhjZG5zX2N0cmwtPmJ1Zl9zaXplLCBHRlBfS0VSTkVMKTsgIAo+ID4KPiA+SWYgeW91 IHVzZSBrbWFsbG9jIGhlcmUgdGhlbiB0aGlzIGJ1ZmZlciB3aWxsIGFsd2F5cyBiZSBETUEtYWJs ZSwKPiA+cmlnaHQ/ICAKPiBSaWdodCBJIGhhdmUgc2VlbiBzdWNoIHNvbHV0aW9uIGluIGFub3Ro ZXIgZHJpdmVyLgo+IAo+IAo+IFRoYW5rcyBmb3IgcmV2aWV2aW5nIHRoaXMgcGF0Y2guIFBsZWFz ZSBhbnN3ZXIgb24gbXkgcXVlc3Rpb24gaG93IHdyaXRlX29vYgo+IGFuZCByZWFkX29vYiBmdW5j dGlvbnMgc2hvdWxkIGJlIGltcGxlbWVudGVkLgo+IAo+ID4KPiA+Cj4gPlRoYW5rcywKPiA+TWlx dcOobCAgCj4gCj4gICBUaGFua3MKPiBQaW90ciBTcm9rYQoKVGhhbmtzLApNaXF1w6hsCgpfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXgg TVREIGRpc2N1c3Npb24gbWFpbGluZyBsaXN0Cmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21h aWxtYW4vbGlzdGluZm8vbGludXgtbXRkLwo= 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 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 1E64FC04A6B for ; Sun, 12 May 2019 12:24:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C36C22173E for ; Sun, 12 May 2019 12:24:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726622AbfELMYx convert rfc822-to-8bit (ORCPT ); Sun, 12 May 2019 08:24:53 -0400 Received: from relay5-d.mail.gandi.net ([217.70.183.197]:58319 "EHLO relay5-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725934AbfELMYw (ORCPT ); Sun, 12 May 2019 08:24:52 -0400 X-Originating-IP: 109.190.253.16 Received: from xps13 (unknown [109.190.253.16]) (Authenticated sender: miquel.raynal@bootlin.com) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id F2C131C0004; Sun, 12 May 2019 12:24:38 +0000 (UTC) Date: Sun, 12 May 2019 14:24:26 +0200 From: Miquel Raynal To: Piotr Sroka Cc: , Boris Brezillon , Richard Weinberger , David Woodhouse , Brian Norris , Marek Vasut , Paul Burton , "Geert Uytterhoeven" , Arnd Bergmann , "Marcel Ziswiler" , Dmitry Osipenko , Stefan Agner , Subject: Re: [PATCH v2 1/2] mtd: nand: Add Cadence NAND controller driver Message-ID: <20190512142426.11453a6c@xps13> In-Reply-To: <20190321093356.GA19577@global.cadence.com> References: <20190219161406.4340-1-piotrs@cadence.com> <20190219161823.22466-1-piotrs@cadence.com> <20190305190954.6c38d681@xps13> <20190321093356.GA19577@global.cadence.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.1 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Piotr, Sorry for de delay. Piotr Sroka wrote on Thu, 21 Mar 2019 09:33:58 +0000: > The 03/05/2019 19:09, Miquel Raynal wrote: > >EXTERNAL MAIL > > > > > >Hi Piotr, > > > >Piotr Sroka wrote on Tue, 19 Feb 2019 16:18:23 > >+0000: > > > >> This patch adds driver for Cadence HPNFC NAND controller. > >> > >> Signed-off-by: Piotr Sroka > >> --- > >> Changes for v2: > >> - create one universal wait function for all events instead of one > >> function per event. > >> - split one big function executing nand operations to separate > >> functions one per each type of operation. > >> - add erase atomic operation to nand operation parser > >> - remove unnecessary includes. > >> - remove unused register defines > >> - add support for multiple nand chips > >> - remove all code using legacy functions > >> - remove chip dependents parameters from dts bindings, they were > >> attached to the SoC specific compatible at the driver level > >> - simplify interrupt handling > >> - simplify timing calculations > >> - fix calculation of maximum supported cs signals > >> - simplify ecc size calculation > >> - remove header file and put whole code to one c file > >> --- > >> drivers/mtd/nand/raw/Kconfig | 8 + > >> drivers/mtd/nand/raw/Makefile | 1 + > >> drivers/mtd/nand/raw/cadence-nand-controller.c | 3288 ++++++++++++++++++++++++ > > > >This driver is way too massive, I am pretty sure it can shrink a > >little bit more. > >[...] > > > I will try to make it shorer but it will be difucult to achive. It is because - there are a lot of calculation needed for PHY - ECC are interleaved with data (like on marvell-nand or gpmi-nand). > Therefore: + RAW mode is complicated + protecting BBM increases number of lines of source code > - need to support two DMA engines internal and external (slave) We will see on next patch version what is the result. That page layout looks: Maybe you don't need to support both internal and external DMA? I am pretty sure there are rooms for size reduction. > > +----------------------------------------- > | Data 1 | ECC 1 | ... | Data N | ECC N | +----------------------------------------- > > ----------------------------------+ > Last Data | OOB bytes | Last ECC | > ----------------------------------+ > /\ || OOB area started > usualy vendor specified BBM > > Flash OOB area starts somewhere in last data sector. Flash OOB area contains part of last sector, oob data (accessible by driver), and last ECC code >> + > >> +struct cdns_nand_chip { > >> + struct cadence_nand_timings timings; > >> + struct nand_chip chip; > >> + u8 nsels; > >> + struct list_head node; > >> + > >> + /* > >> + * part of oob area of NANF flash memory page. > >> + * This part is available for user to read or write. > >> + */ > >> + u32 avail_oob_size; > >> + /* oob area size of NANF flash memory page */ > >> + u32 oob_size; > >> + /* main area size of NANF flash memory page */ > >> + u32 main_size; > > > >These fields are redundant and exist in mtd_info/nand_chip. > > > Ok I will use the parameters from mtd_info. > >> + > >> + /* sector size few sectors are located on main area of NF memory page */ > >> + u32 sector_size; > >> + u32 sector_count; > >> + > >> + /* offset of BBM*/ > >> + u8 bbm_offs; > >> + /* number of bytes reserved for BBM */ > >> + u8 bbm_len; > > > >Why do you bother at the controller driver level with bbm? > > > When ECC is enabled then BBM is somewhere in last data sector. So for write operation real BBM will be overwritten. For read operation > it will be read from wrong offset. To protect BBM we use HW feature skip bytes. To be able to properly configure this feature we need to > know what is the offset of BBM. >> + > >> +static int cadence_nand_set_erase_detection(struct cdns_nand_ctrl *cdns_ctrl, > >> + bool enable, > >> + u8 bitflips_threshold) > > > >What is this for? > Fucntions enables/disables hardware detection of erased data > pages. > Ok, the name is not very explicit , maybe you could tell this with a comment. > >> + > >> +/* hardware initialization */ > >> +static int cadence_nand_hw_init(struct cdns_nand_ctrl *cdns_ctrl) > >> +{ > >> + int status = 0; > >> + u32 reg; > >> + > >> + status = cadence_nand_wait_for_value(cdns_ctrl, CTRL_STATUS, > >> + 1000000, > >> + CTRL_STATUS_INIT_COMP, false); > >> + if (status) > >> + return status; > >> + > >> + reg = readl(cdns_ctrl->reg + CTRL_VERSION); > >> + > >> + dev_info(cdns_ctrl->dev, > >> + "%s: cadence nand controller version reg %x\n", > >> + __func__, reg); > >> + > >> + /* disable cache and multiplane */ > >> + writel(0, cdns_ctrl->reg + MULTIPLANE_CFG); > >> + writel(0, cdns_ctrl->reg + CACHE_CFG); > >> + > >> + /* clear all interrupts */ > >> + writel(0xFFFFFFFF, cdns_ctrl->reg + INTR_STATUS); > >> + > >> + cadence_nand_get_caps(cdns_ctrl); > >> + cadence_nand_read_bch_cfg(cdns_ctrl); > > > >No, you cannot rely on the bootloader's configuration. And I suppose > >this is what the first call to read_bch_cfg does? > I do not realy on boot loader. Just read NAND flash > controller configuration from read only capabilities registers. Ok, if these are RO registers, it's fine. But maybe don't call the function "read bch config" which suggest that this is something you can change. > > > >> + > >> +#define TT_OOB_AREA 1 > >> +#define TT_MAIN_OOB_AREAS 2 > >> +#define TT_RAW_PAGE 3 > >> +#define TT_BBM 4 > >> +#define TT_MAIN_OOB_AREA_EXT 5 > >> + > >> +/* prepare size of data to transfer */ > >> +static int > >> +cadence_nand_prepare_data_size(struct nand_chip *chip, > >> + int transfer_type) > >> +{ > >> + struct cdns_nand_ctrl *cdns_ctrl = to_cdns_nand_ctrl(chip->controller); > >> + struct cdns_nand_chip *cdns_chip = to_cdns_nand_chip(chip); > >> + u32 sec_size = 0, last_sec_size, offset = 0, sec_cnt = 1; > >> + u32 ecc_size = chip->ecc.bytes; > >> + u32 data_ctrl_size = 0; > >> + u32 reg = 0; > >> + > >> + if (cdns_ctrl->curr_trans_type == transfer_type) > >> + return 0; > >> + > >> + switch (transfer_type) { > > > >Please turn the controller driver as dumb as possible. You should not > >care which part of the OOB area you are accessing. > It is a bit confusing for me how accessing OOB should be implemented. > I know that read_oob function is called to check BBM value when BBT is > initialized. It is also a bit confusing for me why the raw version is > not used for that purpose. In current implementation if you write oob by write_page function next > read oob by read_oob function then data will be the same. > If I implement dump functions read_oob and write_oob then > 1. ECC must be disabled for these functions > 2. oob data accessing by write_page/read_page will be different > (different offsets) that the data accessing by read_oob/write_oob > functions No, I fear this is not acceptable. > If above described "functionalities" are acceptable I will change implementation of write_oob and read_oob functions. > The write_page and read_page must be implemented in that way as it is now. Let me know which solution is preffered. If this is too complicated to just write the oob, why not fallback on read/write_page (with oob_required and a dummy data buffer)? > > >> + case TT_OOB_AREA: > >> + offset = cdns_chip->main_size - cdns_chip->sector_size; > >> + ecc_size = ecc_size * (offset / cdns_chip->sector_size); > >> + offset = offset + ecc_size; > >> + sec_cnt = 1; > >> + last_sec_size = cdns_chip->sector_size > >> + + cdns_chip->avail_oob_size; > >> + break; > >> + case TT_MAIN_OOB_AREA_EXT: > >> + sec_cnt = cdns_chip->sector_count; > >> + last_sec_size = cdns_chip->sector_size; > >> + sec_size = cdns_chip->sector_size; > >> + data_ctrl_size = cdns_chip->avail_oob_size; > >> + break; > >> + case TT_MAIN_OOB_AREAS: > >> + sec_cnt = cdns_chip->sector_count; > >> + last_sec_size = cdns_chip->sector_size > >> + + cdns_chip->avail_oob_size; > >> + sec_size = cdns_chip->sector_size; > >> + break; > >> + case TT_RAW_PAGE: > >> + last_sec_size = cdns_chip->main_size + cdns_chip->oob_size; > >> + break; > >> + case TT_BBM: > >> + offset = cdns_chip->main_size + cdns_chip->bbm_offs; > >> + last_sec_size = 8; > >> + break; > >> + default: > >> + dev_err(cdns_ctrl->dev, "Data size preparation failed\n"); > >> + return -EINVAL; > >> + } > >> + > >> + reg = 0; > >> + reg |= FIELD_PREP(TRAN_CFG_0_OFFSET, offset); > >> + reg |= FIELD_PREP(TRAN_CFG_0_SEC_CNT, sec_cnt); > >> + writel(reg, cdns_ctrl->reg + TRAN_CFG_0); > >> + > >> + reg = 0; > >> + reg |= FIELD_PREP(TRAN_CFG_1_LAST_SEC_SIZE, last_sec_size); > >> + reg |= FIELD_PREP(TRAN_CFG_1_SECTOR_SIZE, sec_size); > >> + writel(reg, cdns_ctrl->reg + TRAN_CFG_1); > >> + > >> + reg = readl(cdns_ctrl->reg + CONTROL_DATA_CTRL); > >> + reg &= ~CONTROL_DATA_CTRL_SIZE; > >> + reg |= FIELD_PREP(CONTROL_DATA_CTRL_SIZE, data_ctrl_size); > >> + writel(reg, cdns_ctrl->reg + CONTROL_DATA_CTRL); > >> + > >> + cdns_ctrl->curr_trans_type = transfer_type; > >> + > >> + return 0; > >> +} > >> + > > > >[...] > > > >> + > >> +static int cadence_nand_read_page_raw(struct nand_chip *chip, > >> + u8 *buf, int oob_required, int page) > >> +{ > >> + struct cdns_nand_ctrl *cdns_ctrl = to_cdns_nand_ctrl(chip->controller); > >> + struct cdns_nand_chip *cdns_chip = to_cdns_nand_chip(chip); > >> + int oob_skip = cdns_chip->bbm_len; > > > >Why do you skip the BBM? > > > >In any of the read_page/oob helpers I don't think this is relevant at > >all. > I described the problem at the beginnig. ECC are interleaved with data. > So real possition of BBM is somewehre in last data sector. We use skip > byte feature to skip this BBM. Once used need to handle in each > function. Skip BBM is also used in denali-nand > > > >> + int writesize = cdns_chip->main_size; > >> + int ecc_steps = chip->ecc.steps; > >> + int ecc_size = chip->ecc.size; > >> + int ecc_bytes = chip->ecc.bytes; > >> + void *tmp_buf = cdns_ctrl->buf; > >> + int i, pos, len; > >> + int status = 0; > >> + > >> + status = cadence_nand_select_target(chip); > >> + if (status) > >> + return status; > >> + > >> + cadence_nand_set_skip_bytes_conf(cdns_ctrl, 0, 0, 0); > >> + > >> + cadence_nand_prepare_data_size(chip, TT_RAW_PAGE); > >> + status = cadence_nand_cdma_transfer(cdns_ctrl, > >> + cdns_chip->cs[chip->cur_cs], > >> + page, cdns_ctrl->buf, > >> + NULL, > >> + cdns_chip->main_size > >> + + cdns_chip->oob_size, > >> + 0, DMA_FROM_DEVICE, false); > >> + > >> + switch (status) { > >> + case STAT_ERASED: > >> + case STAT_OK: > >> + break; > >> + default: > >> + dev_err(cdns_ctrl->dev, "read raw page failed\n"); > >> + return -EIO; > >> + } > >> + > >> + /* 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; > >> + } > >> + } > >> + } > >> + > >> + if (oob_required) { > >> + u8 *oob = chip->oob_poi; > >> + u32 oob_data_offset = (cdns_chip->sector_count - 1) * > >> + (cdns_chip->sector_size + chip->ecc.bytes) > >> + + cdns_chip->sector_size + oob_skip; > >> + > >> + /* OOB free */ > >> + memcpy(oob, tmp_buf + oob_data_offset, > >> + cdns_chip->avail_oob_size); > >> + > >> + /* BBM at the beginning of the OOB area */ > >> + memcpy(oob, tmp_buf + writesize, oob_skip); > >> + > >> + oob += cdns_chip->avail_oob_size; > >> + > >> + /* OOB ECC */ > >> + for (i = 0; i < ecc_steps; i++) { > >> + pos = ecc_size + i * (ecc_size + ecc_bytes); > >> + len = ecc_bytes; > >> + > >> + if (i == (ecc_steps - 1)) > >> + pos += cdns_chip->avail_oob_size; > >> + > >> + if (pos >= writesize) > >> + pos += oob_skip; > >> + else if (pos + len > writesize) > >> + len = writesize - pos; > >> + > >> + memcpy(oob, tmp_buf + pos, len); > >> + oob += len; > >> + if (len < ecc_bytes) { > >> + len = ecc_bytes - len; > >> + memcpy(oob, tmp_buf + writesize + oob_skip, > >> + len); > >> + oob += len; > >> + } > >> + } > >> + } > >> + > >> + return 0; > >> +} > [ ...] > >> +} > >> + > >> +static int cadence_nand_read_buf(struct cdns_nand_ctrl *cdns_ctrl, > >> +static int cadence_nand_write_buf(struct cdns_nand_ctrl *cdns_ctrl, > >> +static int cadence_nand_cmd_opcode(struct nand_chip *chip, > >> +static int cadence_nand_cmd_address(struct nand_chip *chip, > >> +static int cadence_nand_cmd_erase(struct nand_chip *chip, > >> +static int cadence_nand_cmd_data(struct nand_chip *chip, > > > >This looks pretty familiar with the legacy approach, I think you just > >renamed some functions instead of trying to fit the ->exec_op interface > >and there is probably a lot to do on this side that would reduce the > >driver size. There are plenty of operations done by each of the above > >helpers that should probably factored out. > > > No I have never used legacy approach for that part. > In previous patch I have one function to hanlde it but Boris point > that one function containing switch is not a good solution so I splited > to few functions. ok >> + > >> +static const struct nand_op_parser cadence_nand_op_parser = NAND_OP_PARSER( > >> + NAND_OP_PARSER_PATTERN( > >> + cadence_nand_cmd_erase, > >> + NAND_OP_PARSER_PAT_CMD_ELEM(false), > >> + NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ERASE_ADDRESS_CYC), > >> + NAND_OP_PARSER_PAT_CMD_ELEM(false), > >> + NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)), > >> + NAND_OP_PARSER_PATTERN( > >> + cadence_nand_cmd_opcode, > >> + NAND_OP_PARSER_PAT_CMD_ELEM(false)), > >> + NAND_OP_PARSER_PATTERN( > >> + cadence_nand_cmd_address, > >> + NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ADDRESS_CYC)), > >> + NAND_OP_PARSER_PATTERN( > >> + cadence_nand_cmd_data, > >> + NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, MAX_DATA_SIZE)), > >> + NAND_OP_PARSER_PATTERN( > >> + cadence_nand_cmd_data, > >> + NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, MAX_DATA_SIZE)), > >> + NAND_OP_PARSER_PATTERN( > >> + cadence_nand_cmd_waitrdy, > >> + NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)) > >> + ); > >> + > >> +static int cadence_nand_exec_op(struct nand_chip *chip, > >> + const struct nand_operation *op, > >> + bool check_only) > >> +{ > >> + int status = cadence_nand_select_target(chip); > >> + > >> + if (status) > >> + return status; > >> + > >> + return nand_op_parser_exec_op(chip, &cadence_nand_op_parser, op, > >> + check_only); > >> +} > >> + > >> +static int cadence_nand_ooblayout_free(struct mtd_info *mtd, int section, > >> + struct mtd_oob_region *oobregion) > >> +{ > >> + struct nand_chip *chip = mtd_to_nand(mtd); > >> + struct cdns_nand_chip *cdns_chip = to_cdns_nand_chip(chip); > >> + > >> + if (section) > >> + return -ERANGE; > >> + > >> + oobregion->offset = cdns_chip->bbm_len; > >> + oobregion->length = cdns_chip->avail_oob_size > >> + - cdns_chip->bbm_len; > >> + > >> + return 0; > >> +} > >> + > >> +static int cadence_nand_ooblayout_ecc(struct mtd_info *mtd, int section, > >> + struct mtd_oob_region *oobregion) > >> +{ > >> + struct nand_chip *chip = mtd_to_nand(mtd); > >> + struct cdns_nand_chip *cdns_chip = to_cdns_nand_chip(chip); > >> + > >> + if (section) > >> + return -ERANGE; > >> + > >> + oobregion->offset = cdns_chip->avail_oob_size; > >> + oobregion->length = chip->ecc.total; > >> + > >> + return 0; > >> +} > >> + > >> +static const struct mtd_ooblayout_ops cadence_nand_ooblayout_ops = { > >> + .free = cadence_nand_ooblayout_free, > >> + .ecc = cadence_nand_ooblayout_ecc, > >> +}; > >> + > >> +static int calc_cycl(u32 timing, u32 clock) > >> +{ > >> + if (timing == 0 || clock == 0) > >> + return 0; > >> + > >> + if ((timing % clock) > 0) > >> + return timing / clock; > >> + else > >> + return timing / clock - 1; > >> +} > >> + > [...] >> + /* > >> + * the idea of those calculation is to get the optimum value > >> + * for tRP and tRH timings if it is NOT possible to sample data > >> + * with optimal tRP/tRH settings the parameters will be extended > >> + */ > >> + if (sdr->tRC_min <= clk_period && > >> + sdr->tRP_min <= (clk_period / 2) && > >> + sdr->tREH_min <= (clk_period / 2)) { > > > >Will this situation really happen? > I think yes for follwing values trc_min 20000 ps > trp_min 10000 ps > treh_min 7000 ps > clk_period 20000 ps Ok, you may add a comment stating that this may be the case in EDO mode 5. > [...] > >> + } > >> + > >> + if (cdns_ctrl->caps2.is_phy_type_dll) { > > > >Is the else part allowed? > > > following register does not exist if caps2.is_phy_type_dll is 0 >> + u32 tpre_cnt = calc_cycl(tpre, clk_period); > >> + u32 tcdqss_cnt = calc_cycl(tcdqss + if_skew, clk_period); > >> + u32 tpsth_cnt = calc_cycl(tpsth + if_skew, clk_period); > >> + > >> + u32 trpst_cnt = calc_cycl(trpst + if_skew, clk_period) + 1; > >> + u32 twpst_cnt = calc_cycl(twpst + if_skew, clk_period) + 1; > >> + u32 tcres_cnt = calc_cycl(tcres + if_skew, clk_period) + 1; > >> + u32 tcdqsh_cnt = calc_cycl(tcdqsh + if_skew, clk_period) + 5; > >> + > >> + tcr_cnt = calc_cycl(tcr + if_skew, clk_period); > >> + /* > >> + * skew not included because this timing defines duration of > >> + * RE or DQS before data transfer > >> + */ > >> + tpsth_cnt = tpsth_cnt + 1; > >> + reg = FIELD_PREP(TOGGLE_TIMINGS0_TPSTH, tpsth_cnt); > >> + reg |= FIELD_PREP(TOGGLE_TIMINGS0_TCDQSS, tcdqss_cnt); > >> + reg |= FIELD_PREP(TOGGLE_TIMINGS0_TPRE, tpre_cnt); > >> + reg |= FIELD_PREP(TOGGLE_TIMINGS0_TCR, tcr_cnt); > >> + t->toggle_timings_0 = reg; > >> + dev_dbg(cdns_ctrl->dev, "TOGGLE_TIMINGS_0_SDR\t%x\n", reg); > >> + > >> + //toggle_timings_1 - tRPST,tWPST > >> + reg = FIELD_PREP(TOGGLE_TIMINGS1_TCDQSH, tcdqsh_cnt); > >> + reg |= FIELD_PREP(TOGGLE_TIMINGS1_TCRES, tcres_cnt); > >> + reg |= FIELD_PREP(TOGGLE_TIMINGS1_TRPST, trpst_cnt); > >> + reg |= FIELD_PREP(TOGGLE_TIMINGS1_TWPST, twpst_cnt); > >> + t->toggle_timings_1 = reg; > >> + dev_dbg(cdns_ctrl->dev, "TOGGLE_TIMINGS_1_SDR\t%x\n", reg); > >> + } > [...] > > >This function is so complicated !!! How can this even work? Really, it > >is hard to get into the code and follow, I am sure you can do > >something. > Yes it is complicated but works, I will try to simplify it... [...] Yes please! > >> + "CS %d already assigned\n", cs); > >> + return -EINVAL; > >> + } > >> + > >> + cdns_chip->cs[i] = cs; > >> + } > >> + > >> + chip = &cdns_chip->chip; > >> + chip->controller = &cdns_ctrl->controller; > >> + nand_set_flash_node(chip, np); > >> + > >> + mtd = nand_to_mtd(chip); > >> + mtd->dev.parent = cdns_ctrl->dev; > >> + > >> + /* > >> + * Default to HW ECC engine mode. If the nand-ecc-mode property is given > >> + * in the DT node, this entry will be overwritten in nand_scan_ident(). > >> + */ > >> + chip->ecc.mode = NAND_ECC_HW; > >> + > >> + /* > >> + * Save a reference value for timing registers before > >> + * ->setup_data_interface() is called. > >> + */ > >> + cadence_nand_get_timings(cdns_ctrl, &cdns_chip->timings); > > > >You cannot rely on the Bootloader's configuration. This driver should > >derive it. > I do not relay on the Bootloader's configuration in any part. I just > init timings structure base on current values of registers to do not > have rubish in timing structure. Values will be calculated by driver when > setup_data_interface is called. In case set_timings is called before > setup_data_interface Does this really happens? I am pretty sure it is taken care of by the core. I don't think you should rely on what's in the registers at boot time. > then we write the same valus to timing registers > which are preset in registres. To be shorter timing registers will stay > unchanged. >> + ret = nand_scan(chip, cdns_chip->nsels); > >> + if (ret) { > >> + dev_err(cdns_ctrl->dev, "could not scan the nand chip\n"); > >> + return ret; > >> + } > >> + > >> + ret = mtd_device_register(mtd, NULL, 0); > >> + if (ret) { > >> + dev_err(cdns_ctrl->dev, > >> + "failed to register mtd device: %d\n", ret); > >> + nand_release(chip); > > > >I think you should call nand_cleanup instead of nand_release here has > >the mtd device is not registered yet. > > > >> + return ret; > >> + } > >> + > >> + list_add_tail(&cdns_chip->node, &cdns_ctrl->chips); > >> + > >> + return 0; > >> +} > >> + > >> +static int cadence_nand_chips_init(struct cdns_nand_ctrl *cdns_ctrl) > >> +{ > >> + struct device_node *np = cdns_ctrl->dev->of_node; > >> + struct device_node *nand_np; > >> + int max_cs = cdns_ctrl->caps2.max_banks; > >> + int nchips; > >> + int ret; > >> + > >> + nchips = of_get_child_count(np); > >> + > >> + if (nchips > max_cs) { > >> + dev_err(cdns_ctrl->dev, > >> + "too many NAND chips: %d (max = %d CS)\n", > >> + nchips, max_cs); > >> + return -EINVAL; > >> + } > >> + > >> + for_each_child_of_node(np, nand_np) { > >> + ret = cadence_nand_chip_init(cdns_ctrl, nand_np); > >> + if (ret) { > >> + of_node_put(nand_np); > >> + return ret; > >> + } > > > >If nand_chip_init() fails on another chip than the first one, there is > >some garbage collection to do. > > > >> + } > >> + > >> + return 0; > >> +} > >> + > >> +static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) > >> +{ > >> + dma_cap_mask_t mask; > >> + int ret = 0; > >> + > >> + cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev, > >> + sizeof(*cdns_ctrl->cdma_desc), > >> + &cdns_ctrl->dma_cdma_desc, > >> + GFP_KERNEL); > >> + if (!cdns_ctrl->dma_cdma_desc) > >> + return -ENOMEM; > >> + > >> + cdns_ctrl->buf_size = 16 * 1024; > > > >s/1024/SZ_1K/ > > > >> + cdns_ctrl->buf = kmalloc(cdns_ctrl->buf_size, GFP_KERNEL); > > > >If you use kmalloc here then this buffer will always be DMA-able, > >right? > Right I have seen such solution in another driver. > > > Thanks for revieving this patch. Please answer on my question how write_oob > and read_oob functions should be implemented. > > > > > > >Thanks, > >Miquèl > > Thanks > Piotr Sroka Thanks, Miquèl