From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.5 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,USER_AGENT_MUTT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27718C43381 for ; Wed, 6 Mar 2019 11:34:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E092320675 for ; Wed, 6 Mar 2019 11:34:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728057AbfCFLed (ORCPT ); Wed, 6 Mar 2019 06:34:33 -0500 Received: from mga05.intel.com ([192.55.52.43]:13832 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728779AbfCFLed (ORCPT ); Wed, 6 Mar 2019 06:34:33 -0500 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Mar 2019 03:34:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,447,1544515200"; d="scan'208";a="152521773" Received: from kuha.fi.intel.com ([10.237.72.189]) by fmsmga001.fm.intel.com with SMTP; 06 Mar 2019 03:34:29 -0800 Received: by kuha.fi.intel.com (sSMTP sendmail emulation); Wed, 06 Mar 2019 13:34:28 +0200 Date: Wed, 6 Mar 2019 13:34:28 +0200 From: Heikki Krogerus To: Biju Das Cc: Greg Kroah-Hartman , Felipe Balbi , linux-usb@vger.kernel.org, Simon Horman , Yoshihiro Shimoda , Geert Uytterhoeven , Chris Paterson , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: Re: [PATCH 3/9] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller Message-ID: <20190306113428.GA28103@kuha.fi.intel.com> References: <1551863246-11656-1-git-send-email-biju.das@bp.renesas.com> <1551863246-11656-4-git-send-email-biju.das@bp.renesas.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1551863246-11656-4-git-send-email-biju.das@bp.renesas.com> User-Agent: Mutt/1.11.3 (2019-02-01) Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Hi Biju, On Wed, Mar 06, 2019 at 09:07:20AM +0000, Biju Das wrote: > Driver for TI HD3SS3220 USB Type-C DRP port controller. > > The driver currently registers the port and supports data role swapping. > > Signed-off-by: Biju Das > --- > drivers/usb/typec/Kconfig | 10 ++ > drivers/usb/typec/Makefile | 1 + > drivers/usb/typec/hd3ss3220.c | 284 ++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 295 insertions(+) > create mode 100644 drivers/usb/typec/hd3ss3220.c > > diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig > index 30a847c..91696d2 100644 > --- a/drivers/usb/typec/Kconfig > +++ b/drivers/usb/typec/Kconfig > @@ -49,6 +49,16 @@ source "drivers/usb/typec/tcpm/Kconfig" > > source "drivers/usb/typec/ucsi/Kconfig" > > +config TYPEC_HD3SS3220 > + tristate "TI HD3SS3220 Type-C DRP Port controller driver" > + depends on I2C > + help > + Say Y or M here if your system has TI HD3SS3220 Type-C DRP Port > + controller driver. > + > + If you choose to build this driver as a dynamically linked module, the > + module will be called hd3ss3220.ko. > + > config TYPEC_TPS6598X > tristate "TI TPS6598x USB Power Delivery controller driver" > depends on I2C > diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile > index 6696b72..7753a5c3 100644 > --- a/drivers/usb/typec/Makefile > +++ b/drivers/usb/typec/Makefile > @@ -4,5 +4,6 @@ typec-y := class.o mux.o bus.o > obj-$(CONFIG_TYPEC) += altmodes/ > obj-$(CONFIG_TYPEC_TCPM) += tcpm/ > obj-$(CONFIG_TYPEC_UCSI) += ucsi/ > +obj-$(CONFIG_TYPEC_HD3SS3220) += hd3ss3220.o > obj-$(CONFIG_TYPEC_TPS6598X) += tps6598x.o > obj-$(CONFIG_TYPEC) += mux/ > diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c > new file mode 100644 > index 0000000..bd3e1ec > --- /dev/null > +++ b/drivers/usb/typec/hd3ss3220.c > @@ -0,0 +1,284 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * TI HD3SS3220 Type-C DRP Port Controller Driver > + * > + * Copyright (C) 2019 Renesas Electronics Corp. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define HD3SS3220_REG_CN_STAT_CTRL 0x09 > +#define HD3SS3220_REG_GEN_CTRL 0x0A > +#define HD3SS3220_REG_DEV_REV 0xA0 > + > +/* Register HD3SS3220_REG_CN_STAT_CTRL*/ > +#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6)) > +#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6) > +#define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7) > +#define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | BIT(6)) > +#define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4) > + > +/* Register HD3SS3220_REG_GEN_CTRL*/ > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1)) > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00 > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1) > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1)) > + > +struct hd3ss3220 { > + struct device *dev; > + struct regmap *regmap; > + struct extcon_dev *extcon; > + struct typec_port *port; > + struct typec_capability typec_cap; > +}; > + > +static const unsigned int hd3ss3220_cable[] = { > + EXTCON_USB, > + EXTCON_USB_HOST, > + EXTCON_NONE > +}; You need to use the USB role class instead of extcon. Check drivers/usb/roles/class/ and include/linux/usb/role.h You may also want to check the updates Yu Chen is introducing to that class: https://lkml.org/lkml/2019/3/2/42 > +static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int src_pref) > +{ > + unsigned int reg_val; > + int ret; > + > + ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, ®_val); > + if (ret < 0) > + return ret; > + > + reg_val &= ~HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK; > + reg_val |= src_pref; > + > + return regmap_write(hd3ss3220->regmap, > + HD3SS3220_REG_GEN_CTRL, reg_val); Please fix the alignment: return regmap_write(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, reg_val); > +} > + > +static int hd3ss3220_attached_state_detect(struct hd3ss3220 *hd3ss3220) > +{ > + unsigned int reg_val; > + int ret, attached_state; > + > + ret = regmap_read(hd3ss3220->regmap, > + HD3SS3220_REG_CN_STAT_CTRL, ®_val); ditto: ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, ®_val); > + if (ret < 0) > + return ret; > + > + reg_val &= HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK; > + switch (reg_val) { switch (reg_val & HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK) > + case HD3SS3220_REG_CN_STAT_CTRL_AS_DFP: > + attached_state = EXTCON_USB_HOST; > + break; > + case HD3SS3220_REG_CN_STAT_CTRL_AS_UFP: > + attached_state = EXTCON_USB; > + break; > + default: > + attached_state = EXTCON_NONE; > + } > + > + return attached_state; > +} > + > +static int hd3ss3220_dr_set(const struct typec_capability *cap, > + enum typec_data_role role) > +{ > + struct hd3ss3220 *hd3ss3220 = > + container_of(cap, struct hd3ss3220, typec_cap); I think scripts/checkpatch.pl would find all these alignment issues: struct hd3ss3220 *hd3ss3220 = container_of(cap, struct hd3ss3220, typec_cap); There are a lot more of those in this patch. Please fix all of them. > + int ret = 0; > + > + if (role == TYPEC_HOST) { > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB, false); > + ret = hd3ss3220_set_source_pref(hd3ss3220, > + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC); > + mdelay(100); Whoa! That's a long delay. A bit too long. You should sleep if you really need to wait that long, but 100 ms? > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB_HOST, true); > + } else { > + extcon_set_state_sync(hd3ss3220->extcon, > + EXTCON_USB_HOST, false); > + ret = hd3ss3220_set_source_pref(hd3ss3220, > + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK); > + mdelay(100); > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB, true); > + } I think you could just call hd3ss3220_set_source_pref() ones here. Just store the value to a variable in those conditions: if (role == TYPEC_HOST) pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC; else pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK; ret = hd3ss3220_set_source_pref(hd3ss3220, pref); ... > + typec_set_data_role(hd3ss3220->port, role); > + > + return ret; > +} > + > +static void hd3ss3220_set_extcon_state(struct hd3ss3220 *hd3ss3220) > +{ > + int attached_state = hd3ss3220_attached_state_detect(hd3ss3220); > + > + if (attached_state == EXTCON_USB_HOST) { > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB, false); > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB_HOST, true); > + typec_set_data_role(hd3ss3220->port, TYPEC_HOST); > + } else if (attached_state == EXTCON_USB) { > + extcon_set_state_sync(hd3ss3220->extcon, > + EXTCON_USB_HOST, false); > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB, true); > + typec_set_data_role(hd3ss3220->port, TYPEC_DEVICE); > + } else { > + hd3ss3220_set_source_pref(hd3ss3220, > + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT); > + extcon_set_state_sync(hd3ss3220->extcon, > + EXTCON_USB_HOST, false); > + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB, false); > + } > +} > + > +irqreturn_t hd3ss3220_irq(struct hd3ss3220 *hd3ss3220) > +{ > + int err; > + unsigned int data; > + > + hd3ss3220_set_extcon_state(hd3ss3220); > + > + err = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, &data); > + if (err < 0) > + return IRQ_NONE; > + > + err = regmap_write(hd3ss3220->regmap, > + HD3SS3220_REG_CN_STAT_CTRL, > + data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS); > + if (err < 0) > + return IRQ_NONE; > + > + return IRQ_HANDLED; > +} > + > +static irqreturn_t hd3ss3220_irq_handler(int irq, void *data) > +{ > + struct i2c_client *client = to_i2c_client(data); > + struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client); > + > + return hd3ss3220_irq(hd3ss3220); > +} > + > +static int hd3ss3220_probe(struct i2c_client *client, > + const struct i2c_device_id *id) > +{ > + struct hd3ss3220 *hd3ss3220; > + int ret; > + unsigned int data; > + static const struct regmap_config config = { > + .reg_bits = 8, > + .val_bits = 8, > + .max_register = 0x0A, > + }; Move that outside of the function. > + hd3ss3220 = devm_kzalloc(&client->dev, sizeof(struct hd3ss3220), > + GFP_KERNEL); > + if (!hd3ss3220) > + return -ENOMEM; > + > + i2c_set_clientdata(client, hd3ss3220); > + > + hd3ss3220->regmap = devm_regmap_init_i2c(client, &config); > + if (IS_ERR(hd3ss3220->regmap)) > + return PTR_ERR(hd3ss3220->regmap); > + > + hd3ss3220_set_source_pref(hd3ss3220, > + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT); > + > + hd3ss3220->extcon = devm_extcon_dev_allocate(&client->dev, > + hd3ss3220_cable); > + if (IS_ERR(hd3ss3220->extcon)) { > + dev_err(&client->dev, "failed to allocate extcon device\n"); > + return PTR_ERR(hd3ss3220->extcon); > + } > + > + ret = devm_extcon_dev_register(&client->dev, hd3ss3220->extcon); > + if (ret < 0) { > + dev_err(&client->dev, "failed to register extcon device\n"); > + return ret; > + } > + > + hd3ss3220->dev = &client->dev; > + hd3ss3220->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE; > + hd3ss3220->typec_cap.dr_set = hd3ss3220_dr_set; > + hd3ss3220->typec_cap.type = TYPEC_PORT_DRP; > + hd3ss3220->typec_cap.data = TYPEC_PORT_DRD; > + > + hd3ss3220->port = typec_register_port(&client->dev, > + &hd3ss3220->typec_cap); > + if (IS_ERR(hd3ss3220->port)) > + return PTR_ERR(hd3ss3220->port); > + > + hd3ss3220_set_extcon_state(hd3ss3220); > + if (client->irq > 0) { > + ret = regmap_read(hd3ss3220->regmap, > + HD3SS3220_REG_CN_STAT_CTRL, &data); > + if (ret < 0) > + goto error; > + > + if (data & HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS) { > + ret = regmap_write(hd3ss3220->regmap, > + HD3SS3220_REG_CN_STAT_CTRL, > + data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS); > + if (ret < 0) > + goto error; > + } > + > + ret = devm_request_threaded_irq(&client->dev, client->irq, > + NULL, hd3ss3220_irq_handler, > + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, > + "hd3ss3220", &client->dev); > + if (ret) > + goto error; > + } > + > + ret = i2c_smbus_read_byte_data(client, HD3SS3220_REG_DEV_REV); > + if (ret < 0) > + goto error; > + > + dev_info(&client->dev, "probed revision=0x%x\n", ret); > + > + return 0; > +error: > + typec_unregister_port(hd3ss3220->port); > + > + return ret; > +} > + > +static int hd3ss3220_remove(struct i2c_client *client) > +{ > + struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client); > + > + typec_unregister_port(hd3ss3220->port); > + > + return 0; > +} > + > +static const struct of_device_id dev_ids[] = { > + { .compatible = "ti,hd3ss3220"}, > + {} > +}; > +MODULE_DEVICE_TABLE(of, dev_ids); > + > +static struct i2c_driver hd3ss3220_driver = { > + .driver = { > + .name = "hd3ss3220", > + .owner = THIS_MODULE, > + .of_match_table = of_match_ptr(dev_ids), > + }, > + .probe = hd3ss3220_probe, > + .remove = hd3ss3220_remove, > +}; > + > +module_i2c_driver(hd3ss3220_driver); > + > +MODULE_AUTHOR("Biju Das "); > +MODULE_DESCRIPTION("TI HD3SS3220 DRP Port Controller Driver"); > +MODULE_LICENSE("GPL"); You will need to use the USB role class instead of extcon. Otherwise this looks OK to me, assuming you fix the style issues ;-). thanks, -- heikki From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [3/9] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller From: Heikki Krogerus Message-Id: <20190306113428.GA28103@kuha.fi.intel.com> Date: Wed, 6 Mar 2019 13:34:28 +0200 To: Biju Das Cc: Greg Kroah-Hartman , Felipe Balbi , linux-usb@vger.kernel.org, Simon Horman , Yoshihiro Shimoda , Geert Uytterhoeven , Chris Paterson , Fabrizio Castro , linux-renesas-soc@vger.kernel.org List-ID: SGkgQmlqdSwKCk9uIFdlZCwgTWFyIDA2LCAyMDE5IGF0IDA5OjA3OjIwQU0gKzAwMDAsIEJpanUg RGFzIHdyb3RlOgo+IERyaXZlciBmb3IgVEkgSEQzU1MzMjIwIFVTQiBUeXBlLUMgRFJQIHBvcnQg Y29udHJvbGxlci4KPiAKPiBUaGUgZHJpdmVyIGN1cnJlbnRseSByZWdpc3RlcnMgdGhlIHBvcnQg YW5kIHN1cHBvcnRzIGRhdGEgcm9sZSBzd2FwcGluZy4KPiAKPiBTaWduZWQtb2ZmLWJ5OiBCaWp1 IERhcyA8YmlqdS5kYXNAYnAucmVuZXNhcy5jb20+Cj4gLS0tCj4gIGRyaXZlcnMvdXNiL3R5cGVj L0tjb25maWcgICAgIHwgIDEwICsrCj4gIGRyaXZlcnMvdXNiL3R5cGVjL01ha2VmaWxlICAgIHwg ICAxICsKPiAgZHJpdmVycy91c2IvdHlwZWMvaGQzc3MzMjIwLmMgfCAyODQgKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gIDMgZmlsZXMgY2hhbmdlZCwgMjk1IGlu c2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL3R5cGVjL2hkM3Nz MzIyMC5jCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3R5cGVjL0tjb25maWcgYi9kcml2 ZXJzL3VzYi90eXBlYy9LY29uZmlnCj4gaW5kZXggMzBhODQ3Yy4uOTE2OTZkMiAxMDA2NDQKPiAt LS0gYS9kcml2ZXJzL3VzYi90eXBlYy9LY29uZmlnCj4gKysrIGIvZHJpdmVycy91c2IvdHlwZWMv S2NvbmZpZwo+IEBAIC00OSw2ICs0OSwxNiBAQCBzb3VyY2UgImRyaXZlcnMvdXNiL3R5cGVjL3Rj cG0vS2NvbmZpZyIKPiAgCj4gIHNvdXJjZSAiZHJpdmVycy91c2IvdHlwZWMvdWNzaS9LY29uZmln Igo+ICAKPiArY29uZmlnIFRZUEVDX0hEM1NTMzIyMAo+ICsJdHJpc3RhdGUgIlRJIEhEM1NTMzIy MCBUeXBlLUMgRFJQIFBvcnQgY29udHJvbGxlciBkcml2ZXIiCj4gKwlkZXBlbmRzIG9uIEkyQwo+ ICsJaGVscAo+ICsJICBTYXkgWSBvciBNIGhlcmUgaWYgeW91ciBzeXN0ZW0gaGFzIFRJIEhEM1NT MzIyMCBUeXBlLUMgRFJQIFBvcnQKPiArCSAgY29udHJvbGxlciBkcml2ZXIuCj4gKwo+ICsJICBJ ZiB5b3UgY2hvb3NlIHRvIGJ1aWxkIHRoaXMgZHJpdmVyIGFzIGEgZHluYW1pY2FsbHkgbGlua2Vk IG1vZHVsZSwgdGhlCj4gKwkgIG1vZHVsZSB3aWxsIGJlIGNhbGxlZCBoZDNzczMyMjAua28uCj4g Kwo+ICBjb25maWcgVFlQRUNfVFBTNjU5OFgKPiAgCXRyaXN0YXRlICJUSSBUUFM2NTk4eCBVU0Ig UG93ZXIgRGVsaXZlcnkgY29udHJvbGxlciBkcml2ZXIiCj4gIAlkZXBlbmRzIG9uIEkyQwo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZSBiL2RyaXZlcnMvdXNiL3R5cGVj L01ha2VmaWxlCj4gaW5kZXggNjY5NmI3Mi4uNzc1M2E1YzMgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVy cy91c2IvdHlwZWMvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZQo+ IEBAIC00LDUgKzQsNiBAQCB0eXBlYy15CQkJCTo9IGNsYXNzLm8gbXV4Lm8gYnVzLm8KPiAgb2Jq LSQoQ09ORklHX1RZUEVDKQkJKz0gYWx0bW9kZXMvCj4gIG9iai0kKENPTkZJR19UWVBFQ19UQ1BN KQkrPSB0Y3BtLwo+ICBvYmotJChDT05GSUdfVFlQRUNfVUNTSSkJKz0gdWNzaS8KPiArb2JqLSQo Q09ORklHX1RZUEVDX0hEM1NTMzIyMCkJKz0gaGQzc3MzMjIwLm8KPiAgb2JqLSQoQ09ORklHX1RZ UEVDX1RQUzY1OThYKQkrPSB0cHM2NTk4eC5vCj4gIG9iai0kKENPTkZJR19UWVBFQykJCSs9IG11 eC8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvaGQzc3MzMjIwLmMgYi9kcml2ZXJz L3VzYi90eXBlYy9oZDNzczMyMjAuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAw MDAwMC4uYmQzZTFlYwo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9o ZDNzczMyMjAuYwo+IEBAIC0wLDAgKzEsMjg0IEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wKwo+ICsvKgo+ICsgKiBUSSBIRDNTUzMyMjAgVHlwZS1DIERSUCBQb3J0IENv bnRyb2xsZXIgRHJpdmVyCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAxOSBSZW5lc2FzIEVs ZWN0cm9uaWNzIENvcnAuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9leHRjb24tcHJvdmlk ZXIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2lycXJldHVybi5oPgo+ICsjaW5jbHVkZSA8bGludXgv aW50ZXJydXB0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1ZGUgPGxp bnV4L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L3NsYWIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3VzYi90eXBlYy5oPgo+ICsjaW5jbHVkZSA8bGlu dXgvZGVsYXkuaD4KPiArCj4gKyNkZWZpbmUgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NUUkwJMHgw OQo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfR0VOX0NUUkwJCTB4MEEKPiArI2RlZmluZSBIRDNT UzMyMjBfUkVHX0RFVl9SRVYJCTB4QTAKPiArCj4gKy8qIFJlZ2lzdGVyIEhEM1NTMzIyMF9SRUdf Q05fU1RBVF9DVFJMKi8KPiArI2RlZmluZSBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTF9BVFRB Q0hFRF9TVEFURV9NQVNLCShCSVQoNykgfCBCSVQoNikpCj4gKyNkZWZpbmUgSEQzU1MzMjIwX1JF R19DTl9TVEFUX0NUUkxfQVNfREZQCQlCSVQoNikKPiArI2RlZmluZSBIRDNTUzMyMjBfUkVHX0NO X1NUQVRfQ1RSTF9BU19VRlAJCUJJVCg3KQo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfQ05fU1RB VF9DVFJMX1RPX0FDQ0VTU09SWQkJKEJJVCg3KSB8IEJJVCg2KSkKPiArI2RlZmluZSBIRDNTUzMy MjBfUkVHX0NOX1NUQVRfQ1RSTF9JTlRfU1RBVFVTCQlCSVQoNCkKPiArCj4gKy8qIFJlZ2lzdGVy IEhEM1NTMzIyMF9SRUdfR0VOX0NUUkwqLwo+ICsjZGVmaW5lIEhEM1NTMzIyMF9SRUdfR0VOX0NU UkxfU1JDX1BSRUZfTUFTSwkJKEJJVCgyKSB8IEJJVCgxKSkKPiArI2RlZmluZSBIRDNTUzMyMjBf UkVHX0dFTl9DVFJMX1NSQ19QUkVGX0RSUF9ERUZBVUxUCTB4MDAKPiArI2RlZmluZSBIRDNTUzMy MjBfUkVHX0dFTl9DVFJMX1NSQ19QUkVGX0RSUF9UUllfU05LCUJJVCgxKQo+ICsjZGVmaW5lIEhE M1NTMzIyMF9SRUdfR0VOX0NUUkxfU1JDX1BSRUZfRFJQX1RSWV9TUkMJKEJJVCgyKSB8IEJJVCgx KSkKPiArCj4gK3N0cnVjdCBoZDNzczMyMjAgewo+ICsJc3RydWN0IGRldmljZSAqZGV2Owo+ICsJ c3RydWN0IHJlZ21hcCAqcmVnbWFwOwo+ICsJc3RydWN0IGV4dGNvbl9kZXYgKmV4dGNvbjsKPiAr CXN0cnVjdCB0eXBlY19wb3J0ICpwb3J0Owo+ICsJc3RydWN0IHR5cGVjX2NhcGFiaWxpdHkgdHlw ZWNfY2FwOwo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBoZDNzczMyMjBf Y2FibGVbXSA9IHsKPiArCUVYVENPTl9VU0IsCj4gKwlFWFRDT05fVVNCX0hPU1QsCj4gKwlFWFRD T05fTk9ORQo+ICt9OwoKWW91IG5lZWQgdG8gdXNlIHRoZSBVU0Igcm9sZSBjbGFzcyBpbnN0ZWFk IG9mIGV4dGNvbi4gQ2hlY2sKZHJpdmVycy91c2Ivcm9sZXMvY2xhc3MvIGFuZCBpbmNsdWRlL2xp bnV4L3VzYi9yb2xlLmgKCllvdSBtYXkgYWxzbyB3YW50IHRvIGNoZWNrIHRoZSB1cGRhdGVzIFl1 IENoZW4gaXMgaW50cm9kdWNpbmcgdG8gdGhhdApjbGFzczoKaHR0cHM6Ly9sa21sLm9yZy9sa21s LzIwMTkvMy8yLzQyCgo+ICtzdGF0aWMgaW50IGhkM3NzMzIyMF9zZXRfc291cmNlX3ByZWYoc3Ry dWN0IGhkM3NzMzIyMCAqaGQzc3MzMjIwLCBpbnQgc3JjX3ByZWYpCj4gK3sKPiArCXVuc2lnbmVk IGludCByZWdfdmFsOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZChoZDNz czMyMjAtPnJlZ21hcCwgSEQzU1MzMjIwX1JFR19HRU5fQ1RSTCwgJnJlZ192YWwpOwo+ICsJaWYg KHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlyZWdfdmFsICY9IH5IRDNTUzMyMjBf UkVHX0dFTl9DVFJMX1NSQ19QUkVGX01BU0s7Cj4gKwlyZWdfdmFsIHw9IHNyY19wcmVmOwo+ICsK PiArCXJldHVybiByZWdtYXBfd3JpdGUoaGQzc3MzMjIwLT5yZWdtYXAsCj4gKwkJCQkJSEQzU1Mz MjIwX1JFR19HRU5fQ1RSTCwgcmVnX3ZhbCk7CgpQbGVhc2UgZml4IHRoZSBhbGlnbm1lbnQ6Cgog ICAgICAgIHJldHVybiByZWdtYXBfd3JpdGUoaGQzc3MzMjIwLT5yZWdtYXAsIEhEM1NTMzIyMF9S RUdfR0VOX0NUUkwsIHJlZ192YWwpOwoKPiArfQo+ICsKPiArc3RhdGljIGludCBoZDNzczMyMjBf YXR0YWNoZWRfc3RhdGVfZGV0ZWN0KHN0cnVjdCBoZDNzczMyMjAgKmhkM3NzMzIyMCkKPiArewo+ ICsJdW5zaWduZWQgaW50IHJlZ192YWw7Cj4gKwlpbnQgcmV0LCBhdHRhY2hlZF9zdGF0ZTsKPiAr Cj4gKwlyZXQgPSByZWdtYXBfcmVhZChoZDNzczMyMjAtPnJlZ21hcCwKPiArCQkJCUhEM1NTMzIy MF9SRUdfQ05fU1RBVF9DVFJMLCAmcmVnX3ZhbCk7CgpkaXR0bzoKCglyZXQgPSByZWdtYXBfcmVh ZChoZDNzczMyMjAtPnJlZ21hcCwgSEQzU1MzMjIwX1JFR19DTl9TVEFUX0NUUkwsCiAgICAgICAg ICAgICAgICAgICAgICAgICAgJnJlZ192YWwpOwoKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVy biByZXQ7Cj4gKwo+ICsJcmVnX3ZhbCAmPSBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTF9BVFRB Q0hFRF9TVEFURV9NQVNLOwo+ICsJc3dpdGNoIChyZWdfdmFsKSB7CgogICAgICAgIHN3aXRjaCAo cmVnX3ZhbCAmIEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJMX0FUVEFDSEVEX1NUQVRFX01BU0sp Cgo+ICsJY2FzZSBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTF9BU19ERlA6Cj4gKwkJYXR0YWNo ZWRfc3RhdGUgPSBFWFRDT05fVVNCX0hPU1Q7Cj4gKwlicmVhazsKPiArCWNhc2UgSEQzU1MzMjIw X1JFR19DTl9TVEFUX0NUUkxfQVNfVUZQOgo+ICsJCWF0dGFjaGVkX3N0YXRlID0gRVhUQ09OX1VT QjsKPiArCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlhdHRhY2hlZF9zdGF0ZSA9IEVYVENPTl9O T05FOwo+ICsJfQo+ICsKPiArCXJldHVybiBhdHRhY2hlZF9zdGF0ZTsKPiArfQo+ICsKPiArc3Rh dGljIGludCBoZDNzczMyMjBfZHJfc2V0KGNvbnN0IHN0cnVjdCB0eXBlY19jYXBhYmlsaXR5ICpj YXAsCj4gKwkJCQkJZW51bSB0eXBlY19kYXRhX3JvbGUgcm9sZSkKPiArewo+ICsJc3RydWN0IGhk M3NzMzIyMCAqaGQzc3MzMjIwID0KPiArCQkJCWNvbnRhaW5lcl9vZihjYXAsIHN0cnVjdCBoZDNz czMyMjAsIHR5cGVjX2NhcCk7CgpJIHRoaW5rIHNjcmlwdHMvY2hlY2twYXRjaC5wbCB3b3VsZCBm aW5kIGFsbCB0aGVzZSBhbGlnbm1lbnQgaXNzdWVzOgoKCXN0cnVjdCBoZDNzczMyMjAgKmhkM3Nz MzIyMCA9IGNvbnRhaW5lcl9vZihjYXAsIHN0cnVjdCBoZDNzczMyMjAsCiAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVjX2NhcCk7CgpUaGVyZSBh cmUgYSBsb3QgbW9yZSBvZiB0aG9zZSBpbiB0aGlzIHBhdGNoLiBQbGVhc2UgZml4IGFsbCBvZiB0 aGVtLgoKPiArCWludCByZXQgPSAwOwo+ICsKPiArCWlmIChyb2xlID09IFRZUEVDX0hPU1QpIHsK PiArCQlleHRjb25fc2V0X3N0YXRlX3N5bmMoaGQzc3MzMjIwLT5leHRjb24sIEVYVENPTl9VU0Is IGZhbHNlKTsKPiArCQlyZXQgPSBoZDNzczMyMjBfc2V0X3NvdXJjZV9wcmVmKGhkM3NzMzIyMCwK PiArCQkJCUhEM1NTMzIyMF9SRUdfR0VOX0NUUkxfU1JDX1BSRUZfRFJQX1RSWV9TUkMpOwo+ICsJ CW1kZWxheSgxMDApOwoKV2hvYSEgVGhhdCdzIGEgbG9uZyBkZWxheS4gQSBiaXQgdG9vIGxvbmcu IFlvdSBzaG91bGQgc2xlZXAgaWYgeW91CnJlYWxseSBuZWVkIHRvIHdhaXQgdGhhdCBsb25nLCBi dXQgMTAwIG1zPwoKPiArCQlleHRjb25fc2V0X3N0YXRlX3N5bmMoaGQzc3MzMjIwLT5leHRjb24s IEVYVENPTl9VU0JfSE9TVCwgdHJ1ZSk7Cj4gKwl9IGVsc2Ugewo+ICsJCWV4dGNvbl9zZXRfc3Rh dGVfc3luYyhoZDNzczMyMjAtPmV4dGNvbiwKPiArCQkJCQkJRVhUQ09OX1VTQl9IT1NULCBmYWxz ZSk7Cj4gKwkJcmV0ID0gaGQzc3MzMjIwX3NldF9zb3VyY2VfcHJlZihoZDNzczMyMjAsCj4gKwkJ CQlIRDNTUzMyMjBfUkVHX0dFTl9DVFJMX1NSQ19QUkVGX0RSUF9UUllfU05LKTsKPiArCQltZGVs YXkoMTAwKTsKPiArCQlleHRjb25fc2V0X3N0YXRlX3N5bmMoaGQzc3MzMjIwLT5leHRjb24sIEVY VENPTl9VU0IsIHRydWUpOwo+ICsJfQoKSSB0aGluayB5b3UgY291bGQganVzdCBjYWxsIGhkM3Nz MzIyMF9zZXRfc291cmNlX3ByZWYoKSBvbmVzIGhlcmUuCkp1c3Qgc3RvcmUgdGhlIHZhbHVlIHRv IGEgdmFyaWFibGUgaW4gdGhvc2UgY29uZGl0aW9uczoKCiAgICAgICAgaWYgKHJvbGUgPT0gVFlQ RUNfSE9TVCkKICAgICAgICAgICAgICAgIHByZWYgPSBIRDNTUzMyMjBfUkVHX0dFTl9DVFJMX1NS Q19QUkVGX0RSUF9UUllfU1JDOwogICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHByZWYgPSBI RDNTUzMyMjBfUkVHX0dFTl9DVFJMX1NSQ19QUkVGX0RSUF9UUllfU05LOwoKICAgICAgICByZXQg PSBoZDNzczMyMjBfc2V0X3NvdXJjZV9wcmVmKGhkM3NzMzIyMCwgcHJlZik7CiAgICAgICAgLi4u Cgo+ICsJdHlwZWNfc2V0X2RhdGFfcm9sZShoZDNzczMyMjAtPnBvcnQsIHJvbGUpOwo+ICsKPiAr CXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGhkM3NzMzIyMF9zZXRfZXh0Y29u X3N0YXRlKHN0cnVjdCBoZDNzczMyMjAgKmhkM3NzMzIyMCkKPiArewo+ICsJaW50IGF0dGFjaGVk X3N0YXRlID0gaGQzc3MzMjIwX2F0dGFjaGVkX3N0YXRlX2RldGVjdChoZDNzczMyMjApOwo+ICsK PiArCWlmIChhdHRhY2hlZF9zdGF0ZSA9PSBFWFRDT05fVVNCX0hPU1QpIHsKPiArCQlleHRjb25f c2V0X3N0YXRlX3N5bmMoaGQzc3MzMjIwLT5leHRjb24sIEVYVENPTl9VU0IsIGZhbHNlKTsKPiAr CQlleHRjb25fc2V0X3N0YXRlX3N5bmMoaGQzc3MzMjIwLT5leHRjb24sIEVYVENPTl9VU0JfSE9T VCwgdHJ1ZSk7Cj4gKwkJdHlwZWNfc2V0X2RhdGFfcm9sZShoZDNzczMyMjAtPnBvcnQsIFRZUEVD X0hPU1QpOwo+ICsJfSBlbHNlIGlmIChhdHRhY2hlZF9zdGF0ZSA9PSBFWFRDT05fVVNCKSB7Cj4g KwkJZXh0Y29uX3NldF9zdGF0ZV9zeW5jKGhkM3NzMzIyMC0+ZXh0Y29uLAo+ICsJCQkJCQkgRVhU Q09OX1VTQl9IT1NULCBmYWxzZSk7Cj4gKwkJZXh0Y29uX3NldF9zdGF0ZV9zeW5jKGhkM3NzMzIy MC0+ZXh0Y29uLCBFWFRDT05fVVNCLCB0cnVlKTsKPiArCQl0eXBlY19zZXRfZGF0YV9yb2xlKGhk M3NzMzIyMC0+cG9ydCwgVFlQRUNfREVWSUNFKTsKPiArCX0gZWxzZSB7Cj4gKwkJaGQzc3MzMjIw X3NldF9zb3VyY2VfcHJlZihoZDNzczMyMjAsCj4gKwkJCQlIRDNTUzMyMjBfUkVHX0dFTl9DVFJM X1NSQ19QUkVGX0RSUF9ERUZBVUxUKTsKPiArCQlleHRjb25fc2V0X3N0YXRlX3N5bmMoaGQzc3Mz MjIwLT5leHRjb24sCj4gKwkJCQkJCUVYVENPTl9VU0JfSE9TVCwgZmFsc2UpOwo+ICsJCWV4dGNv bl9zZXRfc3RhdGVfc3luYyhoZDNzczMyMjAtPmV4dGNvbiwgRVhUQ09OX1VTQiwgZmFsc2UpOwo+ ICsJfQo+ICt9Cj4gKwo+ICtpcnFyZXR1cm5fdCBoZDNzczMyMjBfaXJxKHN0cnVjdCBoZDNzczMy MjAgKmhkM3NzMzIyMCkKPiArewo+ICsJaW50IGVycjsKPiArCXVuc2lnbmVkIGludCBkYXRhOwo+ ICsKPiArCWhkM3NzMzIyMF9zZXRfZXh0Y29uX3N0YXRlKGhkM3NzMzIyMCk7Cj4gKwo+ICsJZXJy ID0gcmVnbWFwX3JlYWQoaGQzc3MzMjIwLT5yZWdtYXAsIEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9D VFJMLCAmZGF0YSk7Cj4gKwlpZiAoZXJyIDwgMCkKPiArCQlyZXR1cm4gSVJRX05PTkU7Cj4gKwo+ ICsJZXJyID0gcmVnbWFwX3dyaXRlKGhkM3NzMzIyMC0+cmVnbWFwLAo+ICsJCQlIRDNTUzMyMjBf UkVHX0NOX1NUQVRfQ1RSTCwKPiArCQkJZGF0YSB8IEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9DVFJM X0lOVF9TVEFUVVMpOwo+ICsJaWYgKGVyciA8IDApCj4gKwkJcmV0dXJuIElSUV9OT05FOwo+ICsK PiArCXJldHVybiBJUlFfSEFORExFRDsKPiArfQo+ICsKPiArc3RhdGljIGlycXJldHVybl90IGhk M3NzMzIyMF9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkYXRhKQo+ICt7Cj4gKwlzdHJ1Y3Qg aTJjX2NsaWVudCAqY2xpZW50ID0gdG9faTJjX2NsaWVudChkYXRhKTsKPiArCXN0cnVjdCBoZDNz czMyMjAgKmhkM3NzMzIyMCA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOwo+ICsKPiArCXJl dHVybiBoZDNzczMyMjBfaXJxKGhkM3NzMzIyMCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgaGQz c3MzMjIwX3Byb2JlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQsCj4gKwkJY29uc3Qgc3RydWN0 IGkyY19kZXZpY2VfaWQgKmlkKQo+ICt7Cj4gKwlzdHJ1Y3QgaGQzc3MzMjIwICpoZDNzczMyMjA7 Cj4gKwlpbnQgcmV0Owo+ICsJdW5zaWduZWQgaW50IGRhdGE7Cj4gKwlzdGF0aWMgY29uc3Qgc3Ry dWN0IHJlZ21hcF9jb25maWcgY29uZmlnID0gewo+ICsJCS5yZWdfYml0cyA9IDgsCj4gKwkJLnZh bF9iaXRzID0gOCwKPiArCQkubWF4X3JlZ2lzdGVyID0gMHgwQSwKPiArCX07CgpNb3ZlIHRoYXQg b3V0c2lkZSBvZiB0aGUgZnVuY3Rpb24uCgo+ICsJaGQzc3MzMjIwID0gZGV2bV9remFsbG9jKCZj bGllbnQtPmRldiwgc2l6ZW9mKHN0cnVjdCBoZDNzczMyMjApLAo+ICsJCQkJR0ZQX0tFUk5FTCk7 Cj4gKwlpZiAoIWhkM3NzMzIyMCkKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlpMmNfc2V0 X2NsaWVudGRhdGEoY2xpZW50LCBoZDNzczMyMjApOwo+ICsKPiArCWhkM3NzMzIyMC0+cmVnbWFw ID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LCAmY29uZmlnKTsKPiArCWlmIChJU19FUlIo aGQzc3MzMjIwLT5yZWdtYXApKQo+ICsJCXJldHVybiBQVFJfRVJSKGhkM3NzMzIyMC0+cmVnbWFw KTsKPiArCj4gKwloZDNzczMyMjBfc2V0X3NvdXJjZV9wcmVmKGhkM3NzMzIyMCwKPiArCQkJCUhE M1NTMzIyMF9SRUdfR0VOX0NUUkxfU1JDX1BSRUZfRFJQX0RFRkFVTFQpOwo+ICsKPiArCWhkM3Nz MzIyMC0+ZXh0Y29uID0gZGV2bV9leHRjb25fZGV2X2FsbG9jYXRlKCZjbGllbnQtPmRldiwKPiAr CQkJCQkJaGQzc3MzMjIwX2NhYmxlKTsKPiArCWlmIChJU19FUlIoaGQzc3MzMjIwLT5leHRjb24p KSB7Cj4gKwkJZGV2X2VycigmY2xpZW50LT5kZXYsICJmYWlsZWQgdG8gYWxsb2NhdGUgZXh0Y29u IGRldmljZVxuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIoaGQzc3MzMjIwLT5leHRjb24pOwo+ICsJ fQo+ICsKPiArCXJldCA9IGRldm1fZXh0Y29uX2Rldl9yZWdpc3RlcigmY2xpZW50LT5kZXYsIGhk M3NzMzIyMC0+ZXh0Y29uKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycigmY2xpZW50 LT5kZXYsICJmYWlsZWQgdG8gcmVnaXN0ZXIgZXh0Y29uIGRldmljZVxuIik7Cj4gKwkJcmV0dXJu IHJldDsKPiArCX0KPiArCj4gKwloZDNzczMyMjAtPmRldiA9ICZjbGllbnQtPmRldjsKPiArCWhk M3NzMzIyMC0+dHlwZWNfY2FwLnByZWZlcl9yb2xlID0gVFlQRUNfTk9fUFJFRkVSUkVEX1JPTEU7 Cj4gKwloZDNzczMyMjAtPnR5cGVjX2NhcC5kcl9zZXQgPSBoZDNzczMyMjBfZHJfc2V0Owo+ICsJ aGQzc3MzMjIwLT50eXBlY19jYXAudHlwZSA9IFRZUEVDX1BPUlRfRFJQOwo+ICsJaGQzc3MzMjIw LT50eXBlY19jYXAuZGF0YSA9IFRZUEVDX1BPUlRfRFJEOwo+ICsKPiArCWhkM3NzMzIyMC0+cG9y dCA9IHR5cGVjX3JlZ2lzdGVyX3BvcnQoJmNsaWVudC0+ZGV2LAo+ICsJCQkJCQkmaGQzc3MzMjIw LT50eXBlY19jYXApOwo+ICsJaWYgKElTX0VSUihoZDNzczMyMjAtPnBvcnQpKQo+ICsJCXJldHVy biBQVFJfRVJSKGhkM3NzMzIyMC0+cG9ydCk7Cj4gKwo+ICsJaGQzc3MzMjIwX3NldF9leHRjb25f c3RhdGUoaGQzc3MzMjIwKTsKPiArCWlmIChjbGllbnQtPmlycSA+IDApIHsKPiArCQlyZXQgPSBy ZWdtYXBfcmVhZChoZDNzczMyMjAtPnJlZ21hcCwKPiArCQkJSEQzU1MzMjIwX1JFR19DTl9TVEFU X0NUUkwsICZkYXRhKTsKPiArCQlpZiAocmV0IDwgMCkKPiArCQkJZ290byBlcnJvcjsKPiArCj4g KwkJaWYgKGRhdGEgJiBIRDNTUzMyMjBfUkVHX0NOX1NUQVRfQ1RSTF9JTlRfU1RBVFVTKSB7Cj4g KwkJCXJldCA9IHJlZ21hcF93cml0ZShoZDNzczMyMjAtPnJlZ21hcCwKPiArCQkJCUhEM1NTMzIy MF9SRUdfQ05fU1RBVF9DVFJMLAo+ICsJCQkJZGF0YSB8IEhEM1NTMzIyMF9SRUdfQ05fU1RBVF9D VFJMX0lOVF9TVEFUVVMpOwo+ICsJCQlpZiAocmV0IDwgMCkKPiArCQkJCWdvdG8gZXJyb3I7Cj4g KwkJfQo+ICsKPiArCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJxKCZjbGllbnQtPmRl diwgY2xpZW50LT5pcnEsCj4gKwkJCU5VTEwsIGhkM3NzMzIyMF9pcnFfaGFuZGxlciwKPiArCQkJ SVJRRl9UUklHR0VSX0ZBTExJTkcgfCBJUlFGX09ORVNIT1QsCj4gKwkJCSJoZDNzczMyMjAiLCAm Y2xpZW50LT5kZXYpOwo+ICsJCWlmIChyZXQpCj4gKwkJCWdvdG8gZXJyb3I7Cj4gKwl9Cj4gKwo+ ICsJcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRhKGNsaWVudCwgSEQzU1MzMjIwX1JFR19E RVZfUkVWKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCWdvdG8gZXJyb3I7Cj4gKwo+ICsJZGV2X2lu Zm8oJmNsaWVudC0+ZGV2LCAicHJvYmVkIHJldmlzaW9uPTB4JXhcbiIsIHJldCk7Cj4gKwo+ICsJ cmV0dXJuIDA7Cj4gK2Vycm9yOgo+ICsJdHlwZWNfdW5yZWdpc3Rlcl9wb3J0KGhkM3NzMzIyMC0+ cG9ydCk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGludCBoZDNzczMy MjBfcmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCj4gK3sKPiArCXN0cnVjdCBoZDNz czMyMjAgKmhkM3NzMzIyMCA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOwo+ICsKPiArCXR5 cGVjX3VucmVnaXN0ZXJfcG9ydChoZDNzczMyMjAtPnBvcnQpOwo+ICsKPiArCXJldHVybiAwOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBkZXZfaWRzW10gPSB7 Cj4gKwl7IC5jb21wYXRpYmxlID0gInRpLGhkM3NzMzIyMCJ9LAo+ICsJe30KPiArfTsKPiArTU9E VUxFX0RFVklDRV9UQUJMRShvZiwgZGV2X2lkcyk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGkyY19k cml2ZXIgaGQzc3MzMjIwX2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAi aGQzc3MzMjIwIiwKPiArCQkub3duZXIgPSBUSElTX01PRFVMRSwKPiArCQkub2ZfbWF0Y2hfdGFi bGUgPSBvZl9tYXRjaF9wdHIoZGV2X2lkcyksCj4gKwl9LAo+ICsJLnByb2JlID0gaGQzc3MzMjIw X3Byb2JlLAo+ICsJLnJlbW92ZSA9ICBoZDNzczMyMjBfcmVtb3ZlLAo+ICt9Owo+ICsKPiArbW9k dWxlX2kyY19kcml2ZXIoaGQzc3MzMjIwX2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfQVVUSE9SKCJC aWp1IERhcyA8YmlqdS5kYXNAYnAucmVuZXNhcy5jb20+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElP TigiVEkgSEQzU1MzMjIwIERSUCBQb3J0IENvbnRyb2xsZXIgRHJpdmVyIik7Cj4gK01PRFVMRV9M SUNFTlNFKCJHUEwiKTsKCllvdSB3aWxsIG5lZWQgdG8gdXNlIHRoZSBVU0Igcm9sZSBjbGFzcyBp bnN0ZWFkIG9mIGV4dGNvbi4gT3RoZXJ3aXNlCnRoaXMgbG9va3MgT0sgdG8gbWUsIGFzc3VtaW5n IHlvdSBmaXggdGhlIHN0eWxlIGlzc3VlcyA7LSkuCgoKdGhhbmtzLAo=