All of lore.kernel.org
 help / color / mirror / Atom feed
From: "shufan_lee(李書帆)" <shufan_lee@richtek.com>
To: 'Greg KH' <greg@kroah.com>, ShuFanLee <leechu729@gmail.com>
Cc: "heikki.krogerus@linux.intel.com"
	<heikki.krogerus@linux.intel.com>,
	"cy_huang(黃啟原)" <cy_huang@richtek.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>
Subject: RE: [PATCH] USB TYPEC: RT1711H Type-C Chip Driver
Date: Thu, 18 Jan 2018 13:13:15 +0000	[thread overview]
Message-ID: <f94537a67a1544d1937eae3dbfcd554f@ex1.rt.l> (raw)
In-Reply-To: <20180117134219.GE3188@kroah.com>

Dear Gerg,

  Many thanks to your comment.
  I've checked all of them and here are some questions need your help.

> +Example:
> +rt1711h@4e {
> +status = "ok";
> +compatible = "richtek,typec_rt1711h";
> +reg = <0x4e>;
> +rt,intr_gpio = <&gpio26 0 0x0>;
> +rt,name = "rt1711h";
> +rt,port_type = <2>; /* 0: DFP, 1: UFP, 2: DRP */
> +rt,def_role = <0>; /* 0: SNK, 1: SRC, -1: TYPEC_NO_PREFERRED_ROLE */
> +};

dts stuff needs to always be in a separate file so the DT maintainers can review/ack it.  Split this patch up into smaller pieces please.

Ok, I'll split it into two patches, one for source code and once for dts related files.
========================================================================

> diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
> index bb3138a..e3aaf3c 100644
> --- a/drivers/usb/typec/Makefile
> +++ b/drivers/usb/typec/Makefile
> @@ -2,6 +2,7 @@
>  obj-$(CONFIG_TYPEC)+= typec.o
>  obj-$(CONFIG_TYPEC_TCPM)+= tcpm.o
>  obj-y+= fusb302/
> +obj-$(CONFIG_TYPEC_RT1711H)+= rt1711h/

Why do you need a whole directory for one file?

Is the suggestion to move rt1711h.c to the same directory level as tcpm? i.e. drivers/usb/typec/rt1711h.c
========================================================================

> +<uapi/linux/sched/types.h>

This last #include should not be needed.  If it does, you are doing something really wrong...

Ok, this #include will be removed
========================================================================

> +
> +#include "rt1711h.h"

Why a .h file for a single .c file?

Is the suggestion to move all content in rt1711h.h into rt1711h.c?
========================================================================

> +
> +#define RT1711H_DRV_VERSION"1.0.3"

When code is in the kernel tree, versions mean nothing, you will note that no other USB driver has them, right?  Please remove.

Ok, this will be removed.
========================================================================

kernel types are u16, u32, u8, and the like, not uint16_t, those are for userspace code only.
Yeah, other drivers do it, but you shouldn't :)

Ok, I'll use u16, u32 and u8 instead of uint16_t, uint32_t and uint8_t
========================================================================

> +/* IRQ */
> +struct kthread_worker irq_worker;
> +struct kthread_work irq_work;
> +struct task_struct *irq_worker_task;

3 things for an irq handler?  That feels wrong.

> +atomic_t poll_count;

Like I said before, why is this an atomic?

I'll use threaded_irq instead, the above things will be removed.
========================================================================

> +/* I2C */
> +atomic_t i2c_busy;
> +atomic_t pm_suspend;

Why are these atomic?  You know that doesn't mean they do not need locking, right?

For my understanding, a single operation on atomic_t doesn't need lock, like a single atomic_set.
But two consecutive operations doesn't guarantee anything. Like atomic_set followed by an atomic_read.
This part is referenced from fusb302 used to make sure I2C is idle before system suspends.
It only needs to guarantee a single read/write on these variable is atomic operation, so atomic is used.
========================================================================

> +};
> +
> +/*
> + * Logging & debugging
> + */
> +
> +#ifdef CONFIG_DEBUG_FS
> +
> +static int rt1711h_reg_block_read(struct rt1711h_chip *chip, uint8_t reg,
> +int len, uint8_t *data);
> +static int rt1711h_reg_block_write(struct rt1711h_chip *chip, uint8_t reg,
> +int len, const uint8_t *data);
> +
> +struct reg_desc {
> +uint8_t addr;
> +uint8_t size;
> +};
> +#define DECL_REG(_addr, _size) {.addr = _addr, .size = _size}
> +
> +static struct reg_desc rt1711h_reg_desc[] = {
> +DECL_REG(RT1711H_REG_VID, 2),
> +DECL_REG(RT1711H_REG_PID, 2),
> +DECL_REG(RT1711H_REG_DID, 2),
> +DECL_REG(RT1711H_REG_TYPEC_REV, 2),
> +DECL_REG(RT1711H_REG_PD_REV, 2),
> +DECL_REG(RT1711H_REG_PDIF_REV, 2),
> +DECL_REG(RT1711H_REG_ALERT, 2),
> +DECL_REG(RT1711H_REG_ALERT_MASK, 2),
> +DECL_REG(RT1711H_REG_POWER_STATUS_MASK, 1),
> +DECL_REG(RT1711H_REG_FAULT_STATUS_MASK, 1),
> +DECL_REG(RT1711H_REG_TCPC_CTRL, 1),
> +DECL_REG(RT1711H_REG_ROLE_CTRL, 1),
> +DECL_REG(RT1711H_REG_FAULT_CTRL, 1),
> +DECL_REG(RT1711H_REG_POWER_CTRL, 1),
> +DECL_REG(RT1711H_REG_CC_STATUS, 1),
> +DECL_REG(RT1711H_REG_POWER_STATUS, 1),
> +DECL_REG(RT1711H_REG_FAULT_STATUS, 1),
> +DECL_REG(RT1711H_REG_COMMAND, 1),
> +DECL_REG(RT1711H_REG_MSG_HDR_INFO, 1),
> +DECL_REG(RT1711H_REG_RX_DETECT, 1),
> +DECL_REG(RT1711H_REG_RX_BYTE_CNT, 1),
> +DECL_REG(RT1711H_REG_RX_BUF_FRAME_TYPE, 1),
> +DECL_REG(RT1711H_REG_RX_HDR, 2),
> +DECL_REG(RT1711H_REG_RX_DATA, 1),
> +DECL_REG(RT1711H_REG_TRANSMIT, 1),
> +DECL_REG(RT1711H_REG_TX_BYTE_CNT, 1),
> +DECL_REG(RT1711H_REG_TX_HDR, 2),
> +DECL_REG(RT1711H_REG_TX_DATA, 1),
> +DECL_REG(RT1711H_REG_CLK_CTRL2, 1),
> +DECL_REG(RT1711H_REG_CLK_CTRL3, 1),
> +DECL_REG(RT1711H_REG_BMC_CTRL, 1),
> +DECL_REG(RT1711H_REG_BMCIO_RXDZSEL, 1),
> +DECL_REG(RT1711H_REG_VCONN_CLIMITEN, 1),
> +DECL_REG(RT1711H_REG_RT_STATUS, 1),
> +DECL_REG(RT1711H_REG_RT_INT, 1),
> +DECL_REG(RT1711H_REG_RT_MASK, 1),
> +DECL_REG(RT1711H_REG_IDLE_CTRL, 1),
> +DECL_REG(RT1711H_REG_INTRST_CTRL, 1),
> +DECL_REG(RT1711H_REG_WATCHDOG_CTRL, 1),
> +DECL_REG(RT1711H_REG_I2CRST_CTRL, 1),
> +DECL_REG(RT1711H_REG_SWRESET, 1),
> +DECL_REG(RT1711H_REG_TTCPC_FILTER, 1),
> +DECL_REG(RT1711H_REG_DRP_TOGGLE_CYCLE, 1),
> +DECL_REG(RT1711H_REG_DRP_DUTY_CTRL, 1),
> +DECL_REG(RT1711H_REG_BMCIO_RXDZEN, 1), };
> +
> +static const char *rt1711h_dbg_filename[RT1711H_DBG_MAX] = {
> +"log", "regs", "reg_addr", "data",
> +};
> +
> +static bool rt1711h_log_full(struct rt1711h_chip *chip) {
> +return chip->logbuffer_tail ==
> +(chip->logbuffer_head + 1) % LOG_BUFFER_ENTRIES; }
> +
> +static void _rt1711h_log(struct rt1711h_chip *chip, const char *fmt,
> + va_list args)
> +{
> +char tmpbuffer[LOG_BUFFER_ENTRY_SIZE];
> +u64 ts_nsec = local_clock();
> +unsigned long rem_nsec;
> +
> +if (!chip->logbuffer[chip->logbuffer_head]) {
> +chip->logbuffer[chip->logbuffer_head] =
> +devm_kzalloc(chip->dev, LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL);
> +if (!chip->logbuffer[chip->logbuffer_head])
> +return;
> +}
> +
> +vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
> +
> +mutex_lock(&chip->logbuffer_lock);
> +
> +if (rt1711h_log_full(chip)) {
> +chip->logbuffer_head = max(chip->logbuffer_head - 1, 0);
> +strlcpy(tmpbuffer, "overflow", sizeof(tmpbuffer));
> +}
> +
> +if (chip->logbuffer_head < 0 ||
> +chip->logbuffer_head >= LOG_BUFFER_ENTRIES) {
> +dev_warn(chip->dev, "%s bad log buffer index %d\n", __func__,
> +chip->logbuffer_head);
> +goto abort;
> +}
> +
> +if (!chip->logbuffer[chip->logbuffer_head]) {
> +dev_warn(chip->dev, "%s log buffer index %d is NULL\n",
> +__func__, chip->logbuffer_head);
> +goto abort;
> +}
> +
> +rem_nsec = do_div(ts_nsec, 1000000000);
> +scnprintf(chip->logbuffer[chip->logbuffer_head], LOG_BUFFER_ENTRY_SIZE,
> +"[%5lu.%06lu] %s", (unsigned long)ts_nsec, rem_nsec / 1000,
> +  tmpbuffer);
> +chip->logbuffer_head = (chip->logbuffer_head + 1) %
> +LOG_BUFFER_ENTRIES;
> +
> +abort:
> +mutex_unlock(&chip->logbuffer_lock);
> +}
> +
> +static void rt1711h_log(struct rt1711h_chip *chip,
> +const char *fmt, ...)
> +{
> +va_list args;
> +
> +va_start(args, fmt);
> +_rt1711h_log(chip, fmt, args);
> +va_end(args);
> +}
> +
> +static int rt1711h_log_show(struct rt1711h_chip *chip, struct
> +seq_file *s) {
> +int tail;
> +
> +mutex_lock(&chip->logbuffer_lock);
> +tail = chip->logbuffer_tail;
> +while (tail != chip->logbuffer_head) {
> +seq_printf(s, "%s", chip->logbuffer[tail]);
> +tail = (tail + 1) % LOG_BUFFER_ENTRIES;
> +}
> +if (!seq_has_overflowed(s))
> +chip->logbuffer_tail = tail;
> +mutex_unlock(&chip->logbuffer_lock);
> +
> +return 0;
> +}
> +
> +static int rt1711h_regs_show(struct rt1711h_chip *chip, struct
> +seq_file *s) {
> +int ret = 0;
> +int i = 0, j = 0;
> +struct reg_desc *desc = NULL;
> +uint8_t regval[2] = {0};
> +
> +for (i = 0; i < ARRAY_SIZE(rt1711h_reg_desc); i++) {
> +desc = &rt1711h_reg_desc[i];
> +ret = rt1711h_reg_block_read(chip, desc->addr, desc->size,
> +regval);
> +if (ret < 0) {
> +dev_err(chip->dev, "%s read reg0x%02X fail\n",
> +__func__, desc->addr);
> +continue;
> +}
> +
> +seq_printf(s, "reg0x%02x:0x", desc->addr);
> +for (j = 0; j < desc->size; j++)
> +seq_printf(s, "%02x,", regval[j]);
> +seq_puts(s, "\n");
> +}
> +
> +return 0;
> +}
> +
> +static inline int rt1711h_reg_addr_show(struct rt1711h_chip *chip,
> +struct seq_file *s)
> +{
> +struct reg_desc *desc = &rt1711h_reg_desc[chip->dbg_regidx];
> +
> +seq_printf(s, "0x%02x\n", desc->addr);
> +return 0;
> +}
> +
> +static inline int rt1711h_data_show(struct rt1711h_chip *chip,
> +struct seq_file *s)
> +{
> +int ret = 0, i = 0;
> +struct reg_desc *desc = &rt1711h_reg_desc[chip->dbg_regidx];
> +uint8_t regval[2] = {0};
> +
> +ret = rt1711h_reg_block_read(chip, desc->addr, desc->size, regval);
> +if (ret < 0)
> +return ret;
> +
> +seq_printf(s, "reg0x%02x=0x", desc->addr);
> +for (i = 0; i < desc->size; i++)
> +seq_printf(s, "%02x,", regval[i]);
> +seq_puts(s, "\n");
> +return 0;
> +}
> +
> +static int rt1711h_dbg_show(struct seq_file *s, void *v) {
> +int ret = 0;
> +struct rt1711h_dbg_info *info = (struct rt1711h_dbg_info *)s->private;
> +struct rt1711h_chip *chip = info->chip;
> +
> +mutex_lock(&chip->dbgops_lock);
> +switch (info->id) {
> +case RT1711H_DBG_LOG:
> +ret = rt1711h_log_show(chip, s);
> +break;
> +case RT1711H_DBG_REGS:
> +ret = rt1711h_regs_show(chip, s);
> +break;
> +case RT1711H_DBG_REG_ADDR:
> +ret = rt1711h_reg_addr_show(chip, s);
> +break;
> +case RT1711H_DBG_DATA:
> +ret = rt1711h_data_show(chip, s);
> +break;
> +default:
> +ret = -EINVAL;
> +break;
> +}
> +
> +mutex_unlock(&chip->dbgops_lock);
> +return ret;
> +}
> +
> +static int rt1711h_dbg_open(struct inode *inode, struct file *file) {
> +if (file->f_mode & FMODE_READ)
> +return single_open(file, rt1711h_dbg_show, inode->i_private);
> +file->private_data = inode->i_private;
> +return 0;
> +}
> +
> +static int get_parameters(char *buf, long int *param1, int
> +num_of_par) {
> +char *token;
> +int base, cnt;
> +
> +token = strsep(&buf, " ");
> +
> +for (cnt = 0; cnt < num_of_par; cnt++) {
> +if (token != NULL) {
> +if ((token[1] == 'x') || (token[1] == 'X'))
> +base = 16;
> +else
> +base = 10;
> +
> +if (kstrtoul(token, base, &param1[cnt]) != 0)
> +return -EINVAL;
> +
> +token = strsep(&buf, " ");
> +} else
> +return -EINVAL;
> +}
> +return 0;
> +}

What is this function doing?  What is your debugfs files for?

There are 4 debug files.
First(log) is for logging which needs a lock for log buffer. The way to log is referenced from fusb302 and tcpm.
Second(regs) is used to dump all register of rt1711h.
Third(reg_addr)&Forth(data) are used to write/read a register specified in reg_addr.
The reason to create these debug files is to make issue support easier.
========================================================================

> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *dbgdir;
> +struct rt1711h_dbg_info dbg_info[RT1711H_DBG_MAX];
> +struct dentry *dbg_files[RT1711H_DBG_MAX];
> +int dbg_regidx;
> +struct mutex dbgops_lock;
> +/* lock for log buffer access */
> +struct mutex logbuffer_lock;
> +int logbuffer_head;
> +int logbuffer_tail;
> +u8 *logbuffer[LOG_BUFFER_ENTRIES];
> +#endif /* CONFIG_DEBUG_FS */

That's a lot of stuff jsut for debugfs.  Why do you care about #define at all?  The code should not.

Is the suggestion to remove #ifdef CONFIG_DEBUG_FS?

And another 2 locks?  Ick, no.

dbgops_lock is used to prevent user from accessing different debug files simultaneously.
Is the suggestion to use the lock of the following one?
> +/* lock for sharing chip states */
> +struct mutex lock;
========================================================================

> +snprintf(dirname, len + 9, "rt1711h-%s", dev_name(chip->dev));
> +if (!chip->dbgdir) {
> +chip->dbgdir = debugfs_create_dir(dirname, NULL);
> +if (!chip->dbgdir)
> +return -ENOMEM;

No need to ever check the return value of debugfs_ calls, you should not care and can always use the value to any future debugfs calls, if you really need it.

If it is NULL without checking and we use it in debugfs_create_file, all the debug files will be created in the root of the debugfs filesystem.
Is this correct?
========================================================================

> +for (i = 0; i < RT1711H_DBG_MAX; i++) {
> +info = &chip->dbg_info[i];

static array of debug info?  That feels odd.

Is the suggestion to use pointer of array and dynamically allocated it?
========================================================================

Like here, you don't need this, and you don't need to care about the return value.

> +goto err;
> +}
> +}
> +
> +return 0;
> +err:
> +debugfs_remove_recursive(chip->dbgdir);
> +return ret;

Why do you care about an error here?  Your code should not do anything different if debugfs stuff does not work or if it does.  It's debugging only.
Ok, this will be removed.
========================================================================

Best Regards,
*****************************
Shu-Fan Lee
Richtek Technology Corporation
TEL: +886-3-5526789 #2359
FAX: +886-3-5526612
*****************************

-----Original Message-----
From: Greg KH [mailto:greg@kroah.com]
Sent: Wednesday, January 17, 2018 9:42 PM
To: ShuFanLee
Cc: heikki.krogerus@linux.intel.com; cy_huang(黃啟原); shufan_lee(李書帆); linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
Subject: Re: [PATCH] USB TYPEC: RT1711H Type-C Chip Driver

On Wed, Jan 10, 2018 at 02:59:12PM +0800, ShuFanLee wrote:
> From: ShuFanLee <shufan_lee@richtek.com>
>
> Richtek RT1711H Type-C chip driver that works with Type-C Port
> Controller Manager to provide USB PD and USB Type-C functionalities.
>
> Signed-off-by: ShuFanLee <shufan_lee@richtek.com>

Minor review of your main structure and your debugfs code and other stuff, all of which need work:

> ---
>  .../devicetree/bindings/usb/richtek,rt1711h.txt    |   38 +
>  arch/arm64/boot/dts/hisilicon/rt1711h.dtsi         |   11 +
>  drivers/usb/typec/Kconfig                          |    2 +
>  drivers/usb/typec/Makefile                         |    1 +
>  drivers/usb/typec/rt1711h/Kconfig                  |    7 +
>  drivers/usb/typec/rt1711h/Makefile                 |    2 +
>  drivers/usb/typec/rt1711h/rt1711h.c                | 2241 ++++++++++++++++++++
>  drivers/usb/typec/rt1711h/rt1711h.h                |  300 +++
>  8 files changed, 2602 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/usb/richtek,rt1711h.txt
>  create mode 100644 arch/arm64/boot/dts/hisilicon/rt1711h.dtsi
>  create mode 100644 drivers/usb/typec/rt1711h/Kconfig  create mode
> 100644 drivers/usb/typec/rt1711h/Makefile
>  create mode 100644 drivers/usb/typec/rt1711h/rt1711h.c
>  create mode 100644 drivers/usb/typec/rt1711h/rt1711h.h
>
> diff --git a/Documentation/devicetree/bindings/usb/richtek,rt1711h.txt
> b/Documentation/devicetree/bindings/usb/richtek,rt1711h.txt
> new file mode 100644
> index 0000000..c28299c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/richtek,rt1711h.txt
> @@ -0,0 +1,38 @@
> +Richtek RT1711H Type-C Port Controller.
> +
> +Required properties:
> +- compatible : Must be "richtek,typec_rt1711h";
> +- reg : Must be 0x4e, it's default slave address of RT1711H.
> +- rt,intr_gpio : IRQ GPIO pin that's connected to RT1711H interrupt.
> +
> +Optional node:
> +- rt,name : Name used for registering IRQ and creating kthread.
> +    If this property is not specified, "default" will be applied.
> +- rt,def_role : Default port role (TYPEC_SINK(0) or TYPEC_SOURCE(1)).
> +Set to TYPEC_NO_PREFERRED_ROLE(-1) if no default role.
> +If this property is not specified, TYPEC_SINK will be applied.
> +- rt,port_type : Port type (TYPEC_PORT_DFP(0), TYPEC_PORT_UFP(1),
> + or TYPEC_PORT_DRP(2)). If this property is not specified,
> + TYPEC_PORT_DRP will be applied.
> +- rt,max_snk_mv : Maximum acceptable sink voltage in mV.
> +  If this property is not specified, 5000mV will be applied.
> +- rt,max_snk_ma : Maximum sink current in mA.
> +  If this property is not specified, 3000mA will be applied.
> +- rt,max_snk_mw : Maximum required sink power in mW.
> +  If this property is not specified, 15000mW will be applied.
> +- rt,operating_snk_mw : Required operating sink power in mW.
> +If this property is not specified,
> +2500mW will be applied.
> +- rt,try_role_hw : True if try.{Src,Snk} is implemented in hardware.
> +   If this property is not specified, False will be applied.
> +
> +Example:
> +rt1711h@4e {
> +status = "ok";
> +compatible = "richtek,typec_rt1711h";
> +reg = <0x4e>;
> +rt,intr_gpio = <&gpio26 0 0x0>;
> +rt,name = "rt1711h";
> +rt,port_type = <2>; /* 0: DFP, 1: UFP, 2: DRP */
> +rt,def_role = <0>; /* 0: SNK, 1: SRC, -1: TYPEC_NO_PREFERRED_ROLE */
> +};

dts stuff needs to always be in a separate file so the DT maintainers can review/ack it.  Split this patch up into smaller pieces please.


> diff --git a/arch/arm64/boot/dts/hisilicon/rt1711h.dtsi
> b/arch/arm64/boot/dts/hisilicon/rt1711h.dtsi
> new file mode 100644
> index 0000000..4196cc0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/hisilicon/rt1711h.dtsi
> @@ -0,0 +1,11 @@
> +&i2c7 {
> +rt1711h@4e {
> +status = "ok";
> +compatible = "richtek,typec_rt1711h";
> +reg = <0x4e>;
> +rt,intr_gpio = <&gpio26 0 0x0>;
> +rt,name = "rt1711h";
> +rt,port_type = <2>; /* 0: DFP, 1: UFP, 2: DRP */
> +rt,def_role = <0>; /* 0: SNK, 1: SRC */
> +};
> +};
> diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
> index bcb2744..7bede0b 100644
> --- a/drivers/usb/typec/Kconfig
> +++ b/drivers/usb/typec/Kconfig
> @@ -56,6 +56,8 @@ if TYPEC_TCPM
>
>  source "drivers/usb/typec/fusb302/Kconfig"
>
> +source "drivers/usb/typec/rt1711h/Kconfig"
> +
>  config TYPEC_WCOVE
>  tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
>  depends on ACPI
> diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
> index bb3138a..e3aaf3c 100644
> --- a/drivers/usb/typec/Makefile
> +++ b/drivers/usb/typec/Makefile
> @@ -2,6 +2,7 @@
>  obj-$(CONFIG_TYPEC)+= typec.o
>  obj-$(CONFIG_TYPEC_TCPM)+= tcpm.o
>  obj-y+= fusb302/
> +obj-$(CONFIG_TYPEC_RT1711H)+= rt1711h/

Why do you need a whole directory for one file?


>  obj-$(CONFIG_TYPEC_WCOVE)+= typec_wcove.o
>  obj-$(CONFIG_TYPEC_UCSI)+= ucsi/
>  obj-$(CONFIG_TYPEC_TPS6598X)+= tps6598x.o
> diff --git a/drivers/usb/typec/rt1711h/Kconfig
> b/drivers/usb/typec/rt1711h/Kconfig
> new file mode 100644
> index 0000000..2fbfff5
> --- /dev/null
> +++ b/drivers/usb/typec/rt1711h/Kconfig
> @@ -0,0 +1,7 @@
> +config TYPEC_RT1711H
> +tristate "Richtek RT1711H Type-C chip driver"
> +depends on I2C && POWER_SUPPLY
> +help
> +  The Richtek RT1711H   Type-C chip driver that works with
> +  Type-C Port Controller Manager to provide USB PD and USB
> +  Type-C functionalities.
> diff --git a/drivers/usb/typec/rt1711h/Makefile
> b/drivers/usb/typec/rt1711h/Makefile
> new file mode 100644
> index 0000000..5fab8ae
> --- /dev/null
> +++ b/drivers/usb/typec/rt1711h/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_TYPEC_RT1711H)+= rt1711h.o
> diff --git a/drivers/usb/typec/rt1711h/rt1711h.c
> b/drivers/usb/typec/rt1711h/rt1711h.c
> new file mode 100644
> index 0000000..1aef3e8
> --- /dev/null
> +++ b/drivers/usb/typec/rt1711h/rt1711h.c
> @@ -0,0 +1,2241 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2017 Richtek Technologh Corp.
> + *
> + * Richtek RT1711H Type-C Chip Driver  */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/version.h>
> +#include <linux/err.h>
> +#include <linux/debugfs.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/i2c.h>
> +#include <linux/usb/typec.h>
> +#include <linux/usb/tcpm.h>
> +#include <linux/usb/pd.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/regulator/consumer.h> #include <linux/power_supply.h>
> +#include <linux/extcon.h> #include <linux/workqueue.h> #include
> +<linux/kthread.h> #include <linux/cpu.h> #include
> +<linux/alarmtimer.h> #include <linux/sched/clock.h> #include
> +<uapi/linux/sched/types.h>

This last #include should not be needed.  If it does, you are doing something really wrong...

> +
> +#include "rt1711h.h"

Why a .h file for a single .c file?

> +
> +#define RT1711H_DRV_VERSION"1.0.3"

When code is in the kernel tree, versions mean nothing, you will note that no other USB driver has them, right?  Please remove.


> +
> +#define LOG_BUFFER_ENTRIES1024
> +#define LOG_BUFFER_ENTRY_SIZE128 /* 128 char per line */
> +
> +enum {
> +RT1711H_DBG_LOG = 0,
> +RT1711H_DBG_REGS,
> +RT1711H_DBG_REG_ADDR,
> +RT1711H_DBG_DATA,
> +RT1711H_DBG_MAX,
> +};
> +
> +struct rt1711h_dbg_info {
> +struct rt1711h_chip *chip;
> +int id;
> +};
> +
> +
> +struct rt1711h_chip {
> +struct i2c_client *i2c;
> +struct device *dev;
> +uint16_t did;

kernel types are u16, u32, u8, and the like, not uint16_t, those are for userspace code only.

Yeah, other drivers do it, but you shouldn't :)


> +int irq_gpio;
> +int irq;
> +char *name;
> +struct tcpc_dev tcpc_dev;
> +struct tcpc_config tcpc_cfg;
> +struct tcpm_port *tcpm_port;
> +struct regulator *vbus;
> +struct extcon_dev *extcon;
> +
> +/* IRQ */
> +struct kthread_worker irq_worker;
> +struct kthread_work irq_work;
> +struct task_struct *irq_worker_task;

3 things for an irq handler?  That feels wrong.

> +atomic_t poll_count;

Like I said before, why is this an atomic?

> +struct delayed_work poll_work;
> +
> +/* LPM */
> +struct delayed_work wakeup_work;
> +struct alarm wakeup_timer;
> +struct mutex wakeup_lock;
> +enum typec_cc_pull lpm_pull;
> +bool wakeup_once;
> +bool low_rp_duty_cntdown;
> +bool cable_only;
> +bool lpm;
> +
> +/* I2C */
> +atomic_t i2c_busy;
> +atomic_t pm_suspend;

Why are these atomic?  You know that doesn't mean they do not need locking, right?

> +
> +/* psy + psy status */
> +struct power_supply *psy;
> +u32 current_limit;
> +u32 supply_voltage;
> +
> +/* lock for sharing chip states */
> +struct mutex lock;

How many locks do you have in this structure?  You should only need 1.

> +
> +/* port status */
> +bool vconn_on;
> +bool vbus_on;
> +bool charge_on;
> +bool vbus_present;
> +enum typec_cc_polarity polarity;
> +enum typec_cc_status cc1;
> +enum typec_cc_status cc2;
> +enum typec_role pwr_role;
> +bool drp_toggling;
> +
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *dbgdir;
> +struct rt1711h_dbg_info dbg_info[RT1711H_DBG_MAX];
> +struct dentry *dbg_files[RT1711H_DBG_MAX];
> +int dbg_regidx;
> +struct mutex dbgops_lock;
> +/* lock for log buffer access */
> +struct mutex logbuffer_lock;
> +int logbuffer_head;
> +int logbuffer_tail;
> +u8 *logbuffer[LOG_BUFFER_ENTRIES];
> +#endif /* CONFIG_DEBUG_FS */

That's a lot of stuff jsut for debugfs.  Why do you care about #define at all?  The code should not.

And another 2 locks?  Ick, no.


> +};
> +
> +/*
> + * Logging & debugging
> + */
> +
> +#ifdef CONFIG_DEBUG_FS
> +
> +static int rt1711h_reg_block_read(struct rt1711h_chip *chip, uint8_t reg,
> +int len, uint8_t *data);
> +static int rt1711h_reg_block_write(struct rt1711h_chip *chip, uint8_t reg,
> +int len, const uint8_t *data);
> +
> +struct reg_desc {
> +uint8_t addr;
> +uint8_t size;
> +};
> +#define DECL_REG(_addr, _size) {.addr = _addr, .size = _size}
> +
> +static struct reg_desc rt1711h_reg_desc[] = {
> +DECL_REG(RT1711H_REG_VID, 2),
> +DECL_REG(RT1711H_REG_PID, 2),
> +DECL_REG(RT1711H_REG_DID, 2),
> +DECL_REG(RT1711H_REG_TYPEC_REV, 2),
> +DECL_REG(RT1711H_REG_PD_REV, 2),
> +DECL_REG(RT1711H_REG_PDIF_REV, 2),
> +DECL_REG(RT1711H_REG_ALERT, 2),
> +DECL_REG(RT1711H_REG_ALERT_MASK, 2),
> +DECL_REG(RT1711H_REG_POWER_STATUS_MASK, 1),
> +DECL_REG(RT1711H_REG_FAULT_STATUS_MASK, 1),
> +DECL_REG(RT1711H_REG_TCPC_CTRL, 1),
> +DECL_REG(RT1711H_REG_ROLE_CTRL, 1),
> +DECL_REG(RT1711H_REG_FAULT_CTRL, 1),
> +DECL_REG(RT1711H_REG_POWER_CTRL, 1),
> +DECL_REG(RT1711H_REG_CC_STATUS, 1),
> +DECL_REG(RT1711H_REG_POWER_STATUS, 1),
> +DECL_REG(RT1711H_REG_FAULT_STATUS, 1),
> +DECL_REG(RT1711H_REG_COMMAND, 1),
> +DECL_REG(RT1711H_REG_MSG_HDR_INFO, 1),
> +DECL_REG(RT1711H_REG_RX_DETECT, 1),
> +DECL_REG(RT1711H_REG_RX_BYTE_CNT, 1),
> +DECL_REG(RT1711H_REG_RX_BUF_FRAME_TYPE, 1),
> +DECL_REG(RT1711H_REG_RX_HDR, 2),
> +DECL_REG(RT1711H_REG_RX_DATA, 1),
> +DECL_REG(RT1711H_REG_TRANSMIT, 1),
> +DECL_REG(RT1711H_REG_TX_BYTE_CNT, 1),
> +DECL_REG(RT1711H_REG_TX_HDR, 2),
> +DECL_REG(RT1711H_REG_TX_DATA, 1),
> +DECL_REG(RT1711H_REG_CLK_CTRL2, 1),
> +DECL_REG(RT1711H_REG_CLK_CTRL3, 1),
> +DECL_REG(RT1711H_REG_BMC_CTRL, 1),
> +DECL_REG(RT1711H_REG_BMCIO_RXDZSEL, 1),
> +DECL_REG(RT1711H_REG_VCONN_CLIMITEN, 1),
> +DECL_REG(RT1711H_REG_RT_STATUS, 1),
> +DECL_REG(RT1711H_REG_RT_INT, 1),
> +DECL_REG(RT1711H_REG_RT_MASK, 1),
> +DECL_REG(RT1711H_REG_IDLE_CTRL, 1),
> +DECL_REG(RT1711H_REG_INTRST_CTRL, 1),
> +DECL_REG(RT1711H_REG_WATCHDOG_CTRL, 1),
> +DECL_REG(RT1711H_REG_I2CRST_CTRL, 1),
> +DECL_REG(RT1711H_REG_SWRESET, 1),
> +DECL_REG(RT1711H_REG_TTCPC_FILTER, 1),
> +DECL_REG(RT1711H_REG_DRP_TOGGLE_CYCLE, 1),
> +DECL_REG(RT1711H_REG_DRP_DUTY_CTRL, 1),
> +DECL_REG(RT1711H_REG_BMCIO_RXDZEN, 1), };
> +
> +static const char *rt1711h_dbg_filename[RT1711H_DBG_MAX] = {
> +"log", "regs", "reg_addr", "data",
> +};
> +
> +static bool rt1711h_log_full(struct rt1711h_chip *chip) {
> +return chip->logbuffer_tail ==
> +(chip->logbuffer_head + 1) % LOG_BUFFER_ENTRIES; }
> +
> +static void _rt1711h_log(struct rt1711h_chip *chip, const char *fmt,
> + va_list args)
> +{
> +char tmpbuffer[LOG_BUFFER_ENTRY_SIZE];
> +u64 ts_nsec = local_clock();
> +unsigned long rem_nsec;
> +
> +if (!chip->logbuffer[chip->logbuffer_head]) {
> +chip->logbuffer[chip->logbuffer_head] =
> +devm_kzalloc(chip->dev, LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL);
> +if (!chip->logbuffer[chip->logbuffer_head])
> +return;
> +}
> +
> +vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
> +
> +mutex_lock(&chip->logbuffer_lock);
> +
> +if (rt1711h_log_full(chip)) {
> +chip->logbuffer_head = max(chip->logbuffer_head - 1, 0);
> +strlcpy(tmpbuffer, "overflow", sizeof(tmpbuffer));
> +}
> +
> +if (chip->logbuffer_head < 0 ||
> +chip->logbuffer_head >= LOG_BUFFER_ENTRIES) {
> +dev_warn(chip->dev, "%s bad log buffer index %d\n", __func__,
> +chip->logbuffer_head);
> +goto abort;
> +}
> +
> +if (!chip->logbuffer[chip->logbuffer_head]) {
> +dev_warn(chip->dev, "%s log buffer index %d is NULL\n",
> +__func__, chip->logbuffer_head);
> +goto abort;
> +}
> +
> +rem_nsec = do_div(ts_nsec, 1000000000);
> +scnprintf(chip->logbuffer[chip->logbuffer_head], LOG_BUFFER_ENTRY_SIZE,
> +"[%5lu.%06lu] %s", (unsigned long)ts_nsec, rem_nsec / 1000,
> +  tmpbuffer);
> +chip->logbuffer_head = (chip->logbuffer_head + 1) %
> +LOG_BUFFER_ENTRIES;
> +
> +abort:
> +mutex_unlock(&chip->logbuffer_lock);
> +}
> +
> +static void rt1711h_log(struct rt1711h_chip *chip,
> +const char *fmt, ...)
> +{
> +va_list args;
> +
> +va_start(args, fmt);
> +_rt1711h_log(chip, fmt, args);
> +va_end(args);
> +}
> +
> +static int rt1711h_log_show(struct rt1711h_chip *chip, struct
> +seq_file *s) {
> +int tail;
> +
> +mutex_lock(&chip->logbuffer_lock);
> +tail = chip->logbuffer_tail;
> +while (tail != chip->logbuffer_head) {
> +seq_printf(s, "%s", chip->logbuffer[tail]);
> +tail = (tail + 1) % LOG_BUFFER_ENTRIES;
> +}
> +if (!seq_has_overflowed(s))
> +chip->logbuffer_tail = tail;
> +mutex_unlock(&chip->logbuffer_lock);
> +
> +return 0;
> +}
> +
> +static int rt1711h_regs_show(struct rt1711h_chip *chip, struct
> +seq_file *s) {
> +int ret = 0;
> +int i = 0, j = 0;
> +struct reg_desc *desc = NULL;
> +uint8_t regval[2] = {0};
> +
> +for (i = 0; i < ARRAY_SIZE(rt1711h_reg_desc); i++) {
> +desc = &rt1711h_reg_desc[i];
> +ret = rt1711h_reg_block_read(chip, desc->addr, desc->size,
> +regval);
> +if (ret < 0) {
> +dev_err(chip->dev, "%s read reg0x%02X fail\n",
> +__func__, desc->addr);
> +continue;
> +}
> +
> +seq_printf(s, "reg0x%02x:0x", desc->addr);
> +for (j = 0; j < desc->size; j++)
> +seq_printf(s, "%02x,", regval[j]);
> +seq_puts(s, "\n");
> +}
> +
> +return 0;
> +}
> +
> +static inline int rt1711h_reg_addr_show(struct rt1711h_chip *chip,
> +struct seq_file *s)
> +{
> +struct reg_desc *desc = &rt1711h_reg_desc[chip->dbg_regidx];
> +
> +seq_printf(s, "0x%02x\n", desc->addr);
> +return 0;
> +}
> +
> +static inline int rt1711h_data_show(struct rt1711h_chip *chip,
> +struct seq_file *s)
> +{
> +int ret = 0, i = 0;
> +struct reg_desc *desc = &rt1711h_reg_desc[chip->dbg_regidx];
> +uint8_t regval[2] = {0};
> +
> +ret = rt1711h_reg_block_read(chip, desc->addr, desc->size, regval);
> +if (ret < 0)
> +return ret;
> +
> +seq_printf(s, "reg0x%02x=0x", desc->addr);
> +for (i = 0; i < desc->size; i++)
> +seq_printf(s, "%02x,", regval[i]);
> +seq_puts(s, "\n");
> +return 0;
> +}
> +
> +static int rt1711h_dbg_show(struct seq_file *s, void *v) {
> +int ret = 0;
> +struct rt1711h_dbg_info *info = (struct rt1711h_dbg_info *)s->private;
> +struct rt1711h_chip *chip = info->chip;
> +
> +mutex_lock(&chip->dbgops_lock);
> +switch (info->id) {
> +case RT1711H_DBG_LOG:
> +ret = rt1711h_log_show(chip, s);
> +break;
> +case RT1711H_DBG_REGS:
> +ret = rt1711h_regs_show(chip, s);
> +break;
> +case RT1711H_DBG_REG_ADDR:
> +ret = rt1711h_reg_addr_show(chip, s);
> +break;
> +case RT1711H_DBG_DATA:
> +ret = rt1711h_data_show(chip, s);
> +break;
> +default:
> +ret = -EINVAL;
> +break;
> +}
> +
> +mutex_unlock(&chip->dbgops_lock);
> +return ret;
> +}
> +
> +static int rt1711h_dbg_open(struct inode *inode, struct file *file) {
> +if (file->f_mode & FMODE_READ)
> +return single_open(file, rt1711h_dbg_show, inode->i_private);
> +file->private_data = inode->i_private;
> +return 0;
> +}
> +
> +static int get_parameters(char *buf, long int *param1, int
> +num_of_par) {
> +char *token;
> +int base, cnt;
> +
> +token = strsep(&buf, " ");
> +
> +for (cnt = 0; cnt < num_of_par; cnt++) {
> +if (token != NULL) {
> +if ((token[1] == 'x') || (token[1] == 'X'))
> +base = 16;
> +else
> +base = 10;
> +
> +if (kstrtoul(token, base, &param1[cnt]) != 0)
> +return -EINVAL;
> +
> +token = strsep(&buf, " ");
> +} else
> +return -EINVAL;
> +}
> +return 0;
> +}

What is this function doing?  What is your debugfs files for?

> +
> +static int get_datas(const char *buf, const int length,
> +unsigned char *data_buffer, unsigned char data_length) {
> +int i, ptr;
> +long int value;
> +char token[5];
> +
> +token[0] = '0';
> +token[1] = 'x';
> +token[4] = 0;
> +if (buf[0] != '0' || buf[1] != 'x')
> +return -EINVAL;
> +
> +ptr = 2;
> +for (i = 0; (i < data_length) && (ptr + 2 <= length); i++) {
> +token[2] = buf[ptr++];
> +token[3] = buf[ptr++];
> +ptr++;
> +if (kstrtoul(token, 16, &value) != 0)
> +return -EINVAL;
> +data_buffer[i] = value;
> +}
> +return 0;
> +}
> +
> +static int rt1711h_regaddr2idx(uint8_t reg_addr) {
> +int i = 0;
> +struct reg_desc *desc = NULL;
> +
> +for (i = 0; i < ARRAY_SIZE(rt1711h_reg_desc); i++) {
> +desc = &rt1711h_reg_desc[i];
> +if (desc->addr == reg_addr)
> +return i;
> +}
> +return -EINVAL;
> +}
> +
> +static ssize_t rt1711h_dbg_write(struct file *file, const char __user *ubuf,
> +size_t count, loff_t *ppos)
> +{
> +int ret = 0;
> +struct rt1711h_dbg_info *info =
> +(struct rt1711h_dbg_info *)file->private_data;
> +struct rt1711h_chip *chip = info->chip;
> +struct reg_desc *desc = NULL;
> +char lbuf[128];
> +long int param[5];
> +unsigned char reg_data[2] = {0};
> +
> +if (count > sizeof(lbuf) - 1)
> +return -EFAULT;
> +
> +ret = copy_from_user(lbuf, ubuf, count);
> +if (ret)
> +return -EFAULT;
> +lbuf[count] = '\0';
> +
> +mutex_lock(&chip->dbgops_lock);
> +switch (info->id) {
> +case RT1711H_DBG_REG_ADDR:
> +ret = get_parameters(lbuf, param, 1);
> +if (ret < 0) {
> +dev_err(chip->dev, "%s get param fail\n", __func__);
> +ret = -EINVAL;
> +goto out;
> +}
> +ret = rt1711h_regaddr2idx(param[0]);
> +if (ret < 0) {
> +dev_err(chip->dev, "%s addr2idx fail\n", __func__);
> +ret = -EINVAL;
> +goto out;
> +}
> +chip->dbg_regidx = ret;
> +break;
> +case RT1711H_DBG_DATA:
> +desc = &rt1711h_reg_desc[chip->dbg_regidx];
> +if ((desc->size - 1) * 3 + 5 != count) {
> +dev_err(chip->dev, "%s incorrect input length\n",
> +__func__);
> +ret = -EINVAL;
> +goto out;
> +}
> +ret = get_datas((char *)ubuf, count, reg_data, desc->size);
> +if (ret < 0) {
> +dev_err(chip->dev, "%s get data fail\n", __func__);
> +ret = -EINVAL;
> +goto out;
> +}
> +ret = rt1711h_reg_block_write(chip, desc->addr, desc->size,
> +reg_data);
> +break;
> +default:
> +ret = -EINVAL;
> +break;
> +}
> +
> +out:
> +mutex_unlock(&chip->dbgops_lock);
> +return ret < 0 ? ret : count;
> +}
> +
> +static int rt1711h_dbg_release(struct inode *inode, struct file
> +*file) {
> +if (file->f_mode & FMODE_READ)
> +return single_release(inode, file);
> +return 0;
> +}
> +
> +static const struct file_operations rt1711h_dbg_ops = {
> +.open= rt1711h_dbg_open,
> +.llseek= seq_lseek,
> +.read= seq_read,
> +.write= rt1711h_dbg_write,
> +.release= rt1711h_dbg_release,
> +};
> +
> +
> +static int rt1711h_debugfs_init(struct rt1711h_chip *chip) {
> +int ret = 0, i = 0;
> +struct rt1711h_dbg_info *info = NULL;
> +int len = 0;
> +char *dirname = NULL;
> +
> +mutex_init(&chip->logbuffer_lock);
> +mutex_init(&chip->dbgops_lock);
> +len = strlen(dev_name(chip->dev));
> +dirname = devm_kzalloc(chip->dev, len + 9, GFP_KERNEL);
> +if (!dirname)
> +return -ENOMEM;
> +snprintf(dirname, len + 9, "rt1711h-%s", dev_name(chip->dev));
> +if (!chip->dbgdir) {
> +chip->dbgdir = debugfs_create_dir(dirname, NULL);
> +if (!chip->dbgdir)
> +return -ENOMEM;

No need to ever check the return value of debugfs_ calls, you should not care and can always use the value to any future debugfs calls, if you really need it.

> +}
> +
> +for (i = 0; i < RT1711H_DBG_MAX; i++) {
> +info = &chip->dbg_info[i];

static array of debug info?  That feels odd.

> +info->chip = chip;
> +info->id = i;
> +chip->dbg_files[i] = debugfs_create_file(
> +rt1711h_dbg_filename[i], S_IFREG | 0444,
> +chip->dbgdir, info, &rt1711h_dbg_ops);
> +if (!chip->dbg_files[i]) {
> +ret = -EINVAL;

Like here, you don't need this, and you don't need to care about the return value.

> +goto err;
> +}
> +}
> +
> +return 0;
> +err:
> +debugfs_remove_recursive(chip->dbgdir);
> +return ret;

Why do you care about an error here?  Your code should not do anything different if debugfs stuff does not work or if it does.  It's debugging only.

> +}
> +
> +static void rt1711h_debugfs_exit(struct rt1711h_chip *chip) {
> +debugfs_remove_recursive(chip->dbgdir);

See, you didn't need those file handles :)

thanks,

greg k-h
************* Email Confidentiality Notice ********************

The information contained in this e-mail message (including any attachments) may be confidential, proprietary, privileged, or otherwise exempt from disclosure under applicable laws. It is intended to be conveyed only to the designated recipient(s). Any use, dissemination, distribution, printing, retaining or copying of this e-mail (including its attachments) by unintended recipient(s) is strictly prohibited and may be unlawful. If you are not an intended recipient of this e-mail, or believe that you have received this e-mail in error, please notify the sender immediately (by replying to this e-mail), delete any and all copies of this e-mail (including any attachments) from your system, and do not disclose the content of this e-mail to any other person. Thank you!

WARNING: multiple messages have this Message-ID (diff)
From: "shufan_lee(李書帆)" <shufan_lee@richtek.com>
To: 'Greg KH' <greg@kroah.com>, ShuFanLee <leechu729@gmail.com>
Cc: "heikki.krogerus@linux.intel.com"
	<heikki.krogerus@linux.intel.com>,
	"cy_huang(黃啟原)" <cy_huang@richtek.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>
Subject: USB TYPEC: RT1711H Type-C Chip Driver
Date: Thu, 18 Jan 2018 13:13:15 +0000	[thread overview]
Message-ID: <f94537a67a1544d1937eae3dbfcd554f@ex1.rt.l> (raw)

RGVhciBHZXJnLA0KDQogIE1hbnkgdGhhbmtzIHRvIHlvdXIgY29tbWVudC4NCiAgSSd2ZSBjaGVj
a2VkIGFsbCBvZiB0aGVtIGFuZCBoZXJlIGFyZSBzb21lIHF1ZXN0aW9ucyBuZWVkIHlvdXIgaGVs
cC4NCg0KPiArRXhhbXBsZToNCj4gK3J0MTcxMWhANGUgew0KPiArc3RhdHVzID0gIm9rIjsNCj4g
K2NvbXBhdGlibGUgPSAicmljaHRlayx0eXBlY19ydDE3MTFoIjsNCj4gK3JlZyA9IDwweDRlPjsN
Cj4gK3J0LGludHJfZ3BpbyA9IDwmZ3BpbzI2IDAgMHgwPjsNCj4gK3J0LG5hbWUgPSAicnQxNzEx
aCI7DQo+ICtydCxwb3J0X3R5cGUgPSA8Mj47IC8qIDA6IERGUCwgMTogVUZQLCAyOiBEUlAgKi8N
Cj4gK3J0LGRlZl9yb2xlID0gPDA+OyAvKiAwOiBTTkssIDE6IFNSQywgLTE6IFRZUEVDX05PX1BS
RUZFUlJFRF9ST0xFICovDQo+ICt9Ow0KDQpkdHMgc3R1ZmYgbmVlZHMgdG8gYWx3YXlzIGJlIGlu
IGEgc2VwYXJhdGUgZmlsZSBzbyB0aGUgRFQgbWFpbnRhaW5lcnMgY2FuIHJldmlldy9hY2sgaXQu
ICBTcGxpdCB0aGlzIHBhdGNoIHVwIGludG8gc21hbGxlciBwaWVjZXMgcGxlYXNlLg0KDQpPaywg
SSdsbCBzcGxpdCBpdCBpbnRvIHR3byBwYXRjaGVzLCBvbmUgZm9yIHNvdXJjZSBjb2RlIGFuZCBv
bmNlIGZvciBkdHMgcmVsYXRlZCBmaWxlcy4NCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQo+IGRpZmYgLS1n
aXQgYS9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZSBiL2RyaXZlcnMvdXNiL3R5cGVjL01ha2Vm
aWxlDQo+IGluZGV4IGJiMzEzOGEuLmUzYWFmM2MgMTAwNjQ0DQo+IC0tLSBhL2RyaXZlcnMvdXNi
L3R5cGVjL01ha2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvdXNiL3R5cGVjL01ha2VmaWxlDQo+IEBA
IC0yLDYgKzIsNyBAQA0KPiAgb2JqLSQoQ09ORklHX1RZUEVDKSs9IHR5cGVjLm8NCj4gIG9iai0k
KENPTkZJR19UWVBFQ19UQ1BNKSs9IHRjcG0ubw0KPiAgb2JqLXkrPSBmdXNiMzAyLw0KPiArb2Jq
LSQoQ09ORklHX1RZUEVDX1JUMTcxMUgpKz0gcnQxNzExaC8NCg0KV2h5IGRvIHlvdSBuZWVkIGEg
d2hvbGUgZGlyZWN0b3J5IGZvciBvbmUgZmlsZT8NCg0KSXMgdGhlIHN1Z2dlc3Rpb24gdG8gbW92
ZSBydDE3MTFoLmMgdG8gdGhlIHNhbWUgZGlyZWN0b3J5IGxldmVsIGFzIHRjcG0/IGkuZS4gZHJp
dmVycy91c2IvdHlwZWMvcnQxNzExaC5jDQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KPiArPHVhcGkvbGlu
dXgvc2NoZWQvdHlwZXMuaD4NCg0KVGhpcyBsYXN0ICNpbmNsdWRlIHNob3VsZCBub3QgYmUgbmVl
ZGVkLiAgSWYgaXQgZG9lcywgeW91IGFyZSBkb2luZyBzb21ldGhpbmcgcmVhbGx5IHdyb25nLi4u
DQoNCk9rLCB0aGlzICNpbmNsdWRlIHdpbGwgYmUgcmVtb3ZlZA0KPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoN
Cj4gKw0KPiArI2luY2x1ZGUgInJ0MTcxMWguaCINCg0KV2h5IGEgLmggZmlsZSBmb3IgYSBzaW5n
bGUgLmMgZmlsZT8NCg0KSXMgdGhlIHN1Z2dlc3Rpb24gdG8gbW92ZSBhbGwgY29udGVudCBpbiBy
dDE3MTFoLmggaW50byBydDE3MTFoLmM/DQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KPiArDQo+ICsjZGVm
aW5lIFJUMTcxMUhfRFJWX1ZFUlNJT04iMS4wLjMiDQoNCldoZW4gY29kZSBpcyBpbiB0aGUga2Vy
bmVsIHRyZWUsIHZlcnNpb25zIG1lYW4gbm90aGluZywgeW91IHdpbGwgbm90ZSB0aGF0IG5vIG90
aGVyIFVTQiBkcml2ZXIgaGFzIHRoZW0sIHJpZ2h0PyAgUGxlYXNlIHJlbW92ZS4NCg0KT2ssIHRo
aXMgd2lsbCBiZSByZW1vdmVkLg0KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNCmtlcm5lbCB0eXBlcyBhcmUg
dTE2LCB1MzIsIHU4LCBhbmQgdGhlIGxpa2UsIG5vdCB1aW50MTZfdCwgdGhvc2UgYXJlIGZvciB1
c2Vyc3BhY2UgY29kZSBvbmx5Lg0KWWVhaCwgb3RoZXIgZHJpdmVycyBkbyBpdCwgYnV0IHlvdSBz
aG91bGRuJ3QgOikNCg0KT2ssIEknbGwgdXNlIHUxNiwgdTMyIGFuZCB1OCBpbnN0ZWFkIG9mIHVp
bnQxNl90LCB1aW50MzJfdCBhbmQgdWludDhfdA0KPT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNCj4gKy8qIElS
USAqLw0KPiArc3RydWN0IGt0aHJlYWRfd29ya2VyIGlycV93b3JrZXI7DQo+ICtzdHJ1Y3Qga3Ro
cmVhZF93b3JrIGlycV93b3JrOw0KPiArc3RydWN0IHRhc2tfc3RydWN0ICppcnFfd29ya2VyX3Rh
c2s7DQoNCjMgdGhpbmdzIGZvciBhbiBpcnEgaGFuZGxlcj8gIFRoYXQgZmVlbHMgd3JvbmcuDQoN
Cj4gK2F0b21pY190IHBvbGxfY291bnQ7DQoNCkxpa2UgSSBzYWlkIGJlZm9yZSwgd2h5IGlzIHRo
aXMgYW4gYXRvbWljPw0KDQpJJ2xsIHVzZSB0aHJlYWRlZF9pcnEgaW5zdGVhZCwgdGhlIGFib3Zl
IHRoaW5ncyB3aWxsIGJlIHJlbW92ZWQuDQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KPiArLyogSTJDICov
DQo+ICthdG9taWNfdCBpMmNfYnVzeTsNCj4gK2F0b21pY190IHBtX3N1c3BlbmQ7DQoNCldoeSBh
cmUgdGhlc2UgYXRvbWljPyAgWW91IGtub3cgdGhhdCBkb2Vzbid0IG1lYW4gdGhleSBkbyBub3Qg
bmVlZCBsb2NraW5nLCByaWdodD8NCg0KRm9yIG15IHVuZGVyc3RhbmRpbmcsIGEgc2luZ2xlIG9w
ZXJhdGlvbiBvbiBhdG9taWNfdCBkb2Vzbid0IG5lZWQgbG9jaywgbGlrZSBhIHNpbmdsZSBhdG9t
aWNfc2V0Lg0KQnV0IHR3byBjb25zZWN1dGl2ZSBvcGVyYXRpb25zIGRvZXNuJ3QgZ3VhcmFudGVl
IGFueXRoaW5nLiBMaWtlIGF0b21pY19zZXQgZm9sbG93ZWQgYnkgYW4gYXRvbWljX3JlYWQuDQpU
aGlzIHBhcnQgaXMgcmVmZXJlbmNlZCBmcm9tIGZ1c2IzMDIgdXNlZCB0byBtYWtlIHN1cmUgSTJD
IGlzIGlkbGUgYmVmb3JlIHN5c3RlbSBzdXNwZW5kcy4NCkl0IG9ubHkgbmVlZHMgdG8gZ3VhcmFu
dGVlIGEgc2luZ2xlIHJlYWQvd3JpdGUgb24gdGhlc2UgdmFyaWFibGUgaXMgYXRvbWljIG9wZXJh
dGlvbiwgc28gYXRvbWljIGlzIHVzZWQuDQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KPiArfTsNCj4gKw0K
PiArLyoNCj4gKyAqIExvZ2dpbmcgJiBkZWJ1Z2dpbmcNCj4gKyAqLw0KPiArDQo+ICsjaWZkZWYg
Q09ORklHX0RFQlVHX0ZTDQo+ICsNCj4gK3N0YXRpYyBpbnQgcnQxNzExaF9yZWdfYmxvY2tfcmVh
ZChzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLCB1aW50OF90IHJlZywNCj4gK2ludCBsZW4sIHVp
bnQ4X3QgKmRhdGEpOw0KPiArc3RhdGljIGludCBydDE3MTFoX3JlZ19ibG9ja193cml0ZShzdHJ1
Y3QgcnQxNzExaF9jaGlwICpjaGlwLCB1aW50OF90IHJlZywNCj4gK2ludCBsZW4sIGNvbnN0IHVp
bnQ4X3QgKmRhdGEpOw0KPiArDQo+ICtzdHJ1Y3QgcmVnX2Rlc2Mgew0KPiArdWludDhfdCBhZGRy
Ow0KPiArdWludDhfdCBzaXplOw0KPiArfTsNCj4gKyNkZWZpbmUgREVDTF9SRUcoX2FkZHIsIF9z
aXplKSB7LmFkZHIgPSBfYWRkciwgLnNpemUgPSBfc2l6ZX0NCj4gKw0KPiArc3RhdGljIHN0cnVj
dCByZWdfZGVzYyBydDE3MTFoX3JlZ19kZXNjW10gPSB7DQo+ICtERUNMX1JFRyhSVDE3MTFIX1JF
R19WSUQsIDIpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfUElELCAyKSwNCj4gK0RFQ0xfUkVH
KFJUMTcxMUhfUkVHX0RJRCwgMiksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19UWVBFQ19SRVYs
IDIpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfUERfUkVWLCAyKSwNCj4gK0RFQ0xfUkVHKFJU
MTcxMUhfUkVHX1BESUZfUkVWLCAyKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0FMRVJULCAy
KSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0FMRVJUX01BU0ssIDIpLA0KPiArREVDTF9SRUco
UlQxNzExSF9SRUdfUE9XRVJfU1RBVFVTX01BU0ssIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9S
RUdfRkFVTFRfU1RBVFVTX01BU0ssIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfVENQQ19D
VFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JPTEVfQ1RSTCwgMSksDQo+ICtERUNM
X1JFRyhSVDE3MTFIX1JFR19GQVVMVF9DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVH
X1BPV0VSX0NUUkwsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfQ0NfU1RBVFVTLCAxKSwN
Cj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1BPV0VSX1NUQVRVUywgMSksDQo+ICtERUNMX1JFRyhS
VDE3MTFIX1JFR19GQVVMVF9TVEFUVVMsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfQ09N
TUFORCwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19NU0dfSERSX0lORk8sIDEpLA0KPiAr
REVDTF9SRUcoUlQxNzExSF9SRUdfUlhfREVURUNULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhf
UkVHX1JYX0JZVEVfQ05ULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JYX0JVRl9GUkFN
RV9UWVBFLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JYX0hEUiwgMiksDQo+ICtERUNM
X1JFRyhSVDE3MTFIX1JFR19SWF9EQVRBLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1RS
QU5TTUlULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1RYX0JZVEVfQ05ULCAxKSwNCj4g
K0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1RYX0hEUiwgMiksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JF
R19UWF9EQVRBLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0NMS19DVFJMMiwgMSksDQo+
ICtERUNMX1JFRyhSVDE3MTFIX1JFR19DTEtfQ1RSTDMsIDEpLA0KPiArREVDTF9SRUcoUlQxNzEx
SF9SRUdfQk1DX0NUUkwsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfQk1DSU9fUlhEWlNF
TCwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19WQ09OTl9DTElNSVRFTiwgMSksDQo+ICtE
RUNMX1JFRyhSVDE3MTFIX1JFR19SVF9TVEFUVVMsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9S
RUdfUlRfSU5ULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JUX01BU0ssIDEpLA0KPiAr
REVDTF9SRUcoUlQxNzExSF9SRUdfSURMRV9DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhf
UkVHX0lOVFJTVF9DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1dBVENIRE9HX0NU
UkwsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfSTJDUlNUX0NUUkwsIDEpLA0KPiArREVD
TF9SRUcoUlQxNzExSF9SRUdfU1dSRVNFVCwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19U
VENQQ19GSUxURVIsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfRFJQX1RPR0dMRV9DWUNM
RSwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19EUlBfRFVUWV9DVFJMLCAxKSwNCj4gK0RF
Q0xfUkVHKFJUMTcxMUhfUkVHX0JNQ0lPX1JYRFpFTiwgMSksIH07DQo+ICsNCj4gK3N0YXRpYyBj
b25zdCBjaGFyICpydDE3MTFoX2RiZ19maWxlbmFtZVtSVDE3MTFIX0RCR19NQVhdID0gew0KPiAr
ImxvZyIsICJyZWdzIiwgInJlZ19hZGRyIiwgImRhdGEiLA0KPiArfTsNCj4gKw0KPiArc3RhdGlj
IGJvb2wgcnQxNzExaF9sb2dfZnVsbChzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwKSB7DQo+ICty
ZXR1cm4gY2hpcC0+bG9nYnVmZmVyX3RhaWwgPT0NCj4gKyhjaGlwLT5sb2didWZmZXJfaGVhZCAr
IDEpICUgTE9HX0JVRkZFUl9FTlRSSUVTOyB9DQo+ICsNCj4gK3N0YXRpYyB2b2lkIF9ydDE3MTFo
X2xvZyhzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLCBjb25zdCBjaGFyICpmbXQsDQo+ICsgdmFf
bGlzdCBhcmdzKQ0KPiArew0KPiArY2hhciB0bXBidWZmZXJbTE9HX0JVRkZFUl9FTlRSWV9TSVpF
XTsNCj4gK3U2NCB0c19uc2VjID0gbG9jYWxfY2xvY2soKTsNCj4gK3Vuc2lnbmVkIGxvbmcgcmVt
X25zZWM7DQo+ICsNCj4gK2lmICghY2hpcC0+bG9nYnVmZmVyW2NoaXAtPmxvZ2J1ZmZlcl9oZWFk
XSkgew0KPiArY2hpcC0+bG9nYnVmZmVyW2NoaXAtPmxvZ2J1ZmZlcl9oZWFkXSA9DQo+ICtkZXZt
X2t6YWxsb2MoY2hpcC0+ZGV2LCBMT0dfQlVGRkVSX0VOVFJZX1NJWkUsIEdGUF9LRVJORUwpOw0K
PiAraWYgKCFjaGlwLT5sb2didWZmZXJbY2hpcC0+bG9nYnVmZmVyX2hlYWRdKQ0KPiArcmV0dXJu
Ow0KPiArfQ0KPiArDQo+ICt2c25wcmludGYodG1wYnVmZmVyLCBzaXplb2YodG1wYnVmZmVyKSwg
Zm10LCBhcmdzKTsNCj4gKw0KPiArbXV0ZXhfbG9jaygmY2hpcC0+bG9nYnVmZmVyX2xvY2spOw0K
PiArDQo+ICtpZiAocnQxNzExaF9sb2dfZnVsbChjaGlwKSkgew0KPiArY2hpcC0+bG9nYnVmZmVy
X2hlYWQgPSBtYXgoY2hpcC0+bG9nYnVmZmVyX2hlYWQgLSAxLCAwKTsNCj4gK3N0cmxjcHkodG1w
YnVmZmVyLCAib3ZlcmZsb3ciLCBzaXplb2YodG1wYnVmZmVyKSk7DQo+ICt9DQo+ICsNCj4gK2lm
IChjaGlwLT5sb2didWZmZXJfaGVhZCA8IDAgfHwNCj4gK2NoaXAtPmxvZ2J1ZmZlcl9oZWFkID49
IExPR19CVUZGRVJfRU5UUklFUykgew0KPiArZGV2X3dhcm4oY2hpcC0+ZGV2LCAiJXMgYmFkIGxv
ZyBidWZmZXIgaW5kZXggJWRcbiIsIF9fZnVuY19fLA0KPiArY2hpcC0+bG9nYnVmZmVyX2hlYWQp
Ow0KPiArZ290byBhYm9ydDsNCj4gK30NCj4gKw0KPiAraWYgKCFjaGlwLT5sb2didWZmZXJbY2hp
cC0+bG9nYnVmZmVyX2hlYWRdKSB7DQo+ICtkZXZfd2FybihjaGlwLT5kZXYsICIlcyBsb2cgYnVm
ZmVyIGluZGV4ICVkIGlzIE5VTExcbiIsDQo+ICtfX2Z1bmNfXywgY2hpcC0+bG9nYnVmZmVyX2hl
YWQpOw0KPiArZ290byBhYm9ydDsNCj4gK30NCj4gKw0KPiArcmVtX25zZWMgPSBkb19kaXYodHNf
bnNlYywgMTAwMDAwMDAwMCk7DQo+ICtzY25wcmludGYoY2hpcC0+bG9nYnVmZmVyW2NoaXAtPmxv
Z2J1ZmZlcl9oZWFkXSwgTE9HX0JVRkZFUl9FTlRSWV9TSVpFLA0KPiArIlslNWx1LiUwNmx1XSAl
cyIsICh1bnNpZ25lZCBsb25nKXRzX25zZWMsIHJlbV9uc2VjIC8gMTAwMCwNCj4gKyAgdG1wYnVm
ZmVyKTsNCj4gK2NoaXAtPmxvZ2J1ZmZlcl9oZWFkID0gKGNoaXAtPmxvZ2J1ZmZlcl9oZWFkICsg
MSkgJQ0KPiArTE9HX0JVRkZFUl9FTlRSSUVTOw0KPiArDQo+ICthYm9ydDoNCj4gK211dGV4X3Vu
bG9jaygmY2hpcC0+bG9nYnVmZmVyX2xvY2spOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgdm9pZCBy
dDE3MTFoX2xvZyhzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLA0KPiArY29uc3QgY2hhciAqZm10
LCAuLi4pDQo+ICt7DQo+ICt2YV9saXN0IGFyZ3M7DQo+ICsNCj4gK3ZhX3N0YXJ0KGFyZ3MsIGZt
dCk7DQo+ICtfcnQxNzExaF9sb2coY2hpcCwgZm10LCBhcmdzKTsNCj4gK3ZhX2VuZChhcmdzKTsN
Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBydDE3MTFoX2xvZ19zaG93KHN0cnVjdCBydDE3MTFo
X2NoaXAgKmNoaXAsIHN0cnVjdA0KPiArc2VxX2ZpbGUgKnMpIHsNCj4gK2ludCB0YWlsOw0KPiAr
DQo+ICttdXRleF9sb2NrKCZjaGlwLT5sb2didWZmZXJfbG9jayk7DQo+ICt0YWlsID0gY2hpcC0+
bG9nYnVmZmVyX3RhaWw7DQo+ICt3aGlsZSAodGFpbCAhPSBjaGlwLT5sb2didWZmZXJfaGVhZCkg
ew0KPiArc2VxX3ByaW50ZihzLCAiJXMiLCBjaGlwLT5sb2didWZmZXJbdGFpbF0pOw0KPiArdGFp
bCA9ICh0YWlsICsgMSkgJSBMT0dfQlVGRkVSX0VOVFJJRVM7DQo+ICt9DQo+ICtpZiAoIXNlcV9o
YXNfb3ZlcmZsb3dlZChzKSkNCj4gK2NoaXAtPmxvZ2J1ZmZlcl90YWlsID0gdGFpbDsNCj4gK211
dGV4X3VubG9jaygmY2hpcC0+bG9nYnVmZmVyX2xvY2spOw0KPiArDQo+ICtyZXR1cm4gMDsNCj4g
K30NCj4gKw0KPiArc3RhdGljIGludCBydDE3MTFoX3JlZ3Nfc2hvdyhzdHJ1Y3QgcnQxNzExaF9j
aGlwICpjaGlwLCBzdHJ1Y3QNCj4gK3NlcV9maWxlICpzKSB7DQo+ICtpbnQgcmV0ID0gMDsNCj4g
K2ludCBpID0gMCwgaiA9IDA7DQo+ICtzdHJ1Y3QgcmVnX2Rlc2MgKmRlc2MgPSBOVUxMOw0KPiAr
dWludDhfdCByZWd2YWxbMl0gPSB7MH07DQo+ICsNCj4gK2ZvciAoaSA9IDA7IGkgPCBBUlJBWV9T
SVpFKHJ0MTcxMWhfcmVnX2Rlc2MpOyBpKyspIHsNCj4gK2Rlc2MgPSAmcnQxNzExaF9yZWdfZGVz
Y1tpXTsNCj4gK3JldCA9IHJ0MTcxMWhfcmVnX2Jsb2NrX3JlYWQoY2hpcCwgZGVzYy0+YWRkciwg
ZGVzYy0+c2l6ZSwNCj4gK3JlZ3ZhbCk7DQo+ICtpZiAocmV0IDwgMCkgew0KPiArZGV2X2Vycihj
aGlwLT5kZXYsICIlcyByZWFkIHJlZzB4JTAyWCBmYWlsXG4iLA0KPiArX19mdW5jX18sIGRlc2Mt
PmFkZHIpOw0KPiArY29udGludWU7DQo+ICt9DQo+ICsNCj4gK3NlcV9wcmludGYocywgInJlZzB4
JTAyeDoweCIsIGRlc2MtPmFkZHIpOw0KPiArZm9yIChqID0gMDsgaiA8IGRlc2MtPnNpemU7IGor
KykNCj4gK3NlcV9wcmludGYocywgIiUwMngsIiwgcmVndmFsW2pdKTsNCj4gK3NlcV9wdXRzKHMs
ICJcbiIpOw0KPiArfQ0KPiArDQo+ICtyZXR1cm4gMDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlu
bGluZSBpbnQgcnQxNzExaF9yZWdfYWRkcl9zaG93KHN0cnVjdCBydDE3MTFoX2NoaXAgKmNoaXAs
DQo+ICtzdHJ1Y3Qgc2VxX2ZpbGUgKnMpDQo+ICt7DQo+ICtzdHJ1Y3QgcmVnX2Rlc2MgKmRlc2Mg
PSAmcnQxNzExaF9yZWdfZGVzY1tjaGlwLT5kYmdfcmVnaWR4XTsNCj4gKw0KPiArc2VxX3ByaW50
ZihzLCAiMHglMDJ4XG4iLCBkZXNjLT5hZGRyKTsNCj4gK3JldHVybiAwOw0KPiArfQ0KPiArDQo+
ICtzdGF0aWMgaW5saW5lIGludCBydDE3MTFoX2RhdGFfc2hvdyhzdHJ1Y3QgcnQxNzExaF9jaGlw
ICpjaGlwLA0KPiArc3RydWN0IHNlcV9maWxlICpzKQ0KPiArew0KPiAraW50IHJldCA9IDAsIGkg
PSAwOw0KPiArc3RydWN0IHJlZ19kZXNjICpkZXNjID0gJnJ0MTcxMWhfcmVnX2Rlc2NbY2hpcC0+
ZGJnX3JlZ2lkeF07DQo+ICt1aW50OF90IHJlZ3ZhbFsyXSA9IHswfTsNCj4gKw0KPiArcmV0ID0g
cnQxNzExaF9yZWdfYmxvY2tfcmVhZChjaGlwLCBkZXNjLT5hZGRyLCBkZXNjLT5zaXplLCByZWd2
YWwpOw0KPiAraWYgKHJldCA8IDApDQo+ICtyZXR1cm4gcmV0Ow0KPiArDQo+ICtzZXFfcHJpbnRm
KHMsICJyZWcweCUwMng9MHgiLCBkZXNjLT5hZGRyKTsNCj4gK2ZvciAoaSA9IDA7IGkgPCBkZXNj
LT5zaXplOyBpKyspDQo+ICtzZXFfcHJpbnRmKHMsICIlMDJ4LCIsIHJlZ3ZhbFtpXSk7DQo+ICtz
ZXFfcHV0cyhzLCAiXG4iKTsNCj4gK3JldHVybiAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50
IHJ0MTcxMWhfZGJnX3Nob3coc3RydWN0IHNlcV9maWxlICpzLCB2b2lkICp2KSB7DQo+ICtpbnQg
cmV0ID0gMDsNCj4gK3N0cnVjdCBydDE3MTFoX2RiZ19pbmZvICppbmZvID0gKHN0cnVjdCBydDE3
MTFoX2RiZ19pbmZvICopcy0+cHJpdmF0ZTsNCj4gK3N0cnVjdCBydDE3MTFoX2NoaXAgKmNoaXAg
PSBpbmZvLT5jaGlwOw0KPiArDQo+ICttdXRleF9sb2NrKCZjaGlwLT5kYmdvcHNfbG9jayk7DQo+
ICtzd2l0Y2ggKGluZm8tPmlkKSB7DQo+ICtjYXNlIFJUMTcxMUhfREJHX0xPRzoNCj4gK3JldCA9
IHJ0MTcxMWhfbG9nX3Nob3coY2hpcCwgcyk7DQo+ICticmVhazsNCj4gK2Nhc2UgUlQxNzExSF9E
QkdfUkVHUzoNCj4gK3JldCA9IHJ0MTcxMWhfcmVnc19zaG93KGNoaXAsIHMpOw0KPiArYnJlYWs7
DQo+ICtjYXNlIFJUMTcxMUhfREJHX1JFR19BRERSOg0KPiArcmV0ID0gcnQxNzExaF9yZWdfYWRk
cl9zaG93KGNoaXAsIHMpOw0KPiArYnJlYWs7DQo+ICtjYXNlIFJUMTcxMUhfREJHX0RBVEE6DQo+
ICtyZXQgPSBydDE3MTFoX2RhdGFfc2hvdyhjaGlwLCBzKTsNCj4gK2JyZWFrOw0KPiArZGVmYXVs
dDoNCj4gK3JldCA9IC1FSU5WQUw7DQo+ICticmVhazsNCj4gK30NCj4gKw0KPiArbXV0ZXhfdW5s
b2NrKCZjaGlwLT5kYmdvcHNfbG9jayk7DQo+ICtyZXR1cm4gcmV0Ow0KPiArfQ0KPiArDQo+ICtz
dGF0aWMgaW50IHJ0MTcxMWhfZGJnX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZp
bGUgKmZpbGUpIHsNCj4gK2lmIChmaWxlLT5mX21vZGUgJiBGTU9ERV9SRUFEKQ0KPiArcmV0dXJu
IHNpbmdsZV9vcGVuKGZpbGUsIHJ0MTcxMWhfZGJnX3Nob3csIGlub2RlLT5pX3ByaXZhdGUpOw0K
PiArZmlsZS0+cHJpdmF0ZV9kYXRhID0gaW5vZGUtPmlfcHJpdmF0ZTsNCj4gK3JldHVybiAwOw0K
PiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IGdldF9wYXJhbWV0ZXJzKGNoYXIgKmJ1ZiwgbG9uZyBp
bnQgKnBhcmFtMSwgaW50DQo+ICtudW1fb2ZfcGFyKSB7DQo+ICtjaGFyICp0b2tlbjsNCj4gK2lu
dCBiYXNlLCBjbnQ7DQo+ICsNCj4gK3Rva2VuID0gc3Ryc2VwKCZidWYsICIgIik7DQo+ICsNCj4g
K2ZvciAoY250ID0gMDsgY250IDwgbnVtX29mX3BhcjsgY250KyspIHsNCj4gK2lmICh0b2tlbiAh
PSBOVUxMKSB7DQo+ICtpZiAoKHRva2VuWzFdID09ICd4JykgfHwgKHRva2VuWzFdID09ICdYJykp
DQo+ICtiYXNlID0gMTY7DQo+ICtlbHNlDQo+ICtiYXNlID0gMTA7DQo+ICsNCj4gK2lmIChrc3Ry
dG91bCh0b2tlbiwgYmFzZSwgJnBhcmFtMVtjbnRdKSAhPSAwKQ0KPiArcmV0dXJuIC1FSU5WQUw7
DQo+ICsNCj4gK3Rva2VuID0gc3Ryc2VwKCZidWYsICIgIik7DQo+ICt9IGVsc2UNCj4gK3JldHVy
biAtRUlOVkFMOw0KPiArfQ0KPiArcmV0dXJuIDA7DQo+ICt9DQoNCldoYXQgaXMgdGhpcyBmdW5j
dGlvbiBkb2luZz8gIFdoYXQgaXMgeW91ciBkZWJ1Z2ZzIGZpbGVzIGZvcj8NCg0KVGhlcmUgYXJl
IDQgZGVidWcgZmlsZXMuDQpGaXJzdChsb2cpIGlzIGZvciBsb2dnaW5nIHdoaWNoIG5lZWRzIGEg
bG9jayBmb3IgbG9nIGJ1ZmZlci4gVGhlIHdheSB0byBsb2cgaXMgcmVmZXJlbmNlZCBmcm9tIGZ1
c2IzMDIgYW5kIHRjcG0uDQpTZWNvbmQocmVncykgaXMgdXNlZCB0byBkdW1wIGFsbCByZWdpc3Rl
ciBvZiBydDE3MTFoLg0KVGhpcmQocmVnX2FkZHIpJkZvcnRoKGRhdGEpIGFyZSB1c2VkIHRvIHdy
aXRlL3JlYWQgYSByZWdpc3RlciBzcGVjaWZpZWQgaW4gcmVnX2FkZHIuDQpUaGUgcmVhc29uIHRv
IGNyZWF0ZSB0aGVzZSBkZWJ1ZyBmaWxlcyBpcyB0byBtYWtlIGlzc3VlIHN1cHBvcnQgZWFzaWVy
Lg0KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09DQoNCj4gKyNpZmRlZiBDT05GSUdfREVCVUdfRlMNCj4gK3N0cnVj
dCBkZW50cnkgKmRiZ2RpcjsNCj4gK3N0cnVjdCBydDE3MTFoX2RiZ19pbmZvIGRiZ19pbmZvW1JU
MTcxMUhfREJHX01BWF07DQo+ICtzdHJ1Y3QgZGVudHJ5ICpkYmdfZmlsZXNbUlQxNzExSF9EQkdf
TUFYXTsNCj4gK2ludCBkYmdfcmVnaWR4Ow0KPiArc3RydWN0IG11dGV4IGRiZ29wc19sb2NrOw0K
PiArLyogbG9jayBmb3IgbG9nIGJ1ZmZlciBhY2Nlc3MgKi8NCj4gK3N0cnVjdCBtdXRleCBsb2di
dWZmZXJfbG9jazsNCj4gK2ludCBsb2didWZmZXJfaGVhZDsNCj4gK2ludCBsb2didWZmZXJfdGFp
bDsNCj4gK3U4ICpsb2didWZmZXJbTE9HX0JVRkZFUl9FTlRSSUVTXTsNCj4gKyNlbmRpZiAvKiBD
T05GSUdfREVCVUdfRlMgKi8NCg0KVGhhdCdzIGEgbG90IG9mIHN0dWZmIGpzdXQgZm9yIGRlYnVn
ZnMuICBXaHkgZG8geW91IGNhcmUgYWJvdXQgI2RlZmluZSBhdCBhbGw/ICBUaGUgY29kZSBzaG91
bGQgbm90Lg0KDQpJcyB0aGUgc3VnZ2VzdGlvbiB0byByZW1vdmUgI2lmZGVmIENPTkZJR19ERUJV
R19GUz8NCg0KQW5kIGFub3RoZXIgMiBsb2Nrcz8gIEljaywgbm8uDQoNCmRiZ29wc19sb2NrIGlz
IHVzZWQgdG8gcHJldmVudCB1c2VyIGZyb20gYWNjZXNzaW5nIGRpZmZlcmVudCBkZWJ1ZyBmaWxl
cyBzaW11bHRhbmVvdXNseS4NCklzIHRoZSBzdWdnZXN0aW9uIHRvIHVzZSB0aGUgbG9jayBvZiB0
aGUgZm9sbG93aW5nIG9uZT8NCj4gKy8qIGxvY2sgZm9yIHNoYXJpbmcgY2hpcCBzdGF0ZXMgKi8N
Cj4gK3N0cnVjdCBtdXRleCBsb2NrOw0KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNCj4gK3NucHJpbnRmKGRp
cm5hbWUsIGxlbiArIDksICJydDE3MTFoLSVzIiwgZGV2X25hbWUoY2hpcC0+ZGV2KSk7DQo+ICtp
ZiAoIWNoaXAtPmRiZ2Rpcikgew0KPiArY2hpcC0+ZGJnZGlyID0gZGVidWdmc19jcmVhdGVfZGly
KGRpcm5hbWUsIE5VTEwpOw0KPiAraWYgKCFjaGlwLT5kYmdkaXIpDQo+ICtyZXR1cm4gLUVOT01F
TTsNCg0KTm8gbmVlZCB0byBldmVyIGNoZWNrIHRoZSByZXR1cm4gdmFsdWUgb2YgZGVidWdmc18g
Y2FsbHMsIHlvdSBzaG91bGQgbm90IGNhcmUgYW5kIGNhbiBhbHdheXMgdXNlIHRoZSB2YWx1ZSB0
byBhbnkgZnV0dXJlIGRlYnVnZnMgY2FsbHMsIGlmIHlvdSByZWFsbHkgbmVlZCBpdC4NCg0KSWYg
aXQgaXMgTlVMTCB3aXRob3V0IGNoZWNraW5nIGFuZCB3ZSB1c2UgaXQgaW4gZGVidWdmc19jcmVh
dGVfZmlsZSwgYWxsIHRoZSBkZWJ1ZyBmaWxlcyB3aWxsIGJlIGNyZWF0ZWQgaW4gdGhlIHJvb3Qg
b2YgdGhlIGRlYnVnZnMgZmlsZXN5c3RlbS4NCklzIHRoaXMgY29ycmVjdD8NCj09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PQ0KDQo+ICtmb3IgKGkgPSAwOyBpIDwgUlQxNzExSF9EQkdfTUFYOyBpKyspIHsNCj4gK2lu
Zm8gPSAmY2hpcC0+ZGJnX2luZm9baV07DQoNCnN0YXRpYyBhcnJheSBvZiBkZWJ1ZyBpbmZvPyAg
VGhhdCBmZWVscyBvZGQuDQoNCklzIHRoZSBzdWdnZXN0aW9uIHRvIHVzZSBwb2ludGVyIG9mIGFy
cmF5IGFuZCBkeW5hbWljYWxseSBhbGxvY2F0ZWQgaXQ/DQo9PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KTGlr
ZSBoZXJlLCB5b3UgZG9uJ3QgbmVlZCB0aGlzLCBhbmQgeW91IGRvbid0IG5lZWQgdG8gY2FyZSBh
Ym91dCB0aGUgcmV0dXJuIHZhbHVlLg0KDQo+ICtnb3RvIGVycjsNCj4gK30NCj4gK30NCj4gKw0K
PiArcmV0dXJuIDA7DQo+ICtlcnI6DQo+ICtkZWJ1Z2ZzX3JlbW92ZV9yZWN1cnNpdmUoY2hpcC0+
ZGJnZGlyKTsNCj4gK3JldHVybiByZXQ7DQoNCldoeSBkbyB5b3UgY2FyZSBhYm91dCBhbiBlcnJv
ciBoZXJlPyAgWW91ciBjb2RlIHNob3VsZCBub3QgZG8gYW55dGhpbmcgZGlmZmVyZW50IGlmIGRl
YnVnZnMgc3R1ZmYgZG9lcyBub3Qgd29yayBvciBpZiBpdCBkb2VzLiAgSXQncyBkZWJ1Z2dpbmcg
b25seS4NCk9rLCB0aGlzIHdpbGwgYmUgcmVtb3ZlZC4NCj09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQpCZXN0
IFJlZ2FyZHMsDQoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KU2h1LUZhbiBMZWUNClJp
Y2h0ZWsgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbg0KVEVMOiArODg2LTMtNTUyNjc4OSAjMjM1OQ0K
RkFYOiArODg2LTMtNTUyNjYxMg0KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCg0KLS0t
LS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCkZyb206IEdyZWcgS0ggW21haWx0bzpncmVnQGtyb2Fo
LmNvbV0NClNlbnQ6IFdlZG5lc2RheSwgSmFudWFyeSAxNywgMjAxOCA5OjQyIFBNDQpUbzogU2h1
RmFuTGVlDQpDYzogaGVpa2tpLmtyb2dlcnVzQGxpbnV4LmludGVsLmNvbTsgY3lfaHVhbmcotsCx
0q3sKTsgc2h1ZmFuX2xlZSin9a7RpnwpOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOyBs
aW51eC11c2JAdmdlci5rZXJuZWwub3JnDQpTdWJqZWN0OiBSZTogW1BBVENIXSBVU0IgVFlQRUM6
IFJUMTcxMUggVHlwZS1DIENoaXAgRHJpdmVyDQoNCk9uIFdlZCwgSmFuIDEwLCAyMDE4IGF0IDAy
OjU5OjEyUE0gKzA4MDAsIFNodUZhbkxlZSB3cm90ZToNCj4gRnJvbTogU2h1RmFuTGVlIDxzaHVm
YW5fbGVlQHJpY2h0ZWsuY29tPg0KPg0KPiBSaWNodGVrIFJUMTcxMUggVHlwZS1DIGNoaXAgZHJp
dmVyIHRoYXQgd29ya3Mgd2l0aCBUeXBlLUMgUG9ydA0KPiBDb250cm9sbGVyIE1hbmFnZXIgdG8g
cHJvdmlkZSBVU0IgUEQgYW5kIFVTQiBUeXBlLUMgZnVuY3Rpb25hbGl0aWVzLg0KPg0KPiBTaWdu
ZWQtb2ZmLWJ5OiBTaHVGYW5MZWUgPHNodWZhbl9sZWVAcmljaHRlay5jb20+DQoNCk1pbm9yIHJl
dmlldyBvZiB5b3VyIG1haW4gc3RydWN0dXJlIGFuZCB5b3VyIGRlYnVnZnMgY29kZSBhbmQgb3Ro
ZXIgc3R1ZmYsIGFsbCBvZiB3aGljaCBuZWVkIHdvcms6DQoNCj4gLS0tDQo+ICAuLi4vZGV2aWNl
dHJlZS9iaW5kaW5ncy91c2IvcmljaHRlayxydDE3MTFoLnR4dCAgICB8ICAgMzggKw0KPiAgYXJj
aC9hcm02NC9ib290L2R0cy9oaXNpbGljb24vcnQxNzExaC5kdHNpICAgICAgICAgfCAgIDExICsN
Cj4gIGRyaXZlcnMvdXNiL3R5cGVjL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgIHwg
ICAgMiArDQo+ICBkcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAg
ICAgICB8ICAgIDEgKw0KPiAgZHJpdmVycy91c2IvdHlwZWMvcnQxNzExaC9LY29uZmlnICAgICAg
ICAgICAgICAgICAgfCAgICA3ICsNCj4gIGRyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvTWFrZWZp
bGUgICAgICAgICAgICAgICAgIHwgICAgMiArDQo+ICBkcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFo
L3J0MTcxMWguYyAgICAgICAgICAgICAgICB8IDIyNDEgKysrKysrKysrKysrKysrKysrKysNCj4g
IGRyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvcnQxNzExaC5oICAgICAgICAgICAgICAgIHwgIDMw
MCArKysNCj4gIDggZmlsZXMgY2hhbmdlZCwgMjYwMiBpbnNlcnRpb25zKCspDQo+ICBjcmVhdGUg
bW9kZSAxMDA2NDQNCj4gRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3VzYi9yaWNo
dGVrLHJ0MTcxMWgudHh0DQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9hcm02NC9ib290L2R0
cy9oaXNpbGljb24vcnQxNzExaC5kdHNpDQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy91
c2IvdHlwZWMvcnQxNzExaC9LY29uZmlnICBjcmVhdGUgbW9kZQ0KPiAxMDA2NDQgZHJpdmVycy91
c2IvdHlwZWMvcnQxNzExaC9NYWtlZmlsZQ0KPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMv
dXNiL3R5cGVjL3J0MTcxMWgvcnQxNzExaC5jDQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy
cy91c2IvdHlwZWMvcnQxNzExaC9ydDE3MTFoLmgNCj4NCj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50
YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy91c2IvcmljaHRlayxydDE3MTFoLnR4dA0KPiBiL0Rv
Y3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy91c2IvcmljaHRlayxydDE3MTFoLnR4dA0K
PiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiBpbmRleCAwMDAwMDAwLi5jMjgyOTljDQo+IC0tLSAv
ZGV2L251bGwNCj4gKysrIGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3VzYi9y
aWNodGVrLHJ0MTcxMWgudHh0DQo+IEBAIC0wLDAgKzEsMzggQEANCj4gK1JpY2h0ZWsgUlQxNzEx
SCBUeXBlLUMgUG9ydCBDb250cm9sbGVyLg0KPiArDQo+ICtSZXF1aXJlZCBwcm9wZXJ0aWVzOg0K
PiArLSBjb21wYXRpYmxlIDogTXVzdCBiZSAicmljaHRlayx0eXBlY19ydDE3MTFoIjsNCj4gKy0g
cmVnIDogTXVzdCBiZSAweDRlLCBpdCdzIGRlZmF1bHQgc2xhdmUgYWRkcmVzcyBvZiBSVDE3MTFI
Lg0KPiArLSBydCxpbnRyX2dwaW8gOiBJUlEgR1BJTyBwaW4gdGhhdCdzIGNvbm5lY3RlZCB0byBS
VDE3MTFIIGludGVycnVwdC4NCj4gKw0KPiArT3B0aW9uYWwgbm9kZToNCj4gKy0gcnQsbmFtZSA6
IE5hbWUgdXNlZCBmb3IgcmVnaXN0ZXJpbmcgSVJRIGFuZCBjcmVhdGluZyBrdGhyZWFkLg0KPiAr
ICAgIElmIHRoaXMgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCwgImRlZmF1bHQiIHdpbGwgYmUg
YXBwbGllZC4NCj4gKy0gcnQsZGVmX3JvbGUgOiBEZWZhdWx0IHBvcnQgcm9sZSAoVFlQRUNfU0lO
SygwKSBvciBUWVBFQ19TT1VSQ0UoMSkpLg0KPiArU2V0IHRvIFRZUEVDX05PX1BSRUZFUlJFRF9S
T0xFKC0xKSBpZiBubyBkZWZhdWx0IHJvbGUuDQo+ICtJZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBz
cGVjaWZpZWQsIFRZUEVDX1NJTksgd2lsbCBiZSBhcHBsaWVkLg0KPiArLSBydCxwb3J0X3R5cGUg
OiBQb3J0IHR5cGUgKFRZUEVDX1BPUlRfREZQKDApLCBUWVBFQ19QT1JUX1VGUCgxKSwNCj4gKyBv
ciBUWVBFQ19QT1JUX0RSUCgyKSkuIElmIHRoaXMgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCwN
Cj4gKyBUWVBFQ19QT1JUX0RSUCB3aWxsIGJlIGFwcGxpZWQuDQo+ICstIHJ0LG1heF9zbmtfbXYg
OiBNYXhpbXVtIGFjY2VwdGFibGUgc2luayB2b2x0YWdlIGluIG1WLg0KPiArICBJZiB0aGlzIHBy
b3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQsIDUwMDBtViB3aWxsIGJlIGFwcGxpZWQuDQo+ICstIHJ0
LG1heF9zbmtfbWEgOiBNYXhpbXVtIHNpbmsgY3VycmVudCBpbiBtQS4NCj4gKyAgSWYgdGhpcyBw
cm9wZXJ0eSBpcyBub3Qgc3BlY2lmaWVkLCAzMDAwbUEgd2lsbCBiZSBhcHBsaWVkLg0KPiArLSBy
dCxtYXhfc25rX213IDogTWF4aW11bSByZXF1aXJlZCBzaW5rIHBvd2VyIGluIG1XLg0KPiArICBJ
ZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQsIDE1MDAwbVcgd2lsbCBiZSBhcHBsaWVk
Lg0KPiArLSBydCxvcGVyYXRpbmdfc25rX213IDogUmVxdWlyZWQgb3BlcmF0aW5nIHNpbmsgcG93
ZXIgaW4gbVcuDQo+ICtJZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQsDQo+ICsyNTAw
bVcgd2lsbCBiZSBhcHBsaWVkLg0KPiArLSBydCx0cnlfcm9sZV9odyA6IFRydWUgaWYgdHJ5LntT
cmMsU25rfSBpcyBpbXBsZW1lbnRlZCBpbiBoYXJkd2FyZS4NCj4gKyAgIElmIHRoaXMgcHJvcGVy
dHkgaXMgbm90IHNwZWNpZmllZCwgRmFsc2Ugd2lsbCBiZSBhcHBsaWVkLg0KPiArDQo+ICtFeGFt
cGxlOg0KPiArcnQxNzExaEA0ZSB7DQo+ICtzdGF0dXMgPSAib2siOw0KPiArY29tcGF0aWJsZSA9
ICJyaWNodGVrLHR5cGVjX3J0MTcxMWgiOw0KPiArcmVnID0gPDB4NGU+Ow0KPiArcnQsaW50cl9n
cGlvID0gPCZncGlvMjYgMCAweDA+Ow0KPiArcnQsbmFtZSA9ICJydDE3MTFoIjsNCj4gK3J0LHBv
cnRfdHlwZSA9IDwyPjsgLyogMDogREZQLCAxOiBVRlAsIDI6IERSUCAqLw0KPiArcnQsZGVmX3Jv
bGUgPSA8MD47IC8qIDA6IFNOSywgMTogU1JDLCAtMTogVFlQRUNfTk9fUFJFRkVSUkVEX1JPTEUg
Ki8NCj4gK307DQoNCmR0cyBzdHVmZiBuZWVkcyB0byBhbHdheXMgYmUgaW4gYSBzZXBhcmF0ZSBm
aWxlIHNvIHRoZSBEVCBtYWludGFpbmVycyBjYW4gcmV2aWV3L2FjayBpdC4gIFNwbGl0IHRoaXMg
cGF0Y2ggdXAgaW50byBzbWFsbGVyIHBpZWNlcyBwbGVhc2UuDQoNCg0KPiBkaWZmIC0tZ2l0IGEv
YXJjaC9hcm02NC9ib290L2R0cy9oaXNpbGljb24vcnQxNzExaC5kdHNpDQo+IGIvYXJjaC9hcm02
NC9ib290L2R0cy9oaXNpbGljb24vcnQxNzExaC5kdHNpDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0
DQo+IGluZGV4IDAwMDAwMDAuLjQxOTZjYzANCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9hcmNo
L2FybTY0L2Jvb3QvZHRzL2hpc2lsaWNvbi9ydDE3MTFoLmR0c2kNCj4gQEAgLTAsMCArMSwxMSBA
QA0KPiArJmkyYzcgew0KPiArcnQxNzExaEA0ZSB7DQo+ICtzdGF0dXMgPSAib2siOw0KPiArY29t
cGF0aWJsZSA9ICJyaWNodGVrLHR5cGVjX3J0MTcxMWgiOw0KPiArcmVnID0gPDB4NGU+Ow0KPiAr
cnQsaW50cl9ncGlvID0gPCZncGlvMjYgMCAweDA+Ow0KPiArcnQsbmFtZSA9ICJydDE3MTFoIjsN
Cj4gK3J0LHBvcnRfdHlwZSA9IDwyPjsgLyogMDogREZQLCAxOiBVRlAsIDI6IERSUCAqLw0KPiAr
cnQsZGVmX3JvbGUgPSA8MD47IC8qIDA6IFNOSywgMTogU1JDICovDQo+ICt9Ow0KPiArfTsNCj4g
ZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3R5cGVjL0tjb25maWcgYi9kcml2ZXJzL3VzYi90eXBl
Yy9LY29uZmlnDQo+IGluZGV4IGJjYjI3NDQuLjdiZWRlMGIgMTAwNjQ0DQo+IC0tLSBhL2RyaXZl
cnMvdXNiL3R5cGVjL0tjb25maWcNCj4gKysrIGIvZHJpdmVycy91c2IvdHlwZWMvS2NvbmZpZw0K
PiBAQCAtNTYsNiArNTYsOCBAQCBpZiBUWVBFQ19UQ1BNDQo+DQo+ICBzb3VyY2UgImRyaXZlcnMv
dXNiL3R5cGVjL2Z1c2IzMDIvS2NvbmZpZyINCj4NCj4gK3NvdXJjZSAiZHJpdmVycy91c2IvdHlw
ZWMvcnQxNzExaC9LY29uZmlnIg0KPiArDQo+ICBjb25maWcgVFlQRUNfV0NPVkUNCj4gIHRyaXN0
YXRlICJJbnRlbCBXaGlza2V5Q292ZSBQTUlDIFVTQiBUeXBlLUMgUEhZIGRyaXZlciINCj4gIGRl
cGVuZHMgb24gQUNQSQ0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvTWFrZWZpbGUg
Yi9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZQ0KPiBpbmRleCBiYjMxMzhhLi5lM2FhZjNjIDEw
MDY0NA0KPiAtLS0gYS9kcml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZQ0KPiArKysgYi9kcml2ZXJz
L3VzYi90eXBlYy9NYWtlZmlsZQ0KPiBAQCAtMiw2ICsyLDcgQEANCj4gIG9iai0kKENPTkZJR19U
WVBFQykrPSB0eXBlYy5vDQo+ICBvYmotJChDT05GSUdfVFlQRUNfVENQTSkrPSB0Y3BtLm8NCj4g
IG9iai15Kz0gZnVzYjMwMi8NCj4gK29iai0kKENPTkZJR19UWVBFQ19SVDE3MTFIKSs9IHJ0MTcx
MWgvDQoNCldoeSBkbyB5b3UgbmVlZCBhIHdob2xlIGRpcmVjdG9yeSBmb3Igb25lIGZpbGU/DQoN
Cg0KPiAgb2JqLSQoQ09ORklHX1RZUEVDX1dDT1ZFKSs9IHR5cGVjX3djb3ZlLm8NCj4gIG9iai0k
KENPTkZJR19UWVBFQ19VQ1NJKSs9IHVjc2kvDQo+ICBvYmotJChDT05GSUdfVFlQRUNfVFBTNjU5
OFgpKz0gdHBzNjU5OHgubw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvcnQxNzEx
aC9LY29uZmlnDQo+IGIvZHJpdmVycy91c2IvdHlwZWMvcnQxNzExaC9LY29uZmlnDQo+IG5ldyBm
aWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4IDAwMDAwMDAuLjJmYmZmZjUNCj4gLS0tIC9kZXYvbnVs
bA0KPiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFoL0tjb25maWcNCj4gQEAgLTAsMCAr
MSw3IEBADQo+ICtjb25maWcgVFlQRUNfUlQxNzExSA0KPiArdHJpc3RhdGUgIlJpY2h0ZWsgUlQx
NzExSCBUeXBlLUMgY2hpcCBkcml2ZXIiDQo+ICtkZXBlbmRzIG9uIEkyQyAmJiBQT1dFUl9TVVBQ
TFkNCj4gK2hlbHANCj4gKyAgVGhlIFJpY2h0ZWsgUlQxNzExSCAgIFR5cGUtQyBjaGlwIGRyaXZl
ciB0aGF0IHdvcmtzIHdpdGgNCj4gKyAgVHlwZS1DIFBvcnQgQ29udHJvbGxlciBNYW5hZ2VyIHRv
IHByb3ZpZGUgVVNCIFBEIGFuZCBVU0INCj4gKyAgVHlwZS1DIGZ1bmN0aW9uYWxpdGllcy4NCj4g
ZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvTWFrZWZpbGUNCj4gYi9kcml2
ZXJzL3VzYi90eXBlYy9ydDE3MTFoL01ha2VmaWxlDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+
IGluZGV4IDAwMDAwMDAuLjVmYWI4YWUNCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJz
L3VzYi90eXBlYy9ydDE3MTFoL01ha2VmaWxlDQo+IEBAIC0wLDAgKzEsMiBAQA0KPiArIyBTUERY
LUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMA0KPiArb2JqLSQoQ09ORklHX1RZUEVDX1JUMTcx
MUgpKz0gcnQxNzExaC5vDQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFo
L3J0MTcxMWguYw0KPiBiL2RyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvcnQxNzExaC5jDQo+IG5l
dyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4IDAwMDAwMDAuLjFhZWYzZTgNCj4gLS0tIC9kZXYv
bnVsbA0KPiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFoL3J0MTcxMWguYw0KPiBAQCAt
MCwwICsxLDIyNDEgQEANCj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wKw0K
PiArLyoNCj4gKyAqIENvcHlyaWdodCAyMDE3IFJpY2h0ZWsgVGVjaG5vbG9naCBDb3JwLg0KPiAr
ICoNCj4gKyAqIFJpY2h0ZWsgUlQxNzExSCBUeXBlLUMgQ2hpcCBEcml2ZXIgICovDQo+ICsNCj4g
KyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4N
Cj4gKyNpbmNsdWRlIDxsaW51eC92ZXJzaW9uLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+
DQo+ICsjaW5jbHVkZSA8bGludXgvZGVidWdmcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L3BtX3J1
bnRpbWUuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC91
c2IvdHlwZWMuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC91c2IvdGNwbS5oPg0KPiArI2luY2x1ZGUg
PGxpbnV4L3VzYi9wZC5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2dwaW8uaD4NCj4gKyNpbmNs
dWRlIDxsaW51eC9vZi5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVk
ZSA8bGludXgvaW50ZXJydXB0Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgvcmVndWxhdG9yL2NvbnN1
bWVyLmg+ICNpbmNsdWRlIDxsaW51eC9wb3dlcl9zdXBwbHkuaD4NCj4gKyNpbmNsdWRlIDxsaW51
eC9leHRjb24uaD4gI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPiAjaW5jbHVkZQ0KPiArPGxp
bnV4L2t0aHJlYWQuaD4gI2luY2x1ZGUgPGxpbnV4L2NwdS5oPiAjaW5jbHVkZQ0KPiArPGxpbnV4
L2FsYXJtdGltZXIuaD4gI2luY2x1ZGUgPGxpbnV4L3NjaGVkL2Nsb2NrLmg+ICNpbmNsdWRlDQo+
ICs8dWFwaS9saW51eC9zY2hlZC90eXBlcy5oPg0KDQpUaGlzIGxhc3QgI2luY2x1ZGUgc2hvdWxk
IG5vdCBiZSBuZWVkZWQuICBJZiBpdCBkb2VzLCB5b3UgYXJlIGRvaW5nIHNvbWV0aGluZyByZWFs
bHkgd3JvbmcuLi4NCg0KPiArDQo+ICsjaW5jbHVkZSAicnQxNzExaC5oIg0KDQpXaHkgYSAuaCBm
aWxlIGZvciBhIHNpbmdsZSAuYyBmaWxlPw0KDQo+ICsNCj4gKyNkZWZpbmUgUlQxNzExSF9EUlZf
VkVSU0lPTiIxLjAuMyINCg0KV2hlbiBjb2RlIGlzIGluIHRoZSBrZXJuZWwgdHJlZSwgdmVyc2lv
bnMgbWVhbiBub3RoaW5nLCB5b3Ugd2lsbCBub3RlIHRoYXQgbm8gb3RoZXIgVVNCIGRyaXZlciBo
YXMgdGhlbSwgcmlnaHQ/ICBQbGVhc2UgcmVtb3ZlLg0KDQoNCj4gKw0KPiArI2RlZmluZSBMT0df
QlVGRkVSX0VOVFJJRVMxMDI0DQo+ICsjZGVmaW5lIExPR19CVUZGRVJfRU5UUllfU0laRTEyOCAv
KiAxMjggY2hhciBwZXIgbGluZSAqLw0KPiArDQo+ICtlbnVtIHsNCj4gK1JUMTcxMUhfREJHX0xP
RyA9IDAsDQo+ICtSVDE3MTFIX0RCR19SRUdTLA0KPiArUlQxNzExSF9EQkdfUkVHX0FERFIsDQo+
ICtSVDE3MTFIX0RCR19EQVRBLA0KPiArUlQxNzExSF9EQkdfTUFYLA0KPiArfTsNCj4gKw0KPiAr
c3RydWN0IHJ0MTcxMWhfZGJnX2luZm8gew0KPiArc3RydWN0IHJ0MTcxMWhfY2hpcCAqY2hpcDsN
Cj4gK2ludCBpZDsNCj4gK307DQo+ICsNCj4gKw0KPiArc3RydWN0IHJ0MTcxMWhfY2hpcCB7DQo+
ICtzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjOw0KPiArc3RydWN0IGRldmljZSAqZGV2Ow0KPiArdWlu
dDE2X3QgZGlkOw0KDQprZXJuZWwgdHlwZXMgYXJlIHUxNiwgdTMyLCB1OCwgYW5kIHRoZSBsaWtl
LCBub3QgdWludDE2X3QsIHRob3NlIGFyZSBmb3IgdXNlcnNwYWNlIGNvZGUgb25seS4NCg0KWWVh
aCwgb3RoZXIgZHJpdmVycyBkbyBpdCwgYnV0IHlvdSBzaG91bGRuJ3QgOikNCg0KDQo+ICtpbnQg
aXJxX2dwaW87DQo+ICtpbnQgaXJxOw0KPiArY2hhciAqbmFtZTsNCj4gK3N0cnVjdCB0Y3BjX2Rl
diB0Y3BjX2RldjsNCj4gK3N0cnVjdCB0Y3BjX2NvbmZpZyB0Y3BjX2NmZzsNCj4gK3N0cnVjdCB0
Y3BtX3BvcnQgKnRjcG1fcG9ydDsNCj4gK3N0cnVjdCByZWd1bGF0b3IgKnZidXM7DQo+ICtzdHJ1
Y3QgZXh0Y29uX2RldiAqZXh0Y29uOw0KPiArDQo+ICsvKiBJUlEgKi8NCj4gK3N0cnVjdCBrdGhy
ZWFkX3dvcmtlciBpcnFfd29ya2VyOw0KPiArc3RydWN0IGt0aHJlYWRfd29yayBpcnFfd29yazsN
Cj4gK3N0cnVjdCB0YXNrX3N0cnVjdCAqaXJxX3dvcmtlcl90YXNrOw0KDQozIHRoaW5ncyBmb3Ig
YW4gaXJxIGhhbmRsZXI/ICBUaGF0IGZlZWxzIHdyb25nLg0KDQo+ICthdG9taWNfdCBwb2xsX2Nv
dW50Ow0KDQpMaWtlIEkgc2FpZCBiZWZvcmUsIHdoeSBpcyB0aGlzIGFuIGF0b21pYz8NCg0KPiAr
c3RydWN0IGRlbGF5ZWRfd29yayBwb2xsX3dvcms7DQo+ICsNCj4gKy8qIExQTSAqLw0KPiArc3Ry
dWN0IGRlbGF5ZWRfd29yayB3YWtldXBfd29yazsNCj4gK3N0cnVjdCBhbGFybSB3YWtldXBfdGlt
ZXI7DQo+ICtzdHJ1Y3QgbXV0ZXggd2FrZXVwX2xvY2s7DQo+ICtlbnVtIHR5cGVjX2NjX3B1bGwg
bHBtX3B1bGw7DQo+ICtib29sIHdha2V1cF9vbmNlOw0KPiArYm9vbCBsb3dfcnBfZHV0eV9jbnRk
b3duOw0KPiArYm9vbCBjYWJsZV9vbmx5Ow0KPiArYm9vbCBscG07DQo+ICsNCj4gKy8qIEkyQyAq
Lw0KPiArYXRvbWljX3QgaTJjX2J1c3k7DQo+ICthdG9taWNfdCBwbV9zdXNwZW5kOw0KDQpXaHkg
YXJlIHRoZXNlIGF0b21pYz8gIFlvdSBrbm93IHRoYXQgZG9lc24ndCBtZWFuIHRoZXkgZG8gbm90
IG5lZWQgbG9ja2luZywgcmlnaHQ/DQoNCj4gKw0KPiArLyogcHN5ICsgcHN5IHN0YXR1cyAqLw0K
PiArc3RydWN0IHBvd2VyX3N1cHBseSAqcHN5Ow0KPiArdTMyIGN1cnJlbnRfbGltaXQ7DQo+ICt1
MzIgc3VwcGx5X3ZvbHRhZ2U7DQo+ICsNCj4gKy8qIGxvY2sgZm9yIHNoYXJpbmcgY2hpcCBzdGF0
ZXMgKi8NCj4gK3N0cnVjdCBtdXRleCBsb2NrOw0KDQpIb3cgbWFueSBsb2NrcyBkbyB5b3UgaGF2
ZSBpbiB0aGlzIHN0cnVjdHVyZT8gIFlvdSBzaG91bGQgb25seSBuZWVkIDEuDQoNCj4gKw0KPiAr
LyogcG9ydCBzdGF0dXMgKi8NCj4gK2Jvb2wgdmNvbm5fb247DQo+ICtib29sIHZidXNfb247DQo+
ICtib29sIGNoYXJnZV9vbjsNCj4gK2Jvb2wgdmJ1c19wcmVzZW50Ow0KPiArZW51bSB0eXBlY19j
Y19wb2xhcml0eSBwb2xhcml0eTsNCj4gK2VudW0gdHlwZWNfY2Nfc3RhdHVzIGNjMTsNCj4gK2Vu
dW0gdHlwZWNfY2Nfc3RhdHVzIGNjMjsNCj4gK2VudW0gdHlwZWNfcm9sZSBwd3Jfcm9sZTsNCj4g
K2Jvb2wgZHJwX3RvZ2dsaW5nOw0KPiArDQo+ICsjaWZkZWYgQ09ORklHX0RFQlVHX0ZTDQo+ICtz
dHJ1Y3QgZGVudHJ5ICpkYmdkaXI7DQo+ICtzdHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyBkYmdfaW5m
b1tSVDE3MTFIX0RCR19NQVhdOw0KPiArc3RydWN0IGRlbnRyeSAqZGJnX2ZpbGVzW1JUMTcxMUhf
REJHX01BWF07DQo+ICtpbnQgZGJnX3JlZ2lkeDsNCj4gK3N0cnVjdCBtdXRleCBkYmdvcHNfbG9j
azsNCj4gKy8qIGxvY2sgZm9yIGxvZyBidWZmZXIgYWNjZXNzICovDQo+ICtzdHJ1Y3QgbXV0ZXgg
bG9nYnVmZmVyX2xvY2s7DQo+ICtpbnQgbG9nYnVmZmVyX2hlYWQ7DQo+ICtpbnQgbG9nYnVmZmVy
X3RhaWw7DQo+ICt1OCAqbG9nYnVmZmVyW0xPR19CVUZGRVJfRU5UUklFU107DQo+ICsjZW5kaWYg
LyogQ09ORklHX0RFQlVHX0ZTICovDQoNClRoYXQncyBhIGxvdCBvZiBzdHVmZiBqc3V0IGZvciBk
ZWJ1Z2ZzLiAgV2h5IGRvIHlvdSBjYXJlIGFib3V0ICNkZWZpbmUgYXQgYWxsPyAgVGhlIGNvZGUg
c2hvdWxkIG5vdC4NCg0KQW5kIGFub3RoZXIgMiBsb2Nrcz8gIEljaywgbm8uDQoNCg0KPiArfTsN
Cj4gKw0KPiArLyoNCj4gKyAqIExvZ2dpbmcgJiBkZWJ1Z2dpbmcNCj4gKyAqLw0KPiArDQo+ICsj
aWZkZWYgQ09ORklHX0RFQlVHX0ZTDQo+ICsNCj4gK3N0YXRpYyBpbnQgcnQxNzExaF9yZWdfYmxv
Y2tfcmVhZChzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLCB1aW50OF90IHJlZywNCj4gK2ludCBs
ZW4sIHVpbnQ4X3QgKmRhdGEpOw0KPiArc3RhdGljIGludCBydDE3MTFoX3JlZ19ibG9ja193cml0
ZShzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLCB1aW50OF90IHJlZywNCj4gK2ludCBsZW4sIGNv
bnN0IHVpbnQ4X3QgKmRhdGEpOw0KPiArDQo+ICtzdHJ1Y3QgcmVnX2Rlc2Mgew0KPiArdWludDhf
dCBhZGRyOw0KPiArdWludDhfdCBzaXplOw0KPiArfTsNCj4gKyNkZWZpbmUgREVDTF9SRUcoX2Fk
ZHIsIF9zaXplKSB7LmFkZHIgPSBfYWRkciwgLnNpemUgPSBfc2l6ZX0NCj4gKw0KPiArc3RhdGlj
IHN0cnVjdCByZWdfZGVzYyBydDE3MTFoX3JlZ19kZXNjW10gPSB7DQo+ICtERUNMX1JFRyhSVDE3
MTFIX1JFR19WSUQsIDIpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfUElELCAyKSwNCj4gK0RF
Q0xfUkVHKFJUMTcxMUhfUkVHX0RJRCwgMiksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19UWVBF
Q19SRVYsIDIpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfUERfUkVWLCAyKSwNCj4gK0RFQ0xf
UkVHKFJUMTcxMUhfUkVHX1BESUZfUkVWLCAyKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0FM
RVJULCAyKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0FMRVJUX01BU0ssIDIpLA0KPiArREVD
TF9SRUcoUlQxNzExSF9SRUdfUE9XRVJfU1RBVFVTX01BU0ssIDEpLA0KPiArREVDTF9SRUcoUlQx
NzExSF9SRUdfRkFVTFRfU1RBVFVTX01BU0ssIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdf
VENQQ19DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JPTEVfQ1RSTCwgMSksDQo+
ICtERUNMX1JFRyhSVDE3MTFIX1JFR19GQVVMVF9DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcx
MUhfUkVHX1BPV0VSX0NUUkwsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfQ0NfU1RBVFVT
LCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1BPV0VSX1NUQVRVUywgMSksDQo+ICtERUNM
X1JFRyhSVDE3MTFIX1JFR19GQVVMVF9TVEFUVVMsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9S
RUdfQ09NTUFORCwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19NU0dfSERSX0lORk8sIDEp
LA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfUlhfREVURUNULCAxKSwNCj4gK0RFQ0xfUkVHKFJU
MTcxMUhfUkVHX1JYX0JZVEVfQ05ULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JYX0JV
Rl9GUkFNRV9UWVBFLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JYX0hEUiwgMiksDQo+
ICtERUNMX1JFRyhSVDE3MTFIX1JFR19SWF9EQVRBLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhf
UkVHX1RSQU5TTUlULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1RYX0JZVEVfQ05ULCAx
KSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1RYX0hEUiwgMiksDQo+ICtERUNMX1JFRyhSVDE3
MTFIX1JFR19UWF9EQVRBLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0NMS19DVFJMMiwg
MSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19DTEtfQ1RSTDMsIDEpLA0KPiArREVDTF9SRUco
UlQxNzExSF9SRUdfQk1DX0NUUkwsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfQk1DSU9f
UlhEWlNFTCwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19WQ09OTl9DTElNSVRFTiwgMSks
DQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19SVF9TVEFUVVMsIDEpLA0KPiArREVDTF9SRUcoUlQx
NzExSF9SRUdfUlRfSU5ULCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1JUX01BU0ssIDEp
LA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfSURMRV9DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJU
MTcxMUhfUkVHX0lOVFJTVF9DVFJMLCAxKSwNCj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX1dBVENI
RE9HX0NUUkwsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfSTJDUlNUX0NUUkwsIDEpLA0K
PiArREVDTF9SRUcoUlQxNzExSF9SRUdfU1dSRVNFVCwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFI
X1JFR19UVENQQ19GSUxURVIsIDEpLA0KPiArREVDTF9SRUcoUlQxNzExSF9SRUdfRFJQX1RPR0dM
RV9DWUNMRSwgMSksDQo+ICtERUNMX1JFRyhSVDE3MTFIX1JFR19EUlBfRFVUWV9DVFJMLCAxKSwN
Cj4gK0RFQ0xfUkVHKFJUMTcxMUhfUkVHX0JNQ0lPX1JYRFpFTiwgMSksIH07DQo+ICsNCj4gK3N0
YXRpYyBjb25zdCBjaGFyICpydDE3MTFoX2RiZ19maWxlbmFtZVtSVDE3MTFIX0RCR19NQVhdID0g
ew0KPiArImxvZyIsICJyZWdzIiwgInJlZ19hZGRyIiwgImRhdGEiLA0KPiArfTsNCj4gKw0KPiAr
c3RhdGljIGJvb2wgcnQxNzExaF9sb2dfZnVsbChzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwKSB7
DQo+ICtyZXR1cm4gY2hpcC0+bG9nYnVmZmVyX3RhaWwgPT0NCj4gKyhjaGlwLT5sb2didWZmZXJf
aGVhZCArIDEpICUgTE9HX0JVRkZFUl9FTlRSSUVTOyB9DQo+ICsNCj4gK3N0YXRpYyB2b2lkIF9y
dDE3MTFoX2xvZyhzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLCBjb25zdCBjaGFyICpmbXQsDQo+
ICsgdmFfbGlzdCBhcmdzKQ0KPiArew0KPiArY2hhciB0bXBidWZmZXJbTE9HX0JVRkZFUl9FTlRS
WV9TSVpFXTsNCj4gK3U2NCB0c19uc2VjID0gbG9jYWxfY2xvY2soKTsNCj4gK3Vuc2lnbmVkIGxv
bmcgcmVtX25zZWM7DQo+ICsNCj4gK2lmICghY2hpcC0+bG9nYnVmZmVyW2NoaXAtPmxvZ2J1ZmZl
cl9oZWFkXSkgew0KPiArY2hpcC0+bG9nYnVmZmVyW2NoaXAtPmxvZ2J1ZmZlcl9oZWFkXSA9DQo+
ICtkZXZtX2t6YWxsb2MoY2hpcC0+ZGV2LCBMT0dfQlVGRkVSX0VOVFJZX1NJWkUsIEdGUF9LRVJO
RUwpOw0KPiAraWYgKCFjaGlwLT5sb2didWZmZXJbY2hpcC0+bG9nYnVmZmVyX2hlYWRdKQ0KPiAr
cmV0dXJuOw0KPiArfQ0KPiArDQo+ICt2c25wcmludGYodG1wYnVmZmVyLCBzaXplb2YodG1wYnVm
ZmVyKSwgZm10LCBhcmdzKTsNCj4gKw0KPiArbXV0ZXhfbG9jaygmY2hpcC0+bG9nYnVmZmVyX2xv
Y2spOw0KPiArDQo+ICtpZiAocnQxNzExaF9sb2dfZnVsbChjaGlwKSkgew0KPiArY2hpcC0+bG9n
YnVmZmVyX2hlYWQgPSBtYXgoY2hpcC0+bG9nYnVmZmVyX2hlYWQgLSAxLCAwKTsNCj4gK3N0cmxj
cHkodG1wYnVmZmVyLCAib3ZlcmZsb3ciLCBzaXplb2YodG1wYnVmZmVyKSk7DQo+ICt9DQo+ICsN
Cj4gK2lmIChjaGlwLT5sb2didWZmZXJfaGVhZCA8IDAgfHwNCj4gK2NoaXAtPmxvZ2J1ZmZlcl9o
ZWFkID49IExPR19CVUZGRVJfRU5UUklFUykgew0KPiArZGV2X3dhcm4oY2hpcC0+ZGV2LCAiJXMg
YmFkIGxvZyBidWZmZXIgaW5kZXggJWRcbiIsIF9fZnVuY19fLA0KPiArY2hpcC0+bG9nYnVmZmVy
X2hlYWQpOw0KPiArZ290byBhYm9ydDsNCj4gK30NCj4gKw0KPiAraWYgKCFjaGlwLT5sb2didWZm
ZXJbY2hpcC0+bG9nYnVmZmVyX2hlYWRdKSB7DQo+ICtkZXZfd2FybihjaGlwLT5kZXYsICIlcyBs
b2cgYnVmZmVyIGluZGV4ICVkIGlzIE5VTExcbiIsDQo+ICtfX2Z1bmNfXywgY2hpcC0+bG9nYnVm
ZmVyX2hlYWQpOw0KPiArZ290byBhYm9ydDsNCj4gK30NCj4gKw0KPiArcmVtX25zZWMgPSBkb19k
aXYodHNfbnNlYywgMTAwMDAwMDAwMCk7DQo+ICtzY25wcmludGYoY2hpcC0+bG9nYnVmZmVyW2No
aXAtPmxvZ2J1ZmZlcl9oZWFkXSwgTE9HX0JVRkZFUl9FTlRSWV9TSVpFLA0KPiArIlslNWx1LiUw
Nmx1XSAlcyIsICh1bnNpZ25lZCBsb25nKXRzX25zZWMsIHJlbV9uc2VjIC8gMTAwMCwNCj4gKyAg
dG1wYnVmZmVyKTsNCj4gK2NoaXAtPmxvZ2J1ZmZlcl9oZWFkID0gKGNoaXAtPmxvZ2J1ZmZlcl9o
ZWFkICsgMSkgJQ0KPiArTE9HX0JVRkZFUl9FTlRSSUVTOw0KPiArDQo+ICthYm9ydDoNCj4gK211
dGV4X3VubG9jaygmY2hpcC0+bG9nYnVmZmVyX2xvY2spOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMg
dm9pZCBydDE3MTFoX2xvZyhzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLA0KPiArY29uc3QgY2hh
ciAqZm10LCAuLi4pDQo+ICt7DQo+ICt2YV9saXN0IGFyZ3M7DQo+ICsNCj4gK3ZhX3N0YXJ0KGFy
Z3MsIGZtdCk7DQo+ICtfcnQxNzExaF9sb2coY2hpcCwgZm10LCBhcmdzKTsNCj4gK3ZhX2VuZChh
cmdzKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBydDE3MTFoX2xvZ19zaG93KHN0cnVjdCBy
dDE3MTFoX2NoaXAgKmNoaXAsIHN0cnVjdA0KPiArc2VxX2ZpbGUgKnMpIHsNCj4gK2ludCB0YWls
Ow0KPiArDQo+ICttdXRleF9sb2NrKCZjaGlwLT5sb2didWZmZXJfbG9jayk7DQo+ICt0YWlsID0g
Y2hpcC0+bG9nYnVmZmVyX3RhaWw7DQo+ICt3aGlsZSAodGFpbCAhPSBjaGlwLT5sb2didWZmZXJf
aGVhZCkgew0KPiArc2VxX3ByaW50ZihzLCAiJXMiLCBjaGlwLT5sb2didWZmZXJbdGFpbF0pOw0K
PiArdGFpbCA9ICh0YWlsICsgMSkgJSBMT0dfQlVGRkVSX0VOVFJJRVM7DQo+ICt9DQo+ICtpZiAo
IXNlcV9oYXNfb3ZlcmZsb3dlZChzKSkNCj4gK2NoaXAtPmxvZ2J1ZmZlcl90YWlsID0gdGFpbDsN
Cj4gK211dGV4X3VubG9jaygmY2hpcC0+bG9nYnVmZmVyX2xvY2spOw0KPiArDQo+ICtyZXR1cm4g
MDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBydDE3MTFoX3JlZ3Nfc2hvdyhzdHJ1Y3QgcnQx
NzExaF9jaGlwICpjaGlwLCBzdHJ1Y3QNCj4gK3NlcV9maWxlICpzKSB7DQo+ICtpbnQgcmV0ID0g
MDsNCj4gK2ludCBpID0gMCwgaiA9IDA7DQo+ICtzdHJ1Y3QgcmVnX2Rlc2MgKmRlc2MgPSBOVUxM
Ow0KPiArdWludDhfdCByZWd2YWxbMl0gPSB7MH07DQo+ICsNCj4gK2ZvciAoaSA9IDA7IGkgPCBB
UlJBWV9TSVpFKHJ0MTcxMWhfcmVnX2Rlc2MpOyBpKyspIHsNCj4gK2Rlc2MgPSAmcnQxNzExaF9y
ZWdfZGVzY1tpXTsNCj4gK3JldCA9IHJ0MTcxMWhfcmVnX2Jsb2NrX3JlYWQoY2hpcCwgZGVzYy0+
YWRkciwgZGVzYy0+c2l6ZSwNCj4gK3JlZ3ZhbCk7DQo+ICtpZiAocmV0IDwgMCkgew0KPiArZGV2
X2VycihjaGlwLT5kZXYsICIlcyByZWFkIHJlZzB4JTAyWCBmYWlsXG4iLA0KPiArX19mdW5jX18s
IGRlc2MtPmFkZHIpOw0KPiArY29udGludWU7DQo+ICt9DQo+ICsNCj4gK3NlcV9wcmludGYocywg
InJlZzB4JTAyeDoweCIsIGRlc2MtPmFkZHIpOw0KPiArZm9yIChqID0gMDsgaiA8IGRlc2MtPnNp
emU7IGorKykNCj4gK3NlcV9wcmludGYocywgIiUwMngsIiwgcmVndmFsW2pdKTsNCj4gK3NlcV9w
dXRzKHMsICJcbiIpOw0KPiArfQ0KPiArDQo+ICtyZXR1cm4gMDsNCj4gK30NCj4gKw0KPiArc3Rh
dGljIGlubGluZSBpbnQgcnQxNzExaF9yZWdfYWRkcl9zaG93KHN0cnVjdCBydDE3MTFoX2NoaXAg
KmNoaXAsDQo+ICtzdHJ1Y3Qgc2VxX2ZpbGUgKnMpDQo+ICt7DQo+ICtzdHJ1Y3QgcmVnX2Rlc2Mg
KmRlc2MgPSAmcnQxNzExaF9yZWdfZGVzY1tjaGlwLT5kYmdfcmVnaWR4XTsNCj4gKw0KPiArc2Vx
X3ByaW50ZihzLCAiMHglMDJ4XG4iLCBkZXNjLT5hZGRyKTsNCj4gK3JldHVybiAwOw0KPiArfQ0K
PiArDQo+ICtzdGF0aWMgaW5saW5lIGludCBydDE3MTFoX2RhdGFfc2hvdyhzdHJ1Y3QgcnQxNzEx
aF9jaGlwICpjaGlwLA0KPiArc3RydWN0IHNlcV9maWxlICpzKQ0KPiArew0KPiAraW50IHJldCA9
IDAsIGkgPSAwOw0KPiArc3RydWN0IHJlZ19kZXNjICpkZXNjID0gJnJ0MTcxMWhfcmVnX2Rlc2Nb
Y2hpcC0+ZGJnX3JlZ2lkeF07DQo+ICt1aW50OF90IHJlZ3ZhbFsyXSA9IHswfTsNCj4gKw0KPiAr
cmV0ID0gcnQxNzExaF9yZWdfYmxvY2tfcmVhZChjaGlwLCBkZXNjLT5hZGRyLCBkZXNjLT5zaXpl
LCByZWd2YWwpOw0KPiAraWYgKHJldCA8IDApDQo+ICtyZXR1cm4gcmV0Ow0KPiArDQo+ICtzZXFf
cHJpbnRmKHMsICJyZWcweCUwMng9MHgiLCBkZXNjLT5hZGRyKTsNCj4gK2ZvciAoaSA9IDA7IGkg
PCBkZXNjLT5zaXplOyBpKyspDQo+ICtzZXFfcHJpbnRmKHMsICIlMDJ4LCIsIHJlZ3ZhbFtpXSk7
DQo+ICtzZXFfcHV0cyhzLCAiXG4iKTsNCj4gK3JldHVybiAwOw0KPiArfQ0KPiArDQo+ICtzdGF0
aWMgaW50IHJ0MTcxMWhfZGJnX3Nob3coc3RydWN0IHNlcV9maWxlICpzLCB2b2lkICp2KSB7DQo+
ICtpbnQgcmV0ID0gMDsNCj4gK3N0cnVjdCBydDE3MTFoX2RiZ19pbmZvICppbmZvID0gKHN0cnVj
dCBydDE3MTFoX2RiZ19pbmZvICopcy0+cHJpdmF0ZTsNCj4gK3N0cnVjdCBydDE3MTFoX2NoaXAg
KmNoaXAgPSBpbmZvLT5jaGlwOw0KPiArDQo+ICttdXRleF9sb2NrKCZjaGlwLT5kYmdvcHNfbG9j
ayk7DQo+ICtzd2l0Y2ggKGluZm8tPmlkKSB7DQo+ICtjYXNlIFJUMTcxMUhfREJHX0xPRzoNCj4g
K3JldCA9IHJ0MTcxMWhfbG9nX3Nob3coY2hpcCwgcyk7DQo+ICticmVhazsNCj4gK2Nhc2UgUlQx
NzExSF9EQkdfUkVHUzoNCj4gK3JldCA9IHJ0MTcxMWhfcmVnc19zaG93KGNoaXAsIHMpOw0KPiAr
YnJlYWs7DQo+ICtjYXNlIFJUMTcxMUhfREJHX1JFR19BRERSOg0KPiArcmV0ID0gcnQxNzExaF9y
ZWdfYWRkcl9zaG93KGNoaXAsIHMpOw0KPiArYnJlYWs7DQo+ICtjYXNlIFJUMTcxMUhfREJHX0RB
VEE6DQo+ICtyZXQgPSBydDE3MTFoX2RhdGFfc2hvdyhjaGlwLCBzKTsNCj4gK2JyZWFrOw0KPiAr
ZGVmYXVsdDoNCj4gK3JldCA9IC1FSU5WQUw7DQo+ICticmVhazsNCj4gK30NCj4gKw0KPiArbXV0
ZXhfdW5sb2NrKCZjaGlwLT5kYmdvcHNfbG9jayk7DQo+ICtyZXR1cm4gcmV0Ow0KPiArfQ0KPiAr
DQo+ICtzdGF0aWMgaW50IHJ0MTcxMWhfZGJnX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3Ry
dWN0IGZpbGUgKmZpbGUpIHsNCj4gK2lmIChmaWxlLT5mX21vZGUgJiBGTU9ERV9SRUFEKQ0KPiAr
cmV0dXJuIHNpbmdsZV9vcGVuKGZpbGUsIHJ0MTcxMWhfZGJnX3Nob3csIGlub2RlLT5pX3ByaXZh
dGUpOw0KPiArZmlsZS0+cHJpdmF0ZV9kYXRhID0gaW5vZGUtPmlfcHJpdmF0ZTsNCj4gK3JldHVy
biAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IGdldF9wYXJhbWV0ZXJzKGNoYXIgKmJ1Ziwg
bG9uZyBpbnQgKnBhcmFtMSwgaW50DQo+ICtudW1fb2ZfcGFyKSB7DQo+ICtjaGFyICp0b2tlbjsN
Cj4gK2ludCBiYXNlLCBjbnQ7DQo+ICsNCj4gK3Rva2VuID0gc3Ryc2VwKCZidWYsICIgIik7DQo+
ICsNCj4gK2ZvciAoY250ID0gMDsgY250IDwgbnVtX29mX3BhcjsgY250KyspIHsNCj4gK2lmICh0
b2tlbiAhPSBOVUxMKSB7DQo+ICtpZiAoKHRva2VuWzFdID09ICd4JykgfHwgKHRva2VuWzFdID09
ICdYJykpDQo+ICtiYXNlID0gMTY7DQo+ICtlbHNlDQo+ICtiYXNlID0gMTA7DQo+ICsNCj4gK2lm
IChrc3RydG91bCh0b2tlbiwgYmFzZSwgJnBhcmFtMVtjbnRdKSAhPSAwKQ0KPiArcmV0dXJuIC1F
SU5WQUw7DQo+ICsNCj4gK3Rva2VuID0gc3Ryc2VwKCZidWYsICIgIik7DQo+ICt9IGVsc2UNCj4g
K3JldHVybiAtRUlOVkFMOw0KPiArfQ0KPiArcmV0dXJuIDA7DQo+ICt9DQoNCldoYXQgaXMgdGhp
cyBmdW5jdGlvbiBkb2luZz8gIFdoYXQgaXMgeW91ciBkZWJ1Z2ZzIGZpbGVzIGZvcj8NCg0KPiAr
DQo+ICtzdGF0aWMgaW50IGdldF9kYXRhcyhjb25zdCBjaGFyICpidWYsIGNvbnN0IGludCBsZW5n
dGgsDQo+ICt1bnNpZ25lZCBjaGFyICpkYXRhX2J1ZmZlciwgdW5zaWduZWQgY2hhciBkYXRhX2xl
bmd0aCkgew0KPiAraW50IGksIHB0cjsNCj4gK2xvbmcgaW50IHZhbHVlOw0KPiArY2hhciB0b2tl
bls1XTsNCj4gKw0KPiArdG9rZW5bMF0gPSAnMCc7DQo+ICt0b2tlblsxXSA9ICd4JzsNCj4gK3Rv
a2VuWzRdID0gMDsNCj4gK2lmIChidWZbMF0gIT0gJzAnIHx8IGJ1ZlsxXSAhPSAneCcpDQo+ICty
ZXR1cm4gLUVJTlZBTDsNCj4gKw0KPiArcHRyID0gMjsNCj4gK2ZvciAoaSA9IDA7IChpIDwgZGF0
YV9sZW5ndGgpICYmIChwdHIgKyAyIDw9IGxlbmd0aCk7IGkrKykgew0KPiArdG9rZW5bMl0gPSBi
dWZbcHRyKytdOw0KPiArdG9rZW5bM10gPSBidWZbcHRyKytdOw0KPiArcHRyKys7DQo+ICtpZiAo
a3N0cnRvdWwodG9rZW4sIDE2LCAmdmFsdWUpICE9IDApDQo+ICtyZXR1cm4gLUVJTlZBTDsNCj4g
K2RhdGFfYnVmZmVyW2ldID0gdmFsdWU7DQo+ICt9DQo+ICtyZXR1cm4gMDsNCj4gK30NCj4gKw0K
PiArc3RhdGljIGludCBydDE3MTFoX3JlZ2FkZHIyaWR4KHVpbnQ4X3QgcmVnX2FkZHIpIHsNCj4g
K2ludCBpID0gMDsNCj4gK3N0cnVjdCByZWdfZGVzYyAqZGVzYyA9IE5VTEw7DQo+ICsNCj4gK2Zv
ciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHJ0MTcxMWhfcmVnX2Rlc2MpOyBpKyspIHsNCj4gK2Rl
c2MgPSAmcnQxNzExaF9yZWdfZGVzY1tpXTsNCj4gK2lmIChkZXNjLT5hZGRyID09IHJlZ19hZGRy
KQ0KPiArcmV0dXJuIGk7DQo+ICt9DQo+ICtyZXR1cm4gLUVJTlZBTDsNCj4gK30NCj4gKw0KPiAr
c3RhdGljIHNzaXplX3QgcnQxNzExaF9kYmdfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0
IGNoYXIgX191c2VyICp1YnVmLA0KPiArc2l6ZV90IGNvdW50LCBsb2ZmX3QgKnBwb3MpDQo+ICt7
DQo+ICtpbnQgcmV0ID0gMDsNCj4gK3N0cnVjdCBydDE3MTFoX2RiZ19pbmZvICppbmZvID0NCj4g
KyhzdHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyAqKWZpbGUtPnByaXZhdGVfZGF0YTsNCj4gK3N0cnVj
dCBydDE3MTFoX2NoaXAgKmNoaXAgPSBpbmZvLT5jaGlwOw0KPiArc3RydWN0IHJlZ19kZXNjICpk
ZXNjID0gTlVMTDsNCj4gK2NoYXIgbGJ1ZlsxMjhdOw0KPiArbG9uZyBpbnQgcGFyYW1bNV07DQo+
ICt1bnNpZ25lZCBjaGFyIHJlZ19kYXRhWzJdID0gezB9Ow0KPiArDQo+ICtpZiAoY291bnQgPiBz
aXplb2YobGJ1ZikgLSAxKQ0KPiArcmV0dXJuIC1FRkFVTFQ7DQo+ICsNCj4gK3JldCA9IGNvcHlf
ZnJvbV91c2VyKGxidWYsIHVidWYsIGNvdW50KTsNCj4gK2lmIChyZXQpDQo+ICtyZXR1cm4gLUVG
QVVMVDsNCj4gK2xidWZbY291bnRdID0gJ1wwJzsNCj4gKw0KPiArbXV0ZXhfbG9jaygmY2hpcC0+
ZGJnb3BzX2xvY2spOw0KPiArc3dpdGNoIChpbmZvLT5pZCkgew0KPiArY2FzZSBSVDE3MTFIX0RC
R19SRUdfQUREUjoNCj4gK3JldCA9IGdldF9wYXJhbWV0ZXJzKGxidWYsIHBhcmFtLCAxKTsNCj4g
K2lmIChyZXQgPCAwKSB7DQo+ICtkZXZfZXJyKGNoaXAtPmRldiwgIiVzIGdldCBwYXJhbSBmYWls
XG4iLCBfX2Z1bmNfXyk7DQo+ICtyZXQgPSAtRUlOVkFMOw0KPiArZ290byBvdXQ7DQo+ICt9DQo+
ICtyZXQgPSBydDE3MTFoX3JlZ2FkZHIyaWR4KHBhcmFtWzBdKTsNCj4gK2lmIChyZXQgPCAwKSB7
DQo+ICtkZXZfZXJyKGNoaXAtPmRldiwgIiVzIGFkZHIyaWR4IGZhaWxcbiIsIF9fZnVuY19fKTsN
Cj4gK3JldCA9IC1FSU5WQUw7DQo+ICtnb3RvIG91dDsNCj4gK30NCj4gK2NoaXAtPmRiZ19yZWdp
ZHggPSByZXQ7DQo+ICticmVhazsNCj4gK2Nhc2UgUlQxNzExSF9EQkdfREFUQToNCj4gK2Rlc2Mg
PSAmcnQxNzExaF9yZWdfZGVzY1tjaGlwLT5kYmdfcmVnaWR4XTsNCj4gK2lmICgoZGVzYy0+c2l6
ZSAtIDEpICogMyArIDUgIT0gY291bnQpIHsNCj4gK2Rldl9lcnIoY2hpcC0+ZGV2LCAiJXMgaW5j
b3JyZWN0IGlucHV0IGxlbmd0aFxuIiwNCj4gK19fZnVuY19fKTsNCj4gK3JldCA9IC1FSU5WQUw7
DQo+ICtnb3RvIG91dDsNCj4gK30NCj4gK3JldCA9IGdldF9kYXRhcygoY2hhciAqKXVidWYsIGNv
dW50LCByZWdfZGF0YSwgZGVzYy0+c2l6ZSk7DQo+ICtpZiAocmV0IDwgMCkgew0KPiArZGV2X2Vy
cihjaGlwLT5kZXYsICIlcyBnZXQgZGF0YSBmYWlsXG4iLCBfX2Z1bmNfXyk7DQo+ICtyZXQgPSAt
RUlOVkFMOw0KPiArZ290byBvdXQ7DQo+ICt9DQo+ICtyZXQgPSBydDE3MTFoX3JlZ19ibG9ja193
cml0ZShjaGlwLCBkZXNjLT5hZGRyLCBkZXNjLT5zaXplLA0KPiArcmVnX2RhdGEpOw0KPiArYnJl
YWs7DQo+ICtkZWZhdWx0Og0KPiArcmV0ID0gLUVJTlZBTDsNCj4gK2JyZWFrOw0KPiArfQ0KPiAr
DQo+ICtvdXQ6DQo+ICttdXRleF91bmxvY2soJmNoaXAtPmRiZ29wc19sb2NrKTsNCj4gK3JldHVy
biByZXQgPCAwID8gcmV0IDogY291bnQ7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBpbnQgcnQxNzEx
aF9kYmdfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZQ0KPiArKmZpbGUp
IHsNCj4gK2lmIChmaWxlLT5mX21vZGUgJiBGTU9ERV9SRUFEKQ0KPiArcmV0dXJuIHNpbmdsZV9y
ZWxlYXNlKGlub2RlLCBmaWxlKTsNCj4gK3JldHVybiAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMg
Y29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBydDE3MTFoX2RiZ19vcHMgPSB7DQo+ICsub3Bl
bj0gcnQxNzExaF9kYmdfb3BlbiwNCj4gKy5sbHNlZWs9IHNlcV9sc2VlaywNCj4gKy5yZWFkPSBz
ZXFfcmVhZCwNCj4gKy53cml0ZT0gcnQxNzExaF9kYmdfd3JpdGUsDQo+ICsucmVsZWFzZT0gcnQx
NzExaF9kYmdfcmVsZWFzZSwNCj4gK307DQo+ICsNCj4gKw0KPiArc3RhdGljIGludCBydDE3MTFo
X2RlYnVnZnNfaW5pdChzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwKSB7DQo+ICtpbnQgcmV0ID0g
MCwgaSA9IDA7DQo+ICtzdHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyAqaW5mbyA9IE5VTEw7DQo+ICtp
bnQgbGVuID0gMDsNCj4gK2NoYXIgKmRpcm5hbWUgPSBOVUxMOw0KPiArDQo+ICttdXRleF9pbml0
KCZjaGlwLT5sb2didWZmZXJfbG9jayk7DQo+ICttdXRleF9pbml0KCZjaGlwLT5kYmdvcHNfbG9j
ayk7DQo+ICtsZW4gPSBzdHJsZW4oZGV2X25hbWUoY2hpcC0+ZGV2KSk7DQo+ICtkaXJuYW1lID0g
ZGV2bV9remFsbG9jKGNoaXAtPmRldiwgbGVuICsgOSwgR0ZQX0tFUk5FTCk7DQo+ICtpZiAoIWRp
cm5hbWUpDQo+ICtyZXR1cm4gLUVOT01FTTsNCj4gK3NucHJpbnRmKGRpcm5hbWUsIGxlbiArIDks
ICJydDE3MTFoLSVzIiwgZGV2X25hbWUoY2hpcC0+ZGV2KSk7DQo+ICtpZiAoIWNoaXAtPmRiZ2Rp
cikgew0KPiArY2hpcC0+ZGJnZGlyID0gZGVidWdmc19jcmVhdGVfZGlyKGRpcm5hbWUsIE5VTEwp
Ow0KPiAraWYgKCFjaGlwLT5kYmdkaXIpDQo+ICtyZXR1cm4gLUVOT01FTTsNCg0KTm8gbmVlZCB0
byBldmVyIGNoZWNrIHRoZSByZXR1cm4gdmFsdWUgb2YgZGVidWdmc18gY2FsbHMsIHlvdSBzaG91
bGQgbm90IGNhcmUgYW5kIGNhbiBhbHdheXMgdXNlIHRoZSB2YWx1ZSB0byBhbnkgZnV0dXJlIGRl
YnVnZnMgY2FsbHMsIGlmIHlvdSByZWFsbHkgbmVlZCBpdC4NCg0KPiArfQ0KPiArDQo+ICtmb3Ig
KGkgPSAwOyBpIDwgUlQxNzExSF9EQkdfTUFYOyBpKyspIHsNCj4gK2luZm8gPSAmY2hpcC0+ZGJn
X2luZm9baV07DQoNCnN0YXRpYyBhcnJheSBvZiBkZWJ1ZyBpbmZvPyAgVGhhdCBmZWVscyBvZGQu
DQoNCj4gK2luZm8tPmNoaXAgPSBjaGlwOw0KPiAraW5mby0+aWQgPSBpOw0KPiArY2hpcC0+ZGJn
X2ZpbGVzW2ldID0gZGVidWdmc19jcmVhdGVfZmlsZSgNCj4gK3J0MTcxMWhfZGJnX2ZpbGVuYW1l
W2ldLCBTX0lGUkVHIHwgMDQ0NCwNCj4gK2NoaXAtPmRiZ2RpciwgaW5mbywgJnJ0MTcxMWhfZGJn
X29wcyk7DQo+ICtpZiAoIWNoaXAtPmRiZ19maWxlc1tpXSkgew0KPiArcmV0ID0gLUVJTlZBTDsN
Cg0KTGlrZSBoZXJlLCB5b3UgZG9uJ3QgbmVlZCB0aGlzLCBhbmQgeW91IGRvbid0IG5lZWQgdG8g
Y2FyZSBhYm91dCB0aGUgcmV0dXJuIHZhbHVlLg0KDQo+ICtnb3RvIGVycjsNCj4gK30NCj4gK30N
Cj4gKw0KPiArcmV0dXJuIDA7DQo+ICtlcnI6DQo+ICtkZWJ1Z2ZzX3JlbW92ZV9yZWN1cnNpdmUo
Y2hpcC0+ZGJnZGlyKTsNCj4gK3JldHVybiByZXQ7DQoNCldoeSBkbyB5b3UgY2FyZSBhYm91dCBh
biBlcnJvciBoZXJlPyAgWW91ciBjb2RlIHNob3VsZCBub3QgZG8gYW55dGhpbmcgZGlmZmVyZW50
IGlmIGRlYnVnZnMgc3R1ZmYgZG9lcyBub3Qgd29yayBvciBpZiBpdCBkb2VzLiAgSXQncyBkZWJ1
Z2dpbmcgb25seS4NCg0KPiArfQ0KPiArDQo+ICtzdGF0aWMgdm9pZCBydDE3MTFoX2RlYnVnZnNf
ZXhpdChzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwKSB7DQo+ICtkZWJ1Z2ZzX3JlbW92ZV9yZWN1
cnNpdmUoY2hpcC0+ZGJnZGlyKTsNCg0KU2VlLCB5b3UgZGlkbid0IG5lZWQgdGhvc2UgZmlsZSBo
YW5kbGVzIDopDQoNCnRoYW5rcywNCg0KZ3JlZyBrLWgNCioqKioqKioqKioqKiogRW1haWwgQ29u
ZmlkZW50aWFsaXR5IE5vdGljZSAqKioqKioqKioqKioqKioqKioqKg0KDQpUaGUgaW5mb3JtYXRp
b24gY29udGFpbmVkIGluIHRoaXMgZS1tYWlsIG1lc3NhZ2UgKGluY2x1ZGluZyBhbnkgYXR0YWNo
bWVudHMpIG1heSBiZSBjb25maWRlbnRpYWwsIHByb3ByaWV0YXJ5LCBwcml2aWxlZ2VkLCBvciBv
dGhlcndpc2UgZXhlbXB0IGZyb20gZGlzY2xvc3VyZSB1bmRlciBhcHBsaWNhYmxlIGxhd3MuIEl0
IGlzIGludGVuZGVkIHRvIGJlIGNvbnZleWVkIG9ubHkgdG8gdGhlIGRlc2lnbmF0ZWQgcmVjaXBp
ZW50KHMpLiBBbnkgdXNlLCBkaXNzZW1pbmF0aW9uLCBkaXN0cmlidXRpb24sIHByaW50aW5nLCBy
ZXRhaW5pbmcgb3IgY29weWluZyBvZiB0aGlzIGUtbWFpbCAoaW5jbHVkaW5nIGl0cyBhdHRhY2ht
ZW50cykgYnkgdW5pbnRlbmRlZCByZWNpcGllbnQocykgaXMgc3RyaWN0bHkgcHJvaGliaXRlZCBh
bmQgbWF5IGJlIHVubGF3ZnVsLiBJZiB5b3UgYXJlIG5vdCBhbiBpbnRlbmRlZCByZWNpcGllbnQg
b2YgdGhpcyBlLW1haWwsIG9yIGJlbGlldmUgdGhhdCB5b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGUt
bWFpbCBpbiBlcnJvciwgcGxlYXNlIG5vdGlmeSB0aGUgc2VuZGVyIGltbWVkaWF0ZWx5IChieSBy
ZXBseWluZyB0byB0aGlzIGUtbWFpbCksIGRlbGV0ZSBhbnkgYW5kIGFsbCBjb3BpZXMgb2YgdGhp
cyBlLW1haWwgKGluY2x1ZGluZyBhbnkgYXR0YWNobWVudHMpIGZyb20geW91ciBzeXN0ZW0sIGFu
ZCBkbyBub3QgZGlzY2xvc2UgdGhlIGNvbnRlbnQgb2YgdGhpcyBlLW1haWwgdG8gYW55IG90aGVy
IHBlcnNvbi4gVGhhbmsgeW91IQ0K
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2018-01-18 13:13 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-10  6:59 [PATCH] USB TYPEC: RT1711H Type-C Chip Driver ShuFanLee
2018-01-10  6:59 ` ShuFanLee
2018-01-17  9:30 ` [PATCH] " shufan_lee(李書帆)
2018-01-17  9:30   ` shufan_lee(李書帆)
2018-01-17 11:08   ` [PATCH] " Heikki Krogerus
2018-01-17 11:08     ` Heikki Krogerus
2018-01-17 11:14     ` [PATCH] " Greg KH
2018-01-17 11:14       ` Greg Kroah-Hartman
2018-01-17 12:00       ` [PATCH] " Heikki Krogerus
2018-01-17 12:00         ` Heikki Krogerus
2018-01-17 13:31         ` [PATCH] " Greg KH
2018-01-17 13:31           ` Greg Kroah-Hartman
2018-01-17 13:33 ` [PATCH] " Greg KH
2018-01-17 13:33   ` Greg KH
2018-01-17 13:33 ` [PATCH] " Greg KH
2018-01-17 13:33   ` Greg KH
2018-01-17 13:42 ` [PATCH] " Greg KH
2018-01-17 13:42   ` Greg KH
2018-01-18 13:13   ` shufan_lee(李書帆) [this message]
2018-01-18 13:13     ` shufan_lee(李書帆)
2018-01-19  8:03     ` [PATCH] " 'Greg KH'
2018-01-19  8:03       ` Greg KH
2018-01-19  3:09 ` [PATCH] " Jun Li
2018-01-19  3:09   ` Jun Li
2018-01-19  5:48   ` [PATCH] " shufan_lee(李書帆)
2018-01-19  5:48     ` shufan_lee(李書帆)
2018-01-19  8:22     ` [PATCH] " Heikki Krogerus
2018-01-19  8:22       ` Heikki Krogerus
2018-01-19  9:01       ` [PATCH] " shufan_lee(李書帆)
2018-01-19  9:01         ` shufan_lee(李書帆)
2018-01-19  9:24         ` [PATCH] " Heikki Krogerus
2018-01-19  9:24           ` Heikki Krogerus
2018-01-19 16:02           ` [PATCH] " Guenter Roeck
2018-01-19 16:02             ` Guenter Roeck
2018-01-22  2:01             ` [PATCH] " shufan_lee(李書帆)
2018-01-22  2:01               ` shufan_lee(李書帆)
2018-01-22 18:50               ` [PATCH] " Guenter Roeck
2018-01-22 18:50                 ` Guenter Roeck
2018-01-29  7:19                 ` [PATCH] " shufan_lee(李書帆)
2018-01-29  7:19                   ` shufan_lee(李書帆)
2018-01-29 19:57                   ` [PATCH] " Guenter Roeck
2018-01-29 19:57                     ` Guenter Roeck
2018-01-30 13:21                     ` [PATCH] " shufan_lee(李書帆)
2018-01-30 13:21                       ` shufan_lee(李書帆)
2018-01-30 23:25                       ` [PATCH] " Guenter Roeck
2018-01-30 23:25                         ` Guenter Roeck
  -- strict thread matches above, loose matches on Subject: below --
2018-01-09  3:13 [PATCH] " shufan_lee(李書帆)
2018-01-09  6:18 ` Randy Dunlap
2018-01-09  8:45   ` shufan_lee(李書帆)
2018-01-09 17:26     ` Randy Dunlap
2018-01-10  2:49       ` shufan_lee(李書帆)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f94537a67a1544d1937eae3dbfcd554f@ex1.rt.l \
    --to=shufan_lee@richtek.com \
    --cc=cy_huang@richtek.com \
    --cc=greg@kroah.com \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=leechu729@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.