From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,USER_AGENT_MUTT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 303A5C43381 for ; Sat, 9 Mar 2019 11:26:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CA0F9207E0 for ; Sat, 9 Mar 2019 11:26:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tThziCyk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726208AbfCIL0H (ORCPT ); Sat, 9 Mar 2019 06:26:07 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:39334 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726164AbfCIL0H (ORCPT ); Sat, 9 Mar 2019 06:26:07 -0500 Received: from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 87A9E49; Sat, 9 Mar 2019 12:26:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1552130763; bh=+z0McpVDw9FqQhFndbafLO7aiSsGZpQE+B+a7XA0ZR4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=tThziCyksSjbWVyxIuFKsHr44hWTJC4WVBVs4nkECDNPRxXmhFhyzgRXkfW+ce8s5 n/8kMHpTgrN41LYHW/eDBGBEGACFi6nrk9rviMGDq1wzPMEa7Sgg1K9AiUikE4aQv5 xRHuJKbyJQkLgyc4E4N0Cm8DdQOlA8paZxgb2PnU= Date: Sat, 9 Mar 2019 13:25:56 +0200 From: Laurent Pinchart To: Jacopo Mondi Cc: Laurent Pinchart , dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, Kieran Bingham Subject: Re: [PATCH/RFC 11/15] drm: rcar-du: lvds: Add support for dual-link mode Message-ID: <20190309112556.GA4924@pendragon.ideasonboard.com> References: <20190306232345.23052-1-laurent.pinchart+renesas@ideasonboard.com> <20190306232345.23052-12-laurent.pinchart+renesas@ideasonboard.com> <20190308172023.vtsvouwo4ltxzgx2@uno.localdomain> <20190308181239.GD11318@pendragon.ideasonboard.com> <20190309111132.qxpppbokn3stfjhl@uno.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20190309111132.qxpppbokn3stfjhl@uno.localdomain> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Hi Jacopo, On Sat, Mar 09, 2019 at 12:11:32PM +0100, Jacopo Mondi wrote: > On Fri, Mar 08, 2019 at 08:12:39PM +0200, Laurent Pinchart wrote: > > On Fri, Mar 08, 2019 at 06:20:23PM +0100, Jacopo Mondi wrote: > >> On Thu, Mar 07, 2019 at 01:23:41AM +0200, Laurent Pinchart wrote: > >>> In dual-link mode the LVDS0 encoder transmits even-numbered pixels, and > >>> sends odd-numbered pixels to the LVDS1 encoder for transmission on a > >>> separate link. > >>> > >>> To implement support for this mode of operation, determine if the LVDS > >>> connection operates in dual-link mode by querying the next device in the > >>> pipeline, locate the companion encoder, and control it directly through > >>> its bridge operations. > >>> > >>> Signed-off-by: Laurent Pinchart > >>> --- > >>> drivers/gpu/drm/rcar-du/rcar_lvds.c | 104 ++++++++++++++++++++++++---- > >>> drivers/gpu/drm/rcar-du/rcar_lvds.h | 5 ++ > >>> 2 files changed, 96 insertions(+), 13 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c > >>> index 5ac92ee15be0..90d33514bb3e 100644 > >>> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c > >>> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c > >>> @@ -66,6 +66,9 @@ struct rcar_lvds { > >>> > >>> struct drm_display_mode display_mode; > >>> enum rcar_lvds_mode mode; > >>> + > >>> + struct drm_bridge *companion; > >>> + bool dual_link; > >>> }; > >>> > >>> #define bridge_to_rcar_lvds(bridge) \ > >>> @@ -400,11 +403,6 @@ static void rcar_lvds_enable(struct drm_bridge *bridge) > >>> { > >>> struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); > >>> const struct drm_display_mode *mode = &lvds->display_mode; > >>> - /* > >>> - * FIXME: We should really retrieve the CRTC through the state, but how > >>> - * do we get a state pointer? > >>> - */ > >>> - struct drm_crtc *crtc = lvds->bridge.encoder->crtc; > >>> u32 lvdhcr; > >>> u32 lvdcr0; > >>> int ret; > >>> @@ -413,6 +411,10 @@ static void rcar_lvds_enable(struct drm_bridge *bridge) > >>> if (ret < 0) > >>> return; > >>> > >>> + /* Enable the companion LVDS encoder in dual-link mode. */ > >>> + if (lvds->dual_link && lvds->companion) > >>> + lvds->companion->funcs->enable(lvds->companion); > >>> + > >>> /* > >>> * Hardcode the channels and control signals routing for now. > >>> * > >>> @@ -435,17 +437,33 @@ static void rcar_lvds_enable(struct drm_bridge *bridge) > >>> rcar_lvds_write(lvds, LVDCHCR, lvdhcr); > >>> > >>> if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) { > >>> - /* Disable dual-link mode. */ > >>> - rcar_lvds_write(lvds, LVDSTRIPE, 0); > >>> + /* > >>> + * Configure vertical stripe based on the mode of operation of > >>> + * the connected device. > >>> + */ > >>> + rcar_lvds_write(lvds, LVDSTRIPE, > >>> + lvds->dual_link ? LVDSTRIPE_ST_ON : 0); > >>> } > >>> > >>> - /* PLL clock configuration. */ > >>> - lvds->info->pll_setup(lvds, mode->clock * 1000); > >>> + /* > >>> + * PLL clock configuration on all instances but the companion in > >>> + * dual-link mode. > >>> + */ > >>> + if (!lvds->dual_link || lvds->companion) > >>> + lvds->info->pll_setup(lvds, mode->clock * 1000); > >>> > >>> /* Set the LVDS mode and select the input. */ > >>> lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT; > >>> - if (drm_crtc_index(crtc) == 2) > >>> - lvdcr0 |= LVDCR0_DUSEL; > >>> + > >>> + if (lvds->bridge.encoder) { > >>> + /* > >>> + * FIXME: We should really retrieve the CRTC through the state, > >>> + * but how do we get a state pointer? > >>> + */ > >>> + if (drm_crtc_index(lvds->bridge.encoder->crtc) == 2) > >>> + lvdcr0 |= LVDCR0_DUSEL; > >>> + } > >>> + > >>> rcar_lvds_write(lvds, LVDCR0, lvdcr0); > >>> > >>> /* Turn all the channels on. */ > >>> @@ -512,6 +530,10 @@ static void rcar_lvds_disable(struct drm_bridge *bridge) > >>> rcar_lvds_write(lvds, LVDCR1, 0); > >>> rcar_lvds_write(lvds, LVDPLLCR, 0); > >>> > >>> + /* Disable the companion LVDS encoder in dual-link mode. */ > >>> + if (lvds->dual_link && lvds->companion) > >>> + lvds->companion->funcs->disable(lvds->companion); > >>> + > >>> clk_disable_unprepare(lvds->clocks.mod); > >>> } > >>> > >>> @@ -628,10 +650,54 @@ static const struct drm_bridge_funcs rcar_lvds_bridge_ops = { > >>> .mode_set = rcar_lvds_mode_set, > >>> }; > >>> > >>> +bool rcar_lvds_dual_link(struct drm_bridge *bridge) > >>> +{ > >>> + struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); > >>> + > >>> + return lvds->dual_link; > >>> +} > >>> +EXPORT_SYMBOL_GPL(rcar_lvds_dual_link); > >>> + > >>> /* ----------------------------------------------------------------------------- > >>> * Probe & Remove > >>> */ > >>> > >>> +static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) > >>> +{ > >>> + const struct of_device_id *match; > >>> + struct device_node *companion; > >>> + struct device *dev = lvds->dev; > >>> + int ret = 0; > >>> + > >>> + /* Locate the companion LVDS encoder for dual-link operation, if any. */ > >>> + companion = of_parse_phandle(dev->of_node, "renesas,companion", 0); > >>> + if (!companion) > >>> + return -ENODEV; > >>> + > >>> + /* > >>> + * Sanity check: the companion encoder must have the same compatible > >>> + * string. > >>> + */ > >>> + match = of_match_device(dev->driver->of_match_table, dev); > >>> + if (!of_device_is_compatible(companion, match->compatible)) { > >>> + ret = -ENODEV; > >>> + goto done; > >>> + } > >>> + > >>> + lvds->companion = of_drm_find_bridge(companion); > >>> + if (!lvds->companion) { > >>> + ret = -EPROBE_DEFER; > >>> + goto done; > >>> + } > >>> + > >>> + dev_dbg(dev, "Found companion encoder %pOF\n", companion); > >>> + > >>> +done: > >>> + of_node_put(companion); > >>> + > >>> + return ret; > >>> +} > >>> + > >>> static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) > >>> { > >>> struct device_node *local_output = NULL; > >>> @@ -682,14 +748,26 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) > >>> > >>> if (is_bridge) { > >>> lvds->next_bridge = of_drm_find_bridge(remote); > >>> - if (!lvds->next_bridge) > >>> + if (!lvds->next_bridge) { > >>> ret = -EPROBE_DEFER; > >>> + goto done; > >>> + } > >>> + > >>> + if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) > >>> + lvds->dual_link = lvds->next_bridge->timings > >>> + ? lvds->next_bridge->timings->dual_link > >>> + : false; > >> > >> I wonder if, in all this patch, you could not use "lvds->companion" in > >> place of "lvds->dual_link", and thus drop that from timings. This mean > >> "renesas,companion" would only be used when operating in dual link > >> mode, which might be less nice (and could actually called differently > >> in that case). > >> > >> Both the THC631024 and the rcar_du-lvds driver would decide > >> independently if they operate in dual link mode or not (one counting > >> its endpoints, the other inspecting the "renesas,companion" property). > > > > I decided to specify the companion in DT regardless of which operating > > mode is used, as it's a property of the LVDS encoder, not of the > > operating mode. Furthermore, I can foresee setups where the mode would > > be selected dynamically at runtime. Our development boards don't allow > > that as they hardcode the mode using DIP switches, but nothing would > > prevent the mode selection signals to be connected to GPIOs. I thus > > think lvds->companion should point to the companion unconditionally, and > > lvds->dual_link should select the operating mode. The dual_link field is > > currently set at probe time as I have no need for dynamic configuration > > of the mode and no mean of testing it, so I decided not to implement > > dynamic switching yet. > > Fine, I tried thinking up a bit if the "renesas,companion" property > could have been made an endpoint property, to be specified in both > the rcar-lvds endpoints and in the DU endpoints, so that the > rcar_du_encoder does not need to pick into the lvds-encoder to know > if it is operating in dual link mode or not and skip creation of the > encoder associated to LVDS1 in such a case. > > Furthermore, we could make a "vstripe-even" "vstripe-odd" endpoint > properties, that would allow you to control the ST_SWAP field of > LVDSTRIPE register, and create another endpoint property that contains > the phandle to the companion, like "dual-link-companion" or > "dual-link-slave". Those properties would need to be specified in both > DU and LVDS endpoints though, which might be clunky, but that would > possibly save a few cross-driver calls. Regarding the stripe odd/even control, I think this should be handled dynamically without involving DT. We will need an API for bridges to report what order(s) they support, and allow the remote component to be configured accordingly. A DT property isn't needed for this. Regarding the companion, it's not a generic concept. It happens that Renesas decided to implement dual-link support by configuring one of the two LVDS encoders as a master and the other one as a slave, but there could be other options. That's why I made this a Renesas-specific property. I believe it is placed correctly in the LVDS encoder DT node, and not in the port or endpoint, as it's a property of the LVDS encoder itself. Other models are possible though, I could have added a third port to the LVDS encoders to model this connection, but as ports don't indicate a direction, I would have needed an extra property anyway to differentiate between the master and the slave. > Anyway, just putting a few more options on the table, if you have > already considered those feel free to stick to this implementation... > > >> The only place where this might be tricky is the here above > >> > >> + /* > >> + * PLL clock configuration on all instances but the companion in > >> + * dual-link mode. > >> + */ > >> + if (!lvds->dual_link || lvds->companion) > >> + lvds->info->pll_setup(lvds, mode->clock * 1000); > >> > >> but that would remove the need for the thc63 bridge to report its > >> operating mode in timings... > >> > >>> } else { > >>> lvds->panel = of_drm_find_panel(remote); > >>> - if (IS_ERR(lvds->panel)) > >>> + if (IS_ERR(lvds->panel)) { > >>> ret = PTR_ERR(lvds->panel); > >>> + goto done; > >>> + } > >>> } > >>> > >>> + if (lvds->dual_link) > >> > >> Note: if (!is_bridge) you would never set lvds->dual_link, so this > >> should be moved inside the here above "if (is_bridge)" > > > > I don't yet, but nothing prevents a panel from operating in dual mode, > > even if not implemented yet. That's why I've move this check out of the > > bridge/panel conditional code. > > I see, still right now is of no use. It's fine though, really minor > stuff. > > >>> + ret = rcar_lvds_parse_dt_companion(lvds); > >>> + > >>> done: > >>> of_node_put(local_output); > >>> of_node_put(remote_input); > >>> diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.h b/drivers/gpu/drm/rcar-du/rcar_lvds.h > >>> index a709cae1bc32..222ec0e60785 100644 > >>> --- a/drivers/gpu/drm/rcar-du/rcar_lvds.h > >>> +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.h > >>> @@ -15,6 +15,7 @@ struct drm_bridge; > >>> #if IS_ENABLED(CONFIG_DRM_RCAR_LVDS) > >>> int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq); > >>> void rcar_lvds_clk_disable(struct drm_bridge *bridge); > >>> +bool rcar_lvds_dual_link(struct drm_bridge *bridge); > >>> #else > >>> static inline int rcar_lvds_clk_enable(struct drm_bridge *bridge, > >>> unsigned long freq) > >>> @@ -22,6 +23,10 @@ static inline int rcar_lvds_clk_enable(struct drm_bridge *bridge, > >>> return -ENOSYS; > >>> } > >>> static inline void rcar_lvds_clk_disable(struct drm_bridge *bridge) { } > >>> +static inline bool rcar_lvds_dual_link(struct drm_bridge *bridge) > >>> +{ > >>> + return false; > >>> +} > >>> #endif /* CONFIG_DRM_RCAR_LVDS */ > >>> > >>> #endif /* __RCAR_LVDS_H__ */ -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH/RFC 11/15] drm: rcar-du: lvds: Add support for dual-link mode Date: Sat, 9 Mar 2019 13:25:56 +0200 Message-ID: <20190309112556.GA4924@pendragon.ideasonboard.com> References: <20190306232345.23052-1-laurent.pinchart+renesas@ideasonboard.com> <20190306232345.23052-12-laurent.pinchart+renesas@ideasonboard.com> <20190308172023.vtsvouwo4ltxzgx2@uno.localdomain> <20190308181239.GD11318@pendragon.ideasonboard.com> <20190309111132.qxpppbokn3stfjhl@uno.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by gabe.freedesktop.org (Postfix) with ESMTPS id B8AB188602 for ; Sat, 9 Mar 2019 11:26:05 +0000 (UTC) Content-Disposition: inline In-Reply-To: <20190309111132.qxpppbokn3stfjhl@uno.localdomain> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Jacopo Mondi Cc: linux-renesas-soc@vger.kernel.org, Laurent Pinchart , Kieran Bingham , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org SGkgSmFjb3BvLAoKT24gU2F0LCBNYXIgMDksIDIwMTkgYXQgMTI6MTE6MzJQTSArMDEwMCwgSmFj b3BvIE1vbmRpIHdyb3RlOgo+IE9uIEZyaSwgTWFyIDA4LCAyMDE5IGF0IDA4OjEyOjM5UE0gKzAy MDAsIExhdXJlbnQgUGluY2hhcnQgd3JvdGU6Cj4gPiBPbiBGcmksIE1hciAwOCwgMjAxOSBhdCAw NjoyMDoyM1BNICswMTAwLCBKYWNvcG8gTW9uZGkgd3JvdGU6Cj4gPj4gT24gVGh1LCBNYXIgMDcs IDIwMTkgYXQgMDE6MjM6NDFBTSArMDIwMCwgTGF1cmVudCBQaW5jaGFydCB3cm90ZToKPiA+Pj4g SW4gZHVhbC1saW5rIG1vZGUgdGhlIExWRFMwIGVuY29kZXIgdHJhbnNtaXRzIGV2ZW4tbnVtYmVy ZWQgcGl4ZWxzLCBhbmQKPiA+Pj4gc2VuZHMgb2RkLW51bWJlcmVkIHBpeGVscyB0byB0aGUgTFZE UzEgZW5jb2RlciBmb3IgdHJhbnNtaXNzaW9uIG9uIGEKPiA+Pj4gc2VwYXJhdGUgbGluay4KPiA+ Pj4KPiA+Pj4gVG8gaW1wbGVtZW50IHN1cHBvcnQgZm9yIHRoaXMgbW9kZSBvZiBvcGVyYXRpb24s IGRldGVybWluZSBpZiB0aGUgTFZEUwo+ID4+PiBjb25uZWN0aW9uIG9wZXJhdGVzIGluIGR1YWwt bGluayBtb2RlIGJ5IHF1ZXJ5aW5nIHRoZSBuZXh0IGRldmljZSBpbiB0aGUKPiA+Pj4gcGlwZWxp bmUsIGxvY2F0ZSB0aGUgY29tcGFuaW9uIGVuY29kZXIsIGFuZCBjb250cm9sIGl0IGRpcmVjdGx5 IHRocm91Z2gKPiA+Pj4gaXRzIGJyaWRnZSBvcGVyYXRpb25zLgo+ID4+Pgo+ID4+PiBTaWduZWQt b2ZmLWJ5OiBMYXVyZW50IFBpbmNoYXJ0IDxsYXVyZW50LnBpbmNoYXJ0K3JlbmVzYXNAaWRlYXNv bmJvYXJkLmNvbT4KPiA+Pj4gLS0tCj4gPj4+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2Fy X2x2ZHMuYyB8IDEwNCArKysrKysrKysrKysrKysrKysrKysrKystLS0tCj4gPj4+ICBkcml2ZXJz L2dwdS9kcm0vcmNhci1kdS9yY2FyX2x2ZHMuaCB8ICAgNSArKwo+ID4+PiAgMiBmaWxlcyBjaGFu Z2VkLCA5NiBpbnNlcnRpb25zKCspLCAxMyBkZWxldGlvbnMoLSkKPiA+Pj4KPiA+Pj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfbHZkcy5jIGIvZHJpdmVycy9ncHUv ZHJtL3JjYXItZHUvcmNhcl9sdmRzLmMKPiA+Pj4gaW5kZXggNWFjOTJlZTE1YmUwLi45MGQzMzUx NGJiM2UgMTAwNjQ0Cj4gPj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfbHZk cy5jCj4gPj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfbHZkcy5jCj4gPj4+ IEBAIC02Niw2ICs2Niw5IEBAIHN0cnVjdCByY2FyX2x2ZHMgewo+ID4+Pgo+ID4+PiAgCXN0cnVj dCBkcm1fZGlzcGxheV9tb2RlIGRpc3BsYXlfbW9kZTsKPiA+Pj4gIAllbnVtIHJjYXJfbHZkc19t b2RlIG1vZGU7Cj4gPj4+ICsKPiA+Pj4gKwlzdHJ1Y3QgZHJtX2JyaWRnZSAqY29tcGFuaW9uOwo+ ID4+PiArCWJvb2wgZHVhbF9saW5rOwo+ID4+PiAgfTsKPiA+Pj4KPiA+Pj4gICNkZWZpbmUgYnJp ZGdlX3RvX3JjYXJfbHZkcyhicmlkZ2UpIFwKPiA+Pj4gQEAgLTQwMCwxMSArNDAzLDYgQEAgc3Rh dGljIHZvaWQgcmNhcl9sdmRzX2VuYWJsZShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ID4+ PiAgewo+ID4+PiAgCXN0cnVjdCByY2FyX2x2ZHMgKmx2ZHMgPSBicmlkZ2VfdG9fcmNhcl9sdmRz KGJyaWRnZSk7Cj4gPj4+ICAJY29uc3Qgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1vZGUgPSAm bHZkcy0+ZGlzcGxheV9tb2RlOwo+ID4+PiAtCS8qCj4gPj4+IC0JICogRklYTUU6IFdlIHNob3Vs ZCByZWFsbHkgcmV0cmlldmUgdGhlIENSVEMgdGhyb3VnaCB0aGUgc3RhdGUsIGJ1dCBob3cKPiA+ Pj4gLQkgKiBkbyB3ZSBnZXQgYSBzdGF0ZSBwb2ludGVyPwo+ID4+PiAtCSAqLwo+ID4+PiAtCXN0 cnVjdCBkcm1fY3J0YyAqY3J0YyA9IGx2ZHMtPmJyaWRnZS5lbmNvZGVyLT5jcnRjOwo+ID4+PiAg CXUzMiBsdmRoY3I7Cj4gPj4+ICAJdTMyIGx2ZGNyMDsKPiA+Pj4gIAlpbnQgcmV0Owo+ID4+PiBA QCAtNDEzLDYgKzQxMSwxMCBAQCBzdGF0aWMgdm9pZCByY2FyX2x2ZHNfZW5hYmxlKHN0cnVjdCBk cm1fYnJpZGdlICpicmlkZ2UpCj4gPj4+ICAJaWYgKHJldCA8IDApCj4gPj4+ICAJCXJldHVybjsK PiA+Pj4KPiA+Pj4gKwkvKiBFbmFibGUgdGhlIGNvbXBhbmlvbiBMVkRTIGVuY29kZXIgaW4gZHVh bC1saW5rIG1vZGUuICovCj4gPj4+ICsJaWYgKGx2ZHMtPmR1YWxfbGluayAmJiBsdmRzLT5jb21w YW5pb24pCj4gPj4+ICsJCWx2ZHMtPmNvbXBhbmlvbi0+ZnVuY3MtPmVuYWJsZShsdmRzLT5jb21w YW5pb24pOwo+ID4+PiArCj4gPj4+ICAJLyoKPiA+Pj4gIAkgKiBIYXJkY29kZSB0aGUgY2hhbm5l bHMgYW5kIGNvbnRyb2wgc2lnbmFscyByb3V0aW5nIGZvciBub3cuCj4gPj4+ICAJICoKPiA+Pj4g QEAgLTQzNSwxNyArNDM3LDMzIEBAIHN0YXRpYyB2b2lkIHJjYXJfbHZkc19lbmFibGUoc3RydWN0 IGRybV9icmlkZ2UgKmJyaWRnZSkKPiA+Pj4gIAlyY2FyX2x2ZHNfd3JpdGUobHZkcywgTFZEQ0hD UiwgbHZkaGNyKTsKPiA+Pj4KPiA+Pj4gIAlpZiAobHZkcy0+aW5mby0+cXVpcmtzICYgUkNBUl9M VkRTX1FVSVJLX0RVQUxfTElOSykgewo+ID4+PiAtCQkvKiBEaXNhYmxlIGR1YWwtbGluayBtb2Rl LiAqLwo+ID4+PiAtCQlyY2FyX2x2ZHNfd3JpdGUobHZkcywgTFZEU1RSSVBFLCAwKTsKPiA+Pj4g KwkJLyoKPiA+Pj4gKwkJICogQ29uZmlndXJlIHZlcnRpY2FsIHN0cmlwZSBiYXNlZCBvbiB0aGUg bW9kZSBvZiBvcGVyYXRpb24gb2YKPiA+Pj4gKwkJICogdGhlIGNvbm5lY3RlZCBkZXZpY2UuCj4g Pj4+ICsJCSAqLwo+ID4+PiArCQlyY2FyX2x2ZHNfd3JpdGUobHZkcywgTFZEU1RSSVBFLAo+ID4+ PiArCQkJCWx2ZHMtPmR1YWxfbGluayA/IExWRFNUUklQRV9TVF9PTiA6IDApOwo+ID4+PiAgCX0K PiA+Pj4KPiA+Pj4gLQkvKiBQTEwgY2xvY2sgY29uZmlndXJhdGlvbi4gKi8KPiA+Pj4gLQlsdmRz LT5pbmZvLT5wbGxfc2V0dXAobHZkcywgbW9kZS0+Y2xvY2sgKiAxMDAwKTsKPiA+Pj4gKwkvKgo+ ID4+PiArCSAqIFBMTCBjbG9jayBjb25maWd1cmF0aW9uIG9uIGFsbCBpbnN0YW5jZXMgYnV0IHRo ZSBjb21wYW5pb24gaW4KPiA+Pj4gKwkgKiBkdWFsLWxpbmsgbW9kZS4KPiA+Pj4gKwkgKi8KPiA+ Pj4gKwlpZiAoIWx2ZHMtPmR1YWxfbGluayB8fCBsdmRzLT5jb21wYW5pb24pCj4gPj4+ICsJCWx2 ZHMtPmluZm8tPnBsbF9zZXR1cChsdmRzLCBtb2RlLT5jbG9jayAqIDEwMDApOwo+ID4+Pgo+ID4+ PiAgCS8qIFNldCB0aGUgTFZEUyBtb2RlIGFuZCBzZWxlY3QgdGhlIGlucHV0LiAqLwo+ID4+PiAg CWx2ZGNyMCA9IGx2ZHMtPm1vZGUgPDwgTFZEQ1IwX0xWTURfU0hJRlQ7Cj4gPj4+IC0JaWYgKGRy bV9jcnRjX2luZGV4KGNydGMpID09IDIpCj4gPj4+IC0JCWx2ZGNyMCB8PSBMVkRDUjBfRFVTRUw7 Cj4gPj4+ICsKPiA+Pj4gKwlpZiAobHZkcy0+YnJpZGdlLmVuY29kZXIpIHsKPiA+Pj4gKwkJLyoK PiA+Pj4gKwkJICogRklYTUU6IFdlIHNob3VsZCByZWFsbHkgcmV0cmlldmUgdGhlIENSVEMgdGhy b3VnaCB0aGUgc3RhdGUsCj4gPj4+ICsJCSAqIGJ1dCBob3cgZG8gd2UgZ2V0IGEgc3RhdGUgcG9p bnRlcj8KPiA+Pj4gKwkJICovCj4gPj4+ICsJCWlmIChkcm1fY3J0Y19pbmRleChsdmRzLT5icmlk Z2UuZW5jb2Rlci0+Y3J0YykgPT0gMikKPiA+Pj4gKwkJCWx2ZGNyMCB8PSBMVkRDUjBfRFVTRUw7 Cj4gPj4+ICsJfQo+ID4+PiArCj4gPj4+ICAJcmNhcl9sdmRzX3dyaXRlKGx2ZHMsIExWRENSMCwg bHZkY3IwKTsKPiA+Pj4KPiA+Pj4gIAkvKiBUdXJuIGFsbCB0aGUgY2hhbm5lbHMgb24uICovCj4g Pj4+IEBAIC01MTIsNiArNTMwLDEwIEBAIHN0YXRpYyB2b2lkIHJjYXJfbHZkc19kaXNhYmxlKHN0 cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UpCj4gPj4+ICAJcmNhcl9sdmRzX3dyaXRlKGx2ZHMsIExW RENSMSwgMCk7Cj4gPj4+ICAJcmNhcl9sdmRzX3dyaXRlKGx2ZHMsIExWRFBMTENSLCAwKTsKPiA+ Pj4KPiA+Pj4gKwkvKiBEaXNhYmxlIHRoZSBjb21wYW5pb24gTFZEUyBlbmNvZGVyIGluIGR1YWwt bGluayBtb2RlLiAqLwo+ID4+PiArCWlmIChsdmRzLT5kdWFsX2xpbmsgJiYgbHZkcy0+Y29tcGFu aW9uKQo+ID4+PiArCQlsdmRzLT5jb21wYW5pb24tPmZ1bmNzLT5kaXNhYmxlKGx2ZHMtPmNvbXBh bmlvbik7Cj4gPj4+ICsKPiA+Pj4gIAljbGtfZGlzYWJsZV91bnByZXBhcmUobHZkcy0+Y2xvY2tz Lm1vZCk7Cj4gPj4+ICB9Cj4gPj4+Cj4gPj4+IEBAIC02MjgsMTAgKzY1MCw1NCBAQCBzdGF0aWMg Y29uc3Qgc3RydWN0IGRybV9icmlkZ2VfZnVuY3MgcmNhcl9sdmRzX2JyaWRnZV9vcHMgPSB7Cj4g Pj4+ICAJLm1vZGVfc2V0ID0gcmNhcl9sdmRzX21vZGVfc2V0LAo+ID4+PiAgfTsKPiA+Pj4KPiA+ Pj4gK2Jvb2wgcmNhcl9sdmRzX2R1YWxfbGluayhzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ ID4+PiArewo+ID4+PiArCXN0cnVjdCByY2FyX2x2ZHMgKmx2ZHMgPSBicmlkZ2VfdG9fcmNhcl9s dmRzKGJyaWRnZSk7Cj4gPj4+ICsKPiA+Pj4gKwlyZXR1cm4gbHZkcy0+ZHVhbF9saW5rOwo+ID4+ PiArfQo+ID4+PiArRVhQT1JUX1NZTUJPTF9HUEwocmNhcl9sdmRzX2R1YWxfbGluayk7Cj4gPj4+ ICsKPiA+Pj4gIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4gPj4+ICAgKiBQcm9iZSAmIFJlbW92 ZQo+ID4+PiAgICovCj4gPj4+Cj4gPj4+ICtzdGF0aWMgaW50IHJjYXJfbHZkc19wYXJzZV9kdF9j b21wYW5pb24oc3RydWN0IHJjYXJfbHZkcyAqbHZkcykKPiA+Pj4gK3sKPiA+Pj4gKwljb25zdCBz dHJ1Y3Qgb2ZfZGV2aWNlX2lkICptYXRjaDsKPiA+Pj4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKmNv bXBhbmlvbjsKPiA+Pj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBsdmRzLT5kZXY7Cj4gPj4+ICsJ aW50IHJldCA9IDA7Cj4gPj4+ICsKPiA+Pj4gKwkvKiBMb2NhdGUgdGhlIGNvbXBhbmlvbiBMVkRT IGVuY29kZXIgZm9yIGR1YWwtbGluayBvcGVyYXRpb24sIGlmIGFueS4gKi8KPiA+Pj4gKwljb21w YW5pb24gPSBvZl9wYXJzZV9waGFuZGxlKGRldi0+b2Zfbm9kZSwgInJlbmVzYXMsY29tcGFuaW9u IiwgMCk7Cj4gPj4+ICsJaWYgKCFjb21wYW5pb24pCj4gPj4+ICsJCXJldHVybiAtRU5PREVWOwo+ ID4+PiArCj4gPj4+ICsJLyoKPiA+Pj4gKwkgKiBTYW5pdHkgY2hlY2s6IHRoZSBjb21wYW5pb24g ZW5jb2RlciBtdXN0IGhhdmUgdGhlIHNhbWUgY29tcGF0aWJsZQo+ID4+PiArCSAqIHN0cmluZy4K PiA+Pj4gKwkgKi8KPiA+Pj4gKwltYXRjaCA9IG9mX21hdGNoX2RldmljZShkZXYtPmRyaXZlci0+ b2ZfbWF0Y2hfdGFibGUsIGRldik7Cj4gPj4+ICsJaWYgKCFvZl9kZXZpY2VfaXNfY29tcGF0aWJs ZShjb21wYW5pb24sIG1hdGNoLT5jb21wYXRpYmxlKSkgewo+ID4+PiArCQlyZXQgPSAtRU5PREVW Owo+ID4+PiArCQlnb3RvIGRvbmU7Cj4gPj4+ICsJfQo+ID4+PiArCj4gPj4+ICsJbHZkcy0+Y29t cGFuaW9uID0gb2ZfZHJtX2ZpbmRfYnJpZGdlKGNvbXBhbmlvbik7Cj4gPj4+ICsJaWYgKCFsdmRz LT5jb21wYW5pb24pIHsKPiA+Pj4gKwkJcmV0ID0gLUVQUk9CRV9ERUZFUjsKPiA+Pj4gKwkJZ290 byBkb25lOwo+ID4+PiArCX0KPiA+Pj4gKwo+ID4+PiArCWRldl9kYmcoZGV2LCAiRm91bmQgY29t cGFuaW9uIGVuY29kZXIgJXBPRlxuIiwgY29tcGFuaW9uKTsKPiA+Pj4gKwo+ID4+PiArZG9uZToK PiA+Pj4gKwlvZl9ub2RlX3B1dChjb21wYW5pb24pOwo+ID4+PiArCj4gPj4+ICsJcmV0dXJuIHJl dDsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiAgc3RhdGljIGludCByY2FyX2x2ZHNfcGFyc2VfZHQo c3RydWN0IHJjYXJfbHZkcyAqbHZkcykKPiA+Pj4gIHsKPiA+Pj4gIAlzdHJ1Y3QgZGV2aWNlX25v ZGUgKmxvY2FsX291dHB1dCA9IE5VTEw7Cj4gPj4+IEBAIC02ODIsMTQgKzc0OCwyNiBAQCBzdGF0 aWMgaW50IHJjYXJfbHZkc19wYXJzZV9kdChzdHJ1Y3QgcmNhcl9sdmRzICpsdmRzKQo+ID4+Pgo+ ID4+PiAgCWlmIChpc19icmlkZ2UpIHsKPiA+Pj4gIAkJbHZkcy0+bmV4dF9icmlkZ2UgPSBvZl9k cm1fZmluZF9icmlkZ2UocmVtb3RlKTsKPiA+Pj4gLQkJaWYgKCFsdmRzLT5uZXh0X2JyaWRnZSkK PiA+Pj4gKwkJaWYgKCFsdmRzLT5uZXh0X2JyaWRnZSkgewo+ID4+PiAgCQkJcmV0ID0gLUVQUk9C RV9ERUZFUjsKPiA+Pj4gKwkJCWdvdG8gZG9uZTsKPiA+Pj4gKwkJfQo+ID4+PiArCj4gPj4+ICsJ CWlmIChsdmRzLT5pbmZvLT5xdWlya3MgJiBSQ0FSX0xWRFNfUVVJUktfRFVBTF9MSU5LKQo+ID4+ PiArCQkJbHZkcy0+ZHVhbF9saW5rID0gbHZkcy0+bmV4dF9icmlkZ2UtPnRpbWluZ3MKPiA+Pj4g KwkJCQkJPyBsdmRzLT5uZXh0X2JyaWRnZS0+dGltaW5ncy0+ZHVhbF9saW5rCj4gPj4+ICsJCQkJ CTogZmFsc2U7Cj4gPj4KPiA+PiBJIHdvbmRlciBpZiwgaW4gYWxsIHRoaXMgcGF0Y2gsIHlvdSBj b3VsZCBub3QgdXNlICJsdmRzLT5jb21wYW5pb24iIGluCj4gPj4gcGxhY2Ugb2YgImx2ZHMtPmR1 YWxfbGluayIsIGFuZCB0aHVzIGRyb3AgdGhhdCBmcm9tIHRpbWluZ3MuIFRoaXMgbWVhbgo+ID4+ ICJyZW5lc2FzLGNvbXBhbmlvbiIgd291bGQgb25seSBiZSB1c2VkIHdoZW4gb3BlcmF0aW5nIGlu IGR1YWwgbGluawo+ID4+IG1vZGUsIHdoaWNoIG1pZ2h0IGJlIGxlc3MgbmljZSAoYW5kIGNvdWxk IGFjdHVhbGx5IGNhbGxlZCBkaWZmZXJlbnRseQo+ID4+IGluIHRoYXQgY2FzZSkuCj4gPj4KPiA+ PiBCb3RoIHRoZSBUSEM2MzEwMjQgYW5kIHRoZSByY2FyX2R1LWx2ZHMgZHJpdmVyIHdvdWxkIGRl Y2lkZQo+ID4+IGluZGVwZW5kZW50bHkgaWYgdGhleSBvcGVyYXRlIGluIGR1YWwgbGluayBtb2Rl IG9yIG5vdCAob25lIGNvdW50aW5nCj4gPj4gaXRzIGVuZHBvaW50cywgdGhlIG90aGVyIGluc3Bl Y3RpbmcgdGhlICJyZW5lc2FzLGNvbXBhbmlvbiIgcHJvcGVydHkpLgo+ID4KPiA+IEkgZGVjaWRl ZCB0byBzcGVjaWZ5IHRoZSBjb21wYW5pb24gaW4gRFQgcmVnYXJkbGVzcyBvZiB3aGljaCBvcGVy YXRpbmcKPiA+IG1vZGUgaXMgdXNlZCwgYXMgaXQncyBhIHByb3BlcnR5IG9mIHRoZSBMVkRTIGVu Y29kZXIsIG5vdCBvZiB0aGUKPiA+IG9wZXJhdGluZyBtb2RlLiBGdXJ0aGVybW9yZSwgSSBjYW4g Zm9yZXNlZSBzZXR1cHMgd2hlcmUgdGhlIG1vZGUgd291bGQKPiA+IGJlIHNlbGVjdGVkIGR5bmFt aWNhbGx5IGF0IHJ1bnRpbWUuIE91ciBkZXZlbG9wbWVudCBib2FyZHMgZG9uJ3QgYWxsb3cKPiA+ IHRoYXQgYXMgdGhleSBoYXJkY29kZSB0aGUgbW9kZSB1c2luZyBESVAgc3dpdGNoZXMsIGJ1dCBu b3RoaW5nIHdvdWxkCj4gPiBwcmV2ZW50IHRoZSBtb2RlIHNlbGVjdGlvbiBzaWduYWxzIHRvIGJl IGNvbm5lY3RlZCB0byBHUElPcy4gSSB0aHVzCj4gPiB0aGluayBsdmRzLT5jb21wYW5pb24gc2hv dWxkIHBvaW50IHRvIHRoZSBjb21wYW5pb24gdW5jb25kaXRpb25hbGx5LCBhbmQKPiA+IGx2ZHMt PmR1YWxfbGluayBzaG91bGQgc2VsZWN0IHRoZSBvcGVyYXRpbmcgbW9kZS4gVGhlIGR1YWxfbGlu ayBmaWVsZCBpcwo+ID4gY3VycmVudGx5IHNldCBhdCBwcm9iZSB0aW1lIGFzIEkgaGF2ZSBubyBu ZWVkIGZvciBkeW5hbWljIGNvbmZpZ3VyYXRpb24KPiA+IG9mIHRoZSBtb2RlIGFuZCBubyBtZWFu IG9mIHRlc3RpbmcgaXQsIHNvIEkgZGVjaWRlZCBub3QgdG8gaW1wbGVtZW50Cj4gPiBkeW5hbWlj IHN3aXRjaGluZyB5ZXQuCj4gCj4gRmluZSwgSSB0cmllZCB0aGlua2luZyB1cCBhIGJpdCBpZiB0 aGUgInJlbmVzYXMsY29tcGFuaW9uIiBwcm9wZXJ0eQo+IGNvdWxkIGhhdmUgYmVlbiBtYWRlIGFu IGVuZHBvaW50IHByb3BlcnR5LCB0byBiZSBzcGVjaWZpZWQgaW4gYm90aAo+IHRoZSByY2FyLWx2 ZHMgZW5kcG9pbnRzIGFuZCBpbiB0aGUgRFUgZW5kcG9pbnRzLCBzbyB0aGF0IHRoZQo+IHJjYXJf ZHVfZW5jb2RlciBkb2VzIG5vdCBuZWVkIHRvIHBpY2sgaW50byB0aGUgbHZkcy1lbmNvZGVyIHRv IGtub3cKPiBpZiBpdCBpcyBvcGVyYXRpbmcgaW4gZHVhbCBsaW5rIG1vZGUgb3Igbm90IGFuZCBz a2lwIGNyZWF0aW9uIG9mIHRoZQo+IGVuY29kZXIgYXNzb2NpYXRlZCB0byBMVkRTMSBpbiBzdWNo IGEgY2FzZS4KPiAKPiBGdXJ0aGVybW9yZSwgd2UgY291bGQgbWFrZSBhICJ2c3RyaXBlLWV2ZW4i ICJ2c3RyaXBlLW9kZCIgZW5kcG9pbnQKPiBwcm9wZXJ0aWVzLCB0aGF0IHdvdWxkIGFsbG93IHlv dSB0byBjb250cm9sIHRoZSBTVF9TV0FQIGZpZWxkIG9mCj4gTFZEU1RSSVBFIHJlZ2lzdGVyLCBh bmQgY3JlYXRlIGFub3RoZXIgZW5kcG9pbnQgcHJvcGVydHkgdGhhdCBjb250YWlucwo+IHRoZSBw aGFuZGxlIHRvIHRoZSBjb21wYW5pb24sIGxpa2UgImR1YWwtbGluay1jb21wYW5pb24iIG9yCj4g ImR1YWwtbGluay1zbGF2ZSIuIFRob3NlIHByb3BlcnRpZXMgd291bGQgbmVlZCB0byBiZSBzcGVj aWZpZWQgaW4gYm90aAo+IERVIGFuZCBMVkRTIGVuZHBvaW50cyB0aG91Z2gsIHdoaWNoIG1pZ2h0 IGJlIGNsdW5reSwgYnV0IHRoYXQgd291bGQKPiBwb3NzaWJseSBzYXZlIGEgZmV3IGNyb3NzLWRy aXZlciBjYWxscy4KClJlZ2FyZGluZyB0aGUgc3RyaXBlIG9kZC9ldmVuIGNvbnRyb2wsIEkgdGhp bmsgdGhpcyBzaG91bGQgYmUgaGFuZGxlZApkeW5hbWljYWxseSB3aXRob3V0IGludm9sdmluZyBE VC4gV2Ugd2lsbCBuZWVkIGFuIEFQSSBmb3IgYnJpZGdlcyB0bwpyZXBvcnQgd2hhdCBvcmRlcihz KSB0aGV5IHN1cHBvcnQsIGFuZCBhbGxvdyB0aGUgcmVtb3RlIGNvbXBvbmVudCB0byBiZQpjb25m aWd1cmVkIGFjY29yZGluZ2x5LiBBIERUIHByb3BlcnR5IGlzbid0IG5lZWRlZCBmb3IgdGhpcy4K ClJlZ2FyZGluZyB0aGUgY29tcGFuaW9uLCBpdCdzIG5vdCBhIGdlbmVyaWMgY29uY2VwdC4gSXQg aGFwcGVucyB0aGF0ClJlbmVzYXMgZGVjaWRlZCB0byBpbXBsZW1lbnQgZHVhbC1saW5rIHN1cHBv cnQgYnkgY29uZmlndXJpbmcgb25lIG9mIHRoZQp0d28gTFZEUyBlbmNvZGVycyBhcyBhIG1hc3Rl ciBhbmQgdGhlIG90aGVyIG9uZSBhcyBhIHNsYXZlLCBidXQgdGhlcmUKY291bGQgYmUgb3RoZXIg b3B0aW9ucy4gVGhhdCdzIHdoeSBJIG1hZGUgdGhpcyBhIFJlbmVzYXMtc3BlY2lmaWMKcHJvcGVy dHkuIEkgYmVsaWV2ZSBpdCBpcyBwbGFjZWQgY29ycmVjdGx5IGluIHRoZSBMVkRTIGVuY29kZXIg RFQgbm9kZSwKYW5kIG5vdCBpbiB0aGUgcG9ydCBvciBlbmRwb2ludCwgYXMgaXQncyBhIHByb3Bl cnR5IG9mIHRoZSBMVkRTIGVuY29kZXIKaXRzZWxmLgoKT3RoZXIgbW9kZWxzIGFyZSBwb3NzaWJs ZSB0aG91Z2gsIEkgY291bGQgaGF2ZSBhZGRlZCBhIHRoaXJkIHBvcnQgdG8gdGhlCkxWRFMgZW5j b2RlcnMgdG8gbW9kZWwgdGhpcyBjb25uZWN0aW9uLCBidXQgYXMgcG9ydHMgZG9uJ3QgaW5kaWNh dGUgYQpkaXJlY3Rpb24sIEkgd291bGQgaGF2ZSBuZWVkZWQgYW4gZXh0cmEgcHJvcGVydHkgYW55 d2F5IHRvIGRpZmZlcmVudGlhdGUKYmV0d2VlbiB0aGUgbWFzdGVyIGFuZCB0aGUgc2xhdmUuCgo+ IEFueXdheSwganVzdCBwdXR0aW5nIGEgZmV3IG1vcmUgb3B0aW9ucyBvbiB0aGUgdGFibGUsIGlm IHlvdSBoYXZlCj4gYWxyZWFkeSBjb25zaWRlcmVkIHRob3NlIGZlZWwgZnJlZSB0byBzdGljayB0 byB0aGlzIGltcGxlbWVudGF0aW9uLi4uCj4gCj4gPj4gVGhlIG9ubHkgcGxhY2Ugd2hlcmUgdGhp cyBtaWdodCBiZSB0cmlja3kgaXMgdGhlIGhlcmUgYWJvdmUKPiA+Pgo+ID4+ICArCS8qCj4gPj4g ICsJICogUExMIGNsb2NrIGNvbmZpZ3VyYXRpb24gb24gYWxsIGluc3RhbmNlcyBidXQgdGhlIGNv bXBhbmlvbiBpbgo+ID4+ICArCSAqIGR1YWwtbGluayBtb2RlLgo+ID4+ICArCSAqLwo+ID4+ICAr CWlmICghbHZkcy0+ZHVhbF9saW5rIHx8IGx2ZHMtPmNvbXBhbmlvbikKPiA+PiAgKwkJbHZkcy0+ aW5mby0+cGxsX3NldHVwKGx2ZHMsIG1vZGUtPmNsb2NrICogMTAwMCk7Cj4gPj4KPiA+PiBidXQg dGhhdCB3b3VsZCByZW1vdmUgdGhlIG5lZWQgZm9yIHRoZSB0aGM2MyBicmlkZ2UgdG8gcmVwb3J0 IGl0cwo+ID4+IG9wZXJhdGluZyBtb2RlIGluIHRpbWluZ3MuLi4KPiA+Pgo+ID4+PiAgCX0gZWxz ZSB7Cj4gPj4+ICAJCWx2ZHMtPnBhbmVsID0gb2ZfZHJtX2ZpbmRfcGFuZWwocmVtb3RlKTsKPiA+ Pj4gLQkJaWYgKElTX0VSUihsdmRzLT5wYW5lbCkpCj4gPj4+ICsJCWlmIChJU19FUlIobHZkcy0+ cGFuZWwpKSB7Cj4gPj4+ICAJCQlyZXQgPSBQVFJfRVJSKGx2ZHMtPnBhbmVsKTsKPiA+Pj4gKwkJ CWdvdG8gZG9uZTsKPiA+Pj4gKwkJfQo+ID4+PiAgCX0KPiA+Pj4KPiA+Pj4gKwlpZiAobHZkcy0+ ZHVhbF9saW5rKQo+ID4+Cj4gPj4gTm90ZTogaWYgKCFpc19icmlkZ2UpIHlvdSB3b3VsZCBuZXZl ciBzZXQgbHZkcy0+ZHVhbF9saW5rLCBzbyB0aGlzCj4gPj4gc2hvdWxkIGJlIG1vdmVkIGluc2lk ZSB0aGUgaGVyZSBhYm92ZSAiaWYgKGlzX2JyaWRnZSkiCj4gPgo+ID4gSSBkb24ndCB5ZXQsIGJ1 dCBub3RoaW5nIHByZXZlbnRzIGEgcGFuZWwgZnJvbSBvcGVyYXRpbmcgaW4gZHVhbCBtb2RlLAo+ ID4gZXZlbiBpZiBub3QgaW1wbGVtZW50ZWQgeWV0LiBUaGF0J3Mgd2h5IEkndmUgbW92ZSB0aGlz IGNoZWNrIG91dCBvZiB0aGUKPiA+IGJyaWRnZS9wYW5lbCBjb25kaXRpb25hbCBjb2RlLgo+IAo+ IEkgc2VlLCBzdGlsbCByaWdodCBub3cgaXMgb2Ygbm8gdXNlLiBJdCdzIGZpbmUgdGhvdWdoLCBy ZWFsbHkgbWlub3IKPiBzdHVmZi4KPiAKPiA+Pj4gKwkJcmV0ID0gcmNhcl9sdmRzX3BhcnNlX2R0 X2NvbXBhbmlvbihsdmRzKTsKPiA+Pj4gKwo+ID4+PiAgZG9uZToKPiA+Pj4gIAlvZl9ub2RlX3B1 dChsb2NhbF9vdXRwdXQpOwo+ID4+PiAgCW9mX25vZGVfcHV0KHJlbW90ZV9pbnB1dCk7Cj4gPj4+ IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2x2ZHMuaCBiL2RyaXZl cnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfbHZkcy5oCj4gPj4+IGluZGV4IGE3MDljYWUxYmMzMi4u MjIyZWMwZTYwNzg1IDEwMDY0NAo+ID4+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9y Y2FyX2x2ZHMuaAo+ID4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2x2ZHMu aAo+ID4+PiBAQCAtMTUsNiArMTUsNyBAQCBzdHJ1Y3QgZHJtX2JyaWRnZTsKPiA+Pj4gICNpZiBJ U19FTkFCTEVEKENPTkZJR19EUk1fUkNBUl9MVkRTKQo+ID4+PiAgaW50IHJjYXJfbHZkc19jbGtf ZW5hYmxlKHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsIHVuc2lnbmVkIGxvbmcgZnJlcSk7Cj4g Pj4+ICB2b2lkIHJjYXJfbHZkc19jbGtfZGlzYWJsZShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdl KTsKPiA+Pj4gK2Jvb2wgcmNhcl9sdmRzX2R1YWxfbGluayhzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJp ZGdlKTsKPiA+Pj4gICNlbHNlCj4gPj4+ICBzdGF0aWMgaW5saW5lIGludCByY2FyX2x2ZHNfY2xr X2VuYWJsZShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlLAo+ID4+PiAgCQkJCSAgICAgICB1bnNp Z25lZCBsb25nIGZyZXEpCj4gPj4+IEBAIC0yMiw2ICsyMywxMCBAQCBzdGF0aWMgaW5saW5lIGlu dCByY2FyX2x2ZHNfY2xrX2VuYWJsZShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlLAo+ID4+PiAg CXJldHVybiAtRU5PU1lTOwo+ID4+PiAgfQo+ID4+PiAgc3RhdGljIGlubGluZSB2b2lkIHJjYXJf bHZkc19jbGtfZGlzYWJsZShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKSB7IH0KPiA+Pj4gK3N0 YXRpYyBpbmxpbmUgYm9vbCByY2FyX2x2ZHNfZHVhbF9saW5rKHN0cnVjdCBkcm1fYnJpZGdlICpi cmlkZ2UpCj4gPj4+ICt7Cj4gPj4+ICsJcmV0dXJuIGZhbHNlOwo+ID4+PiArfQo+ID4+PiAgI2Vu ZGlmIC8qIENPTkZJR19EUk1fUkNBUl9MVkRTICovCj4gPj4+Cj4gPj4+ICAjZW5kaWYgLyogX19S Q0FSX0xWRFNfSF9fICovCgotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hhcnQKX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcg bGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRl c2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVs