From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753295AbeAQNmc (ORCPT + 1 other); Wed, 17 Jan 2018 08:42:32 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:37699 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752276AbeAQNm3 (ORCPT ); Wed, 17 Jan 2018 08:42:29 -0500 X-ME-Sender: Date: Wed, 17 Jan 2018 14:42:19 +0100 From: Greg KH To: ShuFanLee Cc: heikki.krogerus@linux.intel.com, cy_huang@richtek.com, shufan_lee@richtek.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: Re: [PATCH] USB TYPEC: RT1711H Type-C Chip Driver Message-ID: <20180117134219.GE3188@kroah.com> References: <1515567552-7692-1-git-send-email-leechu729@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1515567552-7692-1-git-send-email-leechu729@gmail.com> User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Wed, Jan 10, 2018 at 02:59:12PM +0800, ShuFanLee wrote: > From: ShuFanLee > > 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 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include 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_ENTRIES 1024 > +#define LOG_BUFFER_ENTRY_SIZE 128 /* 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 From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: USB TYPEC: RT1711H Type-C Chip Driver From: Greg KH Message-Id: <20180117134219.GE3188@kroah.com> Date: Wed, 17 Jan 2018 14:42:19 +0100 To: ShuFanLee Cc: heikki.krogerus@linux.intel.com, cy_huang@richtek.com, shufan_lee@richtek.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org List-ID: T24gV2VkLCBKYW4gMTAsIDIwMTggYXQgMDI6NTk6MTJQTSArMDgwMCwgU2h1RmFuTGVlIHdyb3Rl Ogo+IEZyb206IFNodUZhbkxlZSA8c2h1ZmFuX2xlZUByaWNodGVrLmNvbT4KPiAKPiBSaWNodGVr IFJUMTcxMUggVHlwZS1DIGNoaXAgZHJpdmVyIHRoYXQgd29ya3Mgd2l0aAo+IFR5cGUtQyBQb3J0 IENvbnRyb2xsZXIgTWFuYWdlciB0byBwcm92aWRlIFVTQiBQRCBhbmQKPiBVU0IgVHlwZS1DIGZ1 bmN0aW9uYWxpdGllcy4KPiAKPiBTaWduZWQtb2ZmLWJ5OiBTaHVGYW5MZWUgPHNodWZhbl9sZWVA cmljaHRlay5jb20+CgpNaW5vciByZXZpZXcgb2YgeW91ciBtYWluIHN0cnVjdHVyZSBhbmQgeW91 ciBkZWJ1Z2ZzIGNvZGUgYW5kIG90aGVyCnN0dWZmLCBhbGwgb2Ygd2hpY2ggbmVlZCB3b3JrOgoK PiAtLS0KPiAgLi4uL2RldmljZXRyZWUvYmluZGluZ3MvdXNiL3JpY2h0ZWsscnQxNzExaC50eHQg ICAgfCAgIDM4ICsKPiAgYXJjaC9hcm02NC9ib290L2R0cy9oaXNpbGljb24vcnQxNzExaC5kdHNp ICAgICAgICAgfCAgIDExICsKPiAgZHJpdmVycy91c2IvdHlwZWMvS2NvbmZpZyAgICAgICAgICAg ICAgICAgICAgICAgICAgfCAgICAyICsKPiAgZHJpdmVycy91c2IvdHlwZWMvTWFrZWZpbGUgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAxICsKPiAgZHJpdmVycy91c2IvdHlwZWMvcnQxNzEx aC9LY29uZmlnICAgICAgICAgICAgICAgICAgfCAgICA3ICsKPiAgZHJpdmVycy91c2IvdHlwZWMv cnQxNzExaC9NYWtlZmlsZSAgICAgICAgICAgICAgICAgfCAgICAyICsKPiAgZHJpdmVycy91c2Iv dHlwZWMvcnQxNzExaC9ydDE3MTFoLmMgICAgICAgICAgICAgICAgfCAyMjQxICsrKysrKysrKysr KysrKysrKysrCj4gIGRyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvcnQxNzExaC5oICAgICAgICAg ICAgICAgIHwgIDMwMCArKysKPiAgOCBmaWxlcyBjaGFuZ2VkLCAyNjAyIGluc2VydGlvbnMoKykK PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy91 c2IvcmljaHRlayxydDE3MTFoLnR4dAo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9hcm02NC9i b290L2R0cy9oaXNpbGljb24vcnQxNzExaC5kdHNpCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL3VzYi90eXBlYy9ydDE3MTFoL0tjb25maWcKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvdXNiL3R5cGVjL3J0MTcxMWgvTWFrZWZpbGUKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvdXNiL3R5cGVjL3J0MTcxMWgvcnQxNzExaC5jCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL3VzYi90eXBlYy9ydDE3MTFoL3J0MTcxMWguaAo+IAo+IGRpZmYgLS1naXQgYS9Eb2N1bWVu dGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvdXNiL3JpY2h0ZWsscnQxNzExaC50eHQgYi9Eb2N1 bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvdXNiL3JpY2h0ZWsscnQxNzExaC50eHQKPiBu ZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLmMyODI5OWMKPiAtLS0gL2Rldi9u dWxsCj4gKysrIGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3VzYi9yaWNodGVr LHJ0MTcxMWgudHh0Cj4gQEAgLTAsMCArMSwzOCBAQAo+ICtSaWNodGVrIFJUMTcxMUggVHlwZS1D IFBvcnQgQ29udHJvbGxlci4KPiArCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6Cj4gKy0gY29tcGF0 aWJsZSA6IE11c3QgYmUgInJpY2h0ZWssdHlwZWNfcnQxNzExaCI7Cj4gKy0gcmVnIDogTXVzdCBi ZSAweDRlLCBpdCdzIGRlZmF1bHQgc2xhdmUgYWRkcmVzcyBvZiBSVDE3MTFILgo+ICstIHJ0LGlu dHJfZ3BpbyA6IElSUSBHUElPIHBpbiB0aGF0J3MgY29ubmVjdGVkIHRvIFJUMTcxMUggaW50ZXJy dXB0Lgo+ICsKPiArT3B0aW9uYWwgbm9kZToKPiArLSBydCxuYW1lIDogTmFtZSB1c2VkIGZvciBy ZWdpc3RlcmluZyBJUlEgYW5kIGNyZWF0aW5nIGt0aHJlYWQuCj4gKwkgICAgSWYgdGhpcyBwcm9w ZXJ0eSBpcyBub3Qgc3BlY2lmaWVkLCAiZGVmYXVsdCIgd2lsbCBiZSBhcHBsaWVkLgo+ICstIHJ0 LGRlZl9yb2xlIDogRGVmYXVsdCBwb3J0IHJvbGUgKFRZUEVDX1NJTksoMCkgb3IgVFlQRUNfU09V UkNFKDEpKS4KPiArCQlTZXQgdG8gVFlQRUNfTk9fUFJFRkVSUkVEX1JPTEUoLTEpIGlmIG5vIGRl ZmF1bHQgcm9sZS4KPiArCQlJZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQsIFRZUEVD X1NJTksgd2lsbCBiZSBhcHBsaWVkLgo+ICstIHJ0LHBvcnRfdHlwZSA6IFBvcnQgdHlwZSAoVFlQ RUNfUE9SVF9ERlAoMCksIFRZUEVDX1BPUlRfVUZQKDEpLAo+ICsJCSBvciBUWVBFQ19QT1JUX0RS UCgyKSkuIElmIHRoaXMgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCwKPiArCQkgVFlQRUNfUE9S VF9EUlAgd2lsbCBiZSBhcHBsaWVkLgo+ICstIHJ0LG1heF9zbmtfbXYgOiBNYXhpbXVtIGFjY2Vw dGFibGUgc2luayB2b2x0YWdlIGluIG1WLgo+ICsJCSAgSWYgdGhpcyBwcm9wZXJ0eSBpcyBub3Qg c3BlY2lmaWVkLCA1MDAwbVYgd2lsbCBiZSBhcHBsaWVkLgo+ICstIHJ0LG1heF9zbmtfbWEgOiBN YXhpbXVtIHNpbmsgY3VycmVudCBpbiBtQS4KPiArCQkgIElmIHRoaXMgcHJvcGVydHkgaXMgbm90 IHNwZWNpZmllZCwgMzAwMG1BIHdpbGwgYmUgYXBwbGllZC4KPiArLSBydCxtYXhfc25rX213IDog TWF4aW11bSByZXF1aXJlZCBzaW5rIHBvd2VyIGluIG1XLgo+ICsJCSAgSWYgdGhpcyBwcm9wZXJ0 eSBpcyBub3Qgc3BlY2lmaWVkLCAxNTAwMG1XIHdpbGwgYmUgYXBwbGllZC4KPiArLSBydCxvcGVy YXRpbmdfc25rX213IDogUmVxdWlyZWQgb3BlcmF0aW5nIHNpbmsgcG93ZXIgaW4gbVcuCj4gKwkJ CUlmIHRoaXMgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCwKPiArCQkJMjUwMG1XIHdpbGwgYmUg YXBwbGllZC4KPiArLSBydCx0cnlfcm9sZV9odyA6IFRydWUgaWYgdHJ5LntTcmMsU25rfSBpcyBp bXBsZW1lbnRlZCBpbiBoYXJkd2FyZS4KPiArCQkgICBJZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBz cGVjaWZpZWQsIEZhbHNlIHdpbGwgYmUgYXBwbGllZC4KPiArCj4gK0V4YW1wbGU6Cj4gK3J0MTcx MWhANGUgewo+ICsJc3RhdHVzID0gIm9rIjsKPiArCWNvbXBhdGlibGUgPSAicmljaHRlayx0eXBl Y19ydDE3MTFoIjsKPiArCXJlZyA9IDwweDRlPjsKPiArCXJ0LGludHJfZ3BpbyA9IDwmZ3BpbzI2 IDAgMHgwPjsKPiArCXJ0LG5hbWUgPSAicnQxNzExaCI7Cj4gKwlydCxwb3J0X3R5cGUgPSA8Mj47 IC8qIDA6IERGUCwgMTogVUZQLCAyOiBEUlAgKi8KPiArCXJ0LGRlZl9yb2xlID0gPDA+OyAvKiAw OiBTTkssIDE6IFNSQywgLTE6IFRZUEVDX05PX1BSRUZFUlJFRF9ST0xFICovCj4gK307CgpkdHMg c3R1ZmYgbmVlZHMgdG8gYWx3YXlzIGJlIGluIGEgc2VwYXJhdGUgZmlsZSBzbyB0aGUgRFQgbWFp bnRhaW5lcnMKY2FuIHJldmlldy9hY2sgaXQuICBTcGxpdCB0aGlzIHBhdGNoIHVwIGludG8gc21h bGxlciBwaWVjZXMgcGxlYXNlLgoKCj4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQvYm9vdC9kdHMv aGlzaWxpY29uL3J0MTcxMWguZHRzaSBiL2FyY2gvYXJtNjQvYm9vdC9kdHMvaGlzaWxpY29uL3J0 MTcxMWguZHRzaQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uNDE5NmNj MAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9hcmNoL2FybTY0L2Jvb3QvZHRzL2hpc2lsaWNvbi9y dDE3MTFoLmR0c2kKPiBAQCAtMCwwICsxLDExIEBACj4gKyZpMmM3IHsKPiArCXJ0MTcxMWhANGUg ewo+ICsJCXN0YXR1cyA9ICJvayI7Cj4gKwkJY29tcGF0aWJsZSA9ICJyaWNodGVrLHR5cGVjX3J0 MTcxMWgiOwo+ICsJCXJlZyA9IDwweDRlPjsKPiArCQlydCxpbnRyX2dwaW8gPSA8JmdwaW8yNiAw IDB4MD47Cj4gKwkJcnQsbmFtZSA9ICJydDE3MTFoIjsKPiArCQlydCxwb3J0X3R5cGUgPSA8Mj47 IC8qIDA6IERGUCwgMTogVUZQLCAyOiBEUlAgKi8KPiArCQlydCxkZWZfcm9sZSA9IDwwPjsgLyog MDogU05LLCAxOiBTUkMgKi8KPiArCX07Cj4gK307Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNi L3R5cGVjL0tjb25maWcgYi9kcml2ZXJzL3VzYi90eXBlYy9LY29uZmlnCj4gaW5kZXggYmNiMjc0 NC4uN2JlZGUwYiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3VzYi90eXBlYy9LY29uZmlnCj4gKysr IGIvZHJpdmVycy91c2IvdHlwZWMvS2NvbmZpZwo+IEBAIC01Niw2ICs1Niw4IEBAIGlmIFRZUEVD X1RDUE0KPiAgCj4gIHNvdXJjZSAiZHJpdmVycy91c2IvdHlwZWMvZnVzYjMwMi9LY29uZmlnIgo+ ICAKPiArc291cmNlICJkcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFoL0tjb25maWciCj4gKwo+ICBj b25maWcgVFlQRUNfV0NPVkUKPiAgCXRyaXN0YXRlICJJbnRlbCBXaGlza2V5Q292ZSBQTUlDIFVT QiBUeXBlLUMgUEhZIGRyaXZlciIKPiAgCWRlcGVuZHMgb24gQUNQSQo+IGRpZmYgLS1naXQgYS9k cml2ZXJzL3VzYi90eXBlYy9NYWtlZmlsZSBiL2RyaXZlcnMvdXNiL3R5cGVjL01ha2VmaWxlCj4g aW5kZXggYmIzMTM4YS4uZTNhYWYzYyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3VzYi90eXBlYy9N YWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvdXNiL3R5cGVjL01ha2VmaWxlCj4gQEAgLTIsNiArMiw3 IEBACj4gIG9iai0kKENPTkZJR19UWVBFQykJCSs9IHR5cGVjLm8KPiAgb2JqLSQoQ09ORklHX1RZ UEVDX1RDUE0pCSs9IHRjcG0ubwo+ICBvYmoteQkJCQkrPSBmdXNiMzAyLwo+ICtvYmotJChDT05G SUdfVFlQRUNfUlQxNzExSCkJKz0gcnQxNzExaC8KCldoeSBkbyB5b3UgbmVlZCBhIHdob2xlIGRp cmVjdG9yeSBmb3Igb25lIGZpbGU/CgoKPiAgb2JqLSQoQ09ORklHX1RZUEVDX1dDT1ZFKQkrPSB0 eXBlY193Y292ZS5vCj4gIG9iai0kKENPTkZJR19UWVBFQ19VQ1NJKQkrPSB1Y3NpLwo+ICBvYmot JChDT05GSUdfVFlQRUNfVFBTNjU5OFgpCSs9IHRwczY1OTh4Lm8KPiBkaWZmIC0tZ2l0IGEvZHJp dmVycy91c2IvdHlwZWMvcnQxNzExaC9LY29uZmlnIGIvZHJpdmVycy91c2IvdHlwZWMvcnQxNzEx aC9LY29uZmlnCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwLi4yZmJmZmY1 Cj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvS2NvbmZp Zwo+IEBAIC0wLDAgKzEsNyBAQAo+ICtjb25maWcgVFlQRUNfUlQxNzExSAo+ICsJdHJpc3RhdGUg IlJpY2h0ZWsgUlQxNzExSCBUeXBlLUMgY2hpcCBkcml2ZXIiCj4gKwlkZXBlbmRzIG9uIEkyQyAm JiBQT1dFUl9TVVBQTFkKPiArCWhlbHAKPiArCSAgVGhlIFJpY2h0ZWsgUlQxNzExSCAgIFR5cGUt QyBjaGlwIGRyaXZlciB0aGF0IHdvcmtzIHdpdGgKPiArCSAgVHlwZS1DIFBvcnQgQ29udHJvbGxl ciBNYW5hZ2VyIHRvIHByb3ZpZGUgVVNCIFBEIGFuZCBVU0IKPiArCSAgVHlwZS1DIGZ1bmN0aW9u YWxpdGllcy4KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvcnQxNzExaC9NYWtlZmls ZSBiL2RyaXZlcnMvdXNiL3R5cGVjL3J0MTcxMWgvTWFrZWZpbGUKPiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+IGluZGV4IDAwMDAwMDAuLjVmYWI4YWUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJp dmVycy91c2IvdHlwZWMvcnQxNzExaC9NYWtlZmlsZQo+IEBAIC0wLDAgKzEsMiBAQAo+ICsjIFNQ RFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wCj4gK29iai0kKENPTkZJR19UWVBFQ19SVDE3 MTFIKQkrPSBydDE3MTFoLm8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMvcnQxNzEx aC9ydDE3MTFoLmMgYi9kcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFoL3J0MTcxMWguYwo+IG5ldyBm aWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uMWFlZjNlOAo+IC0tLSAvZGV2L251bGwK PiArKysgYi9kcml2ZXJzL3VzYi90eXBlYy9ydDE3MTFoL3J0MTcxMWguYwo+IEBAIC0wLDAgKzEs MjI0MSBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsKPiArLyoKPiAr ICogQ29weXJpZ2h0IDIwMTcgUmljaHRlayBUZWNobm9sb2doIENvcnAuCj4gKyAqCj4gKyAqIFJp Y2h0ZWsgUlQxNzExSCBUeXBlLUMgQ2hpcCBEcml2ZXIKPiArICovCj4gKwo+ICsjaW5jbHVkZSA8 bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KPiArI2luY2x1ZGUg PGxpbnV4L3ZlcnNpb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsjaW5jbHVkZSA8 bGludXgvZGVidWdmcy5oPgo+ICsjaW5jbHVkZSA8bGludXgvcG1fcnVudGltZS5oPgo+ICsjaW5j bHVkZSA8bGludXgvaTJjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC91c2IvdHlwZWMuaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L3VzYi90Y3BtLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC91c2IvcGQuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L29mX2dwaW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4gKyNp bmNsdWRlIDxsaW51eC9kZWxheS5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+Cj4g KyNpbmNsdWRlIDxsaW51eC9yZWd1bGF0b3IvY29uc3VtZXIuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L3Bvd2VyX3N1cHBseS5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXh0Y29uLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC93b3JrcXVldWUuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2t0aHJlYWQuaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L2NwdS5oPgo+ICsjaW5jbHVkZSA8bGludXgvYWxhcm10aW1lci5oPgo+ICsj aW5jbHVkZSA8bGludXgvc2NoZWQvY2xvY2suaD4KPiArI2luY2x1ZGUgPHVhcGkvbGludXgvc2No ZWQvdHlwZXMuaD4KClRoaXMgbGFzdCAjaW5jbHVkZSBzaG91bGQgbm90IGJlIG5lZWRlZC4gIElm IGl0IGRvZXMsIHlvdSBhcmUgZG9pbmcKc29tZXRoaW5nIHJlYWxseSB3cm9uZy4uLgoKPiArCj4g KyNpbmNsdWRlICJydDE3MTFoLmgiCgpXaHkgYSAuaCBmaWxlIGZvciBhIHNpbmdsZSAuYyBmaWxl PwoKPiArCj4gKyNkZWZpbmUgUlQxNzExSF9EUlZfVkVSU0lPTgkiMS4wLjMiCgpXaGVuIGNvZGUg aXMgaW4gdGhlIGtlcm5lbCB0cmVlLCB2ZXJzaW9ucyBtZWFuIG5vdGhpbmcsIHlvdSB3aWxsIG5v dGUKdGhhdCBubyBvdGhlciBVU0IgZHJpdmVyIGhhcyB0aGVtLCByaWdodD8gIFBsZWFzZSByZW1v dmUuCgoKPiArCj4gKyNkZWZpbmUgTE9HX0JVRkZFUl9FTlRSSUVTCTEwMjQKPiArI2RlZmluZSBM T0dfQlVGRkVSX0VOVFJZX1NJWkUJMTI4IC8qIDEyOCBjaGFyIHBlciBsaW5lICovCj4gKwo+ICtl bnVtIHsKPiArCVJUMTcxMUhfREJHX0xPRyA9IDAsCj4gKwlSVDE3MTFIX0RCR19SRUdTLAo+ICsJ UlQxNzExSF9EQkdfUkVHX0FERFIsCj4gKwlSVDE3MTFIX0RCR19EQVRBLAo+ICsJUlQxNzExSF9E QkdfTUFYLAo+ICt9Owo+ICsKPiArc3RydWN0IHJ0MTcxMWhfZGJnX2luZm8gewo+ICsJc3RydWN0 IHJ0MTcxMWhfY2hpcCAqY2hpcDsKPiArCWludCBpZDsKPiArfTsKPiArCj4gKwo+ICtzdHJ1Y3Qg cnQxNzExaF9jaGlwIHsKPiArCXN0cnVjdCBpMmNfY2xpZW50ICppMmM7Cj4gKwlzdHJ1Y3QgZGV2 aWNlICpkZXY7Cj4gKwl1aW50MTZfdCBkaWQ7CgprZXJuZWwgdHlwZXMgYXJlIHUxNiwgdTMyLCB1 OCwgYW5kIHRoZSBsaWtlLCBub3QgdWludDE2X3QsIHRob3NlIGFyZSBmb3IKdXNlcnNwYWNlIGNv ZGUgb25seS4KClllYWgsIG90aGVyIGRyaXZlcnMgZG8gaXQsIGJ1dCB5b3Ugc2hvdWxkbid0IDop CgoKPiArCWludCBpcnFfZ3BpbzsKPiArCWludCBpcnE7Cj4gKwljaGFyICpuYW1lOwo+ICsJc3Ry dWN0IHRjcGNfZGV2IHRjcGNfZGV2Owo+ICsJc3RydWN0IHRjcGNfY29uZmlnIHRjcGNfY2ZnOwo+ ICsJc3RydWN0IHRjcG1fcG9ydCAqdGNwbV9wb3J0Owo+ICsJc3RydWN0IHJlZ3VsYXRvciAqdmJ1 czsKPiArCXN0cnVjdCBleHRjb25fZGV2ICpleHRjb247Cj4gKwo+ICsJLyogSVJRICovCj4gKwlz dHJ1Y3Qga3RocmVhZF93b3JrZXIgaXJxX3dvcmtlcjsKPiArCXN0cnVjdCBrdGhyZWFkX3dvcmsg aXJxX3dvcms7Cj4gKwlzdHJ1Y3QgdGFza19zdHJ1Y3QgKmlycV93b3JrZXJfdGFzazsKCjMgdGhp bmdzIGZvciBhbiBpcnEgaGFuZGxlcj8gIFRoYXQgZmVlbHMgd3JvbmcuCgo+ICsJYXRvbWljX3Qg cG9sbF9jb3VudDsKCkxpa2UgSSBzYWlkIGJlZm9yZSwgd2h5IGlzIHRoaXMgYW4gYXRvbWljPwoK PiArCXN0cnVjdCBkZWxheWVkX3dvcmsgcG9sbF93b3JrOwo+ICsKPiArCS8qIExQTSAqLwo+ICsJ c3RydWN0IGRlbGF5ZWRfd29yayB3YWtldXBfd29yazsKPiArCXN0cnVjdCBhbGFybSB3YWtldXBf dGltZXI7Cj4gKwlzdHJ1Y3QgbXV0ZXggd2FrZXVwX2xvY2s7Cj4gKwllbnVtIHR5cGVjX2NjX3B1 bGwgbHBtX3B1bGw7Cj4gKwlib29sIHdha2V1cF9vbmNlOwo+ICsJYm9vbCBsb3dfcnBfZHV0eV9j bnRkb3duOwo+ICsJYm9vbCBjYWJsZV9vbmx5Owo+ICsJYm9vbCBscG07Cj4gKwo+ICsJLyogSTJD ICovCj4gKwlhdG9taWNfdCBpMmNfYnVzeTsKPiArCWF0b21pY190IHBtX3N1c3BlbmQ7CgpXaHkg YXJlIHRoZXNlIGF0b21pYz8gIFlvdSBrbm93IHRoYXQgZG9lc24ndCBtZWFuIHRoZXkgZG8gbm90 IG5lZWQKbG9ja2luZywgcmlnaHQ/Cgo+ICsKPiArCS8qIHBzeSArIHBzeSBzdGF0dXMgKi8KPiAr CXN0cnVjdCBwb3dlcl9zdXBwbHkgKnBzeTsKPiArCXUzMiBjdXJyZW50X2xpbWl0Owo+ICsJdTMy IHN1cHBseV92b2x0YWdlOwo+ICsKPiArCS8qIGxvY2sgZm9yIHNoYXJpbmcgY2hpcCBzdGF0ZXMg Ki8KPiArCXN0cnVjdCBtdXRleCBsb2NrOwoKSG93IG1hbnkgbG9ja3MgZG8geW91IGhhdmUgaW4g dGhpcyBzdHJ1Y3R1cmU/ICBZb3Ugc2hvdWxkIG9ubHkgbmVlZCAxLgoKPiArCj4gKwkvKiBwb3J0 IHN0YXR1cyAqLwo+ICsJYm9vbCB2Y29ubl9vbjsKPiArCWJvb2wgdmJ1c19vbjsKPiArCWJvb2wg Y2hhcmdlX29uOwo+ICsJYm9vbCB2YnVzX3ByZXNlbnQ7Cj4gKwllbnVtIHR5cGVjX2NjX3BvbGFy aXR5IHBvbGFyaXR5Owo+ICsJZW51bSB0eXBlY19jY19zdGF0dXMgY2MxOwo+ICsJZW51bSB0eXBl Y19jY19zdGF0dXMgY2MyOwo+ICsJZW51bSB0eXBlY19yb2xlIHB3cl9yb2xlOwo+ICsJYm9vbCBk cnBfdG9nZ2xpbmc7Cj4gKwo+ICsjaWZkZWYgQ09ORklHX0RFQlVHX0ZTCj4gKwlzdHJ1Y3QgZGVu dHJ5ICpkYmdkaXI7Cj4gKwlzdHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyBkYmdfaW5mb1tSVDE3MTFI X0RCR19NQVhdOwo+ICsJc3RydWN0IGRlbnRyeSAqZGJnX2ZpbGVzW1JUMTcxMUhfREJHX01BWF07 Cj4gKwlpbnQgZGJnX3JlZ2lkeDsKPiArCXN0cnVjdCBtdXRleCBkYmdvcHNfbG9jazsKPiArCS8q IGxvY2sgZm9yIGxvZyBidWZmZXIgYWNjZXNzICovCj4gKwlzdHJ1Y3QgbXV0ZXggbG9nYnVmZmVy X2xvY2s7Cj4gKwlpbnQgbG9nYnVmZmVyX2hlYWQ7Cj4gKwlpbnQgbG9nYnVmZmVyX3RhaWw7Cj4g Kwl1OCAqbG9nYnVmZmVyW0xPR19CVUZGRVJfRU5UUklFU107Cj4gKyNlbmRpZiAvKiBDT05GSUdf REVCVUdfRlMgKi8KClRoYXQncyBhIGxvdCBvZiBzdHVmZiBqc3V0IGZvciBkZWJ1Z2ZzLiAgV2h5 IGRvIHlvdSBjYXJlIGFib3V0ICNkZWZpbmUKYXQgYWxsPyAgVGhlIGNvZGUgc2hvdWxkIG5vdC4K CkFuZCBhbm90aGVyIDIgbG9ja3M/ICBJY2ssIG5vLgoKCj4gK307Cj4gKwo+ICsvKgo+ICsgKiBM b2dnaW5nICYgZGVidWdnaW5nCj4gKyAqLwo+ICsKPiArI2lmZGVmIENPTkZJR19ERUJVR19GUwo+ ICsKPiArc3RhdGljIGludCBydDE3MTFoX3JlZ19ibG9ja19yZWFkKHN0cnVjdCBydDE3MTFoX2No aXAgKmNoaXAsIHVpbnQ4X3QgcmVnLAo+ICsJaW50IGxlbiwgdWludDhfdCAqZGF0YSk7Cj4gK3N0 YXRpYyBpbnQgcnQxNzExaF9yZWdfYmxvY2tfd3JpdGUoc3RydWN0IHJ0MTcxMWhfY2hpcCAqY2hp cCwgdWludDhfdCByZWcsCj4gKwlpbnQgbGVuLCBjb25zdCB1aW50OF90ICpkYXRhKTsKPiArCj4g K3N0cnVjdCByZWdfZGVzYyB7Cj4gKwl1aW50OF90IGFkZHI7Cj4gKwl1aW50OF90IHNpemU7Cj4g K307Cj4gKyNkZWZpbmUgREVDTF9SRUcoX2FkZHIsIF9zaXplKSB7LmFkZHIgPSBfYWRkciwgLnNp emUgPSBfc2l6ZX0KPiArCj4gK3N0YXRpYyBzdHJ1Y3QgcmVnX2Rlc2MgcnQxNzExaF9yZWdfZGVz Y1tdID0gewo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfVklELCAyKSwKPiArCURFQ0xfUkVHKFJU MTcxMUhfUkVHX1BJRCwgMiksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19ESUQsIDIpLAo+ICsJ REVDTF9SRUcoUlQxNzExSF9SRUdfVFlQRUNfUkVWLCAyKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhf UkVHX1BEX1JFViwgMiksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19QRElGX1JFViwgMiksCj4g KwlERUNMX1JFRyhSVDE3MTFIX1JFR19BTEVSVCwgMiksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JF R19BTEVSVF9NQVNLLCAyKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX1BPV0VSX1NUQVRVU19N QVNLLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX0ZBVUxUX1NUQVRVU19NQVNLLCAxKSwK PiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX1RDUENfQ1RSTCwgMSksCj4gKwlERUNMX1JFRyhSVDE3 MTFIX1JFR19ST0xFX0NUUkwsIDEpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfRkFVTFRfQ1RS TCwgMSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19QT1dFUl9DVFJMLCAxKSwKPiArCURFQ0xf UkVHKFJUMTcxMUhfUkVHX0NDX1NUQVRVUywgMSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19Q T1dFUl9TVEFUVVMsIDEpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfRkFVTFRfU1RBVFVTLCAx KSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX0NPTU1BTkQsIDEpLAo+ICsJREVDTF9SRUcoUlQx NzExSF9SRUdfTVNHX0hEUl9JTkZPLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX1JYX0RF VEVDVCwgMSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19SWF9CWVRFX0NOVCwgMSksCj4gKwlE RUNMX1JFRyhSVDE3MTFIX1JFR19SWF9CVUZfRlJBTUVfVFlQRSwgMSksCj4gKwlERUNMX1JFRyhS VDE3MTFIX1JFR19SWF9IRFIsIDIpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfUlhfREFUQSwg MSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19UUkFOU01JVCwgMSksCj4gKwlERUNMX1JFRyhS VDE3MTFIX1JFR19UWF9CWVRFX0NOVCwgMSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19UWF9I RFIsIDIpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfVFhfREFUQSwgMSksCj4gKwlERUNMX1JF RyhSVDE3MTFIX1JFR19DTEtfQ1RSTDIsIDEpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfQ0xL X0NUUkwzLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX0JNQ19DVFJMLCAxKSwKPiArCURF Q0xfUkVHKFJUMTcxMUhfUkVHX0JNQ0lPX1JYRFpTRUwsIDEpLAo+ICsJREVDTF9SRUcoUlQxNzEx SF9SRUdfVkNPTk5fQ0xJTUlURU4sIDEpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfUlRfU1RB VFVTLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX1JUX0lOVCwgMSksCj4gKwlERUNMX1JF RyhSVDE3MTFIX1JFR19SVF9NQVNLLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX0lETEVf Q1RSTCwgMSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19JTlRSU1RfQ1RSTCwgMSksCj4gKwlE RUNMX1JFRyhSVDE3MTFIX1JFR19XQVRDSERPR19DVFJMLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcx MUhfUkVHX0kyQ1JTVF9DVFJMLCAxKSwKPiArCURFQ0xfUkVHKFJUMTcxMUhfUkVHX1NXUkVTRVQs IDEpLAo+ICsJREVDTF9SRUcoUlQxNzExSF9SRUdfVFRDUENfRklMVEVSLCAxKSwKPiArCURFQ0xf UkVHKFJUMTcxMUhfUkVHX0RSUF9UT0dHTEVfQ1lDTEUsIDEpLAo+ICsJREVDTF9SRUcoUlQxNzEx SF9SRUdfRFJQX0RVVFlfQ1RSTCwgMSksCj4gKwlERUNMX1JFRyhSVDE3MTFIX1JFR19CTUNJT19S WERaRU4sIDEpLAo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IGNoYXIgKnJ0MTcxMWhfZGJnX2Zp bGVuYW1lW1JUMTcxMUhfREJHX01BWF0gPSB7Cj4gKwkibG9nIiwgInJlZ3MiLCAicmVnX2FkZHIi LCAiZGF0YSIsCj4gK307Cj4gKwo+ICtzdGF0aWMgYm9vbCBydDE3MTFoX2xvZ19mdWxsKHN0cnVj dCBydDE3MTFoX2NoaXAgKmNoaXApCj4gK3sKPiArCXJldHVybiBjaGlwLT5sb2didWZmZXJfdGFp bCA9PQo+ICsJCShjaGlwLT5sb2didWZmZXJfaGVhZCArIDEpICUgTE9HX0JVRkZFUl9FTlRSSUVT Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBfcnQxNzExaF9sb2coc3RydWN0IHJ0MTcxMWhfY2hp cCAqY2hpcCwgY29uc3QgY2hhciAqZm10LAo+ICsJCQkgdmFfbGlzdCBhcmdzKQo+ICt7Cj4gKwlj aGFyIHRtcGJ1ZmZlcltMT0dfQlVGRkVSX0VOVFJZX1NJWkVdOwo+ICsJdTY0IHRzX25zZWMgPSBs b2NhbF9jbG9jaygpOwo+ICsJdW5zaWduZWQgbG9uZyByZW1fbnNlYzsKPiArCj4gKwlpZiAoIWNo aXAtPmxvZ2J1ZmZlcltjaGlwLT5sb2didWZmZXJfaGVhZF0pIHsKPiArCQljaGlwLT5sb2didWZm ZXJbY2hpcC0+bG9nYnVmZmVyX2hlYWRdID0KPiArCQlkZXZtX2t6YWxsb2MoY2hpcC0+ZGV2LCBM T0dfQlVGRkVSX0VOVFJZX1NJWkUsIEdGUF9LRVJORUwpOwo+ICsJCWlmICghY2hpcC0+bG9nYnVm ZmVyW2NoaXAtPmxvZ2J1ZmZlcl9oZWFkXSkKPiArCQkJcmV0dXJuOwo+ICsJfQo+ICsKPiArCXZz bnByaW50Zih0bXBidWZmZXIsIHNpemVvZih0bXBidWZmZXIpLCBmbXQsIGFyZ3MpOwo+ICsKPiAr CW11dGV4X2xvY2soJmNoaXAtPmxvZ2J1ZmZlcl9sb2NrKTsKPiArCj4gKwlpZiAocnQxNzExaF9s b2dfZnVsbChjaGlwKSkgewo+ICsJCWNoaXAtPmxvZ2J1ZmZlcl9oZWFkID0gbWF4KGNoaXAtPmxv Z2J1ZmZlcl9oZWFkIC0gMSwgMCk7Cj4gKwkJc3RybGNweSh0bXBidWZmZXIsICJvdmVyZmxvdyIs IHNpemVvZih0bXBidWZmZXIpKTsKPiArCX0KPiArCj4gKwlpZiAoY2hpcC0+bG9nYnVmZmVyX2hl YWQgPCAwIHx8Cj4gKwkJY2hpcC0+bG9nYnVmZmVyX2hlYWQgPj0gTE9HX0JVRkZFUl9FTlRSSUVT KSB7Cj4gKwkJZGV2X3dhcm4oY2hpcC0+ZGV2LCAiJXMgYmFkIGxvZyBidWZmZXIgaW5kZXggJWRc biIsIF9fZnVuY19fLAo+ICsJCQljaGlwLT5sb2didWZmZXJfaGVhZCk7Cj4gKwkJZ290byBhYm9y dDsKPiArCX0KPiArCj4gKwlpZiAoIWNoaXAtPmxvZ2J1ZmZlcltjaGlwLT5sb2didWZmZXJfaGVh ZF0pIHsKPiArCQlkZXZfd2FybihjaGlwLT5kZXYsICIlcyBsb2cgYnVmZmVyIGluZGV4ICVkIGlz IE5VTExcbiIsCj4gKwkJCV9fZnVuY19fLCBjaGlwLT5sb2didWZmZXJfaGVhZCk7Cj4gKwkJZ290 byBhYm9ydDsKPiArCX0KPiArCj4gKwlyZW1fbnNlYyA9IGRvX2Rpdih0c19uc2VjLCAxMDAwMDAw MDAwKTsKPiArCXNjbnByaW50ZihjaGlwLT5sb2didWZmZXJbY2hpcC0+bG9nYnVmZmVyX2hlYWRd LCBMT0dfQlVGRkVSX0VOVFJZX1NJWkUsCj4gKwkJIlslNWx1LiUwNmx1XSAlcyIsICh1bnNpZ25l ZCBsb25nKXRzX25zZWMsIHJlbV9uc2VjIC8gMTAwMCwKPiArCQkgIHRtcGJ1ZmZlcik7Cj4gKwlj aGlwLT5sb2didWZmZXJfaGVhZCA9IChjaGlwLT5sb2didWZmZXJfaGVhZCArIDEpICUgTE9HX0JV RkZFUl9FTlRSSUVTOwo+ICsKPiArYWJvcnQ6Cj4gKwltdXRleF91bmxvY2soJmNoaXAtPmxvZ2J1 ZmZlcl9sb2NrKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgcnQxNzExaF9sb2coc3RydWN0IHJ0 MTcxMWhfY2hpcCAqY2hpcCwKPiArCWNvbnN0IGNoYXIgKmZtdCwgLi4uKQo+ICt7Cj4gKwl2YV9s aXN0IGFyZ3M7Cj4gKwo+ICsJdmFfc3RhcnQoYXJncywgZm10KTsKPiArCV9ydDE3MTFoX2xvZyhj aGlwLCBmbXQsIGFyZ3MpOwo+ICsJdmFfZW5kKGFyZ3MpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50 IHJ0MTcxMWhfbG9nX3Nob3coc3RydWN0IHJ0MTcxMWhfY2hpcCAqY2hpcCwgc3RydWN0IHNlcV9m aWxlICpzKQo+ICt7Cj4gKwlpbnQgdGFpbDsKPiArCj4gKwltdXRleF9sb2NrKCZjaGlwLT5sb2di dWZmZXJfbG9jayk7Cj4gKwl0YWlsID0gY2hpcC0+bG9nYnVmZmVyX3RhaWw7Cj4gKwl3aGlsZSAo dGFpbCAhPSBjaGlwLT5sb2didWZmZXJfaGVhZCkgewo+ICsJCXNlcV9wcmludGYocywgIiVzIiwg Y2hpcC0+bG9nYnVmZmVyW3RhaWxdKTsKPiArCQl0YWlsID0gKHRhaWwgKyAxKSAlIExPR19CVUZG RVJfRU5UUklFUzsKPiArCX0KPiArCWlmICghc2VxX2hhc19vdmVyZmxvd2VkKHMpKQo+ICsJCWNo aXAtPmxvZ2J1ZmZlcl90YWlsID0gdGFpbDsKPiArCW11dGV4X3VubG9jaygmY2hpcC0+bG9nYnVm ZmVyX2xvY2spOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHJ0MTcx MWhfcmVnc19zaG93KHN0cnVjdCBydDE3MTFoX2NoaXAgKmNoaXAsIHN0cnVjdCBzZXFfZmlsZSAq cykKPiArewo+ICsJaW50IHJldCA9IDA7Cj4gKwlpbnQgaSA9IDAsIGogPSAwOwo+ICsJc3RydWN0 IHJlZ19kZXNjICpkZXNjID0gTlVMTDsKPiArCXVpbnQ4X3QgcmVndmFsWzJdID0gezB9Owo+ICsK PiArCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHJ0MTcxMWhfcmVnX2Rlc2MpOyBpKyspIHsK PiArCQlkZXNjID0gJnJ0MTcxMWhfcmVnX2Rlc2NbaV07Cj4gKwkJcmV0ID0gcnQxNzExaF9yZWdf YmxvY2tfcmVhZChjaGlwLCBkZXNjLT5hZGRyLCBkZXNjLT5zaXplLAo+ICsJCQlyZWd2YWwpOwo+ ICsJCWlmIChyZXQgPCAwKSB7Cj4gKwkJCWRldl9lcnIoY2hpcC0+ZGV2LCAiJXMgcmVhZCByZWcw eCUwMlggZmFpbFxuIiwKPiArCQkJCV9fZnVuY19fLCBkZXNjLT5hZGRyKTsKPiArCQkJY29udGlu dWU7Cj4gKwkJfQo+ICsKPiArCQlzZXFfcHJpbnRmKHMsICJyZWcweCUwMng6MHgiLCBkZXNjLT5h ZGRyKTsKPiArCQlmb3IgKGogPSAwOyBqIDwgZGVzYy0+c2l6ZTsgaisrKQo+ICsJCQlzZXFfcHJp bnRmKHMsICIlMDJ4LCIsIHJlZ3ZhbFtqXSk7Cj4gKwkJc2VxX3B1dHMocywgIlxuIik7Cj4gKwl9 Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgaW50IHJ0MTcxMWhf cmVnX2FkZHJfc2hvdyhzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwLAo+ICsJc3RydWN0IHNlcV9m aWxlICpzKQo+ICt7Cj4gKwlzdHJ1Y3QgcmVnX2Rlc2MgKmRlc2MgPSAmcnQxNzExaF9yZWdfZGVz Y1tjaGlwLT5kYmdfcmVnaWR4XTsKPiArCj4gKwlzZXFfcHJpbnRmKHMsICIweCUwMnhcbiIsIGRl c2MtPmFkZHIpOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgaW50IHJ0 MTcxMWhfZGF0YV9zaG93KHN0cnVjdCBydDE3MTFoX2NoaXAgKmNoaXAsCj4gKwlzdHJ1Y3Qgc2Vx X2ZpbGUgKnMpCj4gK3sKPiArCWludCByZXQgPSAwLCBpID0gMDsKPiArCXN0cnVjdCByZWdfZGVz YyAqZGVzYyA9ICZydDE3MTFoX3JlZ19kZXNjW2NoaXAtPmRiZ19yZWdpZHhdOwo+ICsJdWludDhf dCByZWd2YWxbMl0gPSB7MH07Cj4gKwo+ICsJcmV0ID0gcnQxNzExaF9yZWdfYmxvY2tfcmVhZChj aGlwLCBkZXNjLT5hZGRyLCBkZXNjLT5zaXplLCByZWd2YWwpOwo+ICsJaWYgKHJldCA8IDApCj4g KwkJcmV0dXJuIHJldDsKPiArCj4gKwlzZXFfcHJpbnRmKHMsICJyZWcweCUwMng9MHgiLCBkZXNj LT5hZGRyKTsKPiArCWZvciAoaSA9IDA7IGkgPCBkZXNjLT5zaXplOyBpKyspCj4gKwkJc2VxX3By aW50ZihzLCAiJTAyeCwiLCByZWd2YWxbaV0pOwo+ICsJc2VxX3B1dHMocywgIlxuIik7Cj4gKwly ZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBydDE3MTFoX2RiZ19zaG93KHN0cnVjdCBz ZXFfZmlsZSAqcywgdm9pZCAqdikKPiArewo+ICsJaW50IHJldCA9IDA7Cj4gKwlzdHJ1Y3QgcnQx NzExaF9kYmdfaW5mbyAqaW5mbyA9IChzdHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyAqKXMtPnByaXZh dGU7Cj4gKwlzdHJ1Y3QgcnQxNzExaF9jaGlwICpjaGlwID0gaW5mby0+Y2hpcDsKPiArCj4gKwlt dXRleF9sb2NrKCZjaGlwLT5kYmdvcHNfbG9jayk7Cj4gKwlzd2l0Y2ggKGluZm8tPmlkKSB7Cj4g KwljYXNlIFJUMTcxMUhfREJHX0xPRzoKPiArCQlyZXQgPSBydDE3MTFoX2xvZ19zaG93KGNoaXAs IHMpOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBSVDE3MTFIX0RCR19SRUdTOgo+ICsJCXJldCA9IHJ0 MTcxMWhfcmVnc19zaG93KGNoaXAsIHMpOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBSVDE3MTFIX0RC R19SRUdfQUREUjoKPiArCQlyZXQgPSBydDE3MTFoX3JlZ19hZGRyX3Nob3coY2hpcCwgcyk7Cj4g KwkJYnJlYWs7Cj4gKwljYXNlIFJUMTcxMUhfREJHX0RBVEE6Cj4gKwkJcmV0ID0gcnQxNzExaF9k YXRhX3Nob3coY2hpcCwgcyk7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJCXJldCA9IC1F SU5WQUw7Cj4gKwkJYnJlYWs7Cj4gKwl9Cj4gKwo+ICsJbXV0ZXhfdW5sb2NrKCZjaGlwLT5kYmdv cHNfbG9jayk7Cj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHJ0MTcxMWhf ZGJnX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCj4gK3sKPiAr CWlmIChmaWxlLT5mX21vZGUgJiBGTU9ERV9SRUFEKQo+ICsJCXJldHVybiBzaW5nbGVfb3Blbihm aWxlLCBydDE3MTFoX2RiZ19zaG93LCBpbm9kZS0+aV9wcml2YXRlKTsKPiArCWZpbGUtPnByaXZh dGVfZGF0YSA9IGlub2RlLT5pX3ByaXZhdGU7Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBnZXRfcGFyYW1ldGVycyhjaGFyICpidWYsIGxvbmcgaW50ICpwYXJhbTEsIGludCBu dW1fb2ZfcGFyKQo+ICt7Cj4gKwljaGFyICp0b2tlbjsKPiArCWludCBiYXNlLCBjbnQ7Cj4gKwo+ ICsJdG9rZW4gPSBzdHJzZXAoJmJ1ZiwgIiAiKTsKPiArCj4gKwlmb3IgKGNudCA9IDA7IGNudCA8 IG51bV9vZl9wYXI7IGNudCsrKSB7Cj4gKwkJaWYgKHRva2VuICE9IE5VTEwpIHsKPiArCQkJaWYg KCh0b2tlblsxXSA9PSAneCcpIHx8ICh0b2tlblsxXSA9PSAnWCcpKQo+ICsJCQkJYmFzZSA9IDE2 Owo+ICsJCQllbHNlCj4gKwkJCQliYXNlID0gMTA7Cj4gKwo+ICsJCQlpZiAoa3N0cnRvdWwodG9r ZW4sIGJhc2UsICZwYXJhbTFbY250XSkgIT0gMCkKPiArCQkJCXJldHVybiAtRUlOVkFMOwo+ICsK PiArCQkJdG9rZW4gPSBzdHJzZXAoJmJ1ZiwgIiAiKTsKPiArCQl9IGVsc2UKPiArCQkJcmV0dXJu IC1FSU5WQUw7Cj4gKwl9Cj4gKwlyZXR1cm4gMDsKPiArfQoKV2hhdCBpcyB0aGlzIGZ1bmN0aW9u IGRvaW5nPyAgV2hhdCBpcyB5b3VyIGRlYnVnZnMgZmlsZXMgZm9yPwoKPiArCj4gK3N0YXRpYyBp bnQgZ2V0X2RhdGFzKGNvbnN0IGNoYXIgKmJ1ZiwgY29uc3QgaW50IGxlbmd0aCwKPiArCXVuc2ln bmVkIGNoYXIgKmRhdGFfYnVmZmVyLCB1bnNpZ25lZCBjaGFyIGRhdGFfbGVuZ3RoKQo+ICt7Cj4g KwlpbnQgaSwgcHRyOwo+ICsJbG9uZyBpbnQgdmFsdWU7Cj4gKwljaGFyIHRva2VuWzVdOwo+ICsK PiArCXRva2VuWzBdID0gJzAnOwo+ICsJdG9rZW5bMV0gPSAneCc7Cj4gKwl0b2tlbls0XSA9IDA7 Cj4gKwlpZiAoYnVmWzBdICE9ICcwJyB8fCBidWZbMV0gIT0gJ3gnKQo+ICsJCXJldHVybiAtRUlO VkFMOwo+ICsKPiArCXB0ciA9IDI7Cj4gKwlmb3IgKGkgPSAwOyAoaSA8IGRhdGFfbGVuZ3RoKSAm JiAocHRyICsgMiA8PSBsZW5ndGgpOyBpKyspIHsKPiArCQl0b2tlblsyXSA9IGJ1ZltwdHIrK107 Cj4gKwkJdG9rZW5bM10gPSBidWZbcHRyKytdOwo+ICsJCXB0cisrOwo+ICsJCWlmIChrc3RydG91 bCh0b2tlbiwgMTYsICZ2YWx1ZSkgIT0gMCkKPiArCQkJcmV0dXJuIC1FSU5WQUw7Cj4gKwkJZGF0 YV9idWZmZXJbaV0gPSB2YWx1ZTsKPiArCX0KPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgaW50IHJ0MTcxMWhfcmVnYWRkcjJpZHgodWludDhfdCByZWdfYWRkcikKPiArewo+ICsJaW50 IGkgPSAwOwo+ICsJc3RydWN0IHJlZ19kZXNjICpkZXNjID0gTlVMTDsKPiArCj4gKwlmb3IgKGkg PSAwOyBpIDwgQVJSQVlfU0laRShydDE3MTFoX3JlZ19kZXNjKTsgaSsrKSB7Cj4gKwkJZGVzYyA9 ICZydDE3MTFoX3JlZ19kZXNjW2ldOwo+ICsJCWlmIChkZXNjLT5hZGRyID09IHJlZ19hZGRyKQo+ ICsJCQlyZXR1cm4gaTsKPiArCX0KPiArCXJldHVybiAtRUlOVkFMOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgc3NpemVfdCBydDE3MTFoX2RiZ193cml0ZShzdHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgY2hh ciBfX3VzZXIgKnVidWYsCj4gKwlzaXplX3QgY291bnQsIGxvZmZfdCAqcHBvcykKPiArewo+ICsJ aW50IHJldCA9IDA7Cj4gKwlzdHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyAqaW5mbyA9Cj4gKwkJKHN0 cnVjdCBydDE3MTFoX2RiZ19pbmZvICopZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ICsJc3RydWN0IHJ0 MTcxMWhfY2hpcCAqY2hpcCA9IGluZm8tPmNoaXA7Cj4gKwlzdHJ1Y3QgcmVnX2Rlc2MgKmRlc2Mg PSBOVUxMOwo+ICsJY2hhciBsYnVmWzEyOF07Cj4gKwlsb25nIGludCBwYXJhbVs1XTsKPiArCXVu c2lnbmVkIGNoYXIgcmVnX2RhdGFbMl0gPSB7MH07Cj4gKwo+ICsJaWYgKGNvdW50ID4gc2l6ZW9m KGxidWYpIC0gMSkKPiArCQlyZXR1cm4gLUVGQVVMVDsKPiArCj4gKwlyZXQgPSBjb3B5X2Zyb21f dXNlcihsYnVmLCB1YnVmLCBjb3VudCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiAtRUZBVUxU Owo+ICsJbGJ1Zltjb3VudF0gPSAnXDAnOwo+ICsKPiArCW11dGV4X2xvY2soJmNoaXAtPmRiZ29w c19sb2NrKTsKPiArCXN3aXRjaCAoaW5mby0+aWQpIHsKPiArCWNhc2UgUlQxNzExSF9EQkdfUkVH X0FERFI6Cj4gKwkJcmV0ID0gZ2V0X3BhcmFtZXRlcnMobGJ1ZiwgcGFyYW0sIDEpOwo+ICsJCWlm IChyZXQgPCAwKSB7Cj4gKwkJCWRldl9lcnIoY2hpcC0+ZGV2LCAiJXMgZ2V0IHBhcmFtIGZhaWxc biIsIF9fZnVuY19fKTsKPiArCQkJcmV0ID0gLUVJTlZBTDsKPiArCQkJZ290byBvdXQ7Cj4gKwkJ fQo+ICsJCXJldCA9IHJ0MTcxMWhfcmVnYWRkcjJpZHgocGFyYW1bMF0pOwo+ICsJCWlmIChyZXQg PCAwKSB7Cj4gKwkJCWRldl9lcnIoY2hpcC0+ZGV2LCAiJXMgYWRkcjJpZHggZmFpbFxuIiwgX19m dW5jX18pOwo+ICsJCQlyZXQgPSAtRUlOVkFMOwo+ICsJCQlnb3RvIG91dDsKPiArCQl9Cj4gKwkJ Y2hpcC0+ZGJnX3JlZ2lkeCA9IHJldDsKPiArCQlicmVhazsKPiArCWNhc2UgUlQxNzExSF9EQkdf REFUQToKPiArCQlkZXNjID0gJnJ0MTcxMWhfcmVnX2Rlc2NbY2hpcC0+ZGJnX3JlZ2lkeF07Cj4g KwkJaWYgKChkZXNjLT5zaXplIC0gMSkgKiAzICsgNSAhPSBjb3VudCkgewo+ICsJCQlkZXZfZXJy KGNoaXAtPmRldiwgIiVzIGluY29ycmVjdCBpbnB1dCBsZW5ndGhcbiIsCj4gKwkJCQlfX2Z1bmNf Xyk7Cj4gKwkJCXJldCA9IC1FSU5WQUw7Cj4gKwkJCWdvdG8gb3V0Owo+ICsJCX0KPiArCQlyZXQg PSBnZXRfZGF0YXMoKGNoYXIgKil1YnVmLCBjb3VudCwgcmVnX2RhdGEsIGRlc2MtPnNpemUpOwo+ ICsJCWlmIChyZXQgPCAwKSB7Cj4gKwkJCWRldl9lcnIoY2hpcC0+ZGV2LCAiJXMgZ2V0IGRhdGEg ZmFpbFxuIiwgX19mdW5jX18pOwo+ICsJCQlyZXQgPSAtRUlOVkFMOwo+ICsJCQlnb3RvIG91dDsK PiArCQl9Cj4gKwkJcmV0ID0gcnQxNzExaF9yZWdfYmxvY2tfd3JpdGUoY2hpcCwgZGVzYy0+YWRk ciwgZGVzYy0+c2l6ZSwKPiArCQkJcmVnX2RhdGEpOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoK PiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWJyZWFrOwo+ICsJfQo+ICsKPiArb3V0Ogo+ICsJbXV0 ZXhfdW5sb2NrKCZjaGlwLT5kYmdvcHNfbG9jayk7Cj4gKwlyZXR1cm4gcmV0IDwgMCA/IHJldCA6 IGNvdW50Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHJ0MTcxMWhfZGJnX3JlbGVhc2Uoc3RydWN0 IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCj4gK3sKPiArCWlmIChmaWxlLT5mX21v ZGUgJiBGTU9ERV9SRUFEKQo+ICsJCXJldHVybiBzaW5nbGVfcmVsZWFzZShpbm9kZSwgZmlsZSk7 Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJh dGlvbnMgcnQxNzExaF9kYmdfb3BzID0gewo+ICsJLm9wZW4JCT0gcnQxNzExaF9kYmdfb3BlbiwK PiArCS5sbHNlZWsJCT0gc2VxX2xzZWVrLAo+ICsJLnJlYWQJCT0gc2VxX3JlYWQsCj4gKwkud3Jp dGUJCT0gcnQxNzExaF9kYmdfd3JpdGUsCj4gKwkucmVsZWFzZQk9IHJ0MTcxMWhfZGJnX3JlbGVh c2UsCj4gK307Cj4gKwo+ICsKPiArc3RhdGljIGludCBydDE3MTFoX2RlYnVnZnNfaW5pdChzdHJ1 Y3QgcnQxNzExaF9jaGlwICpjaGlwKQo+ICt7Cj4gKwlpbnQgcmV0ID0gMCwgaSA9IDA7Cj4gKwlz dHJ1Y3QgcnQxNzExaF9kYmdfaW5mbyAqaW5mbyA9IE5VTEw7Cj4gKwlpbnQgbGVuID0gMDsKPiAr CWNoYXIgKmRpcm5hbWUgPSBOVUxMOwo+ICsKPiArCW11dGV4X2luaXQoJmNoaXAtPmxvZ2J1ZmZl cl9sb2NrKTsKPiArCW11dGV4X2luaXQoJmNoaXAtPmRiZ29wc19sb2NrKTsKPiArCWxlbiA9IHN0 cmxlbihkZXZfbmFtZShjaGlwLT5kZXYpKTsKPiArCWRpcm5hbWUgPSBkZXZtX2t6YWxsb2MoY2hp cC0+ZGV2LCBsZW4gKyA5LCBHRlBfS0VSTkVMKTsKPiArCWlmICghZGlybmFtZSkKPiArCQlyZXR1 cm4gLUVOT01FTTsKPiArCXNucHJpbnRmKGRpcm5hbWUsIGxlbiArIDksICJydDE3MTFoLSVzIiwg ZGV2X25hbWUoY2hpcC0+ZGV2KSk7Cj4gKwlpZiAoIWNoaXAtPmRiZ2Rpcikgewo+ICsJCWNoaXAt PmRiZ2RpciA9IGRlYnVnZnNfY3JlYXRlX2RpcihkaXJuYW1lLCBOVUxMKTsKPiArCQlpZiAoIWNo aXAtPmRiZ2RpcikKPiArCQkJcmV0dXJuIC1FTk9NRU07CgpObyBuZWVkIHRvIGV2ZXIgY2hlY2sg dGhlIHJldHVybiB2YWx1ZSBvZiBkZWJ1Z2ZzXyBjYWxscywgeW91IHNob3VsZCBub3QKY2FyZSBh bmQgY2FuIGFsd2F5cyB1c2UgdGhlIHZhbHVlIHRvIGFueSBmdXR1cmUgZGVidWdmcyBjYWxscywg aWYgeW91CnJlYWxseSBuZWVkIGl0LgoKPiArCX0KPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgUlQx NzExSF9EQkdfTUFYOyBpKyspIHsKPiArCQlpbmZvID0gJmNoaXAtPmRiZ19pbmZvW2ldOwoKc3Rh dGljIGFycmF5IG9mIGRlYnVnIGluZm8/ICBUaGF0IGZlZWxzIG9kZC4KCj4gKwkJaW5mby0+Y2hp cCA9IGNoaXA7Cj4gKwkJaW5mby0+aWQgPSBpOwo+ICsJCWNoaXAtPmRiZ19maWxlc1tpXSA9IGRl YnVnZnNfY3JlYXRlX2ZpbGUoCj4gKwkJCXJ0MTcxMWhfZGJnX2ZpbGVuYW1lW2ldLCBTX0lGUkVH IHwgMDQ0NCwKPiArCQkJY2hpcC0+ZGJnZGlyLCBpbmZvLCAmcnQxNzExaF9kYmdfb3BzKTsKPiAr CQlpZiAoIWNoaXAtPmRiZ19maWxlc1tpXSkgewo+ICsJCQlyZXQgPSAtRUlOVkFMOwoKTGlrZSBo ZXJlLCB5b3UgZG9uJ3QgbmVlZCB0aGlzLCBhbmQgeW91IGRvbid0IG5lZWQgdG8gY2FyZSBhYm91 dCB0aGUKcmV0dXJuIHZhbHVlLgoKPiArCQkJZ290byBlcnI7Cj4gKwkJfQo+ICsJfQo+ICsKPiAr CXJldHVybiAwOwo+ICtlcnI6Cj4gKwlkZWJ1Z2ZzX3JlbW92ZV9yZWN1cnNpdmUoY2hpcC0+ZGJn ZGlyKTsKPiArCXJldHVybiByZXQ7CgpXaHkgZG8geW91IGNhcmUgYWJvdXQgYW4gZXJyb3IgaGVy ZT8gIFlvdXIgY29kZSBzaG91bGQgbm90IGRvIGFueXRoaW5nCmRpZmZlcmVudCBpZiBkZWJ1Z2Zz IHN0dWZmIGRvZXMgbm90IHdvcmsgb3IgaWYgaXQgZG9lcy4gIEl0J3MgZGVidWdnaW5nCm9ubHku Cgo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBydDE3MTFoX2RlYnVnZnNfZXhpdChzdHJ1Y3QgcnQx NzExaF9jaGlwICpjaGlwKQo+ICt7Cj4gKwlkZWJ1Z2ZzX3JlbW92ZV9yZWN1cnNpdmUoY2hpcC0+ ZGJnZGlyKTsKClNlZSwgeW91IGRpZG4ndCBuZWVkIHRob3NlIGZpbGUgaGFuZGxlcyA6KQoKdGhh bmtzLAoKZ3JlZyBrLWgKLS0tClRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRo ZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC11c2IiIGluCnRoZSBib2R5IG9mIGEgbWVzc2FnZSB0 byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnCk1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6 Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbAo=