From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrzej Pietrasiewicz Subject: Re: [PATCHv2 0/7] Support inhibiting input devices Date: Tue, 2 Jun 2020 20:50:07 +0200 Message-ID: <82e9f2ab-a16e-51ee-1413-bedf0122026a@collabora.com> References: <20200515164943.28480-1-andrzej.p@collabora.com> <842b95bb-8391-5806-fe65-be64b02de122@redhat.com> <6d9921fc-5c2f-beda-4dcd-66d6970a22fe@redhat.com> <09679de4-75d3-1f29-ec5f-8d42c84273dd@collabora.com> <2d224833-3a7e-bc7c-af15-1f803f466697@collabora.com> <20200527063430.GJ89269@dtor-ws> <88f939cd-1518-d516-59f2-8f627a6a70d2@collabora.com> <20200602175241.GO89269@dtor-ws> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Return-path: In-Reply-To: <20200602175241.GO89269@dtor-ws> Content-Language: en-US Sender: linux-tegra-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Dmitry Torokhov Cc: Hans de Goede , linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, patches-yzvPICuk2AA4QjBA90+/kJqQE7yCjDx5@public.gmane.org, ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org, platform-driver-x86-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, "Rafael J . Wysocki" , Len Brown , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Kukjin Kim , Krzysztof Kozlowski , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio List-Id: linux-tegra@vger.kernel.org Hi Dmitry, W dniu 02.06.2020 o 19:52, Dmitry Torokhov pisze: > Hi Andrzej, > > On Tue, Jun 02, 2020 at 06:56:40PM +0200, Andrzej Pietrasiewicz wrote: >> Hi Dmitry, >> >> W dniu 27.05.2020 o 08:34, Dmitry Torokhov pisze: >>> That said, I think the way we should handle inhibit/uninhibit, is that >>> if we have the callback defined, then we call it, and only call open and >>> close if uninhibit or inhibit are _not_ defined. >>> >> >> If I understand you correctly you suggest to call either inhibit, >> if provided or close, if inhibit is not provided, but not both, >> that is, if both are provided then on the inhibit path only >> inhibit is called. And, consequently, you suggest to call either >> uninhibit or open, but not both. The rest of my mail makes this >> assumption, so kindly confirm if I understand you correctly. > > Yes, that is correct. If a driver wants really fine-grained control, it > will provide inhibit (or both inhibit and close), otherwise it will rely > on close in place of inhibit. > >> >> In my opinion this idea will not work. >> >> The first question is should we be able to inhibit a device >> which is not opened? In my opinion we should, in order to be >> able to inhibit a device in anticipation without needing to >> open it first. > > I agree. > >> >> Then what does opening (with input_open_device()) an inhibited >> device mean? Should it succeed or should it fail? > > It should succeed. > >> If it is not >> the first opening then effectively it boils down to increasing >> device's and handle's counters, so we can allow it to succeed. >> If, however, the device is being opened for the first time, >> the ->open() method wants to be called, but that somehow >> contradicts the device's inhibited state. So a logical thing >> to do is to either fail input_open_device() or postpone ->open() >> invocation to the moment of uninhibiting - and the latter is >> what the patches in this series currently do. >> >> Failing input_open_device() because of the inhibited state is >> not the right thing to do. Let me explain. Suppose that a device >> is already inhibited and then a new matching handler appears >> in the system. Most handlers (apm-power.c, evbug.c, input-leds.c, >> mac_hid.c, sysrq.c, vt/keyboard.c and rfkill/input.c) don't create >> any character devices (only evdev.c, joydev.c and mousedev.c do), >> so for them it makes no sense to delay calling input_open_device() >> and it is called in handler's ->connect(). If input_open_device() >> now fails, we have lost the only chance for this ->connect() to >> succeed. >> >> Summarizing, IMO the uninhibit path should be calling both >> ->open() and ->uninhibit() (if provided), and conversely, the inhibit >> path should be calling both ->inhibit() and ->close() (if provided). > > So what you are trying to say is that you see inhibit as something that > is done in addition to what happens in close. But what exactly do you > want to do in inhibit, in addition to what close is doing? See below (*). > > In my view, if we want to have a dedicated inhibit callback, then it > will do everything that close does, they both are aware of each other > and can sort out the state transitions between them. For drivers that do > not have dedicated inhibit/uninhibit, we can use open and close > handlers, and have input core sort out when each should be called. That > means that we should not call dev->open() in input_open_device() when > device is inhibited (and same for dev->close() in input_close_device). > And when uninhibiting, we should not call dev->open() when there are no > users for the device, and no dev->close() when inhibiting with no users. > > Do you see any problems with this approach? My concern is that if e.g. both ->open() and ->uninhibit() are provided, then in certain circumstances ->open() won't be called: 1. users == 0 2. inhibit happens 3. input_open_device() happens, ->open() not called 4. uninhibit happens 5. as part of uninhibit ->uninhibit() is only called, but ->open() is not. They way I understand your answer is that we implicitly impose requirements on drivers which choose to implement e.g. both ->open() and ->uninhibit(): in such a case ->uninhibit() should be doing exactly the same things as ->open() does. Which leads to a conclusion that in practice no drivers should choose to implement both, otherwise they must be aware that ->uninhibit() can be sometimes called instead of ->open(). Then ->open() becomes synonymous with ->uninhibit(), and ->close() with ->inhibit(). Or, maybe, then ->inhibit() can be a superset of ->close() and ->uninhibit() a superset of ->open(). If such an approach is ok with you, it is ok with me, too. (*) Calling both ->inhibit() and ->close() (if they are provided) allows drivers to go fancy and fail inhibiting (which is impossible using only ->close() as it does not return a value, but ->inhibit() by design does). Then ->uninhibit() is mostly for symmetry. Regards, Andrzej From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7458C433DF for ; Tue, 2 Jun 2020 18:50:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9D637206A2 for ; Tue, 2 Jun 2020 18:50:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726728AbgFBSuQ (ORCPT ); Tue, 2 Jun 2020 14:50:16 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:56130 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726000AbgFBSuQ (ORCPT ); Tue, 2 Jun 2020 14:50:16 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: andrzej.p) with ESMTPSA id 6D3B82A3702 Subject: Re: [PATCHv2 0/7] Support inhibiting input devices To: Dmitry Torokhov Cc: Hans de Goede , linux-input@vger.kernel.org, linux-acpi@vger.kernel.org, linux-iio@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-tegra@vger.kernel.org, patches@opensource.cirrus.com, ibm-acpi-devel@lists.sourceforge.net, platform-driver-x86@vger.kernel.org, "Rafael J . Wysocki" , Len Brown , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Kukjin Kim , Krzysztof Kozlowski , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Vladimir Zapolskiy , Sylvain Lemieux , Laxman Dewangan , Thierry Reding , Jonathan Hunter , Barry Song , Michael Hennerich , Nick Dyer , Ferruh Yigit , Sangwon Jee , Henrique de Moraes Holschuh , kernel@collabora.com, Peter Hutterer , Benjamin Tissoires References: <20200515164943.28480-1-andrzej.p@collabora.com> <842b95bb-8391-5806-fe65-be64b02de122@redhat.com> <6d9921fc-5c2f-beda-4dcd-66d6970a22fe@redhat.com> <09679de4-75d3-1f29-ec5f-8d42c84273dd@collabora.com> <2d224833-3a7e-bc7c-af15-1f803f466697@collabora.com> <20200527063430.GJ89269@dtor-ws> <88f939cd-1518-d516-59f2-8f627a6a70d2@collabora.com> <20200602175241.GO89269@dtor-ws> From: Andrzej Pietrasiewicz Message-ID: <82e9f2ab-a16e-51ee-1413-bedf0122026a@collabora.com> Date: Tue, 2 Jun 2020 20:50:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.8.0 MIME-Version: 1.0 In-Reply-To: <20200602175241.GO89269@dtor-ws> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Hi Dmitry, W dniu 02.06.2020 o 19:52, Dmitry Torokhov pisze: > Hi Andrzej, > > On Tue, Jun 02, 2020 at 06:56:40PM +0200, Andrzej Pietrasiewicz wrote: >> Hi Dmitry, >> >> W dniu 27.05.2020 o 08:34, Dmitry Torokhov pisze: >>> That said, I think the way we should handle inhibit/uninhibit, is that >>> if we have the callback defined, then we call it, and only call open and >>> close if uninhibit or inhibit are _not_ defined. >>> >> >> If I understand you correctly you suggest to call either inhibit, >> if provided or close, if inhibit is not provided, but not both, >> that is, if both are provided then on the inhibit path only >> inhibit is called. And, consequently, you suggest to call either >> uninhibit or open, but not both. The rest of my mail makes this >> assumption, so kindly confirm if I understand you correctly. > > Yes, that is correct. If a driver wants really fine-grained control, it > will provide inhibit (or both inhibit and close), otherwise it will rely > on close in place of inhibit. > >> >> In my opinion this idea will not work. >> >> The first question is should we be able to inhibit a device >> which is not opened? In my opinion we should, in order to be >> able to inhibit a device in anticipation without needing to >> open it first. > > I agree. > >> >> Then what does opening (with input_open_device()) an inhibited >> device mean? Should it succeed or should it fail? > > It should succeed. > >> If it is not >> the first opening then effectively it boils down to increasing >> device's and handle's counters, so we can allow it to succeed. >> If, however, the device is being opened for the first time, >> the ->open() method wants to be called, but that somehow >> contradicts the device's inhibited state. So a logical thing >> to do is to either fail input_open_device() or postpone ->open() >> invocation to the moment of uninhibiting - and the latter is >> what the patches in this series currently do. >> >> Failing input_open_device() because of the inhibited state is >> not the right thing to do. Let me explain. Suppose that a device >> is already inhibited and then a new matching handler appears >> in the system. Most handlers (apm-power.c, evbug.c, input-leds.c, >> mac_hid.c, sysrq.c, vt/keyboard.c and rfkill/input.c) don't create >> any character devices (only evdev.c, joydev.c and mousedev.c do), >> so for them it makes no sense to delay calling input_open_device() >> and it is called in handler's ->connect(). If input_open_device() >> now fails, we have lost the only chance for this ->connect() to >> succeed. >> >> Summarizing, IMO the uninhibit path should be calling both >> ->open() and ->uninhibit() (if provided), and conversely, the inhibit >> path should be calling both ->inhibit() and ->close() (if provided). > > So what you are trying to say is that you see inhibit as something that > is done in addition to what happens in close. But what exactly do you > want to do in inhibit, in addition to what close is doing? See below (*). > > In my view, if we want to have a dedicated inhibit callback, then it > will do everything that close does, they both are aware of each other > and can sort out the state transitions between them. For drivers that do > not have dedicated inhibit/uninhibit, we can use open and close > handlers, and have input core sort out when each should be called. That > means that we should not call dev->open() in input_open_device() when > device is inhibited (and same for dev->close() in input_close_device). > And when uninhibiting, we should not call dev->open() when there are no > users for the device, and no dev->close() when inhibiting with no users. > > Do you see any problems with this approach? My concern is that if e.g. both ->open() and ->uninhibit() are provided, then in certain circumstances ->open() won't be called: 1. users == 0 2. inhibit happens 3. input_open_device() happens, ->open() not called 4. uninhibit happens 5. as part of uninhibit ->uninhibit() is only called, but ->open() is not. They way I understand your answer is that we implicitly impose requirements on drivers which choose to implement e.g. both ->open() and ->uninhibit(): in such a case ->uninhibit() should be doing exactly the same things as ->open() does. Which leads to a conclusion that in practice no drivers should choose to implement both, otherwise they must be aware that ->uninhibit() can be sometimes called instead of ->open(). Then ->open() becomes synonymous with ->uninhibit(), and ->close() with ->inhibit(). Or, maybe, then ->inhibit() can be a superset of ->close() and ->uninhibit() a superset of ->open(). If such an approach is ok with you, it is ok with me, too. (*) Calling both ->inhibit() and ->close() (if they are provided) allows drivers to go fancy and fail inhibiting (which is impossible using only ->close() as it does not return a value, but ->inhibit() by design does). Then ->uninhibit() is mostly for symmetry. Regards, Andrzej From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.2 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D2CFC433DF for ; Tue, 2 Jun 2020 18:50:25 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0EC7D206A2 for ; Tue, 2 Jun 2020 18:50:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="lWs/ZCfq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0EC7D206A2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=collabora.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Content-Type: Content-Transfer-Encoding:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=PbLQcEcZNQbBXfI8wJI463KthnjhfvnJYfFuReSTC3c=; b=lWs/ZCfqIKQxgQLZK859m/wsd DgPcCL0OiW52v0xL1wO4EBrrdeD5jI7+dDpG8KxLqwaGavK32XAxoY5X3s6Odkf/QGCtp9JZ2Wzpx Z2rTDUzRKb2DsHd8kVvgbeYnfgqFcEA+4WgxgCs0dE6CzLbbo4Uk+wkBkG8pNBFA/uHxrX0rHQs2H eXcg9bJx9CaISOBNaeK5VjP6SG9zHaCf9uAxNih8hNg/P+TkfOx/dSjX996KMcUoppCNmx7QZnT/3 5K8eHCpx+Fs3ki+l6YdvKFCjdpC/mTK8aJqXmqt55CSFgVjLE9HMGa/HxEIetwy/AaVtxLdEs2rTF xgqXBXpKQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jgBzO-0007O9-TS; Tue, 02 Jun 2020 18:50:18 +0000 Received: from bhuna.collabora.co.uk ([46.235.227.227]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jgBzK-0007Gg-Lh for linux-arm-kernel@lists.infradead.org; Tue, 02 Jun 2020 18:50:16 +0000 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: andrzej.p) with ESMTPSA id 6D3B82A3702 Subject: Re: [PATCHv2 0/7] Support inhibiting input devices To: Dmitry Torokhov References: <20200515164943.28480-1-andrzej.p@collabora.com> <842b95bb-8391-5806-fe65-be64b02de122@redhat.com> <6d9921fc-5c2f-beda-4dcd-66d6970a22fe@redhat.com> <09679de4-75d3-1f29-ec5f-8d42c84273dd@collabora.com> <2d224833-3a7e-bc7c-af15-1f803f466697@collabora.com> <20200527063430.GJ89269@dtor-ws> <88f939cd-1518-d516-59f2-8f627a6a70d2@collabora.com> <20200602175241.GO89269@dtor-ws> From: Andrzej Pietrasiewicz Message-ID: <82e9f2ab-a16e-51ee-1413-bedf0122026a@collabora.com> Date: Tue, 2 Jun 2020 20:50:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.8.0 MIME-Version: 1.0 In-Reply-To: <20200602175241.GO89269@dtor-ws> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200602_115014_985679_CC36B4D0 X-CRM114-Status: GOOD ( 30.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nick Dyer , linux-iio@vger.kernel.org, Benjamin Tissoires , platform-driver-x86@vger.kernel.org, ibm-acpi-devel@lists.sourceforge.net, Laxman Dewangan , Peter Meerwald-Stadler , kernel@collabora.com, Fabio Estevam , linux-samsung-soc@vger.kernel.org, Krzysztof Kozlowski , Jonathan Hunter , linux-acpi@vger.kernel.org, Kukjin Kim , NXP Linux Team , linux-input@vger.kernel.org, Len Brown , Peter Hutterer , Michael Hennerich , Sascha Hauer , Sylvain Lemieux , Henrique de Moraes Holschuh , Vladimir Zapolskiy , Hans de Goede , Lars-Peter Clausen , linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Barry Song , Ferruh Yigit , patches@opensource.cirrus.com, "Rafael J . Wysocki" , Thierry Reding , Sangwon Jee , Pengutronix Kernel Team , Hartmut Knaack , Shawn Guo , Jonathan Cameron Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgRG1pdHJ5LAoKVyBkbml1IDAyLjA2LjIwMjAgb8KgMTk6NTIsIERtaXRyeSBUb3Jva2hvdiBw aXN6ZToKPiBIaSBBbmRyemVqLAo+IAo+IE9uIFR1ZSwgSnVuIDAyLCAyMDIwIGF0IDA2OjU2OjQw UE0gKzAyMDAsIEFuZHJ6ZWogUGlldHJhc2lld2ljeiB3cm90ZToKPj4gSGkgRG1pdHJ5LAo+Pgo+ PiBXIGRuaXUgMjcuMDUuMjAyMCBvwqAwODozNCwgRG1pdHJ5IFRvcm9raG92IHBpc3plOgo+Pj4g VGhhdCBzYWlkLCBJIHRoaW5rIHRoZSB3YXkgd2Ugc2hvdWxkIGhhbmRsZSBpbmhpYml0L3VuaW5o aWJpdCwgaXMgdGhhdAo+Pj4gaWYgd2UgaGF2ZSB0aGUgY2FsbGJhY2sgZGVmaW5lZCwgdGhlbiB3 ZSBjYWxsIGl0LCBhbmQgb25seSBjYWxsIG9wZW4gYW5kCj4+PiBjbG9zZSBpZiB1bmluaGliaXQg b3IgaW5oaWJpdCBhcmUgX25vdF8gZGVmaW5lZC4KPj4+Cj4+Cj4+IElmIEkgdW5kZXJzdGFuZCB5 b3UgY29ycmVjdGx5IHlvdSBzdWdnZXN0IHRvIGNhbGwgZWl0aGVyIGluaGliaXQsCj4+IGlmIHBy b3ZpZGVkIG9yIGNsb3NlLCBpZiBpbmhpYml0IGlzIG5vdCBwcm92aWRlZCwgYnV0IG5vdCBib3Ro LAo+PiB0aGF0IGlzLCBpZiBib3RoIGFyZSBwcm92aWRlZCB0aGVuIG9uIHRoZSBpbmhpYml0IHBh dGggb25seQo+PiBpbmhpYml0IGlzIGNhbGxlZC4gQW5kLCBjb25zZXF1ZW50bHksIHlvdSBzdWdn ZXN0IHRvIGNhbGwgZWl0aGVyCj4+IHVuaW5oaWJpdCBvciBvcGVuLCBidXQgbm90IGJvdGguIFRo ZSByZXN0IG9mIG15IG1haWwgbWFrZXMgdGhpcwo+PiBhc3N1bXB0aW9uLCBzbyBraW5kbHkgY29u ZmlybSBpZiBJIHVuZGVyc3RhbmQgeW91IGNvcnJlY3RseS4KPiAKPiBZZXMsIHRoYXQgaXMgY29y cmVjdC4gSWYgYSBkcml2ZXIgd2FudHMgcmVhbGx5IGZpbmUtZ3JhaW5lZCBjb250cm9sLCBpdAo+ IHdpbGwgcHJvdmlkZSBpbmhpYml0IChvciBib3RoIGluaGliaXQgYW5kIGNsb3NlKSwgb3RoZXJ3 aXNlIGl0IHdpbGwgcmVseQo+IG9uIGNsb3NlIGluIHBsYWNlIG9mIGluaGliaXQuCj4gCj4+Cj4+ IEluIG15IG9waW5pb24gdGhpcyBpZGVhIHdpbGwgbm90IHdvcmsuCj4+Cj4+IFRoZSBmaXJzdCBx dWVzdGlvbiBpcyBzaG91bGQgd2UgYmUgYWJsZSB0byBpbmhpYml0IGEgZGV2aWNlCj4+IHdoaWNo IGlzIG5vdCBvcGVuZWQ/IEluIG15IG9waW5pb24gd2Ugc2hvdWxkLCBpbiBvcmRlciB0byBiZQo+ PiBhYmxlIHRvIGluaGliaXQgYSBkZXZpY2UgaW4gYW50aWNpcGF0aW9uIHdpdGhvdXQgbmVlZGlu ZyB0bwo+PiBvcGVuIGl0IGZpcnN0Lgo+IAo+IEkgYWdyZWUuCj4gCj4+Cj4+IFRoZW4gd2hhdCBk b2VzIG9wZW5pbmcgKHdpdGggaW5wdXRfb3Blbl9kZXZpY2UoKSkgYW4gaW5oaWJpdGVkCj4+IGRl dmljZSBtZWFuPyBTaG91bGQgaXQgc3VjY2VlZCBvciBzaG91bGQgaXQgZmFpbD8KPiAKPiBJdCBz aG91bGQgc3VjY2VlZC4KPiAKPj4gSWYgaXQgaXMgbm90Cj4+IHRoZSBmaXJzdCBvcGVuaW5nIHRo ZW4gZWZmZWN0aXZlbHkgaXQgYm9pbHMgZG93biB0byBpbmNyZWFzaW5nCj4+IGRldmljZSdzIGFu ZCBoYW5kbGUncyBjb3VudGVycywgc28gd2UgY2FuIGFsbG93IGl0IHRvIHN1Y2NlZWQuCj4+IElm LCBob3dldmVyLCB0aGUgZGV2aWNlIGlzIGJlaW5nIG9wZW5lZCBmb3IgdGhlIGZpcnN0IHRpbWUs Cj4+IHRoZSAtPm9wZW4oKSBtZXRob2Qgd2FudHMgdG8gYmUgY2FsbGVkLCBidXQgdGhhdCBzb21l aG93Cj4+IGNvbnRyYWRpY3RzIHRoZSBkZXZpY2UncyBpbmhpYml0ZWQgc3RhdGUuIFNvIGEgbG9n aWNhbCB0aGluZwo+PiB0byBkbyBpcyB0byBlaXRoZXIgZmFpbCBpbnB1dF9vcGVuX2RldmljZSgp IG9yIHBvc3Rwb25lIC0+b3BlbigpCj4+IGludm9jYXRpb24gdG8gdGhlIG1vbWVudCBvZiB1bmlu aGliaXRpbmcgLSBhbmQgdGhlIGxhdHRlciBpcwo+PiB3aGF0IHRoZSBwYXRjaGVzIGluIHRoaXMg c2VyaWVzIGN1cnJlbnRseSBkby4KPj4KPj4gRmFpbGluZyBpbnB1dF9vcGVuX2RldmljZSgpIGJl Y2F1c2Ugb2YgdGhlIGluaGliaXRlZCBzdGF0ZSBpcwo+PiBub3QgdGhlIHJpZ2h0IHRoaW5nIHRv IGRvLiBMZXQgbWUgZXhwbGFpbi4gU3VwcG9zZSB0aGF0IGEgZGV2aWNlCj4+IGlzIGFscmVhZHkg aW5oaWJpdGVkIGFuZCB0aGVuIGEgbmV3IG1hdGNoaW5nIGhhbmRsZXIgYXBwZWFycwo+PiBpbiB0 aGUgc3lzdGVtLiBNb3N0IGhhbmRsZXJzIChhcG0tcG93ZXIuYywgZXZidWcuYywgaW5wdXQtbGVk cy5jLAo+PiBtYWNfaGlkLmMsIHN5c3JxLmMsIHZ0L2tleWJvYXJkLmMgYW5kIHJma2lsbC9pbnB1 dC5jKSBkb24ndCBjcmVhdGUKPj4gYW55IGNoYXJhY3RlciBkZXZpY2VzIChvbmx5IGV2ZGV2LmMs IGpveWRldi5jIGFuZCBtb3VzZWRldi5jIGRvKSwKPj4gc28gZm9yIHRoZW0gaXQgbWFrZXMgbm8g c2Vuc2UgdG8gZGVsYXkgY2FsbGluZyBpbnB1dF9vcGVuX2RldmljZSgpCj4+IGFuZCBpdCBpcyBj YWxsZWQgaW4gaGFuZGxlcidzIC0+Y29ubmVjdCgpLiBJZiBpbnB1dF9vcGVuX2RldmljZSgpCj4+ IG5vdyBmYWlscywgd2UgaGF2ZSBsb3N0IHRoZSBvbmx5IGNoYW5jZSBmb3IgdGhpcyAtPmNvbm5l Y3QoKSB0bwo+PiBzdWNjZWVkLgo+Pgo+PiBTdW1tYXJpemluZywgSU1PIHRoZSB1bmluaGliaXQg cGF0aCBzaG91bGQgYmUgY2FsbGluZyBib3RoCj4+IC0+b3BlbigpIGFuZCAtPnVuaW5oaWJpdCgp IChpZiBwcm92aWRlZCksIGFuZCBjb252ZXJzZWx5LCB0aGUgaW5oaWJpdAo+PiBwYXRoIHNob3Vs ZCBiZSBjYWxsaW5nIGJvdGggLT5pbmhpYml0KCkgYW5kIC0+Y2xvc2UoKSAoaWYgcHJvdmlkZWQp Lgo+IAo+IFNvIHdoYXQgeW91IGFyZSB0cnlpbmcgdG8gc2F5IGlzIHRoYXQgeW91IHNlZSBpbmhp Yml0IGFzIHNvbWV0aGluZyB0aGF0Cj4gaXMgZG9uZSBpbiBhZGRpdGlvbiB0byB3aGF0IGhhcHBl bnMgaW4gY2xvc2UuIEJ1dCB3aGF0IGV4YWN0bHkgZG8geW91Cj4gd2FudCB0byBkbyBpbiBpbmhp Yml0LCBpbiBhZGRpdGlvbiB0byB3aGF0IGNsb3NlIGlzIGRvaW5nPwoKU2VlIGJlbG93ICgqKS4K Cj4gCj4gSW4gbXkgdmlldywgaWYgd2Ugd2FudCB0byBoYXZlIGEgZGVkaWNhdGVkIGluaGliaXQg Y2FsbGJhY2ssIHRoZW4gaXQKPiB3aWxsIGRvIGV2ZXJ5dGhpbmcgdGhhdCBjbG9zZSBkb2VzLCB0 aGV5IGJvdGggYXJlIGF3YXJlIG9mIGVhY2ggb3RoZXIKPiBhbmQgY2FuIHNvcnQgb3V0IHRoZSBz dGF0ZSB0cmFuc2l0aW9ucyBiZXR3ZWVuIHRoZW0uIEZvciBkcml2ZXJzIHRoYXQgZG8KPiBub3Qg aGF2ZSBkZWRpY2F0ZWQgaW5oaWJpdC91bmluaGliaXQsIHdlIGNhbiB1c2Ugb3BlbiBhbmQgY2xv c2UKPiBoYW5kbGVycywgYW5kIGhhdmUgaW5wdXQgY29yZSBzb3J0IG91dCB3aGVuIGVhY2ggc2hv dWxkIGJlIGNhbGxlZC4gVGhhdAo+IG1lYW5zIHRoYXQgd2Ugc2hvdWxkIG5vdCBjYWxsIGRldi0+ b3BlbigpIGluIGlucHV0X29wZW5fZGV2aWNlKCkgd2hlbgo+IGRldmljZSBpcyBpbmhpYml0ZWQg KGFuZCBzYW1lIGZvciBkZXYtPmNsb3NlKCkgaW4gaW5wdXRfY2xvc2VfZGV2aWNlKS4KPiBBbmQg d2hlbiB1bmluaGliaXRpbmcsIHdlIHNob3VsZCBub3QgY2FsbCBkZXYtPm9wZW4oKSB3aGVuIHRo ZXJlIGFyZSBubwo+IHVzZXJzIGZvciB0aGUgZGV2aWNlLCBhbmQgbm8gZGV2LT5jbG9zZSgpIHdo ZW4gaW5oaWJpdGluZyB3aXRoIG5vIHVzZXJzLgo+IAo+IERvIHlvdSBzZWUgYW55IHByb2JsZW1z IHdpdGggdGhpcyBhcHByb2FjaD8KCk15IGNvbmNlcm4gaXMgdGhhdCBpZiBlLmcuIGJvdGggLT5v cGVuKCkgYW5kIC0+dW5pbmhpYml0KCkgYXJlIHByb3ZpZGVkLAp0aGVuIGluIGNlcnRhaW4gY2ly Y3Vtc3RhbmNlcyAtPm9wZW4oKSB3b24ndCBiZSBjYWxsZWQ6CgoxLiB1c2VycyA9PSAwCjIuIGlu aGliaXQgaGFwcGVucwozLiBpbnB1dF9vcGVuX2RldmljZSgpIGhhcHBlbnMsIC0+b3BlbigpIG5v dCBjYWxsZWQKNC4gdW5pbmhpYml0IGhhcHBlbnMKNS4gYXMgcGFydCBvZiB1bmluaGliaXQgLT51 bmluaGliaXQoKSBpcyBvbmx5IGNhbGxlZCwgYnV0IC0+b3BlbigpIGlzIG5vdC4KClRoZXkgd2F5 IEkgdW5kZXJzdGFuZCB5b3VyIGFuc3dlciBpcyB0aGF0IHdlIGltcGxpY2l0bHkgaW1wb3NlIHJl cXVpcmVtZW50cwpvbiBkcml2ZXJzIHdoaWNoIGNob29zZSB0byBpbXBsZW1lbnQgZS5nLiBib3Ro IC0+b3BlbigpIGFuZCAtPnVuaW5oaWJpdCgpOgppbiBzdWNoIGEgY2FzZSAtPnVuaW5oaWJpdCgp IHNob3VsZCBiZSBkb2luZyBleGFjdGx5IHRoZSBzYW1lIHRoaW5ncyBhcwotPm9wZW4oKSBkb2Vz LiBXaGljaCBsZWFkcyB0byBhIGNvbmNsdXNpb24gdGhhdCBpbiBwcmFjdGljZSBubyBkcml2ZXJz CnNob3VsZCBjaG9vc2UgdG8gaW1wbGVtZW50IGJvdGgsIG90aGVyd2lzZSB0aGV5IG11c3QgYmUg YXdhcmUgdGhhdAotPnVuaW5oaWJpdCgpIGNhbiBiZSBzb21ldGltZXMgY2FsbGVkIGluc3RlYWQg b2YgLT5vcGVuKCkuIFRoZW4gLT5vcGVuKCkKYmVjb21lcyBzeW5vbnltb3VzIHdpdGggLT51bmlu aGliaXQoKSwgYW5kIC0+Y2xvc2UoKSB3aXRoIC0+aW5oaWJpdCgpLgpPciwgbWF5YmUsIHRoZW4g LT5pbmhpYml0KCkgY2FuIGJlIGEgc3VwZXJzZXQgb2YgLT5jbG9zZSgpIGFuZAotPnVuaW5oaWJp dCgpIGEgc3VwZXJzZXQgb2YgLT5vcGVuKCkuCgpJZiBzdWNoIGFuIGFwcHJvYWNoIGlzIG9rIHdp dGggeW91LCBpdCBpcyBvayB3aXRoIG1lLCB0b28uCgooKikKQ2FsbGluZyBib3RoIC0+aW5oaWJp dCgpIGFuZCAtPmNsb3NlKCkgKGlmIHRoZXkgYXJlIHByb3ZpZGVkKSBhbGxvd3MKZHJpdmVycyB0 byBnbyBmYW5jeSBhbmQgZmFpbCBpbmhpYml0aW5nICh3aGljaCBpcyBpbXBvc3NpYmxlIHVzaW5n Cm9ubHkgLT5jbG9zZSgpIGFzIGl0IGRvZXMgbm90IHJldHVybiBhIHZhbHVlLCBidXQgLT5pbmhp Yml0KCkgYnkgZGVzaWduCmRvZXMpLiBUaGVuIC0+dW5pbmhpYml0KCkgaXMgbW9zdGx5IGZvciBz eW1tZXRyeS4KClJlZ2FyZHMsCgpBbmRyemVqCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1h cm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcv bWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==