From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 DE602389E05; Thu, 28 May 2026 08:55:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779958508; cv=none; b=DCbyvEWqH/aGCbgxpTcORvUy93bEGZlhlf7rQyxzXAVwO9nYPfBhbbCeFrid2mtA+oWtl3Xkgf07HXyoR+siYAAPSo7lkfEWfsdvX2DGFRPaedeo5WtObPBLVKGtcQj8YN8wbL8DhiIY7Mp8OJR4p2+ZvWBLzY9KAmQQiGljkNg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779958508; c=relaxed/simple; bh=Ugo6u4SyugBnQM5lEoIXKmIhUXIcvCin4jcxhvCcREY=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=Jz9cu0bBC84yCBViq/R3Sz0mgw+SREwKymcR8ALPDpK+N0RMWlgrrkqwbyQWQaL6ohJ9tQYGrmqJ3ASNs3yWUbZ4Ka+D1ldkuWWfQDKJ6xkY74k9x156XncPlJH1eoGlvO27TS8Jkv+8lrsYD6V4g4TRxebVCa4UtihZ1GWfL18= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=tewPilAf; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="tewPilAf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 5FFAEC62445; Thu, 28 May 2026 08:55:03 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2D40060495; Thu, 28 May 2026 08:55:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2F6631088877F; Thu, 28 May 2026 10:54:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779958502; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Mms8zVeKVl4m3zXRZxt6cX5JkM7V/uTQ+FCIhnWPTuw=; b=tewPilAf9ErtzNRl134ztaKZBbhMd+BtcE9t7Nz1h6+7C3DIYKS4DtVVrP3WCJh+Nq5aMX mh3W+V6DCpel514WkiYhPuKb2uquo40VTYRC5UPGMuZuGBnVIVvVR/Rb6Us6nB4vNshfP/ nbACcBMdiYT3FDAf0sZS0h9JBGnQG2n6Kt6VXwRBlb9A2msSHUR+Ikd3mCcBvOD5JPYzj5 MRGBEAMuDd75Lrhxo/ImM4r/Gji1OAD+DSlQY++ncaPsAAAJwNPMIpB1A9XazJAhozmvbc za8xfmesB+NbJ9uydXwwezYFnH2UeicFHQcoXegtu6Y1ZxeHVrQucCx0humGlQ== From: Miquel Raynal To: Santhosh Kumar K Cc: , , , , , , , , , , , , , , , Subject: Re: [PATCH v3 08/13] spi: cadence-quadspi: add PHY tuning support In-Reply-To: <20260527175527.2247679-9-s-k6@ti.com> (Santhosh Kumar K.'s message of "Wed, 27 May 2026 23:25:22 +0530") References: <20260527175527.2247679-1-s-k6@ti.com> <20260527175527.2247679-9-s-k6@ti.com> User-Agent: mu4e 1.12.7; emacs 30.2 Date: Thu, 28 May 2026 10:54:58 +0200 Message-ID: <874ijrhq1p.fsf@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 On 27/05/2026 at 23:25:22 +0530, Santhosh Kumar K wrote: > The Cadence QSPI controller supports a delay-line PHY for high-speed > operation. Without calibration the PHY is unused and read capture relies > on a fixed delay, limiting throughput at frequencies above the base > operating speed. > > Add an execute_tuning callback that performs delay-line calibration using > a known data pattern written to a dedicated flash region. The pattern is > either read from a NOR partition identified by the DT property > cdns,phy-pattern-partition, or written to the NAND page cache before > each calibration read. > > For DDR protocols (8D-8D-8D) a 2D sweep of (rx_delay, tx_delay) pairs > is performed to find the widest passing region in the combined RX/TX > space. Binary search locates the gap boundary between passing regions > when two separate windows exist; the final operating point is placed at > the centre of the larger region with a small temperature-dependent > offset. > > For SDR protocols a 1D sweep of the RX delay is sufficient. Two windows > at adjacent read_delay values are measured; the wider one's midpoint is > selected. > > The tuning infrastructure is platform-specific: only am654-based OSPI > controllers populate the execute_tuning hook. All other platform data > entries return -EOPNOTSUPP and are unaffected. > > spi-max-frequency may carry two values in DT; the second (higher) value > is the tuned target rate stored in max_clk_rate. When only one value is > present max_clk_rate is zero and tuning is skipped. > > Signed-off-by: Santhosh Kumar K > --- There are more than 1800 new lines for the PHY tuning procedure. I left that decision to Mark of course, by maybe we should move that into another .c file. > +static int cqspi_am654_ospi_execute_tuning(struct spi_mem *mem, > + struct spi_mem_op *read_op, > + struct spi_mem_op *write_op) > +{ > + struct cqspi_st *cqspi =3D > + spi_controller_get_devdata(mem->spi->controller); > + struct cqspi_flash_pdata *f_pdata; > + struct device *dev =3D &cqspi->pdev->dev; > + u32 base_speed; > + u32 phy_offset =3D 0; > + int ret; > + > + f_pdata =3D &cqspi->f_pdata[spi_get_chipselect(mem->spi, 0)]; > + > + /* > + * A second spi-max-frequency value (the higher clock rate) must be > + * present for tiered speed support. Without it there is nothing to > + * calibrate towards, so skip tuning gracefully. > + */ > + if (!f_pdata->max_clk_rate) { > + dev_dbg(dev, "No higher clock rate configured, skipping tuning\n"); > + return 0; > + } > + > + base_speed =3D mem->spi->base_speed_hz; > + > + if (write_op) { > + /* > + * For NAND: write the calibration pattern to the page cache. > + * This uses write_op at the safe base speed (base_speed_hz is > + * still active) so the write itself is reliable. > + */ > + ret =3D cqspi_write_pattern_to_cache(f_pdata, mem, write_op); > + if (ret) { > + dev_warn(dev, > + "failed to write pattern to cache: %d, skipping tuning\n", > + ret); > + goto out; > + } > + > + f_pdata->phy_write_op =3D *write_op; > + } else { > + ret =3D cqspi_get_phy_pattern_offset(dev, &phy_offset); > + if (ret) { > + dev_warn(dev, > + "pattern partition not found: %d, skipping tuning\n", > + ret); > + goto out; > + } > + > + read_op->addr.val =3D phy_offset; > + } > + > + /* > + * Verify the calibration pattern exists using the conservative base > + * speed. At high clock rates the DLL is not yet trained, so DTR > + * data capture is unreliable and the read would return garbage. > + * Setting max_freq to 0 here causes apply_base_freq_cap() to cap the > + * read to base_speed_hz, which is well within reliable DTR margins. > + * max_freq is restored to max_speed_hz for the tuning-loop reads > + * after base_speed_hz is cleared below. > + */ > + f_pdata->phy_read_op =3D *read_op; > + f_pdata->phy_read_op.max_freq =3D 0; > + > + ret =3D cqspi_phy_check_pattern(f_pdata, mem); > + if (ret) { > + dev_err(dev, "pattern not found: %d, skipping tuning\n", ret); > + goto out; > + } > + > + /* > + * Pattern confirmed. Now clear base_speed_hz so that tuning-loop > + * exec_op calls run at max_speed_hz, and restore phy_read_op.max_freq > + * so those reads also use the full speed. > + */ > + mem->spi->base_speed_hz =3D 0; If there is a way to avoid touching the core parameters, I would be for using it, but maybe it is simpler to do it this way. > + f_pdata->phy_read_op.max_freq =3D mem->spi->max_speed_hz; > + > + if (read_op->cmd.dtr || read_op->addr.dtr || read_op->dummy.dtr || > + read_op->data.dtr) { > + f_pdata->use_dqs =3D true; > + cqspi_phy_pre_config(cqspi, f_pdata, false); > + ret =3D cqspi_phy_tuning_ddr(f_pdata, mem); > + } else { > + f_pdata->use_dqs =3D false; > + cqspi_phy_pre_config(cqspi, f_pdata, true); > + ret =3D cqspi_phy_tuning_sdr(f_pdata, mem); > + } > + > + if (ret) > + dev_warn(dev, "tuning failed: %d\n", ret); > + > + cqspi_phy_post_config(cqspi, f_pdata->read_delay); > + > +out: > + /* > + * Always restore the conservative base speed cap. On success, write > + * back the validated maximum speed into the caller's op templates so > + * that those specific ops bypass the cap in subsequent exec_op calls. > + */ > + mem->spi->base_speed_hz =3D base_speed; > + if (!ret) { > + read_op->max_freq =3D mem->spi->max_speed_hz; > + if (write_op) > + write_op->max_freq =3D mem->spi->max_speed_hz; > + } Neat. > + > + return ret; > +} > + > +static int cqspi_mem_op_execute_tuning(struct spi_mem *mem, > + struct spi_mem_op *read_op, > + struct spi_mem_op *write_op) > +{ > + struct cqspi_st *cqspi =3D > + spi_controller_get_devdata(mem->spi->controller); > + > + if (!cqspi->ddata->execute_tuning) > + return -EOPNOTSUPP; > + > + return cqspi->ddata->execute_tuning(mem, read_op, write_op); > +} > + > static int cqspi_of_get_flash_pdata(struct platform_device *pdev, > struct cqspi_flash_pdata *f_pdata, > struct device_node *np) > { > + int nfreq, ret; > + > if (of_property_read_u32(np, "cdns,read-delay", &f_pdata->read_delay)) { > dev_err(&pdev->dev, "couldn't determine read-delay\n"); > return -ENXIO; > @@ -1584,7 +3343,26 @@ static int cqspi_of_get_flash_pdata(struct platfor= m_device *pdev, > return -ENXIO; > } >=20=20 > - if (of_property_read_u32(np, "spi-max-frequency", &f_pdata->clk_rate)) { > + /* > + * spi-max-frequency accepts one or two values: > + * - single rate; no tiered speed support > + * - conservative default and higher maximum > + * > + * With two values the SPI core sets spi->base_speed_hz =3D base-freq a= nd > + * spi->max_speed_hz =3D max-freq. Store the second value here as the > + * controller's higher rate target for calibration. > + */ > + nfreq =3D of_property_count_u32_elems(np, "spi-max-frequency"); > + if (nfreq =3D=3D 2) { > + ret =3D of_property_read_u32_index(np, "spi-max-frequency", 1, > + &f_pdata->max_clk_rate); > + if (ret) { > + dev_err(&pdev->dev, "couldn't read spi-max-frequency[1]\n"); > + return ret; > + } > + } else if (nfreq =3D=3D 1) { > + f_pdata->max_clk_rate =3D 0; > + } else { > dev_err(&pdev->dev, "couldn't determine spi-max-frequency\n"); > return -ENXIO; > } Why do we repeat that operation in the driver? Can't we just use what the core has already done for us? Seems like we are parsing the same data twice (even before this patchset). Thanks, Miqu=C3=A8l 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 714DECD5BD1 for ; Thu, 28 May 2026 08:55:11 +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:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:References :In-Reply-To:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Is174ZcwbPKjS0o4nMxyFOu0wHSMGmT7yyH1jkDVtVM=; b=lFlKWrtXyGTglC PMWVoRie2KQ8XZ5kcysYsY08Rdio0DglLSbS9NsE0kgzM/p2/ZuEsa8NUSF+NPx8ONLyJCk/VIASW u7w3xoRDFOASshDpWzZ/sSd829SJ6jvzCkwlL3I8zHhCL+L5H0UDyPlh+2oYtfsYDqrNrdJ8z1c99 JRZ3b4tqT9NCS4gHEyaRILxWdRaLcMphbpgbCJQwYnSFSUSmk0yoJ5Pjqz29QXagieudhq65/GnR2 yOv3Vq4ogj+v8WVFVwgWmQav26DaQklGXrVP0sk4SM8rD5244++FGrl797kuLSy/1PFihWPvKvvTa PDLWtlCnD9fHkrLRYcWw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wSWWD-00000005RWs-2JH2; Thu, 28 May 2026 08:55:09 +0000 Received: from smtpout-03.galae.net ([185.246.85.4]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wSWWA-00000005RVo-2raQ for linux-mtd@lists.infradead.org; Thu, 28 May 2026 08:55:08 +0000 Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 6098B4E42D73; Thu, 28 May 2026 08:55:03 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2D40060495; Thu, 28 May 2026 08:55:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2F6631088877F; Thu, 28 May 2026 10:54:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779958502; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Mms8zVeKVl4m3zXRZxt6cX5JkM7V/uTQ+FCIhnWPTuw=; b=tewPilAf9ErtzNRl134ztaKZBbhMd+BtcE9t7Nz1h6+7C3DIYKS4DtVVrP3WCJh+Nq5aMX mh3W+V6DCpel514WkiYhPuKb2uquo40VTYRC5UPGMuZuGBnVIVvVR/Rb6Us6nB4vNshfP/ nbACcBMdiYT3FDAf0sZS0h9JBGnQG2n6Kt6VXwRBlb9A2msSHUR+Ikd3mCcBvOD5JPYzj5 MRGBEAMuDd75Lrhxo/ImM4r/Gji1OAD+DSlQY++ncaPsAAAJwNPMIpB1A9XazJAhozmvbc za8xfmesB+NbJ9uydXwwezYFnH2UeicFHQcoXegtu6Y1ZxeHVrQucCx0humGlQ== From: Miquel Raynal To: Santhosh Kumar K Cc: , , , , , , , , , , , , , , , Subject: Re: [PATCH v3 08/13] spi: cadence-quadspi: add PHY tuning support In-Reply-To: <20260527175527.2247679-9-s-k6@ti.com> (Santhosh Kumar K.'s message of "Wed, 27 May 2026 23:25:22 +0530") References: <20260527175527.2247679-1-s-k6@ti.com> <20260527175527.2247679-9-s-k6@ti.com> User-Agent: mu4e 1.12.7; emacs 30.2 Date: Thu, 28 May 2026 10:54:58 +0200 Message-ID: <874ijrhq1p.fsf@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260528_015506_996889_AE0DECFC X-CRM114-Status: GOOD ( 30.77 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org T24gMjcvMDUvMjAyNiBhdCAyMzoyNToyMiArMDUzMCwgU2FudGhvc2ggS3VtYXIgSyA8cy1rNkB0 aS5jb20+IHdyb3RlOgoKPiBUaGUgQ2FkZW5jZSBRU1BJIGNvbnRyb2xsZXIgc3VwcG9ydHMgYSBk ZWxheS1saW5lIFBIWSBmb3IgaGlnaC1zcGVlZAo+IG9wZXJhdGlvbi4gV2l0aG91dCBjYWxpYnJh dGlvbiB0aGUgUEhZIGlzIHVudXNlZCBhbmQgcmVhZCBjYXB0dXJlIHJlbGllcwo+IG9uIGEgZml4 ZWQgZGVsYXksIGxpbWl0aW5nIHRocm91Z2hwdXQgYXQgZnJlcXVlbmNpZXMgYWJvdmUgdGhlIGJh c2UKPiBvcGVyYXRpbmcgc3BlZWQuCj4KPiBBZGQgYW4gZXhlY3V0ZV90dW5pbmcgY2FsbGJhY2sg dGhhdCBwZXJmb3JtcyBkZWxheS1saW5lIGNhbGlicmF0aW9uIHVzaW5nCj4gYSBrbm93biBkYXRh IHBhdHRlcm4gd3JpdHRlbiB0byBhIGRlZGljYXRlZCBmbGFzaCByZWdpb24uIFRoZSBwYXR0ZXJu IGlzCj4gZWl0aGVyIHJlYWQgZnJvbSBhIE5PUiBwYXJ0aXRpb24gaWRlbnRpZmllZCBieSB0aGUg RFQgcHJvcGVydHkKPiBjZG5zLHBoeS1wYXR0ZXJuLXBhcnRpdGlvbiwgb3Igd3JpdHRlbiB0byB0 aGUgTkFORCBwYWdlIGNhY2hlIGJlZm9yZQo+IGVhY2ggY2FsaWJyYXRpb24gcmVhZC4KPgo+IEZv ciBERFIgcHJvdG9jb2xzICg4RC04RC04RCkgYSAyRCBzd2VlcCBvZiAocnhfZGVsYXksIHR4X2Rl bGF5KSBwYWlycwo+IGlzIHBlcmZvcm1lZCB0byBmaW5kIHRoZSB3aWRlc3QgcGFzc2luZyByZWdp b24gaW4gdGhlIGNvbWJpbmVkIFJYL1RYCj4gc3BhY2UuIEJpbmFyeSBzZWFyY2ggbG9jYXRlcyB0 aGUgZ2FwIGJvdW5kYXJ5IGJldHdlZW4gcGFzc2luZyByZWdpb25zCj4gd2hlbiB0d28gc2VwYXJh dGUgd2luZG93cyBleGlzdDsgdGhlIGZpbmFsIG9wZXJhdGluZyBwb2ludCBpcyBwbGFjZWQgYXQK PiB0aGUgY2VudHJlIG9mIHRoZSBsYXJnZXIgcmVnaW9uIHdpdGggYSBzbWFsbCB0ZW1wZXJhdHVy ZS1kZXBlbmRlbnQKPiBvZmZzZXQuCj4KPiBGb3IgU0RSIHByb3RvY29scyBhIDFEIHN3ZWVwIG9m IHRoZSBSWCBkZWxheSBpcyBzdWZmaWNpZW50LiBUd28gd2luZG93cwo+IGF0IGFkamFjZW50IHJl YWRfZGVsYXkgdmFsdWVzIGFyZSBtZWFzdXJlZDsgdGhlIHdpZGVyIG9uZSdzIG1pZHBvaW50IGlz Cj4gc2VsZWN0ZWQuCj4KPiBUaGUgdHVuaW5nIGluZnJhc3RydWN0dXJlIGlzIHBsYXRmb3JtLXNw ZWNpZmljOiBvbmx5IGFtNjU0LWJhc2VkIE9TUEkKPiBjb250cm9sbGVycyBwb3B1bGF0ZSB0aGUg ZXhlY3V0ZV90dW5pbmcgaG9vay4gQWxsIG90aGVyIHBsYXRmb3JtIGRhdGEKPiBlbnRyaWVzIHJl dHVybiAtRU9QTk9UU1VQUCBhbmQgYXJlIHVuYWZmZWN0ZWQuCj4KPiBzcGktbWF4LWZyZXF1ZW5j eSBtYXkgY2FycnkgdHdvIHZhbHVlcyBpbiBEVDsgdGhlIHNlY29uZCAoaGlnaGVyKSB2YWx1ZQo+ IGlzIHRoZSB0dW5lZCB0YXJnZXQgcmF0ZSBzdG9yZWQgaW4gbWF4X2Nsa19yYXRlLiBXaGVuIG9u bHkgb25lIHZhbHVlIGlzCj4gcHJlc2VudCBtYXhfY2xrX3JhdGUgaXMgemVybyBhbmQgdHVuaW5n IGlzIHNraXBwZWQuCj4KPiBTaWduZWQtb2ZmLWJ5OiBTYW50aG9zaCBLdW1hciBLIDxzLWs2QHRp LmNvbT4KPiAtLS0KClRoZXJlIGFyZSBtb3JlIHRoYW4gMTgwMCBuZXcgbGluZXMgZm9yIHRoZSBQ SFkgdHVuaW5nIHByb2NlZHVyZS4gSSBsZWZ0CnRoYXQgZGVjaXNpb24gdG8gTWFyayBvZiBjb3Vy c2UsIGJ5IG1heWJlIHdlIHNob3VsZCBtb3ZlIHRoYXQgaW50bwphbm90aGVyIC5jIGZpbGUuCgo+ ICtzdGF0aWMgaW50IGNxc3BpX2FtNjU0X29zcGlfZXhlY3V0ZV90dW5pbmcoc3RydWN0IHNwaV9t ZW0gKm1lbSwKPiArCQkJCQkgICBzdHJ1Y3Qgc3BpX21lbV9vcCAqcmVhZF9vcCwKPiArCQkJCQkg ICBzdHJ1Y3Qgc3BpX21lbV9vcCAqd3JpdGVfb3ApCj4gK3sKPiArCXN0cnVjdCBjcXNwaV9zdCAq Y3FzcGkgPQo+ICsJCXNwaV9jb250cm9sbGVyX2dldF9kZXZkYXRhKG1lbS0+c3BpLT5jb250cm9s bGVyKTsKPiArCXN0cnVjdCBjcXNwaV9mbGFzaF9wZGF0YSAqZl9wZGF0YTsKPiArCXN0cnVjdCBk ZXZpY2UgKmRldiA9ICZjcXNwaS0+cGRldi0+ZGV2Owo+ICsJdTMyIGJhc2Vfc3BlZWQ7Cj4gKwl1 MzIgcGh5X29mZnNldCA9IDA7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWZfcGRhdGEgPSAmY3FzcGkt PmZfcGRhdGFbc3BpX2dldF9jaGlwc2VsZWN0KG1lbS0+c3BpLCAwKV07Cj4gKwo+ICsJLyoKPiAr CSAqIEEgc2Vjb25kIHNwaS1tYXgtZnJlcXVlbmN5IHZhbHVlICh0aGUgaGlnaGVyIGNsb2NrIHJh dGUpIG11c3QgYmUKPiArCSAqIHByZXNlbnQgZm9yIHRpZXJlZCBzcGVlZCBzdXBwb3J0LiAgV2l0 aG91dCBpdCB0aGVyZSBpcyBub3RoaW5nIHRvCj4gKwkgKiBjYWxpYnJhdGUgdG93YXJkcywgc28g c2tpcCB0dW5pbmcgZ3JhY2VmdWxseS4KPiArCSAqLwo+ICsJaWYgKCFmX3BkYXRhLT5tYXhfY2xr X3JhdGUpIHsKPiArCQlkZXZfZGJnKGRldiwgIk5vIGhpZ2hlciBjbG9jayByYXRlIGNvbmZpZ3Vy ZWQsIHNraXBwaW5nIHR1bmluZ1xuIik7Cj4gKwkJcmV0dXJuIDA7Cj4gKwl9Cj4gKwo+ICsJYmFz ZV9zcGVlZCA9IG1lbS0+c3BpLT5iYXNlX3NwZWVkX2h6Owo+ICsKPiArCWlmICh3cml0ZV9vcCkg ewo+ICsJCS8qCj4gKwkJICogRm9yIE5BTkQ6IHdyaXRlIHRoZSBjYWxpYnJhdGlvbiBwYXR0ZXJu IHRvIHRoZSBwYWdlIGNhY2hlLgo+ICsJCSAqIFRoaXMgdXNlcyB3cml0ZV9vcCBhdCB0aGUgc2Fm ZSBiYXNlIHNwZWVkIChiYXNlX3NwZWVkX2h6IGlzCj4gKwkJICogc3RpbGwgYWN0aXZlKSBzbyB0 aGUgd3JpdGUgaXRzZWxmIGlzIHJlbGlhYmxlLgo+ICsJCSAqLwo+ICsJCXJldCA9IGNxc3BpX3dy aXRlX3BhdHRlcm5fdG9fY2FjaGUoZl9wZGF0YSwgbWVtLCB3cml0ZV9vcCk7Cj4gKwkJaWYgKHJl dCkgewo+ICsJCQlkZXZfd2FybihkZXYsCj4gKwkJCQkgImZhaWxlZCB0byB3cml0ZSBwYXR0ZXJu IHRvIGNhY2hlOiAlZCwgc2tpcHBpbmcgdHVuaW5nXG4iLAo+ICsJCQkJIHJldCk7Cj4gKwkJCWdv dG8gb3V0Owo+ICsJCX0KPiArCj4gKwkJZl9wZGF0YS0+cGh5X3dyaXRlX29wID0gKndyaXRlX29w Owo+ICsJfSBlbHNlIHsKPiArCQlyZXQgPSBjcXNwaV9nZXRfcGh5X3BhdHRlcm5fb2Zmc2V0KGRl diwgJnBoeV9vZmZzZXQpOwo+ICsJCWlmIChyZXQpIHsKPiArCQkJZGV2X3dhcm4oZGV2LAo+ICsJ CQkJICJwYXR0ZXJuIHBhcnRpdGlvbiBub3QgZm91bmQ6ICVkLCBza2lwcGluZyB0dW5pbmdcbiIs Cj4gKwkJCQkgcmV0KTsKPiArCQkJZ290byBvdXQ7Cj4gKwkJfQo+ICsKPiArCQlyZWFkX29wLT5h ZGRyLnZhbCA9IHBoeV9vZmZzZXQ7Cj4gKwl9Cj4gKwo+ICsJLyoKPiArCSAqIFZlcmlmeSB0aGUg Y2FsaWJyYXRpb24gcGF0dGVybiBleGlzdHMgdXNpbmcgdGhlIGNvbnNlcnZhdGl2ZSBiYXNlCj4g KwkgKiBzcGVlZC4gIEF0IGhpZ2ggY2xvY2sgcmF0ZXMgdGhlIERMTCBpcyBub3QgeWV0IHRyYWlu ZWQsIHNvIERUUgo+ICsJICogZGF0YSBjYXB0dXJlIGlzIHVucmVsaWFibGUgYW5kIHRoZSByZWFk IHdvdWxkIHJldHVybiBnYXJiYWdlLgo+ICsJICogU2V0dGluZyBtYXhfZnJlcSB0byAwIGhlcmUg Y2F1c2VzIGFwcGx5X2Jhc2VfZnJlcV9jYXAoKSB0byBjYXAgdGhlCj4gKwkgKiByZWFkIHRvIGJh c2Vfc3BlZWRfaHosIHdoaWNoIGlzIHdlbGwgd2l0aGluIHJlbGlhYmxlIERUUiBtYXJnaW5zLgo+ ICsJICogbWF4X2ZyZXEgaXMgcmVzdG9yZWQgdG8gbWF4X3NwZWVkX2h6IGZvciB0aGUgdHVuaW5n LWxvb3AgcmVhZHMKPiArCSAqIGFmdGVyIGJhc2Vfc3BlZWRfaHogaXMgY2xlYXJlZCBiZWxvdy4K PiArCSAqLwo+ICsJZl9wZGF0YS0+cGh5X3JlYWRfb3AgPSAqcmVhZF9vcDsKPiArCWZfcGRhdGEt PnBoeV9yZWFkX29wLm1heF9mcmVxID0gMDsKPiArCj4gKwlyZXQgPSBjcXNwaV9waHlfY2hlY2tf cGF0dGVybihmX3BkYXRhLCBtZW0pOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoZGV2LCAi cGF0dGVybiBub3QgZm91bmQ6ICVkLCBza2lwcGluZyB0dW5pbmdcbiIsIHJldCk7Cj4gKwkJZ290 byBvdXQ7Cj4gKwl9Cj4gKwo+ICsJLyoKPiArCSAqIFBhdHRlcm4gY29uZmlybWVkLiAgTm93IGNs ZWFyIGJhc2Vfc3BlZWRfaHogc28gdGhhdCB0dW5pbmctbG9vcAo+ICsJICogZXhlY19vcCBjYWxs cyBydW4gYXQgbWF4X3NwZWVkX2h6LCBhbmQgcmVzdG9yZSBwaHlfcmVhZF9vcC5tYXhfZnJlcQo+ ICsJICogc28gdGhvc2UgcmVhZHMgYWxzbyB1c2UgdGhlIGZ1bGwgc3BlZWQuCj4gKwkgKi8KPiAr CW1lbS0+c3BpLT5iYXNlX3NwZWVkX2h6ID0gMDsKCklmIHRoZXJlIGlzIGEgd2F5IHRvIGF2b2lk IHRvdWNoaW5nIHRoZSBjb3JlIHBhcmFtZXRlcnMsIEkgd291bGQgYmUgZm9yCnVzaW5nIGl0LCBi dXQgbWF5YmUgaXQgaXMgc2ltcGxlciB0byBkbyBpdCB0aGlzIHdheS4KCj4gKwlmX3BkYXRhLT5w aHlfcmVhZF9vcC5tYXhfZnJlcSA9IG1lbS0+c3BpLT5tYXhfc3BlZWRfaHo7Cj4gKwo+ICsJaWYg KHJlYWRfb3AtPmNtZC5kdHIgfHwgcmVhZF9vcC0+YWRkci5kdHIgfHwgcmVhZF9vcC0+ZHVtbXku ZHRyIHx8Cj4gKwkgICAgcmVhZF9vcC0+ZGF0YS5kdHIpIHsKPiArCQlmX3BkYXRhLT51c2VfZHFz ID0gdHJ1ZTsKPiArCQljcXNwaV9waHlfcHJlX2NvbmZpZyhjcXNwaSwgZl9wZGF0YSwgZmFsc2Up Owo+ICsJCXJldCA9IGNxc3BpX3BoeV90dW5pbmdfZGRyKGZfcGRhdGEsIG1lbSk7Cj4gKwl9IGVs c2Ugewo+ICsJCWZfcGRhdGEtPnVzZV9kcXMgPSBmYWxzZTsKPiArCQljcXNwaV9waHlfcHJlX2Nv bmZpZyhjcXNwaSwgZl9wZGF0YSwgdHJ1ZSk7Cj4gKwkJcmV0ID0gY3FzcGlfcGh5X3R1bmluZ19z ZHIoZl9wZGF0YSwgbWVtKTsKPiArCX0KPiArCj4gKwlpZiAocmV0KQo+ICsJCWRldl93YXJuKGRl diwgInR1bmluZyBmYWlsZWQ6ICVkXG4iLCByZXQpOwo+ICsKPiArCWNxc3BpX3BoeV9wb3N0X2Nv bmZpZyhjcXNwaSwgZl9wZGF0YS0+cmVhZF9kZWxheSk7Cj4gKwo+ICtvdXQ6Cj4gKwkvKgo+ICsJ ICogQWx3YXlzIHJlc3RvcmUgdGhlIGNvbnNlcnZhdGl2ZSBiYXNlIHNwZWVkIGNhcC4gIE9uIHN1 Y2Nlc3MsIHdyaXRlCj4gKwkgKiBiYWNrIHRoZSB2YWxpZGF0ZWQgbWF4aW11bSBzcGVlZCBpbnRv IHRoZSBjYWxsZXIncyBvcCB0ZW1wbGF0ZXMgc28KPiArCSAqIHRoYXQgdGhvc2Ugc3BlY2lmaWMg b3BzIGJ5cGFzcyB0aGUgY2FwIGluIHN1YnNlcXVlbnQgZXhlY19vcCBjYWxscy4KPiArCSAqLwo+ ICsJbWVtLT5zcGktPmJhc2Vfc3BlZWRfaHogPSBiYXNlX3NwZWVkOwo+ICsJaWYgKCFyZXQpIHsK PiArCQlyZWFkX29wLT5tYXhfZnJlcSA9IG1lbS0+c3BpLT5tYXhfc3BlZWRfaHo7Cj4gKwkJaWYg KHdyaXRlX29wKQo+ICsJCQl3cml0ZV9vcC0+bWF4X2ZyZXEgPSBtZW0tPnNwaS0+bWF4X3NwZWVk X2h6Owo+ICsJfQoKTmVhdC4KCj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGlj IGludCBjcXNwaV9tZW1fb3BfZXhlY3V0ZV90dW5pbmcoc3RydWN0IHNwaV9tZW0gKm1lbSwKPiAr CQkJCSAgICAgICBzdHJ1Y3Qgc3BpX21lbV9vcCAqcmVhZF9vcCwKPiArCQkJCSAgICAgICBzdHJ1 Y3Qgc3BpX21lbV9vcCAqd3JpdGVfb3ApCj4gK3sKPiArCXN0cnVjdCBjcXNwaV9zdCAqY3FzcGkg PQo+ICsJCXNwaV9jb250cm9sbGVyX2dldF9kZXZkYXRhKG1lbS0+c3BpLT5jb250cm9sbGVyKTsK PiArCj4gKwlpZiAoIWNxc3BpLT5kZGF0YS0+ZXhlY3V0ZV90dW5pbmcpCj4gKwkJcmV0dXJuIC1F T1BOT1RTVVBQOwo+ICsKPiArCXJldHVybiBjcXNwaS0+ZGRhdGEtPmV4ZWN1dGVfdHVuaW5nKG1l bSwgcmVhZF9vcCwgd3JpdGVfb3ApOwo+ICt9Cj4gKwo+ICBzdGF0aWMgaW50IGNxc3BpX29mX2dl dF9mbGFzaF9wZGF0YShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LAo+ICAJCQkJICAgIHN0 cnVjdCBjcXNwaV9mbGFzaF9wZGF0YSAqZl9wZGF0YSwKPiAgCQkJCSAgICBzdHJ1Y3QgZGV2aWNl X25vZGUgKm5wKQo+ICB7Cj4gKwlpbnQgbmZyZXEsIHJldDsKPiArCj4gIAlpZiAob2ZfcHJvcGVy dHlfcmVhZF91MzIobnAsICJjZG5zLHJlYWQtZGVsYXkiLCAmZl9wZGF0YS0+cmVhZF9kZWxheSkp IHsKPiAgCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJjb3VsZG4ndCBkZXRlcm1pbmUgcmVhZC1kZWxh eVxuIik7Cj4gIAkJcmV0dXJuIC1FTlhJTzsKPiBAQCAtMTU4NCw3ICszMzQzLDI2IEBAIHN0YXRp YyBpbnQgY3FzcGlfb2ZfZ2V0X2ZsYXNoX3BkYXRhKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk ZXYsCj4gIAkJcmV0dXJuIC1FTlhJTzsKPiAgCX0KPiAgCj4gLQlpZiAob2ZfcHJvcGVydHlfcmVh ZF91MzIobnAsICJzcGktbWF4LWZyZXF1ZW5jeSIsICZmX3BkYXRhLT5jbGtfcmF0ZSkpIHsKPiAr CS8qCj4gKwkgKiBzcGktbWF4LWZyZXF1ZW5jeSBhY2NlcHRzIG9uZSBvciB0d28gdmFsdWVzOgo+ ICsJICogICA8bWF4LWZyZXE+ICAgICAgICAgICAgIC0gc2luZ2xlIHJhdGU7IG5vIHRpZXJlZCBz cGVlZCBzdXBwb3J0Cj4gKwkgKiAgIDxiYXNlLWZyZXEgbWF4LWZyZXE+ICAgLSBjb25zZXJ2YXRp dmUgZGVmYXVsdCBhbmQgaGlnaGVyIG1heGltdW0KPiArCSAqCj4gKwkgKiBXaXRoIHR3byB2YWx1 ZXMgdGhlIFNQSSBjb3JlIHNldHMgc3BpLT5iYXNlX3NwZWVkX2h6ID0gYmFzZS1mcmVxIGFuZAo+ ICsJICogc3BpLT5tYXhfc3BlZWRfaHogPSBtYXgtZnJlcS4gIFN0b3JlIHRoZSBzZWNvbmQgdmFs dWUgaGVyZSBhcyB0aGUKPiArCSAqIGNvbnRyb2xsZXIncyBoaWdoZXIgcmF0ZSB0YXJnZXQgZm9y IGNhbGlicmF0aW9uLgo+ICsJICovCj4gKwluZnJlcSA9IG9mX3Byb3BlcnR5X2NvdW50X3UzMl9l bGVtcyhucCwgInNwaS1tYXgtZnJlcXVlbmN5Iik7Cj4gKwlpZiAobmZyZXEgPT0gMikgewo+ICsJ CXJldCA9IG9mX3Byb3BlcnR5X3JlYWRfdTMyX2luZGV4KG5wLCAic3BpLW1heC1mcmVxdWVuY3ki LCAxLAo+ICsJCQkJCQkgJmZfcGRhdGEtPm1heF9jbGtfcmF0ZSk7Cj4gKwkJaWYgKHJldCkgewo+ ICsJCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJjb3VsZG4ndCByZWFkIHNwaS1tYXgtZnJlcXVlbmN5 WzFdXG4iKTsKPiArCQkJcmV0dXJuIHJldDsKPiArCQl9Cj4gKwl9IGVsc2UgaWYgKG5mcmVxID09 IDEpIHsKPiArCQlmX3BkYXRhLT5tYXhfY2xrX3JhdGUgPSAwOwo+ICsJfSBlbHNlIHsKPiAgCQlk ZXZfZXJyKCZwZGV2LT5kZXYsICJjb3VsZG4ndCBkZXRlcm1pbmUgc3BpLW1heC1mcmVxdWVuY3lc biIpOwo+ICAJCXJldHVybiAtRU5YSU87Cj4gIAl9CgpXaHkgZG8gd2UgcmVwZWF0IHRoYXQgb3Bl cmF0aW9uIGluIHRoZSBkcml2ZXI/IENhbid0IHdlIGp1c3QgdXNlIHdoYXQKdGhlIGNvcmUgaGFz IGFscmVhZHkgZG9uZSBmb3IgdXM/IFNlZW1zIGxpa2Ugd2UgYXJlIHBhcnNpbmcgdGhlIHNhbWUK ZGF0YSB0d2ljZSAoZXZlbiBiZWZvcmUgdGhpcyBwYXRjaHNldCkuCgpUaGFua3MsCk1pcXXDqGwK Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpM aW51eCBNVEQgZGlzY3Vzc2lvbiBtYWlsaW5nIGxpc3QKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5v cmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1tdGQvCg==