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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 9D8ACC7115E for ; Thu, 29 Aug 2024 04:01:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3+wnTyWMMDMfT90IzhphOcToX+CkGP9O+bdljkkkDuU=; b=DS8QY6iPeupfh6 wKoaqTCC/MimJKbIVKx16qyZjCkj04ToVRHuz6BUGDTAEJ/jgnHMliwDGgc6ZO58qI81SPlp14rlV hMXlfV6f0pQfDIxDa5eYi3PoXFjfgNj2nlCegKdNpZj7lNnpl1PWGGPwEYNVmEGRzfAG6hWq8fG9S lFokVk/xl911KR/yTlsCdWigyZjNcKBFB/8TxUX/uZ85g9fdkeIAWR3FAHrjqVG5beZ1P5HDArqXU BET3L36cwWPgvkBAYVD0WT0bWdpOzCCVApUtSUUAOEO8suuEb7U/IaCtM2XAaZyFZuwicSZGBrhip nVkZMMI8T9ZRqX2rTukg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sjWLB-00000000Qwn-12B5; Thu, 29 Aug 2024 04:00:57 +0000 Received: from mail-ot1-x32a.google.com ([2607:f8b0:4864:20::32a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sjVLx-00000000Het-1GA9; Thu, 29 Aug 2024 02:57:45 +0000 Received: by mail-ot1-x32a.google.com with SMTP id 46e09a7af769-70c9cda7f1cso112292a34.3; Wed, 28 Aug 2024 19:57:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724900259; x=1725505059; darn=lists.infradead.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=mZDVsY0O6zp9Qo6VeUuJnL7Ovlzlihww3S82jvz9RFg=; b=kbc999EIE4uMxDVS5hYn5wF4f0ccaleecxwaCrMYg5aaz1f+NLMAonvGl2ZjcDg4Ml yG5A6/Z0yr/PU8bMTkzpTCskSwm38ep+e+3Al0MVBP6EXNAGxFO2iLkcL4InBjzW1wrW Y7HtTrOdiPmZXxabaDDSM3WhwrCBptQVMyGNwe2WVoWCdUuFcY6wiuW7U+inTG/Y3B2m RtLNadGoEGUJRz5xu9AhqpU6v8PkjGsiCb7vbKGJomOug3bX3IR8Y0nnBBzn9MHI6p7x Zu7jQ5aT6WKkMIeDhnAjlQg1O2wQ1uLUIFKTOhf8UICpSvq3zdDLnD7T7IHR9HGeKeIu O2vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724900259; x=1725505059; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mZDVsY0O6zp9Qo6VeUuJnL7Ovlzlihww3S82jvz9RFg=; b=vPP9D965dgXlM+Pchke/Lrfq7jBmLAfshT/oPYnBcq5ZZ+KFLtdiEq7ruBUk4ohjYS 5I+MXEDzsc9xlLjOy/U0q2tJ/EGPp4+5uev73E2lEbJOj/ExGGF/uDgYLcnB1gAZhbjH fPZm2m+rvU88MMcEdjTXYuMpQ6GLN2dRuGmjdgHxoyRG2efBFG0U/HJ5782Y6A9qqrMI As3L7a8xM4lUZEnbdAtT1whPn3sF4r3aXRPE8+Cd5pcAlTQYxSodqu9xAti6EbmS4R8Y n7l2sABtkRXYkEddyZ1FEWF+mZcUHSa8qdmzsd1Tsd3Lgb3wRMOHWKDaVhZRqWFRloQS RSKA== X-Forwarded-Encrypted: i=1; AJvYcCV3Jx1/BKCFm99fK7NfVzXL2krY6g2HFjl+dq7iCVmGh5Sg4mRw4Gia0Iuq2w4suEBpqGOq43qZkaZA@lists.infradead.org, AJvYcCViB88Gn7Bys/tmtgVCyLwCA5bRV0R9c8gpn2ZMed5Ggcj5J8Qvgsg8+nEdEjgROpjNiIR7X8b9Q4pvd5nm1UUp@lists.infradead.org X-Gm-Message-State: AOJu0YwinURbBHGobpZSAd1wX/UWDuyDZ9m5CuLIevaw+djAwYgjz4v5 yB1CNFUrR4eqj+IcB9CJOhPzIz774+ShLix+Ty2W8iezxBzwXntg X-Google-Smtp-Source: AGHT+IFHU3B8WAjDc87T+xrsXLLTlNpfYXNyC4HWjX90bS3/ufKoMRFpL+YMWDs5XdQMDHm6WyFstw== X-Received: by 2002:a05:6358:718e:b0:1b5:ec56:a10f with SMTP id e5c5f4694b2df-1b603c14b38mr215335555d.11.1724900259108; Wed, 28 Aug 2024 19:57:39 -0700 (PDT) Received: from [172.19.1.53] (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-715e569edc9sm172310b3a.138.2024.08.28.19.57.35 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 28 Aug 2024 19:57:38 -0700 (PDT) Message-ID: <0eb96a1e-da2b-45fb-9319-73b0b7cea564@gmail.com> Date: Thu, 29 Aug 2024 10:57:34 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3 2/2] mtd: rawnand: nuvoton: add new driver for the Nuvoton MA35 SoC To: Miquel Raynal Cc: richard@nod.at, vigneshr@ti.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, sumit.semwal@linaro.org, christian.koenig@amd.com, esben@geanix.com, linux-arm-kernel@lists.infradead.org, linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org References: <20240821071132.281018-1-hpchen0nvt@gmail.com> <20240821071132.281018-3-hpchen0nvt@gmail.com> <20240823190206.6cd76b43@xps-13> Content-Language: en-US From: Hui-Ping Chen In-Reply-To: <20240823190206.6cd76b43@xps-13> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240828_195741_407602_8E84C11F X-CRM114-Status: GOOD ( 38.70 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org RGVhciBNaXF1ZWwsCgpUaGFuayB5b3UgZm9yIHlvdXIgcmVwbHkuCgoKCk9uIDIwMjQvOC8yNCDk uIrljYggMDE6MDIsIE1pcXVlbCBSYXluYWwgd3JvdGU6Cj4gSGkgSHVpLVBpbmcsCj4KPiBocGNo ZW4wbnZ0QGdtYWlsLmNvbSB3cm90ZSBvbiBXZWQsIDIxIEF1ZyAyMDI0IDA3OjExOjMyICswMDAw Ogo+Cj4+IE51dm90b24gTUEzNSBTb0NzIE5BTkQgRmxhc2ggSW50ZXJmYWNlIENvbnRyb2xsZXIK Pj4gc3VwcG9ydHMgMktCLCA0S0IgYW5kIDhLQiBwYWdlIHNpemUsIGFuZCB1cCB0byA4LWJpdCwK PiBTdWZmaXggaXM6IGtpQgoKCk9rYXksIEkgd2lsbCBmaXggdGhhdC4KCgo+PiAxMi1iaXQsIGFu ZCAyNC1iaXQgaGFyZHdhcmUgRUNDIGNhbGN1bGF0aW9uIGNpcmN1aXQKPj4gdG8gcHJvdGVjdCBk YXRhIGNvbW11bmljYXRpb24uCj4gSXQncyBub3QgdGhlIGNvbW11bmljYXRpb24sIGl0J3MgdGhl IGRhdGEgaXRzZWxmLgoKCk9rYXksIEkgd2lsbCByZW1vdmUgdGhhdC4KCgo+PiBTaWduZWQtb2Zm LWJ5OiBIdWktUGluZyBDaGVuIDxocGNoZW4wbnZ0QGdtYWlsLmNvbT4KPj4gLS0tCj4+ICAgZHJp dmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZyAgICAgICAgICAgICAgIHwgICAgOCArCj4+ICAgZHJp dmVycy9tdGQvbmFuZC9yYXcvTWFrZWZpbGUgICAgICAgICAgICAgIHwgICAgMSArCj4+ICAgZHJp dmVycy9tdGQvbmFuZC9yYXcvbnV2b3Rvbl9tYTM1ZDFfbmFuZC5jIHwgMTA2OCArKysrKysrKysr KysrKysrKysrKwo+PiAgIDMgZmlsZXMgY2hhbmdlZCwgMTA3NyBpbnNlcnRpb25zKCspCj4+ICAg Y3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbXRkL25hbmQvcmF3L251dm90b25fbWEzNWQxX25h bmQuYwo+Pgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZyBiL2Ry aXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcKPj4gaW5kZXggNjE0MjU3MzA4NTE2Li45MzJiZjIy MTU0NzAgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZlcnMvbXRkL25hbmQvcmF3L0tjb25maWcKPj4gKysr IGIvZHJpdmVycy9tdGQvbmFuZC9yYXcvS2NvbmZpZwo+PiBAQCAtNDQ4LDYgKzQ0OCwxNCBAQCBj b25maWcgTVREX05BTkRfUkVORVNBUwo+PiAgIAkgIEVuYWJsZXMgc3VwcG9ydCBmb3IgdGhlIE5B TkQgY29udHJvbGxlciBmb3VuZCBvbiBSZW5lc2FzIFItQ2FyCj4+ICAgCSAgR2VuMyBhbmQgUlov TjEgU29DIGZhbWlsaWVzLgo+PiAgIAo+PiArY29uZmlnIE1URF9OQU5EX05WVF9NQTM1Cj4gSXMg TlZUIHNvIGNvbW1vbiBvciBpcyBpdCBqdXN0IG9uZSBvcHBvcnR1bml0eSB0byBzYXZlIDQgY2hh cnMgaW4gYQo+IEtjb25maWcgZmlsZT8/IEknZCBwcmVmZXIgc29tZXRoaW5nIG1vcmUgZWFzeSB0 byB1bmRlcnN0YW5kLgoKCkkgd2lsbCBjaGFuZ2UgaXQgdG8gTVREX05BTkRfTlVWT1RPTl9NQTM1 LgoKCj4+ICsJdHJpc3RhdGUgIk51dm90b24gTUEzNSBTb0MgTkFORCBjb250cm9sbGVyIgo+PiAr CWRlcGVuZHMgb24gQVJDSF9NQTM1IHx8IENPTVBJTEVfVEVTVAo+PiArCWRlcGVuZHMgb24gT0YK Pj4gKwloZWxwCj4+ICsJICBFbmFibGVzIHN1cHBvcnQgZm9yIHRoZSBOQU5EIGNvbnRyb2xsZXIg Zm91bmQgb24KPj4gKwkgIHRoZSBOdXZvdG9uIE1BMzUgc2VyaWVzIFNvQ3MuCj4+ICsKPj4gICBj b21tZW50ICJNaXNjIgo+PiAgIAo+PiAgIGNvbmZpZyBNVERfU01fQ09NTU9OCj4+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZSBiL2RyaXZlcnMvbXRkL25hbmQvcmF3 L01ha2VmaWxlCj4+IGluZGV4IDI1MTIwYTRhZmFkYS4uY2RmZGZlZTNmNWYzIDEwMDY0NAo+PiAt LS0gYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9NYWtlZmlsZQo+PiArKysgYi9kcml2ZXJzL210ZC9u YW5kL3Jhdy9NYWtlZmlsZQo+PiBAQCAtNTcsNiArNTcsNyBAQCBvYmotJChDT05GSUdfTVREX05B TkRfSU5URUxfTEdNKQkrPSBpbnRlbC1uYW5kLWNvbnRyb2xsZXIubwo+PiAgIG9iai0kKENPTkZJ R19NVERfTkFORF9ST0NLQ0hJUCkJCSs9IHJvY2tjaGlwLW5hbmQtY29udHJvbGxlci5vCj4+ICAg b2JqLSQoQ09ORklHX01URF9OQU5EX1BMMzVYKQkJKz0gcGwzNXgtbmFuZC1jb250cm9sbGVyLm8K Pj4gICBvYmotJChDT05GSUdfTVREX05BTkRfUkVORVNBUykJCSs9IHJlbmVzYXMtbmFuZC1jb250 cm9sbGVyLm8KPj4gK29iai0kKENPTkZJR19NVERfTkFORF9OVlRfTUEzNSkJKz0gbnV2b3Rvbl9t YTM1ZDFfbmFuZC5vCj4+ICAgCj4+ICAgbmFuZC1vYmpzIDo9IG5hbmRfYmFzZS5vIG5hbmRfbGVn YWN5Lm8gbmFuZF9iYnQubyBuYW5kX3RpbWluZ3MubyBuYW5kX2lkcy5vCj4+ICAgbmFuZC1vYmpz ICs9IG5hbmRfb25maS5vCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL210ZC9uYW5kL3Jhdy9udXZv dG9uX21hMzVkMV9uYW5kLmMgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9udXZvdG9uX21hMzVkMV9u YW5kLmMKPj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi5iNDU4 NmQ3YTdhNDUKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL210ZC9uYW5kL3Jhdy9u dXZvdG9uX21hMzVkMV9uYW5kLmMKPj4gQEAgLTAsMCArMSwxMDY4IEBACj4+ICsvLyBTUERYLUxp Y2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+PiArLyoKPj4gKyAqIENvcHlyaWdodCAoQykgMjAy NCBOdXZvdG9uIFRlY2hub2xvZ3kgQ29ycC4KPj4gKyAqLwo+PiArI2luY2x1ZGUgPGxpbnV4L3Ns YWIuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pbml0Lmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbW9k dWxlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+Cj4+ICsjaW5jbHVkZSA8bGlu dXgvaW8uaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPj4gKyNpbmNs dWRlIDxsaW51eC9kZWxheS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+PiArI2luY2x1 ZGUgPGxpbnV4L2Vyci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4+ICsKPiBOb3Qgc3Vy ZSB3aHkgeW91IGRpZG4ndCBzb3J0IHRoZSBiZWxvdyBpbmNsdWRlcyB3aXRoIHRoZSBvbmVzIGFi b3ZlPwoKCkkgd2lsbCBzb3J0IGl0LgoKCj4+ICsjaW5jbHVkZSA8bGludXgvbXRkL210ZC5oPgo+ PiArI2luY2x1ZGUgPGxpbnV4L210ZC9wYXJ0aXRpb25zLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgv bXRkL3Jhd25hbmQuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9kbWEtbWFwcGluZy5oPgo+PiArI2lu Y2x1ZGUgPGxpbnV4L2RtYWVuZ2luZS5oPgo+PiArCj4+ICsvKiBORkkgRE1BIFJlZ2lzdGVycyAq Lwo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfQlVGRkVSMAkJKDB4MDAwKQo+IFlvdSBkb24ndCBu ZWVkIGFsbCB0aGVzZSBwYXJlbnRoZXNlcwoKCk9rYXksIEkgd2lsbCByZW1vdmUgaXQuCgoKPj4g KyNkZWZpbmUgTUEzNV9ORklfUkVHX0RNQUNUTAkJKDB4NDAwKQo+PiArI2RlZmluZSAgIERNQV9F TgkJCQlCSVQoMCkKPj4gKyNkZWZpbmUgICBETUFfUlNUCQkJCUJJVCgxKQo+PiArI2RlZmluZSAg IERNQV9CVVNZCQkJCUJJVCg5KQo+PiArCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19ETUFTQQkJ KDB4NDA4KQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfRE1BQkNOVAkJKDB4NDBDKQo+PiArI2Rl ZmluZSBNQTM1X05GSV9SRUdfRE1BSU5URU4JCSgweDQxMCkKPj4gKyNkZWZpbmUgTUEzNV9ORklf UkVHX0RNQUlOVFNUUwkoMHg0MTQpCj4+ICsKPj4gKy8qIE5GSSBHbG9iYWwgUmVnaXN0ZXJzICov Cj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19HQ1RMCQkoMHg4MDApCj4+ICsjZGVmaW5lICAgTkFO RF9FTgkJCQlCSVQoMykKPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX0dJTlRFTgkJKDB4ODA0KQo+ PiArI2RlZmluZSBNQTM1X05GSV9SRUdfR0lOVFNUUwkJKDB4ODA4KQo+PiArCj4+ICsvKiBOQU5E LXR5cGUgRmxhc2ggUmVnaXN0ZXJzICovCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5EQ1RM CQkoMHg4QTApCj4+ICsjZGVmaW5lICAgU1dSU1QJCQkJQklUKDApCj4+ICsjZGVmaW5lICAgRE1B X1dfRU4JCQkJQklUKDEpCj4+ICsjZGVmaW5lICAgRE1BX1JfRU4JCQkJQklUKDIpCj4+ICsjZGVm aW5lICAgRUNDX0NISwkJCQlCSVQoNykKPj4gKyNkZWZpbmUgICBQUk9UM0JFTgkJCQlCSVQoOCkK Pj4gKyNkZWZpbmUgICBQU0laRV8ySwkJCQkoMSA8PCAxNikKPj4gKyNkZWZpbmUgICBQU0laRV80 SwkJCQkoMiA8PCAxNikKPj4gKyNkZWZpbmUgICBQU0laRV84SwkJCQkoMyA8PCAxNikKPj4gKyNk ZWZpbmUgICBQU0laRV9NQVNLCQkJCSgzIDw8IDE2KQo+PiArI2RlZmluZSAgIEJDSF9UMjQJCQkJ QklUKDE4KQo+PiArI2RlZmluZSAgIEJDSF9UOAkJCQlCSVQoMjApCj4+ICsjZGVmaW5lICAgQkNI X1QxMgkJCQlCSVQoMjEpCj4+ICsjZGVmaW5lICAgQkNIX05PTkUJCQkJKDB4MCkKPj4gKyNkZWZp bmUgICBCQ0hfTUFTSwkJCQkoMHgxZiA8PCAxOCkKPj4gKyNkZWZpbmUgICBFQ0NfRU4JCQkJQklU KDIzKQo+PiArI2RlZmluZSAgIERJU0FCTEVfQ1MwCQkJCUJJVCgyNSkKPj4gKwo+PiArI2RlZmlu ZSBNQTM1X05GSV9SRUdfTkFORFRNQ1RMCSgweDhBNCkKPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVH X05BTkRJTlRFTgkoMHg4QTgpCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5ESU5UU1RTCSgw eDhBQykKPj4gKyNkZWZpbmUgICBJTlRfRE1BCQkJCUJJVCgwKQo+PiArI2RlZmluZSAgIElOVF9F Q0MJCQkJQklUKDIpCj4+ICsjZGVmaW5lICAgSU5UX1JCMAkJCQlCSVQoMTApCj4+ICsjZGVmaW5l ICAgSU5UX1JCMF9TVFMJCQkJQklUKDE4KQo+PiArCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19O QU5EQ01ECQkoMHg4QjApCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5EQUREUgkJKDB4OEI0 KQo+PiArI2RlZmluZSAgIEVOREFERFIJCQkJQklUKDMxKQo+PiArCj4+ICsjZGVmaW5lIE1BMzVf TkZJX1JFR19OQU5EREFUQQkJKDB4OEI4KQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFORFJB Q1RMCSgweDhCQykKPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX05BTkRFQ1RMCQkoMHg4QzApCj4+ ICsjZGVmaW5lICAgRU5BQkxFX1dQCQkJCSgweDApCj4+ICsjZGVmaW5lICAgRElTQUJMRV9XUAkJ CQlCSVQoMCkKPj4gKwo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFOREVDQ0VTMAkoMHg4RDAp Cj4+ICsjZGVmaW5lICAgRUNDX1NUQVRVU19NQVNLCQkJKDB4MykKPj4gKyNkZWZpbmUgICBFQ0Nf RVJSX0NOVF9NQVNLCQkJKDB4MWYpCj4+ICsKPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX05BTkRF Q0NFUzEJKDB4OEQ0KQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFOREVDQ0VTMgkoMHg4RDgp Cj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5ERUNDRVMzCSgweDhEQykKPj4gKwo+PiArLyog TkFORC10eXBlIEZsYXNoIEJDSCBFcnJvciBBZGRyZXNzIFJlZ2lzdGVycyAqLwo+PiArI2RlZmlu ZSBNQTM1X05GSV9SRUdfTkFOREVDQ0VBMAkoMHg5MDApCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JF R19OQU5ERUNDRUExCSgweDkwNCkKPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX05BTkRFQ0NFQTIJ KDB4OTA4KQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFOREVDQ0VBMwkoMHg5MEMpCj4+ICsj ZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5ERUNDRUE0CSgweDkxMCkKPj4gKyNkZWZpbmUgTUEzNV9O RklfUkVHX05BTkRFQ0NFQTUJKDB4OTE0KQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFOREVD Q0VBNgkoMHg5MTgpCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5ERUNDRUE3CSgweDkxQykK Pj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX05BTkRFQ0NFQTgJKDB4OTIwKQo+PiArI2RlZmluZSBN QTM1X05GSV9SRUdfTkFOREVDQ0VBOQkoMHg5MjQpCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19O QU5ERUNDRUExMAkoMHg5MjgpCj4+ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5ERUNDRUExMQko MHg5MkMpCj4+ICsKPj4gKy8qIE5BTkQtdHlwZSBGbGFzaCBCQ0ggRXJyb3IgRGF0YSBSZWdpc3Rl cnMgKi8KPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX05BTkRFQ0NFRDAJKDB4OTYwKQo+PiArI2Rl ZmluZSBNQTM1X05GSV9SRUdfTkFOREVDQ0VEMQkoMHg5NjQpCj4+ICsjZGVmaW5lIE1BMzVfTkZJ X1JFR19OQU5ERUNDRUQyCSgweDk2OCkKPj4gKyNkZWZpbmUgTUEzNV9ORklfUkVHX05BTkRFQ0NF RDMJKDB4OTZDKQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFOREVDQ0VENAkoMHg5NzApCj4+ ICsjZGVmaW5lIE1BMzVfTkZJX1JFR19OQU5ERUNDRUQ1CSgweDk3NCkKPj4gKwo+PiArLyogTkFO RC10eXBlIEZsYXNoIFJlZHVuZGFudCBBcmVhIFJlZ2lzdGVycyAqLwo+PiArI2RlZmluZSBNQTM1 X05GSV9SRUdfTkFORFJBMAkJKDB4QTAwKQo+PiArI2RlZmluZSBNQTM1X05GSV9SRUdfTkFORFJB MQkJKDB4QTA0KQo+PiArCj4+ICsjZGVmaW5lIFNLSVBfU1BBUkVfQllURVMJNAo+PiArCj4+ICsv KiBCQ0ggYWxnb3JpdGhtIHJlbGF0ZWQgY29uc3RhbnRzIGFuZCB2YXJpYWJsZXMgKi8KPj4gK3N0 YXRpYyBjb25zdCBpbnQgbWEzNV9wYXJpdHlbM11bNF0gPSB7Cj4+ICsJezAsICA2MCwgIDkyLCAg OTB9LCAgLyogZm9yIDJLICovCj4+ICsJezAsIDEyMCwgMTg0LCAxODB9LCAgLyogZm9yIDRLICov Cj4+ICsJezAsIDI0MCwgMzY4LCAzNjB9LCAgLyogZm9yIDhLICovCj4gQ2FuIHlvdSBwbGVhc2Ug Y3JlYXRlIGRlZmluaXRpb25zIGZvciB0aGUgbWF0cml4IHJvd3M/ICh1c2luZwo+IGFuIGVudW0g c2VlbXMgYXBwcm9wcmlhdGUpCj4KPiBBbmQgbWF5YmUgYW4gYXJyYXkgb2YgdGhyZWUgc3RydWN0 dXJlcyB3b3VsZCBiZSBiZXN0IGJlY2F1c2UgSSBiZWxpZXZlCj4geW91J3JlIGRlZmluaW5nIG9m ZnNldHMgZm9yIHNvbWV0aGluZyB3aGljaCBpcyBub3QgY2xlYXIgdG8gdGhlIHJlYWRlci4KCgpJ IHdpbGwgdXNlIHRoZSBlbnVtIGFuZCBzcGxpdCBpdCBpbnRvIHRocmVlIHN0cnVjdHVyZXMuCgoK Pj4gK307Cj4+ICsKPj4gK3N0cnVjdCBtYTM1X25hbmRfaW5mbyB7Cj4+ICsJc3RydWN0IG5hbmRf Y29udHJvbGxlciBjb250cm9sbGVyOwo+PiArCXN0cnVjdCBkZXZpY2UgKmRldjsKPj4gKwl2b2lk IF9faW9tZW0gKnJlZ3M7Cj4+ICsJaW50IGlycTsKPj4gKwlzdHJ1Y3QgY2xrICpjbGs7Cj4+ICsJ c3RydWN0IGNvbXBsZXRpb24gY29tcGxldGU7Cj4+ICsKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gbXRk Owo+IFBsZWFzZSBoYXZlIGEgbG9vayBhdCBuYW5kX3RvX210ZCgpCgoKSSB3aWxsIHJlbW92ZSBp dC4KCgo+PiArCXN0cnVjdCBuYW5kX2NoaXAgY2hpcDsKPiBJcyB0aGVyZSBhIHNpbmdsZSBDUyBz dXBwb3J0ZWQ/IElzIHRoZXJlIGEgc2luZ2xlIFJCIHN1cHBvcnRlZD8KCgpZZXMsIHNpbmdsZSBD UyBhbmQgUkIuCgpJIHdpbGwgcmVtb3ZlIGl0LgoKCj4+ICsJc3RydWN0IG10ZF9wYXJ0aXRpb24g KnBhcnRzOwo+IE5vLCB0aGlzIGhhcyBub3RoaW5nIHRvIGRvIGhlcmUuCgoKSSB3aWxsIHJlbW92 ZSBpdC4KCgo+PiArCXN0cnVjdCBuYW5kX2VjY2xheW91dF91c2VyIG5hbmRfb29iOwo+IERlcHJl Y2F0ZWQgc3RydWN0dXJlCgoKSSB3aWxsIHJlbW92ZSBpdC4KCkkgd2lsbCByZWZlciB0byB0aGUg YXBwcm9hY2ggdXNlZCBpbiB0aGUgbmV3IGRyaXZlci4KCgo+PiArCWludCBucl9wYXJ0czsKPj4g Kwo+PiArCXUzMiBiY2g7Cj4+ICsJdTggKmRtYV9idWY7Cj4+ICsJc3BpbmxvY2tfdCBkbWFfbG9j azsKPj4gKwlkbWFfYWRkcl90IGRtYV9hZGRyOwo+PiArfTsKPj4gKwo+PiArc3RhdGljIGludCBt YTM1X29vYmxheW91dF9lY2Moc3RydWN0IG10ZF9pbmZvICptdGQsIGludCBzZWN0aW9uLAo+PiAr CQkJICAgICAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2JyZWdpb24pCj4+ICt7Cj4+ICsJc3Ry dWN0IG5hbmRfY2hpcCAqY2hpcCA9IG10ZF90b19uYW5kKG10ZCk7Cj4+ICsKPj4gKwlpZiAoc2Vj dGlvbikKPj4gKwkJcmV0dXJuIC1FUkFOR0U7Cj4+ICsKPj4gKwlvb2JyZWdpb24tPmxlbmd0aCA9 IGNoaXAtPmVjYy50b3RhbDsKPj4gKwlvb2JyZWdpb24tPm9mZnNldCA9IG10ZC0+b29ic2l6ZSAt IG9vYnJlZ2lvbi0+bGVuZ3RoOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0 YXRpYyBpbnQgbWEzNV9vb2JsYXlvdXRfZnJlZShzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgaW50IHNl Y3Rpb24sCj4+ICsJCQkgICAgICAgc3RydWN0IG10ZF9vb2JfcmVnaW9uICpvb2JyZWdpb24pCj4+ ICt7Cj4+ICsJc3RydWN0IG5hbmRfY2hpcCAqY2hpcCA9IG10ZF90b19uYW5kKG10ZCk7Cj4+ICsK Pj4gKwlpZiAoc2VjdGlvbikKPj4gKwkJcmV0dXJuIC1FUkFOR0U7Cj4+ICsKPj4gKwlvb2JyZWdp b24tPmxlbmd0aCA9IG10ZC0+b29ic2l6ZSAtIGNoaXAtPmVjYy50b3RhbCAtIDI7Cj4+ICsJb29i cmVnaW9uLT5vZmZzZXQgPSAyOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0 YXRpYyBjb25zdCBzdHJ1Y3QgbXRkX29vYmxheW91dF9vcHMgbWEzNV9vb2JsYXlvdXRfb3BzID0g ewo+PiArCS5mcmVlID0gbWEzNV9vb2JsYXlvdXRfZnJlZSwKPj4gKwkuZWNjID0gbWEzNV9vb2Js YXlvdXRfZWNjLAo+PiArfTsKPj4gKwo+PiArLyoKPj4gKyAqIEluaXRpYWxpemUgaGFyZHdhcmUg RUNDCj4+ICsgKi8KPj4gK3N0YXRpYyB2b2lkIG1hMzVfbmFuZF9od2VjY19pbml0KHN0cnVjdCBt YTM1X25hbmRfaW5mbyAqbmFuZCkKPj4gK3sKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5h bmRfdG9fbXRkKCZuYW5kLT5jaGlwKTsKPj4gKwo+PiArCS8qIHJlc2V0IG5hbmQgY29udHJvbGxl ciAqLwo+IAkgICBSZXNldCBOQU5ECgoKVGhpcyByZXNldHMgdGhlIGludGVybmFsIHN0YXRlIG1h Y2hpbmUgYW5kIGNvdW50ZXJzLgoKCj4+ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1 X05GSV9SRUdfTkFORENUTCkgfCBTV1JTVCwKPj4gKwkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JF R19OQU5EQ1RMKTsKPiBJIGJlbGlldmUgaXQncyBmaW5lIHRvIGRvIGl0IG9uIHNldmVyYWwgbGlu ZXMgYW5kIHByb2JhYmx5IGNsZWFyZXIuCj4KPiAJdTMyIHJlZyA9IHJlYWRsKCk7Cj4gCXJlZyB8 PSBTT01FVEhJTkc7Cj4gCXdyaXRlbCgpOwo+Cj4gTm8gd2FpdCBhZnRlciB0aGUgcmVzZXQ/CgoK SSB3aWxsIHJld3JpdGUgdGhpcyBjb2RlLiBBbHNvIGFkZCB3YWl0aW5nLgoKCj4+ICsJLyogUmVk dW5kYW50IGFyZWEgc2l6ZSAqLwo+PiArCXdyaXRlbChtdGQtPm9vYnNpemUsIG5hbmQtPnJlZ3Mg KyBNQTM1X05GSV9SRUdfTkFORFJBQ1RMKTsKPj4gKwo+PiArCS8qIFByb3RlY3QgcmVkdW5kYW50 IDMgYnl0ZXMgKi8KPiBXaGF0IGRvZXMgdGhhdCBtZWFuPwoKClRoZSBNQTM1IE5GSSBzdXBwb3J0 cyBhIHNwYXJlIGFyZWEgd2hlcmUgdGhlIGZpcnN0IDMgYnl0ZXMgYXJlIHByb3RlY3RlZCAKYnkg dGhlIEVDQyBhbGdvcml0aG0uCgpJbiBvdGhlciB3b3JkcywgRUNDIHdpbGwgY2FsY3VsYXRlIHRo ZSBlcnJvciBjb3JyZWN0aW9uIGNvZGUgZm9yIHRoZSAKZGF0YSBwbHVzCgp0aGUgZmlyc3QgMyBi eXRlcyBvZiBvdXQtb2YtYmFuZCAoT09CKSBkYXRhLCBpZiB0aGlzIGZlYXR1cmUgaXMgZW5hYmxl ZC4KCgo+PiArCXdyaXRlbChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwp IHwgUFJPVDNCRU4sCj4+ICsJCW5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCk7Cj4+ ICsKPj4gKwkvKiBXcml0ZSB0aGUgRUNDIHBhcml0eSBjb2RlcyBhdXRvbWF0aWNhbGx5IHRvIE5B TkQgRmxhc2ggKi8KPj4gKwl3cml0ZWwocmVhZGwobmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19O QU5EQ1RMKSB8IEVDQ19DSEssCj4+ICsJCW5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENU TCk7Cj4gTm8sIGJ5IGRlZmF1bHQgeW91IHNob3VsZCBkaXNhYmxlZCB0aGUgRUNDIGVuZ2luZS4g VGhlbiB3aGVuIHlvdSBuZWVkCj4gaXQgeW91IGVuYWJsZS91c2UvZGlzYWJsZSBpdC4KCgpPa2F5 LiBCeSBkZWZhdWx0LCB0aGUgRUNDIGVuZ2luZSB3aWxsIGJlIGRpc2FibGVkLgoKCj4+ICsKPj4g KwlpZiAobmFuZC0+YmNoID09IEJDSF9OT05FKSB7Cj4+ICsJCS8qIERpc2FibGUgSC9XIEVDQywg RUNDIHBhcml0eSBjaGVjayBlbmFibGUgYml0IGR1cmluZyByZWFkIHBhZ2UgKi8KPj4gKwkJd3Jp dGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCkgJiAofkVDQ19FTiks Cj4+ICsJCQluYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpOwo+PiArCX0gZWxzZSB7 Cj4+ICsJCS8qIFNldCBCQ0ggYWxnb3JpdGhtICovCj4+ICsJCXdyaXRlbCgocmVhZGwobmFuZC0+ cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKSAmICh+QkNIX01BU0spKSB8Cj4+ICsJCQluYW5k LT5iY2gsIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCk7Cj4+ICsKPj4gKwkJLyog RW5hYmxlIEgvVyBFQ0MsIEVDQyBwYXJpdHkgY2hlY2sgZW5hYmxlIGJpdCBkdXJpbmcgcmVhZCBw YWdlICovCj4+ICsJCXdyaXRlbChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRD VEwpIHwgRUNDX0VOLAo+PiArCQkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsK Pj4gKwl9Cj4+ICsJc3Bpbl9sb2NrX2luaXQoJm5hbmQtPmRtYV9sb2NrKTsKPj4gK30KPj4gKwo+ PiArc3RhdGljIHZvaWQgbWEzNV9uYW5kX2luaXRpYWxpemUoc3RydWN0IG1hMzVfbmFuZF9pbmZv ICpuYW5kKQo+PiArewo+PiArCXdyaXRlbChOQU5EX0VOLCBuYW5kLT5yZWdzICsgTUEzNV9ORklf UkVHX0dDVEwpOwo+PiArfQo+PiArCj4+ICsKPj4gKy8qIERlZmluZSBzb21lIGNvbnN0YW50cyBm b3IgQkNIICovCj4gCQkJZm9yIHRoZSBCQ0ggaGFyZHdhcmUgRUNDIGVuZ2luZQoKCkkgd2lsbCBj b3JyZWN0IHRoaXMgY29tbWVudC4KCgo+PiArLyogZGVmaW5lIHRoZSB0b3RhbCBwYWRkaW5nIGJ5 dGVzIGZvciA1MTIvMTAyNCBkYXRhIHNlZ21lbnQgKi8KPj4gKyNkZWZpbmUgQkNIX1BBRERJTkdf TEVOXzUxMgkzMgo+PiArI2RlZmluZSBCQ0hfUEFERElOR19MRU5fMTAyNAk2NAo+PiArLyogZGVm aW5lIHRoZSBCQ0ggcGFyaXR5IGNvZGUgbGVuZ3RoIGZvciA1MTIgYnl0ZXMgZGF0YSBwYXR0ZXJu ICovCj4+ICsjZGVmaW5lIEJDSF9QQVJJVFlfTEVOX1Q4CTE1Cj4+ICsjZGVmaW5lIEJDSF9QQVJJ VFlfTEVOX1QxMgkyMwo+PiArLyogZGVmaW5lIHRoZSBCQ0ggcGFyaXR5IGNvZGUgbGVuZ3RoIGZv ciAxMDI0IGJ5dGVzIGRhdGEgcGF0dGVybiAqLwo+PiArI2RlZmluZSBCQ0hfUEFSSVRZX0xFTl9U MjQJNDUKPj4gKwo+IElzIFQgdGhlIHN0cmVuZ3RoPyBDYW4gd2UgbmFtZSBpdCBzdHJlbmd0aCBp bnN0ZWFkPwo+Cj4gUGxlYXNlIG1vdmUgdGhlIGRlZmluaXRpb25zIGF0IHRoZSB0b3AKCgpUIGlz IHRoZSBzdHJlbmd0aC4KCkkgd2lsbCBtb2RpZnkgdGhpcyBuYW1lIGFuZCBtb3ZlIGl0IHRvIHRo ZSB0b3AuCgoKPj4gKy8qIENvcnJlY3QgZGF0YSBieSBCQ0ggYWxyb2dpdGhtICovCj4+ICtzdGF0 aWMgdm9pZCBtYTM1X25maV9jb3JyZWN0ZGF0YShzdHJ1Y3QgbWEzNV9uYW5kX2luZm8gKm5hbmQs IHU4IGluZGV4LAo+PiArCQkJCSB1OCBlcnJfY250LCB1OCAqYWRkcikKPiBjb3JyZWN0ZGF0YSB2 cyBjb3JyZWN0LCB0aGUgbmFtaW5nIG5lZWRzIHRvIGJlIGltcHJvdmVkCgoKSSB3aWxsIG1vZGlm eSB0aGUgbmFtaW5nLgoKCj4+ICt7Cj4+ICsJdTggKnB0ciA9ICh1OCAqKSgobG9uZyluYW5kLT5y ZWdzICsgTUEzNV9ORklfUkVHX05BTkRSQTApOwo+IEhhaGEsIG5vLCBuZXZlci4KPgo+IFBsZWFz ZSBjb21waWxlIHdpdGggQz0xIGFuZCBzZWUgaG93IHRoaXMgZXhwbG9kZXMuCj4KPiBBbHNvLCB5 b3UgY2FuIGVuYWJsZSBXPTEKCgpJIHdpbGwgdHJ5IGNvbXBpbGluZyB3aXRoIEM9MXx8YW5kIFc9 MSBhZ2Fpbi4KCgo+PiArCXUzMiBmaWVsZF9sZW4sIHBhZGRpbmdfbGVuLCBwYXJpdHlfbGVuOwo+ PiArCXUzMiB0ZW1wX2RhdGFbMjRdLCB0ZW1wX2FkZHJbMjRdOwo+PiArCXUzMiB0b3RhbF9maWVs ZF9udW0sIHBhZ2U7Cj4+ICsJdTMyIGVycl9kYXRhWzZdOwo+PiArCXU4ICAqc21yYV9pbmRleDsK Pj4gKwl1OCAgaSwgajsKPj4gKwo+PiArCS8qIGFzc2lnbiBwYXJhbWV0ZXJzIGZvciBkaWZmZXJl bnQgQkNIIGFuZCBwYWdlIHNpemUgKi8KPiAJCQkJCSAgIGNvbmZpZ3VyYXRpb25zCgoKSSB3aWxs IGNvcnJlY3QgdGhpcyBjb21tZW50LgoKCj4+ICsJc3dpdGNoIChyZWFkbChuYW5kLT5yZWdzICsg TUEzNV9ORklfUkVHX05BTkRDVEwpICYgQkNIX01BU0spIHsKPj4gKwljYXNlIEJDSF9UMjQ6Cj4+ ICsJCWZpZWxkX2xlbiA9IDEwMjQ7Cj4+ICsJCXBhcml0eV9sZW4gPSBCQ0hfUEFSSVRZX0xFTl9U MjQ7Cj4+ICsJCXBhZGRpbmdfbGVuID0gQkNIX1BBRERJTkdfTEVOXzEwMjQ7Cj4+ICsJCWJyZWFr Owo+PiArCWNhc2UgQkNIX1QxMjoKPj4gKwkJZmllbGRfbGVuID0gNTEyOwo+PiArCQlwYXJpdHlf bGVuID0gQkNIX1BBUklUWV9MRU5fVDEyOwo+PiArCQlwYWRkaW5nX2xlbiA9IEJDSF9QQURESU5H X0xFTl81MTI7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgQkNIX1Q4Ogo+PiArCQlmaWVsZF9sZW4g PSA1MTI7Cj4+ICsJCXBhcml0eV9sZW4gPSBCQ0hfUEFSSVRZX0xFTl9UODsKPj4gKwkJcGFkZGlu Z19sZW4gPSBCQ0hfUEFERElOR19MRU5fNTEyOwo+PiArCQlicmVhazsKPj4gKwlkZWZhdWx0Ogo+ PiArCQlwcl93YXJuKCJOQU5EIEVSUk9SOiBpbnZhbGlkIFNNQ1JfQkNIX1RTRUwgPSAweCUwOFhc biIsCj4+ICsJCQkodTMyKShyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwp ICYgQkNIX01BU0spKTsKPj4gKwkJcmV0dXJuOwo+PiArCX0KPj4gKwo+PiArCXBhZ2UgPSByZWFk bChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpICYgUFNJWkVfTUFTSzsKPj4gKwlz d2l0Y2ggKHBhZ2UpIHsKPj4gKwljYXNlIFBTSVpFXzhLOgo+PiArCQl0b3RhbF9maWVsZF9udW0g PSA4MTkyIC8gZmllbGRfbGVuOyBicmVhazsKPj4gKwljYXNlIFBTSVpFXzRLOgo+PiArCQl0b3Rh bF9maWVsZF9udW0gPSA0MDk2IC8gZmllbGRfbGVuOyBicmVhazsKPj4gKwljYXNlIFBTSVpFXzJL Ogo+PiArCQl0b3RhbF9maWVsZF9udW0gPSAyMDQ4IC8gZmllbGRfbGVuOyBicmVhazsKPiBCcmVh ayBvbiBhIG5ldyBsaW5lCgoKT2theSwgSSB3aWxsIGZpeCBpdC4KCgo+PiArCWRlZmF1bHQ6Cj4+ ICsJCXByX3dhcm4oIk5BTkQgRVJST1I6IGludmFsaWQgU01DUl9QU0laRSA9IDB4JTA4WFxuIiwg cGFnZSk7Cj4+ICsJCXJldHVybjsKPj4gKwl9Cj4+ICsKPj4gKwkvKiBnb3QgdmFsaWQgQkNIX0VD Q19EQVRBeCBhbmQgcGFyc2UgdGhlbSB0byB0ZW1wX2RhdGFbXQo+PiArCSAqIGdvdCB0aGUgdmFs aWQgcmVnaXN0ZXIgbnVtYmVyIG9mIEJDSF9FQ0NfREFUQXggc2luY2UKPj4gKwkgKiBvbmUgcmVn aXN0ZXIgaW5jbHVkZSA0IGVycm9yIGJ5dGVzCj4+ICsJICovCj4+ICsJaiA9IGVycl9jbnQgLyA0 Owo+PiArCWorKzsKPj4gKwlpZiAoaiA+IDYpCj4+ICsJCWogPSA2OwkvKiB0aGVyZSBhcmUgNiBC Q0hfRUNDX0RBVEF4IHJlZ2lzdGVycyB0byBzdXBwb3J0IEJDSCBUMjQgKi8KPj4gKwo+PiArCWZv ciAoaSA9IDA7IGkgPCBqOyBpKyspCj4+ICsJCWVycl9kYXRhW2ldID0gcmVhZGwobmFuZC0+cmVn cyArIE1BMzVfTkZJX1JFR19OQU5ERUNDRUQwICsgaSo0KTsKPj4gKwo+PiArCWZvciAoaSA9IDA7 IGkgPCBqOyBpKyspIHsKPj4gKwkJdGVtcF9kYXRhW2kqNCswXSA9IGVycl9kYXRhW2ldICYgMHhm ZjsKPj4gKwkJdGVtcF9kYXRhW2kqNCsxXSA9IChlcnJfZGF0YVtpXSA+PiA4KSAmIDB4ZmY7Cj4+ ICsJCXRlbXBfZGF0YVtpKjQrMl0gPSAoZXJyX2RhdGFbaV0gPj4gMTYpICYgMHhmZjsKPj4gKwkJ dGVtcF9kYXRhW2kqNCszXSA9IChlcnJfZGF0YVtpXSA+PiAyNCkgJiAweGZmOwo+PiArCX0KPj4g Kwo+PiArCS8qIGdvdCB2YWxpZCBSRUdfQkNIX0VDQ19BRERSeCBhbmQgcGFyc2UgdGhlbSB0byB0 ZW1wX2FkZHJbXQo+PiArCSAqIGdvdCB0aGUgdmFsaWQgcmVnaXN0ZXIgbnVtYmVyIG9mIFJFR19C Q0hfRUNDX0FERFJ4IHNpbmNlCj4+ICsJICogb25lIHJlZ2lzdGVyIGluY2x1ZGUgMiBlcnJvciBh ZGRyZXNzZXMKPj4gKwkgKi8KPj4gKwlqID0gZXJyX2NudCAvIDI7Cj4+ICsJaisrOwo+PiArCWlm IChqID4gMTIpCj4+ICsJCWogPSAxMjsgLyogdGhlcmUgYXJlIDEyIFJFR19CQ0hfRUNDX0FERFJ4 IHJlZ2lzdGVycyB0byBzdXBwb3J0IEJDSCBUMjQgKi8KPj4gKwo+PiArCWZvciAoaSA9IDA7IGkg PCBqOyBpKyspIHsKPj4gKwkJLyogMTEgYml0cyBmb3IgZXJyb3IgYWRkcmVzcyAqLwo+PiArCQl0 ZW1wX2FkZHJbaSoyKzBdID0gcmVhZGwobmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5ERUND RUEwICsgaSo0KSAmIDB4MDdmZjsKPj4gKwkJdGVtcF9hZGRyW2kqMisxXSA9IChyZWFkbChuYW5k LT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRFQ0NFQTAgKyBpKjQpPj4xNikgJiAweDA3ZmY7Cj4+ ICsJfQo+PiArCj4+ICsJLyogcG9pbnRlciB0byBiZWdpbiBhZGRyZXNzIG9mIGZpZWxkIHRoYXQg d2l0aCBkYXRhIGVycm9yICovCj4+ICsJYWRkciArPSAoaW5kZXgtMSkgKiBmaWVsZF9sZW47Cj4+ ICsKPj4gKwkvKiBjb3JyZWN0IGVhY2ggZXJyb3IgYnl0ZXMgKi8KPj4gKwlmb3IgKGkgPSAwOyBp IDwgZXJyX2NudDsgaSsrKSB7Cj4+ICsJCS8qIGZvciB3cm9uZyBkYXRhIGluIGZpZWxkICovCj4+ ICsJCWlmICh0ZW1wX2FkZHJbaV0gPCBmaWVsZF9sZW4pCj4+ICsJCQkqKGFkZHIrdGVtcF9hZGRy W2ldKSBePSB0ZW1wX2RhdGFbaV07Cj4+ICsKPj4gKwkJLyogZm9yIHdyb25nIGZpcnN0LTMtYnl0 ZXMgaW4gcmVkdW5kYW5jeSBhcmVhICovCj4+ICsJCWVsc2UgaWYgKHRlbXBfYWRkcltpXSA8IChm aWVsZF9sZW4rMykpIHsKPj4gKwkJCXRlbXBfYWRkcltpXSAtPSBmaWVsZF9sZW47Cj4+ICsJCQl0 ZW1wX2FkZHJbaV0gKz0gKHBhcml0eV9sZW4gKiAoaW5kZXgtMSkpOwkvKiBmaWVsZCBvZmZzZXQg Ki8KPj4gKwo+PiArCQkJKihwdHIgKyB0ZW1wX2FkZHJbaV0pIF49IHRlbXBfZGF0YVtpXTsKPj4g KwkJfQo+PiArCQkvKiBmb3Igd3JvbmcgcGFyaXR5IGNvZGUgaW4gcmVkdW5kYW5jeSBhcmVhICov Cj4+ICsJCS8qIEJDSF9FUlJfQUREUnggPSBbZGF0YSBpbiBmaWVsZF0gKyBbMyBieXRlc10gKyBb eHhdICsgW3Bhcml0eSBjb2RlXSAgICAgICAgICAqLwo+PiArCQkvKiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgfDwtLSAgICAgcGFkZGluZyBieXRlcyAgICAgIC0tPnwgICAgICAg ICAgKi8KPj4gKwkJLyogVGhlIEJDSF9FUlJfQUREUnggZm9yIGxhc3QgcGFyaXR5IGNvZGUgYWx3 YXlzID0gZmllbGQgc2l6ZSArIHBhZGRpbmcgc2l6ZS4gICovCj4+ICsJCS8qIFNvLCB0aGUgZmly c3QgcGFyaXR5IGNvZGUgPSBmaWVsZCBzaXplICsgcGFkZGluZyBzaXplIC0gcGFyaXR5IGNvZGUg bGVuZ3RoLiAqLwo+PiArCQkvKiBGb3IgZXhhbXBsZSwgZm9yIEJDSCBUMTIsIHRoZSBmaXJzdCBw YXJpdHkgY29kZSA9IDUxMiArIDMyIC0gMjMgPSA1MjEuICAgICAgKi8KPj4gKwkJLyogVGhhdCBp cywgZXJyb3IgYnl0ZSBhZGRyZXNzIG9mZnNldCB3aXRoaW4gZmllbGQgaXMgICAgICAgICAgICAg ICAgICAgICAgICAgICovCj4+ICsJCWVsc2Ugewo+PiArCQkJdGVtcF9hZGRyW2ldID0gdGVtcF9h ZGRyW2ldIC0gKGZpZWxkX2xlbiArIHBhZGRpbmdfbGVuIC0gcGFyaXR5X2xlbik7Cj4+ICsKPj4g KwkJCS8qIHNtcmFfaW5kZXggcG9pbnQgdG8gdGhlIGZpcnN0IHBhcml0eSBjb2RlIG9mCj4+ICsJ CQkgKiBmaXJzdCBmaWVsZCBpbiByZWdpc3RlciBTTVJBMH5uCj4+ICsJCQkgKi8KPj4gKwkJCXNt cmFfaW5kZXggPSAodTggKikocHRyICsKPj4gKwkJCQkocmVhZGwobmFuZC0+cmVncytNQTM1X05G SV9SRUdfTkFORFJBQ1RMKSAmIDB4MWZmKSAtCj4+ICsJCQkJKHBhcml0eV9sZW4gKiB0b3RhbF9m aWVsZF9udW0pKTsKPj4gKwo+PiArCQkJLyogZmluYWwgYWRkcmVzcyA9IGZpcnN0IHBhcml0eSBj b2RlIG9mIGZpcnN0IGZpZWxkICsgKi8KPj4gKwkJCS8qICAgICAgICAgICAgICAgICBvZmZzZXQg b2YgZmllbGRzICsgICAgICAgICAgICAgICAgICovCj4+ICsJCQkvKiAgICAgICAgICAgICAgICAg b2Zmc2V0IHdpdGhpbiBmaWVsZCAgICAgICAgICAgICAgICAqLwo+IENvZGluZyBzdHlsZQoKCk9r YXksIEkgd2lsbCBmaXggaXQuCgoKPj4gKwo+PiArCQkJKigodTggKilzbXJhX2luZGV4ICsgKHBh cml0eV9sZW4gKiAoaW5kZXggLSAxKSkgKyB0ZW1wX2FkZHJbaV0pCj4+ICsJCQkJXj0gdGVtcF9k YXRhW2ldOwo+IC1FTk9QQVJTRQoKCk1BMzUgRUNDIGVuZ2luZSB3aWxsIHBlcmZvcm0gY2FsY3Vs YXRpb25zIG9uIHRoZSBwYXJpdHkgaW4gdGhlIHNwYXJlIGFyZWEuCgpXaGVuIHRoZSBwYXJpdHkg ZGF0YSBnZW5lcmF0ZXMgYW4gRUNDIGVycm9yLCB0aGUgY2FsY3VsYXRpb25zIG1lbnRpb25lZCAK YWJvdmUgd2lsbCBjb3JyZWN0IHRoZSBwYXJpdHkgZGF0YS4KCgo+PiArCQl9Cj4+ICsJfSAvKiBl bmQgb2YgZm9yIChpIDwgZXJyX2NudCkgKi8KPiBVc2VsZXNzIGNvbW1lbnQKCgpJIHdpbGwgcmVt b3ZlIGl0LgoKCj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgbWEzNV9uZmlfY29ycmVjdChzdHJ1 Y3QgbmFuZF9jaGlwICpjaGlwLCB1bnNpZ25lZCBsb25nIGFkZHIpCj4+ICt7Cj4+ICsJc3RydWN0 IG1hMzVfbmFuZF9pbmZvICpuYW5kID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+ PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4+ICsJaW50IHN0 YXR1cywgaSwgaiwgZmllbGQgPSAwOwo+PiArCWludCByZXBvcnRfZXJyID0gMDsKPj4gKwlpbnQg ZXJyX2NudCA9IDA7Cj4+ICsKPj4gKwlpZiAoKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9S RUdfTkFORENUTCkgJiBCQ0hfTUFTSykgPT0gQkNIX1QyNCkKPj4gKwkJZmllbGQgPSBtdGQtPndy aXRlc2l6ZSAvIDEwMjQ7Cj4gQ2FuIHdlIGNhbGwgdGhpcyBhIG5jaHVua3M/IEFsc28sIHlvdSdy ZSBzdXBwb3NlZCB0byBleHBlY3Qgc29tZSBEVAo+IHByb3BlcnRpZXMgKGJhc2VkIG9uIHlvdXIg YmluZGluZ3MpIGFuZCB5b3UncmUgbm90IHVzaW5nIHRoZWlyIHZhbHVlcywKPiBpdCdzIHN0cmFu Z2UuCgoKSSB3aWxsIGNoYW5nZSB0aGUgZmllbGQgdG8gYG5jaHVua3NgIGFuZCB1c2UgYG5hbmQt ZWNjLXN0ZXAtc2l6ZWAgZm9yIAp0aGUgY2FsY3VsYXRpb25zLgoKCj4+ICsJZWxzZQo+PiArCQlm aWVsZCA9IG10ZC0+d3JpdGVzaXplIC8gNTEyOwo+PiArCj4+ICsJaWYgKGZpZWxkIDwgNCkKPj4g KwkJZmllbGQgPSAxOwo+PiArCWVsc2UKPj4gKwkJZmllbGQgLz0gNDsKPj4gKwo+PiArCWZvciAo aiA9IDA7IGogPCBmaWVsZDsgaisrKSB7Cj4+ICsJCXN0YXR1cyA9IHJlYWRsKG5hbmQtPnJlZ3Mg KyBNQTM1X05GSV9SRUdfTkFOREVDQ0VTMCArIGoqNCk7Cj4+ICsJCWlmICghc3RhdHVzKQo+PiAr CQkJY29udGludWU7Cj4gSXMgdGhpcyBjYXNlIHJlbGV2YW50PyBJc24ndCBpdCB0cmVhdGVkIGJl bG93PwoKClRoaXMgaXMgdG8gZmlyc3QgY2hlY2sgdGhlIEVDQyBzdGF0dXMuCgpJZiB0aGVyZSBh cmUgY29ycmVjdGFibGUgZXJyb3JzLCBpdCB3aWxsIGV4dHJhY3QgdGhlIGVycm9yIGNvdW50LAoK cGVyZm9ybSB0aGUgY2FsY3VsYXRpb25zLCBhbmQgbWFrZSB0aGUgY29ycmVjdGlvbnMuCgoKPj4g Kwo+PiArCQlmb3IgKGkgPSAxOyBpIDwgNTsgaSsrKSB7Cj4gIEZyb20gMSB0byA1PyBUaGF0J3Mg c3RyYW5nZS4KCgpJIHdpbGwgY2hhbmdlIGl0IHRvIDAgdG8gMy4KCgo+PiArCQkJaWYgKCEoc3Rh dHVzICYgRUNDX1NUQVRVU19NQVNLKSkgewo+PiArCQkJCS8qIE5vIGVycm9yICovCj4+ICsJCQkJ c3RhdHVzID4+PSA4Owo+IFlvdSBjYW4ndCBkbyB0aGF0IDUgdGltZXMgb24gYSBpbnQuCgoKT25s eSA0IHRpbWVzLgoKCj4+ICsJCQkJY29udGludWU7Cj4+ICsKPj4gKwkJCX0gZWxzZSBpZiAoKHN0 YXR1cyAmIEVDQ19TVEFUVVNfTUFTSykgPT0gMHgwMSkgewo+PiArCQkJCS8qIENvcnJlY3RhYmxl IGVycm9yICovCj4+ICsJCQkJZXJyX2NudCA9IChzdGF0dXMgPj4gMikgJiBFQ0NfRVJSX0NOVF9N QVNLOwo+IFBsZWFzZSB1c2UgRklFTERfR0VUKCkKCgpJIHdpbGwgdXNlIEZJRUxEX0dFVCgpLgoK Cj4+ICsJCQkJcHJfd2FybigiRmllbGQgKCVkLCAlZCkgaGF2ZSAlZCBlcnJvciFcbiIsIGosIGks IGVycl9jbnQpOwo+IGRldl93YXJuKCkKCgpJIHdpbGwgdXNlIGRldl93YXJuKCkuCgoKPj4gKwkJ CQltYTM1X25maV9jb3JyZWN0ZGF0YShuYW5kLCBqKjQraSwgZXJyX2NudCwgKHU4ICopYWRkcik7 Cj4+ICsJCQkJcmVwb3J0X2VyciArPSBlcnJfY250Owo+PiArCj4+ICsJCQl9IGVsc2Ugewo+PiAr CQkJCS8qIHVuY29ycmVjdGFibGUgZXJyb3IgKi8KPj4gKwkJCQlwcl93YXJuKCJ1bmNvcnJlY3Rh YmxlIGVycm9yISAweCU0eFxuIiwgc3RhdHVzKTsKPj4gKwkJCQlyZXR1cm4gLTE7Cj4+ICsJCQl9 Cj4+ICsJCQlzdGF0dXMgPj49IDg7Cj4+ICsJCX0KPj4gKwl9Cj4+ICsJcmV0dXJuIHJlcG9ydF9l cnI7Cj4+ICt9Cj4+ICsKPj4gKwo+PiArc3RhdGljIGludCBtYTM1X25hbmRfY29ycmVjdF9kYXRh KHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsIHVfY2hhciAqZGF0LAo+PiArCQkJCSAgdV9jaGFyICpy ZWFkX2VjYywgdV9jaGFyICpjYWxjX2VjYykKPj4gK3sKPj4gKwlyZXR1cm4gMDsKPiA/CgoKSSB3 aWxsIHJlbW92ZSBpdC4KCgo+PiArfQo+PiArCj4+ICsKPj4gK3N0YXRpYyB2b2lkIG1hMzVfbmFu ZF9lbmFibGVfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgaW50IG1vZGUpCj4+ICt7Cj4g PwoKCkkgd2lsbCByZW1vdmUgaXQuCgoKPj4gKwo+PiArfQo+PiArCj4+ICsvKgo+PiArICogSW5p dGlhbCBkbWEgY29udHJvbGxlcgo+IEluaXRpYWxpemUgRE1BCgoKSSB3aWxsIG1vZGlmeSBpdC4K Cgo+PiArICovCj4+ICtzdGF0aWMgdm9pZCBtYTM1X25hbmRfZG1hY19pbml0KHN0cnVjdCBtYTM1 X25hbmRfaW5mbyAqbmFuZCkKPj4gK3sKPj4gKwkvKiBETUFDIHJlc2V0IGFuZCBlbmFibGUgKi8K Pj4gKwl3cml0ZWwoRE1BX1JTVCB8IERNQV9FTiwgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19E TUFDVEwpOwo+PiArCXdyaXRlbChETUFfRU4sIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfRE1B Q1RMKTsKPj4gKwo+PiArCS8qIENsZWFyIERNQSBmaW5pc2hlZCBmbGFnICovCj4+ICsJd3JpdGVs KElOVF9ETUEgfCBJTlRfRUNDLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRJTlRTVFMp Owo+PiArCj4+ICsJaW5pdF9jb21wbGV0aW9uKCZuYW5kLT5jb21wbGV0ZSk7Cj4+ICt9Cj4+ICsK Pj4gKy8qCj4+ICsgKiByZWFkIGEgYnl0ZSBmcm9tIE5BTkQgY29udHJvbGxlcgo+ICAgICAgICBS ZWFkIChzYW1lIGJlbG93KQoKCkFzIGJlbG93LgoKCj4+ICsgKi8KPj4gK3N0YXRpYyB1OCBtYTM1 X25hbmRfcmVhZF9ieXRlKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXApCj4+ICt7Cj4+ICsJc3RydWN0 IG1hMzVfbmFuZF9pbmZvICpuYW5kID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+ PiArCXU4IHJldDsKPj4gKwo+PiArCXdyaXRlbChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklf UkVHX05BTkRDVEwpICYgKH5ESVNBQkxFX0NTMCksCj4+ICsJCW5hbmQtPnJlZ3MrTUEzNV9ORklf UkVHX05BTkRDVEwpOwo+PiArCXJldCA9ICh1OClyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklf UkVHX05BTkREQVRBKTsKPiByZWFkYj8gbWF5YmUgeW91IG5lZWQgdG8gaGFuZGxlIGVuZGlhbm5l c3M/CgoKVGhpcyByZWdpc3RlciBvbmx5IGhhcyBvbmUgYnl0ZSBvZiB2YWxpZCBkYXRhLgoKCj4+ ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCkgfCBESVNB QkxFX0NTMCwKPj4gKwkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsKPj4gKwo+ PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gKwo+PiArLyoKPj4gKyAqIHJlYWQgZGF0YSBm cm9tIE5BTkQgY29udHJvbGxlcgo+PiArICovCj4+ICtzdGF0aWMgdm9pZCBtYTM1X25hbmRfcmVh ZF9idWYoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgdTggKmJ1ZiwgaW50IGxlbikKPj4gK3sKPj4g KwlzdHJ1Y3QgbWEzNV9uYW5kX2luZm8gKm5hbmQgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEo Y2hpcCk7Cj4+ICsJaW50IGk7Cj4+ICsKPj4gKwl3cml0ZWwocmVhZGwobmFuZC0+cmVncyArIE1B MzVfTkZJX1JFR19OQU5EQ1RMKSAmICh+RElTQUJMRV9DUzApLAo+PiArCQluYW5kLT5yZWdzICsg TUEzNV9ORklfUkVHX05BTkRDVEwpOwo+PiArCWZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykKPj4g KwkJYnVmW2ldID0gKHU4KXJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORERBVEEp Owo+PiArCXdyaXRlbChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpIHwg RElTQUJMRV9DUzAsCj4+ICsJCW5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCk7Cj4+ ICt9Cj4+ICsvKgo+PiArICogd3JpdGUgZGF0YSB0byBOQU5EIGNvbnRyb2xsZXIKPj4gKyAqLwo+ PiArCj4+ICtzdGF0aWMgdm9pZCBtYTM1X25hbmRfd3JpdGVfYnVmKHN0cnVjdCBuYW5kX2NoaXAg KmNoaXAsIGNvbnN0IHU4ICpidWYsIGludCBsZW4pCj4+ICt7Cj4+ICsJc3RydWN0IG1hMzVfbmFu ZF9pbmZvICpuYW5kID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+PiArCWludCBp Owo+PiArCj4+ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENU TCkgJiAofkRJU0FCTEVfQ1MwKSwKPj4gKwkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5E Q1RMKTsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCj4+ICsJCXdyaXRlbChidWZbaV0s IG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORERBVEEpOwo+PiArCXdyaXRlbChyZWFkbChu YW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpIHwgRElTQUJMRV9DUzAsCj4+ICsJCW5h bmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCk7Cj4+ICt9Cj4+ICsKPj4gKy8qCj4+ICsg KiBjb25maWd1cmUgYW5kIHN0YXJ0IGRtYSB0cmFuc2Zlcgo+PiArICovCj4+ICtzdGF0aWMgaW5s aW5lIGludCBtYTM1X25hbmRfZG1hX3RyYW5zZmVyKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsCj4+ ICsJCQkJCSAgY29uc3QgdV9jaGFyICphZGRyLCB1MzIgbGVuLCBpbnQgaXNfd3JpdGUpCj4+ICt7 Cj4+ICsJc3RydWN0IG1hMzVfbmFuZF9pbmZvICpuYW5kID0gbmFuZF9nZXRfY29udHJvbGxlcl9k YXRhKGNoaXApOwo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7 Cj4+ICsJdW5zaWduZWQgbG9uZyB0aW1lbyA9IGppZmZpZXMgKyBIWi8yOwo+PiArCWRtYV9hZGRy X3QgZG1hX2FkZHI7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXdyaXRlbChyZWFkbChuYW5kLT5y ZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpICYgKH5ESVNBQkxFX0NTMCksCj4+ICsJCW5hbmQt PnJlZ3MrTUEzNV9ORklfUkVHX05BTkRDVEwpOwo+PiArCS8qIEZvciBzYXZlLCB3YWl0IERNQUMg dG8gcmVhZHkgKi8KPiBQbGVhc2UgcmV3b3JrIHRoaXMgY29tbWVudAoKCkkgd2lsbCBjaGFuZ2Ug aXQgdG8gIkNoZWNrIHRoZSBETUEgc3RhdHVzIGJlZm9yZSBlbmFibGluZyB0aGUgRE1BLiIKCgo+ PiArCXdoaWxlICgxKSB7Cj4+ICsJCWlmICgocmVhZGwobmFuZC0+cmVncyArIE1BMzVfTkZJX1JF R19ETUFDVEwpICYgRE1BX0JVU1kpID09IDApCj4+ICsJCQlicmVhazsKPj4gKwkJaWYgKHRpbWVf YWZ0ZXIoamlmZmllcywgdGltZW8pKQo+PiArCQkJcmV0dXJuIC1FVElNRURPVVQ7Cj4gcmVhZGxf cG9sbF90aW1lb3V0KCkKCgpPa2F5LiBJIHdpbGwgdXNlIHJlYWRsX3BvbGxfdGltZW91dCgpLgoK Cj4+ICsJfQo+PiArCj4+ICsJLyogUmVpbml0aWFsIGRtYWMgKi8KPj4gKwltYTM1X25hbmRfZG1h Y19pbml0KG5hbmQpOwo+PiArCj4+ICsJd3JpdGVsKG10ZC0+b29ic2l6ZSwgbmFuZC0+cmVncyAr IE1BMzVfTkZJX1JFR19OQU5EUkFDVEwpOwo+PiArCj4+ICsJLyogc2V0dXAgYW5kIHN0YXJ0IERN QSB1c2luZyBkbWFfYWRkciAqLwo+PiArCWlmIChpc193cml0ZSkgewo+PiArCQl1OCAqcHRyID0g KHU4ICopKChsb25nKW5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORFJBMCk7Cj4+ICsKPj4g KwkJd3JpdGVsKElOVF9ETUEsIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORElOVEVOKTsK Pj4gKwkJLyogVG8gbWFyayB0aGlzIHBhZ2UgYXMgZGlydHkuICovCj4+ICsJCWlmIChwdHJbM10g PT0gMHhGRikKPj4gKwkJCXB0clszXSA9IDA7Cj4+ICsJCWlmIChwdHJbMl0gPT0gMHhGRikKPj4g KwkJCXB0clsyXSA9IDA7Cj4+ICsKPj4gKwkJLyogRmlsbCBkbWFfYWRkciAqLwo+PiArCQlkbWFf YWRkciA9IGRtYV9tYXBfc2luZ2xlKG5hbmQtPmRldiwgKHZvaWQgKilhZGRyLCBsZW4sIERNQV9U T19ERVZJQ0UpOwo+PiArCQlkbWFfc3luY19zaW5nbGVfZm9yX2RldmljZShuYW5kLT5kZXYsIGRt YV9hZGRyLCBsZW4sIERNQV9UT19ERVZJQ0UpOwo+PiArCQlyZXQgPSBkbWFfbWFwcGluZ19lcnJv cihuYW5kLT5kZXYsIGRtYV9hZGRyKTsKPj4gKwkJaWYgKHJldCkgewo+PiArCQkJZGV2X2Vycihu YW5kLT5kZXYsICJkbWEgbWFwcGluZyBlcnJvclxuIik7Cj4+ICsJCQlyZXR1cm4gLUVJTlZBTDsK Pj4gKwkJfQo+PiArCj4+ICsJCXdyaXRlbCgodW5zaWduZWQgbG9uZylkbWFfYWRkciwgbmFuZC0+ cmVncyArIE1BMzVfTkZJX1JFR19ETUFTQSk7Cj4+ICsJCXdyaXRlbChyZWFkbChuYW5kLT5yZWdz ICsgTUEzNV9ORklfUkVHX05BTkRDVEwpIHwgRE1BX1dfRU4sCj4+ICsJCQluYW5kLT5yZWdzICsg TUEzNV9ORklfUkVHX05BTkRDVEwpOwo+PiArCQl3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQo Jm5hbmQtPmNvbXBsZXRlLCBtc2Vjc190b19qaWZmaWVzKDEwMDApKTsKPj4gKwo+PiArCQlkbWFf dW5tYXBfc2luZ2xlKG5hbmQtPmRldiwgZG1hX2FkZHIsIGxlbiwgRE1BX1RPX0RFVklDRSk7Cj4+ ICsJfSBlbHNlIHsKPj4gKwkJd3JpdGVsKElOVF9ETUEgfCBJTlRfRUNDLCBuYW5kLT5yZWdzICsg TUEzNV9ORklfUkVHX05BTkRJTlRFTik7Cj4+ICsJCS8qIEZpbGwgZG1hX2FkZHIgKi8KPj4gKwkJ ZG1hX2FkZHIgPSBkbWFfbWFwX3NpbmdsZShuYW5kLT5kZXYsICh2b2lkICopYWRkciwgbGVuLCBE TUFfRlJPTV9ERVZJQ0UpOwo+PiArCQlyZXQgPSBkbWFfbWFwcGluZ19lcnJvcihuYW5kLT5kZXYs IGRtYV9hZGRyKTsKPj4gKwkJaWYgKHJldCkgewo+PiArCQkJZGV2X2VycihuYW5kLT5kZXYsICJk bWEgbWFwcGluZyBlcnJvclxuIik7Cj4+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwkJfQo+PiAr CQluYW5kLT5kbWFfYnVmID0gKHU4ICopIGFkZHI7Cj4gdGhlIGNhc3Qgc2hvdWxkIG5vdCBiZSBu ZWVkZQoKCk9rYXkuIEkgd2lsbCByZW1vdmUgaXQuCgoKPj4gKwkJbmFuZC0+ZG1hX2FkZHIgPSBk bWFfYWRkcjsKPj4gKwo+PiArCQl3cml0ZWwoKHVuc2lnbmVkIGxvbmcpZG1hX2FkZHIsIG5hbmQt PnJlZ3MgKyBNQTM1X05GSV9SRUdfRE1BU0EpOwo+PiArCQl3cml0ZWwocmVhZGwobmFuZC0+cmVn cyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKSB8IERNQV9SX0VOLAo+PiArCQkJbmFuZC0+cmVncyAr IE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsKPj4gKwkJd2FpdF9mb3JfY29tcGxldGlvbl90aW1lb3V0 KCZuYW5kLT5jb21wbGV0ZSwgbXNlY3NfdG9famlmZmllcygxMDAwKSk7Cj4gQWx3YXlzIGNoZWNr IHJldHVybiB2YWx1ZXMuCgoKSSB3aWxsIGZpeCBpdC4KCgo+PiArCj4+ICsJCWRtYV9zeW5jX3Np bmdsZV9mb3JfY3B1KG5hbmQtPmRldiwgZG1hX2FkZHIsIGxlbiwgRE1BX0ZST01fREVWSUNFKTsK Pj4gKwkJZG1hX3VubWFwX3NpbmdsZShuYW5kLT5kZXYsIGRtYV9hZGRyLCBsZW4sIERNQV9GUk9N X0RFVklDRSk7Cj4+ICsJfQo+PiArCj4+ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1 X05GSV9SRUdfTkFORENUTCkgfCBESVNBQkxFX0NTMCwKPj4gKwkJbmFuZC0+cmVncyArIE1BMzVf TkZJX1JFR19OQU5EQ1RMKTsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgdm9pZCBtYTM1X3JlYWRfYnVmX2RtYShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCB1X2NoYXIg KmJ1ZiwgaW50IGxlbikKPj4gK3sKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9f bXRkKGNoaXApOwo+PiArCj4+ICsJaWYgKGxlbiA9PSBtdGQtPndyaXRlc2l6ZSkKPj4gKwkJbWEz NV9uYW5kX2RtYV90cmFuc2ZlcihjaGlwLCBidWYsIGxlbiwgMHgwKTsKPj4gKwllbHNlCj4+ICsJ CW1hMzVfbmFuZF9yZWFkX2J1ZihjaGlwLCBidWYsIGxlbik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRp YyB2b2lkIG1hMzVfd3JpdGVfYnVmX2RtYShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwLCBjb25zdCB1 X2NoYXIgKmJ1ZiwgaW50IGxlbikKPj4gK3sKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5h bmRfdG9fbXRkKGNoaXApOwo+PiArCj4+ICsJaWYgKGxlbiA9PSBtdGQtPndyaXRlc2l6ZSkKPj4g KwkJbWEzNV9uYW5kX2RtYV90cmFuc2ZlcihjaGlwLCAodV9jaGFyICopYnVmLCBsZW4sIDB4MSk7 Cj4+ICsJZWxzZQo+PiArCQltYTM1X25hbmRfd3JpdGVfYnVmKGNoaXAsIGJ1ZiwgbGVuKTsKPj4g K30KPj4gKwo+IFRoaXMuLi4KCgpJIHdpbGwgcmV3cml0ZSBpdCB0byByZWFkIGFuZCB3cml0ZSBp biB0ZXJtcyBvZiBwYWdlcy4KCgo+PiArc3RhdGljIGludCBtYTM1X25hbmRfZGV2cmVhZHkoc3Ry dWN0IG5hbmRfY2hpcCAqY2hpcCkKPj4gK3sKPj4gKwlzdHJ1Y3QgbWEzNV9uYW5kX2luZm8gKm5h bmQgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEoY2hpcCk7Cj4+ICsJdW5zaWduZWQgaW50IHZh bDsKPj4gKwo+PiArCXdyaXRlbChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRD VEwpICYgKH5ESVNBQkxFX0NTMCksCj4+ICsJCW5hbmQtPnJlZ3MrTUEzNV9ORklfUkVHX05BTkRD VEwpOwo+PiArCXZhbCA9IChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRJTlRT VFMpICYgSU5UX1JCMF9TVFMpID8gMSA6IDA7Cj4+ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3Mg KyBNQTM1X05GSV9SRUdfTkFORENUTCkgfCBESVNBQkxFX0NTMCwKPj4gKwkJbmFuZC0+cmVncytN QTM1X05GSV9SRUdfTkFORENUTCk7Cj4+ICsKPj4gKwlyZXR1cm4gdmFsOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgaW50IG1hMzVfd2FpdGZ1bmMoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCkKPj4gK3sK Pj4gKwlzdHJ1Y3QgbWEzNV9uYW5kX2luZm8gKm5hbmQgPSBuYW5kX2dldF9jb250cm9sbGVyX2Rh dGEoY2hpcCk7Cj4+ICsJdW5zaWduZWQgbG9uZyB0aW1lbyA9IGppZmZpZXM7Cj4+ICsJaW50IHN0 YXR1cyA9IC0xOwo+PiArCj4+ICsJdGltZW8gKz0gbXNlY3NfdG9famlmZmllcyg0MDApOwo+PiAr Cj4+ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCkgJiAo fkRJU0FCTEVfQ1MwKSwKPj4gKwkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsK Pj4gKwl3aGlsZSAodGltZV9iZWZvcmUoamlmZmllcywgdGltZW8pKSB7Cj4+ICsJCXN0YXR1cyA9 IHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORElOVFNUUyk7Cj4+ICsJCWlmIChz dGF0dXMgJiBJTlRfUkIwKSB7Cj4+ICsJCQl3cml0ZWwoSU5UX1JCMCwgbmFuZC0+cmVncyArIE1B MzVfTkZJX1JFR19OQU5ESU5UU1RTKTsKPj4gKwkJCXN0YXR1cyA9IDA7Cj4+ICsJCQlicmVhazsK Pj4gKwkJfQo+PiArCQljb25kX3Jlc2NoZWQoKTsKPj4gKwl9Cj4+ICsJd3JpdGVsKHJlYWRsKG5h bmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENUTCkgfCBESVNBQkxFX0NTMCwKPj4gKwkJbmFu ZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsKPj4gKwo+PiArCXJldHVybiBzdGF0dXM7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIG1hMzVfbmFuZF9jb21tYW5kKHN0cnVjdCBuYW5k X2NoaXAgKmNoaXAsIHUzMiBjb21tYW5kLCBpbnQgY29sdW1uLCBpbnQgcGFnZV9hZGRyKQo+PiAr ewo+PiArCXN0cnVjdCBtYTM1X25hbmRfaW5mbyAqbmFuZCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJf ZGF0YShjaGlwKTsKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKGNoaXAp Owo+PiArCj4+ICsJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENU TCkgJiAofkRJU0FCTEVfQ1MwKSwKPj4gKwkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5E Q1RMKTsKPj4gKwl3cml0ZWwoSU5UX1JCMCwgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5E SU5UU1RTKTsKPj4gKwo+PiArCWlmIChjb21tYW5kID09IE5BTkRfQ01EX1JFQURPT0IpIHsKPj4g KwkJY29tbWFuZCA9IE5BTkRfQ01EX1JFQUQwOwo+PiArCQljb2x1bW4gKz0gbXRkLT53cml0ZXNp emU7Cj4+ICsJfQo+PiArCj4+ICsJc3dpdGNoIChjb21tYW5kKSB7Cj4+ICsJY2FzZSBOQU5EX0NN RF9SRVNFVDoKPj4gKwkJd3JpdGVsKGNvbW1hbmQsIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdf TkFORENNRCk7Cj4+ICsJCWJyZWFrOwo+PiArCj4+ICsJY2FzZSBOQU5EX0NNRF9SRUFESUQ6Cj4+ ICsJCXdyaXRlbChjb21tYW5kLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDTUQpOwo+ PiArCQl3cml0ZWwoRU5EQUREUnxjb2x1bW4sIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFO REFERFIpOwo+PiArCQlicmVhazsKPj4gKwo+PiArCWNhc2UgTkFORF9DTURfUEFSQU06Cj4+ICsJ CXdyaXRlbChjb21tYW5kLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDTUQpOwo+PiAr CQl3cml0ZWwoRU5EQUREUnxjb2x1bW4sIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFOREFE RFIpOwo+PiArCQltYTM1X3dhaXRmdW5jKGNoaXApOwo+PiArCQlicmVhazsKPj4gKwo+PiArCWNh c2UgTkFORF9DTURfUkVBRDA6Cj4+ICsJCXdyaXRlbChFTkFCTEVfV1AsIG5hbmQtPnJlZ3MgKyBN QTM1X05GSV9SRUdfTkFOREVDVEwpOwo+PiArCQl3cml0ZWwoY29tbWFuZCwgbmFuZC0+cmVncyAr IE1BMzVfTkZJX1JFR19OQU5EQ01EKTsKPj4gKwkJaWYgKGNvbHVtbiAhPSAtMSkgewo+PiArCQkJ d3JpdGVsKGNvbHVtbiAmIDB4ZmYsIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFOREFERFIp Owo+PiArCQkJd3JpdGVsKChjb2x1bW4gPj4gOCkgJiAweGZmLCBuYW5kLT5yZWdzICsgTUEzNV9O RklfUkVHX05BTkRBRERSKTsKPj4gKwkJfQo+PiArCQlpZiAocGFnZV9hZGRyICE9IC0xKSB7Cj4+ ICsJCQl3cml0ZWwocGFnZV9hZGRyICYgMHhmZiwgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19O QU5EQUREUik7Cj4+ICsJCQlpZiAoY2hpcC0+b3B0aW9ucyAmIE5BTkRfUk9XX0FERFJfMykgewo+ PiArCQkJCXdyaXRlbCgocGFnZV9hZGRyID4+IDgpICYgMHhmZiwKPj4gKwkJCQkJbmFuZC0+cmVn cyArIE1BMzVfTkZJX1JFR19OQU5EQUREUik7Cj4+ICsJCQkJd3JpdGVsKCgocGFnZV9hZGRyID4+ IDE2KSAmIDB4ZmYpIHwgRU5EQUREUiwKPj4gKwkJCQkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JF R19OQU5EQUREUik7Cj4+ICsJCQl9IGVsc2Ugewo+PiArCQkJCXdyaXRlbCgoKHBhZ2VfYWRkciA+ PiA4KSAmIDB4ZmYpIHwgRU5EQUREUiwKPj4gKwkJCQkJbmFuZC0+cmVncyArIE1BMzVfTkZJX1JF R19OQU5EQUREUik7Cj4+ICsJCQl9Cj4+ICsJCX0KPj4gKwkJd3JpdGVsKE5BTkRfQ01EX1JFQURT VEFSVCwgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ01EKTsKPj4gKwkJbWEzNV93YWl0 ZnVuYyhjaGlwKTsKPj4gKwkJYnJlYWs7Cj4+ICsKPj4gKwljYXNlIE5BTkRfQ01EX0VSQVNFMToK Pj4gKwkJd3JpdGVsKERJU0FCTEVfV1AsIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFOREVD VEwpOwo+PiArCQl3cml0ZWwoY29tbWFuZCwgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5E Q01EKTsKPj4gKwkJd3JpdGVsKHBhZ2VfYWRkciAmIDB4ZmYsIG5hbmQtPnJlZ3MgKyBNQTM1X05G SV9SRUdfTkFOREFERFIpOwo+PiArCQlpZiAoY2hpcC0+b3B0aW9ucyAmIE5BTkRfUk9XX0FERFJf Mykgewo+PiArCQkJd3JpdGVsKChwYWdlX2FkZHIgPj4gOCkgJiAweGZmLAo+PiArCQkJCW5hbmQt PnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFOREFERFIpOwo+PiArCQkJd3JpdGVsKCgocGFnZV9hZGRy ID4+IDE2KSAmIDB4ZmYpIHwgRU5EQUREUiwKPj4gKwkJCQluYW5kLT5yZWdzICsgTUEzNV9ORklf UkVHX05BTkRBRERSKTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCXdyaXRlbCgoKHBhZ2VfYWRkciA+ PiA4KSAmIDB4ZmYpIHwgRU5EQUREUiwKPj4gKwkJCQluYW5kLT5yZWdzICsgTUEzNV9ORklfUkVH X05BTkRBRERSKTsKPj4gKwkJfQo+PiArCQlicmVhazsKPj4gKwo+PiArCWNhc2UgTkFORF9DTURf U0VRSU46Cj4+ICsJCXdyaXRlbChESVNBQkxFX1dQLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVH X05BTkRFQ1RMKTsKPj4gKwkJd3JpdGVsKGNvbW1hbmQsIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9S RUdfTkFORENNRCk7Cj4+ICsJCXdyaXRlbChjb2x1bW4gJiAweGZmLCBuYW5kLT5yZWdzICsgTUEz NV9ORklfUkVHX05BTkRBRERSKTsKPj4gKwkJd3JpdGVsKGNvbHVtbiA+PiA4LCBuYW5kLT5yZWdz ICsgTUEzNV9ORklfUkVHX05BTkRBRERSKTsKPj4gKwkJd3JpdGVsKHBhZ2VfYWRkciAmIDB4ZmYs IG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFOREFERFIpOwo+PiArCQlpZiAoY2hpcC0+b3B0 aW9ucyAmIE5BTkRfUk9XX0FERFJfMykgewo+PiArCQkJd3JpdGVsKChwYWdlX2FkZHIgPj4gOCkg JiAweGZmLAo+PiArCQkJCW5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFOREFERFIpOwo+PiAr CQkJd3JpdGVsKCgocGFnZV9hZGRyID4+IDE2KSAmIDB4ZmYpIHwgRU5EQUREUiwKPj4gKwkJCQlu YW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRBRERSKTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJ CXdyaXRlbCgoKHBhZ2VfYWRkciA+PiA4KSAmIDB4ZmYpIHwgRU5EQUREUiwKPj4gKwkJCQluYW5k LT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRBRERSKTsKPj4gKwkJfQo+PiArCQlicmVhazsKPj4g Kwo+PiArCWNhc2UgTkFORF9DTURfU1RBVFVTOgo+PiArCQl3cml0ZWwoRElTQUJMRV9XUCwgbmFu ZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5ERUNUTCk7Cj4+ICsJCXdyaXRlbChjb21tYW5kLCBu YW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDTUQpOwo+PiArCQlicmVhazsKPj4gKwo+PiAr CWRlZmF1bHQ6Cj4+ICsJCXdyaXRlbChjb21tYW5kLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVH X05BTkRDTUQpOwo+PiArCX0KPj4gKwl3cml0ZWwocmVhZGwobmFuZC0+cmVncyArIE1BMzVfTkZJ X1JFR19OQU5EQ1RMKSB8IERJU0FCTEVfQ1MwLAo+PiArCQluYW5kLT5yZWdzICsgTUEzNV9ORklf UkVHX05BTkRDVEwpOwo+PiArfQo+IC4uLiBpcyB0b3RhbGx5IGxlZ2FjeS4gLT5leGVjX29wKCkg aXMgdGhlIEFQSSB0byBpbXBsZW1lbnQgaW5zdGVhZC4KCgpJIHdpbGwgY2hhbmdlIGl0IHRvIC0+ ZXhlY19vcCgpLgoKCj4+ICsKPj4gKy8qIHNlbGVjdCBjaGlwICovCj4+ICtzdGF0aWMgdm9pZCBt YTM1X25hbmRfc2VsZWN0X2NoaXAoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgaW50IGNzKQo+PiAr ewo+PiArCXN0cnVjdCBtYTM1X25hbmRfaW5mbyAqbmFuZCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJf ZGF0YShjaGlwKTsKPj4gKwo+PiArCWlmIChjcyA9PSAwKQo+PiArCQl3cml0ZWwocmVhZGwobmFu ZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKSAmICh+RElTQUJMRV9DUzApLAo+PiArCQkJ bmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsKPj4gKwllbHNlCj4+ICsJCXdyaXRl bChyZWFkbChuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpIHwgRElTQUJMRV9DUzAs Cj4+ICsJCQluYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgaW50IG1hMzVfbmFuZF9jYWxjdWxhdGVfZWNjKHN0cnVjdCBuYW5kX2NoaXAgKmNo aXAsIGNvbnN0IHVfY2hhciAqZGF0LAo+PiArCQkJCSAgIHVfY2hhciAqZWNjX2NvZGUpCj4+ICt7 Cj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgbWEzNV9uYW5kX3dyaXRl X3BhZ2VfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgY29uc3QgdTggKmJ1ZiwKPj4gKwkJ CQkgICAgICBpbnQgb29iX3JlcXVpcmVkLCBpbnQgcGFnZSkKPj4gK3sKPj4gKwlzdHJ1Y3QgbWEz NV9uYW5kX2luZm8gKm5hbmQgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEoY2hpcCk7Cj4+ICsJ dTggKnB0ciA9ICh1OCAqKSgobG9uZyluYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRSQTAp Owo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4+ICsJdTgg KmVjY19jYWxjID0gY2hpcC0+ZWNjLmNhbGNfYnVmOwo+PiArCj4+ICsJbWVtc2V0KCh2b2lkICop cHRyLCAweEZGLCBtdGQtPm9vYnNpemUpOwo+PiArCW1lbWNweSgodm9pZCAqKXB0ciwgKHZvaWQg KiljaGlwLT5vb2JfcG9pLCBtdGQtPm9vYnNpemUgLSBjaGlwLT5lY2MudG90YWwpOwo+PiArCj4+ ICsJbWEzNV9uYW5kX2NvbW1hbmQoY2hpcCwgTkFORF9DTURfU0VRSU4sIDAsIHBhZ2UpOwo+PiAr CW1hMzVfbmFuZF9kbWFfdHJhbnNmZXIoY2hpcCwgYnVmLCBtdGQtPndyaXRlc2l6ZSwgMHgxKTsK Pj4gKwltYTM1X25hbmRfY29tbWFuZChjaGlwLCBOQU5EX0NNRF9QQUdFUFJPRywgLTEsIC0xKTsK Pj4gKwltYTM1X3dhaXRmdW5jKGNoaXApOwo+PiArCj4+ICsJLyogQ29weSBwYXJpdHkgY29kZSBp biBOQU5EUkEgdG8gY2FsYyAqLwo+PiArCW1lbWNweSgodm9pZCAqKWVjY19jYWxjLAo+PiArCQko dm9pZCAqKShwdHIgKyAobXRkLT5vb2JzaXplIC0gY2hpcC0+ZWNjLnRvdGFsKSksCj4+ICsJCWNo aXAtPmVjYy50b3RhbCk7Cj4+ICsKPj4gKwkvKiBDb3B5IHBhcml0eSBjb2RlIGluIGNhbGMgdG8g b29iX3BvaSAqLwo+PiArCW1lbWNweSgodm9pZCAqKShjaGlwLT5vb2JfcG9pICsgKG10ZC0+b29i c2l6ZSAtIGNoaXAtPmVjYy50b3RhbCkpLAo+PiArCQkodm9pZCAqKWVjY19jYWxjLCBjaGlwLT5l Y2MudG90YWwpOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQg bWEzNV9uYW5kX3JlYWRfcGFnZV9od2VjY19vb2JfZmlyc3Qoc3RydWN0IG5hbmRfY2hpcCAqY2hp cCwgdTggKmJ1ZiwKPj4gKwkJCQkJCWludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+PiArewo+ PiArCXN0cnVjdCBtYTM1X25hbmRfaW5mbyAqbmFuZCA9IG5hbmRfZ2V0X2NvbnRyb2xsZXJfZGF0 YShjaGlwKTsKPj4gKwljaGFyICpwdHIgPSAoY2hhciAqKSgobG9uZyluYW5kLT5yZWdzICsgTUEz NV9ORklfUkVHX05BTkRSQTApOwo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19t dGQoY2hpcCk7Cj4+ICsKPj4gKwkvKiAxLiByZWFkIHRoZSBPT0IgYXJlYSAgKi8KPj4gKwltYTM1 X25hbmRfY29tbWFuZChjaGlwLCBOQU5EX0NNRF9SRUFET09CLCAwLCBwYWdlKTsKPj4gKwltYTM1 X25hbmRfcmVhZF9idWYoY2hpcCwgY2hpcC0+b29iX3BvaSwgbXRkLT5vb2JzaXplKTsKPj4gKwo+ PiArCS8qIDIuIGNvcHkgT09CIGRhdGEgdG8gTkFORFJBIGZvciBwYWdlIHJlYWQgKi8KPj4gKwlt ZW1jcHkoKHZvaWQgKilwdHIsICh2b2lkICopY2hpcC0+b29iX3BvaSwgbXRkLT5vb2JzaXplKTsK Pj4gKwo+PiArCWlmICgoKihwdHIrMikgIT0gMCkgJiYgKCoocHRyKzMpICE9IDApKQo+PiArCQlt ZW1zZXQoKHZvaWQgKilidWYsIDB4ZmYsIG10ZC0+d3JpdGVzaXplKTsKPj4gKwllbHNlIHsKPj4g KwkJLyogMy4gcmVhZCBkYXRhIGZyb20gbmFuZCAqLwo+PiArCQltYTM1X25hbmRfY29tbWFuZChj aGlwLCBOQU5EX0NNRF9SRUFEMCwgMCwgcGFnZSk7Cj4+ICsJCW1hMzVfbmFuZF9kbWFfdHJhbnNm ZXIoY2hpcCwgYnVmLCBtdGQtPndyaXRlc2l6ZSwgMHgwKTsKPj4gKwo+PiArCQkvKiA0LiByZXN0 b3JlIE9PQiBkYXRhIGZyb20gU01SQSAqLwo+PiArCQltZW1jcHkoKHZvaWQgKiljaGlwLT5vb2Jf cG9pLCAodm9pZCAqKXB0ciwgbXRkLT5vb2JzaXplKTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4g MDsKPj4gK30KPj4gKwo+IE5vdCBzdXJlIHdoeSB5b3UgbmVlZCB0aGVzZSB0d28gaW1wbGVtZW50 YXRpb25zPyBVc3VhbGx5IHRoZXJlIGlzIG9ubHkKPiBvbmUgcGVyIGNvbnRyb2xsZXIgYW5kIGZ1 bGx5IGRlcGVuZHMgb24geW91ciBjb250cm9sbGVyCj4gY2FwYWJpbGl0aWVzL2xpbWl0YXRpb25z LiBJZiB5b3UgaGF2ZSBubyBsaW1pdGF0aW9uLCBqdXN0IHN1cHBvcnQgdGhlCj4gc2ltcGxlIGNh c2UuCgoKSSB3aWxsIG1lcmdlIGl0IGludG8gYSBzaW5nbGUgZnVuY3Rpb24uCgoKPj4gK3N0YXRp YyB2b2lkIG1hMzVfbGF5b3V0X29vYl90YWJsZShzdHJ1Y3QgbmFuZF9lY2NsYXlvdXRfdXNlciAq b29idGFibGUsCj4+ICsJCQkJICBpbnQgb29ic2l6ZSwgaW50IGVjY2J5dGVzKQo+PiArewo+PiAr CW9vYnRhYmxlLT5lY2NieXRlcyA9IGVjY2J5dGVzOwo+PiArCW9vYnRhYmxlLT5vb2JhdmFpbCA9 IG9vYnNpemUgLSBTS0lQX1NQQVJFX0JZVEVTIC0gZWNjYnl0ZXM7Cj4+ICsJb29idGFibGUtPm9v YmZyZWVbMF0ub2Zmc2V0ID0gU0tJUF9TUEFSRV9CWVRFUzsKPj4gKwlvb2J0YWJsZS0+b29iZnJl ZVswXS5sZW5ndGggPSBvb2JzaXplIC0gZWNjYnl0ZXMgLSBvb2J0YWJsZS0+b29iZnJlZVswXS5v ZmZzZXQ7Cj4+ICsKPj4gKwlvb2J0YWJsZS0+b29iZnJlZVsxXS5vZmZzZXQgPSAwOwo+PiArCW9v YnRhYmxlLT5vb2JmcmVlWzFdLmxlbmd0aCA9IDA7Cj4+ICt9Cj4gSSdtIG5vdCBzdXJlIHdoeSB5 b3Ugd291bGQgbmVlZCB0aGF0LgoKCkkgd2lsbCBmaXggaXQuCgoKPj4gKwo+PiArc3RhdGljIGlu dCBtYTM1X25hbmRfcmVhZF9vb2JfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgaW50IHBh Z2UpCj4+ICt7Cj4+ICsJc3RydWN0IG1hMzVfbmFuZF9pbmZvICpuYW5kID0gbmFuZF9nZXRfY29u dHJvbGxlcl9kYXRhKGNoaXApOwo+PiArCWNoYXIgKnB0ciA9IChjaGFyICopKChsb25nKW5hbmQt PnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORFJBMCk7Cj4+ICsJc3RydWN0IG10ZF9pbmZvICptdGQg PSBuYW5kX3RvX210ZChjaGlwKTsKPj4gKwo+PiArCW1hMzVfbmFuZF9jb21tYW5kKGNoaXAsIE5B TkRfQ01EX1JFQURPT0IsIDAsIHBhZ2UpOwo+PiArCW1hMzVfbmFuZF9yZWFkX2J1ZihjaGlwLCBj aGlwLT5vb2JfcG9pLCBtdGQtPm9vYnNpemUpOwo+PiArCj4+ICsJLyogY29weSBPT0IgZGF0YSB0 byBOQU5EUkEgZm9yIHBhZ2UgcmVhZCAqLwo+PiArCW1lbWNweSgodm9pZCAqKXB0ciwgKHZvaWQg KiljaGlwLT5vb2JfcG9pLCBtdGQtPm9vYnNpemUpOwo+PiArCj4+ICsJaWYgKCgqKHB0cisyKSAh PSAwKSAmJiAoKihwdHIrMykgIT0gMCkpCj4+ICsJCW1lbXNldCgodm9pZCAqKWNoaXAtPm9vYl9w b2ksIDB4ZmYsIG10ZC0+b29ic2l6ZSk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+ PiArc3RhdGljIGlycXJldHVybl90IG1hMzVfbmFuZF9pcnEoaW50IGlycSwgdm9pZCAqaWQpCj4+ ICt7Cj4+ICsJc3RydWN0IG1hMzVfbmFuZF9pbmZvICpuYW5kID0gKHN0cnVjdCBtYTM1X25hbmRf aW5mbyAqKWlkOwo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoJm5hbmQt PmNoaXApOwo+PiArCWludCBzdGF0ID0gMDsKPj4gKwl1MzIgaXNyOwo+PiArCj4+ICsJc3Bpbl9s b2NrKCZuYW5kLT5kbWFfbG9jayk7Cj4+ICsKPj4gKwlpc3IgPSByZWFkbChuYW5kLT5yZWdzICsg TUEzNV9ORklfUkVHX05BTkRJTlRTVFMpOwo+PiArCWlmIChpc3IgJiBJTlRfRUNDKSB7Cj4+ICsJ CWRtYV9zeW5jX3NpbmdsZV9mb3JfY3B1KG5hbmQtPmRldiwgbmFuZC0+ZG1hX2FkZHIsIG10ZC0+ d3JpdGVzaXplLAo+PiArCQkJCQlETUFfRlJPTV9ERVZJQ0UpOwo+PiArCQlzdGF0ID0gbWEzNV9u ZmlfY29ycmVjdCgmbmFuZC0+Y2hpcCwgKHVuc2lnbmVkIGxvbmcpbmFuZC0+ZG1hX2J1Zik7Cj4+ ICsJCWlmIChzdGF0IDwgMCkgewo+PiArCQkJbXRkLT5lY2Nfc3RhdHMuZmFpbGVkKys7Cj4+ICsJ CQl3cml0ZWwoRE1BX1JTVCB8IERNQV9FTiwgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19ETUFD VEwpOwo+PiArCQkJd3JpdGVsKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfTkFORENU TCkgfCBTV1JTVCwKPj4gKwkJCQluYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwpOwo+ PiArCQl9IGVsc2UgaWYgKHN0YXQgPiAwKSB7Cj4+ICsJCQltdGQtPmVjY19zdGF0cy5jb3JyZWN0 ZWQgKz0gc3RhdDsgICAvKiBBZGQgY29ycmVjdGVkIGJpdCBjb3VudCAqLwo+PiArCQl9Cj4+ICsJ CXdyaXRlbChJTlRfRUNDLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRJTlRTVFMpOwo+ PiArCX0KPj4gKwlpZiAoaXNyICYgSU5UX0RNQSkgewo+PiArCQl3cml0ZWwoSU5UX0RNQSwgbmFu ZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5ESU5UU1RTKTsKPj4gKwkJY29tcGxldGUoJm5hbmQt PmNvbXBsZXRlKTsKPj4gKwl9Cj4+ICsJc3Bpbl91bmxvY2soJm5hbmQtPmRtYV9sb2NrKTsKPj4g Kwo+PiArCXJldHVybiBJUlFfSEFORExFRDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBtYTM1 X25hbmRfYXR0YWNoX2NoaXAoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCkKPj4gK3sKPj4gKwlzdHJ1 Y3QgbWEzNV9uYW5kX2luZm8gKm5hbmQgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEoY2hpcCk7 Cj4+ICsJc3RydWN0IG10ZF9pbmZvICptdGQgPSBuYW5kX3RvX210ZChjaGlwKTsKPj4gKwl1bnNp Z25lZCBpbnQgcmVnOwo+PiArCj4gUGxlYXNlIGhhdmUgYSBsb29rIGF0IG90aGVyIGNvbnRyb2xs ZXIgZHJpdmVycy4gWW91IG5lZWQgdG8gYWxsb3c6Cj4KPiAtIG5vIGNvcnJlY3Rpb24KPiAtIHN3 IGNvcnJlY3Rpb24KPiAtIGh3IEJDSCBjb3JyZWN0aW9uCgoKSSB3aWxsIGZpeCBpdC4KCgo+PiAr CS8qIFNldCBQU2l6ZSAqLwo+PiArCXJlZyA9IHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9S RUdfTkFORENUTCkgJiAoflBTSVpFX01BU0spOwo+PiArCWlmIChtdGQtPndyaXRlc2l6ZSA9PSAy MDQ4KQo+PiArCQl3cml0ZWwocmVnIHwgUFNJWkVfMkssIG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9S RUdfTkFORENUTCk7Cj4+ICsJZWxzZSBpZiAobXRkLT53cml0ZXNpemUgPT0gNDA5NikKPj4gKwkJ d3JpdGVsKHJlZyB8IFBTSVpFXzRLLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRDVEwp Owo+PiArCWVsc2UgaWYgKG10ZC0+d3JpdGVzaXplID09IDgxOTIpCj4+ICsJCXdyaXRlbChyZWcg fCBQU0laRV84SywgbmFuZC0+cmVncyArIE1BMzVfTkZJX1JFR19OQU5EQ1RMKTsKPj4gKwo+PiAr CWlmIChjaGlwLT5lY2Muc3RyZW5ndGggPT0gMCkgewo+PiArCQluYW5kLT5iY2ggPSBCQ0hfTk9O RTsgLyogTm8gRUNDICovCj4+ICsJCW1hMzVfbGF5b3V0X29vYl90YWJsZSgmbmFuZC0+bmFuZF9v b2IsIG10ZC0+b29ic2l6ZSwKPj4gKwkJCQkJbWEzNV9wYXJpdHlbbXRkLT53cml0ZXNpemU+PjEy XVswXSk7Cj4+ICsKPj4gKwl9IGVsc2UgaWYgKGNoaXAtPmVjYy5zdHJlbmd0aCA8PSA4KSB7Cj4+ ICsJCW5hbmQtPmJjaCA9IEJDSF9UODsgLyogVDggKi8KPj4gKwkJbWEzNV9sYXlvdXRfb29iX3Rh YmxlKCZuYW5kLT5uYW5kX29vYiwgbXRkLT5vb2JzaXplLAo+PiArCQkJCQltYTM1X3Bhcml0eVtt dGQtPndyaXRlc2l6ZT4+MTJdWzFdKTsKPj4gKwo+PiArCX0gZWxzZSBpZiAoY2hpcC0+ZWNjLnN0 cmVuZ3RoIDw9IDEyKSB7Cj4+ICsJCW5hbmQtPmJjaCA9IEJDSF9UMTI7IC8qIFQxMiAqLwo+PiAr CQltYTM1X2xheW91dF9vb2JfdGFibGUoJm5hbmQtPm5hbmRfb29iLCBtdGQtPm9vYnNpemUsCj4+ ICsJCQkJCW1hMzVfcGFyaXR5W210ZC0+d3JpdGVzaXplPj4xMl1bMl0pOwo+PiArCj4+ICsJfSBl bHNlIGlmIChjaGlwLT5lY2Muc3RyZW5ndGggPD0gMjQpIHsKPj4gKwkJbmFuZC0+YmNoID0gQkNI X1QyNDsgLyogVDI0ICovCj4+ICsJCW1hMzVfbGF5b3V0X29vYl90YWJsZSgmbmFuZC0+bmFuZF9v b2IsIG10ZC0+b29ic2l6ZSwKPj4gKwkJCQkJbWEzNV9wYXJpdHlbbXRkLT53cml0ZXNpemU+PjEy XVszXSk7Cj4+ICsKPj4gKwl9IGVsc2Ugewo+PiArCQlwcl93YXJuKCJOQU5EIENvbnRyb2xsZXIg aXMgbm90IHN1cHBvcnQgdGhpcyBmbGFzaC4gKCVkLCAlZClcbiIsCj4+ICsJCQltdGQtPndyaXRl c2l6ZSwgbXRkLT5vb2JzaXplKTsKPj4gKwl9Cj4+ICsKPj4gKwljaGlwLT5lY2Muc3RlcHMgPSBt dGQtPndyaXRlc2l6ZSAvIGNoaXAtPmVjYy5zaXplOwo+PiArCWNoaXAtPmVjYy5ieXRlcyA9IG5h bmQtPm5hbmRfb29iLmVjY2J5dGVzIC8gY2hpcC0+ZWNjLnN0ZXBzOwo+PiArCWNoaXAtPmVjYy50 b3RhbCA9IG5hbmQtPm5hbmRfb29iLmVjY2J5dGVzOwo+PiArCW10ZF9zZXRfb29ibGF5b3V0KG10 ZCwgJm1hMzVfb29ibGF5b3V0X29wcyk7Cj4+ICsKPj4gKwkvKiBhZGQgbXRkLWlkLiBUaGUgc3Ry aW5nIHNob3VsZCBzYW1lIGFzIHVib290IGRlZmluaXRpb24gKi8KPj4gKwltdGQtPm5hbWUgPSAi bmFuZDAiOwo+PiArCj4+ICsJbWEzNV9uYW5kX2h3ZWNjX2luaXQobmFuZCk7Cj4+ICsKPj4gKwl3 cml0ZWwoRU5BQkxFX1dQLCBuYW5kLT5yZWdzICsgTUEzNV9ORklfUkVHX05BTkRFQ1RMKTsKPj4g Kwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG5hbmRf Y29udHJvbGxlcl9vcHMgbWEzNV9uYW5kX2NvbnRyb2xsZXJfb3BzID0gewo+PiArCS5hdHRhY2hf Y2hpcCA9IG1hMzVfbmFuZF9hdHRhY2hfY2hpcCwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbnQg bWEzNV9uYW5kX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4+ICt7Cj4+ICsJ c3RydWN0IG1hMzVfbmFuZF9pbmZvICpuYW5kOwo+PiArCXN0cnVjdCBuYW5kX2NoaXAgKmNoaXA7 Cj4+ICsJc3RydWN0IG10ZF9pbmZvICptdGQ7Cj4+ICsJaW50IHJldHZhbCA9IDA7Cj4+ICsKPj4g KwluYW5kID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigqbmFuZCksIEdGUF9LRVJO RUwpOwo+PiArCWlmICghbmFuZCkKPj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4+ICsKPj4gKwluYW5k X2NvbnRyb2xsZXJfaW5pdCgmbmFuZC0+Y29udHJvbGxlcik7Cj4+ICsKPj4gKwluYW5kLT5yZWdz ID0gZGV2bV9wbGF0Zm9ybV9pb3JlbWFwX3Jlc291cmNlKHBkZXYsIDApOwo+PiArCWlmIChJU19F UlIobmFuZC0+cmVncykpCj4+ICsJCXJldHVybiBQVFJfRVJSKG5hbmQtPnJlZ3MpOwo+PiArCj4+ ICsJbmFuZC0+ZGV2ID0gJnBkZXYtPmRldjsKPj4gKwljaGlwID0gJm5hbmQtPmNoaXA7Cj4+ICsJ bXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4+ICsJbmFuZF9zZXRfY29udHJvbGxlcl9kYXRhKGNo aXAsIG5hbmQpOwo+PiArCW5hbmRfc2V0X2ZsYXNoX25vZGUoY2hpcCwgcGRldi0+ZGV2Lm9mX25v ZGUpOwo+PiArCj4+ICsJbXRkLT5wcml2ID0gY2hpcDsKPj4gKwltdGQtPm93bmVyID0gVEhJU19N T0RVTEU7Cj4+ICsJbXRkLT5kZXYucGFyZW50ID0gJnBkZXYtPmRldjsKPj4gKwo+PiArCW5hbmQt PmNsayA9IGRldm1fY2xrX2dldCgmcGRldi0+ZGV2LCAibmFuZF9nYXRlIik7Cj4gZGV2bV9jbGtf Z2V0X2VuYWJsZWQoKQoKCkkgd2lsbCB1c2UgZGV2bV9jbGtfZ2V0X2VuYWJsZWQoKS4KCgo+PiAr CWlmIChJU19FUlIobmFuZC0+Y2xrKSkKPj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoJnBkZXYt PmRldiwgUFRSX0VSUihuYW5kLT5jbGspLAo+PiArCQkJCSAgICAgImZhaWxlZCB0byBmaW5kIG5h bmQgY2xvY2tcbiIpOwo+PiArCj4+ICsJcmV0dmFsID0gY2xrX3ByZXBhcmVfZW5hYmxlKG5hbmQt PmNsayk7Cj4+ICsJaWYgKHJldHZhbCA8IDApIHsKPj4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSBjbG9ja1xuIik7Cj4+ICsJCXJldHZhbCA9IC1FTlhJTzsKPj4gKwl9 Cj4+ICsKPj4gKwluYW5kLT5jaGlwLmNvbnRyb2xsZXIgICAgPSAmbmFuZC0+Y29udHJvbGxlcjsK Pj4gKwo+PiArCWNoaXAtPmxlZ2FjeS5jbWRmdW5jICAgICA9IG1hMzVfbmFuZF9jb21tYW5kOwo+ PiArCWNoaXAtPmxlZ2FjeS53YWl0ZnVuYyAgICA9IG1hMzVfd2FpdGZ1bmM7Cj4+ICsJY2hpcC0+ bGVnYWN5LnJlYWRfYnl0ZSAgID0gbWEzNV9uYW5kX3JlYWRfYnl0ZTsKPj4gKwljaGlwLT5sZWdh Y3kuc2VsZWN0X2NoaXAgPSBtYTM1X25hbmRfc2VsZWN0X2NoaXA7Cj4+ICsJY2hpcC0+bGVnYWN5 LnJlYWRfYnVmICAgID0gbWEzNV9yZWFkX2J1Zl9kbWE7Cj4+ICsJY2hpcC0+bGVnYWN5LndyaXRl X2J1ZiAgID0gbWEzNV93cml0ZV9idWZfZG1hOwo+PiArCWNoaXAtPmxlZ2FjeS5kZXZfcmVhZHkg ICA9IG1hMzVfbmFuZF9kZXZyZWFkeTsKPj4gKwljaGlwLT5sZWdhY3kuY2hpcF9kZWxheSAgPSAy NTsgLyogdXMgKi8KPiBQbGVhc2UgY29udmVydCB0aGlzIGRyaXZlciB0byAtPmV4ZWNfb3AoKS4K Pgo+IE5vIGludHJvZHVjZSBvZiBsZWdhY3kgaG9va3Mgd2lsbCBiZSBhY2NlcHRlZC4KCgpPa2F5 LiBJIHdpbGwgdXNlIGV4ZWNfb3AoKS4KCgo+PiArCj4+ICsJLyogUmVhZCBPT0IgZGF0YSBmaXJz dCwgdGhlbiBIVyByZWFkIHBhZ2UgKi8KPj4gKwljaGlwLT5lY2MuaHdjdGwgICAgICA9IG1hMzVf bmFuZF9lbmFibGVfaHdlY2M7Cj4+ICsJY2hpcC0+ZWNjLmNhbGN1bGF0ZSAgPSBtYTM1X25hbmRf Y2FsY3VsYXRlX2VjYzsKPj4gKwljaGlwLT5lY2MuY29ycmVjdCAgICA9IG1hMzVfbmFuZF9jb3Jy ZWN0X2RhdGE7Cj4+ICsJY2hpcC0+ZWNjLndyaXRlX3BhZ2UgPSBtYTM1X25hbmRfd3JpdGVfcGFn ZV9od2VjYzsKPj4gKwljaGlwLT5lY2MucmVhZF9wYWdlICA9IG1hMzVfbmFuZF9yZWFkX3BhZ2Vf aHdlY2Nfb29iX2ZpcnN0Owo+PiArCWNoaXAtPmVjYy5yZWFkX29vYiAgID0gbWEzNV9uYW5kX3Jl YWRfb29iX2h3ZWNjOwo+PiArCWNoaXAtPm9wdGlvbnMgfD0gKE5BTkRfTk9fU1VCUEFHRV9XUklU RSB8IE5BTkRfVVNFU19ETUEpOwo+PiArCj4+ICsJbWEzNV9uYW5kX2luaXRpYWxpemUobmFuZCk7 Cj4+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgbmFuZCk7Cj4+ICsKPj4gKwluYW5kLT5j b250cm9sbGVyLm9wcyA9ICZtYTM1X25hbmRfY29udHJvbGxlcl9vcHM7Cj4+ICsKPj4gKwluYW5k LT5pcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOwo+PiArCWlmIChuYW5kLT5pcnEgPCAw KQo+PiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZSgmcGRldi0+ZGV2LCBuYW5kLT5pcnEsCj4+ICsJ CQkJICAgICAiZmFpbGVkIHRvIGdldCBwbGF0Zm9ybSBpcnFcbiIpOwo+PiArCj4+ICsJcmV0dmFs ID0gZGV2bV9yZXF1ZXN0X2lycSgmcGRldi0+ZGV2LCBuYW5kLT5pcnEsIG1hMzVfbmFuZF9pcnEs Cj4+ICsJCQkJICBJUlFGX1RSSUdHRVJfSElHSCwgIm1hMzVkMS1uYW5kIiwgbmFuZCk7Cj4+ICsJ aWYgKHJldHZhbCkgewo+PiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJmYWlsZWQgdG8gcmVxdWVz dCBOQU5EIGlycVxuIik7Cj4+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZShuYW5kLT5jbGspOwo+ PiArCQlyZXR1cm4gLUVOWElPOwo+PiArCX0KPj4gKwo+PiArCXJldHZhbCA9IG5hbmRfc2Nhbihj aGlwLCAxKTsKPiBzL3JldHZhbC9yZXQvCgoKSSdtIG5vdCBzdXJlIHdoYXQgdGhpcyBtZWFucy4g U2hvdWxkIGl0IGJlIGNoYW5nZWQgdG8gcmV0ID0gbmFuZF9zY2FuKCk/CgoKPj4gKwlpZiAocmV0 dmFsKQo+PiArCQlyZXR1cm4gcmV0dmFsOwo+PiArCj4+ICsJaWYgKG10ZF9kZXZpY2VfcmVnaXN0 ZXIobXRkLCBuYW5kLT5wYXJ0cywgbmFuZC0+bnJfcGFydHMpKSB7Cj4gcmV0ID0KPiBpZiAocmV0 KQoKCkkgd2lsbCBmaXggaXQuCgoKPj4gKwkJbmFuZF9jbGVhbnVwKGNoaXApOwo+PiArCQlkZXZt X2tmcmVlKCZwZGV2LT5kZXYsIG5hbmQpOwo+PiArCQlyZXR1cm4gcmV0dmFsOwo+PiArCX0KPj4g Kwo+PiArCXJldHVybiByZXR2YWw7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIG1hMzVfbmFu ZF9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sKPj4gKwlzdHJ1Y3Qg bWEzNV9uYW5kX2luZm8gKm5hbmQgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKPj4gKwlp bnQgcmV0Owo+PiArCj4+ICsJZGV2bV9mcmVlX2lycSgmcGRldi0+ZGV2LCBuYW5kLT5pcnEsIG5h bmQpOwo+PiArCXJldCA9IG10ZF9kZXZpY2VfdW5yZWdpc3RlcihuYW5kX3RvX210ZCgmbmFuZC0+ Y2hpcCkpOwo+PiArCVdBUk5fT04ocmV0KTsKPj4gKwluYW5kX2NsZWFudXAoJm5hbmQtPmNoaXAp Owo+PiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShuYW5kLT5jbGspOwo+PiArfQo+PiArCj4+ICsv KiBQTSBTdXBwb3J0ICovCj4+ICsjaWZkZWYgQ09ORklHX1BNCj4+ICtzdGF0aWMgaW50IG1hMzVf bmFuZF9zdXNwZW5kKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsIHBtX21lc3NhZ2VfdCBw bSkKPj4gK3sKPj4gKwlzdHJ1Y3QgbWEzNV9uYW5kX2luZm8gKm5hbmQgPSBwbGF0Zm9ybV9nZXRf ZHJ2ZGF0YShwZGV2KTsKPj4gKwl1bnNpZ25lZCBsb25nIHRpbWVvID0gamlmZmllcyArIEhaLzI7 Cj4+ICsKPj4gKwkvKiB3YWl0IERNQUMgdG8gcmVhZHkgKi8KPj4gKwl3aGlsZSAoMSkgewo+PiAr CQlpZiAoKHJlYWRsKG5hbmQtPnJlZ3MgKyBNQTM1X05GSV9SRUdfRE1BQ1RMKSAmIERNQV9CVVNZ KSA9PSAwKQo+PiArCQkJYnJlYWs7Cj4+ICsJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIHRpbWVv KSkKPj4gKwkJCXJldHVybiAtRVRJTUVET1VUOwo+PiArCX0KPj4gKwo+PiArCWNsa19kaXNhYmxl KG5hbmQtPmNsayk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlu dCBtYTM1X25hbmRfcmVzdW1lKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4+ICt7Cj4+ ICsJc3RydWN0IG1hMzVfbmFuZF9pbmZvICpuYW5kID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRl dik7Cj4+ICsKPj4gKwljbGtfZW5hYmxlKG5hbmQtPmNsayk7Cj4+ICsJbWEzNV9uYW5kX2h3ZWNj X2luaXQobmFuZCk7Cj4+ICsJbWEzNV9uYW5kX2RtYWNfaW5pdChuYW5kKTsKPj4gKwo+PiArCXJl dHVybiAwOwo+PiArfQo+PiArCj4+ICsjZWxzZQo+PiArI2RlZmluZSBtYTM1X25hbmRfc3VzcGVu ZCBOVUxMCj4+ICsjZGVmaW5lIG1hMzVfbmFuZF9yZXN1bWUgTlVMTAo+PiArI2VuZGlmCj4+ICsK Pj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG1hMzVfbmZpX29mX21hdGNoW10g PSB7Cj4+ICsJeyAuY29tcGF0aWJsZSA9ICJudXZvdG9uLG1hMzVkMS1uYW5kIiB9LAo+PiArCXt9 LAo+PiArfTsKPj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIG1hMzVfbmZpX29mX21hdGNoKTsK Pj4gKwo+PiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbWEzNV9uYW5kX2RyaXZlciA9 IHsKPj4gKwkuZHJpdmVyID0gewo+PiArCQkubmFtZSA9ICJtYTM1ZDEtbmFuZCIsCj4+ICsJCS5v Zl9tYXRjaF90YWJsZSA9IG1hMzVfbmZpX29mX21hdGNoLAo+PiArCX0sCj4+ICsJLnByb2JlID0g bWEzNV9uYW5kX3Byb2JlLAo+PiArCS5yZW1vdmVfbmV3ID0gbWEzNV9uYW5kX3JlbW92ZSwKPj4g Kwkuc3VzcGVuZCA9IG1hMzVfbmFuZF9zdXNwZW5kLAo+PiArCS5yZXN1bWUgPSBtYTM1X25hbmRf cmVzdW1lLAo+PiArfTsKPj4gKwo+PiArbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihtYTM1X25hbmRf ZHJpdmVyKTsKPj4gKwo+PiArTU9EVUxFX0RFU0NSSVBUSU9OKCJOdXZvdG9uIG1hMzUgTkFORCBk cml2ZXIiKTsKPj4gK01PRFVMRV9BVVRIT1IoIkh1aS1QaW5nIENoZW4gPGhwY2hlbjBudnRAZ21h aWwuY29tPiIpOwo+PiArTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo+Cj4gVGhhbmtzLAo+IE1pcXXD qGwKCgpCZXN0IHJlZ2FyZHMsCgpIdWktUGluZyBDaGVuCgoKCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpMaW51eCBNVEQgZGlzY3Vzc2lvbiBt YWlsaW5nIGxpc3QKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1tdGQvCg== 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id CDBF6C7115E for ; Thu, 29 Aug 2024 04:01:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:In-Reply-To:From:References:Cc:To:Subject:MIME-Version:Date: Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=mZDVsY0O6zp9Qo6VeUuJnL7Ovlzlihww3S82jvz9RFg=; b=BWbqLUcZiY8QAhEtU5b1C+vyiY 3JzwOnaLbFDxv1Ea9A4KpOepjZd2qeiCQpLPJcAgUPo0ev/TeUqHZopgVfnzzj3MsD1E/aculmmwG blwyT8k2pB+yLPsJh1XgzFc1FZqJcr5D0d+wtuVXdqDFTu4bvAyk8R7ufZlAnbo+Fy8YcR5+9GHxz 8nH4VyYMgOjhhvwcBaPQYK52AwuDkaEZq6UUYLLHU41e1SssRHDDq1EKRgGsx7wsHYVKxp9QvCfPG giwyk1qhDlvwEllpZcTO4auysCM1Y/kKdPo7AwCjkGez75vm5tNQ6CNi9buchizxZxuLM7rvIjIvO skDG8JyA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sjWLA-00000000Qwf-2gqy; Thu, 29 Aug 2024 04:00:56 +0000 Received: from mail-ot1-x32a.google.com ([2607:f8b0:4864:20::32a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sjVLx-00000000Het-1GA9; Thu, 29 Aug 2024 02:57:45 +0000 Received: by mail-ot1-x32a.google.com with SMTP id 46e09a7af769-70c9cda7f1cso112292a34.3; Wed, 28 Aug 2024 19:57:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724900259; x=1725505059; darn=lists.infradead.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=mZDVsY0O6zp9Qo6VeUuJnL7Ovlzlihww3S82jvz9RFg=; b=kbc999EIE4uMxDVS5hYn5wF4f0ccaleecxwaCrMYg5aaz1f+NLMAonvGl2ZjcDg4Ml yG5A6/Z0yr/PU8bMTkzpTCskSwm38ep+e+3Al0MVBP6EXNAGxFO2iLkcL4InBjzW1wrW Y7HtTrOdiPmZXxabaDDSM3WhwrCBptQVMyGNwe2WVoWCdUuFcY6wiuW7U+inTG/Y3B2m RtLNadGoEGUJRz5xu9AhqpU6v8PkjGsiCb7vbKGJomOug3bX3IR8Y0nnBBzn9MHI6p7x Zu7jQ5aT6WKkMIeDhnAjlQg1O2wQ1uLUIFKTOhf8UICpSvq3zdDLnD7T7IHR9HGeKeIu O2vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724900259; x=1725505059; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mZDVsY0O6zp9Qo6VeUuJnL7Ovlzlihww3S82jvz9RFg=; b=vPP9D965dgXlM+Pchke/Lrfq7jBmLAfshT/oPYnBcq5ZZ+KFLtdiEq7ruBUk4ohjYS 5I+MXEDzsc9xlLjOy/U0q2tJ/EGPp4+5uev73E2lEbJOj/ExGGF/uDgYLcnB1gAZhbjH fPZm2m+rvU88MMcEdjTXYuMpQ6GLN2dRuGmjdgHxoyRG2efBFG0U/HJ5782Y6A9qqrMI As3L7a8xM4lUZEnbdAtT1whPn3sF4r3aXRPE8+Cd5pcAlTQYxSodqu9xAti6EbmS4R8Y n7l2sABtkRXYkEddyZ1FEWF+mZcUHSa8qdmzsd1Tsd3Lgb3wRMOHWKDaVhZRqWFRloQS RSKA== X-Forwarded-Encrypted: i=1; AJvYcCV3Jx1/BKCFm99fK7NfVzXL2krY6g2HFjl+dq7iCVmGh5Sg4mRw4Gia0Iuq2w4suEBpqGOq43qZkaZA@lists.infradead.org, AJvYcCViB88Gn7Bys/tmtgVCyLwCA5bRV0R9c8gpn2ZMed5Ggcj5J8Qvgsg8+nEdEjgROpjNiIR7X8b9Q4pvd5nm1UUp@lists.infradead.org X-Gm-Message-State: AOJu0YwinURbBHGobpZSAd1wX/UWDuyDZ9m5CuLIevaw+djAwYgjz4v5 yB1CNFUrR4eqj+IcB9CJOhPzIz774+ShLix+Ty2W8iezxBzwXntg X-Google-Smtp-Source: AGHT+IFHU3B8WAjDc87T+xrsXLLTlNpfYXNyC4HWjX90bS3/ufKoMRFpL+YMWDs5XdQMDHm6WyFstw== X-Received: by 2002:a05:6358:718e:b0:1b5:ec56:a10f with SMTP id e5c5f4694b2df-1b603c14b38mr215335555d.11.1724900259108; Wed, 28 Aug 2024 19:57:39 -0700 (PDT) Received: from [172.19.1.53] (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-715e569edc9sm172310b3a.138.2024.08.28.19.57.35 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 28 Aug 2024 19:57:38 -0700 (PDT) Message-ID: <0eb96a1e-da2b-45fb-9319-73b0b7cea564@gmail.com> Date: Thu, 29 Aug 2024 10:57:34 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3 2/2] mtd: rawnand: nuvoton: add new driver for the Nuvoton MA35 SoC To: Miquel Raynal Cc: richard@nod.at, vigneshr@ti.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, sumit.semwal@linaro.org, christian.koenig@amd.com, esben@geanix.com, linux-arm-kernel@lists.infradead.org, linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org References: <20240821071132.281018-1-hpchen0nvt@gmail.com> <20240821071132.281018-3-hpchen0nvt@gmail.com> <20240823190206.6cd76b43@xps-13> Content-Language: en-US From: Hui-Ping Chen In-Reply-To: <20240823190206.6cd76b43@xps-13> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240828_195741_407602_8E84C11F X-CRM114-Status: GOOD ( 38.70 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Dear Miquel, Thank you for your reply. On 2024/8/24 上午 01:02, Miquel Raynal wrote: > Hi Hui-Ping, > > hpchen0nvt@gmail.com wrote on Wed, 21 Aug 2024 07:11:32 +0000: > >> Nuvoton MA35 SoCs NAND Flash Interface Controller >> supports 2KB, 4KB and 8KB page size, and up to 8-bit, > Suffix is: kiB Okay, I will fix that. >> 12-bit, and 24-bit hardware ECC calculation circuit >> to protect data communication. > It's not the communication, it's the data itself. Okay, I will remove that. >> Signed-off-by: Hui-Ping Chen >> --- >> drivers/mtd/nand/raw/Kconfig | 8 + >> drivers/mtd/nand/raw/Makefile | 1 + >> drivers/mtd/nand/raw/nuvoton_ma35d1_nand.c | 1068 ++++++++++++++++++++ >> 3 files changed, 1077 insertions(+) >> create mode 100644 drivers/mtd/nand/raw/nuvoton_ma35d1_nand.c >> >> diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig >> index 614257308516..932bf2215470 100644 >> --- a/drivers/mtd/nand/raw/Kconfig >> +++ b/drivers/mtd/nand/raw/Kconfig >> @@ -448,6 +448,14 @@ config MTD_NAND_RENESAS >> Enables support for the NAND controller found on Renesas R-Car >> Gen3 and RZ/N1 SoC families. >> >> +config MTD_NAND_NVT_MA35 > Is NVT so common or is it just one opportunity to save 4 chars in a > Kconfig file?? I'd prefer something more easy to understand. I will change it to MTD_NAND_NUVOTON_MA35. >> + tristate "Nuvoton MA35 SoC NAND controller" >> + depends on ARCH_MA35 || COMPILE_TEST >> + depends on OF >> + help >> + Enables support for the NAND controller found on >> + the Nuvoton MA35 series SoCs. >> + >> comment "Misc" >> >> config MTD_SM_COMMON >> diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile >> index 25120a4afada..cdfdfee3f5f3 100644 >> --- a/drivers/mtd/nand/raw/Makefile >> +++ b/drivers/mtd/nand/raw/Makefile >> @@ -57,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_INTEL_LGM) += intel-nand-controller.o >> obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip-nand-controller.o >> obj-$(CONFIG_MTD_NAND_PL35X) += pl35x-nand-controller.o >> obj-$(CONFIG_MTD_NAND_RENESAS) += renesas-nand-controller.o >> +obj-$(CONFIG_MTD_NAND_NVT_MA35) += nuvoton_ma35d1_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/nuvoton_ma35d1_nand.c b/drivers/mtd/nand/raw/nuvoton_ma35d1_nand.c >> new file mode 100644 >> index 000000000000..b4586d7a7a45 >> --- /dev/null >> +++ b/drivers/mtd/nand/raw/nuvoton_ma35d1_nand.c >> @@ -0,0 +1,1068 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Copyright (C) 2024 Nuvoton Technology Corp. >> + */ >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + > Not sure why you didn't sort the below includes with the ones above? I will sort it. >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/* NFI DMA Registers */ >> +#define MA35_NFI_REG_BUFFER0 (0x000) > You don't need all these parentheses Okay, I will remove it. >> +#define MA35_NFI_REG_DMACTL (0x400) >> +#define DMA_EN BIT(0) >> +#define DMA_RST BIT(1) >> +#define DMA_BUSY BIT(9) >> + >> +#define MA35_NFI_REG_DMASA (0x408) >> +#define MA35_NFI_REG_DMABCNT (0x40C) >> +#define MA35_NFI_REG_DMAINTEN (0x410) >> +#define MA35_NFI_REG_DMAINTSTS (0x414) >> + >> +/* NFI Global Registers */ >> +#define MA35_NFI_REG_GCTL (0x800) >> +#define NAND_EN BIT(3) >> +#define MA35_NFI_REG_GINTEN (0x804) >> +#define MA35_NFI_REG_GINTSTS (0x808) >> + >> +/* NAND-type Flash Registers */ >> +#define MA35_NFI_REG_NANDCTL (0x8A0) >> +#define SWRST BIT(0) >> +#define DMA_W_EN BIT(1) >> +#define DMA_R_EN BIT(2) >> +#define ECC_CHK BIT(7) >> +#define PROT3BEN BIT(8) >> +#define PSIZE_2K (1 << 16) >> +#define PSIZE_4K (2 << 16) >> +#define PSIZE_8K (3 << 16) >> +#define PSIZE_MASK (3 << 16) >> +#define BCH_T24 BIT(18) >> +#define BCH_T8 BIT(20) >> +#define BCH_T12 BIT(21) >> +#define BCH_NONE (0x0) >> +#define BCH_MASK (0x1f << 18) >> +#define ECC_EN BIT(23) >> +#define DISABLE_CS0 BIT(25) >> + >> +#define MA35_NFI_REG_NANDTMCTL (0x8A4) >> +#define MA35_NFI_REG_NANDINTEN (0x8A8) >> +#define MA35_NFI_REG_NANDINTSTS (0x8AC) >> +#define INT_DMA BIT(0) >> +#define INT_ECC BIT(2) >> +#define INT_RB0 BIT(10) >> +#define INT_RB0_STS BIT(18) >> + >> +#define MA35_NFI_REG_NANDCMD (0x8B0) >> +#define MA35_NFI_REG_NANDADDR (0x8B4) >> +#define ENDADDR BIT(31) >> + >> +#define MA35_NFI_REG_NANDDATA (0x8B8) >> +#define MA35_NFI_REG_NANDRACTL (0x8BC) >> +#define MA35_NFI_REG_NANDECTL (0x8C0) >> +#define ENABLE_WP (0x0) >> +#define DISABLE_WP BIT(0) >> + >> +#define MA35_NFI_REG_NANDECCES0 (0x8D0) >> +#define ECC_STATUS_MASK (0x3) >> +#define ECC_ERR_CNT_MASK (0x1f) >> + >> +#define MA35_NFI_REG_NANDECCES1 (0x8D4) >> +#define MA35_NFI_REG_NANDECCES2 (0x8D8) >> +#define MA35_NFI_REG_NANDECCES3 (0x8DC) >> + >> +/* NAND-type Flash BCH Error Address Registers */ >> +#define MA35_NFI_REG_NANDECCEA0 (0x900) >> +#define MA35_NFI_REG_NANDECCEA1 (0x904) >> +#define MA35_NFI_REG_NANDECCEA2 (0x908) >> +#define MA35_NFI_REG_NANDECCEA3 (0x90C) >> +#define MA35_NFI_REG_NANDECCEA4 (0x910) >> +#define MA35_NFI_REG_NANDECCEA5 (0x914) >> +#define MA35_NFI_REG_NANDECCEA6 (0x918) >> +#define MA35_NFI_REG_NANDECCEA7 (0x91C) >> +#define MA35_NFI_REG_NANDECCEA8 (0x920) >> +#define MA35_NFI_REG_NANDECCEA9 (0x924) >> +#define MA35_NFI_REG_NANDECCEA10 (0x928) >> +#define MA35_NFI_REG_NANDECCEA11 (0x92C) >> + >> +/* NAND-type Flash BCH Error Data Registers */ >> +#define MA35_NFI_REG_NANDECCED0 (0x960) >> +#define MA35_NFI_REG_NANDECCED1 (0x964) >> +#define MA35_NFI_REG_NANDECCED2 (0x968) >> +#define MA35_NFI_REG_NANDECCED3 (0x96C) >> +#define MA35_NFI_REG_NANDECCED4 (0x970) >> +#define MA35_NFI_REG_NANDECCED5 (0x974) >> + >> +/* NAND-type Flash Redundant Area Registers */ >> +#define MA35_NFI_REG_NANDRA0 (0xA00) >> +#define MA35_NFI_REG_NANDRA1 (0xA04) >> + >> +#define SKIP_SPARE_BYTES 4 >> + >> +/* BCH algorithm related constants and variables */ >> +static const int ma35_parity[3][4] = { >> + {0, 60, 92, 90}, /* for 2K */ >> + {0, 120, 184, 180}, /* for 4K */ >> + {0, 240, 368, 360}, /* for 8K */ > Can you please create definitions for the matrix rows? (using > an enum seems appropriate) > > And maybe an array of three structures would be best because I believe > you're defining offsets for something which is not clear to the reader. I will use the enum and split it into three structures. >> +}; >> + >> +struct ma35_nand_info { >> + struct nand_controller controller; >> + struct device *dev; >> + void __iomem *regs; >> + int irq; >> + struct clk *clk; >> + struct completion complete; >> + >> + struct mtd_info mtd; > Please have a look at nand_to_mtd() I will remove it. >> + struct nand_chip chip; > Is there a single CS supported? Is there a single RB supported? Yes, single CS and RB. I will remove it. >> + struct mtd_partition *parts; > No, this has nothing to do here. I will remove it. >> + struct nand_ecclayout_user nand_oob; > Deprecated structure I will remove it. I will refer to the approach used in the new driver. >> + int nr_parts; >> + >> + u32 bch; >> + u8 *dma_buf; >> + spinlock_t dma_lock; >> + dma_addr_t dma_addr; >> +}; >> + >> +static int ma35_ooblayout_ecc(struct mtd_info *mtd, int section, >> + struct mtd_oob_region *oobregion) >> +{ >> + struct nand_chip *chip = mtd_to_nand(mtd); >> + >> + if (section) >> + return -ERANGE; >> + >> + oobregion->length = chip->ecc.total; >> + oobregion->offset = mtd->oobsize - oobregion->length; >> + >> + return 0; >> +} >> + >> +static int ma35_ooblayout_free(struct mtd_info *mtd, int section, >> + struct mtd_oob_region *oobregion) >> +{ >> + struct nand_chip *chip = mtd_to_nand(mtd); >> + >> + if (section) >> + return -ERANGE; >> + >> + oobregion->length = mtd->oobsize - chip->ecc.total - 2; >> + oobregion->offset = 2; >> + >> + return 0; >> +} >> + >> +static const struct mtd_ooblayout_ops ma35_ooblayout_ops = { >> + .free = ma35_ooblayout_free, >> + .ecc = ma35_ooblayout_ecc, >> +}; >> + >> +/* >> + * Initialize hardware ECC >> + */ >> +static void ma35_nand_hwecc_init(struct ma35_nand_info *nand) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(&nand->chip); >> + >> + /* reset nand controller */ > Reset NAND This resets the internal state machine and counters. >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | SWRST, >> + nand->regs + MA35_NFI_REG_NANDCTL); > I believe it's fine to do it on several lines and probably clearer. > > u32 reg = readl(); > reg |= SOMETHING; > writel(); > > No wait after the reset? I will rewrite this code. Also add waiting. >> + /* Redundant area size */ >> + writel(mtd->oobsize, nand->regs + MA35_NFI_REG_NANDRACTL); >> + >> + /* Protect redundant 3 bytes */ > What does that mean? The MA35 NFI supports a spare area where the first 3 bytes are protected by the ECC algorithm. In other words, ECC will calculate the error correction code for the data plus the first 3 bytes of out-of-band (OOB) data, if this feature is enabled. >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | PROT3BEN, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + >> + /* Write the ECC parity codes automatically to NAND Flash */ >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | ECC_CHK, >> + nand->regs + MA35_NFI_REG_NANDCTL); > No, by default you should disabled the ECC engine. Then when you need > it you enable/use/disable it. Okay. By default, the ECC engine will be disabled. >> + >> + if (nand->bch == BCH_NONE) { >> + /* Disable H/W ECC, ECC parity check enable bit during read page */ >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~ECC_EN), >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + } else { >> + /* Set BCH algorithm */ >> + writel((readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~BCH_MASK)) | >> + nand->bch, nand->regs + MA35_NFI_REG_NANDCTL); >> + >> + /* Enable H/W ECC, ECC parity check enable bit during read page */ >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | ECC_EN, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + } >> + spin_lock_init(&nand->dma_lock); >> +} >> + >> +static void ma35_nand_initialize(struct ma35_nand_info *nand) >> +{ >> + writel(NAND_EN, nand->regs + MA35_NFI_REG_GCTL); >> +} >> + >> + >> +/* Define some constants for BCH */ > for the BCH hardware ECC engine I will correct this comment. >> +/* define the total padding bytes for 512/1024 data segment */ >> +#define BCH_PADDING_LEN_512 32 >> +#define BCH_PADDING_LEN_1024 64 >> +/* define the BCH parity code length for 512 bytes data pattern */ >> +#define BCH_PARITY_LEN_T8 15 >> +#define BCH_PARITY_LEN_T12 23 >> +/* define the BCH parity code length for 1024 bytes data pattern */ >> +#define BCH_PARITY_LEN_T24 45 >> + > Is T the strength? Can we name it strength instead? > > Please move the definitions at the top T is the strength. I will modify this name and move it to the top. >> +/* Correct data by BCH alrogithm */ >> +static void ma35_nfi_correctdata(struct ma35_nand_info *nand, u8 index, >> + u8 err_cnt, u8 *addr) > correctdata vs correct, the naming needs to be improved I will modify the naming. >> +{ >> + u8 *ptr = (u8 *)((long)nand->regs + MA35_NFI_REG_NANDRA0); > Haha, no, never. > > Please compile with C=1 and see how this explodes. > > Also, you can enable W=1 I will try compiling with C=1||and W=1 again. >> + u32 field_len, padding_len, parity_len; >> + u32 temp_data[24], temp_addr[24]; >> + u32 total_field_num, page; >> + u32 err_data[6]; >> + u8 *smra_index; >> + u8 i, j; >> + >> + /* assign parameters for different BCH and page size */ > configurations I will correct this comment. >> + switch (readl(nand->regs + MA35_NFI_REG_NANDCTL) & BCH_MASK) { >> + case BCH_T24: >> + field_len = 1024; >> + parity_len = BCH_PARITY_LEN_T24; >> + padding_len = BCH_PADDING_LEN_1024; >> + break; >> + case BCH_T12: >> + field_len = 512; >> + parity_len = BCH_PARITY_LEN_T12; >> + padding_len = BCH_PADDING_LEN_512; >> + break; >> + case BCH_T8: >> + field_len = 512; >> + parity_len = BCH_PARITY_LEN_T8; >> + padding_len = BCH_PADDING_LEN_512; >> + break; >> + default: >> + pr_warn("NAND ERROR: invalid SMCR_BCH_TSEL = 0x%08X\n", >> + (u32)(readl(nand->regs + MA35_NFI_REG_NANDCTL) & BCH_MASK)); >> + return; >> + } >> + >> + page = readl(nand->regs + MA35_NFI_REG_NANDCTL) & PSIZE_MASK; >> + switch (page) { >> + case PSIZE_8K: >> + total_field_num = 8192 / field_len; break; >> + case PSIZE_4K: >> + total_field_num = 4096 / field_len; break; >> + case PSIZE_2K: >> + total_field_num = 2048 / field_len; break; > Break on a new line Okay, I will fix it. >> + default: >> + pr_warn("NAND ERROR: invalid SMCR_PSIZE = 0x%08X\n", page); >> + return; >> + } >> + >> + /* got valid BCH_ECC_DATAx and parse them to temp_data[] >> + * got the valid register number of BCH_ECC_DATAx since >> + * one register include 4 error bytes >> + */ >> + j = err_cnt / 4; >> + j++; >> + if (j > 6) >> + j = 6; /* there are 6 BCH_ECC_DATAx registers to support BCH T24 */ >> + >> + for (i = 0; i < j; i++) >> + err_data[i] = readl(nand->regs + MA35_NFI_REG_NANDECCED0 + i*4); >> + >> + for (i = 0; i < j; i++) { >> + temp_data[i*4+0] = err_data[i] & 0xff; >> + temp_data[i*4+1] = (err_data[i] >> 8) & 0xff; >> + temp_data[i*4+2] = (err_data[i] >> 16) & 0xff; >> + temp_data[i*4+3] = (err_data[i] >> 24) & 0xff; >> + } >> + >> + /* got valid REG_BCH_ECC_ADDRx and parse them to temp_addr[] >> + * got the valid register number of REG_BCH_ECC_ADDRx since >> + * one register include 2 error addresses >> + */ >> + j = err_cnt / 2; >> + j++; >> + if (j > 12) >> + j = 12; /* there are 12 REG_BCH_ECC_ADDRx registers to support BCH T24 */ >> + >> + for (i = 0; i < j; i++) { >> + /* 11 bits for error address */ >> + temp_addr[i*2+0] = readl(nand->regs + MA35_NFI_REG_NANDECCEA0 + i*4) & 0x07ff; >> + temp_addr[i*2+1] = (readl(nand->regs + MA35_NFI_REG_NANDECCEA0 + i*4)>>16) & 0x07ff; >> + } >> + >> + /* pointer to begin address of field that with data error */ >> + addr += (index-1) * field_len; >> + >> + /* correct each error bytes */ >> + for (i = 0; i < err_cnt; i++) { >> + /* for wrong data in field */ >> + if (temp_addr[i] < field_len) >> + *(addr+temp_addr[i]) ^= temp_data[i]; >> + >> + /* for wrong first-3-bytes in redundancy area */ >> + else if (temp_addr[i] < (field_len+3)) { >> + temp_addr[i] -= field_len; >> + temp_addr[i] += (parity_len * (index-1)); /* field offset */ >> + >> + *(ptr + temp_addr[i]) ^= temp_data[i]; >> + } >> + /* for wrong parity code in redundancy area */ >> + /* BCH_ERR_ADDRx = [data in field] + [3 bytes] + [xx] + [parity code] */ >> + /* |<-- padding bytes -->| */ >> + /* The BCH_ERR_ADDRx for last parity code always = field size + padding size. */ >> + /* So, the first parity code = field size + padding size - parity code length. */ >> + /* For example, for BCH T12, the first parity code = 512 + 32 - 23 = 521. */ >> + /* That is, error byte address offset within field is */ >> + else { >> + temp_addr[i] = temp_addr[i] - (field_len + padding_len - parity_len); >> + >> + /* smra_index point to the first parity code of >> + * first field in register SMRA0~n >> + */ >> + smra_index = (u8 *)(ptr + >> + (readl(nand->regs+MA35_NFI_REG_NANDRACTL) & 0x1ff) - >> + (parity_len * total_field_num)); >> + >> + /* final address = first parity code of first field + */ >> + /* offset of fields + */ >> + /* offset within field */ > Coding style Okay, I will fix it. >> + >> + *((u8 *)smra_index + (parity_len * (index - 1)) + temp_addr[i]) >> + ^= temp_data[i]; > -ENOPARSE MA35 ECC engine will perform calculations on the parity in the spare area. When the parity data generates an ECC error, the calculations mentioned above will correct the parity data. >> + } >> + } /* end of for (i < err_cnt) */ > Useless comment I will remove it. >> +} >> + >> +static int ma35_nfi_correct(struct nand_chip *chip, unsigned long addr) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + int status, i, j, field = 0; >> + int report_err = 0; >> + int err_cnt = 0; >> + >> + if ((readl(nand->regs + MA35_NFI_REG_NANDCTL) & BCH_MASK) == BCH_T24) >> + field = mtd->writesize / 1024; > Can we call this a nchunks? Also, you're supposed to expect some DT > properties (based on your bindings) and you're not using their values, > it's strange. I will change the field to `nchunks` and use `nand-ecc-step-size` for the calculations. >> + else >> + field = mtd->writesize / 512; >> + >> + if (field < 4) >> + field = 1; >> + else >> + field /= 4; >> + >> + for (j = 0; j < field; j++) { >> + status = readl(nand->regs + MA35_NFI_REG_NANDECCES0 + j*4); >> + if (!status) >> + continue; > Is this case relevant? Isn't it treated below? This is to first check the ECC status. If there are correctable errors, it will extract the error count, perform the calculations, and make the corrections. >> + >> + for (i = 1; i < 5; i++) { > From 1 to 5? That's strange. I will change it to 0 to 3. >> + if (!(status & ECC_STATUS_MASK)) { >> + /* No error */ >> + status >>= 8; > You can't do that 5 times on a int. Only 4 times. >> + continue; >> + >> + } else if ((status & ECC_STATUS_MASK) == 0x01) { >> + /* Correctable error */ >> + err_cnt = (status >> 2) & ECC_ERR_CNT_MASK; > Please use FIELD_GET() I will use FIELD_GET(). >> + pr_warn("Field (%d, %d) have %d error!\n", j, i, err_cnt); > dev_warn() I will use dev_warn(). >> + ma35_nfi_correctdata(nand, j*4+i, err_cnt, (u8 *)addr); >> + report_err += err_cnt; >> + >> + } else { >> + /* uncorrectable error */ >> + pr_warn("uncorrectable error! 0x%4x\n", status); >> + return -1; >> + } >> + status >>= 8; >> + } >> + } >> + return report_err; >> +} >> + >> + >> +static int ma35_nand_correct_data(struct nand_chip *chip, u_char *dat, >> + u_char *read_ecc, u_char *calc_ecc) >> +{ >> + return 0; > ? I will remove it. >> +} >> + >> + >> +static void ma35_nand_enable_hwecc(struct nand_chip *chip, int mode) >> +{ > ? I will remove it. >> + >> +} >> + >> +/* >> + * Initial dma controller > Initialize DMA I will modify it. >> + */ >> +static void ma35_nand_dmac_init(struct ma35_nand_info *nand) >> +{ >> + /* DMAC reset and enable */ >> + writel(DMA_RST | DMA_EN, nand->regs + MA35_NFI_REG_DMACTL); >> + writel(DMA_EN, nand->regs + MA35_NFI_REG_DMACTL); >> + >> + /* Clear DMA finished flag */ >> + writel(INT_DMA | INT_ECC, nand->regs + MA35_NFI_REG_NANDINTSTS); >> + >> + init_completion(&nand->complete); >> +} >> + >> +/* >> + * read a byte from NAND controller > Read (same below) As below. >> + */ >> +static u8 ma35_nand_read_byte(struct nand_chip *chip) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + u8 ret; >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs+MA35_NFI_REG_NANDCTL); >> + ret = (u8)readl(nand->regs + MA35_NFI_REG_NANDDATA); > readb? maybe you need to handle endianness? This register only has one byte of valid data. >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + >> + return ret; >> +} >> + >> + >> +/* >> + * read data from NAND controller >> + */ >> +static void ma35_nand_read_buf(struct nand_chip *chip, u8 *buf, int len) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + int i; >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + for (i = 0; i < len; i++) >> + buf[i] = (u8)readl(nand->regs + MA35_NFI_REG_NANDDATA); >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> +} >> +/* >> + * write data to NAND controller >> + */ >> + >> +static void ma35_nand_write_buf(struct nand_chip *chip, const u8 *buf, int len) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + int i; >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + for (i = 0; i < len; i++) >> + writel(buf[i], nand->regs + MA35_NFI_REG_NANDDATA); >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> +} >> + >> +/* >> + * configure and start dma transfer >> + */ >> +static inline int ma35_nand_dma_transfer(struct nand_chip *chip, >> + const u_char *addr, u32 len, int is_write) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + unsigned long timeo = jiffies + HZ/2; >> + dma_addr_t dma_addr; >> + int ret; >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs+MA35_NFI_REG_NANDCTL); >> + /* For save, wait DMAC to ready */ > Please rework this comment I will change it to "Check the DMA status before enabling the DMA." >> + while (1) { >> + if ((readl(nand->regs + MA35_NFI_REG_DMACTL) & DMA_BUSY) == 0) >> + break; >> + if (time_after(jiffies, timeo)) >> + return -ETIMEDOUT; > readl_poll_timeout() Okay. I will use readl_poll_timeout(). >> + } >> + >> + /* Reinitial dmac */ >> + ma35_nand_dmac_init(nand); >> + >> + writel(mtd->oobsize, nand->regs + MA35_NFI_REG_NANDRACTL); >> + >> + /* setup and start DMA using dma_addr */ >> + if (is_write) { >> + u8 *ptr = (u8 *)((long)nand->regs + MA35_NFI_REG_NANDRA0); >> + >> + writel(INT_DMA, nand->regs + MA35_NFI_REG_NANDINTEN); >> + /* To mark this page as dirty. */ >> + if (ptr[3] == 0xFF) >> + ptr[3] = 0; >> + if (ptr[2] == 0xFF) >> + ptr[2] = 0; >> + >> + /* Fill dma_addr */ >> + dma_addr = dma_map_single(nand->dev, (void *)addr, len, DMA_TO_DEVICE); >> + dma_sync_single_for_device(nand->dev, dma_addr, len, DMA_TO_DEVICE); >> + ret = dma_mapping_error(nand->dev, dma_addr); >> + if (ret) { >> + dev_err(nand->dev, "dma mapping error\n"); >> + return -EINVAL; >> + } >> + >> + writel((unsigned long)dma_addr, nand->regs + MA35_NFI_REG_DMASA); >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DMA_W_EN, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + wait_for_completion_timeout(&nand->complete, msecs_to_jiffies(1000)); >> + >> + dma_unmap_single(nand->dev, dma_addr, len, DMA_TO_DEVICE); >> + } else { >> + writel(INT_DMA | INT_ECC, nand->regs + MA35_NFI_REG_NANDINTEN); >> + /* Fill dma_addr */ >> + dma_addr = dma_map_single(nand->dev, (void *)addr, len, DMA_FROM_DEVICE); >> + ret = dma_mapping_error(nand->dev, dma_addr); >> + if (ret) { >> + dev_err(nand->dev, "dma mapping error\n"); >> + return -EINVAL; >> + } >> + nand->dma_buf = (u8 *) addr; > the cast should not be neede Okay. I will remove it. >> + nand->dma_addr = dma_addr; >> + >> + writel((unsigned long)dma_addr, nand->regs + MA35_NFI_REG_DMASA); >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DMA_R_EN, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + wait_for_completion_timeout(&nand->complete, msecs_to_jiffies(1000)); > Always check return values. I will fix it. >> + >> + dma_sync_single_for_cpu(nand->dev, dma_addr, len, DMA_FROM_DEVICE); >> + dma_unmap_single(nand->dev, dma_addr, len, DMA_FROM_DEVICE); >> + } >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + >> + return 0; >> +} >> + >> +static void ma35_read_buf_dma(struct nand_chip *chip, u_char *buf, int len) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + >> + if (len == mtd->writesize) >> + ma35_nand_dma_transfer(chip, buf, len, 0x0); >> + else >> + ma35_nand_read_buf(chip, buf, len); >> +} >> + >> +static void ma35_write_buf_dma(struct nand_chip *chip, const u_char *buf, int len) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + >> + if (len == mtd->writesize) >> + ma35_nand_dma_transfer(chip, (u_char *)buf, len, 0x1); >> + else >> + ma35_nand_write_buf(chip, buf, len); >> +} >> + > This... I will rewrite it to read and write in terms of pages. >> +static int ma35_nand_devready(struct nand_chip *chip) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + unsigned int val; >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs+MA35_NFI_REG_NANDCTL); >> + val = (readl(nand->regs + MA35_NFI_REG_NANDINTSTS) & INT_RB0_STS) ? 1 : 0; >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs+MA35_NFI_REG_NANDCTL); >> + >> + return val; >> +} >> + >> +static int ma35_waitfunc(struct nand_chip *chip) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + unsigned long timeo = jiffies; >> + int status = -1; >> + >> + timeo += msecs_to_jiffies(400); >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + while (time_before(jiffies, timeo)) { >> + status = readl(nand->regs + MA35_NFI_REG_NANDINTSTS); >> + if (status & INT_RB0) { >> + writel(INT_RB0, nand->regs + MA35_NFI_REG_NANDINTSTS); >> + status = 0; >> + break; >> + } >> + cond_resched(); >> + } >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + >> + return status; >> +} >> + >> +static void ma35_nand_command(struct nand_chip *chip, u32 command, int column, int page_addr) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + writel(INT_RB0, nand->regs + MA35_NFI_REG_NANDINTSTS); >> + >> + if (command == NAND_CMD_READOOB) { >> + command = NAND_CMD_READ0; >> + column += mtd->writesize; >> + } >> + >> + switch (command) { >> + case NAND_CMD_RESET: >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + break; >> + >> + case NAND_CMD_READID: >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + writel(ENDADDR|column, nand->regs + MA35_NFI_REG_NANDADDR); >> + break; >> + >> + case NAND_CMD_PARAM: >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + writel(ENDADDR|column, nand->regs + MA35_NFI_REG_NANDADDR); >> + ma35_waitfunc(chip); >> + break; >> + >> + case NAND_CMD_READ0: >> + writel(ENABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL); >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + if (column != -1) { >> + writel(column & 0xff, nand->regs + MA35_NFI_REG_NANDADDR); >> + writel((column >> 8) & 0xff, nand->regs + MA35_NFI_REG_NANDADDR); >> + } >> + if (page_addr != -1) { >> + writel(page_addr & 0xff, nand->regs + MA35_NFI_REG_NANDADDR); >> + if (chip->options & NAND_ROW_ADDR_3) { >> + writel((page_addr >> 8) & 0xff, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + writel(((page_addr >> 16) & 0xff) | ENDADDR, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + } else { >> + writel(((page_addr >> 8) & 0xff) | ENDADDR, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + } >> + } >> + writel(NAND_CMD_READSTART, nand->regs + MA35_NFI_REG_NANDCMD); >> + ma35_waitfunc(chip); >> + break; >> + >> + case NAND_CMD_ERASE1: >> + writel(DISABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL); >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + writel(page_addr & 0xff, nand->regs + MA35_NFI_REG_NANDADDR); >> + if (chip->options & NAND_ROW_ADDR_3) { >> + writel((page_addr >> 8) & 0xff, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + writel(((page_addr >> 16) & 0xff) | ENDADDR, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + } else { >> + writel(((page_addr >> 8) & 0xff) | ENDADDR, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + } >> + break; >> + >> + case NAND_CMD_SEQIN: >> + writel(DISABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL); >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + writel(column & 0xff, nand->regs + MA35_NFI_REG_NANDADDR); >> + writel(column >> 8, nand->regs + MA35_NFI_REG_NANDADDR); >> + writel(page_addr & 0xff, nand->regs + MA35_NFI_REG_NANDADDR); >> + if (chip->options & NAND_ROW_ADDR_3) { >> + writel((page_addr >> 8) & 0xff, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + writel(((page_addr >> 16) & 0xff) | ENDADDR, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + } else { >> + writel(((page_addr >> 8) & 0xff) | ENDADDR, >> + nand->regs + MA35_NFI_REG_NANDADDR); >> + } >> + break; >> + >> + case NAND_CMD_STATUS: >> + writel(DISABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL); >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + break; >> + >> + default: >> + writel(command, nand->regs + MA35_NFI_REG_NANDCMD); >> + } >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> +} > ... is totally legacy. ->exec_op() is the API to implement instead. I will change it to ->exec_op(). >> + >> +/* select chip */ >> +static void ma35_nand_select_chip(struct nand_chip *chip, int cs) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + >> + if (cs == 0) >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~DISABLE_CS0), >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + else >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DISABLE_CS0, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> +} >> + >> +static int ma35_nand_calculate_ecc(struct nand_chip *chip, const u_char *dat, >> + u_char *ecc_code) >> +{ >> + return 0; >> +} >> + >> +static int ma35_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf, >> + int oob_required, int page) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + u8 *ptr = (u8 *)((long)nand->regs + MA35_NFI_REG_NANDRA0); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + u8 *ecc_calc = chip->ecc.calc_buf; >> + >> + memset((void *)ptr, 0xFF, mtd->oobsize); >> + memcpy((void *)ptr, (void *)chip->oob_poi, mtd->oobsize - chip->ecc.total); >> + >> + ma35_nand_command(chip, NAND_CMD_SEQIN, 0, page); >> + ma35_nand_dma_transfer(chip, buf, mtd->writesize, 0x1); >> + ma35_nand_command(chip, NAND_CMD_PAGEPROG, -1, -1); >> + ma35_waitfunc(chip); >> + >> + /* Copy parity code in NANDRA to calc */ >> + memcpy((void *)ecc_calc, >> + (void *)(ptr + (mtd->oobsize - chip->ecc.total)), >> + chip->ecc.total); >> + >> + /* Copy parity code in calc to oob_poi */ >> + memcpy((void *)(chip->oob_poi + (mtd->oobsize - chip->ecc.total)), >> + (void *)ecc_calc, chip->ecc.total); >> + >> + return 0; >> +} >> + >> +static int ma35_nand_read_page_hwecc_oob_first(struct nand_chip *chip, u8 *buf, >> + int oob_required, int page) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + char *ptr = (char *)((long)nand->regs + MA35_NFI_REG_NANDRA0); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + >> + /* 1. read the OOB area */ >> + ma35_nand_command(chip, NAND_CMD_READOOB, 0, page); >> + ma35_nand_read_buf(chip, chip->oob_poi, mtd->oobsize); >> + >> + /* 2. copy OOB data to NANDRA for page read */ >> + memcpy((void *)ptr, (void *)chip->oob_poi, mtd->oobsize); >> + >> + if ((*(ptr+2) != 0) && (*(ptr+3) != 0)) >> + memset((void *)buf, 0xff, mtd->writesize); >> + else { >> + /* 3. read data from nand */ >> + ma35_nand_command(chip, NAND_CMD_READ0, 0, page); >> + ma35_nand_dma_transfer(chip, buf, mtd->writesize, 0x0); >> + >> + /* 4. restore OOB data from SMRA */ >> + memcpy((void *)chip->oob_poi, (void *)ptr, mtd->oobsize); >> + } >> + >> + return 0; >> +} >> + > Not sure why you need these two implementations? Usually there is only > one per controller and fully depends on your controller > capabilities/limitations. If you have no limitation, just support the > simple case. I will merge it into a single function. >> +static void ma35_layout_oob_table(struct nand_ecclayout_user *oobtable, >> + int oobsize, int eccbytes) >> +{ >> + oobtable->eccbytes = eccbytes; >> + oobtable->oobavail = oobsize - SKIP_SPARE_BYTES - eccbytes; >> + oobtable->oobfree[0].offset = SKIP_SPARE_BYTES; >> + oobtable->oobfree[0].length = oobsize - eccbytes - oobtable->oobfree[0].offset; >> + >> + oobtable->oobfree[1].offset = 0; >> + oobtable->oobfree[1].length = 0; >> +} > I'm not sure why you would need that. I will fix it. >> + >> +static int ma35_nand_read_oob_hwecc(struct nand_chip *chip, int page) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + char *ptr = (char *)((long)nand->regs + MA35_NFI_REG_NANDRA0); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + >> + ma35_nand_command(chip, NAND_CMD_READOOB, 0, page); >> + ma35_nand_read_buf(chip, chip->oob_poi, mtd->oobsize); >> + >> + /* copy OOB data to NANDRA for page read */ >> + memcpy((void *)ptr, (void *)chip->oob_poi, mtd->oobsize); >> + >> + if ((*(ptr+2) != 0) && (*(ptr+3) != 0)) >> + memset((void *)chip->oob_poi, 0xff, mtd->oobsize); >> + >> + return 0; >> +} >> + >> +static irqreturn_t ma35_nand_irq(int irq, void *id) >> +{ >> + struct ma35_nand_info *nand = (struct ma35_nand_info *)id; >> + struct mtd_info *mtd = nand_to_mtd(&nand->chip); >> + int stat = 0; >> + u32 isr; >> + >> + spin_lock(&nand->dma_lock); >> + >> + isr = readl(nand->regs + MA35_NFI_REG_NANDINTSTS); >> + if (isr & INT_ECC) { >> + dma_sync_single_for_cpu(nand->dev, nand->dma_addr, mtd->writesize, >> + DMA_FROM_DEVICE); >> + stat = ma35_nfi_correct(&nand->chip, (unsigned long)nand->dma_buf); >> + if (stat < 0) { >> + mtd->ecc_stats.failed++; >> + writel(DMA_RST | DMA_EN, nand->regs + MA35_NFI_REG_DMACTL); >> + writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | SWRST, >> + nand->regs + MA35_NFI_REG_NANDCTL); >> + } else if (stat > 0) { >> + mtd->ecc_stats.corrected += stat; /* Add corrected bit count */ >> + } >> + writel(INT_ECC, nand->regs + MA35_NFI_REG_NANDINTSTS); >> + } >> + if (isr & INT_DMA) { >> + writel(INT_DMA, nand->regs + MA35_NFI_REG_NANDINTSTS); >> + complete(&nand->complete); >> + } >> + spin_unlock(&nand->dma_lock); >> + >> + return IRQ_HANDLED; >> +} >> + >> +static int ma35_nand_attach_chip(struct nand_chip *chip) >> +{ >> + struct ma35_nand_info *nand = nand_get_controller_data(chip); >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + unsigned int reg; >> + > Please have a look at other controller drivers. You need to allow: > > - no correction > - sw correction > - hw BCH correction I will fix it. >> + /* Set PSize */ >> + reg = readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~PSIZE_MASK); >> + if (mtd->writesize == 2048) >> + writel(reg | PSIZE_2K, nand->regs + MA35_NFI_REG_NANDCTL); >> + else if (mtd->writesize == 4096) >> + writel(reg | PSIZE_4K, nand->regs + MA35_NFI_REG_NANDCTL); >> + else if (mtd->writesize == 8192) >> + writel(reg | PSIZE_8K, nand->regs + MA35_NFI_REG_NANDCTL); >> + >> + if (chip->ecc.strength == 0) { >> + nand->bch = BCH_NONE; /* No ECC */ >> + ma35_layout_oob_table(&nand->nand_oob, mtd->oobsize, >> + ma35_parity[mtd->writesize>>12][0]); >> + >> + } else if (chip->ecc.strength <= 8) { >> + nand->bch = BCH_T8; /* T8 */ >> + ma35_layout_oob_table(&nand->nand_oob, mtd->oobsize, >> + ma35_parity[mtd->writesize>>12][1]); >> + >> + } else if (chip->ecc.strength <= 12) { >> + nand->bch = BCH_T12; /* T12 */ >> + ma35_layout_oob_table(&nand->nand_oob, mtd->oobsize, >> + ma35_parity[mtd->writesize>>12][2]); >> + >> + } else if (chip->ecc.strength <= 24) { >> + nand->bch = BCH_T24; /* T24 */ >> + ma35_layout_oob_table(&nand->nand_oob, mtd->oobsize, >> + ma35_parity[mtd->writesize>>12][3]); >> + >> + } else { >> + pr_warn("NAND Controller is not support this flash. (%d, %d)\n", >> + mtd->writesize, mtd->oobsize); >> + } >> + >> + chip->ecc.steps = mtd->writesize / chip->ecc.size; >> + chip->ecc.bytes = nand->nand_oob.eccbytes / chip->ecc.steps; >> + chip->ecc.total = nand->nand_oob.eccbytes; >> + mtd_set_ooblayout(mtd, &ma35_ooblayout_ops); >> + >> + /* add mtd-id. The string should same as uboot definition */ >> + mtd->name = "nand0"; >> + >> + ma35_nand_hwecc_init(nand); >> + >> + writel(ENABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL); >> + >> + return 0; >> +} >> + >> +static const struct nand_controller_ops ma35_nand_controller_ops = { >> + .attach_chip = ma35_nand_attach_chip, >> +}; >> + >> +static int ma35_nand_probe(struct platform_device *pdev) >> +{ >> + struct ma35_nand_info *nand; >> + struct nand_chip *chip; >> + struct mtd_info *mtd; >> + int retval = 0; >> + >> + nand = devm_kzalloc(&pdev->dev, sizeof(*nand), GFP_KERNEL); >> + if (!nand) >> + return -ENOMEM; >> + >> + nand_controller_init(&nand->controller); >> + >> + nand->regs = devm_platform_ioremap_resource(pdev, 0); >> + if (IS_ERR(nand->regs)) >> + return PTR_ERR(nand->regs); >> + >> + nand->dev = &pdev->dev; >> + chip = &nand->chip; >> + mtd = nand_to_mtd(chip); >> + nand_set_controller_data(chip, nand); >> + nand_set_flash_node(chip, pdev->dev.of_node); >> + >> + mtd->priv = chip; >> + mtd->owner = THIS_MODULE; >> + mtd->dev.parent = &pdev->dev; >> + >> + nand->clk = devm_clk_get(&pdev->dev, "nand_gate"); > devm_clk_get_enabled() I will use devm_clk_get_enabled(). >> + if (IS_ERR(nand->clk)) >> + return dev_err_probe(&pdev->dev, PTR_ERR(nand->clk), >> + "failed to find nand clock\n"); >> + >> + retval = clk_prepare_enable(nand->clk); >> + if (retval < 0) { >> + dev_err(&pdev->dev, "failed to enable clock\n"); >> + retval = -ENXIO; >> + } >> + >> + nand->chip.controller = &nand->controller; >> + >> + chip->legacy.cmdfunc = ma35_nand_command; >> + chip->legacy.waitfunc = ma35_waitfunc; >> + chip->legacy.read_byte = ma35_nand_read_byte; >> + chip->legacy.select_chip = ma35_nand_select_chip; >> + chip->legacy.read_buf = ma35_read_buf_dma; >> + chip->legacy.write_buf = ma35_write_buf_dma; >> + chip->legacy.dev_ready = ma35_nand_devready; >> + chip->legacy.chip_delay = 25; /* us */ > Please convert this driver to ->exec_op(). > > No introduce of legacy hooks will be accepted. Okay. I will use exec_op(). >> + >> + /* Read OOB data first, then HW read page */ >> + chip->ecc.hwctl = ma35_nand_enable_hwecc; >> + chip->ecc.calculate = ma35_nand_calculate_ecc; >> + chip->ecc.correct = ma35_nand_correct_data; >> + chip->ecc.write_page = ma35_nand_write_page_hwecc; >> + chip->ecc.read_page = ma35_nand_read_page_hwecc_oob_first; >> + chip->ecc.read_oob = ma35_nand_read_oob_hwecc; >> + chip->options |= (NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA); >> + >> + ma35_nand_initialize(nand); >> + platform_set_drvdata(pdev, nand); >> + >> + nand->controller.ops = &ma35_nand_controller_ops; >> + >> + nand->irq = platform_get_irq(pdev, 0); >> + if (nand->irq < 0) >> + return dev_err_probe(&pdev->dev, nand->irq, >> + "failed to get platform irq\n"); >> + >> + retval = devm_request_irq(&pdev->dev, nand->irq, ma35_nand_irq, >> + IRQF_TRIGGER_HIGH, "ma35d1-nand", nand); >> + if (retval) { >> + dev_err(&pdev->dev, "failed to request NAND irq\n"); >> + clk_disable_unprepare(nand->clk); >> + return -ENXIO; >> + } >> + >> + retval = nand_scan(chip, 1); > s/retval/ret/ I'm not sure what this means. Should it be changed to ret = nand_scan()? >> + if (retval) >> + return retval; >> + >> + if (mtd_device_register(mtd, nand->parts, nand->nr_parts)) { > ret = > if (ret) I will fix it. >> + nand_cleanup(chip); >> + devm_kfree(&pdev->dev, nand); >> + return retval; >> + } >> + >> + return retval; >> +} >> + >> +static void ma35_nand_remove(struct platform_device *pdev) >> +{ >> + struct ma35_nand_info *nand = platform_get_drvdata(pdev); >> + int ret; >> + >> + devm_free_irq(&pdev->dev, nand->irq, nand); >> + ret = mtd_device_unregister(nand_to_mtd(&nand->chip)); >> + WARN_ON(ret); >> + nand_cleanup(&nand->chip); >> + clk_disable_unprepare(nand->clk); >> +} >> + >> +/* PM Support */ >> +#ifdef CONFIG_PM >> +static int ma35_nand_suspend(struct platform_device *pdev, pm_message_t pm) >> +{ >> + struct ma35_nand_info *nand = platform_get_drvdata(pdev); >> + unsigned long timeo = jiffies + HZ/2; >> + >> + /* wait DMAC to ready */ >> + while (1) { >> + if ((readl(nand->regs + MA35_NFI_REG_DMACTL) & DMA_BUSY) == 0) >> + break; >> + if (time_after(jiffies, timeo)) >> + return -ETIMEDOUT; >> + } >> + >> + clk_disable(nand->clk); >> + >> + return 0; >> +} >> + >> +static int ma35_nand_resume(struct platform_device *pdev) >> +{ >> + struct ma35_nand_info *nand = platform_get_drvdata(pdev); >> + >> + clk_enable(nand->clk); >> + ma35_nand_hwecc_init(nand); >> + ma35_nand_dmac_init(nand); >> + >> + return 0; >> +} >> + >> +#else >> +#define ma35_nand_suspend NULL >> +#define ma35_nand_resume NULL >> +#endif >> + >> +static const struct of_device_id ma35_nfi_of_match[] = { >> + { .compatible = "nuvoton,ma35d1-nand" }, >> + {}, >> +}; >> +MODULE_DEVICE_TABLE(of, ma35_nfi_of_match); >> + >> +static struct platform_driver ma35_nand_driver = { >> + .driver = { >> + .name = "ma35d1-nand", >> + .of_match_table = ma35_nfi_of_match, >> + }, >> + .probe = ma35_nand_probe, >> + .remove_new = ma35_nand_remove, >> + .suspend = ma35_nand_suspend, >> + .resume = ma35_nand_resume, >> +}; >> + >> +module_platform_driver(ma35_nand_driver); >> + >> +MODULE_DESCRIPTION("Nuvoton ma35 NAND driver"); >> +MODULE_AUTHOR("Hui-Ping Chen "); >> +MODULE_LICENSE("GPL"); > > Thanks, > Miquèl Best regards, Hui-Ping Chen