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, ¶m1[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, ¶m1[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
next prev parent 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: linkBe 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.