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=-8.2 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_2 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 5DBB8C54E4A for ; Thu, 7 May 2020 15:09:51 +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 3149B20838 for ; Thu, 7 May 2020 15:09:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="XYA0Lyn8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3149B20838 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=p+oTIxCT2oO2H4m/2p7kUUND0QXjs2g3276N4MVWirk=; b=XYA0Lyn8UX6fcv vhmWrLsOJCEUSLALUvyMM0qEHo35mdRv/vi1t9UXs1mDXMcSDL5ODW8Qtdlg9peO9likjgKgFyRVh Cr2DTxsufa/4oOChKnpT37mkz2Z/lcqTu420C7LcKS/tc6VKjKzYaOM7Ekax62Y1Z2SKkUDWZWPUr i9d7qWjjqjWObjdoPDE3NcX0hvON2LiamMSztssdx7y5OpU5Gt8TQlt64qvvRluzSEMjKfTRU4mp7 QX109qXSBqFSDUkG+F7YoOVg+dFe9jNF6aG9lm3y6KefVtD4tyT0X0sWz1EJEhlkU5FkVFyELSTu4 ORCsXeIpi8gHJ4voWHwQ==; 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 1jWi9Z-0005fs-EM; Thu, 07 May 2020 15:09:37 +0000 Received: from relay12.mail.gandi.net ([217.70.178.232]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jWi9T-0005c5-L5 for linux-mtd@lists.infradead.org; Thu, 07 May 2020 15:09:36 +0000 Received: from xps13 (unknown [91.224.148.103]) (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 9BA89200006; Thu, 7 May 2020 15:09:27 +0000 (UTC) Date: Thu, 7 May 2020 17:09:26 +0200 From: Miquel Raynal To: Boris Brezillon Subject: Re: [PATCH v3 8/8] mtd: rawnand: arasan: Support the hardware BCH ECC engine Message-ID: <20200507170926.1dd85246@xps13> In-Reply-To: <20200507140336.02b3edff@collabora.com> References: <20200507110034.14736-1-miquel.raynal@bootlin.com> <20200507110034.14736-9-miquel.raynal@bootlin.com> <20200507140336.02b3edff@collabora.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.4 (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-20200507_080931_972416_02BCD6C2 X-CRM114-Status: GOOD ( 33.86 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, Michal Simek , Vignesh Raghavendra , Tudor Ambarus , Richard Weinberger , Rob Herring , linux-mtd@lists.infradead.org, Thomas Petazzoni , Naga Sureshkumar Relli 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 SGkgQm9yaXMsCgpCb3JpcyBCcmV6aWxsb24gPGJvcmlzLmJyZXppbGxvbkBjb2xsYWJvcmEuY29t PiB3cm90ZSBvbiBUaHUsIDcgTWF5CjIwMjAgMTQ6MDM6MzYgKzAyMDA6Cgo+IE9uIFRodSwgIDcg TWF5IDIwMjAgMTM6MDA6MzQgKzAyMDAKPiBNaXF1ZWwgUmF5bmFsIDxtaXF1ZWwucmF5bmFsQGJv b3RsaW4uY29tPiB3cm90ZToKPiAKPiA+IEFkZCBzdXBwb3J0IGZvciB0aGUgaGFyZHdhcmUgRUND IEJDSCBlbmdpbmUuCj4gPiAKPiA+IFBsZWFzZSBtaW5kIHRoYXQgdGhpcyBlbmdpbmUgYXMgYW4g aW1wb3J0YW50IGxpbWl0YXRpb246ICAKPiAKPiAJCQkJXmhhcwoKT29wcwoKPiAKPiA+IEJDSCBp bXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBpbmZvcm0gdGhlIHVzZXIgd2hlbiBhbiB1bmNvcnJlY3Rh YmxlIEVDQwo+ID4gZXJyb3Igb2NjdXJzLiBUbyB3b3JrYXJvdW5kIHRoaXMsIHdlIGF2b2lkIHVz aW5nIHRoZSBoYXJkd2FyZSBlbmdpbmUKPiA+IGluIHRoZSByZWFkIHBhdGggYW5kIGRvIHRoZSBj b21wdXRhdGlvbiB3aXRoIHRoZSBzb2Z0d2FyZSBCQ0gKPiA+IGltcGxlbWVudGF0aW9uLCB3aGlj aCBpcyBmYXN0ZXIgdGhhbiBtaXhpbmcgaGFyZHdhcmUgKGZvciBjb3JyZWN0aW9uKQo+ID4gYW5k IHNvZnR3YXJlIChmb3IgdmVyaWZpY2F0aW9uKS4KPiA+IAo+ID4gU2lnbmVkLW9mZi1ieTogTWlx dWVsIFJheW5hbCA8bWlxdWVsLnJheW5hbEBib290bGluLmNvbT4KPiA+IC0tLQo+ID4gIGRyaXZl cnMvbXRkL25hbmQvcmF3L2FyYXNhbi1uYW5kLWNvbnRyb2xsZXIuYyB8IDM0MCArKysrKysrKysr KysrKysrKysKPiA+ICAxIGZpbGUgY2hhbmdlZCwgMzQwIGluc2VydGlvbnMoKykKPiA+IAo+ID4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQvcmF3L2FyYXNhbi1uYW5kLWNvbnRyb2xsZXIu YyBiL2RyaXZlcnMvbXRkL25hbmQvcmF3L2FyYXNhbi1uYW5kLWNvbnRyb2xsZXIuYwo+ID4gaW5k ZXggNjFlYTkwZWNmODZlLi4wMWMwYTc0MWI0Y2QgMTAwNjQ0Cj4gPiAtLS0gYS9kcml2ZXJzL210 ZC9uYW5kL3Jhdy9hcmFzYW4tbmFuZC1jb250cm9sbGVyLmMKPiA+ICsrKyBiL2RyaXZlcnMvbXRk L25hbmQvcmF3L2FyYXNhbi1uYW5kLWNvbnRyb2xsZXIuYwo+ID4gQEAgLTEwLDYgKzEwLDcgQEAK PiA+ICAgKiAgIE5hZ2EgU3VyZXNoa3VtYXIgUmVsbGkgPG5hZ2FzdXJlQHhpbGlueC5jb20+Cj4g PiAgICovCj4gPiAgCj4gPiArI2luY2x1ZGUgPGxpbnV4L2JjaC5oPgo+ID4gICNpbmNsdWRlIDxs aW51eC9iaXRmaWVsZC5oPgo+ID4gICNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPiA+ICAjaW5jbHVk ZSA8bGludXgvZGVsYXkuaD4KPiA+IEBAIC0xNDMsNiArMTQ0LDEwIEBAIHN0cnVjdCBhbmZjX29w IHsKPiA+ICAgKiBAc3RyZW5ndGg6CQlSZWdpc3RlciB2YWx1ZSBvZiB0aGUgRUNDIHN0cmVuZ3Ro Cj4gPiAgICogQHJhZGRyX2N5Y2xlczoJUm93IGFkZHJlc3MgY3ljbGUgaW5mb3JtYXRpb24KPiA+ ICAgKiBAY2FkZHJfY3ljbGVzOglDb2x1bW4gYWRkcmVzcyBjeWNsZSBpbmZvcm1hdGlvbgo+ID4g KyAqIEBlY2NfYml0czoJCUV4YWN0IG51bWJlciBvZiBFQ0MgYml0cyBwZXIgc3luZHJvbWUKPiA+ ICsgKiBAZWNjX3RvdGFsOgkJVG90YWwgbnVtYmVyIG9mIEVDQyBieXRlcwo+ID4gKyAqIEBod19l Y2M6CQlCdWZmZXIgdG8gc3RvcmUgc3luZHJvbWVzIGNvbXB1dGVkIGJ5IGhhcmR3YXJlCj4gPiAr ICogQGJjaDoJCUJDSCBzdHJ1Y3R1cmUKPiA+ICAgKi8KPiA+ICBzdHJ1Y3QgYW5hbmQgewo+ID4g IAlzdHJ1Y3QgbGlzdF9oZWFkIG5vZGU7Cj4gPiBAQCAtMTU2LDYgKzE2MSwxMCBAQCBzdHJ1Y3Qg YW5hbmQgewo+ID4gIAl1MzIgc3RyZW5ndGg7Cj4gPiAgCXUxNiByYWRkcl9jeWNsZXM7Cj4gPiAg CXUxNiBjYWRkcl9jeWNsZXM7Cj4gPiArCXVuc2lnbmVkIGludCBlY2NfYml0czsKPiA+ICsJdW5z aWduZWQgaW50IGVjY190b3RhbDsKPiA+ICsJdTggKmh3X2VjYzsKPiA+ICsJc3RydWN0IGJjaF9j b250cm9sICpiY2g7Cj4gPiAgfTsKPiA+ICAKPiA+ICAvKioKPiA+IEBAIC0xNjgsNiArMTc3LDcg QEAgc3RydWN0IGFuYW5kIHsKPiA+ICAgKiBAY2hpcHM6CQlMaXN0IG9mIGFsbCBOQU5EIGNoaXBz IGF0dGFjaGVkIHRvIHRoZSBjb250cm9sbGVyCj4gPiAgICogQGFzc2lnbmVkX2NzOglCaXRtYXNr IGRlc2NyaWJpbmcgYWxyZWFkeSBhc3NpZ25lZCBDUyBsaW5lcwo+ID4gICAqIEBjdXJfY2xrOgkJ Q3VycmVudCBjbG9jayByYXRlCj4gPiArICogQGVycmxvYzoJCUFycmF5IG9mIGVycm9ycyBsb2Nh dGVkIHdpdGggc29mdCBCQ0gKPiA+ICAgKiBAYmY6CQkJQXJyYXkgb2YgYml0ZmxpcHMgcmVhZCBp biBlYWNoIEVDQyBzdGVwCj4gPiAgICovCj4gPiAgc3RydWN0IGFyYXNhbl9uZmMgewo+ID4gQEAg LTE3OSw2ICsxODksNyBAQCBzdHJ1Y3QgYXJhc2FuX25mYyB7Cj4gPiAgCXN0cnVjdCBsaXN0X2hl YWQgY2hpcHM7Cj4gPiAgCXVuc2lnbmVkIGxvbmcgYXNzaWduZWRfY3M7Cj4gPiAgCXVuc2lnbmVk IGludCBjdXJfY2xrOwo+ID4gKwl1bnNpZ25lZCBpbnQgKmVycmxvYzsKPiA+ICAJdTggKmJmOwo+ ID4gIH07Cj4gPiAgCj4gPiBAQCAtMjU3LDYgKzI2OCwyMDYgQEAgc3RhdGljIGludCBhbmZjX2xl bl90b19zdGVwcyhzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCB1bnNpZ25lZCBpbnQgbGVuKQo+ID4g IAlyZXR1cm4gc3RlcHM7Cj4gPiAgfQo+ID4gIAo+ID4gK3N0YXRpYyB2b2lkIGFuZmNfZXh0cmFj dF9lY2NfYml0cyhzdHJ1Y3QgYW5hbmQgKmFuYW5kLCBjb25zdCB1OCAqZWNjKQo+ID4gK3sKPiA+ ICsJc3RydWN0IG5hbmRfY2hpcCAqY2hpcCA9ICZhbmFuZC0+Y2hpcDsKPiA+ICsJaW50IHN0ZXA7 Cj4gPiArCj4gPiArCW1lbXNldChhbmFuZC0+aHdfZWNjLCAwLCBjaGlwLT5lY2MuYnl0ZXMgKiBj aGlwLT5lY2Muc3RlcHMpOwo+ID4gKwo+ID4gKwlmb3IgKHN0ZXAgPSAwOyBzdGVwIDwgY2hpcC0+ ZWNjLnN0ZXBzOyBzdGVwKyspIHsKPiA+ICsJCXVuc2lnbmVkIGludCBzcmNfb2ZmID0gYW5hbmQt PmVjY19iaXRzICogc3RlcDsKPiA+ICsJCXU4ICpkc3QgPSAmYW5hbmQtPmh3X2VjY1tjaGlwLT5l Y2MuYnl0ZXMgKiBzdGVwXTsKPiA+ICsKPiA+ICsJCS8qIEV4dHJhY3QgdGhlIHN5bmRyb21lLCBp dCBpcyBub3QgbmVjZXNzYXJpbHkgYWxpZ25lZCAqLwo+ID4gKwkJbmFuZF9leHRyYWN0X2JpdHMo ZHN0LCBlY2MsIHNyY19vZmYsIGFuYW5kLT5lY2NfYml0cyk7ICAKPiAKPiBJIGRvbid0IHRoaW5r IHlvdSBuZWVkIHRvIGV4dHJhY3QgYWxsIGJ5dGVzIGFoZWFkIG9mIHRpbWUuIEp1c3QgbW92ZQo+ IHRoZSBleHRyYWN0aW9uIGJpdHMgdG8gdGhlIGZvcl9lYWNoX2VjY19zdGVwKCkgbG9vcCBpbgo+ IGFuZmNfcmVhZF9wYWdlX2h3X2VjYygpLiBUaGlzIHdheSB5b3UgY2FuIG1ha2UgdGhlIGFuYW5k LT5od19lY2MgYnVmZmVyCj4gc21hbGxlci4KCkZhaXJlIGVub3VnaC4KCj4gCj4gPiArCX0KPiA+ ICt9Cj4gPiArCj4gPiArLyoKPiA+ICsgKiBXaGVuIHVzaW5nIHRoZSBlbWJlZGRlZCBoYXJkd2Fy ZSBFQ0MgZW5naW5lLCB0aGUgY29udHJvbGxlciBpcyBpbiBjaGFyZ2Ugb2YKPiA+ICsgKiBmZWVk aW5nIHRoZSBlbmdpbmUgd2l0aCwgZmlyc3QsIHRoZSBFQ0MgcmVzaWR1ZSBwcmVzZW50IGluIHRo ZSBkYXRhIGFycmF5Lgo+ID4gKyAqIEEgdHlwaWNhbCByZWFkIG9wZXJhdGlvbiBpczoKPiA+ICsg KiAxLyBBc3NlcnQgdGhlIHJlYWQgb3BlcmF0aW9uIGJ5IHNlbmRpbmcgdGhlIHJlbGV2YW50IGNv bW1hbmQvYWRkcmVzcyBjeWNsZXMKPiA+ICsgKiAgICBidXQgdGFyZ2V0aW5nIHRoZSBjb2x1bW4g b2YgdGhlIGZpcnN0IEVDQyBieXRlcyBpbiB0aGUgT09CIGFyZWEgaW5zdGVhZCBvZgo+ID4gKyAq ICAgIHRoZSBtYWluIGRhdGEgZGlyZWN0bHkuCj4gPiArICogMi8gQWZ0ZXIgaGF2aW5nIHJlYWQg dGhlIHJlbGV2YW50IG51bWJlciBvZiBFQ0MgYnl0ZXMsIHRoZSBjb250cm9sbGVyIHVzZXMKPiA+ ICsgKiAgICB0aGUgUk5ET1VUL1JORFNUQVJUIGNvbW1hbmRzIHdoaWNoIGFyZSBzZXQgaW50byB0 aGUgIkVDQyBTcGFyZSBDb21tYW5kCj4gPiArICogICAgUmVnaXN0ZXIiIHRvIG1vdmUgdGhlIHBv aW50ZXIgYmFjayBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBtYWluIGRhdGEuCj4gPiArICogMy8g SXQgd2lsbCByZWFkIHRoZSBjb250ZW50IG9mIHRoZSBtYWluIGFyZWEgZm9yIGEgZ2l2ZW4gc2l6 ZSAocGt0c2l6ZSkgYW5kCj4gPiArICogICAgd2lsbCBmZWVkIHRoZSBFQ0MgZW5naW5lIHdpdGgg dGhpcyBidWZmZXIgYWdhaW4uCj4gPiArICogNC8gVGhlIEVDQyBlbmdpbmUgZGVyaXZlcyB0aGUg RUNDIGJ5dGVzIGZvciB0aGUgZ2l2ZW4gZGF0YSBhbmQgY29tcGFyZSB0aGVtCj4gPiArICogICAg d2l0aCB0aGUgb25lcyBhbHJlYWR5IHJlY2VpdmVkLiBJdCBldmVudHVhbGx5IHRyaWdnZXIgc3Rh dHVzIGZsYWdzIGFuZAo+ID4gKyAqICAgIHRoZW4gc2V0IHRoZSAiQnVmZmVyIFJlYWQgUmVhZHki IGZsYWcuCj4gPiArICogNS8gVGhlIGNvcnJlY3RlZCBkYXRhIGlzIHRoZW4gYXZhaWxhYmxlIGZv ciByZWFkaW5nIGZyb20gdGhlIGRhdGEgcG9ydAo+ID4gKyAqICAgIHJlZ2lzdGVyLgo+ID4gKyAq Cj4gPiArICogVGhlIGhhcmR3YXJlIEJDSCBFQ0MgZW5naW5lIGlzIGtub3duIHRvIGJlIGluY29u c3RlbnQgaW4gQkNIIG1vZGUgYW5kIG5ldmVyCj4gPiArICogcmVwb3J0cyBlcnJvcnMuIFdlIG5l ZWQgdG8gZW5zdXJlIHdlIHJldHVybiBjb25zaXN0ZW50IGRhdGEuIFRoaXMgaW52b2x2ZXMgIAo+ IAo+IAkgICAgIF4gdW5jb3JyZWN0YWJsZSBlcnJvcnMKClRydWUuCgo+IAo+ID4gKyAqIGtub3dp bmcgdGhlIHByaW1hcnkgcG9seW5vbWlhbCB1c2VkIGJ5IHRoZSBoYXJkd2FyZSBlbmdpbmUgYW5k IGNvbXB1dGUgdGhlCj4gPiArICogc3luZHJvbWUgYnkgb3Vyc2VsdmVzIGluIHRoZSByZWFkIHBh dGggaW5zdGVhZCBvZiByZWx5aW5nIG9uIHRoZSBoYXJkd2FyZS4gIAo+IAo+IEkgd291bGQganVz dCBzYXkgIkJlY2F1c2Ugb2YgdGhpcyBidWcsIHdlIGhhdmUgdG8gdXNlIHRoZQo+IHNvZnR3YXJl IEJDSCBpbXBsZW1lbnRhdGlvbiBpbiB0aGUgcmVhZCBwYXRoLiIKPiAKPiA+ICsgKi8KPiA+ICtz dGF0aWMgaW50IGFuZmNfcmVhZF9wYWdlX2h3X2VjYyhzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCB1 OCAqYnVmLAo+ID4gKwkJCQkgaW50IG9vYl9yZXF1aXJlZCwgaW50IHBhZ2UpCj4gPiArewo+ID4g KwlzdHJ1Y3QgYXJhc2FuX25mYyAqbmZjID0gdG9fYW5mYyhjaGlwLT5jb250cm9sbGVyKTsKPiA+ ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZChjaGlwKTsKPiA+ICsJc3RydWN0 IGFuYW5kICphbmFuZCA9IHRvX2FuYW5kKGNoaXApOwo+ID4gKwl1bnNpZ25lZCBpbnQgbGVuID0g bXRkLT53cml0ZXNpemUgKyAob29iX3JlcXVpcmVkID8gbXRkLT5vb2JzaXplIDogMCk7Cj4gPiAr CXVuc2lnbmVkIGludCBtYXhfYml0ZmxpcHMgPSAwOwo+ID4gKwlkbWFfYWRkcl90IHBhZGRyOwo+ ID4gKwlpbnQgc3RlcCwgcmV0Owo+ID4gKwlzdHJ1Y3QgYW5mY19vcCBuZmNfb3AgPSB7Cj4gPiAr CQkucGt0X3JlZyA9Cj4gPiArCQkJUEtUX1NJWkUoY2hpcC0+ZWNjLnNpemUpIHwKPiA+ICsJCQlQ S1RfU1RFUFMoY2hpcC0+ZWNjLnN0ZXBzKSwKPiA+ICsJCS5hZGRyMV9yZWcgPQo+ID4gKwkJCShw YWdlICYgMHhGRikgPDwgKDggKiAoYW5hbmQtPmNhZGRyX2N5Y2xlcykpIHwKPiA+ICsJCQkoKChw YWdlID4+IDgpICYgMHhGRikgPDwgKDggKiAoMSArIGFuYW5kLT5jYWRkcl9jeWNsZXMpKSksCj4g PiArCQkuYWRkcjJfcmVnID0KPiA+ICsJCQkoKHBhZ2UgPj4gMTYpICYgMHhGRikgfAo+ID4gKwkJ CUFERFIyX1NUUkVOR1RIKGFuYW5kLT5zdHJlbmd0aCkgfAo+ID4gKwkJCUFERFIyX0NTKGFuYW5k LT5jcyksCj4gPiArCQkuY21kX3JlZyA9Cj4gPiArCQkJQ01EXzEoTkFORF9DTURfUkVBRDApIHwK PiA+ICsJCQlDTURfMihOQU5EX0NNRF9SRUFEU1RBUlQpIHwKPiA+ICsJCQlDTURfUEFHRV9TSVpF KGFuYW5kLT5wYWdlX3N6KSB8Cj4gPiArCQkJQ01EX0RNQV9FTkFCTEUgfAo+ID4gKwkJCUNNRF9O QUREUlMoYW5hbmQtPmNhZGRyX2N5Y2xlcyArCj4gPiArCQkJCSAgIGFuYW5kLT5yYWRkcl9jeWNs ZXMpLAo+ID4gKwkJLnByb2dfcmVnID0gUFJPR19QR1JELAo+ID4gKwl9Owo+ID4gKwo+ID4gKwlw YWRkciA9IGRtYV9tYXBfc2luZ2xlKG5mYy0+ZGV2LCAodm9pZCAqKWJ1ZiwgbGVuLCBETUFfRlJP TV9ERVZJQ0UpOwo+ID4gKwlpZiAoZG1hX21hcHBpbmdfZXJyb3IobmZjLT5kZXYsIHBhZGRyKSkg ewo+ID4gKwkJZGV2X2VycihuZmMtPmRldiwgIkJ1ZmZlciBtYXBwaW5nIGVycm9yIik7Cj4gPiAr CQlyZXR1cm4gLUVJTzsKPiA+ICsJfQo+ID4gKwo+ID4gKwl3cml0ZWxfcmVsYXhlZChwYWRkciwg bmZjLT5iYXNlICsgRE1BX0FERFIwX1JFRyk7Cj4gPiArCXdyaXRlbF9yZWxheGVkKChwYWRkciA+ PiAzMiksIG5mYy0+YmFzZSArIERNQV9BRERSMV9SRUcpOwo+ID4gKwo+ID4gKwlhbmZjX3RyaWdn ZXJfb3AobmZjLCAmbmZjX29wKTsKPiA+ICsKPiA+ICsJcmV0ID0gYW5mY193YWl0X2Zvcl9ldmVu dChuZmMsIFhGRVJfQ09NUExFVEUpOwo+ID4gKwlkbWFfdW5tYXBfc2luZ2xlKG5mYy0+ZGV2LCBw YWRkciwgbGVuLCBETUFfRlJPTV9ERVZJQ0UpOwo+ID4gKwlpZiAocmV0KSB7Cj4gPiArCQlkZXZf ZXJyKG5mYy0+ZGV2LCAiRXJyb3IgcmVhZGluZyBwYWdlICVkXG4iLCBwYWdlKTsKPiA+ICsJCXJl dHVybiByZXQ7Cj4gPiArCX0KPiA+ICsKPiA+ICsJLyogU3RvcmUgdGhlIHJhdyBPT0IgYnl0ZXMg YXMgd2VsbCAqLwo+ID4gKwlyZXQgPSBuYW5kX2NoYW5nZV9yZWFkX2NvbHVtbl9vcChjaGlwLCBt dGQtPndyaXRlc2l6ZSwgY2hpcC0+b29iX3BvaSwKPiA+ICsJCQkJCSBtdGQtPm9vYnNpemUsIDAp Owo+ID4gKwlpZiAocmV0KQo+ID4gKwkJcmV0dXJuIHJldDsKPiA+ICsKPiA+ICsJLyogRXh0cmFj dCBhbmQgcmVvcmRlciBFQ0MgYnl0ZXMgKi8KPiA+ICsJYW5mY19leHRyYWN0X2VjY19iaXRzKGFu YW5kLCAmY2hpcC0+b29iX3BvaVttdGQtPm9vYnNpemUgLQo+ID4gKwkJCQkJCSAgICBhbmFuZC0+ ZWNjX3RvdGFsXSk7Cj4gPiArCj4gPiArCS8qCj4gPiArCSAqIEZvciBlYWNoIHN0ZXAsIGNvbXB1 dGUgYnkgc29mdGFyZSB0aGUgQkNIIHN5bmRyb21lIG92ZXIgdGhlIHJhdyBkYXRhLgo+ID4gKwkg KiBDb21wYXJlIHRoZSB0aGVvcmV0aWNhbCBhbW91bnQgb2YgZXJyb3JzIGFuZCBjb21wYXJlIHdp dGggdGhlCj4gPiArCSAqIGhhcmR3YXJlIGVuZ2luZSBmZWVkYmFjay4KPiA+ICsJICovCj4gPiAr CWZvciAoc3RlcCA9IDA7IHN0ZXAgPCBjaGlwLT5lY2Muc3RlcHM7IHN0ZXArKykgewo+ID4gKwkJ dTggKnJhd19idWYgPSAmYnVmW3N0ZXAgKiBjaGlwLT5lY2Muc2l6ZV07Cj4gPiArCQl1OCAqZWNj X2J1ZiA9ICZhbmFuZC0+aHdfZWNjW2NoaXAtPmVjYy5ieXRlcyAqIHN0ZXBdOwo+ID4gKwkJdW5z aWduZWQgaW50IGJpdCwgYnl0ZTsKPiA+ICsJCWludCBiZiwgaTsKPiA+ICsKPiA+ICsJCWJmID0g YmNoX2RlY29kZShhbmFuZC0+YmNoLCByYXdfYnVmLCBjaGlwLT5lY2Muc2l6ZSwgZWNjX2J1ZiwK PiA+ICsJCQkJTlVMTCwgTlVMTCwgbmZjLT5lcnJsb2MpOwo+ID4gKwkJaWYgKCFiZikgewo+ID4g KwkJCWNvbnRpbnVlOwo+ID4gKwkJfSBlbHNlIGlmIChiZiA+IDApIHsKPiA+ICsJCQlmb3IgKGkg PSAwOyBpIDwgYmY7IGkrKykgewo+ID4gKwkJCQkvKiBPbmx5IGNvcnJlY3QgdGhlIGRhdGEsIG5v dCB0aGUgc3luZHJvbWUgKi8KPiA+ICsJCQkJaWYgKG5mYy0+ZXJybG9jW2ldIDwgKGNoaXAtPmVj Yy5zaXplICogOCkpIHsKPiA+ICsJCQkJCWJpdCA9IEJJVChuZmMtPmVycmxvY1tpXSAmIDcpOwo+ ID4gKwkJCQkJYnl0ZSA9IG5mYy0+ZXJybG9jW2ldID4+IDM7Cj4gPiArCQkJCQlyYXdfYnVmW2J5 dGVdIF49IGJpdDsKPiA+ICsJCQkJfQo+ID4gKwkJCX0KPiA+ICsKPiA+ICsJCQltdGQtPmVjY19z dGF0cy5jb3JyZWN0ZWQgKz0gYmY7Cj4gPiArCQkJbWF4X2JpdGZsaXBzID0gbWF4X3QodW5zaWdu ZWQgaW50LCBtYXhfYml0ZmxpcHMsIGJmKTsKPiA+ICsKPiA+ICsJCQljb250aW51ZTsKPiA+ICsJ CX0KPiA+ICsKPiA+ICsJCWJmID0gbmFuZF9jaGVja19lcmFzZWRfZWNjX2NodW5rKHJhd19idWYs IGNoaXAtPmVjYy5zaXplLAo+ID4gKwkJCQkJCSBOVUxMLCAwLCBOVUxMLCAwLAo+ID4gKwkJCQkJ CSBjaGlwLT5lY2Muc3RyZW5ndGgpOwo+ID4gKwkJaWYgKGJmID4gMCkgewo+ID4gKwkJCW10ZC0+ ZWNjX3N0YXRzLmNvcnJlY3RlZCArPSBiZjsKPiA+ICsJCQltYXhfYml0ZmxpcHMgPSBtYXhfdCh1 bnNpZ25lZCBpbnQsIG1heF9iaXRmbGlwcywgYmYpOwo+ID4gKwkJCW1lbXNldChyYXdfYnVmLCAw eEZGLCBjaGlwLT5lY2Muc2l6ZSk7Cj4gPiArCQl9IGVsc2UgaWYgKGJmIDwgMCkgewo+ID4gKwkJ CW10ZC0+ZWNjX3N0YXRzLmZhaWxlZCsrOwo+ID4gKwkJfQo+ID4gKwl9Cj4gPiArCj4gPiArCXJl dHVybiAwOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IGFuZmNfd3JpdGVfcGFnZV9od19l Y2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgY29uc3QgdTggKmJ1ZiwKPiA+ICsJCQkJICBpbnQg b29iX3JlcXVpcmVkLCBpbnQgcGFnZSkKPiA+ICt7Cj4gPiArCXN0cnVjdCBhbmFuZCAqYW5hbmQg PSB0b19hbmFuZChjaGlwKTsKPiA+ICsJc3RydWN0IGFyYXNhbl9uZmMgKm5mYyA9IHRvX2FuZmMo Y2hpcC0+Y29udHJvbGxlcik7Cj4gPiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19t dGQoY2hpcCk7Cj4gPiArCXVuc2lnbmVkIGludCBsZW4gPSBtdGQtPndyaXRlc2l6ZSArIChvb2Jf cmVxdWlyZWQgPyBtdGQtPm9vYnNpemUgOiAwKTsKPiA+ICsJZG1hX2FkZHJfdCBwYWRkcjsKPiA+ ICsJaW50IHJldDsKPiA+ICsJc3RydWN0IGFuZmNfb3AgbmZjX29wID0gewo+ID4gKwkJLnBrdF9y ZWcgPQo+ID4gKwkJCVBLVF9TSVpFKGNoaXAtPmVjYy5zaXplKSB8Cj4gPiArCQkJUEtUX1NURVBT KGNoaXAtPmVjYy5zdGVwcyksCj4gPiArCQkuYWRkcjFfcmVnID0KPiA+ICsJCQkocGFnZSAmIDB4 RkYpIDw8ICg4ICogKGFuYW5kLT5jYWRkcl9jeWNsZXMpKSB8Cj4gPiArCQkJKCgocGFnZSA+PiA4 KSAmIDB4RkYpIDw8ICg4ICogKDEgKyBhbmFuZC0+Y2FkZHJfY3ljbGVzKSkpLAo+ID4gKwkJLmFk ZHIyX3JlZyA9Cj4gPiArCQkJKChwYWdlID4+IDE2KSAmIDB4RkYpIHwKPiA+ICsJCQlBRERSMl9T VFJFTkdUSChhbmFuZC0+c3RyZW5ndGgpIHwKPiA+ICsJCQlBRERSMl9DUyhhbmFuZC0+Y3MpLAo+ ID4gKwkJLmNtZF9yZWcgPQo+ID4gKwkJCUNNRF8xKE5BTkRfQ01EX1NFUUlOKSB8Cj4gPiArCQkJ Q01EXzIoTkFORF9DTURfUEFHRVBST0cpIHwKPiA+ICsJCQlDTURfUEFHRV9TSVpFKGFuYW5kLT5w YWdlX3N6KSB8Cj4gPiArCQkJQ01EX0RNQV9FTkFCTEUgfAo+ID4gKwkJCUNNRF9OQUREUlMoYW5h bmQtPmNhZGRyX2N5Y2xlcyArCj4gPiArCQkJCSAgIGFuYW5kLT5yYWRkcl9jeWNsZXMpIHwKPiA+ ICsJCQlDTURfRUNDX0VOQUJMRSwKPiA+ICsJCS5wcm9nX3JlZyA9IFBST0dfUEdQUk9HLAo+ID4g Kwl9Owo+ID4gKwo+ID4gKwl3cml0ZWxfcmVsYXhlZChhbmFuZC0+ZWNjX2NvbmYsIG5mYy0+YmFz ZSArIEVDQ19DT05GX1JFRyk7Cj4gPiArCXdyaXRlbF9yZWxheGVkKEVDQ19TUF9DTUQxKE5BTkRf Q01EX1JORElOKSB8Cj4gPiArCQkgICAgICAgRUNDX1NQX0FERFJTKGFuYW5kLT5jYWRkcl9jeWNs ZXMpLAo+ID4gKwkJICAgICAgIG5mYy0+YmFzZSArIEVDQ19TUF9SRUcpOwo+ID4gKwo+ID4gKwlw YWRkciA9IGRtYV9tYXBfc2luZ2xlKG5mYy0+ZGV2LCAodm9pZCAqKWJ1ZiwgbGVuLCBETUFfVE9f REVWSUNFKTsKPiA+ICsJaWYgKGRtYV9tYXBwaW5nX2Vycm9yKG5mYy0+ZGV2LCBwYWRkcikpIHsK PiA+ICsJCWRldl9lcnIobmZjLT5kZXYsICJCdWZmZXIgbWFwcGluZyBlcnJvciIpOwo+ID4gKwkJ cmV0dXJuIC1FSU87Cj4gPiArCX0KPiA+ICsKPiA+ICsJd3JpdGVsX3JlbGF4ZWQocGFkZHIsIG5m Yy0+YmFzZSArIERNQV9BRERSMF9SRUcpOwo+ID4gKwl3cml0ZWxfcmVsYXhlZCgocGFkZHIgPj4g MzIpLCBuZmMtPmJhc2UgKyBETUFfQUREUjFfUkVHKTsKPiA+ICsKPiA+ICsJYW5mY190cmlnZ2Vy X29wKG5mYywgJm5mY19vcCk7Cj4gPiArCXJldCA9IGFuZmNfd2FpdF9mb3JfZXZlbnQobmZjLCBY RkVSX0NPTVBMRVRFKTsKPiA+ICsJZG1hX3VubWFwX3NpbmdsZShuZmMtPmRldiwgcGFkZHIsIGxl biwgRE1BX1RPX0RFVklDRSk7Cj4gPiArCWlmIChyZXQpCj4gPiArCQlkZXZfZXJyKG5mYy0+ZGV2 LCAiRXJyb3Igd3JpdGluZyBwYWdlICVkXG4iLCBwYWdlKTsKPiA+ICsKPiA+ICsJLyogT09CIGRh dGEgY2Fubm90IGJlIHdyaXR0ZW4gaGVyZSAqLwo+ID4gKwo+ID4gKwlyZXR1cm4gcmV0Owo+ID4g K30KPiA+ICsKPiA+ICAvKiBOQU5EIGZyYW1ld29yayAtPmV4ZWNfb3AoKSBob29rcyBhbmQgcmVs YXRlZCBoZWxwZXJzICovCj4gPiAgc3RhdGljIHZvaWQgYW5mY19wYXJzZV9pbnN0cnVjdGlvbnMo c3RydWN0IG5hbmRfY2hpcCAqY2hpcCwKPiA+ICAJCQkJICAgIGNvbnN0IHN0cnVjdCBuYW5kX3N1 Ym9wICpzdWJvcCwKPiA+IEBAIC01OTksNiArODEwLDEyMSBAQCBzdGF0aWMgaW50IGFuZmNfc2V0 dXBfZGF0YV9pbnRlcmZhY2Uoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgaW50IHRhcmdldCwKPiA+ ICAJcmV0dXJuIDA7Cj4gPiAgfQo+ID4gIAo+ID4gK3N0YXRpYyBpbnQgYW5mY19pbml0X2h3X2Vj Y19jb250cm9sbGVyKHN0cnVjdCBhcmFzYW5fbmZjICpuZmMsCj4gPiArCQkJCSAgICAgICBzdHJ1 Y3QgbmFuZF9jaGlwICpjaGlwKQo+ID4gK3sKPiA+ICsJc3RydWN0IGFuYW5kICphbmFuZCA9IHRv X2FuYW5kKGNoaXApOwo+ID4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKGNo aXApOwo+ID4gKwlzdHJ1Y3QgbmFuZF9lY2NfY3RybCAqZWNjID0gJmNoaXAtPmVjYzsKPiA+ICsJ dW5zaWduZWQgaW50IGJjaF9wcmltX3BvbHkgPSAwLCBiY2hfZ2ZfbWFnID0gMCwgZWNjX29mZnNl dDsKPiA+ICsKPiA+ICsJc3dpdGNoIChtdGQtPndyaXRlc2l6ZSkgewo+ID4gKwljYXNlIFNaXzUx MjoKPiA+ICsJY2FzZSBTWl8ySzoKPiA+ICsJY2FzZSBTWl80SzoKPiA+ICsJY2FzZSBTWl84SzoK PiA+ICsJY2FzZSBTWl8xNks6Cj4gPiArCQlicmVhazsKPiA+ICsJZGVmYXVsdDoKPiA+ICsJCWRl dl9lcnIobmZjLT5kZXYsICJVbnN1cHBvcnRlZCBwYWdlIHNpemUgJWRcbiIsIG10ZC0+d3JpdGVz aXplKTsKPiA+ICsJCXJldHVybiAtRUlOVkFMOwo+ID4gKwl9Cj4gPiArCj4gPiArCWlmICghZWNj LT5zaXplIHx8ICFlY2MtPnN0cmVuZ3RoKSB7Cj4gPiArCQllY2MtPnNpemUgPSBjaGlwLT5iYXNl LmVjY3JlcS5zdGVwX3NpemU7Cj4gPiArCQllY2MtPnN0cmVuZ3RoID0gY2hpcC0+YmFzZS5lY2Ny ZXEuc3RyZW5ndGg7Cj4gPiArCX0KPiA+ICsKPiA+ICsJaWYgKCFlY2MtPnNpemUgfHwgIWVjYy0+ c3RyZW5ndGgpIHsKPiA+ICsJCWRldl9lcnIobmZjLT5kZXYsCj4gPiArCQkJIk1pc3NpbmcgY29u dHJvbGxlciBFQ0Mgc3RlcCBzaXplL3N0cmVuZ3RoXG4iKTsKPiA+ICsJCXJldHVybiAtRUlOVkFM Owo+ID4gKwl9Cj4gPiArCj4gPiArCXN3aXRjaCAoZWNjLT5zdHJlbmd0aCkgewo+ID4gKwljYXNl IDE6Cj4gPiArCQlhbmFuZC0+c3RyZW5ndGggPSAweDA7Cj4gPiArCQlicmVhazsKPiA+ICsJY2Fz ZSAxMjoKPiA+ICsJCWFuYW5kLT5zdHJlbmd0aCA9IDB4MTsKPiA+ICsJCWJyZWFrOwo+ID4gKwlj YXNlIDg6Cj4gPiArCQlhbmFuZC0+c3RyZW5ndGggPSAweDI7Cj4gPiArCQlicmVhazsKPiA+ICsJ Y2FzZSA0Ogo+ID4gKwkJYW5hbmQtPnN0cmVuZ3RoID0gMHgzOwo+ID4gKwkJYnJlYWs7Cj4gPiAr CWNhc2UgMjQ6Cj4gPiArCQlhbmFuZC0+c3RyZW5ndGggPSAweDQ7Cj4gPiArCQlicmVhazsKPiA+ ICsJZGVmYXVsdDogIAo+IAo+IE1heWJlIHlvdSBzaG91bGQgcGljayBzb21ldGhpbmcgdGhhdCdz IGhpZ2hlciB0aGFuIHRoZSByZXF1ZXN0ZWQKPiBzdHJlbmd0aCBpbiB0aGF0IGNhc2UgaW5zdGVh ZCBvZiByZXR1cm5pbmcgYW4gZXJyb3IuIFRoZXJlJ3MgZ2VuZXJpYwo+IGhlbHBlciB0byBoZWxw IHdpdGggdGhhdCBJSVJDLgoKVGhhdCdzIHJpZ2h0LiBJJ2xsIHRyeSB0byB3cml0ZSBzb21ldGhp bmcgZWFzaWVyIGZvciB0aGUgdXNlciBzbyB0aGF0CnRoZSBuYW5kLWVjYy1zaXplL3N0cmVuZ3Ro IERUIHByb3BlcnRpZXMgYXJlIG5vdCBuZWVkZWQuCgo+IAo+ID4gKwkJZGV2X2VycihuZmMtPmRl diwgIlVuc3VwcG9ydGVkIHN0cmVuZ3RoICVkXG4iLCBlY2MtPnN0cmVuZ3RoKTsKPiA+ICsJCXJl dHVybiAtRUlOVkFMOwo+ID4gKwl9Cj4gPiArCj4gPiArCXN3aXRjaCAoZWNjLT5zaXplKSB7Cj4g PiArCWNhc2UgU1pfNTEyOgo+ID4gKwkJYmNoX2dmX21hZyA9IDEzOwo+ID4gKwkJYmNoX3ByaW1f cG9seSA9IDB4MjAxYjsKPiA+ICsJCWJyZWFrOwo+ID4gKwljYXNlIFNaXzFLOgo+ID4gKwkJYmNo X2dmX21hZyA9IDE0Owo+ID4gKwkJYmNoX3ByaW1fcG9seSA9IDB4NDQ0MzsKPiA+ICsJCWJyZWFr Owo+ID4gKwlkZWZhdWx0Ogo+ID4gKwkJZGV2X2VycihuZmMtPmRldiwgIlVuc3VwcG9ydGVkIHN0 ZXAgc2l6ZSAlZFxuIiwgZWNjLT5zdHJlbmd0aCk7Cj4gPiArCQlyZXR1cm4gLUVJTlZBTDsKPiA+ ICsJfQo+ID4gKwo+ID4gKwlpZiAoKGVjYy0+c2l6ZSA9PSBTWl8xSyAmJiBlY2MtPnN0cmVuZ3Ro ICE9IDI0KSB8fAo+ID4gKwkgICAgKGVjYy0+c2l6ZSAhPSBTWl8xSyAmJiBlY2MtPnN0cmVuZ3Ro ID09IDI0KSkgewo+ID4gKwkJZGV2X2VycihuZmMtPmRldiwKPiA+ICsJCQkiVW5zdXBwb3J0ZWQg Y291cGxlIHN0cmVuZ3RoL3N0ZXAtc2l6ZTogJWRCLyVkYlxuIiwKPiA+ICsJCQllY2MtPnN0cmVu Z3RoLCBlY2MtPnNpemUpOwo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gPiArCX0KPiA+ICsKPiA+ ICsJbXRkX3NldF9vb2JsYXlvdXQobXRkLCAmbmFuZF9vb2JsYXlvdXRfbHBfb3BzKTsKPiA+ICsK PiA+ICsJZWNjLT5zdGVwcyA9IG10ZC0+d3JpdGVzaXplIC8gZWNjLT5zaXplOwo+ID4gKwo+ID4g KwlpZiAoZWNjLT5zdHJlbmd0aCA9PSAxKSB7Cj4gPiArCQlkZXZfZXJyKG5mYy0+ZGV2LCAiSGFy ZHdhcmUgSGFtbWluZyBlbmdpbmUgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwo+ID4gKwkJcmV0dXJu IC1FSU5WQUw7Cj4gPiArCX0KPiA+ICsKPiA+ICsJZWNjLT5hbGdvID0gTkFORF9FQ0NfQkNIOwo+ ID4gKwlhbmFuZC0+ZWNjX2JpdHMgPSBiY2hfZ2ZfbWFnICogZWNjLT5zdHJlbmd0aDsKPiA+ICsJ ZWNjLT5ieXRlcyA9IERJVl9ST1VORF9VUChhbmFuZC0+ZWNjX2JpdHMsIDgpOwo+ID4gKwlhbmFu ZC0+ZWNjX3RvdGFsID0gRElWX1JPVU5EX1VQKGFuYW5kLT5lY2NfYml0cyAqIGVjYy0+c3RlcHMs IDgpOwo+ID4gKwllY2Nfb2Zmc2V0ID0gbXRkLT53cml0ZXNpemUgKyBtdGQtPm9vYnNpemUgLSBh bmFuZC0+ZWNjX3RvdGFsOwo+ID4gKwlhbmFuZC0+ZWNjX2NvbmYgPSBFQ0NfQ09ORl9DT0woZWNj X29mZnNldCkgfAo+ID4gKwkJCSAgRUNDX0NPTkZfTEVOKGFuYW5kLT5lY2NfdG90YWwpIHwKPiA+ ICsJCQkgIEVDQ19DT05GX0JDSF9FTjsKPiA+ICsKPiA+ICsJbmZjLT5lcnJsb2MgPSBkZXZtX2tt YWxsb2NfYXJyYXkobmZjLT5kZXYsIGVjYy0+c3RyZW5ndGgsCj4gPiArCQkJCQkgc2l6ZW9mKCpu ZmMtPmVycmxvYyksIEdGUF9LRVJORUwpOwo+ID4gKwlpZiAoIW5mYy0+ZXJybG9jKQo+ID4gKwkJ cmV0dXJuIC1FTk9NRU07Cj4gPiArCj4gPiArCWFuYW5kLT5od19lY2MgPSBkZXZtX2ttYWxsb2Mo bmZjLT5kZXYsIGVjYy0+c3RlcHMgKiBlY2MtPmJ5dGVzLAo+ID4gKwkJCQkgICAgIEdGUF9LRVJO RUwpOwo+ID4gKwlpZiAoIWFuYW5kLT5od19lY2MpCj4gPiArCQlyZXR1cm4gLUVOT01FTTsKPiA+ ICsKPiA+ICsJYW5hbmQtPmJjaCA9IGJjaF9pbml0KGJjaF9nZl9tYWcsIGVjYy0+c3RyZW5ndGgs Cj4gPiArCQkJICAgICAgYmNoX3ByaW1fcG9seSk7Cj4gPiArCWlmICghYW5hbmQtPmJjaCkKPiA+ ICsJCXJldHVybiAtRUlOVkFMOwo+ID4gKwo+ID4gKwlhbmFuZC0+YmNoLT5zd2FwX2JpdHMgPSB0 cnVlOyAgCj4gCj4gQXMgbWVudGlvbmVkIGluIG15IHByZXZpb3VzIHJlcGx5LCBJIGRvbid0IHRo aW5rIHdlIHNob3VsZCB0b3VjaCB0aGUKPiBiY2hfY29udHJvbCBmaWVsZHMgKGV2ZW4gaWYgdGhl eSBhcmUgZXhwb3NlZCkuCgpZZXMsIEknbGwgYWRkIGEgYm9vbGVhbiB0byBiY2hfaW5pdC4KCj4g Cj4gPiArCj4gPiArCWVjYy0+cmVhZF9wYWdlID0gYW5mY19yZWFkX3BhZ2VfaHdfZWNjOwo+ID4g KwllY2MtPndyaXRlX3BhZ2UgPSBhbmZjX3dyaXRlX3BhZ2VfaHdfZWNjOwo+ID4gKwo+ID4gKwly ZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiAgc3RhdGljIGludCBhbmZjX2F0dGFjaF9jaGlwKHN0 cnVjdCBuYW5kX2NoaXAgKmNoaXApCj4gPiAgewo+ID4gIAlzdHJ1Y3QgYW5hbmQgKmFuYW5kID0g dG9fYW5hbmQoY2hpcCk7Cj4gPiBAQCAtNjQ5LDYgKzk3NSw4IEBAIHN0YXRpYyBpbnQgYW5mY19h dHRhY2hfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+ID4gIAljYXNlIE5BTkRfRUNDX09O X0RJRToKPiA+ICAJCWJyZWFrOwo+ID4gIAljYXNlIE5BTkRfRUNDX0hXOgo+ID4gKwkJcmV0ID0g YW5mY19pbml0X2h3X2VjY19jb250cm9sbGVyKG5mYywgY2hpcCk7Cj4gPiArCQlicmVhazsKPiA+ ICAJZGVmYXVsdDoKPiA+ICAJCWRldl9lcnIobmZjLT5kZXYsICJVbnN1cHBvcnRlZCBFQ0MgbW9k ZTogJWRcbiIsCj4gPiAgCQkJY2hpcC0+ZWNjLm1vZGUpOwo+ID4gQEAgLTY1OCwxMCArOTg2LDE5 IEBAIHN0YXRpYyBpbnQgYW5mY19hdHRhY2hfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+ ID4gIAlyZXR1cm4gcmV0Owo+ID4gIH0KPiA+ICAKPiA+ICtzdGF0aWMgdm9pZCBhbmZjX2RldGFj aF9jaGlwKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXApCj4gPiArewo+ID4gKwlzdHJ1Y3QgYW5hbmQg KmFuYW5kID0gdG9fYW5hbmQoY2hpcCk7Cj4gPiArCj4gPiArCWlmIChhbmFuZC0+YmNoKQo+ID4g KwkJYmNoX2ZyZWUoYW5hbmQtPmJjaCk7Cj4gPiArfQo+ID4gKwo+ID4gIHN0YXRpYyBjb25zdCBz dHJ1Y3QgbmFuZF9jb250cm9sbGVyX29wcyBhbmZjX29wcyA9IHsKPiA+ICAJLmV4ZWNfb3AgPSBh bmZjX2V4ZWNfb3AsCj4gPiAgCS5zZXR1cF9kYXRhX2ludGVyZmFjZSA9IGFuZmNfc2V0dXBfZGF0 YV9pbnRlcmZhY2UsCj4gPiAgCS5hdHRhY2hfY2hpcCA9IGFuZmNfYXR0YWNoX2NoaXAsCj4gPiAr CS5kZXRhY2hfY2hpcCA9IGFuZmNfZGV0YWNoX2NoaXAsCj4gPiAgfTsKPiA+ICAKPiA+ICBzdGF0 aWMgaW50IGFuZmNfY2hpcF9pbml0KHN0cnVjdCBhcmFzYW5fbmZjICpuZmMsIHN0cnVjdCBkZXZp Y2Vfbm9kZSAqbnApCj4gPiBAQCAtNzM3LDYgKzEwNzQsOSBAQCBzdGF0aWMgdm9pZCBhbmZjX2No aXBzX2NsZWFudXAoc3RydWN0IGFyYXNhbl9uZmMgKm5mYykKPiA+ICAJc3RydWN0IGFuYW5kICph bmFuZCwgKnRtcDsKPiA+ICAKPiA+ICAJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGFuYW5kLCB0 bXAsICZuZmMtPmNoaXBzLCBub2RlKSB7Cj4gPiArCQlpZiAoYW5hbmQtPmJjaCkKPiA+ICsJCQli Y2hfZnJlZShhbmFuZC0+YmNoKTsKPiA+ICsgIAo+IAo+IExvb2tzIGxpa2UgeW91IGhhdmUgYSBk b3VibGUtZnJlZSBoZXJlLiBJIGV4cGVjdCAtPmRldGFjaF9jaGlwKCkgdG8gYmUKPiBjYWxsZWQg YXMgcGFydCBvZiB0aGUgbmFuZF9jbGVhbnVwKCkgc3RlcC4KCkdvb2Qgb25lIEkgZm9yZ290IGFi b3V0IHRoYXQuCgo+IAo+ID4gIAkJbmFuZF9yZWxlYXNlKCZhbmFuZC0+Y2hpcCk7Cj4gPiAgCQls aXN0X2RlbCgmYW5hbmQtPm5vZGUpOwo+ID4gIAl9ICAKPiAKClRoYW5rcyBmb3IgcmV2aWV3aW5n IQpNaXF1w6hsCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KTGludXggTVREIGRpc2N1c3Npb24gbWFpbGluZyBsaXN0Cmh0dHA6Ly9saXN0cy5p bmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtbXRkLwo= 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=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_2 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 A2665C38A24 for ; Thu, 7 May 2020 15:09:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7CAF320838 for ; Thu, 7 May 2020 15:09:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726788AbgEGPJd convert rfc822-to-8bit (ORCPT ); Thu, 7 May 2020 11:09:33 -0400 Received: from relay12.mail.gandi.net ([217.70.178.232]:47517 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727067AbgEGPJd (ORCPT ); Thu, 7 May 2020 11:09:33 -0400 Received: from xps13 (unknown [91.224.148.103]) (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 9BA89200006; Thu, 7 May 2020 15:09:27 +0000 (UTC) Date: Thu, 7 May 2020 17:09:26 +0200 From: Miquel Raynal To: Boris Brezillon Cc: Rob Herring , Mark Rutland , , Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , , Thomas Petazzoni , Michal Simek , Naga Sureshkumar Relli Subject: Re: [PATCH v3 8/8] mtd: rawnand: arasan: Support the hardware BCH ECC engine Message-ID: <20200507170926.1dd85246@xps13> In-Reply-To: <20200507140336.02b3edff@collabora.com> References: <20200507110034.14736-1-miquel.raynal@bootlin.com> <20200507110034.14736-9-miquel.raynal@bootlin.com> <20200507140336.02b3edff@collabora.com> Organization: Bootlin X-Mailer: Claws Mail 3.17.4 (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: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Hi Boris, Boris Brezillon wrote on Thu, 7 May 2020 14:03:36 +0200: > On Thu, 7 May 2020 13:00:34 +0200 > Miquel Raynal wrote: > > > Add support for the hardware ECC BCH engine. > > > > Please mind that this engine as an important limitation: > > ^has Oops > > > BCH implementation does not inform the user when an uncorrectable ECC > > error occurs. To workaround this, we avoid using the hardware engine > > in the read path and do the computation with the software BCH > > implementation, which is faster than mixing hardware (for correction) > > and software (for verification). > > > > Signed-off-by: Miquel Raynal > > --- > > drivers/mtd/nand/raw/arasan-nand-controller.c | 340 ++++++++++++++++++ > > 1 file changed, 340 insertions(+) > > > > diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c > > index 61ea90ecf86e..01c0a741b4cd 100644 > > --- a/drivers/mtd/nand/raw/arasan-nand-controller.c > > +++ b/drivers/mtd/nand/raw/arasan-nand-controller.c > > @@ -10,6 +10,7 @@ > > * Naga Sureshkumar Relli > > */ > > > > +#include > > #include > > #include > > #include > > @@ -143,6 +144,10 @@ struct anfc_op { > > * @strength: Register value of the ECC strength > > * @raddr_cycles: Row address cycle information > > * @caddr_cycles: Column address cycle information > > + * @ecc_bits: Exact number of ECC bits per syndrome > > + * @ecc_total: Total number of ECC bytes > > + * @hw_ecc: Buffer to store syndromes computed by hardware > > + * @bch: BCH structure > > */ > > struct anand { > > struct list_head node; > > @@ -156,6 +161,10 @@ struct anand { > > u32 strength; > > u16 raddr_cycles; > > u16 caddr_cycles; > > + unsigned int ecc_bits; > > + unsigned int ecc_total; > > + u8 *hw_ecc; > > + struct bch_control *bch; > > }; > > > > /** > > @@ -168,6 +177,7 @@ struct anand { > > * @chips: List of all NAND chips attached to the controller > > * @assigned_cs: Bitmask describing already assigned CS lines > > * @cur_clk: Current clock rate > > + * @errloc: Array of errors located with soft BCH > > * @bf: Array of bitflips read in each ECC step > > */ > > struct arasan_nfc { > > @@ -179,6 +189,7 @@ struct arasan_nfc { > > struct list_head chips; > > unsigned long assigned_cs; > > unsigned int cur_clk; > > + unsigned int *errloc; > > u8 *bf; > > }; > > > > @@ -257,6 +268,206 @@ static int anfc_len_to_steps(struct nand_chip *chip, unsigned int len) > > return steps; > > } > > > > +static void anfc_extract_ecc_bits(struct anand *anand, const u8 *ecc) > > +{ > > + struct nand_chip *chip = &anand->chip; > > + int step; > > + > > + memset(anand->hw_ecc, 0, chip->ecc.bytes * chip->ecc.steps); > > + > > + for (step = 0; step < chip->ecc.steps; step++) { > > + unsigned int src_off = anand->ecc_bits * step; > > + u8 *dst = &anand->hw_ecc[chip->ecc.bytes * step]; > > + > > + /* Extract the syndrome, it is not necessarily aligned */ > > + nand_extract_bits(dst, ecc, src_off, anand->ecc_bits); > > I don't think you need to extract all bytes ahead of time. Just move > the extraction bits to the for_each_ecc_step() loop in > anfc_read_page_hw_ecc(). This way you can make the anand->hw_ecc buffer > smaller. Faire enough. > > > + } > > +} > > + > > +/* > > + * When using the embedded hardware ECC engine, the controller is in charge of > > + * feeding the engine with, first, the ECC residue present in the data array. > > + * A typical read operation is: > > + * 1/ Assert the read operation by sending the relevant command/address cycles > > + * but targeting the column of the first ECC bytes in the OOB area instead of > > + * the main data directly. > > + * 2/ After having read the relevant number of ECC bytes, the controller uses > > + * the RNDOUT/RNDSTART commands which are set into the "ECC Spare Command > > + * Register" to move the pointer back at the beginning of the main data. > > + * 3/ It will read the content of the main area for a given size (pktsize) and > > + * will feed the ECC engine with this buffer again. > > + * 4/ The ECC engine derives the ECC bytes for the given data and compare them > > + * with the ones already received. It eventually trigger status flags and > > + * then set the "Buffer Read Ready" flag. > > + * 5/ The corrected data is then available for reading from the data port > > + * register. > > + * > > + * The hardware BCH ECC engine is known to be inconstent in BCH mode and never > > + * reports errors. We need to ensure we return consistent data. This involves > > ^ uncorrectable errors True. > > > + * knowing the primary polynomial used by the hardware engine and compute the > > + * syndrome by ourselves in the read path instead of relying on the hardware. > > I would just say "Because of this bug, we have to use the > software BCH implementation in the read path." > > > + */ > > +static int anfc_read_page_hw_ecc(struct nand_chip *chip, u8 *buf, > > + int oob_required, int page) > > +{ > > + struct arasan_nfc *nfc = to_anfc(chip->controller); > > + struct mtd_info *mtd = nand_to_mtd(chip); > > + struct anand *anand = to_anand(chip); > > + unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0); > > + unsigned int max_bitflips = 0; > > + dma_addr_t paddr; > > + int step, ret; > > + struct anfc_op nfc_op = { > > + .pkt_reg = > > + PKT_SIZE(chip->ecc.size) | > > + PKT_STEPS(chip->ecc.steps), > > + .addr1_reg = > > + (page & 0xFF) << (8 * (anand->caddr_cycles)) | > > + (((page >> 8) & 0xFF) << (8 * (1 + anand->caddr_cycles))), > > + .addr2_reg = > > + ((page >> 16) & 0xFF) | > > + ADDR2_STRENGTH(anand->strength) | > > + ADDR2_CS(anand->cs), > > + .cmd_reg = > > + CMD_1(NAND_CMD_READ0) | > > + CMD_2(NAND_CMD_READSTART) | > > + CMD_PAGE_SIZE(anand->page_sz) | > > + CMD_DMA_ENABLE | > > + CMD_NADDRS(anand->caddr_cycles + > > + anand->raddr_cycles), > > + .prog_reg = PROG_PGRD, > > + }; > > + > > + paddr = dma_map_single(nfc->dev, (void *)buf, len, DMA_FROM_DEVICE); > > + if (dma_mapping_error(nfc->dev, paddr)) { > > + dev_err(nfc->dev, "Buffer mapping error"); > > + return -EIO; > > + } > > + > > + writel_relaxed(paddr, nfc->base + DMA_ADDR0_REG); > > + writel_relaxed((paddr >> 32), nfc->base + DMA_ADDR1_REG); > > + > > + anfc_trigger_op(nfc, &nfc_op); > > + > > + ret = anfc_wait_for_event(nfc, XFER_COMPLETE); > > + dma_unmap_single(nfc->dev, paddr, len, DMA_FROM_DEVICE); > > + if (ret) { > > + dev_err(nfc->dev, "Error reading page %d\n", page); > > + return ret; > > + } > > + > > + /* Store the raw OOB bytes as well */ > > + ret = nand_change_read_column_op(chip, mtd->writesize, chip->oob_poi, > > + mtd->oobsize, 0); > > + if (ret) > > + return ret; > > + > > + /* Extract and reorder ECC bytes */ > > + anfc_extract_ecc_bits(anand, &chip->oob_poi[mtd->oobsize - > > + anand->ecc_total]); > > + > > + /* > > + * For each step, compute by softare the BCH syndrome over the raw data. > > + * Compare the theoretical amount of errors and compare with the > > + * hardware engine feedback. > > + */ > > + for (step = 0; step < chip->ecc.steps; step++) { > > + u8 *raw_buf = &buf[step * chip->ecc.size]; > > + u8 *ecc_buf = &anand->hw_ecc[chip->ecc.bytes * step]; > > + unsigned int bit, byte; > > + int bf, i; > > + > > + bf = bch_decode(anand->bch, raw_buf, chip->ecc.size, ecc_buf, > > + NULL, NULL, nfc->errloc); > > + if (!bf) { > > + continue; > > + } else if (bf > 0) { > > + for (i = 0; i < bf; i++) { > > + /* Only correct the data, not the syndrome */ > > + if (nfc->errloc[i] < (chip->ecc.size * 8)) { > > + bit = BIT(nfc->errloc[i] & 7); > > + byte = nfc->errloc[i] >> 3; > > + raw_buf[byte] ^= bit; > > + } > > + } > > + > > + mtd->ecc_stats.corrected += bf; > > + max_bitflips = max_t(unsigned int, max_bitflips, bf); > > + > > + continue; > > + } > > + > > + bf = nand_check_erased_ecc_chunk(raw_buf, chip->ecc.size, > > + NULL, 0, NULL, 0, > > + chip->ecc.strength); > > + if (bf > 0) { > > + mtd->ecc_stats.corrected += bf; > > + max_bitflips = max_t(unsigned int, max_bitflips, bf); > > + memset(raw_buf, 0xFF, chip->ecc.size); > > + } else if (bf < 0) { > > + mtd->ecc_stats.failed++; > > + } > > + } > > + > > + return 0; > > +} > > + > > +static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, > > + int oob_required, int page) > > +{ > > + struct anand *anand = to_anand(chip); > > + struct arasan_nfc *nfc = to_anfc(chip->controller); > > + struct mtd_info *mtd = nand_to_mtd(chip); > > + unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0); > > + dma_addr_t paddr; > > + int ret; > > + struct anfc_op nfc_op = { > > + .pkt_reg = > > + PKT_SIZE(chip->ecc.size) | > > + PKT_STEPS(chip->ecc.steps), > > + .addr1_reg = > > + (page & 0xFF) << (8 * (anand->caddr_cycles)) | > > + (((page >> 8) & 0xFF) << (8 * (1 + anand->caddr_cycles))), > > + .addr2_reg = > > + ((page >> 16) & 0xFF) | > > + ADDR2_STRENGTH(anand->strength) | > > + ADDR2_CS(anand->cs), > > + .cmd_reg = > > + CMD_1(NAND_CMD_SEQIN) | > > + CMD_2(NAND_CMD_PAGEPROG) | > > + CMD_PAGE_SIZE(anand->page_sz) | > > + CMD_DMA_ENABLE | > > + CMD_NADDRS(anand->caddr_cycles + > > + anand->raddr_cycles) | > > + CMD_ECC_ENABLE, > > + .prog_reg = PROG_PGPROG, > > + }; > > + > > + writel_relaxed(anand->ecc_conf, nfc->base + ECC_CONF_REG); > > + writel_relaxed(ECC_SP_CMD1(NAND_CMD_RNDIN) | > > + ECC_SP_ADDRS(anand->caddr_cycles), > > + nfc->base + ECC_SP_REG); > > + > > + paddr = dma_map_single(nfc->dev, (void *)buf, len, DMA_TO_DEVICE); > > + if (dma_mapping_error(nfc->dev, paddr)) { > > + dev_err(nfc->dev, "Buffer mapping error"); > > + return -EIO; > > + } > > + > > + writel_relaxed(paddr, nfc->base + DMA_ADDR0_REG); > > + writel_relaxed((paddr >> 32), nfc->base + DMA_ADDR1_REG); > > + > > + anfc_trigger_op(nfc, &nfc_op); > > + ret = anfc_wait_for_event(nfc, XFER_COMPLETE); > > + dma_unmap_single(nfc->dev, paddr, len, DMA_TO_DEVICE); > > + if (ret) > > + dev_err(nfc->dev, "Error writing page %d\n", page); > > + > > + /* OOB data cannot be written here */ > > + > > + return ret; > > +} > > + > > /* NAND framework ->exec_op() hooks and related helpers */ > > static void anfc_parse_instructions(struct nand_chip *chip, > > const struct nand_subop *subop, > > @@ -599,6 +810,121 @@ static int anfc_setup_data_interface(struct nand_chip *chip, int target, > > return 0; > > } > > > > +static int anfc_init_hw_ecc_controller(struct arasan_nfc *nfc, > > + struct nand_chip *chip) > > +{ > > + struct anand *anand = to_anand(chip); > > + struct mtd_info *mtd = nand_to_mtd(chip); > > + struct nand_ecc_ctrl *ecc = &chip->ecc; > > + unsigned int bch_prim_poly = 0, bch_gf_mag = 0, ecc_offset; > > + > > + switch (mtd->writesize) { > > + case SZ_512: > > + case SZ_2K: > > + case SZ_4K: > > + case SZ_8K: > > + case SZ_16K: > > + break; > > + default: > > + dev_err(nfc->dev, "Unsupported page size %d\n", mtd->writesize); > > + return -EINVAL; > > + } > > + > > + if (!ecc->size || !ecc->strength) { > > + ecc->size = chip->base.eccreq.step_size; > > + ecc->strength = chip->base.eccreq.strength; > > + } > > + > > + if (!ecc->size || !ecc->strength) { > > + dev_err(nfc->dev, > > + "Missing controller ECC step size/strength\n"); > > + return -EINVAL; > > + } > > + > > + switch (ecc->strength) { > > + case 1: > > + anand->strength = 0x0; > > + break; > > + case 12: > > + anand->strength = 0x1; > > + break; > > + case 8: > > + anand->strength = 0x2; > > + break; > > + case 4: > > + anand->strength = 0x3; > > + break; > > + case 24: > > + anand->strength = 0x4; > > + break; > > + default: > > Maybe you should pick something that's higher than the requested > strength in that case instead of returning an error. There's generic > helper to help with that IIRC. That's right. I'll try to write something easier for the user so that the nand-ecc-size/strength DT properties are not needed. > > > + dev_err(nfc->dev, "Unsupported strength %d\n", ecc->strength); > > + return -EINVAL; > > + } > > + > > + switch (ecc->size) { > > + case SZ_512: > > + bch_gf_mag = 13; > > + bch_prim_poly = 0x201b; > > + break; > > + case SZ_1K: > > + bch_gf_mag = 14; > > + bch_prim_poly = 0x4443; > > + break; > > + default: > > + dev_err(nfc->dev, "Unsupported step size %d\n", ecc->strength); > > + return -EINVAL; > > + } > > + > > + if ((ecc->size == SZ_1K && ecc->strength != 24) || > > + (ecc->size != SZ_1K && ecc->strength == 24)) { > > + dev_err(nfc->dev, > > + "Unsupported couple strength/step-size: %dB/%db\n", > > + ecc->strength, ecc->size); > > + return -EINVAL; > > + } > > + > > + mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); > > + > > + ecc->steps = mtd->writesize / ecc->size; > > + > > + if (ecc->strength == 1) { > > + dev_err(nfc->dev, "Hardware Hamming engine not supported yet\n"); > > + return -EINVAL; > > + } > > + > > + ecc->algo = NAND_ECC_BCH; > > + anand->ecc_bits = bch_gf_mag * ecc->strength; > > + ecc->bytes = DIV_ROUND_UP(anand->ecc_bits, 8); > > + anand->ecc_total = DIV_ROUND_UP(anand->ecc_bits * ecc->steps, 8); > > + ecc_offset = mtd->writesize + mtd->oobsize - anand->ecc_total; > > + anand->ecc_conf = ECC_CONF_COL(ecc_offset) | > > + ECC_CONF_LEN(anand->ecc_total) | > > + ECC_CONF_BCH_EN; > > + > > + nfc->errloc = devm_kmalloc_array(nfc->dev, ecc->strength, > > + sizeof(*nfc->errloc), GFP_KERNEL); > > + if (!nfc->errloc) > > + return -ENOMEM; > > + > > + anand->hw_ecc = devm_kmalloc(nfc->dev, ecc->steps * ecc->bytes, > > + GFP_KERNEL); > > + if (!anand->hw_ecc) > > + return -ENOMEM; > > + > > + anand->bch = bch_init(bch_gf_mag, ecc->strength, > > + bch_prim_poly); > > + if (!anand->bch) > > + return -EINVAL; > > + > > + anand->bch->swap_bits = true; > > As mentioned in my previous reply, I don't think we should touch the > bch_control fields (even if they are exposed). Yes, I'll add a boolean to bch_init. > > > + > > + ecc->read_page = anfc_read_page_hw_ecc; > > + ecc->write_page = anfc_write_page_hw_ecc; > > + > > + return 0; > > +} > > + > > static int anfc_attach_chip(struct nand_chip *chip) > > { > > struct anand *anand = to_anand(chip); > > @@ -649,6 +975,8 @@ static int anfc_attach_chip(struct nand_chip *chip) > > case NAND_ECC_ON_DIE: > > break; > > case NAND_ECC_HW: > > + ret = anfc_init_hw_ecc_controller(nfc, chip); > > + break; > > default: > > dev_err(nfc->dev, "Unsupported ECC mode: %d\n", > > chip->ecc.mode); > > @@ -658,10 +986,19 @@ static int anfc_attach_chip(struct nand_chip *chip) > > return ret; > > } > > > > +static void anfc_detach_chip(struct nand_chip *chip) > > +{ > > + struct anand *anand = to_anand(chip); > > + > > + if (anand->bch) > > + bch_free(anand->bch); > > +} > > + > > static const struct nand_controller_ops anfc_ops = { > > .exec_op = anfc_exec_op, > > .setup_data_interface = anfc_setup_data_interface, > > .attach_chip = anfc_attach_chip, > > + .detach_chip = anfc_detach_chip, > > }; > > > > static int anfc_chip_init(struct arasan_nfc *nfc, struct device_node *np) > > @@ -737,6 +1074,9 @@ static void anfc_chips_cleanup(struct arasan_nfc *nfc) > > struct anand *anand, *tmp; > > > > list_for_each_entry_safe(anand, tmp, &nfc->chips, node) { > > + if (anand->bch) > > + bch_free(anand->bch); > > + > > Looks like you have a double-free here. I expect ->detach_chip() to be > called as part of the nand_cleanup() step. Good one I forgot about that. > > > nand_release(&anand->chip); > > list_del(&anand->node); > > } > Thanks for reviewing! Miquèl