From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 14848463B8E for ; Mon, 31 Aug 2026 15:08:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788188897; cv=none; b=dyiXOzarTsh/+X8GrbFn5ghtaUie2UUMWdaMZhHwcMFbgO8wOZjK9fi+kY/1dwGwxaen8cBdNe7T30xPgcxIwB9fuXH4tWTOLuuwtbkT0mVy0pNw9mAEpedCoqJGgfr5XFFtaoUE13xKXTo7P9y0psoOa+/tZ1of9KYEfyKPvWw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788188897; c=relaxed/simple; bh=rCpC9Dwj5ujiSpDavJucdkRcsyXErHFhB3VN3pLX8BM=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=fKHjl0ITJos8qRqN1BflCoFtmxIDgQlXsZFHfB8M7zJkLwQWqZM6JxmqraVsI5pMurHPwjblfRNIVUG8/cSCUDZNho46t1f9kRe364Z6FPzUuknxF7swmkMbk79ptEVuYJ/ThQDhj6YHOktopOuBSUG9MugQpwFkes47hr7uu/o= 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=LFP762yg; arc=none smtp.client-ip=185.246.85.4 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="LFP762yg" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 38FD74E41437; Mon, 31 Aug 2026 15:08:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0560360231; Mon, 31 Aug 2026 15:08:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 39F8B11C78A75; Mon, 31 Aug 2026 17:08:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1788188885; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=sqiOiFdMJrkbxYSuM3+7ydV7NdUJCu5eq/N9GzPyYT8=; b=LFP762yg7Bf3/oiL2TKSiwe3Tj2/qtPwTa/cB66Cun87afaUb5eqvmWMaVfnpsoiF+Tmo7 zr8ZIHSnZLWy8Tcre/B+NR2KMiCY1RCyRcOvRsrL42l70wu7WhhQTAK7i7XpvfponEx9Iq NDNz9SPoci+JtMGSwpKBEKA/GaHtTxSekTyKvlvfN5WmJo7V7r47r9AuqYY2Q/tYRFSGoX 3FVnB4UcfxYuS2+7Sr+sIk4rBbZRmSElImx1DNri1mbNbeqfZDIKRKTUcZ0UFj3QLNY0gg jZBG6u+xkEChkiOnBKcwHGwJ03KGobNM6WdDAlOYp5nkm/WjCng6Fz2Ah9dzBA== From: Miquel Raynal To: "Michael Walle" Cc: "Pratyush Yadav" , "Takahiro Kuwano" , "Richard Weinberger" , "Vignesh Raghavendra" , "Nicolas Ferre" , "Alexandre Belloni" , "Claudiu Beznea" , "Jonathan Corbet" , "Shuah Khan" , "Steam Lin" , "Hsin-Yi Wang" , "Thomas Petazzoni" , , , , Subject: Re: [PATCH v3 05/23] mtd: spi-nor: Create the concept of fixup table with match function In-Reply-To: (Michael Walle's message of "Fri, 28 Aug 2026 11:43:06 +0200") References: <20260813-winbond-v7-1-spi-nor-rv-addition-v3-0-b637cf120d5c@bootlin.com> <20260813-winbond-v7-1-spi-nor-rv-addition-v3-5-b637cf120d5c@bootlin.com> <87cxv3cy5j.fsf@bootlin.com> User-Agent: mu4e 1.12.12; emacs 30.2 Date: Mon, 31 Aug 2026 17:07:59 +0200 Message-ID: <878q5m9vlc.fsf@bootlin.com> Precedence: bulk X-Mailing-List: linux-doc@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 28/08/2026 at 11:43:06 +02, "Michael Walle" wrote: > Hi, > > On Thu Aug 27, 2026 at 6:43 PM CEST, Miquel Raynal wrote: >> I took me a lot of time to go through all your requests, in the end I >> will not implement most of your feedback because either I do not >> understand what is the gain, or because the result is not better at all >> from my point of view. I try to explain that in my feedback >> below. Nevertheless, I truly appreciate the deep review you made. I >> think I mostly agree with the comments in the other messages. >> >> On 14/08/2026 at 11:40:21 +02, "Michael Walle" wrote: >> >>> On Thu Aug 13, 2026 at 5:19 PM CEST, Miquel Raynal wrote: >>>> Manufacturer ID tables increase and fixup() hooks proliferate. Having >>>> one possible structure per chip was fine until the fixups started being >>>> more and more common and needed, to some extend due to ID reuses. Mixi= ng >>>> fixups and chips becomes hard and requires extra helpers to sort which >>>> ones are needed for a given chip, which every time this happens requir= es >>>> a lot of rework. >>> >>> Thanks, this patch looks really promising! >>> >>>> Replace the two-level fixup association (a manufacturer wide hook and a >>>> per flash_info hook) with a per-manufacturer list of fixups that can be >>>> looked up by flash ID and/or match function. >>>> >>>> The match logic works as follows: >>>> - If there is an ID, it must match >>>> - If there is a match function, it must match (cumulative) >>>> - If there is no identifier (no ID nor any match function), it's a >>>> catch-all entry typically used for flagging manufacturer fixups. > > I think this one is the crux. See more below. > >>> This mimics, how it's currently handled. But since the fixups are >>> now treated as a separate list, i.e. it has it's own SNOR_ID, we >>> shall move away from this manufacturer thingy too. >> >> Why shall we? See below, I don't get the point. I drafted something it >> took me two full days to work on that, to eventually realize I did not >> see *any* benefit. > > Then let me ask the other way around,=20 Mm :) Generally we are asked to justify the changes, not the opposite. Nevertheless, I'll try to play this game ;) > what is the benefit of having the manufacturer? Grouping all chips following similar patterns, using similar helpers, etc. In general the scope of the manufacturer driver is pretty convenient to store static functions only usable inside. Unlike chip names, giving manufacturers a name is also handy and people like to see it, despite its actual use. Sometimes it is also useful to distinguish if you have version A of the HW with chip from manufacturer from version B using chip from manufacturer . > There is now one central place for the fixups. Good. But now there > is that catch-all thing, which is the replacement for the former > manufacturer fixup if I read your code correctly. I think so, but what is the problem with that? I mean, maybe it wasn't so nice to set up in the first place, and we may want to limit the propagation of manufacturer wide fixups. I don't find that catch-all entry useless though. But at this stage we anyway need an equivalent, hence the manufacturer wide catch-all entry. > BUT. We don't have a concept of a 'manufacturer'. We don't match the > manufacturer id. This is very easy to do, maybe I should have done that instead of having a blind manufacturer-wide fixup. At this stage I do not see the difference, but I can easily add the first ID byte to match. > The manufacturer is just set as an additional > information if there is already matching entry for a specific > flash, so we already know the exact part. Before the generic driver, > this might have made sense. The intention was to have a common place > for the default flags for all *known* flashes of a manufacturer > (which probably also was the result of the core rewrite). But now, > we might have flashes we do not know, that is, aren't in the > database. At least I would assume, that the manufacturer fixups are > still applied though. There were already a few different times I > proposed to have fixups for SNOR_ID(vendor_id). > > I mean, even you fell into the trap that you'll have to have that > catch-all/fallback entry in the flash db (can't find the mail > anymore though, so please correct me if I'm wrong). Yes, absolutely. > Also, having the fixups separate from the flash db, we can use the > generic flash driver and still have some fixups for given flashes. Nothing we cannot do with the current approach, no? You will anyway need some kind of identification in order to apply the fixups. I prefer having them in vendor drivers rather than in the core. > If - for example - one would be adding locking support later, > nothing but the new flashdb entry has to be added as the fixups are > still applied. Yes, but that's also possible with the approach carried here (using the Macronix and now Winbond catch all entries). >>> IMHO that really >>> clutters the code. >> >> Clearly an opinion I do not share. Maybe I am missing something. >> >>> As a fun fact, spi_nor_match_id() will have the >>> unexpected side effect of setting nor->manufacturer. >> >> Not sure I get why this is unexpected? > > The signature of the function is: > static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, > const u8 *id) > > Clearly it will return a pointer to the flash_info entry for a given > id. But as a side effect it also sets nor->manufacturer. What if I'd > call that twice with different ids? Maybe it's just me, but it looks > like a pure function but isn't. I probably got burnt by the generic > nor driver which hit that in the first place. Maybe the name can be improved, naming is never easy, but once there is a match, associating a manufacturer name to the device doesn't sound so silly to me :) >>> So here's how I'd do it:=20 >>> (1) remove spi_nor_manufacturer. >>> (2) have a list of initcalls in the core to call into the individual >>> vendor modules (that could later be replaced by something more >>> sophiticated) >>> (3) that initcall will then call spi_nor_register_parts(const struct >>> flash_info *parts, int nparts) >>> (4) (optionally) calls spi_nor_register_fixups(const struct >>> spi_nor_fixup *fixups, int nfixups) >> >> I've been trying hard to follow your approach, but really, I don't get >> the point. Initcalls are not possible here, or it would prevent >> CONIFG_MTD_SPI_NOR=3Dm so I went for an alternative approach with an init >> registration which I believe matches your expectations. This is not >> an actual problem. >> >> But registering parts and fixups independently, maybe, but again, why? >> What is the intended benefit? We now need to go through 96 (spi-nor >> wide) fixups. But what do we get in exchange? > > I don't get that. You already have a (new) winbond_fixups[] for > example. What is the difference between having that set in > spi_nor_manufacturer vs having that in a > > winbond_init() { > spi_nor_register_flash_devices(&winbond_nor_parts); > spi_nor_register_fixups(&winbond_fixups); The difference is that you end up with a big list of parts (like before) and a big list of fixups as well, which are not related to the parts. So when you have a match with a part, for each of the 6 fixup cases, you will check every single fixup entry (96 at this stage) for a match. Before this was limited to a dozen at most. OTOH I do not see any benefit in registering the parts and fixups like that, compared to just exposing the (exported) manufacturer structures.=20 > And probably setting the manufacturer name in winbond_nor_fixups(). Here again: yes that's possible, but for what benefit? > I guess that all falls apart because of the empty match entry. That > could be replaced with the SNOR_ID(winbond_id), though. Then we have > *real* per manufacturer fixups. Ah ok, I believe we agree here, so in the end, do you prefer having a manufacturer wide fixup entry without SNOR_ID? Or do you prefer to always have an ID to match with, and use the manufacturer ID for that? I don't think there is a need for filling an SNOR_ID for this entry since the fixup list is associated to the parts list though. > That is basically what commit afe1ea1344bb ("mtd: spi-nor: add > support for Macronix Octal flash") made. > >> From my point of view: >> extra churn and boilerplate, nothing particularly better than before. I >> must admit, I do not understand your aversion for the manufacturer >> structure. So while I like the idea of a flash-info independent fixup >> list (which I implemented in v3), I do not understand the need for this >> extra step. > > See above. > >> Since I do not get the point of this request, I prefer to not implement >> it, because I will anyway do it the wrong way. If someone wants to make >> a proposal, I will have a look, but at this point I need to back >> off. > > I can do that myself, but I'd like to avoid any code churn. So I > don't know what you've already tried to come up with, but if there > is something which somewhat goes in the right direction of moving the > registration to a function inside of the vendor modules. That would > really be appreciated. Unfortunately after struggling hours with it, I dropped it entirely /o\ I experimented using initcalls, creating those parts/fixup registration helpers, etc. >> There are already ~70 patches pending which I hope will be applied >> ASAP after -rc1 gets tagged and we agree on the remaining points (there >> are other comments from you and Takahiro which I need to address). > > Looks like I need to apply the patches to the tree, too. Honestly, > I've never done that, so I first need to actually see how it's done > and if I even have access to the tree. Thanks. I can help you with that. My setup has been overly simplified since I switched to b4. I will share the the details privately. [...] >>>> --- a/drivers/mtd/spi-nor/gigadevice.c >>>> +++ b/drivers/mtd/spi-nor/gigadevice.c >>>> @@ -64,7 +64,6 @@ static const struct flash_info gigadevice_nor_parts[= ] =3D { >>>> .id =3D SNOR_ID(0xc8, 0x40, 0x19), >>>> .name =3D "gd25q256", >>>> .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6, >>>> - .fixups =3D &gd25q256_fixups, >>>> .fixup_flags =3D SPI_NOR_4B_OPCODES, >>> >>> The fixup_flags should also go into the fixups list. >> >> Yes, we can use a similar logic here. Actually if at some point we want >> to get rid of those flags, we could transform the flags into proper >> fixup functions, but I'm not going to do that now. > > The flags actually serve the purpose of *not* having a huge amount > of different fixup functions. So these should be kept for now. As an > alternative, with the new list it might be possible to have multiple > fixups for the same flash part. In any case, the fixup_flags have to > be removed from the flash_info struct. I've added a patch for that. >> [...] >> >>>> +/* PM25LV parts have no JEDEC ID and are likely matched by name */ >>>> +static bool issi_pm25lv_match(const struct spi_nor *nor) >>>> +{ >>>> + const char *name =3D nor->info ? nor->info->name : NULL; >>>> + >>>> + return name && !strncmp(name, "pm25lv", 6); >>> >>> Won't just strcmp("pm25lv", name) do it? Both arguments are >>> guaranteed to be NUL terminated. The above would also match >>> "pm25lvextrabytes", no, and we get rid of that redundant size >>> argument. >> >> No it won't, because that would no longer be a match, you would compare >> pm25lv against pm25lv010 or pm25lv512 -> no match if you don't limit to >> the first 6 bytes. Since names are part of the sysfs ABI, we cannot just >> modify the names for that. We also need two different entries (two >> different sizes) since we do not even match with an ID. > > Ah I see, you actually *want* that extra bytes, in that case, please > use strstarts(). Yeah, no pb. >> [...] >> >>>> @@ -233,6 +230,17 @@ static int mt25qu512a_post_bfpt_fixup(struct spi_= nor *nor, >>>> return 0; >>>> } >>>>=20=20 >>>> +/* >>>> + * n25q00a parts share the first same 3 ID bytes with mt25qu01g. >>>> + * In order to not mix the fixups, further filter out using the part = name. >>> >>> How would that work? The part name is also set by the duplicated ID, >>> so the first one wins, no? >> >> - First part (mt25qu01g) is checked >> -> ID match >> - There is a match function where we compare the name with n25q00a >> -> no match, not applying the fixup >> >> - Second part (n25q00a) is checked >> -> ID match >> - There is a match function where we compare the name with n25q00a >> -> name match >> >> The fixup is only applied for n25q00a. > > Ah, I now get what you want to try to achieve. Only the first three > bytes (I missed that in the function doc) are shared. So no actual ID > collision. > >> For the other chip we can just give more ID bytes for the match. > > Giving there are more IDs for the n25q00a. > >> So I believe there is no problem here? > > Yes, no problem. But use strncmp() here, because this actually > matches just one particular flash. Ok. > FWIW I don't think this is sustainable, though. It's basically a > workaround for the different matching in spi_nor_match_id() (first > entry wins) and the fixups ID matching (any matching entry is > applied). Though, I can't think of a more generic solution for now. 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 9793BC624A5 for ; Mon, 31 Aug 2026 15:08:22 +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=HFpQlUykmPHvP2KbBJbYKQB32CZiemhBJ1A9Usfrqco=; b=RlgEPDxUZVJ0eX Mq44nXqqqP5YgKyh5VqfYWfz4Xletf+bznxFqyC3mkQm5d96w8cwx0xx8kHdsf6irNl+aExMoPggz TzTXrNcBCfFsSyeqQX60E9fJn53XE2arneR2eCDVXCuyNSWOUJ89LC6nzhe6IrhJbWzWDyIhk1/09 ZaqJlzQj6Lkeu1EbIUraV04n4XzH5Tnqc5sPZaoaa1IY7VlMIMhxkF2UcHP/rr/pc4iiTx7xRd5uv b1P8niJilbWpbiHdAqYRtYx77PfW0XpYYOPSJAt+2JMJM2hJKGxnY4lY9zvkUFHmo8PlYtU8wgf+N 9yDycsYja0P226TdilUw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x13cS-00000009nzO-0tBP; Mon, 31 Aug 2026 15:08:20 +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 1x13cN-00000009nye-3JQa; Mon, 31 Aug 2026 15:08:18 +0000 Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 38FD74E41437; Mon, 31 Aug 2026 15:08:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0560360231; Mon, 31 Aug 2026 15:08:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 39F8B11C78A75; Mon, 31 Aug 2026 17:08:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1788188885; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=sqiOiFdMJrkbxYSuM3+7ydV7NdUJCu5eq/N9GzPyYT8=; b=LFP762yg7Bf3/oiL2TKSiwe3Tj2/qtPwTa/cB66Cun87afaUb5eqvmWMaVfnpsoiF+Tmo7 zr8ZIHSnZLWy8Tcre/B+NR2KMiCY1RCyRcOvRsrL42l70wu7WhhQTAK7i7XpvfponEx9Iq NDNz9SPoci+JtMGSwpKBEKA/GaHtTxSekTyKvlvfN5WmJo7V7r47r9AuqYY2Q/tYRFSGoX 3FVnB4UcfxYuS2+7Sr+sIk4rBbZRmSElImx1DNri1mbNbeqfZDIKRKTUcZ0UFj3QLNY0gg jZBG6u+xkEChkiOnBKcwHGwJ03KGobNM6WdDAlOYp5nkm/WjCng6Fz2Ah9dzBA== From: Miquel Raynal To: "Michael Walle" Cc: "Pratyush Yadav" , "Takahiro Kuwano" , "Richard Weinberger" , "Vignesh Raghavendra" , "Nicolas Ferre" , "Alexandre Belloni" , "Claudiu Beznea" , "Jonathan Corbet" , "Shuah Khan" , "Steam Lin" , "Hsin-Yi Wang" , "Thomas Petazzoni" , , , , Subject: Re: [PATCH v3 05/23] mtd: spi-nor: Create the concept of fixup table with match function In-Reply-To: (Michael Walle's message of "Fri, 28 Aug 2026 11:43:06 +0200") References: <20260813-winbond-v7-1-spi-nor-rv-addition-v3-0-b637cf120d5c@bootlin.com> <20260813-winbond-v7-1-spi-nor-rv-addition-v3-5-b637cf120d5c@bootlin.com> <87cxv3cy5j.fsf@bootlin.com> User-Agent: mu4e 1.12.12; emacs 30.2 Date: Mon, 31 Aug 2026 17:07:59 +0200 Message-ID: <878q5m9vlc.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-20260831_080816_154875_12371497 X-CRM114-Status: GOOD ( 79.29 ) 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 T24gMjgvMDgvMjAyNiBhdCAxMTo0MzowNiArMDIsICJNaWNoYWVsIFdhbGxlIiA8bXdhbGxlQGtl cm5lbC5vcmc+IHdyb3RlOgoKPiBIaSwKPgo+IE9uIFRodSBBdWcgMjcsIDIwMjYgYXQgNjo0MyBQ TSBDRVNULCBNaXF1ZWwgUmF5bmFsIHdyb3RlOgo+PiBJIHRvb2sgbWUgYSBsb3Qgb2YgdGltZSB0 byBnbyB0aHJvdWdoIGFsbCB5b3VyIHJlcXVlc3RzLCBpbiB0aGUgZW5kIEkKPj4gd2lsbCBub3Qg aW1wbGVtZW50IG1vc3Qgb2YgeW91ciBmZWVkYmFjayBiZWNhdXNlIGVpdGhlciBJIGRvIG5vdAo+ PiB1bmRlcnN0YW5kIHdoYXQgaXMgdGhlIGdhaW4sIG9yIGJlY2F1c2UgdGhlIHJlc3VsdCBpcyBu b3QgYmV0dGVyIGF0IGFsbAo+PiBmcm9tIG15IHBvaW50IG9mIHZpZXcuIEkgdHJ5IHRvIGV4cGxh aW4gdGhhdCBpbiBteSBmZWVkYmFjawo+PiBiZWxvdy4gTmV2ZXJ0aGVsZXNzLCBJIHRydWx5IGFw cHJlY2lhdGUgdGhlIGRlZXAgcmV2aWV3IHlvdSBtYWRlLiBJCj4+IHRoaW5rIEkgbW9zdGx5IGFn cmVlIHdpdGggdGhlIGNvbW1lbnRzIGluIHRoZSBvdGhlciBtZXNzYWdlcy4KPj4KPj4gT24gMTQv MDgvMjAyNiBhdCAxMTo0MDoyMSArMDIsICJNaWNoYWVsIFdhbGxlIiA8bXdhbGxlQGtlcm5lbC5v cmc+IHdyb3RlOgo+Pgo+Pj4gT24gVGh1IEF1ZyAxMywgMjAyNiBhdCA1OjE5IFBNIENFU1QsIE1p cXVlbCBSYXluYWwgd3JvdGU6Cj4+Pj4gTWFudWZhY3R1cmVyIElEIHRhYmxlcyBpbmNyZWFzZSBh bmQgZml4dXAoKSBob29rcyBwcm9saWZlcmF0ZS4gSGF2aW5nCj4+Pj4gb25lIHBvc3NpYmxlIHN0 cnVjdHVyZSBwZXIgY2hpcCB3YXMgZmluZSB1bnRpbCB0aGUgZml4dXBzIHN0YXJ0ZWQgYmVpbmcK Pj4+PiBtb3JlIGFuZCBtb3JlIGNvbW1vbiBhbmQgbmVlZGVkLCB0byBzb21lIGV4dGVuZCBkdWUg dG8gSUQgcmV1c2VzLiBNaXhpbmcKPj4+PiBmaXh1cHMgYW5kIGNoaXBzIGJlY29tZXMgaGFyZCBh bmQgcmVxdWlyZXMgZXh0cmEgaGVscGVycyB0byBzb3J0IHdoaWNoCj4+Pj4gb25lcyBhcmUgbmVl ZGVkIGZvciBhIGdpdmVuIGNoaXAsIHdoaWNoIGV2ZXJ5IHRpbWUgdGhpcyBoYXBwZW5zIHJlcXVp cmVzCj4+Pj4gYSBsb3Qgb2YgcmV3b3JrLgo+Pj4KPj4+IFRoYW5rcywgdGhpcyBwYXRjaCBsb29r cyByZWFsbHkgcHJvbWlzaW5nIQo+Pj4KPj4+PiBSZXBsYWNlIHRoZSB0d28tbGV2ZWwgZml4dXAg YXNzb2NpYXRpb24gKGEgbWFudWZhY3R1cmVyIHdpZGUgaG9vayBhbmQgYQo+Pj4+IHBlciBmbGFz aF9pbmZvIGhvb2spIHdpdGggYSBwZXItbWFudWZhY3R1cmVyIGxpc3Qgb2YgZml4dXBzIHRoYXQg Y2FuIGJlCj4+Pj4gbG9va2VkIHVwIGJ5IGZsYXNoIElEIGFuZC9vciBtYXRjaCBmdW5jdGlvbi4K Pj4+Pgo+Pj4+IFRoZSBtYXRjaCBsb2dpYyB3b3JrcyBhcyBmb2xsb3dzOgo+Pj4+IC0gSWYgdGhl cmUgaXMgYW4gSUQsIGl0IG11c3QgbWF0Y2gKPj4+PiAtIElmIHRoZXJlIGlzIGEgbWF0Y2ggZnVu Y3Rpb24sIGl0IG11c3QgbWF0Y2ggKGN1bXVsYXRpdmUpCj4+Pj4gLSBJZiB0aGVyZSBpcyBubyBp ZGVudGlmaWVyIChubyBJRCBub3IgYW55IG1hdGNoIGZ1bmN0aW9uKSwgaXQncyBhCj4+Pj4gICBj YXRjaC1hbGwgZW50cnkgdHlwaWNhbGx5IHVzZWQgZm9yIGZsYWdnaW5nIG1hbnVmYWN0dXJlciBm aXh1cHMuCj4KPiBJIHRoaW5rIHRoaXMgb25lIGlzIHRoZSBjcnV4LiBTZWUgbW9yZSBiZWxvdy4K Pgo+Pj4gVGhpcyBtaW1pY3MsIGhvdyBpdCdzIGN1cnJlbnRseSBoYW5kbGVkLiBCdXQgc2luY2Ug dGhlIGZpeHVwcyBhcmUKPj4+IG5vdyB0cmVhdGVkIGFzIGEgc2VwYXJhdGUgbGlzdCwgaS5lLiBp dCBoYXMgaXQncyBvd24gU05PUl9JRCwgd2UKPj4+IHNoYWxsIG1vdmUgYXdheSBmcm9tIHRoaXMg bWFudWZhY3R1cmVyIHRoaW5neSB0b28uCj4+Cj4+IFdoeSBzaGFsbCB3ZT8gU2VlIGJlbG93LCBJ IGRvbid0IGdldCB0aGUgcG9pbnQuIEkgZHJhZnRlZCBzb21ldGhpbmcgaXQKPj4gdG9vayBtZSB0 d28gZnVsbCBkYXlzIHRvIHdvcmsgb24gdGhhdCwgdG8gZXZlbnR1YWxseSByZWFsaXplIEkgZGlk IG5vdAo+PiBzZWUgKmFueSogYmVuZWZpdC4KPgo+IFRoZW4gbGV0IG1lIGFzayB0aGUgb3RoZXIg d2F5IGFyb3VuZCwgCgpNbSA6KSBHZW5lcmFsbHkgd2UgYXJlIGFza2VkIHRvIGp1c3RpZnkgdGhl IGNoYW5nZXMsIG5vdCB0aGUKb3Bwb3NpdGUuIE5ldmVydGhlbGVzcywgSSdsbCB0cnkgdG8gcGxh eSB0aGlzIGdhbWUgOykKCj4gd2hhdCBpcyB0aGUgYmVuZWZpdCBvZiBoYXZpbmcgdGhlIG1hbnVm YWN0dXJlcj8KCkdyb3VwaW5nIGFsbCBjaGlwcyBmb2xsb3dpbmcgc2ltaWxhciBwYXR0ZXJucywg dXNpbmcgc2ltaWxhciBoZWxwZXJzLApldGMuIEluIGdlbmVyYWwgdGhlIHNjb3BlIG9mIHRoZSBt YW51ZmFjdHVyZXIgZHJpdmVyIGlzIHByZXR0eQpjb252ZW5pZW50IHRvIHN0b3JlIHN0YXRpYyBm dW5jdGlvbnMgb25seSB1c2FibGUgaW5zaWRlLiBVbmxpa2UgY2hpcApuYW1lcywgZ2l2aW5nIG1h bnVmYWN0dXJlcnMgYSBuYW1lIGlzIGFsc28gaGFuZHkgYW5kIHBlb3BsZSBsaWtlIHRvIHNlZQpp dCwgZGVzcGl0ZSBpdHMgYWN0dWFsIHVzZS4gU29tZXRpbWVzIGl0IGlzIGFsc28gdXNlZnVsIHRv IGRpc3Rpbmd1aXNoCmlmIHlvdSBoYXZlIHZlcnNpb24gQSBvZiB0aGUgSFcgd2l0aCBjaGlwIGZy b20gbWFudWZhY3R1cmVyIDxmb28+IGZyb20KdmVyc2lvbiBCIHVzaW5nIGNoaXAgZnJvbSBtYW51 ZmFjdHVyZXIgPGJhcj4uCgo+IFRoZXJlIGlzIG5vdyBvbmUgY2VudHJhbCBwbGFjZSBmb3IgdGhl IGZpeHVwcy4gR29vZC4gQnV0IG5vdyB0aGVyZQo+IGlzIHRoYXQgY2F0Y2gtYWxsIHRoaW5nLCB3 aGljaCBpcyB0aGUgcmVwbGFjZW1lbnQgZm9yIHRoZSBmb3JtZXIKPiBtYW51ZmFjdHVyZXIgZml4 dXAgaWYgSSByZWFkIHlvdXIgY29kZSBjb3JyZWN0bHkuCgpJIHRoaW5rIHNvLCBidXQgd2hhdCBp cyB0aGUgcHJvYmxlbSB3aXRoIHRoYXQ/IEkgbWVhbiwgbWF5YmUgaXQgd2Fzbid0CnNvIG5pY2Ug dG8gc2V0IHVwIGluIHRoZSBmaXJzdCBwbGFjZSwgYW5kIHdlIG1heSB3YW50IHRvIGxpbWl0IHRo ZQpwcm9wYWdhdGlvbiBvZiBtYW51ZmFjdHVyZXIgd2lkZSBmaXh1cHMuIEkgZG9uJ3QgZmluZCB0 aGF0IGNhdGNoLWFsbAplbnRyeSB1c2VsZXNzIHRob3VnaC4gQnV0IGF0IHRoaXMgc3RhZ2Ugd2Ug YW55d2F5IG5lZWQgYW4gZXF1aXZhbGVudCwKaGVuY2UgdGhlIG1hbnVmYWN0dXJlciB3aWRlIGNh dGNoLWFsbCBlbnRyeS4KCj4gQlVULiBXZSBkb24ndCBoYXZlIGEgY29uY2VwdCBvZiBhICdtYW51 ZmFjdHVyZXInLiBXZSBkb24ndCBtYXRjaCB0aGUKPiBtYW51ZmFjdHVyZXIgaWQuCgpUaGlzIGlz IHZlcnkgZWFzeSB0byBkbywgbWF5YmUgSSBzaG91bGQgaGF2ZSBkb25lIHRoYXQgaW5zdGVhZCBv ZiBoYXZpbmcKYSBibGluZCBtYW51ZmFjdHVyZXItd2lkZSBmaXh1cC4gQXQgdGhpcyBzdGFnZSBJ IGRvIG5vdCBzZWUgdGhlCmRpZmZlcmVuY2UsIGJ1dCBJIGNhbiBlYXNpbHkgYWRkIHRoZSBmaXJz dCBJRCBieXRlIHRvIG1hdGNoLgoKPiBUaGUgbWFudWZhY3R1cmVyIGlzIGp1c3Qgc2V0IGFzIGFu IGFkZGl0aW9uYWwKPiBpbmZvcm1hdGlvbiBpZiB0aGVyZSBpcyBhbHJlYWR5ICBtYXRjaGluZyBl bnRyeSBmb3IgYSBzcGVjaWZpYwo+IGZsYXNoLCBzbyB3ZSBhbHJlYWR5IGtub3cgdGhlIGV4YWN0 IHBhcnQuIEJlZm9yZSB0aGUgZ2VuZXJpYyBkcml2ZXIsCj4gdGhpcyBtaWdodCBoYXZlIG1hZGUg c2Vuc2UuIFRoZSBpbnRlbnRpb24gd2FzIHRvIGhhdmUgYSBjb21tb24gcGxhY2UKPiBmb3IgdGhl IGRlZmF1bHQgZmxhZ3MgZm9yIGFsbCAqa25vd24qIGZsYXNoZXMgb2YgYSBtYW51ZmFjdHVyZXIK PiAod2hpY2ggcHJvYmFibHkgYWxzbyB3YXMgdGhlIHJlc3VsdCBvZiB0aGUgY29yZSByZXdyaXRl KS4gQnV0IG5vdywKPiB3ZSBtaWdodCBoYXZlIGZsYXNoZXMgd2UgZG8gbm90IGtub3csIHRoYXQg aXMsIGFyZW4ndCBpbiB0aGUKPiBkYXRhYmFzZS4gQXQgbGVhc3QgSSB3b3VsZCBhc3N1bWUsIHRo YXQgdGhlIG1hbnVmYWN0dXJlciBmaXh1cHMgYXJlCj4gc3RpbGwgYXBwbGllZCB0aG91Z2guIFRo ZXJlIHdlcmUgYWxyZWFkeSBhIGZldyBkaWZmZXJlbnQgdGltZXMgSQo+IHByb3Bvc2VkIHRvIGhh dmUgZml4dXBzIGZvciBTTk9SX0lEKHZlbmRvcl9pZCkuCj4KPiBJIG1lYW4sIGV2ZW4geW91IGZl bGwgaW50byB0aGUgdHJhcCB0aGF0IHlvdSdsbCBoYXZlIHRvIGhhdmUgdGhhdAo+IGNhdGNoLWFs bC9mYWxsYmFjayBlbnRyeSBpbiB0aGUgZmxhc2ggZGIgKGNhbid0IGZpbmQgdGhlIG1haWwKPiBh bnltb3JlIHRob3VnaCwgc28gcGxlYXNlIGNvcnJlY3QgbWUgaWYgSSdtIHdyb25nKS4KClllcywg YWJzb2x1dGVseS4KCj4gQWxzbywgaGF2aW5nIHRoZSBmaXh1cHMgc2VwYXJhdGUgZnJvbSB0aGUg Zmxhc2ggZGIsIHdlIGNhbiB1c2UgdGhlCj4gZ2VuZXJpYyBmbGFzaCBkcml2ZXIgYW5kIHN0aWxs IGhhdmUgc29tZSBmaXh1cHMgZm9yIGdpdmVuIGZsYXNoZXMuCgpOb3RoaW5nIHdlIGNhbm5vdCBk byB3aXRoIHRoZSBjdXJyZW50IGFwcHJvYWNoLCBubz8gWW91IHdpbGwgYW55d2F5IG5lZWQKc29t ZSBraW5kIG9mIGlkZW50aWZpY2F0aW9uIGluIG9yZGVyIHRvIGFwcGx5IHRoZSBmaXh1cHMuIEkg cHJlZmVyCmhhdmluZyB0aGVtIGluIHZlbmRvciBkcml2ZXJzIHJhdGhlciB0aGFuIGluIHRoZSBj b3JlLgoKPiBJZiAtIGZvciBleGFtcGxlIC0gb25lIHdvdWxkIGJlIGFkZGluZyBsb2NraW5nIHN1 cHBvcnQgbGF0ZXIsCj4gbm90aGluZyBidXQgdGhlIG5ldyBmbGFzaGRiIGVudHJ5IGhhcyB0byBi ZSBhZGRlZCBhcyB0aGUgZml4dXBzIGFyZQo+IHN0aWxsIGFwcGxpZWQuCgpZZXMsIGJ1dCB0aGF0 J3MgYWxzbyBwb3NzaWJsZSB3aXRoIHRoZSBhcHByb2FjaCBjYXJyaWVkIGhlcmUgKHVzaW5nIHRo ZQpNYWNyb25peCBhbmQgbm93IFdpbmJvbmQgY2F0Y2ggYWxsIGVudHJpZXMpLgoKPj4+IElNSE8g dGhhdCByZWFsbHkKPj4+IGNsdXR0ZXJzIHRoZSBjb2RlLgo+Pgo+PiBDbGVhcmx5IGFuIG9waW5p b24gSSBkbyBub3Qgc2hhcmUuIE1heWJlIEkgYW0gbWlzc2luZyBzb21ldGhpbmcuCj4+Cj4+PiBB cyBhIGZ1biBmYWN0LCBzcGlfbm9yX21hdGNoX2lkKCkgd2lsbCBoYXZlIHRoZQo+Pj4gdW5leHBl Y3RlZCBzaWRlIGVmZmVjdCBvZiBzZXR0aW5nIG5vci0+bWFudWZhY3R1cmVyLgo+Pgo+PiBOb3Qg c3VyZSBJIGdldCB3aHkgdGhpcyBpcyB1bmV4cGVjdGVkPwo+Cj4gVGhlIHNpZ25hdHVyZSBvZiB0 aGUgZnVuY3Rpb24gaXM6Cj4gc3RhdGljIGNvbnN0IHN0cnVjdCBmbGFzaF9pbmZvICpzcGlfbm9y X21hdGNoX2lkKHN0cnVjdCBzcGlfbm9yICpub3IsCj4gCQkJCQkJIGNvbnN0IHU4ICppZCkKPgo+ IENsZWFybHkgaXQgd2lsbCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBmbGFzaF9pbmZvIGVudHJ5 IGZvciBhIGdpdmVuCj4gaWQuIEJ1dCBhcyBhIHNpZGUgZWZmZWN0IGl0IGFsc28gc2V0cyBub3It Pm1hbnVmYWN0dXJlci4gV2hhdCBpZiBJJ2QKPiBjYWxsIHRoYXQgdHdpY2Ugd2l0aCBkaWZmZXJl bnQgaWRzPyBNYXliZSBpdCdzIGp1c3QgbWUsIGJ1dCBpdCBsb29rcwo+IGxpa2UgYSBwdXJlIGZ1 bmN0aW9uIGJ1dCBpc24ndC4gSSBwcm9iYWJseSBnb3QgYnVybnQgYnkgdGhlIGdlbmVyaWMKPiBu b3IgZHJpdmVyIHdoaWNoIGhpdCB0aGF0IGluIHRoZSBmaXJzdCBwbGFjZS4KCk1heWJlIHRoZSBu YW1lIGNhbiBiZSBpbXByb3ZlZCwgbmFtaW5nIGlzIG5ldmVyIGVhc3ksIGJ1dCBvbmNlIHRoZXJl IGlzCmEgbWF0Y2gsIGFzc29jaWF0aW5nIGEgbWFudWZhY3R1cmVyIG5hbWUgdG8gdGhlIGRldmlj ZSBkb2Vzbid0IHNvdW5kIHNvCnNpbGx5IHRvIG1lIDopCgo+Pj4gU28gaGVyZSdzIGhvdyBJJ2Qg ZG8gaXQ6IAo+Pj4gKDEpIHJlbW92ZSBzcGlfbm9yX21hbnVmYWN0dXJlci4KPj4+ICgyKSBoYXZl IGEgbGlzdCBvZiBpbml0Y2FsbHMgaW4gdGhlIGNvcmUgdG8gY2FsbCBpbnRvIHRoZSBpbmRpdmlk dWFsCj4+PiAgICAgdmVuZG9yIG1vZHVsZXMgKHRoYXQgY291bGQgbGF0ZXIgYmUgcmVwbGFjZWQg Ynkgc29tZXRoaW5nIG1vcmUKPj4+ICAgICBzb3BoaXRpY2F0ZWQpCj4+PiAoMykgdGhhdCBpbml0 Y2FsbCB3aWxsIHRoZW4gY2FsbCBzcGlfbm9yX3JlZ2lzdGVyX3BhcnRzKGNvbnN0IHN0cnVjdAo+ Pj4gICAgIGZsYXNoX2luZm8gKnBhcnRzLCBpbnQgbnBhcnRzKQo+Pj4gKDQpIChvcHRpb25hbGx5 KSBjYWxscyBzcGlfbm9yX3JlZ2lzdGVyX2ZpeHVwcyhjb25zdCBzdHJ1Y3QKPj4+ICAgICBzcGlf bm9yX2ZpeHVwICpmaXh1cHMsIGludCBuZml4dXBzKQo+Pgo+PiBJJ3ZlIGJlZW4gdHJ5aW5nIGhh cmQgdG8gZm9sbG93IHlvdXIgYXBwcm9hY2gsIGJ1dCByZWFsbHksIEkgZG9uJ3QgZ2V0Cj4+IHRo ZSBwb2ludC4gSW5pdGNhbGxzIGFyZSBub3QgcG9zc2libGUgaGVyZSwgb3IgaXQgd291bGQgcHJl dmVudAo+PiBDT05JRkdfTVREX1NQSV9OT1I9bSBzbyBJIHdlbnQgZm9yIGFuIGFsdGVybmF0aXZl IGFwcHJvYWNoIHdpdGggYW4gaW5pdAo+PiByZWdpc3RyYXRpb24gd2hpY2ggSSBiZWxpZXZlIG1h dGNoZXMgeW91ciBleHBlY3RhdGlvbnMuIFRoaXMgaXMgbm90Cj4+IGFuIGFjdHVhbCBwcm9ibGVt Lgo+Pgo+PiBCdXQgcmVnaXN0ZXJpbmcgcGFydHMgYW5kIGZpeHVwcyBpbmRlcGVuZGVudGx5LCBt YXliZSwgYnV0IGFnYWluLCB3aHk/Cj4+IFdoYXQgaXMgdGhlIGludGVuZGVkIGJlbmVmaXQ/IFdl IG5vdyBuZWVkIHRvIGdvIHRocm91Z2ggOTYgKHNwaS1ub3IKPj4gd2lkZSkgZml4dXBzLiBCdXQg d2hhdCBkbyB3ZSBnZXQgaW4gZXhjaGFuZ2U/Cj4KPiBJIGRvbid0IGdldCB0aGF0LiBZb3UgYWxy ZWFkeSBoYXZlIGEgKG5ldykgd2luYm9uZF9maXh1cHNbXSBmb3IKPiBleGFtcGxlLiBXaGF0IGlz IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gaGF2aW5nIHRoYXQgc2V0IGluCj4gc3BpX25vcl9tYW51 ZmFjdHVyZXIgdnMgaGF2aW5nIHRoYXQgaW4gYQo+Cj4gd2luYm9uZF9pbml0KCkgewo+IAlzcGlf bm9yX3JlZ2lzdGVyX2ZsYXNoX2RldmljZXMoJndpbmJvbmRfbm9yX3BhcnRzKTsKPiAJc3BpX25v cl9yZWdpc3Rlcl9maXh1cHMoJndpbmJvbmRfZml4dXBzKTsKClRoZSBkaWZmZXJlbmNlIGlzIHRo YXQgeW91IGVuZCB1cCB3aXRoIGEgYmlnIGxpc3Qgb2YgcGFydHMgKGxpa2UgYmVmb3JlKQphbmQg YSBiaWcgbGlzdCBvZiBmaXh1cHMgYXMgd2VsbCwgd2hpY2ggYXJlIG5vdCByZWxhdGVkIHRvIHRo ZSBwYXJ0cy4gU28Kd2hlbiB5b3UgaGF2ZSBhIG1hdGNoIHdpdGggYSBwYXJ0LCBmb3IgZWFjaCBv ZiB0aGUgNiBmaXh1cCBjYXNlcywgeW91CndpbGwgY2hlY2sgZXZlcnkgc2luZ2xlIGZpeHVwIGVu dHJ5ICg5NiBhdCB0aGlzIHN0YWdlKSBmb3IgYQptYXRjaC4gQmVmb3JlIHRoaXMgd2FzIGxpbWl0 ZWQgdG8gYSBkb3plbiBhdCBtb3N0LiBPVE9IIEkgZG8gbm90IHNlZSBhbnkKYmVuZWZpdCBpbiBy ZWdpc3RlcmluZyB0aGUgcGFydHMgYW5kIGZpeHVwcyBsaWtlIHRoYXQsIGNvbXBhcmVkIHRvIGp1 c3QKZXhwb3NpbmcgdGhlIChleHBvcnRlZCkgbWFudWZhY3R1cmVyIHN0cnVjdHVyZXMuIAoKPiBB bmQgcHJvYmFibHkgc2V0dGluZyB0aGUgbWFudWZhY3R1cmVyIG5hbWUgaW4gd2luYm9uZF9ub3Jf Zml4dXBzKCkuCgpIZXJlIGFnYWluOiB5ZXMgdGhhdCdzIHBvc3NpYmxlLCBidXQgZm9yIHdoYXQg YmVuZWZpdD8KCj4gSSBndWVzcyB0aGF0IGFsbCBmYWxscyBhcGFydCBiZWNhdXNlIG9mIHRoZSBl bXB0eSBtYXRjaCBlbnRyeS4gVGhhdAo+IGNvdWxkIGJlIHJlcGxhY2VkIHdpdGggdGhlIFNOT1Jf SUQod2luYm9uZF9pZCksIHRob3VnaC4gVGhlbiB3ZSBoYXZlCj4gKnJlYWwqIHBlciBtYW51ZmFj dHVyZXIgZml4dXBzLgoKQWggb2ssIEkgYmVsaWV2ZSB3ZSBhZ3JlZSBoZXJlLCBzbyBpbiB0aGUg ZW5kLCBkbyB5b3UgcHJlZmVyIGhhdmluZyBhCm1hbnVmYWN0dXJlciB3aWRlIGZpeHVwIGVudHJ5 IHdpdGhvdXQgU05PUl9JRD8gT3IgZG8geW91IHByZWZlciB0bwphbHdheXMgaGF2ZSBhbiBJRCB0 byBtYXRjaCB3aXRoLCBhbmQgdXNlIHRoZSBtYW51ZmFjdHVyZXIgSUQgZm9yIHRoYXQ/IEkKZG9u J3QgdGhpbmsgdGhlcmUgaXMgYSBuZWVkIGZvciBmaWxsaW5nIGFuIFNOT1JfSUQgZm9yIHRoaXMg ZW50cnkgc2luY2UKdGhlIGZpeHVwIGxpc3QgaXMgYXNzb2NpYXRlZCB0byB0aGUgcGFydHMgbGlz dCB0aG91Z2guCgo+IFRoYXQgaXMgYmFzaWNhbGx5IHdoYXQgY29tbWl0IGFmZTFlYTEzNDRiYiAo Im10ZDogc3BpLW5vcjogYWRkCj4gc3VwcG9ydCBmb3IgTWFjcm9uaXggT2N0YWwgZmxhc2giKSBt YWRlLgo+Cj4+IEZyb20gbXkgcG9pbnQgb2YgdmlldzoKPj4gZXh0cmEgY2h1cm4gYW5kIGJvaWxl cnBsYXRlLCBub3RoaW5nIHBhcnRpY3VsYXJseSBiZXR0ZXIgdGhhbiBiZWZvcmUuIEkKPj4gbXVz dCBhZG1pdCwgSSBkbyBub3QgdW5kZXJzdGFuZCB5b3VyIGF2ZXJzaW9uIGZvciB0aGUgbWFudWZh Y3R1cmVyCj4+IHN0cnVjdHVyZS4gU28gd2hpbGUgSSBsaWtlIHRoZSBpZGVhIG9mIGEgZmxhc2gt aW5mbyBpbmRlcGVuZGVudCBmaXh1cAo+PiBsaXN0ICh3aGljaCBJIGltcGxlbWVudGVkIGluIHYz KSwgSSBkbyBub3QgdW5kZXJzdGFuZCB0aGUgbmVlZCBmb3IgdGhpcwo+PiBleHRyYSBzdGVwLgo+ Cj4gU2VlIGFib3ZlLgo+Cj4+IFNpbmNlIEkgZG8gbm90IGdldCB0aGUgcG9pbnQgb2YgdGhpcyBy ZXF1ZXN0LCBJIHByZWZlciB0byBub3QgaW1wbGVtZW50Cj4+IGl0LCBiZWNhdXNlIEkgd2lsbCBh bnl3YXkgZG8gaXQgdGhlIHdyb25nIHdheS4gSWYgc29tZW9uZSB3YW50cyB0byBtYWtlCj4+IGEg cHJvcG9zYWwsIEkgd2lsbCBoYXZlIGEgbG9vaywgYnV0IGF0IHRoaXMgcG9pbnQgSSBuZWVkIHRv IGJhY2sKPj4gb2ZmLgo+Cj4gSSBjYW4gZG8gdGhhdCBteXNlbGYsIGJ1dCBJJ2QgbGlrZSB0byBh dm9pZCBhbnkgY29kZSBjaHVybi4gU28gSQo+IGRvbid0IGtub3cgd2hhdCB5b3UndmUgYWxyZWFk eSB0cmllZCB0byBjb21lIHVwIHdpdGgsIGJ1dCBpZiB0aGVyZQo+IGlzIHNvbWV0aGluZyB3aGlj aCBzb21ld2hhdCBnb2VzIGluIHRoZSByaWdodCBkaXJlY3Rpb24gb2YgbW92aW5nIHRoZQo+IHJl Z2lzdHJhdGlvbiB0byBhIGZ1bmN0aW9uIGluc2lkZSBvZiB0aGUgdmVuZG9yIG1vZHVsZXMuIFRo YXQgd291bGQKPiByZWFsbHkgYmUgYXBwcmVjaWF0ZWQuCgpVbmZvcnR1bmF0ZWx5IGFmdGVyIHN0 cnVnZ2xpbmcgaG91cnMgd2l0aCBpdCwgSSBkcm9wcGVkIGl0IGVudGlyZWx5IC9vXApJIGV4cGVy aW1lbnRlZCB1c2luZyBpbml0Y2FsbHMsIGNyZWF0aW5nIHRob3NlIHBhcnRzL2ZpeHVwIHJlZ2lz dHJhdGlvbgpoZWxwZXJzLCBldGMuCgo+PiBUaGVyZSBhcmUgYWxyZWFkeSB+NzAgcGF0Y2hlcyBw ZW5kaW5nIHdoaWNoIEkgaG9wZSB3aWxsIGJlIGFwcGxpZWQKPj4gQVNBUCBhZnRlciAtcmMxIGdl dHMgdGFnZ2VkIGFuZCB3ZSBhZ3JlZSBvbiB0aGUgcmVtYWluaW5nIHBvaW50cyAodGhlcmUKPj4g YXJlIG90aGVyIGNvbW1lbnRzIGZyb20geW91IGFuZCBUYWthaGlybyB3aGljaCBJIG5lZWQgdG8g YWRkcmVzcykuCj4KPiBMb29rcyBsaWtlIEkgbmVlZCB0byBhcHBseSB0aGUgcGF0Y2hlcyB0byB0 aGUgdHJlZSwgdG9vLiBIb25lc3RseSwKPiBJJ3ZlIG5ldmVyIGRvbmUgdGhhdCwgc28gSSBmaXJz dCBuZWVkIHRvIGFjdHVhbGx5IHNlZSBob3cgaXQncyBkb25lCj4gYW5kIGlmIEkgZXZlbiBoYXZl IGFjY2VzcyB0byB0aGUgdHJlZS4KClRoYW5rcy4gSSBjYW4gaGVscCB5b3Ugd2l0aCB0aGF0LiBN eSBzZXR1cCBoYXMgYmVlbiBvdmVybHkgc2ltcGxpZmllZApzaW5jZSBJIHN3aXRjaGVkIHRvIGI0 LiBJIHdpbGwgc2hhcmUgdGhlIHRoZSBkZXRhaWxzIHByaXZhdGVseS4KClsuLi5dCgo+Pj4+IC0t LSBhL2RyaXZlcnMvbXRkL3NwaS1ub3IvZ2lnYWRldmljZS5jCj4+Pj4gKysrIGIvZHJpdmVycy9t dGQvc3BpLW5vci9naWdhZGV2aWNlLmMKPj4+PiBAQCAtNjQsNyArNjQsNiBAQCBzdGF0aWMgY29u c3Qgc3RydWN0IGZsYXNoX2luZm8gZ2lnYWRldmljZV9ub3JfcGFydHNbXSA9IHsKPj4+PiAgCQku aWQgPSBTTk9SX0lEKDB4YzgsIDB4NDAsIDB4MTkpLAo+Pj4+ICAJCS5uYW1lID0gImdkMjVxMjU2 IiwKPj4+PiAgCQkuZmxhZ3MgPSBTUElfTk9SX0hBU19MT0NLIHwgU1BJX05PUl9IQVNfVEIgfCBT UElfTk9SX1RCX1NSX0JJVDYsCj4+Pj4gLQkJLmZpeHVwcyA9ICZnZDI1cTI1Nl9maXh1cHMsCj4+ Pj4gIAkJLmZpeHVwX2ZsYWdzID0gU1BJX05PUl80Ql9PUENPREVTLAo+Pj4KPj4+IFRoZSBmaXh1 cF9mbGFncyBzaG91bGQgYWxzbyBnbyBpbnRvIHRoZSBmaXh1cHMgbGlzdC4KPj4KPj4gWWVzLCB3 ZSBjYW4gdXNlIGEgc2ltaWxhciBsb2dpYyBoZXJlLiBBY3R1YWxseSBpZiBhdCBzb21lIHBvaW50 IHdlIHdhbnQKPj4gdG8gZ2V0IHJpZCBvZiB0aG9zZSBmbGFncywgd2UgY291bGQgdHJhbnNmb3Jt IHRoZSBmbGFncyBpbnRvIHByb3Blcgo+PiBmaXh1cCBmdW5jdGlvbnMsIGJ1dCBJJ20gbm90IGdv aW5nIHRvIGRvIHRoYXQgbm93Lgo+Cj4gVGhlIGZsYWdzIGFjdHVhbGx5IHNlcnZlIHRoZSBwdXJw b3NlIG9mICpub3QqIGhhdmluZyBhIGh1Z2UgYW1vdW50Cj4gb2YgZGlmZmVyZW50IGZpeHVwIGZ1 bmN0aW9ucy4gU28gdGhlc2Ugc2hvdWxkIGJlIGtlcHQgZm9yIG5vdy4gQXMgYW4KPiBhbHRlcm5h dGl2ZSwgd2l0aCB0aGUgbmV3IGxpc3QgaXQgbWlnaHQgYmUgcG9zc2libGUgdG8gaGF2ZSBtdWx0 aXBsZQo+IGZpeHVwcyBmb3IgdGhlIHNhbWUgZmxhc2ggcGFydC4gSW4gYW55IGNhc2UsIHRoZSBm aXh1cF9mbGFncyBoYXZlIHRvCj4gYmUgcmVtb3ZlZCBmcm9tIHRoZSBmbGFzaF9pbmZvIHN0cnVj dC4KCkkndmUgYWRkZWQgYSBwYXRjaCBmb3IgdGhhdC4KCj4+IFsuLi5dCj4+Cj4+Pj4gKy8qIFBN MjVMViBwYXJ0cyBoYXZlIG5vIEpFREVDIElEIGFuZCBhcmUgbGlrZWx5IG1hdGNoZWQgYnkgbmFt ZSAqLwo+Pj4+ICtzdGF0aWMgYm9vbCBpc3NpX3BtMjVsdl9tYXRjaChjb25zdCBzdHJ1Y3Qgc3Bp X25vciAqbm9yKQo+Pj4+ICt7Cj4+Pj4gKwljb25zdCBjaGFyICpuYW1lID0gbm9yLT5pbmZvID8g bm9yLT5pbmZvLT5uYW1lIDogTlVMTDsKPj4+PiArCj4+Pj4gKwlyZXR1cm4gbmFtZSAmJiAhc3Ry bmNtcChuYW1lLCAicG0yNWx2IiwgNik7Cj4+Pgo+Pj4gV29uJ3QganVzdCBzdHJjbXAoInBtMjVs diIsIG5hbWUpIGRvIGl0PyBCb3RoIGFyZ3VtZW50cyBhcmUKPj4+IGd1YXJhbnRlZWQgdG8gYmUg TlVMIHRlcm1pbmF0ZWQuIFRoZSBhYm92ZSB3b3VsZCBhbHNvIG1hdGNoCj4+PiAicG0yNWx2ZXh0 cmFieXRlcyIsIG5vLCBhbmQgd2UgZ2V0IHJpZCBvZiB0aGF0IHJlZHVuZGFudCBzaXplCj4+PiBh cmd1bWVudC4KPj4KPj4gTm8gaXQgd29uJ3QsIGJlY2F1c2UgdGhhdCB3b3VsZCBubyBsb25nZXIg YmUgYSBtYXRjaCwgeW91IHdvdWxkIGNvbXBhcmUKPj4gcG0yNWx2IGFnYWluc3QgcG0yNWx2MDEw IG9yIHBtMjVsdjUxMiAtPiBubyBtYXRjaCBpZiB5b3UgZG9uJ3QgbGltaXQgdG8KPj4gdGhlIGZp cnN0IDYgYnl0ZXMuIFNpbmNlIG5hbWVzIGFyZSBwYXJ0IG9mIHRoZSBzeXNmcyBBQkksIHdlIGNh bm5vdCBqdXN0Cj4+IG1vZGlmeSB0aGUgbmFtZXMgZm9yIHRoYXQuIFdlIGFsc28gbmVlZCB0d28g ZGlmZmVyZW50IGVudHJpZXMgKHR3bwo+PiBkaWZmZXJlbnQgc2l6ZXMpIHNpbmNlIHdlIGRvIG5v dCBldmVuIG1hdGNoIHdpdGggYW4gSUQuCj4KPiBBaCBJIHNlZSwgeW91IGFjdHVhbGx5ICp3YW50 KiB0aGF0IGV4dHJhIGJ5dGVzLCBpbiB0aGF0IGNhc2UsIHBsZWFzZQo+IHVzZSBzdHJzdGFydHMo KS4KClllYWgsIG5vIHBiLgoKPj4gWy4uLl0KPj4KPj4+PiBAQCAtMjMzLDYgKzIzMCwxNyBAQCBz dGF0aWMgaW50IG10MjVxdTUxMmFfcG9zdF9iZnB0X2ZpeHVwKHN0cnVjdCBzcGlfbm9yICpub3Is Cj4+Pj4gIAlyZXR1cm4gMDsKPj4+PiAgfQo+Pj4+ICAKPj4+PiArLyoKPj4+PiArICogbjI1cTAw YSBwYXJ0cyBzaGFyZSB0aGUgZmlyc3Qgc2FtZSAzIElEIGJ5dGVzIHdpdGggbXQyNXF1MDFnLgo+ Pj4+ICsgKiBJbiBvcmRlciB0byBub3QgbWl4IHRoZSBmaXh1cHMsIGZ1cnRoZXIgZmlsdGVyIG91 dCB1c2luZyB0aGUgcGFydCBuYW1lLgo+Pj4KPj4+IEhvdyB3b3VsZCB0aGF0IHdvcms/IFRoZSBw YXJ0IG5hbWUgaXMgYWxzbyBzZXQgYnkgdGhlIGR1cGxpY2F0ZWQgSUQsCj4+PiBzbyB0aGUgZmly c3Qgb25lIHdpbnMsIG5vPwo+Pgo+PiAtIEZpcnN0IHBhcnQgKG10MjVxdTAxZykgaXMgY2hlY2tl ZAo+PiAgIC0+IElEIG1hdGNoCj4+IC0gVGhlcmUgaXMgYSBtYXRjaCBmdW5jdGlvbiB3aGVyZSB3 ZSBjb21wYXJlIHRoZSBuYW1lIHdpdGggbjI1cTAwYQo+PiAgIC0+IG5vIG1hdGNoLCBub3QgYXBw bHlpbmcgdGhlIGZpeHVwCj4+Cj4+IC0gU2Vjb25kIHBhcnQgKG4yNXEwMGEpIGlzIGNoZWNrZWQK Pj4gICAtPiBJRCBtYXRjaAo+PiAtIFRoZXJlIGlzIGEgbWF0Y2ggZnVuY3Rpb24gd2hlcmUgd2Ug Y29tcGFyZSB0aGUgbmFtZSB3aXRoIG4yNXEwMGEKPj4gICAtPiBuYW1lIG1hdGNoCj4+Cj4+IFRo ZSBmaXh1cCBpcyBvbmx5IGFwcGxpZWQgZm9yIG4yNXEwMGEuCj4KPiBBaCwgSSBub3cgZ2V0IHdo YXQgeW91IHdhbnQgdG8gdHJ5IHRvIGFjaGlldmUuIE9ubHkgdGhlIGZpcnN0IHRocmVlCj4gYnl0 ZXMgKEkgbWlzc2VkIHRoYXQgaW4gdGhlIGZ1bmN0aW9uIGRvYykgYXJlIHNoYXJlZC4gU28gbm8g YWN0dWFsIElECj4gY29sbGlzaW9uLgo+Cj4+IEZvciB0aGUgb3RoZXIgY2hpcCB3ZSBjYW4ganVz dCBnaXZlIG1vcmUgSUQgYnl0ZXMgZm9yIHRoZSBtYXRjaC4KPgo+IEdpdmluZyB0aGVyZSBhcmUg bW9yZSBJRHMgZm9yIHRoZSBuMjVxMDBhLgo+Cj4+IFNvIEkgYmVsaWV2ZSB0aGVyZSBpcyBubyBw cm9ibGVtIGhlcmU/Cj4KPiBZZXMsIG5vIHByb2JsZW0uIEJ1dCB1c2Ugc3RybmNtcCgpIGhlcmUs IGJlY2F1c2UgdGhpcyBhY3R1YWxseQo+IG1hdGNoZXMganVzdCBvbmUgcGFydGljdWxhciBmbGFz aC4KCk9rLgoKPiBGV0lXIEkgZG9uJ3QgdGhpbmsgdGhpcyBpcyBzdXN0YWluYWJsZSwgdGhvdWdo LiBJdCdzIGJhc2ljYWxseSBhCj4gd29ya2Fyb3VuZCBmb3IgdGhlIGRpZmZlcmVudCBtYXRjaGlu ZyBpbiBzcGlfbm9yX21hdGNoX2lkKCkgKGZpcnN0Cj4gZW50cnkgd2lucykgYW5kIHRoZSBmaXh1 cHMgSUQgbWF0Y2hpbmcgKGFueSBtYXRjaGluZyBlbnRyeSBpcwo+IGFwcGxpZWQpLiBUaG91Z2gs IEkgY2FuJ3QgdGhpbmsgb2YgYSBtb3JlIGdlbmVyaWMgc29sdXRpb24gZm9yIG5vdy4KClRoYW5r cywKTWlxdcOobAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fCkxpbnV4IE1URCBkaXNjdXNzaW9uIG1haWxpbmcgbGlzdApodHRwOi8vbGlzdHMu aW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LW10ZC8K