From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C8FF227E80; Thu, 13 Feb 2025 11:38:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.193 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739446730; cv=none; b=ieoVZPCkghetBD2+N0WS6kcETaamwBuTrZlo+9CV0r/1zR5avi1hCsTzl2/xTZpjvVx48UEPSgHisFJqjTqZXdOC6jbuqA/hTsbd8j5hCyaUdVlBCoYkI5hjeTdOKWoPLtq8CdCfv56QthqCdGEb6clnKqJKHms1VDymlfadhuA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739446730; c=relaxed/simple; bh=679LWPq1UIT+awLBMfjIOGHjQ6M6IKZcllKoEW4ZCAM=; h=Message-ID:Date:MIME-Version:Cc:Subject:To:References:From: In-Reply-To:Content-Type; b=J1WYZI9JXwQotnSVj9D5+E9tLOPV4vsvY4xDVzc99UBNGZuRDwDE1PAQVCl1P09Z64s/7UaYZ8dVy88BUAPL0M7MT+r/hHZLriP3aMqs3GTD+Dfzvspv9BXTmkKPiECt/KDLpt7IoL6K8tUpHCmtD2qlBqrAQtH+6TD2jl6s70g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EqOIh/wP; arc=none smtp.client-ip=209.85.214.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EqOIh/wP" Received: by mail-pl1-f193.google.com with SMTP id d9443c01a7336-220c8eb195aso14192735ad.0; Thu, 13 Feb 2025 03:38:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739446727; x=1740051527; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:cc:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=Nu4dweML0+Ie1q0qi8i3kLeCSVDD+04dwqEC37g0okk=; b=EqOIh/wPgocBNMiUQYav5NorXQqPzD1hrmTecO0907C+vBYGen5sT9ONY3Krz9qY8A 5IRZjskc/SHCgji4HWS0t4f8yAQSADilAN99mRWhCUdLW0vXLo5PYW7Ap9fGvq4sv4C+ 43O1/1iWSOYuX8dj3f6syWz0UZmjaUh0xSc6wp7PgENx6rbq0lv74KCk0h1DSiva22YT GulCNc7J2SjGaA7A1avCaF8SlnjHB++LlsF5THv2kz5pr/nXqG2JqTEv6gpMHJNAyWIN dTNGKMruOOu0nVOLSD2VEmhhyjY/R0TYQG+SgaIDrmkvMI/SDh63IrRButwnJ+R1lqCt oSYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739446727; x=1740051527; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:cc:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Nu4dweML0+Ie1q0qi8i3kLeCSVDD+04dwqEC37g0okk=; b=DpfKo384Wcnq9VnhPXKyaoYpFffpz2ymC5/bpzqldTGwejKOBqZkEhTwLz2fSDlFky OjM6+k7taUZ/I6sTMHWUkIFhNTNuXN3+rX+/h9RpOvg6rbOCc4oR5NKTiMFvemnkX1Mw rVH8y0u2Ur2GMP4ljT3uQFFAXxjKMmPdAfSWA/4VjTu2UDy29JYlVKmQYZKzYjY3qDKt jFu4r1LLsMaTw7tRh+phhsOiJvzCY3UDmPYNkRziz/D0jMwO5ZiZch2/E8RFTMK2RBz1 Uh3FA+CG30v+6dKv8iH9CoUN7MSF2AGVZza0hxDPxA/y0Z07EkpU4WRy4yBEsKNL1IMc vthg== X-Forwarded-Encrypted: i=1; AJvYcCW5YMxOy7FGOnyXVeyeURQEOcmiFLYIIZXFxnI14lNcjM2qggHvip9R+MqAYXxCWCVVHwkLSozucnF5@vger.kernel.org, AJvYcCX9QkHCOVxAEkHxOvOHAkgpVinPq9p5/1rNCld68Eod7nOvembhIWOfLmQYooQmQGsnWh1C7ttmZLFd@vger.kernel.org, AJvYcCXiUZsZ4wlOUmgf6rG34dzl6rPPxh4JR3G2iQ5jEswuy5PStYIlTXYS+zxvquvoYSMzHf6x78UGPTLZsQeI@vger.kernel.org X-Gm-Message-State: AOJu0Yxay4T9PYxhlIZP1KIp+JLNsvRIgYV0BWk8l5EHgSRj2aSIPC96 3AEYyChgtYWqFaq3jP5/hPLc/olwDfgLgcv8bhCeP7HYCqxyTA7/ X-Gm-Gg: ASbGnctmGF0X0BIViZk1kyGPZ5qY2uR8oXAxLksHIDf40GlRRJAQ1Cqs8PK5A+nMI9w rUF4VKF5NG+8G9Xc9SJHytdbGiLD0GtUABmgaWwmE1ocoaZwGBpJryXJDH99ym+eGCqAluOFRqH FeRASODFpN3dDTbSMvgX08LRO/+fOCPq0uVg3JuwjfTDAq9/7zVPRg5VWHLZ+mJzHoYAcbV6OL6 15AFd1g/0HUFqPYaL9MLr4W4GskRtK8dgPYTP++HW0ATS+dJQpmATE33afa0p4rtr9aWAb7084= X-Google-Smtp-Source: AGHT+IFRw10Abzym+Gw/HDJE8srGG6kzSoM3Umm1CUVPJlbKkT+yq5D0RSUBiYifJdlbBlbJZjnuQw== X-Received: by 2002:a17:902:f78f:b0:21f:1549:a55f with SMTP id d9443c01a7336-220bbad9896mr113149055ad.19.1739446726338; Thu, 13 Feb 2025 03:38:46 -0800 (PST) Received: from [127.0.0.1] ([2407:cdc0:8010::ec]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-220d53490c2sm10797505ad.47.2025.02.13.03.38.40 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 13 Feb 2025 03:38:45 -0800 (PST) Message-ID: <8ccec6ba-4897-424e-8ff1-cfc663dfa2b5@gmail.com> Date: Thu, 13 Feb 2025 19:38:36 +0800 Precedence: bulk X-Mailing-List: linux-i2c@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Cc: troymitchell988@gmail.com, linux-riscv@lists.infradead.org, linux-i2c@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v4 2/2] i2c: spacemit: add support for SpacemiT K1 SoC To: Alex Elder , Andi Shyti , Rob Herring , Krzysztof Kozlowski , Conor Dooley References: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com> <20241125-k1-i2c-master-v4-2-0f3d5886336b@gmail.com> <4658f274-5df6-4055-82db-118217f28447@ieee.org> Content-Language: en-US From: Troy Mitchell In-Reply-To: <4658f274-5df6-4055-82db-118217f28447@ieee.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi! Alex. Thanks for ur detailed review. On 2025/2/12 05:39, Alex Elder wrote: > On 11/25/24 12:49 AM, Troy Mitchell wrote: >> From: Troy Mitchell >> >> This patch introduces basic I2C support for the SpacemiT K1 SoC, >> utilizing interrupts for transfers. >> >> The driver has been tested using i2c-tools on a Bananapi-F3 board, >> and basic I2C read/write operations have been confirmed to work. >> >> Signed-off-by: Troy Mitchell > > This is a very detailed review.  My hope is that this helps > get this driver ready for acceptance more quickly. Thanks. I will handle it ASAP. > >> --- >>   drivers/i2c/busses/Kconfig  |  19 ++ >>   drivers/i2c/busses/Makefile |   1 + >>   drivers/i2c/busses/i2c-k1.c | 655 ++++++++++++++++++++++++++++++++++++++++++++ >>   3 files changed, 675 insertions(+) >> >> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig >> index 6b3ba7e5723a..91630f55667f 100644 >> --- a/drivers/i2c/busses/Kconfig >> +++ b/drivers/i2c/busses/Kconfig >> @@ -779,6 +779,25 @@ config I2C_JZ4780 >>          If you don't know what to do here, say N. >>   +config I2C_K1 >> +    tristate "Spacemit K1 I2C adapter" >> +    depends on ARCH_SPACEMIT || COMPILE_TEST >> +    depends on OF >> +    help >> +      This option enables support for the I2C interface on the Spacemit K1 >> +      platform. >> + >> +      If you enable this configuration, the kernel will include support for >> +      the I2C adapter specific to the Spacemit K1 platform. This driver ca >> +      be used to manage I2C bus transactions, which are necessary for >> +      interfacing with I2C peripherals such as sensors, EEPROMs, and other >> +      devices. >> + >> +      This driver can also be compiled as a module. If you choose to build >> +      it as a module, the resulting kernel module will be named `i2c-k1`. >> +      Loading this module will enable the I2C functionality for the K1 >> +      platform dynamically, without requiring a rebuild of the kernel. >> + >>   config I2C_KEBA >>       tristate "KEBA I2C controller support" >>       depends on HAS_IOMEM >> diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile >> index ecc07c50f2a0..9744b0e58598 100644 >> --- a/drivers/i2c/busses/Makefile >> +++ b/drivers/i2c/busses/Makefile >> @@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX)        += i2c-imx.o >>   obj-$(CONFIG_I2C_IMX_LPI2C)    += i2c-imx-lpi2c.o >>   obj-$(CONFIG_I2C_IOP3XX)    += i2c-iop3xx.o >>   obj-$(CONFIG_I2C_JZ4780)    += i2c-jz4780.o >> +obj-$(CONFIG_I2C_K1)        += i2c-k1.o >>   obj-$(CONFIG_I2C_KEBA)        += i2c-keba.o >>   obj-$(CONFIG_I2C_KEMPLD)    += i2c-kempld.o >>   obj-$(CONFIG_I2C_LPC2K)        += i2c-lpc2k.o >> diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c >> new file mode 100644 >> index 000000000000..5812296bfc32 >> --- /dev/null >> +++ b/drivers/i2c/busses/i2c-k1.c >> @@ -0,0 +1,655 @@ >> +// SPDX-License-Identifier: GPL-2.0-only >> +/* >> + * Copyright (C) 2024 Troy Mitchell >> + */ >> + >> + #include >> + #include >> + #include >> + #include >> + #include >> + #include >> + >> +/* spacemit i2c registers */ > > These are good register descriptions. > >> +#define ICR          0x0        /* Control Register */ >> +#define ISR          0x4        /* Status Register */ >> +#define ISAR         0x8        /* Slave Address Register */ > > You never set the slave address register.  Is there any reason to? This register is used for slave mode and currently no slave functionality is added. I will drop it. > >> +#define IDBR         0xc        /* Data Buffer Register */ > > You never use the next three registers.  You could simplify things > by only defining them when support is added for them in the driver. I will drop them. > >> +#define ILCR         0x10        /* Load Count Register */ >> +#define IWCR         0x14        /* Wait Count Register */ >> +#define IRST_CYC     0x18        /* Bus reset cycle counter */ >> +#define IBMR         0x1c        /* Bus monitor register */ > > You do not implement any FIFO functionality currently.  I think > you can simply omit the following register definitions until > they are actually needed. I will do. > >> +#define IWFIFO       0x20        /* Write FIFO Register */ >> +#define IWFIFO_WPTR  0x24        /* Write FIFO Write Pointer Register */ >> +#define IWFIFO_RPTR  0x28        /* Write FIFO Read Pointer Register */ >> +#define IRFIFO       0x2c        /* Read FIFO Register */ >> +#define IRFIFO_WPTR  0x30        /* Read FIFO Write Pointer Register */ >> +#define IRFIFO_RPTR  0x34        /* Read FIFO Read Pointer Register */ >> + >> +/* register ICR fields */ > > The descriptions below are also good.  Maybe be consistent > with your capitalization in comments?  (Though I suppose > the capitalization above is to explain the name of the > register.) > Yes. The above is to explain the full name. So I still need to keep them consistent? >> +#define CR_START        BIT(0)        /* start bit */ >> +#define CR_STOP         BIT(1)        /* stop bit */ >> +#define CR_ACKNAK       BIT(2)        /* send ACK(0) or NAK(1) */ >> +#define CR_TB           BIT(3)        /* transfer byte bit */ >> +#define CR_TXBEGIN      BIT(4)        /* transaction begin */ >> +#define CR_FIFOEN       BIT(5)        /* enable FIFO mode */ >> +#define CR_GPIOEN       BIT(6)        /* enable GPIO mode for SCL in HS */ >> +#define CR_DMAEN        BIT(7)        /* enable DMA for TX and RX FIFOs */ >> +#define CR_MODE_FAST    BIT(8)        /* bus mode (master operation) */ >> +#define CR_MODE_HIGH    BIT(9)        /* bus mode (master operation) */ >> +#define CR_UR           BIT(10)        /* unit reset */ >> +#define CR_RSTREQ       BIT(11)        /* i2c bus reset request */ >> +#define CR_MA           BIT(12)        /* master abort */ >> +#define CR_SCLE         BIT(13)        /* master clock enable */ >> +#define CR_IUE          BIT(14)        /* unit enable */ > > /* Bit 15 is reserved */ > >> +#define CR_HS_STRETCH   BIT(16)        /* I2C hs stretch */ > > /* Bit 17 is reserved */ > > Actually, why is the CURSRC_FIX_BYPASS bit (17) not defined? I never use it. Like the registers above that are not used. Are register bits different from registers? Do register bits need to be defined even if they are not used? > > For the *IE symbols that follow, why not use *_IE as the spec > does? The symbols follow the datasheet of SpacemiT. Even if the data sheet doesn't have IE, should I add it myself? > >> +#define CR_ALDIE        BIT(18)        /* enable arbitration interrupt */ >> +#define CR_DTEIE        BIT(19)        /* enable tx interrupts */ >> +#define CR_DRFIE        BIT(20)        /* enable rx interrupts */ >> +#define CR_GCD          BIT(21)        /* general call disable */ >> +#define CR_BEIE         BIT(22)        /* enable bus error ints */ >> +#define CR_SADIE        BIT(23)        /* slave address detected int enable */ >> +#define CR_SSDIE        BIT(24)        /* slave STOP detected int enable */ >> +#define CR_MSDIE        BIT(25)        /* master STOP detected int enable */ >> +#define CR_MSDE         BIT(26)        /* master STOP detected enable */ >> +#define CR_TXDONEIE     BIT(27)        /* transaction done int enable */ >> +#define CR_TXEIE        BIT(28)        /* transmit FIFO empty int enable */ >> +#define CR_RXHFIE       BIT(29)        /* receive FIFO half-full int enable */ >> +#define CR_RXFIE        BIT(30)        /* receive FIFO full int enable */ >> +#define CR_RXOVIE       BIT(31)        /* receive FIFO overrun int enable */ >> + >> +/* register ISR fields */ > > /* Bits 0-12 are reserved */ I will add it. > >> +#define SR_RWM          BIT(13)        /* read/write mode */ >> +#define SR_ACKNAK       BIT(14)        /* ACK/NACK status */ >> +#define SR_UB           BIT(15)        /* unit busy */ >> +#define SR_IBB          BIT(16)        /* i2c bus busy */ >> +#define SR_EBB          BIT(17)        /* early bus busy */ >> +#define SR_ALD          BIT(18)        /* arbitration loss detected */ >> +#define SR_ITE          BIT(19)        /* tx buffer empty */ >> +#define SR_IRF          BIT(20)        /* rx buffer full */ >> +#define SR_GCAD         BIT(21)        /* general call address detected */ >> +#define SR_BED          BIT(22)        /* bus error no ACK/NAK */ >> +#define SR_SAD          BIT(23)        /* slave address detected */ >> +#define SR_SSD          BIT(24)        /* slave stop detected */ > > /* Bit 25 is reserved */ I will add it. > >> +#define SR_MSD          BIT(26)        /* master stop detected */ >> +#define SR_TXDONE       BIT(27)        /* transaction done */ >> +#define SR_TXE          BIT(28)        /* tx FIFO empty */ >> +#define SR_RXHF         BIT(29)        /* rx FIFO half-full */ >> +#define SR_RXF          BIT(30)        /* rx FIFO full */ >> +#define SR_RXOV         BIT(31)        /* RX FIFO overrun */ >> + >> +/* register ILCR fields */ > > Please use GENMASK(hi, lo) to define these fields, and all other > similar fields below. > >> +#define LCR_SLV         0x000001FF    /* SLV: bit[8:0] */ > > #define LCR_SLV        GENMASK(8, 0)    /* Standard-mode load value */ > > You actually never touch the ILCR register.  (Perhaps you should > do that at startup time.)  Until you do, I suggest you just remove > these definitions; they simply add space and apparent complexity > to the driver. I will. Thanks. > >> +#define LCR_FLV         0x0003FE00    /* FLV: bit[17:9] */ >> +#define LCR_HLVH        0x07FC0000    /* HLVH: bit[26:18] */ >> +#define LCR_HLVL        0xF8000000    /* HLVL: bit[31:27] */ >> + > > You never touch the IWCR register, so I suggest you omit the > definition of its fields. I will. > >> +/* register IWCR fields */ >> +#define WCR_COUNT       0x0000001F    /* COUNT: bit[4:0] */ >> +#define WCR_COUNT1      0x000003E0    /* HS_COUNT1: bit[9:5] */ >> +#define WCR_COUNT2      0x00007C00    /* HS_COUNT2: bit[14:10] */ >> + >> +/* register IBMR fields */ >> +#define BMR_SDA         BIT(0)        /* SDA line level */ >> +#define BMR_SCL         BIT(1)        /* SCL line level */ >> + > > Here too, I suggest all these FIFO field definitions can be omitted. I will do. > >> +/* register IWFIFO fields */ >> +#define WFIFO_DATA_MSK      0x000000FF  /* data: bit[7:0] */ >> +#define WFIFO_CTRL_MSK      0x000003E0  /* control: bit[11:8] */ >> +#define WFIFO_CTRL_START    BIT(8)      /* start bit */ >> +#define WFIFO_CTRL_STOP     BIT(9)      /* stop bit */ >> +#define WFIFO_CTRL_ACKNAK   BIT(10)     /* send ACK(0) or NAK(1) */ >> +#define WFIFO_CTRL_TB       BIT(11)     /* transfer byte bit */ >> + >> +/* status register init value */ >> +#define I2C_INT_STATUS_MASK    0xfffc0000  /* SR bits[31:18] */ > > Actually, this should be 0xfdff0000, because bit 25 reserved. > I would group this definition with the rest of the ISR field > definitions, above. > > Above you use a hex value; below you compute the mask value > to use symbolically.  Do one or the other in both cases. > > I'd group the next symbol with the ICR field definitions, above. Makes sense. Thanks! Very detailed. > > This describes all the interrupt-enable bits--except it omits > CR_SADIE and CR_SSDIE.  Maybe add a comment indicating this, > and explaining why. I think this is consistent with the above question. I would remove these two and other unused bits to avoid complicating the driver definition. > >> +#define I2C_INT_CTRL_MASK      (CR_ALDIE | CR_DTEIE | CR_DRFIE | \ >> +                CR_BEIE | CR_TXDONEIE | CR_TXEIE | \ >> +                CR_RXHFIE | CR_RXFIE | CR_RXOVIE | \ >> +                CR_MSDIE) >> + >> +/* i2c bus recover timeout: us */ > > What you call "bus recover" is waiting for the bus to be free > before beginning a transfer.  I'm no I2C expert, and maybe this > is a normal term, but "bus busy" timeout would be more meaningful > for me. makes sense. > >> +#define I2C_BUS_RECOVER_TIMEOUT        (100000) > > Parentheses are not required around simple constant values. > > This is the only supported frequency, correct?  That's the only frequency that driver supports now. > Is it simply assumed to be already configured that way?  (This > driver doesn't set it at initialization time.)  Someday > we should set things up explicitly. yes. by dts. I will handle frequency that is from dts in next version. > > The only place the next symbol is used is in computing a > custom timeout period before initiating a transfer. Yes, but I wanna explain the freq number is fast mode. So I define it here. But don't worry, I will drop it in next version and accept freq from dts. > >> +#define I2C_FAST_MODE_FREQ        (400000) >> + >> +enum spacemit_i2c_state { >> +    STATE_IDLE, >> +    STATE_START, >> +    STATE_READ, >> +    STATE_WRITE, >> +}; >> + > > Don't bother with spacemit_i2c_dir enumeration.  Just define > a Boolean flag in the spacemit_i2c_dev structure that indicates > whether the current transfer mode is read or not (read == true > means the same as dir == DIR_READ). I will do. > >> +enum spacemit_i2c_dir { >> +    DIR_WRITE, >> +    DIR_READ >> +}; >> + >> +/* i2c-spacemit driver's main struct */ >> +struct spacemit_i2c_dev { >> +    struct device *dev; >> +    struct i2c_adapter adapt; >> + >> +    /* hardware resources */ >> +    void __iomem *base; >> +    int irq; >> + >> +    struct i2c_msg *msgs; >> +    int msg_num; > > I don't think there's any need to keep a pointer to the > current message.  It's always i2c->msgs[msg_idx]. It is just for shorter name to avoid more line breaks... I will drop it and use local var. > >> +    struct i2c_msg *cur_msg; >> + >> +    /* index of the current message being processed */ >> +    int msg_idx; >> +    u8 *msg_buf; >> +    /* the number of unprocessed bytes remaining in each message  */ >> +    size_t unprocessed; >> + >> +    enum spacemit_i2c_state state; >> +    enum spacemit_i2c_dir dir; >> +    struct completion complete; >> +    u32 status; >> +    u32 err; > > I think you should remove the "err" field.  It only contains a > subset of what's in the status field.  It's set in the IRQ > handler: >         i2c->status = status; >         i2c->err = status & (SR_BED | SR_RXOV | SR_ALD); > And the only other time either is assigned is when they are > both zeroed in spacemit_i2c_xfer_msg(). I will. > >> +}; >> + >> +static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 val; >> + >> +    val = readl(i2c->base + ICR); > > In every other place you do read/modify/write, you do it with > three lines.  So I suggest you do this here, for consistency: > >         val = readl(i2c->base + ICR); >     val |= CR_IUE; >         writel(val, i2c->base + ICR); Thanks. Your eyes are really good. > >> +    writel(val | CR_IUE, i2c->base + ICR); >> +} >> + >> +static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 val; >> + >> +    val = readl(i2c->base + ICR); >> +    val &= ~CR_IUE; >> +    writel(val, i2c->base + ICR); >> +} >> + >> +static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c) >> +{ >> +    writel(CR_UR, i2c->base + ICR); >> +    udelay(5); > > The spec says you should ensure the unit is not busy before > asserting the reset.  It also says you should clear the ISR > register before clearing the ICR here.  (Apparently your code > still works; I'm just reporting what I read.) > >> +    writel(0, i2c->base + ICR); >> +} >> + >> +static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c); > > Just define i2c_handle_err() here, rather than declaring it > here and defining it later. > > The next function only resets the bus if it's not idle (where > "idle" means both SCL and SDA are high).  Based on the name > of the function, I'd expect it to always reset.  In other > words, I'd rather this be named something slightly different, > or have the check of SDA and SCL be done in the caller(s). How about `spacemit_i2c_conditional_reset`? Because I am worried that in the future, when the fifo or other reset is called, SDA and SCL will always be checked. > >> +static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 status; >> + >> +    /* if bus is locked, reset unit. 0: locked */ >> +    status = readl(i2c->base + IBMR); >> +    if ((status & BMR_SDA) && (status & BMR_SCL)) >> +        return; >> + >> +    spacemit_i2c_reset(i2c); >> +    usleep_range(10, 20); >> + >> +    /* check scl status again */ >> +    status = readl(i2c->base + IBMR); >> +    if (!(status & BMR_SCL)) >> +        dev_warn_ratelimited(i2c->dev, "unit reset failed\n"); >> +} >> + >> +static int spacemit_i2c_recover_bus_busy(struct spacemit_i2c_dev *i2c) >> +{ >> +    int ret = 0; >> +    u32 val; >> + > > I think the next 4 lines can be deleted.  The readl_poll_timeout() > immediately does what they do, without delay. The register value is always returned directly。 but it needs to be judged if the bus is busy by !(val & (SR_UB | SR_IBB). > >> +    val = readl(i2c->base + ISR); >> +    if (likely(!(val & (SR_UB | SR_IBB)))) >> +        return 0; >> + >> +    ret = readl_poll_timeout(i2c->base + ISR, val, !(val & (SR_UB | SR_IBB)), >> +                 1500, I2C_BUS_RECOVER_TIMEOUT); >> +    if (unlikely(ret)) { >> +        spacemit_i2c_reset(i2c); > > If readl_poll_timeout() returns non-zero, it is -ETIMEDOUT. > Why change it to -EAGAIN?  (It ultimately gets consumed by > spacemit_i2c_xfer(), which handles -ETIMEDOUT and -EAGAIN > identically. I will drop it. > >> +        ret = -EAGAIN; >> +    } >> + >> +    return ret; >> +} >> + >> +static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c) >> +{ >> +    /* in case bus is not released after transfer completes */ > > As said by others, you essentially *never* need to specify > likely() or unlikely().  And nowhere in this code are you > running in such a performance-critical way that it matters. I will drop them. > >> +    if (unlikely(readl(i2c->base + ISR) & SR_EBB)) { >> +        spacemit_i2c_bus_reset(i2c); >> +        usleep_range(90, 150); >> +    } >> +} >> + >> +static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 val = 0; >> + >> +    /* >> +     * Unmask interrupt bits for all xfer mode: >> +     * bus error, arbitration loss detected. >> +     * For transaction complete signal, we use master stop >> +     * interrupt, so we don't need to unmask CR_TXDONEIE. >> +     */ >> +    val |= CR_BEIE | CR_ALDIE; > > I'd just skip zeroing val above and doing this here: >     val = CR_BEIE | CR_ALDIE; I will. Thanks. >> + >> +    /* >> +     * Unmask interrupt bits for interrupt xfer mode: >> +     * DBR rx full. >> +     * For tx empty interrupt CR_DTEIE, we only >> +     * need to enable when trigger byte transfer to start >> +     * data sending. >> +     */ >> +    val |= CR_DRFIE; >> + >> +    /* set speed bits: default fast mode */ >> +    val |= CR_MODE_FAST; >> + >> +    /* disable response to general call */ >> +    val |= CR_GCD; >> + >> +    /* enable SCL clock output */ >> +    val |= CR_SCLE; >> + >> +    /* enable master stop detected */ >> +    val |= CR_MSDE | CR_MSDIE; >> + >> +    writel(val, i2c->base + ICR); >> +} >> + > > The following function is used in two places, but I don't think > it really adds any value.  Just open-code the writel() call in > those two spots. I want to explain more clearly what is done in the init phase, so I put them into a function and assign values step by step. Is it not necessary? or maybe I can add `inline`. > >> +static inline void >> +spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask) >> +{ >> +    writel(mask & I2C_INT_STATUS_MASK, i2c->base + ISR); >> +} >> + >> +static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 slave_addr_rw, val; > > Use a local variable to track the current message.  There's > no need to stash it in the i2c structure. I will. > >     struct i2c_msg *cur_msg = i2c->msgs[i2c->msg_idx]; >> + >> +    i2c->dir = i2c->cur_msg->flags & I2C_M_RD; > > As suggested before, use a Boolean "read" flag instead. I will. > >     i2c->read = i2c->cur_msg->flags & I2C_M_RD; > > (This doesn't assume I2C_M_RD == DIR_READ either, though > technically I2C_M_RD is guaranteed to be 1...> >> +    i2c->state = STATE_START; >> + >> +    if (i2c->cur_msg->flags & I2C_M_RD) >> +        slave_addr_rw = ((i2c->cur_msg->addr & 0x7f) << 1) | 1; >> +    else >> +        slave_addr_rw = (i2c->cur_msg->addr & 0x7f) << 1; > >     slave_addr_rw = (i2c->cur_msg->addr & 0x7f) << 1; >     if (i2c->read) >         slave_addr_rw |= I2C_M_RD; cool, I will > >> + >> +    writel(slave_addr_rw, i2c->base + IDBR); >> + > > Put the "send start pulse" comment here, then group the lines > that read/modify/write the register together. I will. > >> +    val = readl(i2c->base + ICR); >> + >> +    /* send start pulse */ >> +    val &= ~CR_STOP; >> +    val |= CR_START | CR_TB | CR_DTEIE; >> +    writel(val, i2c->base + ICR); >> +} >> + >> +static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 val; >> + >> +    val = readl(i2c->base + ICR); >> + >> +    val |= CR_STOP | CR_ALDIE | CR_TB; >> + >> +    if (i2c->dir == DIR_READ) >> +        val |= CR_ACKNAK; >> + >> +    writel(val, i2c->base + ICR); >> +} >> + >> +static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c) >> +{ >> +    unsigned long time_left; >> + >> +    for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) { >> +        i2c->cur_msg = i2c->msgs + i2c->msg_idx; >> +        i2c->msg_buf = i2c->cur_msg->buf; >> +        i2c->err = 0; >> +        i2c->status = 0; >> +        i2c->unprocessed = i2c->cur_msg->len; >> + >> +        reinit_completion(&i2c->complete); >> + >> +        spacemit_i2c_start(i2c); >> + >> +        time_left = wait_for_completion_timeout(&i2c->complete, >> +                            i2c->adapt.timeout); >> +        if (unlikely(time_left == 0)) { > >         if (!time_left) { I will drop all unlikely/likely > >> +            dev_alert(i2c->dev, "msg completion timeout\n"); >> +            spacemit_i2c_bus_reset(i2c); >> +            spacemit_i2c_reset(i2c); >> +            return -ETIMEDOUT; >> +        } >> + >> +        if (unlikely(i2c->err)) >> +            return spacemit_i2c_handle_err(i2c); >> +    } >> + >> +    return 0; >> +} >> + >> +static int spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c) >> +{ > > static bool spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c) > { >     if (i2c->msg_idx != i2c->msg_num - 1) >         return false; >      >     if (i2c->read) >         return i2c->unprocessed == 1; > >     return !i2c->unprocessed; > } > cool method. I learn a lot from ur review. Thanks again. >> +    if (i2c->dir == DIR_READ) { >> +        if (i2c->unprocessed == 1 && i2c->msg_idx == i2c->msg_num - 1) >> +            return 1; >> +    } else if (i2c->dir == DIR_WRITE) { >> +        if (!i2c->unprocessed && i2c->msg_idx == i2c->msg_num - 1) >> +            return 1; >> +    } >> + >> +    return 0; >> +} >> + >> +static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c) >> +{ >> +    /* if transfer completes, ISR will handle it */ >> +    if (i2c->status & SR_MSD) >> +        return; >> + >> +    if (i2c->unprocessed) { >> +        writel(*i2c->msg_buf++, i2c->base + IDBR); >> +        i2c->unprocessed--; >> +        return; >> +    } >> + >> +    /* STATE_IDLE avoids trigger next byte */ >> +    i2c->state = STATE_IDLE; >> +    complete(&i2c->complete); >> +} >> + >> +static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c) >> +{ >> +    if (i2c->unprocessed) { >> +        *i2c->msg_buf++ = readl(i2c->base + IDBR); >> +        i2c->unprocessed--; >> +    } >> + >> +    /* if transfer completes, ISR will handle it */ >> +    if (i2c->status & (SR_MSD | SR_ACKNAK)) >> +        return; >> + >> +    /* it has to append stop bit in icr that read last byte */ >> +    if (i2c->unprocessed) >> +        return; >> + >> +    /* STATE_IDLE avoids trigger next byte */ >> +    i2c->state = STATE_IDLE; >> +    complete(&i2c->complete); >> +} >> + >> +static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c) >> +{ > { >     i2c->state = i2c->read ? STATE_READ : STATE_WRITE; >     if (i2c->state == STATE_WRITE) >         spacemit_i2c_handle_write(i2c); > } > cool. >> +    if (i2c->dir == DIR_READ) { >> +        i2c->state = STATE_READ; >> +        return; >> +    } >> + >> +    if (i2c->dir == DIR_WRITE) { >> +        i2c->state = STATE_WRITE; >> +        spacemit_i2c_handle_write(i2c); >> +    } >> +} >> + >> +static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c) >> +{ > > This function is only called in one place, and in that place > the caller already verified that i2c->err is non-zero.  So > drop the next if statement. I will. > >> +    if (!i2c->err) >> +        return 0; >> + >> +    dev_dbg(i2c->dev, "i2c error status: 0x%08x\n",    i2c->status); >> + >> +    if (i2c->err & (SR_BED | SR_ALD)) >> +        spacemit_i2c_reset(i2c); >> + >> +    if (i2c->err & (SR_RXOV | SR_ALD)) >> +        return -EAGAIN; >> + >> +    return (i2c->status & SR_ACKNAK) ? -ENXIO : -EIO; > > No need for parentheses in the above line. I will drop. > >> +} >> + >> +static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c) >> +{ >> +    u32 val; > > Add a blank line here. Thanks! > > Change the logic to: >     if (!i2c->err && !(i2c->status & SR_MSD)) >         return; > > Then the rest of the function can be shifted out a level. > > If you get rid of i2c->err, this can be: >     u32 error = i2c->status & (SR_ALD | SR_BED | SR_MSD | SR_RXOV); > >     if (!error) >         return; > That's so detailed. Sry for my newbie behavior >> +    /* >> +     * send transaction complete signal: >> +     * error happens, detect master stop >> +     */ >> +    if (likely(i2c->err || (i2c->status & SR_MSD))) { >> +        /* >> +         * Here the transaction is already done, we don't need any >> +         * other interrupt signals from now, in case any interrupt >> +         * happens before spacemit_i2c_xfer to disable irq and i2c unit, >> +         * we mask all the interrupt signals and clear the interrupt >> +         * status. >> +         */ >> +        val = readl(i2c->base + ICR); >> +        val &= ~I2C_INT_CTRL_MASK; >> +        writel(val, i2c->base + ICR); >> + > > Why are *all* interrupt status bits cleared here, rather than > just the ones with bits set in i2c->status? Because if there are any errors, we don't need interrupts to avoid further issues. just exit. > >> +        spacemit_i2c_clear_int_status(i2c, I2C_INT_STATUS_MASK); >> + >> +        i2c->state = STATE_IDLE; >> +        complete(&i2c->complete); >> +    } >> +} >> + >> +static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid) >> +{ >> +    struct spacemit_i2c_dev *i2c = devid; >> +    u32 status, val; >> + >> +    status = readl(i2c->base + ISR); > > Is there any reason not to assign i2c->status here? actualy to avoid zero. But I think there is not reason to avoid zero. I will drop local var. > >> +    if (!status) >> +        return IRQ_HANDLED; >> + >> +    i2c->status = status; >> + >> +    i2c->err = status & (SR_BED | SR_RXOV | SR_ALD); > > As I said earlier, I think you can simply check these bits in > the status field rather than tracking i2c->err separately. > I think the result will actually be a little simpler. ok. > >> + >> +    spacemit_i2c_clear_int_status(i2c, status); >> + >> +    if (unlikely(i2c->err)) >> +        goto err_out; >> + >> +    val = readl(i2c->base + ICR); >> + >> +    val &= ~(CR_TB | CR_ACKNAK | CR_STOP | CR_START); >> +    writel(val, i2c->base + ICR); >> + >> +    switch (i2c->state) { >> +    case STATE_START: >> +        spacemit_i2c_handle_start(i2c); >> +        break; >> +    case STATE_READ: >> +        spacemit_i2c_handle_read(i2c); >> +        break; >> +    case STATE_WRITE: >> +        spacemit_i2c_handle_write(i2c); >> +        break; >> +    default: >> +        break; >> +    } >> + >> +    if (i2c->state != STATE_IDLE) { >> +        if (spacemit_i2c_is_last_msg(i2c)) { >> +            /* trigger next byte with stop */ >> +            spacemit_i2c_stop(i2c); >> +        } else { >> +            /* trigger next byte */ >> +            val |= CR_ALDIE | CR_TB; >> +            writel(val, i2c->base + ICR); >> +        } >> +    } >> + >> +err_out: >> +    spacemit_i2c_err_check(i2c); >> +    return IRQ_HANDLED; >> +} >> + >> +static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c) >> +{ >> +    unsigned long timeout; >> +    int idx = 0, cnt = 0, freq; >> + > > This loop counts the number of i2c_msg structs, and adds up > the number of bytes that must be transferred (including the > target address for each) for them all.> >> +    while (idx < i2c->msg_num) { >> +        cnt += (i2c->msgs + idx)->len + 1; >> +        idx++; >> +    } >> + >> +    freq = I2C_FAST_MODE_FREQ; > > You can just use I2C_FAST_MODE_FREQ below, and get rid of the > local variable. In this version, we can use I2C_FAST_MODE_FREQ. but as I said earlier, I will read freq from dts. so I will add i2c->freq to storage and modify this function. > >> +    /* >> +     * multiply by 9 because each byte in I2C transmission requires >> +     * 9 clock cycles: 8 bits of data plus 1 ACK/NACK bit. >> +     */ >> +    timeout = cnt * 9 * USEC_PER_SEC / freq; > > So now, timeout is the number of microseconds required to transfer > all bits across all messages. > > The next line has me confused. > > You add half a second, and convert it to jiffies.  (Why add half > a second?) half a second is buffer time to avoid extremely low probability events. > > Then you divide that by the number of messages.  (Why divide by > this?  This timeout applies to the time required to transfer > all message segments in a tranasaction, right.  I.e., the time > required for a call to call spacemit_i2c_xfer()?) just one msg instead of all msgs. so that's why we divide that by the number of msgs. and half a second is equally divided among each message. > >> + >> +    i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 2) / >> i2c->msg_num; >> +} >> + >> +static int spacemit_i2c_xfer_core(struct spacemit_i2c_dev *i2c) >> +{ >> +    int ret; >> + >> +    spacemit_i2c_reset(i2c); >> + >> +    spacemit_i2c_calc_timeout(i2c); >> + >> +    spacemit_i2c_init(i2c); >> + >> +    spacemit_i2c_enable(i2c); >> +    enable_irq(i2c->irq); >> + >> +    /* i2c wait for bus busy */ >> +    ret = spacemit_i2c_recover_bus_busy(i2c); >> +    if (unlikely(ret)) >> +        return ret; >> + >> +    ret = spacemit_i2c_xfer_msg(i2c); >> +    if (unlikely(ret < 0)) { >> +        dev_dbg(i2c->dev, "i2c transfer error\n"); > > Put the dev_dbg() call under the next comment. I will. > >> +        /* timeout error should not be overridden, and the transfer >> +         * error will be confirmed by err handle function latter, >> +         * the reset should be invalid argument error. >> +         */ >> +        if (ret != -ETIMEDOUT) >> +            ret = -EINVAL; >> +    } >> + >> +    return ret; >> +} >> + >> +static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg >> msgs[], int num) > > Why do you use msgs[] in the prototype rather than *msgs as the > definition of the i2c_algorithm structure does? I will. > >> +{ >> +    struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt); >> +    int ret; >> + >> +    i2c->msgs = msgs; >> +    i2c->msg_num = num; >> + >> +    ret = spacemit_i2c_xfer_core(i2c); >> +    if (likely(!ret)) >> +        spacemit_i2c_check_bus_release(i2c); >> + >> +    disable_irq(i2c->irq); >> + >> +    spacemit_i2c_disable(i2c); >> + >> +    if (unlikely((ret == -ETIMEDOUT || ret == -EAGAIN))) >> +        dev_alert(i2c->dev, "i2c transfer failed, ret %d err 0x%x\n", ret, >> i2c->err); >> + >> +    return ret < 0 ? ret : num; >> +} >> + >> +static u32 spacemit_i2c_func(struct i2c_adapter *adap) >> +{ >> +    return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); >> +} >> + >> +static const struct i2c_algorithm spacemit_i2c_algo = { >> +    .xfer = spacemit_i2c_xfer, >> +    .functionality = spacemit_i2c_func, >> +}; >> + >> +static int spacemit_i2c_probe(struct platform_device *pdev) >> +{ >> +    struct spacemit_i2c_dev *i2c; >> +    struct device_node *of_node = pdev->dev.of_node; > >     struct device *dev = &pdev->dev; > > Then use the local "dev" pointer in all calls below. I will. > >> +    struct clk *clk; >> +    int ret = 0; >> + >> +    i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); >> +    if (!i2c) >> +        return -ENOMEM; >> + >> +    i2c->dev = &pdev->dev; >> + >> +    i2c->base = devm_platform_ioremap_resource(pdev, 0); >> +    if (IS_ERR(i2c->base)) >> +        return dev_err_probe(&pdev->dev, PTR_ERR(i2c->base), "failed to do >> ioremap"); >> + >> +    i2c->irq = platform_get_irq(pdev, 0); >> +    if (i2c->irq < 0) >> +        return dev_err_probe(&pdev->dev, i2c->irq, "failed to get irq >> resource"); >> + >> +    ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler, >> +                   IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c); >> +    if (ret) >> +        return dev_err_probe(&pdev->dev, ret, "failed to request irq"); >> + >> +    disable_irq(i2c->irq); >> + >> +    clk = devm_clk_get_enabled(&pdev->dev, NULL); >> +    if (IS_ERR(clk)) >> +        return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to enable >> clock"); >> + >> +    i2c_set_adapdata(&i2c->adapt, i2c); >> +    i2c->adapt.owner = THIS_MODULE; >> +    i2c->adapt.algo = &spacemit_i2c_algo; >> +    i2c->adapt.dev.parent = i2c->dev; >> +    i2c->adapt.nr = pdev->id; >> + >> +    i2c->adapt.dev.of_node = of_node; >> +    i2c->adapt.algo_data = i2c; >> + >> +    strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name)); >> + >> +    init_completion(&i2c->complete); >> + > > Set the driver data here so it's fully initialized > before you add it. I will. > >                     -Alex Thank you very much Alex for giving me very detailed instructions. > >> +    ret = i2c_add_numbered_adapter(&i2c->adapt); >> +    if (ret) >> +        return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter"); >> + >> +    platform_set_drvdata(pdev, i2c); >> + >> +    return 0; >> +} >> + >> +static void spacemit_i2c_remove(struct platform_device *pdev) >> +{ >> +    struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev); >> + >> +    i2c_del_adapter(&i2c->adapt); >> +} >> + >> +static const struct of_device_id spacemit_i2c_of_match[] = { >> +    { .compatible = "spacemit,k1-i2c", }, >> +    { /* sentinel */ } >> +}; >> +MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match); >> + >> +static struct platform_driver spacemit_i2c_driver = { >> +    .probe = spacemit_i2c_probe, >> +    .remove = spacemit_i2c_remove, >> +    .driver = { >> +        .name = "i2c-k1", >> +        .of_match_table = spacemit_i2c_of_match, >> +    }, >> +}; >> +module_platform_driver(spacemit_i2c_driver); >> + >> +MODULE_LICENSE("GPL"); >> +MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC"); >> > -- Troy Mitchell From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8219DC0219D for ; Thu, 13 Feb 2025 11:39:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:From:References:To:Subject: Cc:MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3+5MQuijHb8mgh6aj2s7VnAcuzLzb0k3Jnsl90QWZ/U=; b=f+3c0Q2okZVr1F /oLMNoEtWgWubOIFqFWbz76ZjTsSTw/sm9Js8I0iURMQBcljidRnMmD2vwG+9FpaS0YOy/CXRbYxB abvZOnichPNv7CRRoP/Pi7Ordw2F66AMp8PSZ29seWGT2cTd9XTBrq7FVbikLUtuDYnaw9RNtdMuw I115sYe92MOfquD0Eu59YDcBpclz583FRTYCZGbeboTUE4DfuNwmvaX2mty7bqvkqFcwQrbtWv07g wuyUb8SVGbYczVoGMYx6of7L5cHoEo/GGuSjXO4CirbNV89PNmBOgRj0Y/gMCAGF98dYDyHTrGgRH Nji5oyfB0KyXr/xE8mZg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tiXYi-0000000At6W-3I57; Thu, 13 Feb 2025 11:39:08 +0000 Received: from mail-pl1-x643.google.com ([2607:f8b0:4864:20::643]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tiXYO-0000000At36-0QVc for linux-riscv@lists.infradead.org; Thu, 13 Feb 2025 11:38:49 +0000 Received: by mail-pl1-x643.google.com with SMTP id d9443c01a7336-21f6d2642faso19033585ad.1 for ; Thu, 13 Feb 2025 03:38:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739446727; x=1740051527; darn=lists.infradead.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:cc:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=Nu4dweML0+Ie1q0qi8i3kLeCSVDD+04dwqEC37g0okk=; b=FdQ55REu7GSQ6ZCCaV6w7iRxj7i45dtEUNDi75xXlBsxVF76VPgPcoXh2wpktW751t R/pgGyK+8O/QrVeVRnQleKSGvXsDls832/H8FIIvzO7+685VhJbHMnyVwFL463mv4CKf PDXpjC2dXG5+jp29Z+n5pa23wwOZPL0M7iEiIp5gV8WHMx7vwTCBaoTPNIBiGQ7FCr6a opSdsRgp2voFNOkHCQesrUPGNbQcjVpWTYUacHKfGhUvTgF51ZTuCq3tkigfIFHTnaSU J7SNJ3iiGWCjBgd/gXnMBokj7bmlmr46soTqZYHu8EMTSdp7Gjdu9JYXf0vxwl48tNja mgpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739446727; x=1740051527; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:cc:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Nu4dweML0+Ie1q0qi8i3kLeCSVDD+04dwqEC37g0okk=; b=X3dMDK6PvB48TB4tG/5a2BOnBQARZFRM/fl0qUFWIDt24WUu7ZPMHAYH7LzMmc379O eKEfzb1DvGoepr1powFFvH6VKPdHhA15eiwXsMP8KepkEsRjGc1n9dSXeJ6KAXIIdyZK 9G1UYaTPapSU2ky5DBKC33cUWikXGbkcwLuRecYPEvyFtHRq6VamA8jLwmX5C5bIOYkX O40UjodFT1Q5PfMaX+KX2uH7Uft3u3O6tsPFYTX8aM/EeuJEgX5f0O0DrhKjhT7iNpEU HwCP9AJJwKD4BYcfKRxnJtRJAifSkVlsuE3jhIREvAcxXQvIUiRKGmSLDInoQ/KPtN6c pKNw== X-Forwarded-Encrypted: i=1; AJvYcCWRP7uuu3UM1h/jzJ2pXzso/hlLTKkV2SD6nH5xxopTp7pvOdInIdAPa3tu8Y264VWMkgyWMITpyVd4mA==@lists.infradead.org X-Gm-Message-State: AOJu0YzL+Ky3DI73d+UylN0IXS3i3PDVMxoznWs0ClFsxvSjmgvXpyEb J72pva3w5IgAGqRlIXqScGsNQdJPtlTZc7el3ozrKBWB/gdWPQdt X-Gm-Gg: ASbGnctOp6Ybiby0alrCG2wgYaAIitWpf3UXSswx+vVs2qnhBPWwzQbPNZ4YPj91F7a ncRHaeHyJ+n3hqK4j65R+1KycJepeKbpC8qbf1zLB7ayoGOyfPFWUqibSbtAd96MB/1GPZk+1AA cUMGBDTRdDm1iTKfmThMGUFu9s0WWh6j0LShiLG9M7AJ11pQyNOsVKuAP+pNVSjOfmAVwh7/MDE gf03kHdwDg4zn/rHgGhRMd6xJdR2ORFFh7Q8iMotoLCZKCNqOD7UbFeyewOgAdkUd6YuThxz2Q= X-Google-Smtp-Source: AGHT+IFRw10Abzym+Gw/HDJE8srGG6kzSoM3Umm1CUVPJlbKkT+yq5D0RSUBiYifJdlbBlbJZjnuQw== X-Received: by 2002:a17:902:f78f:b0:21f:1549:a55f with SMTP id d9443c01a7336-220bbad9896mr113149055ad.19.1739446726338; Thu, 13 Feb 2025 03:38:46 -0800 (PST) Received: from [127.0.0.1] ([2407:cdc0:8010::ec]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-220d53490c2sm10797505ad.47.2025.02.13.03.38.40 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 13 Feb 2025 03:38:45 -0800 (PST) Message-ID: <8ccec6ba-4897-424e-8ff1-cfc663dfa2b5@gmail.com> Date: Thu, 13 Feb 2025 19:38:36 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Cc: troymitchell988@gmail.com, linux-riscv@lists.infradead.org, linux-i2c@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v4 2/2] i2c: spacemit: add support for SpacemiT K1 SoC To: Alex Elder , Andi Shyti , Rob Herring , Krzysztof Kozlowski , Conor Dooley References: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com> <20241125-k1-i2c-master-v4-2-0f3d5886336b@gmail.com> <4658f274-5df6-4055-82db-118217f28447@ieee.org> Content-Language: en-US From: Troy Mitchell In-Reply-To: <4658f274-5df6-4055-82db-118217f28447@ieee.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250213_033848_166915_2B025C8D X-CRM114-Status: GOOD ( 37.74 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org SGkhIEFsZXguClRoYW5rcyBmb3IgdXIgZGV0YWlsZWQgcmV2aWV3LgoKT24gMjAyNS8yLzEyIDA1 OjM5LCBBbGV4IEVsZGVyIHdyb3RlOgo+IE9uIDExLzI1LzI0IDEyOjQ5IEFNLCBUcm95IE1pdGNo ZWxsIHdyb3RlOgo+PiBGcm9tOiBUcm95IE1pdGNoZWxsIDx0cm95bWl0Y2hlbGw5ODhAZ21haWwu Y29tPgo+Pgo+PiBUaGlzIHBhdGNoIGludHJvZHVjZXMgYmFzaWMgSTJDIHN1cHBvcnQgZm9yIHRo ZSBTcGFjZW1pVCBLMSBTb0MsCj4+IHV0aWxpemluZyBpbnRlcnJ1cHRzIGZvciB0cmFuc2ZlcnMu Cj4+Cj4+IFRoZSBkcml2ZXIgaGFzIGJlZW4gdGVzdGVkIHVzaW5nIGkyYy10b29scyBvbiBhIEJh bmFuYXBpLUYzIGJvYXJkLAo+PiBhbmQgYmFzaWMgSTJDIHJlYWQvd3JpdGUgb3BlcmF0aW9ucyBo YXZlIGJlZW4gY29uZmlybWVkIHRvIHdvcmsuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IFRyb3kgTWl0 Y2hlbGwgPFRyb3lNaXRjaGVsbDk4OEBnbWFpbC5jb20+Cj4gCj4gVGhpcyBpcyBhIHZlcnkgZGV0 YWlsZWQgcmV2aWV3LsKgIE15IGhvcGUgaXMgdGhhdCB0aGlzIGhlbHBzCj4gZ2V0IHRoaXMgZHJp dmVyIHJlYWR5IGZvciBhY2NlcHRhbmNlIG1vcmUgcXVpY2tseS4KVGhhbmtzLiBJIHdpbGwgaGFu ZGxlIGl0IEFTQVAuCj4gCj4+IC0tLQo+PiDCoCBkcml2ZXJzL2kyYy9idXNzZXMvS2NvbmZpZ8Kg IHzCoCAxOSArKwo+PiDCoCBkcml2ZXJzL2kyYy9idXNzZXMvTWFrZWZpbGUgfMKgwqAgMSArCj4+ IMKgIGRyaXZlcnMvaTJjL2J1c3Nlcy9pMmMtazEuYyB8IDY1NSArKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKwo+PiDCoCAzIGZpbGVzIGNoYW5nZWQsIDY3NSBpbnNl cnRpb25zKCspCj4+Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2kyYy9idXNzZXMvS2NvbmZpZyBi L2RyaXZlcnMvaTJjL2J1c3Nlcy9LY29uZmlnCj4+IGluZGV4IDZiM2JhN2U1NzIzYS4uOTE2MzBm NTU2NjdmIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2kyYy9idXNzZXMvS2NvbmZpZwo+PiArKysg Yi9kcml2ZXJzL2kyYy9idXNzZXMvS2NvbmZpZwo+PiBAQCAtNzc5LDYgKzc3OSwyNSBAQCBjb25m aWcgSTJDX0paNDc4MAo+PiDCoCDCoMKgwqDCoMKgwqAgSWYgeW91IGRvbid0IGtub3cgd2hhdCB0 byBkbyBoZXJlLCBzYXkgTi4KPj4gwqAgK2NvbmZpZyBJMkNfSzEKPj4gK8KgwqDCoCB0cmlzdGF0 ZSAiU3BhY2VtaXQgSzEgSTJDIGFkYXB0ZXIiCj4+ICvCoMKgwqAgZGVwZW5kcyBvbiBBUkNIX1NQ QUNFTUlUIHx8IENPTVBJTEVfVEVTVAo+PiArwqDCoMKgIGRlcGVuZHMgb24gT0YKPj4gK8KgwqDC oCBoZWxwCj4+ICvCoMKgwqDCoMKgIFRoaXMgb3B0aW9uIGVuYWJsZXMgc3VwcG9ydCBmb3IgdGhl IEkyQyBpbnRlcmZhY2Ugb24gdGhlIFNwYWNlbWl0IEsxCj4+ICvCoMKgwqDCoMKgIHBsYXRmb3Jt Lgo+PiArCj4+ICvCoMKgwqDCoMKgIElmIHlvdSBlbmFibGUgdGhpcyBjb25maWd1cmF0aW9uLCB0 aGUga2VybmVsIHdpbGwgaW5jbHVkZSBzdXBwb3J0IGZvcgo+PiArwqDCoMKgwqDCoCB0aGUgSTJD IGFkYXB0ZXIgc3BlY2lmaWMgdG8gdGhlIFNwYWNlbWl0IEsxIHBsYXRmb3JtLiBUaGlzIGRyaXZl ciBjYQo+PiArwqDCoMKgwqDCoCBiZSB1c2VkIHRvIG1hbmFnZSBJMkMgYnVzIHRyYW5zYWN0aW9u cywgd2hpY2ggYXJlIG5lY2Vzc2FyeSBmb3IKPj4gK8KgwqDCoMKgwqAgaW50ZXJmYWNpbmcgd2l0 aCBJMkMgcGVyaXBoZXJhbHMgc3VjaCBhcyBzZW5zb3JzLCBFRVBST01zLCBhbmQgb3RoZXIKPj4g K8KgwqDCoMKgwqAgZGV2aWNlcy4KPj4gKwo+PiArwqDCoMKgwqDCoCBUaGlzIGRyaXZlciBjYW4g YWxzbyBiZSBjb21waWxlZCBhcyBhIG1vZHVsZS4gSWYgeW91IGNob29zZSB0byBidWlsZAo+PiAr wqDCoMKgwqDCoCBpdCBhcyBhIG1vZHVsZSwgdGhlIHJlc3VsdGluZyBrZXJuZWwgbW9kdWxlIHdp bGwgYmUgbmFtZWQgYGkyYy1rMWAuCj4+ICvCoMKgwqDCoMKgIExvYWRpbmcgdGhpcyBtb2R1bGUg d2lsbCBlbmFibGUgdGhlIEkyQyBmdW5jdGlvbmFsaXR5IGZvciB0aGUgSzEKPj4gK8KgwqDCoMKg wqAgcGxhdGZvcm0gZHluYW1pY2FsbHksIHdpdGhvdXQgcmVxdWlyaW5nIGEgcmVidWlsZCBvZiB0 aGUga2VybmVsLgo+PiArCj4+IMKgIGNvbmZpZyBJMkNfS0VCQQo+PiDCoMKgwqDCoMKgIHRyaXN0 YXRlICJLRUJBIEkyQyBjb250cm9sbGVyIHN1cHBvcnQiCj4+IMKgwqDCoMKgwqAgZGVwZW5kcyBv biBIQVNfSU9NRU0KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaTJjL2J1c3Nlcy9NYWtlZmlsZSBi L2RyaXZlcnMvaTJjL2J1c3Nlcy9NYWtlZmlsZQo+PiBpbmRleCBlY2MwN2M1MGYyYTAuLjk3NDRi MGU1ODU5OCAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9pMmMvYnVzc2VzL01ha2VmaWxlCj4+ICsr KyBiL2RyaXZlcnMvaTJjL2J1c3Nlcy9NYWtlZmlsZQo+PiBAQCAtNzYsNiArNzYsNyBAQCBvYmot JChDT05GSUdfSTJDX0lNWCnCoMKgwqDCoMKgwqDCoCArPSBpMmMtaW14Lm8KPj4gwqAgb2JqLSQo Q09ORklHX0kyQ19JTVhfTFBJMkMpwqDCoMKgICs9IGkyYy1pbXgtbHBpMmMubwo+PiDCoCBvYmot JChDT05GSUdfSTJDX0lPUDNYWCnCoMKgwqAgKz0gaTJjLWlvcDN4eC5vCj4+IMKgIG9iai0kKENP TkZJR19JMkNfSlo0NzgwKcKgwqDCoCArPSBpMmMtano0NzgwLm8KPj4gK29iai0kKENPTkZJR19J MkNfSzEpwqDCoMKgwqDCoMKgwqAgKz0gaTJjLWsxLm8KPj4gwqAgb2JqLSQoQ09ORklHX0kyQ19L RUJBKcKgwqDCoMKgwqDCoMKgICs9IGkyYy1rZWJhLm8KPj4gwqAgb2JqLSQoQ09ORklHX0kyQ19L RU1QTEQpwqDCoMKgICs9IGkyYy1rZW1wbGQubwo+PiDCoCBvYmotJChDT05GSUdfSTJDX0xQQzJL KcKgwqDCoMKgwqDCoMKgICs9IGkyYy1scGMyay5vCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2ky Yy9idXNzZXMvaTJjLWsxLmMgYi9kcml2ZXJzL2kyYy9idXNzZXMvaTJjLWsxLmMKPj4gbmV3IGZp bGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi41ODEyMjk2YmZjMzIKPj4gLS0t IC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL2kyYy9idXNzZXMvaTJjLWsxLmMKPj4gQEAgLTAs MCArMSw2NTUgQEAKPj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkK Pj4gKy8qCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMjQgVHJveSBNaXRjaGVsbCA8dHJveW1pdGNo ZWxsOTg4QGdtYWlsLmNvbT4KPj4gKyAqLwo+PiArCj4+ICsgI2luY2x1ZGUgPGxpbnV4L2Nsay5o Pgo+PiArICNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPj4gKyAjaW5jbHVkZSA8bGludXgvaW9wb2xs Lmg+Cj4+ICsgI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+PiArICNpbmNsdWRlIDxsaW51eC9v Zl9hZGRyZXNzLmg+Cj4+ICsgI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+PiAr Cj4+ICsvKiBzcGFjZW1pdCBpMmMgcmVnaXN0ZXJzICovCj4gCj4gVGhlc2UgYXJlIGdvb2QgcmVn aXN0ZXIgZGVzY3JpcHRpb25zLgo+IAo+PiArI2RlZmluZSBJQ1LCoMKgwqDCoMKgwqDCoMKgwqAg MHgwwqDCoMKgwqDCoMKgwqAgLyogQ29udHJvbCBSZWdpc3RlciAqLwo+PiArI2RlZmluZSBJU1LC oMKgwqDCoMKgwqDCoMKgwqAgMHg0wqDCoMKgwqDCoMKgwqAgLyogU3RhdHVzIFJlZ2lzdGVyICov Cj4+ICsjZGVmaW5lIElTQVLCoMKgwqDCoMKgwqDCoMKgIDB4OMKgwqDCoMKgwqDCoMKgIC8qIFNs YXZlIEFkZHJlc3MgUmVnaXN0ZXIgKi8KPiAKPiBZb3UgbmV2ZXIgc2V0IHRoZSBzbGF2ZSBhZGRy ZXNzIHJlZ2lzdGVyLsKgIElzIHRoZXJlIGFueSByZWFzb24gdG8/ClRoaXMgcmVnaXN0ZXIgaXMg dXNlZCBmb3Igc2xhdmUgbW9kZSBhbmQgY3VycmVudGx5IG5vIHNsYXZlIGZ1bmN0aW9uYWxpdHkg aXMgYWRkZWQuCkkgd2lsbCBkcm9wIGl0Lgo+IAo+PiArI2RlZmluZSBJREJSwqDCoMKgwqDCoMKg wqDCoCAweGPCoMKgwqDCoMKgwqDCoCAvKiBEYXRhIEJ1ZmZlciBSZWdpc3RlciAqLwo+IAo+IFlv dSBuZXZlciB1c2UgdGhlIG5leHQgdGhyZWUgcmVnaXN0ZXJzLsKgIFlvdSBjb3VsZCBzaW1wbGlm eSB0aGluZ3MKPiBieSBvbmx5IGRlZmluaW5nIHRoZW0gd2hlbiBzdXBwb3J0IGlzIGFkZGVkIGZv ciB0aGVtIGluIHRoZSBkcml2ZXIuCkkgd2lsbCBkcm9wIHRoZW0uCj4gCj4+ICsjZGVmaW5lIElM Q1LCoMKgwqDCoMKgwqDCoMKgIDB4MTDCoMKgwqDCoMKgwqDCoCAvKiBMb2FkIENvdW50IFJlZ2lz dGVyICovCj4+ICsjZGVmaW5lIElXQ1LCoMKgwqDCoMKgwqDCoMKgIDB4MTTCoMKgwqDCoMKgwqDC oCAvKiBXYWl0IENvdW50IFJlZ2lzdGVyICovCj4+ICsjZGVmaW5lIElSU1RfQ1lDwqDCoMKgwqAg MHgxOMKgwqDCoMKgwqDCoMKgIC8qIEJ1cyByZXNldCBjeWNsZSBjb3VudGVyICovCj4+ICsjZGVm aW5lIElCTVLCoMKgwqDCoMKgwqDCoMKgIDB4MWPCoMKgwqDCoMKgwqDCoCAvKiBCdXMgbW9uaXRv ciByZWdpc3RlciAqLwo+IAo+IFlvdSBkbyBub3QgaW1wbGVtZW50IGFueSBGSUZPIGZ1bmN0aW9u YWxpdHkgY3VycmVudGx5LsKgIEkgdGhpbmsKPiB5b3UgY2FuIHNpbXBseSBvbWl0IHRoZSBmb2xs b3dpbmcgcmVnaXN0ZXIgZGVmaW5pdGlvbnMgdW50aWwKPiB0aGV5IGFyZSBhY3R1YWxseSBuZWVk ZWQuCkkgd2lsbCBkby4KPiAKPj4gKyNkZWZpbmUgSVdGSUZPwqDCoMKgwqDCoMKgIDB4MjDCoMKg wqDCoMKgwqDCoCAvKiBXcml0ZSBGSUZPIFJlZ2lzdGVyICovCj4+ICsjZGVmaW5lIElXRklGT19X UFRSwqAgMHgyNMKgwqDCoMKgwqDCoMKgIC8qIFdyaXRlIEZJRk8gV3JpdGUgUG9pbnRlciBSZWdp c3RlciAqLwo+PiArI2RlZmluZSBJV0ZJRk9fUlBUUsKgIDB4MjjCoMKgwqDCoMKgwqDCoCAvKiBX cml0ZSBGSUZPIFJlYWQgUG9pbnRlciBSZWdpc3RlciAqLwo+PiArI2RlZmluZSBJUkZJRk/CoMKg wqDCoMKgwqAgMHgyY8KgwqDCoMKgwqDCoMKgIC8qIFJlYWQgRklGTyBSZWdpc3RlciAqLwo+PiAr I2RlZmluZSBJUkZJRk9fV1BUUsKgIDB4MzDCoMKgwqDCoMKgwqDCoCAvKiBSZWFkIEZJRk8gV3Jp dGUgUG9pbnRlciBSZWdpc3RlciAqLwo+PiArI2RlZmluZSBJUkZJRk9fUlBUUsKgIDB4MzTCoMKg wqDCoMKgwqDCoCAvKiBSZWFkIEZJRk8gUmVhZCBQb2ludGVyIFJlZ2lzdGVyICovCj4+ICsKPj4g Ky8qIHJlZ2lzdGVyIElDUiBmaWVsZHMgKi8KPiAKPiBUaGUgZGVzY3JpcHRpb25zIGJlbG93IGFy ZSBhbHNvIGdvb2QuwqAgTWF5YmUgYmUgY29uc2lzdGVudAo+IHdpdGggeW91ciBjYXBpdGFsaXph dGlvbiBpbiBjb21tZW50cz/CoCAoVGhvdWdoIEkgc3VwcG9zZQo+IHRoZSBjYXBpdGFsaXphdGlv biBhYm92ZSBpcyB0byBleHBsYWluIHRoZSBuYW1lIG9mIHRoZQo+IHJlZ2lzdGVyLikKPiAKWWVz LiBUaGUgYWJvdmUgaXMgdG8gZXhwbGFpbiB0aGUgZnVsbCBuYW1lLgpTbyBJIHN0aWxsIG5lZWQg dG8ga2VlcCB0aGVtIGNvbnNpc3RlbnQ/Cj4+ICsjZGVmaW5lIENSX1NUQVJUwqDCoMKgwqDCoMKg wqAgQklUKDApwqDCoMKgwqDCoMKgwqAgLyogc3RhcnQgYml0ICovCj4+ICsjZGVmaW5lIENSX1NU T1DCoMKgwqDCoMKgwqDCoMKgIEJJVCgxKcKgwqDCoMKgwqDCoMKgIC8qIHN0b3AgYml0ICovCj4+ ICsjZGVmaW5lIENSX0FDS05BS8KgwqDCoMKgwqDCoCBCSVQoMinCoMKgwqDCoMKgwqDCoCAvKiBz ZW5kIEFDSygwKSBvciBOQUsoMSkgKi8KPj4gKyNkZWZpbmUgQ1JfVELCoMKgwqDCoMKgwqDCoMKg wqDCoCBCSVQoMynCoMKgwqDCoMKgwqDCoCAvKiB0cmFuc2ZlciBieXRlIGJpdCAqLwo+PiArI2Rl ZmluZSBDUl9UWEJFR0lOwqDCoMKgwqDCoCBCSVQoNCnCoMKgwqDCoMKgwqDCoCAvKiB0cmFuc2Fj dGlvbiBiZWdpbiAqLwo+PiArI2RlZmluZSBDUl9GSUZPRU7CoMKgwqDCoMKgwqAgQklUKDUpwqDC oMKgwqDCoMKgwqAgLyogZW5hYmxlIEZJRk8gbW9kZSAqLwo+PiArI2RlZmluZSBDUl9HUElPRU7C oMKgwqDCoMKgwqAgQklUKDYpwqDCoMKgwqDCoMKgwqAgLyogZW5hYmxlIEdQSU8gbW9kZSBmb3Ig U0NMIGluIEhTICovCj4+ICsjZGVmaW5lIENSX0RNQUVOwqDCoMKgwqDCoMKgwqAgQklUKDcpwqDC oMKgwqDCoMKgwqAgLyogZW5hYmxlIERNQSBmb3IgVFggYW5kIFJYIEZJRk9zICovCj4+ICsjZGVm aW5lIENSX01PREVfRkFTVMKgwqDCoCBCSVQoOCnCoMKgwqDCoMKgwqDCoCAvKiBidXMgbW9kZSAo bWFzdGVyIG9wZXJhdGlvbikgKi8KPj4gKyNkZWZpbmUgQ1JfTU9ERV9ISUdIwqDCoMKgIEJJVCg5 KcKgwqDCoMKgwqDCoMKgIC8qIGJ1cyBtb2RlIChtYXN0ZXIgb3BlcmF0aW9uKSAqLwo+PiArI2Rl ZmluZSBDUl9VUsKgwqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgxMCnCoMKgwqDCoMKgwqDCoCAvKiB1 bml0IHJlc2V0ICovCj4+ICsjZGVmaW5lIENSX1JTVFJFUcKgwqDCoMKgwqDCoCBCSVQoMTEpwqDC oMKgwqDCoMKgwqAgLyogaTJjIGJ1cyByZXNldCByZXF1ZXN0ICovCj4+ICsjZGVmaW5lIENSX01B wqDCoMKgwqDCoMKgwqDCoMKgwqAgQklUKDEyKcKgwqDCoMKgwqDCoMKgIC8qIG1hc3RlciBhYm9y dCAqLwo+PiArI2RlZmluZSBDUl9TQ0xFwqDCoMKgwqDCoMKgwqDCoCBCSVQoMTMpwqDCoMKgwqDC oMKgwqAgLyogbWFzdGVyIGNsb2NrIGVuYWJsZSAqLwo+PiArI2RlZmluZSBDUl9JVUXCoMKgwqDC oMKgwqDCoMKgwqAgQklUKDE0KcKgwqDCoMKgwqDCoMKgIC8qIHVuaXQgZW5hYmxlICovCj4gCj4g LyogQml0IDE1IGlzIHJlc2VydmVkICovCj4gCj4+ICsjZGVmaW5lIENSX0hTX1NUUkVUQ0jCoMKg IEJJVCgxNinCoMKgwqDCoMKgwqDCoCAvKiBJMkMgaHMgc3RyZXRjaCAqLwo+IAo+IC8qIEJpdCAx NyBpcyByZXNlcnZlZCAqLwo+IAo+IEFjdHVhbGx5LCB3aHkgaXMgdGhlIENVUlNSQ19GSVhfQllQ QVNTIGJpdCAoMTcpIG5vdCBkZWZpbmVkPwpJIG5ldmVyIHVzZSBpdC4gTGlrZSB0aGUgcmVnaXN0 ZXJzIGFib3ZlIHRoYXQgYXJlIG5vdCB1c2VkLgpBcmUgcmVnaXN0ZXIgYml0cyBkaWZmZXJlbnQg ZnJvbSByZWdpc3RlcnM/IERvIHJlZ2lzdGVyIGJpdHMgbmVlZCB0byBiZSBkZWZpbmVkCmV2ZW4g aWYgdGhleSBhcmUgbm90IHVzZWQ/Cj4gCj4gRm9yIHRoZSAqSUUgc3ltYm9scyB0aGF0IGZvbGxv dywgd2h5IG5vdCB1c2UgKl9JRSBhcyB0aGUgc3BlYwo+IGRvZXM/ClRoZSBzeW1ib2xzIGZvbGxv dyB0aGUgZGF0YXNoZWV0IG9mIFNwYWNlbWlULgpFdmVuIGlmIHRoZSBkYXRhIHNoZWV0IGRvZXNu J3QgaGF2ZSBJRSwgc2hvdWxkIEkgYWRkIGl0IG15c2VsZj8KPiAKPj4gKyNkZWZpbmUgQ1JfQUxE SUXCoMKgwqDCoMKgwqDCoCBCSVQoMTgpwqDCoMKgwqDCoMKgwqAgLyogZW5hYmxlIGFyYml0cmF0 aW9uIGludGVycnVwdCAqLwo+PiArI2RlZmluZSBDUl9EVEVJRcKgwqDCoMKgwqDCoMKgIEJJVCgx OSnCoMKgwqDCoMKgwqDCoCAvKiBlbmFibGUgdHggaW50ZXJydXB0cyAqLwo+PiArI2RlZmluZSBD Ul9EUkZJRcKgwqDCoMKgwqDCoMKgIEJJVCgyMCnCoMKgwqDCoMKgwqDCoCAvKiBlbmFibGUgcngg aW50ZXJydXB0cyAqLwo+PiArI2RlZmluZSBDUl9HQ0TCoMKgwqDCoMKgwqDCoMKgwqAgQklUKDIx KcKgwqDCoMKgwqDCoMKgIC8qIGdlbmVyYWwgY2FsbCBkaXNhYmxlICovCj4+ICsjZGVmaW5lIENS X0JFSUXCoMKgwqDCoMKgwqDCoMKgIEJJVCgyMinCoMKgwqDCoMKgwqDCoCAvKiBlbmFibGUgYnVz IGVycm9yIGludHMgKi8KPj4gKyNkZWZpbmUgQ1JfU0FESUXCoMKgwqDCoMKgwqDCoCBCSVQoMjMp wqDCoMKgwqDCoMKgwqAgLyogc2xhdmUgYWRkcmVzcyBkZXRlY3RlZCBpbnQgZW5hYmxlICovCj4+ ICsjZGVmaW5lIENSX1NTRElFwqDCoMKgwqDCoMKgwqAgQklUKDI0KcKgwqDCoMKgwqDCoMKgIC8q IHNsYXZlIFNUT1AgZGV0ZWN0ZWQgaW50IGVuYWJsZSAqLwo+PiArI2RlZmluZSBDUl9NU0RJRcKg wqDCoMKgwqDCoMKgIEJJVCgyNSnCoMKgwqDCoMKgwqDCoCAvKiBtYXN0ZXIgU1RPUCBkZXRlY3Rl ZCBpbnQgZW5hYmxlICovCj4+ICsjZGVmaW5lIENSX01TREXCoMKgwqDCoMKgwqDCoMKgIEJJVCgy NinCoMKgwqDCoMKgwqDCoCAvKiBtYXN0ZXIgU1RPUCBkZXRlY3RlZCBlbmFibGUgKi8KPj4gKyNk ZWZpbmUgQ1JfVFhET05FSUXCoMKgwqDCoCBCSVQoMjcpwqDCoMKgwqDCoMKgwqAgLyogdHJhbnNh Y3Rpb24gZG9uZSBpbnQgZW5hYmxlICovCj4+ICsjZGVmaW5lIENSX1RYRUlFwqDCoMKgwqDCoMKg wqAgQklUKDI4KcKgwqDCoMKgwqDCoMKgIC8qIHRyYW5zbWl0IEZJRk8gZW1wdHkgaW50IGVuYWJs ZSAqLwo+PiArI2RlZmluZSBDUl9SWEhGSUXCoMKgwqDCoMKgwqAgQklUKDI5KcKgwqDCoMKgwqDC oMKgIC8qIHJlY2VpdmUgRklGTyBoYWxmLWZ1bGwgaW50IGVuYWJsZSAqLwo+PiArI2RlZmluZSBD Ul9SWEZJRcKgwqDCoMKgwqDCoMKgIEJJVCgzMCnCoMKgwqDCoMKgwqDCoCAvKiByZWNlaXZlIEZJ Rk8gZnVsbCBpbnQgZW5hYmxlICovCj4+ICsjZGVmaW5lIENSX1JYT1ZJRcKgwqDCoMKgwqDCoCBC SVQoMzEpwqDCoMKgwqDCoMKgwqAgLyogcmVjZWl2ZSBGSUZPIG92ZXJydW4gaW50IGVuYWJsZSAq Lwo+PiArCj4+ICsvKiByZWdpc3RlciBJU1IgZmllbGRzICovCj4gCj4gLyogQml0cyAwLTEyIGFy ZSByZXNlcnZlZCAqLwpJIHdpbGwgYWRkIGl0Lgo+IAo+PiArI2RlZmluZSBTUl9SV03CoMKgwqDC oMKgwqDCoMKgwqAgQklUKDEzKcKgwqDCoMKgwqDCoMKgIC8qIHJlYWQvd3JpdGUgbW9kZSAqLwo+ PiArI2RlZmluZSBTUl9BQ0tOQUvCoMKgwqDCoMKgwqAgQklUKDE0KcKgwqDCoMKgwqDCoMKgIC8q IEFDSy9OQUNLIHN0YXR1cyAqLwo+PiArI2RlZmluZSBTUl9VQsKgwqDCoMKgwqDCoMKgwqDCoMKg IEJJVCgxNSnCoMKgwqDCoMKgwqDCoCAvKiB1bml0IGJ1c3kgKi8KPj4gKyNkZWZpbmUgU1JfSUJC wqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgxNinCoMKgwqDCoMKgwqDCoCAvKiBpMmMgYnVzIGJ1c3kg Ki8KPj4gKyNkZWZpbmUgU1JfRUJCwqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgxNynCoMKgwqDCoMKg wqDCoCAvKiBlYXJseSBidXMgYnVzeSAqLwo+PiArI2RlZmluZSBTUl9BTETCoMKgwqDCoMKgwqDC oMKgwqAgQklUKDE4KcKgwqDCoMKgwqDCoMKgIC8qIGFyYml0cmF0aW9uIGxvc3MgZGV0ZWN0ZWQg Ki8KPj4gKyNkZWZpbmUgU1JfSVRFwqDCoMKgwqDCoMKgwqDCoMKgIEJJVCgxOSnCoMKgwqDCoMKg wqDCoCAvKiB0eCBidWZmZXIgZW1wdHkgKi8KPj4gKyNkZWZpbmUgU1JfSVJGwqDCoMKgwqDCoMKg wqDCoMKgIEJJVCgyMCnCoMKgwqDCoMKgwqDCoCAvKiByeCBidWZmZXIgZnVsbCAqLwo+PiArI2Rl ZmluZSBTUl9HQ0FEwqDCoMKgwqDCoMKgwqDCoCBCSVQoMjEpwqDCoMKgwqDCoMKgwqAgLyogZ2Vu ZXJhbCBjYWxsIGFkZHJlc3MgZGV0ZWN0ZWQgKi8KPj4gKyNkZWZpbmUgU1JfQkVEwqDCoMKgwqDC oMKgwqDCoMKgIEJJVCgyMinCoMKgwqDCoMKgwqDCoCAvKiBidXMgZXJyb3Igbm8gQUNLL05BSyAq Lwo+PiArI2RlZmluZSBTUl9TQUTCoMKgwqDCoMKgwqDCoMKgwqAgQklUKDIzKcKgwqDCoMKgwqDC oMKgIC8qIHNsYXZlIGFkZHJlc3MgZGV0ZWN0ZWQgKi8KPj4gKyNkZWZpbmUgU1JfU1NEwqDCoMKg wqDCoMKgwqDCoMKgIEJJVCgyNCnCoMKgwqDCoMKgwqDCoCAvKiBzbGF2ZSBzdG9wIGRldGVjdGVk ICovCj4gCj4gLyogQml0IDI1IGlzIHJlc2VydmVkICovCkkgd2lsbCBhZGQgaXQuCj4gCj4+ICsj ZGVmaW5lIFNSX01TRMKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMjYpwqDCoMKgwqDCoMKgwqAgLyog bWFzdGVyIHN0b3AgZGV0ZWN0ZWQgKi8KPj4gKyNkZWZpbmUgU1JfVFhET05FwqDCoMKgwqDCoMKg IEJJVCgyNynCoMKgwqDCoMKgwqDCoCAvKiB0cmFuc2FjdGlvbiBkb25lICovCj4+ICsjZGVmaW5l IFNSX1RYRcKgwqDCoMKgwqDCoMKgwqDCoCBCSVQoMjgpwqDCoMKgwqDCoMKgwqAgLyogdHggRklG TyBlbXB0eSAqLwo+PiArI2RlZmluZSBTUl9SWEhGwqDCoMKgwqDCoMKgwqDCoCBCSVQoMjkpwqDC oMKgwqDCoMKgwqAgLyogcnggRklGTyBoYWxmLWZ1bGwgKi8KPj4gKyNkZWZpbmUgU1JfUlhGwqDC oMKgwqDCoMKgwqDCoMKgIEJJVCgzMCnCoMKgwqDCoMKgwqDCoCAvKiByeCBGSUZPIGZ1bGwgKi8K Pj4gKyNkZWZpbmUgU1JfUlhPVsKgwqDCoMKgwqDCoMKgwqAgQklUKDMxKcKgwqDCoMKgwqDCoMKg IC8qIFJYIEZJRk8gb3ZlcnJ1biAqLwo+PiArCj4+ICsvKiByZWdpc3RlciBJTENSIGZpZWxkcyAq Lwo+IAo+IFBsZWFzZSB1c2UgR0VOTUFTSyhoaSwgbG8pIHRvIGRlZmluZSB0aGVzZSBmaWVsZHMs IGFuZCBhbGwgb3RoZXIKPiBzaW1pbGFyIGZpZWxkcyBiZWxvdy4KPiAKPj4gKyNkZWZpbmUgTENS X1NMVsKgwqDCoMKgwqDCoMKgwqAgMHgwMDAwMDFGRsKgwqDCoCAvKiBTTFY6IGJpdFs4OjBdICov Cj4gCj4gI2RlZmluZSBMQ1JfU0xWwqDCoMKgwqDCoMKgwqAgR0VOTUFTSyg4LCAwKcKgwqDCoCAv KiBTdGFuZGFyZC1tb2RlIGxvYWQgdmFsdWUgKi8KPiAKPiBZb3UgYWN0dWFsbHkgbmV2ZXIgdG91 Y2ggdGhlIElMQ1IgcmVnaXN0ZXIuwqAgKFBlcmhhcHMgeW91IHNob3VsZAo+IGRvIHRoYXQgYXQg c3RhcnR1cCB0aW1lLinCoCBVbnRpbCB5b3UgZG8sIEkgc3VnZ2VzdCB5b3UganVzdCByZW1vdmUK PiB0aGVzZSBkZWZpbml0aW9uczsgdGhleSBzaW1wbHkgYWRkIHNwYWNlIGFuZCBhcHBhcmVudCBj b21wbGV4aXR5Cj4gdG8gdGhlIGRyaXZlci4KSSB3aWxsLiBUaGFua3MuCj4gCj4+ICsjZGVmaW5l IExDUl9GTFbCoMKgwqDCoMKgwqDCoMKgIDB4MDAwM0ZFMDDCoMKgwqAgLyogRkxWOiBiaXRbMTc6 OV0gKi8KPj4gKyNkZWZpbmUgTENSX0hMVkjCoMKgwqDCoMKgwqDCoCAweDA3RkMwMDAwwqDCoMKg IC8qIEhMVkg6IGJpdFsyNjoxOF0gKi8KPj4gKyNkZWZpbmUgTENSX0hMVkzCoMKgwqDCoMKgwqDC oCAweEY4MDAwMDAwwqDCoMKgIC8qIEhMVkw6IGJpdFszMToyN10gKi8KPj4gKwo+IAo+IFlvdSBu ZXZlciB0b3VjaCB0aGUgSVdDUiByZWdpc3Rlciwgc28gSSBzdWdnZXN0IHlvdSBvbWl0IHRoZQo+ IGRlZmluaXRpb24gb2YgaXRzIGZpZWxkcy4KSSB3aWxsLgo+IAo+PiArLyogcmVnaXN0ZXIgSVdD UiBmaWVsZHMgKi8KPj4gKyNkZWZpbmUgV0NSX0NPVU5UwqDCoMKgwqDCoMKgIDB4MDAwMDAwMUbC oMKgwqAgLyogQ09VTlQ6IGJpdFs0OjBdICovCj4+ICsjZGVmaW5lIFdDUl9DT1VOVDHCoMKgwqDC oMKgIDB4MDAwMDAzRTDCoMKgwqAgLyogSFNfQ09VTlQxOiBiaXRbOTo1XSAqLwo+PiArI2RlZmlu ZSBXQ1JfQ09VTlQywqDCoMKgwqDCoCAweDAwMDA3QzAwwqDCoMKgIC8qIEhTX0NPVU5UMjogYml0 WzE0OjEwXSAqLwo+PiArCj4+ICsvKiByZWdpc3RlciBJQk1SIGZpZWxkcyAqLwo+PiArI2RlZmlu ZSBCTVJfU0RBwqDCoMKgwqDCoMKgwqDCoCBCSVQoMCnCoMKgwqDCoMKgwqDCoCAvKiBTREEgbGlu ZSBsZXZlbCAqLwo+PiArI2RlZmluZSBCTVJfU0NMwqDCoMKgwqDCoMKgwqDCoCBCSVQoMSnCoMKg wqDCoMKgwqDCoCAvKiBTQ0wgbGluZSBsZXZlbCAqLwo+PiArCj4gCj4gSGVyZSB0b28sIEkgc3Vn Z2VzdCBhbGwgdGhlc2UgRklGTyBmaWVsZCBkZWZpbml0aW9ucyBjYW4gYmUgb21pdHRlZC4KSSB3 aWxsIGRvLgo+IAo+PiArLyogcmVnaXN0ZXIgSVdGSUZPIGZpZWxkcyAqLwo+PiArI2RlZmluZSBX RklGT19EQVRBX01TS8KgwqDCoMKgwqAgMHgwMDAwMDBGRsKgIC8qIGRhdGE6IGJpdFs3OjBdICov Cj4+ICsjZGVmaW5lIFdGSUZPX0NUUkxfTVNLwqDCoMKgwqDCoCAweDAwMDAwM0UwwqAgLyogY29u dHJvbDogYml0WzExOjhdICovCj4+ICsjZGVmaW5lIFdGSUZPX0NUUkxfU1RBUlTCoMKgwqAgQklU KDgpwqDCoMKgwqDCoCAvKiBzdGFydCBiaXQgKi8KPj4gKyNkZWZpbmUgV0ZJRk9fQ1RSTF9TVE9Q wqDCoMKgwqAgQklUKDkpwqDCoMKgwqDCoCAvKiBzdG9wIGJpdCAqLwo+PiArI2RlZmluZSBXRklG T19DVFJMX0FDS05BS8KgwqAgQklUKDEwKcKgwqDCoMKgIC8qIHNlbmQgQUNLKDApIG9yIE5BSygx KSAqLwo+PiArI2RlZmluZSBXRklGT19DVFJMX1RCwqDCoMKgwqDCoMKgIEJJVCgxMSnCoMKgwqDC oCAvKiB0cmFuc2ZlciBieXRlIGJpdCAqLwo+PiArCj4+ICsvKiBzdGF0dXMgcmVnaXN0ZXIgaW5p dCB2YWx1ZSAqLwo+PiArI2RlZmluZSBJMkNfSU5UX1NUQVRVU19NQVNLwqDCoMKgIDB4ZmZmYzAw MDDCoCAvKiBTUiBiaXRzWzMxOjE4XSAqLwo+IAo+IEFjdHVhbGx5LCB0aGlzIHNob3VsZCBiZSAw eGZkZmYwMDAwLCBiZWNhdXNlIGJpdCAyNSByZXNlcnZlZC4KPiBJIHdvdWxkIGdyb3VwIHRoaXMg ZGVmaW5pdGlvbiB3aXRoIHRoZSByZXN0IG9mIHRoZSBJU1IgZmllbGQKPiBkZWZpbml0aW9ucywg YWJvdmUuCj4gCj4gQWJvdmUgeW91IHVzZSBhIGhleCB2YWx1ZTsgYmVsb3cgeW91IGNvbXB1dGUg dGhlIG1hc2sgdmFsdWUKPiB0byB1c2Ugc3ltYm9saWNhbGx5LsKgIERvIG9uZSBvciB0aGUgb3Ro ZXIgaW4gYm90aCBjYXNlcy4KPiAKPiBJJ2QgZ3JvdXAgdGhlIG5leHQgc3ltYm9sIHdpdGggdGhl IElDUiBmaWVsZCBkZWZpbml0aW9ucywgYWJvdmUuCgpNYWtlcyBzZW5zZS4gVGhhbmtzIQpWZXJ5 IGRldGFpbGVkLgoKPiAKPiBUaGlzIGRlc2NyaWJlcyBhbGwgdGhlIGludGVycnVwdC1lbmFibGUg Yml0cy0tZXhjZXB0IGl0IG9taXRzCj4gQ1JfU0FESUUgYW5kIENSX1NTRElFLsKgIE1heWJlIGFk ZCBhIGNvbW1lbnQgaW5kaWNhdGluZyB0aGlzLAo+IGFuZCBleHBsYWluaW5nIHdoeS4KCkkgdGhp bmsgdGhpcyBpcyBjb25zaXN0ZW50IHdpdGggdGhlIGFib3ZlIHF1ZXN0aW9uLiBJIHdvdWxkIHJl bW92ZSB0aGVzZSB0d28gYW5kCm90aGVyIHVudXNlZCBiaXRzIHRvIGF2b2lkIGNvbXBsaWNhdGlu ZyB0aGUgZHJpdmVyIGRlZmluaXRpb24uCgo+IAo+PiArI2RlZmluZSBJMkNfSU5UX0NUUkxfTUFT S8KgwqDCoMKgwqAgKENSX0FMRElFIHwgQ1JfRFRFSUUgfCBDUl9EUkZJRSB8IFwKPj4gK8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBDUl9CRUlFIHwgQ1JfVFhET05FSUUgfCBDUl9UWEVJ RSB8IFwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBDUl9SWEhGSUUgfCBDUl9S WEZJRSB8IENSX1JYT1ZJRSB8IFwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBD Ul9NU0RJRSkKPj4gKwo+PiArLyogaTJjIGJ1cyByZWNvdmVyIHRpbWVvdXQ6IHVzICovCj4gCj4g V2hhdCB5b3UgY2FsbCAiYnVzIHJlY292ZXIiIGlzIHdhaXRpbmcgZm9yIHRoZSBidXMgdG8gYmUg ZnJlZQo+IGJlZm9yZSBiZWdpbm5pbmcgYSB0cmFuc2Zlci7CoCBJJ20gbm8gSTJDIGV4cGVydCwg YW5kIG1heWJlIHRoaXMKPiBpcyBhIG5vcm1hbCB0ZXJtLCBidXQgImJ1cyBidXN5IiB0aW1lb3V0 IHdvdWxkIGJlIG1vcmUgbWVhbmluZ2Z1bAo+IGZvciBtZS4KbWFrZXMgc2Vuc2UuCj4gCj4+ICsj ZGVmaW5lIEkyQ19CVVNfUkVDT1ZFUl9USU1FT1VUwqDCoMKgwqDCoMKgwqAgKDEwMDAwMCkKPiAK PiBQYXJlbnRoZXNlcyBhcmUgbm90IHJlcXVpcmVkIGFyb3VuZCBzaW1wbGUgY29uc3RhbnQgdmFs dWVzLgo+IAo+IFRoaXMgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIGZyZXF1ZW5jeSwgY29ycmVjdD/C oAoKVGhhdCdzIHRoZSBvbmx5IGZyZXF1ZW5jeSB0aGF0IGRyaXZlciBzdXBwb3J0cyBub3cuCgo+ IElzIGl0IHNpbXBseSBhc3N1bWVkIHRvIGJlIGFscmVhZHkgY29uZmlndXJlZCB0aGF0IHdheT/C oCAoVGhpcwo+IGRyaXZlciBkb2Vzbid0IHNldCBpdCBhdCBpbml0aWFsaXphdGlvbiB0aW1lLinC oCBTb21lZGF5Cj4gd2Ugc2hvdWxkIHNldCB0aGluZ3MgdXAgZXhwbGljaXRseS4KeWVzLiBieSBk dHMuCkkgd2lsbCBoYW5kbGUgZnJlcXVlbmN5IHRoYXQgaXMgZnJvbSBkdHMgaW4gbmV4dCB2ZXJz aW9uLgo+IAo+IFRoZSBvbmx5IHBsYWNlIHRoZSBuZXh0IHN5bWJvbCBpcyB1c2VkIGlzIGluIGNv bXB1dGluZyBhCj4gY3VzdG9tIHRpbWVvdXQgcGVyaW9kIGJlZm9yZSBpbml0aWF0aW5nIGEgdHJh bnNmZXIuClllcywgYnV0IEkgd2FubmEgZXhwbGFpbiB0aGUgZnJlcSBudW1iZXIgaXMgZmFzdCBt b2RlLgpTbyBJIGRlZmluZSBpdCBoZXJlLgpCdXQgZG9uJ3Qgd29ycnksIEkgd2lsbCBkcm9wIGl0 IGluIG5leHQgdmVyc2lvbiBhbmQgYWNjZXB0IGZyZXEgZnJvbSBkdHMuCj4gCj4+ICsjZGVmaW5l IEkyQ19GQVNUX01PREVfRlJFUcKgwqDCoMKgwqDCoMKgICg0MDAwMDApCj4+ICsKPj4gK2VudW0g c3BhY2VtaXRfaTJjX3N0YXRlIHsKPj4gK8KgwqDCoCBTVEFURV9JRExFLAo+PiArwqDCoMKgIFNU QVRFX1NUQVJULAo+PiArwqDCoMKgIFNUQVRFX1JFQUQsCj4+ICvCoMKgwqAgU1RBVEVfV1JJVEUs Cj4+ICt9Owo+PiArCj4gCj4gRG9uJ3QgYm90aGVyIHdpdGggc3BhY2VtaXRfaTJjX2RpciBlbnVt ZXJhdGlvbi7CoCBKdXN0IGRlZmluZQo+IGEgQm9vbGVhbiBmbGFnIGluIHRoZSBzcGFjZW1pdF9p MmNfZGV2IHN0cnVjdHVyZSB0aGF0IGluZGljYXRlcwo+IHdoZXRoZXIgdGhlIGN1cnJlbnQgdHJh bnNmZXIgbW9kZSBpcyByZWFkIG9yIG5vdCAocmVhZCA9PSB0cnVlCj4gbWVhbnMgdGhlIHNhbWUg YXMgZGlyID09IERJUl9SRUFEKS4KSSB3aWxsIGRvLgo+IAo+PiArZW51bSBzcGFjZW1pdF9pMmNf ZGlyIHsKPj4gK8KgwqDCoCBESVJfV1JJVEUsCj4+ICvCoMKgwqAgRElSX1JFQUQKPj4gK307Cj4+ ICsKPj4gKy8qIGkyYy1zcGFjZW1pdCBkcml2ZXIncyBtYWluIHN0cnVjdCAqLwo+PiArc3RydWN0 IHNwYWNlbWl0X2kyY19kZXYgewo+PiArwqDCoMKgIHN0cnVjdCBkZXZpY2UgKmRldjsKPj4gK8Kg wqDCoCBzdHJ1Y3QgaTJjX2FkYXB0ZXIgYWRhcHQ7Cj4+ICsKPj4gK8KgwqDCoCAvKiBoYXJkd2Fy ZSByZXNvdXJjZXMgKi8KPj4gK8KgwqDCoCB2b2lkIF9faW9tZW0gKmJhc2U7Cj4+ICvCoMKgwqAg aW50IGlycTsKPj4gKwo+PiArwqDCoMKgIHN0cnVjdCBpMmNfbXNnICptc2dzOwo+PiArwqDCoMKg IGludCBtc2dfbnVtOwo+IAo+IEkgZG9uJ3QgdGhpbmsgdGhlcmUncyBhbnkgbmVlZCB0byBrZWVw IGEgcG9pbnRlciB0byB0aGUKPiBjdXJyZW50IG1lc3NhZ2UuwqAgSXQncyBhbHdheXMgaTJjLT5t c2dzW21zZ19pZHhdLgpJdCBpcyBqdXN0IGZvciBzaG9ydGVyIG5hbWUgdG8gYXZvaWQgbW9yZSBs aW5lIGJyZWFrcy4uLgpJIHdpbGwgZHJvcCBpdCBhbmQgdXNlIGxvY2FsIHZhci4KPiAKPj4gK8Kg wqDCoCBzdHJ1Y3QgaTJjX21zZyAqY3VyX21zZzsKPj4gKwo+PiArwqDCoMKgIC8qIGluZGV4IG9m IHRoZSBjdXJyZW50IG1lc3NhZ2UgYmVpbmcgcHJvY2Vzc2VkICovCj4+ICvCoMKgwqAgaW50IG1z Z19pZHg7Cj4+ICvCoMKgwqAgdTggKm1zZ19idWY7Cj4+ICvCoMKgwqAgLyogdGhlIG51bWJlciBv ZiB1bnByb2Nlc3NlZCBieXRlcyByZW1haW5pbmcgaW4gZWFjaCBtZXNzYWdlwqAgKi8KPj4gK8Kg wqDCoCBzaXplX3QgdW5wcm9jZXNzZWQ7Cj4+ICsKPj4gK8KgwqDCoCBlbnVtIHNwYWNlbWl0X2ky Y19zdGF0ZSBzdGF0ZTsKPj4gK8KgwqDCoCBlbnVtIHNwYWNlbWl0X2kyY19kaXIgZGlyOwo+PiAr wqDCoMKgIHN0cnVjdCBjb21wbGV0aW9uIGNvbXBsZXRlOwo+PiArwqDCoMKgIHUzMiBzdGF0dXM7 Cj4+ICvCoMKgwqAgdTMyIGVycjsKPiAKPiBJIHRoaW5rIHlvdSBzaG91bGQgcmVtb3ZlIHRoZSAi ZXJyIiBmaWVsZC7CoCBJdCBvbmx5IGNvbnRhaW5zIGEKPiBzdWJzZXQgb2Ygd2hhdCdzIGluIHRo ZSBzdGF0dXMgZmllbGQuwqAgSXQncyBzZXQgaW4gdGhlIElSUQo+IGhhbmRsZXI6Cj4gwqDCoMKg wqDCoMKgwqAgaTJjLT5zdGF0dXMgPSBzdGF0dXM7Cj4gwqDCoMKgwqDCoMKgwqAgaTJjLT5lcnIg PSBzdGF0dXMgJiAoU1JfQkVEIHwgU1JfUlhPViB8IFNSX0FMRCk7Cj4gQW5kIHRoZSBvbmx5IG90 aGVyIHRpbWUgZWl0aGVyIGlzIGFzc2lnbmVkIGlzIHdoZW4gdGhleSBhcmUKPiBib3RoIHplcm9l ZCBpbiBzcGFjZW1pdF9pMmNfeGZlcl9tc2coKS4KSSB3aWxsLgo+IAo+PiArfTsKPj4gKwo+PiAr c3RhdGljIHZvaWQgc3BhY2VtaXRfaTJjX2VuYWJsZShzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAq aTJjKQo+PiArewo+PiArwqDCoMKgIHUzMiB2YWw7Cj4+ICsKPj4gK8KgwqDCoCB2YWwgPSByZWFk bChpMmMtPmJhc2UgKyBJQ1IpOwo+IAo+IEluIGV2ZXJ5IG90aGVyIHBsYWNlIHlvdSBkbyByZWFk L21vZGlmeS93cml0ZSwgeW91IGRvIGl0IHdpdGgKPiB0aHJlZSBsaW5lcy7CoCBTbyBJIHN1Z2dl c3QgeW91IGRvIHRoaXMgaGVyZSwgZm9yIGNvbnNpc3RlbmN5Ogo+IAo+IMKgwqDCoMKgwqDCoMKg IHZhbCA9IHJlYWRsKGkyYy0+YmFzZSArIElDUik7Cj4gwqDCoMKgwqB2YWwgfD0gQ1JfSVVFOwo+ IMKgwqDCoMKgwqDCoMKgIHdyaXRlbCh2YWwsIGkyYy0+YmFzZSArIElDUik7ClRoYW5rcy4gWW91 ciBleWVzIGFyZSByZWFsbHkgZ29vZC4KPiAKPj4gK8KgwqDCoCB3cml0ZWwodmFsIHwgQ1JfSVVF LCBpMmMtPmJhc2UgKyBJQ1IpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBzcGFjZW1pdF9p MmNfZGlzYWJsZShzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjKQo+PiArewo+PiArwqDCoMKg IHUzMiB2YWw7Cj4+ICsKPj4gK8KgwqDCoCB2YWwgPSByZWFkbChpMmMtPmJhc2UgKyBJQ1IpOwo+ PiArwqDCoMKgIHZhbCAmPSB+Q1JfSVVFOwo+PiArwqDCoMKgIHdyaXRlbCh2YWwsIGkyYy0+YmFz ZSArIElDUik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHNwYWNlbWl0X2kyY19yZXNldChz dHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjKQo+PiArewo+PiArwqDCoMKgIHdyaXRlbChDUl9V UiwgaTJjLT5iYXNlICsgSUNSKTsKPj4gK8KgwqDCoCB1ZGVsYXkoNSk7Cj4gCj4gVGhlIHNwZWMg c2F5cyB5b3Ugc2hvdWxkIGVuc3VyZSB0aGUgdW5pdCBpcyBub3QgYnVzeSBiZWZvcmUKPiBhc3Nl cnRpbmcgdGhlIHJlc2V0LsKgIEl0IGFsc28gc2F5cyB5b3Ugc2hvdWxkIGNsZWFyIHRoZSBJU1IK PiByZWdpc3RlciBiZWZvcmUgY2xlYXJpbmcgdGhlIElDUiBoZXJlLsKgIChBcHBhcmVudGx5IHlv dXIgY29kZQo+IHN0aWxsIHdvcmtzOyBJJ20ganVzdCByZXBvcnRpbmcgd2hhdCBJIHJlYWQuKQo+ IAo+PiArwqDCoMKgIHdyaXRlbCgwLCBpMmMtPmJhc2UgKyBJQ1IpOwo+PiArfQo+PiArCj4+ICtz dGF0aWMgaW50IHNwYWNlbWl0X2kyY19oYW5kbGVfZXJyKHN0cnVjdCBzcGFjZW1pdF9pMmNfZGV2 ICppMmMpOwo+IAo+IEp1c3QgZGVmaW5lIGkyY19oYW5kbGVfZXJyKCkgaGVyZSwgcmF0aGVyIHRo YW4gZGVjbGFyaW5nIGl0Cj4gaGVyZSBhbmQgZGVmaW5pbmcgaXQgbGF0ZXIuCj4gCj4gVGhlIG5l eHQgZnVuY3Rpb24gb25seSByZXNldHMgdGhlIGJ1cyBpZiBpdCdzIG5vdCBpZGxlICh3aGVyZQo+ ICJpZGxlIiBtZWFucyBib3RoIFNDTCBhbmQgU0RBIGFyZSBoaWdoKS7CoCBCYXNlZCBvbiB0aGUg bmFtZQo+IG9mIHRoZSBmdW5jdGlvbiwgSSdkIGV4cGVjdCBpdCB0byBhbHdheXMgcmVzZXQuwqAg SW4gb3RoZXIKPiB3b3JkcywgSSdkIHJhdGhlciB0aGlzIGJlIG5hbWVkIHNvbWV0aGluZyBzbGln aHRseSBkaWZmZXJlbnQsCj4gb3IgaGF2ZSB0aGUgY2hlY2sgb2YgU0RBIGFuZCBTQ0wgYmUgZG9u ZSBpbiB0aGUgY2FsbGVyKHMpLgpIb3cgYWJvdXQgYHNwYWNlbWl0X2kyY19jb25kaXRpb25hbF9y ZXNldGA/CkJlY2F1c2UgSSBhbSB3b3JyaWVkIHRoYXQgaW4gdGhlIGZ1dHVyZSwgd2hlbiB0aGUg ZmlmbyBvciBvdGhlciByZXNldCBpcyBjYWxsZWQsClNEQSBhbmQgU0NMIHdpbGwgYWx3YXlzIGJl IGNoZWNrZWQuCj4gCj4+ICtzdGF0aWMgdm9pZCBzcGFjZW1pdF9pMmNfYnVzX3Jlc2V0KHN0cnVj dCBzcGFjZW1pdF9pMmNfZGV2ICppMmMpCj4+ICt7Cj4+ICvCoMKgwqAgdTMyIHN0YXR1czsKPj4g Kwo+PiArwqDCoMKgIC8qIGlmIGJ1cyBpcyBsb2NrZWQsIHJlc2V0IHVuaXQuIDA6IGxvY2tlZCAq Lwo+PiArwqDCoMKgIHN0YXR1cyA9IHJlYWRsKGkyYy0+YmFzZSArIElCTVIpOwo+PiArwqDCoMKg IGlmICgoc3RhdHVzICYgQk1SX1NEQSkgJiYgKHN0YXR1cyAmIEJNUl9TQ0wpKQo+PiArwqDCoMKg wqDCoMKgwqAgcmV0dXJuOwo+PiArCj4+ICvCoMKgwqAgc3BhY2VtaXRfaTJjX3Jlc2V0KGkyYyk7 Cj4+ICvCoMKgwqAgdXNsZWVwX3JhbmdlKDEwLCAyMCk7Cj4+ICsKPj4gK8KgwqDCoCAvKiBjaGVj ayBzY2wgc3RhdHVzIGFnYWluICovCj4+ICvCoMKgwqAgc3RhdHVzID0gcmVhZGwoaTJjLT5iYXNl ICsgSUJNUik7Cj4+ICvCoMKgwqAgaWYgKCEoc3RhdHVzICYgQk1SX1NDTCkpCj4+ICvCoMKgwqDC oMKgwqDCoCBkZXZfd2Fybl9yYXRlbGltaXRlZChpMmMtPmRldiwgInVuaXQgcmVzZXQgZmFpbGVk XG4iKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBzcGFjZW1pdF9pMmNfcmVjb3Zlcl9idXNf YnVzeShzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjKQo+PiArewo+PiArwqDCoMKgIGludCBy ZXQgPSAwOwo+PiArwqDCoMKgIHUzMiB2YWw7Cj4+ICsKPiAKPiBJIHRoaW5rIHRoZSBuZXh0IDQg bGluZXMgY2FuIGJlIGRlbGV0ZWQuwqAgVGhlIHJlYWRsX3BvbGxfdGltZW91dCgpCj4gaW1tZWRp YXRlbHkgZG9lcyB3aGF0IHRoZXkgZG8sIHdpdGhvdXQgZGVsYXkuClRoZSByZWdpc3RlciB2YWx1 ZSBpcyBhbHdheXMgcmV0dXJuZWQgZGlyZWN0bHnjgIIKYnV0IGl0IG5lZWRzIHRvIGJlIGp1ZGdl ZCBpZiB0aGUgYnVzIGlzIGJ1c3kgYnkgISh2YWwgJiAoU1JfVUIgfCBTUl9JQkIpLgo+IAo+PiAr wqDCoMKgIHZhbCA9IHJlYWRsKGkyYy0+YmFzZSArIElTUik7Cj4+ICvCoMKgwqAgaWYgKGxpa2Vs eSghKHZhbCAmIChTUl9VQiB8IFNSX0lCQikpKSkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiAw Owo+PiArCj4+ICvCoMKgwqAgcmV0ID0gcmVhZGxfcG9sbF90aW1lb3V0KGkyYy0+YmFzZSArIElT UiwgdmFsLCAhKHZhbCAmIChTUl9VQiB8IFNSX0lCQikpLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgMTUwMCwgSTJDX0JVU19SRUNPVkVSX1RJTUVPVVQpOwo+PiArwqDCoMKg IGlmICh1bmxpa2VseShyZXQpKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBzcGFjZW1pdF9pMmNfcmVz ZXQoaTJjKTsKPiAKPiBJZiByZWFkbF9wb2xsX3RpbWVvdXQoKSByZXR1cm5zIG5vbi16ZXJvLCBp dCBpcyAtRVRJTUVET1VULgo+IFdoeSBjaGFuZ2UgaXQgdG8gLUVBR0FJTj/CoCAoSXQgdWx0aW1h dGVseSBnZXRzIGNvbnN1bWVkIGJ5Cj4gc3BhY2VtaXRfaTJjX3hmZXIoKSwgd2hpY2ggaGFuZGxl cyAtRVRJTUVET1VUIGFuZCAtRUFHQUlOCj4gaWRlbnRpY2FsbHkuCkkgd2lsbCBkcm9wIGl0Lgo+ IAo+PiArwqDCoMKgwqDCoMKgwqAgcmV0ID0gLUVBR0FJTjsKPj4gK8KgwqDCoCB9Cj4+ICsKPj4g K8KgwqDCoCByZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBzcGFjZW1pdF9p MmNfY2hlY2tfYnVzX3JlbGVhc2Uoc3RydWN0IHNwYWNlbWl0X2kyY19kZXYgKmkyYykKPj4gK3sK Pj4gK8KgwqDCoCAvKiBpbiBjYXNlIGJ1cyBpcyBub3QgcmVsZWFzZWQgYWZ0ZXIgdHJhbnNmZXIg Y29tcGxldGVzICovCj4gCj4gQXMgc2FpZCBieSBvdGhlcnMsIHlvdSBlc3NlbnRpYWxseSAqbmV2 ZXIqIG5lZWQgdG8gc3BlY2lmeQo+IGxpa2VseSgpIG9yIHVubGlrZWx5KCkuwqAgQW5kIG5vd2hl cmUgaW4gdGhpcyBjb2RlIGFyZSB5b3UKPiBydW5uaW5nIGluIHN1Y2ggYSBwZXJmb3JtYW5jZS1j cml0aWNhbCB3YXkgdGhhdCBpdCBtYXR0ZXJzLgpJIHdpbGwgZHJvcCB0aGVtLgo+IAo+PiArwqDC oMKgIGlmICh1bmxpa2VseShyZWFkbChpMmMtPmJhc2UgKyBJU1IpICYgU1JfRUJCKSkgewo+PiAr wqDCoMKgwqDCoMKgwqAgc3BhY2VtaXRfaTJjX2J1c19yZXNldChpMmMpOwo+PiArwqDCoMKgwqDC oMKgwqAgdXNsZWVwX3JhbmdlKDkwLCAxNTApOwo+PiArwqDCoMKgIH0KPj4gK30KPj4gKwo+PiAr c3RhdGljIHZvaWQgc3BhY2VtaXRfaTJjX2luaXQoc3RydWN0IHNwYWNlbWl0X2kyY19kZXYgKmky YykKPj4gK3sKPj4gK8KgwqDCoCB1MzIgdmFsID0gMDsKPj4gKwo+PiArwqDCoMKgIC8qCj4+ICvC oMKgwqDCoCAqIFVubWFzayBpbnRlcnJ1cHQgYml0cyBmb3IgYWxsIHhmZXIgbW9kZToKPj4gK8Kg wqDCoMKgICogYnVzIGVycm9yLCBhcmJpdHJhdGlvbiBsb3NzIGRldGVjdGVkLgo+PiArwqDCoMKg wqAgKiBGb3IgdHJhbnNhY3Rpb24gY29tcGxldGUgc2lnbmFsLCB3ZSB1c2UgbWFzdGVyIHN0b3AK Pj4gK8KgwqDCoMKgICogaW50ZXJydXB0LCBzbyB3ZSBkb24ndCBuZWVkIHRvIHVubWFzayBDUl9U WERPTkVJRS4KPj4gK8KgwqDCoMKgICovCj4+ICvCoMKgwqAgdmFsIHw9IENSX0JFSUUgfCBDUl9B TERJRTsKPiAKPiBJJ2QganVzdCBza2lwIHplcm9pbmcgdmFsIGFib3ZlIGFuZCBkb2luZyB0aGlz IGhlcmU6Cj4gwqDCoMKgwqB2YWwgPSBDUl9CRUlFIHwgQ1JfQUxESUU7Ckkgd2lsbC4gVGhhbmtz Lgo+PiArCj4+ICvCoMKgwqAgLyoKPj4gK8KgwqDCoMKgICogVW5tYXNrIGludGVycnVwdCBiaXRz IGZvciBpbnRlcnJ1cHQgeGZlciBtb2RlOgo+PiArwqDCoMKgwqAgKiBEQlIgcnggZnVsbC4KPj4g K8KgwqDCoMKgICogRm9yIHR4IGVtcHR5IGludGVycnVwdCBDUl9EVEVJRSwgd2Ugb25seQo+PiAr wqDCoMKgwqAgKiBuZWVkIHRvIGVuYWJsZSB3aGVuIHRyaWdnZXIgYnl0ZSB0cmFuc2ZlciB0byBz dGFydAo+PiArwqDCoMKgwqAgKiBkYXRhIHNlbmRpbmcuCj4+ICvCoMKgwqDCoCAqLwo+PiArwqDC oMKgIHZhbCB8PSBDUl9EUkZJRTsKPj4gKwo+PiArwqDCoMKgIC8qIHNldCBzcGVlZCBiaXRzOiBk ZWZhdWx0IGZhc3QgbW9kZSAqLwo+PiArwqDCoMKgIHZhbCB8PSBDUl9NT0RFX0ZBU1Q7Cj4+ICsK Pj4gK8KgwqDCoCAvKiBkaXNhYmxlIHJlc3BvbnNlIHRvIGdlbmVyYWwgY2FsbCAqLwo+PiArwqDC oMKgIHZhbCB8PSBDUl9HQ0Q7Cj4+ICsKPj4gK8KgwqDCoCAvKiBlbmFibGUgU0NMIGNsb2NrIG91 dHB1dCAqLwo+PiArwqDCoMKgIHZhbCB8PSBDUl9TQ0xFOwo+PiArCj4+ICvCoMKgwqAgLyogZW5h YmxlIG1hc3RlciBzdG9wIGRldGVjdGVkICovCj4+ICvCoMKgwqAgdmFsIHw9IENSX01TREUgfCBD Ul9NU0RJRTsKPj4gKwo+PiArwqDCoMKgIHdyaXRlbCh2YWwsIGkyYy0+YmFzZSArIElDUik7Cj4+ ICt9Cj4+ICsKPiAKPiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIGlzIHVzZWQgaW4gdHdvIHBsYWNl cywgYnV0IEkgZG9uJ3QgdGhpbmsKPiBpdCByZWFsbHkgYWRkcyBhbnkgdmFsdWUuwqAgSnVzdCBv cGVuLWNvZGUgdGhlIHdyaXRlbCgpIGNhbGwgaW4KPiB0aG9zZSB0d28gc3BvdHMuCkkgd2FudCB0 byBleHBsYWluIG1vcmUgY2xlYXJseSB3aGF0IGlzIGRvbmUgaW4gdGhlIGluaXQgcGhhc2UsIHNv IEkgcHV0IHRoZW0KaW50byBhIGZ1bmN0aW9uIGFuZCBhc3NpZ24gdmFsdWVzIHN0ZXAgYnkgc3Rl cC4KSXMgaXQgbm90IG5lY2Vzc2FyeT8Kb3IgbWF5YmUgSSBjYW4gYWRkIGBpbmxpbmVgLgo+IAo+ PiArc3RhdGljIGlubGluZSB2b2lkCj4+ICtzcGFjZW1pdF9pMmNfY2xlYXJfaW50X3N0YXR1cyhz dHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjLCB1MzIgbWFzaykKPj4gK3sKPj4gK8KgwqDCoCB3 cml0ZWwobWFzayAmIEkyQ19JTlRfU1RBVFVTX01BU0ssIGkyYy0+YmFzZSArIElTUik7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHNwYWNlbWl0X2kyY19zdGFydChzdHJ1Y3Qgc3BhY2VtaXRf aTJjX2RldiAqaTJjKQo+PiArewo+PiArwqDCoMKgIHUzMiBzbGF2ZV9hZGRyX3J3LCB2YWw7Cj4g Cj4gVXNlIGEgbG9jYWwgdmFyaWFibGUgdG8gdHJhY2sgdGhlIGN1cnJlbnQgbWVzc2FnZS7CoCBU aGVyZSdzCj4gbm8gbmVlZCB0byBzdGFzaCBpdCBpbiB0aGUgaTJjIHN0cnVjdHVyZS4KSSB3aWxs Lgo+IAo+IMKgwqDCoMKgc3RydWN0IGkyY19tc2cgKmN1cl9tc2cgPSBpMmMtPm1zZ3NbaTJjLT5t c2dfaWR4XTsKPj4gKwo+PiArwqDCoMKgIGkyYy0+ZGlyID0gaTJjLT5jdXJfbXNnLT5mbGFncyAm IEkyQ19NX1JEOwo+IAo+IEFzIHN1Z2dlc3RlZCBiZWZvcmUsIHVzZSBhIEJvb2xlYW4gInJlYWQi IGZsYWcgaW5zdGVhZC4KSSB3aWxsLgo+IAo+IMKgwqDCoMKgaTJjLT5yZWFkID0gaTJjLT5jdXJf bXNnLT5mbGFncyAmIEkyQ19NX1JEOwo+IAo+IChUaGlzIGRvZXNuJ3QgYXNzdW1lIEkyQ19NX1JE ID09IERJUl9SRUFEIGVpdGhlciwgdGhvdWdoCj4gdGVjaG5pY2FsbHkgSTJDX01fUkQgaXMgZ3Vh cmFudGVlZCB0byBiZSAxLi4uPgo+PiArwqDCoMKgIGkyYy0+c3RhdGUgPSBTVEFURV9TVEFSVDsK Pj4gKwo+PiArwqDCoMKgIGlmIChpMmMtPmN1cl9tc2ctPmZsYWdzICYgSTJDX01fUkQpCj4+ICvC oMKgwqDCoMKgwqDCoCBzbGF2ZV9hZGRyX3J3ID0gKChpMmMtPmN1cl9tc2ctPmFkZHIgJiAweDdm KSA8PCAxKSB8IDE7Cj4+ICvCoMKgwqAgZWxzZQo+PiArwqDCoMKgwqDCoMKgwqAgc2xhdmVfYWRk cl9ydyA9IChpMmMtPmN1cl9tc2ctPmFkZHIgJiAweDdmKSA8PCAxOwo+IAo+IMKgwqDCoMKgc2xh dmVfYWRkcl9ydyA9IChpMmMtPmN1cl9tc2ctPmFkZHIgJiAweDdmKSA8PCAxOwo+IMKgwqDCoMKg aWYgKGkyYy0+cmVhZCkKPiDCoMKgwqDCoMKgwqDCoCBzbGF2ZV9hZGRyX3J3IHw9IEkyQ19NX1JE Owpjb29sLCBJIHdpbGwKPiAKPj4gKwo+PiArwqDCoMKgIHdyaXRlbChzbGF2ZV9hZGRyX3J3LCBp MmMtPmJhc2UgKyBJREJSKTsKPj4gKwo+IAo+IFB1dCB0aGUgInNlbmQgc3RhcnQgcHVsc2UiIGNv bW1lbnQgaGVyZSwgdGhlbiBncm91cCB0aGUgbGluZXMKPiB0aGF0IHJlYWQvbW9kaWZ5L3dyaXRl IHRoZSByZWdpc3RlciB0b2dldGhlci4KSSB3aWxsLgo+IAo+PiArwqDCoMKgIHZhbCA9IHJlYWRs KGkyYy0+YmFzZSArIElDUik7Cj4+ICsKPj4gK8KgwqDCoCAvKiBzZW5kIHN0YXJ0IHB1bHNlICov Cj4+ICvCoMKgwqAgdmFsICY9IH5DUl9TVE9QOwo+PiArwqDCoMKgIHZhbCB8PSBDUl9TVEFSVCB8 IENSX1RCIHwgQ1JfRFRFSUU7Cj4+ICvCoMKgwqAgd3JpdGVsKHZhbCwgaTJjLT5iYXNlICsgSUNS KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgc3BhY2VtaXRfaTJjX3N0b3Aoc3RydWN0IHNw YWNlbWl0X2kyY19kZXYgKmkyYykKPj4gK3sKPj4gK8KgwqDCoCB1MzIgdmFsOwo+PiArCj4+ICvC oMKgwqAgdmFsID0gcmVhZGwoaTJjLT5iYXNlICsgSUNSKTsKPj4gKwo+PiArwqDCoMKgIHZhbCB8 PSBDUl9TVE9QIHwgQ1JfQUxESUUgfCBDUl9UQjsKPj4gKwo+PiArwqDCoMKgIGlmIChpMmMtPmRp ciA9PSBESVJfUkVBRCkKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCB8PSBDUl9BQ0tOQUs7Cj4+ICsK Pj4gK8KgwqDCoCB3cml0ZWwodmFsLCBpMmMtPmJhc2UgKyBJQ1IpOwo+PiArfQo+PiArCj4+ICtz dGF0aWMgaW50IHNwYWNlbWl0X2kyY194ZmVyX21zZyhzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAq aTJjKQo+PiArewo+PiArwqDCoMKgIHVuc2lnbmVkIGxvbmcgdGltZV9sZWZ0Owo+PiArCj4+ICvC oMKgwqAgZm9yIChpMmMtPm1zZ19pZHggPSAwOyBpMmMtPm1zZ19pZHggPCBpMmMtPm1zZ19udW07 IGkyYy0+bXNnX2lkeCsrKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpMmMtPmN1cl9tc2cgPSBpMmMt Pm1zZ3MgKyBpMmMtPm1zZ19pZHg7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpMmMtPm1zZ19idWYgPSBp MmMtPmN1cl9tc2ctPmJ1ZjsKPj4gK8KgwqDCoMKgwqDCoMKgIGkyYy0+ZXJyID0gMDsKPj4gK8Kg wqDCoMKgwqDCoMKgIGkyYy0+c3RhdHVzID0gMDsKPj4gK8KgwqDCoMKgwqDCoMKgIGkyYy0+dW5w cm9jZXNzZWQgPSBpMmMtPmN1cl9tc2ctPmxlbjsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgcmVp bml0X2NvbXBsZXRpb24oJmkyYy0+Y29tcGxldGUpOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBz cGFjZW1pdF9pMmNfc3RhcnQoaTJjKTsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgdGltZV9sZWZ0 ID0gd2FpdF9mb3JfY29tcGxldGlvbl90aW1lb3V0KCZpMmMtPmNvbXBsZXRlLAo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGkyYy0+YWRh cHQudGltZW91dCk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAodW5saWtlbHkodGltZV9sZWZ0ID09 IDApKSB7Cj4gCj4gwqDCoMKgwqDCoMKgwqAgaWYgKCF0aW1lX2xlZnQpIHsKSSB3aWxsIGRyb3Ag YWxsIHVubGlrZWx5L2xpa2VseQo+IAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBkZXZfYWxl cnQoaTJjLT5kZXYsICJtc2cgY29tcGxldGlvbiB0aW1lb3V0XG4iKTsKPj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqAgc3BhY2VtaXRfaTJjX2J1c19yZXNldChpMmMpOwo+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBzcGFjZW1pdF9pMmNfcmVzZXQoaTJjKTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqAgcmV0dXJuIC1FVElNRURPVVQ7Cj4+ICvCoMKgwqDCoMKgwqDCoCB9Cj4+ICsKPj4gK8Kg wqDCoMKgwqDCoMKgIGlmICh1bmxpa2VseShpMmMtPmVycikpCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIHJldHVybiBzcGFjZW1pdF9pMmNfaGFuZGxlX2VycihpMmMpOwo+PiArwqDCoMKgIH0K Pj4gKwo+PiArwqDCoMKgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHNwYWNl bWl0X2kyY19pc19sYXN0X21zZyhzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjKQo+PiArewo+ IAo+IHN0YXRpYyBib29sIHNwYWNlbWl0X2kyY19pc19sYXN0X21zZyhzdHJ1Y3Qgc3BhY2VtaXRf aTJjX2RldiAqaTJjKQo+IHsKPiDCoMKgwqDCoGlmIChpMmMtPm1zZ19pZHggIT0gaTJjLT5tc2df bnVtIC0gMSkKPiDCoMKgwqDCoMKgwqDCoCByZXR1cm4gZmFsc2U7Cj4gwqDCoMKgwqAKPiDCoMKg wqDCoGlmIChpMmMtPnJlYWQpCj4gwqDCoMKgwqDCoMKgwqAgcmV0dXJuIGkyYy0+dW5wcm9jZXNz ZWQgPT0gMTsKPiAKPiDCoMKgwqDCoHJldHVybiAhaTJjLT51bnByb2Nlc3NlZDsKPiB9Cj4gCmNv b2wgbWV0aG9kLiBJIGxlYXJuIGEgbG90IGZyb20gdXIgcmV2aWV3LgpUaGFua3MgYWdhaW4uCj4+ ICvCoMKgwqAgaWYgKGkyYy0+ZGlyID09IERJUl9SRUFEKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBp ZiAoaTJjLT51bnByb2Nlc3NlZCA9PSAxICYmIGkyYy0+bXNnX2lkeCA9PSBpMmMtPm1zZ19udW0g LSAxKQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gMTsKPj4gK8KgwqDCoCB9IGVs c2UgaWYgKGkyYy0+ZGlyID09IERJUl9XUklURSkgewo+PiArwqDCoMKgwqDCoMKgwqAgaWYgKCFp MmMtPnVucHJvY2Vzc2VkICYmIGkyYy0+bXNnX2lkeCA9PSBpMmMtPm1zZ19udW0gLSAxKQo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gMTsKPj4gK8KgwqDCoCB9Cj4+ICsKPj4gK8Kg wqDCoCByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgc3BhY2VtaXRfaTJjX2hh bmRsZV93cml0ZShzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjKQo+PiArewo+PiArwqDCoMKg IC8qIGlmIHRyYW5zZmVyIGNvbXBsZXRlcywgSVNSIHdpbGwgaGFuZGxlIGl0ICovCj4+ICvCoMKg wqAgaWYgKGkyYy0+c3RhdHVzICYgU1JfTVNEKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+ PiArCj4+ICvCoMKgwqAgaWYgKGkyYy0+dW5wcm9jZXNzZWQpIHsKPj4gK8KgwqDCoMKgwqDCoMKg IHdyaXRlbCgqaTJjLT5tc2dfYnVmKyssIGkyYy0+YmFzZSArIElEQlIpOwo+PiArwqDCoMKgwqDC oMKgwqAgaTJjLT51bnByb2Nlc3NlZC0tOwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+PiAr wqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIC8qIFNUQVRFX0lETEUgYXZvaWRzIHRyaWdnZXIgbmV4 dCBieXRlICovCj4+ICvCoMKgwqAgaTJjLT5zdGF0ZSA9IFNUQVRFX0lETEU7Cj4+ICvCoMKgwqAg Y29tcGxldGUoJmkyYy0+Y29tcGxldGUpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBzcGFj ZW1pdF9pMmNfaGFuZGxlX3JlYWQoc3RydWN0IHNwYWNlbWl0X2kyY19kZXYgKmkyYykKPj4gK3sK Pj4gK8KgwqDCoCBpZiAoaTJjLT51bnByb2Nlc3NlZCkgewo+PiArwqDCoMKgwqDCoMKgwqAgKmky Yy0+bXNnX2J1ZisrID0gcmVhZGwoaTJjLT5iYXNlICsgSURCUik7Cj4+ICvCoMKgwqDCoMKgwqDC oCBpMmMtPnVucHJvY2Vzc2VkLS07Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgLyogaWYg dHJhbnNmZXIgY29tcGxldGVzLCBJU1Igd2lsbCBoYW5kbGUgaXQgKi8KPj4gK8KgwqDCoCBpZiAo aTJjLT5zdGF0dXMgJiAoU1JfTVNEIHwgU1JfQUNLTkFLKSkKPj4gK8KgwqDCoMKgwqDCoMKgIHJl dHVybjsKPj4gKwo+PiArwqDCoMKgIC8qIGl0IGhhcyB0byBhcHBlbmQgc3RvcCBiaXQgaW4gaWNy IHRoYXQgcmVhZCBsYXN0IGJ5dGUgKi8KPj4gK8KgwqDCoCBpZiAoaTJjLT51bnByb2Nlc3NlZCkK Pj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4gKwo+PiArwqDCoMKgIC8qIFNUQVRFX0lETEUg YXZvaWRzIHRyaWdnZXIgbmV4dCBieXRlICovCj4+ICvCoMKgwqAgaTJjLT5zdGF0ZSA9IFNUQVRF X0lETEU7Cj4+ICvCoMKgwqAgY29tcGxldGUoJmkyYy0+Y29tcGxldGUpOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgdm9pZCBzcGFjZW1pdF9pMmNfaGFuZGxlX3N0YXJ0KHN0cnVjdCBzcGFjZW1pdF9p MmNfZGV2ICppMmMpCj4+ICt7Cj4gewo+IMKgwqDCoMKgaTJjLT5zdGF0ZSA9IGkyYy0+cmVhZCA/ IFNUQVRFX1JFQUQgOiBTVEFURV9XUklURTsKPiDCoMKgwqDCoGlmIChpMmMtPnN0YXRlID09IFNU QVRFX1dSSVRFKQo+IMKgwqDCoMKgwqDCoMKgIHNwYWNlbWl0X2kyY19oYW5kbGVfd3JpdGUoaTJj KTsKPiB9Cj4gCmNvb2wuCj4+ICvCoMKgwqAgaWYgKGkyYy0+ZGlyID09IERJUl9SRUFEKSB7Cj4+ ICvCoMKgwqDCoMKgwqDCoCBpMmMtPnN0YXRlID0gU1RBVEVfUkVBRDsKPj4gK8KgwqDCoMKgwqDC oMKgIHJldHVybjsKPj4gK8KgwqDCoCB9Cj4+ICsKPj4gK8KgwqDCoCBpZiAoaTJjLT5kaXIgPT0g RElSX1dSSVRFKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpMmMtPnN0YXRlID0gU1RBVEVfV1JJVEU7 Cj4+ICvCoMKgwqDCoMKgwqDCoCBzcGFjZW1pdF9pMmNfaGFuZGxlX3dyaXRlKGkyYyk7Cj4+ICvC oMKgwqAgfQo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHNwYWNlbWl0X2kyY19oYW5kbGVfZXJy KHN0cnVjdCBzcGFjZW1pdF9pMmNfZGV2ICppMmMpCj4+ICt7Cj4gCj4gVGhpcyBmdW5jdGlvbiBp cyBvbmx5IGNhbGxlZCBpbiBvbmUgcGxhY2UsIGFuZCBpbiB0aGF0IHBsYWNlCj4gdGhlIGNhbGxl ciBhbHJlYWR5IHZlcmlmaWVkIHRoYXQgaTJjLT5lcnIgaXMgbm9uLXplcm8uwqAgU28KPiBkcm9w IHRoZSBuZXh0IGlmIHN0YXRlbWVudC4KSSB3aWxsLgo+IAo+PiArwqDCoMKgIGlmICghaTJjLT5l cnIpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gMDsKPj4gKwo+PiArwqDCoMKgIGRldl9kYmco aTJjLT5kZXYsICJpMmMgZXJyb3Igc3RhdHVzOiAweCUwOHhcbiIswqDCoMKgIGkyYy0+c3RhdHVz KTsKPj4gKwo+PiArwqDCoMKgIGlmIChpMmMtPmVyciAmIChTUl9CRUQgfCBTUl9BTEQpKQo+PiAr wqDCoMKgwqDCoMKgwqAgc3BhY2VtaXRfaTJjX3Jlc2V0KGkyYyk7Cj4+ICsKPj4gK8KgwqDCoCBp ZiAoaTJjLT5lcnIgJiAoU1JfUlhPViB8IFNSX0FMRCkpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1 cm4gLUVBR0FJTjsKPj4gKwo+PiArwqDCoMKgIHJldHVybiAoaTJjLT5zdGF0dXMgJiBTUl9BQ0tO QUspID8gLUVOWElPIDogLUVJTzsKPiAKPiBObyBuZWVkIGZvciBwYXJlbnRoZXNlcyBpbiB0aGUg YWJvdmUgbGluZS4KSSB3aWxsIGRyb3AuCj4gCj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHNw YWNlbWl0X2kyY19lcnJfY2hlY2soc3RydWN0IHNwYWNlbWl0X2kyY19kZXYgKmkyYykKPj4gK3sK Pj4gK8KgwqDCoCB1MzIgdmFsOwo+IAo+IEFkZCBhIGJsYW5rIGxpbmUgaGVyZS4KVGhhbmtzIQo+ IAo+IENoYW5nZSB0aGUgbG9naWMgdG86Cj4gwqDCoMKgwqBpZiAoIWkyYy0+ZXJyICYmICEoaTJj LT5zdGF0dXMgJiBTUl9NU0QpKQo+IMKgwqDCoMKgwqDCoMKgIHJldHVybjsKPiAKPiBUaGVuIHRo ZSByZXN0IG9mIHRoZSBmdW5jdGlvbiBjYW4gYmUgc2hpZnRlZCBvdXQgYSBsZXZlbC4KPiAKPiBJ ZiB5b3UgZ2V0IHJpZCBvZiBpMmMtPmVyciwgdGhpcyBjYW4gYmU6Cj4gwqDCoMKgwqB1MzIgZXJy b3IgPSBpMmMtPnN0YXR1cyAmIChTUl9BTEQgfCBTUl9CRUQgfCBTUl9NU0QgfCBTUl9SWE9WKTsK PiAKPiDCoMKgwqDCoGlmICghZXJyb3IpCj4gwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+IApUaGF0 J3Mgc28gZGV0YWlsZWQuClNyeSBmb3IgbXkgbmV3YmllIGJlaGF2aW9yCj4+ICvCoMKgwqAgLyoK Pj4gK8KgwqDCoMKgICogc2VuZCB0cmFuc2FjdGlvbiBjb21wbGV0ZSBzaWduYWw6Cj4+ICvCoMKg wqDCoCAqIGVycm9yIGhhcHBlbnMsIGRldGVjdCBtYXN0ZXIgc3RvcAo+PiArwqDCoMKgwqAgKi8K Pj4gK8KgwqDCoCBpZiAobGlrZWx5KGkyYy0+ZXJyIHx8IChpMmMtPnN0YXR1cyAmIFNSX01TRCkp KSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCAvKgo+PiArwqDCoMKgwqDCoMKgwqDCoCAqIEhlcmUgdGhl IHRyYW5zYWN0aW9uIGlzIGFscmVhZHkgZG9uZSwgd2UgZG9uJ3QgbmVlZCBhbnkKPj4gK8KgwqDC oMKgwqDCoMKgwqAgKiBvdGhlciBpbnRlcnJ1cHQgc2lnbmFscyBmcm9tIG5vdywgaW4gY2FzZSBh bnkgaW50ZXJydXB0Cj4+ICvCoMKgwqDCoMKgwqDCoMKgICogaGFwcGVucyBiZWZvcmUgc3BhY2Vt aXRfaTJjX3hmZXIgdG8gZGlzYWJsZSBpcnEgYW5kIGkyYyB1bml0LAo+PiArwqDCoMKgwqDCoMKg wqDCoCAqIHdlIG1hc2sgYWxsIHRoZSBpbnRlcnJ1cHQgc2lnbmFscyBhbmQgY2xlYXIgdGhlIGlu dGVycnVwdAo+PiArwqDCoMKgwqDCoMKgwqDCoCAqIHN0YXR1cy4KPj4gK8KgwqDCoMKgwqDCoMKg wqAgKi8KPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9IHJlYWRsKGkyYy0+YmFzZSArIElDUik7Cj4+ ICvCoMKgwqDCoMKgwqDCoCB2YWwgJj0gfkkyQ19JTlRfQ1RSTF9NQVNLOwo+PiArwqDCoMKgwqDC oMKgwqAgd3JpdGVsKHZhbCwgaTJjLT5iYXNlICsgSUNSKTsKPj4gKwo+IAo+IFdoeSBhcmUgKmFs bCogaW50ZXJydXB0IHN0YXR1cyBiaXRzIGNsZWFyZWQgaGVyZSwgcmF0aGVyIHRoYW4KPiBqdXN0 IHRoZSBvbmVzIHdpdGggYml0cyBzZXQgaW4gaTJjLT5zdGF0dXM/CkJlY2F1c2UgaWYgdGhlcmUg YXJlIGFueSBlcnJvcnMsIHdlIGRvbid0IG5lZWQgaW50ZXJydXB0cyB0byBhdm9pZCBmdXJ0aGVy Cmlzc3Vlcy4ganVzdCBleGl0LgoKPiAKPj4gK8KgwqDCoMKgwqDCoMKgIHNwYWNlbWl0X2kyY19j bGVhcl9pbnRfc3RhdHVzKGkyYywgSTJDX0lOVF9TVEFUVVNfTUFTSyk7Cj4+ICsKPj4gK8KgwqDC oMKgwqDCoMKgIGkyYy0+c3RhdGUgPSBTVEFURV9JRExFOwo+PiArwqDCoMKgwqDCoMKgwqAgY29t cGxldGUoJmkyYy0+Y29tcGxldGUpOwo+PiArwqDCoMKgIH0KPj4gK30KPj4gKwo+PiArc3RhdGlj IGlycXJldHVybl90IHNwYWNlbWl0X2kyY19pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZp ZCkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3Qgc3BhY2VtaXRfaTJjX2RldiAqaTJjID0gZGV2aWQ7 Cj4+ICvCoMKgwqAgdTMyIHN0YXR1cywgdmFsOwo+PiArCj4+ICvCoMKgwqAgc3RhdHVzID0gcmVh ZGwoaTJjLT5iYXNlICsgSVNSKTsKPiAKPiBJcyB0aGVyZSBhbnkgcmVhc29uIG5vdCB0byBhc3Np Z24gaTJjLT5zdGF0dXMgaGVyZT8KYWN0dWFseSB0byBhdm9pZCB6ZXJvLgpCdXQgSSB0aGluayB0 aGVyZSBpcyBub3QgcmVhc29uIHRvIGF2b2lkIHplcm8uCkkgd2lsbCBkcm9wIGxvY2FsIHZhci4K PiAKPj4gK8KgwqDCoCBpZiAoIXN0YXR1cykKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBJUlFf SEFORExFRDsKPj4gKwo+PiArwqDCoMKgIGkyYy0+c3RhdHVzID0gc3RhdHVzOwo+PiArCj4+ICvC oMKgwqAgaTJjLT5lcnIgPSBzdGF0dXMgJiAoU1JfQkVEIHwgU1JfUlhPViB8IFNSX0FMRCk7Cj4g Cj4gQXMgSSBzYWlkIGVhcmxpZXIsIEkgdGhpbmsgeW91IGNhbiBzaW1wbHkgY2hlY2sgdGhlc2Ug Yml0cyBpbgo+IHRoZSBzdGF0dXMgZmllbGQgcmF0aGVyIHRoYW4gdHJhY2tpbmcgaTJjLT5lcnIg c2VwYXJhdGVseS4KPiBJIHRoaW5rIHRoZSByZXN1bHQgd2lsbCBhY3R1YWxseSBiZSBhIGxpdHRs ZSBzaW1wbGVyLgpvay4KPiAKPj4gKwo+PiArwqDCoMKgIHNwYWNlbWl0X2kyY19jbGVhcl9pbnRf c3RhdHVzKGkyYywgc3RhdHVzKTsKPj4gKwo+PiArwqDCoMKgIGlmICh1bmxpa2VseShpMmMtPmVy cikpCj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIGVycl9vdXQ7Cj4+ICsKPj4gK8KgwqDCoCB2YWwg PSByZWFkbChpMmMtPmJhc2UgKyBJQ1IpOwo+PiArCj4+ICvCoMKgwqAgdmFsICY9IH4oQ1JfVEIg fCBDUl9BQ0tOQUsgfCBDUl9TVE9QIHwgQ1JfU1RBUlQpOwo+PiArwqDCoMKgIHdyaXRlbCh2YWws IGkyYy0+YmFzZSArIElDUik7Cj4+ICsKPj4gK8KgwqDCoCBzd2l0Y2ggKGkyYy0+c3RhdGUpIHsK Pj4gK8KgwqDCoCBjYXNlIFNUQVRFX1NUQVJUOgo+PiArwqDCoMKgwqDCoMKgwqAgc3BhY2VtaXRf aTJjX2hhbmRsZV9zdGFydChpMmMpOwo+PiArwqDCoMKgwqDCoMKgwqAgYnJlYWs7Cj4+ICvCoMKg wqAgY2FzZSBTVEFURV9SRUFEOgo+PiArwqDCoMKgwqDCoMKgwqAgc3BhY2VtaXRfaTJjX2hhbmRs ZV9yZWFkKGkyYyk7Cj4+ICvCoMKgwqDCoMKgwqDCoCBicmVhazsKPj4gK8KgwqDCoCBjYXNlIFNU QVRFX1dSSVRFOgo+PiArwqDCoMKgwqDCoMKgwqAgc3BhY2VtaXRfaTJjX2hhbmRsZV93cml0ZShp MmMpOwo+PiArwqDCoMKgwqDCoMKgwqAgYnJlYWs7Cj4+ICvCoMKgwqAgZGVmYXVsdDoKPj4gK8Kg wqDCoMKgwqDCoMKgIGJyZWFrOwo+PiArwqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIGlmIChpMmMt PnN0YXRlICE9IFNUQVRFX0lETEUpIHsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChzcGFjZW1pdF9p MmNfaXNfbGFzdF9tc2coaTJjKSkgewo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAvKiB0cmln Z2VyIG5leHQgYnl0ZSB3aXRoIHN0b3AgKi8KPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3Bh Y2VtaXRfaTJjX3N0b3AoaTJjKTsKPj4gK8KgwqDCoMKgwqDCoMKgIH0gZWxzZSB7Cj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIC8qIHRyaWdnZXIgbmV4dCBieXRlICovCj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHZhbCB8PSBDUl9BTERJRSB8IENSX1RCOwo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCB3cml0ZWwodmFsLCBpMmMtPmJhc2UgKyBJQ1IpOwo+PiArwqDCoMKgwqDCoMKgwqAg fQo+PiArwqDCoMKgIH0KPj4gKwo+PiArZXJyX291dDoKPj4gK8KgwqDCoCBzcGFjZW1pdF9pMmNf ZXJyX2NoZWNrKGkyYyk7Cj4+ICvCoMKgwqAgcmV0dXJuIElSUV9IQU5ETEVEOwo+PiArfQo+PiAr Cj4+ICtzdGF0aWMgdm9pZCBzcGFjZW1pdF9pMmNfY2FsY190aW1lb3V0KHN0cnVjdCBzcGFjZW1p dF9pMmNfZGV2ICppMmMpCj4+ICt7Cj4+ICvCoMKgwqAgdW5zaWduZWQgbG9uZyB0aW1lb3V0Owo+ PiArwqDCoMKgIGludCBpZHggPSAwLCBjbnQgPSAwLCBmcmVxOwo+PiArCj4gCj4gVGhpcyBsb29w IGNvdW50cyB0aGUgbnVtYmVyIG9mIGkyY19tc2cgc3RydWN0cywgYW5kIGFkZHMgdXAKPiB0aGUg bnVtYmVyIG9mIGJ5dGVzIHRoYXQgbXVzdCBiZSB0cmFuc2ZlcnJlZCAoaW5jbHVkaW5nIHRoZQo+ IHRhcmdldCBhZGRyZXNzIGZvciBlYWNoKSBmb3IgdGhlbSBhbGwuPgo+PiArwqDCoMKgIHdoaWxl IChpZHggPCBpMmMtPm1zZ19udW0pIHsKPj4gK8KgwqDCoMKgwqDCoMKgIGNudCArPSAoaTJjLT5t c2dzICsgaWR4KS0+bGVuICsgMTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlkeCsrOwo+PiArwqDCoMKg IH0KPj4gKwo+PiArwqDCoMKgIGZyZXEgPSBJMkNfRkFTVF9NT0RFX0ZSRVE7Cj4gCj4gWW91IGNh biBqdXN0IHVzZSBJMkNfRkFTVF9NT0RFX0ZSRVEgYmVsb3csIGFuZCBnZXQgcmlkIG9mIHRoZQo+ IGxvY2FsIHZhcmlhYmxlLgpJbiB0aGlzIHZlcnNpb24sIHdlIGNhbiB1c2UgSTJDX0ZBU1RfTU9E RV9GUkVRLgpidXQgYXMgSSBzYWlkIGVhcmxpZXIsIEkgd2lsbCByZWFkIGZyZXEgZnJvbSBkdHMu CnNvIEkgd2lsbCBhZGQgaTJjLT5mcmVxIHRvIHN0b3JhZ2UgYW5kIG1vZGlmeSB0aGlzIGZ1bmN0 aW9uLgo+IAo+PiArwqDCoMKgIC8qCj4+ICvCoMKgwqDCoCAqIG11bHRpcGx5IGJ5IDkgYmVjYXVz ZSBlYWNoIGJ5dGUgaW4gSTJDIHRyYW5zbWlzc2lvbiByZXF1aXJlcwo+PiArwqDCoMKgwqAgKiA5 IGNsb2NrIGN5Y2xlczogOCBiaXRzIG9mIGRhdGEgcGx1cyAxIEFDSy9OQUNLIGJpdC4KPj4gK8Kg wqDCoMKgICovCj4+ICvCoMKgwqAgdGltZW91dCA9IGNudCAqIDkgKiBVU0VDX1BFUl9TRUMgLyBm cmVxOwo+IAo+IFNvIG5vdywgdGltZW91dCBpcyB0aGUgbnVtYmVyIG9mIG1pY3Jvc2Vjb25kcyBy ZXF1aXJlZCB0byB0cmFuc2Zlcgo+IGFsbCBiaXRzIGFjcm9zcyBhbGwgbWVzc2FnZXMuCj4gCj4g VGhlIG5leHQgbGluZSBoYXMgbWUgY29uZnVzZWQuCj4gCj4gWW91IGFkZCBoYWxmIGEgc2Vjb25k LCBhbmQgY29udmVydCBpdCB0byBqaWZmaWVzLsKgIChXaHkgYWRkIGhhbGYKPiBhIHNlY29uZD8p CmhhbGYgYSBzZWNvbmQgaXMgYnVmZmVyIHRpbWUgdG8gYXZvaWQgZXh0cmVtZWx5IGxvdyBwcm9i YWJpbGl0eSBldmVudHMuCj4gCj4gVGhlbiB5b3UgZGl2aWRlIHRoYXQgYnkgdGhlIG51bWJlciBv ZiBtZXNzYWdlcy7CoCAoV2h5IGRpdmlkZSBieQo+IHRoaXM/wqAgVGhpcyB0aW1lb3V0IGFwcGxp ZXMgdG8gdGhlIHRpbWUgcmVxdWlyZWQgdG8gdHJhbnNmZXIKPiBhbGwgbWVzc2FnZSBzZWdtZW50 cyBpbiBhIHRyYW5hc2FjdGlvbiwgcmlnaHQuwqAgSS5lLiwgdGhlIHRpbWUKPiByZXF1aXJlZCBm b3IgYSBjYWxsIHRvIGNhbGwgc3BhY2VtaXRfaTJjX3hmZXIoKT8pCmp1c3Qgb25lIG1zZyBpbnN0 ZWFkIG9mIGFsbCBtc2dzLgpzbyB0aGF0J3Mgd2h5IHdlIGRpdmlkZSB0aGF0IGJ5IHRoZSBudW1i ZXIgb2YgbXNncy4KYW5kIGhhbGYgYSBzZWNvbmQgaXMgZXF1YWxseSBkaXZpZGVkIGFtb25nIGVh Y2ggbWVzc2FnZS4KPiAKPj4gKwo+PiArwqDCoMKgIGkyYy0+YWRhcHQudGltZW91dCA9IHVzZWNz X3RvX2ppZmZpZXModGltZW91dCArIFVTRUNfUEVSX1NFQyAvIDIpIC8KPj4gaTJjLT5tc2dfbnVt Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHNwYWNlbWl0X2kyY194ZmVyX2NvcmUoc3RydWN0 IHNwYWNlbWl0X2kyY19kZXYgKmkyYykKPj4gK3sKPj4gK8KgwqDCoCBpbnQgcmV0Owo+PiArCj4+ ICvCoMKgwqAgc3BhY2VtaXRfaTJjX3Jlc2V0KGkyYyk7Cj4+ICsKPj4gK8KgwqDCoCBzcGFjZW1p dF9pMmNfY2FsY190aW1lb3V0KGkyYyk7Cj4+ICsKPj4gK8KgwqDCoCBzcGFjZW1pdF9pMmNfaW5p dChpMmMpOwo+PiArCj4+ICvCoMKgwqAgc3BhY2VtaXRfaTJjX2VuYWJsZShpMmMpOwo+PiArwqDC oMKgIGVuYWJsZV9pcnEoaTJjLT5pcnEpOwo+PiArCj4+ICvCoMKgwqAgLyogaTJjIHdhaXQgZm9y IGJ1cyBidXN5ICovCj4+ICvCoMKgwqAgcmV0ID0gc3BhY2VtaXRfaTJjX3JlY292ZXJfYnVzX2J1 c3koaTJjKTsKPj4gK8KgwqDCoCBpZiAodW5saWtlbHkocmV0KSkKPj4gK8KgwqDCoMKgwqDCoMKg IHJldHVybiByZXQ7Cj4+ICsKPj4gK8KgwqDCoCByZXQgPSBzcGFjZW1pdF9pMmNfeGZlcl9tc2co aTJjKTsKPj4gK8KgwqDCoCBpZiAodW5saWtlbHkocmV0IDwgMCkpIHsKPj4gK8KgwqDCoMKgwqDC oMKgIGRldl9kYmcoaTJjLT5kZXYsICJpMmMgdHJhbnNmZXIgZXJyb3JcbiIpOwo+IAo+IFB1dCB0 aGUgZGV2X2RiZygpIGNhbGwgdW5kZXIgdGhlIG5leHQgY29tbWVudC4KSSB3aWxsLgo+IAo+PiAr wqDCoMKgwqDCoMKgwqAgLyogdGltZW91dCBlcnJvciBzaG91bGQgbm90IGJlIG92ZXJyaWRkZW4s IGFuZCB0aGUgdHJhbnNmZXIKPj4gK8KgwqDCoMKgwqDCoMKgwqAgKiBlcnJvciB3aWxsIGJlIGNv bmZpcm1lZCBieSBlcnIgaGFuZGxlIGZ1bmN0aW9uIGxhdHRlciwKPj4gK8KgwqDCoMKgwqDCoMKg wqAgKiB0aGUgcmVzZXQgc2hvdWxkIGJlIGludmFsaWQgYXJndW1lbnQgZXJyb3IuCj4+ICvCoMKg wqDCoMKgwqDCoMKgICovCj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAocmV0ICE9IC1FVElNRURPVVQp Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldCA9IC1FSU5WQUw7Cj4+ICvCoMKgwqAgfQo+ PiArCj4+ICvCoMKgwqAgcmV0dXJuIHJldDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBzcGFj ZW1pdF9pMmNfeGZlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0LCBzdHJ1Y3QgaTJjX21zZwo+ PiBtc2dzW10sIGludCBudW0pCj4gCj4gV2h5IGRvIHlvdSB1c2UgbXNnc1tdIGluIHRoZSBwcm90 b3R5cGUgcmF0aGVyIHRoYW4gKm1zZ3MgYXMgdGhlCj4gZGVmaW5pdGlvbiBvZiB0aGUgaTJjX2Fs Z29yaXRobSBzdHJ1Y3R1cmUgZG9lcz8KSSB3aWxsLgo+IAo+PiArewo+PiArwqDCoMKgIHN0cnVj dCBzcGFjZW1pdF9pMmNfZGV2ICppMmMgPSBpMmNfZ2V0X2FkYXBkYXRhKGFkYXB0KTsKPj4gK8Kg wqDCoCBpbnQgcmV0Owo+PiArCj4+ICvCoMKgwqAgaTJjLT5tc2dzID0gbXNnczsKPj4gK8KgwqDC oCBpMmMtPm1zZ19udW0gPSBudW07Cj4+ICsKPj4gK8KgwqDCoCByZXQgPSBzcGFjZW1pdF9pMmNf eGZlcl9jb3JlKGkyYyk7Cj4+ICvCoMKgwqAgaWYgKGxpa2VseSghcmV0KSkKPj4gK8KgwqDCoMKg wqDCoMKgIHNwYWNlbWl0X2kyY19jaGVja19idXNfcmVsZWFzZShpMmMpOwo+PiArCj4+ICvCoMKg wqAgZGlzYWJsZV9pcnEoaTJjLT5pcnEpOwo+PiArCj4+ICvCoMKgwqAgc3BhY2VtaXRfaTJjX2Rp c2FibGUoaTJjKTsKPj4gKwo+PiArwqDCoMKgIGlmICh1bmxpa2VseSgocmV0ID09IC1FVElNRURP VVQgfHwgcmV0ID09IC1FQUdBSU4pKSkKPj4gK8KgwqDCoMKgwqDCoMKgIGRldl9hbGVydChpMmMt PmRldiwgImkyYyB0cmFuc2ZlciBmYWlsZWQsIHJldCAlZCBlcnIgMHgleFxuIiwgcmV0LAo+PiBp MmMtPmVycik7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gcmV0IDwgMCA/IHJldCA6IG51bTsKPj4g K30KPj4gKwo+PiArc3RhdGljIHUzMiBzcGFjZW1pdF9pMmNfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0 ZXIgKmFkYXApCj4+ICt7Cj4+ICvCoMKgwqAgcmV0dXJuIEkyQ19GVU5DX0kyQyB8IChJMkNfRlVO Q19TTUJVU19FTVVMICYgfkkyQ19GVU5DX1NNQlVTX1FVSUNLKTsKPj4gK30KPj4gKwo+PiArc3Rh dGljIGNvbnN0IHN0cnVjdCBpMmNfYWxnb3JpdGhtIHNwYWNlbWl0X2kyY19hbGdvID0gewo+PiAr wqDCoMKgIC54ZmVyID0gc3BhY2VtaXRfaTJjX3hmZXIsCj4+ICvCoMKgwqAgLmZ1bmN0aW9uYWxp dHkgPSBzcGFjZW1pdF9pMmNfZnVuYywKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbnQgc3BhY2Vt aXRfaTJjX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4+ICt7Cj4+ICvCoMKg wqAgc3RydWN0IHNwYWNlbWl0X2kyY19kZXYgKmkyYzsKPj4gK8KgwqDCoCBzdHJ1Y3QgZGV2aWNl X25vZGUgKm9mX25vZGUgPSBwZGV2LT5kZXYub2Zfbm9kZTsKPiAKPiDCoMKgwqDCoHN0cnVjdCBk ZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7Cj4gCj4gVGhlbiB1c2UgdGhlIGxvY2FsICJkZXYiIHBv aW50ZXIgaW4gYWxsIGNhbGxzIGJlbG93LgpJIHdpbGwuCj4gCj4+ICvCoMKgwqAgc3RydWN0IGNs ayAqY2xrOwo+PiArwqDCoMKgIGludCByZXQgPSAwOwo+PiArCj4+ICvCoMKgwqAgaTJjID0gZGV2 bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigqaTJjKSwgR0ZQX0tFUk5FTCk7Cj4+ICvCoMKg wqAgaWYgKCFpMmMpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVOT01FTTsKPj4gKwo+PiAr wqDCoMKgIGkyYy0+ZGV2ID0gJnBkZXYtPmRldjsKPj4gKwo+PiArwqDCoMKgIGkyYy0+YmFzZSA9 IGRldm1fcGxhdGZvcm1faW9yZW1hcF9yZXNvdXJjZShwZGV2LCAwKTsKPj4gK8KgwqDCoCBpZiAo SVNfRVJSKGkyYy0+YmFzZSkpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gZGV2X2Vycl9wcm9i ZSgmcGRldi0+ZGV2LCBQVFJfRVJSKGkyYy0+YmFzZSksICJmYWlsZWQgdG8gZG8KPj4gaW9yZW1h cCIpOwo+PiArCj4+ICvCoMKgwqAgaTJjLT5pcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDAp Owo+PiArwqDCoMKgIGlmIChpMmMtPmlycSA8IDApCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4g ZGV2X2Vycl9wcm9iZSgmcGRldi0+ZGV2LCBpMmMtPmlycSwgImZhaWxlZCB0byBnZXQgaXJxCj4+ IHJlc291cmNlIik7Cj4+ICsKPj4gK8KgwqDCoCByZXQgPSBkZXZtX3JlcXVlc3RfaXJxKGkyYy0+ ZGV2LCBpMmMtPmlycSwgc3BhY2VtaXRfaTJjX2lycV9oYW5kbGVyLAo+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElSUUZfTk9fU1VTUEVORCB8IElSUUZfT05FU0hPVCwg ZGV2X25hbWUoaTJjLT5kZXYpLCBpMmMpOwo+PiArwqDCoMKgIGlmIChyZXQpCj4+ICvCoMKgwqDC oMKgwqDCoCByZXR1cm4gZGV2X2Vycl9wcm9iZSgmcGRldi0+ZGV2LCByZXQsICJmYWlsZWQgdG8g cmVxdWVzdCBpcnEiKTsKPj4gKwo+PiArwqDCoMKgIGRpc2FibGVfaXJxKGkyYy0+aXJxKTsKPj4g Kwo+PiArwqDCoMKgIGNsayA9IGRldm1fY2xrX2dldF9lbmFibGVkKCZwZGV2LT5kZXYsIE5VTEwp Owo+PiArwqDCoMKgIGlmIChJU19FUlIoY2xrKSkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBk ZXZfZXJyX3Byb2JlKCZwZGV2LT5kZXYsIFBUUl9FUlIoY2xrKSwgImZhaWxlZCB0byBlbmFibGUK Pj4gY2xvY2siKTsKPj4gKwo+PiArwqDCoMKgIGkyY19zZXRfYWRhcGRhdGEoJmkyYy0+YWRhcHQs IGkyYyk7Cj4+ICvCoMKgwqAgaTJjLT5hZGFwdC5vd25lciA9IFRISVNfTU9EVUxFOwo+PiArwqDC oMKgIGkyYy0+YWRhcHQuYWxnbyA9ICZzcGFjZW1pdF9pMmNfYWxnbzsKPj4gK8KgwqDCoCBpMmMt PmFkYXB0LmRldi5wYXJlbnQgPSBpMmMtPmRldjsKPj4gK8KgwqDCoCBpMmMtPmFkYXB0Lm5yID0g cGRldi0+aWQ7Cj4+ICsKPj4gK8KgwqDCoCBpMmMtPmFkYXB0LmRldi5vZl9ub2RlID0gb2Zfbm9k ZTsKPj4gK8KgwqDCoCBpMmMtPmFkYXB0LmFsZ29fZGF0YSA9IGkyYzsKPj4gKwo+PiArwqDCoMKg IHN0cnNjcHkoaTJjLT5hZGFwdC5uYW1lLCAic3BhY2VtaXQtaTJjLWFkYXB0ZXIiLCBzaXplb2Yo aTJjLT5hZGFwdC5uYW1lKSk7Cj4+ICsKPj4gK8KgwqDCoCBpbml0X2NvbXBsZXRpb24oJmkyYy0+ Y29tcGxldGUpOwo+PiArCj4gCj4gU2V0IHRoZSBkcml2ZXIgZGF0YSBoZXJlIHNvIGl0J3MgZnVs bHkgaW5pdGlhbGl6ZWQKPiBiZWZvcmUgeW91IGFkZCBpdC4KSSB3aWxsLgo+IAo+IMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIC1BbGV4ClRoYW5rIHlvdSB2ZXJ5IG11Y2gg QWxleCBmb3IgZ2l2aW5nIG1lIHZlcnkgZGV0YWlsZWQgaW5zdHJ1Y3Rpb25zLgo+IAo+PiArwqDC oMKgIHJldCA9IGkyY19hZGRfbnVtYmVyZWRfYWRhcHRlcigmaTJjLT5hZGFwdCk7Cj4+ICvCoMKg wqAgaWYgKHJldCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBkZXZfZXJyX3Byb2JlKCZwZGV2 LT5kZXYsIHJldCwgImZhaWxlZCB0byBhZGQgaTJjIGFkYXB0ZXIiKTsKPj4gKwo+PiArwqDCoMKg IHBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGkyYyk7Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4g MDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgc3BhY2VtaXRfaTJjX3JlbW92ZShzdHJ1Y3Qg cGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBzcGFjZW1pdF9p MmNfZGV2ICppMmMgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKPj4gKwo+PiArwqDCoMKg IGkyY19kZWxfYWRhcHRlcigmaTJjLT5hZGFwdCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIHNwYWNlbWl0X2kyY19vZl9tYXRjaFtdID0gewo+PiArwqDC oMKgIHsgLmNvbXBhdGlibGUgPSAic3BhY2VtaXQsazEtaTJjIiwgfSwKPj4gK8KgwqDCoCB7IC8q IHNlbnRpbmVsICovIH0KPj4gK307Cj4+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBzcGFjZW1p dF9pMmNfb2ZfbWF0Y2gpOwo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBz cGFjZW1pdF9pMmNfZHJpdmVyID0gewo+PiArwqDCoMKgIC5wcm9iZSA9IHNwYWNlbWl0X2kyY19w cm9iZSwKPj4gK8KgwqDCoCAucmVtb3ZlID0gc3BhY2VtaXRfaTJjX3JlbW92ZSwKPj4gK8KgwqDC oCAuZHJpdmVyID0gewo+PiArwqDCoMKgwqDCoMKgwqAgLm5hbWUgPSAiaTJjLWsxIiwKPj4gK8Kg wqDCoMKgwqDCoMKgIC5vZl9tYXRjaF90YWJsZSA9IHNwYWNlbWl0X2kyY19vZl9tYXRjaCwKPj4g K8KgwqDCoCB9LAo+PiArfTsKPj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIoc3BhY2VtaXRfaTJj X2RyaXZlcik7Cj4+ICsKPj4gK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKPj4gK01PRFVMRV9ERVND UklQVElPTigiSTJDIGJ1cyBkcml2ZXIgZm9yIFNwYWNlbWlUIEsxIFNvQyIpOwo+Pgo+IAoKLS0g ClRyb3kgTWl0Y2hlbGwKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fCmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51eC1yaXNjdkBsaXN0cy5pbmZyYWRl YWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgt cmlzY3YK