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=-7.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,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 2709BC10F03 for ; Mon, 4 Mar 2019 09:43:24 +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 CCD0F20836 for ; Mon, 4 Mar 2019 09:43:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Cay4xvZd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CCD0F20836 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=KPODlDyBLDiaKkDN4tBQM/+hHc2UIFNk3qCkxRECLps=; b=Cay4xvZd0AyrZ6 Wlt6GtprEOtzYxHjSBXVDtg7WoTX6gYKbzzQ3rIvhXp+7aA2GDX+O9S4H05KtLAdGxoxPM23yG2wa IKhFDPCxZIfzk21CarSxltRJa9icT9X4lQlr4kZrB/YadFoI7u3Pjz8ZlNeXu/ZYEXWr9vmIqi7oi 8Q0S8WEMD4QjO2tHihJ441nYGO2bIwfeoVIsTvsboxAG5y+vtWwkUuo/pn3LfYADIOGe++K7uklHa hv8VFjDBzOK7I/7KcQcW6+SuIT9IUi0BER18tRbOK8PnOQ/imkvBCn0puSknu623TrANVfWv1Lkef CmmB+Wuzsgz/0r0WgUpA==; 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 1h0k81-0002bj-0m; Mon, 04 Mar 2019 09:43:21 +0000 Received: from relay10.mail.gandi.net ([217.70.178.230]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1h0k7u-0002aw-9H for linux-mtd@lists.infradead.org; Mon, 04 Mar 2019 09:43:19 +0000 Received: from xps13 (aaubervilliers-681-1-27-150.w90-88.abo.wanadoo.fr [90.88.147.150]) (Authenticated sender: miquel.raynal@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id B218C240015; Mon, 4 Mar 2019 09:43:02 +0000 (UTC) Date: Mon, 4 Mar 2019 10:43:01 +0100 From: Miquel Raynal To: Naga Sureshkumar Relli Subject: Re: [LINUX PATCH v13] rawnand: pl353: Add basic driver for arm pl353 smc nand interface Message-ID: <20190304104301.062ccc1e@xps13> In-Reply-To: <1549694247-24625-1-git-send-email-naga.sureshkumar.relli@xilinx.com> References: <1549694247-24625-1-git-send-email-naga.sureshkumar.relli@xilinx.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-20190304_014314_784993_404F1A66 X-CRM114-Status: GOOD ( 34.54 ) 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: bbrezillon@kernel.org, richard@nod.at, linux-kernel@vger.kernel.org, marek.vasut@gmail.com, linux-mtd@lists.infradead.org, nagasureshkumarrelli@gmail.com, michals@xilinx.com, computersforpeace@gmail.com, dwmw2@infradead.org 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 SGkgTmFnYSwKCk5hZ2EgU3VyZXNoa3VtYXIgUmVsbGkgPG5hZ2Euc3VyZXNoa3VtYXIucmVsbGlA eGlsaW54LmNvbT4gd3JvdGUgb24KU2F0LCA5IEZlYiAyMDE5IDEyOjA3OjI3ICswNTMwOgoKPiBB ZGQgZHJpdmVyIGZvciBhcm0gcGwzNTMgc3RhdGljIG1lbW9yeSBjb250cm9sbGVyIG5hbmQgaW50 ZXJmYWNlIHdpdGgKPiBIVyBFQ0Mgc3VwcG9ydC4gVGhpcyBjb250cm9sbGVyIGlzIHVzZWQgaW4g WGlsaW54IFp5bnEgU29DIGZvcgo+IGludGVyZmFjaW5nIHRoZSBOQU5EIGZsYXNoIG1lbW9yeS4K PiAKPiBTaWduZWQtb2ZmLWJ5OiBOYWdhIFN1cmVzaGt1bWFyIFJlbGxpIDxuYWdhLnN1cmVzaGt1 bWFyLnJlbGxpQHhpbGlueC5jb20+Cj4gLS0tCj4geGlsaW54IHp5bnEgVFJNIGxpbms6Cj4gaHR0 cHM6Ly93d3cueGlsaW54LmNvbS9zdXBwb3J0L2RvY3VtZW50YXRpb24vdXNlcl9ndWlkZXMvdWc1 ODUtWnlucS03MDAwLVRSTS5wZGYKPiAKPiBBUk0gcGwzNTMgc21jIFRSTSBsaW5rOgo+IGh0dHA6 Ly9pbmZvY2VudGVyLmFybS5jb20vaGVscC90b3BpYy9jb20uYXJtLmRvYy5kZGkwMzgwZy9EREkw MzgwR19zbWNfcGwzNTBfc2VyaWVzX3IycDFfdHJtLnBkZgo+IAo+IFRlc3RlZCBNaWNyb24gTVQy OUYyRzA4QUJBRUFXUCAoT24tZGllIGNhcGFibGUpIGFuZCBBTUQvU3BhbnNpb24gUzM0TUwwMUcx Lgo+IAo+IFNNQyBtZW1vcnkgY29udHJvbGxlciBkcml2ZXIgaXMgYXQgZHJpdmVycy9tZW1vcnkv cGwzNTMtc21jLmMKPiAKPiBDaGFuZ2VzIGluIHYxMzoKPiAgLSBSZWJhc2VkIHRoZSBkcml2ZXIg dG8gbXRkL25leHQKPiBDaGFuZ2VzIGluIHYxMjoKPiAgLSBSZWJhc2VkIHRoZSBkcml2ZXIgb24g dG9wIG9mIHY0LjE5IG5hbmQgdHJlZQo+ICAtIFJlbW92ZWQgbmFuZF9zY2FuX2lkZW50KCkgYW5k IG5hbmRfc2Nhbl90YWlsKCksIGFuZCBhZGRlZCBuYW5kX2NvbnRyb2xsZXJfb3BzCj4gICAgd2l0 aCAtPmF0dGFjaF9jaGlwKCkgYW5kIHVzZWQgbmFuZF9zY2FuKCkgaW5zdGVhZC4KPiAgLSBSZW5h bWVkIHBsMzUzX25hbmRfaW5mbyBzdHJ1Y3R1cmUgdG8gcGwzNTNfbmFuZF9jb250cm9sbGVyCj4g IC0gUmVuYW1lZCBuYW5kX2Jhc2UgYW5kIG5hbmRhZGRyIGluIHBsMzUzX25hbmRfY29udHJvbGxl ciB0byAncmVncycgYW5kICdidWZfYWRkcicKPiAgLSBBZGRlZCBuZXcgQVBJIHBsMzUzX3dhaXRf Zm9yX2VjY19kb25lKCkgdG8gd2FpdCBmb3IgZWNjIGRvbmUgYW5kIGNhbGwgaXQgZnJvbQo+ICAg IHBsMzUzX25hbmRfd3JpdGVfcGFnZV9od2VjYygpIGFuZCBwbDM1M19uYW5kX3JlYWRfcGFnZV9o d2VjYygpCj4gIC0gRGVmaW5lZCBuZXcgbWFjcm8gZm9yIG1heCBFQ0MgYmxvY2tzCj4gIC0gQWRk ZWQgcmV0dXJuIHZhbHVlIGNoZWNrIGZvciBlY2MuY2FsY3VsYXRlKCkKPiAgLSBSZW5hbWVkIHBs MzUzX25hbmRfY21kX2Z1bmN0aW9uKCkgdG8gcGwzNTNfbmFuZF9leGVjX29wX2NtZCgpCj4gIC0g QWRkZWQgeDE2IGJ1cy13aWR0aCBzdXBwb3J0Cj4gIC0gVGhlIGRlcGVuZGVudCBkcml2ZXIgcGwz NTMtc21jIGlzIGFscmVhZHkgcmV2aWV3ZWQgYW5kIGhlbmNlIGRyb3BwZWQgdGhlCj4gICAgc21j IGRyaXZlcgo+IENoYW5nZXMgaW4gdjExOgo+ICAtIFJlbW92ZWQgRG9jdW1lbnRhdGlvbiBwYXRj aCBhbmQgYWRkZWQgdGhlIHJlcXVpcmVkIGluZm8gaW4gZHJpdmVyIGFzCj4gICAgcGVyIEJvcmlz IGNvbW1lbnRzLgo+ICAtIFJlbW92ZWQgdW53YW50ZWQgdmFyaWFibGVzIGZyb20gcGwzNTNfbmFu ZF9pbmZvIGFzIHBlciBNaXF1ZWwgY29tbWVudHMKPiAgLSBSZW1vdmVkIElPX0FERFJfUi9XLgo+ ICAtIFJlcGxhY2VkIG9uaG90KCkgd2l0aCBod2VpZ2h0MzIoKQo+ICAtIERlZmluZWQgbWFjcm9z IGZvciBzdGF0aWMgdmFsdWVzIGluIGZ1bmN0aW9uIHBsMzUzX25hbmRfY29ycmVjdF9kYXRhKCkK PiAgLSBSZW1vdmVkIGFsbCB1bm5lY2Vzc2FyeSBkZWxheXMKPiAgLSBVc2VkIG5hbmRfd2FpdF9y ZWFkeSgpIHdoZXJlIGV2ZXIgaXMgcmVxdWlyZWQKPiAgLSBNb2RpZmVkIHRoZSBwbDM1M19zZXR1 cF9kYXRhX2ludGVyZmFjZSgpIGxvZ2ljIGFzIHBlciBNaXF1ZWwgY29tbWVudHMuCj4gIC0gVGFr ZW4gYXJyYXkgaW5zdGVhZCBvZiA3IHZhbHVlcyBpbiBwbDM1M19zZXR1cF9kYXRhX2ludGVyZmFj ZSgpIGFuZCBwYXNzCj4gICAgaXQgdG8gc21jIGRyaXZlci4KPiAgLSBBZGRlZCBjaGVjayB0byBj b2xsZWN0IHRoZSByZXR1cm4gdmFsdWUgb2YgbXRkX2RldmljZV9yZWdpc3RlcigpLgo+IENoYW5n ZXMgaW4gMTA6Cj4gIC0gVHlwb3MgY29ycmVjdGlvbiBsaWtlIG5hbmQgdG8gTkFORCBhbmQgc29j IHRvIFNPQyBldGMuLgo+ICAtIERlZmluZWQgbWFjcm9zIGZvciB0aGUgdmFsdWVzIGluIHBsMzUz X25hbmRfY2FsY3VsYXRlX2h3ZWNjKCkKPiAgLSBNb2RpZmVkIGVjY19zdGF0dXMgZnJvbSBpbnQg dG8gY2hhciBpbiBwbDM1M19uYW5kX2NhbGN1bGF0ZV9od2VjYygpCj4gIC0gQ2hhbmdlZCB0aGUg cmV0dXJuIHR5cGUgZm9ybSBpbnQgdG8gYm9vbCB0byB0aGUgZnVuY3Rpb24KPiAgICBvbmVob3Qo KQo+ICAtIFJlbW92ZWQgdWRlbGF5KDEwMDApIGluIHBsMzUzX2NtZF9mdW5jdGlvbiwgYXMgaXQg aXMgbm90IHJlcXVpcmVkCj4gIC0gRHJvcHBlZCBlY2MtPmh3Y3RsID0gTlVMTCBpbiBwbDM1M19l Y2NfaW5pdCgpCj4gIC0gQWRkZWQgYW4gZXJyb3IgbWVzc2FnZSBpbiBwbDM1M19lY2NfaW5pdCgp LCB3aGVuIHRoZXJlIGlzIG5vIG1hdGNoaW5nCj4gICAgb29ic2l6ZQo+ICAtIENoYW5nZWQgdGhl IHZhcmlhYmxlIGZyb20geG5hbmQgdG8geG5mYwo+ICAtIEFkZGVkIGxvZ2ljIHRvIGdldCBtdGQt Pm5hbWUgZnJvbSBEVCwgaWYgaXQgaXMgc3BlY2lmaWVkIGluIERUCj4gQ2hhbmdlcyBpbiB2OToK PiAgLSBBZGRyZXNzZWQgdGhlIGJlbG93IGNvbW1lbnRzIGdpdmVuIGJ5IE1pcXVlbAo+ICAtIGlu c3RlYWQgb2YgdXNpbmcgcGwzNTNfbmFuZF93cml0ZTMyLCB1c2UgZGlyZWN0bHkgd3JpdGVsX3Jl bGF4ZWQKPiAgLSBGaXhlZCBjaGVjayBwYXRjaCB3YXJuaW5ncwo+ICAtIFJlbmFtZWQgd3JpdGVf YnVmL3JlYWRfYnVmIHRvIHdyaXRlX2RhdGFfb3AvcmVhZF9kYXRhX29wCj4gIC0gdXNlIEJJVCBt YWNybyBpbnN0ZWFkIG9mIDEgPDwgbnIKPiAgLSBVc2UgTkFORF9ST1dfQUREUl8zIGZsYWcKPiAg LSBVc2UgbmFuZF93YWl0X3JlYWR5KCkKPiAgLSBSZW1vdmVkIHN3ZWNjIGZ1bmN0aW9ucwo+ICAt IFVzZSBhZGRyZXNzIGN5Y2xlcyBhcyBwZXIgc2l6ZSwgaW5zdGVhZCBvZiByZWFkaW5nIGl0IGZy b20gUGFyYW1ldGVyIHBhZ2UKPiAgLSBJbnN0ZWFkIG9mIHdyaXRpbmcgdG9vIG1hbnkgcGF0dGVy bnMsIHVzZSBvcHRpb25hbCBwcm9wZXJ0eQo+IENoYW5nZXMgaW4gdjg6Cj4gIC0gQWRkZWQgZXhl Y19vcCgpIGltcGxlbWVudGF0aW9uCj4gIC0gRml4ZWQgdGhlIGJlbG93IHY3IHJldmlldyBjb21t ZW50cwo+ICAtIHJlbW92ZWQgbXRkX2luZm8gZnJvbSBwbDM1M19uYW5kX2luZm8gc3RydWN0Cj4g IC0gQ29ycmVjdGVkIGVjYyBsYXlvdXQgb2Zmc2V0cwo+ICAtIEFkZGVkIG9uLWRpZSBlY2Mgc3Vw cG9ydAo+IENoYW5nZXMgaW4gdjc6Cj4gIC0gQ3VycmVudGx5IG5vdCBpbXBsZW1lbnRlZCB0aGUg bWVtY2xrIHJhdGUgYWRqdXN0bWVudHMuIEkgd2lsbAo+ICAgIGxvb2sgaW50byB0aGlzIGxhdGVy IGFuZCBvbmNlIHRoZSBiYXNpYyBkcml2ZXIgaXMgYWNjZXB0ZWQuCj4gIC0gRml4ZWQgR1BMIGxp Y2VuY2UgaWRlbnQKPiBDaGFuZ2VzIGluIHY2Ogo+ICAtIEZpeGVkIHRoZSBjaGVja3BhdGNoLnBs IHJlcG9ydGVkIHdhcm5pbmdzCj4gIC0gVXNpbmcgdGhlIGFkZHJlc3MgY3ljbGVzIGluZm9ybWF0 aW9uIGZyb20gdGhlIG9uZmkgcGFyYW0gcGFnZQo+ICAgIGVhcmxpZXIgaXQgaXMgaGFyZGNvZGVk IHRvIDUgaW4gZHJpdmVyCj4gQ2hhbmdlcyBpbiB2NToKPiAgLSBDb25maWd1cmUgdGhlIG5hbmQg dGltaW5nIHBhcmFtZXRlcnMgYXMgcGVyIHRoZSBvbmZpIHNwZWMgQ2hhbmdlcyBpbiB2NDoKPiAg LSBVcGRhdGVkIHRoZSBkcml2ZXIgdG8gc3luYyB3aXRoIHBsMzUzX3NtYyBkcml2ZXIgQVBJcwo+ IENoYW5nZXMgaW4gdjM6Cj4gIC0gaW1wbGVtZW50ZWQgdGhlIHByb3BlciBlcnJvciBjb2Rlcwo+ ICAtIGZ1cnRoZXIgYnJlYWtkb3duIHRoaXMgcGF0Y2ggdG8gbXVsdGlwbGUgc2V0cwo+ICAtIGFk ZGVkIHRoZSBjb250cm9sbGVyIGFuZCBkcml2ZXIgZGV0YWlscyB0byBEb2N1bWVudGF0aW9uIHNl Y3Rpb24KPiAgLSB1cGRhdGVkIHRoZSBsaWNlbmVjZSB0byBHUEx2Mgo+ICAtIHJlb3JnYW5pemVk IHRoZSBwbDM1M19uYW5kX2VjY19pbml0IGZ1bmN0aW9uCj4gQ2hhbmdlcyBpbiB2MjoKPiAgLSB1 c2UgImRlcGVuZHMgb24iIHJhdGhlciB0aGFuICJzZWxlY3QiIG9wdGlvbiBpbiBrY29uZmlnCj4g IC0gcmVtb3ZlIHVudXNlZCB2YXJpYWJsZSBwYXJ0cwo+IC0tLQo+ICBkcml2ZXJzL210ZC9uYW5k L3Jhdy9LY29uZmlnICAgICAgfCAgICA4ICsKPiAgZHJpdmVycy9tdGQvbmFuZC9yYXcvTWFrZWZp bGUgICAgIHwgICAgMSArCj4gIGRyaXZlcnMvbXRkL25hbmQvcmF3L3BsMzUzX25hbmQuYyB8IDEz ODAgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ICAzIGZpbGVzIGNoYW5n ZWQsIDEzODkgaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tdGQv bmFuZC9yYXcvcGwzNTNfbmFuZC5jCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQv cmF3L0tjb25maWcgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnCj4gaW5kZXggMWE1NWQz ZS4uYmM2YzBhMCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9LY29uZmlnCj4g KysrIGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+IEBAIC01NDEsNCArNTQxLDEyIEBA IGNvbmZpZyBNVERfTkFORF9URUdSQQo+ICAJICBpcyBzdXBwb3J0ZWQuIEV4dHJhIE9PQiBieXRl cyB3aGVuIHVzaW5nIEhXIEVDQyBhcmUgY3VycmVudGx5Cj4gIAkgIG5vdCBzdXBwb3J0ZWQuCj4g IAo+ICtjb25maWcgTVREX05BTkRfUEwzNTMKPiArCXRyaXN0YXRlICJBUk0gUGwzNTMgTkFORCBm bGFzaCBkcml2ZXIiCj4gKwlkZXBlbmRzIG9uIE1URF9OQU5EICYmIEFSTQo+ICsJZGVwZW5kcyBv biBQTDM1M19TTUMKPiArCWhlbHAKPiArCSAgRW5hYmxlcyBzdXBwb3J0IGZvciBQcmltZUNlbGwg U3RhdGljIE1lbW9yeSBDb250cm9sbGVyIFBMMzUzLgo+ICsKPiArCj4gIGVuZGlmICMgTVREX05B TkQKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvTWFrZWZpbGUgYi9kcml2ZXJz L210ZC9uYW5kL3Jhdy9NYWtlZmlsZQo+IGluZGV4IDU3MTU5YjMuLjlkM2M0OGQgMTAwNjQ0Cj4g LS0tIGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL210ZC9u YW5kL3Jhdy9NYWtlZmlsZQo+IEBAIC01Niw2ICs1Niw3IEBAIG9iai0kKENPTkZJR19NVERfTkFO RF9CUkNNTkFORCkJCSs9IGJyY21uYW5kLwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfUUNPTSkJ CSs9IHFjb21fbmFuZGMubwo+ICBvYmotJChDT05GSUdfTVREX05BTkRfTVRLKQkJKz0gbXRrX2Vj Yy5vIG10a19uYW5kLm8KPiAgb2JqLSQoQ09ORklHX01URF9OQU5EX1RFR1JBKQkJKz0gdGVncmFf bmFuZC5vCj4gK29iai0kKENPTkZJR19NVERfTkFORF9QTDM1MykJCSs9IHBsMzUzX25hbmQubwo+ ICAKPiAgbmFuZC1vYmpzIDo9IG5hbmRfYmFzZS5vIG5hbmRfbGVnYWN5Lm8gbmFuZF9iYnQubyBu YW5kX3RpbWluZ3MubyBuYW5kX2lkcy5vCj4gIG5hbmQtb2JqcyArPSBuYW5kX29uZmkubwo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9wbDM1M19uYW5kLmMgYi9kcml2ZXJzL210 ZC9uYW5kL3Jhdy9wbDM1M19uYW5kLmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAw MDAwMDAuLjFkYmFhZTUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9tdGQvbmFuZC9y YXcvcGwzNTNfbmFuZC5jCj4gQEAgLTAsMCArMSwxMzgwIEBACj4gKy8vIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiBHUEwtMi4wCj4gKy8qCj4gKyAqIEFSTSBQTDM1MyBOQU5EIGZsYXNoIGNvbnRy b2xsZXIgZHJpdmVyCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNyBYaWxpbngsIEluYwo+ ICsgKiBBdXRob3I6IFB1bm5haWFoIGNob3dkYXJ5IGthbGx1cmkgPHB1bm5haWFoQHhpbGlueC5j b20+Cj4gKyAqIEF1dGhvcjogTmFnYSBTdXJlc2hrdW1hciBSZWxsaSA8bmFnYXN1cmVAeGlsaW54 LmNvbT4KPiArICoKPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9kZWxheS5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+Cj4gKyNp bmNsdWRlIDxsaW51eC9pby5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9pcnEuaD4KPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVk ZSA8bGludXgvbW9kdWxlcGFyYW0uaD4KPiArI2luY2x1ZGUgPGxpbnV4L210ZC9tdGQuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L210ZC9yYXduYW5kLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tdGQvbmFu ZF9lY2MuaD4KPiArI2luY2x1ZGUgPGxpbnV4L210ZC9wYXJ0aXRpb25zLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9vZl9hZGRyZXNzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L29mX3BsYXRmb3JtLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9y bV9kZXZpY2UuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L3BsMzUzLXNtYy5oPgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKwo+ICsjZGVmaW5lIFBM MzUzX05BTkRfRFJJVkVSX05BTUUgInBsMzUzLW5hbmQiCj4gKwo+ICsvKiBOQU5EIGZsYXNoIGRy aXZlciBkZWZpbmVzICovCj4gKyNkZWZpbmUgUEwzNTNfTkFORF9DTURfUEhBU0UJMQkvKiBFbmQg Y29tbWFuZCB2YWxpZCBpbiBjb21tYW5kIHBoYXNlICovCj4gKyNkZWZpbmUgUEwzNTNfTkFORF9E QVRBX1BIQVNFCTIJLyogRW5kIGNvbW1hbmQgdmFsaWQgaW4gZGF0YSBwaGFzZSAqLwo+ICsjZGVm aW5lIFBMMzUzX05BTkRfRUNDX1NJWkUJNTEyCS8qIFNpemUgb2YgZGF0YSBmb3IgRUNDIG9wZXJh dGlvbiAqLwo+ICsKPiArLyogRmxhc2ggbWVtb3J5IGNvbnRyb2xsZXIgb3BlcmF0aW5nIHBhcmFt ZXRlcnMgKi8KPiArCj4gKyNkZWZpbmUgUEwzNTNfTkFORF9FQ0NfQ09ORklHCShCSVQoNCkgIHwJ LyogRUNDIHJlYWQgYXQgZW5kIG9mIHBhZ2UgKi8gXAo+ICsJCQkJICgwIDw8IDUpKQkvKiBObyBK dW1waW5nICovCj4gKwo+ICsvKiBBWEkgQWRkcmVzcyBkZWZpbml0aW9ucyAqLwo+ICsjZGVmaW5l IFNUQVJUX0NNRF9TSElGVAkJMwo+ICsjZGVmaW5lIEVORF9DTURfU0hJRlQJCTExCj4gKyNkZWZp bmUgRU5EX0NNRF9WQUxJRF9TSElGVAkyMAo+ICsjZGVmaW5lIEFERFJfQ1lDTEVTX1NISUZUCTIx Cj4gKyNkZWZpbmUgQ0xFQVJfQ1NfU0hJRlQJCTIxCj4gKyNkZWZpbmUgRUNDX0xBU1RfU0hJRlQJ CTEwCj4gKyNkZWZpbmUgQ09NTUFORF9QSEFTRQkJKDAgPDwgMTkpCj4gKyNkZWZpbmUgREFUQV9Q SEFTRQkJQklUKDE5KQo+ICsKPiArI2RlZmluZSBQTDM1M19OQU5EX0VDQ19MQVNUCUJJVChFQ0Nf TEFTVF9TSElGVCkJLyogU2V0IEVDQ19MYXN0ICovCj4gKyNkZWZpbmUgUEwzNTNfTkFORF9DTEVB Ul9DUwlCSVQoQ0xFQVJfQ1NfU0hJRlQpCS8qIENsZWFyIGNoaXAgc2VsZWN0ICovCj4gKwo+ICsj ZGVmaW5lIFBMMzUzX05BTkRfRUNDX0JVU1lfVElNRU9VVAkoMSAqIEhaKQo+ICsjZGVmaW5lIFBM MzUzX05BTkRfREVWX0JVU1lfVElNRU9VVAkoMSAqIEhaKQo+ICsjZGVmaW5lIFBMMzUzX05BTkRf TEFTVF9UUkFOU0ZFUl9MRU5HVEgJNAo+ICsjZGVmaW5lIFBMMzUzX05BTkRfRUNDX1ZBTElEX1NI SUZUCTI0Cj4gKyNkZWZpbmUgUEwzNTNfTkFORF9FQ0NfVkFMSURfTUFTSwkweDQwCj4gKyNkZWZp bmUgUEwzNTNfRUNDX0JJVFNfQllURU9GRl9NQVNLCTB4MUZGCj4gKyNkZWZpbmUgUEwzNTNfRUND X0JJVFNfQklUT0ZGX01BU0sJMHg3Cj4gKyNkZWZpbmUgUEwzNTNfRUNDX0JJVF9NQVNLCQkweEZG Rgo+ICsjZGVmaW5lIFBMMzUzX1RSRUFfTUFYX1ZBTFVFCQkxCj4gKyNkZWZpbmUgUEwzNTNfTUFY X0VDQ19DSFVOS1MJCTQKPiArI2RlZmluZSBQTDM1M19NQVhfRUNDX0JZVEVTCQkzCj4gKwo+ICtz dHJ1Y3QgcGwzNTNfbmZjX29wIHsKPiArCXUzMiBjbW5kc1s0XTsKPiArCXUzMiBlbmRfY21kOwo+ ICsJdTMyIGFkZHJzOwo+ICsJdTMyIG5hZGRyczsKPiArCXUzMiBhZGRyNTsKPiArCXUzMiBhZGRy NjsKPiArCXVuc2lnbmVkIGludCBkYXRhX2luc3RyX2lkeDsKPiArCXVuc2lnbmVkIGludCByZHlf dGltZW91dF9tczsKPiArCXVuc2lnbmVkIGludCByZHlfZGVsYXlfbnM7Cj4gKwl1bnNpZ25lZCBp bnQgY2xlX2FsZV9kZWxheV9uczsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX29wX2luc3RyICpkYXRh X2luc3RyOwo+ICt9Owo+ICsKPiArLyoqCj4gKyAqIHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xs ZXIgLSBEZWZpbmVzIHRoZSBOQU5EIGZsYXNoIGNvbnRyb2xsZXIgZHJpdmVyCj4gKyAqCQkJCSAg aW5zdGFuY2UKPiArICogQGNoaXA6CQlOQU5EIGNoaXAgaW5mb3JtYXRpb24gc3RydWN0dXJlCj4g KyAqIEBkZXY6CQlQYXJlbnQgZGV2aWNlICh1c2VkIHRvIHByaW50IGVycm9yIG1lc3NhZ2VzKQo+ ICsgKiBAcmVnczoJCVZpcnR1YWwgYWRkcmVzcyBvZiB0aGUgTkFORCBmbGFzaCBkZXZpY2UKPiAr ICogQGJ1Zl9hZGRyOgkJVmlydHVhbCBhZGRyZXNzIG9mIHRoZSBOQU5EIGZsYXNoIGRldmljZSBm b3IKPiArICoJCQlkYXRhIHJlYWQvd3JpdGVzCj4gKyAqIEBhZGRyX2N5Y2xlczoJQWRkcmVzcyBj eWNsZXMKPiArICogQG1jbGs6CQlNZW1vcnkgY29udHJvbGxlciBjbG9jawo+ICsgKiBAYnVzd2lk dGg6CQlCdXMgd2lkdGggOCBvciAxNgo+ICsgKi8KPiArc3RydWN0IHBsMzUzX25hbmRfY29udHJv bGxlciB7Cj4gKwlzdHJ1Y3QgbmFuZF9jb250cm9sbGVyIGNvbnRyb2xsZXI7Cj4gKwlzdHJ1Y3Qg bmFuZF9jaGlwIGNoaXA7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwl2b2lkIF9faW9tZW0g KnJlZ3M7Cj4gKwl2b2lkIF9faW9tZW0gKmJ1Zl9hZGRyOwo+ICsJdTggYWRkcl9jeWNsZXM7Cj4g KwlzdHJ1Y3QgY2xrICptY2xrOwo+ICsJdTMyIGJ1c3dpZHRoOwo+ICt9Owo+ICsKPiArc3RhdGlj IGludCBwbDM1M19lY2Nfb29ibGF5b3V0MTZfZWNjKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBpbnQg c2VjdGlvbiwKPiArCQkJCSAgICAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2JyZWdpb24pCj4g K3sKPiArCXN0cnVjdCBuYW5kX2NoaXAgKmNoaXAgPSBtdGRfdG9fbmFuZChtdGQpOwo+ICsKPiAr CWlmIChzZWN0aW9uID49IGNoaXAtPmVjYy5zdGVwcykKPiArCQlyZXR1cm4gLUVSQU5HRTsKPiAr Cj4gKwlvb2JyZWdpb24tPm9mZnNldCA9IChzZWN0aW9uICogY2hpcC0+ZWNjLmJ5dGVzKTsKPiAr CW9vYnJlZ2lvbi0+bGVuZ3RoID0gY2hpcC0+ZWNjLmJ5dGVzOwo+ICsKPiArCXJldHVybiAwOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHBsMzUzX2VjY19vb2JsYXlvdXQxNl9mcmVlKHN0cnVjdCBt dGRfaW5mbyAqbXRkLCBpbnQgc2VjdGlvbiwKPiArCQkJCSAgICAgIHN0cnVjdCBtdGRfb29iX3Jl Z2lvbiAqb29icmVnaW9uKQo+ICt7Cj4gKwlzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwID0gbXRkX3Rv X25hbmQobXRkKTsKPiArCj4gKwlpZiAoc2VjdGlvbiA+PSBjaGlwLT5lY2Muc3RlcHMpCj4gKwkJ cmV0dXJuIC1FUkFOR0U7Cj4gKwo+ICsJb29icmVnaW9uLT5vZmZzZXQgPSAoc2VjdGlvbiAqIGNo aXAtPmVjYy5ieXRlcykgKyA4Owo+ICsJb29icmVnaW9uLT5sZW5ndGggPSA4Owo+ICsKPiArCXJl dHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG10ZF9vb2JsYXlvdXRfb3Bz IHBsMzUzX2VjY19vb2JsYXlvdXQxNl9vcHMgPSB7Cj4gKwkuZWNjID0gcGwzNTNfZWNjX29vYmxh eW91dDE2X2VjYywKPiArCS5mcmVlID0gcGwzNTNfZWNjX29vYmxheW91dDE2X2ZyZWUsCj4gK307 Cj4gKwo+ICtzdGF0aWMgaW50IHBsMzUzX2VjY19vb2JsYXlvdXQ2NF9lY2Moc3RydWN0IG10ZF9p bmZvICptdGQsIGludCBzZWN0aW9uLAo+ICsJCQkJICAgICBzdHJ1Y3QgbXRkX29vYl9yZWdpb24g Km9vYnJlZ2lvbikKPiArewo+ICsJc3RydWN0IG5hbmRfY2hpcCAqY2hpcCA9IG10ZF90b19uYW5k KG10ZCk7Cj4gKwo+ICsJaWYgKHNlY3Rpb24gPj0gY2hpcC0+ZWNjLnN0ZXBzKQo+ICsJCXJldHVy biAtRVJBTkdFOwo+ICsKPiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0gKHNlY3Rpb24gKiBjaGlwLT5l Y2MuYnl0ZXMpICsgNTI7Cj4gKwlvb2JyZWdpb24tPmxlbmd0aCA9IGNoaXAtPmVjYy5ieXRlczsK PiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBwbDM1M19lY2Nfb29ibGF5 b3V0NjRfZnJlZShzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNlY3Rpb24sCj4gKwkJCQkgICAg ICBzdHJ1Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPiArewo+ICsJc3RydWN0IG5hbmRf Y2hpcCAqY2hpcCA9IG10ZF90b19uYW5kKG10ZCk7Cj4gKwo+ICsJaWYgKHNlY3Rpb24pCj4gKwkJ cmV0dXJuIC1FUkFOR0U7Cj4gKwo+ICsJaWYgKHNlY3Rpb24gPj0gY2hpcC0+ZWNjLnN0ZXBzKQo+ ICsJCXJldHVybiAtRVJBTkdFOwo+ICsKPiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0gKHNlY3Rpb24g KiBjaGlwLT5lY2MuYnl0ZXMpICsgMjsKPiArCW9vYnJlZ2lvbi0+bGVuZ3RoID0gNTA7Cj4gKwo+ ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgbXRkX29vYmxheW91 dF9vcHMgcGwzNTNfZWNjX29vYmxheW91dDY0X29wcyA9IHsKPiArCS5lY2MgPSBwbDM1M19lY2Nf b29ibGF5b3V0NjRfZWNjLAo+ICsJLmZyZWUgPSBwbDM1M19lY2Nfb29ibGF5b3V0NjRfZnJlZSwK PiArfTsKPiArCj4gKy8qIEdlbmVyaWMgZmxhc2ggYmJ0IGRlY3JpcHRvcnMgKi8KPiArc3RhdGlj IHU4IGJidF9wYXR0ZXJuW10gPSB7ICdCJywgJ2InLCAndCcsICcwJyB9Owo+ICtzdGF0aWMgdTgg bWlycm9yX3BhdHRlcm5bXSA9IHsgJzEnLCAndCcsICdiJywgJ0InIH07Cj4gKwo+ICtzdGF0aWMg c3RydWN0IG5hbmRfYmJ0X2Rlc2NyIGJidF9tYWluX2Rlc2NyID0gewo+ICsJLm9wdGlvbnMgPSBO QU5EX0JCVF9MQVNUQkxPQ0sgfCBOQU5EX0JCVF9DUkVBVEUgfCBOQU5EX0JCVF9XUklURQo+ICsJ CXwgTkFORF9CQlRfMkJJVCB8IE5BTkRfQkJUX1ZFUlNJT04gfCBOQU5EX0JCVF9QRVJDSElQLAo+ ICsJLm9mZnMgPSA0LAo+ICsJLmxlbiA9IDQsCj4gKwkudmVyb2ZmcyA9IDIwLAo+ICsJLm1heGJs b2NrcyA9IDQsCj4gKwkucGF0dGVybiA9IGJidF9wYXR0ZXJuCj4gK307Cj4gKwo+ICtzdGF0aWMg c3RydWN0IG5hbmRfYmJ0X2Rlc2NyIGJidF9taXJyb3JfZGVzY3IgPSB7Cj4gKwkub3B0aW9ucyA9 IE5BTkRfQkJUX0xBU1RCTE9DSyB8IE5BTkRfQkJUX0NSRUFURSB8IE5BTkRfQkJUX1dSSVRFCj4g KwkJfCBOQU5EX0JCVF8yQklUIHwgTkFORF9CQlRfVkVSU0lPTiB8IE5BTkRfQkJUX1BFUkNISVAs Cj4gKwkub2ZmcyA9IDQsCj4gKwkubGVuID0gNCwKPiArCS52ZXJvZmZzID0gMjAsCj4gKwkubWF4 YmxvY2tzID0gNCwKPiArCS5wYXR0ZXJuID0gbWlycm9yX3BhdHRlcm4KPiArfTsKPiArCj4gK3N0 YXRpYyB2b2lkIHBsMzUzX25mY19mb3JjZV9ieXRlX2FjY2VzcyhzdHJ1Y3QgbmFuZF9jaGlwICpj aGlwLAo+ICsJCQkJCWJvb2wgZm9yY2VfOGJpdCkKPiArewo+ICsJc3RydWN0IHBsMzUzX25hbmRf Y29udHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFpbmVyX29mKGNoaXAsIHN0cnVjdCBwbDM1M19u YW5kX2NvbnRyb2xsZXIsIGNoaXApOwo+ICsKPiArCWlmICghKGNoaXAtPm9wdGlvbnMgJiBOQU5E X0JVU1dJRFRIXzE2KSkKPiArCQlyZXR1cm47Cj4gKwo+ICsJaWYgKGZvcmNlXzhiaXQpCj4gKwkJ cGwzNTNfc21jX3NldF9idXN3aWR0aChQTDM1M19TTUNfTUVNX1dJRFRIXzgpOwo+ICsJZWxzZQo+ ICsJCXBsMzUzX3NtY19zZXRfYnVzd2lkdGgoUEwzNTNfU01DX01FTV9XSURUSF8xNik7Cj4gK30K PiArCj4gKy8qKgo+ICsgKiBwbDM1M19uYW5kX3JlYWRfZGF0YV9vcCAtIHJlYWQgY2hpcCBkYXRh IGludG8gYnVmZmVyCj4gKyAqIEBjaGlwOglQb2ludGVyIHRvIHRoZSBOQU5EIGNoaXAgaW5mbyBz dHJ1Y3R1cmUKPiArICogQGluOgkJUG9pbnRlciB0byB0aGUgYnVmZmVyIHRvIHN0b3JlIHJlYWQg ZGF0YQo+ICsgKiBAbGVuOglOdW1iZXIgb2YgYnl0ZXMgdG8gcmVhZAo+ICsgKiBAZm9yY2VfOGJp dDoJRm9yY2UgOC1iaXQgYnVzIGFjY2Vzcwo+ICsgKiBSZXR1cm46CUFsd2F5cyByZXR1cm4gemVy bwo+ICsgKi8KPiArc3RhdGljIGludCBwbDM1M19uYW5kX3JlYWRfZGF0YV9vcChzdHJ1Y3QgbmFu ZF9jaGlwICpjaGlwLAo+ICsJCQkJICAgdTggKmluLAo+ICsJCQkJICAgdW5zaWduZWQgaW50IGxl biwgYm9vbCBmb3JjZV84Yml0KQo+ICt7Cj4gKwlpbnQgaTsKPiArCXN0cnVjdCBwbDM1M19uYW5k X2NvbnRyb2xsZXIgKnhuZmMgPQo+ICsJCWNvbnRhaW5lcl9vZihjaGlwLCBzdHJ1Y3QgcGwzNTNf bmFuZF9jb250cm9sbGVyLCBjaGlwKTsKPiArCj4gKwlpZiAoZm9yY2VfOGJpdCkKPiArCQlwbDM1 M19uZmNfZm9yY2VfYnl0ZV9hY2Nlc3MoY2hpcCwgdHJ1ZSk7Cj4gKwo+ICsJaWYgKChJU19BTElH TkVEKCh1aW50MzJfdClpbiwgc2l6ZW9mKHVpbnQzMl90KSkgJiYKPiArCSAgICAgSVNfQUxJR05F RChsZW4sIHNpemVvZih1aW50MzJfdCkpKSB8fCAhZm9yY2VfOGJpdCkgewo+ICsJCXUzMiAqcHRy ID0gKHUzMiAqKWluOwo+ICsKPiArCQlsZW4gLz0gNDsKPiArCQlmb3IgKGkgPSAwOyBpIDwgbGVu OyBpKyspCj4gKwkJCXB0cltpXSA9IHJlYWRsKHhuZmMtPmJ1Zl9hZGRyKTsKPiArCX0gZWxzZSB7 Cj4gKwkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKQo+ICsJCQlpbltpXSA9IHJlYWRiKHhuZmMt PmJ1Zl9hZGRyKTsKPiArCX0KPiArCWlmIChmb3JjZV84Yml0KQo+ICsJCXBsMzUzX25mY19mb3Jj ZV9ieXRlX2FjY2VzcyhjaGlwLCBmYWxzZSk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4g Ky8qKgo+ICsgKiBwbDM1M19uYW5kX3dyaXRlX2J1ZiAtIHdyaXRlIGJ1ZmZlciB0byBjaGlwCj4g KyAqIEBtdGQ6CVBvaW50ZXIgdG8gdGhlIG10ZCBpbmZvIHN0cnVjdHVyZQo+ICsgKiBAYnVmOglQ b2ludGVyIHRvIHRoZSBidWZmZXIgdG8gc3RvcmUgd3JpdGUgZGF0YQo+ICsgKiBAbGVuOglOdW1i ZXIgb2YgYnl0ZXMgdG8gd3JpdGUKPiArICogQGZvcmNlXzhiaXQ6CUZvcmNlIDgtYml0IGJ1cyBh Y2Nlc3MKPiArICovCj4gK3N0YXRpYyB2b2lkIHBsMzUzX25hbmRfd3JpdGVfZGF0YV9vcChzdHJ1 Y3QgbmFuZF9jaGlwICpjaGlwLCBjb25zdCB1OCAqYnVmLAo+ICsJCQkJICAgICBpbnQgbGVuLCBi b29sIGZvcmNlXzhiaXQpCj4gK3sKPiArCWludCBpOwo+ICsJc3RydWN0IHBsMzUzX25hbmRfY29u dHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFpbmVyX29mKGNoaXAsIHN0cnVjdCBwbDM1M19uYW5k X2NvbnRyb2xsZXIsIGNoaXApOwo+ICsKPiArCWlmIChmb3JjZV84Yml0KQo+ICsJCXBsMzUzX25m Y19mb3JjZV9ieXRlX2FjY2VzcyhjaGlwLCB0cnVlKTsKPiArCj4gKwlpZiAoKElTX0FMSUdORUQo KHVpbnQzMl90KWJ1Ziwgc2l6ZW9mKHVpbnQzMl90KSkgJiYKPiArCSAgICAgSVNfQUxJR05FRChs ZW4sIHNpemVvZih1aW50MzJfdCkpKSB8fCAhZm9yY2VfOGJpdCkgewo+ICsJCXUzMiAqcHRyID0g KHUzMiAqKWJ1ZjsKPiArCj4gKwkJbGVuIC89IDQ7Cj4gKwkJZm9yIChpID0gMDsgaSA8IGxlbjsg aSsrKQo+ICsJCQl3cml0ZWwocHRyW2ldLCB4bmZjLT5idWZfYWRkcik7Cj4gKwl9IGVsc2Ugewo+ ICsJCWZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykKPiArCQkJd3JpdGViKGJ1ZltpXSwgeG5mYy0+ YnVmX2FkZHIpOwo+ICsJfQo+ICsJaWYgKGZvcmNlXzhiaXQpCj4gKwkJcGwzNTNfbmZjX2ZvcmNl X2J5dGVfYWNjZXNzKGNoaXAsIGZhbHNlKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBwbDM1M193 YWl0X2Zvcl9lY2NfZG9uZSh2b2lkKQo+ICt7Cj4gKwl1bnNpZ25lZCBsb25nIHRpbWVvdXQgPSBq aWZmaWVzICsgUEwzNTNfTkFORF9FQ0NfQlVTWV9USU1FT1VUOwo+ICsKPiArCWRvIHsKPiArCQlp ZiAocGwzNTNfc21jX2VjY19pc19idXN5KCkpCj4gKwkJCWNwdV9yZWxheCgpOwo+ICsJCWVsc2UK PiArCQkJYnJlYWs7Cj4gKwl9IHdoaWxlICghdGltZV9hZnRlcl9lcShqaWZmaWVzLCB0aW1lb3V0 KSk7Cj4gKwo+ICsJaWYgKHRpbWVfYWZ0ZXJfZXEoamlmZmllcywgdGltZW91dCkpIHsKPiArCQlw cl9lcnIoIiVzIHRpbWVkIG91dFxuIiwgX19mdW5jX18pOwo+ICsJCXJldHVybiAtRVRJTUVET1VU Owo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKioKPiArICogcGwzNTNfbmFu ZF9jYWxjdWxhdGVfaHdlY2MgLSBDYWxjdWxhdGUgSGFyZHdhcmUgRUNDCj4gKyAqIEBtdGQ6CVBv aW50ZXIgdG8gdGhlIG10ZF9pbmZvIHN0cnVjdHVyZQo+ICsgKiBAZGF0YToJUG9pbnRlciB0byB0 aGUgcGFnZSBkYXRhCj4gKyAqIEBlY2M6CVBvaW50ZXIgdG8gdGhlIEVDQyBidWZmZXIgd2hlcmUg RUNDIGRhdGEgbmVlZHMgdG8gYmUgc3RvcmVkCj4gKyAqCj4gKyAqIFRoaXMgZnVuY3Rpb24gcmV0 cmlldmVzIHRoZSBIYXJkd2FyZSBFQ0MgZGF0YSBmcm9tIHRoZSBjb250cm9sbGVyIGFuZCByZXR1 cm5zCj4gKyAqIEVDQyBkYXRhIGJhY2sgdG8gdGhlIE1URCBzdWJzeXN0ZW0uCj4gKyAqIEl0IG9w ZXJhdGVzIG9uIGEgbnVtYmVyIG9mIDUxMiBieXRlIGJsb2NrcyBvZiBOQU5EIG1lbW9yeSBhbmQg Y2FuIGJlCj4gKyAqIHByb2dyYW1tZWQgdG8gc3RvcmUgdGhlIEVDQyBjb2RlcyBhZnRlciB0aGUg ZGF0YSBpbiBtZW1vcnkuIEZvciB3cml0ZXMsCj4gKyAqIHRoZSBFQ0MgaXMgd3JpdHRlbiB0byB0 aGUgc3BhcmUgYXJlYSBvZiB0aGUgcGFnZS4gRm9yIHJlYWRzLCB0aGUgcmVzdWx0IG9mCj4gKyAq IGEgYmxvY2sgRUNDIGNoZWNrIGFyZSBtYWRlIGF2YWlsYWJsZSB0byB0aGUgZGV2aWNlIGRyaXZl ci4KPiArICoKPiArICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4gKyAqIHwgICAgICAgICAgICAgICBuICog NTEyIGJsb2NrcyAgICAgICAgICAgICAgICAgIHwgZXh0cmEgIHwgZWNjICAgIHwgICAgIHwKPiAr ICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBibG9j ayAgfCBjb2RlcyAgfCAgICAgfAo+ICsgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiArICoKPiArICogVGhl IEVDQyBjYWxjdWxhdGlvbiB1c2VzIGEgc2ltcGxlIEhhbW1pbmcgY29kZSwgdXNpbmcgMS1iaXQg Y29ycmVjdGlvbiAyLWJpdAo+ICsgKiBkZXRlY3Rpb24uIEl0IHN0YXJ0cyB3aGVuIGEgdmFsaWQg cmVhZCBvciB3cml0ZSBjb21tYW5kIHdpdGggYSA1MTIgYnl0ZQo+ICsgKiBhbGlnbmVkIGFkZHJl c3MgaXMgZGV0ZWN0ZWQgb24gdGhlIG1lbW9yeSBpbnRlcmZhY2UuCj4gKyAqCj4gKyAqIFJldHVy bjoJMCBvbiBzdWNjZXNzIG9yIGVycm9yIHZhbHVlIG9uIGZhaWx1cmUKPiArICovCj4gK3N0YXRp YyBpbnQgcGwzNTNfbmFuZF9jYWxjdWxhdGVfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwK PiArCQkJCSAgICAgIGNvbnN0IHU4ICpkYXRhLCB1OCAqZWNjKQo+ICt7Cj4gKwl1MzIgZWNjX3Zh bHVlOwo+ICsJdTggY2h1bmssIGVjY19ieXRlLCBlY2Nfc3RhdHVzOwo+ICsKPiArCWZvciAoY2h1 bmsgPSAwOyBjaHVuayA8IFBMMzUzX01BWF9FQ0NfQ0hVTktTOyBjaHVuaysrKSB7Cj4gKwkJLyog UmVhZCBFQ0MgdmFsdWUgZm9yIGVhY2ggYmxvY2sgKi8KPiArCQllY2NfdmFsdWUgPSBwbDM1M19z bWNfZ2V0X2VjY192YWwoY2h1bmspOwo+ICsJCWVjY19zdGF0dXMgPSAoZWNjX3ZhbHVlID4+IFBM MzUzX05BTkRfRUNDX1ZBTElEX1NISUZUKTsKPiArCj4gKwkJLyogRUNDIHZhbHVlIHZhbGlkICov Cj4gKwkJaWYgKGVjY19zdGF0dXMgJiBQTDM1M19OQU5EX0VDQ19WQUxJRF9NQVNLKSB7Cj4gKwkJ CWZvciAoZWNjX2J5dGUgPSAwOyBlY2NfYnl0ZSA8IFBMMzUzX01BWF9FQ0NfQllURVM7Cj4gKwkJ CSAgICAgZWNjX2J5dGUrKykgewo+ICsJCQkJLyogQ29weSBFQ0MgYnl0ZXMgdG8gTVREIGJ1ZmZl ciAqLwo+ICsJCQkJKmVjYyA9IH5lY2NfdmFsdWUgJiAweEZGOwo+ICsJCQkJZWNjX3ZhbHVlID0g ZWNjX3ZhbHVlID4+IDg7Cj4gKwkJCQllY2MrKzsKPiArCQkJfQo+ICsJCX0gZWxzZSB7Cj4gKwkJ CXByX3dhcm4oIiVzIHN0YXR1cyBmYWlsZWRcbiIsIF9fZnVuY19fKTsKPiArCQkJcmV0dXJuIC0x Owo+ICsJCX0KPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHBs MzUzX25hbmRfY29ycmVjdF9kYXRhIC0gRUNDIGNvcnJlY3Rpb24gZnVuY3Rpb24KPiArICogQG10 ZDoJUG9pbnRlciB0byB0aGUgbXRkX2luZm8gc3RydWN0dXJlCj4gKyAqIEBidWY6CVBvaW50ZXIg dG8gdGhlIHBhZ2UgZGF0YQo+ICsgKiBAcmVhZF9lY2M6CVBvaW50ZXIgdG8gdGhlIEVDQyB2YWx1 ZSByZWFkIGZyb20gc3BhcmUgZGF0YSBhcmVhCj4gKyAqIEBjYWxjX2VjYzoJUG9pbnRlciB0byB0 aGUgY2FsY3VsYXRlZCBFQ0MgdmFsdWUKPiArICoKPiArICogVGhpcyBmdW5jdGlvbiBjb3JyZWN0 cyB0aGUgRUNDIHNpbmdsZSBiaXQgZXJyb3JzICYgZGV0ZWN0cyAyLWJpdCBlcnJvcnMuCj4gKyAq Cj4gKyAqIFJldHVybjoJMCBpZiBubyBFQ0MgZXJyb3JzIGZvdW5kCj4gKyAqCQkxIGlmIHNpbmds ZSBiaXQgZXJyb3IgZm91bmQgYW5kIGNvcnJlY3RlZC4KPiArICoJCS0xIGlmIG11bHRpcGxlIHVu Y29ycmVjdGFibGUgRUNDIGVycm9ycyBmb3VuZC4KPiArICovCj4gK3N0YXRpYyBpbnQgcGwzNTNf bmFuZF9jb3JyZWN0X2RhdGEoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgdW5zaWduZWQgY2hhciAq YnVmLAo+ICsJCQkJICAgdW5zaWduZWQgY2hhciAqcmVhZF9lY2MsCj4gKwkJCQkgICB1bnNpZ25l ZCBjaGFyICpjYWxjX2VjYykKCklzbid0IGl0IGEgcmVndWxhciBIYW1taW5nIHNvZnR3YXJlIEVD QyBhbGdvcml0aG0/IENhbid0IHlvdSByZS11c2UgdGhlCmltcGxlbWVudGF0aW9uIGFscmVhZHkg ZXhpc3Rpbmc/Cgo+ICt7Cj4gKwl1bnNpZ25lZCBjaGFyIGJpdF9hZGRyOwo+ICsJdW5zaWduZWQg aW50IGJ5dGVfYWRkcjsKPiArCXVuc2lnbmVkIHNob3J0IGVjY19vZGQsIGVjY19ldmVuLCByZWFk X2VjY19sb3dlciwgcmVhZF9lY2NfdXBwZXI7Cj4gKwl1bnNpZ25lZCBzaG9ydCBjYWxjX2VjY19s b3dlciwgY2FsY19lY2NfdXBwZXI7Cj4gKwo+ICsJcmVhZF9lY2NfbG93ZXIgPSAocmVhZF9lY2Nb MF0gfCAocmVhZF9lY2NbMV0gPDwgOCkpICYKPiArCQkJICBQTDM1M19FQ0NfQklUX01BU0s7Cj4g KwlyZWFkX2VjY191cHBlciA9ICgocmVhZF9lY2NbMV0gPj4gNCkgfCAocmVhZF9lY2NbMl0gPDwg NCkpICYKPiArCQkJICBQTDM1M19FQ0NfQklUX01BU0s7Cj4gKwo+ICsJY2FsY19lY2NfbG93ZXIg PSAoY2FsY19lY2NbMF0gfCAoY2FsY19lY2NbMV0gPDwgOCkpICYKPiArCQkJICBQTDM1M19FQ0Nf QklUX01BU0s7Cj4gKwljYWxjX2VjY191cHBlciA9ICgoY2FsY19lY2NbMV0gPj4gNCkgfCAoY2Fs Y19lY2NbMl0gPDwgNCkpICYKPiArCQkJICBQTDM1M19FQ0NfQklUX01BU0s7Cj4gKwo+ICsJZWNj X29kZCA9IHJlYWRfZWNjX2xvd2VyIF4gY2FsY19lY2NfbG93ZXI7Cj4gKwllY2NfZXZlbiA9IHJl YWRfZWNjX3VwcGVyIF4gY2FsY19lY2NfdXBwZXI7Cj4gKwo+ICsJLyogbm8gZXJyb3IgKi8KPiAr CWlmICghZWNjX29kZCAmJiAhZWNjX2V2ZW4pCj4gKwkJcmV0dXJuIDA7Cj4gKwo+ICsJaWYgKGVj Y19vZGQgPT0gKH5lY2NfZXZlbiAmIFBMMzUzX0VDQ19CSVRfTUFTSykpIHsKPiArCQkvKiBiaXRz IFsxMTozXSBvZiBlcnJvciBjb2RlIGlzIGJ5dGUgb2Zmc2V0ICovCj4gKwkJYnl0ZV9hZGRyID0g KGVjY19vZGQgPj4gMykgJiBQTDM1M19FQ0NfQklUU19CWVRFT0ZGX01BU0s7Cj4gKwkJLyogYml0 cyBbMjowXSBvZiBlcnJvciBjb2RlIGlzIGJpdCBvZmZzZXQgKi8KPiArCQliaXRfYWRkciA9IGVj Y19vZGQgJiBQTDM1M19FQ0NfQklUU19CSVRPRkZfTUFTSzsKPiArCQkvKiBUb2dnbGluZyBlcnJv ciBiaXQgKi8KPiArCQlidWZbYnl0ZV9hZGRyXSBePSAoQklUKGJpdF9hZGRyKSk7Cj4gKwkJcmV0 dXJuIDE7Cj4gKwl9Cj4gKwo+ICsJLyogb25lIGVycm9yIGluIHBhcml0eSAqLwo+ICsJaWYgKGh3 ZWlnaHQzMihlY2Nfb2RkIHwgZWNjX2V2ZW4pID09IDEpCj4gKwkJcmV0dXJuIDE7Cj4gKwo+ICsJ LyogVW5jb3JyZWN0YWJsZSBlcnJvciAqLwo+ICsJcmV0dXJuIC0xOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgdm9pZCBwbDM1M19wcmVwYXJlX2NtZChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLAo+ICsJCQkg ICAgICBpbnQgcGFnZSwgaW50IGNvbHVtbiwgaW50IHN0YXJ0X2NtZCwgaW50IGVuZF9jbWQsCj4g KwkJCSAgICAgIGJvb2wgcmVhZCkKPiArewo+ICsJdW5zaWduZWQgbG9uZyBkYXRhX3BoYXNlX2Fk ZHI7Cj4gKwl1MzIgZW5kX2NtZF92YWxpZCA9IDA7Cj4gKwl1bnNpZ25lZCBsb25nIGNtZF9waGFz ZV9hZGRyID0gMCwgY21kX3BoYXNlX2RhdGEgPSAwOwo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQg PSBuYW5kX3RvX210ZChjaGlwKTsKPiArCj4gKwlzdHJ1Y3QgcGwzNTNfbmFuZF9jb250cm9sbGVy ICp4bmZjID0KPiArCQljb250YWluZXJfb2YoY2hpcCwgc3RydWN0IHBsMzUzX25hbmRfY29udHJv bGxlciwgY2hpcCk7Cj4gKwo+ICsJZW5kX2NtZF92YWxpZCA9IHJlYWQgPyAxIDogMDsKPiArCj4g KwljbWRfcGhhc2VfYWRkciA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+cmVncyArCj4g KwkJCSAoKHhuZmMtPmFkZHJfY3ljbGVzCj4gKwkJCSA8PCBBRERSX0NZQ0xFU19TSElGVCkgfAo+ ICsJCQkgKGVuZF9jbWRfdmFsaWQgPDwgRU5EX0NNRF9WQUxJRF9TSElGVCkgfAo+ICsJCQkgKENP TU1BTkRfUEhBU0UpIHwKPiArCQkJIChlbmRfY21kIDw8IEVORF9DTURfU0hJRlQpIHwKPiArCQkJ IChzdGFydF9jbWQgPDwgU1RBUlRfQ01EX1NISUZUKSk7Cj4gKwo+ICsJLyogR2V0IHRoZSBkYXRh IHBoYXNlIGFkZHJlc3MgKi8KPiArCWRhdGFfcGhhc2VfYWRkciA9ICh1bnNpZ25lZCBsb25nIF9f Zm9yY2UpeG5mYy0+cmVncyArCj4gKwkJCSAgKCgweDAgPDwgQ0xFQVJfQ1NfU0hJRlQpIHwKPiAr CQkJICAoMCA8PCBFTkRfQ01EX1ZBTElEX1NISUZUKSB8Cj4gKwkJCSAgKERBVEFfUEhBU0UpIHwK PiArCQkJICAoZW5kX2NtZCA8PCBFTkRfQ01EX1NISUZUKSB8Cj4gKwkJCSAgKDB4MCA8PCBFQ0Nf TEFTVF9TSElGVCkpOwo+ICsKPiArCXhuZmMtPmJ1Zl9hZGRyID0gKHZvaWQgX19pb21lbSAqIF9f Zm9yY2UpZGF0YV9waGFzZV9hZGRyOwo+ICsKPiArCWlmIChjaGlwLT5vcHRpb25zICYgTkFORF9C VVNXSURUSF8xNikKPiArCQljb2x1bW4gLz0gMjsKPiArCWNtZF9waGFzZV9kYXRhID0gY29sdW1u Owo+ICsJaWYgKG10ZC0+d3JpdGVzaXplID4gUEwzNTNfTkFORF9FQ0NfU0laRSkgewo+ICsJCWNt ZF9waGFzZV9kYXRhIHw9IHBhZ2UgPDwgMTY7Cj4gKwkJLyogQW5vdGhlciBhZGRyZXNzIGN5Y2xl IGZvciBkZXZpY2VzID4gMTI4TWlCICovCj4gKwkJaWYgKGNoaXAtPm9wdGlvbnMgJiBOQU5EX1JP V19BRERSXzMpIHsKPiArCQkJd3JpdGVsX3JlbGF4ZWQoY21kX3BoYXNlX2RhdGEsCj4gKwkJCQkg ICAgICAgKHZvaWQgX19pb21lbSAqIF9fZm9yY2UpY21kX3BoYXNlX2FkZHIpOwo+ICsJCQljbWRf cGhhc2VfZGF0YSA9IChwYWdlID4+IDE2KTsKPiArCQl9Cj4gKwl9IGVsc2Ugewo+ICsJCWNtZF9w aGFzZV9kYXRhIHw9IHBhZ2UgPDwgODsKPiArCX0KPiArCj4gKwl3cml0ZWxfcmVsYXhlZChjbWRf cGhhc2VfZGF0YSwgKHZvaWQgX19pb21lbSAqIF9fZm9yY2UpY21kX3BoYXNlX2FkZHIpOwo+ICt9 Cj4gKwo+ICsvKioKPiArICogcGwzNTNfbmFuZF9yZWFkX29vYiAtIFtSRVBMQUNFQUJMRV0gdGhl IG1vc3QgY29tbW9uIE9PQiBkYXRhIHJlYWQgZnVuY3Rpb24KPiArICogQG10ZDoJUG9pbnRlciB0 byB0aGUgbXRkX2luZm8gc3RydWN0dXJlCj4gKyAqIEBjaGlwOglQb2ludGVyIHRvIHRoZSBuYW5k X2NoaXAgc3RydWN0dXJlCj4gKyAqIEBwYWdlOglQYWdlIG51bWJlciB0byByZWFkCj4gKyAqCj4g KyAqIFJldHVybjoJQWx3YXlzIHJldHVybiB6ZXJvCj4gKyAqLwo+ICtzdGF0aWMgaW50IHBsMzUz X25hbmRfcmVhZF9vb2Ioc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwKPiArCQkJICAgICAgIGludCBw YWdlKQo+ICt7Cj4gKwl1bnNpZ25lZCBsb25nIGRhdGFfcGhhc2VfYWRkcjsKPiArCXU4ICpwOwo+ ICsJc3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFpbmVyX29m KGNoaXAsIHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIsIGNoaXApOwo+ICsJdW5zaWduZWQg bG9uZyBuYW5kX29mZnNldCA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+cmVnczsKPiAr CXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gKwo+ICsJY2hpcC0+ cGFnZWJ1ZiA9IC0xOwo+ICsJaWYgKG10ZC0+d3JpdGVzaXplIDwgUEwzNTNfTkFORF9FQ0NfU0la RSkKPiArCQlyZXR1cm4gMDsKPiArCj4gKwlwbDM1M19wcmVwYXJlX2NtZChjaGlwLCBwYWdlLCBt dGQtPndyaXRlc2l6ZSwgTkFORF9DTURfUkVBRDAsCj4gKwkJCSAgTkFORF9DTURfUkVBRFNUQVJU LCAxKTsKPiArCj4gKwluYW5kX3dhaXRfcmVhZHkoY2hpcCk7Cj4gKwo+ICsJcCA9IGNoaXAtPm9v Yl9wb2k7Cj4gKwlwbDM1M19uYW5kX3JlYWRfZGF0YV9vcChjaGlwLCBwLAo+ICsJCQkJKG10ZC0+ b29ic2l6ZSAtCj4gKwkJCQlQTDM1M19OQU5EX0xBU1RfVFJBTlNGRVJfTEVOR1RIKSwgZmFsc2Up Owo+ICsJcCArPSAobXRkLT5vb2JzaXplIC0gUEwzNTNfTkFORF9MQVNUX1RSQU5TRkVSX0xFTkdU SCk7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgPSAodW5zaWduZWQgbG9uZyBfX2ZvcmNlKXhuZmMtPmJ1 Zl9hZGRyOwo+ICsJZGF0YV9waGFzZV9hZGRyIC09IG5hbmRfb2Zmc2V0Owo+ICsJZGF0YV9waGFz ZV9hZGRyIHw9IFBMMzUzX05BTkRfQ0xFQVJfQ1M7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgKz0gbmFu ZF9vZmZzZXQ7Cj4gKwl4bmZjLT5idWZfYWRkciA9ICh2b2lkIF9faW9tZW0gKiBfX2ZvcmNlKWRh dGFfcGhhc2VfYWRkcjsKPiArCXBsMzUzX25hbmRfcmVhZF9kYXRhX29wKGNoaXAsIHAsIFBMMzUz X05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgsCj4gKwkJCQlmYWxzZSk7Cj4gKwo+ICsJcmV0dXJu IDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBwbDM1M19uYW5kX3dyaXRlX29vYiAtIFtSRVBMQUNF QUJMRV0gdGhlIG1vc3QgY29tbW9uIE9PQiBkYXRhIHdyaXRlIGZ1bmN0aW9uCj4gKyAqIEBtdGQ6 CVBvaW50ZXIgdG8gdGhlIG10ZCBpbmZvIHN0cnVjdHVyZQo+ICsgKiBAY2hpcDoJUG9pbnRlciB0 byB0aGUgTkFORCBjaGlwIGluZm8gc3RydWN0dXJlCj4gKyAqIEBwYWdlOglQYWdlIG51bWJlciB0 byB3cml0ZQo+ICsgKgo+ICsgKiBSZXR1cm46CVplcm8gb24gc3VjY2VzcyBhbmQgRUlPIG9uIGZh aWx1cmUKPiArICovCj4gK3N0YXRpYyBpbnQgcGwzNTNfbmFuZF93cml0ZV9vb2Ioc3RydWN0IG5h bmRfY2hpcCAqY2hpcCwKPiArCQkJCWludCBwYWdlKQo+ICt7Cj4gKwljb25zdCB1OCAqYnVmID0g Y2hpcC0+b29iX3BvaTsKPiArCXVuc2lnbmVkIGxvbmcgZGF0YV9waGFzZV9hZGRyOwo+ICsJc3Ry dWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFpbmVyX29mKGNoaXAs IHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIsIGNoaXApOwo+ICsJdW5zaWduZWQgbG9uZyBu YW5kX29mZnNldCA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+cmVnczsKPiArCXN0cnVj dCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gKwl1MzIgYWRkcmN5Y2xlcyA9 IDA7Cj4gKwo+ICsJY2hpcC0+cGFnZWJ1ZiA9IC0xOwo+ICsJYWRkcmN5Y2xlcyA9IHhuZmMtPmFk ZHJfY3ljbGVzOwo+ICsJcGwzNTNfcHJlcGFyZV9jbWQoY2hpcCwgcGFnZSwgbXRkLT53cml0ZXNp emUsIE5BTkRfQ01EX1NFUUlOLAo+ICsJCQkgIE5BTkRfQ01EX1BBR0VQUk9HLCAwKTsKPiArCj4g KwlwbDM1M19uYW5kX3dyaXRlX2RhdGFfb3AoY2hpcCwgYnVmLAo+ICsJCQkJIChtdGQtPm9vYnNp emUgLQo+ICsJCQkJIFBMMzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgpLCBmYWxzZSk7Cj4g KwlidWYgKz0gKG10ZC0+b29ic2l6ZSAtIFBMMzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgp Owo+ICsKPiArCWRhdGFfcGhhc2VfYWRkciA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+ YnVmX2FkZHI7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgLT0gbmFuZF9vZmZzZXQ7Cj4gKwlkYXRhX3Bo YXNlX2FkZHIgfD0gUEwzNTNfTkFORF9DTEVBUl9DUzsKPiArCWRhdGFfcGhhc2VfYWRkciB8PSAo MSA8PCBFTkRfQ01EX1ZBTElEX1NISUZUKTsKPiArCWRhdGFfcGhhc2VfYWRkciArPSBuYW5kX29m ZnNldDsKPiArCXhuZmMtPmJ1Zl9hZGRyID0gKHZvaWQgX19pb21lbSAqIF9fZm9yY2UpZGF0YV9w aGFzZV9hZGRyOwo+ICsJcGwzNTNfbmFuZF93cml0ZV9kYXRhX29wKGNoaXAsIGJ1ZiwgUEwzNTNf TkFORF9MQVNUX1RSQU5TRkVSX0xFTkdUSCwKPiArCQkJCSBmYWxzZSk7Cj4gKwluYW5kX3dhaXRf cmVhZHkoY2hpcCk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBwbDM1 M19uYW5kX3JlYWRfcGFnZV9yYXcgLSBbSW50ZXJuXSByZWFkIHJhdyBwYWdlIGRhdGEgd2l0aG91 dCBlY2MKPiArICogQG10ZDoJCVBvaW50ZXIgdG8gdGhlIG10ZCBpbmZvIHN0cnVjdHVyZQo+ICsg KiBAY2hpcDoJCVBvaW50ZXIgdG8gdGhlIE5BTkQgY2hpcCBpbmZvIHN0cnVjdHVyZQo+ICsgKiBA YnVmOgkJUG9pbnRlciB0byB0aGUgZGF0YSBidWZmZXIKPiArICogQG9vYl9yZXF1aXJlZDoJQ2Fs bGVyIHJlcXVpcmVzIE9PQiBkYXRhIHJlYWQgdG8gY2hpcC0+b29iX3BvaQo+ICsgKiBAcGFnZToJ CVBhZ2UgbnVtYmVyIHRvIHJlYWQKPiArICoKPiArICogUmV0dXJuOglBbHdheXMgcmV0dXJuIHpl cm8KPiArICovCj4gK3N0YXRpYyBpbnQgcGwzNTNfbmFuZF9yZWFkX3BhZ2VfcmF3KHN0cnVjdCBu YW5kX2NoaXAgKmNoaXAsCj4gKwkJCQkgICAgdTggKmJ1ZiwgaW50IG9vYl9yZXF1aXJlZCwgaW50 IHBhZ2UpCj4gK3sKPiArCXVuc2lnbmVkIGxvbmcgZGF0YV9waGFzZV9hZGRyOwo+ICsJdTggKnA7 Cj4gKwlzdHJ1Y3QgcGwzNTNfbmFuZF9jb250cm9sbGVyICp4bmZjID0KPiArCQljb250YWluZXJf b2YoY2hpcCwgc3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciwgY2hpcCk7Cj4gKwl1bnNpZ25l ZCBsb25nIG5hbmRfb2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcgX19mb3JjZSl4bmZjLT5yZWdzOwo+ ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZChjaGlwKTsKPiArCj4gKwlwbDM1 M19wcmVwYXJlX2NtZChjaGlwLCBwYWdlLCAwLCBOQU5EX0NNRF9SRUFEMCwKPiArCQkJICBOQU5E X0NNRF9SRUFEU1RBUlQsIDEpOwo+ICsJbmFuZF93YWl0X3JlYWR5KGNoaXApOwo+ICsJcGwzNTNf bmFuZF9yZWFkX2RhdGFfb3AoY2hpcCwgYnVmLCBtdGQtPndyaXRlc2l6ZSwgZmFsc2UpOwo+ICsJ cCA9IGNoaXAtPm9vYl9wb2k7Cj4gKwlwbDM1M19uYW5kX3JlYWRfZGF0YV9vcChjaGlwLCBwLAo+ ICsJCQkJKG10ZC0+b29ic2l6ZSAtCj4gKwkJCQlQTDM1M19OQU5EX0xBU1RfVFJBTlNGRVJfTEVO R1RIKSwgZmFsc2UpOwo+ICsJcCArPSAobXRkLT5vb2JzaXplIC0gUEwzNTNfTkFORF9MQVNUX1RS QU5TRkVSX0xFTkdUSCk7Cj4gKwo+ICsJZGF0YV9waGFzZV9hZGRyID0gKHVuc2lnbmVkIGxvbmcg X19mb3JjZSl4bmZjLT5idWZfYWRkcjsKPiArCWRhdGFfcGhhc2VfYWRkciAtPSBuYW5kX29mZnNl dDsKPiArCWRhdGFfcGhhc2VfYWRkciB8PSBQTDM1M19OQU5EX0NMRUFSX0NTOwo+ICsJZGF0YV9w aGFzZV9hZGRyICs9IG5hbmRfb2Zmc2V0Owo+ICsJeG5mYy0+YnVmX2FkZHIgPSAodm9pZCBfX2lv bWVtICogX19mb3JjZSlkYXRhX3BoYXNlX2FkZHI7Cj4gKwo+ICsJcGwzNTNfbmFuZF9yZWFkX2Rh dGFfb3AoY2hpcCwgcCwgUEwzNTNfTkFORF9MQVNUX1RSQU5TRkVSX0xFTkdUSCwKPiArCQkJCWZh bHNlKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHBsMzUzX25hbmRf d3JpdGVfcGFnZV9yYXcgLSBbSW50ZXJuXSByYXcgcGFnZSB3cml0ZSBmdW5jdGlvbgo+ICsgKiBA bXRkOgkJUG9pbnRlciB0byB0aGUgbXRkIGluZm8gc3RydWN0dXJlCj4gKyAqIEBjaGlwOgkJUG9p bnRlciB0byB0aGUgTkFORCBjaGlwIGluZm8gc3RydWN0dXJlCj4gKyAqIEBidWY6CQlQb2ludGVy IHRvIHRoZSBkYXRhIGJ1ZmZlcgo+ICsgKiBAb29iX3JlcXVpcmVkOglDYWxsZXIgcmVxdWlyZXMg T09CIGRhdGEgcmVhZCB0byBjaGlwLT5vb2JfcG9pCj4gKyAqIEBwYWdlOgkJUGFnZSBudW1iZXIg dG8gd3JpdGUKPiArICoKPiArICogUmV0dXJuOglBbHdheXMgcmV0dXJuIHplcm8KPiArICovCj4g K3N0YXRpYyBpbnQgcGwzNTNfbmFuZF93cml0ZV9wYWdlX3JhdyhzdHJ1Y3QgbmFuZF9jaGlwICpj aGlwLAo+ICsJCQkJICAgICBjb25zdCB1OCAqYnVmLCBpbnQgb29iX3JlcXVpcmVkLAo+ICsJCQkJ ICAgICBpbnQgcGFnZSkKPiArewo+ICsJdW5zaWduZWQgbG9uZyBkYXRhX3BoYXNlX2FkZHI7Cj4g Kwl1OCAqcDsKPiArCXN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIgKnhuZmMgPQo+ICsJCWNv bnRhaW5lcl9vZihjaGlwLCBzdHJ1Y3QgcGwzNTNfbmFuZF9jb250cm9sbGVyLCBjaGlwKTsKPiAr CXVuc2lnbmVkIGxvbmcgbmFuZF9vZmZzZXQgPSAodW5zaWduZWQgbG9uZyBfX2ZvcmNlKXhuZmMt PnJlZ3M7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKGNoaXApOwo+ICsK PiArCXBsMzUzX3ByZXBhcmVfY21kKGNoaXAsIHBhZ2UsIDAsIE5BTkRfQ01EX1NFUUlOLAo+ICsJ CQkgIE5BTkRfQ01EX1BBR0VQUk9HLCAwKTsKPiArCXBsMzUzX25hbmRfd3JpdGVfZGF0YV9vcChj aGlwLCBidWYsIG10ZC0+d3JpdGVzaXplLCBmYWxzZSk7Cj4gKwlwID0gY2hpcC0+b29iX3BvaTsK PiArCXBsMzUzX25hbmRfd3JpdGVfZGF0YV9vcChjaGlwLCBwLAo+ICsJCQkJIChtdGQtPm9vYnNp emUgLQo+ICsJCQkJIFBMMzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgpLCBmYWxzZSk7Cj4g KwlwICs9IChtdGQtPm9vYnNpemUgLSBQTDM1M19OQU5EX0xBU1RfVFJBTlNGRVJfTEVOR1RIKTsK PiArCj4gKwlkYXRhX3BoYXNlX2FkZHIgPSAodW5zaWduZWQgbG9uZyBfX2ZvcmNlKXhuZmMtPmJ1 Zl9hZGRyOwo+ICsJZGF0YV9waGFzZV9hZGRyIC09IG5hbmRfb2Zmc2V0Owo+ICsJZGF0YV9waGFz ZV9hZGRyIHw9IFBMMzUzX05BTkRfQ0xFQVJfQ1M7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgfD0gKDEg PDwgRU5EX0NNRF9WQUxJRF9TSElGVCk7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgKz0gbmFuZF9vZmZz ZXQ7Cj4gKwl4bmZjLT5idWZfYWRkciA9ICh2b2lkIF9faW9tZW0gKiBfX2ZvcmNlKWRhdGFfcGhh c2VfYWRkcjsKPiArCXBsMzUzX25hbmRfd3JpdGVfZGF0YV9vcChjaGlwLCBwLCBQTDM1M19OQU5E X0xBU1RfVFJBTlNGRVJfTEVOR1RILAo+ICsJCQkJIGZhbHNlKTsKPiArCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArLyoqCj4gKyAqIG5hbmRfd3JpdGVfcGFnZV9od2VjYyAtIEhhcmR3YXJlIEVD QyBiYXNlZCBwYWdlIHdyaXRlIGZ1bmN0aW9uCj4gKyAqIEBtdGQ6CQlQb2ludGVyIHRvIHRoZSBt dGQgaW5mbyBzdHJ1Y3R1cmUKPiArICogQGNoaXA6CQlQb2ludGVyIHRvIHRoZSBOQU5EIGNoaXAg aW5mbyBzdHJ1Y3R1cmUKPiArICogQGJ1ZjoJCVBvaW50ZXIgdG8gdGhlIGRhdGEgYnVmZmVyCj4g KyAqIEBvb2JfcmVxdWlyZWQ6CUNhbGxlciByZXF1aXJlcyBPT0IgZGF0YSByZWFkIHRvIGNoaXAt Pm9vYl9wb2kKPiArICogQHBhZ2U6CQlQYWdlIG51bWJlciB0byB3cml0ZQo+ICsgKgo+ICsgKiBU aGlzIGZ1bmN0aW9ucyB3cml0ZXMgZGF0YSBhbmQgaGFyZHdhcmUgZ2VuZXJhdGVkIEVDQyB2YWx1 ZXMgaW4gdG8gdGhlIHBhZ2UuCj4gKyAqCj4gKyAqIFJldHVybjoJQWx3YXlzIHJldHVybiB6ZXJv Cj4gKyAqLwo+ICtzdGF0aWMgaW50IHBsMzUzX25hbmRfd3JpdGVfcGFnZV9od2VjYyhzdHJ1Y3Qg bmFuZF9jaGlwICpjaGlwLAo+ICsJCQkJICAgICAgIGNvbnN0IHU4ICpidWYsIGludCBvb2JfcmVx dWlyZWQsCj4gKwkJCQkgICAgICAgaW50IHBhZ2UpCj4gK3sKPiArCWludCBlY2NzaXplID0gY2hp cC0+ZWNjLnNpemU7Cj4gKwlpbnQgZWNjc3RlcHMgPSBjaGlwLT5lY2Muc3RlcHM7Cj4gKwl1OCAq ZWNjX2NhbGMgPSBjaGlwLT5lY2MuY2FsY19idWY7Cj4gKwl1OCAqb29iX3B0cjsKPiArCWNvbnN0 IHU4ICpwID0gYnVmOwo+ICsJdTMyIHJldDsKPiArCXVuc2lnbmVkIGxvbmcgZGF0YV9waGFzZV9h ZGRyOwo+ICsJc3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFp bmVyX29mKGNoaXAsIHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIsIGNoaXApOwo+ICsJdW5z aWduZWQgbG9uZyBuYW5kX29mZnNldCA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+cmVn czsKPiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gKwo+ICsJ cGwzNTNfcHJlcGFyZV9jbWQoY2hpcCwgcGFnZSwgMCwgTkFORF9DTURfU0VRSU4sCj4gKwkJCSAg TkFORF9DTURfUEFHRVBST0csIDApOwo+ICsKPiArCWZvciAoIDsgKGVjY3N0ZXBzIC0gMSk7IGVj Y3N0ZXBzLS0pIHsKPiArCQlwbDM1M19uYW5kX3dyaXRlX2RhdGFfb3AoY2hpcCwgcCwgZWNjc2l6 ZSwgZmFsc2UpOwo+ICsJCXAgKz0gZWNjc2l6ZTsKPiArCX0KPiArCXBsMzUzX25hbmRfd3JpdGVf ZGF0YV9vcChjaGlwLCBwLAo+ICsJCQkJIChlY2NzaXplIC0gUEwzNTNfTkFORF9MQVNUX1RSQU5T RkVSX0xFTkdUSCksCj4gKwkJCQkgZmFsc2UpOwo+ICsJcCArPSAoZWNjc2l6ZSAtIFBMMzUzX05B TkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgpOwo+ICsKPiArCS8qIFNldCBFQ0MgTGFzdCBiaXQgdG8g MSAqLwo+ICsJZGF0YV9waGFzZV9hZGRyID0gKHVuc2lnbmVkIGxvbmcgX19mb3JjZSl4bmZjLT5i dWZfYWRkcjsKPiArCWRhdGFfcGhhc2VfYWRkciAtPSBuYW5kX29mZnNldDsKPiArCWRhdGFfcGhh c2VfYWRkciB8PSBQTDM1M19OQU5EX0VDQ19MQVNUOwo+ICsJZGF0YV9waGFzZV9hZGRyICs9IG5h bmRfb2Zmc2V0Owo+ICsJeG5mYy0+YnVmX2FkZHIgPSAodm9pZCBfX2lvbWVtICogX19mb3JjZSlk YXRhX3BoYXNlX2FkZHI7Cj4gKwlwbDM1M19uYW5kX3dyaXRlX2RhdGFfb3AoY2hpcCwgcCwgUEwz NTNfTkFORF9MQVNUX1RSQU5TRkVSX0xFTkdUSCwKPiArCQkJCSBmYWxzZSk7Cj4gKwo+ICsJLyog V2FpdCB0aWxsIHRoZSBFQ0Mgb3BlcmF0aW9uIGlzIGNvbXBsZXRlIG9yIHRpbWVvdXQgKi8KPiAr CXJldCA9IHBsMzUzX3dhaXRfZm9yX2VjY19kb25lKCk7Cj4gKwlpZiAocmV0KQo+ICsJCWRldl9l cnIoeG5mYy0+ZGV2LCAiRUNDIFRpbWVvdXRcbiIpOwo+ICsJcCA9IGJ1ZjsKPiArCXJldCA9IGNo aXAtPmVjYy5jYWxjdWxhdGUoY2hpcCwgcCwgJmVjY19jYWxjWzBdKTsKPiArCWlmIChyZXQpCj4g KwkJcmV0dXJuIHJldDsKPiArCj4gKwkvKiBXYWl0IGZvciBFQ0MgdG8gYmUgY2FsY3VsYXRlZCBh bmQgcmVhZCB0aGUgZXJyb3IgdmFsdWVzICovCj4gKwlyZXQgPSBtdGRfb29ibGF5b3V0X3NldF9l Y2NieXRlcyhtdGQsIGVjY19jYWxjLCBjaGlwLT5vb2JfcG9pLAo+ICsJCQkJCSAwLCBjaGlwLT5l Y2MudG90YWwpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsJLyogQ2xlYXIgRUND IGxhc3QgYml0ICovCj4gKwlkYXRhX3BoYXNlX2FkZHIgPSAodW5zaWduZWQgbG9uZyBfX2ZvcmNl KXhuZmMtPmJ1Zl9hZGRyOwo+ICsJZGF0YV9waGFzZV9hZGRyIC09IG5hbmRfb2Zmc2V0Owo+ICsJ ZGF0YV9waGFzZV9hZGRyICY9IH5QTDM1M19OQU5EX0VDQ19MQVNUOwo+ICsJZGF0YV9waGFzZV9h ZGRyICs9IG5hbmRfb2Zmc2V0Owo+ICsJeG5mYy0+YnVmX2FkZHIgPSAodm9pZCBfX2lvbWVtICog X19mb3JjZSlkYXRhX3BoYXNlX2FkZHI7Cj4gKwo+ICsJLyogV3JpdGUgdGhlIHNwYXJlIGFyZWEg d2l0aCBFQ0MgYnl0ZXMgKi8KPiArCW9vYl9wdHIgPSBjaGlwLT5vb2JfcG9pOwo+ICsJcGwzNTNf bmFuZF93cml0ZV9kYXRhX29wKGNoaXAsIG9vYl9wdHIsCj4gKwkJCQkgKG10ZC0+b29ic2l6ZSAt Cj4gKwkJCQkgUEwzNTNfTkFORF9MQVNUX1RSQU5TRkVSX0xFTkdUSCksIGZhbHNlKTsKPiArCj4g KwlkYXRhX3BoYXNlX2FkZHIgPSAodW5zaWduZWQgbG9uZyBfX2ZvcmNlKXhuZmMtPmJ1Zl9hZGRy Owo+ICsJZGF0YV9waGFzZV9hZGRyIC09IG5hbmRfb2Zmc2V0Owo+ICsJZGF0YV9waGFzZV9hZGRy IHw9IFBMMzUzX05BTkRfQ0xFQVJfQ1M7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgfD0gKDEgPDwgRU5E X0NNRF9WQUxJRF9TSElGVCk7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgKz0gbmFuZF9vZmZzZXQ7Cj4g Kwl4bmZjLT5idWZfYWRkciA9ICh2b2lkIF9faW9tZW0gKiBfX2ZvcmNlKWRhdGFfcGhhc2VfYWRk cjsKPiArCW9vYl9wdHIgKz0gKG10ZC0+b29ic2l6ZSAtIFBMMzUzX05BTkRfTEFTVF9UUkFOU0ZF Ul9MRU5HVEgpOwo+ICsJcGwzNTNfbmFuZF93cml0ZV9kYXRhX29wKGNoaXAsIG9vYl9wdHIsIFBM MzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgsCj4gKwkJCQkgZmFsc2UpOwo+ICsJbmFuZF93 YWl0X3JlYWR5KGNoaXApOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKioKPiArICog cGwzNTNfbmFuZF9yZWFkX3BhZ2VfaHdlY2MgLSBIYXJkd2FyZSBFQ0MgYmFzZWQgcGFnZSByZWFk IGZ1bmN0aW9uCj4gKyAqIEBtdGQ6CQlQb2ludGVyIHRvIHRoZSBtdGQgaW5mbyBzdHJ1Y3R1cmUK PiArICogQGNoaXA6CQlQb2ludGVyIHRvIHRoZSBOQU5EIGNoaXAgaW5mbyBzdHJ1Y3R1cmUKPiAr ICogQGJ1ZjoJCVBvaW50ZXIgdG8gdGhlIGJ1ZmZlciB0byBzdG9yZSByZWFkIGRhdGEKPiArICog QG9vYl9yZXF1aXJlZDoJQ2FsbGVyIHJlcXVpcmVzIE9PQiBkYXRhIHJlYWQgdG8gY2hpcC0+b29i X3BvaQo+ICsgKiBAcGFnZToJCVBhZ2UgbnVtYmVyIHRvIHJlYWQKPiArICoKPiArICogVGhpcyBm dW5jdGlvbnMgcmVhZHMgZGF0YSBhbmQgY2hlY2tzIHRoZSBkYXRhIGludGVncml0eSBieSBjb21w YXJpbmcKPiArICogaGFyZHdhcmUgZ2VuZXJhdGVkIEVDQyB2YWx1ZXMgYW5kIHJlYWQgRUNDIHZh bHVlcyBmcm9tIHNwYXJlIGFyZWEuCj4gKyAqIFRoZXJlIGlzIGEgbGltaXRhdGlvbiBpbiBTTUMg Y29udHJvbGxlciwgdGhhdCB3ZSBtdXN0IHNldCBFQ0MgTEFTVCBvbgo+ICsgKiBsYXN0IGRhdGEg cGhhc2UgYWNjZXNzLCB0byB0ZWxsIEVDQyBibG9jayBub3QgdG8gZXhwZWN0IGFueSBkYXRhIGZ1 cnRoZXIuCj4gKyAqIEV4OiAgV2hlbiBudW1iZXIgb2YgRUNDIFNURVBTIGFyZSA0LCB0aGVuIHRp bGwgMyB3ZSB3aWxsIHdyaXRlIHRvIGZsYXNoCj4gKyAqIHVzaW5nIFNNQyB3aXRoIEhXIEVDQyBl bmFibGVkLiBBbmQgZm9yIHRoZSBsYXN0IEVDQyBTVEVQLCB3ZSB3aWxsIHN1YnRyYWN0Cj4gKyAq IDRieXRlcyBmcm9tIHBhZ2Ugc2l6ZSwgYW5kIHdpbGwgaW5pdGlhdGUgYSB0cmFuc2Zlci4gQW5k IHRoZSByZW1haW5pbmcgNCBhcwo+ICsgKiBvbmUgbW9yZSB0cmFuc2ZlciB3aXRoIEVDQ19MQVNU IGJpdCBzZXQgaW4gTkFORCBkYXRhIHBoYXNlIHJlZ2lzdGVyIHRvCj4gKyAqIG5vdGlmeSBFQ0Mg YmxvY2sgbm90IHRvIGV4cGVjdCBhbnkgbW9yZSBkYXRhLiBUaGUgbGFzdCBibG9jayBzaG91bGQg YmUgYWxpZ24KPiArICogd2l0aCBlbmQgb2YgNTEyIGJ5dGUgYmxvY2suIEJlY2F1c2Ugb2YgdGhp cyBsaW1pdGF0aW9uLCB3ZSBhcmUgbm90IHVzaW5nCj4gKyAqIGNvcmUgcm91dGluZXMuCj4gKyAq Cj4gKyAqIFJldHVybjoJMCBhbHdheXMgYW5kIHVwZGF0ZXMgRUNDIG9wZXJhdGlvbiBzdGF0dXMg aW4gdG8gTVREIHN0cnVjdHVyZQo+ICsgKi8KPiArc3RhdGljIGludCBwbDM1M19uYW5kX3JlYWRf cGFnZV9od2VjYyhzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLAo+ICsJCQkJICAgICAgdTggKmJ1Ziwg aW50IG9vYl9yZXF1aXJlZCwgaW50IHBhZ2UpCj4gK3sKPiArCWludCBpLCBzdGF0LCBlY2NzaXpl ID0gY2hpcC0+ZWNjLnNpemU7Cj4gKwlpbnQgZWNjYnl0ZXMgPSBjaGlwLT5lY2MuYnl0ZXM7Cj4g KwlpbnQgZWNjc3RlcHMgPSBjaGlwLT5lY2Muc3RlcHM7Cj4gKwl1OCAqcCA9IGJ1ZjsKPiArCXU4 ICplY2NfY2FsYyA9IGNoaXAtPmVjYy5jYWxjX2J1ZjsKPiArCXU4ICplY2MgPSBjaGlwLT5lY2Mu Y29kZV9idWY7Cj4gKwl1bnNpZ25lZCBpbnQgbWF4X2JpdGZsaXBzID0gMDsKPiArCXU4ICpvb2Jf cHRyOwo+ICsJdTMyIHJldDsKPiArCXVuc2lnbmVkIGxvbmcgZGF0YV9waGFzZV9hZGRyOwo+ICsJ c3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFpbmVyX29mKGNo aXAsIHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIsIGNoaXApOwo+ICsJdW5zaWduZWQgbG9u ZyBuYW5kX29mZnNldCA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+cmVnczsKPiArCXN0 cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gKwo+ICsJcGwzNTNfcHJl cGFyZV9jbWQoY2hpcCwgcGFnZSwgMCwgTkFORF9DTURfUkVBRDAsCj4gKwkJCSAgTkFORF9DTURf UkVBRFNUQVJULCAxKTsKPiArCW5hbmRfd2FpdF9yZWFkeShjaGlwKTsKPiArCj4gKwlmb3IgKCA7 IChlY2NzdGVwcyAtIDEpOyBlY2NzdGVwcy0tKSB7Cj4gKwkJcGwzNTNfbmFuZF9yZWFkX2RhdGFf b3AoY2hpcCwgcCwgZWNjc2l6ZSwgZmFsc2UpOwo+ICsJCXAgKz0gZWNjc2l6ZTsKPiArCX0KPiAr CXBsMzUzX25hbmRfcmVhZF9kYXRhX29wKGNoaXAsIHAsCj4gKwkJCQkoZWNjc2l6ZSAtIFBMMzUz X05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgpLAo+ICsJCQkJZmFsc2UpOwo+ICsJcCArPSAoZWNj c2l6ZSAtIFBMMzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgpOwo+ICsKPiArCS8qIFNldCBF Q0MgTGFzdCBiaXQgdG8gMSAqLwo+ICsJZGF0YV9waGFzZV9hZGRyID0gKHVuc2lnbmVkIGxvbmcg X19mb3JjZSl4bmZjLT5idWZfYWRkcjsKPiArCWRhdGFfcGhhc2VfYWRkciAtPSBuYW5kX29mZnNl dDsKPiArCWRhdGFfcGhhc2VfYWRkciB8PSBQTDM1M19OQU5EX0VDQ19MQVNUOwo+ICsJZGF0YV9w aGFzZV9hZGRyICs9IG5hbmRfb2Zmc2V0Owo+ICsJeG5mYy0+YnVmX2FkZHIgPSAodm9pZCBfX2lv bWVtICogX19mb3JjZSlkYXRhX3BoYXNlX2FkZHI7Cj4gKwlwbDM1M19uYW5kX3JlYWRfZGF0YV9v cChjaGlwLCBwLCBQTDM1M19OQU5EX0xBU1RfVFJBTlNGRVJfTEVOR1RILAo+ICsJCQkJZmFsc2Up Owo+ICsKPiArCS8qIFdhaXQgdGlsbCB0aGUgRUNDIG9wZXJhdGlvbiBpcyBjb21wbGV0ZSBvciB0 aW1lb3V0ICovCj4gKwlyZXQgPSBwbDM1M193YWl0X2Zvcl9lY2NfZG9uZSgpOwo+ICsJaWYgKHJl dCkKPiArCQlkZXZfZXJyKHhuZmMtPmRldiwgIkVDQyBUaW1lb3V0XG4iKTsKPiArCj4gKwkvKiBS ZWFkIHRoZSBjYWxjdWxhdGVkIEVDQyB2YWx1ZSAqLwo+ICsJcCA9IGJ1ZjsKPiArCXJldCA9IGNo aXAtPmVjYy5jYWxjdWxhdGUoY2hpcCwgcCwgJmVjY19jYWxjWzBdKTsKPiArCWlmIChyZXQpCj4g KwkJcmV0dXJuIHJldDsKPiArCj4gKwkvKiBDbGVhciBFQ0MgbGFzdCBiaXQgKi8KPiArCWRhdGFf cGhhc2VfYWRkciA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+YnVmX2FkZHI7Cj4gKwlk YXRhX3BoYXNlX2FkZHIgLT0gbmFuZF9vZmZzZXQ7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgJj0gflBM MzUzX05BTkRfRUNDX0xBU1Q7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgKz0gbmFuZF9vZmZzZXQ7Cj4g Kwl4bmZjLT5idWZfYWRkciA9ICh2b2lkIF9faW9tZW0gKiBfX2ZvcmNlKWRhdGFfcGhhc2VfYWRk cjsKPiArCj4gKwkvKiBSZWFkIHRoZSBzdG9yZWQgRUNDIHZhbHVlICovCj4gKwlvb2JfcHRyID0g Y2hpcC0+b29iX3BvaTsKPiArCXBsMzUzX25hbmRfcmVhZF9kYXRhX29wKGNoaXAsIG9vYl9wdHIs Cj4gKwkJCQkobXRkLT5vb2JzaXplIC0KPiArCQkJCVBMMzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9M RU5HVEgpLCBmYWxzZSk7Cj4gKwo+ICsJLyogZGUtYXNzZXJ0IGNoaXAgc2VsZWN0ICovCj4gKwlk YXRhX3BoYXNlX2FkZHIgPSAodW5zaWduZWQgbG9uZyBfX2ZvcmNlKXhuZmMtPmJ1Zl9hZGRyOwo+ ICsJZGF0YV9waGFzZV9hZGRyIC09IG5hbmRfb2Zmc2V0Owo+ICsJZGF0YV9waGFzZV9hZGRyIHw9 IFBMMzUzX05BTkRfQ0xFQVJfQ1M7Cj4gKwlkYXRhX3BoYXNlX2FkZHIgKz0gbmFuZF9vZmZzZXQ7 Cj4gKwl4bmZjLT5idWZfYWRkciA9ICh2b2lkIF9faW9tZW0gKiBfX2ZvcmNlKWRhdGFfcGhhc2Vf YWRkcjsKPiArCj4gKwlvb2JfcHRyICs9IChtdGQtPm9vYnNpemUgLSBQTDM1M19OQU5EX0xBU1Rf VFJBTlNGRVJfTEVOR1RIKTsKPiArCXBsMzUzX25hbmRfcmVhZF9kYXRhX29wKGNoaXAsIG9vYl9w dHIsIFBMMzUzX05BTkRfTEFTVF9UUkFOU0ZFUl9MRU5HVEgsCj4gKwkJCQlmYWxzZSk7Cj4gKwo+ ICsJcmV0ID0gbXRkX29vYmxheW91dF9nZXRfZWNjYnl0ZXMobXRkLCBlY2MsIGNoaXAtPm9vYl9w b2ksIDAsCj4gKwkJCQkJIGNoaXAtPmVjYy50b3RhbCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVy biByZXQ7Cj4gKwo+ICsJZWNjc3RlcHMgPSBjaGlwLT5lY2Muc3RlcHM7Cj4gKwlwID0gYnVmOwo+ ICsKPiArCS8qIENoZWNrIEVDQyBlcnJvciBmb3IgYWxsIGJsb2NrcyBhbmQgY29ycmVjdCBpZiBp dCBpcyBjb3JyZWN0YWJsZSAqLwo+ICsJZm9yIChpID0gMCA7IGVjY3N0ZXBzOyBlY2NzdGVwcy0t LCBpICs9IGVjY2J5dGVzLCBwICs9IGVjY3NpemUpIHsKPiArCQlzdGF0ID0gY2hpcC0+ZWNjLmNv cnJlY3QoY2hpcCwgcCwgJmVjY1tpXSwgJmVjY19jYWxjW2ldKTsKPiArCQlpZiAoc3RhdCA8IDAp IHsKPiArCQkJbXRkLT5lY2Nfc3RhdHMuZmFpbGVkKys7Cj4gKwkJfSBlbHNlIHsKPiArCQkJbXRk LT5lY2Nfc3RhdHMuY29ycmVjdGVkICs9IHN0YXQ7Cj4gKwkJCW1heF9iaXRmbGlwcyA9IG1heF90 KHVuc2lnbmVkIGludCwgbWF4X2JpdGZsaXBzLCBzdGF0KTsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJ cmV0dXJuIG1heF9iaXRmbGlwczsKPiArfQo+ICsKPiArLyogTkFORCBmcmFtZXdvcmsgLT5leGVj X29wKCkgaG9va3MgYW5kIHJlbGF0ZWQgaGVscGVycyAqLwo+ICtzdGF0aWMgdm9pZCBwbDM1M19u ZmNfcGFyc2VfaW5zdHJ1Y3Rpb25zKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsCj4gKwkJCQkJIGNv bnN0IHN0cnVjdCBuYW5kX3N1Ym9wICpzdWJvcCwKPiArCQkJCQkgc3RydWN0IHBsMzUzX25mY19v cCAqbmZjX29wKQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3QgbmFuZF9vcF9pbnN0ciAqaW5zdHIgPSBO VUxMOwo+ICsJdW5zaWduZWQgaW50IG9wX2lkLCBvZmZzZXQsIG5hZGRyczsKPiArCWludCBpOwo+ ICsJY29uc3QgdTggKmFkZHJzOwo+ICsKPiArCW1lbXNldChuZmNfb3AsIDAsIHNpemVvZihzdHJ1 Y3QgcGwzNTNfbmZjX29wKSk7Cj4gKwlmb3IgKG9wX2lkID0gMDsgb3BfaWQgPCBzdWJvcC0+bmlu c3Ryczsgb3BfaWQrKykgewo+ICsJCWluc3RyID0gJnN1Ym9wLT5pbnN0cnNbb3BfaWRdOwo+ICsK PiArCQlzd2l0Y2ggKGluc3RyLT50eXBlKSB7Cj4gKwkJY2FzZSBOQU5EX09QX0NNRF9JTlNUUjoK PiArCQkJaWYgKG9wX2lkKQo+ICsJCQkJbmZjX29wLT5jbW5kc1sxXSA9IGluc3RyLT5jdHguY21k Lm9wY29kZTsKPiArCQkJZWxzZQo+ICsJCQkJbmZjX29wLT5jbW5kc1swXSA9IGluc3RyLT5jdHgu Y21kLm9wY29kZTsKPiArCQkJbmZjX29wLT5jbGVfYWxlX2RlbGF5X25zID0gaW5zdHItPmRlbGF5 X25zOwo+ICsJCQlicmVhazsKPiArCj4gKwkJY2FzZSBOQU5EX09QX0FERFJfSU5TVFI6Cj4gKwkJ CW9mZnNldCA9IG5hbmRfc3Vib3BfZ2V0X2FkZHJfc3RhcnRfb2ZmKHN1Ym9wLCBvcF9pZCk7Cj4g KwkJCW5hZGRycyA9IG5hbmRfc3Vib3BfZ2V0X251bV9hZGRyX2N5YyhzdWJvcCwgb3BfaWQpOwo+ ICsJCQlhZGRycyA9ICZpbnN0ci0+Y3R4LmFkZHIuYWRkcnNbb2Zmc2V0XTsKPiArCQkJbmZjX29w LT5hZGRycyA9IGluc3RyLT5jdHguYWRkci5hZGRyc1tvZmZzZXRdOwo+ICsJCQlmb3IgKGkgPSAw OyBpIDwgbWluX3QodW5zaWduZWQgaW50LCA0LCBuYWRkcnMpOyBpKyspIHsKPiArCQkJCW5mY19v cC0+YWRkcnMgfD0gaW5zdHItPmN0eC5hZGRyLmFkZHJzW2ldIDw8Cj4gKwkJCQkJCSAoOCAqIGkp Owo+ICsJCQl9Cj4gKwo+ICsJCQlpZiAobmFkZHJzID49IDUpCj4gKwkJCQluZmNfb3AtPmFkZHI1 ID0gYWRkcnNbNF07Cj4gKwkJCWlmIChuYWRkcnMgPj0gNikKPiArCQkJCW5mY19vcC0+YWRkcjYg PSBhZGRyc1s1XTsKPiArCQkJbmZjX29wLT5uYWRkcnMgPSBuYW5kX3N1Ym9wX2dldF9udW1fYWRk cl9jeWMoc3Vib3AsCj4gKwkJCQkJCQkJICAgICBvcF9pZCk7Cj4gKwkJCW5mY19vcC0+Y2xlX2Fs ZV9kZWxheV9ucyA9IGluc3RyLT5kZWxheV9uczsKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNhc2Ug TkFORF9PUF9EQVRBX0lOX0lOU1RSOgo+ICsJCQluZmNfb3AtPmRhdGFfaW5zdHIgPSBpbnN0cjsK PiArCQkJbmZjX29wLT5kYXRhX2luc3RyX2lkeCA9IG9wX2lkOwo+ICsJCQlicmVhazsKPiArCj4g KwkJY2FzZSBOQU5EX09QX0RBVEFfT1VUX0lOU1RSOgo+ICsJCQluZmNfb3AtPmRhdGFfaW5zdHIg PSBpbnN0cjsKPiArCQkJbmZjX29wLT5kYXRhX2luc3RyX2lkeCA9IG9wX2lkOwo+ICsJCQlicmVh azsKPiArCj4gKwkJY2FzZSBOQU5EX09QX1dBSVRSRFlfSU5TVFI6Cj4gKwkJCW5mY19vcC0+cmR5 X3RpbWVvdXRfbXMgPSBpbnN0ci0+Y3R4LndhaXRyZHkudGltZW91dF9tczsKPiArCQkJbmZjX29w LT5yZHlfZGVsYXlfbnMgPSBpbnN0ci0+ZGVsYXlfbnM7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiAr CX0KPiArfQo+ICsKPiArc3RhdGljIHZvaWQgY29uZF9kZWxheSh1bnNpZ25lZCBpbnQgbnMpCj4g K3sKPiArCWlmICghbnMpCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlmIChucyA8IDEwMDAwKQo+ICsJ CW5kZWxheShucyk7Cj4gKwllbHNlCj4gKwkJdWRlbGF5KERJVl9ST1VORF9VUChucywgMTAwMCkp Owo+ICt9Cj4gKwo+ICsvKioKPiArICogcGwzNTNfbmFuZF9leGVjX29wX2NtZCAtIFNlbmQgY29t bWFuZCB0byBOQU5EIGRldmljZQo+ICsgKiBAY2hpcDoJUG9pbnRlciB0byB0aGUgTkFORCBjaGlw IGluZm8gc3RydWN0dXJlCj4gKyAqIEBzdWJvcDoJUG9pbnRlciB0byBhcnJheSBvZiBpbnN0cnVj dGlvbnMKPiArICogUmV0dXJuOglBbHdheXMgcmV0dXJuIHplcm8KPiArICovCj4gK3N0YXRpYyBp bnQgcGwzNTNfbmFuZF9leGVjX29wX2NtZChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLAo+ICsJCQkJ ICBjb25zdCBzdHJ1Y3QgbmFuZF9zdWJvcCAqc3Vib3ApCj4gK3sKPiArCXN0cnVjdCBtdGRfaW5m byAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4gKwljb25zdCBzdHJ1Y3QgbmFuZF9vcF9pbnN0 ciAqaW5zdHI7Cj4gKwlzdHJ1Y3QgcGwzNTNfbmZjX29wIG5mY19vcCA9IHt9Owo+ICsJc3RydWN0 IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9Cj4gKwkJY29udGFpbmVyX29mKGNoaXAsIHN0 cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIsIGNoaXApOwo+ICsJdW5zaWduZWQgbG9uZyBjbWRf cGhhc2VfZGF0YSA9IDAsIGVuZF9jbWRfdmFsaWQgPSAwOwo+ICsJdW5zaWduZWQgbG9uZyBjbWRf cGhhc2VfYWRkciwgZGF0YV9waGFzZV9hZGRyLCBlbmRfY21kOwo+ICsJdW5zaWduZWQgaW50IG9w X2lkLCBsZW4sIG9mZnNldDsKPiArCWJvb2wgcmVhZGluZzsKPiArCj4gKwlwbDM1M19uZmNfcGFy c2VfaW5zdHJ1Y3Rpb25zKGNoaXAsIHN1Ym9wLCAmbmZjX29wKTsKPiArCWluc3RyID0gbmZjX29w LmRhdGFfaW5zdHI7Cj4gKwlvcF9pZCA9IG5mY19vcC5kYXRhX2luc3RyX2lkeDsKPiArCj4gKwlv ZmZzZXQgPSBuYW5kX3N1Ym9wX2dldF9kYXRhX3N0YXJ0X29mZihzdWJvcCwgb3BfaWQpOwo+ICsK PiArCXBsMzUzX3NtY19jbHJfbmFuZF9pbnQoKTsKPiArCS8qIEdldCB0aGUgY29tbWFuZCBwaGFz ZSBhZGRyZXNzICovCj4gKwlpZiAobmZjX29wLmNtbmRzWzFdICE9IDApIHsKPiArCQlpZiAobmZj X29wLmNtbmRzWzBdID09IE5BTkRfQ01EX1NFUUlOKQo+ICsJCQllbmRfY21kX3ZhbGlkID0gMDsK PiArCQllbHNlCj4gKwkJCWVuZF9jbWRfdmFsaWQgPSAxOwo+ICsJCWVuZF9jbWQgPSBuZmNfb3Au Y21uZHNbMV07Cj4gKwl9ICBlbHNlIHsKPiArCQllbmRfY21kID0gMHgwOwo+ICsJfQo+ICsKPiAr CS8qCj4gKwkgKiBUaGUgU01DIGRlZmluZXMgdHdvIHBoYXNlcyBvZiBjb21tYW5kcyB3aGVuIHRy YW5zZmVycmluZyBkYXRhIHRvIG9yCj4gKwkgKiBmcm9tIE5BTkQgZmxhc2guCj4gKwkgKiBDb21t YW5kIHBoYXNlOiBDb21tYW5kcyBhbmQgb3B0aW9uYWwgYWRkcmVzcyBpbmZvcm1hdGlvbiBhcmUg d3JpdHRlbgo+ICsJICogdG8gdGhlIE5BTkQgZmxhc2guVGhlIGNvbW1hbmQgYW5kIGFkZHJlc3Mg Y2FuIGJlIGFzc29jaWF0ZWQgd2l0aAo+ICsJICogZWl0aGVyIGEgZGF0YSBwaGFzZSBvcGVyYXRp b24gdG8gd3JpdGUgdG8gb3IgcmVhZCBmcm9tIHRoZSBhcnJheSwKPiArCSAqIG9yIGEgc3RhdHVz L0lEIHJlZ2lzdGVyIHRyYW5zZmVyLgo+ICsJICogRGF0YSBwaGFzZTogRGF0YSBpcyBlaXRoZXIg d3JpdHRlbiB0byBvciByZWFkIGZyb20gdGhlIE5BTkQgZmxhc2guCj4gKwkgKiBUaGlzIGRhdGEg Y2FuIGJlIGVpdGhlciBkYXRhIHRyYW5zZmVycmVkIHRvIG9yIGZyb20gdGhlIGFycmF5LAo+ICsJ ICogb3Igc3RhdHVzL0lEIHJlZ2lzdGVyIGluZm9ybWF0aW9uLgo+ICsJICovCj4gKwljbWRfcGhh c2VfYWRkciA9ICh1bnNpZ25lZCBsb25nIF9fZm9yY2UpeG5mYy0+cmVncyArCj4gKwkJCSAoKG5m Y19vcC5uYWRkcnMgPDwgQUREUl9DWUNMRVNfU0hJRlQpIHwKPiArCQkJIChlbmRfY21kX3ZhbGlk IDw8IEVORF9DTURfVkFMSURfU0hJRlQpIHwKPiArCQkJIChDT01NQU5EX1BIQVNFKSB8Cj4gKwkJ CSAoZW5kX2NtZCA8PCBFTkRfQ01EX1NISUZUKSB8Cj4gKwkJCSAobmZjX29wLmNtbmRzWzBdIDw8 IFNUQVJUX0NNRF9TSElGVCkpOwo+ICsKPiArCS8qIEdldCB0aGUgZGF0YSBwaGFzZSBhZGRyZXNz ICovCj4gKwllbmRfY21kX3ZhbGlkID0gMDsKPiArCj4gKwlkYXRhX3BoYXNlX2FkZHIgPSAodW5z aWduZWQgbG9uZyBfX2ZvcmNlKXhuZmMtPnJlZ3MgKwo+ICsJCQkgICgoMHgwIDw8IENMRUFSX0NT X1NISUZUKSB8Cj4gKwkJCSAgKGVuZF9jbWRfdmFsaWQgPDwgRU5EX0NNRF9WQUxJRF9TSElGVCkg fAo+ICsJCQkgIChEQVRBX1BIQVNFKSB8Cj4gKwkJCSAgKGVuZF9jbWQgPDwgRU5EX0NNRF9TSElG VCkgfAo+ICsJCQkgICgweDAgPDwgRUNDX0xBU1RfU0hJRlQpKTsKPiArCXhuZmMtPmJ1Zl9hZGRy ID0gKHZvaWQgX19pb21lbSAqIF9fZm9yY2UpZGF0YV9waGFzZV9hZGRyOwo+ICsKPiArCS8qIENv bW1hbmQgcGhhc2UgQVhJIFJlYWQgJiBXcml0ZSAqLwo+ICsJaWYgKG5mY19vcC5uYWRkcnMgPj0g NSkgewo+ICsJCWlmIChtdGQtPndyaXRlc2l6ZSA+IFBMMzUzX05BTkRfRUNDX1NJWkUpIHsKPiAr CQkJY21kX3BoYXNlX2RhdGEgPSBuZmNfb3AuYWRkcnM7Cj4gKwkJCS8qIEFub3RoZXIgYWRkcmVz cyBjeWNsZSBmb3IgZGV2aWNlcyA+IDEyOE1pQiAqLwo+ICsJCQlpZiAoY2hpcC0+b3B0aW9ucyAm IE5BTkRfUk9XX0FERFJfMykgewo+ICsJCQkJd3JpdGVsX3JlbGF4ZWQoY21kX3BoYXNlX2RhdGEs Cj4gKwkJCQkJICAgICAgICh2b2lkIF9faW9tZW0gKiBfX2ZvcmNlKQo+ICsJCQkJCSAgICAgICBj bWRfcGhhc2VfYWRkcik7Cj4gKwkJCQljbWRfcGhhc2VfZGF0YSA9IG5mY19vcC5hZGRyNTsKPiAr CQkJCWlmIChuZmNfb3AubmFkZHJzID49IDYpCj4gKwkJCQkJY21kX3BoYXNlX2RhdGEgfD0gKG5m Y19vcC5hZGRyNiA8PCA4KTsKPiArCQkJfQo+ICsJCX0KPiArCX0gIGVsc2Ugewo+ICsJCWlmIChu ZmNfb3AuYWRkcnMgIT0gLTEpIHsKPiArCQkJaW50IGNvbHVtbiA9IG5mY19vcC5hZGRyczsKPiAr CQkJLyoKPiArCQkJICogQ2hhbmdlIHJlYWQvd3JpdGUgY29sdW1uLCByZWFkIGlkIGV0Ywo+ICsJ CQkgKiBBZGp1c3QgY29sdW1ucyBmb3IgMTYgYml0IGJ1cyB3aWR0aAo+ICsJCQkgKi8KPiArCQkJ aWYgKChjaGlwLT5vcHRpb25zICYgTkFORF9CVVNXSURUSF8xNikgJiYKPiArCQkJICAgIChuZmNf b3AuY21uZHNbMF0gPT0gTkFORF9DTURfUkVBRDAgfHwKPiArCQkJCW5mY19vcC5jbW5kc1swXSA9 PSBOQU5EX0NNRF9TRVFJTiB8fAo+ICsJCQkJbmZjX29wLmNtbmRzWzBdID09IE5BTkRfQ01EX1JO RE9VVCB8fAo+ICsJCQkJbmZjX29wLmNtbmRzWzBdID09IE5BTkRfQ01EX1JORElOKSkgewo+ICsJ CQkJY29sdW1uID4+PSAxOwo+ICsJCQl9Cj4gKwkJCWNtZF9waGFzZV9kYXRhID0gY29sdW1uOwo+ ICsJCX0KPiArCX0KPiArCXdyaXRlbF9yZWxheGVkKGNtZF9waGFzZV9kYXRhLCAodm9pZCBfX2lv bWVtICogX19mb3JjZSljbWRfcGhhc2VfYWRkcik7Cj4gKwo+ICsJaWYgKCFuZmNfb3AuZGF0YV9p bnN0cikgewo+ICsJCWlmIChuZmNfb3AucmR5X3RpbWVvdXRfbXMpCj4gKwkJCW5hbmRfd2FpdF9y ZWFkeShjaGlwKTsKPiArCQlyZXR1cm4gMDsKPiArCX0KPiArCj4gKwlyZWFkaW5nID0gKG5mY19v cC5kYXRhX2luc3RyLT50eXBlID09IE5BTkRfT1BfREFUQV9JTl9JTlNUUik7Cj4gKwlpZiAoIXJl YWRpbmcpIHsKPiArCQlsZW4gPSBuYW5kX3N1Ym9wX2dldF9kYXRhX2xlbihzdWJvcCwgb3BfaWQp Owo+ICsJCXBsMzUzX25hbmRfd3JpdGVfZGF0YV9vcChjaGlwLCBpbnN0ci0+Y3R4LmRhdGEuYnVm Lm91dCwKPiArCQkJCQkgbGVuLCBpbnN0ci0+Y3R4LmRhdGEuZm9yY2VfOGJpdCk7Cj4gKwkJaWYg KG5mY19vcC5yZHlfdGltZW91dF9tcykKPiArCQkJbmFuZF93YWl0X3JlYWR5KGNoaXApOwo+ICsJ CWNvbmRfZGVsYXkobmZjX29wLnJkeV9kZWxheV9ucyk7Cj4gKwl9CgplbHNlID8KCj4gKwlpZiAo cmVhZGluZykgewo+ICsJCWxlbiA9IG5hbmRfc3Vib3BfZ2V0X2RhdGFfbGVuKHN1Ym9wLCBvcF9p ZCk7Cj4gKwkJY29uZF9kZWxheShuZmNfb3AucmR5X2RlbGF5X25zKTsKPiArCQlpZiAobmZjX29w LnJkeV90aW1lb3V0X21zKQo+ICsJCQluYW5kX3dhaXRfcmVhZHkoY2hpcCk7Cj4gKwkJcGwzNTNf bmFuZF9yZWFkX2RhdGFfb3AoY2hpcCwgaW5zdHItPmN0eC5kYXRhLmJ1Zi5pbiwgbGVuLAo+ICsJ CQkJCWluc3RyLT5jdHguZGF0YS5mb3JjZV84Yml0KTsKPiArCX0KPiArCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBuYW5kX29wX3BhcnNlciBwbDM1M19uZmNf b3BfcGFyc2VyID0gTkFORF9PUF9QQVJTRVIKPiArCShOQU5EX09QX1BBUlNFUl9QQVRURVJOCj4g KwkJKHBsMzUzX25hbmRfZXhlY19vcF9jbWQsCj4gKwkJTkFORF9PUF9QQVJTRVJfUEFUX0NNRF9F TEVNKHRydWUpLAo+ICsJCU5BTkRfT1BfUEFSU0VSX1BBVF9BRERSX0VMRU0odHJ1ZSwgNyksCj4g KwkJTkFORF9PUF9QQVJTRVJfUEFUX1dBSVRSRFlfRUxFTSh0cnVlKSwKPiArCQlOQU5EX09QX1BB UlNFUl9QQVRfREFUQV9JTl9FTEVNKGZhbHNlLCAyMDQ4KSksCj4gKwlOQU5EX09QX1BBUlNFUl9Q QVRURVJOCj4gKwkJKHBsMzUzX25hbmRfZXhlY19vcF9jbWQsCj4gKwkJTkFORF9PUF9QQVJTRVJf UEFUX0NNRF9FTEVNKGZhbHNlKSwKPiArCQlOQU5EX09QX1BBUlNFUl9QQVRfQUREUl9FTEVNKGZh bHNlLCA3KSwKPiArCQlOQU5EX09QX1BBUlNFUl9QQVRfQ01EX0VMRU0oZmFsc2UpLAo+ICsJCU5B TkRfT1BfUEFSU0VSX1BBVF9XQUlUUkRZX0VMRU0oZmFsc2UpLAo+ICsJCU5BTkRfT1BfUEFSU0VS X1BBVF9EQVRBX0lOX0VMRU0oZmFsc2UsIDIwNDgpKSwKPiArCU5BTkRfT1BfUEFSU0VSX1BBVFRF Uk4KPiArCQkocGwzNTNfbmFuZF9leGVjX29wX2NtZCwKPiArCQlOQU5EX09QX1BBUlNFUl9QQVRf Q01EX0VMRU0oZmFsc2UpLAo+ICsJCU5BTkRfT1BfUEFSU0VSX1BBVF9BRERSX0VMRU0odHJ1ZSwg NyksCj4gKwkJTkFORF9PUF9QQVJTRVJfUEFUX0NNRF9FTEVNKHRydWUpLAo+ICsJCU5BTkRfT1Bf UEFSU0VSX1BBVF9XQUlUUkRZX0VMRU0oZmFsc2UpKSwKPiArCU5BTkRfT1BfUEFSU0VSX1BBVFRF Uk4KPiArCQkocGwzNTNfbmFuZF9leGVjX29wX2NtZCwKPiArCQlOQU5EX09QX1BBUlNFUl9QQVRf Q01EX0VMRU0oZmFsc2UpLAo+ICsJCU5BTkRfT1BfUEFSU0VSX1BBVF9BRERSX0VMRU0oZmFsc2Us IDgpLAo+ICsJCU5BTkRfT1BfUEFSU0VSX1BBVF9EQVRBX09VVF9FTEVNKGZhbHNlLCAyMDQ4KSwK PiArCQlOQU5EX09QX1BBUlNFUl9QQVRfQ01EX0VMRU0odHJ1ZSksCj4gKwkJTkFORF9PUF9QQVJT RVJfUEFUX1dBSVRSRFlfRUxFTSh0cnVlKSksCj4gKwlOQU5EX09QX1BBUlNFUl9QQVRURVJOCj4g KwkJKHBsMzUzX25hbmRfZXhlY19vcF9jbWQsCj4gKwkJTkFORF9PUF9QQVJTRVJfUEFUX0NNRF9F TEVNKGZhbHNlKSksCj4gKwkpOwo+ICsKPiArc3RhdGljIGludCBwbDM1M19uZmNfZXhlY19vcChz dHJ1Y3QgbmFuZF9jaGlwICpjaGlwLAo+ICsJCQkgICAgIGNvbnN0IHN0cnVjdCBuYW5kX29wZXJh dGlvbiAqb3AsCj4gKwkJCSAgICAgYm9vbCBjaGVja19vbmx5KQo+ICt7Cj4gKwlyZXR1cm4gbmFu ZF9vcF9wYXJzZXJfZXhlY19vcChjaGlwLCAmcGwzNTNfbmZjX29wX3BhcnNlciwKPiArCQkJCQkg ICAgICBvcCwgY2hlY2tfb25seSk7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiBwbDM1M19uYW5kX2Rl dmljZV9yZWFkeSAtIENoZWNrIGRldmljZSByZWFkeS9idXN5IGxpbmUKPiArICogQG10ZDoJUG9p bnRlciB0byB0aGUgbXRkX2luZm8gc3RydWN0dXJlCj4gKyAqCj4gKyAqIFJldHVybjoJMCBvbiBi dXN5IG9yIDEgb24gcmVhZHkgc3RhdGUKPiArICovCj4gK3N0YXRpYyBpbnQgcGwzNTNfbmFuZF9k ZXZpY2VfcmVhZHkoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCkKPiArewo+ICsJaWYgKHBsMzUzX3Nt Y19nZXRfbmFuZF9pbnRfc3RhdHVzX3JhdygpKSB7Cj4gKwkJcGwzNTNfc21jX2Nscl9uYW5kX2lu dCgpOwo+ICsJCXJldHVybiAxOwo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICsv KioKPiArICogcGwzNTNfbmFuZF9lY2NfaW5pdCAtIEluaXRpYWxpemUgdGhlIGVjYyBpbmZvcm1h dGlvbiBhcyBwZXIgdGhlIGVjYyBtb2RlCj4gKyAqIEBtdGQ6CVBvaW50ZXIgdG8gdGhlIG10ZF9p bmZvIHN0cnVjdHVyZQo+ICsgKiBAZWNjOglQb2ludGVyIHRvIEVDQyBjb250cm9sIHN0cnVjdHVy ZQo+ICsgKiBAZWNjX21vZGU6CW9uZGllIGVjYyBzdGF0dXMKPiArICoKPiArICogVGhpcyBmdW5j dGlvbiBpbml0aWFsaXplcyB0aGUgZWNjIGJsb2NrIGFuZCBmdW5jdGlvbmFsIHBvaW50ZXJzIGFz IHBlciB0aGUKPiArICogZWNjIG1vZGUKPiArICoKPiArICogUmV0dXJuOgkwIG9uIHN1Y2Nlc3Mg b3IgbmVnYXRpdmUgZXJybm8uCj4gKyAqLwo+ICtzdGF0aWMgaW50IHBsMzUzX25hbmRfZWNjX2lu aXQoc3RydWN0IG10ZF9pbmZvICptdGQsIHN0cnVjdCBuYW5kX2VjY19jdHJsICplY2MsCj4gKwkJ CSAgICAgICBpbnQgZWNjX21vZGUpCj4gK3sKPiArCXN0cnVjdCBuYW5kX2NoaXAgKmNoaXAgPSBt dGRfdG9fbmFuZChtdGQpOwo+ICsJc3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9 Cj4gKwkJY29udGFpbmVyX29mKGNoaXAsIHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xsZXIsIGNo aXApOwo+ICsJaW50IGVyciA9IDA7Cj4gKwo+ICsJZWNjLT53cml0ZV9wYWdlX3JhdyA9IHBsMzUz X25hbmRfd3JpdGVfcGFnZV9yYXc7Cj4gKwllY2MtPnJlYWRfcGFnZV9yYXcgPSBwbDM1M19uYW5k X3JlYWRfcGFnZV9yYXc7Cj4gKwllY2MtPnJlYWRfb29iID0gcGwzNTNfbmFuZF9yZWFkX29vYjsK PiArCWVjYy0+d3JpdGVfb29iID0gcGwzNTNfbmFuZF93cml0ZV9vb2I7Cj4gKwo+ICsJaWYgKGVj Y19tb2RlID09IE5BTkRfRUNDX09OX0RJRSkgewo+ICsJCXBsMzUzX3NtY19zZXRfZWNjX21vZGUo UEwzNTNfU01DX0VDQ01PREVfQllQQVNTKTsKPiArCQkvKgo+ICsJCSAqIE9uLURpZSBFQ0Mgc3Bh cmUgYnl0ZXMgb2Zmc2V0IDggaXMgdXNlZCBmb3IgRUNDIGNvZGVzCj4gKwkJICogVXNlIHRoZSBC QlQgcGF0dGVybiBkZXNjcmlwdG9ycwo+ICsJCSAqLwo+ICsJCWNoaXAtPmJidF90ZCA9ICZiYnRf bWFpbl9kZXNjcjsKPiArCQljaGlwLT5iYnRfbWQgPSAmYmJ0X21pcnJvcl9kZXNjcjsKPiArCX0g ZWxzZSB7Cj4gKwkJZWNjLT5tb2RlID0gTkFORF9FQ0NfSFc7Cj4gKwkJLyogSGFyZHdhcmUgRUND IGdlbmVyYXRlcyAzIGJ5dGVzIEVDQyBjb2RlIGZvciBlYWNoIDUxMiBieXRlcyAqLwo+ICsJCWVj Yy0+Ynl0ZXMgPSAzOwo+ICsJCWVjYy0+c3RyZW5ndGggPSAxOwo+ICsJCWVjYy0+Y2FsY3VsYXRl ID0gcGwzNTNfbmFuZF9jYWxjdWxhdGVfaHdlY2M7Cj4gKwkJZWNjLT5jb3JyZWN0ID0gcGwzNTNf bmFuZF9jb3JyZWN0X2RhdGE7Cj4gKwkJZWNjLT5yZWFkX3BhZ2UgPSBwbDM1M19uYW5kX3JlYWRf cGFnZV9od2VjYzsKPiArCQllY2MtPnNpemUgPSBQTDM1M19OQU5EX0VDQ19TSVpFOwo+ICsJCWVj Yy0+cmVhZF9wYWdlID0gcGwzNTNfbmFuZF9yZWFkX3BhZ2VfaHdlY2M7Cj4gKwkJZWNjLT53cml0 ZV9wYWdlID0gcGwzNTNfbmFuZF93cml0ZV9wYWdlX2h3ZWNjOwo+ICsJCXBsMzUzX3NtY19zZXRf ZWNjX3BnX3NpemUobXRkLT53cml0ZXNpemUpOwo+ICsJCXN3aXRjaCAobXRkLT53cml0ZXNpemUp IHsKPiArCQljYXNlIFNaXzUxMjoKPiArCQljYXNlIFNaXzFLOgo+ICsJCWNhc2UgU1pfMks6Cj4g KwkJCXBsMzUzX3NtY19zZXRfZWNjX21vZGUoUEwzNTNfU01DX0VDQ01PREVfQVBCKTsKPiArCQkJ YnJlYWs7Cj4gKwkJZGVmYXVsdDoKPiArCQkJZWNjLT5jYWxjdWxhdGUgPSBuYW5kX2NhbGN1bGF0 ZV9lY2M7Cj4gKwkJCWVjYy0+Y29ycmVjdCA9IG5hbmRfY29ycmVjdF9kYXRhOwo+ICsJCQllY2Mt PnNpemUgPSAyNTY7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCj4gKwkJaWYgKG10ZC0+b29ic2l6 ZSA9PSAxNikgewo+ICsJCQltdGRfc2V0X29vYmxheW91dChtdGQsICZwbDM1M19lY2Nfb29ibGF5 b3V0MTZfb3BzKTsKPiArCQl9IGVsc2UgaWYgKG10ZC0+b29ic2l6ZSA9PSA2NCkgewo+ICsJCQlt dGRfc2V0X29vYmxheW91dChtdGQsICZwbDM1M19lY2Nfb29ibGF5b3V0NjRfb3BzKTsKPiArCQl9 IGVsc2Ugewo+ICsJCQllcnIgPSAtRU5YSU87Cj4gKwkJCWRldl9lcnIoeG5mYy0+ZGV2LCAiVW5z dXBwb3J0ZWQgb29iIExheW91dFxuIik7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCXJldHVybiBlcnI7 Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcGwzNTNfbmZjX3NldHVwX2RhdGFfaW50ZXJmYWNlKHN0 cnVjdCBuYW5kX2NoaXAgKmNoaXAsIGludCBjc2xpbmUsCj4gKwkJCQkJICBjb25zdCBzdHJ1Y3Qg bmFuZF9kYXRhX2ludGVyZmFjZQo+ICsJCQkJCSAgKmNvbmYpCj4gK3sKPiArCXN0cnVjdCBwbDM1 M19uYW5kX2NvbnRyb2xsZXIgKnhuZmMgPQo+ICsJCWNvbnRhaW5lcl9vZihjaGlwLCBzdHJ1Y3Qg cGwzNTNfbmFuZF9jb250cm9sbGVyLCBjaGlwKTsKPiArCWNvbnN0IHN0cnVjdCBuYW5kX3Nkcl90 aW1pbmdzICpzZHI7Cj4gKwl1MzIgdGltaW5nc1s3XSwgbWNrcGVyaW9kcHM7Cj4gKwo+ICsJaWYg KGNzbGluZSA9PSBOQU5EX0RBVEFfSUZBQ0VfQ0hFQ0tfT05MWSkKPiArCQlyZXR1cm4gMDsKPiAr Cj4gKwlzZHIgPSBuYW5kX2dldF9zZHJfdGltaW5ncyhjb25mKTsKPiArCWlmIChJU19FUlIoc2Ry KSkKPiArCQlyZXR1cm4gUFRSX0VSUihzZHIpOwo+ICsKPiArCS8qCj4gKwkgKiBTRFIgdGltaW5n cyBhcmUgZ2l2ZW4gaW4gcGljby1zZWNvbmRzIHdoaWxlIE5GQyB0aW1pbmdzIG11c3QgYmUKPiAr CSAqIGV4cHJlc3NlZCBpbiBOQU5EIGNvbnRyb2xsZXIgY2xvY2sgY3ljbGVzLgo+ICsJICovCj4g KwltY2twZXJpb2RwcyA9IE5TRUNfUEVSX1NFQyAvIGNsa19nZXRfcmF0ZSh4bmZjLT5tY2xrKTsK PiArCW1ja3BlcmlvZHBzICo9IDEwMDA7Cj4gKwlpZiAoc2RyLT50UkNfbWluIDw9IDIwMDAwKQo+ ICsJCS8qCj4gKwkJICogUEwzNTMgU01DIG5lZWRzIG9uZSBleHRyYSByZWFkIGN5Y2xlIGluIFNE UiBNb2RlIDUKPiArCQkgKiBUaGlzIGlzIG5vdCB3cml0dGVuIGFueXdoZXJlIGluIHRoZSBkYXRh c2hlZXQgYnV0Cj4gKwkJICogdGhlIHJlc3VsdHMgb2JzZXJ2ZWQgZHVyaW5nIHRlc3RpbmcuCj4g KwkJICovCj4gKwkJdGltaW5nc1swXSA9IERJVl9ST1VORF9VUChzZHItPnRSQ19taW4sIG1ja3Bl cmlvZHBzKSArIDE7Cj4gKwllbHNlCj4gKwkJdGltaW5nc1swXSA9IERJVl9ST1VORF9VUChzZHIt PnRSQ19taW4sIG1ja3BlcmlvZHBzKTsKPiArCj4gKwl0aW1pbmdzWzFdID0gRElWX1JPVU5EX1VQ KHNkci0+dFdDX21pbiwgbWNrcGVyaW9kcHMpOwo+ICsJLyoKPiArCSAqIEZvciBhbGwgU0RSIG1v ZGVzLCBQTDM1MyBTTUMgbmVlZHMgdFJFQSBtYXggdmFsdWUgYXMgMSwKPiArCSAqIFJlc3VsdHMg b2JzZXJ2ZWQgZHVyaW5nIHRlc3RpbmcuCj4gKwkgKi8KPiArCXRpbWluZ3NbMl0gPSBQTDM1M19U UkVBX01BWF9WQUxVRTsKPiArCXRpbWluZ3NbM10gPSBESVZfUk9VTkRfVVAoc2RyLT50V1BfbWlu LCBtY2twZXJpb2Rwcyk7Cj4gKwl0aW1pbmdzWzRdID0gRElWX1JPVU5EX1VQKHNkci0+dENMUl9t aW4sIG1ja3BlcmlvZHBzKTsKPiArCXRpbWluZ3NbNV0gPSBESVZfUk9VTkRfVVAoc2RyLT50QVJf bWluLCBtY2twZXJpb2Rwcyk7Cj4gKwl0aW1pbmdzWzZdID0gRElWX1JPVU5EX1VQKHNkci0+dFJS X21pbiwgbWNrcGVyaW9kcHMpOwo+ICsJcGwzNTNfc21jX3NldF9jeWNsZXModGltaW5ncyk7Cj4g Kwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcGwzNTNfbmFuZF9hdHRhY2hf Y2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+ICt7Cj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10 ZCA9IG5hbmRfdG9fbXRkKGNoaXApOwo+ICsJc3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAq eG5mYyA9Cj4gKwkJY29udGFpbmVyX29mKGNoaXAsIHN0cnVjdCBwbDM1M19uYW5kX2NvbnRyb2xs ZXIsIGNoaXApOwo+ICsJdTMyIHJldDsKPiArCj4gKwlpZiAoY2hpcC0+b3B0aW9ucyAmIE5BTkRf QlVTV0lEVEhfMTYpCj4gKwkJcGwzNTNfc21jX3NldF9idXN3aWR0aChQTDM1M19TTUNfTUVNX1dJ RFRIXzE2KTsKPiArCj4gKwlpZiAobXRkLT53cml0ZXNpemUgPD0gU1pfNTEyKQo+ICsJCXhuZmMt PmFkZHJfY3ljbGVzID0gMTsKPiArCWVsc2UKPiArCQl4bmZjLT5hZGRyX2N5Y2xlcyA9IDI7Cj4g Kwo+ICsJaWYgKGNoaXAtPm9wdGlvbnMgJiBOQU5EX1JPV19BRERSXzMpCj4gKwkJeG5mYy0+YWRk cl9jeWNsZXMgKz0gMzsKPiArCWVsc2UKPiArCQl4bmZjLT5hZGRyX2N5Y2xlcyArPSAyOwo+ICsK PiArCXJldCA9IHBsMzUzX25hbmRfZWNjX2luaXQobXRkLCAmY2hpcC0+ZWNjLCBjaGlwLT5lY2Mu bW9kZSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2Vycih4bmZjLT5kZXYsICJFQ0MgaW5pdCBm YWlsZWRcbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJaWYgKCFtdGQtPm5hbWUp IHsKPiArCQkvKgo+ICsJCSAqIElmIHRoZSBuZXcgYmluZGluZ3MgYXJlIHVzZWQgYW5kIHRoZSBi b290bG9hZGVyIGhhcyBub3QgYmVlbgo+ICsJCSAqIHVwZGF0ZWQgdG8gcGFzcyBhIG5ldyBtdGRw YXJ0cyBwYXJhbWV0ZXIgb24gdGhlIGNtZGxpbmUsIHlvdQo+ICsJCSAqIHNob3VsZCBkZWZpbmUg dGhlIGZvbGxvd2luZyBwcm9wZXJ0eSBpbiB5b3VyIE5BTkQgbm9kZSwgaWU6Cj4gKwkJICoKPiAr CQkgKglsYWJlbCA9ICJwbDM1My1uYW5kIjsKPiArCQkgKgo+ICsJCSAqIFRoaXMgd2F5LCBtdGQt Pm5hbWUgd2lsbCBiZSBzZXQgYnkgdGhlIGNvcmUgd2hlbgo+ICsJCSAqIG5hbmRfc2V0X2ZsYXNo X25vZGUoKSBpcyBjYWxsZWQuCj4gKwkJICovCj4gKwkJbXRkLT5uYW1lID0gZGV2bV9rYXNwcmlu dGYoeG5mYy0+ZGV2LCBHRlBfS0VSTkVMLAo+ICsJCQkJCSAgICIlcyIsIFBMMzUzX05BTkRfRFJJ VkVSX05BTUUpOwo+ICsJCWlmICghbXRkLT5uYW1lKSB7Cj4gKwkJCWRldl9lcnIoeG5mYy0+ZGV2 LCAiRmFpbGVkIHRvIGFsbG9jYXRlIG10ZC0+bmFtZVxuIik7Cj4gKwkJCXJldHVybiAtRU5PTUVN Owo+ICsJCX0KPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBuYW5kX2NvbnRyb2xsZXJfb3BzIHBsMzUzX25hbmRfY29udHJvbGxlcl9vcHMgPSB7 Cj4gKwkuYXR0YWNoX2NoaXAgPSBwbDM1M19uYW5kX2F0dGFjaF9jaGlwLAo+ICsJLmV4ZWNfb3Ag PSBwbDM1M19uZmNfZXhlY19vcCwKPiArCS5zZXR1cF9kYXRhX2ludGVyZmFjZSA9IHBsMzUzX25m Y19zZXR1cF9kYXRhX2ludGVyZmFjZSwKPiArfTsKPiArCj4gKy8qKgo+ICsgKiBwbDM1M19uYW5k X3Byb2JlIC0gUHJvYmUgbWV0aG9kIGZvciB0aGUgTkFORCBkcml2ZXIKPiArICogQHBkZXY6CVBv aW50ZXIgdG8gdGhlIHBsYXRmb3JtX2RldmljZSBzdHJ1Y3R1cmUKPiArICoKPiArICogVGhpcyBm dW5jdGlvbiBpbml0aWFsaXplcyB0aGUgZHJpdmVyIGRhdGEgc3RydWN0dXJlcyBhbmQgdGhlIGhh cmR3YXJlLgo+ICsgKiBUaGUgTkFORCBkcml2ZXIgaGFzIGRlcGVuZGVuY3kgd2l0aCB0aGUgcGwz NTNfc21jIG1lbW9yeSBjb250cm9sbGVyCj4gKyAqIGRyaXZlciBmb3IgaW5pdGlhbGl6aW5nIHRo ZSBOQU5EIHRpbWluZyBwYXJhbWV0ZXJzLCBidXMgd2lkdGgsIEVDQyBtb2RlcywKPiArICogY29u dHJvbCBhbmQgc3RhdHVzIGluZm9ybWF0aW9uLgo+ICsgKgo+ICsgKiBSZXR1cm46CTAgb24gc3Vj Y2VzcyBvciBlcnJvciB2YWx1ZSBvbiBmYWlsdXJlCj4gKyAqLwo+ICtzdGF0aWMgaW50IHBsMzUz X25hbmRfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0 IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYzsKPiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkOwo+ ICsJc3RydWN0IG5hbmRfY2hpcCAqY2hpcDsKPiArCXN0cnVjdCByZXNvdXJjZSAqcmVzOwo+ICsJ c3RydWN0IGRldmljZV9ub2RlICpucCwgKmRuOwo+ICsJdTMyIHJldCwgdmFsOwo+ICsKPiArCXhu ZmMgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgc2l6ZW9mKCp4bmZjKSwgR0ZQX0tFUk5FTCk7 Cj4gKwlpZiAoIXhuZmMpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwl4bmZjLT5kZXYgPSAmcGRl di0+ZGV2Owo+ICsKPiArCW5hbmRfY29udHJvbGxlcl9pbml0KCZ4bmZjLT5jb250cm9sbGVyKTsK PiArCXhuZmMtPmNvbnRyb2xsZXIub3BzID0gJnBsMzUzX25hbmRfY29udHJvbGxlcl9vcHM7Cj4g KwkvKiBNYXAgcGh5c2ljYWwgYWRkcmVzcyBvZiBOQU5EIGZsYXNoICovCj4gKwlyZXMgPSBwbGF0 Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOwo+ICsJeG5mYy0+cmVn cyA9IGRldm1faW9yZW1hcF9yZXNvdXJjZSh4bmZjLT5kZXYsIHJlcyk7Cj4gKwlpZiAoSVNfRVJS KHhuZmMtPnJlZ3MpKQo+ICsJCXJldHVybiBQVFJfRVJSKHhuZmMtPnJlZ3MpOwo+ICsKPiArCWNo aXAgPSAmeG5mYy0+Y2hpcDsKPiArCWNoaXAtPmNvbnRyb2xsZXIgPSAmeG5mYy0+Y29udHJvbGxl cjsKPiArCW10ZCA9IG5hbmRfdG9fbXRkKGNoaXApOwo+ICsJbmFuZF9zZXRfY29udHJvbGxlcl9k YXRhKGNoaXAsIHhuZmMpOwo+ICsJbXRkLT5wcml2ID0gY2hpcDsKPiArCW10ZC0+b3duZXIgPSBU SElTX01PRFVMRTsKPiArCW5hbmRfc2V0X2ZsYXNoX25vZGUoY2hpcCwgeG5mYy0+ZGV2LT5vZl9u b2RlKTsKPiArCj4gKwkvKiBTZXQgdGhlIGRyaXZlciBlbnRyeSBwb2ludHMgZm9yIE1URCAqLwo+ ICsJY2hpcC0+bGVnYWN5LmRldl9yZWFkeSA9IHBsMzUzX25hbmRfZGV2aWNlX3JlYWR5OwoKUGxl YXNlIGRvIG5vdCBpbXBsZW1lbnQgbGVnYWN5IGludGVyZmFjZXMuCgo+ICsJLyogSWYgd2UgZG9u J3Qgc2V0IHRoaXMgZGVsYXkgZHJpdmVyIHNldHMgMjB1cyBieSBkZWZhdWx0ICovCj4gKwlucCA9 IG9mX2dldF9uZXh0X3BhcmVudCh4bmZjLT5kZXYtPm9mX25vZGUpOwo+ICsJeG5mYy0+bWNsayA9 IG9mX2Nsa19nZXQobnAsIDApOwo+ICsJaWYgKElTX0VSUih4bmZjLT5tY2xrKSkgewo+ICsJCWRl dl9lcnIoeG5mYy0+ZGV2LCAiRmFpbGVkIHRvIHJldHJpZXZlIE1DSyBjbGtcbiIpOwo+ICsJCXJl dHVybiBQVFJfRVJSKHhuZmMtPm1jbGspOwo+ICsJfQo+ICsKPiArCWRuID0gbmFuZF9nZXRfZmxh c2hfbm9kZShjaGlwKTsKPiArCj4gKwkvKiBTZXQgdGhlIGRldmljZSBvcHRpb24gYW5kIGZsYXNo IHdpZHRoICovCj4gKwljaGlwLT5vcHRpb25zID0gTkFORF9CVVNXSURUSF9BVVRPOwo+ICsJY2hp cC0+YmJ0X29wdGlvbnMgPSBOQU5EX0JCVF9VU0VfRkxBU0g7Cj4gKwlwbGF0Zm9ybV9zZXRfZHJ2 ZGF0YShwZGV2LCB4bmZjKTsKPiArCXJldCA9IG5hbmRfc2NhbihjaGlwLCAxKTsKPiArCWlmIChy ZXQpIHsKPiArCQlkZXZfZXJyKHhuZmMtPmRldiwgImNvdWxkIG5vdCBzY2FuIHRoZSBuYW5kIGNo aXBcbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gbXRkX2RldmljZV9y ZWdpc3RlcihtdGQsIE5VTEwsIDApOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoeG5mYy0+ ZGV2LCAiRmFpbGVkIHRvIHJlZ2lzdGVyIG10ZCBkZXZpY2U6ICVkXG4iLCByZXQpOwo+ICsJCW5h bmRfY2xlYW51cChjaGlwKTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXJldHVybiAw Owo+ICt9Cj4gKwo+ICsvKioKPiArICogcGwzNTNfbmFuZF9yZW1vdmUgLSBSZW1vdmUgbWV0aG9k IGZvciB0aGUgTkFORCBkcml2ZXIKPiArICogQHBkZXY6CVBvaW50ZXIgdG8gdGhlIHBsYXRmb3Jt X2RldmljZSBzdHJ1Y3R1cmUKPiArICoKPiArICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgaWYg dGhlIGRyaXZlciBtb2R1bGUgaXMgYmVpbmcgdW5sb2FkZWQuIEl0IGZyZWVzIGFsbAo+ICsgKiBy ZXNvdXJjZXMgYWxsb2NhdGVkIHRvIHRoZSBkZXZpY2UuCj4gKyAqCj4gKyAqIFJldHVybjoJMCBv biBzdWNjZXNzIG9yIGVycm9yIHZhbHVlIG9uIGZhaWx1cmUKPiArICovCj4gK3N0YXRpYyBpbnQg cGwzNTNfbmFuZF9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJ c3RydWN0IHBsMzUzX25hbmRfY29udHJvbGxlciAqeG5mYyA9IHBsYXRmb3JtX2dldF9kcnZkYXRh KHBkZXYpOwo+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZCgmeG5mYy0+Y2hp cCk7Cj4gKwlzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwID0gbXRkX3RvX25hbmQobXRkKTsKPiArCj4g KwkvKiBSZWxlYXNlIHJlc291cmNlcywgdW5yZWdpc3RlciBkZXZpY2UgKi8KPiArCW5hbmRfcmVs ZWFzZShjaGlwKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArLyogTWF0Y2ggdGFibGUg Zm9yIGRldmljZSB0cmVlIGJpbmRpbmcgKi8KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp Y2VfaWQgcGwzNTNfbmFuZF9vZl9tYXRjaFtdID0gewo+ICsJeyAuY29tcGF0aWJsZSA9ICJhcm0s cGwzNTMtbmFuZC1yMnAxIiB9LAo+ICsJe30sCj4gK307Cj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUo b2YsIHBsMzUzX25hbmRfb2ZfbWF0Y2gpOwo+ICsKPiArLyoKPiArICogcGwzNTNfbmFuZF9kcml2 ZXIgLSBUaGlzIHN0cnVjdHVyZSBkZWZpbmVzIHRoZSBOQU5EIHN1YnN5c3RlbSBwbGF0Zm9ybSBk cml2ZXIKPiArICovCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsMzUzX25hbmRf ZHJpdmVyID0gewo+ICsJLnByb2JlCQk9IHBsMzUzX25hbmRfcHJvYmUsCj4gKwkucmVtb3ZlCQk9 IHBsMzUzX25hbmRfcmVtb3ZlLAo+ICsJLmRyaXZlcgkJPSB7Cj4gKwkJLm5hbWUJPSBQTDM1M19O QU5EX0RSSVZFUl9OQU1FLAo+ICsJCS5vZl9tYXRjaF90YWJsZSA9IHBsMzUzX25hbmRfb2ZfbWF0 Y2gsCj4gKwl9LAo+ICt9Owo+ICsKPiArbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihwbDM1M19uYW5k X2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfQVVUSE9SKCJYaWxpbngsIEluYy4iKTsKPiArTU9EVUxF X0FMSUFTKCJwbGF0Zm9ybToiIFBMMzUzX05BTkRfRFJJVkVSX05BTUUpOwo+ICtNT0RVTEVfREVT Q1JJUFRJT04oIkFSTSBQTDM1MyBOQU5EIEZsYXNoIERyaXZlciIpOwo+ICtNT0RVTEVfTElDRU5T RSgiR1BMIik7CgoKVGhhbmtzLApNaXF1w6hsCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXggTVREIGRpc2N1c3Npb24gbWFpbGluZyBs aXN0Cmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtbXRk Lwo= 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=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,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 53652C43381 for ; Mon, 4 Mar 2019 09:43:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A499E20836 for ; Mon, 4 Mar 2019 09:43:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726338AbfCDJnR convert rfc822-to-8bit (ORCPT ); Mon, 4 Mar 2019 04:43:17 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:36957 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726034AbfCDJnQ (ORCPT ); Mon, 4 Mar 2019 04:43:16 -0500 Received: from xps13 (aaubervilliers-681-1-27-150.w90-88.abo.wanadoo.fr [90.88.147.150]) (Authenticated sender: miquel.raynal@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id B218C240015; Mon, 4 Mar 2019 09:43:02 +0000 (UTC) Date: Mon, 4 Mar 2019 10:43:01 +0100 From: Miquel Raynal To: Naga Sureshkumar Relli Cc: , , , , , , , , Subject: Re: [LINUX PATCH v13] rawnand: pl353: Add basic driver for arm pl353 smc nand interface Message-ID: <20190304104301.062ccc1e@xps13> In-Reply-To: <1549694247-24625-1-git-send-email-naga.sureshkumar.relli@xilinx.com> References: <1549694247-24625-1-git-send-email-naga.sureshkumar.relli@xilinx.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 Naga, Naga Sureshkumar Relli wrote on Sat, 9 Feb 2019 12:07:27 +0530: > Add driver for arm pl353 static memory controller nand interface with > HW ECC support. This controller is used in Xilinx Zynq SoC for > interfacing the NAND flash memory. > > Signed-off-by: Naga Sureshkumar Relli > --- > xilinx zynq TRM link: > https://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf > > ARM pl353 smc TRM link: > http://infocenter.arm.com/help/topic/com.arm.doc.ddi0380g/DDI0380G_smc_pl350_series_r2p1_trm.pdf > > Tested Micron MT29F2G08ABAEAWP (On-die capable) and AMD/Spansion S34ML01G1. > > SMC memory controller driver is at drivers/memory/pl353-smc.c > > Changes in v13: > - Rebased the driver to mtd/next > Changes in v12: > - Rebased the driver on top of v4.19 nand tree > - Removed nand_scan_ident() and nand_scan_tail(), and added nand_controller_ops > with ->attach_chip() and used nand_scan() instead. > - Renamed pl353_nand_info structure to pl353_nand_controller > - Renamed nand_base and nandaddr in pl353_nand_controller to 'regs' and 'buf_addr' > - Added new API pl353_wait_for_ecc_done() to wait for ecc done and call it from > pl353_nand_write_page_hwecc() and pl353_nand_read_page_hwecc() > - Defined new macro for max ECC blocks > - Added return value check for ecc.calculate() > - Renamed pl353_nand_cmd_function() to pl353_nand_exec_op_cmd() > - Added x16 bus-width support > - The dependent driver pl353-smc is already reviewed and hence dropped the > smc driver > Changes in v11: > - Removed Documentation patch and added the required info in driver as > per Boris comments. > - Removed unwanted variables from pl353_nand_info as per Miquel comments > - Removed IO_ADDR_R/W. > - Replaced onhot() with hweight32() > - Defined macros for static values in function pl353_nand_correct_data() > - Removed all unnecessary delays > - Used nand_wait_ready() where ever is required > - Modifed the pl353_setup_data_interface() logic as per Miquel comments. > - Taken array instead of 7 values in pl353_setup_data_interface() and pass > it to smc driver. > - Added check to collect the return value of mtd_device_register(). > Changes in 10: > - Typos correction like nand to NAND and soc to SOC etc.. > - Defined macros for the values in pl353_nand_calculate_hwecc() > - Modifed ecc_status from int to char in pl353_nand_calculate_hwecc() > - Changed the return type form int to bool to the function > onehot() > - Removed udelay(1000) in pl353_cmd_function, as it is not required > - Dropped ecc->hwctl = NULL in pl353_ecc_init() > - Added an error message in pl353_ecc_init(), when there is no matching > oobsize > - Changed the variable from xnand to xnfc > - Added logic to get mtd->name from DT, if it is specified in DT > Changes in v9: > - Addressed the below comments given by Miquel > - instead of using pl353_nand_write32, use directly writel_relaxed > - Fixed check patch warnings > - Renamed write_buf/read_buf to write_data_op/read_data_op > - use BIT macro instead of 1 << nr > - Use NAND_ROW_ADDR_3 flag > - Use nand_wait_ready() > - Removed swecc functions > - Use address cycles as per size, instead of reading it from Parameter page > - Instead of writing too many patterns, use optional property > Changes in v8: > - Added exec_op() implementation > - Fixed the below v7 review comments > - removed mtd_info from pl353_nand_info struct > - Corrected ecc layout offsets > - Added on-die ecc support > Changes in v7: > - Currently not implemented the memclk rate adjustments. I will > look into this later and once the basic driver is accepted. > - Fixed GPL licence ident > Changes in v6: > - Fixed the checkpatch.pl reported warnings > - Using the address cycles information from the onfi param page > earlier it is hardcoded to 5 in driver > Changes in v5: > - Configure the nand timing parameters as per the onfi spec Changes in v4: > - Updated the driver to sync with pl353_smc driver APIs > Changes in v3: > - implemented the proper error codes > - further breakdown this patch to multiple sets > - added the controller and driver details to Documentation section > - updated the licenece to GPLv2 > - reorganized the pl353_nand_ecc_init function > Changes in v2: > - use "depends on" rather than "select" option in kconfig > - remove unused variable parts > --- > drivers/mtd/nand/raw/Kconfig | 8 + > drivers/mtd/nand/raw/Makefile | 1 + > drivers/mtd/nand/raw/pl353_nand.c | 1380 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 1389 insertions(+) > create mode 100644 drivers/mtd/nand/raw/pl353_nand.c > > diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig > index 1a55d3e..bc6c0a0 100644 > --- a/drivers/mtd/nand/raw/Kconfig > +++ b/drivers/mtd/nand/raw/Kconfig > @@ -541,4 +541,12 @@ config MTD_NAND_TEGRA > is supported. Extra OOB bytes when using HW ECC are currently > not supported. > > +config MTD_NAND_PL353 > + tristate "ARM Pl353 NAND flash driver" > + depends on MTD_NAND && ARM > + depends on PL353_SMC > + help > + Enables support for PrimeCell Static Memory Controller PL353. > + > + > endif # MTD_NAND > diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile > index 57159b3..9d3c48d 100644 > --- a/drivers/mtd/nand/raw/Makefile > +++ b/drivers/mtd/nand/raw/Makefile > @@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ > obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o > obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o > obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o > +obj-$(CONFIG_MTD_NAND_PL353) += pl353_nand.o > > nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o > nand-objs += nand_onfi.o > diff --git a/drivers/mtd/nand/raw/pl353_nand.c b/drivers/mtd/nand/raw/pl353_nand.c > new file mode 100644 > index 0000000..1dbaae5 > --- /dev/null > +++ b/drivers/mtd/nand/raw/pl353_nand.c > @@ -0,0 +1,1380 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * ARM PL353 NAND flash controller driver > + * > + * Copyright (C) 2017 Xilinx, Inc > + * Author: Punnaiah chowdary kalluri > + * Author: Naga Sureshkumar Relli > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define PL353_NAND_DRIVER_NAME "pl353-nand" > + > +/* NAND flash driver defines */ > +#define PL353_NAND_CMD_PHASE 1 /* End command valid in command phase */ > +#define PL353_NAND_DATA_PHASE 2 /* End command valid in data phase */ > +#define PL353_NAND_ECC_SIZE 512 /* Size of data for ECC operation */ > + > +/* Flash memory controller operating parameters */ > + > +#define PL353_NAND_ECC_CONFIG (BIT(4) | /* ECC read at end of page */ \ > + (0 << 5)) /* No Jumping */ > + > +/* AXI Address definitions */ > +#define START_CMD_SHIFT 3 > +#define END_CMD_SHIFT 11 > +#define END_CMD_VALID_SHIFT 20 > +#define ADDR_CYCLES_SHIFT 21 > +#define CLEAR_CS_SHIFT 21 > +#define ECC_LAST_SHIFT 10 > +#define COMMAND_PHASE (0 << 19) > +#define DATA_PHASE BIT(19) > + > +#define PL353_NAND_ECC_LAST BIT(ECC_LAST_SHIFT) /* Set ECC_Last */ > +#define PL353_NAND_CLEAR_CS BIT(CLEAR_CS_SHIFT) /* Clear chip select */ > + > +#define PL353_NAND_ECC_BUSY_TIMEOUT (1 * HZ) > +#define PL353_NAND_DEV_BUSY_TIMEOUT (1 * HZ) > +#define PL353_NAND_LAST_TRANSFER_LENGTH 4 > +#define PL353_NAND_ECC_VALID_SHIFT 24 > +#define PL353_NAND_ECC_VALID_MASK 0x40 > +#define PL353_ECC_BITS_BYTEOFF_MASK 0x1FF > +#define PL353_ECC_BITS_BITOFF_MASK 0x7 > +#define PL353_ECC_BIT_MASK 0xFFF > +#define PL353_TREA_MAX_VALUE 1 > +#define PL353_MAX_ECC_CHUNKS 4 > +#define PL353_MAX_ECC_BYTES 3 > + > +struct pl353_nfc_op { > + u32 cmnds[4]; > + u32 end_cmd; > + u32 addrs; > + u32 naddrs; > + u32 addr5; > + u32 addr6; > + unsigned int data_instr_idx; > + unsigned int rdy_timeout_ms; > + unsigned int rdy_delay_ns; > + unsigned int cle_ale_delay_ns; > + const struct nand_op_instr *data_instr; > +}; > + > +/** > + * struct pl353_nand_controller - Defines the NAND flash controller driver > + * instance > + * @chip: NAND chip information structure > + * @dev: Parent device (used to print error messages) > + * @regs: Virtual address of the NAND flash device > + * @buf_addr: Virtual address of the NAND flash device for > + * data read/writes > + * @addr_cycles: Address cycles > + * @mclk: Memory controller clock > + * @buswidth: Bus width 8 or 16 > + */ > +struct pl353_nand_controller { > + struct nand_controller controller; > + struct nand_chip chip; > + struct device *dev; > + void __iomem *regs; > + void __iomem *buf_addr; > + u8 addr_cycles; > + struct clk *mclk; > + u32 buswidth; > +}; > + > +static int pl353_ecc_ooblayout16_ecc(struct mtd_info *mtd, int section, > + struct mtd_oob_region *oobregion) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + if (section >= chip->ecc.steps) > + return -ERANGE; > + > + oobregion->offset = (section * chip->ecc.bytes); > + oobregion->length = chip->ecc.bytes; > + > + return 0; > +} > + > +static int pl353_ecc_ooblayout16_free(struct mtd_info *mtd, int section, > + struct mtd_oob_region *oobregion) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + if (section >= chip->ecc.steps) > + return -ERANGE; > + > + oobregion->offset = (section * chip->ecc.bytes) + 8; > + oobregion->length = 8; > + > + return 0; > +} > + > +static const struct mtd_ooblayout_ops pl353_ecc_ooblayout16_ops = { > + .ecc = pl353_ecc_ooblayout16_ecc, > + .free = pl353_ecc_ooblayout16_free, > +}; > + > +static int pl353_ecc_ooblayout64_ecc(struct mtd_info *mtd, int section, > + struct mtd_oob_region *oobregion) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + if (section >= chip->ecc.steps) > + return -ERANGE; > + > + oobregion->offset = (section * chip->ecc.bytes) + 52; > + oobregion->length = chip->ecc.bytes; > + > + return 0; > +} > + > +static int pl353_ecc_ooblayout64_free(struct mtd_info *mtd, int section, > + struct mtd_oob_region *oobregion) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + if (section) > + return -ERANGE; > + > + if (section >= chip->ecc.steps) > + return -ERANGE; > + > + oobregion->offset = (section * chip->ecc.bytes) + 2; > + oobregion->length = 50; > + > + return 0; > +} > + > +static const struct mtd_ooblayout_ops pl353_ecc_ooblayout64_ops = { > + .ecc = pl353_ecc_ooblayout64_ecc, > + .free = pl353_ecc_ooblayout64_free, > +}; > + > +/* Generic flash bbt decriptors */ > +static u8 bbt_pattern[] = { 'B', 'b', 't', '0' }; > +static u8 mirror_pattern[] = { '1', 't', 'b', 'B' }; > + > +static struct nand_bbt_descr bbt_main_descr = { > + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE > + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, > + .offs = 4, > + .len = 4, > + .veroffs = 20, > + .maxblocks = 4, > + .pattern = bbt_pattern > +}; > + > +static struct nand_bbt_descr bbt_mirror_descr = { > + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE > + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, > + .offs = 4, > + .len = 4, > + .veroffs = 20, > + .maxblocks = 4, > + .pattern = mirror_pattern > +}; > + > +static void pl353_nfc_force_byte_access(struct nand_chip *chip, > + bool force_8bit) > +{ > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + > + if (!(chip->options & NAND_BUSWIDTH_16)) > + return; > + > + if (force_8bit) > + pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_8); > + else > + pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_16); > +} > + > +/** > + * pl353_nand_read_data_op - read chip data into buffer > + * @chip: Pointer to the NAND chip info structure > + * @in: Pointer to the buffer to store read data > + * @len: Number of bytes to read > + * @force_8bit: Force 8-bit bus access > + * Return: Always return zero > + */ > +static int pl353_nand_read_data_op(struct nand_chip *chip, > + u8 *in, > + unsigned int len, bool force_8bit) > +{ > + int i; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + > + if (force_8bit) > + pl353_nfc_force_byte_access(chip, true); > + > + if ((IS_ALIGNED((uint32_t)in, sizeof(uint32_t)) && > + IS_ALIGNED(len, sizeof(uint32_t))) || !force_8bit) { > + u32 *ptr = (u32 *)in; > + > + len /= 4; > + for (i = 0; i < len; i++) > + ptr[i] = readl(xnfc->buf_addr); > + } else { > + for (i = 0; i < len; i++) > + in[i] = readb(xnfc->buf_addr); > + } > + if (force_8bit) > + pl353_nfc_force_byte_access(chip, false); > + > + return 0; > +} > + > +/** > + * pl353_nand_write_buf - write buffer to chip > + * @mtd: Pointer to the mtd info structure > + * @buf: Pointer to the buffer to store write data > + * @len: Number of bytes to write > + * @force_8bit: Force 8-bit bus access > + */ > +static void pl353_nand_write_data_op(struct nand_chip *chip, const u8 *buf, > + int len, bool force_8bit) > +{ > + int i; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + > + if (force_8bit) > + pl353_nfc_force_byte_access(chip, true); > + > + if ((IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && > + IS_ALIGNED(len, sizeof(uint32_t))) || !force_8bit) { > + u32 *ptr = (u32 *)buf; > + > + len /= 4; > + for (i = 0; i < len; i++) > + writel(ptr[i], xnfc->buf_addr); > + } else { > + for (i = 0; i < len; i++) > + writeb(buf[i], xnfc->buf_addr); > + } > + if (force_8bit) > + pl353_nfc_force_byte_access(chip, false); > +} > + > +static int pl353_wait_for_ecc_done(void) > +{ > + unsigned long timeout = jiffies + PL353_NAND_ECC_BUSY_TIMEOUT; > + > + do { > + if (pl353_smc_ecc_is_busy()) > + cpu_relax(); > + else > + break; > + } while (!time_after_eq(jiffies, timeout)); > + > + if (time_after_eq(jiffies, timeout)) { > + pr_err("%s timed out\n", __func__); > + return -ETIMEDOUT; > + } > + > + return 0; > +} > + > +/** > + * pl353_nand_calculate_hwecc - Calculate Hardware ECC > + * @mtd: Pointer to the mtd_info structure > + * @data: Pointer to the page data > + * @ecc: Pointer to the ECC buffer where ECC data needs to be stored > + * > + * This function retrieves the Hardware ECC data from the controller and returns > + * ECC data back to the MTD subsystem. > + * It operates on a number of 512 byte blocks of NAND memory and can be > + * programmed to store the ECC codes after the data in memory. For writes, > + * the ECC is written to the spare area of the page. For reads, the result of > + * a block ECC check are made available to the device driver. > + * > + * ------------------------------------------------------------------------ > + * | n * 512 blocks | extra | ecc | | > + * | | block | codes | | > + * ------------------------------------------------------------------------ > + * > + * The ECC calculation uses a simple Hamming code, using 1-bit correction 2-bit > + * detection. It starts when a valid read or write command with a 512 byte > + * aligned address is detected on the memory interface. > + * > + * Return: 0 on success or error value on failure > + */ > +static int pl353_nand_calculate_hwecc(struct nand_chip *chip, > + const u8 *data, u8 *ecc) > +{ > + u32 ecc_value; > + u8 chunk, ecc_byte, ecc_status; > + > + for (chunk = 0; chunk < PL353_MAX_ECC_CHUNKS; chunk++) { > + /* Read ECC value for each block */ > + ecc_value = pl353_smc_get_ecc_val(chunk); > + ecc_status = (ecc_value >> PL353_NAND_ECC_VALID_SHIFT); > + > + /* ECC value valid */ > + if (ecc_status & PL353_NAND_ECC_VALID_MASK) { > + for (ecc_byte = 0; ecc_byte < PL353_MAX_ECC_BYTES; > + ecc_byte++) { > + /* Copy ECC bytes to MTD buffer */ > + *ecc = ~ecc_value & 0xFF; > + ecc_value = ecc_value >> 8; > + ecc++; > + } > + } else { > + pr_warn("%s status failed\n", __func__); > + return -1; > + } > + } > + > + return 0; > +} > + > +/** > + * pl353_nand_correct_data - ECC correction function > + * @mtd: Pointer to the mtd_info structure > + * @buf: Pointer to the page data > + * @read_ecc: Pointer to the ECC value read from spare data area > + * @calc_ecc: Pointer to the calculated ECC value > + * > + * This function corrects the ECC single bit errors & detects 2-bit errors. > + * > + * Return: 0 if no ECC errors found > + * 1 if single bit error found and corrected. > + * -1 if multiple uncorrectable ECC errors found. > + */ > +static int pl353_nand_correct_data(struct nand_chip *chip, unsigned char *buf, > + unsigned char *read_ecc, > + unsigned char *calc_ecc) Isn't it a regular Hamming software ECC algorithm? Can't you re-use the implementation already existing? > +{ > + unsigned char bit_addr; > + unsigned int byte_addr; > + unsigned short ecc_odd, ecc_even, read_ecc_lower, read_ecc_upper; > + unsigned short calc_ecc_lower, calc_ecc_upper; > + > + read_ecc_lower = (read_ecc[0] | (read_ecc[1] << 8)) & > + PL353_ECC_BIT_MASK; > + read_ecc_upper = ((read_ecc[1] >> 4) | (read_ecc[2] << 4)) & > + PL353_ECC_BIT_MASK; > + > + calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] << 8)) & > + PL353_ECC_BIT_MASK; > + calc_ecc_upper = ((calc_ecc[1] >> 4) | (calc_ecc[2] << 4)) & > + PL353_ECC_BIT_MASK; > + > + ecc_odd = read_ecc_lower ^ calc_ecc_lower; > + ecc_even = read_ecc_upper ^ calc_ecc_upper; > + > + /* no error */ > + if (!ecc_odd && !ecc_even) > + return 0; > + > + if (ecc_odd == (~ecc_even & PL353_ECC_BIT_MASK)) { > + /* bits [11:3] of error code is byte offset */ > + byte_addr = (ecc_odd >> 3) & PL353_ECC_BITS_BYTEOFF_MASK; > + /* bits [2:0] of error code is bit offset */ > + bit_addr = ecc_odd & PL353_ECC_BITS_BITOFF_MASK; > + /* Toggling error bit */ > + buf[byte_addr] ^= (BIT(bit_addr)); > + return 1; > + } > + > + /* one error in parity */ > + if (hweight32(ecc_odd | ecc_even) == 1) > + return 1; > + > + /* Uncorrectable error */ > + return -1; > +} > + > +static void pl353_prepare_cmd(struct nand_chip *chip, > + int page, int column, int start_cmd, int end_cmd, > + bool read) > +{ > + unsigned long data_phase_addr; > + u32 end_cmd_valid = 0; > + unsigned long cmd_phase_addr = 0, cmd_phase_data = 0; > + struct mtd_info *mtd = nand_to_mtd(chip); > + > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + > + end_cmd_valid = read ? 1 : 0; > + > + cmd_phase_addr = (unsigned long __force)xnfc->regs + > + ((xnfc->addr_cycles > + << ADDR_CYCLES_SHIFT) | > + (end_cmd_valid << END_CMD_VALID_SHIFT) | > + (COMMAND_PHASE) | > + (end_cmd << END_CMD_SHIFT) | > + (start_cmd << START_CMD_SHIFT)); > + > + /* Get the data phase address */ > + data_phase_addr = (unsigned long __force)xnfc->regs + > + ((0x0 << CLEAR_CS_SHIFT) | > + (0 << END_CMD_VALID_SHIFT) | > + (DATA_PHASE) | > + (end_cmd << END_CMD_SHIFT) | > + (0x0 << ECC_LAST_SHIFT)); > + > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + > + if (chip->options & NAND_BUSWIDTH_16) > + column /= 2; > + cmd_phase_data = column; > + if (mtd->writesize > PL353_NAND_ECC_SIZE) { > + cmd_phase_data |= page << 16; > + /* Another address cycle for devices > 128MiB */ > + if (chip->options & NAND_ROW_ADDR_3) { > + writel_relaxed(cmd_phase_data, > + (void __iomem * __force)cmd_phase_addr); > + cmd_phase_data = (page >> 16); > + } > + } else { > + cmd_phase_data |= page << 8; > + } > + > + writel_relaxed(cmd_phase_data, (void __iomem * __force)cmd_phase_addr); > +} > + > +/** > + * pl353_nand_read_oob - [REPLACEABLE] the most common OOB data read function > + * @mtd: Pointer to the mtd_info structure > + * @chip: Pointer to the nand_chip structure > + * @page: Page number to read > + * > + * Return: Always return zero > + */ > +static int pl353_nand_read_oob(struct nand_chip *chip, > + int page) > +{ > + unsigned long data_phase_addr; > + u8 *p; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long nand_offset = (unsigned long __force)xnfc->regs; > + struct mtd_info *mtd = nand_to_mtd(chip); > + > + chip->pagebuf = -1; > + if (mtd->writesize < PL353_NAND_ECC_SIZE) > + return 0; > + > + pl353_prepare_cmd(chip, page, mtd->writesize, NAND_CMD_READ0, > + NAND_CMD_READSTART, 1); > + > + nand_wait_ready(chip); > + > + p = chip->oob_poi; > + pl353_nand_read_data_op(chip, p, > + (mtd->oobsize - > + PL353_NAND_LAST_TRANSFER_LENGTH), false); > + p += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_CLEAR_CS; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + pl353_nand_read_data_op(chip, p, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + > + return 0; > +} > + > +/** > + * pl353_nand_write_oob - [REPLACEABLE] the most common OOB data write function > + * @mtd: Pointer to the mtd info structure > + * @chip: Pointer to the NAND chip info structure > + * @page: Page number to write > + * > + * Return: Zero on success and EIO on failure > + */ > +static int pl353_nand_write_oob(struct nand_chip *chip, > + int page) > +{ > + const u8 *buf = chip->oob_poi; > + unsigned long data_phase_addr; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long nand_offset = (unsigned long __force)xnfc->regs; > + struct mtd_info *mtd = nand_to_mtd(chip); > + u32 addrcycles = 0; > + > + chip->pagebuf = -1; > + addrcycles = xnfc->addr_cycles; > + pl353_prepare_cmd(chip, page, mtd->writesize, NAND_CMD_SEQIN, > + NAND_CMD_PAGEPROG, 0); > + > + pl353_nand_write_data_op(chip, buf, > + (mtd->oobsize - > + PL353_NAND_LAST_TRANSFER_LENGTH), false); > + buf += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_CLEAR_CS; > + data_phase_addr |= (1 << END_CMD_VALID_SHIFT); > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + pl353_nand_write_data_op(chip, buf, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + nand_wait_ready(chip); > + > + return 0; > +} > + > +/** > + * pl353_nand_read_page_raw - [Intern] read raw page data without ecc > + * @mtd: Pointer to the mtd info structure > + * @chip: Pointer to the NAND chip info structure > + * @buf: Pointer to the data buffer > + * @oob_required: Caller requires OOB data read to chip->oob_poi > + * @page: Page number to read > + * > + * Return: Always return zero > + */ > +static int pl353_nand_read_page_raw(struct nand_chip *chip, > + u8 *buf, int oob_required, int page) > +{ > + unsigned long data_phase_addr; > + u8 *p; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long nand_offset = (unsigned long __force)xnfc->regs; > + struct mtd_info *mtd = nand_to_mtd(chip); > + > + pl353_prepare_cmd(chip, page, 0, NAND_CMD_READ0, > + NAND_CMD_READSTART, 1); > + nand_wait_ready(chip); > + pl353_nand_read_data_op(chip, buf, mtd->writesize, false); > + p = chip->oob_poi; > + pl353_nand_read_data_op(chip, p, > + (mtd->oobsize - > + PL353_NAND_LAST_TRANSFER_LENGTH), false); > + p += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_CLEAR_CS; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + > + pl353_nand_read_data_op(chip, p, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + > + return 0; > +} > + > +/** > + * pl353_nand_write_page_raw - [Intern] raw page write function > + * @mtd: Pointer to the mtd info structure > + * @chip: Pointer to the NAND chip info structure > + * @buf: Pointer to the data buffer > + * @oob_required: Caller requires OOB data read to chip->oob_poi > + * @page: Page number to write > + * > + * Return: Always return zero > + */ > +static int pl353_nand_write_page_raw(struct nand_chip *chip, > + const u8 *buf, int oob_required, > + int page) > +{ > + unsigned long data_phase_addr; > + u8 *p; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long nand_offset = (unsigned long __force)xnfc->regs; > + struct mtd_info *mtd = nand_to_mtd(chip); > + > + pl353_prepare_cmd(chip, page, 0, NAND_CMD_SEQIN, > + NAND_CMD_PAGEPROG, 0); > + pl353_nand_write_data_op(chip, buf, mtd->writesize, false); > + p = chip->oob_poi; > + pl353_nand_write_data_op(chip, p, > + (mtd->oobsize - > + PL353_NAND_LAST_TRANSFER_LENGTH), false); > + p += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_CLEAR_CS; > + data_phase_addr |= (1 << END_CMD_VALID_SHIFT); > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + pl353_nand_write_data_op(chip, p, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + > + return 0; > +} > + > +/** > + * nand_write_page_hwecc - Hardware ECC based page write function > + * @mtd: Pointer to the mtd info structure > + * @chip: Pointer to the NAND chip info structure > + * @buf: Pointer to the data buffer > + * @oob_required: Caller requires OOB data read to chip->oob_poi > + * @page: Page number to write > + * > + * This functions writes data and hardware generated ECC values in to the page. > + * > + * Return: Always return zero > + */ > +static int pl353_nand_write_page_hwecc(struct nand_chip *chip, > + const u8 *buf, int oob_required, > + int page) > +{ > + int eccsize = chip->ecc.size; > + int eccsteps = chip->ecc.steps; > + u8 *ecc_calc = chip->ecc.calc_buf; > + u8 *oob_ptr; > + const u8 *p = buf; > + u32 ret; > + unsigned long data_phase_addr; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long nand_offset = (unsigned long __force)xnfc->regs; > + struct mtd_info *mtd = nand_to_mtd(chip); > + > + pl353_prepare_cmd(chip, page, 0, NAND_CMD_SEQIN, > + NAND_CMD_PAGEPROG, 0); > + > + for ( ; (eccsteps - 1); eccsteps--) { > + pl353_nand_write_data_op(chip, p, eccsize, false); > + p += eccsize; > + } > + pl353_nand_write_data_op(chip, p, > + (eccsize - PL353_NAND_LAST_TRANSFER_LENGTH), > + false); > + p += (eccsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + > + /* Set ECC Last bit to 1 */ > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_ECC_LAST; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + pl353_nand_write_data_op(chip, p, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + > + /* Wait till the ECC operation is complete or timeout */ > + ret = pl353_wait_for_ecc_done(); > + if (ret) > + dev_err(xnfc->dev, "ECC Timeout\n"); > + p = buf; > + ret = chip->ecc.calculate(chip, p, &ecc_calc[0]); > + if (ret) > + return ret; > + > + /* Wait for ECC to be calculated and read the error values */ > + ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, > + 0, chip->ecc.total); > + if (ret) > + return ret; > + /* Clear ECC last bit */ > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr &= ~PL353_NAND_ECC_LAST; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + > + /* Write the spare area with ECC bytes */ > + oob_ptr = chip->oob_poi; > + pl353_nand_write_data_op(chip, oob_ptr, > + (mtd->oobsize - > + PL353_NAND_LAST_TRANSFER_LENGTH), false); > + > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_CLEAR_CS; > + data_phase_addr |= (1 << END_CMD_VALID_SHIFT); > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + oob_ptr += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + pl353_nand_write_data_op(chip, oob_ptr, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + nand_wait_ready(chip); > + > + return 0; > +} > + > +/** > + * pl353_nand_read_page_hwecc - Hardware ECC based page read function > + * @mtd: Pointer to the mtd info structure > + * @chip: Pointer to the NAND chip info structure > + * @buf: Pointer to the buffer to store read data > + * @oob_required: Caller requires OOB data read to chip->oob_poi > + * @page: Page number to read > + * > + * This functions reads data and checks the data integrity by comparing > + * hardware generated ECC values and read ECC values from spare area. > + * There is a limitation in SMC controller, that we must set ECC LAST on > + * last data phase access, to tell ECC block not to expect any data further. > + * Ex: When number of ECC STEPS are 4, then till 3 we will write to flash > + * using SMC with HW ECC enabled. And for the last ECC STEP, we will subtract > + * 4bytes from page size, and will initiate a transfer. And the remaining 4 as > + * one more transfer with ECC_LAST bit set in NAND data phase register to > + * notify ECC block not to expect any more data. The last block should be align > + * with end of 512 byte block. Because of this limitation, we are not using > + * core routines. > + * > + * Return: 0 always and updates ECC operation status in to MTD structure > + */ > +static int pl353_nand_read_page_hwecc(struct nand_chip *chip, > + u8 *buf, int oob_required, int page) > +{ > + int i, stat, eccsize = chip->ecc.size; > + int eccbytes = chip->ecc.bytes; > + int eccsteps = chip->ecc.steps; > + u8 *p = buf; > + u8 *ecc_calc = chip->ecc.calc_buf; > + u8 *ecc = chip->ecc.code_buf; > + unsigned int max_bitflips = 0; > + u8 *oob_ptr; > + u32 ret; > + unsigned long data_phase_addr; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long nand_offset = (unsigned long __force)xnfc->regs; > + struct mtd_info *mtd = nand_to_mtd(chip); > + > + pl353_prepare_cmd(chip, page, 0, NAND_CMD_READ0, > + NAND_CMD_READSTART, 1); > + nand_wait_ready(chip); > + > + for ( ; (eccsteps - 1); eccsteps--) { > + pl353_nand_read_data_op(chip, p, eccsize, false); > + p += eccsize; > + } > + pl353_nand_read_data_op(chip, p, > + (eccsize - PL353_NAND_LAST_TRANSFER_LENGTH), > + false); > + p += (eccsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + > + /* Set ECC Last bit to 1 */ > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_ECC_LAST; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + pl353_nand_read_data_op(chip, p, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + > + /* Wait till the ECC operation is complete or timeout */ > + ret = pl353_wait_for_ecc_done(); > + if (ret) > + dev_err(xnfc->dev, "ECC Timeout\n"); > + > + /* Read the calculated ECC value */ > + p = buf; > + ret = chip->ecc.calculate(chip, p, &ecc_calc[0]); > + if (ret) > + return ret; > + > + /* Clear ECC last bit */ > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr &= ~PL353_NAND_ECC_LAST; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + > + /* Read the stored ECC value */ > + oob_ptr = chip->oob_poi; > + pl353_nand_read_data_op(chip, oob_ptr, > + (mtd->oobsize - > + PL353_NAND_LAST_TRANSFER_LENGTH), false); > + > + /* de-assert chip select */ > + data_phase_addr = (unsigned long __force)xnfc->buf_addr; > + data_phase_addr -= nand_offset; > + data_phase_addr |= PL353_NAND_CLEAR_CS; > + data_phase_addr += nand_offset; > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + > + oob_ptr += (mtd->oobsize - PL353_NAND_LAST_TRANSFER_LENGTH); > + pl353_nand_read_data_op(chip, oob_ptr, PL353_NAND_LAST_TRANSFER_LENGTH, > + false); > + > + ret = mtd_ooblayout_get_eccbytes(mtd, ecc, chip->oob_poi, 0, > + chip->ecc.total); > + if (ret) > + return ret; > + > + eccsteps = chip->ecc.steps; > + p = buf; > + > + /* Check ECC error for all blocks and correct if it is correctable */ > + for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { > + stat = chip->ecc.correct(chip, p, &ecc[i], &ecc_calc[i]); > + if (stat < 0) { > + mtd->ecc_stats.failed++; > + } else { > + mtd->ecc_stats.corrected += stat; > + max_bitflips = max_t(unsigned int, max_bitflips, stat); > + } > + } > + > + return max_bitflips; > +} > + > +/* NAND framework ->exec_op() hooks and related helpers */ > +static void pl353_nfc_parse_instructions(struct nand_chip *chip, > + const struct nand_subop *subop, > + struct pl353_nfc_op *nfc_op) > +{ > + const struct nand_op_instr *instr = NULL; > + unsigned int op_id, offset, naddrs; > + int i; > + const u8 *addrs; > + > + memset(nfc_op, 0, sizeof(struct pl353_nfc_op)); > + for (op_id = 0; op_id < subop->ninstrs; op_id++) { > + instr = &subop->instrs[op_id]; > + > + switch (instr->type) { > + case NAND_OP_CMD_INSTR: > + if (op_id) > + nfc_op->cmnds[1] = instr->ctx.cmd.opcode; > + else > + nfc_op->cmnds[0] = instr->ctx.cmd.opcode; > + nfc_op->cle_ale_delay_ns = instr->delay_ns; > + break; > + > + case NAND_OP_ADDR_INSTR: > + offset = nand_subop_get_addr_start_off(subop, op_id); > + naddrs = nand_subop_get_num_addr_cyc(subop, op_id); > + addrs = &instr->ctx.addr.addrs[offset]; > + nfc_op->addrs = instr->ctx.addr.addrs[offset]; > + for (i = 0; i < min_t(unsigned int, 4, naddrs); i++) { > + nfc_op->addrs |= instr->ctx.addr.addrs[i] << > + (8 * i); > + } > + > + if (naddrs >= 5) > + nfc_op->addr5 = addrs[4]; > + if (naddrs >= 6) > + nfc_op->addr6 = addrs[5]; > + nfc_op->naddrs = nand_subop_get_num_addr_cyc(subop, > + op_id); > + nfc_op->cle_ale_delay_ns = instr->delay_ns; > + break; > + > + case NAND_OP_DATA_IN_INSTR: > + nfc_op->data_instr = instr; > + nfc_op->data_instr_idx = op_id; > + break; > + > + case NAND_OP_DATA_OUT_INSTR: > + nfc_op->data_instr = instr; > + nfc_op->data_instr_idx = op_id; > + break; > + > + case NAND_OP_WAITRDY_INSTR: > + nfc_op->rdy_timeout_ms = instr->ctx.waitrdy.timeout_ms; > + nfc_op->rdy_delay_ns = instr->delay_ns; > + break; > + } > + } > +} > + > +static void cond_delay(unsigned int ns) > +{ > + if (!ns) > + return; > + > + if (ns < 10000) > + ndelay(ns); > + else > + udelay(DIV_ROUND_UP(ns, 1000)); > +} > + > +/** > + * pl353_nand_exec_op_cmd - Send command to NAND device > + * @chip: Pointer to the NAND chip info structure > + * @subop: Pointer to array of instructions > + * Return: Always return zero > + */ > +static int pl353_nand_exec_op_cmd(struct nand_chip *chip, > + const struct nand_subop *subop) > +{ > + struct mtd_info *mtd = nand_to_mtd(chip); > + const struct nand_op_instr *instr; > + struct pl353_nfc_op nfc_op = {}; > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + unsigned long cmd_phase_data = 0, end_cmd_valid = 0; > + unsigned long cmd_phase_addr, data_phase_addr, end_cmd; > + unsigned int op_id, len, offset; > + bool reading; > + > + pl353_nfc_parse_instructions(chip, subop, &nfc_op); > + instr = nfc_op.data_instr; > + op_id = nfc_op.data_instr_idx; > + > + offset = nand_subop_get_data_start_off(subop, op_id); > + > + pl353_smc_clr_nand_int(); > + /* Get the command phase address */ > + if (nfc_op.cmnds[1] != 0) { > + if (nfc_op.cmnds[0] == NAND_CMD_SEQIN) > + end_cmd_valid = 0; > + else > + end_cmd_valid = 1; > + end_cmd = nfc_op.cmnds[1]; > + } else { > + end_cmd = 0x0; > + } > + > + /* > + * The SMC defines two phases of commands when transferring data to or > + * from NAND flash. > + * Command phase: Commands and optional address information are written > + * to the NAND flash.The command and address can be associated with > + * either a data phase operation to write to or read from the array, > + * or a status/ID register transfer. > + * Data phase: Data is either written to or read from the NAND flash. > + * This data can be either data transferred to or from the array, > + * or status/ID register information. > + */ > + cmd_phase_addr = (unsigned long __force)xnfc->regs + > + ((nfc_op.naddrs << ADDR_CYCLES_SHIFT) | > + (end_cmd_valid << END_CMD_VALID_SHIFT) | > + (COMMAND_PHASE) | > + (end_cmd << END_CMD_SHIFT) | > + (nfc_op.cmnds[0] << START_CMD_SHIFT)); > + > + /* Get the data phase address */ > + end_cmd_valid = 0; > + > + data_phase_addr = (unsigned long __force)xnfc->regs + > + ((0x0 << CLEAR_CS_SHIFT) | > + (end_cmd_valid << END_CMD_VALID_SHIFT) | > + (DATA_PHASE) | > + (end_cmd << END_CMD_SHIFT) | > + (0x0 << ECC_LAST_SHIFT)); > + xnfc->buf_addr = (void __iomem * __force)data_phase_addr; > + > + /* Command phase AXI Read & Write */ > + if (nfc_op.naddrs >= 5) { > + if (mtd->writesize > PL353_NAND_ECC_SIZE) { > + cmd_phase_data = nfc_op.addrs; > + /* Another address cycle for devices > 128MiB */ > + if (chip->options & NAND_ROW_ADDR_3) { > + writel_relaxed(cmd_phase_data, > + (void __iomem * __force) > + cmd_phase_addr); > + cmd_phase_data = nfc_op.addr5; > + if (nfc_op.naddrs >= 6) > + cmd_phase_data |= (nfc_op.addr6 << 8); > + } > + } > + } else { > + if (nfc_op.addrs != -1) { > + int column = nfc_op.addrs; > + /* > + * Change read/write column, read id etc > + * Adjust columns for 16 bit bus width > + */ > + if ((chip->options & NAND_BUSWIDTH_16) && > + (nfc_op.cmnds[0] == NAND_CMD_READ0 || > + nfc_op.cmnds[0] == NAND_CMD_SEQIN || > + nfc_op.cmnds[0] == NAND_CMD_RNDOUT || > + nfc_op.cmnds[0] == NAND_CMD_RNDIN)) { > + column >>= 1; > + } > + cmd_phase_data = column; > + } > + } > + writel_relaxed(cmd_phase_data, (void __iomem * __force)cmd_phase_addr); > + > + if (!nfc_op.data_instr) { > + if (nfc_op.rdy_timeout_ms) > + nand_wait_ready(chip); > + return 0; > + } > + > + reading = (nfc_op.data_instr->type == NAND_OP_DATA_IN_INSTR); > + if (!reading) { > + len = nand_subop_get_data_len(subop, op_id); > + pl353_nand_write_data_op(chip, instr->ctx.data.buf.out, > + len, instr->ctx.data.force_8bit); > + if (nfc_op.rdy_timeout_ms) > + nand_wait_ready(chip); > + cond_delay(nfc_op.rdy_delay_ns); > + } else ? > + if (reading) { > + len = nand_subop_get_data_len(subop, op_id); > + cond_delay(nfc_op.rdy_delay_ns); > + if (nfc_op.rdy_timeout_ms) > + nand_wait_ready(chip); > + pl353_nand_read_data_op(chip, instr->ctx.data.buf.in, len, > + instr->ctx.data.force_8bit); > + } > + > + return 0; > +} > + > +static const struct nand_op_parser pl353_nfc_op_parser = NAND_OP_PARSER > + (NAND_OP_PARSER_PATTERN > + (pl353_nand_exec_op_cmd, > + NAND_OP_PARSER_PAT_CMD_ELEM(true), > + NAND_OP_PARSER_PAT_ADDR_ELEM(true, 7), > + NAND_OP_PARSER_PAT_WAITRDY_ELEM(true), > + NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 2048)), > + NAND_OP_PARSER_PATTERN > + (pl353_nand_exec_op_cmd, > + NAND_OP_PARSER_PAT_CMD_ELEM(false), > + NAND_OP_PARSER_PAT_ADDR_ELEM(false, 7), > + NAND_OP_PARSER_PAT_CMD_ELEM(false), > + NAND_OP_PARSER_PAT_WAITRDY_ELEM(false), > + NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 2048)), > + NAND_OP_PARSER_PATTERN > + (pl353_nand_exec_op_cmd, > + NAND_OP_PARSER_PAT_CMD_ELEM(false), > + NAND_OP_PARSER_PAT_ADDR_ELEM(true, 7), > + NAND_OP_PARSER_PAT_CMD_ELEM(true), > + NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)), > + NAND_OP_PARSER_PATTERN > + (pl353_nand_exec_op_cmd, > + NAND_OP_PARSER_PAT_CMD_ELEM(false), > + NAND_OP_PARSER_PAT_ADDR_ELEM(false, 8), > + NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, 2048), > + NAND_OP_PARSER_PAT_CMD_ELEM(true), > + NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)), > + NAND_OP_PARSER_PATTERN > + (pl353_nand_exec_op_cmd, > + NAND_OP_PARSER_PAT_CMD_ELEM(false)), > + ); > + > +static int pl353_nfc_exec_op(struct nand_chip *chip, > + const struct nand_operation *op, > + bool check_only) > +{ > + return nand_op_parser_exec_op(chip, &pl353_nfc_op_parser, > + op, check_only); > +} > + > +/** > + * pl353_nand_device_ready - Check device ready/busy line > + * @mtd: Pointer to the mtd_info structure > + * > + * Return: 0 on busy or 1 on ready state > + */ > +static int pl353_nand_device_ready(struct nand_chip *chip) > +{ > + if (pl353_smc_get_nand_int_status_raw()) { > + pl353_smc_clr_nand_int(); > + return 1; > + } > + > + return 0; > +} > + > +/** > + * pl353_nand_ecc_init - Initialize the ecc information as per the ecc mode > + * @mtd: Pointer to the mtd_info structure > + * @ecc: Pointer to ECC control structure > + * @ecc_mode: ondie ecc status > + * > + * This function initializes the ecc block and functional pointers as per the > + * ecc mode > + * > + * Return: 0 on success or negative errno. > + */ > +static int pl353_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, > + int ecc_mode) > +{ > + struct nand_chip *chip = mtd_to_nand(mtd); > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + int err = 0; > + > + ecc->write_page_raw = pl353_nand_write_page_raw; > + ecc->read_page_raw = pl353_nand_read_page_raw; > + ecc->read_oob = pl353_nand_read_oob; > + ecc->write_oob = pl353_nand_write_oob; > + > + if (ecc_mode == NAND_ECC_ON_DIE) { > + pl353_smc_set_ecc_mode(PL353_SMC_ECCMODE_BYPASS); > + /* > + * On-Die ECC spare bytes offset 8 is used for ECC codes > + * Use the BBT pattern descriptors > + */ > + chip->bbt_td = &bbt_main_descr; > + chip->bbt_md = &bbt_mirror_descr; > + } else { > + ecc->mode = NAND_ECC_HW; > + /* Hardware ECC generates 3 bytes ECC code for each 512 bytes */ > + ecc->bytes = 3; > + ecc->strength = 1; > + ecc->calculate = pl353_nand_calculate_hwecc; > + ecc->correct = pl353_nand_correct_data; > + ecc->read_page = pl353_nand_read_page_hwecc; > + ecc->size = PL353_NAND_ECC_SIZE; > + ecc->read_page = pl353_nand_read_page_hwecc; > + ecc->write_page = pl353_nand_write_page_hwecc; > + pl353_smc_set_ecc_pg_size(mtd->writesize); > + switch (mtd->writesize) { > + case SZ_512: > + case SZ_1K: > + case SZ_2K: > + pl353_smc_set_ecc_mode(PL353_SMC_ECCMODE_APB); > + break; > + default: > + ecc->calculate = nand_calculate_ecc; > + ecc->correct = nand_correct_data; > + ecc->size = 256; > + break; > + } > + > + if (mtd->oobsize == 16) { > + mtd_set_ooblayout(mtd, &pl353_ecc_ooblayout16_ops); > + } else if (mtd->oobsize == 64) { > + mtd_set_ooblayout(mtd, &pl353_ecc_ooblayout64_ops); > + } else { > + err = -ENXIO; > + dev_err(xnfc->dev, "Unsupported oob Layout\n"); > + } > + } > + > + return err; > +} > + > +static int pl353_nfc_setup_data_interface(struct nand_chip *chip, int csline, > + const struct nand_data_interface > + *conf) > +{ > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + const struct nand_sdr_timings *sdr; > + u32 timings[7], mckperiodps; > + > + if (csline == NAND_DATA_IFACE_CHECK_ONLY) > + return 0; > + > + sdr = nand_get_sdr_timings(conf); > + if (IS_ERR(sdr)) > + return PTR_ERR(sdr); > + > + /* > + * SDR timings are given in pico-seconds while NFC timings must be > + * expressed in NAND controller clock cycles. > + */ > + mckperiodps = NSEC_PER_SEC / clk_get_rate(xnfc->mclk); > + mckperiodps *= 1000; > + if (sdr->tRC_min <= 20000) > + /* > + * PL353 SMC needs one extra read cycle in SDR Mode 5 > + * This is not written anywhere in the datasheet but > + * the results observed during testing. > + */ > + timings[0] = DIV_ROUND_UP(sdr->tRC_min, mckperiodps) + 1; > + else > + timings[0] = DIV_ROUND_UP(sdr->tRC_min, mckperiodps); > + > + timings[1] = DIV_ROUND_UP(sdr->tWC_min, mckperiodps); > + /* > + * For all SDR modes, PL353 SMC needs tREA max value as 1, > + * Results observed during testing. > + */ > + timings[2] = PL353_TREA_MAX_VALUE; > + timings[3] = DIV_ROUND_UP(sdr->tWP_min, mckperiodps); > + timings[4] = DIV_ROUND_UP(sdr->tCLR_min, mckperiodps); > + timings[5] = DIV_ROUND_UP(sdr->tAR_min, mckperiodps); > + timings[6] = DIV_ROUND_UP(sdr->tRR_min, mckperiodps); > + pl353_smc_set_cycles(timings); > + > + return 0; > +} > + > +static int pl353_nand_attach_chip(struct nand_chip *chip) > +{ > + struct mtd_info *mtd = nand_to_mtd(chip); > + struct pl353_nand_controller *xnfc = > + container_of(chip, struct pl353_nand_controller, chip); > + u32 ret; > + > + if (chip->options & NAND_BUSWIDTH_16) > + pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_16); > + > + if (mtd->writesize <= SZ_512) > + xnfc->addr_cycles = 1; > + else > + xnfc->addr_cycles = 2; > + > + if (chip->options & NAND_ROW_ADDR_3) > + xnfc->addr_cycles += 3; > + else > + xnfc->addr_cycles += 2; > + > + ret = pl353_nand_ecc_init(mtd, &chip->ecc, chip->ecc.mode); > + if (ret) { > + dev_err(xnfc->dev, "ECC init failed\n"); > + return ret; > + } > + > + if (!mtd->name) { > + /* > + * If the new bindings are used and the bootloader has not been > + * updated to pass a new mtdparts parameter on the cmdline, you > + * should define the following property in your NAND node, ie: > + * > + * label = "pl353-nand"; > + * > + * This way, mtd->name will be set by the core when > + * nand_set_flash_node() is called. > + */ > + mtd->name = devm_kasprintf(xnfc->dev, GFP_KERNEL, > + "%s", PL353_NAND_DRIVER_NAME); > + if (!mtd->name) { > + dev_err(xnfc->dev, "Failed to allocate mtd->name\n"); > + return -ENOMEM; > + } > + } > + > + return 0; > +} > + > +static const struct nand_controller_ops pl353_nand_controller_ops = { > + .attach_chip = pl353_nand_attach_chip, > + .exec_op = pl353_nfc_exec_op, > + .setup_data_interface = pl353_nfc_setup_data_interface, > +}; > + > +/** > + * pl353_nand_probe - Probe method for the NAND driver > + * @pdev: Pointer to the platform_device structure > + * > + * This function initializes the driver data structures and the hardware. > + * The NAND driver has dependency with the pl353_smc memory controller > + * driver for initializing the NAND timing parameters, bus width, ECC modes, > + * control and status information. > + * > + * Return: 0 on success or error value on failure > + */ > +static int pl353_nand_probe(struct platform_device *pdev) > +{ > + struct pl353_nand_controller *xnfc; > + struct mtd_info *mtd; > + struct nand_chip *chip; > + struct resource *res; > + struct device_node *np, *dn; > + u32 ret, val; > + > + xnfc = devm_kzalloc(&pdev->dev, sizeof(*xnfc), GFP_KERNEL); > + if (!xnfc) > + return -ENOMEM; > + xnfc->dev = &pdev->dev; > + > + nand_controller_init(&xnfc->controller); > + xnfc->controller.ops = &pl353_nand_controller_ops; > + /* Map physical address of NAND flash */ > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + xnfc->regs = devm_ioremap_resource(xnfc->dev, res); > + if (IS_ERR(xnfc->regs)) > + return PTR_ERR(xnfc->regs); > + > + chip = &xnfc->chip; > + chip->controller = &xnfc->controller; > + mtd = nand_to_mtd(chip); > + nand_set_controller_data(chip, xnfc); > + mtd->priv = chip; > + mtd->owner = THIS_MODULE; > + nand_set_flash_node(chip, xnfc->dev->of_node); > + > + /* Set the driver entry points for MTD */ > + chip->legacy.dev_ready = pl353_nand_device_ready; Please do not implement legacy interfaces. > + /* If we don't set this delay driver sets 20us by default */ > + np = of_get_next_parent(xnfc->dev->of_node); > + xnfc->mclk = of_clk_get(np, 0); > + if (IS_ERR(xnfc->mclk)) { > + dev_err(xnfc->dev, "Failed to retrieve MCK clk\n"); > + return PTR_ERR(xnfc->mclk); > + } > + > + dn = nand_get_flash_node(chip); > + > + /* Set the device option and flash width */ > + chip->options = NAND_BUSWIDTH_AUTO; > + chip->bbt_options = NAND_BBT_USE_FLASH; > + platform_set_drvdata(pdev, xnfc); > + ret = nand_scan(chip, 1); > + if (ret) { > + dev_err(xnfc->dev, "could not scan the nand chip\n"); > + return ret; > + } > + > + ret = mtd_device_register(mtd, NULL, 0); > + if (ret) { > + dev_err(xnfc->dev, "Failed to register mtd device: %d\n", ret); > + nand_cleanup(chip); > + return ret; > + } > + > + return 0; > +} > + > +/** > + * pl353_nand_remove - Remove method for the NAND driver > + * @pdev: Pointer to the platform_device structure > + * > + * This function is called if the driver module is being unloaded. It frees all > + * resources allocated to the device. > + * > + * Return: 0 on success or error value on failure > + */ > +static int pl353_nand_remove(struct platform_device *pdev) > +{ > + struct pl353_nand_controller *xnfc = platform_get_drvdata(pdev); > + struct mtd_info *mtd = nand_to_mtd(&xnfc->chip); > + struct nand_chip *chip = mtd_to_nand(mtd); > + > + /* Release resources, unregister device */ > + nand_release(chip); > + > + return 0; > +} > + > +/* Match table for device tree binding */ > +static const struct of_device_id pl353_nand_of_match[] = { > + { .compatible = "arm,pl353-nand-r2p1" }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, pl353_nand_of_match); > + > +/* > + * pl353_nand_driver - This structure defines the NAND subsystem platform driver > + */ > +static struct platform_driver pl353_nand_driver = { > + .probe = pl353_nand_probe, > + .remove = pl353_nand_remove, > + .driver = { > + .name = PL353_NAND_DRIVER_NAME, > + .of_match_table = pl353_nand_of_match, > + }, > +}; > + > +module_platform_driver(pl353_nand_driver); > + > +MODULE_AUTHOR("Xilinx, Inc."); > +MODULE_ALIAS("platform:" PL353_NAND_DRIVER_NAME); > +MODULE_DESCRIPTION("ARM PL353 NAND Flash Driver"); > +MODULE_LICENSE("GPL"); Thanks, Miquèl