From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7C13343D7F for ; Fri, 28 Aug 2026 19:35:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787945749; cv=none; b=Scy0oiT7OjGJTUy6TqbzEaxhJeNknEuy4yaUMyg2AGKojSuIgxgMKGiZTvfQjAxuOaAKNUZZvmJOyI2Y2ZkFbyTJ4fL8MEJQExzJzlgtn5PrzazWF0Z3uwF8h2rPmEddSN0tAlByk26dWgCl2FNqFELRPepMtn2LlYpNa5uA03s= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787945749; c=relaxed/simple; bh=4/mv+sJLDfY2fJ0an1a45ML9wMBsZpoweWbWqNHieik=; h=From:Subject:To:Cc:In-Reply-To:References:Content-Type:Date: Message-Id; b=qJ4woLZO7j3Is7AZlocJSCZB9V5lYDJ28YElBLUpQh74yEOYQfBq3Cpq7upNf0i61imTRxc8/DLGxoXX2rKX4gGmGcpX9XqjUmlC/vhV/9Lb7S+Gaoh+vhPPg6u4FKwhkVzXFj2nzgbhfFbH/qhmYVBbHuCMbdqZrM4bmTZ5cQk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OUcgN07+; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OUcgN07+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB8341F000E9; Fri, 28 Aug 2026 19:35:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787945747; bh=nbNMfePVJR9CI5tQ+37IJV6hYXrZnkLK9bNwv1DFARo=; h=From:Subject:Reply-To:To:Cc:In-Reply-To:References:Date; b=OUcgN07+A9Tdtqw6i95f7eQodFCtoAyP1/0bDrdTWdFYRf81cOeW50X7jqLNdr14A 8fJPewWGd86NVcjotRbo78cIPBhkawNdAg2FQyADQZ0qy1P4wjr1uUgYC9J3ufE1fJ d4NPWWGxvrPLCz8OOvHySm8lrAIOUm5DFeCvrOYDWhupdyOcAuevARu406tjzVl8fH E373njJHSaeGJe3KWmm8tdTrutUm2OO4zo2Vu04IeSsnUmZuXsOf+5WwK81bzjdVFh dTW2SrNs0qNKsN36shuJ9Z38Kqwqx3qo2ooiu/ukk/MO79vsbgNLGyNUtOhc53iAZ4 fnJCTa/g508tA== From: sashiko-bot@kernel.org Subject: Re: [PATCH 2/2] phy: renesas: Add Renesas Multi-Protocol PHY driver for R-Car X5H Reply-To: sashiko-reviews@lists.linux.dev To: "Marek Vasut" Cc: devicetree@vger.kernel.org, olteanv@gmail.com, neil.armstrong@linaro.org, linux-phy@lists.infradead.org, conor+dt@kernel.org, vkoul@kernel.org, wsa+renesas@sang-engineering.com, robh@kernel.org In-Reply-To: <20260828192223.402422-2-marek.vasut+renesas@mailbox.org> References: <20260828192223.402422-1-marek.vasut+renesas@mailbox.org> <20260828192223.402422-2-marek.vasut+renesas@mailbox.org> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Date: Fri, 28 Aug 2026 19:35:46 +0000 Message-Id: <20260828193546.AB8341F000E9@smtp.kernel.org> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Thank you for your contribution! Sashiko AI review found 11 potential issue= (s) to consider: - [High] Regmap readable and writable ranges specify inverted address bound= s and omit valid registers, preventing the driver from initializing hardwar= e registers. - [High] Runtime PM usage counter leaks when `mp_phy_init()` encounters an = error or returns early. - [High] Missing firmware size validation leads to out-of-bounds memory acc= esses and memory-mapped I/O corruption. - [High] Inconsistent use of `phy->id` in PCIe initialization leads to inco= rrect port configuration and out-of-bounds register accesses. - [High] `mp_phy_suspend()` clears `chan->initialized` without dropping PM = domains, permanently bricking PHY channels after a suspend/resume cycle. - [High] Unconditional register access in `mp_phy_resume()` for all channel= s without checking if their respective power domains are turned on. - [Medium] Memory and resource leaks in `mp_phy_probe()` error paths: firmw= are buffer and attached power domains are not released on subsequent initia= lization failures. - [Medium] Asynchronous `pm_runtime_put()` is immediately followed by `pm_r= untime_disable()` during device removal, violating PM subsystem guidelines. - [Medium] Missing bounds check on device tree index in `mp_phy_xlate()` le= ads to an out-of-bounds array access. - [Medium] `reset_control_bulk_deassert()` iterates sequentially, violating= the hardware requirement to deassert `mpphy02` last. - [Medium] PHY provider is exposed to consumers before PHY instances are cr= eated and hardware is powered on. -- commit 54820191afa1ae9e0aa531e1706a7cd7acbab1ca Author: Thanh Quan Subject: phy: renesas: Add Renesas Multi-Protocol PHY driver for R-Car X5H This commit introduces a new Renesas Multi-Protocol PHY driver for the R-Car X5H SoC. It supports multiplexing five input IPs (PCIe4, USB 3.2, Ethernet) to four separate IO blocks based on the device tree configuration. > diff --git a/drivers/phy/renesas/phy-rcar-gen5-mpphy.c b/drivers/phy/rene= sas/phy-rcar-gen5-mpphy.c > new file mode 100644 > --- /dev/null > +++ b/drivers/phy/renesas/phy-rcar-gen5-mpphy.c [ ... ] > +#define MPPHY_PX_RD_RANGE(n) \ > + regmap_reg_range(MPPHY_PXCNTXT1(n), MPPHY_CHAN_BASE(n)), \ > + regmap_reg_range(MPPHY_PXREFCLK(n), MPPHY_PXREFCLK(n)), \ > + regmap_reg_range(MPPHY_PXRXREQ1(n), MPPHY_PXRXREQ1(n)), \ > + regmap_reg_range(MPPHY_PXRXCNT(n), MPPHY_PXRXCNT(n)), \ > + regmap_reg_range(MPPHY_PXSRAMCNT(n), MPPHY_PXTXREQ(n)) [Severity: High] Does this inverted range cause regmap to reject accesses? MPPHY_PXCNTXT1(n) is defined as (MPPHY_CHAN_BASE(n) + 0x4). Since range_min > range_max, regmap_reg_range will set a range where the minimum is greater than the maximum, preventing the driver from reading these hardware registers during initialization. [ ... ] > +static void mp_phy_update_firmware(struct phy *phy) > +{ > + struct mp_phy_priv *priv =3D phy_get_drvdata(phy); > + int i; > + > + for (i =3D 0; i < priv->fw->size; i +=3D 2) { > + writew(priv->fw->data[i] | (priv->fw->data[i + 1] << 8), > + priv->base + MPPHY_FW_BASE + (MPPHY_FW_CH_OFFSET * phy->id) + i= ); > + } > +} [Severity: High] Does this code risk an out-of-bounds read or memory corruption if the firmware size is odd or larger than expected? Since mp_phy_parse_dt() doesn't validate priv->fw->size, a large firmware file could write beyond the allocated MPPHY_FW_CH_OFFSET (0x20000) or outsi= de the I/O region completely. If the size is odd, reading priv->fw->data[i + 1] will result in an out-of-bounds access. [ ... ] > +static int mp_phy_init_pcie4(struct phy *phy) > +{ > + struct mp_phy_priv *priv =3D phy_get_drvdata(phy); > + > + if (priv->num_lanes[phy->id] =3D=3D 1 || priv->num_lanes[phy->id] =3D= =3D 2) { > + if (phy->id =3D=3D 0) { > + regmap_set_bits(priv->map, MPPHY_PXCNTXT1(0), 0x2010002); > + regmap_set_bits(priv->map, MPPHY_PXCNTXT2(0), 0x2020201); > + regmap_set_bits(priv->map, MPPHY_PXTXREQ(0), 0x80004); > + regmap_set_bits(priv->map, MPPHY_PXREFCLK(0), 0x30); > + regmap_set_bits(priv->map, MPPHY_PXREFCLK(0), 0x4); > + regmap_set_bits(priv->map, MPPHY_PXREFCLK(0), 0x1); > + regmap_set_bits(priv->map, MPPHY_PXRXCNT(0), 0x202); > + regmap_clear_bits(priv->map, MPPHY_PXRXCNT(0), 0x202); > + } else if (phy->id =3D=3D 1) { > + regmap_set_bits(priv->map, MPPHY_PXCNTXT1(2), 0x2010002); [Severity: High] Is phy->id used consistently here? The code seems to treat phy->id as a controller index rather than a port in= dex, ignoring cases where phy->id is 2 or 3. This could lead to incorrect port configuration if phy->id maps directly to the port being initialized. [ ... ] > +static int mp_phy_init(struct phy *phy) > +{ > + struct mp_phy_priv *priv =3D phy_get_drvdata(phy); > + struct mp_phy_chan_priv *chan =3D &priv->chan[phy->id]; > + int ret; > + > + /* > + * Note: Current source code support for Ethernet, PCIe > + * initialization is based on the bare metal code shared > + * by the board team. > + */ > + ret =3D pm_runtime_get_sync(priv->pd_list->pd_devs[phy->id]); > + if (ret < 0) { > + dev_err(priv->dev, > + "Failed to power on domain for channel %d: %d\n", > + phy->id, ret); > + return ret; > + } > + > + /* Check if initialized with same protocol then skip */ > + if (chan->initialized) > + return 0; [Severity: High] Does this code leak the power management usage counter? If chan->initialized is true, the function returns directly without dropping the reference acquired by pm_runtime_get_sync(). > + > + if (chan->protocol_id =3D=3D PHY_MODE_PCIE) > + ret =3D mp_phy_init_pcie4(phy); > + else if (chan->protocol_id =3D=3D PHY_MODE_ETHERNET) > + ret =3D mp_phy_init_ethernet(phy); > + else > + ret =3D mp_phy_init_usb(phy); > + if (ret) > + return ret; [Severity: High] Could this error path also leak the PM usage counter? If protocol initialization fails, the function returns without decrementing the usage counter, preventing the power domain from ever suspending. [ ... ] > +static int mp_phy_power_on(struct phy *phy) > +{ > + struct mp_phy_priv *priv =3D phy_get_drvdata(phy); > + struct mp_phy_chan_priv *chan =3D &priv->chan[phy->id]; > + int ret; > + > + if (!chan->initialized) { > + dev_err(priv->dev, "Channel %d not initialized\n", phy->id); > + return -EINVAL; > + } [Severity: High] Will this unconditionally fail after a suspend/resume cycle? Since mp_phy_suspend() clears chan->initialized for all channels without dropping their associated PM domain references, subsequent calls to phy_power_on() after resume will hit this condition and fail. [ ... ] > + } else if (priv->num_lanes[phy->id] =3D=3D 4) { > + ret =3D mp_phy_reg_wait(priv, MPPHY_PXSRAMCNT(2 * phy->id), 0x20, 0x2= 0); > + if (ret) > + return ret; > + ret =3D mp_phy_reg_wait(priv, MPPHY_PXSRAMCNT((2 * phy->id) + 1), 0x2= 0, 0x20); [Severity: High] Can this result in an out-of-bounds regmap access? If phy->id is 2, (2 * phy->id) + 1 evaluates to 5, which exceeds the maximum channel index (MPPHY_NUM_CHANNELS is 4). [ ... ] > +static struct phy *mp_phy_xlate(struct device *dev, > + const struct of_phandle_args *args) > +{ > + struct mp_phy_priv *priv =3D dev_get_drvdata(dev); > + int id; > + > + if (args->args_count > 1) { > + dev_err(dev, "Invalid args_count: %d\n", args->args_count); > + return ERR_PTR(-EINVAL); > + } > + > + if (args->args_count >=3D 1) > + id =3D args->args[0]; > + else > + id =3D 0; > + > + return priv->chan[id].phy; > +} [Severity: Medium] Does this code overflow the priv->chan[] array? If a consumer passes an id >=3D MPPHY_NUM_CHANNELS via the device tree, this will result in an out-of-bounds array access since there is no bounds checking on the raw argument before indexing the array. [ ... ] > +static int mp_phy_probe(struct platform_device *pdev) > +{ [ ... ] > + ret =3D mp_phy_parse_dt(pdev, priv); > + if (ret) > + return ret; > + > + priv->base =3D devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(priv->base)) > + return dev_err_probe(dev, PTR_ERR(priv->base), "Failed to map PHY regi= sters\n"); [Severity: Medium] Does this error path leak the allocated firmware? mp_phy_parse_dt() can successfully allocate priv->fw via request_firmware(). If devm_platform_ioremap_resource() fails, the function returns directly without calling release_firmware(). [ ... ] > + /* > + * The reset ID order here does matters, reset_control_bulk_assert() > + * asserts these resets in this order, with mpphy02 reset being > + * asserted first, reset_control_bulk_deassert() deasserts these > + * resets in reverse order, with mpphy02 being reset being > + * deasserted last. This is the behavior the hardware expects. > + */ > + priv->resets[0].id =3D "mpphy02"; > + priv->resets[1].id =3D "mpphy01"; > + priv->resets[2].id =3D "mpphy11"; > + priv->resets[3].id =3D "mpphy21"; > + priv->resets[4].id =3D "mpphy31"; > + ret =3D devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(pr= iv->resets), > + priv->resets); [Severity: Medium] Will reset_control_bulk_deassert() actually deassert these resets in reverse order? The reset_control_bulk_deassert() API processes the array sequentially unle= ss it is unwinding from a failure. This would mean mpphy02 is deasserted first rather than last, violating the hardware expectation described in the comme= nt. [ ... ] > + ret =3D devm_pm_runtime_enable(dev); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to enable PHY runtime PM\n"); [Severity: Medium] Could this error path leak priv->fw and the power domains? If devm_pm_runtime_enable() fails, the function returns without calling release_firmware() or dev_pm_domain_detach_list(). > + > + provider =3D devm_of_phy_provider_register(dev, mp_phy_xlate); > + if (IS_ERR(provider)) > + return dev_err_probe(dev, PTR_ERR(provider), "Failed to register PHY p= rovider\n"); > + > + for (i =3D 0; i < MPPHY_NUM_CHANNELS; i++) { > + priv->chan[i].phy =3D devm_phy_create(dev, NULL, &mp_phy_ops); > + if (IS_ERR(priv->chan[i].phy)) { > + return dev_err_probe(dev, PTR_ERR(priv->chan[i].phy), > + "Failed to create PHY %d\n", i); > + } > + > + priv->chan[i].phy->id =3D i; > + phy_set_drvdata(priv->chan[i].phy, priv); > + } [Severity: Medium] Does registering the provider here expose the PHY to consumers prematurely? The provider is registered before the PHY objects (priv->chan[i].phy) are created. If a consumer probes immediately, mp_phy_xlate() would return a NULL pointer. [ ... ] > +static void mp_phy_remove(struct platform_device *pdev) > +{ > + struct mp_phy_priv *priv =3D dev_get_drvdata(&pdev->dev); > + struct device *dev =3D &pdev->dev; > + > + pm_runtime_put(dev); > + > + dev_pm_domain_detach_list(priv->pd_list); > + > + pm_runtime_disable(&pdev->dev); [Severity: Medium] Can this result in an aborted power state transition? According to PM subsystem rules, calling pm_runtime_disable() immediately after an asynchronous pm_runtime_put() can cancel pending suspend work. Should pm_runtime_put_sync() be used here instead? [ ... ] > +static int mp_phy_suspend(struct device *dev) > +{ > + struct mp_phy_priv *priv =3D dev_get_drvdata(dev); > + int i; > + > + for (i =3D 0; i < MPPHY_NUM_CHANNELS; i++) > + priv->chan[i].initialized =3D false; > + > + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); > + > + dev_info(dev, "Multi-Protocol PHY suspended\n"); > + > + return 0; > +} [Severity: High] Will clearing chan->initialized here break the PHY on resume? This flag is cleared without decrementing the associated PM domain usage counter. On resume, it is never restored to true, causing subsequent calls to mp_phy_power_on() to fail unconditionally. [ ... ] > +static int mp_phy_resume(struct device *dev) > +{ [ ... ] > + for (i =3D 0; i < MPPHY_NUM_CHANNELS; i++) { > + regmap_set_bits(priv->map, MPPHY_PXTEST(i), MPPHY_PXTEST_BIT); > + regmap_write(priv->map, MPPHY_PXSRAMCNT(i), priv->sramcnt[i]); > + > + if (priv->write_cntxt1 & BIT(i)) { > + regmap_write(priv->map, MPPHY_CHAN_BASE(i) + 0x10c, 0xff0ff); [Severity: High] Are we guaranteed that the power domains for all 4 channels are turned on h= ere? If a channel is unused and its power domain is off, accessing its registers blindly in this loop could lead to a bus fault and system crash. [Severity: High] Also, will regmap reject this write to 0x10c? This register offset does not appear to be declared in the mp_phy_writeable_range table, meaning the regmap core will return an -EIO error. --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260828192223.4024= 22-1-marek.vasut+renesas@mailbox.org?part=3D2 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 77AAAC61DBD for ; Fri, 28 Aug 2026 19:35:50 +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-Transfer-Encoding:Content-Type:MIME-Version:Reply-To:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: References:In-Reply-To:Cc:To:Subject:From:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/N/6icjcZSkWci4UtooonqFeAoDCquULTdp5mGJPYLg=; b=a0ceX0clURnONC iFnYciGO+2m2cRNjVycPdep6vtHxmRS26/ybaS0d6U02nrtvcHA0Yb+HntTR6Z176+e4QErZaJuTu YcS6mNU1ZEuQtaChsYj4+ffpqZJv9tsVk2nLNFiakD1O/nSgiC2cblKhIAYc+i5yhTTMf+zbqYbo7 zTrrNSDQXyDDpJP5hMtvBHoFjfquEIbw8PUKDPmzmkV9O1f6f8zkf3ch91fwXMvPwI8kE1RE4ripq VL0HiyDOI/sJ2aD9anlFbrAwOHLYx6CC1Yfuzz3WLFNhApdwO9mvD6HJyrjTOyM+Lz+teKd/KWQAs HwVvCHGzmePxvbisxgyA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x02Mf-00000006Mvl-3PtF; Fri, 28 Aug 2026 19:35:50 +0000 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x02Me-00000006MvG-0kPB for linux-phy@lists.infradead.org; Fri, 28 Aug 2026 19:35:48 +0000 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 4514743571; Fri, 28 Aug 2026 19:35:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB8341F000E9; Fri, 28 Aug 2026 19:35:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787945747; bh=nbNMfePVJR9CI5tQ+37IJV6hYXrZnkLK9bNwv1DFARo=; h=From:Subject:Reply-To:To:Cc:In-Reply-To:References:Date; b=OUcgN07+A9Tdtqw6i95f7eQodFCtoAyP1/0bDrdTWdFYRf81cOeW50X7jqLNdr14A 8fJPewWGd86NVcjotRbo78cIPBhkawNdAg2FQyADQZ0qy1P4wjr1uUgYC9J3ufE1fJ d4NPWWGxvrPLCz8OOvHySm8lrAIOUm5DFeCvrOYDWhupdyOcAuevARu406tjzVl8fH E373njJHSaeGJe3KWmm8tdTrutUm2OO4zo2Vu04IeSsnUmZuXsOf+5WwK81bzjdVFh dTW2SrNs0qNKsN36shuJ9Z38Kqwqx3qo2ooiu/ukk/MO79vsbgNLGyNUtOhc53iAZ4 fnJCTa/g508tA== From: sashiko-bot@kernel.org Subject: Re: [PATCH 2/2] phy: renesas: Add Renesas Multi-Protocol PHY driver for R-Car X5H To: "Marek Vasut" Cc: devicetree@vger.kernel.org, olteanv@gmail.com, neil.armstrong@linaro.org, linux-phy@lists.infradead.org, conor+dt@kernel.org, vkoul@kernel.org, wsa+renesas@sang-engineering.com, robh@kernel.org In-Reply-To: <20260828192223.402422-2-marek.vasut+renesas@mailbox.org> References: <20260828192223.402422-1-marek.vasut+renesas@mailbox.org> <20260828192223.402422-2-marek.vasut+renesas@mailbox.org> Date: Fri, 28 Aug 2026 19:35:46 +0000 Message-Id: <20260828193546.AB8341F000E9@smtp.kernel.org> X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: sashiko-reviews@lists.linux.dev MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org VGhhbmsgeW91IGZvciB5b3VyIGNvbnRyaWJ1dGlvbiEgU2FzaGlrbyBBSSByZXZpZXcgZm91bmQg MTEgcG90ZW50aWFsIGlzc3VlKHMpIHRvIGNvbnNpZGVyOgotIFtIaWdoXSBSZWdtYXAgcmVhZGFi bGUgYW5kIHdyaXRhYmxlIHJhbmdlcyBzcGVjaWZ5IGludmVydGVkIGFkZHJlc3MgYm91bmRzIGFu ZCBvbWl0IHZhbGlkIHJlZ2lzdGVycywgcHJldmVudGluZyB0aGUgZHJpdmVyIGZyb20gaW5pdGlh bGl6aW5nIGhhcmR3YXJlIHJlZ2lzdGVycy4KLSBbSGlnaF0gUnVudGltZSBQTSB1c2FnZSBjb3Vu dGVyIGxlYWtzIHdoZW4gYG1wX3BoeV9pbml0KClgIGVuY291bnRlcnMgYW4gZXJyb3Igb3IgcmV0 dXJucyBlYXJseS4KLSBbSGlnaF0gTWlzc2luZyBmaXJtd2FyZSBzaXplIHZhbGlkYXRpb24gbGVh ZHMgdG8gb3V0LW9mLWJvdW5kcyBtZW1vcnkgYWNjZXNzZXMgYW5kIG1lbW9yeS1tYXBwZWQgSS9P IGNvcnJ1cHRpb24uCi0gW0hpZ2hdIEluY29uc2lzdGVudCB1c2Ugb2YgYHBoeS0+aWRgIGluIFBD SWUgaW5pdGlhbGl6YXRpb24gbGVhZHMgdG8gaW5jb3JyZWN0IHBvcnQgY29uZmlndXJhdGlvbiBh bmQgb3V0LW9mLWJvdW5kcyByZWdpc3RlciBhY2Nlc3Nlcy4KLSBbSGlnaF0gYG1wX3BoeV9zdXNw ZW5kKClgIGNsZWFycyBgY2hhbi0+aW5pdGlhbGl6ZWRgIHdpdGhvdXQgZHJvcHBpbmcgUE0gZG9t YWlucywgcGVybWFuZW50bHkgYnJpY2tpbmcgUEhZIGNoYW5uZWxzIGFmdGVyIGEgc3VzcGVuZC9y ZXN1bWUgY3ljbGUuCi0gW0hpZ2hdIFVuY29uZGl0aW9uYWwgcmVnaXN0ZXIgYWNjZXNzIGluIGBt cF9waHlfcmVzdW1lKClgIGZvciBhbGwgY2hhbm5lbHMgd2l0aG91dCBjaGVja2luZyBpZiB0aGVp ciByZXNwZWN0aXZlIHBvd2VyIGRvbWFpbnMgYXJlIHR1cm5lZCBvbi4KLSBbTWVkaXVtXSBNZW1v cnkgYW5kIHJlc291cmNlIGxlYWtzIGluIGBtcF9waHlfcHJvYmUoKWAgZXJyb3IgcGF0aHM6IGZp cm13YXJlIGJ1ZmZlciBhbmQgYXR0YWNoZWQgcG93ZXIgZG9tYWlucyBhcmUgbm90IHJlbGVhc2Vk IG9uIHN1YnNlcXVlbnQgaW5pdGlhbGl6YXRpb24gZmFpbHVyZXMuCi0gW01lZGl1bV0gQXN5bmNo cm9ub3VzIGBwbV9ydW50aW1lX3B1dCgpYCBpcyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBgcG1f cnVudGltZV9kaXNhYmxlKClgIGR1cmluZyBkZXZpY2UgcmVtb3ZhbCwgdmlvbGF0aW5nIFBNIHN1 YnN5c3RlbSBndWlkZWxpbmVzLgotIFtNZWRpdW1dIE1pc3NpbmcgYm91bmRzIGNoZWNrIG9uIGRl dmljZSB0cmVlIGluZGV4IGluIGBtcF9waHlfeGxhdGUoKWAgbGVhZHMgdG8gYW4gb3V0LW9mLWJv dW5kcyBhcnJheSBhY2Nlc3MuCi0gW01lZGl1bV0gYHJlc2V0X2NvbnRyb2xfYnVsa19kZWFzc2Vy dCgpYCBpdGVyYXRlcyBzZXF1ZW50aWFsbHksIHZpb2xhdGluZyB0aGUgaGFyZHdhcmUgcmVxdWly ZW1lbnQgdG8gZGVhc3NlcnQgYG1wcGh5MDJgIGxhc3QuCi0gW01lZGl1bV0gUEhZIHByb3ZpZGVy IGlzIGV4cG9zZWQgdG8gY29uc3VtZXJzIGJlZm9yZSBQSFkgaW5zdGFuY2VzIGFyZSBjcmVhdGVk IGFuZCBoYXJkd2FyZSBpcyBwb3dlcmVkIG9uLgotLQoKY29tbWl0IDU0ODIwMTkxYWZhMWFlOWUw YWE1MzFlMTcwNmE3Y2Q3YWNiYWIxY2EKQXV0aG9yOiBUaGFuaCBRdWFuIDx0aGFuaC5xdWFuLnhu QHJlbmVzYXMuY29tPgpTdWJqZWN0OiBwaHk6IHJlbmVzYXM6IEFkZCBSZW5lc2FzIE11bHRpLVBy b3RvY29sIFBIWSBkcml2ZXIgZm9yIFItQ2FyIFg1SAoKVGhpcyBjb21taXQgaW50cm9kdWNlcyBh IG5ldyBSZW5lc2FzIE11bHRpLVByb3RvY29sIFBIWSBkcml2ZXIgZm9yIHRoZSBSLUNhcgpYNUgg U29DLiBJdCBzdXBwb3J0cyBtdWx0aXBsZXhpbmcgZml2ZSBpbnB1dCBJUHMgKFBDSWU0LCBVU0Ig My4yLCBFdGhlcm5ldCkKdG8gZm91ciBzZXBhcmF0ZSBJTyBibG9ja3MgYmFzZWQgb24gdGhlIGRl dmljZSB0cmVlIGNvbmZpZ3VyYXRpb24uCgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BoeS9yZW5l c2FzL3BoeS1yY2FyLWdlbjUtbXBwaHkuYyBiL2RyaXZlcnMvcGh5L3JlbmVzYXMvcGh5LXJjYXIt Z2VuNS1tcHBoeS5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiAtLS0gL2Rldi9udWxsCj4gKysr IGIvZHJpdmVycy9waHkvcmVuZXNhcy9waHktcmNhci1nZW41LW1wcGh5LmMKWyAuLi4gXQo+ICsj ZGVmaW5lIE1QUEhZX1BYX1JEX1JBTkdFKG4pCQkJCQkJXAo+ICsJcmVnbWFwX3JlZ19yYW5nZShN UFBIWV9QWENOVFhUMShuKSwgTVBQSFlfQ0hBTl9CQVNFKG4pKSwJXAo+ICsJcmVnbWFwX3JlZ19y YW5nZShNUFBIWV9QWFJFRkNMSyhuKSwgTVBQSFlfUFhSRUZDTEsobikpLAkJXAo+ICsJcmVnbWFw X3JlZ19yYW5nZShNUFBIWV9QWFJYUkVRMShuKSwgTVBQSFlfUFhSWFJFUTEobikpLAkJXAo+ICsJ cmVnbWFwX3JlZ19yYW5nZShNUFBIWV9QWFJYQ05UKG4pLCBNUFBIWV9QWFJYQ05UKG4pKSwJCVwK PiArCXJlZ21hcF9yZWdfcmFuZ2UoTVBQSFlfUFhTUkFNQ05UKG4pLCBNUFBIWV9QWFRYUkVRKG4p KQoKW1NldmVyaXR5OiBIaWdoXQpEb2VzIHRoaXMgaW52ZXJ0ZWQgcmFuZ2UgY2F1c2UgcmVnbWFw IHRvIHJlamVjdCBhY2Nlc3Nlcz8KTVBQSFlfUFhDTlRYVDEobikgaXMgZGVmaW5lZCBhcyAoTVBQ SFlfQ0hBTl9CQVNFKG4pICsgMHg0KS4KU2luY2UgcmFuZ2VfbWluID4gcmFuZ2VfbWF4LCByZWdt YXBfcmVnX3JhbmdlIHdpbGwgc2V0IGEgcmFuZ2Ugd2hlcmUgdGhlCm1pbmltdW0gaXMgZ3JlYXRl ciB0aGFuIHRoZSBtYXhpbXVtLCBwcmV2ZW50aW5nIHRoZSBkcml2ZXIgZnJvbSByZWFkaW5nCnRo ZXNlIGhhcmR3YXJlIHJlZ2lzdGVycyBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCgpbIC4uLiBdCj4g K3N0YXRpYyB2b2lkIG1wX3BoeV91cGRhdGVfZmlybXdhcmUoc3RydWN0IHBoeSAqcGh5KQo+ICt7 Cj4gKwlzdHJ1Y3QgbXBfcGh5X3ByaXYgKnByaXYgPSBwaHlfZ2V0X2RydmRhdGEocGh5KTsKPiAr CWludCBpOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBwcml2LT5mdy0+c2l6ZTsgaSArPSAyKSB7 Cj4gKwkJd3JpdGV3KHByaXYtPmZ3LT5kYXRhW2ldIHwgKHByaXYtPmZ3LT5kYXRhW2kgKyAxXSA8 PCA4KSwKPiArCQkgICAgICAgcHJpdi0+YmFzZSArIE1QUEhZX0ZXX0JBU0UgKyAoTVBQSFlfRldf Q0hfT0ZGU0VUICogcGh5LT5pZCkgKyBpKTsKPiArCX0KPiArfQoKW1NldmVyaXR5OiBIaWdoXQpE b2VzIHRoaXMgY29kZSByaXNrIGFuIG91dC1vZi1ib3VuZHMgcmVhZCBvciBtZW1vcnkgY29ycnVw dGlvbiBpZiB0aGUKZmlybXdhcmUgc2l6ZSBpcyBvZGQgb3IgbGFyZ2VyIHRoYW4gZXhwZWN0ZWQ/ ClNpbmNlIG1wX3BoeV9wYXJzZV9kdCgpIGRvZXNuJ3QgdmFsaWRhdGUgcHJpdi0+ZnctPnNpemUs IGEgbGFyZ2UgZmlybXdhcmUKZmlsZSBjb3VsZCB3cml0ZSBiZXlvbmQgdGhlIGFsbG9jYXRlZCBN UFBIWV9GV19DSF9PRkZTRVQgKDB4MjAwMDApIG9yIG91dHNpZGUKdGhlIEkvTyByZWdpb24gY29t cGxldGVseS4gSWYgdGhlIHNpemUgaXMgb2RkLCByZWFkaW5nIHByaXYtPmZ3LT5kYXRhW2kgKyAx XQp3aWxsIHJlc3VsdCBpbiBhbiBvdXQtb2YtYm91bmRzIGFjY2Vzcy4KClsgLi4uIF0KPiArc3Rh dGljIGludCBtcF9waHlfaW5pdF9wY2llNChzdHJ1Y3QgcGh5ICpwaHkpCj4gK3sKPiArCXN0cnVj dCBtcF9waHlfcHJpdiAqcHJpdiA9IHBoeV9nZXRfZHJ2ZGF0YShwaHkpOwo+ICsKPiArCWlmIChw cml2LT5udW1fbGFuZXNbcGh5LT5pZF0gPT0gMSB8fCBwcml2LT5udW1fbGFuZXNbcGh5LT5pZF0g PT0gMikgewo+ICsJCWlmIChwaHktPmlkID09IDApIHsKPiArCQkJcmVnbWFwX3NldF9iaXRzKHBy aXYtPm1hcCwgTVBQSFlfUFhDTlRYVDEoMCksIDB4MjAxMDAwMik7Cj4gKwkJCXJlZ21hcF9zZXRf Yml0cyhwcml2LT5tYXAsIE1QUEhZX1BYQ05UWFQyKDApLCAweDIwMjAyMDEpOwo+ICsJCQlyZWdt YXBfc2V0X2JpdHMocHJpdi0+bWFwLCBNUFBIWV9QWFRYUkVRKDApLCAweDgwMDA0KTsKPiArCQkJ cmVnbWFwX3NldF9iaXRzKHByaXYtPm1hcCwgTVBQSFlfUFhSRUZDTEsoMCksIDB4MzApOwo+ICsJ CQlyZWdtYXBfc2V0X2JpdHMocHJpdi0+bWFwLCBNUFBIWV9QWFJFRkNMSygwKSwgMHg0KTsKPiAr CQkJcmVnbWFwX3NldF9iaXRzKHByaXYtPm1hcCwgTVBQSFlfUFhSRUZDTEsoMCksIDB4MSk7Cj4g KwkJCXJlZ21hcF9zZXRfYml0cyhwcml2LT5tYXAsIE1QUEhZX1BYUlhDTlQoMCksIDB4MjAyKTsK PiArCQkJcmVnbWFwX2NsZWFyX2JpdHMocHJpdi0+bWFwLCBNUFBIWV9QWFJYQ05UKDApLCAweDIw Mik7Cj4gKwkJfSBlbHNlIGlmIChwaHktPmlkID09IDEpIHsKPiArCQkJcmVnbWFwX3NldF9iaXRz KHByaXYtPm1hcCwgTVBQSFlfUFhDTlRYVDEoMiksIDB4MjAxMDAwMik7CgpbU2V2ZXJpdHk6IEhp Z2hdCklzIHBoeS0+aWQgdXNlZCBjb25zaXN0ZW50bHkgaGVyZT8KVGhlIGNvZGUgc2VlbXMgdG8g dHJlYXQgcGh5LT5pZCBhcyBhIGNvbnRyb2xsZXIgaW5kZXggcmF0aGVyIHRoYW4gYSBwb3J0IGlu ZGV4LAppZ25vcmluZyBjYXNlcyB3aGVyZSBwaHktPmlkIGlzIDIgb3IgMy4gVGhpcyBjb3VsZCBs ZWFkIHRvIGluY29ycmVjdCBwb3J0CmNvbmZpZ3VyYXRpb24gaWYgcGh5LT5pZCBtYXBzIGRpcmVj dGx5IHRvIHRoZSBwb3J0IGJlaW5nIGluaXRpYWxpemVkLgoKWyAuLi4gXQo+ICtzdGF0aWMgaW50 IG1wX3BoeV9pbml0KHN0cnVjdCBwaHkgKnBoeSkKPiArewo+ICsJc3RydWN0IG1wX3BoeV9wcml2 ICpwcml2ID0gcGh5X2dldF9kcnZkYXRhKHBoeSk7Cj4gKwlzdHJ1Y3QgbXBfcGh5X2NoYW5fcHJp diAqY2hhbiA9ICZwcml2LT5jaGFuW3BoeS0+aWRdOwo+ICsJaW50IHJldDsKPiArCj4gKwkvKgo+ ICsJICogTm90ZTogQ3VycmVudCBzb3VyY2UgY29kZSBzdXBwb3J0IGZvciBFdGhlcm5ldCwgUENJ ZQo+ICsJICogaW5pdGlhbGl6YXRpb24gaXMgYmFzZWQgb24gdGhlIGJhcmUgbWV0YWwgY29kZSBz aGFyZWQKPiArCSAqIGJ5IHRoZSBib2FyZCB0ZWFtLgo+ICsJICovCj4gKwlyZXQgPSBwbV9ydW50 aW1lX2dldF9zeW5jKHByaXYtPnBkX2xpc3QtPnBkX2RldnNbcGh5LT5pZF0pOwo+ICsJaWYgKHJl dCA8IDApIHsKPiArCQlkZXZfZXJyKHByaXYtPmRldiwKPiArCQkJIkZhaWxlZCB0byBwb3dlciBv biBkb21haW4gZm9yIGNoYW5uZWwgJWQ6ICVkXG4iLAo+ICsJCQlwaHktPmlkLCByZXQpOwo+ICsJ CXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJLyogQ2hlY2sgaWYgaW5pdGlhbGl6ZWQgd2l0aCBz YW1lIHByb3RvY29sIHRoZW4gc2tpcCAqLwo+ICsJaWYgKGNoYW4tPmluaXRpYWxpemVkKQo+ICsJ CXJldHVybiAwOwoKW1NldmVyaXR5OiBIaWdoXQpEb2VzIHRoaXMgY29kZSBsZWFrIHRoZSBwb3dl ciBtYW5hZ2VtZW50IHVzYWdlIGNvdW50ZXI/CklmIGNoYW4tPmluaXRpYWxpemVkIGlzIHRydWUs IHRoZSBmdW5jdGlvbiByZXR1cm5zIGRpcmVjdGx5IHdpdGhvdXQgZHJvcHBpbmcKdGhlIHJlZmVy ZW5jZSBhY3F1aXJlZCBieSBwbV9ydW50aW1lX2dldF9zeW5jKCkuCgo+ICsKPiArCWlmIChjaGFu LT5wcm90b2NvbF9pZCA9PSBQSFlfTU9ERV9QQ0lFKQo+ICsJCXJldCA9IG1wX3BoeV9pbml0X3Bj aWU0KHBoeSk7Cj4gKwllbHNlIGlmIChjaGFuLT5wcm90b2NvbF9pZCA9PSBQSFlfTU9ERV9FVEhF Uk5FVCkKPiArCQlyZXQgPSBtcF9waHlfaW5pdF9ldGhlcm5ldChwaHkpOwo+ICsJZWxzZQo+ICsJ CXJldCA9IG1wX3BoeV9pbml0X3VzYihwaHkpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0 OwoKW1NldmVyaXR5OiBIaWdoXQpDb3VsZCB0aGlzIGVycm9yIHBhdGggYWxzbyBsZWFrIHRoZSBQ TSB1c2FnZSBjb3VudGVyPwpJZiBwcm90b2NvbCBpbml0aWFsaXphdGlvbiBmYWlscywgdGhlIGZ1 bmN0aW9uIHJldHVybnMgd2l0aG91dCBkZWNyZW1lbnRpbmcKdGhlIHVzYWdlIGNvdW50ZXIsIHBy ZXZlbnRpbmcgdGhlIHBvd2VyIGRvbWFpbiBmcm9tIGV2ZXIgc3VzcGVuZGluZy4KClsgLi4uIF0K PiArc3RhdGljIGludCBtcF9waHlfcG93ZXJfb24oc3RydWN0IHBoeSAqcGh5KQo+ICt7Cj4gKwlz dHJ1Y3QgbXBfcGh5X3ByaXYgKnByaXYgPSBwaHlfZ2V0X2RydmRhdGEocGh5KTsKPiArCXN0cnVj dCBtcF9waHlfY2hhbl9wcml2ICpjaGFuID0gJnByaXYtPmNoYW5bcGh5LT5pZF07Cj4gKwlpbnQg cmV0Owo+ICsKPiArCWlmICghY2hhbi0+aW5pdGlhbGl6ZWQpIHsKPiArCQlkZXZfZXJyKHByaXYt PmRldiwgIkNoYW5uZWwgJWQgbm90IGluaXRpYWxpemVkXG4iLCBwaHktPmlkKTsKPiArCQlyZXR1 cm4gLUVJTlZBTDsKPiArCX0KCltTZXZlcml0eTogSGlnaF0KV2lsbCB0aGlzIHVuY29uZGl0aW9u YWxseSBmYWlsIGFmdGVyIGEgc3VzcGVuZC9yZXN1bWUgY3ljbGU/ClNpbmNlIG1wX3BoeV9zdXNw ZW5kKCkgY2xlYXJzIGNoYW4tPmluaXRpYWxpemVkIGZvciBhbGwgY2hhbm5lbHMgd2l0aG91dApk cm9wcGluZyB0aGVpciBhc3NvY2lhdGVkIFBNIGRvbWFpbiByZWZlcmVuY2VzLCBzdWJzZXF1ZW50 IGNhbGxzIHRvCnBoeV9wb3dlcl9vbigpIGFmdGVyIHJlc3VtZSB3aWxsIGhpdCB0aGlzIGNvbmRp dGlvbiBhbmQgZmFpbC4KClsgLi4uIF0KPiArCQl9IGVsc2UgaWYgKHByaXYtPm51bV9sYW5lc1tw aHktPmlkXSA9PSA0KSB7Cj4gKwkJCXJldCA9IG1wX3BoeV9yZWdfd2FpdChwcml2LCBNUFBIWV9Q WFNSQU1DTlQoMiAqIHBoeS0+aWQpLCAweDIwLCAweDIwKTsKPiArCQkJaWYgKHJldCkKPiArCQkJ CXJldHVybiByZXQ7Cj4gKwkJCXJldCA9IG1wX3BoeV9yZWdfd2FpdChwcml2LCBNUFBIWV9QWFNS QU1DTlQoKDIgKiBwaHktPmlkKSArIDEpLCAweDIwLCAweDIwKTsKCltTZXZlcml0eTogSGlnaF0K Q2FuIHRoaXMgcmVzdWx0IGluIGFuIG91dC1vZi1ib3VuZHMgcmVnbWFwIGFjY2Vzcz8KSWYgcGh5 LT5pZCBpcyAyLCAoMiAqIHBoeS0+aWQpICsgMSBldmFsdWF0ZXMgdG8gNSwgd2hpY2ggZXhjZWVk cyB0aGUKbWF4aW11bSBjaGFubmVsIGluZGV4IChNUFBIWV9OVU1fQ0hBTk5FTFMgaXMgNCkuCgpb IC4uLiBdCj4gK3N0YXRpYyBzdHJ1Y3QgcGh5ICptcF9waHlfeGxhdGUoc3RydWN0IGRldmljZSAq ZGV2LAo+ICsJCQkJY29uc3Qgc3RydWN0IG9mX3BoYW5kbGVfYXJncyAqYXJncykKPiArewo+ICsJ c3RydWN0IG1wX3BoeV9wcml2ICpwcml2ID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwlpbnQg aWQ7Cj4gKwo+ICsJaWYgKGFyZ3MtPmFyZ3NfY291bnQgPiAxKSB7Cj4gKwkJZGV2X2VycihkZXYs ICJJbnZhbGlkIGFyZ3NfY291bnQ6ICVkXG4iLCBhcmdzLT5hcmdzX2NvdW50KTsKPiArCQlyZXR1 cm4gRVJSX1BUUigtRUlOVkFMKTsKPiArCX0KPiArCj4gKwlpZiAoYXJncy0+YXJnc19jb3VudCA+ PSAxKQo+ICsJCWlkID0gYXJncy0+YXJnc1swXTsKPiArCWVsc2UKPiArCQlpZCA9IDA7Cj4gKwo+ ICsJcmV0dXJuIHByaXYtPmNoYW5baWRdLnBoeTsKPiArfQoKW1NldmVyaXR5OiBNZWRpdW1dCkRv ZXMgdGhpcyBjb2RlIG92ZXJmbG93IHRoZSBwcml2LT5jaGFuW10gYXJyYXk/CklmIGEgY29uc3Vt ZXIgcGFzc2VzIGFuIGlkID49IE1QUEhZX05VTV9DSEFOTkVMUyB2aWEgdGhlIGRldmljZSB0cmVl LAp0aGlzIHdpbGwgcmVzdWx0IGluIGFuIG91dC1vZi1ib3VuZHMgYXJyYXkgYWNjZXNzIHNpbmNl IHRoZXJlIGlzIG5vCmJvdW5kcyBjaGVja2luZyBvbiB0aGUgcmF3IGFyZ3VtZW50IGJlZm9yZSBp bmRleGluZyB0aGUgYXJyYXkuCgpbIC4uLiBdCj4gK3N0YXRpYyBpbnQgbXBfcGh5X3Byb2JlKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKWyAuLi4gXQo+ICsJcmV0ID0gbXBfcGh5 X3BhcnNlX2R0KHBkZXYsIHByaXYpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsK PiArCXByaXYtPmJhc2UgPSBkZXZtX3BsYXRmb3JtX2lvcmVtYXBfcmVzb3VyY2UocGRldiwgMCk7 Cj4gKwlpZiAoSVNfRVJSKHByaXYtPmJhc2UpKQo+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRl diwgUFRSX0VSUihwcml2LT5iYXNlKSwgIkZhaWxlZCB0byBtYXAgUEhZIHJlZ2lzdGVyc1xuIik7 CgpbU2V2ZXJpdHk6IE1lZGl1bV0KRG9lcyB0aGlzIGVycm9yIHBhdGggbGVhayB0aGUgYWxsb2Nh dGVkIGZpcm13YXJlPwptcF9waHlfcGFyc2VfZHQoKSBjYW4gc3VjY2Vzc2Z1bGx5IGFsbG9jYXRl IHByaXYtPmZ3IHZpYSByZXF1ZXN0X2Zpcm13YXJlKCkuCklmIGRldm1fcGxhdGZvcm1faW9yZW1h cF9yZXNvdXJjZSgpIGZhaWxzLCB0aGUgZnVuY3Rpb24gcmV0dXJucyBkaXJlY3RseQp3aXRob3V0 IGNhbGxpbmcgcmVsZWFzZV9maXJtd2FyZSgpLgoKWyAuLi4gXQo+ICsJLyoKPiArCSAqIFRoZSBy ZXNldCBJRCBvcmRlciBoZXJlIGRvZXMgbWF0dGVycywgcmVzZXRfY29udHJvbF9idWxrX2Fzc2Vy dCgpCj4gKwkgKiBhc3NlcnRzIHRoZXNlIHJlc2V0cyBpbiB0aGlzIG9yZGVyLCB3aXRoIG1wcGh5 MDIgcmVzZXQgYmVpbmcKPiArCSAqIGFzc2VydGVkIGZpcnN0LCByZXNldF9jb250cm9sX2J1bGtf ZGVhc3NlcnQoKSBkZWFzc2VydHMgdGhlc2UKPiArCSAqIHJlc2V0cyBpbiByZXZlcnNlIG9yZGVy LCB3aXRoIG1wcGh5MDIgYmVpbmcgcmVzZXQgYmVpbmcKPiArCSAqIGRlYXNzZXJ0ZWQgbGFzdC4g VGhpcyBpcyB0aGUgYmVoYXZpb3IgdGhlIGhhcmR3YXJlIGV4cGVjdHMuCj4gKwkgKi8KPiArCXBy aXYtPnJlc2V0c1swXS5pZCA9ICJtcHBoeTAyIjsKPiArCXByaXYtPnJlc2V0c1sxXS5pZCA9ICJt cHBoeTAxIjsKPiArCXByaXYtPnJlc2V0c1syXS5pZCA9ICJtcHBoeTExIjsKPiArCXByaXYtPnJl c2V0c1szXS5pZCA9ICJtcHBoeTIxIjsKPiArCXByaXYtPnJlc2V0c1s0XS5pZCA9ICJtcHBoeTMx IjsKPiArCXJldCA9IGRldm1fcmVzZXRfY29udHJvbF9idWxrX2dldF9leGNsdXNpdmUoJnBkZXYt PmRldiwgQVJSQVlfU0laRShwcml2LT5yZXNldHMpLAo+ICsJCQkJCQkgICAgcHJpdi0+cmVzZXRz KTsKCltTZXZlcml0eTogTWVkaXVtXQpXaWxsIHJlc2V0X2NvbnRyb2xfYnVsa19kZWFzc2VydCgp IGFjdHVhbGx5IGRlYXNzZXJ0IHRoZXNlIHJlc2V0cyBpbiByZXZlcnNlCm9yZGVyPwpUaGUgcmVz ZXRfY29udHJvbF9idWxrX2RlYXNzZXJ0KCkgQVBJIHByb2Nlc3NlcyB0aGUgYXJyYXkgc2VxdWVu dGlhbGx5IHVubGVzcwppdCBpcyB1bndpbmRpbmcgZnJvbSBhIGZhaWx1cmUuIFRoaXMgd291bGQg bWVhbiBtcHBoeTAyIGlzIGRlYXNzZXJ0ZWQgZmlyc3QKcmF0aGVyIHRoYW4gbGFzdCwgdmlvbGF0 aW5nIHRoZSBoYXJkd2FyZSBleHBlY3RhdGlvbiBkZXNjcmliZWQgaW4gdGhlIGNvbW1lbnQuCgpb IC4uLiBdCj4gKwlyZXQgPSBkZXZtX3BtX3J1bnRpbWVfZW5hYmxlKGRldik7Cj4gKwlpZiAocmV0 KQo+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgcmV0LCAiRmFpbGVkIHRvIGVuYWJsZSBQ SFkgcnVudGltZSBQTVxuIik7CgpbU2V2ZXJpdHk6IE1lZGl1bV0KQ291bGQgdGhpcyBlcnJvciBw YXRoIGxlYWsgcHJpdi0+ZncgYW5kIHRoZSBwb3dlciBkb21haW5zPwpJZiBkZXZtX3BtX3J1bnRp bWVfZW5hYmxlKCkgZmFpbHMsIHRoZSBmdW5jdGlvbiByZXR1cm5zIHdpdGhvdXQgY2FsbGluZwpy ZWxlYXNlX2Zpcm13YXJlKCkgb3IgZGV2X3BtX2RvbWFpbl9kZXRhY2hfbGlzdCgpLgoKPiArCj4g Kwlwcm92aWRlciA9IGRldm1fb2ZfcGh5X3Byb3ZpZGVyX3JlZ2lzdGVyKGRldiwgbXBfcGh5X3hs YXRlKTsKPiArCWlmIChJU19FUlIocHJvdmlkZXIpKQo+ICsJCXJldHVybiBkZXZfZXJyX3Byb2Jl KGRldiwgUFRSX0VSUihwcm92aWRlciksICJGYWlsZWQgdG8gcmVnaXN0ZXIgUEhZIHByb3ZpZGVy XG4iKTsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgTVBQSFlfTlVNX0NIQU5ORUxTOyBpKyspIHsK PiArCQlwcml2LT5jaGFuW2ldLnBoeSA9IGRldm1fcGh5X2NyZWF0ZShkZXYsIE5VTEwsICZtcF9w aHlfb3BzKTsKPiArCQlpZiAoSVNfRVJSKHByaXYtPmNoYW5baV0ucGh5KSkgewo+ICsJCQlyZXR1 cm4gZGV2X2Vycl9wcm9iZShkZXYsIFBUUl9FUlIocHJpdi0+Y2hhbltpXS5waHkpLAo+ICsJCQkJ CSAgICAgIkZhaWxlZCB0byBjcmVhdGUgUEhZICVkXG4iLCBpKTsKPiArCQl9Cj4gKwo+ICsJCXBy aXYtPmNoYW5baV0ucGh5LT5pZCA9IGk7Cj4gKwkJcGh5X3NldF9kcnZkYXRhKHByaXYtPmNoYW5b aV0ucGh5LCBwcml2KTsKPiArCX0KCltTZXZlcml0eTogTWVkaXVtXQpEb2VzIHJlZ2lzdGVyaW5n IHRoZSBwcm92aWRlciBoZXJlIGV4cG9zZSB0aGUgUEhZIHRvIGNvbnN1bWVycyBwcmVtYXR1cmVs eT8KVGhlIHByb3ZpZGVyIGlzIHJlZ2lzdGVyZWQgYmVmb3JlIHRoZSBQSFkgb2JqZWN0cyAocHJp di0+Y2hhbltpXS5waHkpIGFyZQpjcmVhdGVkLiBJZiBhIGNvbnN1bWVyIHByb2JlcyBpbW1lZGlh dGVseSwgbXBfcGh5X3hsYXRlKCkgd291bGQgcmV0dXJuIGEKTlVMTCBwb2ludGVyLgoKWyAuLi4g XQo+ICtzdGF0aWMgdm9pZCBtcF9waHlfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYpCj4gK3sKPiArCXN0cnVjdCBtcF9waHlfcHJpdiAqcHJpdiA9IGRldl9nZXRfZHJ2ZGF0YSgm cGRldi0+ZGV2KTsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7Cj4gKwo+ICsJ cG1fcnVudGltZV9wdXQoZGV2KTsKPiArCj4gKwlkZXZfcG1fZG9tYWluX2RldGFjaF9saXN0KHBy aXYtPnBkX2xpc3QpOwo+ICsKPiArCXBtX3J1bnRpbWVfZGlzYWJsZSgmcGRldi0+ZGV2KTsKCltT ZXZlcml0eTogTWVkaXVtXQpDYW4gdGhpcyByZXN1bHQgaW4gYW4gYWJvcnRlZCBwb3dlciBzdGF0 ZSB0cmFuc2l0aW9uPwpBY2NvcmRpbmcgdG8gUE0gc3Vic3lzdGVtIHJ1bGVzLCBjYWxsaW5nIHBt X3J1bnRpbWVfZGlzYWJsZSgpIGltbWVkaWF0ZWx5CmFmdGVyIGFuIGFzeW5jaHJvbm91cyBwbV9y dW50aW1lX3B1dCgpIGNhbiBjYW5jZWwgcGVuZGluZyBzdXNwZW5kIHdvcmsuClNob3VsZCBwbV9y dW50aW1lX3B1dF9zeW5jKCkgYmUgdXNlZCBoZXJlIGluc3RlYWQ/CgpbIC4uLiBdCj4gK3N0YXRp YyBpbnQgbXBfcGh5X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQo+ICt7Cj4gKwlzdHJ1Y3Qg bXBfcGh5X3ByaXYgKnByaXYgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiArCWludCBpOwo+ICsK PiArCWZvciAoaSA9IDA7IGkgPCBNUFBIWV9OVU1fQ0hBTk5FTFM7IGkrKykKPiArCQlwcml2LT5j aGFuW2ldLmluaXRpYWxpemVkID0gZmFsc2U7Cj4gKwo+ICsJY2xrX2J1bGtfZGlzYWJsZV91bnBy ZXBhcmUocHJpdi0+bnVtX2Nsa3MsIHByaXYtPmNsa3MpOwo+ICsKPiArCWRldl9pbmZvKGRldiwg Ik11bHRpLVByb3RvY29sIFBIWSBzdXNwZW5kZWRcbiIpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9 CgpbU2V2ZXJpdHk6IEhpZ2hdCldpbGwgY2xlYXJpbmcgY2hhbi0+aW5pdGlhbGl6ZWQgaGVyZSBi cmVhayB0aGUgUEhZIG9uIHJlc3VtZT8KVGhpcyBmbGFnIGlzIGNsZWFyZWQgd2l0aG91dCBkZWNy ZW1lbnRpbmcgdGhlIGFzc29jaWF0ZWQgUE0gZG9tYWluIHVzYWdlCmNvdW50ZXIuIE9uIHJlc3Vt ZSwgaXQgaXMgbmV2ZXIgcmVzdG9yZWQgdG8gdHJ1ZSwgY2F1c2luZyBzdWJzZXF1ZW50IGNhbGxz CnRvIG1wX3BoeV9wb3dlcl9vbigpIHRvIGZhaWwgdW5jb25kaXRpb25hbGx5LgoKWyAuLi4gXQo+ ICtzdGF0aWMgaW50IG1wX3BoeV9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQo+ICt7ClsgLi4u IF0KPiArCWZvciAoaSA9IDA7IGkgPCBNUFBIWV9OVU1fQ0hBTk5FTFM7IGkrKykgewo+ICsJCXJl Z21hcF9zZXRfYml0cyhwcml2LT5tYXAsIE1QUEhZX1BYVEVTVChpKSwgTVBQSFlfUFhURVNUX0JJ VCk7Cj4gKwkJcmVnbWFwX3dyaXRlKHByaXYtPm1hcCwgTVBQSFlfUFhTUkFNQ05UKGkpLCBwcml2 LT5zcmFtY250W2ldKTsKPiArCj4gKwkJaWYgKHByaXYtPndyaXRlX2NudHh0MSAmIEJJVChpKSkg ewo+ICsJCQlyZWdtYXBfd3JpdGUocHJpdi0+bWFwLCBNUFBIWV9DSEFOX0JBU0UoaSkgKyAweDEw YywgMHhmZjBmZik7CgpbU2V2ZXJpdHk6IEhpZ2hdCkFyZSB3ZSBndWFyYW50ZWVkIHRoYXQgdGhl IHBvd2VyIGRvbWFpbnMgZm9yIGFsbCA0IGNoYW5uZWxzIGFyZSB0dXJuZWQgb24gaGVyZT8KSWYg YSBjaGFubmVsIGlzIHVudXNlZCBhbmQgaXRzIHBvd2VyIGRvbWFpbiBpcyBvZmYsIGFjY2Vzc2lu ZyBpdHMgcmVnaXN0ZXJzCmJsaW5kbHkgaW4gdGhpcyBsb29wIGNvdWxkIGxlYWQgdG8gYSBidXMg ZmF1bHQgYW5kIHN5c3RlbSBjcmFzaC4KCltTZXZlcml0eTogSGlnaF0KQWxzbywgd2lsbCByZWdt YXAgcmVqZWN0IHRoaXMgd3JpdGUgdG8gMHgxMGM/ClRoaXMgcmVnaXN0ZXIgb2Zmc2V0IGRvZXMg bm90IGFwcGVhciB0byBiZSBkZWNsYXJlZCBpbiB0aGUKbXBfcGh5X3dyaXRlYWJsZV9yYW5nZSB0 YWJsZSwgbWVhbmluZyB0aGUgcmVnbWFwIGNvcmUgd2lsbCByZXR1cm4gYW4gLUVJTwplcnJvci4K Ci0tIApTYXNoaWtvIEFJIHJldmlldyDCtyBodHRwczovL3Nhc2hpa28uZGV2LyMvcGF0Y2hzZXQv MjAyNjA4MjgxOTIyMjMuNDAyNDIyLTEtbWFyZWsudmFzdXQrcmVuZXNhc0BtYWlsYm94Lm9yZz9w YXJ0PTIKCi0tIApsaW51eC1waHkgbWFpbGluZyBsaXN0CmxpbnV4LXBoeUBsaXN0cy5pbmZyYWRl YWQub3JnCmh0dHBzOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4 LXBoeQo=